| 978 | } |
| 979 | |
| 980 | Result<Expression> ReplaceFieldsWithKnownValues(const KnownFieldValues& known_values, |
| 981 | Expression expr) { |
| 982 | if (!expr.IsBound()) { |
| 983 | return Status::Invalid( |
| 984 | "ReplaceFieldsWithKnownValues called on an unbound Expression"); |
| 985 | } |
| 986 | |
| 987 | return ModifyExpression( |
| 988 | std::move(expr), |
| 989 | [&known_values](Expression expr) -> Result<Expression> { |
| 990 | if (auto ref = expr.field_ref()) { |
| 991 | auto it = known_values.map.find(*ref); |
| 992 | if (it != known_values.map.end()) { |
| 993 | Datum lit = it->second; |
| 994 | if (lit.type()->Equals(*expr.type())) return literal(std::move(lit)); |
| 995 | // type mismatch, try casting the known value to the correct type |
| 996 | |
| 997 | if (expr.type()->id() == Type::DICTIONARY && |
| 998 | lit.type()->id() != Type::DICTIONARY) { |
| 999 | // the known value must be dictionary encoded |
| 1000 | |
| 1001 | const auto& dict_type = checked_cast<const DictionaryType&>(*expr.type()); |
| 1002 | if (!lit.type()->Equals(dict_type.value_type())) { |
| 1003 | ARROW_ASSIGN_OR_RAISE(lit, compute::Cast(lit, dict_type.value_type())); |
| 1004 | } |
| 1005 | |
| 1006 | if (lit.is_scalar()) { |
| 1007 | ARROW_ASSIGN_OR_RAISE(auto dictionary, |
| 1008 | MakeArrayFromScalar(*lit.scalar(), 1)); |
| 1009 | |
| 1010 | lit = Datum{DictionaryScalar::Make(MakeScalar<int32_t>(0), |
| 1011 | std::move(dictionary))}; |
| 1012 | } |
| 1013 | } |
| 1014 | |
| 1015 | ARROW_ASSIGN_OR_RAISE(lit, compute::Cast(lit, expr.type()->GetSharedPtr())); |
| 1016 | return literal(std::move(lit)); |
| 1017 | } |
| 1018 | } |
| 1019 | return expr; |
| 1020 | }, |
| 1021 | [](Expression expr, ...) { return expr; }); |
| 1022 | } |
| 1023 | |
| 1024 | namespace { |
| 1025 |
no test coverage detected