duckdb 0.5.2-dev1545.0 → 0.5.2-dev1579.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);
@@ -111076,14 +111082,18 @@ namespace duckdb {
111076
111082
  static void CardinalityFunction(DataChunk &args, ExpressionState &state, Vector &result) {
111077
111083
  auto &map = args.data[0];
111078
111084
  UnifiedVectorFormat list_data;
111085
+ UnifiedVectorFormat map_data;
111079
111086
  result.SetVectorType(VectorType::FLAT_VECTOR);
111080
111087
  auto result_data = FlatVector::GetData<uint64_t>(result);
111088
+ auto &result_validity = FlatVector::Validity(result);
111081
111089
 
111090
+ map.ToUnifiedFormat(args.size(), map_data);
111082
111091
  auto &children = StructVector::GetEntries(map);
111083
111092
  children[0]->ToUnifiedFormat(args.size(), list_data);
111084
111093
  for (idx_t row = 0; row < args.size(); row++) {
111085
111094
  auto list_entry = ((list_entry_t *)list_data.data)[list_data.sel->get_index(row)];
111086
111095
  result_data[row] = list_entry.length;
111096
+ result_validity.Set(row, map_data.validity.RowIsValid(map_data.sel->get_index(row)));
111087
111097
  }
111088
111098
 
111089
111099
  if (args.size() == 1) {
@@ -111093,6 +111103,9 @@ static void CardinalityFunction(DataChunk &args, ExpressionState &state, Vector
111093
111103
 
111094
111104
  static unique_ptr<FunctionData> CardinalityBind(ClientContext &context, ScalarFunction &bound_function,
111095
111105
  vector<unique_ptr<Expression>> &arguments) {
111106
+ if (arguments.size() != 1) {
111107
+ throw BinderException("Cardinality must have exactly one arguments");
111108
+ }
111096
111109
 
111097
111110
  if (arguments[0]->return_type.id() != LogicalTypeId::MAP) {
111098
111111
  throw BinderException("Cardinality can only operate on MAPs");
@@ -111105,7 +111118,7 @@ static unique_ptr<FunctionData> CardinalityBind(ClientContext &context, ScalarFu
111105
111118
  void CardinalityFun::RegisterFunction(BuiltinFunctions &set) {
111106
111119
  ScalarFunction fun("cardinality", {LogicalType::ANY}, LogicalType::UBIGINT, CardinalityFunction, CardinalityBind);
111107
111120
  fun.varargs = LogicalType::ANY;
111108
- fun.null_handling = FunctionNullHandling::SPECIAL_HANDLING;
111121
+ fun.null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING;
111109
111122
  set.AddFunction(fun);
111110
111123
  }
111111
111124
 
@@ -129375,7 +129388,7 @@ void BaseAppender::Close() {
129375
129388
  //===----------------------------------------------------------------------===//
129376
129389
  // DuckDB
129377
129390
  //
129378
- // duckdb/main/capi_internal.hpp
129391
+ // duckdb/main/capi/capi_internal.hpp
129379
129392
  //
129380
129393
  //
129381
129394
  //===----------------------------------------------------------------------===//
@@ -129761,6 +129774,399 @@ duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_st
129761
129774
  *out_result = (duckdb_arrow)arrow_wrapper;
129762
129775
  return !arrow_wrapper->result->HasError() ? DuckDBSuccess : DuckDBError;
129763
129776
  }
129777
+ //===----------------------------------------------------------------------===//
129778
+ // DuckDB
129779
+ //
129780
+ // duckdb/main/capi/capi_cast_from_decimal.hpp
129781
+ //
129782
+ //
129783
+ //===----------------------------------------------------------------------===//
129784
+
129785
+
129786
+
129787
+ //===----------------------------------------------------------------------===//
129788
+ // DuckDB
129789
+ //
129790
+ // duckdb/main/capi/cast/utils.hpp
129791
+ //
129792
+ //
129793
+ //===----------------------------------------------------------------------===//
129794
+
129795
+
129796
+
129797
+
129798
+
129799
+
129800
+
129801
+
129802
+ namespace duckdb {
129803
+
129804
+ //===--------------------------------------------------------------------===//
129805
+ // Unsafe Fetch (for internal use only)
129806
+ //===--------------------------------------------------------------------===//
129807
+ template <class T>
129808
+ T UnsafeFetchFromPtr(void *pointer) {
129809
+ return *((T *)pointer);
129810
+ }
129811
+
129812
+ template <class T>
129813
+ void *UnsafeFetchPtr(duckdb_result *result, idx_t col, idx_t row) {
129814
+ D_ASSERT(row < result->__deprecated_row_count);
129815
+ return (void *)&(((T *)result->__deprecated_columns[col].__deprecated_data)[row]);
129816
+ }
129817
+
129818
+ template <class T>
129819
+ T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) {
129820
+ return UnsafeFetchFromPtr<T>(UnsafeFetchPtr<T>(result, col, row));
129821
+ }
129822
+
129823
+ //===--------------------------------------------------------------------===//
129824
+ // Fetch Default Value
129825
+ //===--------------------------------------------------------------------===//
129826
+ struct FetchDefaultValue {
129827
+ template <class T>
129828
+ static T Operation() {
129829
+ return 0;
129830
+ }
129831
+ };
129832
+
129833
+ template <>
129834
+ duckdb_decimal FetchDefaultValue::Operation();
129835
+ template <>
129836
+ date_t FetchDefaultValue::Operation();
129837
+ template <>
129838
+ dtime_t FetchDefaultValue::Operation();
129839
+ template <>
129840
+ timestamp_t FetchDefaultValue::Operation();
129841
+ template <>
129842
+ interval_t FetchDefaultValue::Operation();
129843
+ template <>
129844
+ char *FetchDefaultValue::Operation();
129845
+ template <>
129846
+ duckdb_blob FetchDefaultValue::Operation();
129847
+
129848
+ //===--------------------------------------------------------------------===//
129849
+ // String Casts
129850
+ //===--------------------------------------------------------------------===//
129851
+ template <class OP>
129852
+ struct FromCStringCastWrapper {
129853
+ template <class SOURCE_TYPE, class RESULT_TYPE>
129854
+ static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
129855
+ string_t input(input_str);
129856
+ return OP::template Operation<string_t, RESULT_TYPE>(input, result);
129857
+ }
129858
+ };
129859
+
129860
+ template <class OP>
129861
+ struct ToCStringCastWrapper {
129862
+ template <class SOURCE_TYPE, class RESULT_TYPE>
129863
+ static bool Operation(SOURCE_TYPE input, RESULT_TYPE &result) {
129864
+ Vector result_vector(LogicalType::VARCHAR, nullptr);
129865
+ auto result_string = OP::template Operation<SOURCE_TYPE>(input, result_vector);
129866
+ auto result_size = result_string.GetSize();
129867
+ auto result_data = result_string.GetDataUnsafe();
129868
+
129869
+ result = (char *)duckdb_malloc(result_size + 1);
129870
+ memcpy(result, result_data, result_size);
129871
+ result[result_size] = '\0';
129872
+ return true;
129873
+ }
129874
+ };
129875
+
129876
+ //===--------------------------------------------------------------------===//
129877
+ // Blob Casts
129878
+ //===--------------------------------------------------------------------===//
129879
+ struct FromCBlobCastWrapper {
129880
+ template <class SOURCE_TYPE, class RESULT_TYPE>
129881
+ static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
129882
+ return false;
129883
+ }
129884
+ };
129885
+
129886
+ template <>
129887
+ bool FromCBlobCastWrapper::Operation(duckdb_blob input, char *&result);
129888
+
129889
+ template <class SOURCE_TYPE, class RESULT_TYPE, class OP>
129890
+ RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) {
129891
+ RESULT_TYPE result_value;
129892
+ try {
129893
+ if (!OP::template Operation<SOURCE_TYPE, RESULT_TYPE>(UnsafeFetch<SOURCE_TYPE>(result, col, row),
129894
+ result_value)) {
129895
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129896
+ }
129897
+ } catch (...) {
129898
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129899
+ }
129900
+ return result_value;
129901
+ }
129902
+
129903
+ } // namespace duckdb
129904
+
129905
+ bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row);
129906
+ bool CanUseDeprecatedFetch(duckdb_result *result, idx_t col, idx_t row);
129907
+
129908
+
129909
+ namespace duckdb {
129910
+
129911
+ //! DECIMAL -> ?
129912
+ template <class RESULT_TYPE>
129913
+ bool CastDecimalCInternal(duckdb_result *source, RESULT_TYPE &result, idx_t col, idx_t row) {
129914
+ auto result_data = (duckdb::DuckDBResultData *)source->internal_data;
129915
+ auto &query_result = result_data->result;
129916
+ auto &source_type = query_result->types[col];
129917
+ auto width = duckdb::DecimalType::GetWidth(source_type);
129918
+ auto scale = duckdb::DecimalType::GetScale(source_type);
129919
+ void *source_address = UnsafeFetchPtr<hugeint_t>(source, col, row);
129920
+ switch (source_type.InternalType()) {
129921
+ case duckdb::PhysicalType::INT16:
129922
+ return duckdb::TryCastFromDecimal::Operation<int16_t, RESULT_TYPE>(UnsafeFetchFromPtr<int16_t>(source_address),
129923
+ result, nullptr, width, scale);
129924
+ case duckdb::PhysicalType::INT32:
129925
+ return duckdb::TryCastFromDecimal::Operation<int32_t, RESULT_TYPE>(UnsafeFetchFromPtr<int32_t>(source_address),
129926
+ result, nullptr, width, scale);
129927
+ case duckdb::PhysicalType::INT64:
129928
+ return duckdb::TryCastFromDecimal::Operation<int64_t, RESULT_TYPE>(UnsafeFetchFromPtr<int64_t>(source_address),
129929
+ result, nullptr, width, scale);
129930
+ case duckdb::PhysicalType::INT128:
129931
+ return duckdb::TryCastFromDecimal::Operation<hugeint_t, RESULT_TYPE>(
129932
+ UnsafeFetchFromPtr<hugeint_t>(source_address), result, nullptr, width, scale);
129933
+ default:
129934
+ throw duckdb::InternalException("Unimplemented internal type for decimal");
129935
+ }
129936
+ }
129937
+
129938
+ //! DECIMAL -> VARCHAR
129939
+ template <>
129940
+ bool CastDecimalCInternal(duckdb_result *source, char *&result, idx_t col, idx_t row);
129941
+
129942
+ //! DECIMAL -> DECIMAL (internal fetch)
129943
+ template <>
129944
+ bool CastDecimalCInternal(duckdb_result *source, duckdb_decimal &result, idx_t col, idx_t row);
129945
+
129946
+ //! DECIMAL -> ...
129947
+ template <class RESULT_TYPE>
129948
+ RESULT_TYPE TryCastDecimalCInternal(duckdb_result *source, idx_t col, idx_t row) {
129949
+ RESULT_TYPE result_value;
129950
+ try {
129951
+ if (!CastDecimalCInternal<RESULT_TYPE>(source, result_value, col, row)) {
129952
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129953
+ }
129954
+ } catch (...) {
129955
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
129956
+ }
129957
+ return result_value;
129958
+ }
129959
+
129960
+ } // namespace duckdb
129961
+
129962
+
129963
+
129964
+ namespace duckdb {
129965
+
129966
+ //! DECIMAL -> VARCHAR
129967
+ template <>
129968
+ bool CastDecimalCInternal(duckdb_result *source, char *&result, idx_t col, idx_t row) {
129969
+ auto result_data = (duckdb::DuckDBResultData *)source->internal_data;
129970
+ auto &query_result = result_data->result;
129971
+ auto &source_type = query_result->types[col];
129972
+ auto width = duckdb::DecimalType::GetWidth(source_type);
129973
+ auto scale = duckdb::DecimalType::GetScale(source_type);
129974
+ duckdb::Vector result_vec(duckdb::LogicalType::VARCHAR, false, false);
129975
+ duckdb::string_t result_string;
129976
+ void *source_address = UnsafeFetchPtr<hugeint_t>(source, col, row);
129977
+ switch (source_type.InternalType()) {
129978
+ case duckdb::PhysicalType::INT16:
129979
+ result_string = duckdb::StringCastFromDecimal::Operation<int16_t>(UnsafeFetchFromPtr<int16_t>(source_address),
129980
+ width, scale, result_vec);
129981
+ break;
129982
+ case duckdb::PhysicalType::INT32:
129983
+ result_string = duckdb::StringCastFromDecimal::Operation<int32_t>(UnsafeFetchFromPtr<int32_t>(source_address),
129984
+ width, scale, result_vec);
129985
+ break;
129986
+ case duckdb::PhysicalType::INT64:
129987
+ result_string = duckdb::StringCastFromDecimal::Operation<int64_t>(UnsafeFetchFromPtr<int64_t>(source_address),
129988
+ width, scale, result_vec);
129989
+ break;
129990
+ case duckdb::PhysicalType::INT128:
129991
+ result_string = duckdb::StringCastFromDecimal::Operation<hugeint_t>(
129992
+ UnsafeFetchFromPtr<hugeint_t>(source_address), width, scale, result_vec);
129993
+ break;
129994
+ default:
129995
+ throw duckdb::InternalException("Unimplemented internal type for decimal");
129996
+ }
129997
+ result = (char *)duckdb_malloc(sizeof(char) * (result_string.GetSize() + 1));
129998
+ memcpy(result, result_string.GetDataUnsafe(), result_string.GetSize());
129999
+ result[result_string.GetSize()] = '\0';
130000
+ return true;
130001
+ }
130002
+
130003
+ template <class INTERNAL_TYPE>
130004
+ duckdb_hugeint FetchInternals(void *source_address) {
130005
+ throw duckdb::NotImplementedException("FetchInternals not implemented for internal type");
130006
+ }
130007
+
130008
+ template <>
130009
+ duckdb_hugeint FetchInternals<int16_t>(void *source_address) {
130010
+ duckdb_hugeint result;
130011
+ int16_t intermediate_result;
130012
+
130013
+ if (!TryCast::Operation<int16_t, int16_t>(UnsafeFetchFromPtr<int16_t>(source_address), intermediate_result)) {
130014
+ intermediate_result = FetchDefaultValue::Operation<int16_t>();
130015
+ }
130016
+ hugeint_t hugeint_result = Hugeint::Cast<int16_t>(intermediate_result);
130017
+ result.lower = hugeint_result.lower;
130018
+ result.upper = hugeint_result.upper;
130019
+ return result;
130020
+ }
130021
+ template <>
130022
+ duckdb_hugeint FetchInternals<int32_t>(void *source_address) {
130023
+ duckdb_hugeint result;
130024
+ int32_t intermediate_result;
130025
+
130026
+ if (!TryCast::Operation<int32_t, int32_t>(UnsafeFetchFromPtr<int32_t>(source_address), intermediate_result)) {
130027
+ intermediate_result = FetchDefaultValue::Operation<int32_t>();
130028
+ }
130029
+ hugeint_t hugeint_result = Hugeint::Cast<int32_t>(intermediate_result);
130030
+ result.lower = hugeint_result.lower;
130031
+ result.upper = hugeint_result.upper;
130032
+ return result;
130033
+ }
130034
+ template <>
130035
+ duckdb_hugeint FetchInternals<int64_t>(void *source_address) {
130036
+ duckdb_hugeint result;
130037
+ int64_t intermediate_result;
130038
+
130039
+ if (!TryCast::Operation<int64_t, int64_t>(UnsafeFetchFromPtr<int64_t>(source_address), intermediate_result)) {
130040
+ intermediate_result = FetchDefaultValue::Operation<int64_t>();
130041
+ }
130042
+ hugeint_t hugeint_result = Hugeint::Cast<int64_t>(intermediate_result);
130043
+ result.lower = hugeint_result.lower;
130044
+ result.upper = hugeint_result.upper;
130045
+ return result;
130046
+ }
130047
+ template <>
130048
+ duckdb_hugeint FetchInternals<hugeint_t>(void *source_address) {
130049
+ duckdb_hugeint result;
130050
+ hugeint_t intermediate_result;
130051
+
130052
+ if (!TryCast::Operation<hugeint_t, hugeint_t>(UnsafeFetchFromPtr<hugeint_t>(source_address), intermediate_result)) {
130053
+ intermediate_result = FetchDefaultValue::Operation<hugeint_t>();
130054
+ }
130055
+ result.lower = intermediate_result.lower;
130056
+ result.upper = intermediate_result.upper;
130057
+ return result;
130058
+ }
130059
+
130060
+ //! DECIMAL -> DECIMAL (internal fetch)
130061
+ template <>
130062
+ bool CastDecimalCInternal(duckdb_result *source, duckdb_decimal &result, idx_t col, idx_t row) {
130063
+ auto result_data = (duckdb::DuckDBResultData *)source->internal_data;
130064
+ result_data->result->types[col].GetDecimalProperties(result.width, result.scale);
130065
+ auto source_address = UnsafeFetchPtr<hugeint_t>(source, col, row);
130066
+
130067
+ if (result.width > duckdb::Decimal::MAX_WIDTH_INT64) {
130068
+ result.value = FetchInternals<hugeint_t>(source_address);
130069
+ } else if (result.width > duckdb::Decimal::MAX_WIDTH_INT32) {
130070
+ result.value = FetchInternals<int64_t>(source_address);
130071
+ } else if (result.width > duckdb::Decimal::MAX_WIDTH_INT16) {
130072
+ result.value = FetchInternals<int32_t>(source_address);
130073
+ } else {
130074
+ result.value = FetchInternals<int16_t>(source_address);
130075
+ }
130076
+ return true;
130077
+ }
130078
+
130079
+ } // namespace duckdb
130080
+
130081
+
130082
+ namespace duckdb {
130083
+
130084
+ template <>
130085
+ duckdb_decimal FetchDefaultValue::Operation() {
130086
+ duckdb_decimal result;
130087
+ result.scale = 0;
130088
+ result.width = 0;
130089
+ result.value = {0, 0};
130090
+ return result;
130091
+ }
130092
+
130093
+ template <>
130094
+ date_t FetchDefaultValue::Operation() {
130095
+ date_t result;
130096
+ result.days = 0;
130097
+ return result;
130098
+ }
130099
+
130100
+ template <>
130101
+ dtime_t FetchDefaultValue::Operation() {
130102
+ dtime_t result;
130103
+ result.micros = 0;
130104
+ return result;
130105
+ }
130106
+
130107
+ template <>
130108
+ timestamp_t FetchDefaultValue::Operation() {
130109
+ timestamp_t result;
130110
+ result.value = 0;
130111
+ return result;
130112
+ }
130113
+
130114
+ template <>
130115
+ interval_t FetchDefaultValue::Operation() {
130116
+ interval_t result;
130117
+ result.months = 0;
130118
+ result.days = 0;
130119
+ result.micros = 0;
130120
+ return result;
130121
+ }
130122
+
130123
+ template <>
130124
+ char *FetchDefaultValue::Operation() {
130125
+ return nullptr;
130126
+ }
130127
+
130128
+ template <>
130129
+ duckdb_blob FetchDefaultValue::Operation() {
130130
+ duckdb_blob result;
130131
+ result.data = nullptr;
130132
+ result.size = 0;
130133
+ return result;
130134
+ }
130135
+
130136
+ //===--------------------------------------------------------------------===//
130137
+ // Blob Casts
130138
+ //===--------------------------------------------------------------------===//
130139
+
130140
+ template <>
130141
+ bool FromCBlobCastWrapper::Operation(duckdb_blob input, char *&result) {
130142
+ string_t input_str((const char *)input.data, input.size);
130143
+ return ToCStringCastWrapper<duckdb::CastFromBlob>::template Operation<string_t, char *>(input_str, result);
130144
+ }
130145
+
130146
+ } // namespace duckdb
130147
+
130148
+ bool CanUseDeprecatedFetch(duckdb_result *result, idx_t col, idx_t row) {
130149
+ if (!result) {
130150
+ return false;
130151
+ }
130152
+ if (!duckdb::deprecated_materialize_result(result)) {
130153
+ return false;
130154
+ }
130155
+ if (col >= result->__deprecated_column_count || row >= result->__deprecated_row_count) {
130156
+ return false;
130157
+ }
130158
+ return true;
130159
+ }
130160
+
130161
+ bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row) {
130162
+ if (!CanUseDeprecatedFetch(result, col, row)) {
130163
+ return false;
130164
+ }
130165
+ if (result->__deprecated_columns[col].__deprecated_nullmask[row]) {
130166
+ return false;
130167
+ }
130168
+ return true;
130169
+ }
129764
130170
 
129765
130171
 
129766
130172
 
@@ -130382,6 +130788,142 @@ idx_t duckdb_vector_size() {
130382
130788
 
130383
130789
 
130384
130790
 
130791
+ //===----------------------------------------------------------------------===//
130792
+ // DuckDB
130793
+ //
130794
+ // duckdb/main/capi/capi_cast_from_decimal.hpp
130795
+ //
130796
+ //
130797
+ //===----------------------------------------------------------------------===//
130798
+
130799
+
130800
+
130801
+
130802
+
130803
+ namespace duckdb {
130804
+
130805
+ template <class INTERNAL_TYPE>
130806
+ struct ToCDecimalCastWrapper {
130807
+ template <class SOURCE_TYPE>
130808
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130809
+ throw NotImplementedException("Type not implemented for CDecimalCastWrapper");
130810
+ }
130811
+ };
130812
+
130813
+ //! Hugeint
130814
+ template <>
130815
+ struct ToCDecimalCastWrapper<hugeint_t> {
130816
+ template <class SOURCE_TYPE>
130817
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130818
+ hugeint_t intermediate_result;
130819
+
130820
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, hugeint_t>(input, intermediate_result, error, width, scale)) {
130821
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130822
+ return false;
130823
+ }
130824
+ result.scale = scale;
130825
+ result.width = width;
130826
+
130827
+ duckdb_hugeint hugeint_value;
130828
+ hugeint_value.upper = intermediate_result.upper;
130829
+ hugeint_value.lower = intermediate_result.lower;
130830
+ result.value = hugeint_value;
130831
+ return true;
130832
+ }
130833
+ };
130834
+
130835
+ //! FIXME: reduce duplication here by just matching on the signed-ness of the type
130836
+ //! INTERNAL_TYPE = int16_t
130837
+ template <>
130838
+ struct ToCDecimalCastWrapper<int16_t> {
130839
+ template <class SOURCE_TYPE>
130840
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130841
+ int16_t intermediate_result;
130842
+
130843
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, int16_t>(input, intermediate_result, error, width, scale)) {
130844
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130845
+ return false;
130846
+ }
130847
+ hugeint_t hugeint_result = Hugeint::Convert(intermediate_result);
130848
+
130849
+ result.scale = scale;
130850
+ result.width = width;
130851
+
130852
+ duckdb_hugeint hugeint_value;
130853
+ hugeint_value.upper = hugeint_result.upper;
130854
+ hugeint_value.lower = hugeint_result.lower;
130855
+ result.value = hugeint_value;
130856
+ return true;
130857
+ }
130858
+ };
130859
+ //! INTERNAL_TYPE = int32_t
130860
+ template <>
130861
+ struct ToCDecimalCastWrapper<int32_t> {
130862
+ template <class SOURCE_TYPE>
130863
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130864
+ int32_t intermediate_result;
130865
+
130866
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, int32_t>(input, intermediate_result, error, width, scale)) {
130867
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130868
+ return false;
130869
+ }
130870
+ hugeint_t hugeint_result = Hugeint::Convert(intermediate_result);
130871
+
130872
+ result.scale = scale;
130873
+ result.width = width;
130874
+
130875
+ duckdb_hugeint hugeint_value;
130876
+ hugeint_value.upper = hugeint_result.upper;
130877
+ hugeint_value.lower = hugeint_result.lower;
130878
+ result.value = hugeint_value;
130879
+ return true;
130880
+ }
130881
+ };
130882
+ //! INTERNAL_TYPE = int64_t
130883
+ template <>
130884
+ struct ToCDecimalCastWrapper<int64_t> {
130885
+ template <class SOURCE_TYPE>
130886
+ static bool Operation(SOURCE_TYPE input, duckdb_decimal &result, std::string *error, uint8_t width, uint8_t scale) {
130887
+ int64_t intermediate_result;
130888
+
130889
+ if (!TryCastToDecimal::Operation<SOURCE_TYPE, int64_t>(input, intermediate_result, error, width, scale)) {
130890
+ result = FetchDefaultValue::Operation<duckdb_decimal>();
130891
+ return false;
130892
+ }
130893
+ hugeint_t hugeint_result = Hugeint::Convert(intermediate_result);
130894
+
130895
+ result.scale = scale;
130896
+ result.width = width;
130897
+
130898
+ duckdb_hugeint hugeint_value;
130899
+ hugeint_value.upper = hugeint_result.upper;
130900
+ hugeint_value.lower = hugeint_result.lower;
130901
+ result.value = hugeint_value;
130902
+ return true;
130903
+ }
130904
+ };
130905
+
130906
+ template <class SOURCE_TYPE, class OP>
130907
+ duckdb_decimal TryCastToDecimalCInternal(SOURCE_TYPE source, uint8_t width, uint8_t scale) {
130908
+ duckdb_decimal result;
130909
+ try {
130910
+ if (!OP::template Operation<SOURCE_TYPE>(source, result, nullptr, width, scale)) {
130911
+ return FetchDefaultValue::Operation<duckdb_decimal>();
130912
+ }
130913
+ } catch (...) {
130914
+ return FetchDefaultValue::Operation<duckdb_decimal>();
130915
+ }
130916
+ return result;
130917
+ }
130918
+
130919
+ template <class SOURCE_TYPE, class OP>
130920
+ duckdb_decimal TryCastToDecimalCInternal(duckdb_result *result, idx_t col, idx_t row, uint8_t width, uint8_t scale) {
130921
+ return TryCastToDecimalCInternal<SOURCE_TYPE, OP>(UnsafeFetch<SOURCE_TYPE>(result, col, row), width, scale);
130922
+ }
130923
+
130924
+ } // namespace duckdb
130925
+
130926
+
130385
130927
  using duckdb::Hugeint;
