duckdb 0.5.2-dev1545.0 → 0.5.2-dev1575.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/duckdb.cpp CHANGED
@@ -24035,7 +24035,7 @@ bool TryCastFromDecimal::Operation(hugeint_t input, double &result, string *erro
24035
24035
  uint8_t scale);
24036
24036
 
24037
24037
  //===--------------------------------------------------------------------===//
24038
- // Cast Decimal -> VARCHAR
24038
+ // Cast Decimal <-> VARCHAR
24039
24039
  //===--------------------------------------------------------------------===//
24040
24040
  template <>
24041
24041
  DUCKDB_API bool TryCastToDecimal::Operation(string_t input, int16_t &result, string *error_message, uint8_t width,
@@ -45527,6 +45527,12 @@ bool Hugeint::TryConvert(uint64_t value, hugeint_t &result) {
45527
45527
  return true;
45528
45528
  }
45529
45529
 
45530
+ template <>
45531
+ bool Hugeint::TryConvert(hugeint_t value, hugeint_t &result) {
45532
+ result = value;
45533
+ return true;
45534
+ }
45535
+
45530
45536
  template <>
45531
45537
  bool Hugeint::TryConvert(float value, hugeint_t &result) {
45532
45538
  return Hugeint::TryConvert(double(value), result);
@@ -129375,7 +129381,7 @@ void BaseAppender::Close() {
129375
129381
  //===----------------------------------------------------------------------===//
129376
129382
  // DuckDB
129377
129383
  //
129378
- // duckdb/main/capi_internal.hpp
129384
+ // duckdb/main/capi/capi_internal.hpp
129379
129385
  //
129380
129386
  //
129381
129387
  //===----------------------------------------------------------------------===//
@@ -129761,6 +129767,399 @@ duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_st
129761
129767
  *out_result = (duckdb_arrow)arrow_wrapper;
129762
129768
  return !arrow_wrapper->result->HasError() ? DuckDBSuccess : DuckDBError;
129763
129769
  }
129770
+ //===----------------------------------------------------------------------===//
129771
+ // DuckDB
129772
+ //
129773
+ // duckdb/main/capi/capi_cast_from_decimal.hpp
129774
+ //
129775
+ //
129776
+ //===----------------------------------------------------------------------===//
129777
+
129778
+
129779
+
129780
+ //===----------------------------------------------------------------------===//
129781
+ // DuckDB
129782
+ //
129783
+ // duckdb/main/capi/cast/utils.hpp
129784
+ //
129785
+ //
129786
+ //===----------------------------------------------------------------------===//
129787
+
129788
+
129789
+
129790
+
129791
+
129792
+
129793
+
129794
+
129795
+ namespace duckdb {
129796
+
129797
+ //===--------------------------------------------------------------------===//
129798
+ // Unsafe Fetch (for internal use only)
129799
+ //===--------------------------------------------------------------------===//
129800
+ template <class T>
129801
+ T UnsafeFetchFromPtr(void *pointer) {
129802
+ return *((T *)pointer);
129803
+ }
129804
+
129805
+ template <class T>
129806
+ void *UnsafeFetchPtr(duckdb_result *result, idx_t col, idx_t row) {
129807
+ D_ASSERT(row < result->__deprecated_row_count);
129808
+ return (void *)&(((T *)result->__deprecated_columns[col].__deprecated_data)[row]);
129809
+ }
129810
+
129811
+ template <class T>
129812
+ T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) {
129813
+ return UnsafeFetchFromPtr<T>(UnsafeFetchPtr<T>(result, col, row));
129814
+ }
129815
+
129816
+ //===--------------------------------------------------------------------===//
129817
+ // Fetch Default Value
129818
+ //===--------------------------------------------------------------------===//
129819
+ struct FetchDefaultValue {
129820
+ template <class T>
129821
+ static T Operation() {
129822
+ return 0;
129823
+ }
129824
+ };
129825
+
129826
+ template <>
129827
+ duckdb_decimal FetchDefaultValue::Operation();
129828
+ template <>
129829
+ date_t FetchDefaultValue::Operation();
129830
+ template <>
129831
+ dtime_t FetchDefaultValue::Operation();
129832
+ template <>
129833
+ timestamp_t FetchDefaultValue::Operation();
129834
+ template <>
129835
+ interval_t FetchDefaultValue::Operation();
129836
+ template <>
129837
+ char *FetchDefaultValue::Operation();
129838
+ template <>
129839
+ duckdb_blob FetchDefaultValue::Operation();
129840
+
129841
+ //===--------------------------------------------------------------------===//
129842
+ // String Casts
129843
+ //===--------------------------------------------------------------------===//
129844
+ template <class OP>
129845
+ struct FromCStringCastWrapper {
129846
+ template <class SOURCE_TYPE, class RESULT_TYPE>
129847
+ static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
129848
+ string_t input(input_str);
129849
+ return OP::template Operation<string_t, RESULT_TYPE>(input, result);
129850
+ }
129851
+ };
129852
+
129853
+ template <class OP>
129854
+ struct ToCStringCastWrapper {
129855
+ template <class SOURCE_TYPE, class RESULT_TYPE>
129856
+ static bool Operation(SOURCE_TYPE input, RESULT_TYPE &result) {
129857
+ Vector result_vector(LogicalType::VARCHAR, nullptr);
129858
+ auto result_string = OP::template Operation<SOURCE_TYPE>(input, result_vector);
129859
+ auto result_size = result_string.GetSize();
129860
+ auto result_data = result_string.GetDataUnsafe();
129861
+
129862
+ result = (char *)duckdb_malloc(result_size + 1);
129863
+ memcpy(result, result_data, result_size);
129864
+ result[result_size] = '\0';
129865
+ return true;
129866
+ }
129867
+ };
129868
+
129869
+ //===--------------------------------------------------------------------===//
129870
+ // Blob Casts
129871
+ //===--------------------------------------------------------------------===//
129872
+ struct FromCBlobCastWrapper {
129873
+ template <class SOURCE_TYPE, class RESULT_TYPE>
129874
+ static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
129875
+ return false;
129876
+ }
129877
+ };
129878
+
129879
+ template <>
129880
+ bool FromCBlobCastWrapper::Operation(duckdb_blob input, char *&result);
129881
+
129882
+ template <class SOURCE_TYPE, class RESULT_TYPE, class OP>
129883
+ RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) {
129884
+ RESULT_TYPE result_value;
129885
+ try {
129886
+ if (!OP::template Operation<SOURCE_TYPE, RESULT_TYPE>(UnsafeFetch<SOURCE_TYPE>(result, col, row),
129887
+ result_value)) {
129888
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129889
+ }
129890
+ } catch (...) {
129891
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129892
+ }
129893
+ return result_value;
129894
+ }
129895
+
129896
+ } // namespace duckdb
129897
+
129898
+ bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row);
129899
+ bool CanUseDeprecatedFetch(duckdb_result *result, idx_t col, idx_t row);
129900
+
129901
+
129902
+ namespace duckdb {
129903
+
129904
+ //! DECIMAL -> ?
129905
+ template <class RESULT_TYPE>
129906
+ bool CastDecimalCInternal(duckdb_result *source, RESULT_TYPE &result, idx_t col, idx_t row) {
129907
+ auto result_data = (duckdb::DuckDBResultData *)source->internal_data;
129908
+ auto &query_result = result_data->result;
129909
+ auto &source_type = query_result->types[col];
129910
+ auto width = duckdb::DecimalType::GetWidth(source_type);
129911
+ auto scale = duckdb::DecimalType::GetScale(source_type);
129912
+ void *source_address = UnsafeFetchPtr<hugeint_t>(source, col, row);
129913
+ switch (source_type.InternalType()) {
129914
+ case duckdb::PhysicalType::INT16:
129915
+ return duckdb::TryCastFromDecimal::Operation<int16_t, RESULT_TYPE>(UnsafeFetchFromPtr<int16_t>(source_address),
129916
+ result, nullptr, width, scale);
129917
+ case duckdb::PhysicalType::INT32:
129918
+ return duckdb::TryCastFromDecimal::Operation<int32_t, RESULT_TYPE>(UnsafeFetchFromPtr<int32_t>(source_address),
129919
+ result, nullptr, width, scale);
129920
+ case duckdb::PhysicalType::INT64:
129921
+ return duckdb::TryCastFromDecimal::Operation<int64_t, RESULT_TYPE>(UnsafeFetchFromPtr<int64_t>(source_address),
129922
+ result, nullptr, width, scale);
129923
+ case duckdb::PhysicalType::INT128:
129924
+ return duckdb::TryCastFromDecimal::Operation<hugeint_t, RESULT_TYPE>(
129925
+ UnsafeFetchFromPtr<hugeint_t>(source_address), result, nullptr, width, scale);
129926
+ default:
129927
+ throw duckdb::InternalException("Unimplemented internal type for decimal");
129928
+ }
129929
+ }
129930
+
129931
+ //! DECIMAL -> VARCHAR
129932
+ template <>
129933
+ bool CastDecimalCInternal(duckdb_result *source, char *&result, idx_t col, idx_t row);
129934
+
129935
+ //! DECIMAL -> DECIMAL (internal fetch)
129936
+ template <>
129937
+ bool CastDecimalCInternal(duckdb_result *source, duckdb_decimal &result, idx_t col, idx_t row);
129938
+
129939
+ //! DECIMAL -> ...
129940
+ template <class RESULT_TYPE>
129941
+ RESULT_TYPE TryCastDecimalCInternal(duckdb_result *source, idx_t col, idx_t row) {
129942
+ RESULT_TYPE result_value;
129943
+ try {
129944
+ if (!CastDecimalCInternal<RESULT_TYPE>(source, result_value, col, row)) {
129945
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129946
+ }
129947
+ } catch (...) {
129948
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129949
+ }
129950
+ return result_value;
129951
+ }
129952
+
129953
+ } // namespace duckdb
129954
+
129955
+
129956
+
129957
+ namespace duckdb {
129958
+
129959
+ //! DECIMAL -> VARCHAR
129960
+ template <>
129961
+ bool CastDecimalCInternal(duckdb_result *source, char *&result, idx_t col, idx_t row) {
129962
+ auto result_data = (duckdb::DuckDBResultData *)source->internal_data;
129963
+ auto &query_result = result_data->result;
129964
+ auto &source_type = query_result->types[col];
129965
+ auto width = duckdb::DecimalType::GetWidth(source_type);
129966
+ auto scale = duckdb::DecimalType::GetScale(source_type);
129967
+ duckdb::Vector result_vec(duckdb::LogicalType::VARCHAR, false, false);
129968
+ duckdb::string_t result_string;
129969
+ void *source_address = UnsafeFetchPtr<hugeint_t>(source, col, row);
129970
+ switch (source_type.InternalType()) {
129971
+ case duckdb::PhysicalType::INT16:
129972
+ result_string = duckdb::StringCastFromDecimal::Operation<int16_t>(UnsafeFetchFromPtr<int16_t>(source_address),
129973
+ width, scale, result_vec);
129974
+ break;
129975
+ case duckdb::PhysicalType::INT32:
129976
+ result_string = duckdb::StringCastFromDecimal::Operation<int32_t>(UnsafeFetchFromPtr<int32_t>(source_address),
129977
+ width, scale, result_vec);
129978
+ break;
129979
+ case duckdb::PhysicalType::INT64:
129980
+ result_string = duckdb::StringCastFromDecimal::Operation<int64_t>(UnsafeFetchFromPtr<int64_t>(source_address),
129981
+ width, scale, result_vec);
129982
+ break;
129983
+ case duckdb::PhysicalType::INT128:
129984
+ result_string = duckdb::StringCastFromDecimal::Operation<hugeint_t>(
129985
+ UnsafeFetchFromPtr<hugeint_t>(source_address), width, scale, result_vec);
129986
+ break;
129987
+ default:
129988
+ throw duckdb::InternalException("Unimplemented internal type for decimal");
129989
+ }
129990
+ result = (char *)duckdb_malloc(sizeof(char) * (result_string.GetSize() + 1));
129991
+ memcpy(result, result_string.GetDataUnsafe(), result_string.GetSize());
129992
+ result[result_string.GetSize()] = '\0';
129993
+ return true;
129994
+ }
129995
+
129996
+ template <class INTERNAL_TYPE>
129997
+ duckdb_hugeint FetchInternals(void *source_address) {
129998
+ throw duckdb::NotImplementedException("FetchInternals not implemented for internal type");
129999
+ }
130000
+
130001
+ template <>
130002
+ duckdb_hugeint FetchInternals<int16_t>(void *source_address) {
130003
+ duckdb_hugeint result;
130004
+ int16_t intermediate_result;
130005
+
130006
+ if (!TryCast::Operation<int16_t, int16_t>(UnsafeFetchFromPtr<int16_t>(source_address), intermediate_result)) {
130007
+ intermediate_result = FetchDefaultValue::Operation<int16_t>();
130008
+ }
130009
+ hugeint_t hugeint_result = Hugeint::Cast<int16_t>(intermediate_result);
130010
+ result.lower = hugeint_result.lower;
130011
+ result.upper = hugeint_result.upper;
130012
+ return result;
130013
+ }
130014
+ template <>
130015
+ duckdb_hugeint FetchInternals<int32_t>(void *source_address) {
130016
+ duckdb_hugeint result;
130017
+ int32_t intermediate_result;
130018
+
130019
+ if (!TryCast::Operation<int32_t, int32_t>(UnsafeFetchFromPtr<int32_t>(source_address), intermediate_result)) {
130020
+ intermediate_result = FetchDefaultValue::Operation<int32_t>();
130021
+ }
130022
+ hugeint_t hugeint_result = Hugeint::Cast<int32_t>(intermediate_result);
130023
+ result.lower = hugeint_result.lower;
130024
+ result.upper = hugeint_result.upper;
130025
+ return result;
130026
+ }
130027
+ template <>
130028
+ duckdb_hugeint FetchInternals<int64_t>(void *source_address) {
130029
+ duckdb_hugeint result;
130030
+ int64_t intermediate_result;
130031
+
130032
+ if (!TryCast::Operation<int64_t, int64_t>(UnsafeFetchFromPtr<int64_t>(source_address), intermediate_result)) {
130033
+ intermediate_result = FetchDefaultValue::Operation<int64_t>();
130034
+ }
130035
+ hugeint_t hugeint_result = Hugeint::Cast<int64_t>(intermediate_result);
130036
+ result.lower = hugeint_result.lower;
130037
+ result.upper = hugeint_result.upper;
130038
+ return result;
130039
+ }
130040
+ template <>
130041
+ duckdb_hugeint FetchInternals<hugeint_t>(void *source_address) {
130042
+ duckdb_hugeint result;
130043
+ hugeint_t intermediate_result;
130044
+
130045
+ if (!TryCast::Operation<hugeint_t, hugeint_t>(UnsafeFetchFromPtr<hugeint_t>(source_address), intermediate_result)) {
130046
+ intermediate_result = FetchDefaultValue::Operation<hugeint_t>();
130047
+ }
130048
+ result.lower = intermediate_result.lower;
130049
+ result.upper = intermediate_result.upper;
130050
+ return result;
130051
+ }
130052
+
130053
+ //! DECIMAL -> DECIMAL (internal fetch)
130054
+ template <>
130055
+ bool CastDecimalCInternal(duckdb_result *source, duckdb_decimal &result, idx_t col, idx_t row) {
130056
+ auto result_data = (duckdb::DuckDBResultData *)source->internal_data;
130057
+ result_data->result->types[col].GetDecimalProperties(result.width, result.scale);
130058
+ auto source_address = UnsafeFetchPtr<hugeint_t>(source, col, row);
130059
+
130060
+ if (result.width > duckdb::Decimal::MAX_WIDTH_INT64) {
130061
+ result.value = FetchInternals<hugeint_t>(source_address);
130062
+ } else if (result.width > duckdb::Decimal::MAX_WIDTH_INT32) {
130063
+ result.value = FetchInternals<int64_t>(source_address);
130064
+ } else if (result.width > duckdb::Decimal::MAX_WIDTH_INT16) {
130065
+ result.value = FetchInternals<int32_t>(source_address);
130066
+ } else {
130067
+ result.value = FetchInternals<int16_t>(source_address);
130068
+ }
130069
+ return true;
130070
+ }
130071
+
130072
+ } // namespace duckdb
130073
+
130074
+
130075
+ namespace duckdb {
130076
+
130077
+ template <>
130078
+ duckdb_decimal FetchDefaultValue::Operation() {
130079
+ duckdb_decimal result;
130080
+ result.scale = 0;
130081
+ result.width = 0;
130082
+ result.value = {0, 0};
130083
+ return result;
130084
+ }
130085
+
130086
+ template <>
130087
+ date_t FetchDefaultValue::Operation() {
130088
+ date_t result;
130089
+ result.days = 0;
130090
+ return result;
130091
+ }
130092
+
130093
+ template <>
130094
+ dtime_t FetchDefaultValue::Operation() {
130095
+ dtime_t result;
130096
+ result.micros = 0;
130097
+ return result;
130098
+ }
130099
+
130100
+ template <>
130101
+ timestamp_t FetchDefaultValue::Operation() {
130102
+ timestamp_t result;
130103
+ result.value = 0;
130104
+ return result;
130105
+ }
130106
+
130107
+ template <>
130108
+ interval_t FetchDefaultValue::Operation() {
130109
+ interval_t result;
130110
+ result.months = 0;
130111
+ result.days = 0;
130112
+ result.micros = 0;
130113
+ return result;
130114
+ }
130115
+
130116
+ template <>
130117
+ char *FetchDefaultValue::Operation() {
130118
+ return nullptr;
130119
+ }
130120
+
130121
+ template <>
130122
+ duckdb_blob FetchDefaultValue::Operation() {
130123
+ duckdb_blob result;
130124
+ result.data = nullptr;
130125
+ result.size = 0;
130126
+ return result;
130127
+ }
130128
+
130129
+ //===--------------------------------------------------------------------===//
130130
+ // Blob Casts
130131
+ //===--------------------------------------------------------------------===//
130132
+
130133
+ template <>
130134
+ bool FromCBlobCastWrapper::Operation(duckdb_blob input, char *&result) {
130135
+ string_t input_str((const char *)input.data, input.size);
130136
+ return ToCStringCastWrapper<duckdb::CastFromBlob>::template Operation<string_t, char *>(input_str, result);
130137
+ }
130138
+
130139
+ } // namespace duckdb
130140
+
130141
+ bool CanUseDeprecatedFetch(duckdb_result *result, idx_t col, idx_t row) {
130142
+ if (!result) {
130143
+ return false;
130144
+ }
130145
+ if (!duckdb::deprecated_materialize_result(result)) {
130146
+ return false;
130147
+ }
130148
+ if (col >= result->__deprecated_column_count || row >= result->__deprecated_row_count) {
130149
+ return false;
130150
+ }
130151
+ return true;
130152
+ }
130153
+
130154
+ bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row) {
130155
+ if (!CanUseDeprecatedFetch(result, col, row)) {
130156
+ return false;
130157
+ }
130158
+ if (result->__deprecated_columns[col].__deprecated_nullmask[row]) {
130159
+ return false;
130160
+ }
130161
+ return true;
130162
+ }
129764
130163
 
