1#include "duckdb/common/operator/cast_operators.hpp"
2#include "duckdb/common/operator/string_cast.hpp"
3#include "duckdb/common/operator/numeric_cast.hpp"
4#include "duckdb/common/operator/decimal_cast_operators.hpp"
5#include "duckdb/common/operator/multiply.hpp"
6
7#include "duckdb/common/exception.hpp"
8#include "duckdb/common/limits.hpp"
9#include "duckdb/common/string_util.hpp"
10#include "duckdb/common/types/blob.hpp"
11#include "duckdb/common/types/cast_helpers.hpp"
12#include "duckdb/common/types/date.hpp"
13#include "duckdb/common/types/decimal.hpp"
14#include "duckdb/common/types/hugeint.hpp"
15#include "duckdb/common/types/uuid.hpp"
16#include "duckdb/common/types/interval.hpp"
17#include "duckdb/common/types/time.hpp"
18#include "duckdb/common/types/timestamp.hpp"
19#include "duckdb/common/types/vector.hpp"
20#include "duckdb/common/types.hpp"
21#include "fast_float/fast_float.h"
22#include "fmt/format.h"
23#include "duckdb/common/types/bit.hpp"
24
25#include <cctype>
26#include <cmath>
27#include <cstdlib>
28
29namespace duckdb {
30
31//===--------------------------------------------------------------------===//
32// Cast bool -> Numeric
33//===--------------------------------------------------------------------===//
34template <>
35bool TryCast::Operation(bool input, bool &result, bool strict) {
36 return NumericTryCast::Operation<bool, bool>(input, result, strict);
37}
38
39template <>
40bool TryCast::Operation(bool input, int8_t &result, bool strict) {
41 return NumericTryCast::Operation<bool, int8_t>(input, result, strict);
42}
43
44template <>
45bool TryCast::Operation(bool input, int16_t &result, bool strict) {
46 return NumericTryCast::Operation<bool, int16_t>(input, result, strict);
47}
48
49template <>
50bool TryCast::Operation(bool input, int32_t &result, bool strict) {
51 return NumericTryCast::Operation<bool, int32_t>(input, result, strict);
52}
53
54template <>
55bool TryCast::Operation(bool input, int64_t &result, bool strict) {
56 return NumericTryCast::Operation<bool, int64_t>(input, result, strict);
57}
58
59template <>
60bool TryCast::Operation(bool input, hugeint_t &result, bool strict) {
61 return NumericTryCast::Operation<bool, hugeint_t>(input, result, strict);
62}
63
64template <>
65bool TryCast::Operation(bool input, uint8_t &result, bool strict) {
66 return NumericTryCast::Operation<bool, uint8_t>(input, result, strict);
67}
68
69template <>
70bool TryCast::Operation(bool input, uint16_t &result, bool strict) {
71 return NumericTryCast::Operation<bool, uint16_t>(input, result, strict);
72}
73
74template <>
75bool TryCast::Operation(bool input, uint32_t &result, bool strict) {
76 return NumericTryCast::Operation<bool, uint32_t>(input, result, strict);
77}
78
79template <>
80bool TryCast::Operation(bool input, uint64_t &result, bool strict) {
81 return NumericTryCast::Operation<bool, uint64_t>(input, result, strict);
82}
83
84template <>
85bool TryCast::Operation(bool input, float &result, bool strict) {
86 return NumericTryCast::Operation<bool, float>(input, result, strict);
87}
88
89template <>
90bool TryCast::Operation(bool input, double &result, bool strict) {
91 return NumericTryCast::Operation<bool, double>(input, result, strict);
92}
93
94//===--------------------------------------------------------------------===//
95// Cast int8_t -> Numeric
96//===--------------------------------------------------------------------===//
97template <>
98bool TryCast::Operation(int8_t input, bool &result, bool strict) {
99 return NumericTryCast::Operation<int8_t, bool>(input, result, strict);
100}
101
102template <>
103bool TryCast::Operation(int8_t input, int8_t &result, bool strict) {
104 return NumericTryCast::Operation<int8_t, int8_t>(input, result, strict);
105}
106
107template <>
108bool TryCast::Operation(int8_t input, int16_t &result, bool strict) {
109 return NumericTryCast::Operation<int8_t, int16_t>(input, result, strict);
110}
111
112template <>
113bool TryCast::Operation(int8_t input, int32_t &result, bool strict) {
114 return NumericTryCast::Operation<int8_t, int32_t>(input, result, strict);
115}
116
117template <>
118bool TryCast::Operation(int8_t input, int64_t &result, bool strict) {
119 return NumericTryCast::Operation<int8_t, int64_t>(input, result, strict);
120}
121
122template <>
123bool TryCast::Operation(int8_t input, hugeint_t &result, bool strict) {
124 return NumericTryCast::Operation<int8_t, hugeint_t>(input, result, strict);
125}
126
127template <>
128bool TryCast::Operation(int8_t input, uint8_t &result, bool strict) {
129 return NumericTryCast::Operation<int8_t, uint8_t>(input, result, strict);
130}
131
132template <>
133bool TryCast::Operation(int8_t input, uint16_t &result, bool strict) {
134 return NumericTryCast::Operation<int8_t, uint16_t>(input, result, strict);
135}
136
137template <>
138bool TryCast::Operation(int8_t input, uint32_t &result, bool strict) {
139 return NumericTryCast::Operation<int8_t, uint32_t>(input, result, strict);
140}
141
142template <>
143bool TryCast::Operation(int8_t input, uint64_t &result, bool strict) {
144 return NumericTryCast::Operation<int8_t, uint64_t>(input, result, strict);
145}
146
147template <>
148bool TryCast::Operation(int8_t input, float &result, bool strict) {
149 return NumericTryCast::Operation<int8_t, float>(input, result, strict);
150}
151
152template <>
153bool TryCast::Operation(int8_t input, double &result, bool strict) {
154 return NumericTryCast::Operation<int8_t, double>(input, result, strict);
155}
156
157//===--------------------------------------------------------------------===//
158// Cast int16_t -> Numeric
159//===--------------------------------------------------------------------===//
160template <>
161bool TryCast::Operation(int16_t input, bool &result, bool strict) {
162 return NumericTryCast::Operation<int16_t, bool>(input, result, strict);
163}
164
165template <>
166bool TryCast::Operation(int16_t input, int8_t &result, bool strict) {
167 return NumericTryCast::Operation<int16_t, int8_t>(input, result, strict);
168}
169
170template <>
171bool TryCast::Operation(int16_t input, int16_t &result, bool strict) {
172 return NumericTryCast::Operation<int16_t, int16_t>(input, result, strict);
173}
174
175template <>
176bool TryCast::Operation(int16_t input, int32_t &result, bool strict) {
177 return NumericTryCast::Operation<int16_t, int32_t>(input, result, strict);
178}
179
180template <>
181bool TryCast::Operation(int16_t input, int64_t &result, bool strict) {
182 return NumericTryCast::Operation<int16_t, int64_t>(input, result, strict);
183}
184
185template <>
186bool TryCast::Operation(int16_t input, hugeint_t &result, bool strict) {
187 return NumericTryCast::Operation<int16_t, hugeint_t>(input, result, strict);
188}
189
190template <>
191bool TryCast::Operation(int16_t input, uint8_t &result, bool strict) {
192 return NumericTryCast::Operation<int16_t, uint8_t>(input, result, strict);
193}
194
195template <>
196bool TryCast::Operation(int16_t input, uint16_t &result, bool strict) {
197 return NumericTryCast::Operation<int16_t, uint16_t>(input, result, strict);
198}
199
200template <>
201bool TryCast::Operation(int16_t input, uint32_t &result, bool strict) {
202 return NumericTryCast::Operation<int16_t, uint32_t>(input, result, strict);
203}
204
205template <>
206bool TryCast::Operation(int16_t input, uint64_t &result, bool strict) {
207 return NumericTryCast::Operation<int16_t, uint64_t>(input, result, strict);
208}
209
210template <>
211bool TryCast::Operation(int16_t input, float &result, bool strict) {
212 return NumericTryCast::Operation<int16_t, float>(input, result, strict);
213}
214
215template <>
216bool TryCast::Operation(int16_t input, double &result, bool strict) {
217 return NumericTryCast::Operation<int16_t, double>(input, result, strict);
218}
219
220//===--------------------------------------------------------------------===//
221// Cast int32_t -> Numeric
222//===--------------------------------------------------------------------===//
223template <>
224bool TryCast::Operation(int32_t input, bool &result, bool strict) {
225 return NumericTryCast::Operation<int32_t, bool>(input, result, strict);
226}
227
228template <>
229bool TryCast::Operation(int32_t input, int8_t &result, bool strict) {
230 return NumericTryCast::Operation<int32_t, int8_t>(input, result, strict);
231}
232
233template <>
234bool TryCast::Operation(int32_t input, int16_t &result, bool strict) {
235 return NumericTryCast::Operation<int32_t, int16_t>(input, result, strict);
236}
237
238template <>
239bool TryCast::Operation(int32_t input, int32_t &result, bool strict) {
240 return NumericTryCast::Operation<int32_t, int32_t>(input, result, strict);
241}
242
243template <>
244bool TryCast::Operation(int32_t input, int64_t &result, bool strict) {
245 return NumericTryCast::Operation<int32_t, int64_t>(input, result, strict);
246}
247
248template <>
249bool TryCast::Operation(int32_t input, hugeint_t &result, bool strict) {
250 return NumericTryCast::Operation<int32_t, hugeint_t>(input, result, strict);
251}
252
253template <>
254bool TryCast::Operation(int32_t input, uint8_t &result, bool strict) {
255 return NumericTryCast::Operation<int32_t, uint8_t>(input, result, strict);
256}
257
258template <>
259bool TryCast::Operation(int32_t input, uint16_t &result, bool strict) {
260 return NumericTryCast::Operation<int32_t, uint16_t>(input, result, strict);
261}
262
263template <>
264bool TryCast::Operation(int32_t input, uint32_t &result, bool strict) {
265 return NumericTryCast::Operation<int32_t, uint32_t>(input, result, strict);
266}
267
268template <>
269bool TryCast::Operation(int32_t input, uint64_t &result, bool strict) {
270 return NumericTryCast::Operation<int32_t, uint64_t>(input, result, strict);
271}
272
273template <>
274bool TryCast::Operation(int32_t input, float &result, bool strict) {
275 return NumericTryCast::Operation<int32_t, float>(input, result, strict);
276}
277
278template <>
279bool TryCast::Operation(int32_t input, double &result, bool strict) {
280 return NumericTryCast::Operation<int32_t, double>(input, result, strict);
281}
282
283//===--------------------------------------------------------------------===//
284// Cast int64_t -> Numeric
285//===--------------------------------------------------------------------===//
286template <>
287bool TryCast::Operation(int64_t input, bool &result, bool strict) {
288 return NumericTryCast::Operation<int64_t, bool>(input, result, strict);
289}
290
291template <>
292bool TryCast::Operation(int64_t input, int8_t &result, bool strict) {
293 return NumericTryCast::Operation<int64_t, int8_t>(input, result, strict);
294}
295
296template <>
297bool TryCast::Operation(int64_t input, int16_t &result, bool strict) {
298 return NumericTryCast::Operation<int64_t, int16_t>(input, result, strict);
299}
300
301template <>
302bool TryCast::Operation(int64_t input, int32_t &result, bool strict) {
303 return NumericTryCast::Operation<int64_t, int32_t>(input, result, strict);
304}
305
306template <>
307bool TryCast::Operation(int64_t input, int64_t &result, bool strict) {
308 return NumericTryCast::Operation<int64_t, int64_t>(input, result, strict);
309}
310
311template <>
312bool TryCast::Operation(int64_t input, hugeint_t &result, bool strict) {
313 return NumericTryCast::Operation<int64_t, hugeint_t>(input, result, strict);
314}
315
316template <>
317bool TryCast::Operation(int64_t input, uint8_t &result, bool strict) {
318 return NumericTryCast::Operation<int64_t, uint8_t>(input, result, strict);
319}
320
321template <>
322bool TryCast::Operation(int64_t input, uint16_t &result, bool strict) {
323 return NumericTryCast::Operation<int64_t, uint16_t>(input, result, strict);
324}
325
326template <>
327bool TryCast::Operation(int64_t input, uint32_t &result, bool strict) {
328 return NumericTryCast::Operation<int64_t, uint32_t>(input, result, strict);
329}
330
331template <>
332bool TryCast::Operation(int64_t input, uint64_t &result, bool strict) {
333 return NumericTryCast::Operation<int64_t, uint64_t>(input, result, strict);
334}
335
336template <>
337bool TryCast::Operation(int64_t input, float &result, bool strict) {
338 return NumericTryCast::Operation<int64_t, float>(input, result, strict);
339}
340
341template <>
342bool TryCast::Operation(int64_t input, double &result, bool strict) {
343 return NumericTryCast::Operation<int64_t, double>(input, result, strict);
344}
345
346//===--------------------------------------------------------------------===//
347// Cast hugeint_t -> Numeric
348//===--------------------------------------------------------------------===//
349template <>
350bool TryCast::Operation(hugeint_t input, bool &result, bool strict) {
351 return NumericTryCast::Operation<hugeint_t, bool>(input, result, strict);
352}
353
354template <>
355bool TryCast::Operation(hugeint_t input, int8_t &result, bool strict) {
356 return NumericTryCast::Operation<hugeint_t, int8_t>(input, result, strict);
357}
358
359template <>
360bool TryCast::Operation(hugeint_t input, int16_t &result, bool strict) {
361 return NumericTryCast::Operation<hugeint_t, int16_t>(input, result, strict);
362}
363
364template <>
365bool TryCast::Operation(hugeint_t input, int32_t &result, bool strict) {
366 return NumericTryCast::Operation<hugeint_t, int32_t>(input, result, strict);
367}
368
369template <>
370bool TryCast::Operation(hugeint_t input, int64_t &result, bool strict) {
371 return NumericTryCast::Operation<hugeint_t, int64_t>(input, result, strict);
372}
373
374template <>
375bool TryCast::Operation(hugeint_t input, hugeint_t &result, bool strict) {
376 return NumericTryCast::Operation<hugeint_t, hugeint_t>(input, result, strict);
377}
378
379template <>
380bool TryCast::Operation(hugeint_t input, uint8_t &result, bool strict) {
381 return NumericTryCast::Operation<hugeint_t, uint8_t>(input, result, strict);
382}
383
384template <>
385bool TryCast::Operation(hugeint_t input, uint16_t &result, bool strict) {
386 return NumericTryCast::Operation<hugeint_t, uint16_t>(input, result, strict);
387}
388
389template <>
390bool TryCast::Operation(hugeint_t input, uint32_t &result, bool strict) {
391 return NumericTryCast::Operation<hugeint_t, uint32_t>(input, result, strict);
392}
393
394template <>
395bool TryCast::Operation(hugeint_t input, uint64_t &result, bool strict) {
396 return NumericTryCast::Operation<hugeint_t, uint64_t>(input, result, strict);
397}
398
399template <>
400bool TryCast::Operation(hugeint_t input, float &result, bool strict) {
401 return NumericTryCast::Operation<hugeint_t, float>(input, result, strict);
402}
403
404template <>
405bool TryCast::Operation(hugeint_t input, double &result, bool strict) {
406 return NumericTryCast::Operation<hugeint_t, double>(input, result, strict);
407}
408
409//===--------------------------------------------------------------------===//
410// Cast uint8_t -> Numeric
411//===--------------------------------------------------------------------===//
412template <>
413bool TryCast::Operation(uint8_t input, bool &result, bool strict) {
414 return NumericTryCast::Operation<uint8_t, bool>(input, result, strict);
415}
416
417template <>
418bool TryCast::Operation(uint8_t input, int8_t &result, bool strict) {
419 return NumericTryCast::Operation<uint8_t, int8_t>(input, result, strict);
420}
421
422template <>
423bool TryCast::Operation(uint8_t input, int16_t &result, bool strict) {
424 return NumericTryCast::Operation<uint8_t, int16_t>(input, result, strict);
425}
426
427template <>
428bool TryCast::Operation(uint8_t input, int32_t &result, bool strict) {
429 return NumericTryCast::Operation<uint8_t, int32_t>(input, result, strict);
430}
431
432template <>
433bool TryCast::Operation(uint8_t input, int64_t &result, bool strict) {
434 return NumericTryCast::Operation<uint8_t, int64_t>(input, result, strict);
435}
436
437template <>
438bool TryCast::Operation(uint8_t input, hugeint_t &result, bool strict) {
439 return NumericTryCast::Operation<uint8_t, hugeint_t>(input, result, strict);
440}
441
442template <>
443bool TryCast::Operation(uint8_t input, uint8_t &result, bool strict) {
444 return NumericTryCast::Operation<uint8_t, uint8_t>(input, result, strict);
445}
446
447template <>
448bool TryCast::Operation(uint8_t input, uint16_t &result, bool strict) {
449 return NumericTryCast::Operation<uint8_t, uint16_t>(input, result, strict);
450}
451
452template <>
453bool TryCast::Operation(uint8_t input, uint32_t &result, bool strict) {
454 return NumericTryCast::Operation<uint8_t, uint32_t>(input, result, strict);
455}
456
457template <>
458bool TryCast::Operation(uint8_t input, uint64_t &result, bool strict) {
459 return NumericTryCast::Operation<uint8_t, uint64_t>(input, result, strict);
460}
461
462template <>
463bool TryCast::Operation(uint8_t input, float &result, bool strict) {
464 return NumericTryCast::Operation<uint8_t, float>(input, result, strict);
465}
466
467template <>
468bool TryCast::Operation(uint8_t input, double &result, bool strict) {
469 return NumericTryCast::Operation<uint8_t, double>(input, result, strict);
470}
471
472//===--------------------------------------------------------------------===//
473// Cast uint16_t -> Numeric
474//===--------------------------------------------------------------------===//
475template <>
476bool TryCast::Operation(uint16_t input, bool &result, bool strict) {
477 return NumericTryCast::Operation<uint16_t, bool>(input, result, strict);
478}
479
480template <>
481bool TryCast::Operation(uint16_t input, int8_t &result, bool strict) {
482 return NumericTryCast::Operation<uint16_t, int8_t>(input, result, strict);
483}
484
485template <>
486bool TryCast::Operation(uint16_t input, int16_t &result, bool strict) {
487 return NumericTryCast::Operation<uint16_t, int16_t>(input, result, strict);
488}
489
490template <>
491bool TryCast::Operation(uint16_t input, int32_t &result, bool strict) {
492 return NumericTryCast::Operation<uint16_t, int32_t>(input, result, strict);
493}
494
495template <>
496bool TryCast::Operation(uint16_t input, int64_t &result, bool strict) {
497 return NumericTryCast::Operation<uint16_t, int64_t>(input, result, strict);
498}
499
500template <>
501bool TryCast::Operation(uint16_t input, hugeint_t &result, bool strict) {
502 return NumericTryCast::Operation<uint16_t, hugeint_t>(input, result, strict);
503}
504
505template <>
506bool TryCast::Operation(uint16_t input, uint8_t &result, bool strict) {
507 return NumericTryCast::Operation<uint16_t, uint8_t>(input, result, strict);
508}
509
510template <>
511bool TryCast::Operation(uint16_t input, uint16_t &result, bool strict) {
512 return NumericTryCast::Operation<uint16_t, uint16_t>(input, result, strict);
513}
514
515template <>
516bool TryCast::Operation(uint16_t input, uint32_t &result, bool strict) {
517 return NumericTryCast::Operation<uint16_t, uint32_t>(input, result, strict);
518}
519
520template <>
521bool TryCast::Operation(uint16_t input, uint64_t &result, bool strict) {
522 return NumericTryCast::Operation<uint16_t, uint64_t>(input, result, strict);
523}
524
525template <>
526bool TryCast::Operation(uint16_t input, float &result, bool strict) {
527 return NumericTryCast::Operation<uint16_t, float>(input, result, strict);
528}
529
530template <>
531bool TryCast::Operation(uint16_t input, double &result, bool strict) {
532 return NumericTryCast::Operation<uint16_t, double>(input, result, strict);
533}
534
535//===--------------------------------------------------------------------===//
536// Cast uint32_t -> Numeric
537//===--------------------------------------------------------------------===//
538template <>
539bool TryCast::Operation(uint32_t input, bool &result, bool strict) {
540 return NumericTryCast::Operation<uint32_t, bool>(input, result, strict);
541}
542
543template <>
544bool TryCast::Operation(uint32_t input, int8_t &result, bool strict) {
545 return NumericTryCast::Operation<uint32_t, int8_t>(input, result, strict);
546}
547
548template <>
549bool TryCast::Operation(uint32_t input, int16_t &result, bool strict) {
550 return NumericTryCast::Operation<uint32_t, int16_t>(input, result, strict);
551}
552
553template <>
554bool TryCast::Operation(uint32_t input, int32_t &result, bool strict) {
555 return NumericTryCast::Operation<uint32_t, int32_t>(input, result, strict);
556}
557
558template <>
559bool TryCast::Operation(uint32_t input, int64_t &result, bool strict) {
560 return NumericTryCast::Operation<uint32_t, int64_t>(input, result, strict);
561}
562
563template <>
564bool TryCast::Operation(uint32_t input, hugeint_t &result, bool strict) {
565 return NumericTryCast::Operation<uint32_t, hugeint_t>(input, result, strict);
566}
567
568template <>
569bool TryCast::Operation(uint32_t input, uint8_t &result, bool strict) {
570 return NumericTryCast::Operation<uint32_t, uint8_t>(input, result, strict);
571}
572
573template <>
574bool TryCast::Operation(uint32_t input, uint16_t &result, bool strict) {
575 return NumericTryCast::Operation<uint32_t, uint16_t>(input, result, strict);
576}
577
578template <>
579bool TryCast::Operation(uint32_t input, uint32_t &result, bool strict) {
580 return NumericTryCast::Operation<uint32_t, uint32_t>(input, result, strict);
581}
582
583template <>
584bool TryCast::Operation(uint32_t input, uint64_t &result, bool strict) {
585 return NumericTryCast::Operation<uint32_t, uint64_t>(input, result, strict);
586}
587
588template <>
589bool TryCast::Operation(uint32_t input, float &result, bool strict) {
590 return NumericTryCast::Operation<uint32_t, float>(input, result, strict);
591}
592
593template <>
594bool TryCast::Operation(uint32_t input, double &result, bool strict) {
595 return NumericTryCast::Operation<uint32_t, double>(input, result, strict);
596}
597
598//===--------------------------------------------------------------------===//
599// Cast uint64_t -> Numeric
600//===--------------------------------------------------------------------===//
601template <>
602bool TryCast::Operation(uint64_t input, bool &result, bool strict) {
603 return NumericTryCast::Operation<uint64_t, bool>(input, result, strict);
604}
605
606template <>
607bool TryCast::Operation(uint64_t input, int8_t &result, bool strict) {
608 return NumericTryCast::Operation<uint64_t, int8_t>(input, result, strict);
609}
610
611template <>
612bool TryCast::Operation(uint64_t input, int16_t &result, bool strict) {
613 return NumericTryCast::Operation<uint64_t, int16_t>(input, result, strict);
614}
615
616template <>
617bool TryCast::Operation(uint64_t input, int32_t &result, bool strict) {
618 return NumericTryCast::Operation<uint64_t, int32_t>(input, result, strict);
619}
620
621template <>
622bool TryCast::Operation(uint64_t input, int64_t &result, bool strict) {
623 return NumericTryCast::Operation<uint64_t, int64_t>(input, result, strict);
624}
625
626template <>
627bool TryCast::Operation(uint64_t input, hugeint_t &result, bool strict) {
628 return NumericTryCast::Operation<uint64_t, hugeint_t>(input, result, strict);
629}
630
631template <>
632bool TryCast::Operation(uint64_t input, uint8_t &result, bool strict) {
633 return NumericTryCast::Operation<uint64_t, uint8_t>(input, result, strict);
634}
635
636template <>
637bool TryCast::Operation(uint64_t input, uint16_t &result, bool strict) {
638 return NumericTryCast::Operation<uint64_t, uint16_t>(input, result, strict);
639}
640
641template <>
642bool TryCast::Operation(uint64_t input, uint32_t &result, bool strict) {
643 return NumericTryCast::Operation<uint64_t, uint32_t>(input, result, strict);
644}
645
646template <>
647bool TryCast::Operation(uint64_t input, uint64_t &result, bool strict) {
648 return NumericTryCast::Operation<uint64_t, uint64_t>(input, result, strict);
649}
650
651template <>
652bool TryCast::Operation(uint64_t input, float &result, bool strict) {
653 return NumericTryCast::Operation<uint64_t, float>(input, result, strict);
654}
655
656template <>
657bool TryCast::Operation(uint64_t input, double &result, bool strict) {
658 return NumericTryCast::Operation<uint64_t, double>(input, result, strict);
659}
660
661//===--------------------------------------------------------------------===//
662// Cast float -> Numeric
663//===--------------------------------------------------------------------===//
664template <>
665bool TryCast::Operation(float input, bool &result, bool strict) {
666 return NumericTryCast::Operation<float, bool>(input, result, strict);
667}
668
669template <>
670bool TryCast::Operation(float input, int8_t &result, bool strict) {
671 return NumericTryCast::Operation<float, int8_t>(input, result, strict);
672}
673
674template <>
675bool TryCast::Operation(float input, int16_t &result, bool strict) {
676 return NumericTryCast::Operation<float, int16_t>(input, result, strict);
677}
678
679template <>
680bool TryCast::Operation(float input, int32_t &result, bool strict) {
681 return NumericTryCast::Operation<float, int32_t>(input, result, strict);
682}
683
684template <>
685bool TryCast::Operation(float input, int64_t &result, bool strict) {
686 return NumericTryCast::Operation<float, int64_t>(input, result, strict);
687}
688
689template <>
690bool TryCast::Operation(float input, hugeint_t &result, bool strict) {
691 return NumericTryCast::Operation<float, hugeint_t>(input, result, strict);
692}
693
694template <>
695bool TryCast::Operation(float input, uint8_t &result, bool strict) {
696 return NumericTryCast::Operation<float, uint8_t>(input, result, strict);
697}
698
699template <>
700bool TryCast::Operation(float input, uint16_t &result, bool strict) {
701 return NumericTryCast::Operation<float, uint16_t>(input, result, strict);
702}
703
704template <>
705bool TryCast::Operation(float input, uint32_t &result, bool strict) {
706 return NumericTryCast::Operation<float, uint32_t>(input, result, strict);
707}
708
709template <>
710bool TryCast::Operation(float input, uint64_t &result, bool strict) {
711 return NumericTryCast::Operation<float, uint64_t>(input, result, strict);
712}
713
714template <>
715bool TryCast::Operation(float input, float &result, bool strict) {
716 return NumericTryCast::Operation<float, float>(input, result, strict);
717}
718
719template <>
720bool TryCast::Operation(float input, double &result, bool strict) {
721 return NumericTryCast::Operation<float, double>(input, result, strict);
722}
723
724//===--------------------------------------------------------------------===//
725// Cast double -> Numeric
726//===--------------------------------------------------------------------===//
727template <>
728bool TryCast::Operation(double input, bool &result, bool strict) {
729 return NumericTryCast::Operation<double, bool>(input, result, strict);
730}
731
732template <>
733bool TryCast::Operation(double input, int8_t &result, bool strict) {
734 return NumericTryCast::Operation<double, int8_t>(input, result, strict);
735}
736
737template <>
738bool TryCast::Operation(double input, int16_t &result, bool strict) {
739 return NumericTryCast::Operation<double, int16_t>(input, result, strict);
740}
741
742template <>
743bool TryCast::Operation(double input, int32_t &result, bool strict) {
744 return NumericTryCast::Operation<double, int32_t>(input, result, strict);
745}
746
747template <>
748bool TryCast::Operation(double input, int64_t &result, bool strict) {
749 return NumericTryCast::Operation<double, int64_t>(input, result, strict);
750}
751
752template <>
753bool TryCast::Operation(double input, hugeint_t &result, bool strict) {
754 return NumericTryCast::Operation<double, hugeint_t>(input, result, strict);
755}
756
757template <>
758bool TryCast::Operation(double input, uint8_t &result, bool strict) {
759 return NumericTryCast::Operation<double, uint8_t>(input, result, strict);
760}
761
762template <>
763bool TryCast::Operation(double input, uint16_t &result, bool strict) {
764 return NumericTryCast::Operation<double, uint16_t>(input, result, strict);
765}
766
767template <>
768bool TryCast::Operation(double input, uint32_t &result, bool strict) {
769 return NumericTryCast::Operation<double, uint32_t>(input, result, strict);
770}
771
772template <>
773bool TryCast::Operation(double input, uint64_t &result, bool strict) {
774 return NumericTryCast::Operation<double, uint64_t>(input, result, strict);
775}
776
777template <>
778bool TryCast::Operation(double input, float &result, bool strict) {
779 return NumericTryCast::Operation<double, float>(input, result, strict);
780}
781
782template <>
783bool TryCast::Operation(double input, double &result, bool strict) {
784 return NumericTryCast::Operation<double, double>(input, result, strict);
785}
786
787//===--------------------------------------------------------------------===//
788// Cast String -> Numeric
789//===--------------------------------------------------------------------===//
790template <typename T>
791struct IntegerCastData {
792 using Result = T;
793 Result result;
794 bool seen_decimal;
795};
796
797struct IntegerCastOperation {
798 template <class T, bool NEGATIVE>
799 static bool HandleDigit(T &state, uint8_t digit) {
800 using result_t = typename T::Result;
801 if (NEGATIVE) {
802 if (state.result < (NumericLimits<result_t>::Minimum() + digit) / 10) {
803 return false;
804 }
805 state.result = state.result * 10 - digit;
806 } else {
807 if (state.result > (NumericLimits<result_t>::Maximum() - digit) / 10) {
808 return false;
809 }
810 state.result = state.result * 10 + digit;
811 }
812 return true;
813 }
814
815 template <class T, bool NEGATIVE>
816 static bool HandleHexDigit(T &state, uint8_t digit) {
817 using result_t = typename T::Result;
818 if (state.result > (NumericLimits<result_t>::Maximum() - digit) / 16) {
819 return false;
820 }
821 state.result = state.result * 16 + digit;
822 return true;
823 }
824
825 template <class T, bool NEGATIVE>
826 static bool HandleBinaryDigit(T &state, uint8_t digit) {
827 using result_t = typename T::Result;
828 if (state.result > (NumericLimits<result_t>::Maximum() - digit) / 2) {
829 return false;
830 }
831 state.result = state.result * 2 + digit;
832 return true;
833 }
834
835 template <class T, bool NEGATIVE>
836 static bool HandleExponent(T &state, int32_t exponent) {
837 using result_t = typename T::Result;
838 double dbl_res = state.result * std::pow(x: 10.0L, y: exponent);
839 if (dbl_res < (double)NumericLimits<result_t>::Minimum() ||
840 dbl_res > (double)NumericLimits<result_t>::Maximum()) {
841 return false;
842 }
843 state.result = (result_t)std::nearbyint(x: dbl_res);
844 return true;
845 }
846
847 template <class T, bool NEGATIVE, bool ALLOW_EXPONENT>
848 static bool HandleDecimal(T &state, uint8_t digit) {
849 if (state.seen_decimal) {
850 return true;
851 }
852 state.seen_decimal = true;
853 // round the integer based on what is after the decimal point
854 // if digit >= 5, then we round up (or down in case of negative numbers)
855 auto increment = digit >= 5;
856 if (!increment) {
857 return true;
858 }
859 if (NEGATIVE) {
860 if (state.result == NumericLimits<typename T::Result>::Minimum()) {
861 return false;
862 }
863 state.result--;
864 } else {
865 if (state.result == NumericLimits<typename T::Result>::Maximum()) {
866 return false;
867 }
868 state.result++;
869 }
870 return true;
871 }
872
873 template <class T, bool NEGATIVE>
874 static bool Finalize(T &state) {
875 return true;
876 }
877};
878
879template <class T, bool NEGATIVE, bool ALLOW_EXPONENT, class OP = IntegerCastOperation, char decimal_separator = '.'>
880static bool IntegerCastLoop(const char *buf, idx_t len, T &result, bool strict) {
881 idx_t start_pos;
882 if (NEGATIVE) {
883 start_pos = 1;
884 } else {
885 if (*buf == '+') {
886 if (strict) {
887 // leading plus is not allowed in strict mode
888 return false;
889 }
890 start_pos = 1;
891 } else {
892 start_pos = 0;
893 }
894 }
895 idx_t pos = start_pos;
896 while (pos < len) {
897 if (!StringUtil::CharacterIsDigit(c: buf[pos])) {
898 // not a digit!
899 if (buf[pos] == decimal_separator) {
900 if (strict) {
901 return false;
902 }
903 bool number_before_period = pos > start_pos;
904 // decimal point: we accept decimal values for integers as well
905 // we just truncate them
906 // make sure everything after the period is a number
907 pos++;
908 idx_t start_digit = pos;
909 while (pos < len) {
910 if (!StringUtil::CharacterIsDigit(c: buf[pos])) {
911 break;
912 }
913 if (!OP::template HandleDecimal<T, NEGATIVE, ALLOW_EXPONENT>(result, buf[pos] - '0')) {
914 return false;
915 }
916 pos++;
917 }
918 // make sure there is either (1) one number after the period, or (2) one number before the period
919 // i.e. we accept "1." and ".1" as valid numbers, but not "."
920 if (!(number_before_period || pos > start_digit)) {
921 return false;
922 }
923 if (pos >= len) {
924 break;
925 }
926 }
927 if (StringUtil::CharacterIsSpace(c: buf[pos])) {
928 // skip any trailing spaces
929 while (++pos < len) {
930 if (!StringUtil::CharacterIsSpace(c: buf[pos])) {
931 return false;
932 }
933 }
934 break;
935 }
936 if (ALLOW_EXPONENT) {
937 if (buf[pos] == 'e' || buf[pos] == 'E') {
938 if (pos == start_pos) {
939 return false;
940 }
941 pos++;
942 if (pos >= len) {
943 return false;
944 }
945 using ExponentData = IntegerCastData<int32_t>;
946 ExponentData exponent {.result: 0, .seen_decimal: false};
947 int negative = buf[pos] == '-';
948 if (negative) {
949 if (!IntegerCastLoop<ExponentData, true, false, IntegerCastOperation, decimal_separator>(
950 buf + pos, len - pos, exponent, strict)) {
951 return false;
952 }
953 } else {
954 if (!IntegerCastLoop<ExponentData, false, false, IntegerCastOperation, decimal_separator>(
955 buf + pos, len - pos, exponent, strict)) {
956 return false;
957 }
958 }
959 return OP::template HandleExponent<T, NEGATIVE>(result, exponent.result);
960 }
961 }
962 return false;
963 }
964 uint8_t digit = buf[pos++] - '0';
965 if (!OP::template HandleDigit<T, NEGATIVE>(result, digit)) {
966 return false;
967 }
968 }
969 if (!OP::template Finalize<T, NEGATIVE>(result)) {
970 return false;
971 }
972 return pos > start_pos;
973}
974
975template <class T, bool NEGATIVE, bool ALLOW_EXPONENT, class OP = IntegerCastOperation>
976static bool IntegerHexCastLoop(const char *buf, idx_t len, T &result, bool strict) {
977 if (ALLOW_EXPONENT || NEGATIVE) {
978 return false;
979 }
980 idx_t start_pos = 1;
981 idx_t pos = start_pos;
982 char current_char;
983 while (pos < len) {
984 current_char = StringUtil::CharacterToLower(c: buf[pos]);
985 if (!StringUtil::CharacterIsHex(c: current_char)) {
986 return false;
987 }
988 uint8_t digit;
989 if (current_char >= 'a') {
990 digit = current_char - 'a' + 10;
991 } else {
992 digit = current_char - '0';
993 }
994 pos++;
995 if (!OP::template HandleHexDigit<T, NEGATIVE>(result, digit)) {
996 return false;
997 }
998 }
999 if (!OP::template Finalize<T, NEGATIVE>(result)) {
1000 return false;
1001 }
1002 return pos > start_pos;
1003}
1004
1005template <class T, bool NEGATIVE, bool ALLOW_EXPONENT, class OP = IntegerCastOperation>
1006static bool IntegerBinaryCastLoop(const char *buf, idx_t len, T &result, bool strict) {
1007 if (ALLOW_EXPONENT || NEGATIVE) {
1008 return false;
1009 }
1010 idx_t start_pos = 1;
1011 idx_t pos = start_pos;
1012 uint8_t digit;
1013 char current_char;
1014 while (pos < len) {
1015 current_char = buf[pos];
1016 if (current_char == '_' && pos > start_pos) {
1017 // skip underscore, if it is not the first character
1018 pos++;
1019 if (pos == len) {
1020 // we cant end on an underscore either
1021 return false;
1022 }
1023 continue;
1024 } else if (current_char == '0') {
1025 digit = 0;
1026 } else if (current_char == '1') {
1027 digit = 1;
1028 } else {
1029 return false;
1030 }
1031 pos++;
1032 if (!OP::template HandleBinaryDigit<T, NEGATIVE>(result, digit)) {
1033 return false;
1034 }
1035 }
1036 if (!OP::template Finalize<T, NEGATIVE>(result)) {
1037 return false;
1038 }
1039 return pos > start_pos;
1040}
1041
1042template <class T, bool IS_SIGNED = true, bool ALLOW_EXPONENT = true, class OP = IntegerCastOperation,
1043 bool ZERO_INITIALIZE = true, char decimal_separator = '.'>
1044static bool TryIntegerCast(const char *buf, idx_t len, T &result, bool strict) {
1045 // skip any spaces at the start
1046 while (len > 0 && StringUtil::CharacterIsSpace(c: *buf)) {
1047 buf++;
1048 len--;
1049 }
1050 if (len == 0) {
1051 return false;
1052 }
1053 if (ZERO_INITIALIZE) {
1054 memset(&result, 0, sizeof(T));
1055 }
1056 // if the number is negative, we set the negative flag and skip the negative sign
1057 if (*buf == '-') {
1058 if (!IS_SIGNED) {
1059 // Need to check if its not -0
1060 idx_t pos = 1;
1061 while (pos < len) {
1062 if (buf[pos++] != '0') {
1063 return false;
1064 }
1065 }
1066 }
1067 return IntegerCastLoop<T, true, ALLOW_EXPONENT, OP, decimal_separator>(buf, len, result, strict);
1068 }
1069 if (len > 1 && *buf == '0') {
1070 if (buf[1] == 'x' || buf[1] == 'X') {
1071 // If it starts with 0x or 0X, we parse it as a hex value
1072 buf++;
1073 len--;
1074 return IntegerHexCastLoop<T, false, false, OP>(buf, len, result, strict);
1075 } else if (buf[1] == 'b' || buf[1] == 'B') {
1076 // If it starts with 0b or 0B, we parse it as a binary value
1077 buf++;
1078 len--;
1079 return IntegerBinaryCastLoop<T, false, false, OP>(buf, len, result, strict);
1080 } else if (strict && StringUtil::CharacterIsDigit(c: buf[1])) {
1081 // leading zeros are not allowed in strict mode
1082 return false;
1083 }
1084 }
1085 return IntegerCastLoop<T, false, ALLOW_EXPONENT, OP, decimal_separator>(buf, len, result, strict);
1086}
1087
1088template <typename T, bool IS_SIGNED = true>
1089static inline bool TrySimpleIntegerCast(const char *buf, idx_t len, T &result, bool strict) {
1090 IntegerCastData<T> data;
1091 if (TryIntegerCast<IntegerCastData<T>, IS_SIGNED>(buf, len, data, strict)) {
1092 result = data.result;
1093 return true;
1094 }
1095 return false;
1096}
1097
1098template <>
1099bool TryCast::Operation(string_t input, bool &result, bool strict) {
1100 auto input_data = input.GetData();
1101 auto input_size = input.GetSize();
1102
1103 switch (input_size) {
1104 case 1: {
1105 char c = std::tolower(c: *input_data);
1106 if (c == 't' || (!strict && c == '1')) {
1107 result = true;
1108 return true;
1109 } else if (c == 'f' || (!strict && c == '0')) {
1110 result = false;
1111 return true;
1112 }
1113 return false;
1114 }
1115 case 4: {
1116 char t = std::tolower(c: input_data[0]);
1117 char r = std::tolower(c: input_data[1]);
1118 char u = std::tolower(c: input_data[2]);
1119 char e = std::tolower(c: input_data[3]);
1120 if (t == 't' && r == 'r' && u == 'u' && e == 'e') {
1121 result = true;
1122 return true;
1123 }
1124 return false;
1125 }
1126 case 5: {
1127 char f = std::tolower(c: input_data[0]);
1128 char a = std::tolower(c: input_data[1]);
1129 char l = std::tolower(c: input_data[2]);
1130 char s = std::tolower(c: input_data[3]);
1131 char e = std::tolower(c: input_data[4]);
1132 if (f == 'f' && a == 'a' && l == 'l' && s == 's' && e == 'e') {
1133 result = false;
1134 return true;
1135 }
1136 return false;
1137 }
1138 default:
1139 return false;
1140 }
1141}
1142template <>
1143bool TryCast::Operation(string_t input, int8_t &result, bool strict) {
1144 return TrySimpleIntegerCast<int8_t>(buf: input.GetData(), len: input.GetSize(), result, strict);
1145}
1146template <>
1147bool TryCast::Operation(string_t input, int16_t &result, bool strict) {
1148 return TrySimpleIntegerCast<int16_t>(buf: input.GetData(), len: input.GetSize(), result, strict);
1149}
1150template <>
1151bool TryCast::Operation(string_t input, int32_t &result, bool strict) {
1152 return TrySimpleIntegerCast<int32_t>(buf: input.GetData(), len: input.GetSize(), result, strict);
1153}
1154template <>
1155bool TryCast::Operation(string_t input, int64_t &result, bool strict) {
1156 return TrySimpleIntegerCast<int64_t>(buf: input.GetData(), len: input.GetSize(), result, strict);
1157}
1158
1159template <>
1160bool TryCast::Operation(string_t input, uint8_t &result, bool strict) {
1161 return TrySimpleIntegerCast<uint8_t, false>(buf: input.GetData(), len: input.GetSize(), result, strict);
1162}
1163template <>
1164bool TryCast::Operation(string_t input, uint16_t &result, bool strict) {
1165 return TrySimpleIntegerCast<uint16_t, false>(buf: input.GetData(), len: input.GetSize(), result, strict);
1166}
1167template <>
1168bool TryCast::Operation(string_t input, uint32_t &result, bool strict) {
1169 return TrySimpleIntegerCast<uint32_t, false>(buf: input.GetData(), len: input.GetSize(), result, strict);
1170}
1171template <>
1172bool TryCast::Operation(string_t input, uint64_t &result, bool strict) {
1173 return TrySimpleIntegerCast<uint64_t, false>(buf: input.GetData(), len: input.GetSize(), result, strict);
1174}
1175
1176template <class T, char decimal_separator = '.'>
1177static bool TryDoubleCast(const char *buf, idx_t len, T &result, bool strict) {
1178 // skip any spaces at the start
1179 while (len > 0 && StringUtil::CharacterIsSpace(c: *buf)) {
1180 buf++;
1181 len--;
1182 }
1183 if (len == 0) {
1184 return false;
1185 }
1186 if (*buf == '+') {
1187 if (strict) {
1188 // plus is not allowed in strict mode
1189 return false;
1190 }
1191 buf++;
1192 len--;
1193 }
1194 if (strict && len >= 2) {
1195 if (buf[0] == '0' && StringUtil::CharacterIsDigit(c: buf[1])) {
1196 // leading zeros are not allowed in strict mode
1197 return false;
1198 }
1199 }
1200 auto endptr = buf + len;
1201 auto parse_result = duckdb_fast_float::from_chars(buf, buf + len, result, decimal_separator);
1202 if (parse_result.ec != std::errc()) {
1203 return false;
1204 }
1205 auto current_end = parse_result.ptr;
1206 if (!strict) {
1207 while (current_end < endptr && StringUtil::CharacterIsSpace(c: *current_end)) {
1208 current_end++;
1209 }
1210 }
1211 return current_end == endptr;
1212}
1213
1214template <>
1215bool TryCast::Operation(string_t input, float &result, bool strict) {
1216 return TryDoubleCast<float>(buf: input.GetData(), len: input.GetSize(), result, strict);
1217}
1218
1219template <>
1220bool TryCast::Operation(string_t input, double &result, bool strict) {
1221 return TryDoubleCast<double>(buf: input.GetData(), len: input.GetSize(), result, strict);
1222}
1223
1224template <>
1225bool TryCastErrorMessageCommaSeparated::Operation(string_t input, float &result, string *error_message, bool strict) {
1226 if (!TryDoubleCast<float, ','>(buf: input.GetData(), len: input.GetSize(), result, strict)) {
1227 HandleCastError::AssignError(error_message: StringUtil::Format(fmt_str: "Could not cast string to float: \"%s\"", params: input.GetString()),
1228 error_message_ptr: error_message);
1229 return false;
1230 }
1231 return true;
1232}
1233
1234template <>
1235bool TryCastErrorMessageCommaSeparated::Operation(string_t input, double &result, string *error_message, bool strict) {
1236 if (!TryDoubleCast<double, ','>(buf: input.GetData(), len: input.GetSize(), result, strict)) {
1237 HandleCastError::AssignError(error_message: StringUtil::Format(fmt_str: "Could not cast string to double: \"%s\"", params: input.GetString()),
1238 error_message_ptr: error_message);
1239 return false;
1240 }
1241 return true;
1242}
1243
1244//===--------------------------------------------------------------------===//
1245// Cast From Date
1246//===--------------------------------------------------------------------===//
1247template <>
1248bool TryCast::Operation(date_t input, date_t &result, bool strict) {
1249 result = input;
1250 return true;
1251}
1252
1253template <>
1254bool TryCast::Operation(date_t input, timestamp_t &result, bool strict) {
1255 if (input == date_t::infinity()) {
1256 result = timestamp_t::infinity();
1257 return true;
1258 } else if (input == date_t::ninfinity()) {
1259 result = timestamp_t::ninfinity();
1260 return true;
1261 }
1262 return Timestamp::TryFromDatetime(date: input, time: Time::FromTime(hour: 0, minute: 0, second: 0), result);
1263}
1264
1265//===--------------------------------------------------------------------===//
1266// Cast From Time
1267//===--------------------------------------------------------------------===//
1268template <>
1269bool TryCast::Operation(dtime_t input, dtime_t &result, bool strict) {
1270 result = input;
1271 return true;
1272}
1273
1274//===--------------------------------------------------------------------===//
1275// Cast From Timestamps
1276//===--------------------------------------------------------------------===//
1277template <>
1278bool TryCast::Operation(timestamp_t input, date_t &result, bool strict) {
1279 result = Timestamp::GetDate(timestamp: input);
1280 return true;
1281}
1282
1283template <>
1284bool TryCast::Operation(timestamp_t input, dtime_t &result, bool strict) {
1285 if (!Timestamp::IsFinite(timestamp: input)) {
1286 return false;
1287 }
1288 result = Timestamp::GetTime(timestamp: input);
1289 return true;
1290}
1291
1292template <>
1293bool TryCast::Operation(timestamp_t input, timestamp_t &result, bool strict) {
1294 result = input;
1295 return true;
1296}
1297
1298//===--------------------------------------------------------------------===//
1299// Cast from Interval
1300//===--------------------------------------------------------------------===//
1301template <>
1302bool TryCast::Operation(interval_t input, interval_t &result, bool strict) {
1303 result = input;
1304 return true;
1305}
1306
1307//===--------------------------------------------------------------------===//
1308// Non-Standard Timestamps
1309//===--------------------------------------------------------------------===//
1310template <>
1311duckdb::string_t CastFromTimestampNS::Operation(duckdb::timestamp_t input, Vector &result) {
1312 return StringCast::Operation<timestamp_t>(input: Timestamp::FromEpochNanoSeconds(micros: input.value), result);
1313}
1314template <>
1315duckdb::string_t CastFromTimestampMS::Operation(duckdb::timestamp_t input, Vector &result) {
1316 return StringCast::Operation<timestamp_t>(input: Timestamp::FromEpochMs(ms: input.value), result);
1317}
1318template <>
1319duckdb::string_t CastFromTimestampSec::Operation(duckdb::timestamp_t input, Vector &result) {
1320 return StringCast::Operation<timestamp_t>(input: Timestamp::FromEpochSeconds(ms: input.value), result);
1321}
1322
1323template <>
1324timestamp_t CastTimestampUsToMs::Operation(timestamp_t input) {
1325 timestamp_t cast_timestamp(Timestamp::GetEpochMs(timestamp: input));
1326 return cast_timestamp;
1327}
1328
1329template <>
1330timestamp_t CastTimestampUsToNs::Operation(timestamp_t input) {
1331 timestamp_t cast_timestamp(Timestamp::GetEpochNanoSeconds(timestamp: input));
1332 return cast_timestamp;
1333}
1334
1335template <>
1336timestamp_t CastTimestampUsToSec::Operation(timestamp_t input) {
1337 timestamp_t cast_timestamp(Timestamp::GetEpochSeconds(timestamp: input));
1338 return cast_timestamp;
1339}
1340template <>
1341timestamp_t CastTimestampMsToUs::Operation(timestamp_t input) {
1342 return Timestamp::FromEpochMs(ms: input.value);
1343}
1344
1345template <>
1346timestamp_t CastTimestampNsToUs::Operation(timestamp_t input) {
1347 return Timestamp::FromEpochNanoSeconds(micros: input.value);
1348}
1349
1350template <>
1351timestamp_t CastTimestampSecToUs::Operation(timestamp_t input) {
1352 return Timestamp::FromEpochSeconds(ms: input.value);
1353}
1354
1355//===--------------------------------------------------------------------===//
1356// Cast To Timestamp
1357//===--------------------------------------------------------------------===//
1358template <>
1359bool TryCastToTimestampNS::Operation(string_t input, timestamp_t &result, bool strict) {
1360 if (!TryCast::Operation<string_t, timestamp_t>(input, result, strict)) {
1361 return false;
1362 }
1363 result = Timestamp::GetEpochNanoSeconds(timestamp: result);
1364 return true;
1365}
1366
1367template <>
1368bool TryCastToTimestampMS::Operation(string_t input, timestamp_t &result, bool strict) {
1369 if (!TryCast::Operation<string_t, timestamp_t>(input, result, strict)) {
1370 return false;
1371 }
1372 result = Timestamp::GetEpochMs(timestamp: result);
1373 return true;
1374}
1375
1376template <>
1377bool TryCastToTimestampSec::Operation(string_t input, timestamp_t &result, bool strict) {
1378 if (!TryCast::Operation<string_t, timestamp_t>(input, result, strict)) {
1379 return false;
1380 }
1381 result = Timestamp::GetEpochSeconds(timestamp: result);
1382 return true;
1383}
1384
1385template <>
1386bool TryCastToTimestampNS::Operation(date_t input, timestamp_t &result, bool strict) {
1387 if (!TryCast::Operation<date_t, timestamp_t>(input, result, strict)) {
1388 return false;
1389 }
1390 if (!TryMultiplyOperator::Operation(left: result.value, right: Interval::NANOS_PER_MICRO, result&: result.value)) {
1391 return false;
1392 }
1393 return true;
1394}
1395
1396template <>
1397bool TryCastToTimestampMS::Operation(date_t input, timestamp_t &result, bool strict) {
1398 if (!TryCast::Operation<date_t, timestamp_t>(input, result, strict)) {
1399 return false;
1400 }
1401 result.value /= Interval::MICROS_PER_MSEC;
1402 return true;
1403}
1404
1405template <>
1406bool TryCastToTimestampSec::Operation(date_t input, timestamp_t &result, bool strict) {
1407 if (!TryCast::Operation<date_t, timestamp_t>(input, result, strict)) {
1408 return false;
1409 }
1410 result.value /= Interval::MICROS_PER_MSEC * Interval::MSECS_PER_SEC;
1411 return true;
1412}
1413
1414//===--------------------------------------------------------------------===//
1415// Cast From Blob
1416//===--------------------------------------------------------------------===//
1417template <>
1418string_t CastFromBlob::Operation(string_t input, Vector &vector) {
1419 idx_t result_size = Blob::GetStringSize(blob: input);
1420
1421 string_t result = StringVector::EmptyString(vector, len: result_size);
1422 Blob::ToString(blob: input, output: result.GetDataWriteable());
1423 result.Finalize();
1424
1425 return result;
1426}
1427
1428//===--------------------------------------------------------------------===//
1429// Cast From Bit
1430//===--------------------------------------------------------------------===//
1431template <>
1432string_t CastFromBit::Operation(string_t input, Vector &vector) {
1433
1434 idx_t result_size = Bit::BitLength(bits: input);
1435 string_t result = StringVector::EmptyString(vector, len: result_size);
1436 Bit::ToString(bits: input, output: result.GetDataWriteable());
1437 result.Finalize();
1438
1439 return result;
1440}
1441
1442//===--------------------------------------------------------------------===//
1443// Cast From Pointer
1444//===--------------------------------------------------------------------===//
1445template <>
1446string_t CastFromPointer::Operation(uintptr_t input, Vector &vector) {
1447 std::string s = duckdb_fmt::format(format_str: "0x{:x}", args&: input);
1448 return StringVector::AddString(vector, data: s);
1449}
1450
1451//===--------------------------------------------------------------------===//
1452// Cast To Blob
1453//===--------------------------------------------------------------------===//
1454template <>
1455bool TryCastToBlob::Operation(string_t input, string_t &result, Vector &result_vector, string *error_message,
1456 bool strict) {
1457 idx_t result_size;
1458 if (!Blob::TryGetBlobSize(str: input, result_size, error_message)) {
1459 return false;
1460 }
1461
1462 result = StringVector::EmptyString(vector&: result_vector, len: result_size);
1463 Blob::ToBlob(str: input, output: data_ptr_cast(src: result.GetDataWriteable()));
1464 result.Finalize();
1465 return true;
1466}
1467
1468//===--------------------------------------------------------------------===//
1469// Cast To Bit
1470//===--------------------------------------------------------------------===//
1471template <>
1472bool TryCastToBit::Operation(string_t input, string_t &result, Vector &result_vector, string *error_message,
1473 bool strict) {
1474 idx_t result_size;
1475 if (!Bit::TryGetBitStringSize(str: input, result_size, error_message)) {
1476 return false;
1477 }
1478
1479 result = StringVector::EmptyString(vector&: result_vector, len: result_size);
1480 Bit::ToBit(str: input, output&: result);
1481 result.Finalize();
1482 return true;
1483}
1484
1485//===--------------------------------------------------------------------===//
1486// Cast From UUID
1487//===--------------------------------------------------------------------===//
1488template <>
1489string_t CastFromUUID::Operation(hugeint_t input, Vector &vector) {
1490 string_t result = StringVector::EmptyString(vector, len: 36);
1491 UUID::ToString(input, buf: result.GetDataWriteable());
1492 result.Finalize();
1493 return result;
1494}
1495
1496//===--------------------------------------------------------------------===//
1497// Cast To UUID
1498//===--------------------------------------------------------------------===//
1499template <>
1500bool TryCastToUUID::Operation(string_t input, hugeint_t &result, Vector &result_vector, string *error_message,
1501 bool strict) {
1502 return UUID::FromString(str: input.GetString(), result);
1503}
1504
1505//===--------------------------------------------------------------------===//
1506// Cast To Date
1507//===--------------------------------------------------------------------===//
1508template <>
1509bool TryCastErrorMessage::Operation(string_t input, date_t &result, string *error_message, bool strict) {
1510 if (!TryCast::Operation<string_t, date_t>(input, result, strict)) {
1511 HandleCastError::AssignError(error_message: Date::ConversionError(str: input), error_message_ptr: error_message);
1512 return false;
1513 }
1514 return true;
1515}
1516
1517template <>
1518bool TryCast::Operation(string_t input, date_t &result, bool strict) {
1519 idx_t pos;
1520 bool special = false;
1521 return Date::TryConvertDate(buf: input.GetData(), len: input.GetSize(), pos, result, special, strict);
1522}
1523
1524template <>
1525date_t Cast::Operation(string_t input) {
1526 return Date::FromCString(str: input.GetData(), len: input.GetSize());
1527}
1528
1529//===--------------------------------------------------------------------===//
1530// Cast To Time
1531//===--------------------------------------------------------------------===//
1532template <>
1533bool TryCastErrorMessage::Operation(string_t input, dtime_t &result, string *error_message, bool strict) {
1534 if (!TryCast::Operation<string_t, dtime_t>(input, result, strict)) {
1535 HandleCastError::AssignError(error_message: Time::ConversionError(str: input), error_message_ptr: error_message);
1536 return false;
1537 }
1538 return true;
1539}
1540
1541template <>
1542bool TryCast::Operation(string_t input, dtime_t &result, bool strict) {
1543 idx_t pos;
1544 return Time::TryConvertTime(buf: input.GetData(), len: input.GetSize(), pos, result, strict);
1545}
1546
1547template <>
1548dtime_t Cast::Operation(string_t input) {
1549 return Time::FromCString(buf: input.GetData(), len: input.GetSize());
1550}
1551
1552//===--------------------------------------------------------------------===//
1553// Cast To Timestamp
1554//===--------------------------------------------------------------------===//
1555template <>
1556bool TryCastErrorMessage::Operation(string_t input, timestamp_t &result, string *error_message, bool strict) {
1557 auto cast_result = Timestamp::TryConvertTimestamp(str: input.GetData(), len: input.GetSize(), result);
1558 if (cast_result == TimestampCastResult::SUCCESS) {
1559 return true;
1560 }
1561 if (cast_result == TimestampCastResult::ERROR_INCORRECT_FORMAT) {
1562 HandleCastError::AssignError(error_message: Timestamp::ConversionError(str: input), error_message_ptr: error_message);
1563 } else {
1564 HandleCastError::AssignError(error_message: Timestamp::UnsupportedTimezoneError(str: input), error_message_ptr: error_message);
1565 }
1566 return false;
1567}
1568
1569template <>
1570bool TryCast::Operation(string_t input, timestamp_t &result, bool strict) {
1571 return Timestamp::TryConvertTimestamp(str: input.GetData(), len: input.GetSize(), result) == TimestampCastResult::SUCCESS;
1572}
1573
1574template <>
1575timestamp_t Cast::Operation(string_t input) {
1576 return Timestamp::FromCString(str: input.GetData(), len: input.GetSize());
1577}
1578
1579//===--------------------------------------------------------------------===//
1580// Cast From Interval
1581//===--------------------------------------------------------------------===//
1582template <>
1583bool TryCastErrorMessage::Operation(string_t input, interval_t &result, string *error_message, bool strict) {
1584 return Interval::FromCString(str: input.GetData(), len: input.GetSize(), result, error_message, strict);
1585}
1586
1587//===--------------------------------------------------------------------===//
1588// Cast From Hugeint
1589//===--------------------------------------------------------------------===//
1590// parsing hugeint from string is done a bit differently for performance reasons
1591// for other integer types we keep track of a single value
1592// and multiply that value by 10 for every digit we read
1593// however, for hugeints, multiplication is very expensive (>20X as expensive as for int64)
1594// for that reason, we parse numbers first into an int64 value
1595// when that value is full, we perform a HUGEINT multiplication to flush it into the hugeint
1596// this takes the number of HUGEINT multiplications down from [0-38] to [0-2]
1597struct HugeIntCastData {
1598 hugeint_t hugeint;
1599 int64_t intermediate;
1600 uint8_t digits;
1601 bool decimal;
1602
1603 bool Flush() {
1604 if (digits == 0 && intermediate == 0) {
1605 return true;
1606 }
1607 if (hugeint.lower != 0 || hugeint.upper != 0) {
1608 if (digits > 38) {
1609 return false;
1610 }
1611 if (!Hugeint::TryMultiply(lhs: hugeint, rhs: Hugeint::POWERS_OF_TEN[digits], result&: hugeint)) {
1612 return false;
1613 }
1614 }
1615 if (!Hugeint::AddInPlace(lhs&: hugeint, rhs: hugeint_t(intermediate))) {
1616 return false;
1617 }
1618 digits = 0;
1619 intermediate = 0;
1620 return true;
1621 }
1622};
1623
1624struct HugeIntegerCastOperation {
1625 template <class T, bool NEGATIVE>
1626 static bool HandleDigit(T &result, uint8_t digit) {
1627 if (NEGATIVE) {
1628 if (result.intermediate < (NumericLimits<int64_t>::Minimum() + digit) / 10) {
1629 // intermediate is full: need to flush it
1630 if (!result.Flush()) {
1631 return false;
1632 }
1633 }
1634 result.intermediate = result.intermediate * 10 - digit;
1635 } else {
1636 if (result.intermediate > (NumericLimits<int64_t>::Maximum() - digit) / 10) {
1637 if (!result.Flush()) {
1638 return false;
1639 }
1640 }
1641 result.intermediate = result.intermediate * 10 + digit;
1642 }
1643 result.digits++;
1644 return true;
1645 }
1646
1647 template <class T, bool NEGATIVE>
1648 static bool HandleHexDigit(T &result, uint8_t digit) {
1649 return false;
1650 }
1651
1652 template <class T, bool NEGATIVE>
1653 static bool HandleBinaryDigit(T &result, uint8_t digit) {
1654 if (result.intermediate > (NumericLimits<int64_t>::Maximum() - digit) / 2) {
1655 // intermediate is full: need to flush it
1656 if (!result.Flush()) {
1657 return false;
1658 }
1659 }
1660 result.intermediate = result.intermediate * 2 + digit;
1661 result.digits++;
1662 return true;
1663 }
1664
1665 template <class T, bool NEGATIVE>
1666 static bool HandleExponent(T &result, int32_t exponent) {
1667 if (!result.Flush()) {
1668 return false;
1669 }
1670 if (exponent < -38 || exponent > 38) {
1671 // out of range for exact exponent: use double and convert
1672 double dbl_res = Hugeint::Cast<double>(result.hugeint) * std::pow(x: 10.0L, y: exponent);
1673 if (dbl_res < Hugeint::Cast<double>(input: NumericLimits<hugeint_t>::Minimum()) ||
1674 dbl_res > Hugeint::Cast<double>(input: NumericLimits<hugeint_t>::Maximum())) {
1675 return false;
1676 }
1677 result.hugeint = Hugeint::Convert(value: dbl_res);
1678 return true;
1679 }
1680 if (exponent < 0) {
1681 // negative exponent: divide by power of 10
1682 result.hugeint = Hugeint::Divide(lhs: result.hugeint, rhs: Hugeint::POWERS_OF_TEN[-exponent]);
1683 return true;
1684 } else {
1685 // positive exponent: multiply by power of 10
1686 return Hugeint::TryMultiply(lhs: result.hugeint, rhs: Hugeint::POWERS_OF_TEN[exponent], result&: result.hugeint);
1687 }
1688 }
1689
1690 template <class T, bool NEGATIVE, bool ALLOW_EXPONENT>
1691 static bool HandleDecimal(T &result, uint8_t digit) {
1692 // Integer casts round
1693 if (!result.decimal) {
1694 if (!result.Flush()) {
1695 return false;
1696 }
1697 if (NEGATIVE) {
1698 result.intermediate = -(digit >= 5);
1699 } else {
1700 result.intermediate = (digit >= 5);
1701 }
1702 }
1703 result.decimal = true;
1704
1705 return true;
1706 }
1707
1708 template <class T, bool NEGATIVE>
1709 static bool Finalize(T &result) {
1710 return result.Flush();
1711 }
1712};
1713
1714template <>
1715bool TryCast::Operation(string_t input, hugeint_t &result, bool strict) {
1716 HugeIntCastData data;
1717 if (!TryIntegerCast<HugeIntCastData, true, true, HugeIntegerCastOperation>(buf: input.GetData(), len: input.GetSize(), result&: data,
1718 strict)) {
1719 return false;
1720 }
1721 result = data.hugeint;
1722 return true;
1723}
1724
1725//===--------------------------------------------------------------------===//
1726// Decimal String Cast
1727//===--------------------------------------------------------------------===//
1728
1729template <class TYPE>
1730struct DecimalCastData {
1731 typedef TYPE type_t;
1732 TYPE result;
1733 uint8_t width;
1734 uint8_t scale;
1735 uint8_t digit_count;
1736 uint8_t decimal_count;
1737 //! Whether we have determined if the result should be rounded
1738 bool round_set;
1739 //! If the result should be rounded
1740 bool should_round;
1741 //! Only set when ALLOW_EXPONENT is enabled
1742 enum class ExponentType : uint8_t { NONE, POSITIVE, NEGATIVE };
1743 uint8_t excessive_decimals;
1744 ExponentType exponent_type;
1745};
1746
1747struct DecimalCastOperation {
1748 template <class T, bool NEGATIVE>
1749 static bool HandleDigit(T &state, uint8_t digit) {
1750 if (state.result == 0 && digit == 0) {
1751 // leading zero's don't count towards the digit count
1752 return true;
1753 }
1754 if (state.digit_count == state.width - state.scale) {
1755 // width of decimal type is exceeded!
1756 return false;
1757 }
1758 state.digit_count++;
1759 if (NEGATIVE) {
1760 if (state.result < (NumericLimits<typename T::type_t>::Minimum() / 10)) {
1761 return false;
1762 }
1763 state.result = state.result * 10 - digit;
1764 } else {
1765 if (state.result > (NumericLimits<typename T::type_t>::Maximum() / 10)) {
1766 return false;
1767 }
1768 state.result = state.result * 10 + digit;
1769 }
1770 return true;
1771 }
1772
1773 template <class T, bool NEGATIVE>
1774 static bool HandleHexDigit(T &state, uint8_t digit) {
1775 return false;
1776 }
1777
1778 template <class T, bool NEGATIVE>
1779 static bool HandleBinaryDigit(T &state, uint8_t digit) {
1780 return false;
1781 }
1782
1783 template <class T, bool NEGATIVE>
1784 static void RoundUpResult(T &state) {
1785 if (NEGATIVE) {
1786 state.result -= 1;
1787 } else {
1788 state.result += 1;
1789 }
1790 }
1791
1792 template <class T, bool NEGATIVE>
1793 static bool HandleExponent(T &state, int32_t exponent) {
1794 auto decimal_excess = (state.decimal_count > state.scale) ? state.decimal_count - state.scale : 0;
1795 if (exponent > 0) {
1796 state.exponent_type = T::ExponentType::POSITIVE;
1797 // Positive exponents need up to 'exponent' amount of digits
1798 // Everything beyond that amount needs to be truncated
1799 if (decimal_excess > exponent) {
1800 // We've allowed too many decimals
1801 state.excessive_decimals = decimal_excess - exponent;
1802 exponent = 0;
1803 } else {
1804 exponent -= decimal_excess;
1805 }
1806 D_ASSERT(exponent >= 0);
1807 } else if (exponent < 0) {
1808 state.exponent_type = T::ExponentType::NEGATIVE;
1809 }
1810 if (!Finalize<T, NEGATIVE>(state)) {
1811 return false;
1812 }
1813 if (exponent < 0) {
1814 bool round_up = false;
1815 for (idx_t i = 0; i < idx_t(-int64_t(exponent)); i++) {
1816 auto mod = state.result % 10;
1817 round_up = NEGATIVE ? mod <= -5 : mod >= 5;
1818 state.result /= 10;
1819 if (state.result == 0) {
1820 break;
1821 }
1822 }
1823 if (round_up) {
1824 RoundUpResult<T, NEGATIVE>(state);
1825 }
1826 return true;
1827 } else {
1828 // positive exponent: append 0's
1829 for (idx_t i = 0; i < idx_t(exponent); i++) {
1830 if (!HandleDigit<T, NEGATIVE>(state, 0)) {
1831 return false;
1832 }
1833 }
1834 return true;
1835 }
1836 }
1837
1838 template <class T, bool NEGATIVE, bool ALLOW_EXPONENT>
1839 static bool HandleDecimal(T &state, uint8_t digit) {
1840 if (state.decimal_count == state.scale && !state.round_set) {
1841 // Determine whether the last registered decimal should be rounded or not
1842 state.round_set = true;
1843 state.should_round = digit >= 5;
1844 }
1845 if (!ALLOW_EXPONENT && state.decimal_count == state.scale) {
1846 // we exceeded the amount of supported decimals
1847 // however, we don't throw an error here
1848 // we just truncate the decimal
1849 return true;
1850 }
1851 //! If we expect an exponent, we need to preserve the decimals
1852 //! But we don't want to overflow, so we prevent overflowing the result with this check
1853 if (state.digit_count + state.decimal_count >= DecimalWidth<decltype(state.result)>::max) {
1854 return true;
1855 }
1856 state.decimal_count++;
1857 if (NEGATIVE) {
1858 state.result = state.result * 10 - digit;
1859 } else {
1860 state.result = state.result * 10 + digit;
1861 }
1862 return true;
1863 }
1864
1865 template <class T, bool NEGATIVE>
1866 static bool TruncateExcessiveDecimals(T &state) {
1867 D_ASSERT(state.excessive_decimals);
1868 bool round_up = false;
1869 for (idx_t i = 0; i < state.excessive_decimals; i++) {
1870 auto mod = state.result % 10;
1871 round_up = NEGATIVE ? mod <= -5 : mod >= 5;
1872 state.result /= 10.0;
1873 }
1874 //! Only round up when exponents are involved
1875 if (state.exponent_type == T::ExponentType::POSITIVE && round_up) {
1876 RoundUpResult<T, NEGATIVE>(state);
1877 }
1878 D_ASSERT(state.decimal_count > state.scale);
1879 state.decimal_count = state.scale;
1880 return true;
1881 }
1882
1883 template <class T, bool NEGATIVE>
1884 static bool Finalize(T &state) {
1885 if (state.exponent_type != T::ExponentType::POSITIVE && state.decimal_count > state.scale) {
1886 //! Did not encounter an exponent, but ALLOW_EXPONENT was on
1887 state.excessive_decimals = state.decimal_count - state.scale;
1888 }
1889 if (state.excessive_decimals && !TruncateExcessiveDecimals<T, NEGATIVE>(state)) {
1890 return false;
1891 }
1892 if (state.exponent_type == T::ExponentType::NONE && state.round_set && state.should_round) {
1893 RoundUpResult<T, NEGATIVE>(state);
1894 }
1895 // if we have not gotten exactly "scale" decimals, we need to multiply the result
1896 // e.g. if we have a string "1.0" that is cast to a DECIMAL(9,3), the value needs to be 1000
1897 // but we have only gotten the value "10" so far, so we multiply by 1000
1898 for (uint8_t i = state.decimal_count; i < state.scale; i++) {
1899 state.result *= 10;
1900 }
1901 return true;
1902 }
1903};
1904
1905template <class T, char decimal_separator = '.'>
1906bool TryDecimalStringCast(string_t input, T &result, string *error_message, uint8_t width, uint8_t scale) {
1907 DecimalCastData<T> state;
1908 state.result = 0;
1909 state.width = width;
1910 state.scale = scale;
1911 state.digit_count = 0;
1912 state.decimal_count = 0;
1913 state.excessive_decimals = 0;
1914 state.exponent_type = DecimalCastData<T>::ExponentType::NONE;
1915 state.round_set = false;
1916 state.should_round = false;
1917 if (!TryIntegerCast<DecimalCastData<T>, true, true, DecimalCastOperation, false, decimal_separator>(
1918 input.GetData(), input.GetSize(), state, false)) {
1919 string error = StringUtil::Format(fmt_str: "Could not convert string \"%s\" to DECIMAL(%d,%d)", params: input.GetString(),
1920 params: (int)width, params: (int)scale);
1921 HandleCastError::AssignError(error_message: error, error_message_ptr: error_message);
1922 return false;
1923 }
1924 result = state.result;
1925 return true;
1926}
1927
1928template <>
1929bool TryCastToDecimal::Operation(string_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
1930 return TryDecimalStringCast<int16_t>(input, result, error_message, width, scale);
1931}
1932
1933template <>
1934bool TryCastToDecimal::Operation(string_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
1935 return TryDecimalStringCast<int32_t>(input, result, error_message, width, scale);
1936}
1937
1938template <>
1939bool TryCastToDecimal::Operation(string_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
1940 return TryDecimalStringCast<int64_t>(input, result, error_message, width, scale);
1941}
1942
1943template <>
1944bool TryCastToDecimal::Operation(string_t input, hugeint_t &result, string *error_message, uint8_t width,
1945 uint8_t scale) {
1946 return TryDecimalStringCast<hugeint_t>(input, result, error_message, width, scale);
1947}
1948
1949template <>
1950bool TryCastToDecimalCommaSeparated::Operation(string_t input, int16_t &result, string *error_message, uint8_t width,
1951 uint8_t scale) {
1952 return TryDecimalStringCast<int16_t, ','>(input, result, error_message, width, scale);
1953}
1954
1955template <>
1956bool TryCastToDecimalCommaSeparated::Operation(string_t input, int32_t &result, string *error_message, uint8_t width,
1957 uint8_t scale) {
1958 return TryDecimalStringCast<int32_t, ','>(input, result, error_message, width, scale);
1959}
1960
1961template <>
1962bool TryCastToDecimalCommaSeparated::Operation(string_t input, int64_t &result, string *error_message, uint8_t width,
1963 uint8_t scale) {
1964 return TryDecimalStringCast<int64_t, ','>(input, result, error_message, width, scale);
1965}
1966
1967template <>
1968bool TryCastToDecimalCommaSeparated::Operation(string_t input, hugeint_t &result, string *error_message, uint8_t width,
1969 uint8_t scale) {
1970 return TryDecimalStringCast<hugeint_t, ','>(input, result, error_message, width, scale);
1971}
1972
1973template <>
1974string_t StringCastFromDecimal::Operation(int16_t input, uint8_t width, uint8_t scale, Vector &result) {
1975 return DecimalToString::Format<int16_t, uint16_t>(value: input, width, scale, vector&: result);
1976}
1977
1978template <>
1979string_t StringCastFromDecimal::Operation(int32_t input, uint8_t width, uint8_t scale, Vector &result) {
1980 return DecimalToString::Format<int32_t, uint32_t>(value: input, width, scale, vector&: result);
1981}
1982
1983template <>
1984string_t StringCastFromDecimal::Operation(int64_t input, uint8_t width, uint8_t scale, Vector &result) {
1985 return DecimalToString::Format<int64_t, uint64_t>(value: input, width, scale, vector&: result);
1986}
1987
1988template <>
1989string_t StringCastFromDecimal::Operation(hugeint_t input, uint8_t width, uint8_t scale, Vector &result) {
1990 return HugeintToStringCast::FormatDecimal(value: input, width, scale, vector&: result);
1991}
1992
1993//===--------------------------------------------------------------------===//
1994// Decimal Casts
1995//===--------------------------------------------------------------------===//
1996// Decimal <-> Bool
1997//===--------------------------------------------------------------------===//
1998template <class T, class OP = NumericHelper>
1999bool TryCastBoolToDecimal(bool input, T &result, string *error_message, uint8_t width, uint8_t scale) {
2000 if (width > scale) {
2001 result = input ? OP::POWERS_OF_TEN[scale] : 0;
2002 return true;
2003 } else {
2004 return TryCast::Operation<bool, T>(input, result);
2005 }
2006}
2007
2008template <>
2009bool TryCastToDecimal::Operation(bool input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2010 return TryCastBoolToDecimal<int16_t>(input, result, error_message, width, scale);
2011}
2012
2013template <>
2014bool TryCastToDecimal::Operation(bool input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2015 return TryCastBoolToDecimal<int32_t>(input, result, error_message, width, scale);
2016}
2017
2018template <>
2019bool TryCastToDecimal::Operation(bool input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2020 return TryCastBoolToDecimal<int64_t>(input, result, error_message, width, scale);
2021}
2022
2023template <>
2024bool TryCastToDecimal::Operation(bool input, hugeint_t &result, string *error_message, uint8_t width, uint8_t scale) {
2025 return TryCastBoolToDecimal<hugeint_t, Hugeint>(input, result, error_message, width, scale);
2026}
2027
2028template <>
2029bool TryCastFromDecimal::Operation(int16_t input, bool &result, string *error_message, uint8_t width, uint8_t scale) {
2030 return TryCast::Operation<int16_t, bool>(input, result);
2031}
2032
2033template <>
2034bool TryCastFromDecimal::Operation(int32_t input, bool &result, string *error_message, uint8_t width, uint8_t scale) {
2035 return TryCast::Operation<int32_t, bool>(input, result);
2036}
2037
2038template <>
2039bool TryCastFromDecimal::Operation(int64_t input, bool &result, string *error_message, uint8_t width, uint8_t scale) {
2040 return TryCast::Operation<int64_t, bool>(input, result);
2041}
2042
2043template <>
2044bool TryCastFromDecimal::Operation(hugeint_t input, bool &result, string *error_message, uint8_t width, uint8_t scale) {
2045 return TryCast::Operation<hugeint_t, bool>(input, result);
2046}
2047
2048//===--------------------------------------------------------------------===//
2049// Numeric -> Decimal Cast
2050//===--------------------------------------------------------------------===//
2051struct SignedToDecimalOperator {
2052 template <class SRC, class DST>
2053 static bool Operation(SRC input, DST max_width) {
2054 return int64_t(input) >= int64_t(max_width) || int64_t(input) <= int64_t(-max_width);
2055 }
2056};
2057
2058struct UnsignedToDecimalOperator {
2059 template <class SRC, class DST>
2060 static bool Operation(SRC input, DST max_width) {
2061 return uint64_t(input) >= uint64_t(max_width);
2062 }
2063};
2064
2065template <class SRC, class DST, class OP = SignedToDecimalOperator>
2066bool StandardNumericToDecimalCast(SRC input, DST &result, string *error_message, uint8_t width, uint8_t scale) {
2067 // check for overflow
2068 DST max_width = NumericHelper::POWERS_OF_TEN[width - scale];
2069 if (OP::template Operation<SRC, DST>(input, max_width)) {
2070 string error = StringUtil::Format("Could not cast value %d to DECIMAL(%d,%d)", input, width, scale);
2071 HandleCastError::AssignError(error_message: error, error_message_ptr: error_message);
2072 return false;
2073 }
2074 result = DST(input) * NumericHelper::POWERS_OF_TEN[scale];
2075 return true;
2076}
2077
2078template <class SRC>
2079bool NumericToHugeDecimalCast(SRC input, hugeint_t &result, string *error_message, uint8_t width, uint8_t scale) {
2080 // check for overflow
2081 hugeint_t max_width = Hugeint::POWERS_OF_TEN[width - scale];
2082 hugeint_t hinput = Hugeint::Convert(input);
2083 if (hinput >= max_width || hinput <= -max_width) {
2084 string error = StringUtil::Format(fmt_str: "Could not cast value %s to DECIMAL(%d,%d)", params: hinput.ToString(), params: width, params: scale);
2085 HandleCastError::AssignError(error_message: error, error_message_ptr: error_message);
2086 return false;
2087 }
2088 result = hinput * Hugeint::POWERS_OF_TEN[scale];
2089 return true;
2090}
2091
2092//===--------------------------------------------------------------------===//
2093// Cast int8_t -> Decimal
2094//===--------------------------------------------------------------------===//
2095template <>
2096bool TryCastToDecimal::Operation(int8_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2097 return StandardNumericToDecimalCast<int8_t, int16_t>(input, result, error_message, width, scale);
2098}
2099template <>
2100bool TryCastToDecimal::Operation(int8_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2101 return StandardNumericToDecimalCast<int8_t, int32_t>(input, result, error_message, width, scale);
2102}
2103template <>
2104bool TryCastToDecimal::Operation(int8_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2105 return StandardNumericToDecimalCast<int8_t, int64_t>(input, result, error_message, width, scale);
2106}
2107template <>
2108bool TryCastToDecimal::Operation(int8_t input, hugeint_t &result, string *error_message, uint8_t width, uint8_t scale) {
2109 return NumericToHugeDecimalCast<int8_t>(input, result, error_message, width, scale);
2110}
2111
2112//===--------------------------------------------------------------------===//
2113// Cast int16_t -> Decimal
2114//===--------------------------------------------------------------------===//
2115template <>
2116bool TryCastToDecimal::Operation(int16_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2117 return StandardNumericToDecimalCast<int16_t, int16_t>(input, result, error_message, width, scale);
2118}
2119template <>
2120bool TryCastToDecimal::Operation(int16_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2121 return StandardNumericToDecimalCast<int16_t, int32_t>(input, result, error_message, width, scale);
2122}
2123template <>
2124bool TryCastToDecimal::Operation(int16_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2125 return StandardNumericToDecimalCast<int16_t, int64_t>(input, result, error_message, width, scale);
2126}
2127template <>
2128bool TryCastToDecimal::Operation(int16_t input, hugeint_t &result, string *error_message, uint8_t width,
2129 uint8_t scale) {
2130 return NumericToHugeDecimalCast<int16_t>(input, result, error_message, width, scale);
2131}
2132
2133//===--------------------------------------------------------------------===//
2134// Cast int32_t -> Decimal
2135//===--------------------------------------------------------------------===//
2136template <>
2137bool TryCastToDecimal::Operation(int32_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2138 return StandardNumericToDecimalCast<int32_t, int16_t>(input, result, error_message, width, scale);
2139}
2140template <>
2141bool TryCastToDecimal::Operation(int32_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2142 return StandardNumericToDecimalCast<int32_t, int32_t>(input, result, error_message, width, scale);
2143}
2144template <>
2145bool TryCastToDecimal::Operation(int32_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2146 return StandardNumericToDecimalCast<int32_t, int64_t>(input, result, error_message, width, scale);
2147}
2148template <>
2149bool TryCastToDecimal::Operation(int32_t input, hugeint_t &result, string *error_message, uint8_t width,
2150 uint8_t scale) {
2151 return NumericToHugeDecimalCast<int32_t>(input, result, error_message, width, scale);
2152}
2153
2154//===--------------------------------------------------------------------===//
2155// Cast int64_t -> Decimal
2156//===--------------------------------------------------------------------===//
2157template <>
2158bool TryCastToDecimal::Operation(int64_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2159 return StandardNumericToDecimalCast<int64_t, int16_t>(input, result, error_message, width, scale);
2160}
2161template <>
2162bool TryCastToDecimal::Operation(int64_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2163 return StandardNumericToDecimalCast<int64_t, int32_t>(input, result, error_message, width, scale);
2164}
2165template <>
2166bool TryCastToDecimal::Operation(int64_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2167 return StandardNumericToDecimalCast<int64_t, int64_t>(input, result, error_message, width, scale);
2168}
2169template <>
2170bool TryCastToDecimal::Operation(int64_t input, hugeint_t &result, string *error_message, uint8_t width,
2171 uint8_t scale) {
2172 return NumericToHugeDecimalCast<int64_t>(input, result, error_message, width, scale);
2173}
2174
2175//===--------------------------------------------------------------------===//
2176// Cast uint8_t -> Decimal
2177//===--------------------------------------------------------------------===//
2178template <>
2179bool TryCastToDecimal::Operation(uint8_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2180 return StandardNumericToDecimalCast<uint8_t, int16_t, UnsignedToDecimalOperator>(input, result, error_message,
2181 width, scale);
2182}
2183template <>
2184bool TryCastToDecimal::Operation(uint8_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2185 return StandardNumericToDecimalCast<uint8_t, int32_t, UnsignedToDecimalOperator>(input, result, error_message,
2186 width, scale);
2187}
2188template <>
2189bool TryCastToDecimal::Operation(uint8_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2190 return StandardNumericToDecimalCast<uint8_t, int64_t, UnsignedToDecimalOperator>(input, result, error_message,
2191 width, scale);
2192}
2193template <>
2194bool TryCastToDecimal::Operation(uint8_t input, hugeint_t &result, string *error_message, uint8_t width,
2195 uint8_t scale) {
2196 return NumericToHugeDecimalCast<uint8_t>(input, result, error_message, width, scale);
2197}
2198
2199//===--------------------------------------------------------------------===//
2200// Cast uint16_t -> Decimal
2201//===--------------------------------------------------------------------===//
2202template <>
2203bool TryCastToDecimal::Operation(uint16_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2204 return StandardNumericToDecimalCast<uint16_t, int16_t, UnsignedToDecimalOperator>(input, result, error_message,
2205 width, scale);
2206}
2207template <>
2208bool TryCastToDecimal::Operation(uint16_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2209 return StandardNumericToDecimalCast<uint16_t, int32_t, UnsignedToDecimalOperator>(input, result, error_message,
2210 width, scale);
2211}
2212template <>
2213bool TryCastToDecimal::Operation(uint16_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2214 return StandardNumericToDecimalCast<uint16_t, int64_t, UnsignedToDecimalOperator>(input, result, error_message,
2215 width, scale);
2216}
2217template <>
2218bool TryCastToDecimal::Operation(uint16_t input, hugeint_t &result, string *error_message, uint8_t width,
2219 uint8_t scale) {
2220 return NumericToHugeDecimalCast<uint16_t>(input, result, error_message, width, scale);
2221}
2222
2223//===--------------------------------------------------------------------===//
2224// Cast uint32_t -> Decimal
2225//===--------------------------------------------------------------------===//
2226template <>
2227bool TryCastToDecimal::Operation(uint32_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2228 return StandardNumericToDecimalCast<uint32_t, int16_t, UnsignedToDecimalOperator>(input, result, error_message,
2229 width, scale);
2230}
2231template <>
2232bool TryCastToDecimal::Operation(uint32_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2233 return StandardNumericToDecimalCast<uint32_t, int32_t, UnsignedToDecimalOperator>(input, result, error_message,
2234 width, scale);
2235}
2236template <>
2237bool TryCastToDecimal::Operation(uint32_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2238 return StandardNumericToDecimalCast<uint32_t, int64_t, UnsignedToDecimalOperator>(input, result, error_message,
2239 width, scale);
2240}
2241template <>
2242bool TryCastToDecimal::Operation(uint32_t input, hugeint_t &result, string *error_message, uint8_t width,
2243 uint8_t scale) {
2244 return NumericToHugeDecimalCast<uint32_t>(input, result, error_message, width, scale);
2245}
2246
2247//===--------------------------------------------------------------------===//
2248// Cast uint64_t -> Decimal
2249//===--------------------------------------------------------------------===//
2250template <>
2251bool TryCastToDecimal::Operation(uint64_t input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2252 return StandardNumericToDecimalCast<uint64_t, int16_t, UnsignedToDecimalOperator>(input, result, error_message,
2253 width, scale);
2254}
2255template <>
2256bool TryCastToDecimal::Operation(uint64_t input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2257 return StandardNumericToDecimalCast<uint64_t, int32_t, UnsignedToDecimalOperator>(input, result, error_message,
2258 width, scale);
2259}
2260template <>
2261bool TryCastToDecimal::Operation(uint64_t input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2262 return StandardNumericToDecimalCast<uint64_t, int64_t, UnsignedToDecimalOperator>(input, result, error_message,
2263 width, scale);
2264}
2265template <>
2266bool TryCastToDecimal::Operation(uint64_t input, hugeint_t &result, string *error_message, uint8_t width,
2267 uint8_t scale) {
2268 return NumericToHugeDecimalCast<uint64_t>(input, result, error_message, width, scale);
2269}
2270
2271//===--------------------------------------------------------------------===//
2272// Hugeint -> Decimal Cast
2273//===--------------------------------------------------------------------===//
2274template <class DST>
2275bool HugeintToDecimalCast(hugeint_t input, DST &result, string *error_message, uint8_t width, uint8_t scale) {
2276 // check for overflow
2277 hugeint_t max_width = Hugeint::POWERS_OF_TEN[width - scale];
2278 if (input >= max_width || input <= -max_width) {
2279 string error = StringUtil::Format(fmt_str: "Could not cast value %s to DECIMAL(%d,%d)", params: input.ToString(), params: width, params: scale);
2280 HandleCastError::AssignError(error_message: error, error_message_ptr: error_message);
2281 return false;
2282 }
2283 result = Hugeint::Cast<DST>(input * Hugeint::POWERS_OF_TEN[scale]);
2284 return true;
2285}
2286
2287template <>
2288bool TryCastToDecimal::Operation(hugeint_t input, int16_t &result, string *error_message, uint8_t width,
2289 uint8_t scale) {
2290 return HugeintToDecimalCast<int16_t>(input, result, error_message, width, scale);
2291}
2292
2293template <>
2294bool TryCastToDecimal::Operation(hugeint_t input, int32_t &result, string *error_message, uint8_t width,
2295 uint8_t scale) {
2296 return HugeintToDecimalCast<int32_t>(input, result, error_message, width, scale);
2297}
2298
2299template <>
2300bool TryCastToDecimal::Operation(hugeint_t input, int64_t &result, string *error_message, uint8_t width,
2301 uint8_t scale) {
2302 return HugeintToDecimalCast<int64_t>(input, result, error_message, width, scale);
2303}
2304
2305template <>
2306bool TryCastToDecimal::Operation(hugeint_t input, hugeint_t &result, string *error_message, uint8_t width,
2307 uint8_t scale) {
2308 return HugeintToDecimalCast<hugeint_t>(input, result, error_message, width, scale);
2309}
2310
2311//===--------------------------------------------------------------------===//
2312// Float/Double -> Decimal Cast
2313//===--------------------------------------------------------------------===//
2314template <class SRC, class DST>
2315bool DoubleToDecimalCast(SRC input, DST &result, string *error_message, uint8_t width, uint8_t scale) {
2316 double value = input * NumericHelper::DOUBLE_POWERS_OF_TEN[scale];
2317 // Add the sign (-1, 0, 1) times a tiny value to fix floating point issues (issue 3091)
2318 double sign = (double(0) < value) - (value < double(0));
2319 value += 1e-9 * sign;
2320 if (value <= -NumericHelper::DOUBLE_POWERS_OF_TEN[width] || value >= NumericHelper::DOUBLE_POWERS_OF_TEN[width]) {
2321 string error = StringUtil::Format(fmt_str: "Could not cast value %f to DECIMAL(%d,%d)", params: value, params: width, params: scale);
2322 HandleCastError::AssignError(error_message: error, error_message_ptr: error_message);
2323 return false;
2324 }
2325 result = Cast::Operation<SRC, DST>(value);
2326 return true;
2327}
2328
2329template <>
2330bool TryCastToDecimal::Operation(float input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2331 return DoubleToDecimalCast<float, int16_t>(input, result, error_message, width, scale);
2332}
2333
2334template <>
2335bool TryCastToDecimal::Operation(float input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2336 return DoubleToDecimalCast<float, int32_t>(input, result, error_message, width, scale);
2337}
2338
2339template <>
2340bool TryCastToDecimal::Operation(float input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2341 return DoubleToDecimalCast<float, int64_t>(input, result, error_message, width, scale);
2342}
2343
2344template <>
2345bool TryCastToDecimal::Operation(float input, hugeint_t &result, string *error_message, uint8_t width, uint8_t scale) {
2346 return DoubleToDecimalCast<float, hugeint_t>(input, result, error_message, width, scale);
2347}
2348
2349template <>
2350bool TryCastToDecimal::Operation(double input, int16_t &result, string *error_message, uint8_t width, uint8_t scale) {
2351 return DoubleToDecimalCast<double, int16_t>(input, result, error_message, width, scale);
2352}
2353
2354template <>
2355bool TryCastToDecimal::Operation(double input, int32_t &result, string *error_message, uint8_t width, uint8_t scale) {
2356 return DoubleToDecimalCast<double, int32_t>(input, result, error_message, width, scale);
2357}
2358
2359template <>
2360bool TryCastToDecimal::Operation(double input, int64_t &result, string *error_message, uint8_t width, uint8_t scale) {
2361 return DoubleToDecimalCast<double, int64_t>(input, result, error_message, width, scale);
2362}
2363
2364template <>
2365bool TryCastToDecimal::Operation(double input, hugeint_t &result, string *error_message, uint8_t width, uint8_t scale) {
2366 return DoubleToDecimalCast<double, hugeint_t>(input, result, error_message, width, scale);
2367}
2368
2369//===--------------------------------------------------------------------===//
2370// Decimal -> Numeric Cast
2371//===--------------------------------------------------------------------===//
2372template <class SRC, class DST>
2373bool TryCastDecimalToNumeric(SRC input, DST &result, string *error_message, uint8_t scale) {
2374 // Round away from 0.
2375 const auto power = NumericHelper::POWERS_OF_TEN[scale];
2376 // https://graphics.stanford.edu/~seander/bithacks.html#ConditionalNegate
2377 const auto fNegate = int64_t(input < 0);
2378 const auto rounding = ((power ^ -fNegate) + fNegate) / 2;
2379 const auto scaled_value = (input + rounding) / power;
2380 if (!TryCast::Operation<SRC, DST>(scaled_value, result)) {
2381 string error = StringUtil::Format("Failed to cast decimal value %d to type %s", scaled_value, GetTypeId<DST>());
2382 HandleCastError::AssignError(error_message: error, error_message_ptr: error_message);
2383 return false;
2384 }
2385 return true;
2386}
2387
2388template <class DST>
2389bool TryCastHugeDecimalToNumeric(hugeint_t input, DST &result, string *error_message, uint8_t scale) {
2390 const auto power = Hugeint::POWERS_OF_TEN[scale];
2391 const auto rounding = ((input < 0) ? -power : power) / 2;
2392 auto scaled_value = (input + rounding) / power;
2393 if (!TryCast::Operation<hugeint_t, DST>(scaled_value, result)) {
2394 string error = StringUtil::Format("Failed to cast decimal value %s to type %s",
2395 ConvertToString::Operation(input: scaled_value), GetTypeId<DST>());
2396 HandleCastError::AssignError(error_message: error, error_message_ptr: error_message);
2397 return false;
2398 }
2399 return true;
2400}
2401
2402//===--------------------------------------------------------------------===//
2403// Cast Decimal -> int8_t
2404//===--------------------------------------------------------------------===//
2405template <>
2406bool TryCastFromDecimal::Operation(int16_t input, int8_t &result, string *error_message, uint8_t width, uint8_t scale) {
2407 return TryCastDecimalToNumeric<int16_t, int8_t>(input, result, error_message, scale);
2408}
2409template <>
2410bool TryCastFromDecimal::Operation(int32_t input, int8_t &result, string *error_message, uint8_t width, uint8_t scale) {
2411 return TryCastDecimalToNumeric<int32_t, int8_t>(input, result, error_message, scale);
2412}
2413template <>
2414bool TryCastFromDecimal::Operation(int64_t input, int8_t &result, string *error_message, uint8_t width, uint8_t scale) {
2415 return TryCastDecimalToNumeric<int64_t, int8_t>(input, result, error_message, scale);
2416}
2417template <>
2418bool TryCastFromDecimal::Operation(hugeint_t input, int8_t &result, string *error_message, uint8_t width,
2419 uint8_t scale) {
2420 return TryCastHugeDecimalToNumeric<int8_t>(input, result, error_message, scale);
2421}
2422
2423//===--------------------------------------------------------------------===//
2424// Cast Decimal -> int16_t
2425//===--------------------------------------------------------------------===//
2426template <>
2427bool TryCastFromDecimal::Operation(int16_t input, int16_t &result, string *error_message, uint8_t width,
2428 uint8_t scale) {
2429 return TryCastDecimalToNumeric<int16_t, int16_t>(input, result, error_message, scale);
2430}
2431template <>
2432bool TryCastFromDecimal::Operation(int32_t input, int16_t &result, string *error_message, uint8_t width,
2433 uint8_t scale) {
2434 return TryCastDecimalToNumeric<int32_t, int16_t>(input, result, error_message, scale);
2435}
2436template <>
2437bool TryCastFromDecimal::Operation(int64_t input, int16_t &result, string *error_message, uint8_t width,
2438 uint8_t scale) {
2439 return TryCastDecimalToNumeric<int64_t, int16_t>(input, result, error_message, scale);
2440}
2441template <>
2442bool TryCastFromDecimal::Operation(hugeint_t input, int16_t &result, string *error_message, uint8_t width,
2443 uint8_t scale) {
2444 return TryCastHugeDecimalToNumeric<int16_t>(input, result, error_message, scale);
2445}
2446
2447//===--------------------------------------------------------------------===//
2448// Cast Decimal -> int32_t
2449//===--------------------------------------------------------------------===//
2450template <>
2451bool TryCastFromDecimal::Operation(int16_t input, int32_t &result, string *error_message, uint8_t width,
2452 uint8_t scale) {
2453 return TryCastDecimalToNumeric<int16_t, int32_t>(input, result, error_message, scale);
2454}
2455template <>
2456bool TryCastFromDecimal::Operation(int32_t input, int32_t &result, string *error_message, uint8_t width,
2457 uint8_t scale) {
2458 return TryCastDecimalToNumeric<int32_t, int32_t>(input, result, error_message, scale);
2459}
2460template <>
2461bool TryCastFromDecimal::Operation(int64_t input, int32_t &result, string *error_message, uint8_t width,
2462 uint8_t scale) {
2463 return TryCastDecimalToNumeric<int64_t, int32_t>(input, result, error_message, scale);
2464}
2465template <>
2466bool TryCastFromDecimal::Operation(hugeint_t input, int32_t &result, string *error_message, uint8_t width,
2467 uint8_t scale) {
2468 return TryCastHugeDecimalToNumeric<int32_t>(input, result, error_message, scale);
2469}
2470
2471//===--------------------------------------------------------------------===//
2472// Cast Decimal -> int64_t
2473//===--------------------------------------------------------------------===//
2474template <>
2475bool TryCastFromDecimal::Operation(int16_t input, int64_t &result, string *error_message, uint8_t width,
2476 uint8_t scale) {
2477 return TryCastDecimalToNumeric<int16_t, int64_t>(input, result, error_message, scale);
2478}
2479template <>
2480bool TryCastFromDecimal::Operation(int32_t input, int64_t &result, string *error_message, uint8_t width,
2481 uint8_t scale) {
2482 return TryCastDecimalToNumeric<int32_t, int64_t>(input, result, error_message, scale);
2483}
2484template <>
2485bool TryCastFromDecimal::Operation(int64_t input, int64_t &result, string *error_message, uint8_t width,
2486 uint8_t scale) {
2487 return TryCastDecimalToNumeric<int64_t, int64_t>(input, result, error_message, scale);
2488}
2489template <>
2490bool TryCastFromDecimal::Operation(hugeint_t input, int64_t &result, string *error_message, uint8_t width,
2491 uint8_t scale) {
2492 return TryCastHugeDecimalToNumeric<int64_t>(input, result, error_message, scale);
2493}
2494
2495//===--------------------------------------------------------------------===//
2496// Cast Decimal -> uint8_t
2497//===--------------------------------------------------------------------===//
2498template <>
2499bool TryCastFromDecimal::Operation(int16_t input, uint8_t &result, string *error_message, uint8_t width,
2500 uint8_t scale) {
2501 return TryCastDecimalToNumeric<int16_t, uint8_t>(input, result, error_message, scale);
2502}
2503template <>
2504bool TryCastFromDecimal::Operation(int32_t input, uint8_t &result, string *error_message, uint8_t width,
2505 uint8_t scale) {
2506 return TryCastDecimalToNumeric<int32_t, uint8_t>(input, result, error_message, scale);
2507}
2508template <>
2509bool TryCastFromDecimal::Operation(int64_t input, uint8_t &result, string *error_message, uint8_t width,
2510 uint8_t scale) {
2511 return TryCastDecimalToNumeric<int64_t, uint8_t>(input, result, error_message, scale);
2512}
2513template <>
2514bool TryCastFromDecimal::Operation(hugeint_t input, uint8_t &result, string *error_message, uint8_t width,
2515 uint8_t scale) {
2516 return TryCastHugeDecimalToNumeric<uint8_t>(input, result, error_message, scale);
2517}
2518
2519//===--------------------------------------------------------------------===//
2520// Cast Decimal -> uint16_t
2521//===--------------------------------------------------------------------===//
2522template <>
2523bool TryCastFromDecimal::Operation(int16_t input, uint16_t &result, string *error_message, uint8_t width,
2524 uint8_t scale) {
2525 return TryCastDecimalToNumeric<int16_t, uint16_t>(input, result, error_message, scale);
2526}
2527template <>
2528bool TryCastFromDecimal::Operation(int32_t input, uint16_t &result, string *error_message, uint8_t width,
2529 uint8_t scale) {
2530 return TryCastDecimalToNumeric<int32_t, uint16_t>(input, result, error_message, scale);
2531}
2532template <>
2533bool TryCastFromDecimal::Operation(int64_t input, uint16_t &result, string *error_message, uint8_t width,
2534 uint8_t scale) {
2535 return TryCastDecimalToNumeric<int64_t, uint16_t>(input, result, error_message, scale);
2536}
2537template <>
2538bool TryCastFromDecimal::Operation(hugeint_t input, uint16_t &result, string *error_message, uint8_t width,
2539 uint8_t scale) {
2540 return TryCastHugeDecimalToNumeric<uint16_t>(input, result, error_message, scale);
2541}
2542
2543//===--------------------------------------------------------------------===//
2544// Cast Decimal -> uint32_t
2545//===--------------------------------------------------------------------===//
2546template <>
2547bool TryCastFromDecimal::Operation(int16_t input, uint32_t &result, string *error_message, uint8_t width,
2548 uint8_t scale) {
2549 return TryCastDecimalToNumeric<int16_t, uint32_t>(input, result, error_message, scale);
2550}
2551template <>
2552bool TryCastFromDecimal::Operation(int32_t input, uint32_t &result, string *error_message, uint8_t width,
2553 uint8_t scale) {
2554 return TryCastDecimalToNumeric<int32_t, uint32_t>(input, result, error_message, scale);
2555}
2556template <>
2557bool TryCastFromDecimal::Operation(int64_t input, uint32_t &result, string *error_message, uint8_t width,
2558 uint8_t scale) {
2559 return TryCastDecimalToNumeric<int64_t, uint32_t>(input, result, error_message, scale);
2560}
2561template <>
2562bool TryCastFromDecimal::Operation(hugeint_t input, uint32_t &result, string *error_message, uint8_t width,
2563 uint8_t scale) {
2564 return TryCastHugeDecimalToNumeric<uint32_t>(input, result, error_message, scale);
2565}
2566
2567//===--------------------------------------------------------------------===//
2568// Cast Decimal -> uint64_t
2569//===--------------------------------------------------------------------===//
2570template <>
2571bool TryCastFromDecimal::Operation(int16_t input, uint64_t &result, string *error_message, uint8_t width,
2572 uint8_t scale) {
2573 return TryCastDecimalToNumeric<int16_t, uint64_t>(input, result, error_message, scale);
2574}
2575template <>
2576bool TryCastFromDecimal::Operation(int32_t input, uint64_t &result, string *error_message, uint8_t width,
2577 uint8_t scale) {
2578 return TryCastDecimalToNumeric<int32_t, uint64_t>(input, result, error_message, scale);
2579}
2580template <>
2581bool TryCastFromDecimal::Operation(int64_t input, uint64_t &result, string *error_message, uint8_t width,
2582 uint8_t scale) {
2583 return TryCastDecimalToNumeric<int64_t, uint64_t>(input, result, error_message, scale);
2584}
2585template <>
2586bool TryCastFromDecimal::Operation(hugeint_t input, uint64_t &result, string *error_message, uint8_t width,
2587 uint8_t scale) {
2588 return TryCastHugeDecimalToNumeric<uint64_t>(input, result, error_message, scale);
2589}
2590
2591//===--------------------------------------------------------------------===//
2592// Cast Decimal -> hugeint_t
2593//===--------------------------------------------------------------------===//
2594template <>
2595bool TryCastFromDecimal::Operation(int16_t input, hugeint_t &result, string *error_message, uint8_t width,
2596 uint8_t scale) {
2597 return TryCastDecimalToNumeric<int16_t, hugeint_t>(input, result, error_message, scale);
2598}
2599template <>
2600bool TryCastFromDecimal::Operation(int32_t input, hugeint_t &result, string *error_message, uint8_t width,
2601 uint8_t scale) {
2602 return TryCastDecimalToNumeric<int32_t, hugeint_t>(input, result, error_message, scale);
2603}
2604template <>
2605bool TryCastFromDecimal::Operation(int64_t input, hugeint_t &result, string *error_message, uint8_t width,
2606 uint8_t scale) {
2607 return TryCastDecimalToNumeric<int64_t, hugeint_t>(input, result, error_message, scale);
2608}
2609template <>
2610bool TryCastFromDecimal::Operation(hugeint_t input, hugeint_t &result, string *error_message, uint8_t width,
2611 uint8_t scale) {
2612 return TryCastHugeDecimalToNumeric<hugeint_t>(input, result, error_message, scale);
2613}
2614
2615//===--------------------------------------------------------------------===//
2616// Decimal -> Float/Double Cast
2617//===--------------------------------------------------------------------===//
2618template <class SRC, class DST>
2619bool TryCastDecimalToFloatingPoint(SRC input, DST &result, uint8_t scale) {
2620 result = Cast::Operation<SRC, DST>(input) / DST(NumericHelper::DOUBLE_POWERS_OF_TEN[scale]);
2621 return true;
2622}
2623
2624// DECIMAL -> FLOAT
2625template <>
2626bool TryCastFromDecimal::Operation(int16_t input, float &result, string *error_message, uint8_t width, uint8_t scale) {
2627 return TryCastDecimalToFloatingPoint<int16_t, float>(input, result, scale);
2628}
2629
2630template <>
2631bool TryCastFromDecimal::Operation(int32_t input, float &result, string *error_message, uint8_t width, uint8_t scale) {
2632 return TryCastDecimalToFloatingPoint<int32_t, float>(input, result, scale);
2633}
2634
2635template <>
2636bool TryCastFromDecimal::Operation(int64_t input, float &result, string *error_message, uint8_t width, uint8_t scale) {
2637 return TryCastDecimalToFloatingPoint<int64_t, float>(input, result, scale);
2638}
2639
2640template <>
2641bool TryCastFromDecimal::Operation(hugeint_t input, float &result, string *error_message, uint8_t width,
2642 uint8_t scale) {
2643 return TryCastDecimalToFloatingPoint<hugeint_t, float>(input, result, scale);
2644}
2645
2646// DECIMAL -> DOUBLE
2647template <>
2648bool TryCastFromDecimal::Operation(int16_t input, double &result, string *error_message, uint8_t width, uint8_t scale) {
2649 return TryCastDecimalToFloatingPoint<int16_t, double>(input, result, scale);
2650}
2651
2652template <>
2653bool TryCastFromDecimal::Operation(int32_t input, double &result, string *error_message, uint8_t width, uint8_t scale) {
2654 return TryCastDecimalToFloatingPoint<int32_t, double>(input, result, scale);
2655}
2656
2657template <>
2658bool TryCastFromDecimal::Operation(int64_t input, double &result, string *error_message, uint8_t width, uint8_t scale) {
2659 return TryCastDecimalToFloatingPoint<int64_t, double>(input, result, scale);
2660}
2661
2662template <>
2663bool TryCastFromDecimal::Operation(hugeint_t input, double &result, string *error_message, uint8_t width,
2664 uint8_t scale) {
2665 return TryCastDecimalToFloatingPoint<hugeint_t, double>(input, result, scale);
2666}
2667
2668} // namespace duckdb
2669