| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "arrow/type.h" |
| |
| #include <climits> |
| #include <cstddef> |
| #include <ostream> |
| #include <sstream> // IWYU pragma: keep |
| #include <string> |
| #include <unordered_map> |
| #include <utility> |
| #include <vector> |
| |
| #include "arrow/array.h" |
| #include "arrow/compare.h" |
| #include "arrow/status.h" |
| #include "arrow/util/checked_cast.h" |
| #include "arrow/util/key_value_metadata.h" |
| #include "arrow/util/logging.h" |
| #include "arrow/util/stl.h" |
| #include "arrow/visitor_inline.h" |
| |
| namespace arrow { |
| |
| using internal::checked_cast; |
| |
| bool Field::HasMetadata() const { |
| return (metadata_ != nullptr) && (metadata_->size() > 0); |
| } |
| |
| std::shared_ptr<Field> Field::AddMetadata( |
| const std::shared_ptr<const KeyValueMetadata>& metadata) const { |
| return std::make_shared<Field>(name_, type_, nullable_, metadata); |
| } |
| |
| std::shared_ptr<Field> Field::RemoveMetadata() const { |
| return std::make_shared<Field>(name_, type_, nullable_); |
| } |
| |
| std::shared_ptr<Field> Field::WithType(const std::shared_ptr<DataType>& type) const { |
| return std::make_shared<Field>(name_, type, nullable_, metadata_); |
| } |
| |
| std::shared_ptr<Field> Field::WithName(const std::string& name) const { |
| return std::make_shared<Field>(name, type_, nullable_, metadata_); |
| } |
| |
| std::vector<std::shared_ptr<Field>> Field::Flatten() const { |
| std::vector<std::shared_ptr<Field>> flattened; |
| if (type_->id() == Type::STRUCT) { |
| for (const auto& child : type_->children()) { |
| auto flattened_child = child->Copy(); |
| flattened.push_back(flattened_child); |
| flattened_child->name_.insert(0, name() + "."); |
| flattened_child->nullable_ |= nullable_; |
| } |
| } else { |
| flattened.push_back(this->Copy()); |
| } |
| return flattened; |
| } |
| |
| std::shared_ptr<Field> Field::Copy() const { |
| return ::arrow::field(name_, type_, nullable_, metadata_); |
| } |
| |
| bool Field::Equals(const Field& other, bool check_metadata) const { |
| if (this == &other) { |
| return true; |
| } |
| if (this->name_ == other.name_ && this->nullable_ == other.nullable_ && |
| this->type_->Equals(*other.type_.get(), check_metadata)) { |
| if (!check_metadata) { |
| return true; |
| } else if (this->HasMetadata() && other.HasMetadata()) { |
| return metadata_->Equals(*other.metadata_); |
| } else if (!this->HasMetadata() && !other.HasMetadata()) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| return false; |
| } |
| |
| bool Field::Equals(const std::shared_ptr<Field>& other, bool check_metadata) const { |
| return Equals(*other.get(), check_metadata); |
| } |
| |
| std::string Field::ToString() const { |
| std::stringstream ss; |
| ss << this->name_ << ": " << this->type_->ToString(); |
| if (!this->nullable_) { |
| ss << " not null"; |
| } |
| return ss.str(); |
| } |
| |
| DataType::~DataType() {} |
| |
| bool DataType::Equals(const DataType& other, bool check_metadata) const { |
| return TypeEquals(*this, other, check_metadata); |
| } |
| |
| bool DataType::Equals(const std::shared_ptr<DataType>& other) const { |
| if (!other) { |
| return false; |
| } |
| return Equals(*other.get()); |
| } |
| |
| std::ostream& operator<<(std::ostream& os, const DataType& type) { |
| os << type.ToString(); |
| return os; |
| } |
| |
| std::string BooleanType::ToString() const { return name(); } |
| |
| FloatingPointType::Precision HalfFloatType::precision() const { |
| return FloatingPointType::HALF; |
| } |
| |
| FloatingPointType::Precision FloatType::precision() const { |
| return FloatingPointType::SINGLE; |
| } |
| |
| FloatingPointType::Precision DoubleType::precision() const { |
| return FloatingPointType::DOUBLE; |
| } |
| |
| std::string StringType::ToString() const { return std::string("string"); } |
| |
| std::string ListType::ToString() const { |
| std::stringstream s; |
| s << "list<" << value_field()->ToString() << ">"; |
| return s.str(); |
| } |
| |
| MapType::MapType(const std::shared_ptr<DataType>& key_type, |
| const std::shared_ptr<DataType>& item_type, bool keys_sorted) |
| : ListType(std::make_shared<Field>( |
| "entries", |
| struct_({std::make_shared<Field>("key", key_type, false), |
| std::make_shared<Field>("value", item_type)}), |
| false)), |
| keys_sorted_(keys_sorted) { |
| id_ = type_id; |
| } |
| |
| std::string MapType::ToString() const { |
| std::stringstream s; |
| s << "map<" << key_type()->ToString() << ", " << item_type()->ToString(); |
| if (keys_sorted_) { |
| s << ", keys_sorted"; |
| } |
| s << ">"; |
| return s.str(); |
| } |
| |
| std::string FixedSizeListType::ToString() const { |
| std::stringstream s; |
| s << "fixed_size_list<" << value_field()->ToString() << ">[" << list_size_ << "]"; |
| return s.str(); |
| } |
| |
| std::string BinaryType::ToString() const { return std::string("binary"); } |
| |
| int FixedSizeBinaryType::bit_width() const { return CHAR_BIT * byte_width(); } |
| |
| std::string FixedSizeBinaryType::ToString() const { |
| std::stringstream ss; |
| ss << "fixed_size_binary[" << byte_width_ << "]"; |
| return ss.str(); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Date types |
| |
| DateType::DateType(Type::type type_id) : TemporalType(type_id) {} |
| |
| Date32Type::Date32Type() : DateType(Type::DATE32) {} |
| |
| Date64Type::Date64Type() : DateType(Type::DATE64) {} |
| |
| std::string Date64Type::ToString() const { return std::string("date64[ms]"); } |
| |
| std::string Date32Type::ToString() const { return std::string("date32[day]"); } |
| |
| // ---------------------------------------------------------------------- |
| // Time types |
| |
| TimeType::TimeType(Type::type type_id, TimeUnit::type unit) |
| : TemporalType(type_id), unit_(unit) {} |
| |
| Time32Type::Time32Type(TimeUnit::type unit) : TimeType(Type::TIME32, unit) { |
| ARROW_CHECK(unit == TimeUnit::SECOND || unit == TimeUnit::MILLI) |
| << "Must be seconds or milliseconds"; |
| } |
| |
| std::string Time32Type::ToString() const { |
| std::stringstream ss; |
| ss << "time32[" << this->unit_ << "]"; |
| return ss.str(); |
| } |
| |
| Time64Type::Time64Type(TimeUnit::type unit) : TimeType(Type::TIME64, unit) { |
| ARROW_CHECK(unit == TimeUnit::MICRO || unit == TimeUnit::NANO) |
| << "Must be microseconds or nanoseconds"; |
| } |
| |
| std::string Time64Type::ToString() const { |
| std::stringstream ss; |
| ss << "time64[" << this->unit_ << "]"; |
| return ss.str(); |
| } |
| |
| std::ostream& operator<<(std::ostream& os, TimeUnit::type unit) { |
| switch (unit) { |
| case TimeUnit::SECOND: |
| os << "s"; |
| break; |
| case TimeUnit::MILLI: |
| os << "ms"; |
| break; |
| case TimeUnit::MICRO: |
| os << "us"; |
| break; |
| case TimeUnit::NANO: |
| os << "ns"; |
| break; |
| } |
| return os; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Timestamp types |
| |
| std::string TimestampType::ToString() const { |
| std::stringstream ss; |
| ss << "timestamp[" << this->unit_; |
| if (this->timezone_.size() > 0) { |
| ss << ", tz=" << this->timezone_; |
| } |
| ss << "]"; |
| return ss.str(); |
| } |
| |
| // Duration types |
| std::string DurationType::ToString() const { |
| std::stringstream ss; |
| ss << "duration[" << this->unit_ << "]"; |
| return ss.str(); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Union type |
| |
| UnionType::UnionType(const std::vector<std::shared_ptr<Field>>& fields, |
| const std::vector<uint8_t>& type_codes, UnionMode::type mode) |
| : NestedType(Type::UNION), mode_(mode), type_codes_(type_codes) { |
| children_ = fields; |
| } |
| |
| DataTypeLayout UnionType::layout() const { |
| if (mode_ == UnionMode::SPARSE) { |
| return {{1, CHAR_BIT, DataTypeLayout::kAlwaysNullBuffer}, false}; |
| } else { |
| return {{1, CHAR_BIT, sizeof(int32_t) * CHAR_BIT}, false}; |
| } |
| } |
| |
| std::string UnionType::ToString() const { |
| std::stringstream s; |
| |
| if (mode_ == UnionMode::SPARSE) { |
| s << "union[sparse]<"; |
| } else { |
| s << "union[dense]<"; |
| } |
| |
| for (size_t i = 0; i < children_.size(); ++i) { |
| if (i) { |
| s << ", "; |
| } |
| s << children_[i]->ToString() << "=" << static_cast<int>(type_codes_[i]); |
| } |
| s << ">"; |
| return s.str(); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Struct type |
| |
| namespace { |
| |
| std::unordered_multimap<std::string, int> CreateNameToIndexMap( |
| const std::vector<std::shared_ptr<Field>>& fields) { |
| std::unordered_multimap<std::string, int> name_to_index; |
| for (size_t i = 0; i < fields.size(); ++i) { |
| name_to_index.emplace(fields[i]->name(), static_cast<int>(i)); |
| } |
| return name_to_index; |
| } |
| |
| int LookupNameIndex(const std::unordered_multimap<std::string, int>& name_to_index, |
| const std::string& name) { |
| auto p = name_to_index.equal_range(name); |
| auto it = p.first; |
| if (it == p.second) { |
| // Not found |
| return -1; |
| } |
| auto index = it->second; |
| if (++it != p.second) { |
| // Duplicate field name |
| return -1; |
| } |
| return index; |
| } |
| |
| } // namespace |
| |
| class StructType::Impl { |
| public: |
| explicit Impl(const std::vector<std::shared_ptr<Field>>& fields) |
| : name_to_index_(CreateNameToIndexMap(fields)) {} |
| |
| const std::unordered_multimap<std::string, int> name_to_index_; |
| }; |
| |
| StructType::StructType(const std::vector<std::shared_ptr<Field>>& fields) |
| : NestedType(Type::STRUCT), impl_(new Impl(fields)) { |
| children_ = fields; |
| } |
| |
| StructType::~StructType() {} |
| |
| std::string StructType::ToString() const { |
| std::stringstream s; |
| s << "struct<"; |
| for (int i = 0; i < this->num_children(); ++i) { |
| if (i > 0) { |
| s << ", "; |
| } |
| std::shared_ptr<Field> field = this->child(i); |
| s << field->name() << ": " << field->type()->ToString(); |
| } |
| s << ">"; |
| return s.str(); |
| } |
| |
| std::shared_ptr<Field> StructType::GetFieldByName(const std::string& name) const { |
| int i = GetFieldIndex(name); |
| return i == -1 ? nullptr : children_[i]; |
| } |
| |
| int StructType::GetFieldIndex(const std::string& name) const { |
| return LookupNameIndex(impl_->name_to_index_, name); |
| } |
| |
| std::vector<int> StructType::GetAllFieldIndices(const std::string& name) const { |
| std::vector<int> result; |
| auto p = impl_->name_to_index_.equal_range(name); |
| for (auto it = p.first; it != p.second; ++it) { |
| result.push_back(it->second); |
| } |
| return result; |
| } |
| |
| std::vector<std::shared_ptr<Field>> StructType::GetAllFieldsByName( |
| const std::string& name) const { |
| std::vector<std::shared_ptr<Field>> result; |
| auto p = impl_->name_to_index_.equal_range(name); |
| for (auto it = p.first; it != p.second; ++it) { |
| result.push_back(children_[it->second]); |
| } |
| return result; |
| } |
| |
| // Deprecated methods |
| |
| std::shared_ptr<Field> StructType::GetChildByName(const std::string& name) const { |
| return GetFieldByName(name); |
| } |
| |
| int StructType::GetChildIndex(const std::string& name) const { |
| return GetFieldIndex(name); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Decimal128 type |
| |
| Decimal128Type::Decimal128Type(int32_t precision, int32_t scale) |
| : DecimalType(16, precision, scale) { |
| ARROW_CHECK_GE(precision, 1); |
| ARROW_CHECK_LE(precision, 38); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Dictionary-encoded type |
| |
| int DictionaryType::bit_width() const { |
| return checked_cast<const FixedWidthType&>(*index_type_).bit_width(); |
| } |
| |
| DictionaryType::DictionaryType(const std::shared_ptr<DataType>& index_type, |
| const std::shared_ptr<DataType>& value_type, bool ordered) |
| : FixedWidthType(Type::DICTIONARY), |
| index_type_(index_type), |
| value_type_(value_type), |
| ordered_(ordered) { |
| ARROW_CHECK(is_integer(index_type->id())) |
| << "dictionary index type should be signed integer"; |
| const auto& int_type = checked_cast<const IntegerType&>(*index_type); |
| ARROW_CHECK(int_type.is_signed()) << "dictionary index type should be signed integer"; |
| } |
| |
| DataTypeLayout DictionaryType::layout() const { |
| auto layout = index_type_->layout(); |
| layout.has_dictionary = true; |
| return layout; |
| } |
| |
| std::string DictionaryType::ToString() const { |
| std::stringstream ss; |
| ss << this->name() << "<values=" << value_type_->ToString() |
| << ", indices=" << index_type_->ToString() << ", ordered=" << ordered_ << ">"; |
| return ss.str(); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Null type |
| |
| std::string NullType::ToString() const { return name(); } |
| |
| // ---------------------------------------------------------------------- |
| // Schema implementation |
| |
| class Schema::Impl { |
| public: |
| Impl(const std::vector<std::shared_ptr<Field>>& fields, |
| const std::shared_ptr<const KeyValueMetadata>& metadata) |
| : fields_(fields), |
| name_to_index_(CreateNameToIndexMap(fields_)), |
| metadata_(metadata) {} |
| |
| Impl(std::vector<std::shared_ptr<Field>>&& fields, |
| const std::shared_ptr<const KeyValueMetadata>& metadata) |
| : fields_(std::move(fields)), |
| name_to_index_(CreateNameToIndexMap(fields_)), |
| metadata_(metadata) {} |
| |
| std::vector<std::shared_ptr<Field>> fields_; |
| std::unordered_multimap<std::string, int> name_to_index_; |
| std::shared_ptr<const KeyValueMetadata> metadata_; |
| }; |
| |
| Schema::Schema(const std::vector<std::shared_ptr<Field>>& fields, |
| const std::shared_ptr<const KeyValueMetadata>& metadata) |
| : impl_(new Impl(fields, metadata)) {} |
| |
| Schema::Schema(std::vector<std::shared_ptr<Field>>&& fields, |
| const std::shared_ptr<const KeyValueMetadata>& metadata) |
| : impl_(new Impl(std::move(fields), metadata)) {} |
| |
| Schema::Schema(const Schema& schema) : impl_(new Impl(*schema.impl_)) {} |
| |
| Schema::~Schema() {} |
| |
| int Schema::num_fields() const { return static_cast<int>(impl_->fields_.size()); } |
| |
| std::shared_ptr<Field> Schema::field(int i) const { return impl_->fields_[i]; } |
| |
| const std::vector<std::shared_ptr<Field>>& Schema::fields() const { |
| return impl_->fields_; |
| } |
| |
| bool Schema::Equals(const Schema& other, bool check_metadata) const { |
| if (this == &other) { |
| return true; |
| } |
| |
| // checks field equality |
| if (num_fields() != other.num_fields()) { |
| return false; |
| } |
| for (int i = 0; i < num_fields(); ++i) { |
| if (!field(i)->Equals(*other.field(i).get(), check_metadata)) { |
| return false; |
| } |
| } |
| |
| // check metadata equality |
| if (!check_metadata) { |
| return true; |
| } else if (this->HasMetadata() && other.HasMetadata()) { |
| return impl_->metadata_->Equals(*other.impl_->metadata_); |
| } else if (!this->HasMetadata() && !other.HasMetadata()) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| std::shared_ptr<Field> Schema::GetFieldByName(const std::string& name) const { |
| int i = GetFieldIndex(name); |
| return i == -1 ? nullptr : impl_->fields_[i]; |
| } |
| |
| int Schema::GetFieldIndex(const std::string& name) const { |
| return LookupNameIndex(impl_->name_to_index_, name); |
| } |
| |
| std::vector<int> Schema::GetAllFieldIndices(const std::string& name) const { |
| std::vector<int> result; |
| auto p = impl_->name_to_index_.equal_range(name); |
| for (auto it = p.first; it != p.second; ++it) { |
| result.push_back(it->second); |
| } |
| return result; |
| } |
| |
| std::vector<std::shared_ptr<Field>> Schema::GetAllFieldsByName( |
| const std::string& name) const { |
| std::vector<std::shared_ptr<Field>> result; |
| auto p = impl_->name_to_index_.equal_range(name); |
| for (auto it = p.first; it != p.second; ++it) { |
| result.push_back(impl_->fields_[it->second]); |
| } |
| return result; |
| } |
| |
| Status Schema::AddField(int i, const std::shared_ptr<Field>& field, |
| std::shared_ptr<Schema>* out) const { |
| if (i < 0 || i > this->num_fields()) { |
| return Status::Invalid("Invalid column index to add field."); |
| } |
| |
| *out = std::make_shared<Schema>(internal::AddVectorElement(impl_->fields_, i, field), |
| impl_->metadata_); |
| return Status::OK(); |
| } |
| |
| Status Schema::SetField(int i, const std::shared_ptr<Field>& field, |
| std::shared_ptr<Schema>* out) const { |
| if (i < 0 || i > this->num_fields()) { |
| return Status::Invalid("Invalid column index to add field."); |
| } |
| |
| *out = std::make_shared<Schema>( |
| internal::ReplaceVectorElement(impl_->fields_, i, field), impl_->metadata_); |
| return Status::OK(); |
| } |
| |
| bool Schema::HasMetadata() const { |
| return (impl_->metadata_ != nullptr) && (impl_->metadata_->size() > 0); |
| } |
| |
| std::shared_ptr<Schema> Schema::AddMetadata( |
| const std::shared_ptr<const KeyValueMetadata>& metadata) const { |
| return std::make_shared<Schema>(impl_->fields_, metadata); |
| } |
| |
| std::shared_ptr<const KeyValueMetadata> Schema::metadata() const { |
| return impl_->metadata_; |
| } |
| |
| std::shared_ptr<Schema> Schema::RemoveMetadata() const { |
| return std::make_shared<Schema>(impl_->fields_); |
| } |
| |
| Status Schema::RemoveField(int i, std::shared_ptr<Schema>* out) const { |
| if (i < 0 || i >= this->num_fields()) { |
| return Status::Invalid("Invalid column index to remove field."); |
| } |
| |
| *out = std::make_shared<Schema>(internal::DeleteVectorElement(impl_->fields_, i), |
| impl_->metadata_); |
| return Status::OK(); |
| } |
| |
| std::string Schema::ToString() const { |
| std::stringstream buffer; |
| |
| int i = 0; |
| for (const auto& field : impl_->fields_) { |
| if (i > 0) { |
| buffer << std::endl; |
| } |
| buffer << field->ToString(); |
| ++i; |
| } |
| |
| if (impl_->metadata_) { |
| buffer << impl_->metadata_->ToString(); |
| } |
| |
| return buffer.str(); |
| } |
| |
| std::vector<std::string> Schema::field_names() const { |
| std::vector<std::string> names; |
| for (const auto& field : impl_->fields_) { |
| names.push_back(field->name()); |
| } |
| return names; |
| } |
| |
| std::shared_ptr<Schema> schema(const std::vector<std::shared_ptr<Field>>& fields, |
| const std::shared_ptr<const KeyValueMetadata>& metadata) { |
| return std::make_shared<Schema>(fields, metadata); |
| } |
| |
| std::shared_ptr<Schema> schema(std::vector<std::shared_ptr<Field>>&& fields, |
| const std::shared_ptr<const KeyValueMetadata>& metadata) { |
| return std::make_shared<Schema>(std::move(fields), metadata); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Visitors and factory functions |
| |
| Status DataType::Accept(TypeVisitor* visitor) const { |
| return VisitTypeInline(*this, visitor); |
| } |
| |
| #define TYPE_FACTORY(NAME, KLASS) \ |
| std::shared_ptr<DataType> NAME() { \ |
| static std::shared_ptr<DataType> result = std::make_shared<KLASS>(); \ |
| return result; \ |
| } |
| |
| TYPE_FACTORY(null, NullType) |
| TYPE_FACTORY(boolean, BooleanType) |
| TYPE_FACTORY(int8, Int8Type) |
| TYPE_FACTORY(uint8, UInt8Type) |
| TYPE_FACTORY(int16, Int16Type) |
| TYPE_FACTORY(uint16, UInt16Type) |
| TYPE_FACTORY(int32, Int32Type) |
| TYPE_FACTORY(uint32, UInt32Type) |
| TYPE_FACTORY(int64, Int64Type) |
| TYPE_FACTORY(uint64, UInt64Type) |
| TYPE_FACTORY(float16, HalfFloatType) |
| TYPE_FACTORY(float32, FloatType) |
| TYPE_FACTORY(float64, DoubleType) |
| TYPE_FACTORY(utf8, StringType) |
| TYPE_FACTORY(binary, BinaryType) |
| TYPE_FACTORY(date64, Date64Type) |
| TYPE_FACTORY(date32, Date32Type) |
| |
| std::shared_ptr<DataType> fixed_size_binary(int32_t byte_width) { |
| return std::make_shared<FixedSizeBinaryType>(byte_width); |
| } |
| |
| std::shared_ptr<DataType> duration(TimeUnit::type unit) { |
| return std::make_shared<DurationType>(unit); |
| } |
| |
| std::shared_ptr<DataType> day_time_interval() { |
| return std::make_shared<DayTimeIntervalType>(); |
| } |
| |
| std::shared_ptr<DataType> month_interval() { |
| return std::make_shared<MonthIntervalType>(); |
| } |
| |
| std::shared_ptr<DataType> timestamp(TimeUnit::type unit) { |
| return std::make_shared<TimestampType>(unit); |
| } |
| |
| std::shared_ptr<DataType> timestamp(TimeUnit::type unit, const std::string& timezone) { |
| return std::make_shared<TimestampType>(unit, timezone); |
| } |
| |
| std::shared_ptr<DataType> time32(TimeUnit::type unit) { |
| return std::make_shared<Time32Type>(unit); |
| } |
| |
| std::shared_ptr<DataType> time64(TimeUnit::type unit) { |
| return std::make_shared<Time64Type>(unit); |
| } |
| |
| std::shared_ptr<DataType> list(const std::shared_ptr<DataType>& value_type) { |
| return std::make_shared<ListType>(value_type); |
| } |
| |
| std::shared_ptr<DataType> list(const std::shared_ptr<Field>& value_field) { |
| return std::make_shared<ListType>(value_field); |
| } |
| |
| std::shared_ptr<DataType> map(const std::shared_ptr<DataType>& key_type, |
| const std::shared_ptr<DataType>& value_type, |
| bool keys_sorted) { |
| return std::make_shared<MapType>(key_type, value_type, keys_sorted); |
| } |
| |
| std::shared_ptr<DataType> fixed_size_list(const std::shared_ptr<DataType>& value_type, |
| int32_t list_size) { |
| return std::make_shared<FixedSizeListType>(value_type, list_size); |
| } |
| |
| std::shared_ptr<DataType> fixed_size_list(const std::shared_ptr<Field>& value_field, |
| int32_t list_size) { |
| return std::make_shared<FixedSizeListType>(value_field, list_size); |
| } |
| |
| std::shared_ptr<DataType> struct_(const std::vector<std::shared_ptr<Field>>& fields) { |
| return std::make_shared<StructType>(fields); |
| } |
| |
| std::shared_ptr<DataType> union_(const std::vector<std::shared_ptr<Field>>& child_fields, |
| const std::vector<uint8_t>& type_codes, |
| UnionMode::type mode) { |
| return std::make_shared<UnionType>(child_fields, type_codes, mode); |
| } |
| |
| std::shared_ptr<DataType> union_(const std::vector<std::shared_ptr<Array>>& children, |
| const std::vector<std::string>& field_names, |
| const std::vector<uint8_t>& given_type_codes, |
| UnionMode::type mode) { |
| std::vector<std::shared_ptr<Field>> types; |
| std::vector<uint8_t> type_codes(given_type_codes); |
| uint8_t counter = 0; |
| for (const auto& child : children) { |
| if (field_names.size() == 0) { |
| types.push_back(field(std::to_string(counter), child->type())); |
| } else { |
| types.push_back(field(field_names[counter], child->type())); |
| } |
| if (given_type_codes.size() == 0) { |
| type_codes.push_back(counter); |
| } |
| counter++; |
| } |
| return union_(types, type_codes, mode); |
| } |
| |
| std::shared_ptr<DataType> dictionary(const std::shared_ptr<DataType>& index_type, |
| const std::shared_ptr<DataType>& dict_type, |
| bool ordered) { |
| return std::make_shared<DictionaryType>(index_type, dict_type, ordered); |
| } |
| |
| std::shared_ptr<Field> field(const std::string& name, |
| const std::shared_ptr<DataType>& type, bool nullable, |
| const std::shared_ptr<const KeyValueMetadata>& metadata) { |
| return std::make_shared<Field>(name, type, nullable, metadata); |
| } |
| |
| std::shared_ptr<DataType> decimal(int32_t precision, int32_t scale) { |
| return std::make_shared<Decimal128Type>(precision, scale); |
| } |
| |
| std::string Decimal128Type::ToString() const { |
| std::stringstream s; |
| s << "decimal(" << precision_ << ", " << scale_ << ")"; |
| return s.str(); |
| } |
| |
| } // namespace arrow |