| 202 | } |
| 203 | |
| 204 | Result<compute::Expression> KeyValuePartitioning::ConvertKey(const Key& key) const { |
| 205 | ARROW_ASSIGN_OR_RAISE(auto match, FieldRef(key.name).FindOneOrNone(*schema_)); |
| 206 | if (match.empty()) { |
| 207 | return compute::literal(true); |
| 208 | } |
| 209 | |
| 210 | auto field_index = match[0]; |
| 211 | auto field = schema_->field(field_index); |
| 212 | |
| 213 | std::shared_ptr<Scalar> converted; |
| 214 | |
| 215 | if (!key.value.has_value()) { |
| 216 | return compute::is_null(compute::field_ref(field->name())); |
| 217 | } else if (field->type()->id() == Type::DICTIONARY) { |
| 218 | if (dictionaries_.empty() || dictionaries_[field_index] == nullptr) { |
| 219 | return Status::Invalid("No dictionary provided for dictionary field ", |
| 220 | field->ToString()); |
| 221 | } |
| 222 | |
| 223 | DictionaryScalar::ValueType value; |
| 224 | value.dictionary = dictionaries_[field_index]; |
| 225 | |
| 226 | const auto& dictionary_type = checked_cast<const DictionaryType&>(*field->type()); |
| 227 | if (!value.dictionary->type()->Equals(dictionary_type.value_type())) { |
| 228 | return Status::TypeError("Dictionary supplied for field ", field->ToString(), |
| 229 | " had incorrect type ", |
| 230 | value.dictionary->type()->ToString()); |
| 231 | } |
| 232 | |
| 233 | // look up the partition value in the dictionary |
| 234 | ARROW_ASSIGN_OR_RAISE(converted, Scalar::Parse(value.dictionary->type(), *key.value)); |
| 235 | ARROW_ASSIGN_OR_RAISE(auto index, compute::IndexIn(converted, value.dictionary)); |
| 236 | auto to_index_type = compute::CastOptions::Safe(dictionary_type.index_type()); |
| 237 | ARROW_ASSIGN_OR_RAISE(index, compute::Cast(index, to_index_type)); |
| 238 | value.index = index.scalar(); |
| 239 | if (!value.index->is_valid) { |
| 240 | return Status::Invalid("Dictionary supplied for field ", field->ToString(), |
| 241 | " does not contain '", *key.value, "'"); |
| 242 | } |
| 243 | converted = std::make_shared<DictionaryScalar>(std::move(value), field->type()); |
| 244 | } else { |
| 245 | ARROW_ASSIGN_OR_RAISE(converted, Scalar::Parse(field->type(), *key.value)); |
| 246 | } |
| 247 | |
| 248 | return compute::equal(compute::field_ref(field->name()), |
| 249 | compute::literal(std::move(converted))); |
| 250 | } |
| 251 | |
| 252 | Result<compute::Expression> KeyValuePartitioning::Parse(const std::string& path) const { |
| 253 | std::vector<compute::Expression> expressions; |
nothing calls this directly
no test coverage detected