129765
130164
 
129766
130165
 
@@ -130382,6 +130781,142 @@ idx_t duckdb_vector_size() {
130382
130781
 
130383
130782
 
130384
130783
 
130784
+ //===----------------------------------------------------------------------===//
130785
+ // DuckDB
130786
+ //
130787
+ // duckdb/main/capi/capi_cast_from_decimal.hpp
130788
+ //
130789
+ //
130790
+ //===----------------------------------------------------------------------===//
130791
+
130792
+
130793
+
130794
+
130795
+
130796
+ namespace duckdb {
130797
+
130798
+ template <class INTERNAL_TYPE>
130799
+ struct ToCDecimalCastWrapper {
130800
+ template <class SOURCE_TYPE>
130801
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130802
+ throw NotImplementedException("Type not implemented for CDecimalCastWrapper");
130803
+ }
130804
+ };
130805
+
130806
+ //! Hugeint
130807
+ template <>
130808
+ struct ToCDecimalCastWrapper<hugeint_t> {
130809
+ template <class SOURCE_TYPE>
130810
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130811
+ hugeint_t intermediate_result;
130812
+
130813
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, hugeint_t>(input, intermediate_result, error, width, scale)) {
130814
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130815
+ return false;
130816
+ }
130817
+ result.scale = scale;
130818
+ result.width = width;
130819
+
130820
+ duckdb_hugeint hugeint_value;
130821
+ hugeint_value.upper = intermediate_result.upper;
130822
+ hugeint_value.lower = intermediate_result.lower;
130823
+ result.value = hugeint_value;
130824
+ return true;
130825
+ }
130826
+ };
130827
+
130828
+ //! FIXME: reduce duplication here by just matching on the signed-ness of the type
130829
+ //! INTERNAL_TYPE = int16_t
130830
+ template <>
130831
+ struct ToCDecimalCastWrapper<int16_t> {
130832
+ template <class SOURCE_TYPE>
130833
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130834
+ int16_t intermediate_result;
130835
+
130836
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, int16_t>(input, intermediate_result, error, width, scale)) {
130837
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130838
+ return false;
130839
+ }
130840
+ hugeint_t hugeint_result = Hugeint::Convert(intermediate_result);
130841
+
130842
+ result.scale = scale;
130843
+ result.width = width;
130844
+
130845
+ duckdb_hugeint hugeint_value;
130846
+ hugeint_value.upper = hugeint_result.upper;
130847
+ hugeint_value.lower = hugeint_result.lower;
130848
+ result.value = hugeint_value;
130849
+ return true;
130850
+ }
130851
+ };
130852
+ //! INTERNAL_TYPE = int32_t
130853
+ template <>
130854
+ struct ToCDecimalCastWrapper<int32_t> {
130855
+ template <class SOURCE_TYPE>
130856
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130857
+ int32_t intermediate_result;
130858
+
130859
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, int32_t>(input, intermediate_result, error, width, scale)) {
130860
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130861
+ return false;
130862
+ }
130863
+ hugeint_t hugeint_result = Hugeint::Convert(intermediate_result);
130864
+
130865
+ result.scale = scale;
130866
+ result.width = width;
130867
+
130868
+ duckdb_hugeint hugeint_value;
130869
+ hugeint_value.upper = hugeint_result.upper;
130870
+ hugeint_value.lower = hugeint_result.lower;
130871
+ result.value = hugeint_value;
130872
+ return true;
130873
+ }
130874
+ };
130875
+ //! INTERNAL_TYPE = int64_t
130876
+ template <>
130877
+ struct ToCDecimalCastWrapper<int64_t> {
130878
+ template <class SOURCE_TYPE>
130879
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130880
+ int64_t intermediate_result;
130881
+
130882
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, int64_t>(input, intermediate_result, error, width, scale)) {
130883
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130884
+ return false;
130885
+ }
130886
+ hugeint_t hugeint_result = Hugeint::Convert(intermediate_result);
130887
+
130888
+ result.scale = scale;
130889
+ result.width = width;
130890
+
130891
+ duckdb_hugeint hugeint_value;
130892
+ hugeint_value.upper = hugeint_result.upper;
130893
+ hugeint_value.lower = hugeint_result.lower;
130894
+ result.value = hugeint_value;
130895
+ return true;
130896
+ }
130897
+ };
130898
+
130899
+ template <class SOURCE_TYPE, class OP>
130900
+ duckdb_decimal TryCastToDecimalCInternal(SOURCE_TYPE source, uint8_t width, uint8_t scale) {
130901
+ duckdb_decimal result;
130902
+ try {
130903
+ if (!OP::template Operation<SOURCE_TYPE>(source, result, nullptr, width, scale)) {
130904
+ return FetchDefaultValue::Operation<duckdb_decimal>();
130905
+ }
130906
+ } catch (...) {
130907
+ return FetchDefaultValue::Operation<duckdb_decimal>();
130908
+ }
130909
+ return result;
130910
+ }
130911
+
130912
+ template <class SOURCE_TYPE, class OP>
130913
+ duckdb_decimal TryCastToDecimalCInternal(duckdb_result *result, idx_t col, idx_t row, uint8_t width, uint8_t scale) {
130914
+ return TryCastToDecimalCInternal<SOURCE_TYPE, OP>(UnsafeFetch<SOURCE_TYPE>(result, col, row), width, scale);
130915
+ }
130916
+
130917
+ } // namespace duckdb
130918
+
130919
+
130385
130920
  using duckdb::Hugeint;
