| 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 | |