130386
130928
  using duckdb::hugeint_t;
130387
130929
  using duckdb::Value;
@@ -130393,6 +130935,26 @@ double duckdb_hugeint_to_double(duckdb_hugeint val) {
130393
130935
  return Hugeint::Cast<double>(internal);
130394
130936
  }
130395
130937
 
130938
+ static duckdb_decimal to_decimal_cast(double val, uint8_t width, uint8_t scale) {
130939
+ if (width > duckdb::Decimal::MAX_WIDTH_INT64) {
130940
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<hugeint_t>>(val, width, scale);
130941
+ }
130942
+ if (width > duckdb::Decimal::MAX_WIDTH_INT32) {
130943
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int64_t>>(val, width, scale);
130944
+ }
130945
+ if (width > duckdb::Decimal::MAX_WIDTH_INT16) {
130946
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int32_t>>(val, width, scale);
130947
+ }
130948
+ return duckdb::TryCastToDecimalCInternal<double, duckdb::ToCDecimalCastWrapper<int16_t>>(val, width, scale);
130949
+ }
130950
+
130951
+ duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale) {
130952
+ if (scale > width || width > duckdb::Decimal::MAX_WIDTH_INT128) {
130953
+ return duckdb::FetchDefaultValue::Operation<duckdb_decimal>();
130954
+ }
130955
+ return to_decimal_cast(val, width, scale);
130956
+ }
130957
+
130396
130958
  duckdb_hugeint duckdb_double_to_hugeint(double val) {
130397
130959
  hugeint_t internal_result;
130398
130960
  if (!Value::DoubleIsFinite(val) || !Hugeint::TryConvert<double>(val, internal_result)) {
@@ -130711,6 +131273,7 @@ duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb
130711
131273
 
130712
131274
 
130713
131275
 
131276
+
130714
131277
  using duckdb::Connection;
130715
131278
  using duckdb::date_t;
130716
131279
  using duckdb::dtime_t;
@@ -130806,11 +131369,15 @@ duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx
130806
131369
  return duckdb_bind_value(prepared_statement, param_idx, Value::BIGINT(val));
130807
131370
  }
130808
131371
 
130809
- duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, duckdb_hugeint val) {
131372
+ static hugeint_t duckdb_internal_hugeint(duckdb_hugeint val) {
130810
131373
  hugeint_t internal;
130811
131374
  internal.lower = val.lower;
130812
131375
  internal.upper = val.upper;
130813
- return duckdb_bind_value(prepared_statement, param_idx, Value::HUGEINT(internal));
131376
+ return internal;
131377
+ }
131378
+
131379
+ duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, duckdb_hugeint val) {
131380
+ return duckdb_bind_value(prepared_statement, param_idx, Value::HUGEINT(duckdb_internal_hugeint(val)));
130814
131381
  }