130386
130921
  using duckdb::hugeint_t;
130387
130922
  using duckdb::Value;
@@ -130393,6 +130928,26 @@ double duckdb_hugeint_to_double(duckdb_hugeint val) {
130393
130928
  return Hugeint::Cast<double>(internal);
130394
130929
  }
130395
130930
 
130931
+ static duckdb_decimal to_decimal_cast(double val, uint8_t width, uint8_t scale) {
130932
+ if (width > duckdb::Decimal::MAX_WIDTH_INT64) {
130933
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<hugeint_t>>(val, width, scale);
130934
+ }
130935
+ if (width > duckdb::Decimal::MAX_WIDTH_INT32) {
130936
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int64_t>>(val, width, scale);
130937
+ }
130938
+ if (width > duckdb::Decimal::MAX_WIDTH_INT16) {
130939
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int32_t>>(val, width, scale);
130940
+ }
130941
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int16_t>>(val, width, scale);
130942
+ }
130943
+
130944
+ duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale) {
130945
+ if (scale > width || width > duckdb::Decimal::MAX_WIDTH_INT128) {
130946
+ return duckdb::FetchDefaultValue::Operation<duckdb_decimal>();
130947
+ }
130948
+ return to_decimal_cast(val, width, scale);
130949
+ }
130950
+
130396
130951
  duckdb_hugeint duckdb_double_to_hugeint(double val) {
130397
130952
  hugeint_t internal_result;
130398
130953
  if (!Value::DoubleIsFinite(val) || !Hugeint::TryConvert<double>(val, internal_result)) {
@@ -130711,6 +131266,7 @@ duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb
130711
131266
 
130712
131267
 
130713
131268
 
131269
+
130714
131270
  using duckdb::Connection;
130715
131271
  using duckdb::date_t;
130716
131272
  using duckdb::dtime_t;
@@ -130806,11 +131362,15 @@ duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx
130806
131362
  return duckdb_bind_value(prepared_statement, param_idx, Value::BIGINT(val));
130807
131363
  }
130808
131364
 
130809
- duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, duckdb_hugeint val) {
131365
+ static hugeint_t duckdb_internal_hugeint(duckdb_hugeint val) {
130810
131366
  hugeint_t internal;
130811
131367
  internal.lower = val.lower;
130812
131368
  internal.upper = val.upper;
130813
- return duckdb_bind_value(prepared_statement, param_idx, Value::HUGEINT(internal));
131369
+ return internal;
131370
+ }
131371
+
131372
+ duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, duckdb_hugeint val) {
131373
+ return duckdb_bind_value(prepared_statement, param_idx, Value::HUGEINT(duckdb_internal_hugeint(val)));
130814
131374
  }
