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
6using namespace duckdb;
7using namespace std;
8
9static 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
17static 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
32static 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
47BindResult 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