1#include "duckdb/common/vector_operations/vector_operations.hpp"
2#include "duckdb/execution/expression_executor.hpp"
3#include "duckdb/planner/expression/bound_operator_expression.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundOperatorExpression &expr,
9 ExpressionExecutorState &root) {
10 auto result = make_unique<ExpressionState>(expr, root);
11 for (auto &child : expr.children) {
12 result->AddChild(child.get());
13 }
14 return result;
15}
16
17void ExpressionExecutor::Execute(BoundOperatorExpression &expr, ExpressionState *state, const SelectionVector *sel,
18 idx_t count, Vector &result) {
19 // special handling for special snowflake 'IN'
20 // IN has n children
21 if (expr.type == ExpressionType::COMPARE_IN || expr.type == ExpressionType::COMPARE_NOT_IN) {
22 if (expr.children.size() < 2) {
23 throw Exception("IN needs at least two children");
24 }
25 Vector left(expr.children[0]->return_type);
26 // eval left side
27 Execute(*expr.children[0], state->child_states[0].get(), sel, count, left);
28
29 // init result to false
30 Vector intermediate(TypeId::BOOL);
31 Value false_val = Value::BOOLEAN(false);
32 intermediate.Reference(false_val);
33
34 // in rhs is a list of constants
35 // for every child, OR the result of the comparision with the left
36 // to get the overall result.
37 for (idx_t child = 1; child < expr.children.size(); child++) {
38 Vector vector_to_check(expr.children[child]->return_type);
39 Vector comp_res(TypeId::BOOL);
40
41 Execute(*expr.children[child], state->child_states[child].get(), sel, count, vector_to_check);
42 VectorOperations::Equals(left, vector_to_check, comp_res, count);
43
44 if (child == 1) {
45 // first child: move to result
46 intermediate.Reference(comp_res);
47 } else {
48 // otherwise OR together
49 Vector new_result(TypeId::BOOL, true, false);
50 VectorOperations::Or(intermediate, comp_res, new_result, count);
51 intermediate.Reference(new_result);
52 }
53 }
54 if (expr.type == ExpressionType::COMPARE_NOT_IN) {
55 // NOT IN: invert result
56 VectorOperations::Not(intermediate, result, count);
57 } else {
58 // directly use the result
59 result.Reference(intermediate);
60 }
61 } else if (expr.children.size() == 1) {
62 Vector child(expr.children[0]->return_type);
63 Execute(*expr.children[0], state->child_states[0].get(), sel, count, child);
64 switch (expr.type) {
65 case ExpressionType::OPERATOR_NOT: {
66 VectorOperations::Not(child, result, count);
67 break;
68 }
69 case ExpressionType::OPERATOR_IS_NULL: {
70 VectorOperations::IsNull(child, result, count);
71 break;
72 }
73 case ExpressionType::OPERATOR_IS_NOT_NULL: {
74 VectorOperations::IsNotNull(child, result, count);
75 break;
76 }
77 default:
78 throw NotImplementedException("Unsupported operator type with 1 child!");
79 }
80 } else {
81 throw NotImplementedException("operator");
82 }
83}
84