130815
131375
 
130816
131376
  duckdb_state duckdb_bind_uint8(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint8_t val) {
@@ -130871,6 +131431,15 @@ duckdb_state duckdb_bind_varchar_length(duckdb_prepared_statement prepared_state
130871
131431
  }
130872
131432
  }
130873
131433
 
131434
+ duckdb_state duckdb_bind_decimal(duckdb_prepared_statement prepared_statement, idx_t param_idx, duckdb_decimal val) {
131435
+ auto hugeint_val = duckdb_internal_hugeint(val.value);
131436
+ if (val.width > duckdb::Decimal::MAX_WIDTH_INT64) {
131437
+ return duckdb_bind_value(prepared_statement, param_idx, Value::DECIMAL(hugeint_val, val.width, val.scale));
131438
+ }
131439
+ auto value = hugeint_val.lower;
131440
+ return duckdb_bind_value(prepared_statement, param_idx, Value::DECIMAL((int64_t)value, val.width, val.scale));
131441
+ }
131442
+
130874
131443
  duckdb_state duckdb_bind_blob(duckdb_prepared_statement prepared_statement, idx_t param_idx, const void *data,
130875
131444
  idx_t length) {
130876
131445
  return duckdb_bind_value(prepared_statement, param_idx, Value::BLOB((duckdb::const_data_ptr_t)data, length));
@@ -132026,180 +132595,28 @@ void duckdb_destroy_task_state(duckdb_task_state state_p) {
132026
132595
 
132027
132596
 
132028
132597
 
132598
+ //===----------------------------------------------------------------------===//
132599
+ // DuckDB
132600
+ //
132601
+ // duckdb/main/capi/cast/generic_cast.hpp
132602
+ //
132603
+ //
132604
+ //===----------------------------------------------------------------------===//
132029
132605
 
132030
- using duckdb::const_data_ptr_t;
132031
- using duckdb::Date;
132032
- using duckdb::date_t;
132033
- using duckdb::dtime_t;
132034
- using duckdb::hugeint_t;
132035
- using duckdb::interval_t;
132036
- using duckdb::LogicalType;
132037
- using duckdb::string;
132038
- using duckdb::string_t;
132039
- using duckdb::Time;
132040
- using duckdb::Timestamp;
132041
- using duckdb::timestamp_t;
132042
- using duckdb::Value;
132043
- using duckdb::Vector;
132044
-
132045
- namespace duckdb {
132046
-
132047
- //===--------------------------------------------------------------------===//
132048
- // Unsafe Fetch (for internal use only)
132049
- //===--------------------------------------------------------------------===//
132050
- template <class T>
132051
- T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) {
132052
- D_ASSERT(row < result->__deprecated_row_count);
132053
- return ((T *)result->__deprecated_columns[col].__deprecated_data)[row];
132054
- }
132055
-
132056
- //===--------------------------------------------------------------------===//
132057
- // Fetch Default Value
132058
- //===--------------------------------------------------------------------===//
132059
- struct FetchDefaultValue {
132060
- template <class T>
132061
- static T Operation() {
132062
- return 0;
132063
- }
132064
- };
132065
-
132066
- template <>
132067
- date_t FetchDefaultValue::Operation() {
132068
- date_t result;
132069
- result.days = 0;
132070
- return result;
132071
- }
132072
-
132073
- template <>
132074
- dtime_t FetchDefaultValue::Operation() {
132075
- dtime_t result;
132076
- result.micros = 0;
132077
- return result;
132078
- }
132079
-
132080
- template <>
132081
- timestamp_t FetchDefaultValue::Operation() {
132082
- timestamp_t result;
132083
- result.value = 0;
132084
- return result;
132085
- }
132086
-
132087
- template <>
132088
- interval_t FetchDefaultValue::Operation() {
132089
- interval_t result;
132090
- result.months = 0;
132091
- result.days = 0;
132092
- result.micros = 0;
132093
- return result;
132094
- }
132095
-
132096
- template <>
132097
- char *FetchDefaultValue::Operation() {
132098
- return nullptr;
132099
- }
132100
132606
 
132101
- template <>
132102
- duckdb_blob FetchDefaultValue::Operation() {
132103
- duckdb_blob result;
132104
- result.data = nullptr;
132105
- result.size = 0;
132106
- return result;
132107
- }
132108
132607
 
132109
- //===--------------------------------------------------------------------===//
132110
- // String Casts
132111
- //===--------------------------------------------------------------------===//
132112
- template <class OP>
132113
- struct FromCStringCastWrapper {
132114
- template <class SOURCE_TYPE, class RESULT_TYPE>
132115
- static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
132116
- string_t input(input_str);
132117
- return OP::template Operation<string_t, RESULT_TYPE>(input, result);
132118
- }
132119
- };
132120
132608
 
132121
- template <class OP>
132122
- struct ToCStringCastWrapper {
132123
- template <class SOURCE_TYPE, class RESULT_TYPE>
132124
- static bool Operation(SOURCE_TYPE input, RESULT_TYPE &result) {
132125
- Vector result_vector(LogicalType::VARCHAR, nullptr);
132126
- auto result_string = OP::template Operation<SOURCE_TYPE>(input, result_vector);
132127
- auto result_size = result_string.GetSize();
132128
- auto result_data = result_string.GetDataUnsafe();
132129
132609
 
132130
- result = (char *)duckdb_malloc(result_size + 1);
132131
- memcpy(result, result_data, result_size);
132132
- result[result_size] = '\0';
132133
- return true;
132134
- }
132135
- };
132136
132610
 
132137
- //===--------------------------------------------------------------------===//
132138
- // Blob Casts
132139
- //===--------------------------------------------------------------------===//
132140
- struct FromCBlobCastWrapper {
132141
- template <class SOURCE_TYPE, class RESULT_TYPE>
132142
- static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
132143
- return false;
132144
- }
132145
- };
132146
132611
 
