1 | #include "duckdb/parser/expression/operator_expression.hpp" |
2 | #include "duckdb/planner/expression/bound_cast_expression.hpp" |
3 | #include "duckdb/planner/expression/bound_operator_expression.hpp" |
4 | #include "duckdb/planner/expression_binder.hpp" |
5 | |
6 | using namespace duckdb; |
7 | using namespace std; |
8 | |
9 | static SQLType ResolveNotType(OperatorExpression &op, vector<BoundExpression *> &children) { |
10 | // NOT expression, cast child to BOOLEAN |
11 | assert(children.size() == 1); |
12 | children[0]->expr = |
13 | BoundCastExpression::AddCastToType(move(children[0]->expr), children[0]->sql_type, SQLType(SQLTypeId::BOOLEAN)); |
14 | return SQLType(SQLTypeId::BOOLEAN); |
15 | } |
16 | |
17 | static SQLType ResolveInType(OperatorExpression &op, vector<BoundExpression *> &children) { |
18 | // get the maximum type from the children |
19 | SQLType max_type = children[0]->sql_type; |
20 | for (idx_t i = 1; i < children.size(); i++) { |
21 | max_type = MaxSQLType(max_type, children[i]->sql_type); |
22 | } |
23 | // cast all children to the same type |
24 | for (idx_t i = 0; i < children.size(); i++) { |
25 | children[i]->expr = |
26 | BoundCastExpression::AddCastToType(move(children[i]->expr), children[i]->sql_type, max_type); |
27 | } |
28 | // (NOT) IN always returns a boolean |
29 | return SQLType(SQLTypeId::BOOLEAN); |
30 | } |
31 | |
32 | static SQLType ResolveOperatorType(OperatorExpression &op, vector<BoundExpression *> &children) { |
33 | switch (op.type) { |
34 | case ExpressionType::OPERATOR_IS_NULL: |
35 | case ExpressionType::OPERATOR_IS_NOT_NULL: |
36 | // IS (NOT) NULL always returns a boolean, and does not cast its children |
37 | return SQLType(SQLTypeId::BOOLEAN); |
38 | case ExpressionType::COMPARE_IN: |
39 | case ExpressionType::COMPARE_NOT_IN: |
40 | return ResolveInType(op, children); |
41 | default: |
42 | assert(op.type == ExpressionType::OPERATOR_NOT); |
43 | return ResolveNotType(op, children); |
44 | } |
45 | } |
46 | |
47 | BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) { |
48 | // bind the children of the operator expression |
49 | string error; |
50 | for (idx_t i = 0; i < op.children.size(); i++) { |
51 | BindChild(op.children[i], depth, error); |
52 | } |
53 | if (!error.empty()) { |
54 | return BindResult(error); |
55 | } |
56 | // all children bound successfully, extract them |
57 | vector<BoundExpression *> children; |
58 | for (idx_t i = 0; i < op.children.size(); i++) { |
59 | assert(op.children[i]->expression_class == ExpressionClass::BOUND_EXPRESSION); |
60 | children.push_back((BoundExpression *)op.children[i].get()); |
61 | } |
62 | // now resolve the types |
63 | SQLType result_type = ResolveOperatorType(op, children); |
64 | |
65 | auto result = make_unique<BoundOperatorExpression>(op.type, GetInternalType(result_type)); |
66 | for (auto &child : children) { |
67 | result->children.push_back(move(child->expr)); |
68 | } |
69 | return BindResult(move(result), result_type); |
70 | } |
71 | |