MCPcopy Create free account
hub / github.com/apache/arrow / FoldConstants

Function FoldConstants

cpp/src/arrow/compute/expression.cc:839–907  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

837}
838
839Result<Expression> FoldConstants(Expression expr) {
840 if (!expr.IsBound()) {
841 return Status::Invalid("Cannot fold constants in unbound expression.");
842 }
843
844 return ModifyExpression(
845 std::move(expr), [](Expression expr) { return expr; },
846 [](Expression expr, ...) -> Result<Expression> {
847 auto call = CallNotNull(expr);
848 if (!call->function->is_pure()) return expr;
849
850 if (std::all_of(call->arguments.begin(), call->arguments.end(),
851 [](const Expression& argument) { return argument.literal(); })) {
852 // all arguments are literal; we can evaluate this subexpression *now*
853 static const ExecBatch ignored_input = ExecBatch({}, 1);
854 ARROW_ASSIGN_OR_RAISE(Datum constant,
855 ExecuteScalarExpression(expr, ignored_input));
856
857 return literal(std::move(constant));
858 }
859
860 // XXX the following should probably be in a registry of passes instead
861 // of inline
862
863 if (GetNullHandling(*call) == compute::NullHandling::INTERSECTION) {
864 // kernels which always produce intersected validity can be resolved
865 // to null *now* if any of their inputs is a null literal
866 for (const Expression& argument : call->arguments) {
867 if (argument.IsNullLiteral()) {
868 if (argument.type()->Equals(*call->type.type)) {
869 return argument;
870 } else {
871 return literal(MakeNullScalar(call->type.GetSharedPtr()));
872 }
873 }
874 }
875 }
876
877 if (call->function_name == "and_kleene") {
878 for (auto args : ArgumentsAndFlippedArguments(*call)) {
879 // true and x == x
880 if (args.first == literal(true)) return args.second;
881
882 // false and x == false
883 if (args.first == literal(false)) return args.first;
884
885 // x and x == x
886 if (args.first == args.second) return args.first;
887 }
888 return expr;
889 }
890
891 if (call->function_name == "or_kleene") {
892 for (auto args : ArgumentsAndFlippedArguments(*call)) {
893 // false or x == x
894 if (args.first == literal(false)) return args.second;
895
896 // true or x == true

Callers 1

SimplifyWithGuaranteeFunction · 0.85

Calls 15

ModifyExpressionFunction · 0.85
CallNotNullFunction · 0.85
GetNullHandlingFunction · 0.85
MakeNullScalarFunction · 0.85
IsBoundMethod · 0.80
literalMethod · 0.80
IsNullLiteralMethod · 0.80
ExecBatchFunction · 0.70
literalFunction · 0.70
InvalidFunction · 0.50
beginMethod · 0.45

Tested by

no test coverage detected