132147
- template <>
132148
- bool FromCBlobCastWrapper::Operation(duckdb_blob input, char *&result) {
132149
- string_t input_str((const char *)input.data, input.size);
132150
- return ToCStringCastWrapper<duckdb::CastFromBlob>::template Operation<string_t, char *>(input_str, result);
132151
- }
132152
-
132153
- } // namespace duckdb
132154
132612
 
132155
- using duckdb::FetchDefaultValue;
132156
- using duckdb::FromCBlobCastWrapper;
132157
- using duckdb::FromCStringCastWrapper;
132158
- using duckdb::ToCStringCastWrapper;
132159
- using duckdb::UnsafeFetch;
132160
132613
 
132161
- //===--------------------------------------------------------------------===//
132162
- // Templated Casts
132163
- //===--------------------------------------------------------------------===//
132164
- template <class SOURCE_TYPE, class RESULT_TYPE, class OP>
132165
- RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) {
132166
- RESULT_TYPE result_value;
132167
- try {
132168
- if (!OP::template Operation<SOURCE_TYPE, RESULT_TYPE>(UnsafeFetch<SOURCE_TYPE>(result, col, row),
132169
- result_value)) {
132170
- return FetchDefaultValue::Operation<RESULT_TYPE>();
132171
- }
132172
- } catch (...) {
132173
- return FetchDefaultValue::Operation<RESULT_TYPE>();
132174
- }
132175
- return result_value;
132176
- }
132177
132614
 
