1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/optimizer/matcher/expression_matcher.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/exception.hpp"
12#include "duckdb/optimizer/matcher/expression_type_matcher.hpp"
13#include "duckdb/optimizer/matcher/set_matcher.hpp"
14#include "duckdb/optimizer/matcher/type_matcher.hpp"
15#include "duckdb/optimizer/matcher/function_matcher.hpp"
16#include "duckdb/planner/logical_operator.hpp"
17
18namespace duckdb {
19
20//! The ExpressionMatcher class contains a set of matchers that can be used to pattern match Expressions
21class ExpressionMatcher {
22public:
23 explicit ExpressionMatcher(ExpressionClass type = ExpressionClass::INVALID) : expr_class(type) {
24 }
25 virtual ~ExpressionMatcher() {
26 }
27
28 //! Checks if the given expression matches this ExpressionMatcher. If it does, the expression is appended to the
29 //! bindings list and true is returned. Otherwise, false is returned.
30 virtual bool Match(Expression &expr, vector<reference<Expression>> &bindings);
31
32 //! The ExpressionClass of the to-be-matched expression. ExpressionClass::INVALID for ANY.
33 ExpressionClass expr_class;
34 //! Matcher for the ExpressionType of the operator (nullptr for ANY)
35 unique_ptr<ExpressionTypeMatcher> expr_type;
36 //! Matcher for the return_type of the expression (nullptr for ANY)
37 unique_ptr<TypeMatcher> type;
38};
39
40//! The ExpressionEqualityMatcher matches on equality with another (given) expression
41class ExpressionEqualityMatcher : public ExpressionMatcher {
42public:
43 explicit ExpressionEqualityMatcher(Expression &expr)
44 : ExpressionMatcher(ExpressionClass::INVALID), expression(expr) {
45 }
46
47 bool Match(Expression &expr, vector<reference<Expression>> &bindings) override;
48
49private:
50 const Expression &expression;
51};
52
53class ConstantExpressionMatcher : public ExpressionMatcher {
54public:
55 ConstantExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CONSTANT) {
56 }
57};
58
59class CaseExpressionMatcher : public ExpressionMatcher {
60public:
61 CaseExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CASE) {
62 }
63
64 bool Match(Expression &expr_, vector<reference<Expression>> &bindings) override;
65};
66
67class ComparisonExpressionMatcher : public ExpressionMatcher {
68public:
69 ComparisonExpressionMatcher()
70 : ExpressionMatcher(ExpressionClass::BOUND_COMPARISON), policy(SetMatcher::Policy::INVALID) {
71 }
72 //! The matchers for the child expressions
73 vector<unique_ptr<ExpressionMatcher>> matchers;
74 //! The set matcher matching policy to use
75 SetMatcher::Policy policy;
76
77 bool Match(Expression &expr_, vector<reference<Expression>> &bindings) override;
78};
79
80class CastExpressionMatcher : public ExpressionMatcher {
81public:
82 CastExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CAST) {
83 }
84 //! The matcher for the child expressions
85 unique_ptr<ExpressionMatcher> matcher;
86
87 bool Match(Expression &expr_, vector<reference<Expression>> &bindings) override;
88};
89
90class InClauseExpressionMatcher : public ExpressionMatcher {
91public:
92 InClauseExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_OPERATOR) {
93 }
94 //! The matchers for the child expressions
95 vector<unique_ptr<ExpressionMatcher>> matchers;
96 //! The set matcher matching policy to use
97 SetMatcher::Policy policy;
98
99 bool Match(Expression &expr_, vector<reference<Expression>> &bindings) override;
100};
101
102class ConjunctionExpressionMatcher : public ExpressionMatcher {
103public:
104 ConjunctionExpressionMatcher()
105 : ExpressionMatcher(ExpressionClass::BOUND_CONJUNCTION), policy(SetMatcher::Policy::INVALID) {
106 }
107 //! The matchers for the child expressions
108 vector<unique_ptr<ExpressionMatcher>> matchers;
109 //! The set matcher matching policy to use
110 SetMatcher::Policy policy;
111
112 bool Match(Expression &expr_, vector<reference<Expression>> &bindings) override;
113};
114
115class FunctionExpressionMatcher : public ExpressionMatcher {
116public:
117 FunctionExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_FUNCTION) {
118 }
119 //! The matchers for the child expressions
120 vector<unique_ptr<ExpressionMatcher>> matchers;
121 //! The set matcher matching policy to use
122 SetMatcher::Policy policy;
123 //! The function name to match
124 unique_ptr<FunctionMatcher> function;
125
126 bool Match(Expression &expr_, vector<reference<Expression>> &bindings) override;
127};
128
129//! The FoldableConstant matcher matches any expression that is foldable into a constant by the ExpressionExecutor (i.e.
130//! scalar but not aggregate/window/parameter)
131class FoldableConstantMatcher : public ExpressionMatcher {
132public:
133 FoldableConstantMatcher() : ExpressionMatcher(ExpressionClass::INVALID) {
134 }
135
136 bool Match(Expression &expr, vector<reference<Expression>> &bindings) override;
137};
138
139} // namespace duckdb
140