1#include "duckdb/common/vector_operations/vector_operations.hpp"
2#include "duckdb/execution/expression_executor.hpp"
3#include "duckdb/planner/expression/bound_comparison_expression.hpp"
4#include "duckdb/common/operator/comparison_operators.hpp"
5#include "duckdb/common/vector_operations/binary_executor.hpp"
6
7using namespace duckdb;
8using namespace std;
9
10unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundComparisonExpression &expr,
11 ExpressionExecutorState &root) {
12 auto result = make_unique<ExpressionState>(expr, root);
13 result->AddChild(expr.left.get());
14 result->AddChild(expr.right.get());
15 return result;
16}
17
18void ExpressionExecutor::Execute(BoundComparisonExpression &expr, ExpressionState *state, const SelectionVector *sel,
19 idx_t count, Vector &result) {
20 // resolve the children
21 Vector left(expr.left->return_type), right(expr.right->return_type);
22 Execute(*expr.left, state->child_states[0].get(), sel, count, left);
23 Execute(*expr.right, state->child_states[1].get(), sel, count, right);
24
25 switch (expr.type) {
26 case ExpressionType::COMPARE_EQUAL:
27 VectorOperations::Equals(left, right, result, count);
28 break;
29 case ExpressionType::COMPARE_NOTEQUAL:
30 VectorOperations::NotEquals(left, right, result, count);
31 break;
32 case ExpressionType::COMPARE_LESSTHAN:
33 VectorOperations::LessThan(left, right, result, count);
34 break;
35 case ExpressionType::COMPARE_GREATERTHAN:
36 VectorOperations::GreaterThan(left, right, result, count);
37 break;
38 case ExpressionType::COMPARE_LESSTHANOREQUALTO:
39 VectorOperations::LessThanEquals(left, right, result, count);
40 break;
41 case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
42 VectorOperations::GreaterThanEquals(left, right, result, count);
43 break;
44 case ExpressionType::COMPARE_DISTINCT_FROM:
45 throw NotImplementedException("Unimplemented compare: COMPARE_DISTINCT_FROM");
46 default:
47 throw NotImplementedException("Unknown comparison type!");
48 }
49}
50
51template <class OP>
52static idx_t templated_select_operation(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
53 SelectionVector *true_sel, SelectionVector *false_sel) {
54 // the inplace loops take the result as the last parameter
55 switch (left.type) {
56 case TypeId::BOOL:
57 case TypeId::INT8:
58 return BinaryExecutor::Select<int8_t, int8_t, OP>(left, right, sel, count, true_sel, false_sel);
59 case TypeId::INT16:
60 return BinaryExecutor::Select<int16_t, int16_t, OP>(left, right, sel, count, true_sel, false_sel);
61 case TypeId::INT32:
62 return BinaryExecutor::Select<int32_t, int32_t, OP>(left, right, sel, count, true_sel, false_sel);
63 case TypeId::INT64:
64 return BinaryExecutor::Select<int64_t, int64_t, OP>(left, right, sel, count, true_sel, false_sel);
65 case TypeId::POINTER:
66 return BinaryExecutor::Select<uintptr_t, uintptr_t, OP>(left, right, sel, count, true_sel, false_sel);
67 case TypeId::FLOAT:
68 return BinaryExecutor::Select<float, float, OP>(left, right, sel, count, true_sel, false_sel);
69 case TypeId::DOUBLE:
70 return BinaryExecutor::Select<double, double, OP>(left, right, sel, count, true_sel, false_sel);
71 case TypeId::VARCHAR:
72 return BinaryExecutor::Select<string_t, string_t, OP>(left, right, sel, count, true_sel, false_sel);
73 default:
74 throw InvalidTypeException(left.type, "Invalid type for comparison");
75 }
76}
77
78idx_t ExpressionExecutor::Select(BoundComparisonExpression &expr, ExpressionState *state, const SelectionVector *sel,
79 idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
80 // resolve the children
81 Vector left(expr.left->return_type), right(expr.right->return_type);
82 Execute(*expr.left, state->child_states[0].get(), sel, count, left);
83 Execute(*expr.right, state->child_states[1].get(), sel, count, right);
84
85 switch (expr.type) {
86 case ExpressionType::COMPARE_EQUAL:
87 return templated_select_operation<duckdb::Equals>(left, right, sel, count, true_sel, false_sel);
88 case ExpressionType::COMPARE_NOTEQUAL:
89 return templated_select_operation<duckdb::NotEquals>(left, right, sel, count, true_sel, false_sel);
90 case ExpressionType::COMPARE_LESSTHAN:
91 return templated_select_operation<duckdb::LessThan>(left, right, sel, count, true_sel, false_sel);
92 case ExpressionType::COMPARE_GREATERTHAN:
93 return templated_select_operation<duckdb::GreaterThan>(left, right, sel, count, true_sel, false_sel);
94 case ExpressionType::COMPARE_LESSTHANOREQUALTO:
95 return templated_select_operation<duckdb::LessThanEquals>(left, right, sel, count, true_sel, false_sel);
96 case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
97 return templated_select_operation<duckdb::GreaterThanEquals>(left, right, sel, count, true_sel, false_sel);
98 case ExpressionType::COMPARE_DISTINCT_FROM:
99 throw NotImplementedException("Unimplemented compare: COMPARE_DISTINCT_FROM");
100 default:
101 throw NotImplementedException("Unknown comparison type!");
102 }
103}
104