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
8using namespace duckdb;
9using namespace std;
10
11Binder::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
25BoundStatement 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
61unique_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
78BoundStatement 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
91unique_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}
103unique_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
124unique_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
147void 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
157unique_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
168idx_t Binder::GenerateTableIndex() {
169 if (parent) {
170 return parent->GenerateTableIndex();
171 }
172 return bound_tables++;
173}
174
175void Binder::PushExpressionBinder(ExpressionBinder *binder) {
176 GetActiveBinders().push_back(binder);
177}
178
179void Binder::PopExpressionBinder() {
180 assert(HasActiveBinder());
181 GetActiveBinders().pop_back();
182}
183
184void Binder::SetActiveBinder(ExpressionBinder *binder) {
185 assert(HasActiveBinder());
186 GetActiveBinders().back() = binder;
187}
188
189ExpressionBinder *Binder::GetActiveBinder() {
190 return GetActiveBinders().back();
191}
192
193bool Binder::HasActiveBinder() {
194 return GetActiveBinders().size() > 0;
195}
196
197vector<ExpressionBinder *> &Binder::GetActiveBinders() {
198 if (parent) {
199 return parent->GetActiveBinders();
200 }
201 return active_binders;
202}
203
204void Binder::MoveCorrelatedExpressions(Binder &other) {
205 MergeCorrelatedColumns(other.correlated_columns);
206 other.correlated_columns.clear();
207}
208
209void Binder::MergeCorrelatedColumns(vector<CorrelatedColumnInfo> &other) {
210 for (idx_t i = 0; i < other.size(); i++) {
211 AddCorrelatedColumn(other[i]);
212 }
213}
214
215void 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