1#include "duckdb/planner/expression/bound_cast_expression.hpp"
2#include "duckdb/planner/expression/bound_default_expression.hpp"
3#include "duckdb/planner/expression/bound_parameter_expression.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8BoundCastExpression::BoundCastExpression(TypeId target, unique_ptr<Expression> child, SQLType source_type,
9 SQLType target_type)
10 : Expression(ExpressionType::OPERATOR_CAST, ExpressionClass::BOUND_CAST, target), child(move(child)),
11 source_type(source_type), target_type(target_type) {
12}
13
14unique_ptr<Expression> BoundCastExpression::AddCastToType(unique_ptr<Expression> expr, SQLType source_type,
15 SQLType target_type) {
16 assert(expr);
17 if (expr->expression_class == ExpressionClass::BOUND_PARAMETER) {
18 auto &parameter = (BoundParameterExpression &)*expr;
19 parameter.sql_type = target_type;
20 parameter.return_type = GetInternalType(target_type);
21 } else if (expr->expression_class == ExpressionClass::BOUND_DEFAULT) {
22 auto &def = (BoundDefaultExpression &)*expr;
23 def.sql_type = target_type;
24 def.return_type = GetInternalType(target_type);
25 } else if (source_type != target_type) {
26 return make_unique<BoundCastExpression>(GetInternalType(target_type), move(expr), source_type, target_type);
27 }
28 return expr;
29}
30
31bool BoundCastExpression::CastIsInvertible(SQLType source_type, SQLType target_type) {
32 if (source_type.id == SQLTypeId::BOOLEAN || target_type.id == SQLTypeId::BOOLEAN) {
33 return false;
34 }
35 if (source_type.id == SQLTypeId::FLOAT || target_type.id == SQLTypeId::FLOAT) {
36 return false;
37 }
38 if (source_type.id == SQLTypeId::DOUBLE || target_type.id == SQLTypeId::DOUBLE) {
39 return false;
40 }
41 if (source_type.id == SQLTypeId::VARCHAR) {
42 return target_type.id == SQLTypeId::DATE || target_type.id == SQLTypeId::TIMESTAMP;
43 }
44 if (target_type.id == SQLTypeId::VARCHAR) {
45 return source_type.id == SQLTypeId::DATE || source_type.id == SQLTypeId::TIMESTAMP;
46 }
47 return true;
48}
49
50string BoundCastExpression::ToString() const {
51 return "CAST[" + TypeIdToString(return_type) + "](" + child->GetName() + ")";
52}
53
54bool BoundCastExpression::Equals(const BaseExpression *other_) const {
55 if (!BaseExpression::Equals(other_)) {
56 return false;
57 }
58 auto other = (BoundCastExpression *)other_;
59 if (!Expression::Equals(child.get(), other->child.get())) {
60 return false;
61 }
62 if (source_type != other->source_type || target_type != other->target_type) {
63 return false;
64 }
65 return true;
66}
67
68unique_ptr<Expression> BoundCastExpression::Copy() {
69 auto copy = make_unique<BoundCastExpression>(return_type, child->Copy(), source_type, target_type);
70 copy->CopyProperties(*this);
71 return move(copy);
72}
73