1 | #include "duckdb/planner/planner.hpp" |
2 | |
3 | #include "duckdb/common/serializer.hpp" |
4 | #include "duckdb/main/client_context.hpp" |
5 | #include "duckdb/main/database.hpp" |
6 | #include "duckdb/parser/statement/pragma_statement.hpp" |
7 | #include "duckdb/parser/statement/prepare_statement.hpp" |
8 | #include "duckdb/planner/binder.hpp" |
9 | #include "duckdb/planner/expression/bound_parameter_expression.hpp" |
10 | #include "duckdb/planner/operator/logical_prepare.hpp" |
11 | #include "duckdb/planner/query_node/bound_select_node.hpp" |
12 | #include "duckdb/planner/query_node/bound_set_operation_node.hpp" |
13 | #include "duckdb/planner/pragma_handler.hpp" |
14 | #include "duckdb/parser/parsed_data/drop_info.hpp" |
15 | |
16 | using namespace duckdb; |
17 | using namespace std; |
18 | |
19 | Planner::Planner(ClientContext &context) : binder(context), context(context) { |
20 | } |
21 | |
22 | void Planner::CreatePlan(SQLStatement &statement) { |
23 | vector<BoundParameterExpression *> bound_parameters; |
24 | |
25 | // first bind the tables and columns to the catalog |
26 | context.profiler.StartPhase("binder" ); |
27 | binder.parameters = &bound_parameters; |
28 | auto bound_statement = binder.Bind(statement); |
29 | context.profiler.EndPhase(); |
30 | |
31 | // VerifyQuery(*bound_statement); |
32 | |
33 | this->read_only = binder.read_only; |
34 | this->requires_valid_transaction = binder.requires_valid_transaction; |
35 | this->names = bound_statement.names; |
36 | this->sql_types = bound_statement.types; |
37 | this->plan = move(bound_statement.plan); |
38 | |
39 | // now create a logical query plan from the query |
40 | // context.profiler.StartPhase("logical_planner"); |
41 | // LogicalPlanGenerator logical_planner(binder, context); |
42 | // this->plan = logical_planner.CreatePlan(*bound_statement); |
43 | // context.profiler.EndPhase(); |
44 | |
45 | // set up a map of parameter number -> value entries |
46 | for (auto &expr : bound_parameters) { |
47 | // check if the type of the parameter could be resolved |
48 | if (expr->return_type == TypeId::INVALID) { |
49 | throw BinderException("Could not determine type of parameters: try adding explicit type casts" ); |
50 | } |
51 | auto value = make_unique<Value>(expr->return_type); |
52 | expr->value = value.get(); |
53 | // check if the parameter number has been used before |
54 | if (value_map.find(expr->parameter_nr) != value_map.end()) { |
55 | throw BinderException("Duplicate parameter index. Use $1, $2 etc. to differentiate." ); |
56 | } |
57 | PreparedValueEntry entry; |
58 | entry.value = move(value); |
59 | entry.target_type = expr->sql_type; |
60 | value_map[expr->parameter_nr] = move(entry); |
61 | } |
62 | } |
63 | |
64 | void Planner::CreatePlan(unique_ptr<SQLStatement> statement) { |
65 | assert(statement); |
66 | switch (statement->type) { |
67 | case StatementType::SELECT_STATEMENT: |
68 | case StatementType::INSERT_STATEMENT: |
69 | case StatementType::COPY_STATEMENT: |
70 | case StatementType::DELETE_STATEMENT: |
71 | case StatementType::UPDATE_STATEMENT: |
72 | case StatementType::CREATE_STATEMENT: |
73 | case StatementType::EXECUTE_STATEMENT: |
74 | case StatementType::DROP_STATEMENT: |
75 | case StatementType::ALTER_STATEMENT: |
76 | case StatementType::TRANSACTION_STATEMENT: |
77 | case StatementType::EXPLAIN_STATEMENT: |
78 | case StatementType::VACUUM_STATEMENT: |
79 | case StatementType::RELATION_STATEMENT: |
80 | CreatePlan(*statement); |
81 | break; |
82 | case StatementType::PRAGMA_STATEMENT: { |
83 | auto &stmt = *reinterpret_cast<PragmaStatement *>(statement.get()); |
84 | PragmaHandler handler(context); |
85 | // some pragma statements have a "replacement" SQL statement that will be executed instead |
86 | // use the PragmaHandler to get the (potential) replacement SQL statement |
87 | auto new_stmt = handler.HandlePragma(*stmt.info); |
88 | if (new_stmt) { |
89 | CreatePlan(move(new_stmt)); |
90 | } else { |
91 | CreatePlan(stmt); |
92 | } |
93 | break; |
94 | } |
95 | case StatementType::PREPARE_STATEMENT: { |
96 | auto &stmt = *reinterpret_cast<PrepareStatement *>(statement.get()); |
97 | auto statement_type = stmt.statement->type; |
98 | // create a plan of the underlying statement |
99 | CreatePlan(move(stmt.statement)); |
100 | // now create the logical prepare |
101 | auto prepared_data = make_unique<PreparedStatementData>(statement_type); |
102 | prepared_data->names = names; |
103 | prepared_data->sql_types = sql_types; |
104 | prepared_data->value_map = move(value_map); |
105 | prepared_data->read_only = this->read_only; |
106 | prepared_data->requires_valid_transaction = this->requires_valid_transaction; |
107 | |
108 | this->read_only = true; |
109 | this->requires_valid_transaction = false; |
110 | |
111 | auto prepare = make_unique<LogicalPrepare>(stmt.name, move(prepared_data), move(plan)); |
112 | names = {"Success" }; |
113 | sql_types = {SQLType(SQLTypeId::BOOLEAN)}; |
114 | plan = move(prepare); |
115 | break; |
116 | } |
117 | default: |
118 | throw NotImplementedException("Cannot plan statement of type %s!" , |
119 | StatementTypeToString(statement->type).c_str()); |
120 | } |
121 | } |
122 | |
123 | // void Planner::VerifyQuery(BoundSQLStatement &statement) { |
124 | // if (!context.query_verification_enabled) { |
125 | // return; |
126 | // } |
127 | // if (statement.type != StatementType::SELECT_STATEMENT) { |
128 | // return; |
129 | // } |
130 | // auto &select = (BoundSelectStatement &)statement; |
131 | // VerifyNode(*select.node); |
132 | // } |
133 | |
134 | // void Planner::VerifyNode(BoundQueryNode &node) { |
135 | // if (node.type == QueryNodeType::SELECT_NODE) { |
136 | // auto &select_node = (BoundSelectNode &)node; |
137 | // vector<unique_ptr<Expression>> copies; |
138 | // for (auto &expr : select_node.select_list) { |
139 | // VerifyExpression(*expr, copies); |
140 | // } |
141 | // if (select_node.where_clause) { |
142 | // VerifyExpression(*select_node.where_clause, copies); |
143 | // } |
144 | // for (auto &expr : select_node.groups) { |
145 | // VerifyExpression(*expr, copies); |
146 | // } |
147 | // if (select_node.having) { |
148 | // VerifyExpression(*select_node.having, copies); |
149 | // } |
150 | // for (auto &aggr : select_node.aggregates) { |
151 | // VerifyExpression(*aggr, copies); |
152 | // } |
153 | // for (auto &window : select_node.windows) { |
154 | // VerifyExpression(*window, copies); |
155 | // } |
156 | |
157 | // // double loop to verify that (in)equality of hashes |
158 | // for (idx_t i = 0; i < copies.size(); i++) { |
159 | // auto outer_hash = copies[i]->Hash(); |
160 | // for (idx_t j = 0; j < copies.size(); j++) { |
161 | // auto inner_hash = copies[j]->Hash(); |
162 | // if (outer_hash != inner_hash) { |
163 | // // if hashes are not equivalent the expressions should not be equivalent |
164 | // assert(!Expression::Equals(copies[i].get(), copies[j].get())); |
165 | // } |
166 | // } |
167 | // } |
168 | // } else { |
169 | // assert(node.type == QueryNodeType::SET_OPERATION_NODE); |
170 | // auto &setop_node = (BoundSetOperationNode &)node; |
171 | // VerifyNode(*setop_node.left); |
172 | // VerifyNode(*setop_node.right); |
173 | // } |
174 | // } |
175 | |
176 | // void Planner::VerifyExpression(Expression &expr, vector<unique_ptr<Expression>> &copies) { |
177 | // if (expr.HasSubquery()) { |
178 | // // can't copy subqueries |
179 | // return; |
180 | // } |
181 | // // verify that the copy of expressions works |
182 | // auto copy = expr.Copy(); |
183 | // // copy should have identical hash and identical equality function |
184 | // assert(copy->Hash() == expr.Hash()); |
185 | // assert(Expression::Equals(copy.get(), &expr)); |
186 | // copies.push_back(move(copy)); |
187 | // } |
188 | |