1 | #include "duckdb/main/capi/capi_internal.hpp" |
2 | #include "duckdb/common/types/hugeint.hpp" |
3 | #include "duckdb/common/types/decimal.hpp" |
4 | #include "duckdb/common/operator/decimal_cast_operators.hpp" |
5 | #include "duckdb/main/capi/cast/utils.hpp" |
6 | #include "duckdb/main/capi/cast/to_decimal.hpp" |
7 | |
8 | using duckdb::Hugeint; |
9 | using duckdb::hugeint_t; |
10 | using duckdb::Value; |
11 | |
12 | double duckdb_hugeint_to_double(duckdb_hugeint val) { |
13 | hugeint_t internal; |
14 | internal.lower = val.lower; |
15 | internal.upper = val.upper; |
16 | return Hugeint::Cast<double>(input: internal); |
17 | } |
18 | |
19 | static duckdb_decimal to_decimal_cast(double val, uint8_t width, uint8_t scale) { |
20 | if (width > duckdb::Decimal::MAX_WIDTH_INT64) { |
21 | return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<hugeint_t>>(source: val, width, scale); |
22 | } |
23 | if (width > duckdb::Decimal::MAX_WIDTH_INT32) { |
24 | return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int64_t>>(source: val, width, scale); |
25 | } |
26 | if (width > duckdb::Decimal::MAX_WIDTH_INT16) { |
27 | return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int32_t>>(source: val, width, scale); |
28 | } |
29 | return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int16_t>>(source: val, width, scale); |
30 | } |
31 | |
32 | duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale) { |
33 | if (scale > width || width > duckdb::Decimal::MAX_WIDTH_INT128) { |
34 | return duckdb::FetchDefaultValue::Operation<duckdb_decimal>(); |
35 | } |
36 | return to_decimal_cast(val, width, scale); |
37 | } |
38 | |
39 | duckdb_hugeint duckdb_double_to_hugeint(double val) { |
40 | hugeint_t internal_result; |
41 | if (!Value::DoubleIsFinite(value: val) || !Hugeint::TryConvert<double>(value: val, result&: internal_result)) { |
42 | internal_result.lower = 0; |
43 | internal_result.upper = 0; |
44 | } |
45 | |
46 | duckdb_hugeint result; |
47 | result.lower = internal_result.lower; |
48 | result.upper = internal_result.upper; |
49 | return result; |
50 | } |
51 | |
52 | double duckdb_decimal_to_double(duckdb_decimal val) { |
53 | double result; |
54 | hugeint_t value; |
55 | value.lower = val.value.lower; |
56 | value.upper = val.value.upper; |
57 | duckdb::TryCastFromDecimal::Operation<hugeint_t, double>(input: value, result, error_message: nullptr, width: val.width, scale: val.scale); |
58 | return result; |
59 | } |
60 | |