130815
131382
 
130816
131383
  duckdb_state duckdb_bind_uint8(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint8_t val) {
@@ -130871,6 +131438,15 @@ duckdb_state duckdb_bind_varchar_length(duckdb_prepared_statement prepared_state
130871
131438
  }
130872
131439
  }
130873
131440
 
131441
+ duckdb_state duckdb_bind_decimal(duckdb_prepared_statement prepared_statement, idx_t param_idx, duckdb_decimal val) {
131442
+ auto hugeint_val = duckdb_internal_hugeint(val.value);
131443
+ if (val.width > duckdb::Decimal::MAX_WIDTH_INT64) {
131444
+ return duckdb_bind_value(prepared_statement, param_idx, Value::DECIMAL(hugeint_val, val.width, val.scale));
131445
+ }
131446
+ auto value = hugeint_val.lower;
131447
+ return duckdb_bind_value(prepared_statement, param_idx, Value::DECIMAL((int64_t)value, val.width, val.scale));
131448
+ }
131449
+
130874
131450
  duckdb_state duckdb_bind_blob(duckdb_prepared_statement prepared_statement, idx_t param_idx, const void *data,
130875
131451
  idx_t length) {
130876
131452
  return duckdb_bind_value(prepared_statement, param_idx, Value::BLOB((duckdb::const_data_ptr_t)data, length));
@@ -132026,180 +132602,28 @@ void duckdb_destroy_task_state(duckdb_task_state state_p) {
132026
132602
 
132027
132603
 
132028
132604
 
132605
+ //===----------------------------------------------------------------------===//
132606
+ // DuckDB
132607
+ //
132608
+ // duckdb/main/capi/cast/generic_cast.hpp
132609
+ //
132610
+ //
132611
+ //===----------------------------------------------------------------------===//
132029
132612
 
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
132613
 
132101
- template <>
132102
- duckdb_blob FetchDefaultValue::Operation() {
132103
- duckdb_blob result;
132104
- result.data = nullptr;
132105
- result.size = 0;
132106
- return result;
132107
- }
132108
132614
 
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
132615
 
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
132616
 
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
132617
 
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
132618
 
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
132619
 
132155
- using duckdb::FetchDefaultValue;
132156
- using duckdb::FromCBlobCastWrapper;
132157
- using duckdb::FromCStringCastWrapper;
132158
- using duckdb::ToCStringCastWrapper;
132159
- using duckdb::UnsafeFetch;
132160
132620
 
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
132621
 
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
132622
 
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
- }
132623
+ namespace duckdb {
132200
132624
 
132201
132625
  template <class RESULT_TYPE, class OP = duckdb::TryCast>
132202
- static RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row) {
132626
+ RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row) {
132203
132627
  if (!CanFetchValue(result, col, row)) {
132204
132628
  return FetchDefaultValue::Operation<RESULT_TYPE>();
132205
132629
  }
@@ -132235,23 +132659,35 @@ static RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row
132235
132659
  case DUCKDB_TYPE_HUGEINT:
132236
132660
  return TryCastCInternal<hugeint_t, RESULT_TYPE, OP>(result, col, row);
132237
132661
  case DUCKDB_TYPE_DECIMAL:
132238
- return TryCastCInternal<hugeint_t, RESULT_TYPE, OP>(result, col, row);
132662
+ return TryCastDecimalCInternal<RESULT_TYPE>(result, col, row);
132239
132663
  case DUCKDB_TYPE_INTERVAL:
132240
132664
  return TryCastCInternal<interval_t, RESULT_TYPE, OP>(result, col, row);
132241
132665
  case DUCKDB_TYPE_VARCHAR:
132242
132666
  return TryCastCInternal<char *, RESULT_TYPE, FromCStringCastWrapper<OP>>(result, col, row);
132243
132667
  case DUCKDB_TYPE_BLOB:
132244
132668
  return TryCastCInternal<duckdb_blob, RESULT_TYPE, FromCBlobCastWrapper>(result, col, row);
132245
- default: // LCOV_EXCL_START
132669
+ default: { // LCOV_EXCL_START
132246
132670
  // invalid type for C to C++ conversion
132247
132671
  D_ASSERT(0);
132248
132672
  return FetchDefaultValue::Operation<RESULT_TYPE>();
132249
132673
  } // LCOV_EXCL_STOP
132674
+ }
132250
132675
  }
