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/package.json +1 -1
- package/src/duckdb.cpp +740 -388
- package/src/duckdb.hpp +45 -16
- package/src/parquet-amalgamation.cpp +36583 -36595
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
|
|
18287
|
-
if (!(value
|
|
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
|
-
|
|
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
|
-
|
|
18297
|
-
|
|
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
|
-
|
|
18306
|
-
|
|
18307
|
-
|
|
18308
|
-
|
|
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 (
|
|
18315
|
-
|
|
18335
|
+
if (!Value::IsFinite(input)) {
|
|
18336
|
+
result = float(input);
|
|
18337
|
+
return true;
|
|
18316
18338
|
}
|
|
18317
|
-
auto res = (
|
|
18318
|
-
if (
|
|
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
|
-
|
|
24713
|
-
// return UINT_MAX;
|
|
24724
|
+
return UINT_MAX - 1;
|
|
24714
24725
|
}
|
|
24715
24726
|
//! -infinity
|
|
24716
24727
|
if (x < -FLT_MAX) {
|
|
24717
|
-
|
|
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
|
-
|
|
24741
|
-
// return ULLONG_MAX;
|
|
24754
|
+
return ULLONG_MAX - 1;
|
|
24742
24755
|
}
|
|
24743
24756
|
//! -infinity
|
|
24744
24757
|
if (x < -DBL_MAX) {
|
|
24745
|
-
|
|
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::
|
|
37804
|
+
bool Value::FloatIsFinite(float value) {
|
|
37794
37805
|
return !(std::isnan(value) || std::isinf(value));
|
|
37795
37806
|
}
|
|
37796
37807
|
|
|
37797
|
-
bool 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
|
-
|
|
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
|
-
|
|
64144
|
-
|
|
64145
|
-
|
|
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
|
-
|
|
64774
|
-
|
|
64775
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
72658
|
-
throw OutOfRangeException("STDDEV_POP for X is
|
|
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::
|
|
72662
|
-
throw OutOfRangeException("STDDEV_POP for Y is
|
|
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::
|
|
74227
|
-
|
|
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::
|
|
74941
|
-
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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(),
|
|
84639
|
-
|
|
84640
|
-
|
|
84641
|
-
|
|
84642
|
-
|
|
84643
|
-
|
|
84644
|
-
|
|
84645
|
-
|
|
84646
|
-
|
|
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
|
|
84856
|
+
StrfTimeFunctionDate<false>, false, StrfTimeBindFunction<false>));
|
|
84655
84857
|
|
|
84656
84858
|
strftime.AddFunction(ScalarFunction({LogicalType::TIMESTAMP, LogicalType::VARCHAR}, LogicalType::VARCHAR,
|
|
84657
|
-
StrfTimeFunctionTimestamp
|
|
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
|
-
|
|
87982
|
+
ScalarFunction::BinaryFunction<double, double, double, NextAfterOperator>, false));
|
|
87816
87983
|
next_after_fun.AddFunction(ScalarFunction("nextafter", {LogicalType::FLOAT, LogicalType::FLOAT}, LogicalType::FLOAT,
|
|
87817
|
-
|
|
87818
|
-
|
|
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
|
|
87896
|
-
if (
|
|
88062
|
+
static TR Operation(TA input) {
|
|
88063
|
+
if (input == TA(0)) {
|
|
87897
88064
|
return 0;
|
|
87898
|
-
} else if (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
88316
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
88347
|
-
|
|
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
|
-
|
|
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
|
|
88362
|
-
|
|
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
|
-
|
|
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
|
|
88377
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
88441
|
-
|
|
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(
|
|
88456
|
-
|
|
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(
|
|
88471
|
-
|
|
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(
|
|
88489
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
88549
|
-
|
|
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
|
|
88558
|
-
|
|
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
|
-
|
|
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
|
|
88573
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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
|
-
|
|
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
|
-
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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
|
-
|
|
127793
|
-
|
|
127794
|
-
//!
|
|
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
|
-
|
|
155778
|
-
|
|
155779
|
-
|
|
155780
|
-
|
|
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
|
-
|
|
156256
|
-
|
|
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
|
|
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
|
-
|
|
156868
|
-
|
|
156869
|
-
|
|
156870
|
-
|
|
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
|
|