1 | #include "duckdb/common/types/cast_helpers.hpp" |
2 | #include "duckdb/common/operator/string_cast.hpp" |
3 | #include "duckdb/common/types/vector.hpp" |
4 | #include "duckdb/common/types/date.hpp" |
5 | #include "duckdb/common/types/decimal.hpp" |
6 | #include "duckdb/common/types/hugeint.hpp" |
7 | #include "duckdb/common/types/interval.hpp" |
8 | #include "duckdb/common/types/time.hpp" |
9 | #include "duckdb/common/types/timestamp.hpp" |
10 | |
11 | namespace duckdb { |
12 | |
13 | //===--------------------------------------------------------------------===// |
14 | // Cast Numeric -> String |
15 | //===--------------------------------------------------------------------===// |
16 | template <> |
17 | string_t StringCast::Operation(bool input, Vector &vector) { |
18 | if (input) { |
19 | return StringVector::AddString(vector, data: "true" , len: 4); |
20 | } else { |
21 | return StringVector::AddString(vector, data: "false" , len: 5); |
22 | } |
23 | } |
24 | |
25 | template <> |
26 | string_t StringCast::Operation(int8_t input, Vector &vector) { |
27 | return NumericHelper::FormatSigned<int8_t, uint8_t>(value: input, vector); |
28 | } |
29 | |
30 | template <> |
31 | string_t StringCast::Operation(int16_t input, Vector &vector) { |
32 | return NumericHelper::FormatSigned<int16_t, uint16_t>(value: input, vector); |
33 | } |
34 | template <> |
35 | string_t StringCast::Operation(int32_t input, Vector &vector) { |
36 | return NumericHelper::FormatSigned<int32_t, uint32_t>(value: input, vector); |
37 | } |
38 | |
39 | template <> |
40 | string_t StringCast::Operation(int64_t input, Vector &vector) { |
41 | return NumericHelper::FormatSigned<int64_t, uint64_t>(value: input, vector); |
42 | } |
43 | template <> |
44 | duckdb::string_t StringCast::Operation(uint8_t input, Vector &vector) { |
45 | return NumericHelper::FormatSigned<uint8_t, uint64_t>(value: input, vector); |
46 | } |
47 | template <> |
48 | duckdb::string_t StringCast::Operation(uint16_t input, Vector &vector) { |
49 | return NumericHelper::FormatSigned<uint16_t, uint64_t>(value: input, vector); |
50 | } |
51 | template <> |
52 | duckdb::string_t StringCast::Operation(uint32_t input, Vector &vector) { |
53 | return NumericHelper::FormatSigned<uint32_t, uint64_t>(value: input, vector); |
54 | } |
55 | template <> |
56 | duckdb::string_t StringCast::Operation(uint64_t input, Vector &vector) { |
57 | return NumericHelper::FormatSigned<uint64_t, uint64_t>(value: input, vector); |
58 | } |
59 | |
60 | template <> |
61 | string_t StringCast::Operation(float input, Vector &vector) { |
62 | std::string s = duckdb_fmt::format(format_str: "{}" , args&: input); |
63 | return StringVector::AddString(vector, data: s); |
64 | } |
65 | |
66 | template <> |
67 | string_t StringCast::Operation(double input, Vector &vector) { |
68 | std::string s = duckdb_fmt::format(format_str: "{}" , args&: input); |
69 | return StringVector::AddString(vector, data: s); |
70 | } |
71 | |
72 | template <> |
73 | string_t StringCast::Operation(interval_t input, Vector &vector) { |
74 | char buffer[70]; |
75 | idx_t length = IntervalToStringCast::Format(interval: input, buffer); |
76 | return StringVector::AddString(vector, data: buffer, len: length); |
77 | } |
78 | |
79 | template <> |
80 | duckdb::string_t StringCast::Operation(hugeint_t input, Vector &vector) { |
81 | return HugeintToStringCast::FormatSigned(value: input, vector); |
82 | } |
83 | |
84 | template <> |
85 | duckdb::string_t StringCast::Operation(date_t input, Vector &vector) { |
86 | if (input == date_t::infinity()) { |
87 | return StringVector::AddString(vector, data: Date::PINF); |
88 | } else if (input == date_t::ninfinity()) { |
89 | return StringVector::AddString(vector, data: Date::NINF); |
90 | } |
91 | int32_t date[3]; |
92 | Date::Convert(date: input, out_year&: date[0], out_month&: date[1], out_day&: date[2]); |
93 | |
94 | idx_t year_length; |
95 | bool add_bc; |
96 | idx_t length = DateToStringCast::Length(date, year_length, add_bc); |
97 | |
98 | string_t result = StringVector::EmptyString(vector, len: length); |
99 | auto data = result.GetDataWriteable(); |
100 | |
101 | DateToStringCast::Format(data, date, year_length, add_bc); |
102 | |
103 | result.Finalize(); |
104 | return result; |
105 | } |
106 | |
107 | template <> |
108 | duckdb::string_t StringCast::Operation(dtime_t input, Vector &vector) { |
109 | int32_t time[4]; |
110 | Time::Convert(time: input, out_hour&: time[0], out_min&: time[1], out_sec&: time[2], out_micros&: time[3]); |
111 | |
112 | char micro_buffer[10]; |
113 | idx_t length = TimeToStringCast::Length(time, micro_buffer); |
114 | |
115 | string_t result = StringVector::EmptyString(vector, len: length); |
116 | auto data = result.GetDataWriteable(); |
117 | |
118 | TimeToStringCast::Format(data, length, time, micro_buffer); |
119 | |
120 | result.Finalize(); |
121 | return result; |
122 | } |
123 | |
124 | template <> |
125 | duckdb::string_t StringCast::Operation(timestamp_t input, Vector &vector) { |
126 | if (input == timestamp_t::infinity()) { |
127 | return StringVector::AddString(vector, data: Date::PINF); |
128 | } else if (input == timestamp_t::ninfinity()) { |
129 | return StringVector::AddString(vector, data: Date::NINF); |
130 | } |
131 | date_t date_entry; |
132 | dtime_t time_entry; |
133 | Timestamp::Convert(date: input, out_date&: date_entry, out_time&: time_entry); |
134 | |
135 | int32_t date[3], time[4]; |
136 | Date::Convert(date: date_entry, out_year&: date[0], out_month&: date[1], out_day&: date[2]); |
137 | Time::Convert(time: time_entry, out_hour&: time[0], out_min&: time[1], out_sec&: time[2], out_micros&: time[3]); |
138 | |
139 | // format for timestamp is DATE TIME (separated by space) |
140 | idx_t year_length; |
141 | bool add_bc; |
142 | char micro_buffer[6]; |
143 | idx_t date_length = DateToStringCast::Length(date, year_length, add_bc); |
144 | idx_t time_length = TimeToStringCast::Length(time, micro_buffer); |
145 | idx_t length = date_length + time_length + 1; |
146 | |
147 | string_t result = StringVector::EmptyString(vector, len: length); |
148 | auto data = result.GetDataWriteable(); |
149 | |
150 | DateToStringCast::Format(data, date, year_length, add_bc); |
151 | data[date_length] = ' '; |
152 | TimeToStringCast::Format(data: data + date_length + 1, length: time_length, time, micro_buffer); |
153 | |
154 | result.Finalize(); |
155 | return result; |
156 | } |
157 | |
158 | template <> |
159 | duckdb::string_t StringCast::Operation(duckdb::string_t input, Vector &result) { |
160 | return StringVector::AddStringOrBlob(vector&: result, data: input); |
161 | } |
162 | |
163 | template <> |
164 | string_t StringCastTZ::Operation(dtime_t input, Vector &vector) { |
165 | int32_t time[4]; |
166 | Time::Convert(time: input, out_hour&: time[0], out_min&: time[1], out_sec&: time[2], out_micros&: time[3]); |
167 | |
168 | // format for timetz is TIME+00 |
169 | char micro_buffer[10]; |
170 | const auto time_length = TimeToStringCast::Length(time, micro_buffer); |
171 | const idx_t length = time_length + 3; |
172 | |
173 | string_t result = StringVector::EmptyString(vector, len: length); |
174 | auto data = result.GetDataWriteable(); |
175 | |
176 | idx_t pos = 0; |
177 | TimeToStringCast::Format(data: data + pos, length, time, micro_buffer); |
178 | pos += time_length; |
179 | data[pos++] = '+'; |
180 | data[pos++] = '0'; |
181 | data[pos++] = '0'; |
182 | |
183 | result.Finalize(); |
184 | return result; |
185 | } |
186 | |
187 | template <> |
188 | string_t StringCastTZ::Operation(timestamp_t input, Vector &vector) { |
189 | if (input == timestamp_t::infinity()) { |
190 | return StringVector::AddString(vector, data: Date::PINF); |
191 | } else if (input == timestamp_t::ninfinity()) { |
192 | return StringVector::AddString(vector, data: Date::NINF); |
193 | } |
194 | date_t date_entry; |
195 | dtime_t time_entry; |
196 | Timestamp::Convert(date: input, out_date&: date_entry, out_time&: time_entry); |
197 | |
198 | int32_t date[3], time[4]; |
199 | Date::Convert(date: date_entry, out_year&: date[0], out_month&: date[1], out_day&: date[2]); |
200 | Time::Convert(time: time_entry, out_hour&: time[0], out_min&: time[1], out_sec&: time[2], out_micros&: time[3]); |
201 | |
202 | // format for timestamptz is DATE TIME+00 (separated by space) |
203 | idx_t year_length; |
204 | bool add_bc; |
205 | char micro_buffer[6]; |
206 | const idx_t date_length = DateToStringCast::Length(date, year_length, add_bc); |
207 | const idx_t time_length = TimeToStringCast::Length(time, micro_buffer); |
208 | const idx_t length = date_length + 1 + time_length + 3; |
209 | |
210 | string_t result = StringVector::EmptyString(vector, len: length); |
211 | auto data = result.GetDataWriteable(); |
212 | |
213 | idx_t pos = 0; |
214 | DateToStringCast::Format(data: data + pos, date, year_length, add_bc); |
215 | pos += date_length; |
216 | data[pos++] = ' '; |
217 | TimeToStringCast::Format(data: data + pos, length: time_length, time, micro_buffer); |
218 | pos += time_length; |
219 | data[pos++] = '+'; |
220 | data[pos++] = '0'; |
221 | data[pos++] = '0'; |
222 | |
223 | result.Finalize(); |
224 | return result; |
225 | } |
226 | |
227 | } // namespace duckdb |
228 | |