132251
132676
 
132252
- //===--------------------------------------------------------------------===//
132253
- // duckdb_value_ functions
132254
- //===--------------------------------------------------------------------===//
132677
+ } // namespace duckdb
132678
+
132679
+
132680
+ using duckdb::date_t;
132681
+ using duckdb::dtime_t;
132682
+ using duckdb::FetchDefaultValue;
132683
+ using duckdb::GetInternalCValue;
132684
+ using duckdb::hugeint_t;
132685
+ using duckdb::interval_t;
132686
+ using duckdb::StringCast;
132687
+ using duckdb::timestamp_t;
132688
+ using duckdb::ToCStringCastWrapper;
132689
+ using duckdb::UnsafeFetch;
132690
+
132255
132691
  bool duckdb_value_boolean(duckdb_result *result, idx_t col, idx_t row) {
132256
132692
  return GetInternalCValue<bool>(result, col, row);
132257
132693
  }
@@ -132272,16 +132708,25 @@ int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row) {
132272
132708
  return GetInternalCValue<int64_t>(result, col, row);
132273
132709
  }
132274
132710
 
132275
- duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row) {
132276
- duckdb_decimal result_value;
132277
-
132711
+ static bool ResultIsDecimal(duckdb_result *result, idx_t col) {
132712
+ if (!result) {
132713
+ return false;
132714
+ }
132715
+ if (!result->internal_data) {
132716
+ return false;
132717
+ }
132278
132718
  auto result_data = (duckdb::DuckDBResultData *)result->internal_data;
132279
- result_data->result->types[col].GetDecimalProperties(result_value.width, result_value.scale);
132719
+ auto &query_result = result_data->result;
132720
+ auto &source_type = query_result->types[col];
132721
+ return source_type.id() == duckdb::LogicalTypeId::DECIMAL;
132722
+ }
132280
132723
 
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;
132724
+ duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row) {
132725
+ if (!CanFetchValue(result, col, row) || !ResultIsDecimal(result, col)) {
132726
+ return FetchDefaultValue::Operation<duckdb_decimal>();
132727
+ }
132728
+
132729
+ return GetInternalCValue<duckdb_decimal>(result, col, row);
132285
132730
  }
132286
132731
 
132287
132732
  duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row) {
@@ -132344,7 +132789,7 @@ duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t ro
132344
132789
  }
132345
132790
 
132346
132791
  char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row) {
132347
- return GetInternalCValue<char *, ToCStringCastWrapper<duckdb::StringCast>>(result, col, row);
132792
+ return GetInternalCValue<char *, ToCStringCastWrapper<StringCast>>(result, col, row);
132348
132793
  }
132349
132794
 
132350
132795
  char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row) {