1 | #include "duckdb/common/vector_operations/vector_operations.hpp" |
2 | #include "duckdb/execution/expression_executor.hpp" |
3 | #include "duckdb/planner/expression/bound_between_expression.hpp" |
4 | #include "duckdb/common/operator/comparison_operators.hpp" |
5 | #include "duckdb/common/vector_operations/ternary_executor.hpp" |
6 | |
7 | using namespace duckdb; |
8 | using namespace std; |
9 | |
10 | struct BothInclusiveBetweenOperator { |
11 | template <class T> static inline bool Operation(T input, T lower, T upper) { |
12 | return GreaterThanEquals::Operation<T>(input, lower) && LessThanEquals::Operation<T>(input, upper); |
13 | } |
14 | }; |
15 | |
16 | struct LowerInclusiveBetweenOperator { |
17 | template <class T> static inline bool Operation(T input, T lower, T upper) { |
18 | return GreaterThanEquals::Operation<T>(input, lower) && LessThan::Operation<T>(input, upper); |
19 | } |
20 | }; |
21 | |
22 | struct UpperInclusiveBetweenOperator { |
23 | template <class T> static inline bool Operation(T input, T lower, T upper) { |
24 | return GreaterThan::Operation<T>(input, lower) && LessThanEquals::Operation<T>(input, upper); |
25 | } |
26 | }; |
27 | |
28 | struct ExclusiveBetweenOperator { |
29 | template <class T> static inline bool Operation(T input, T lower, T upper) { |
30 | return GreaterThan::Operation<T>(input, lower) && LessThan::Operation<T>(input, upper); |
31 | } |
32 | }; |
33 | |
34 | template <class OP> |
35 | static idx_t between_loop_type_switch(Vector &input, Vector &lower, Vector &upper, const SelectionVector *sel, |
36 | idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) { |
37 | switch (input.type) { |
38 | case TypeId::BOOL: |
39 | case TypeId::INT8: |
40 | return TernaryExecutor::Select<int8_t, int8_t, int8_t, OP>(input, lower, upper, sel, count, true_sel, |
41 | false_sel); |
42 | case TypeId::INT16: |
43 | return TernaryExecutor::Select<int16_t, int16_t, int16_t, OP>(input, lower, upper, sel, count, true_sel, |
44 | false_sel); |
45 | case TypeId::INT32: |
46 | return TernaryExecutor::Select<int32_t, int32_t, int32_t, OP>(input, lower, upper, sel, count, true_sel, |
47 | false_sel); |
48 | case TypeId::INT64: |
49 | return TernaryExecutor::Select<int64_t, int64_t, int64_t, OP>(input, lower, upper, sel, count, true_sel, |
50 | false_sel); |
51 | case TypeId::FLOAT: |
52 | return TernaryExecutor::Select<float, float, float, OP>(input, lower, upper, sel, count, true_sel, false_sel); |
53 | case TypeId::DOUBLE: |
54 | return TernaryExecutor::Select<double, double, double, OP>(input, lower, upper, sel, count, true_sel, |
55 | false_sel); |
56 | case TypeId::VARCHAR: |
57 | return TernaryExecutor::Select<string_t, string_t, string_t, OP>(input, lower, upper, sel, count, true_sel, |
58 | false_sel); |
59 | default: |
60 | throw InvalidTypeException(input.type, "Invalid type for BETWEEN" ); |
61 | } |
62 | } |
63 | |
64 | unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundBetweenExpression &expr, |
65 | ExpressionExecutorState &root) { |
66 | auto result = make_unique<ExpressionState>(expr, root); |
67 | result->AddChild(expr.input.get()); |
68 | result->AddChild(expr.lower.get()); |
69 | result->AddChild(expr.upper.get()); |
70 | return result; |
71 | } |
72 | |
73 | void ExpressionExecutor::Execute(BoundBetweenExpression &expr, ExpressionState *state, const SelectionVector *sel, |
74 | idx_t count, Vector &result) { |
75 | // resolve the children |
76 | Vector input(expr.input->return_type), lower(expr.lower->return_type), upper(expr.upper->return_type); |
77 | Execute(*expr.input, state->child_states[0].get(), sel, count, input); |
78 | Execute(*expr.lower, state->child_states[1].get(), sel, count, lower); |
79 | Execute(*expr.upper, state->child_states[2].get(), sel, count, upper); |
80 | |
81 | Vector intermediate1(TypeId::BOOL); |
82 | Vector intermediate2(TypeId::BOOL); |
83 | |
84 | if (expr.upper_inclusive && expr.lower_inclusive) { |
85 | VectorOperations::GreaterThanEquals(input, lower, intermediate1, count); |
86 | VectorOperations::LessThanEquals(input, upper, intermediate2, count); |
87 | } else if (expr.lower_inclusive) { |
88 | VectorOperations::GreaterThanEquals(input, lower, intermediate1, count); |
89 | VectorOperations::LessThan(input, upper, intermediate2, count); |
90 | } else if (expr.upper_inclusive) { |
91 | VectorOperations::GreaterThan(input, lower, intermediate1, count); |
92 | VectorOperations::LessThanEquals(input, upper, intermediate2, count); |
93 | } else { |
94 | VectorOperations::GreaterThan(input, lower, intermediate1, count); |
95 | VectorOperations::LessThan(input, upper, intermediate2, count); |
96 | } |
97 | VectorOperations::And(intermediate1, intermediate2, result, count); |
98 | } |
99 | |
100 | idx_t ExpressionExecutor::Select(BoundBetweenExpression &expr, ExpressionState *state, const SelectionVector *sel, |
101 | idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) { |
102 | // resolve the children |
103 | Vector input(expr.input->return_type), lower(expr.lower->return_type), upper(expr.upper->return_type); |
104 | Execute(*expr.input, state->child_states[0].get(), sel, count, input); |
105 | Execute(*expr.lower, state->child_states[1].get(), sel, count, lower); |
106 | Execute(*expr.upper, state->child_states[2].get(), sel, count, upper); |
107 | |
108 | if (expr.upper_inclusive && expr.lower_inclusive) { |
109 | return between_loop_type_switch<BothInclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel, |
110 | false_sel); |
111 | } else if (expr.lower_inclusive) { |
112 | return between_loop_type_switch<LowerInclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel, |
113 | false_sel); |
114 | } else if (expr.upper_inclusive) { |
115 | return between_loop_type_switch<UpperInclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel, |
116 | false_sel); |
117 | } else { |
118 | return between_loop_type_switch<ExclusiveBetweenOperator>(input, lower, upper, sel, count, true_sel, false_sel); |
119 | } |
120 | } |
121 | |