1 | #include "duckdb/planner/binder.hpp" |
2 | |
3 | #include "duckdb/parser/statement/list.hpp" |
4 | #include "duckdb/planner/bound_query_node.hpp" |
5 | #include "duckdb/planner/bound_tableref.hpp" |
6 | #include "duckdb/planner/expression.hpp" |
7 | |
8 | using namespace duckdb; |
9 | using namespace std; |
10 | |
11 | Binder::Binder(ClientContext &context, Binder *parent_) |
12 | : context(context), read_only(true), parent(!parent_ ? nullptr : (parent_->parent ? parent_->parent : parent_)), |
13 | bound_tables(0) { |
14 | if (parent_) { |
15 | // We have to inherit CTE bindings from the parent bind_context, if there is a parent. |
16 | bind_context.SetCTEBindings(parent_->bind_context.GetCTEBindings()); |
17 | bind_context.cte_references = parent_->bind_context.cte_references; |
18 | } |
19 | if (parent) { |
20 | parameters = parent->parameters; |
21 | CTE_bindings = parent->CTE_bindings; |
22 | } |
23 | } |
24 | |
25 | BoundStatement Binder::Bind(SQLStatement &statement) { |
26 | switch (statement.type) { |
27 | case StatementType::SELECT_STATEMENT: |
28 | return Bind((SelectStatement &)statement); |
29 | case StatementType::INSERT_STATEMENT: |
30 | return Bind((InsertStatement &)statement); |
31 | case StatementType::COPY_STATEMENT: |
32 | return Bind((CopyStatement &)statement); |
33 | case StatementType::DELETE_STATEMENT: |
34 | return Bind((DeleteStatement &)statement); |
35 | case StatementType::UPDATE_STATEMENT: |
36 | return Bind((UpdateStatement &)statement); |
37 | case StatementType::RELATION_STATEMENT: |
38 | return Bind((RelationStatement &)statement); |
39 | case StatementType::CREATE_STATEMENT: |
40 | return Bind((CreateStatement &)statement); |
41 | case StatementType::DROP_STATEMENT: |
42 | return Bind((DropStatement &)statement); |
43 | case StatementType::ALTER_STATEMENT: |
44 | return Bind((AlterTableStatement &)statement); |
45 | case StatementType::TRANSACTION_STATEMENT: |
46 | return Bind((TransactionStatement &)statement); |
47 | case StatementType::PRAGMA_STATEMENT: |
48 | return Bind((PragmaStatement &)statement); |
49 | case StatementType::EXECUTE_STATEMENT: |
50 | return Bind((ExecuteStatement &)statement); |
51 | case StatementType::EXPLAIN_STATEMENT: |
52 | return Bind((ExplainStatement &)statement); |
53 | case StatementType::VACUUM_STATEMENT: |
54 | return Bind((VacuumStatement &)statement); |
55 | default: |
56 | throw NotImplementedException("Unimplemented statement type \"%s\" for Bind" , |
57 | StatementTypeToString(statement.type).c_str()); |
58 | } |
59 | } |
60 | |
61 | unique_ptr<BoundQueryNode> Binder::BindNode(QueryNode &node) { |
62 | unique_ptr<BoundQueryNode> result; |
63 | switch (node.type) { |
64 | case QueryNodeType::SELECT_NODE: |
65 | result = BindNode((SelectNode &)node); |
66 | break; |
67 | case QueryNodeType::RECURSIVE_CTE_NODE: |
68 | result = BindNode((RecursiveCTENode &)node); |
69 | break; |
70 | default: |
71 | assert(node.type == QueryNodeType::SET_OPERATION_NODE); |
72 | result = BindNode((SetOperationNode &)node); |
73 | break; |
74 | } |
75 | return result; |
76 | } |
77 | |
78 | BoundStatement Binder::Bind(QueryNode &node) { |
79 | BoundStatement result; |
80 | // bind the node |
81 | auto bound_node = BindNode(node); |
82 | |
83 | result.names = bound_node->names; |
84 | result.types = bound_node->types; |
85 | |
86 | // and plan it |
87 | result.plan = CreatePlan(*bound_node); |
88 | return result; |
89 | } |
90 | |
91 | unique_ptr<LogicalOperator> Binder::CreatePlan(BoundQueryNode &node) { |
92 | switch (node.type) { |
93 | case QueryNodeType::SELECT_NODE: |
94 | return CreatePlan((BoundSelectNode &)node); |
95 | case QueryNodeType::SET_OPERATION_NODE: |
96 | return CreatePlan((BoundSetOperationNode &)node); |
97 | case QueryNodeType::RECURSIVE_CTE_NODE: |
98 | return CreatePlan((BoundRecursiveCTENode &)node); |
99 | default: |
100 | throw Exception("Unsupported bound query node type" ); |
101 | } |
102 | } |
103 | unique_ptr<BoundTableRef> Binder::Bind(TableRef &ref) { |
104 | switch (ref.type) { |
105 | case TableReferenceType::BASE_TABLE: |
106 | return Bind((BaseTableRef &)ref); |
107 | case TableReferenceType::CROSS_PRODUCT: |
108 | return Bind((CrossProductRef &)ref); |
109 | case TableReferenceType::JOIN: |
110 | return Bind((JoinRef &)ref); |
111 | case TableReferenceType::SUBQUERY: |
112 | return Bind((SubqueryRef &)ref); |
113 | case TableReferenceType::EMPTY: |
114 | return Bind((EmptyTableRef &)ref); |
115 | case TableReferenceType::TABLE_FUNCTION: |
116 | return Bind((TableFunctionRef &)ref); |
117 | case TableReferenceType::EXPRESSION_LIST: |
118 | return Bind((ExpressionListRef &)ref); |
119 | default: |
120 | throw Exception("Unknown table ref type" ); |
121 | } |
122 | } |
123 | |
124 | unique_ptr<LogicalOperator> Binder::CreatePlan(BoundTableRef &ref) { |
125 | switch (ref.type) { |
126 | case TableReferenceType::BASE_TABLE: |
127 | return CreatePlan((BoundBaseTableRef &)ref); |
128 | case TableReferenceType::SUBQUERY: |
129 | return CreatePlan((BoundSubqueryRef &)ref); |
130 | case TableReferenceType::JOIN: |
131 | return CreatePlan((BoundJoinRef &)ref); |
132 | case TableReferenceType::CROSS_PRODUCT: |
133 | return CreatePlan((BoundCrossProductRef &)ref); |
134 | case TableReferenceType::TABLE_FUNCTION: |
135 | return CreatePlan((BoundTableFunction &)ref); |
136 | case TableReferenceType::EMPTY: |
137 | return CreatePlan((BoundEmptyTableRef &)ref); |
138 | case TableReferenceType::EXPRESSION_LIST: |
139 | return CreatePlan((BoundExpressionListRef &)ref); |
140 | case TableReferenceType::CTE: |
141 | return CreatePlan((BoundCTERef &)ref); |
142 | default: |
143 | throw Exception("Unsupported bound table ref type type" ); |
144 | } |
145 | } |
146 | |
147 | void Binder::AddCTE(const string &name, QueryNode *cte) { |
148 | assert(cte); |
149 | assert(!name.empty()); |
150 | auto entry = CTE_bindings.find(name); |
151 | if (entry != CTE_bindings.end()) { |
152 | throw BinderException("Duplicate CTE \"%s\" in query!" , name.c_str()); |
153 | } |
154 | CTE_bindings[name] = cte; |
155 | } |
156 | |
157 | unique_ptr<QueryNode> Binder::FindCTE(const string &name) { |
158 | auto entry = CTE_bindings.find(name); |
159 | if (entry == CTE_bindings.end()) { |
160 | if (parent) { |
161 | return parent->FindCTE(name); |
162 | } |
163 | return nullptr; |
164 | } |
165 | return entry->second->Copy(); |
166 | } |
167 | |
168 | idx_t Binder::GenerateTableIndex() { |
169 | if (parent) { |
170 | return parent->GenerateTableIndex(); |
171 | } |
172 | return bound_tables++; |
173 | } |
174 | |
175 | void Binder::PushExpressionBinder(ExpressionBinder *binder) { |
176 | GetActiveBinders().push_back(binder); |
177 | } |
178 | |
179 | void Binder::PopExpressionBinder() { |
180 | assert(HasActiveBinder()); |
181 | GetActiveBinders().pop_back(); |
182 | } |
183 | |
184 | void Binder::SetActiveBinder(ExpressionBinder *binder) { |
185 | assert(HasActiveBinder()); |
186 | GetActiveBinders().back() = binder; |
187 | } |
188 | |
189 | ExpressionBinder *Binder::GetActiveBinder() { |
190 | return GetActiveBinders().back(); |
191 | } |
192 | |
193 | bool Binder::HasActiveBinder() { |
194 | return GetActiveBinders().size() > 0; |
195 | } |
196 | |
197 | vector<ExpressionBinder *> &Binder::GetActiveBinders() { |
198 | if (parent) { |
199 | return parent->GetActiveBinders(); |
200 | } |
201 | return active_binders; |
202 | } |
203 | |
204 | void Binder::MoveCorrelatedExpressions(Binder &other) { |
205 | MergeCorrelatedColumns(other.correlated_columns); |
206 | other.correlated_columns.clear(); |
207 | } |
208 | |
209 | void Binder::MergeCorrelatedColumns(vector<CorrelatedColumnInfo> &other) { |
210 | for (idx_t i = 0; i < other.size(); i++) { |
211 | AddCorrelatedColumn(other[i]); |
212 | } |
213 | } |
214 | |
215 | void Binder::AddCorrelatedColumn(CorrelatedColumnInfo info) { |
216 | // we only add correlated columns to the list if they are not already there |
217 | if (std::find(correlated_columns.begin(), correlated_columns.end(), info) == correlated_columns.end()) { |
218 | correlated_columns.push_back(info); |
219 | } |
220 | } |
221 | |