1#include "duckdb/optimizer/matcher/expression_matcher.hpp"
2
3#include "duckdb/planner/expression/list.hpp"
4
5namespace duckdb {
6
7bool ExpressionMatcher::Match(Expression &expr, vector<reference<Expression>> &bindings) {
8 if (type && !type->Match(type: expr.return_type)) {
9 return false;
10 }
11 if (expr_type && !expr_type->Match(type: expr.type)) {
12 return false;
13 }
14 if (expr_class != ExpressionClass::INVALID && expr_class != expr.GetExpressionClass()) {
15 return false;
16 }
17 bindings.push_back(x: expr);
18 return true;
19}
20
21bool ExpressionEqualityMatcher::Match(Expression &expr, vector<reference<Expression>> &bindings) {
22 if (!expr.Equals(other: expression)) {
23 return false;
24 }
25 bindings.push_back(x: expr);
26 return true;
27}
28
29bool CaseExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
30 if (!ExpressionMatcher::Match(expr&: expr_p, bindings)) {
31 return false;
32 }
33 return true;
34}
35
36bool ComparisonExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
37 if (!ExpressionMatcher::Match(expr&: expr_p, bindings)) {
38 return false;
39 }
40 auto &expr = expr_p.Cast<BoundComparisonExpression>();
41 vector<reference<Expression>> expressions;
42 expressions.push_back(x: *expr.left);
43 expressions.push_back(x: *expr.right);
44 return SetMatcher::Match(matchers, entries&: expressions, bindings, policy);
45}
46
47bool CastExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
48 if (!ExpressionMatcher::Match(expr&: expr_p, bindings)) {
49 return false;
50 }
51 if (!matcher) {
52 return true;
53 }
54 auto &expr = expr_p.Cast<BoundCastExpression>();
55 return matcher->Match(expr&: *expr.child, bindings);
56}
57
58bool InClauseExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
59 if (!ExpressionMatcher::Match(expr&: expr_p, bindings)) {
60 return false;
61 }
62 auto &expr = expr_p.Cast<BoundOperatorExpression>();
63 if (expr.type != ExpressionType::COMPARE_IN || expr.type == ExpressionType::COMPARE_NOT_IN) {
64 return false;
65 }
66 return SetMatcher::Match(matchers, entries&: expr.children, bindings, policy);
67}
68
69bool ConjunctionExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
70 if (!ExpressionMatcher::Match(expr&: expr_p, bindings)) {
71 return false;
72 }
73 auto &expr = expr_p.Cast<BoundConjunctionExpression>();
74 if (!SetMatcher::Match(matchers, entries&: expr.children, bindings, policy)) {
75 return false;
76 }
77 return true;
78}
79
80bool FunctionExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
81 if (!ExpressionMatcher::Match(expr&: expr_p, bindings)) {
82 return false;
83 }
84 auto &expr = expr_p.Cast<BoundFunctionExpression>();
85 if (!FunctionMatcher::Match(matcher&: function, name&: expr.function.name)) {
86 return false;
87 }
88 if (!SetMatcher::Match(matchers, entries&: expr.children, bindings, policy)) {
89 return false;
90 }
91 return true;
92}
93
94bool FoldableConstantMatcher::Match(Expression &expr, vector<reference<Expression>> &bindings) {
95 // we match on ANY expression that is a scalar expression
96 if (!expr.IsFoldable()) {
97 return false;
98 }
99 bindings.push_back(x: expr);
100 return true;
101}
102
103} // namespace duckdb
104