| 891 | } |
| 892 | |
| 893 | Status ReadDictionary(const Buffer& metadata, IpcReadContext context, |
| 894 | DictionaryKind* kind, io::RandomAccessFile* file) { |
| 895 | const flatbuf::Message* message = nullptr; |
| 896 | RETURN_NOT_OK(internal::VerifyMessage(metadata.data(), metadata.size(), &message)); |
| 897 | const auto dictionary_batch = message->header_as_DictionaryBatch(); |
| 898 | if (dictionary_batch == nullptr) { |
| 899 | return Status::IOError( |
| 900 | "Header-type of flatbuffer-encoded Message is not DictionaryBatch."); |
| 901 | } |
| 902 | |
| 903 | // The dictionary is embedded in a record batch with a single column |
| 904 | const auto batch_meta = dictionary_batch->data(); |
| 905 | |
| 906 | CHECK_FLATBUFFERS_NOT_NULL(batch_meta, "DictionaryBatch.data"); |
| 907 | |
| 908 | RETURN_NOT_OK(GetCompression(batch_meta, &context.compression)); |
| 909 | if (context.compression == Compression::UNCOMPRESSED && |
| 910 | message->version() == flatbuf::MetadataVersion::MetadataVersion_V4) { |
| 911 | // Possibly obtain codec information from experimental serialization format |
| 912 | // in 0.17.x |
| 913 | RETURN_NOT_OK(GetCompressionExperimental(message, &context.compression)); |
| 914 | } |
| 915 | |
| 916 | const int64_t id = dictionary_batch->id(); |
| 917 | |
| 918 | // Look up the dictionary value type, which must have been added to the |
| 919 | // DictionaryMemo already prior to invoking this function |
| 920 | ARROW_ASSIGN_OR_RAISE(auto value_type, context.dictionary_memo->GetDictionaryType(id)); |
| 921 | |
| 922 | // Load the dictionary data from the dictionary batch |
| 923 | ArrayLoader loader(batch_meta, internal::GetMetadataVersion(message->version()), |
| 924 | context.options, file); |
| 925 | auto dict_data = std::make_shared<ArrayData>(); |
| 926 | const Field dummy_field("", value_type); |
| 927 | RETURN_NOT_OK(loader.Load(&dummy_field, dict_data.get())); |
| 928 | |
| 929 | // Run post-load steps: buffer decompression, etc. |
| 930 | RecordBatchLoader batch_loader{context, /*schema=*/nullptr, batch_meta->length(), |
| 931 | /*inclusion_mask=*/std::vector<bool>{}}; |
| 932 | ARROW_ASSIGN_OR_RAISE( |
| 933 | auto dict_columns, |
| 934 | batch_loader.CreateColumns({dict_data}, /*resolve_dictionaries=*/false)); |
| 935 | DCHECK_EQ(dict_columns.size(), 1); |
| 936 | dict_data = dict_columns[0]; |
| 937 | |
| 938 | if (dictionary_batch->isDelta()) { |
| 939 | if (kind != nullptr) { |
| 940 | *kind = DictionaryKind::Delta; |
| 941 | } |
| 942 | return context.dictionary_memo->AddDictionaryDelta(id, dict_data); |
| 943 | } |
| 944 | ARROW_ASSIGN_OR_RAISE(bool inserted, |
| 945 | context.dictionary_memo->AddOrReplaceDictionary(id, dict_data)); |
| 946 | if (kind != nullptr) { |
| 947 | *kind = inserted ? DictionaryKind::New : DictionaryKind::Replacement; |
| 948 | } |
| 949 | return Status::OK(); |
| 950 | } |
no test coverage detected