132178
- static bool CanUseDeprecatedFetch(duckdb_result *result, idx_t col, idx_t row) {
132179
- if (!result) {
132180
- return false;
132181
- }
132182
- if (!duckdb::deprecated_materialize_result(result)) {
132183
- return false;
132184
- }
132185
- if (col >= result->__deprecated_column_count || row >= result->__deprecated_row_count) {
132186
- return false;
132187
- }
132188
- return true;
132189
- }
132190
132615
 
132191
- static bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row) {
132192
- if (!CanUseDeprecatedFetch(result, col, row)) {
132193
- return false;
132194
- }
132195
- if (result->__deprecated_columns[col].__deprecated_nullmask[row]) {
132196
- return false;
132197
- }
132198
- return true;
132199
- }
132616
+ namespace duckdb {
132200
132617
 
132201
132618
  template <class RESULT_TYPE, class OP = duckdb::TryCast>
132202
- static RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row) {
132619
+ RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row) {
132203
132620
  if (!CanFetchValue(result, col, row)) {
132204
132621
  return FetchDefaultValue::Operation<RESULT_TYPE>();
132205
132622
  }
@@ -132235,23 +132652,35 @@ static RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row
132235
132652
  case DUCKDB_TYPE_HUGEINT:
132236
132653
  return TryCastCInternal<hugeint_t, RESULT_TYPE, OP>(result, col, row);
132237
132654
  case DUCKDB_TYPE_DECIMAL:
132238
- return TryCastCInternal<hugeint_t, RESULT_TYPE, OP>(result, col, row);
132655
+ return TryCastDecimalCInternal<RESULT_TYPE>(result, col, row);
132239
132656
  case DUCKDB_TYPE_INTERVAL:
132240
132657
  return TryCastCInternal<interval_t, RESULT_TYPE, OP>(result, col, row);
132241
132658
  case DUCKDB_TYPE_VARCHAR:
132242
132659
  return TryCastCInternal<char *, RESULT_TYPE, FromCStringCastWrapper<OP>>(result, col, row);
132243
132660
  case DUCKDB_TYPE_BLOB:
132244
132661
  return TryCastCInternal<duckdb_blob, RESULT_TYPE, FromCBlobCastWrapper>(result, col, row);
132245
- default: // LCOV_EXCL_START
132662
+ default: { // LCOV_EXCL_START
132246
132663
  // invalid type for C to C++ conversion
132247
132664
  D_ASSERT(0);
132248
132665
  return FetchDefaultValue::Operation<RESULT_TYPE>();
132249
132666
  } // LCOV_EXCL_STOP
132667
+ }
132250
132668
  }
