1 | #include "duckdb/execution/expression_executor.hpp" |
2 | |
3 | #include "duckdb/common/vector_operations/vector_operations.hpp" |
4 | |
5 | using namespace duckdb; |
6 | using namespace std; |
7 | |
8 | ExpressionExecutor::ExpressionExecutor() { |
9 | } |
10 | |
11 | ExpressionExecutor::ExpressionExecutor(Expression *expression) { |
12 | assert(expression); |
13 | AddExpression(*expression); |
14 | } |
15 | |
16 | ExpressionExecutor::ExpressionExecutor(Expression &expression) { |
17 | AddExpression(expression); |
18 | } |
19 | |
20 | ExpressionExecutor::ExpressionExecutor(vector<unique_ptr<Expression>> &exprs) { |
21 | assert(exprs.size() > 0); |
22 | for (auto &expr : exprs) { |
23 | AddExpression(*expr); |
24 | } |
25 | } |
26 | |
27 | void ExpressionExecutor::AddExpression(Expression &expr) { |
28 | expressions.push_back(&expr); |
29 | auto state = make_unique<ExpressionExecutorState>(); |
30 | Initialize(expr, *state); |
31 | states.push_back(move(state)); |
32 | } |
33 | |
34 | void ExpressionExecutor::Initialize(Expression &expression, ExpressionExecutorState &state) { |
35 | state.root_state = InitializeState(expression, state); |
36 | state.executor = this; |
37 | } |
38 | |
39 | void ExpressionExecutor::Execute(DataChunk *input, DataChunk &result) { |
40 | SetChunk(input); |
41 | |
42 | assert(expressions.size() == result.column_count()); |
43 | assert(expressions.size() > 0); |
44 | result.Reset(); |
45 | for (idx_t i = 0; i < expressions.size(); i++) { |
46 | ExecuteExpression(i, result.data[i]); |
47 | } |
48 | result.SetCardinality(input ? input->size() : 1); |
49 | result.Verify(); |
50 | } |
51 | |
52 | void ExpressionExecutor::ExecuteExpression(DataChunk &input, Vector &result) { |
53 | SetChunk(&input); |
54 | ExecuteExpression(result); |
55 | } |
56 | |
57 | idx_t ExpressionExecutor::SelectExpression(DataChunk &input, SelectionVector &sel) { |
58 | assert(expressions.size() == 1); |
59 | SetChunk(&input); |
60 | return Select(*expressions[0], states[0]->root_state.get(), nullptr, input.size(), &sel, nullptr); |
61 | } |
62 | |
63 | void ExpressionExecutor::ExecuteExpression(Vector &result) { |
64 | assert(expressions.size() == 1); |
65 | ExecuteExpression(0, result); |
66 | } |
67 | |
68 | void ExpressionExecutor::ExecuteExpression(idx_t expr_idx, Vector &result) { |
69 | assert(expr_idx < expressions.size()); |
70 | assert(result.type == expressions[expr_idx]->return_type); |
71 | Execute(*expressions[expr_idx], states[expr_idx]->root_state.get(), nullptr, chunk ? chunk->size() : 1, result); |
72 | } |
73 | |
74 | Value ExpressionExecutor::EvaluateScalar(Expression &expr) { |
75 | assert(expr.IsFoldable()); |
76 | // use an ExpressionExecutor to execute the expression |
77 | ExpressionExecutor executor(expr); |
78 | |
79 | Vector result(expr.return_type); |
80 | executor.ExecuteExpression(result); |
81 | |
82 | assert(result.vector_type == VectorType::CONSTANT_VECTOR); |
83 | return result.GetValue(0); |
84 | } |
85 | |
86 | void ExpressionExecutor::Verify(Expression &expr, Vector &vector, idx_t count) { |
87 | assert(expr.return_type == vector.type); |
88 | vector.Verify(count); |
89 | } |
90 | |
91 | unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(Expression &expr, ExpressionExecutorState &state) { |
92 | switch (expr.expression_class) { |
93 | case ExpressionClass::BOUND_REF: |
94 | return InitializeState((BoundReferenceExpression &)expr, state); |
95 | case ExpressionClass::BOUND_BETWEEN: |
96 | return InitializeState((BoundBetweenExpression &)expr, state); |
97 | case ExpressionClass::BOUND_CASE: |
98 | return InitializeState((BoundCaseExpression &)expr, state); |
99 | case ExpressionClass::BOUND_CAST: |
100 | return InitializeState((BoundCastExpression &)expr, state); |
101 | case ExpressionClass::BOUND_COMPARISON: |
102 | return InitializeState((BoundComparisonExpression &)expr, state); |
103 | case ExpressionClass::BOUND_CONJUNCTION: |
104 | return InitializeState((BoundConjunctionExpression &)expr, state); |
105 | case ExpressionClass::BOUND_CONSTANT: |
106 | return InitializeState((BoundConstantExpression &)expr, state); |
107 | case ExpressionClass::BOUND_FUNCTION: |
108 | return InitializeState((BoundFunctionExpression &)expr, state); |
109 | case ExpressionClass::BOUND_OPERATOR: |
110 | return InitializeState((BoundOperatorExpression &)expr, state); |
111 | case ExpressionClass::BOUND_PARAMETER: |
112 | return InitializeState((BoundParameterExpression &)expr, state); |
113 | default: |
114 | throw NotImplementedException("Attempting to initialize state of expression of unknown type!" ); |
115 | } |
116 | } |
117 | |
118 | void ExpressionExecutor::Execute(Expression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count, |
119 | Vector &result) { |
120 | if (count == 0) { |
121 | return; |
122 | } |
123 | switch (expr.expression_class) { |
124 | case ExpressionClass::BOUND_BETWEEN: |
125 | Execute((BoundBetweenExpression &)expr, state, sel, count, result); |
126 | break; |
127 | case ExpressionClass::BOUND_REF: |
128 | Execute((BoundReferenceExpression &)expr, state, sel, count, result); |
129 | break; |
130 | case ExpressionClass::BOUND_CASE: |
131 | Execute((BoundCaseExpression &)expr, state, sel, count, result); |
132 | break; |
133 | case ExpressionClass::BOUND_CAST: |
134 | Execute((BoundCastExpression &)expr, state, sel, count, result); |
135 | break; |
136 | case ExpressionClass::BOUND_COMPARISON: |
137 | Execute((BoundComparisonExpression &)expr, state, sel, count, result); |
138 | break; |
139 | case ExpressionClass::BOUND_CONJUNCTION: |
140 | Execute((BoundConjunctionExpression &)expr, state, sel, count, result); |
141 | break; |
142 | case ExpressionClass::BOUND_CONSTANT: |
143 | Execute((BoundConstantExpression &)expr, state, sel, count, result); |
144 | break; |
145 | case ExpressionClass::BOUND_FUNCTION: |
146 | Execute((BoundFunctionExpression &)expr, state, sel, count, result); |
147 | break; |
148 | case ExpressionClass::BOUND_OPERATOR: |
149 | Execute((BoundOperatorExpression &)expr, state, sel, count, result); |
150 | break; |
151 | case ExpressionClass::BOUND_PARAMETER: |
152 | Execute((BoundParameterExpression &)expr, state, sel, count, result); |
153 | break; |
154 | default: |
155 | throw NotImplementedException("Attempting to execute expression of unknown type!" ); |
156 | } |
157 | Verify(expr, result, count); |
158 | } |
159 | |
160 | idx_t ExpressionExecutor::Select(Expression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count, |
161 | SelectionVector *true_sel, SelectionVector *false_sel) { |
162 | if (count == 0) { |
163 | return 0; |
164 | } |
165 | assert(true_sel || false_sel); |
166 | assert(expr.return_type == TypeId::BOOL); |
167 | switch (expr.expression_class) { |
168 | case ExpressionClass::BOUND_BETWEEN: |
169 | return Select((BoundBetweenExpression &)expr, state, sel, count, true_sel, false_sel); |
170 | case ExpressionClass::BOUND_COMPARISON: |
171 | return Select((BoundComparisonExpression &)expr, state, sel, count, true_sel, false_sel); |
172 | case ExpressionClass::BOUND_CONJUNCTION: |
173 | return Select((BoundConjunctionExpression &)expr, state, sel, count, true_sel, false_sel); |
174 | default: |
175 | return DefaultSelect(expr, state, sel, count, true_sel, false_sel); |
176 | } |
177 | } |
178 | |
179 | template <bool NO_NULL, bool HAS_TRUE_SEL, bool HAS_FALSE_SEL> |
180 | static inline idx_t DefaultSelectLoop(const SelectionVector *bsel, bool *__restrict bdata, nullmask_t &nullmask, |
181 | const SelectionVector *sel, idx_t count, SelectionVector *true_sel, |
182 | SelectionVector *false_sel) { |
183 | idx_t true_count = 0, false_count = 0; |
184 | for (idx_t i = 0; i < count; i++) { |
185 | auto bidx = bsel->get_index(i); |
186 | auto result_idx = sel->get_index(i); |
187 | if (bdata[bidx] && (NO_NULL || !nullmask[bidx])) { |
188 | if (HAS_TRUE_SEL) { |
189 | true_sel->set_index(true_count++, result_idx); |
190 | } |
191 | } else { |
192 | if (HAS_FALSE_SEL) { |
193 | false_sel->set_index(false_count++, result_idx); |
194 | } |
195 | } |
196 | } |
197 | if (HAS_TRUE_SEL) { |
198 | return true_count; |
199 | } else { |
200 | return count - false_count; |
201 | } |
202 | } |
203 | |
204 | template <bool NO_NULL> |
205 | static inline idx_t DefaultSelectSwitch(VectorData &idata, const SelectionVector *sel, idx_t count, |
206 | SelectionVector *true_sel, SelectionVector *false_sel) { |
207 | if (true_sel && false_sel) { |
208 | return DefaultSelectLoop<NO_NULL, true, true>(idata.sel, (bool *)idata.data, *idata.nullmask, sel, count, |
209 | true_sel, false_sel); |
210 | } else if (true_sel) { |
211 | return DefaultSelectLoop<NO_NULL, true, false>(idata.sel, (bool *)idata.data, *idata.nullmask, sel, count, |
212 | true_sel, false_sel); |
213 | } else { |
214 | assert(false_sel); |
215 | return DefaultSelectLoop<NO_NULL, false, true>(idata.sel, (bool *)idata.data, *idata.nullmask, sel, count, |
216 | true_sel, false_sel); |
217 | } |
218 | } |
219 | |
220 | idx_t ExpressionExecutor::DefaultSelect(Expression &expr, ExpressionState *state, const SelectionVector *sel, |
221 | idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) { |
222 | // generic selection of boolean expression: |
223 | // resolve the true/false expression first |
224 | // then use that to generate the selection vector |
225 | bool intermediate_bools[STANDARD_VECTOR_SIZE]; |
226 | Vector intermediate(TypeId::BOOL, (data_ptr_t)intermediate_bools); |
227 | Execute(expr, state, sel, count, intermediate); |
228 | |
229 | VectorData idata; |
230 | intermediate.Orrify(count, idata); |
231 | if (!sel) { |
232 | sel = &FlatVector::IncrementalSelectionVector; |
233 | } |
234 | if (idata.nullmask->any()) { |
235 | return DefaultSelectSwitch<false>(idata, sel, count, true_sel, false_sel); |
236 | } else { |
237 | return DefaultSelectSwitch<true>(idata, sel, count, true_sel, false_sel); |
238 | } |
239 | } |
240 | |