1#include "duckdb/function/cast_rules.hpp"
2#include "duckdb/common/exception.hpp"
3
4using namespace duckdb;
5using namespace std;
6
7//! The target type determines the preferred implicit casts
8static int64_t TargetTypeCost(SQLType type) {
9 switch (type.id) {
10 case SQLTypeId::INTEGER:
11 return 103;
12 case SQLTypeId::BIGINT:
13 return 101;
14 case SQLTypeId::DOUBLE:
15 return 102;
16 case SQLTypeId::VARCHAR:
17 return 199;
18 default:
19 return 110;
20 }
21}
22
23static int64_t ImplicitCastTinyint(SQLType to) {
24 switch (to.id) {
25 case SQLTypeId::SMALLINT:
26 case SQLTypeId::INTEGER:
27 case SQLTypeId::BIGINT:
28 case SQLTypeId::FLOAT:
29 case SQLTypeId::DOUBLE:
30 case SQLTypeId::DECIMAL:
31 return TargetTypeCost(to);
32 default:
33 return -1;
34 }
35}
36
37static int64_t ImplicitCastSmallint(SQLType to) {
38 switch (to.id) {
39 case SQLTypeId::INTEGER:
40 case SQLTypeId::BIGINT:
41 case SQLTypeId::FLOAT:
42 case SQLTypeId::DOUBLE:
43 case SQLTypeId::DECIMAL:
44 return TargetTypeCost(to);
45 default:
46 return -1;
47 }
48}
49
50static int64_t ImplicitCastInteger(SQLType to) {
51 switch (to.id) {
52 case SQLTypeId::BIGINT:
53 case SQLTypeId::FLOAT:
54 case SQLTypeId::DOUBLE:
55 case SQLTypeId::DECIMAL:
56 return TargetTypeCost(to);
57 default:
58 return -1;
59 }
60}
61
62static int64_t ImplicitCastBigint(SQLType to) {
63 switch (to.id) {
64 case SQLTypeId::FLOAT:
65 case SQLTypeId::DOUBLE:
66 case SQLTypeId::DECIMAL:
67 return TargetTypeCost(to);
68 default:
69 return -1;
70 }
71}
72
73static int64_t ImplicitCastFloat(SQLType to) {
74 switch (to.id) {
75 case SQLTypeId::DOUBLE:
76 case SQLTypeId::DECIMAL:
77 return TargetTypeCost(to);
78 default:
79 return -1;
80 }
81}
82
83static int64_t ImplicitCastDouble(SQLType to) {
84 switch (to.id) {
85 case SQLTypeId::DECIMAL:
86 return TargetTypeCost(to);
87 default:
88 return -1;
89 }
90}
91
92int64_t CastRules::ImplicitCast(SQLType from, SQLType to) {
93 if (to.id == SQLTypeId::ANY) {
94 // anything can be cast to ANY type for no cost
95 return 0;
96 }
97 if (from.id == SQLTypeId::SQLNULL || from.id == SQLTypeId::UNKNOWN) {
98 // NULL expression or parameter expression can be cast to anything
99 return TargetTypeCost(to);
100 }
101 if (from.id == SQLTypeId::BLOB && to.id == SQLTypeId::VARCHAR) {
102 //Implicit cast not allowed from BLOB to VARCHAR
103 return -1;
104 }
105 if (to.id == SQLTypeId::VARCHAR) {
106 // everything can be cast to VARCHAR, but this cast has a high cost
107 return TargetTypeCost(to);
108 }
109 switch (from.id) {
110 case SQLTypeId::TINYINT:
111 return ImplicitCastTinyint(to);
112 case SQLTypeId::SMALLINT:
113 return ImplicitCastSmallint(to);
114 case SQLTypeId::INTEGER:
115 return ImplicitCastInteger(to);
116 case SQLTypeId::BIGINT:
117 return ImplicitCastBigint(to);
118 case SQLTypeId::FLOAT:
119 return ImplicitCastFloat(to);
120 case SQLTypeId::DOUBLE:
121 return ImplicitCastDouble(to);
122 default:
123 return -1;
124 }
125}
126