132251
132669
 
132252
- //===--------------------------------------------------------------------===//
132253
- // duckdb_value_ functions
132254
- //===--------------------------------------------------------------------===//
132670
+ } // namespace duckdb
132671
+
132672
+
132673
+ using duckdb::date_t;
132674
+ using duckdb::dtime_t;
132675
+ using duckdb::FetchDefaultValue;
132676
+ using duckdb::GetInternalCValue;
132677
+ using duckdb::hugeint_t;
132678
+ using duckdb::interval_t;
132679
+ using duckdb::StringCast;
132680
+ using duckdb::timestamp_t;
132681
+ using duckdb::ToCStringCastWrapper;
132682
+ using duckdb::UnsafeFetch;
132683
+
132255
132684
  bool duckdb_value_boolean(duckdb_result *result, idx_t col, idx_t row) {
132256
132685
  return GetInternalCValue<bool>(result, col, row);
132257
132686
  }
@@ -132272,16 +132701,25 @@ int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row) {
132272
132701
  return GetInternalCValue<int64_t>(result, col, row);
132273
132702
  }
132274
132703
 
132275
- duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row) {
132276
- duckdb_decimal result_value;
132277
-
132704
+ static bool ResultIsDecimal(duckdb_result *result, idx_t col) {
132705
+ if (!result) {
132706
+ return false;
132707
+ }
132708
+ if (!result->internal_data) {
132709
+ return false;
132710
+ }
132278
132711
  auto result_data = (duckdb::DuckDBResultData *)result->internal_data;
132279
- result_data->result->types[col].GetDecimalProperties(result_value.width, result_value.scale);
132712
+ auto &query_result = result_data->result;
132713
+ auto &source_type = query_result->types[col];
132714
+ return source_type.id() == duckdb::LogicalTypeId::DECIMAL;
132715
+ }
132280
132716
 
132281
- auto internal_value = GetInternalCValue<hugeint_t>(result, col, row);
132282
- result_value.value.lower = internal_value.lower;
132283
- result_value.value.upper = internal_value.upper;
132284
- return result_value;
132717
+ duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row) {
132718
+ if (!CanFetchValue(result, col, row) || !ResultIsDecimal(result, col)) {
132719
+ return FetchDefaultValue::Operation<duckdb_decimal>();
132720
+ }
132721
+
132722
+ return GetInternalCValue<duckdb_decimal>(result, col, row);
132285
132723
  }
132286
132724
 
132287
132725
  duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row) {
@@ -132344,7 +132782,7 @@ duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t ro
132344
132782
  }
132345
132783
 
132346
132784
  char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row) {
132347
- return GetInternalCValue<char *, ToCStringCastWrapper<duckdb::StringCast>>(result, col, row);
132785
+ return GetInternalCValue<char *, ToCStringCastWrapper<StringCast>>(result, col, row);
132348
132786
  }
132349
132787
 
132350
132788
  char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row) {