1#include "duckdb/execution/expression_executor.hpp"
2
3#include "duckdb/common/vector_operations/vector_operations.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8ExpressionExecutor::ExpressionExecutor() {
9}
10
11ExpressionExecutor::ExpressionExecutor(Expression *expression) {
12 assert(expression);
13 AddExpression(*expression);
14}
15
16ExpressionExecutor::ExpressionExecutor(Expression &expression) {
17 AddExpression(expression);
18}
19
20ExpressionExecutor::ExpressionExecutor(vector<unique_ptr<Expression>> &exprs) {
21 assert(exprs.size() > 0);
22 for (auto &expr : exprs) {
23 AddExpression(*expr);
24 }
25}
26
27void 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
34void ExpressionExecutor::Initialize(Expression &expression, ExpressionExecutorState &state) {
35 state.root_state = InitializeState(expression, state);
36 state.executor = this;
37}
38
39void 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
52void ExpressionExecutor::ExecuteExpression(DataChunk &input, Vector &result) {
53 SetChunk(&input);
54 ExecuteExpression(result);
55}
56
57idx_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
63void ExpressionExecutor::ExecuteExpression(Vector &result) {
64 assert(expressions.size() == 1);
65 ExecuteExpression(0, result);
66}
67
68void 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
74Value 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
86void ExpressionExecutor::Verify(Expression &expr, Vector &vector, idx_t count) {
87 assert(expr.return_type == vector.type);
88 vector.Verify(count);
89}
90
91unique_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
118void 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
160idx_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
179template <bool NO_NULL, bool HAS_TRUE_SEL, bool HAS_FALSE_SEL>
180static 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
204template <bool NO_NULL>
205static 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
220idx_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