| 862 | }; |
| 863 | |
| 864 | Status FieldFromFlatbuffer(const flatbuf::Field* field, FieldPosition field_pos, |
| 865 | DictionaryMemo* dictionary_memo, std::shared_ptr<Field>* out) { |
| 866 | std::shared_ptr<DataType> type; |
| 867 | |
| 868 | std::shared_ptr<KeyValueMetadata> metadata; |
| 869 | RETURN_NOT_OK(internal::GetKeyValueMetadata(field->custom_metadata(), &metadata)); |
| 870 | |
| 871 | // Reconstruct the data type |
| 872 | // 1. Data type children |
| 873 | FieldVector child_fields; |
| 874 | const auto& children = field->children(); |
| 875 | // As a tolerance, allow for a null children field meaning "no children" (ARROW-12100) |
| 876 | if (children != nullptr) { |
| 877 | child_fields.resize(children->size()); |
| 878 | for (int i = 0; i < static_cast<int>(children->size()); ++i) { |
| 879 | RETURN_NOT_OK(FieldFromFlatbuffer(children->Get(i), field_pos.child(i), |
| 880 | dictionary_memo, &child_fields[i])); |
| 881 | } |
| 882 | } |
| 883 | |
| 884 | // 2. Top-level concrete data type |
| 885 | auto type_data = field->type(); |
| 886 | CHECK_FLATBUFFERS_NOT_NULL(type_data, "Field.type"); |
| 887 | RETURN_NOT_OK(ConcreteTypeFromFlatbuffer(field->type_type(), type_data, |
| 888 | std::move(child_fields), &type)); |
| 889 | |
| 890 | // 3. Is it a dictionary type? |
| 891 | int64_t dictionary_id = -1; |
| 892 | std::shared_ptr<DataType> dict_value_type; |
| 893 | const flatbuf::DictionaryEncoding* encoding = field->dictionary(); |
| 894 | if (encoding != nullptr) { |
| 895 | // The field is dictionary-encoded. Construct the DictionaryType |
| 896 | // based on the DictionaryEncoding metadata and record in the |
| 897 | // dictionary_memo |
| 898 | std::shared_ptr<DataType> index_type; |
| 899 | auto int_data = encoding->indexType(); |
| 900 | CHECK_FLATBUFFERS_NOT_NULL(int_data, "DictionaryEncoding.indexType"); |
| 901 | RETURN_NOT_OK(IntFromFlatbuffer(int_data, &index_type)); |
| 902 | dict_value_type = type; |
| 903 | ARROW_ASSIGN_OR_RAISE(type, |
| 904 | DictionaryType::Make(index_type, type, encoding->isOrdered())); |
| 905 | dictionary_id = encoding->id(); |
| 906 | } |
| 907 | |
| 908 | // 4. Is it an extension type? |
| 909 | if (metadata != nullptr) { |
| 910 | // Look for extension metadata in custom_metadata field |
| 911 | int name_index = metadata->FindKey(kExtensionTypeKeyName); |
| 912 | if (name_index != -1) { |
| 913 | std::shared_ptr<ExtensionType> ext_type = |
| 914 | GetExtensionType(metadata->value(name_index)); |
| 915 | if (ext_type != nullptr) { |
| 916 | int data_index = metadata->FindKey(kExtensionMetadataKeyName); |
| 917 | std::string type_data = data_index == -1 ? "" : metadata->value(data_index); |
| 918 | |
| 919 | ARROW_ASSIGN_OR_RAISE(type, ext_type->Deserialize(type, type_data)); |
| 920 | // Remove the metadata, for faithful roundtripping |
| 921 | if (data_index != -1) { |
no test coverage detected