duckdb 0.3.3-dev1232.0 → 0.3.3-dev1273.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
@@ -18236,10 +18236,14 @@ duckdb::string_t StringCastTZ::Operation(timestamp_t input, Vector &result);
18236
18236
 
18237
18237
 
18238
18238
 
18239
+
18239
18240
  namespace duckdb {
18240
18241
 
18241
18242
  template <class SRC, class DST>
18242
18243
  static bool TryCastWithOverflowCheck(SRC value, DST &result) {
18244
+ if (!Value::IsFinite<SRC>(value)) {
18245
+ return false;
18246
+ }
18243
18247
  if (NumericLimits<SRC>::IsSigned() != NumericLimits<DST>::IsSigned()) {
18244
18248
  if (NumericLimits<SRC>::IsSigned()) {
18245
18249
  // signed to unsigned conversion
@@ -18282,40 +18286,58 @@ static bool TryCastWithOverflowCheck(SRC value, DST &result) {
18282
18286
  }
18283
18287
  }
18284
18288
 
18285
- template <>
18286
- bool TryCastWithOverflowCheck(float value, int32_t &result) {
18287
- if (!(value >= -2147483648.0f && value < 2147483648.0f)) {
18289
+ template <class SRC, class T>
18290
+ bool TryCastWithOverflowCheckFloat(SRC value, T &result, SRC min, SRC max) {
18291
+ if (!Value::IsFinite<SRC>(value)) {
18288
18292
  return false;
18289
18293
  }
18290
- result = int32_t(value);
18294
+ if (!(value >= min && value < max)) {
18295
+ return false;
18296
+ }
18297
+ result = T(value);
18291
18298
  return true;
18292
18299
  }
18293
18300
 
18301
+ template <>
18302
+ bool TryCastWithOverflowCheck(float value, int32_t &result) {
18303
+ return TryCastWithOverflowCheckFloat<float, int32_t>(value, result, -2147483648.0f, 2147483648.0f);
18304
+ }
18305
+
18294
18306
  template <>
18295
18307
  bool TryCastWithOverflowCheck(float value, int64_t &result) {
18296
- if (!(value >= -9223372036854775808.0f && value < 9223372036854775808.0f)) {
18297
- return false;
18298
- }
18299
- result = int64_t(value);
18300
- return true;
18308
+ return TryCastWithOverflowCheckFloat<float, int64_t>(value, result, -9223372036854775808.0f,
18309
+ 9223372036854775808.0f);
18301
18310
  }
18302
18311
 
18303
18312
  template <>
18304
18313
  bool TryCastWithOverflowCheck(double value, int64_t &result) {
18305
- if (!(value >= -9223372036854775808.0 && value < 9223372036854775808.0)) {
18306
- return false;
18307
- }
18308
- result = int64_t(value);
18314
+ return TryCastWithOverflowCheckFloat<double, int64_t>(value, result, -9223372036854775808.0, 9223372036854775808.0);
18315
+ }
18316
+
18317
+ template <>
18318
+ bool TryCastWithOverflowCheck(float input, float &result) {
18319
+ result = input;
18320
+ return true;
18321
+ }
18322
+ template <>
18323
+ bool TryCastWithOverflowCheck(float input, double &result) {
18324
+ result = double(input);
18325
+ return true;
18326
+ }
18327
+ template <>
18328
+ bool TryCastWithOverflowCheck(double input, double &result) {
18329
+ result = input;
18309
18330
  return true;
18310
18331
  }
18311
18332
 
18312
18333
  template <>
18313
18334
  bool TryCastWithOverflowCheck(double input, float &result) {
18314
- if (input < (double)NumericLimits<float>::Minimum() || input > (double)NumericLimits<float>::Maximum()) {
18315
- return false;
18335
+ if (!Value::IsFinite(input)) {
18336
+ result = float(input);
18337
+ return true;
18316
18338
  }
18317
- auto res = (float)input;
18318
- if (std::isnan(res) || std::isinf(res)) {
18339
+ auto res = float(input);
18340
+ if (!Value::FloatIsFinite(input)) {
18319
18341
  return false;
18320
18342
  }
18321
18343
  result = res;
@@ -22956,19 +22978,6 @@ bool TryCast::Operation(string_t input, uint64_t &result, bool strict) {
22956
22978
  return TryIntegerCast<uint64_t, false>(input.GetDataUnsafe(), input.GetSize(), result, strict);
22957
22979
  }
22958
22980
 
22959
- template <class T>
22960
- bool CheckDoubleValidity(T value);
22961
-
22962
- template <>
22963
- bool CheckDoubleValidity(float value) {
22964
- return Value::FloatIsValid(value);
22965
- }
22966
-
22967
- template <>
22968
- bool CheckDoubleValidity(double value) {
22969
- return Value::DoubleIsValid(value);
22970
- }
22971
-
22972
22981
  template <class T>
22973
22982
  static bool TryDoubleCast(const char *buf, idx_t len, T &result, bool strict) {
22974
22983
  // skip any spaces at the start
@@ -22985,9 +22994,6 @@ static bool TryDoubleCast(const char *buf, idx_t len, T &result, bool strict) {
22985
22994
  }
22986
22995
  auto endptr = buf + len;
22987
22996
  auto parse_result = duckdb_fast_float::from_chars(buf, buf + len, result);
22988
- if (!CheckDoubleValidity<T>(result)) {
22989
- return false;
22990
- }
22991
22997
  if (parse_result.ec != std::errc()) {
22992
22998
  return false;
22993
22999
  }
@@ -24679,6 +24685,8 @@ void ProgressBar::Update(bool final) {
24679
24685
  } // namespace duckdb
24680
24686
 
24681
24687
 
24688
+
24689
+
24682
24690
  #include <cfloat>
24683
24691
  #include <cstring> // strlen() on Solaris
24684
24692
  #include <limits.h>
@@ -24707,15 +24715,17 @@ uint32_t EncodeFloat(float x) {
24707
24715
  buff |= (1u << 31);
24708
24716
  return buff;
24709
24717
  }
24718
+ // nan
24719
+ if (Value::IsNan(x)) {
24720
+ return UINT_MAX;
24721
+ }
24710
24722
  //! infinity
24711
24723
  if (x > FLT_MAX) {
24712
- throw InternalException("+INFINITY detected in floating point number");
24713
- // return UINT_MAX;
24724
+ return UINT_MAX - 1;
24714
24725
  }
24715
24726
  //! -infinity
24716
24727
  if (x < -FLT_MAX) {
24717
- throw InternalException("-INFINITY detected in floating point number");
24718
- // return 0;
24728
+ return 0;
24719
24729
  }
24720
24730
  buff = Load<uint32_t>((const_data_ptr_t)&x);
24721
24731
  if ((buff & (1u << 31)) == 0) { //! +0 and positive numbers
@@ -24735,15 +24745,17 @@ uint64_t EncodeDouble(double x) {
24735
24745
  buff += (1ull << 63);
24736
24746
  return buff;
24737
24747
  }
24748
+ // nan
24749
+ if (Value::IsNan(x)) {
24750
+ return ULLONG_MAX;
24751
+ }
24738
24752
  //! infinity
24739
24753
  if (x > DBL_MAX) {
24740
- throw InternalException("+INFINITY detected in floating point number");
24741
- // return ULLONG_MAX;
24754
+ return ULLONG_MAX - 1;
24742
24755
  }
24743
24756
  //! -infinity
24744
24757
  if (x < -DBL_MAX) {
24745
- throw InternalException("-INFINITY detected in floating point number");
24746
- // return 0;
24758
+ return 0;
24747
24759
  }
24748
24760
  buff = Load<uint64_t>((const_data_ptr_t)&x);
24749
24761
  if (buff < (1ull << 63)) { //! +0 and positive numbers
@@ -34687,6 +34699,7 @@ hash_t Hash(uint8_t *val, size_t size) {
34687
34699
 
34688
34700
 
34689
34701
 
34702
+
34690
34703
  #include <cmath>
34691
34704
  #include <limits>
34692
34705
 
@@ -35226,6 +35239,9 @@ bool Hugeint::TryConvert(float value, hugeint_t &result) {
35226
35239
 
35227
35240
  template <class REAL_T>
35228
35241
  bool ConvertFloatingToBigint(REAL_T value, hugeint_t &result) {
35242
+ if (!Value::IsFinite<REAL_T>(value)) {
35243
+ return false;
35244
+ }
35229
35245
  if (value <= -170141183460469231731687303715884105728.0 || value >= 170141183460469231731687303715884105727.0) {
35230
35246
  return false;
35231
35247
  }
@@ -37382,8 +37398,6 @@ void ValidityMask::Slice(const ValidityMask &other, idx_t offset) {
37382
37398
  }
37383
37399
 
37384
37400
  } // namespace duckdb
37385
- #include <utility>
37386
-
37387
37401
 
37388
37402
 
37389
37403
 
@@ -37493,6 +37507,9 @@ hugeint_t ModuloOperator::Operation(hugeint_t left, hugeint_t right);
37493
37507
 
37494
37508
 
37495
37509
 
37510
+ #include <utility>
37511
+ #include <cmath>
37512
+
37496
37513
  namespace duckdb {
37497
37514
 
37498
37515
  Value::Value(LogicalType type) : type_(move(type)), is_null(true) {
@@ -37507,16 +37524,10 @@ Value::Value(int64_t val) : type_(LogicalType::BIGINT), is_null(false) {
37507
37524
  }
37508
37525
 
37509
37526
  Value::Value(float val) : type_(LogicalType::FLOAT), is_null(false) {
37510
- if (!Value::FloatIsValid(val)) {
37511
- throw OutOfRangeException("Invalid float value %f", val);
37512
- }
37513
37527
  value_.float_ = val;
37514
37528
  }
37515
37529
 
37516
37530
  Value::Value(double val) : type_(LogicalType::DOUBLE), is_null(false) {
37517
- if (!Value::DoubleIsValid(val)) {
37518
- throw OutOfRangeException("Invalid double value %f", val);
37519
- }
37520
37531
  value_.double_ = val;
37521
37532
  }
37522
37533
 
@@ -37790,14 +37801,34 @@ Value Value::UBIGINT(uint64_t value) {
37790
37801
  return result;
37791
37802
  }
37792
37803
 
37793
- bool Value::FloatIsValid(float value) {
37804
+ bool Value::FloatIsFinite(float value) {
37794
37805
  return !(std::isnan(value) || std::isinf(value));
37795
37806
  }
37796
37807
 
37797
- bool Value::DoubleIsValid(double value) {
37808
+ bool Value::DoubleIsFinite(double value) {
37798
37809
  return !(std::isnan(value) || std::isinf(value));
37799
37810
  }
37800
37811
 
37812
+ template <>
37813
+ bool Value::IsNan(float input) {
37814
+ return std::isnan(input);
37815
+ }
37816
+
37817
+ template <>
37818
+ bool Value::IsNan(double input) {
37819
+ return std::isnan(input);
37820
+ }
37821
+
37822
+ template <>
37823
+ bool Value::IsFinite(float input) {
37824
+ return Value::FloatIsFinite(input);
37825
+ }
37826
+
37827
+ template <>
37828
+ bool Value::IsFinite(double input) {
37829
+ return Value::DoubleIsFinite(input);
37830
+ }
37831
+
37801
37832
  bool Value::StringIsValid(const char *str, idx_t length) {
37802
37833
  auto utf_type = Utf8Proc::Analyze(str, length);
37803
37834
  return utf_type != UnicodeType::INVALID;
@@ -37850,9 +37881,6 @@ Value Value::DECIMAL(hugeint_t value, uint8_t width, uint8_t scale) {
37850
37881
  }
37851
37882
 
37852
37883
  Value Value::FLOAT(float value) {
37853
- if (!Value::FloatIsValid(value)) {
37854
- throw OutOfRangeException("Invalid float value %f", value);
37855
- }
37856
37884
  Value result(LogicalType::FLOAT);
37857
37885
  result.value_.float_ = value;
37858
37886
  result.is_null = false;
@@ -37860,9 +37888,6 @@ Value Value::FLOAT(float value) {
37860
37888
  }
37861
37889
 
37862
37890
  Value Value::DOUBLE(double value) {
37863
- if (!Value::DoubleIsValid(value)) {
37864
- throw OutOfRangeException("Invalid double value %f", value);
37865
- }
37866
37891
  Value result(LogicalType::DOUBLE);
37867
37892
  result.value_.double_ = value;
37868
37893
  result.is_null = false;
@@ -38863,6 +38888,22 @@ string Value::ToSQLString() const {
38863
38888
  ret += "}";
38864
38889
  return ret;
38865
38890
  }
38891
+ case LogicalTypeId::FLOAT:
38892
+ if (!FloatIsFinite(FloatValue::Get(*this))) {
38893
+ return "'" + ToString() + "'::" + type_.ToString();
38894
+ }
38895
+ return ToString();
38896
+ case LogicalTypeId::DOUBLE: {
38897
+ double val = DoubleValue::Get(*this);
38898
+ if (!DoubleIsFinite(val)) {
38899
+ if (!Value::IsNan(val)) {
38900
+ // to infinity and beyond
38901
+ return val < 0 ? "-1e1000" : "1e1000";
38902
+ }
38903
+ return "'" + ToString() + "'::" + type_.ToString();
38904
+ }
38905
+ return ToString();
38906
+ }
38866
38907
  case LogicalTypeId::LIST: {
38867
38908
  string ret = "[";
38868
38909
  for (size_t i = 0; i < list_value.size(); i++) {
@@ -39242,16 +39283,6 @@ bool Value::ValuesAreEqual(const Value &result_value, const Value &value) {
39242
39283
  }
39243
39284
  }
39244
39285
 
39245
- template <>
39246
- bool Value::IsValid(float value) {
39247
- return Value::FloatIsValid(value);
39248
- }
39249
-
39250
- template <>
39251
- bool Value::IsValid(double value) {
39252
- return Value::DoubleIsValid(value);
39253
- }
39254
-
39255
39286
  } // namespace duckdb
39256
39287
 
39257
39288
 
@@ -40239,30 +40270,6 @@ void Vector::Verify(const SelectionVector &sel, idx_t count) {
40239
40270
  (GetVectorType() == VectorType::CONSTANT_VECTOR || GetVectorType() == VectorType::FLAT_VECTOR)) {
40240
40271
  D_ASSERT(!auxiliary);
40241
40272
  }
40242
- if (GetType().InternalType() == PhysicalType::DOUBLE) {
40243
- // verify that there are no INF or NAN values
40244
- switch (GetVectorType()) {
40245
- case VectorType::CONSTANT_VECTOR: {
40246
- auto dbl = ConstantVector::GetData<double>(*this);
40247
- if (!ConstantVector::IsNull(*this)) {
40248
- D_ASSERT(Value::DoubleIsValid(*dbl));
40249
- }
40250
- break;
40251
- }
40252
- case VectorType::FLAT_VECTOR: {
40253
- auto doubles = FlatVector::GetData<double>(*this);
40254
- for (idx_t i = 0; i < count; i++) {
40255
- auto oidx = sel.get_index(i);
40256
- if (validity.RowIsValid(oidx)) {
40257
- D_ASSERT(Value::DoubleIsValid(doubles[oidx]));
40258
- }
40259
- }
40260
- break;
40261
- }
40262
- default:
40263
- break;
40264
- }
40265
- }
40266
40273
  if (GetType().id() == LogicalTypeId::VARCHAR || GetType().id() == LogicalTypeId::JSON) {
40267
40274
  // verify that there are no '\0' bytes in string values
40268
40275
  switch (GetVectorType()) {
@@ -41763,11 +41770,23 @@ void LogicalType::Verify() const {
41763
41770
  }
41764
41771
 
41765
41772
  bool ApproxEqual(float ldecimal, float rdecimal) {
41773
+ if (Value::IsNan(ldecimal) && Value::IsNan(rdecimal)) {
41774
+ return true;
41775
+ }
41776
+ if (!Value::FloatIsFinite(ldecimal) || !Value::FloatIsFinite(rdecimal)) {
41777
+ return ldecimal == rdecimal;
41778
+ }
41766
41779
  float epsilon = std::fabs(rdecimal) * 0.01;
41767
41780
  return std::fabs(ldecimal - rdecimal) <= epsilon;
41768
41781
  }
41769
41782
 
41770
41783
  bool ApproxEqual(double ldecimal, double rdecimal) {
41784
+ if (Value::IsNan(ldecimal) && Value::IsNan(rdecimal)) {
41785
+ return true;
41786
+ }
41787
+ if (!Value::DoubleIsFinite(ldecimal) || !Value::DoubleIsFinite(rdecimal)) {
41788
+ return ldecimal == rdecimal;
41789
+ }
41771
41790
  double epsilon = std::fabs(rdecimal) * 0.01;
41772
41791
  return std::fabs(ldecimal - rdecimal) <= epsilon;
41773
41792
  }
@@ -42847,8 +42866,101 @@ void VectorOperations::Not(Vector &input, Vector &result, idx_t count) {
42847
42866
 
42848
42867
 
42849
42868
 
42869
+ //===----------------------------------------------------------------------===//
42870
+ // DuckDB
42871
+ //
42872
+ // duckdb/common/likely.hpp
42873
+ //
42874
+ //
42875
+ //===----------------------------------------------------------------------===//
42876
+
42877
+
42878
+
42879
+ #if __GNUC__
42880
+ #define DUCKDB_BUILTIN_EXPECT(cond, expected_value) (__builtin_expect(cond, expected_value))
42881
+ #else
42882
+ #define DUCKDB_BUILTIN_EXPECT(cond, expected_value) (cond)
42883
+ #endif
42884
+
42885
+ #define DUCKDB_LIKELY(...) DUCKDB_BUILTIN_EXPECT((__VA_ARGS__), 1)
42886
+ #define DUCKDB_UNLIKELY(...) DUCKDB_BUILTIN_EXPECT((__VA_ARGS__), 0)
42887
+
42888
+
42850
42889
  namespace duckdb {
42851
42890
 
42891
+ template <class T>
42892
+ bool EqualsFloat(T left, T right) {
42893
+ if (DUCKDB_UNLIKELY(Value::IsNan(left) && Value::IsNan(right))) {
42894
+ return true;
42895
+ }
42896
+ return left == right;
42897
+ }
42898
+
42899
+ template <>
42900
+ bool Equals::Operation(float left, float right) {
42901
+ return EqualsFloat<float>(left, right);
42902
+ }
42903
+
42904
+ template <>
42905
+ bool Equals::Operation(double left, double right) {
42906
+ return EqualsFloat<double>(left, right);
42907
+ }
42908
+
42909
+ template <class T>
42910
+ bool GreaterThanFloat(T left, T right) {
42911
+ // handle nans
42912
+ // nan is always bigger than everything else
42913
+ bool left_is_nan = Value::IsNan(left);
42914
+ bool right_is_nan = Value::IsNan(right);
42915
+ // if right is nan, there is no number that is bigger than right
42916
+ if (DUCKDB_UNLIKELY(right_is_nan)) {
42917
+ return false;
42918
+ }
42919
+ // if left is nan, but right is not, left is always bigger
42920
+ if (DUCKDB_UNLIKELY(left_is_nan)) {
42921
+ return true;
42922
+ }
42923
+ return left > right;
42924
+ }
42925
+
42926
+ template <>
42927
+ bool GreaterThan::Operation(float left, float right) {
42928
+ return GreaterThanFloat<float>(left, right);
42929
+ }
42930
+
42931
+ template <>
42932
+ bool GreaterThan::Operation(double left, double right) {
42933
+ return GreaterThanFloat<double>(left, right);
42934
+ }
42935
+
42936
+ template <class T>
42937
+ bool GreaterThanEqualsFloat(T left, T right) {
42938
+ // handle nans
42939
+ // nan is always bigger than everything else
42940
+ bool left_is_nan = Value::IsNan(left);
42941
+ bool right_is_nan = Value::IsNan(right);
42942
+ // if right is nan, there is no bigger number
42943
+ // we only return true if left is also nan (in which case the numbers are equal)
42944
+ if (DUCKDB_UNLIKELY(right_is_nan)) {
42945
+ return left_is_nan;
42946
+ }
42947
+ // if left is nan, but right is not, left is always bigger
42948
+ if (DUCKDB_UNLIKELY(left_is_nan)) {
42949
+ return true;
42950
+ }
42951
+ return left >= right;
42952
+ }
42953
+
42954
+ template <>
42955
+ bool GreaterThanEquals::Operation(float left, float right) {
42956
+ return GreaterThanEqualsFloat<float>(left, right);
42957
+ }
42958
+
42959
+ template <>
42960
+ bool GreaterThanEquals::Operation(double left, double right) {
42961
+ return GreaterThanEqualsFloat<double>(left, right);
42962
+ }
42963
+
42852
42964
  struct ComparisonSelector {
42853
42965
  template <typename OP>
42854
42966
  static idx_t Select(Vector &left, Vector &right, const SelectionVector *sel, idx_t count, SelectionVector *true_sel,
@@ -44696,24 +44808,6 @@ static bool DecimalCastSwitch(Vector &source, Vector &result, idx_t count, strin
44696
44808
  } // namespace duckdb
44697
44809
 
44698
44810
 
44699
- //===----------------------------------------------------------------------===//
44700
- // DuckDB
44701
- //
44702
- // duckdb/common/likely.hpp
44703
- //
44704
- //
44705
- //===----------------------------------------------------------------------===//
44706
-
44707
-
44708
-
44709
- #if __GNUC__
44710
- #define DUCKDB_BUILTIN_EXPECT(cond, expected_value) (__builtin_expect(cond, expected_value))
44711
- #else
44712
- #define DUCKDB_BUILTIN_EXPECT(cond, expected_value) (cond)
44713
- #endif
44714
-
44715
- #define DUCKDB_LIKELY(...) DUCKDB_BUILTIN_EXPECT((__VA_ARGS__), 1)
44716
- #define DUCKDB_UNLIKELY(...) DUCKDB_BUILTIN_EXPECT((__VA_ARGS__), 0)
44717
44811
 
44718
44812
 
44719
44813
  namespace duckdb {
@@ -64051,14 +64145,15 @@ class DataTable;
64051
64145
  class PhysicalDelete : public PhysicalOperator {
64052
64146
  public:
64053
64147
  PhysicalDelete(vector<LogicalType> types, TableCatalogEntry &tableref, DataTable &table, idx_t row_id_index,
64054
- idx_t estimated_cardinality)
64148
+ idx_t estimated_cardinality, bool return_chunk)
64055
64149
  : PhysicalOperator(PhysicalOperatorType::DELETE_OPERATOR, move(types), estimated_cardinality),
64056
- tableref(tableref), table(table), row_id_index(row_id_index) {
64150
+ tableref(tableref), table(table), row_id_index(row_id_index), return_chunk(return_chunk) {
64057
64151
  }
64058
64152
 
64059
64153
  TableCatalogEntry &tableref;
64060
64154
  DataTable &table;
64061
64155
  idx_t row_id_index;
64156
+ bool return_chunk;
64062
64157
 
64063
64158
  public:
64064
64159
  // Source interface
@@ -64069,6 +64164,7 @@ public:
64069
64164
  public:
64070
64165
  // Sink interface
64071
64166
  unique_ptr<GlobalSinkState> GetGlobalSinkState(ClientContext &context) const override;
64167
+ unique_ptr<LocalSinkState> GetLocalSinkState(ExecutionContext &context) const override;
64072
64168
  SinkResultType Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate,
64073
64169
  DataChunk &input) const override;
64074
64170
 
@@ -64088,6 +64184,7 @@ public:
64088
64184
 
64089
64185
 
64090
64186
 
64187
+
64091
64188
  namespace duckdb {
64092
64189
 
64093
64190
  //===--------------------------------------------------------------------===//
@@ -64095,21 +64192,46 @@ namespace duckdb {
64095
64192
  //===--------------------------------------------------------------------===//
64096
64193
  class DeleteGlobalState : public GlobalSinkState {
64097
64194
  public:
64098
- DeleteGlobalState() : deleted_count(0) {
64195
+ DeleteGlobalState() : deleted_count(0), returned_chunk_count(0) {
64099
64196
  }
64100
64197
 
64101
64198
  mutex delete_lock;
64102
64199
  idx_t deleted_count;
64200
+ ChunkCollection return_chunk_collection;
64201
+ idx_t returned_chunk_count;
64202
+ };
64203
+
64204
+ class DeleteLocalState : public LocalSinkState {
64205
+ public:
64206
+ explicit DeleteLocalState(const vector<LogicalType> &table_types) {
64207
+ delete_chunk.Initialize(table_types);
64208
+ }
64209
+ DataChunk delete_chunk;
64103
64210
  };
64104
64211
 
64105
64212
  SinkResultType PhysicalDelete::Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate,
64106
64213
  DataChunk &input) const {
64107
64214
  auto &gstate = (DeleteGlobalState &)state;
64215
+ auto &ustate = (DeleteLocalState &)lstate;
64216
+
64217
+ // get rows and
64218
+ auto &transaction = Transaction::GetTransaction(context.client);
64219
+ auto &row_identifiers = input.data[row_id_index];
64220
+
64221
+ vector<column_t> column_ids;
64222
+ for (idx_t i = 0; i < table.column_definitions.size(); i++) {
64223
+ column_ids.emplace_back(i);
64224
+ };
64225
+ auto cfs = ColumnFetchState();
64108
64226
 
64109
- // delete data in the base table
64110
- // the row ids are given to us as the last column of the child chunk
64111
64227
  lock_guard<mutex> delete_guard(gstate.delete_lock);
64112
- gstate.deleted_count += table.Delete(tableref, context.client, input.data[row_id_index], input.size());
64228
+ if (return_chunk) {
64229
+ row_identifiers.Normalify(input.size());
64230
+ table.Fetch(transaction, ustate.delete_chunk, column_ids, row_identifiers, input.size(), cfs);
64231
+ gstate.return_chunk_collection.Append(ustate.delete_chunk);
64232
+ }
64233
+ gstate.deleted_count += table.Delete(tableref, context.client, row_identifiers, input.size());
64234
+
64113
64235
  return SinkResultType::NEED_MORE_INPUT;
64114
64236
  }
64115
64237
 
@@ -64117,6 +64239,10 @@ unique_ptr<GlobalSinkState> PhysicalDelete::GetGlobalSinkState(ClientContext &co
64117
64239
  return make_unique<DeleteGlobalState>();
64118
64240
  }
64119
64241
 
64242
+ unique_ptr<LocalSinkState> PhysicalDelete::GetLocalSinkState(ExecutionContext &context) const {
64243
+ return make_unique<DeleteLocalState>(table.GetTypes());
64244
+ }
64245
+
64120
64246
  //===--------------------------------------------------------------------===//
64121
64247
  // Source
64122
64248
  //===--------------------------------------------------------------------===//
@@ -64140,9 +64266,22 @@ void PhysicalDelete::GetData(ExecutionContext &context, DataChunk &chunk, Global
64140
64266
  return;
64141
64267
  }
64142
64268
 
64143
- chunk.SetCardinality(1);
64144
- chunk.SetValue(0, 0, Value::BIGINT(g.deleted_count));
64145
- state.finished = true;
64269
+ if (!return_chunk) {
64270
+ chunk.SetCardinality(1);
64271
+ chunk.SetValue(0, 0, Value::BIGINT(g.deleted_count));
64272
+ state.finished = true;
64273
+ }
64274
+
64275
+ idx_t chunk_return = g.returned_chunk_count;
64276
+ if (chunk_return >= g.return_chunk_collection.Chunks().size()) {
64277
+ return;
64278
+ }
64279
+ chunk.Reference(g.return_chunk_collection.GetChunk(chunk_return));
64280
+ chunk.SetCardinality((g.return_chunk_collection.GetChunk(chunk_return)).size());
64281
+ g.returned_chunk_count += 1;
64282
+ if (g.returned_chunk_count >= g.return_chunk_collection.Chunks().size()) {
64283
+ state.finished = true;
64284
+ }
64146
64285
  }
64147
64286
 
64148
64287
  } // namespace duckdb
@@ -64589,10 +64728,10 @@ class PhysicalUpdate : public PhysicalOperator {
64589
64728
  public:
64590
64729
  PhysicalUpdate(vector<LogicalType> types, TableCatalogEntry &tableref, DataTable &table, vector<column_t> columns,
64591
64730
  vector<unique_ptr<Expression>> expressions, vector<unique_ptr<Expression>> bound_defaults,
64592
- idx_t estimated_cardinality)
64731
+ idx_t estimated_cardinality, bool return_chunk)
64593
64732
  : PhysicalOperator(PhysicalOperatorType::UPDATE, move(types), estimated_cardinality), tableref(tableref),
64594
64733
  table(table), columns(std::move(columns)), expressions(move(expressions)),
64595
- bound_defaults(move(bound_defaults)) {
64734
+ bound_defaults(move(bound_defaults)), return_chunk(return_chunk) {
64596
64735
  }
64597
64736
 
64598
64737
  TableCatalogEntry &tableref;
@@ -64601,6 +64740,8 @@ public:
64601
64740
  vector<unique_ptr<Expression>> expressions;
64602
64741
  vector<unique_ptr<Expression>> bound_defaults;
64603
64742
  bool update_is_del_and_insert;
64743
+ //! If the returning statement is present, return the whole chunk
64744
+ bool return_chunk;
64604
64745
 
64605
64746
  public:
64606
64747
  // Source interface
@@ -64634,6 +64775,7 @@ public:
64634
64775
 
64635
64776
 
64636
64777
 
64778
+
64637
64779
  namespace duckdb {
64638
64780
 
64639
64781
  //===--------------------------------------------------------------------===//
@@ -64641,12 +64783,14 @@ namespace duckdb {
64641
64783
  //===--------------------------------------------------------------------===//
64642
64784
  class UpdateGlobalState : public GlobalSinkState {
64643
64785
  public:
64644
- UpdateGlobalState() : updated_count(0) {
64786
+ UpdateGlobalState() : updated_count(0), returned_chunk_count(0) {
64645
64787
  }
64646
64788
 
64647
64789
  mutex lock;
64648
64790
  idx_t updated_count;
64649
64791
  unordered_set<row_t> updated_columns;
64792
+ ChunkCollection return_chunk_collection;
64793
+ idx_t returned_chunk_count;
64650
64794
  };
64651
64795
 
64652
64796
  class UpdateLocalState : public LocalSinkState {
@@ -64726,9 +64870,21 @@ SinkResultType PhysicalUpdate::Sink(ExecutionContext &context, GlobalSinkState &
64726
64870
  }
64727
64871
  table.Append(tableref, context.client, mock_chunk);
64728
64872
  } else {
64873
+ if (return_chunk) {
64874
+ mock_chunk.SetCardinality(update_chunk);
64875
+ for (idx_t i = 0; i < columns.size(); i++) {
64876
+ mock_chunk.data[columns[i]].Reference(update_chunk.data[i]);
64877
+ }
64878
+ }
64729
64879
  table.Update(tableref, context.client, row_ids, columns, update_chunk);
64730
64880
  }
64881
+
64882
+ if (return_chunk) {
64883
+ gstate.return_chunk_collection.Append(mock_chunk);
64884
+ }
64885
+
64731
64886
  gstate.updated_count += chunk.size();
64887
+
64732
64888
  return SinkResultType::NEED_MORE_INPUT;
64733
64889
  }
64734
64890
 
@@ -64769,10 +64925,22 @@ void PhysicalUpdate::GetData(ExecutionContext &context, DataChunk &chunk, Global
64769
64925
  if (state.finished) {
64770
64926
  return;
64771
64927
  }
64928
+ if (!return_chunk) {
64929
+ chunk.SetCardinality(1);
64930
+ chunk.SetValue(0, 0, Value::BIGINT(g.updated_count));
64931
+ state.finished = true;
64932
+ }
64772
64933
 
64773
- chunk.SetCardinality(1);
64774
- chunk.SetValue(0, 0, Value::BIGINT(g.updated_count));
64775
- state.finished = true;
64934
+ idx_t chunk_return = g.returned_chunk_count;
64935
+ if (chunk_return >= g.return_chunk_collection.Chunks().size()) {
64936
+ return;
64937
+ }
64938
+ chunk.Reference(g.return_chunk_collection.GetChunk(chunk_return));
64939
+ chunk.SetCardinality((g.return_chunk_collection.GetChunk(chunk_return)).size());
64940
+ g.returned_chunk_count += 1;
64941
+ if (g.returned_chunk_count >= g.return_chunk_collection.Chunks().size()) {
64942
+ state.finished = true;
64943
+ }
64776
64944
  }
64777
64945
 
64778
64946
  } // namespace duckdb
@@ -68395,14 +68563,27 @@ namespace duckdb {
68395
68563
  class LogicalDelete : public LogicalOperator {
68396
68564
  public:
68397
68565
  explicit LogicalDelete(TableCatalogEntry *table)
68398
- : LogicalOperator(LogicalOperatorType::LOGICAL_DELETE), table(table) {
68566
+ : LogicalOperator(LogicalOperatorType::LOGICAL_DELETE), table(table), table_index(0), return_chunk(false) {
68399
68567
  }
68400
68568
 
68401
68569
  TableCatalogEntry *table;
68570
+ idx_t table_index;
68571
+ bool return_chunk;
68402
68572
 
68403
68573
  protected:
68574
+ vector<ColumnBinding> GetColumnBindings() override {
68575
+ if (return_chunk) {
68576
+ return GenerateColumnBindings(table_index, table->columns.size());
68577
+ }
68578
+ return {ColumnBinding(0, 0)};
68579
+ }
68580
+
68404
68581
  void ResolveTypes() override {
68405
- types.emplace_back(LogicalType::BIGINT);
68582
+ if (return_chunk) {
68583
+ types = table->GetTypes();
68584
+ } else {
68585
+ types.emplace_back(LogicalType::BIGINT);
68586
+ }
68406
68587
  }
68407
68588
  };
68408
68589
  } // namespace duckdb
@@ -68421,8 +68602,8 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalDelete &op
68421
68602
  auto &bound_ref = (BoundReferenceExpression &)*op.expressions[0];
68422
68603
 
68423
68604
  dependencies.insert(op.table);
68424
- auto del =
68425
- make_unique<PhysicalDelete>(op.types, *op.table, *op.table->storage, bound_ref.index, op.estimated_cardinality);
68605
+ auto del = make_unique<PhysicalDelete>(op.types, *op.table, *op.table->storage, bound_ref.index,
68606
+ op.estimated_cardinality, op.return_chunk);
68426
68607
  del->children.push_back(move(plan));
68427
68608
  return move(del);
68428
68609
  }
@@ -70711,17 +70892,33 @@ namespace duckdb {
70711
70892
  class LogicalUpdate : public LogicalOperator {
70712
70893
  public:
70713
70894
  explicit LogicalUpdate(TableCatalogEntry *table)
70714
- : LogicalOperator(LogicalOperatorType::LOGICAL_UPDATE), table(table) {
70895
+ : LogicalOperator(LogicalOperatorType::LOGICAL_UPDATE), table(table), table_index(0), return_chunk(false) {
70715
70896
  }
70716
70897
 
70898
+ //! The base table to update
70717
70899
  TableCatalogEntry *table;
70900
+ //! table catalog index
70901
+ idx_t table_index;
70902
+ //! if returning option is used, return the update chunk
70903
+ bool return_chunk;
70718
70904
  vector<column_t> columns;
70719
70905
  vector<unique_ptr<Expression>> bound_defaults;
70720
70906
  bool update_is_del_and_insert;
70721
70907
 
70722
70908
  protected:
70909
+ vector<ColumnBinding> GetColumnBindings() override {
70910
+ if (return_chunk) {
70911
+ return GenerateColumnBindings(table_index, table->columns.size());
70912
+ }
70913
+ return {ColumnBinding(0, 0)};
70914
+ }
70915
+
70723
70916
  void ResolveTypes() override {
70724
- types.emplace_back(LogicalType::BIGINT);
70917
+ if (return_chunk) {
70918
+ types = table->GetTypes();
70919
+ } else {
70920
+ types.emplace_back(LogicalType::BIGINT);
70921
+ }
70725
70922
  }
70726
70923
  };
70727
70924
  } // namespace duckdb
@@ -70736,7 +70933,8 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalUpdate &op
70736
70933
 
70737
70934
  dependencies.insert(op.table);
70738
70935
  auto update = make_unique<PhysicalUpdate>(op.types, *op.table, *op.table->storage, op.columns, move(op.expressions),
70739
- move(op.bound_defaults), op.estimated_cardinality);
70936
+ move(op.bound_defaults), op.estimated_cardinality, op.return_chunk);
70937
+
70740
70938
  update->update_is_del_and_insert = op.update_is_del_and_insert;
70741
70939
  update->children.push_back(move(plan));
70742
70940
  return move(update);
@@ -72276,7 +72474,7 @@ struct NumericAverageOperation : public BaseSumOperation<AverageSetOperation, Re
72276
72474
  if (state->count == 0) {
72277
72475
  mask.SetInvalid(idx);
72278
72476
  } else {
72279
- if (!Value::DoubleIsValid(state->value)) {
72477
+ if (!Value::DoubleIsFinite(state->value)) {
72280
72478
  throw OutOfRangeException("AVG is out of range!");
72281
72479
  }
72282
72480
  target[idx] = (state->value / state->count);
@@ -72290,7 +72488,7 @@ struct KahanAverageOperation : public BaseSumOperation<AverageSetOperation, Kaha
72290
72488
  if (state->count == 0) {
72291
72489
  mask.SetInvalid(idx);
72292
72490
  } else {
72293
- if (!Value::DoubleIsValid(state->value)) {
72491
+ if (!Value::DoubleIsFinite(state->value)) {
72294
72492
  throw OutOfRangeException("AVG is out of range!");
72295
72493
  }
72296
72494
  target[idx] = (state->value / state->count) + (state->err / state->count);
@@ -72534,7 +72732,7 @@ struct VarSampOperation : public STDDevBaseOperation {
72534
72732
  mask.SetInvalid(idx);
72535
72733
  } else {
72536
72734
  target[idx] = state->dsquared / (state->count - 1);
72537
- if (!Value::DoubleIsValid(target[idx])) {
72735
+ if (!Value::DoubleIsFinite(target[idx])) {
72538
72736
  throw OutOfRangeException("VARSAMP is out of range!");
72539
72737
  }
72540
72738
  }
@@ -72548,7 +72746,7 @@ struct VarPopOperation : public STDDevBaseOperation {
72548
72746
  mask.SetInvalid(idx);
72549
72747
  } else {
72550
72748
  target[idx] = state->count > 1 ? (state->dsquared / state->count) : 0;
72551
- if (!Value::DoubleIsValid(target[idx])) {
72749
+ if (!Value::DoubleIsFinite(target[idx])) {
72552
72750
  throw OutOfRangeException("VARPOP is out of range!");
72553
72751
  }
72554
72752
  }
@@ -72562,7 +72760,7 @@ struct STDDevSampOperation : public STDDevBaseOperation {
72562
72760
  mask.SetInvalid(idx);
72563
72761
  } else {
72564
72762
  target[idx] = sqrt(state->dsquared / (state->count - 1));
72565
- if (!Value::DoubleIsValid(target[idx])) {
72763
+ if (!Value::DoubleIsFinite(target[idx])) {
72566
72764
  throw OutOfRangeException("STDDEV_SAMP is out of range!");
72567
72765
  }
72568
72766
  }
@@ -72576,7 +72774,7 @@ struct STDDevPopOperation : public STDDevBaseOperation {
72576
72774
  mask.SetInvalid(idx);
72577
72775
  } else {
72578
72776
  target[idx] = state->count > 1 ? sqrt(state->dsquared / state->count) : 0;
72579
- if (!Value::DoubleIsValid(target[idx])) {
72777
+ if (!Value::DoubleIsFinite(target[idx])) {
72580
72778
  throw OutOfRangeException("STDDEV_POP is out of range!");
72581
72779
  }
72582
72780
  }
@@ -72590,7 +72788,7 @@ struct StandardErrorOfTheMeanOperation : public STDDevBaseOperation {
72590
72788
  mask.SetInvalid(idx);
72591
72789
  } else {
72592
72790
  target[idx] = sqrt(state->dsquared / state->count) / sqrt((state->count));
72593
- if (!Value::DoubleIsValid(target[idx])) {
72791
+ if (!Value::DoubleIsFinite(target[idx])) {
72594
72792
  throw OutOfRangeException("SEM is out of range!");
72595
72793
  }
72596
72794
  }
@@ -72654,12 +72852,12 @@ struct CorrOperation {
72654
72852
  } else {
72655
72853
  auto cov = state->cov_pop.co_moment / state->cov_pop.count;
72656
72854
  auto std_x = state->dev_pop_x.count > 1 ? sqrt(state->dev_pop_x.dsquared / state->dev_pop_x.count) : 0;
72657
- if (!Value::DoubleIsValid(std_x)) {
72658
- throw OutOfRangeException("STDDEV_POP for X is invalid!");
72855
+ if (!Value::DoubleIsFinite(std_x)) {
72856
+ throw OutOfRangeException("STDDEV_POP for X is out of range!");
72659
72857
  }
72660
72858
  auto std_y = state->dev_pop_y.count > 1 ? sqrt(state->dev_pop_y.dsquared / state->dev_pop_y.count) : 0;
72661
- if (!Value::DoubleIsValid(std_y)) {
72662
- throw OutOfRangeException("STDDEV_POP for Y is invalid!");
72859
+ if (!Value::DoubleIsFinite(std_y)) {
72860
+ throw OutOfRangeException("STDDEV_POP for Y is out of range!");
72663
72861
  }
72664
72862
  if (std_x * std_y == 0) {
72665
72863
  mask.SetInvalid(idx);
@@ -74223,8 +74421,8 @@ struct KurtosisOperation {
74223
74421
  mask.SetInvalid(idx);
74224
74422
  } // LCOV_EXCL_STOP
74225
74423
  target[idx] = (n - 1) * ((n + 1) * m4 / (m2 * m2) - 3 * (n - 1)) / ((n - 2) * (n - 3));
74226
- if (!Value::DoubleIsValid(target[idx])) {
74227
- mask.SetInvalid(idx);
74424
+ if (!Value::DoubleIsFinite(target[idx])) {
74425
+ throw OutOfRangeException("Kurtosis is out of range!");
74228
74426
  }
74229
74427
  }
74230
74428
 
@@ -74937,8 +75135,8 @@ struct SkewnessOperation {
74937
75135
  target[idx] = temp1 * temp *
74938
75136
  (state->sum_cub - 3 * state->sum_sqr * state->sum * temp + 2 * pow(state->sum, 3) * temp * temp) /
74939
75137
  div;
74940
- if (!Value::DoubleIsValid(target[idx])) {
74941
- mask.SetInvalid(idx);
75138
+ if (!Value::DoubleIsFinite(target[idx])) {
75139
+ throw OutOfRangeException("SKEW is out of range!");
74942
75140
  }
74943
75141
  }
74944
75142
 
@@ -75147,7 +75345,7 @@ struct DoubleSumOperation : public BaseSumOperation<SumSetOperation, ADD_OPERATO
75147
75345
  if (!state->isset) {
75148
75346
  mask.SetInvalid(idx);
75149
75347
  } else {
75150
- if (!Value::DoubleIsValid(state->value)) {
75348
+ if (!Value::DoubleIsFinite(state->value)) {
75151
75349
  throw OutOfRangeException("SUM is out of range!");
75152
75350
  }
75153
75351
  target[idx] = state->value;
@@ -78827,7 +79025,7 @@ struct RegrSlopeOperation {
78827
79025
  } else {
78828
79026
  auto cov = state->cov_pop.co_moment / state->cov_pop.count;
78829
79027
  auto var_pop = state->var_pop.count > 1 ? (state->var_pop.dsquared / state->var_pop.count) : 0;
78830
- if (!Value::DoubleIsValid(var_pop)) {
79028
+ if (!Value::DoubleIsFinite(var_pop)) {
78831
79029
  throw OutOfRangeException("VARPOP is out of range!");
78832
79030
  }
78833
79031
  if (var_pop == 0) {
@@ -78952,7 +79150,7 @@ struct RegrR2Operation {
78952
79150
  template <class T, class STATE>
78953
79151
  static void Finalize(Vector &result, FunctionData *fd, STATE *state, T *target, ValidityMask &mask, idx_t idx) {
78954
79152
  auto var_pop_x = state->var_pop_x.count > 1 ? (state->var_pop_x.dsquared / state->var_pop_x.count) : 0;
78955
- if (!Value::DoubleIsValid(var_pop_x)) {
79153
+ if (!Value::DoubleIsFinite(var_pop_x)) {
78956
79154
  throw OutOfRangeException("VARPOP(X) is out of range!");
78957
79155
  }
78958
79156
  if (var_pop_x == 0) {
@@ -78960,7 +79158,7 @@ struct RegrR2Operation {
78960
79158
  return;
78961
79159
  }
78962
79160
  auto var_pop_y = state->var_pop_y.count > 1 ? (state->var_pop_y.dsquared / state->var_pop_y.count) : 0;
78963
- if (!Value::DoubleIsValid(var_pop_y)) {
79161
+ if (!Value::DoubleIsFinite(var_pop_y)) {
78964
79162
  throw OutOfRangeException("VARPOP(Y) is out of range!");
78965
79163
  }
78966
79164
  if (var_pop_y == 0) {
@@ -79041,7 +79239,7 @@ struct RegrBaseOperation {
79041
79239
  return;
79042
79240
  }
79043
79241
  auto var_pop = state->var_pop.count > 1 ? (state->var_pop.dsquared / state->var_pop.count) : 0;
79044
- if (!Value::DoubleIsValid(var_pop)) {
79242
+ if (!Value::DoubleIsFinite(var_pop)) {
79045
79243
  throw OutOfRangeException("VARPOP is out of range!");
79046
79244
  }
79047
79245
  RegrCountFunction::Finalize<T, size_t>(result, fd, &state->count, target, mask, idx);
@@ -84589,12 +84787,13 @@ struct StrfTimeBindData : public FunctionData {
84589
84787
  }
84590
84788
  };
84591
84789
 
84790
+ template <bool REVERSED>
84592
84791
  static unique_ptr<FunctionData> StrfTimeBindFunction(ClientContext &context, ScalarFunction &bound_function,
84593
84792
  vector<unique_ptr<Expression>> &arguments) {
84594
84793
  if (!arguments[1]->IsFoldable()) {
84595
84794
  throw InvalidInputException("strftime format must be a constant");
84596
84795
  }
84597
- Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
84796
+ Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[REVERSED ? 0 : 1]);
84598
84797
  StrfTimeFormat format;
84599
84798
  if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
84600
84799
  auto format_string = options_str.GetValue<string>();
@@ -84606,16 +84805,17 @@ static unique_ptr<FunctionData> StrfTimeBindFunction(ClientContext &context, Sca
84606
84805
  return make_unique<StrfTimeBindData>(format);
84607
84806
  }
84608
84807
 
84808
+ template <bool REVERSED>
84609
84809
  static void StrfTimeFunctionDate(DataChunk &args, ExpressionState &state, Vector &result) {
84610
84810
  auto &func_expr = (BoundFunctionExpression &)state.expr;
84611
84811
  auto &info = (StrfTimeBindData &)*func_expr.bind_info;
84612
84812
 
84613
- if (ConstantVector::IsNull(args.data[1])) {
84813
+ if (ConstantVector::IsNull(args.data[REVERSED ? 0 : 1])) {
84614
84814
  result.SetVectorType(VectorType::CONSTANT_VECTOR);
84615
84815
  ConstantVector::SetNull(result, true);
84616
84816
  return;
84617
84817
  }
84618
- UnaryExecutor::Execute<date_t, string_t>(args.data[0], result, args.size(), [&](date_t input) {
84818
+ UnaryExecutor::Execute<date_t, string_t>(args.data[REVERSED ? 1 : 0], result, args.size(), [&](date_t input) {
84619
84819
  dtime_t time(0);
84620
84820
  idx_t len = info.format.GetLength(input, time);
84621
84821
  string_t target = StringVector::EmptyString(result, len);
@@ -84625,36 +84825,44 @@ static void StrfTimeFunctionDate(DataChunk &args, ExpressionState &state, Vector
84625
84825
  });
84626
84826
  }
84627
84827
 
84828
+ template <bool REVERSED>
84628
84829
  static void StrfTimeFunctionTimestamp(DataChunk &args, ExpressionState &state, Vector &result) {
84629
84830
  auto &func_expr = (BoundFunctionExpression &)state.expr;
84630
84831
  auto &info = (StrfTimeBindData &)*func_expr.bind_info;
84631
84832
 
84632
- if (ConstantVector::IsNull(args.data[1])) {
84833
+ if (ConstantVector::IsNull(args.data[REVERSED ? 0 : 1])) {
84633
84834
  result.SetVectorType(VectorType::CONSTANT_VECTOR);
84634
84835
  ConstantVector::SetNull(result, true);
84635
84836
  return;
84636
84837
  }
84637
84838
 
84638
- UnaryExecutor::Execute<timestamp_t, string_t>(args.data[0], result, args.size(), [&](timestamp_t input) {
84639
- date_t date;
84640
- dtime_t time;
84641
- Timestamp::Convert(input, date, time);
84642
- idx_t len = info.format.GetLength(date, time);
84643
- string_t target = StringVector::EmptyString(result, len);
84644
- info.format.FormatString(date, time, target.GetDataWriteable());
84645
- target.Finalize();
84646
- return target;
84647
- });
84839
+ UnaryExecutor::Execute<timestamp_t, string_t>(args.data[REVERSED ? 1 : 0], result, args.size(),
84840
+ [&](timestamp_t input) {
84841
+ date_t date;
84842
+ dtime_t time;
84843
+ Timestamp::Convert(input, date, time);
84844
+ idx_t len = info.format.GetLength(date, time);
84845
+ string_t target = StringVector::EmptyString(result, len);
84846
+ info.format.FormatString(date, time, target.GetDataWriteable());
84847
+ target.Finalize();
84848
+ return target;
84849
+ });
84648
84850
  }
84649
84851
 
84650
84852
  void StrfTimeFun::RegisterFunction(BuiltinFunctions &set) {
84651
84853
  ScalarFunctionSet strftime("strftime");
84652
84854
 
84653
84855
  strftime.AddFunction(ScalarFunction({LogicalType::DATE, LogicalType::VARCHAR}, LogicalType::VARCHAR,
84654
- StrfTimeFunctionDate, false, StrfTimeBindFunction));
84856
+ StrfTimeFunctionDate<false>, false, StrfTimeBindFunction<false>));
84655
84857
 
84656
84858
  strftime.AddFunction(ScalarFunction({LogicalType::TIMESTAMP, LogicalType::VARCHAR}, LogicalType::VARCHAR,
84657
- StrfTimeFunctionTimestamp, false, StrfTimeBindFunction));
84859
+ StrfTimeFunctionTimestamp<false>, false, StrfTimeBindFunction<false>));
84860
+
84861
+ strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::DATE}, LogicalType::VARCHAR,
84862
+ StrfTimeFunctionDate<true>, false, StrfTimeBindFunction<true>));
84863
+
84864
+ strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP}, LogicalType::VARCHAR,
84865
+ StrfTimeFunctionTimestamp<true>, false, StrfTimeBindFunction<true>));
84658
84866
 
84659
84867
  set.AddFunction(strftime);
84660
84868
  }
@@ -87646,6 +87854,18 @@ struct EvenFun {
87646
87854
  static void RegisterFunction(BuiltinFunctions &set);
87647
87855
  };
87648
87856
 
87857
+ struct IsNanFun {
87858
+ static void RegisterFunction(BuiltinFunctions &set);
87859
+ };
87860
+
87861
+ struct IsInfiniteFun {
87862
+ static void RegisterFunction(BuiltinFunctions &set);
87863
+ };
87864
+
87865
+ struct IsFiniteFun {
87866
+ static void RegisterFunction(BuiltinFunctions &set);
87867
+ };
87868
+
87649
87869
  } // namespace duckdb
87650
87870
 
87651
87871
 
@@ -87704,6 +87924,7 @@ struct Atan2Fun {
87704
87924
 
87705
87925
 
87706
87926
 
87927
+
87707
87928
  #include <cmath>
87708
87929
  #include <errno.h>
87709
87930
 
@@ -87734,51 +87955,6 @@ static scalar_function_t GetScalarIntegerUnaryFunctionFixedReturn(const LogicalT
87734
87955
  return function;
87735
87956
  }
87736
87957
 
87737
- template <class OP>
87738
- struct UnaryDoubleWrapper {
87739
- template <class INPUT_TYPE, class RESULT_TYPE>
87740
- static RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
87741
- RESULT_TYPE result = OP::template Operation<INPUT_TYPE, RESULT_TYPE>(input);
87742
- if (std::isnan(result) || std::isinf(result) || errno != 0) {
87743
- errno = 0;
87744
- mask.SetInvalid(idx);
87745
- return 0;
87746
- }
87747
- return result;
87748
- }
87749
- };
87750
-
87751
- template <class T, class OP>
87752
- static void UnaryDoubleFunctionWrapper(DataChunk &input, ExpressionState &state, Vector &result) {
87753
- D_ASSERT(input.ColumnCount() >= 1);
87754
- errno = 0;
87755
- UnaryExecutor::GenericExecute<T, T, UnaryDoubleWrapper<OP>>(input.data[0], result, input.size(), nullptr, true);
87756
- }
87757
-
87758
- struct BinaryDoubleWrapper {
87759
- template <class FUNC, class OP, class TA, class TB, class TR>
87760
- static inline TR Operation(FUNC fun, TA left, TB right, ValidityMask &mask, idx_t idx) {
87761
- TR result = OP::template Operation<TA, TB, TR>(left, right);
87762
- if (std::isnan(result) || std::isinf(result) || errno != 0) {
87763
- errno = 0;
87764
- mask.SetInvalid(idx);
87765
- return 0;
87766
- }
87767
- return result;
87768
- }
87769
-
87770
- static bool AddsNulls() {
87771
- return true;
87772
- }
87773
- };
87774
-
87775
- template <class T, class OP>
87776
- static void BinaryDoubleFunctionWrapper(DataChunk &input, ExpressionState &state, Vector &result) {
87777
- D_ASSERT(input.ColumnCount() >= 2);
87778
- errno = 0;
87779
- BinaryExecutor::Execute<T, T, T, OP, BinaryDoubleWrapper>(input.data[0], input.data[1], result, input.size());
87780
- }
87781
-
87782
87958
  //===--------------------------------------------------------------------===//
87783
87959
  // nextafter
87784
87960
  //===--------------------------------------------------------------------===//
@@ -87799,23 +87975,14 @@ struct NextAfterOperator {
87799
87975
  }
87800
87976
  };
87801
87977
 
87802
- unique_ptr<FunctionData> BindNextAfter(ClientContext &context, ScalarFunction &function,
87803
- vector<unique_ptr<Expression>> &arguments) {
87804
- if ((arguments[0]->return_type != arguments[1]->return_type) ||
87805
- (arguments[0]->return_type != LogicalType::FLOAT && arguments[0]->return_type != LogicalType::DOUBLE)) {
87806
- throw NotImplementedException("Unimplemented type for NextAfter Function");
87807
- }
87808
- return nullptr;
87809
- }
87810
-
87811
87978
  void NextAfterFun::RegisterFunction(BuiltinFunctions &set) {
87812
87979
  ScalarFunctionSet next_after_fun("nextafter");
87813
87980
  next_after_fun.AddFunction(
87814
87981
  ScalarFunction("nextafter", {LogicalType::DOUBLE, LogicalType::DOUBLE}, LogicalType::DOUBLE,
87815
- BinaryDoubleFunctionWrapper<double, NextAfterOperator>, false, BindNextAfter));
87982
+ ScalarFunction::BinaryFunction<double, double, double, NextAfterOperator>, false));
87816
87983
  next_after_fun.AddFunction(ScalarFunction("nextafter", {LogicalType::FLOAT, LogicalType::FLOAT}, LogicalType::FLOAT,
87817
- BinaryDoubleFunctionWrapper<float, NextAfterOperator>, false,
87818
- BindNextAfter));
87984
+ ScalarFunction::BinaryFunction<float, float, float, NextAfterOperator>,
87985
+ false));
87819
87986
  set.AddFunction(next_after_fun);
87820
87987
  }
87821
87988
 
@@ -87892,10 +88059,10 @@ void BitCountFun::RegisterFunction(BuiltinFunctions &set) {
87892
88059
  //===--------------------------------------------------------------------===//
87893
88060
  struct SignOperator {
87894
88061
  template <class TA, class TR>
87895
- static inline TR Operation(TA left) {
87896
- if (left == TA(0)) {
88062
+ static TR Operation(TA input) {
88063
+ if (input == TA(0)) {
87897
88064
  return 0;
87898
- } else if (left > TA(0)) {
88065
+ } else if (input > TA(0)) {
87899
88066
  return 1;
87900
88067
  } else {
87901
88068
  return -1;
@@ -87903,6 +88070,28 @@ struct SignOperator {
87903
88070
  }
87904
88071
  };
87905
88072
 
88073
+ template <>
88074
+ int8_t SignOperator::Operation(float input) {
88075
+ if (input == 0 || Value::IsNan(input)) {
88076
+ return 0;
88077
+ } else if (input > 0) {
88078
+ return 1;
88079
+ } else {
88080
+ return -1;
88081
+ }
88082
+ }
88083
+
88084
+ template <>
88085
+ int8_t SignOperator::Operation(double input) {
88086
+ if (input == 0 || Value::IsNan(input)) {
88087
+ return 0;
88088
+ } else if (input > 0) {
88089
+ return 1;
88090
+ } else {
88091
+ return -1;
88092
+ }
88093
+ }
88094
+
87906
88095
  void SignFun::RegisterFunction(BuiltinFunctions &set) {
87907
88096
  ScalarFunctionSet sign("sign");
87908
88097
  for (auto &type : LogicalType::Numeric()) {
@@ -88282,7 +88471,7 @@ struct ExpOperator {
88282
88471
 
88283
88472
  void ExpFun::RegisterFunction(BuiltinFunctions &set) {
88284
88473
  set.AddFunction(ScalarFunction("exp", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88285
- UnaryDoubleFunctionWrapper<double, ExpOperator>));
88474
+ ScalarFunction::UnaryFunction<double, double, ExpOperator>));
88286
88475
  }
88287
88476
 
88288
88477
  //===--------------------------------------------------------------------===//
@@ -88297,7 +88486,7 @@ struct PowOperator {
88297
88486
 
88298
88487
  void PowFun::RegisterFunction(BuiltinFunctions &set) {
88299
88488
  ScalarFunction power_function("pow", {LogicalType::DOUBLE, LogicalType::DOUBLE}, LogicalType::DOUBLE,
88300
- BinaryDoubleFunctionWrapper<double, PowOperator>);
88489
+ ScalarFunction::BinaryFunction<double, double, double, PowOperator>);
88301
88490
  set.AddFunction(power_function);
88302
88491
  power_function.name = "power";
88303
88492
  set.AddFunction(power_function);
@@ -88312,14 +88501,17 @@ void PowFun::RegisterFunction(BuiltinFunctions &set) {
88312
88501
  //===--------------------------------------------------------------------===//
88313
88502
  struct SqrtOperator {
88314
88503
  template <class TA, class TR>
88315
- static inline TR Operation(TA left) {
88316
- return std::sqrt(left);
88504
+ static inline TR Operation(TA input) {
88505
+ if (input < 0) {
88506
+ throw OutOfRangeException("cannot take square root of a negative number");
88507
+ }
88508
+ return std::sqrt(input);
88317
88509
  }
88318
88510
  };
88319
88511
 
88320
88512
  void SqrtFun::RegisterFunction(BuiltinFunctions &set) {
88321
88513
  set.AddFunction(ScalarFunction("sqrt", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88322
- UnaryDoubleFunctionWrapper<double, SqrtOperator>));
88514
+ ScalarFunction::UnaryFunction<double, double, SqrtOperator>));
88323
88515
  }
88324
88516
 
88325
88517
  //===--------------------------------------------------------------------===//
@@ -88334,7 +88526,7 @@ struct CbRtOperator {
88334
88526
 
88335
88527
  void CbrtFun::RegisterFunction(BuiltinFunctions &set) {
88336
88528
  set.AddFunction(ScalarFunction("cbrt", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88337
- UnaryDoubleFunctionWrapper<double, CbRtOperator>));
88529
+ ScalarFunction::UnaryFunction<double, double, CbRtOperator>));
88338
88530
  }
88339
88531
 
88340
88532
  //===--------------------------------------------------------------------===//
@@ -88343,14 +88535,20 @@ void CbrtFun::RegisterFunction(BuiltinFunctions &set) {
88343
88535
 
88344
88536
  struct LnOperator {
88345
88537
  template <class TA, class TR>
88346
- static inline TR Operation(TA left) {
88347
- return std::log(left);
88538
+ static inline TR Operation(TA input) {
88539
+ if (input < 0) {
88540
+ throw OutOfRangeException("cannot take logarithm of a negative number");
88541
+ }
88542
+ if (input == 0) {
88543
+ throw OutOfRangeException("cannot take logarithm of zero");
88544
+ }
88545
+ return std::log(input);
88348
88546
  }
88349
88547
  };
88350
88548
 
88351
88549
  void LnFun::RegisterFunction(BuiltinFunctions &set) {
88352
88550
  set.AddFunction(ScalarFunction("ln", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88353
- UnaryDoubleFunctionWrapper<double, LnOperator>));
88551
+ ScalarFunction::UnaryFunction<double, double, LnOperator>));
88354
88552
  }
88355
88553
 
88356
88554
  //===--------------------------------------------------------------------===//
@@ -88358,14 +88556,20 @@ void LnFun::RegisterFunction(BuiltinFunctions &set) {
88358
88556
  //===--------------------------------------------------------------------===//
88359
88557
  struct Log10Operator {
88360
88558
  template <class TA, class TR>
88361
- static inline TR Operation(TA left) {
88362
- return std::log10(left);
88559
+ static inline TR Operation(TA input) {
88560
+ if (input < 0) {
88561
+ throw OutOfRangeException("cannot take logarithm of a negative number");
88562
+ }
88563
+ if (input == 0) {
88564
+ throw OutOfRangeException("cannot take logarithm of zero");
88565
+ }
88566
+ return std::log10(input);
88363
88567
  }
88364
88568
  };
88365
88569
 
88366
88570
  void Log10Fun::RegisterFunction(BuiltinFunctions &set) {
88367
88571
  set.AddFunction({"log10", "log"}, ScalarFunction({LogicalType::DOUBLE}, LogicalType::DOUBLE,
88368
- UnaryDoubleFunctionWrapper<double, Log10Operator>));
88572
+ ScalarFunction::UnaryFunction<double, double, Log10Operator>));
88369
88573
  }
88370
88574
 
88371
88575
  //===--------------------------------------------------------------------===//
@@ -88373,14 +88577,20 @@ void Log10Fun::RegisterFunction(BuiltinFunctions &set) {
88373
88577
  //===--------------------------------------------------------------------===//
88374
88578
  struct Log2Operator {
88375
88579
  template <class TA, class TR>
88376
- static inline TR Operation(TA left) {
88377
- return std::log2(left);
88580
+ static inline TR Operation(TA input) {
88581
+ if (input < 0) {
88582
+ throw OutOfRangeException("cannot take logarithm of a negative number");
88583
+ }
88584
+ if (input == 0) {
88585
+ throw OutOfRangeException("cannot take logarithm of zero");
88586
+ }
88587
+ return std::log2(input);
88378
88588
  }
88379
88589
  };
88380
88590
 
88381
88591
  void Log2Fun::RegisterFunction(BuiltinFunctions &set) {
88382
88592
  set.AddFunction(ScalarFunction("log2", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88383
- UnaryDoubleFunctionWrapper<double, Log2Operator>));
88593
+ ScalarFunction::UnaryFunction<double, double, Log2Operator>));
88384
88594
  }
88385
88595
 
88386
88596
  //===--------------------------------------------------------------------===//
@@ -88408,7 +88618,7 @@ struct DegreesOperator {
88408
88618
 
88409
88619
  void DegreesFun::RegisterFunction(BuiltinFunctions &set) {
88410
88620
  set.AddFunction(ScalarFunction("degrees", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88411
- UnaryDoubleFunctionWrapper<double, DegreesOperator>));
88621
+ ScalarFunction::UnaryFunction<double, double, DegreesOperator>));
88412
88622
  }
88413
88623
 
88414
88624
  //===--------------------------------------------------------------------===//
@@ -88423,12 +88633,83 @@ struct RadiansOperator {
88423
88633
 
88424
88634
  void RadiansFun::RegisterFunction(BuiltinFunctions &set) {
88425
88635
  set.AddFunction(ScalarFunction("radians", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88426
- UnaryDoubleFunctionWrapper<double, RadiansOperator>));
88636
+ ScalarFunction::UnaryFunction<double, double, RadiansOperator>));
88637
+ }
88638
+
88639
+ //===--------------------------------------------------------------------===//
88640
+ // isnan
88641
+ //===--------------------------------------------------------------------===//
88642
+ struct IsNanOperator {
88643
+ template <class TA, class TR>
88644
+ static inline TR Operation(TA input) {
88645
+ return Value::IsNan(input);
88646
+ }
88647
+ };
88648
+
88649
+ void IsNanFun::RegisterFunction(BuiltinFunctions &set) {
88650
+ ScalarFunctionSet funcs("isnan");
88651
+ funcs.AddFunction(ScalarFunction({LogicalType::FLOAT}, LogicalType::BOOLEAN,
88652
+ ScalarFunction::UnaryFunction<float, bool, IsNanOperator>));
88653
+ funcs.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::BOOLEAN,
88654
+ ScalarFunction::UnaryFunction<double, bool, IsNanOperator>));
88655
+ set.AddFunction(funcs);
88656
+ }
88657
+
88658
+ //===--------------------------------------------------------------------===//
88659
+ // isinf
88660
+ //===--------------------------------------------------------------------===//
88661
+ struct IsInfiniteOperator {
88662
+ template <class TA, class TR>
88663
+ static inline TR Operation(TA input) {
88664
+ return !Value::IsNan(input) && !Value::IsFinite(input);
88665
+ }
88666
+ };
88667
+
88668
+ void IsInfiniteFun::RegisterFunction(BuiltinFunctions &set) {
88669
+ ScalarFunctionSet funcs("isinf");
88670
+ funcs.AddFunction(ScalarFunction({LogicalType::FLOAT}, LogicalType::BOOLEAN,
88671
+ ScalarFunction::UnaryFunction<float, bool, IsInfiniteOperator>));
88672
+ funcs.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::BOOLEAN,
88673
+ ScalarFunction::UnaryFunction<double, bool, IsInfiniteOperator>));
88674
+ set.AddFunction(funcs);
88675
+ }
88676
+
88677
+ //===--------------------------------------------------------------------===//
88678
+ // isfinite
88679
+ //===--------------------------------------------------------------------===//
88680
+ struct IsFiniteOperator {
88681
+ template <class TA, class TR>
88682
+ static inline TR Operation(TA input) {
88683
+ return Value::IsFinite(input);
88684
+ }
88685
+ };
88686
+
88687
+ void IsFiniteFun::RegisterFunction(BuiltinFunctions &set) {
88688
+ ScalarFunctionSet funcs("isfinite");
88689
+ funcs.AddFunction(ScalarFunction({LogicalType::FLOAT}, LogicalType::BOOLEAN,
88690
+ ScalarFunction::UnaryFunction<float, bool, IsFiniteOperator>));
88691
+ funcs.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::BOOLEAN,
88692
+ ScalarFunction::UnaryFunction<double, bool, IsFiniteOperator>));
88693
+ set.AddFunction(funcs);
88427
88694
  }
88428
88695
 
88429
88696
  //===--------------------------------------------------------------------===//
88430
88697
  // sin
88431
88698
  //===--------------------------------------------------------------------===//
88699
+ template <class OP>
88700
+ struct NoInfiniteDoubleWrapper {
88701
+ template <class INPUT_TYPE, class RESULT_TYPE>
88702
+ static RESULT_TYPE Operation(INPUT_TYPE input) {
88703
+ if (DUCKDB_UNLIKELY(!Value::IsFinite(input))) {
88704
+ if (Value::IsNan(input)) {
88705
+ return input;
88706
+ }
88707
+ throw OutOfRangeException("input value %lf is out of range for numeric function", input);
88708
+ }
88709
+ return OP::template Operation<INPUT_TYPE, RESULT_TYPE>(input);
88710
+ }
88711
+ };
88712
+
88432
88713
  struct SinOperator {
88433
88714
  template <class TA, class TR>
88434
88715
  static inline TR Operation(TA input) {
@@ -88437,8 +88718,9 @@ struct SinOperator {
88437
88718
  };
88438
88719
 
88439
88720
  void SinFun::RegisterFunction(BuiltinFunctions &set) {
88440
- set.AddFunction(ScalarFunction("sin", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88441
- UnaryDoubleFunctionWrapper<double, SinOperator>));
88721
+ set.AddFunction(
88722
+ ScalarFunction("sin", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88723
+ ScalarFunction::UnaryFunction<double, double, NoInfiniteDoubleWrapper<SinOperator>>));
88442
88724
  }
88443
88725
 
88444
88726
  //===--------------------------------------------------------------------===//
@@ -88452,8 +88734,9 @@ struct CosOperator {
88452
88734
  };
88453
88735
 
88454
88736
  void CosFun::RegisterFunction(BuiltinFunctions &set) {
88455
- set.AddFunction(ScalarFunction("cos", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88456
- UnaryDoubleFunctionWrapper<double, CosOperator>));
88737
+ set.AddFunction(
88738
+ ScalarFunction("cos", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88739
+ ScalarFunction::UnaryFunction<double, double, NoInfiniteDoubleWrapper<CosOperator>>));
88457
88740
  }
88458
88741
 
88459
88742
  //===--------------------------------------------------------------------===//
@@ -88467,8 +88750,9 @@ struct TanOperator {
88467
88750
  };
88468
88751
 
88469
88752
  void TanFun::RegisterFunction(BuiltinFunctions &set) {
88470
- set.AddFunction(ScalarFunction("tan", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88471
- UnaryDoubleFunctionWrapper<double, TanOperator>));
88753
+ set.AddFunction(
88754
+ ScalarFunction("tan", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88755
+ ScalarFunction::UnaryFunction<double, double, NoInfiniteDoubleWrapper<TanOperator>>));
88472
88756
  }
88473
88757
 
88474
88758
  //===--------------------------------------------------------------------===//
@@ -88485,8 +88769,9 @@ struct ASinOperator {
88485
88769
  };
88486
88770
 
88487
88771
  void AsinFun::RegisterFunction(BuiltinFunctions &set) {
88488
- set.AddFunction(ScalarFunction("asin", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88489
- UnaryDoubleFunctionWrapper<double, ASinOperator>));
88772
+ set.AddFunction(
88773
+ ScalarFunction("asin", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88774
+ ScalarFunction::UnaryFunction<double, double, NoInfiniteDoubleWrapper<ASinOperator>>));
88490
88775
  }
88491
88776
 
88492
88777
  //===--------------------------------------------------------------------===//
@@ -88501,7 +88786,7 @@ struct ATanOperator {
88501
88786
 
88502
88787
  void AtanFun::RegisterFunction(BuiltinFunctions &set) {
88503
88788
  set.AddFunction(ScalarFunction("atan", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88504
- UnaryDoubleFunctionWrapper<double, ATanOperator>));
88789
+ ScalarFunction::UnaryFunction<double, double, ATanOperator>));
88505
88790
  }
88506
88791
 
88507
88792
  //===--------------------------------------------------------------------===//
@@ -88516,7 +88801,7 @@ struct ATan2 {
88516
88801
 
88517
88802
  void Atan2Fun::RegisterFunction(BuiltinFunctions &set) {
88518
88803
  set.AddFunction(ScalarFunction("atan2", {LogicalType::DOUBLE, LogicalType::DOUBLE}, LogicalType::DOUBLE,
88519
- BinaryDoubleFunctionWrapper<double, ATan2>));
88804
+ ScalarFunction::BinaryFunction<double, double, double, ATan2>));
88520
88805
  }
88521
88806
 
88522
88807
  //===--------------------------------------------------------------------===//
@@ -88530,8 +88815,8 @@ struct ACos {
88530
88815
  };
88531
88816
 
88532
88817
  void AcosFun::RegisterFunction(BuiltinFunctions &set) {
88533
- set.AddFunction(
88534
- ScalarFunction("acos", {LogicalType::DOUBLE}, LogicalType::DOUBLE, UnaryDoubleFunctionWrapper<double, ACos>));
88818
+ set.AddFunction(ScalarFunction("acos", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88819
+ ScalarFunction::UnaryFunction<double, double, NoInfiniteDoubleWrapper<ACos>>));
88535
88820
  }
88536
88821
 
88537
88822
  //===--------------------------------------------------------------------===//
@@ -88545,8 +88830,9 @@ struct CotOperator {
88545
88830
  };
88546
88831
 
88547
88832
  void CotFun::RegisterFunction(BuiltinFunctions &set) {
88548
- set.AddFunction(ScalarFunction("cot", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88549
- UnaryDoubleFunctionWrapper<double, CotOperator>));
88833
+ set.AddFunction(
88834
+ ScalarFunction("cot", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88835
+ ScalarFunction::UnaryFunction<double, double, NoInfiniteDoubleWrapper<CotOperator>>));
88550
88836
  }
88551
88837
 
88552
88838
  //===--------------------------------------------------------------------===//
@@ -88554,14 +88840,17 @@ void CotFun::RegisterFunction(BuiltinFunctions &set) {
88554
88840
  //===--------------------------------------------------------------------===//
88555
88841
  struct GammaOperator {
88556
88842
  template <class TA, class TR>
88557
- static inline TR Operation(TA left) {
88558
- return std::tgamma(left);
88843
+ static inline TR Operation(TA input) {
88844
+ if (input == 0) {
88845
+ throw OutOfRangeException("cannot take gamma of zero");
88846
+ }
88847
+ return std::tgamma(input);
88559
88848
  }
88560
88849
  };
88561
88850
 
88562
88851
  void GammaFun::RegisterFunction(BuiltinFunctions &set) {
88563
88852
  set.AddFunction(ScalarFunction("gamma", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88564
- UnaryDoubleFunctionWrapper<double, GammaOperator>));
88853
+ ScalarFunction::UnaryFunction<double, double, GammaOperator>));
88565
88854
  }
88566
88855
 
88567
88856
  //===--------------------------------------------------------------------===//
@@ -88569,14 +88858,17 @@ void GammaFun::RegisterFunction(BuiltinFunctions &set) {
88569
88858
  //===--------------------------------------------------------------------===//
88570
88859
  struct LogGammaOperator {
88571
88860
  template <class TA, class TR>
88572
- static inline TR Operation(TA left) {
88573
- return std::lgamma(left);
88861
+ static inline TR Operation(TA input) {
88862
+ if (input == 0) {
88863
+ throw OutOfRangeException("cannot take log gamma of zero");
88864
+ }
88865
+ return std::lgamma(input);
88574
88866
  }
88575
88867
  };
88576
88868
 
88577
88869
  void LogGammaFun::RegisterFunction(BuiltinFunctions &set) {
88578
88870
  set.AddFunction(ScalarFunction("lgamma", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88579
- UnaryDoubleFunctionWrapper<double, LogGammaOperator>));
88871
+ ScalarFunction::UnaryFunction<double, double, LogGammaOperator>));
88580
88872
  }
88581
88873
 
88582
88874
  //===--------------------------------------------------------------------===//
@@ -88626,7 +88918,7 @@ struct EvenOperator {
88626
88918
 
88627
88919
  void EvenFun::RegisterFunction(BuiltinFunctions &set) {
88628
88920
  set.AddFunction(ScalarFunction("even", {LogicalType::DOUBLE}, LogicalType::DOUBLE,
88629
- UnaryDoubleFunctionWrapper<double, EvenOperator>));
88921
+ ScalarFunction::UnaryFunction<double, double, EvenOperator>));
88630
88922
  }
88631
88923
 
88632
88924
  } // namespace duckdb
@@ -88766,6 +89058,10 @@ void BuiltinFunctions::RegisterMathFunctions() {
88766
89058
  Register<NextAfterFun>();
88767
89059
 
88768
89060
  Register<EvenFun>();
89061
+
89062
+ Register<IsNanFun>();
89063
+ Register<IsInfiniteFun>();
89064
+ Register<IsFiniteFun>();
88769
89065
  }
88770
89066
 
88771
89067
  } // namespace duckdb
@@ -88811,7 +89107,7 @@ namespace duckdb {
88811
89107
  template <>
88812
89108
  float AddOperator::Operation(float left, float right) {
88813
89109
  auto result = left + right;
88814
- if (!Value::FloatIsValid(result)) {
89110
+ if (!Value::FloatIsFinite(result)) {
88815
89111
  throw OutOfRangeException("Overflow in addition of float!");
88816
89112
  }
88817
89113
  return result;
@@ -88820,7 +89116,7 @@ float AddOperator::Operation(float left, float right) {
88820
89116
  template <>
88821
89117
  double AddOperator::Operation(double left, double right) {
88822
89118
  auto result = left + right;
88823
- if (!Value::DoubleIsValid(result)) {
89119
+ if (!Value::DoubleIsFinite(result)) {
88824
89120
  throw OutOfRangeException("Overflow in addition of double!");
88825
89121
  }
88826
89122
  return result;
@@ -89447,6 +89743,16 @@ struct NegateOperator {
89447
89743
  }
89448
89744
  };
89449
89745
 
89746
+ template <>
89747
+ bool NegateOperator::CanNegate(float input) {
89748
+ return Value::FloatIsFinite(input);
89749
+ }
89750
+
89751
+ template <>
89752
+ bool NegateOperator::CanNegate(double input) {
89753
+ return Value::DoubleIsFinite(input);
89754
+ }
89755
+
89450
89756
  template <>
89451
89757
  interval_t NegateOperator::Operation(interval_t input) {
89452
89758
  interval_t result;
@@ -89772,7 +90078,7 @@ void MultiplyFun::RegisterFunction(BuiltinFunctions &set) {
89772
90078
  template <>
89773
90079
  float DivideOperator::Operation(float left, float right) {
89774
90080
  auto result = left / right;
89775
- if (!Value::FloatIsValid(result)) {
90081
+ if (!Value::FloatIsFinite(result)) {
89776
90082
  throw OutOfRangeException("Overflow in division of float!");
89777
90083
  }
89778
90084
  return result;
@@ -89781,7 +90087,7 @@ float DivideOperator::Operation(float left, float right) {
89781
90087
  template <>
89782
90088
  double DivideOperator::Operation(double left, double right) {
89783
90089
  auto result = left / right;
89784
- if (!Value::DoubleIsValid(result)) {
90090
+ if (!Value::DoubleIsFinite(result)) {
89785
90091
  throw OutOfRangeException("Overflow in division of double!");
89786
90092
  }
89787
90093
  return result;
@@ -89893,13 +90199,21 @@ void DivideFun::RegisterFunction(BuiltinFunctions &set) {
89893
90199
  template <>
89894
90200
  float ModuloOperator::Operation(float left, float right) {
89895
90201
  D_ASSERT(right != 0);
89896
- return std::fmod(left, right);
90202
+ auto result = std::fmod(left, right);
90203
+ if (!Value::FloatIsFinite(result)) {
90204
+ throw OutOfRangeException("Overflow in modulo of float!");
90205
+ }
90206
+ return result;
89897
90207
  }
89898
90208
 
89899
90209
  template <>
89900
90210
  double ModuloOperator::Operation(double left, double right) {
89901
90211
  D_ASSERT(right != 0);
89902
- return std::fmod(left, right);
90212
+ auto result = std::fmod(left, right);
90213
+ if (!Value::DoubleIsFinite(result)) {
90214
+ throw OutOfRangeException("Overflow in modulo of double!");
90215
+ }
90216
+ return result;
89903
90217
  }
89904
90218
 
89905
90219
  template <>
@@ -90142,7 +90456,7 @@ namespace duckdb {
90142
90456
  template <>
90143
90457
  float MultiplyOperator::Operation(float left, float right) {
90144
90458
  auto result = left * right;
90145
- if (!Value::FloatIsValid(result)) {
90459
+ if (!Value::FloatIsFinite(result)) {
90146
90460
  throw OutOfRangeException("Overflow in multiplication of float!");
90147
90461
  }
90148
90462
  return result;
@@ -90151,7 +90465,7 @@ float MultiplyOperator::Operation(float left, float right) {
90151
90465
  template <>
90152
90466
  double MultiplyOperator::Operation(double left, double right) {
90153
90467
  auto result = left * right;
90154
- if (!Value::DoubleIsValid(result)) {
90468
+ if (!Value::DoubleIsFinite(result)) {
90155
90469
  throw OutOfRangeException("Overflow in multiplication of double!");
90156
90470
  }
90157
90471
  return result;
@@ -90375,7 +90689,7 @@ namespace duckdb {
90375
90689
  template <>
90376
90690
  float SubtractOperator::Operation(float left, float right) {
90377
90691
  auto result = left - right;
90378
- if (!Value::FloatIsValid(result)) {
90692
+ if (!Value::FloatIsFinite(result)) {
90379
90693
  throw OutOfRangeException("Overflow in subtraction of float!");
90380
90694
  }
90381
90695
  return result;
@@ -90384,7 +90698,7 @@ float SubtractOperator::Operation(float left, float right) {
90384
90698
  template <>
90385
90699
  double SubtractOperator::Operation(double left, double right) {
90386
90700
  auto result = left - right;
90387
- if (!Value::DoubleIsValid(result)) {
90701
+ if (!Value::DoubleIsFinite(result)) {
90388
90702
  throw OutOfRangeException("Overflow in subtraction of double!");
90389
90703
  }
90390
90704
  return result;
@@ -97086,6 +97400,7 @@ void ColumnArrowToDuckDB(Vector &vector, ArrowArray &array, ArrowScanState &scan
97086
97400
  case LogicalTypeId::SMALLINT:
97087
97401
  case LogicalTypeId::INTEGER:
97088
97402
  case LogicalTypeId::FLOAT:
97403
+ case LogicalTypeId::DOUBLE:
97089
97404
  case LogicalTypeId::UTINYINT:
97090
97405
  case LogicalTypeId::USMALLINT:
97091
97406
  case LogicalTypeId::UINTEGER:
@@ -97099,18 +97414,6 @@ void ColumnArrowToDuckDB(Vector &vector, ArrowArray &array, ArrowScanState &scan
97099
97414
  DirectConversion(vector, array, scan_state, nested_offset);
97100
97415
  break;
97101
97416
  }
97102
- case LogicalTypeId::DOUBLE: {
97103
- DirectConversion(vector, array, scan_state, nested_offset);
97104
- //! Need to check if there are NaNs, if yes, must turn that to null
97105
- auto data = (double *)vector.GetData();
97106
- auto &mask = FlatVector::Validity(vector);
97107
- for (idx_t row_idx = 0; row_idx < size; row_idx++) {
97108
- if (!Value::DoubleIsValid(data[row_idx])) {
97109
- mask.SetInvalid(row_idx);
97110
- }
97111
- }
97112
- break;
97113
- }
97114
97417
  case LogicalTypeId::JSON:
97115
97418
  case LogicalTypeId::VARCHAR: {
97116
97419
  auto original_type = arrow_convert_data[col_idx]->variable_sz_type[arrow_convert_idx.first++];
@@ -102096,6 +102399,8 @@ void PragmaTableInfo::RegisterFunction(BuiltinFunctions &set) {
102096
102399
  } // namespace duckdb
102097
102400
 
102098
102401
 
102402
+ #include <cmath>
102403
+ #include <limits>
102099
102404
 
102100
102405
  namespace duckdb {
102101
102406
 
@@ -102198,6 +102503,13 @@ static vector<TestType> GetTestTypes() {
102198
102503
  Value(LogicalType::INTEGER), Value::INTEGER(-42)});
102199
102504
  result.emplace_back(int_list_type, "int_array", empty_int_list, int_list);
102200
102505
 
102506
+ auto double_list_type = LogicalType::LIST(LogicalType::DOUBLE);
102507
+ auto empty_double_list = Value::EMPTYLIST(LogicalType::DOUBLE);
102508
+ auto double_list = Value::LIST(
102509
+ {Value::DOUBLE(42), Value::DOUBLE(NAN), Value::DOUBLE(std::numeric_limits<double>::infinity()),
102510
+ Value::DOUBLE(-std::numeric_limits<double>::infinity()), Value(LogicalType::DOUBLE), Value::DOUBLE(-42)});
102511
+ result.emplace_back(double_list_type, "double_array", empty_double_list, double_list);
102512
+
102201
102513
  auto varchar_list_type = LogicalType::LIST(LogicalType::VARCHAR);
102202
102514
  auto empty_varchar_list = Value::EMPTYLIST(LogicalType::VARCHAR);
102203
102515
  auto varchar_list =
@@ -103235,17 +103547,11 @@ void BaseAppender::Append(string_t value) {
103235
103547
 
103236
103548
  template <>
103237
103549
  void BaseAppender::Append(float value) {
103238
- if (!Value::FloatIsValid(value)) {
103239
- throw InvalidInputException("Float value is out of range!");
103240
- }
103241
103550
  AppendValueInternal<float>(value);
103242
103551
  }
103243
103552
 
103244
103553
  template <>
103245
103554
  void BaseAppender::Append(double value) {
103246
- if (!Value::DoubleIsValid(value)) {
103247
- throw InvalidInputException("Double value is out of range!");
103248
- }
103249
103555
  AppendValueInternal<double>(value);
103250
103556
  }
103251
103557
 
@@ -104331,7 +104637,7 @@ double duckdb_hugeint_to_double(duckdb_hugeint val) {
104331
104637
 
104332
104638
  duckdb_hugeint duckdb_double_to_hugeint(double val) {
104333
104639
  hugeint_t internal_result;
104334
- if (!Value::DoubleIsValid(val) || !Hugeint::TryConvert<double>(val, internal_result)) {
104640
+ if (!Value::DoubleIsFinite(val) || !Hugeint::TryConvert<double>(val, internal_result)) {
104335
104641
  internal_result.lower = 0;
104336
104642
  internal_result.upper = 0;
104337
104643
  }
@@ -104621,16 +104927,10 @@ duckdb_state duckdb_bind_uint64(duckdb_prepared_statement prepared_statement, id
104621
104927
  }
104622
104928
 
104623
104929
  duckdb_state duckdb_bind_float(duckdb_prepared_statement prepared_statement, idx_t param_idx, float val) {
104624
- if (!Value::FloatIsValid(val)) {
104625
- return DuckDBError;
104626
- }
104627
104930
  return duckdb_bind_value(prepared_statement, param_idx, Value::FLOAT(val));
104628
104931
  }
104629
104932
 
104630
104933
  duckdb_state duckdb_bind_double(duckdb_prepared_statement prepared_statement, idx_t param_idx, double val) {
104631
- if (!Value::DoubleIsValid(val)) {
104632
- return DuckDBError;
104633
- }
104634
104934
  return duckdb_bind_value(prepared_statement, param_idx, Value::DOUBLE(val));
104635
104935
  }
104636
104936
 
@@ -117856,7 +118156,7 @@ void OperatorProfiler::AddTiming(const PhysicalOperator *op, double time, idx_t
117856
118156
  if (!enabled) {
117857
118157
  return;
117858
118158
  }
117859
- if (!Value::DoubleIsValid(time)) {
118159
+ if (!Value::DoubleIsFinite(time)) {
117860
118160
  return;
117861
118161
  }
117862
118162
  auto entry = timings.find(op);
@@ -119089,6 +119389,7 @@ public:
119089
119389
  unique_ptr<ParsedExpression> condition;
119090
119390
  unique_ptr<TableRef> table;
119091
119391
  vector<unique_ptr<TableRef>> using_clauses;
119392
+ vector<unique_ptr<ParsedExpression>> returning_list;
119092
119393
 
119093
119394
  protected:
119094
119395
  DeleteStatement(const DeleteStatement &other);
@@ -120393,6 +120694,8 @@ public:
120393
120694
  unique_ptr<TableRef> from_table;
120394
120695
  vector<string> columns;
120395
120696
  vector<unique_ptr<ParsedExpression>> expressions;
120697
+ //! keep track of optional returningList if statement contains a RETURNING keyword
120698
+ vector<unique_ptr<ParsedExpression>> returning_list;
120396
120699
 
120397
120700
  protected:
120398
120701
  UpdateStatement(const UpdateStatement &other);
@@ -127788,10 +128091,14 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) {
127788
128091
  remove.VisitOperator(*op.children[0]);
127789
128092
  return;
127790
128093
  }
127791
- case LogicalOperatorType::LOGICAL_INSERT: {
127792
- //! When RETURNING is used, a PROJECTION is the top level operator
127793
- //! We still need to project all values from the insert so the projection
127794
- //! on top of the INSERT can select from only that table values being inserted
128094
+ case LogicalOperatorType::LOGICAL_INSERT:
128095
+ case LogicalOperatorType::LOGICAL_UPDATE:
128096
+ case LogicalOperatorType::LOGICAL_DELETE: {
128097
+ //! When RETURNING is used, a PROJECTION is the top level operator for INSERTS, UPDATES, and DELETES
128098
+ //! We still need to project all values from these operators so the projection
128099
+ //! on top of them can select from only the table values being inserted.
128100
+ //! TODO: Push down the projections from the returning statement
128101
+ //! TODO: Be careful because you might be adding expressions when a user returns *
127795
128102
  RemoveUnusedColumns remove(binder, context, true);
127796
128103
  remove.VisitOperatorExpressions(op);
127797
128104
  remove.VisitOperator(*op.children[0]);
@@ -146604,9 +146911,6 @@ unique_ptr<ConstantExpression> Transformer::TransformValue(duckdb_libpgquery::PG
146604
146911
  }
146605
146912
  // if there is a decimal or the value is too big to cast as either hugeint or bigint
146606
146913
  double dbl_value = Cast::Operation<string_t, double>(str_val);
146607
- if (!Value::DoubleIsValid(dbl_value)) {
146608
- throw ParserException("Double value \"%s\" is out of range!", val.val.str);
146609
- }
146610
146914
  return make_unique<ConstantExpression>(Value::DOUBLE(dbl_value));
146611
146915
  }
146612
146916
  case duckdb_libpgquery::T_PGNull:
@@ -149736,6 +150040,10 @@ unique_ptr<DeleteStatement> Transformer::TransformDelete(duckdb_libpgquery::PGNo
149736
150040
  result->using_clauses.push_back(move(using_entry));
149737
150041
  }
149738
150042
  }
150043
+
150044
+ if (stmt->returningList) {
150045
+ Transformer::TransformExpressionList(*(stmt->returningList), result->returning_list);
150046
+ }
149739
150047
  return result;
149740
150048
  }
149741
150049
 
@@ -150500,6 +150808,11 @@ unique_ptr<UpdateStatement> Transformer::TransformUpdate(duckdb_libpgquery::PGNo
150500
150808
  result->expressions.push_back(TransformExpression(target->val));
150501
150809
  }
150502
150810
 
150811
+ // Grab and transform the returning columns from the parser.
150812
+ if (stmt->returningList) {
150813
+ Transformer::TransformExpressionList(*(stmt->returningList), result->returning_list);
150814
+ }
150815
+
150503
150816
  result->condition = TransformExpression(stmt->whereClause);
150504
150817
  return result;
150505
150818
  }
@@ -155700,6 +156013,32 @@ unique_ptr<BoundCreateTableInfo> Binder::BindCreateTableInfo(unique_ptr<CreateIn
155700
156013
 
155701
156014
 
155702
156015
 
156016
+ //===----------------------------------------------------------------------===//
156017
+ // DuckDB
156018
+ //
156019
+ // duckdb/planner/expression_binder/returning_binder.hpp
156020
+ //
156021
+ //
156022
+ //===----------------------------------------------------------------------===//
156023
+
156024
+
156025
+
156026
+
156027
+
156028
+ namespace duckdb {
156029
+
156030
+ //! The RETURNING binder is responsible for binding expressions within the RETURNING statement
156031
+ class ReturningBinder : public ExpressionBinder {
156032
+ public:
156033
+ ReturningBinder(Binder &binder, ClientContext &context);
156034
+
156035
+ protected:
156036
+ BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
156037
+ bool root_expression = false) override;
156038
+ };
156039
+
156040
+ } // namespace duckdb
156041
+
155703
156042
 
155704
156043
 
155705
156044
 
@@ -155774,10 +156113,21 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) {
155774
156113
  LogicalType::ROW_TYPE, ColumnBinding(get.table_index, get.column_ids.size())));
155775
156114
  get.column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID);
155776
156115
 
155777
- result.plan = move(del);
155778
- result.names = {"Count"};
155779
- result.types = {LogicalType::BIGINT};
155780
- this->allow_stream_result = false;
156116
+ if (!stmt.returning_list.empty()) {
156117
+ del->return_chunk = true;
156118
+
156119
+ auto update_table_index = GenerateTableIndex();
156120
+ del->table_index = update_table_index;
156121
+
156122
+ unique_ptr<LogicalOperator> del_as_logicaloperator = move(del);
156123
+ return BindReturning(move(stmt.returning_list), table, update_table_index, move(del_as_logicaloperator),
156124
+ move(result));
156125
+ } else {
156126
+ result.plan = move(del);
156127
+ result.names = {"Count"};
156128
+ result.types = {LogicalType::BIGINT};
156129
+ this->allow_stream_result = false;
156130
+ }
155781
156131
  return result;
155782
156132
  }
155783
156133
 
@@ -156100,31 +156450,6 @@ protected:
156100
156450
 
156101
156451
 
156102
156452
 
156103
- //===----------------------------------------------------------------------===//
156104
- // DuckDB
156105
- //
156106
- // duckdb/planner/expression_binder/returning_binder.hpp
156107
- //
156108
- //
156109
- //===----------------------------------------------------------------------===//
156110
-
156111
-
156112
-
156113
-
156114
-
156115
- namespace duckdb {
156116
-
156117
- //! The RETURNING binder is responsible for binding expressions within the RETURNING statement
156118
- class ReturningBinder : public ExpressionBinder {
156119
- public:
156120
- ReturningBinder(Binder &binder, ClientContext &context);
156121
-
156122
- protected:
156123
- BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
156124
- bool root_expression = false) override;
156125
- };
156126
-
156127
- } // namespace duckdb
156128
156453
 
156129
156454
 
156130
156455
  namespace duckdb {
@@ -156245,57 +156570,15 @@ BoundStatement Binder::Bind(InsertStatement &stmt) {
156245
156570
 
156246
156571
  if (!stmt.returning_list.empty()) {
156247
156572
  insert->return_chunk = true;
156248
- // clear result type and names because returning list will update them
156249
156573
  result.types.clear();
156250
156574
  result.names.clear();
156251
-
156252
156575
  auto insert_table_index = GenerateTableIndex();
156253
156576
  insert->table_index = insert_table_index;
156577
+ unique_ptr<LogicalOperator> index_as_logicaloperator = move(insert);
156254
156578
 
156255
- auto binder = Binder::CreateBinder(context);
156256
- auto types = table->GetTypes();
156257
- vector<std::string> names;
156258
- for (auto &col : table->columns) {
156259
- names.push_back(col.name);
156260
- }
156261
-
156262
- binder->bind_context.AddGenericBinding(insert->table_index, stmt.table, names, types);
156263
- ReturningBinder returning_binder(*binder, context);
156264
-
156265
- unique_ptr<LogicalOperator> insert_as_logicaloperator = move(insert);
156266
-
156267
- vector<unique_ptr<Expression>> projection_expressions;
156268
- LogicalType result_type;
156269
- for (auto &returning_expr : stmt.returning_list) {
156270
- auto expr_type = returning_expr->GetExpressionType();
156271
- if (expr_type == ExpressionType::STAR) {
156272
- auto generated_star_list = vector<unique_ptr<ParsedExpression>>();
156273
- binder->bind_context.GenerateAllColumnExpressions((StarExpression &)*returning_expr,
156274
- generated_star_list);
156275
-
156276
- for (auto &star_column : generated_star_list) {
156277
- auto star_expr = returning_binder.Bind(star_column, &result_type);
156278
- result.types.push_back(result_type);
156279
- result.names.push_back(star_expr->GetName());
156280
- projection_expressions.push_back(move(star_expr));
156281
- }
156282
- } else {
156283
- auto expr = returning_binder.Bind(returning_expr, &result_type);
156284
- result.names.push_back(expr->GetName());
156285
- result.types.push_back(result_type);
156286
- projection_expressions.push_back(move(expr));
156287
- }
156288
- }
156289
-
156290
- auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), move(projection_expressions));
156291
- projection->AddChild(move(insert_as_logicaloperator));
156292
- result.plan = move(projection);
156293
- D_ASSERT(result.types.size() == result.names.size());
156294
- this->allow_stream_result = true;
156295
- return result;
156579
+ return BindReturning(move(stmt.returning_list), table, insert_table_index, move(index_as_logicaloperator),
156580
+ move(result));
156296
156581
  } else {
156297
- insert->table_index = 0;
156298
- insert->return_chunk = false;
156299
156582
  D_ASSERT(result.types.size() == result.names.size());
156300
156583
  result.plan = move(insert);
156301
156584
  this->allow_stream_result = false;
@@ -156750,6 +157033,8 @@ static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, Log
156750
157033
  }
156751
157034
  // for index updates we always turn any update into an insert and a delete
156752
157035
  // we thus need all the columns to be available, hence we check if the update touches any index columns
157036
+ // If the returning keyword is used, we need access to the whole row in case the user requests it.
157037
+ // Therefore switch the update to a delete and insert.
156753
157038
  update.update_is_del_and_insert = false;
156754
157039
  table.storage->info->indexes.Scan([&](Index &index) {
156755
157040
  if (index.IndexIsUpdated(update.columns)) {
@@ -156767,8 +157052,9 @@ static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, Log
156767
157052
  }
156768
157053
  }
156769
157054
 
156770
- if (update.update_is_del_and_insert) {
156771
- // the update updates a column required by an index, push projections for all columns
157055
+ if (update.update_is_del_and_insert || update.return_chunk) {
157056
+ // the update updates a column required by an index or requires returning the updated rows,
157057
+ // push projections for all columns
156772
157058
  unordered_set<column_t> all_columns;
156773
157059
  for (idx_t i = 0; i < table.storage->column_definitions.size(); i++) {
156774
157060
  all_columns.insert(i);
@@ -156806,6 +157092,11 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
156806
157092
  this->read_only = false;
156807
157093
  }
156808
157094
  auto update = make_unique<LogicalUpdate>(table);
157095
+
157096
+ // set return_chunk boolean early because it needs uses update_is_del_and_insert logic
157097
+ if (!stmt.returning_list.empty()) {
157098
+ update->return_chunk = true;
157099
+ }
156809
157100
  // bind the default values
156810
157101
  BindDefaultValues(table->columns, update->bound_defaults);
156811
157102
 
@@ -156824,6 +157115,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
156824
157115
 
156825
157116
  auto proj_index = GenerateTableIndex();
156826
157117
  vector<unique_ptr<Expression>> projection_expressions;
157118
+
156827
157119
  for (idx_t i = 0; i < stmt.columns.size(); i++) {
156828
157120
  auto &colname = stmt.columns[i];
156829
157121
  auto &expr = stmt.expressions[i];
@@ -156849,6 +157141,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
156849
157141
  projection_expressions.push_back(move(bound_expr));
156850
157142
  }
156851
157143
  }
157144
+
156852
157145
  // now create the projection
156853
157146
  auto proj = make_unique<LogicalProjection>(proj_index, move(projection_expressions));
156854
157147
  proj->AddChild(move(root));
@@ -156864,10 +157157,21 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
156864
157157
  // set the projection as child of the update node and finalize the result
156865
157158
  update->AddChild(move(proj));
156866
157159
 
156867
- result.names = {"Count"};
156868
- result.types = {LogicalType::BIGINT};
156869
- result.plan = move(update);
156870
- this->allow_stream_result = false;
157160
+ if (!stmt.returning_list.empty()) {
157161
+ auto update_table_index = GenerateTableIndex();
157162
+ update->table_index = update_table_index;
157163
+ unique_ptr<LogicalOperator> update_as_logicaloperator = move(update);
157164
+
157165
+ return BindReturning(move(stmt.returning_list), table, update_table_index, move(update_as_logicaloperator),
157166
+ move(result));
157167
+
157168
+ } else {
157169
+ update->table_index = 0;
157170
+ result.names = {"Count"};
157171
+ result.types = {LogicalType::BIGINT};
157172
+ result.plan = move(update);
157173
+ this->allow_stream_result = false;
157174
+ }
156871
157175
  return result;
156872
157176
  }
156873
157177
 
@@ -158130,6 +158434,7 @@ unique_ptr<LogicalOperator> Binder::CreatePlan(BoundTableFunction &ref) {
158130
158434
 
158131
158435
 
158132
158436
 
158437
+
158133
158438
  #include <algorithm>
158134
158439
 
158135
158440
 
@@ -158498,6 +158803,53 @@ string Binder::FormatErrorRecursive(idx_t query_location, const string &message,
158498
158803
  return context.FormatErrorRecursive(message, values);
158499
158804
  }
158500
158805
 
158806
+ BoundStatement Binder::BindReturning(vector<unique_ptr<ParsedExpression>> returning_list, TableCatalogEntry *table,
158807
+ idx_t update_table_index, unique_ptr<LogicalOperator> child_operator,
158808
+ BoundStatement result) {
158809
+
158810
+ vector<LogicalType> types;
158811
+ vector<std::string> names;
158812
+
158813
+ auto binder = Binder::CreateBinder(context);
158814
+
158815
+ for (auto &col : table->columns) {
158816
+ names.push_back(col.name);
158817
+ types.push_back(col.type);
158818
+ }
158819
+
158820
+ binder->bind_context.AddGenericBinding(update_table_index, table->name, names, types);
158821
+ ReturningBinder returning_binder(*binder, context);
158822
+
158823
+ vector<unique_ptr<Expression>> projection_expressions;
158824
+ LogicalType result_type;
158825
+ for (auto &returning_expr : returning_list) {
158826
+ auto expr_type = returning_expr->GetExpressionType();
158827
+ if (expr_type == ExpressionType::STAR) {
158828
+ auto generated_star_list = vector<unique_ptr<ParsedExpression>>();
158829
+ binder->bind_context.GenerateAllColumnExpressions((StarExpression &)*returning_expr, generated_star_list);
158830
+
158831
+ for (auto &star_column : generated_star_list) {
158832
+ auto star_expr = returning_binder.Bind(star_column, &result_type);
158833
+ result.types.push_back(result_type);
158834
+ result.names.push_back(star_expr->GetName());
158835
+ projection_expressions.push_back(move(star_expr));
158836
+ }
158837
+ } else {
158838
+ auto expr = returning_binder.Bind(returning_expr, &result_type);
158839
+ result.names.push_back(expr->GetName());
158840
+ result.types.push_back(result_type);
158841
+ projection_expressions.push_back(move(expr));
158842
+ }
158843
+ }
158844
+
158845
+ auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), move(projection_expressions));
158846
+ projection->AddChild(move(child_operator));
158847
+ D_ASSERT(result.types.size() == result.names.size());
158848
+ result.plan = move(projection);
158849
+ this->allow_stream_result = true;
158850
+ return result;
158851
+ }
158852
+
158501
158853
  } // namespace duckdb
158502
158854
 
158503
158855