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
11namespace duckdb {
12
13//===--------------------------------------------------------------------===//
14// Cast Numeric -> String
15//===--------------------------------------------------------------------===//
16template <>
17string_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
25template <>
26string_t StringCast::Operation(int8_t input, Vector &vector) {
27 return NumericHelper::FormatSigned<int8_t, uint8_t>(value: input, vector);
28}
29
30template <>
31string_t StringCast::Operation(int16_t input, Vector &vector) {
32 return NumericHelper::FormatSigned<int16_t, uint16_t>(value: input, vector);
33}
34template <>
35string_t StringCast::Operation(int32_t input, Vector &vector) {
36 return NumericHelper::FormatSigned<int32_t, uint32_t>(value: input, vector);
37}
38
39template <>
40string_t StringCast::Operation(int64_t input, Vector &vector) {
41 return NumericHelper::FormatSigned<int64_t, uint64_t>(value: input, vector);
42}
43template <>
44duckdb::string_t StringCast::Operation(uint8_t input, Vector &vector) {
45 return NumericHelper::FormatSigned<uint8_t, uint64_t>(value: input, vector);
46}
47template <>
48duckdb::string_t StringCast::Operation(uint16_t input, Vector &vector) {
49 return NumericHelper::FormatSigned<uint16_t, uint64_t>(value: input, vector);
50}
51template <>
52duckdb::string_t StringCast::Operation(uint32_t input, Vector &vector) {
53 return NumericHelper::FormatSigned<uint32_t, uint64_t>(value: input, vector);
54}
55template <>
56duckdb::string_t StringCast::Operation(uint64_t input, Vector &vector) {
57 return NumericHelper::FormatSigned<uint64_t, uint64_t>(value: input, vector);
58}
59
60template <>
61string_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
66template <>
67string_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
72template <>
73string_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
79template <>
80duckdb::string_t StringCast::Operation(hugeint_t input, Vector &vector) {
81 return HugeintToStringCast::FormatSigned(value: input, vector);
82}
83
84template <>
85duckdb::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
107template <>
108duckdb::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
124template <>
125duckdb::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
158template <>
159duckdb::string_t StringCast::Operation(duckdb::string_t input, Vector &result) {
160 return StringVector::AddStringOrBlob(vector&: result, data: input);
161}
162
163template <>
164string_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
187template <>
188string_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