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

Function Canonicalize

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

Source from the content-addressed store, hash-verified

1056} // namespace
1057
1058Result<Expression> Canonicalize(Expression expr, compute::ExecContext* exec_context) {
1059 if (!expr.IsBound()) {
1060 return Status::Invalid("Cannot canonicalize an unbound expression.");
1061 }
1062
1063 if (exec_context == nullptr) {
1064 compute::ExecContext exec_context;
1065 return Canonicalize(std::move(expr), &exec_context);
1066 }
1067
1068 // If potentially reconstructing more deeply than a call's immediate arguments
1069 // (for example, when reorganizing an associative chain), add expressions to this set to
1070 // avoid unnecessary work
1071 struct {
1072 std::unordered_set<Expression, Expression::Hash> set_;
1073
1074 bool operator()(const Expression& expr) const {
1075 return set_.find(expr) != set_.end();
1076 }
1077
1078 void Add(std::vector<Expression> exprs) {
1079 std::move(exprs.begin(), exprs.end(), std::inserter(set_, set_.end()));
1080 }
1081 } AlreadyCanonicalized;
1082
1083 return ModifyExpression(
1084 std::move(expr),
1085 [&AlreadyCanonicalized, exec_context](Expression expr) -> Result<Expression> {
1086 auto call = expr.call();
1087 if (!call) return expr;
1088 if (!call->function->is_pure()) return expr;
1089
1090 if (AlreadyCanonicalized(expr)) return expr;
1091
1092 if (IsBinaryAssociativeCommutative(*call)) {
1093 struct {
1094 int Priority(const Expression& operand) const {
1095 // order literals first, starting with nulls
1096 if (operand.IsNullLiteral()) return 0;
1097 if (operand.literal()) return 1;
1098 return 2;
1099 }
1100 bool operator()(const Expression& l, const Expression& r) const {
1101 return Priority(l) < Priority(r);
1102 }
1103 } CanonicalOrdering;
1104
1105 FlattenedAssociativeChain chain(expr);
1106
1107 if (chain.was_left_folded &&
1108 std::is_sorted(chain.fringe.begin(), chain.fringe.end(),
1109 CanonicalOrdering)) {
1110 // fast path for expressions which happen to have arrived in an
1111 // already-canonical form
1112 AlreadyCanonicalized.Add(std::move(chain.exprs));
1113 return expr;
1114 }
1115

Callers 1

SimplifyWithGuaranteeFunction · 0.85

Calls 14

ModifyExpressionFunction · 0.85
HandleInconsistentTypesFunction · 0.85
swapFunction · 0.85
BindNonRecursiveFunction · 0.85
IsBoundMethod · 0.80
callMethod · 0.80
literalMethod · 0.80
GetFunction · 0.70
InvalidFunction · 0.50
ARROW_ASSIGN_OR_RAISEFunction · 0.50
beginMethod · 0.45

Tested by

no test coverage detected