duckdb 0.3.2-dev901.0 → 0.3.2-dev941.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 +890 -853
- package/src/duckdb.hpp +196 -69
- package/src/parquet-amalgamation.cpp +26896 -26913
- package/src/statement.cpp +15 -13
package/src/duckdb.cpp
CHANGED
|
@@ -1861,6 +1861,7 @@ void EncodeStringDataPrefix(data_ptr_t dataptr, string_t value, idx_t prefix_len
|
|
|
1861
1861
|
|
|
1862
1862
|
|
|
1863
1863
|
|
|
1864
|
+
|
|
1864
1865
|
namespace duckdb {
|
|
1865
1866
|
|
|
1866
1867
|
class Key {
|
|
@@ -1877,6 +1878,11 @@ public:
|
|
|
1877
1878
|
return make_unique<Key>(move(data), sizeof(element));
|
|
1878
1879
|
}
|
|
1879
1880
|
|
|
1881
|
+
template <class T>
|
|
1882
|
+
static unique_ptr<Key> CreateKey(const Value &element, bool is_little_endian) {
|
|
1883
|
+
return CreateKey(element.GetValueUnsafe<T>(), is_little_endian);
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1880
1886
|
public:
|
|
1881
1887
|
data_t &operator[](std::size_t i) {
|
|
1882
1888
|
return data[i];
|
|
@@ -1889,8 +1895,6 @@ public:
|
|
|
1889
1895
|
bool operator>=(const Key &k) const;
|
|
1890
1896
|
bool operator==(const Key &k) const;
|
|
1891
1897
|
|
|
1892
|
-
string ToString(bool is_little_endian, PhysicalType type);
|
|
1893
|
-
|
|
1894
1898
|
private:
|
|
1895
1899
|
template <class T>
|
|
1896
1900
|
static unique_ptr<data_t[]> CreateData(T value, bool is_little_endian) {
|
|
@@ -29285,23 +29289,6 @@ int NumericHelper::UnsignedLength(uint64_t value) {
|
|
|
29285
29289
|
namespace duckdb {
|
|
29286
29290
|
|
|
29287
29291
|
struct ValueOperations {
|
|
29288
|
-
//===--------------------------------------------------------------------===//
|
|
29289
|
-
// Numeric Operations
|
|
29290
|
-
//===--------------------------------------------------------------------===//
|
|
29291
|
-
// A + B
|
|
29292
|
-
static Value Add(const Value &left, const Value &right);
|
|
29293
|
-
// A - B
|
|
29294
|
-
static Value Subtract(const Value &left, const Value &right);
|
|
29295
|
-
// A * B
|
|
29296
|
-
static Value Multiply(const Value &left, const Value &right);
|
|
29297
|
-
// A / B
|
|
29298
|
-
static Value Divide(const Value &left, const Value &right);
|
|
29299
|
-
// A % B
|
|
29300
|
-
static Value Modulo(const Value &left, const Value &right);
|
|
29301
|
-
// // MIN(A, B)
|
|
29302
|
-
// static Value Min(const Value &left, const Value &right);
|
|
29303
|
-
// // MAX(A, B)
|
|
29304
|
-
// static Value Max(const Value &left, const Value &right);
|
|
29305
29292
|
//===--------------------------------------------------------------------===//
|
|
29306
29293
|
// Comparison Operations
|
|
29307
29294
|
//===--------------------------------------------------------------------===//
|
|
@@ -29332,11 +29319,6 @@ struct ValueOperations {
|
|
|
29332
29319
|
static bool DistinctLessThan(const Value &left, const Value &right);
|
|
29333
29320
|
// A <= B, NULLs last
|
|
29334
29321
|
static bool DistinctLessThanEquals(const Value &left, const Value &right);
|
|
29335
|
-
//===--------------------------------------------------------------------===//
|
|
29336
|
-
// Hash functions
|
|
29337
|
-
//===--------------------------------------------------------------------===//
|
|
29338
|
-
// result = HASH(A)
|
|
29339
|
-
static hash_t Hash(const Value &left);
|
|
29340
29322
|
};
|
|
29341
29323
|
} // namespace duckdb
|
|
29342
29324
|
|
|
@@ -33979,6 +33961,7 @@ hugeint_t ModuloOperator::Operation(hugeint_t left, hugeint_t right);
|
|
|
33979
33961
|
|
|
33980
33962
|
|
|
33981
33963
|
|
|
33964
|
+
|
|
33982
33965
|
namespace duckdb {
|
|
33983
33966
|
|
|
33984
33967
|
Value::Value(LogicalType type) : type_(move(type)), is_null(true) {
|
|
@@ -34021,6 +34004,39 @@ Value::Value(string val) : type_(LogicalType::VARCHAR), is_null(false), str_valu
|
|
|
34021
34004
|
}
|
|
34022
34005
|
}
|
|
34023
34006
|
|
|
34007
|
+
Value::~Value() {
|
|
34008
|
+
}
|
|
34009
|
+
|
|
34010
|
+
Value::Value(const Value &other)
|
|
34011
|
+
: type_(other.type_), is_null(other.is_null), value_(other.value_), str_value(other.str_value),
|
|
34012
|
+
struct_value(other.struct_value), list_value(other.list_value) {
|
|
34013
|
+
}
|
|
34014
|
+
|
|
34015
|
+
Value::Value(Value &&other) noexcept
|
|
34016
|
+
: type_(move(other.type_)), is_null(other.is_null), value_(other.value_), str_value(move(other.str_value)),
|
|
34017
|
+
struct_value(move(other.struct_value)), list_value(move(other.list_value)) {
|
|
34018
|
+
}
|
|
34019
|
+
|
|
34020
|
+
Value &Value::operator=(const Value &other) {
|
|
34021
|
+
type_ = other.type_;
|
|
34022
|
+
is_null = other.is_null;
|
|
34023
|
+
value_ = other.value_;
|
|
34024
|
+
str_value = other.str_value;
|
|
34025
|
+
struct_value = other.struct_value;
|
|
34026
|
+
list_value = other.list_value;
|
|
34027
|
+
return *this;
|
|
34028
|
+
}
|
|
34029
|
+
|
|
34030
|
+
Value &Value::operator=(Value &&other) noexcept {
|
|
34031
|
+
type_ = move(other.type_);
|
|
34032
|
+
is_null = other.is_null;
|
|
34033
|
+
value_ = other.value_;
|
|
34034
|
+
str_value = move(other.str_value);
|
|
34035
|
+
struct_value = move(other.struct_value);
|
|
34036
|
+
list_value = move(other.list_value);
|
|
34037
|
+
return *this;
|
|
34038
|
+
}
|
|
34039
|
+
|
|
34024
34040
|
Value Value::MinimumValue(const LogicalType &type) {
|
|
34025
34041
|
switch (type.id()) {
|
|
34026
34042
|
case LogicalTypeId::BOOLEAN:
|
|
@@ -34625,7 +34641,7 @@ Value Value::CreateValue(Value value) {
|
|
|
34625
34641
|
//===--------------------------------------------------------------------===//
|
|
34626
34642
|
template <class T>
|
|
34627
34643
|
T Value::GetValueInternal() const {
|
|
34628
|
-
if (
|
|
34644
|
+
if (IsNull()) {
|
|
34629
34645
|
return NullValue<T>();
|
|
34630
34646
|
}
|
|
34631
34647
|
switch (type_.id()) {
|
|
@@ -34780,24 +34796,31 @@ uintptr_t Value::GetPointer() const {
|
|
|
34780
34796
|
|
|
34781
34797
|
Value Value::Numeric(const LogicalType &type, int64_t value) {
|
|
34782
34798
|
switch (type.id()) {
|
|
34799
|
+
case LogicalTypeId::BOOLEAN:
|
|
34800
|
+
D_ASSERT(value == 0 || value == 1);
|
|
34801
|
+
return Value::BOOLEAN(value ? 1 : 0);
|
|
34783
34802
|
case LogicalTypeId::TINYINT:
|
|
34784
|
-
D_ASSERT(value <= NumericLimits<int8_t>::Maximum());
|
|
34803
|
+
D_ASSERT(value >= NumericLimits<int8_t>::Minimum() && value <= NumericLimits<int8_t>::Maximum());
|
|
34785
34804
|
return Value::TINYINT((int8_t)value);
|
|
34786
34805
|
case LogicalTypeId::SMALLINT:
|
|
34787
|
-
D_ASSERT(value <= NumericLimits<int16_t>::Maximum());
|
|
34806
|
+
D_ASSERT(value >= NumericLimits<int16_t>::Minimum() && value <= NumericLimits<int16_t>::Maximum());
|
|
34788
34807
|
return Value::SMALLINT((int16_t)value);
|
|
34789
34808
|
case LogicalTypeId::INTEGER:
|
|
34790
|
-
D_ASSERT(value <= NumericLimits<int32_t>::Maximum());
|
|
34809
|
+
D_ASSERT(value >= NumericLimits<int32_t>::Minimum() && value <= NumericLimits<int32_t>::Maximum());
|
|
34791
34810
|
return Value::INTEGER((int32_t)value);
|
|
34792
34811
|
case LogicalTypeId::BIGINT:
|
|
34793
34812
|
return Value::BIGINT(value);
|
|
34794
34813
|
case LogicalTypeId::UTINYINT:
|
|
34814
|
+
D_ASSERT(value >= NumericLimits<uint8_t>::Minimum() && value <= NumericLimits<uint8_t>::Maximum());
|
|
34795
34815
|
return Value::UTINYINT((uint8_t)value);
|
|
34796
34816
|
case LogicalTypeId::USMALLINT:
|
|
34817
|
+
D_ASSERT(value >= NumericLimits<uint16_t>::Minimum() && value <= NumericLimits<uint16_t>::Maximum());
|
|
34797
34818
|
return Value::USMALLINT((uint16_t)value);
|
|
34798
34819
|
case LogicalTypeId::UINTEGER:
|
|
34820
|
+
D_ASSERT(value >= NumericLimits<uint32_t>::Minimum() && value <= NumericLimits<uint32_t>::Maximum());
|
|
34799
34821
|
return Value::UINTEGER((uint32_t)value);
|
|
34800
34822
|
case LogicalTypeId::UBIGINT:
|
|
34823
|
+
D_ASSERT(value >= 0);
|
|
34801
34824
|
return Value::UBIGINT(value);
|
|
34802
34825
|
case LogicalTypeId::HUGEINT:
|
|
34803
34826
|
return Value::HUGEINT(value);
|
|
@@ -34812,7 +34835,7 @@ Value Value::Numeric(const LogicalType &type, int64_t value) {
|
|
|
34812
34835
|
case LogicalTypeId::POINTER:
|
|
34813
34836
|
return Value::POINTER(value);
|
|
34814
34837
|
case LogicalTypeId::DATE:
|
|
34815
|
-
D_ASSERT(value <= NumericLimits<int32_t>::Maximum());
|
|
34838
|
+
D_ASSERT(value >= NumericLimits<int32_t>::Minimum() && value <= NumericLimits<int32_t>::Maximum());
|
|
34816
34839
|
return Value::DATE(date_t(value));
|
|
34817
34840
|
case LogicalTypeId::TIME:
|
|
34818
34841
|
return Value::TIME(dtime_t(value));
|
|
@@ -34831,10 +34854,13 @@ Value Value::Numeric(const LogicalType &type, int64_t value) {
|
|
|
34831
34854
|
case LogicalTypeId::ENUM:
|
|
34832
34855
|
switch (type.InternalType()) {
|
|
34833
34856
|
case PhysicalType::UINT8:
|
|
34857
|
+
D_ASSERT(value >= NumericLimits<uint8_t>::Minimum() && value <= NumericLimits<uint8_t>::Maximum());
|
|
34834
34858
|
return Value::UTINYINT((uint8_t)value);
|
|
34835
34859
|
case PhysicalType::UINT16:
|
|
34860
|
+
D_ASSERT(value >= NumericLimits<uint16_t>::Minimum() && value <= NumericLimits<uint16_t>::Maximum());
|
|
34836
34861
|
return Value::USMALLINT((uint16_t)value);
|
|
34837
34862
|
case PhysicalType::UINT32:
|
|
34863
|
+
D_ASSERT(value >= NumericLimits<uint32_t>::Minimum() && value <= NumericLimits<uint32_t>::Maximum());
|
|
34838
34864
|
return Value::UINTEGER((uint32_t)value);
|
|
34839
34865
|
default:
|
|
34840
34866
|
throw InternalException("Enum doesn't accept this physical type");
|
|
@@ -34844,116 +34870,284 @@ Value Value::Numeric(const LogicalType &type, int64_t value) {
|
|
|
34844
34870
|
}
|
|
34845
34871
|
}
|
|
34846
34872
|
|
|
34873
|
+
Value Value::Numeric(const LogicalType &type, hugeint_t value) {
|
|
34874
|
+
#ifdef DEBUG
|
|
34875
|
+
// perform a throwing cast to verify that the type fits
|
|
34876
|
+
Value::HUGEINT(value).CastAs(type);
|
|
34877
|
+
#endif
|
|
34878
|
+
switch (type.id()) {
|
|
34879
|
+
case LogicalTypeId::HUGEINT:
|
|
34880
|
+
return Value::HUGEINT(value);
|
|
34881
|
+
case LogicalTypeId::UBIGINT:
|
|
34882
|
+
return Value::UBIGINT(Hugeint::Cast<uint64_t>(value));
|
|
34883
|
+
default:
|
|
34884
|
+
return Value::Numeric(type, Hugeint::Cast<int64_t>(value));
|
|
34885
|
+
}
|
|
34886
|
+
}
|
|
34887
|
+
|
|
34847
34888
|
//===--------------------------------------------------------------------===//
|
|
34848
34889
|
// GetValueUnsafe
|
|
34849
34890
|
//===--------------------------------------------------------------------===//
|
|
34850
34891
|
template <>
|
|
34851
|
-
|
|
34892
|
+
DUCKDB_API bool Value::GetValueUnsafe() const {
|
|
34893
|
+
D_ASSERT(type_.InternalType() == PhysicalType::BOOL);
|
|
34894
|
+
return value_.boolean;
|
|
34895
|
+
}
|
|
34896
|
+
|
|
34897
|
+
template <>
|
|
34898
|
+
int8_t Value::GetValueUnsafe() const {
|
|
34852
34899
|
D_ASSERT(type_.InternalType() == PhysicalType::INT8 || type_.InternalType() == PhysicalType::BOOL);
|
|
34853
34900
|
return value_.tinyint;
|
|
34854
34901
|
}
|
|
34855
34902
|
|
|
34856
34903
|
template <>
|
|
34857
|
-
int16_t
|
|
34904
|
+
int16_t Value::GetValueUnsafe() const {
|
|
34858
34905
|
D_ASSERT(type_.InternalType() == PhysicalType::INT16);
|
|
34859
34906
|
return value_.smallint;
|
|
34860
34907
|
}
|
|
34861
34908
|
|
|
34862
34909
|
template <>
|
|
34863
|
-
int32_t
|
|
34910
|
+
int32_t Value::GetValueUnsafe() const {
|
|
34864
34911
|
D_ASSERT(type_.InternalType() == PhysicalType::INT32);
|
|
34865
34912
|
return value_.integer;
|
|
34866
34913
|
}
|
|
34867
34914
|
|
|
34868
34915
|
template <>
|
|
34869
|
-
int64_t
|
|
34916
|
+
int64_t Value::GetValueUnsafe() const {
|
|
34870
34917
|
D_ASSERT(type_.InternalType() == PhysicalType::INT64);
|
|
34871
34918
|
return value_.bigint;
|
|
34872
34919
|
}
|
|
34873
34920
|
|
|
34874
34921
|
template <>
|
|
34875
|
-
hugeint_t
|
|
34922
|
+
hugeint_t Value::GetValueUnsafe() const {
|
|
34876
34923
|
D_ASSERT(type_.InternalType() == PhysicalType::INT128);
|
|
34877
34924
|
return value_.hugeint;
|
|
34878
34925
|
}
|
|
34879
34926
|
|
|
34880
34927
|
template <>
|
|
34881
|
-
uint8_t
|
|
34928
|
+
uint8_t Value::GetValueUnsafe() const {
|
|
34882
34929
|
D_ASSERT(type_.InternalType() == PhysicalType::UINT8);
|
|
34883
34930
|
return value_.utinyint;
|
|
34884
34931
|
}
|
|
34885
34932
|
|
|
34886
34933
|
template <>
|
|
34887
|
-
uint16_t
|
|
34934
|
+
uint16_t Value::GetValueUnsafe() const {
|
|
34888
34935
|
D_ASSERT(type_.InternalType() == PhysicalType::UINT16);
|
|
34889
34936
|
return value_.usmallint;
|
|
34890
34937
|
}
|
|
34891
34938
|
|
|
34892
34939
|
template <>
|
|
34893
|
-
uint32_t
|
|
34940
|
+
uint32_t Value::GetValueUnsafe() const {
|
|
34894
34941
|
D_ASSERT(type_.InternalType() == PhysicalType::UINT32);
|
|
34895
34942
|
return value_.uinteger;
|
|
34896
34943
|
}
|
|
34897
34944
|
|
|
34898
34945
|
template <>
|
|
34899
|
-
uint64_t
|
|
34946
|
+
uint64_t Value::GetValueUnsafe() const {
|
|
34900
34947
|
D_ASSERT(type_.InternalType() == PhysicalType::UINT64);
|
|
34901
34948
|
return value_.ubigint;
|
|
34902
34949
|
}
|
|
34903
34950
|
|
|
34904
34951
|
template <>
|
|
34905
|
-
string
|
|
34952
|
+
string Value::GetValueUnsafe() const {
|
|
34906
34953
|
D_ASSERT(type_.InternalType() == PhysicalType::VARCHAR);
|
|
34907
34954
|
return str_value;
|
|
34908
34955
|
}
|
|
34909
34956
|
|
|
34910
34957
|
template <>
|
|
34911
|
-
|
|
34958
|
+
DUCKDB_API string_t Value::GetValueUnsafe() const {
|
|
34959
|
+
D_ASSERT(type_.InternalType() == PhysicalType::VARCHAR);
|
|
34960
|
+
return string_t(str_value);
|
|
34961
|
+
}
|
|
34962
|
+
|
|
34963
|
+
template <>
|
|
34964
|
+
float Value::GetValueUnsafe() const {
|
|
34912
34965
|
D_ASSERT(type_.InternalType() == PhysicalType::FLOAT);
|
|
34913
34966
|
return value_.float_;
|
|
34914
34967
|
}
|
|
34915
34968
|
|
|
34916
34969
|
template <>
|
|
34917
|
-
double
|
|
34970
|
+
double Value::GetValueUnsafe() const {
|
|
34918
34971
|
D_ASSERT(type_.InternalType() == PhysicalType::DOUBLE);
|
|
34919
34972
|
return value_.double_;
|
|
34920
34973
|
}
|
|
34921
34974
|
|
|
34922
34975
|
template <>
|
|
34923
|
-
date_t
|
|
34976
|
+
date_t Value::GetValueUnsafe() const {
|
|
34924
34977
|
D_ASSERT(type_.InternalType() == PhysicalType::INT32);
|
|
34925
34978
|
return value_.date;
|
|
34926
34979
|
}
|
|
34927
34980
|
|
|
34928
34981
|
template <>
|
|
34929
|
-
dtime_t
|
|
34982
|
+
dtime_t Value::GetValueUnsafe() const {
|
|
34930
34983
|
D_ASSERT(type_.InternalType() == PhysicalType::INT64);
|
|
34931
34984
|
return value_.time;
|
|
34932
34985
|
}
|
|
34933
34986
|
|
|
34934
34987
|
template <>
|
|
34935
|
-
timestamp_t
|
|
34988
|
+
timestamp_t Value::GetValueUnsafe() const {
|
|
34936
34989
|
D_ASSERT(type_.InternalType() == PhysicalType::INT64);
|
|
34937
34990
|
return value_.timestamp;
|
|
34938
34991
|
}
|
|
34939
34992
|
|
|
34940
34993
|
template <>
|
|
34941
|
-
interval_t
|
|
34994
|
+
interval_t Value::GetValueUnsafe() const {
|
|
34942
34995
|
D_ASSERT(type_.InternalType() == PhysicalType::INTERVAL);
|
|
34943
34996
|
return value_.interval;
|
|
34944
34997
|
}
|
|
34945
34998
|
|
|
34946
|
-
|
|
34947
|
-
|
|
34948
|
-
|
|
34949
|
-
|
|
34999
|
+
//===--------------------------------------------------------------------===//
|
|
35000
|
+
// GetReferenceUnsafe
|
|
35001
|
+
//===--------------------------------------------------------------------===//
|
|
35002
|
+
template <>
|
|
35003
|
+
int8_t &Value::GetReferenceUnsafe() {
|
|
35004
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT8 || type_.InternalType() == PhysicalType::BOOL);
|
|
35005
|
+
return value_.tinyint;
|
|
35006
|
+
}
|
|
35007
|
+
|
|
35008
|
+
template <>
|
|
35009
|
+
int16_t &Value::GetReferenceUnsafe() {
|
|
35010
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT16);
|
|
35011
|
+
return value_.smallint;
|
|
35012
|
+
}
|
|
35013
|
+
|
|
35014
|
+
template <>
|
|
35015
|
+
int32_t &Value::GetReferenceUnsafe() {
|
|
35016
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT32);
|
|
35017
|
+
return value_.integer;
|
|
35018
|
+
}
|
|
35019
|
+
|
|
35020
|
+
template <>
|
|
35021
|
+
int64_t &Value::GetReferenceUnsafe() {
|
|
35022
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT64);
|
|
35023
|
+
return value_.bigint;
|
|
35024
|
+
}
|
|
35025
|
+
|
|
35026
|
+
template <>
|
|
35027
|
+
hugeint_t &Value::GetReferenceUnsafe() {
|
|
35028
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT128);
|
|
35029
|
+
return value_.hugeint;
|
|
35030
|
+
}
|
|
35031
|
+
|
|
35032
|
+
template <>
|
|
35033
|
+
uint8_t &Value::GetReferenceUnsafe() {
|
|
35034
|
+
D_ASSERT(type_.InternalType() == PhysicalType::UINT8);
|
|
35035
|
+
return value_.utinyint;
|
|
35036
|
+
}
|
|
35037
|
+
|
|
35038
|
+
template <>
|
|
35039
|
+
uint16_t &Value::GetReferenceUnsafe() {
|
|
35040
|
+
D_ASSERT(type_.InternalType() == PhysicalType::UINT16);
|
|
35041
|
+
return value_.usmallint;
|
|
35042
|
+
}
|
|
35043
|
+
|
|
35044
|
+
template <>
|
|
35045
|
+
uint32_t &Value::GetReferenceUnsafe() {
|
|
35046
|
+
D_ASSERT(type_.InternalType() == PhysicalType::UINT32);
|
|
35047
|
+
return value_.uinteger;
|
|
35048
|
+
}
|
|
35049
|
+
|
|
35050
|
+
template <>
|
|
35051
|
+
uint64_t &Value::GetReferenceUnsafe() {
|
|
35052
|
+
D_ASSERT(type_.InternalType() == PhysicalType::UINT64);
|
|
35053
|
+
return value_.ubigint;
|
|
35054
|
+
}
|
|
35055
|
+
|
|
35056
|
+
template <>
|
|
35057
|
+
float &Value::GetReferenceUnsafe() {
|
|
35058
|
+
D_ASSERT(type_.InternalType() == PhysicalType::FLOAT);
|
|
35059
|
+
return value_.float_;
|
|
35060
|
+
}
|
|
35061
|
+
|
|
35062
|
+
template <>
|
|
35063
|
+
double &Value::GetReferenceUnsafe() {
|
|
35064
|
+
D_ASSERT(type_.InternalType() == PhysicalType::DOUBLE);
|
|
35065
|
+
return value_.double_;
|
|
35066
|
+
}
|
|
35067
|
+
|
|
35068
|
+
template <>
|
|
35069
|
+
date_t &Value::GetReferenceUnsafe() {
|
|
35070
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT32);
|
|
35071
|
+
return value_.date;
|
|
35072
|
+
}
|
|
35073
|
+
|
|
35074
|
+
template <>
|
|
35075
|
+
dtime_t &Value::GetReferenceUnsafe() {
|
|
35076
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT64);
|
|
35077
|
+
return value_.time;
|
|
35078
|
+
}
|
|
35079
|
+
|
|
35080
|
+
template <>
|
|
35081
|
+
timestamp_t &Value::GetReferenceUnsafe() {
|
|
35082
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INT64);
|
|
35083
|
+
return value_.timestamp;
|
|
35084
|
+
}
|
|
35085
|
+
|
|
35086
|
+
template <>
|
|
35087
|
+
interval_t &Value::GetReferenceUnsafe() {
|
|
35088
|
+
D_ASSERT(type_.InternalType() == PhysicalType::INTERVAL);
|
|
35089
|
+
return value_.interval;
|
|
35090
|
+
}
|
|
35091
|
+
|
|
35092
|
+
//===--------------------------------------------------------------------===//
|
|
35093
|
+
// Hash
|
|
35094
|
+
//===--------------------------------------------------------------------===//
|
|
35095
|
+
hash_t Value::Hash() const {
|
|
35096
|
+
if (IsNull()) {
|
|
35097
|
+
return 0;
|
|
35098
|
+
}
|
|
35099
|
+
switch (type_.InternalType()) {
|
|
35100
|
+
case PhysicalType::BOOL:
|
|
35101
|
+
return duckdb::Hash(value_.boolean);
|
|
35102
|
+
case PhysicalType::INT8:
|
|
35103
|
+
return duckdb::Hash(value_.tinyint);
|
|
35104
|
+
case PhysicalType::INT16:
|
|
35105
|
+
return duckdb::Hash(value_.smallint);
|
|
35106
|
+
case PhysicalType::INT32:
|
|
35107
|
+
return duckdb::Hash(value_.integer);
|
|
35108
|
+
case PhysicalType::INT64:
|
|
35109
|
+
return duckdb::Hash(value_.bigint);
|
|
35110
|
+
case PhysicalType::UINT8:
|
|
35111
|
+
return duckdb::Hash(value_.utinyint);
|
|
35112
|
+
case PhysicalType::UINT16:
|
|
35113
|
+
return duckdb::Hash(value_.usmallint);
|
|
35114
|
+
case PhysicalType::UINT32:
|
|
35115
|
+
return duckdb::Hash(value_.uinteger);
|
|
35116
|
+
case PhysicalType::UINT64:
|
|
35117
|
+
return duckdb::Hash(value_.ubigint);
|
|
35118
|
+
case PhysicalType::INT128:
|
|
35119
|
+
return duckdb::Hash(value_.hugeint);
|
|
35120
|
+
case PhysicalType::FLOAT:
|
|
35121
|
+
return duckdb::Hash(value_.float_);
|
|
35122
|
+
case PhysicalType::DOUBLE:
|
|
35123
|
+
return duckdb::Hash(value_.double_);
|
|
35124
|
+
case PhysicalType::INTERVAL:
|
|
35125
|
+
return duckdb::Hash(value_.interval);
|
|
35126
|
+
case PhysicalType::VARCHAR:
|
|
35127
|
+
return duckdb::Hash(string_t(StringValue::Get(*this)));
|
|
35128
|
+
case PhysicalType::STRUCT: {
|
|
35129
|
+
auto &struct_children = StructValue::GetChildren(*this);
|
|
35130
|
+
hash_t hash = 0;
|
|
35131
|
+
for (auto &entry : struct_children) {
|
|
35132
|
+
hash ^= entry.Hash();
|
|
35133
|
+
}
|
|
35134
|
+
return hash;
|
|
35135
|
+
}
|
|
35136
|
+
case PhysicalType::LIST: {
|
|
35137
|
+
auto &list_children = ListValue::GetChildren(*this);
|
|
35138
|
+
hash_t hash = 0;
|
|
35139
|
+
for (auto &entry : list_children) {
|
|
35140
|
+
hash ^= entry.Hash();
|
|
35141
|
+
}
|
|
35142
|
+
return hash;
|
|
35143
|
+
}
|
|
34950
35144
|
default:
|
|
34951
|
-
|
|
35145
|
+
throw InternalException("Unimplemented type for value hash");
|
|
34952
35146
|
}
|
|
34953
35147
|
}
|
|
34954
35148
|
|
|
34955
35149
|
string Value::ToString() const {
|
|
34956
|
-
if (
|
|
35150
|
+
if (IsNull()) {
|
|
34957
35151
|
return "NULL";
|
|
34958
35152
|
}
|
|
34959
35153
|
switch (type_.id()) {
|
|
@@ -35086,27 +35280,110 @@ string Value::ToString() const {
|
|
|
35086
35280
|
}
|
|
35087
35281
|
|
|
35088
35282
|
//===--------------------------------------------------------------------===//
|
|
35089
|
-
//
|
|
35283
|
+
// Type-specific getters
|
|
35090
35284
|
//===--------------------------------------------------------------------===//
|
|
35091
|
-
|
|
35092
|
-
return
|
|
35285
|
+
bool BooleanValue::Get(const Value &value) {
|
|
35286
|
+
return value.GetValueUnsafe<bool>();
|
|
35287
|
+
}
|
|
35288
|
+
|
|
35289
|
+
int8_t TinyIntValue::Get(const Value &value) {
|
|
35290
|
+
return value.GetValueUnsafe<int8_t>();
|
|
35291
|
+
}
|
|
35292
|
+
|
|
35293
|
+
int16_t SmallIntValue::Get(const Value &value) {
|
|
35294
|
+
return value.GetValueUnsafe<int16_t>();
|
|
35295
|
+
}
|
|
35296
|
+
|
|
35297
|
+
int32_t IntegerValue::Get(const Value &value) {
|
|
35298
|
+
return value.GetValueUnsafe<int32_t>();
|
|
35299
|
+
}
|
|
35300
|
+
|
|
35301
|
+
int64_t BigIntValue::Get(const Value &value) {
|
|
35302
|
+
return value.GetValueUnsafe<int64_t>();
|
|
35303
|
+
}
|
|
35304
|
+
|
|
35305
|
+
hugeint_t HugeIntValue::Get(const Value &value) {
|
|
35306
|
+
return value.GetValueUnsafe<hugeint_t>();
|
|
35307
|
+
}
|
|
35308
|
+
|
|
35309
|
+
uint8_t UTinyIntValue::Get(const Value &value) {
|
|
35310
|
+
return value.GetValueUnsafe<uint8_t>();
|
|
35311
|
+
}
|
|
35312
|
+
|
|
35313
|
+
uint16_t USmallIntValue::Get(const Value &value) {
|
|
35314
|
+
return value.GetValueUnsafe<uint16_t>();
|
|
35093
35315
|
}
|
|
35094
35316
|
|
|
35095
|
-
|
|
35096
|
-
return
|
|
35317
|
+
uint32_t UIntegerValue::Get(const Value &value) {
|
|
35318
|
+
return value.GetValueUnsafe<uint32_t>();
|
|
35097
35319
|
}
|
|
35098
35320
|
|
|
35099
|
-
|
|
35100
|
-
return
|
|
35321
|
+
uint64_t UBigIntValue::Get(const Value &value) {
|
|
35322
|
+
return value.GetValueUnsafe<uint64_t>();
|
|
35101
35323
|
}
|
|
35102
35324
|
|
|
35103
|
-
|
|
35104
|
-
return
|
|
35325
|
+
float FloatValue::Get(const Value &value) {
|
|
35326
|
+
return value.GetValueUnsafe<float>();
|
|
35105
35327
|
}
|
|
35106
35328
|
|
|
35107
|
-
|
|
35108
|
-
|
|
35109
|
-
|
|
35329
|
+
double DoubleValue::Get(const Value &value) {
|
|
35330
|
+
return value.GetValueUnsafe<double>();
|
|
35331
|
+
}
|
|
35332
|
+
|
|
35333
|
+
const string &StringValue::Get(const Value &value) {
|
|
35334
|
+
D_ASSERT(value.type().InternalType() == PhysicalType::VARCHAR);
|
|
35335
|
+
return value.str_value;
|
|
35336
|
+
}
|
|
35337
|
+
|
|
35338
|
+
date_t DateValue::Get(const Value &value) {
|
|
35339
|
+
return value.GetValueUnsafe<date_t>();
|
|
35340
|
+
}
|
|
35341
|
+
|
|
35342
|
+
dtime_t TimeValue::Get(const Value &value) {
|
|
35343
|
+
return value.GetValueUnsafe<dtime_t>();
|
|
35344
|
+
}
|
|
35345
|
+
|
|
35346
|
+
timestamp_t TimestampValue::Get(const Value &value) {
|
|
35347
|
+
return value.GetValueUnsafe<timestamp_t>();
|
|
35348
|
+
}
|
|
35349
|
+
|
|
35350
|
+
interval_t IntervalValue::Get(const Value &value) {
|
|
35351
|
+
return value.GetValueUnsafe<interval_t>();
|
|
35352
|
+
}
|
|
35353
|
+
|
|
35354
|
+
const vector<Value> &StructValue::GetChildren(const Value &value) {
|
|
35355
|
+
D_ASSERT(value.type().InternalType() == PhysicalType::STRUCT);
|
|
35356
|
+
return value.struct_value;
|
|
35357
|
+
}
|
|
35358
|
+
|
|
35359
|
+
const vector<Value> &ListValue::GetChildren(const Value &value) {
|
|
35360
|
+
D_ASSERT(value.type().InternalType() == PhysicalType::LIST);
|
|
35361
|
+
return value.list_value;
|
|
35362
|
+
}
|
|
35363
|
+
|
|
35364
|
+
hugeint_t IntegralValue::Get(const Value &value) {
|
|
35365
|
+
switch (value.type().InternalType()) {
|
|
35366
|
+
case PhysicalType::INT8:
|
|
35367
|
+
return TinyIntValue::Get(value);
|
|
35368
|
+
case PhysicalType::INT16:
|
|
35369
|
+
return SmallIntValue::Get(value);
|
|
35370
|
+
case PhysicalType::INT32:
|
|
35371
|
+
return IntegerValue::Get(value);
|
|
35372
|
+
case PhysicalType::INT64:
|
|
35373
|
+
return BigIntValue::Get(value);
|
|
35374
|
+
case PhysicalType::INT128:
|
|
35375
|
+
return HugeIntValue::Get(value);
|
|
35376
|
+
case PhysicalType::UINT8:
|
|
35377
|
+
return UTinyIntValue::Get(value);
|
|
35378
|
+
case PhysicalType::UINT16:
|
|
35379
|
+
return USmallIntValue::Get(value);
|
|
35380
|
+
case PhysicalType::UINT32:
|
|
35381
|
+
return UIntegerValue::Get(value);
|
|
35382
|
+
case PhysicalType::UINT64:
|
|
35383
|
+
return UBigIntValue::Get(value);
|
|
35384
|
+
default:
|
|
35385
|
+
throw InternalException("Invalid internal type \"%s\" for IntegralValue::Get", value.type().ToString());
|
|
35386
|
+
}
|
|
35110
35387
|
}
|
|
35111
35388
|
|
|
35112
35389
|
//===--------------------------------------------------------------------===//
|
|
@@ -35200,8 +35477,8 @@ bool Value::TryCastAs(const LogicalType &target_type, bool strict) {
|
|
|
35200
35477
|
|
|
35201
35478
|
void Value::Serialize(Serializer &serializer) {
|
|
35202
35479
|
type_.Serialize(serializer);
|
|
35203
|
-
serializer.Write<bool>(
|
|
35204
|
-
if (!
|
|
35480
|
+
serializer.Write<bool>(IsNull());
|
|
35481
|
+
if (!IsNull()) {
|
|
35205
35482
|
switch (type_.InternalType()) {
|
|
35206
35483
|
case PhysicalType::BOOL:
|
|
35207
35484
|
serializer.Write<int8_t>(value_.boolean);
|
|
@@ -35319,10 +35596,10 @@ void Value::Print() const {
|
|
|
35319
35596
|
}
|
|
35320
35597
|
|
|
35321
35598
|
bool Value::ValuesAreEqual(const Value &result_value, const Value &value) {
|
|
35322
|
-
if (result_value.
|
|
35599
|
+
if (result_value.IsNull() != value.IsNull()) {
|
|
35323
35600
|
return false;
|
|
35324
35601
|
}
|
|
35325
|
-
if (result_value.
|
|
35602
|
+
if (result_value.IsNull() && value.IsNull()) {
|
|
35326
35603
|
// NULL = NULL in checking code
|
|
35327
35604
|
return true;
|
|
35328
35605
|
}
|
|
@@ -35440,12 +35717,13 @@ void Vector::Reference(const Value &value) {
|
|
|
35440
35717
|
auto struct_buffer = make_unique<VectorStructBuffer>();
|
|
35441
35718
|
auto &child_types = StructType::GetChildTypes(value.type());
|
|
35442
35719
|
auto &child_vectors = struct_buffer->GetChildren();
|
|
35720
|
+
auto &value_children = StructValue::GetChildren(value);
|
|
35443
35721
|
for (idx_t i = 0; i < child_types.size(); i++) {
|
|
35444
|
-
auto vector = make_unique<Vector>(value.
|
|
35722
|
+
auto vector = make_unique<Vector>(value.IsNull() ? Value(child_types[i].second) : value_children[i]);
|
|
35445
35723
|
child_vectors.push_back(move(vector));
|
|
35446
35724
|
}
|
|
35447
35725
|
auxiliary = move(struct_buffer);
|
|
35448
|
-
if (value.
|
|
35726
|
+
if (value.IsNull()) {
|
|
35449
35727
|
SetValue(0, value);
|
|
35450
35728
|
}
|
|
35451
35729
|
} else if (internal_type == PhysicalType::LIST) {
|
|
@@ -35663,100 +35941,66 @@ void Vector::SetValue(idx_t index, const Value &val) {
|
|
|
35663
35941
|
}
|
|
35664
35942
|
|
|
35665
35943
|
validity.EnsureWritable();
|
|
35666
|
-
validity.Set(index, !val.
|
|
35667
|
-
if (val.
|
|
35944
|
+
validity.Set(index, !val.IsNull());
|
|
35945
|
+
if (val.IsNull() && GetType().InternalType() != PhysicalType::STRUCT) {
|
|
35668
35946
|
// for structs we still need to set the child-entries to NULL
|
|
35669
35947
|
// so we do not bail out yet
|
|
35670
35948
|
return;
|
|
35671
35949
|
}
|
|
35672
35950
|
|
|
35673
|
-
switch (GetType().
|
|
35674
|
-
case
|
|
35675
|
-
((bool *)data)[index] = val.
|
|
35676
|
-
break;
|
|
35677
|
-
case LogicalTypeId::TINYINT:
|
|
35678
|
-
((int8_t *)data)[index] = val.value_.tinyint;
|
|
35679
|
-
break;
|
|
35680
|
-
case LogicalTypeId::SMALLINT:
|
|
35681
|
-
((int16_t *)data)[index] = val.value_.smallint;
|
|
35951
|
+
switch (GetType().InternalType()) {
|
|
35952
|
+
case PhysicalType::BOOL:
|
|
35953
|
+
((bool *)data)[index] = val.GetValueUnsafe<bool>();
|
|
35682
35954
|
break;
|
|
35683
|
-
case
|
|
35684
|
-
|
|
35685
|
-
((int32_t *)data)[index] = val.value_.integer;
|
|
35955
|
+
case PhysicalType::INT8:
|
|
35956
|
+
((int8_t *)data)[index] = val.GetValueUnsafe<int8_t>();
|
|
35686
35957
|
break;
|
|
35687
|
-
case
|
|
35688
|
-
|
|
35689
|
-
case LogicalTypeId::TIMESTAMP_MS:
|
|
35690
|
-
case LogicalTypeId::TIMESTAMP_NS:
|
|
35691
|
-
case LogicalTypeId::HASH:
|
|
35692
|
-
case LogicalTypeId::TIME:
|
|
35693
|
-
case LogicalTypeId::BIGINT:
|
|
35694
|
-
case LogicalTypeId::TIMESTAMP_TZ:
|
|
35695
|
-
case LogicalTypeId::TIME_TZ:
|
|
35696
|
-
((int64_t *)data)[index] = val.value_.bigint;
|
|
35958
|
+
case PhysicalType::INT16:
|
|
35959
|
+
((int16_t *)data)[index] = val.GetValueUnsafe<int16_t>();
|
|
35697
35960
|
break;
|
|
35698
|
-
case
|
|
35699
|
-
((
|
|
35961
|
+
case PhysicalType::INT32:
|
|
35962
|
+
((int32_t *)data)[index] = val.GetValueUnsafe<int32_t>();
|
|
35700
35963
|
break;
|
|
35701
|
-
case
|
|
35702
|
-
((
|
|
35964
|
+
case PhysicalType::INT64:
|
|
35965
|
+
((int64_t *)data)[index] = val.GetValueUnsafe<int64_t>();
|
|
35703
35966
|
break;
|
|
35704
|
-
case
|
|
35705
|
-
((
|
|
35967
|
+
case PhysicalType::INT128:
|
|
35968
|
+
((hugeint_t *)data)[index] = val.GetValueUnsafe<hugeint_t>();
|
|
35706
35969
|
break;
|
|
35707
|
-
case
|
|
35708
|
-
((
|
|
35970
|
+
case PhysicalType::UINT8:
|
|
35971
|
+
((uint8_t *)data)[index] = val.GetValueUnsafe<uint8_t>();
|
|
35709
35972
|
break;
|
|
35710
|
-
case
|
|
35711
|
-
|
|
35712
|
-
((hugeint_t *)data)[index] = val.value_.hugeint;
|
|
35973
|
+
case PhysicalType::UINT16:
|
|
35974
|
+
((uint16_t *)data)[index] = val.GetValueUnsafe<uint16_t>();
|
|
35713
35975
|
break;
|
|
35714
|
-
case
|
|
35715
|
-
|
|
35716
|
-
D_ASSERT(DecimalType::GetScale(GetType()) == DecimalType::GetScale(val.type()));
|
|
35717
|
-
switch (GetType().InternalType()) {
|
|
35718
|
-
case PhysicalType::INT16:
|
|
35719
|
-
((int16_t *)data)[index] = val.value_.smallint;
|
|
35720
|
-
break;
|
|
35721
|
-
case PhysicalType::INT32:
|
|
35722
|
-
((int32_t *)data)[index] = val.value_.integer;
|
|
35723
|
-
break;
|
|
35724
|
-
case PhysicalType::INT64:
|
|
35725
|
-
((int64_t *)data)[index] = val.value_.bigint;
|
|
35726
|
-
break;
|
|
35727
|
-
case PhysicalType::INT128:
|
|
35728
|
-
((hugeint_t *)data)[index] = val.value_.hugeint;
|
|
35729
|
-
break;
|
|
35730
|
-
default:
|
|
35731
|
-
throw InternalException("Widths bigger than 38 are not supported");
|
|
35732
|
-
}
|
|
35976
|
+
case PhysicalType::UINT32:
|
|
35977
|
+
((uint32_t *)data)[index] = val.GetValueUnsafe<uint32_t>();
|
|
35733
35978
|
break;
|
|
35734
|
-
case
|
|
35735
|
-
((
|
|
35979
|
+
case PhysicalType::UINT64:
|
|
35980
|
+
((uint64_t *)data)[index] = val.GetValueUnsafe<uint64_t>();
|
|
35736
35981
|
break;
|
|
35737
|
-
case
|
|
35738
|
-
((
|
|
35982
|
+
case PhysicalType::FLOAT:
|
|
35983
|
+
((float *)data)[index] = val.GetValueUnsafe<float>();
|
|
35739
35984
|
break;
|
|
35740
|
-
case
|
|
35741
|
-
((
|
|
35985
|
+
case PhysicalType::DOUBLE:
|
|
35986
|
+
((double *)data)[index] = val.GetValueUnsafe<double>();
|
|
35742
35987
|
break;
|
|
35743
|
-
case
|
|
35744
|
-
((interval_t *)data)[index] = val.
|
|
35988
|
+
case PhysicalType::INTERVAL:
|
|
35989
|
+
((interval_t *)data)[index] = val.GetValueUnsafe<interval_t>();
|
|
35745
35990
|
break;
|
|
35746
|
-
case
|
|
35747
|
-
|
|
35748
|
-
((string_t *)data)[index] = StringVector::AddStringOrBlob(*this, val.str_value);
|
|
35991
|
+
case PhysicalType::VARCHAR:
|
|
35992
|
+
((string_t *)data)[index] = StringVector::AddStringOrBlob(*this, StringValue::Get(val));
|
|
35749
35993
|
break;
|
|
35750
|
-
case
|
|
35751
|
-
case LogicalTypeId::STRUCT: {
|
|
35994
|
+
case PhysicalType::STRUCT: {
|
|
35752
35995
|
D_ASSERT(GetVectorType() == VectorType::CONSTANT_VECTOR || GetVectorType() == VectorType::FLAT_VECTOR);
|
|
35753
35996
|
|
|
35754
35997
|
auto &children = StructVector::GetEntries(*this);
|
|
35755
|
-
|
|
35998
|
+
auto &val_children = StructValue::GetChildren(val);
|
|
35999
|
+
D_ASSERT(val.IsNull() || children.size() == val_children.size());
|
|
35756
36000
|
for (size_t i = 0; i < children.size(); i++) {
|
|
35757
36001
|
auto &vec_child = children[i];
|
|
35758
|
-
if (!val.
|
|
35759
|
-
auto &struct_child =
|
|
36002
|
+
if (!val.IsNull()) {
|
|
36003
|
+
auto &struct_child = val_children[i];
|
|
35760
36004
|
vec_child->SetValue(index, struct_child);
|
|
35761
36005
|
} else {
|
|
35762
36006
|
vec_child->SetValue(index, Value());
|
|
@@ -35764,36 +36008,20 @@ void Vector::SetValue(idx_t index, const Value &val) {
|
|
|
35764
36008
|
}
|
|
35765
36009
|
break;
|
|
35766
36010
|
}
|
|
35767
|
-
case
|
|
36011
|
+
case PhysicalType::LIST: {
|
|
35768
36012
|
auto offset = ListVector::GetListSize(*this);
|
|
35769
|
-
|
|
35770
|
-
|
|
35771
|
-
|
|
35772
|
-
ListVector::PushBack(*this,
|
|
36013
|
+
auto &val_children = ListValue::GetChildren(val);
|
|
36014
|
+
if (!val_children.empty()) {
|
|
36015
|
+
for (idx_t i = 0; i < val_children.size(); i++) {
|
|
36016
|
+
ListVector::PushBack(*this, val_children[i]);
|
|
35773
36017
|
}
|
|
35774
36018
|
}
|
|
35775
36019
|
//! now set the pointer
|
|
35776
36020
|
auto &entry = ((list_entry_t *)data)[index];
|
|
35777
|
-
entry.length =
|
|
36021
|
+
entry.length = val_children.size();
|
|
35778
36022
|
entry.offset = offset;
|
|
35779
36023
|
break;
|
|
35780
36024
|
}
|
|
35781
|
-
case LogicalTypeId::ENUM: {
|
|
35782
|
-
switch (type.InternalType()) {
|
|
35783
|
-
case PhysicalType::UINT8:
|
|
35784
|
-
((uint8_t *)data)[index] = val.value_.utinyint;
|
|
35785
|
-
break;
|
|
35786
|
-
case PhysicalType::UINT16:
|
|
35787
|
-
((uint16_t *)data)[index] = val.value_.usmallint;
|
|
35788
|
-
break;
|
|
35789
|
-
case PhysicalType::UINT32:
|
|
35790
|
-
((uint32_t *)data)[index] = val.value_.uinteger;
|
|
35791
|
-
break;
|
|
35792
|
-
default:
|
|
35793
|
-
throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types");
|
|
35794
|
-
}
|
|
35795
|
-
break;
|
|
35796
|
-
}
|
|
35797
36025
|
default:
|
|
35798
36026
|
throw InternalException("Unimplemented type for Vector::SetValue");
|
|
35799
36027
|
}
|
|
@@ -35909,26 +36137,31 @@ Value Vector::GetValue(idx_t index) const {
|
|
|
35909
36137
|
auto str = ((string_t *)data)[index];
|
|
35910
36138
|
return Value::BLOB((const_data_ptr_t)str.GetDataUnsafe(), str.GetSize());
|
|
35911
36139
|
}
|
|
35912
|
-
case LogicalTypeId::MAP:
|
|
36140
|
+
case LogicalTypeId::MAP: {
|
|
36141
|
+
auto &child_entries = StructVector::GetEntries(*this);
|
|
36142
|
+
Value key = child_entries[0]->GetValue(index);
|
|
36143
|
+
Value value = child_entries[1]->GetValue(index);
|
|
36144
|
+
return Value::MAP(move(key), move(value));
|
|
36145
|
+
}
|
|
35913
36146
|
case LogicalTypeId::STRUCT: {
|
|
35914
|
-
Value ret(GetType());
|
|
35915
|
-
ret.is_null = false;
|
|
35916
36147
|
// we can derive the value schema from the vector schema
|
|
35917
36148
|
auto &child_entries = StructVector::GetEntries(*this);
|
|
35918
|
-
|
|
35919
|
-
|
|
36149
|
+
child_list_t<Value> children;
|
|
36150
|
+
for (idx_t child_idx = 0; child_idx < child_entries.size(); child_idx++) {
|
|
36151
|
+
auto &struct_child = child_entries[child_idx];
|
|
36152
|
+
children.push_back(
|
|
36153
|
+
make_pair(StructType::GetChildName(GetType(), child_idx), struct_child->GetValue(index)));
|
|
35920
36154
|
}
|
|
35921
|
-
return
|
|
36155
|
+
return Value::STRUCT(move(children));
|
|
35922
36156
|
}
|
|
35923
36157
|
case LogicalTypeId::LIST: {
|
|
35924
|
-
Value ret(GetType());
|
|
35925
|
-
ret.is_null = false;
|
|
35926
36158
|
auto offlen = ((list_entry_t *)data)[index];
|
|
35927
36159
|
auto &child_vec = ListVector::GetEntry(*this);
|
|
36160
|
+
vector<Value> children;
|
|
35928
36161
|
for (idx_t i = offlen.offset; i < offlen.offset + offlen.length; i++) {
|
|
35929
|
-
|
|
36162
|
+
children.push_back(child_vec.GetValue(i));
|
|
35930
36163
|
}
|
|
35931
|
-
return
|
|
36164
|
+
return Value::LIST(ListType::GetChildType(GetType()), move(children));
|
|
35932
36165
|
}
|
|
35933
36166
|
default:
|
|
35934
36167
|
throw InternalException("Unimplemented type for value access");
|
|
@@ -36786,7 +37019,14 @@ void TemplatedSearchInMap(Vector &list, T key, vector<idx_t> &offsets, bool is_k
|
|
|
36786
37019
|
}
|
|
36787
37020
|
}
|
|
36788
37021
|
|
|
36789
|
-
|
|
37022
|
+
template <class T>
|
|
37023
|
+
void TemplatedSearchInMap(Vector &list, const Value &key, vector<idx_t> &offsets, bool is_key_null, idx_t offset,
|
|
37024
|
+
idx_t length) {
|
|
37025
|
+
TemplatedSearchInMap<T>(list, key.template GetValueUnsafe<T>(), offsets, is_key_null, offset, length);
|
|
37026
|
+
}
|
|
37027
|
+
|
|
37028
|
+
void SearchStringInMap(Vector &list, const string &key, vector<idx_t> &offsets, bool is_key_null, idx_t offset,
|
|
37029
|
+
idx_t length) {
|
|
36790
37030
|
auto &list_vector = ListVector::GetEntry(list);
|
|
36791
37031
|
VectorData vector_data;
|
|
36792
37032
|
list_vector.Orrify(ListVector::GetListSize(list), vector_data);
|
|
@@ -36811,80 +37051,49 @@ void SearchString(Vector &list, string &key, vector<idx_t> &offsets, bool is_key
|
|
|
36811
37051
|
}
|
|
36812
37052
|
}
|
|
36813
37053
|
|
|
36814
|
-
vector<idx_t> ListVector::Search(Vector &list, Value &key, idx_t row) {
|
|
37054
|
+
vector<idx_t> ListVector::Search(Vector &list, const Value &key, idx_t row) {
|
|
36815
37055
|
vector<idx_t> offsets;
|
|
36816
37056
|
|
|
36817
37057
|
auto &list_vector = ListVector::GetEntry(list);
|
|
36818
37058
|
auto &entry = ((list_entry_t *)list.GetData())[row];
|
|
36819
|
-
switch (list_vector.GetType().id()) {
|
|
36820
37059
|
|
|
36821
|
-
|
|
36822
|
-
|
|
36823
|
-
|
|
36824
|
-
|
|
36825
|
-
}
|
|
36826
|
-
}
|
|
36827
|
-
break;
|
|
36828
|
-
case LogicalTypeId::UTINYINT:
|
|
36829
|
-
::duckdb::TemplatedSearchInMap<uint8_t>(list, key.value_.utinyint, offsets, key.is_null, entry.offset,
|
|
36830
|
-
entry.length);
|
|
36831
|
-
break;
|
|
36832
|
-
case LogicalTypeId::TINYINT:
|
|
36833
|
-
::duckdb::TemplatedSearchInMap<int8_t>(list, key.value_.tinyint, offsets, key.is_null, entry.offset,
|
|
36834
|
-
entry.length);
|
|
36835
|
-
break;
|
|
36836
|
-
case LogicalTypeId::USMALLINT:
|
|
36837
|
-
::duckdb::TemplatedSearchInMap<uint16_t>(list, key.value_.usmallint, offsets, key.is_null, entry.offset,
|
|
36838
|
-
entry.length);
|
|
36839
|
-
break;
|
|
36840
|
-
case LogicalTypeId::SMALLINT:
|
|
36841
|
-
::duckdb::TemplatedSearchInMap<int16_t>(list, key.value_.smallint, offsets, key.is_null, entry.offset,
|
|
36842
|
-
entry.length);
|
|
37060
|
+
switch (list_vector.GetType().InternalType()) {
|
|
37061
|
+
case PhysicalType::BOOL:
|
|
37062
|
+
case PhysicalType::INT8:
|
|
37063
|
+
TemplatedSearchInMap<int8_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36843
37064
|
break;
|
|
36844
|
-
case
|
|
36845
|
-
|
|
36846
|
-
entry.length);
|
|
37065
|
+
case PhysicalType::INT16:
|
|
37066
|
+
TemplatedSearchInMap<int16_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36847
37067
|
break;
|
|
36848
|
-
case
|
|
36849
|
-
|
|
36850
|
-
entry.length);
|
|
37068
|
+
case PhysicalType::INT32:
|
|
37069
|
+
TemplatedSearchInMap<int32_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36851
37070
|
break;
|
|
36852
|
-
case
|
|
36853
|
-
|
|
36854
|
-
entry.length);
|
|
37071
|
+
case PhysicalType::INT64:
|
|
37072
|
+
TemplatedSearchInMap<int64_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36855
37073
|
break;
|
|
36856
|
-
case
|
|
36857
|
-
|
|
36858
|
-
entry.length);
|
|
37074
|
+
case PhysicalType::INT128:
|
|
37075
|
+
TemplatedSearchInMap<hugeint_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36859
37076
|
break;
|
|
36860
|
-
case
|
|
36861
|
-
|
|
36862
|
-
entry.length);
|
|
37077
|
+
case PhysicalType::UINT8:
|
|
37078
|
+
TemplatedSearchInMap<uint8_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36863
37079
|
break;
|
|
36864
|
-
case
|
|
36865
|
-
|
|
36866
|
-
entry.length);
|
|
37080
|
+
case PhysicalType::UINT16:
|
|
37081
|
+
TemplatedSearchInMap<uint16_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36867
37082
|
break;
|
|
36868
|
-
case
|
|
36869
|
-
|
|
36870
|
-
entry.length);
|
|
37083
|
+
case PhysicalType::UINT32:
|
|
37084
|
+
TemplatedSearchInMap<uint32_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36871
37085
|
break;
|
|
36872
|
-
case
|
|
36873
|
-
|
|
37086
|
+
case PhysicalType::UINT64:
|
|
37087
|
+
TemplatedSearchInMap<uint64_t>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36874
37088
|
break;
|
|
36875
|
-
case
|
|
36876
|
-
|
|
36877
|
-
::duckdb::TemplatedSearchInMap<dtime_t>(list, key.value_.time, offsets, key.is_null, entry.offset,
|
|
36878
|
-
entry.length);
|
|
37089
|
+
case PhysicalType::FLOAT:
|
|
37090
|
+
TemplatedSearchInMap<float>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36879
37091
|
break;
|
|
36880
|
-
case
|
|
36881
|
-
|
|
36882
|
-
::duckdb::TemplatedSearchInMap<timestamp_t>(list, key.value_.timestamp, offsets, key.is_null, entry.offset,
|
|
36883
|
-
entry.length);
|
|
37092
|
+
case PhysicalType::DOUBLE:
|
|
37093
|
+
TemplatedSearchInMap<double>(list, key, offsets, key.IsNull(), entry.offset, entry.length);
|
|
36884
37094
|
break;
|
|
36885
|
-
case
|
|
36886
|
-
|
|
36887
|
-
::duckdb::SearchString(list, key.str_value, offsets, key.is_null, entry.offset, entry.length);
|
|
37095
|
+
case PhysicalType::VARCHAR:
|
|
37096
|
+
SearchStringInMap(list, StringValue::Get(key), offsets, key.IsNull(), entry.offset, entry.length);
|
|
36888
37097
|
break;
|
|
36889
37098
|
default:
|
|
36890
37099
|
throw InvalidTypeException(list.GetType().id(), "Invalid type for List Vector Search");
|
|
@@ -36893,13 +37102,13 @@ vector<idx_t> ListVector::Search(Vector &list, Value &key, idx_t row) {
|
|
|
36893
37102
|
}
|
|
36894
37103
|
|
|
36895
37104
|
Value ListVector::GetValuesFromOffsets(Vector &list, vector<idx_t> &offsets) {
|
|
36896
|
-
Value ret(ListType::GetChildType(list.GetType()));
|
|
36897
|
-
ret.is_null = false;
|
|
36898
37105
|
auto &child_vec = ListVector::GetEntry(list);
|
|
37106
|
+
vector<Value> list_values;
|
|
37107
|
+
list_values.reserve(offsets.size());
|
|
36899
37108
|
for (auto &offset : offsets) {
|
|
36900
|
-
|
|
37109
|
+
list_values.push_back(child_vec.GetValue(offset));
|
|
36901
37110
|
}
|
|
36902
|
-
return
|
|
37111
|
+
return Value::LIST(ListType::GetChildType(list.GetType()), move(list_values));
|
|
36903
37112
|
}
|
|
36904
37113
|
|
|
36905
37114
|
idx_t ListVector::GetListSize(const Vector &vec) {
|
|
@@ -36947,7 +37156,7 @@ void ListVector::Append(Vector &target, const Vector &source, const SelectionVec
|
|
|
36947
37156
|
target_buffer.Append(source, sel, source_size, source_offset);
|
|
36948
37157
|
}
|
|
36949
37158
|
|
|
36950
|
-
void ListVector::PushBack(Vector &target, Value &insert) {
|
|
37159
|
+
void ListVector::PushBack(Vector &target, const Value &insert) {
|
|
36951
37160
|
auto &target_buffer = (VectorListBuffer &)*target.auxiliary;
|
|
36952
37161
|
target_buffer.PushBack(insert);
|
|
36953
37162
|
}
|
|
@@ -37032,7 +37241,7 @@ void VectorListBuffer::Append(const Vector &to_append, const SelectionVector &se
|
|
|
37032
37241
|
size += to_append_size - source_offset;
|
|
37033
37242
|
}
|
|
37034
37243
|
|
|
37035
|
-
void VectorListBuffer::PushBack(Value &insert) {
|
|
37244
|
+
void VectorListBuffer::PushBack(const Value &insert) {
|
|
37036
37245
|
if (size + 1 > capacity) {
|
|
37037
37246
|
child->Resize(capacity, capacity * 2);
|
|
37038
37247
|
capacity *= 2;
|
|
@@ -38348,16 +38557,7 @@ int64_t EnumType::GetPos(const LogicalType &type, const string &key) {
|
|
|
38348
38557
|
const string EnumType::GetValue(const Value &val) {
|
|
38349
38558
|
auto info = val.type().AuxInfo();
|
|
38350
38559
|
auto &values_insert_order = ((EnumTypeInfo &)*info).values_insert_order;
|
|
38351
|
-
|
|
38352
|
-
case PhysicalType::UINT8:
|
|
38353
|
-
return values_insert_order.GetValue(val.value_.utinyint).ToString();
|
|
38354
|
-
case PhysicalType::UINT16:
|
|
38355
|
-
return values_insert_order.GetValue(val.value_.usmallint).ToString();
|
|
38356
|
-
case PhysicalType::UINT32:
|
|
38357
|
-
return values_insert_order.GetValue(val.value_.uinteger).ToString();
|
|
38358
|
-
default:
|
|
38359
|
-
throw InternalException("Invalid Internal Type for ENUMs");
|
|
38360
|
-
}
|
|
38560
|
+
return StringValue::Get(values_insert_order.GetValue(val.GetValue<uint32_t>()));
|
|
38361
38561
|
}
|
|
38362
38562
|
|
|
38363
38563
|
Vector &EnumType::GetValuesInsertOrder(const LogicalType &type) {
|
|
@@ -38592,56 +38792,60 @@ static bool TemplatedBooleanOperation(const Value &left, const Value &right) {
|
|
|
38592
38792
|
}
|
|
38593
38793
|
switch (left_type.InternalType()) {
|
|
38594
38794
|
case PhysicalType::BOOL:
|
|
38595
|
-
return OP::Operation(left.
|
|
38795
|
+
return OP::Operation(left.GetValueUnsafe<bool>(), right.GetValueUnsafe<bool>());
|
|
38596
38796
|
case PhysicalType::INT8:
|
|
38597
|
-
return OP::Operation(left.
|
|
38797
|
+
return OP::Operation(left.GetValueUnsafe<int8_t>(), right.GetValueUnsafe<int8_t>());
|
|
38598
38798
|
case PhysicalType::INT16:
|
|
38599
|
-
return OP::Operation(left.
|
|
38799
|
+
return OP::Operation(left.GetValueUnsafe<int16_t>(), right.GetValueUnsafe<int16_t>());
|
|
38600
38800
|
case PhysicalType::INT32:
|
|
38601
|
-
return OP::Operation(left.
|
|
38801
|
+
return OP::Operation(left.GetValueUnsafe<int32_t>(), right.GetValueUnsafe<int32_t>());
|
|
38602
38802
|
case PhysicalType::INT64:
|
|
38603
|
-
return OP::Operation(left.
|
|
38803
|
+
return OP::Operation(left.GetValueUnsafe<int64_t>(), right.GetValueUnsafe<int64_t>());
|
|
38604
38804
|
case PhysicalType::UINT8:
|
|
38605
|
-
return OP::Operation(left.
|
|
38805
|
+
return OP::Operation(left.GetValueUnsafe<uint8_t>(), right.GetValueUnsafe<uint8_t>());
|
|
38606
38806
|
case PhysicalType::UINT16:
|
|
38607
|
-
return OP::Operation(left.
|
|
38807
|
+
return OP::Operation(left.GetValueUnsafe<uint16_t>(), right.GetValueUnsafe<uint16_t>());
|
|
38608
38808
|
case PhysicalType::UINT32:
|
|
38609
|
-
return OP::Operation(left.
|
|
38809
|
+
return OP::Operation(left.GetValueUnsafe<uint32_t>(), right.GetValueUnsafe<uint32_t>());
|
|
38610
38810
|
case PhysicalType::UINT64:
|
|
38611
|
-
return OP::Operation(left.
|
|
38811
|
+
return OP::Operation(left.GetValueUnsafe<uint64_t>(), right.GetValueUnsafe<uint64_t>());
|
|
38612
38812
|
case PhysicalType::INT128:
|
|
38613
|
-
return OP::Operation(left.
|
|
38813
|
+
return OP::Operation(left.GetValueUnsafe<hugeint_t>(), right.GetValueUnsafe<hugeint_t>());
|
|
38614
38814
|
case PhysicalType::FLOAT:
|
|
38615
|
-
return OP::Operation(left.
|
|
38815
|
+
return OP::Operation(left.GetValueUnsafe<float>(), right.GetValueUnsafe<float>());
|
|
38616
38816
|
case PhysicalType::DOUBLE:
|
|
38617
|
-
return OP::Operation(left.
|
|
38817
|
+
return OP::Operation(left.GetValueUnsafe<double>(), right.GetValueUnsafe<double>());
|
|
38618
38818
|
case PhysicalType::INTERVAL:
|
|
38619
|
-
return OP::Operation(left.
|
|
38819
|
+
return OP::Operation(left.GetValueUnsafe<interval_t>(), right.GetValueUnsafe<interval_t>());
|
|
38620
38820
|
case PhysicalType::VARCHAR:
|
|
38621
|
-
return OP::Operation(left
|
|
38821
|
+
return OP::Operation(StringValue::Get(left), StringValue::Get(right));
|
|
38622
38822
|
case PhysicalType::STRUCT: {
|
|
38823
|
+
auto &left_children = StructValue::GetChildren(left);
|
|
38824
|
+
auto &right_children = StructValue::GetChildren(right);
|
|
38623
38825
|
// this should be enforced by the type
|
|
38624
|
-
D_ASSERT(
|
|
38826
|
+
D_ASSERT(left_children.size() == right_children.size());
|
|
38625
38827
|
idx_t i = 0;
|
|
38626
|
-
for (; i <
|
|
38627
|
-
if (ValuePositionComparator::Definite<OP>(
|
|
38828
|
+
for (; i < left_children.size() - 1; ++i) {
|
|
38829
|
+
if (ValuePositionComparator::Definite<OP>(left_children[i], right_children[i])) {
|
|
38628
38830
|
return true;
|
|
38629
38831
|
}
|
|
38630
|
-
if (!ValuePositionComparator::Possible<OP>(
|
|
38832
|
+
if (!ValuePositionComparator::Possible<OP>(left_children[i], right_children[i])) {
|
|
38631
38833
|
return false;
|
|
38632
38834
|
}
|
|
38633
38835
|
}
|
|
38634
|
-
return ValuePositionComparator::Final<OP>(
|
|
38836
|
+
return ValuePositionComparator::Final<OP>(left_children[i], right_children[i]);
|
|
38635
38837
|
}
|
|
38636
38838
|
case PhysicalType::LIST: {
|
|
38839
|
+
auto &left_children = ListValue::GetChildren(left);
|
|
38840
|
+
auto &right_children = ListValue::GetChildren(right);
|
|
38637
38841
|
for (idx_t pos = 0;; ++pos) {
|
|
38638
|
-
if (pos ==
|
|
38639
|
-
return ValuePositionComparator::TieBreak<OP>(
|
|
38842
|
+
if (pos == left_children.size() || pos == right_children.size()) {
|
|
38843
|
+
return ValuePositionComparator::TieBreak<OP>(left_children.size(), right_children.size());
|
|
38640
38844
|
}
|
|
38641
|
-
if (ValuePositionComparator::Definite<OP>(
|
|
38845
|
+
if (ValuePositionComparator::Definite<OP>(left_children[pos], right_children[pos])) {
|
|
38642
38846
|
return true;
|
|
38643
38847
|
}
|
|
38644
|
-
if (!ValuePositionComparator::Possible<OP>(
|
|
38848
|
+
if (!ValuePositionComparator::Possible<OP>(left_children[pos], right_children[pos])) {
|
|
38645
38849
|
return false;
|
|
38646
38850
|
}
|
|
38647
38851
|
}
|
|
@@ -38653,7 +38857,7 @@ static bool TemplatedBooleanOperation(const Value &left, const Value &right) {
|
|
|
38653
38857
|
}
|
|
38654
38858
|
|
|
38655
38859
|
bool ValueOperations::Equals(const Value &left, const Value &right) {
|
|
38656
|
-
if (left.
|
|
38860
|
+
if (left.IsNull() || right.IsNull()) {
|
|
38657
38861
|
throw InternalException("Comparison on NULL values");
|
|
38658
38862
|
}
|
|
38659
38863
|
return TemplatedBooleanOperation<duckdb::Equals>(left, right);
|
|
@@ -38664,14 +38868,14 @@ bool ValueOperations::NotEquals(const Value &left, const Value &right) {
|
|
|
38664
38868
|
}
|
|
38665
38869
|
|
|
38666
38870
|
bool ValueOperations::GreaterThan(const Value &left, const Value &right) {
|
|
38667
|
-
if (left.
|
|
38871
|
+
if (left.IsNull() || right.IsNull()) {
|
|
38668
38872
|
throw InternalException("Comparison on NULL values");
|
|
38669
38873
|
}
|
|
38670
38874
|
return TemplatedBooleanOperation<duckdb::GreaterThan>(left, right);
|
|
38671
38875
|
}
|
|
38672
38876
|
|
|
38673
38877
|
bool ValueOperations::GreaterThanEquals(const Value &left, const Value &right) {
|
|
38674
|
-
if (left.
|
|
38878
|
+
if (left.IsNull() || right.IsNull()) {
|
|
38675
38879
|
throw InternalException("Comparison on NULL values");
|
|
38676
38880
|
}
|
|
38677
38881
|
return TemplatedBooleanOperation<duckdb::GreaterThanEquals>(left, right);
|
|
@@ -38686,10 +38890,10 @@ bool ValueOperations::LessThanEquals(const Value &left, const Value &right) {
|
|
|
38686
38890
|
}
|
|
38687
38891
|
|
|
38688
38892
|
bool ValueOperations::NotDistinctFrom(const Value &left, const Value &right) {
|
|
38689
|
-
if (left.
|
|
38893
|
+
if (left.IsNull() && right.IsNull()) {
|
|
38690
38894
|
return true;
|
|
38691
38895
|
}
|
|
38692
|
-
if (left.
|
|
38896
|
+
if (left.IsNull() != right.IsNull()) {
|
|
38693
38897
|
return false;
|
|
38694
38898
|
}
|
|
38695
38899
|
return TemplatedBooleanOperation<duckdb::Equals>(left, right);
|
|
@@ -38700,20 +38904,20 @@ bool ValueOperations::DistinctFrom(const Value &left, const Value &right) {
|
|
|
38700
38904
|
}
|
|
38701
38905
|
|
|
38702
38906
|
bool ValueOperations::DistinctGreaterThan(const Value &left, const Value &right) {
|
|
38703
|
-
if (left.
|
|
38907
|
+
if (left.IsNull() && right.IsNull()) {
|
|
38704
38908
|
return false;
|
|
38705
|
-
} else if (right.
|
|
38909
|
+
} else if (right.IsNull()) {
|
|
38706
38910
|
return false;
|
|
38707
|
-
} else if (left.
|
|
38911
|
+
} else if (left.IsNull()) {
|
|
38708
38912
|
return true;
|
|
38709
38913
|
}
|
|
38710
38914
|
return TemplatedBooleanOperation<duckdb::GreaterThan>(left, right);
|
|
38711
38915
|
}
|
|
38712
38916
|
|
|
38713
38917
|
bool ValueOperations::DistinctGreaterThanEquals(const Value &left, const Value &right) {
|
|
38714
|
-
if (left.
|
|
38918
|
+
if (left.IsNull()) {
|
|
38715
38919
|
return true;
|
|
38716
|
-
} else if (right.
|
|
38920
|
+
} else if (right.IsNull()) {
|
|
38717
38921
|
return false;
|
|
38718
38922
|
}
|
|
38719
38923
|
return TemplatedBooleanOperation<duckdb::GreaterThanEquals>(left, right);
|
|
@@ -38728,297 +38932,6 @@ bool ValueOperations::DistinctLessThanEquals(const Value &left, const Value &rig
|
|
|
38728
38932
|
}
|
|
38729
38933
|
|
|
38730
38934
|
} // namespace duckdb
|
|
38731
|
-
|
|
38732
|
-
|
|
38733
|
-
|
|
38734
|
-
|
|
38735
|
-
|
|
38736
|
-
namespace duckdb {
|
|
38737
|
-
|
|
38738
|
-
hash_t ValueOperations::Hash(const Value &op) {
|
|
38739
|
-
if (op.is_null) {
|
|
38740
|
-
return 0;
|
|
38741
|
-
}
|
|
38742
|
-
switch (op.type().InternalType()) {
|
|
38743
|
-
case PhysicalType::BOOL:
|
|
38744
|
-
return duckdb::Hash(op.value_.boolean);
|
|
38745
|
-
case PhysicalType::INT8:
|
|
38746
|
-
return duckdb::Hash(op.value_.tinyint);
|
|
38747
|
-
case PhysicalType::INT16:
|
|
38748
|
-
return duckdb::Hash(op.value_.smallint);
|
|
38749
|
-
case PhysicalType::INT32:
|
|
38750
|
-
return duckdb::Hash(op.value_.integer);
|
|
38751
|
-
case PhysicalType::INT64:
|
|
38752
|
-
return duckdb::Hash(op.value_.bigint);
|
|
38753
|
-
case PhysicalType::UINT8:
|
|
38754
|
-
return duckdb::Hash(op.value_.utinyint);
|
|
38755
|
-
case PhysicalType::UINT16:
|
|
38756
|
-
return duckdb::Hash(op.value_.usmallint);
|
|
38757
|
-
case PhysicalType::UINT32:
|
|
38758
|
-
return duckdb::Hash(op.value_.uinteger);
|
|
38759
|
-
case PhysicalType::UINT64:
|
|
38760
|
-
return duckdb::Hash(op.value_.ubigint);
|
|
38761
|
-
case PhysicalType::INT128:
|
|
38762
|
-
return duckdb::Hash(op.value_.hugeint);
|
|
38763
|
-
case PhysicalType::FLOAT:
|
|
38764
|
-
return duckdb::Hash(op.value_.float_);
|
|
38765
|
-
case PhysicalType::DOUBLE:
|
|
38766
|
-
return duckdb::Hash(op.value_.double_);
|
|
38767
|
-
case PhysicalType::INTERVAL:
|
|
38768
|
-
return duckdb::Hash(op.value_.interval);
|
|
38769
|
-
case PhysicalType::VARCHAR:
|
|
38770
|
-
return duckdb::Hash(op.str_value.c_str());
|
|
38771
|
-
case PhysicalType::LIST: {
|
|
38772
|
-
hash_t hash = 0;
|
|
38773
|
-
for (auto &entry : op.list_value) {
|
|
38774
|
-
hash ^= ValueOperations::Hash(entry);
|
|
38775
|
-
}
|
|
38776
|
-
return hash;
|
|
38777
|
-
}
|
|
38778
|
-
case PhysicalType::STRUCT: {
|
|
38779
|
-
hash_t hash = 0;
|
|
38780
|
-
for (auto &entry : op.struct_value) {
|
|
38781
|
-
hash ^= ValueOperations::Hash(entry);
|
|
38782
|
-
}
|
|
38783
|
-
return hash;
|
|
38784
|
-
}
|
|
38785
|
-
default:
|
|
38786
|
-
throw InternalException("Unimplemented type for value hash");
|
|
38787
|
-
}
|
|
38788
|
-
}
|
|
38789
|
-
|
|
38790
|
-
} // namespace duckdb
|
|
38791
|
-
|
|
38792
|
-
|
|
38793
|
-
|
|
38794
|
-
|
|
38795
|
-
|
|
38796
|
-
|
|
38797
|
-
|
|
38798
|
-
//===----------------------------------------------------------------------===//
|
|
38799
|
-
// DuckDB
|
|
38800
|
-
//
|
|
38801
|
-
// duckdb/common/operator/subtract.hpp
|
|
38802
|
-
//
|
|
38803
|
-
//
|
|
38804
|
-
//===----------------------------------------------------------------------===//
|
|
38805
|
-
|
|
38806
|
-
|
|
38807
|
-
|
|
38808
|
-
|
|
38809
|
-
|
|
38810
|
-
|
|
38811
|
-
namespace duckdb {
|
|
38812
|
-
|
|
38813
|
-
struct SubtractOperator {
|
|
38814
|
-
template <class TA, class TB, class TR>
|
|
38815
|
-
static inline TR Operation(TA left, TB right) {
|
|
38816
|
-
return left - right;
|
|
38817
|
-
}
|
|
38818
|
-
};
|
|
38819
|
-
|
|
38820
|
-
template <>
|
|
38821
|
-
float SubtractOperator::Operation(float left, float right);
|
|
38822
|
-
template <>
|
|
38823
|
-
double SubtractOperator::Operation(double left, double right);
|
|
38824
|
-
template <>
|
|
38825
|
-
interval_t SubtractOperator::Operation(interval_t left, interval_t right);
|
|
38826
|
-
template <>
|
|
38827
|
-
int64_t SubtractOperator::Operation(date_t left, date_t right);
|
|
38828
|
-
template <>
|
|
38829
|
-
date_t SubtractOperator::Operation(date_t left, int32_t right);
|
|
38830
|
-
template <>
|
|
38831
|
-
date_t SubtractOperator::Operation(date_t left, interval_t right);
|
|
38832
|
-
template <>
|
|
38833
|
-
timestamp_t SubtractOperator::Operation(timestamp_t left, interval_t right);
|
|
38834
|
-
template <>
|
|
38835
|
-
interval_t SubtractOperator::Operation(timestamp_t left, timestamp_t right);
|
|
38836
|
-
|
|
38837
|
-
struct TrySubtractOperator {
|
|
38838
|
-
template <class TA, class TB, class TR>
|
|
38839
|
-
static inline bool Operation(TA left, TB right, TR &result) {
|
|
38840
|
-
throw InternalException("Unimplemented type for TrySubtractOperator");
|
|
38841
|
-
}
|
|
38842
|
-
};
|
|
38843
|
-
|
|
38844
|
-
template <>
|
|
38845
|
-
bool TrySubtractOperator::Operation(uint8_t left, uint8_t right, uint8_t &result);
|
|
38846
|
-
template <>
|
|
38847
|
-
bool TrySubtractOperator::Operation(uint16_t left, uint16_t right, uint16_t &result);
|
|
38848
|
-
template <>
|
|
38849
|
-
bool TrySubtractOperator::Operation(uint32_t left, uint32_t right, uint32_t &result);
|
|
38850
|
-
template <>
|
|
38851
|
-
bool TrySubtractOperator::Operation(uint64_t left, uint64_t right, uint64_t &result);
|
|
38852
|
-
|
|
38853
|
-
template <>
|
|
38854
|
-
bool TrySubtractOperator::Operation(int8_t left, int8_t right, int8_t &result);
|
|
38855
|
-
template <>
|
|
38856
|
-
bool TrySubtractOperator::Operation(int16_t left, int16_t right, int16_t &result);
|
|
38857
|
-
template <>
|
|
38858
|
-
bool TrySubtractOperator::Operation(int32_t left, int32_t right, int32_t &result);
|
|
38859
|
-
template <>
|
|
38860
|
-
bool TrySubtractOperator::Operation(int64_t left, int64_t right, int64_t &result);
|
|
38861
|
-
|
|
38862
|
-
struct SubtractOperatorOverflowCheck {
|
|
38863
|
-
template <class TA, class TB, class TR>
|
|
38864
|
-
static inline TR Operation(TA left, TB right) {
|
|
38865
|
-
TR result;
|
|
38866
|
-
if (!TrySubtractOperator::Operation(left, right, result)) {
|
|
38867
|
-
throw OutOfRangeException("Overflow in subtraction of %s (%d - %d)!", TypeIdToString(GetTypeId<TA>()), left,
|
|
38868
|
-
right);
|
|
38869
|
-
}
|
|
38870
|
-
return result;
|
|
38871
|
-
}
|
|
38872
|
-
};
|
|
38873
|
-
|
|
38874
|
-
struct TryDecimalSubtract {
|
|
38875
|
-
template <class TA, class TB, class TR>
|
|
38876
|
-
static inline bool Operation(TA left, TB right, TR &result) {
|
|
38877
|
-
throw InternalException("Unimplemented type for TryDecimalSubtract");
|
|
38878
|
-
}
|
|
38879
|
-
};
|
|
38880
|
-
|
|
38881
|
-
template <>
|
|
38882
|
-
bool TryDecimalSubtract::Operation(int16_t left, int16_t right, int16_t &result);
|
|
38883
|
-
template <>
|
|
38884
|
-
bool TryDecimalSubtract::Operation(int32_t left, int32_t right, int32_t &result);
|
|
38885
|
-
template <>
|
|
38886
|
-
bool TryDecimalSubtract::Operation(int64_t left, int64_t right, int64_t &result);
|
|
38887
|
-
template <>
|
|
38888
|
-
bool TryDecimalSubtract::Operation(hugeint_t left, hugeint_t right, hugeint_t &result);
|
|
38889
|
-
|
|
38890
|
-
struct DecimalSubtractOverflowCheck {
|
|
38891
|
-
template <class TA, class TB, class TR>
|
|
38892
|
-
static inline TR Operation(TA left, TB right) {
|
|
38893
|
-
TR result;
|
|
38894
|
-
if (!TryDecimalSubtract::Operation<TA, TB, TR>(left, right, result)) {
|
|
38895
|
-
throw OutOfRangeException("Overflow in subtract of DECIMAL(18) (%d - %d). You might want to add an "
|
|
38896
|
-
"explicit cast to a bigger decimal.",
|
|
38897
|
-
left, right);
|
|
38898
|
-
}
|
|
38899
|
-
return result;
|
|
38900
|
-
}
|
|
38901
|
-
};
|
|
38902
|
-
|
|
38903
|
-
template <>
|
|
38904
|
-
hugeint_t DecimalSubtractOverflowCheck::Operation(hugeint_t left, hugeint_t right);
|
|
38905
|
-
|
|
38906
|
-
struct SubtractTimeOperator {
|
|
38907
|
-
template <class TA, class TB, class TR>
|
|
38908
|
-
static TR Operation(TA left, TB right);
|
|
38909
|
-
};
|
|
38910
|
-
|
|
38911
|
-
template <>
|
|
38912
|
-
dtime_t SubtractTimeOperator::Operation(dtime_t left, interval_t right);
|
|
38913
|
-
|
|
38914
|
-
} // namespace duckdb
|
|
38915
|
-
|
|
38916
|
-
|
|
38917
|
-
namespace duckdb {
|
|
38918
|
-
|
|
38919
|
-
template <class OP>
|
|
38920
|
-
static Value BinaryValueOperation(const Value &left, const Value &right) {
|
|
38921
|
-
auto left_type = left.type();
|
|
38922
|
-
auto right_type = right.type();
|
|
38923
|
-
LogicalType result_type = left_type;
|
|
38924
|
-
if (left_type != right_type) {
|
|
38925
|
-
result_type = LogicalType::MaxLogicalType(left.type(), right.type());
|
|
38926
|
-
Value left_cast = left.CastAs(result_type);
|
|
38927
|
-
Value right_cast = right.CastAs(result_type);
|
|
38928
|
-
return BinaryValueOperation<OP>(left_cast, right_cast);
|
|
38929
|
-
}
|
|
38930
|
-
if (left.is_null || right.is_null) {
|
|
38931
|
-
return Value().CastAs(result_type);
|
|
38932
|
-
}
|
|
38933
|
-
if (TypeIsIntegral(result_type.InternalType())) {
|
|
38934
|
-
hugeint_t left_hugeint;
|
|
38935
|
-
hugeint_t right_hugeint;
|
|
38936
|
-
switch (result_type.InternalType()) {
|
|
38937
|
-
case PhysicalType::INT8:
|
|
38938
|
-
left_hugeint = Hugeint::Convert(left.value_.tinyint);
|
|
38939
|
-
right_hugeint = Hugeint::Convert(right.value_.tinyint);
|
|
38940
|
-
break;
|
|
38941
|
-
case PhysicalType::INT16:
|
|
38942
|
-
left_hugeint = Hugeint::Convert(left.value_.smallint);
|
|
38943
|
-
right_hugeint = Hugeint::Convert(right.value_.smallint);
|
|
38944
|
-
break;
|
|
38945
|
-
case PhysicalType::INT32:
|
|
38946
|
-
left_hugeint = Hugeint::Convert(left.value_.integer);
|
|
38947
|
-
right_hugeint = Hugeint::Convert(right.value_.integer);
|
|
38948
|
-
break;
|
|
38949
|
-
case PhysicalType::INT64:
|
|
38950
|
-
left_hugeint = Hugeint::Convert(left.value_.bigint);
|
|
38951
|
-
right_hugeint = Hugeint::Convert(right.value_.bigint);
|
|
38952
|
-
break;
|
|
38953
|
-
case PhysicalType::UINT8:
|
|
38954
|
-
left_hugeint = Hugeint::Convert(left.value_.utinyint);
|
|
38955
|
-
right_hugeint = Hugeint::Convert(right.value_.utinyint);
|
|
38956
|
-
break;
|
|
38957
|
-
case PhysicalType::UINT16:
|
|
38958
|
-
left_hugeint = Hugeint::Convert(left.value_.usmallint);
|
|
38959
|
-
right_hugeint = Hugeint::Convert(right.value_.usmallint);
|
|
38960
|
-
break;
|
|
38961
|
-
case PhysicalType::UINT32:
|
|
38962
|
-
left_hugeint = Hugeint::Convert(left.value_.uinteger);
|
|
38963
|
-
right_hugeint = Hugeint::Convert(right.value_.uinteger);
|
|
38964
|
-
break;
|
|
38965
|
-
case PhysicalType::UINT64:
|
|
38966
|
-
left_hugeint = Hugeint::Convert(left.value_.ubigint);
|
|
38967
|
-
right_hugeint = Hugeint::Convert(right.value_.ubigint);
|
|
38968
|
-
break;
|
|
38969
|
-
case PhysicalType::INT128:
|
|
38970
|
-
left_hugeint = left.value_.hugeint;
|
|
38971
|
-
right_hugeint = right.value_.hugeint;
|
|
38972
|
-
break;
|
|
38973
|
-
default:
|
|
38974
|
-
throw NotImplementedException("Unimplemented type for value binary op");
|
|
38975
|
-
}
|
|
38976
|
-
// integer addition
|
|
38977
|
-
return Value::Numeric(result_type,
|
|
38978
|
-
OP::template Operation<hugeint_t, hugeint_t, hugeint_t>(left_hugeint, right_hugeint));
|
|
38979
|
-
} else if (result_type.InternalType() == PhysicalType::FLOAT) {
|
|
38980
|
-
return Value::FLOAT(
|
|
38981
|
-
OP::template Operation<float, float, float>(left.GetValue<float>(), right.GetValue<float>()));
|
|
38982
|
-
} else if (result_type.InternalType() == PhysicalType::DOUBLE) {
|
|
38983
|
-
return Value::DOUBLE(
|
|
38984
|
-
OP::template Operation<double, double, double>(left.GetValue<double>(), right.GetValue<double>()));
|
|
38985
|
-
} else {
|
|
38986
|
-
throw NotImplementedException("Unimplemented type for value binary op");
|
|
38987
|
-
}
|
|
38988
|
-
}
|
|
38989
|
-
|
|
38990
|
-
//===--------------------------------------------------------------------===//
|
|
38991
|
-
// Numeric Operations
|
|
38992
|
-
//===--------------------------------------------------------------------===//
|
|
38993
|
-
Value ValueOperations::Add(const Value &left, const Value &right) {
|
|
38994
|
-
return BinaryValueOperation<duckdb::AddOperator>(left, right);
|
|
38995
|
-
}
|
|
38996
|
-
|
|
38997
|
-
Value ValueOperations::Subtract(const Value &left, const Value &right) {
|
|
38998
|
-
return BinaryValueOperation<duckdb::SubtractOperator>(left, right);
|
|
38999
|
-
}
|
|
39000
|
-
|
|
39001
|
-
Value ValueOperations::Multiply(const Value &left, const Value &right) {
|
|
39002
|
-
return BinaryValueOperation<duckdb::MultiplyOperator>(left, right);
|
|
39003
|
-
}
|
|
39004
|
-
|
|
39005
|
-
Value ValueOperations::Modulo(const Value &left, const Value &right) {
|
|
39006
|
-
if (right == 0) {
|
|
39007
|
-
return Value(right.type());
|
|
39008
|
-
} else {
|
|
39009
|
-
return BinaryValueOperation<duckdb::ModuloOperator>(left, right);
|
|
39010
|
-
}
|
|
39011
|
-
}
|
|
39012
|
-
|
|
39013
|
-
Value ValueOperations::Divide(const Value &left, const Value &right) {
|
|
39014
|
-
if (right == 0) {
|
|
39015
|
-
return Value(right.type());
|
|
39016
|
-
} else {
|
|
39017
|
-
return BinaryValueOperation<duckdb::DivideOperator>(left, right);
|
|
39018
|
-
}
|
|
39019
|
-
}
|
|
39020
|
-
|
|
39021
|
-
} // namespace duckdb
|
|
39022
38935
|
//===--------------------------------------------------------------------===//
|
|
39023
38936
|
// boolean_operators.cpp
|
|
39024
38937
|
// Description: This file contains the implementation of the boolean
|
|
@@ -41592,7 +41505,7 @@ void EnumToVarchar(Vector &source, Vector &result, idx_t count, PhysicalType enu
|
|
|
41592
41505
|
|
|
41593
41506
|
for (idx_t i = 0; i < count; i++) {
|
|
41594
41507
|
auto src_val = source.GetValue(i);
|
|
41595
|
-
if (src_val.
|
|
41508
|
+
if (src_val.IsNull()) {
|
|
41596
41509
|
result.SetValue(i, Value());
|
|
41597
41510
|
continue;
|
|
41598
41511
|
}
|
|
@@ -41600,13 +41513,13 @@ void EnumToVarchar(Vector &source, Vector &result, idx_t count, PhysicalType enu
|
|
|
41600
41513
|
uint64_t enum_idx;
|
|
41601
41514
|
switch (enum_physical_type) {
|
|
41602
41515
|
case PhysicalType::UINT8:
|
|
41603
|
-
enum_idx = src_val
|
|
41516
|
+
enum_idx = UTinyIntValue::Get(src_val);
|
|
41604
41517
|
break;
|
|
41605
41518
|
case PhysicalType::UINT16:
|
|
41606
|
-
enum_idx = src_val
|
|
41519
|
+
enum_idx = USmallIntValue::Get(src_val);
|
|
41607
41520
|
break;
|
|
41608
41521
|
case PhysicalType::UINT32:
|
|
41609
|
-
enum_idx = src_val
|
|
41522
|
+
enum_idx = UIntegerValue::Get(src_val);
|
|
41610
41523
|
break;
|
|
41611
41524
|
default:
|
|
41612
41525
|
throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types");
|
|
@@ -45710,32 +45623,31 @@ static unique_ptr<Key> CreateKey(ART &art, PhysicalType type, Value &value) {
|
|
|
45710
45623
|
D_ASSERT(type == value.type().InternalType());
|
|
45711
45624
|
switch (type) {
|
|
45712
45625
|
case PhysicalType::BOOL:
|
|
45713
|
-
return Key::CreateKey<bool>(value
|
|
45626
|
+
return Key::CreateKey<bool>(value, art.is_little_endian);
|
|
45714
45627
|
case PhysicalType::INT8:
|
|
45715
|
-
return Key::CreateKey<int8_t>(value
|
|
45628
|
+
return Key::CreateKey<int8_t>(value, art.is_little_endian);
|
|
45716
45629
|
case PhysicalType::INT16:
|
|
45717
|
-
return Key::CreateKey<int16_t>(value
|
|
45630
|
+
return Key::CreateKey<int16_t>(value, art.is_little_endian);
|
|
45718
45631
|
case PhysicalType::INT32:
|
|
45719
|
-
return Key::CreateKey<int32_t>(value
|
|
45632
|
+
return Key::CreateKey<int32_t>(value, art.is_little_endian);
|
|
45720
45633
|
case PhysicalType::INT64:
|
|
45721
|
-
return Key::CreateKey<int64_t>(value
|
|
45634
|
+
return Key::CreateKey<int64_t>(value, art.is_little_endian);
|
|
45722
45635
|
case PhysicalType::UINT8:
|
|
45723
|
-
return Key::CreateKey<uint8_t>(value
|
|
45636
|
+
return Key::CreateKey<uint8_t>(value, art.is_little_endian);
|
|
45724
45637
|
case PhysicalType::UINT16:
|
|
45725
|
-
return Key::CreateKey<uint16_t>(value
|
|
45638
|
+
return Key::CreateKey<uint16_t>(value, art.is_little_endian);
|
|
45726
45639
|
case PhysicalType::UINT32:
|
|
45727
|
-
return Key::CreateKey<uint32_t>(value
|
|
45640
|
+
return Key::CreateKey<uint32_t>(value, art.is_little_endian);
|
|
45728
45641
|
case PhysicalType::UINT64:
|
|
45729
|
-
return Key::CreateKey<uint64_t>(value
|
|
45642
|
+
return Key::CreateKey<uint64_t>(value, art.is_little_endian);
|
|
45730
45643
|
case PhysicalType::INT128:
|
|
45731
|
-
return Key::CreateKey<hugeint_t>(value
|
|
45644
|
+
return Key::CreateKey<hugeint_t>(value, art.is_little_endian);
|
|
45732
45645
|
case PhysicalType::FLOAT:
|
|
45733
|
-
return Key::CreateKey<float>(value
|
|
45646
|
+
return Key::CreateKey<float>(value, art.is_little_endian);
|
|
45734
45647
|
case PhysicalType::DOUBLE:
|
|
45735
|
-
return Key::CreateKey<double>(value
|
|
45648
|
+
return Key::CreateKey<double>(value, art.is_little_endian);
|
|
45736
45649
|
case PhysicalType::VARCHAR:
|
|
45737
|
-
return Key::CreateKey<string_t>(
|
|
45738
|
-
art.is_little_endian);
|
|
45650
|
+
return Key::CreateKey<string_t>(value, art.is_little_endian);
|
|
45739
45651
|
default:
|
|
45740
45652
|
throw InternalException("Invalid type for index");
|
|
45741
45653
|
}
|
|
@@ -46074,7 +45986,7 @@ bool ART::Scan(Transaction &transaction, DataTable &table, IndexScanState &table
|
|
|
46074
45986
|
|
|
46075
45987
|
vector<row_t> row_ids;
|
|
46076
45988
|
bool success = true;
|
|
46077
|
-
if (state->values[1].
|
|
45989
|
+
if (state->values[1].IsNull()) {
|
|
46078
45990
|
lock_guard<mutex> l(lock);
|
|
46079
45991
|
// single predicate
|
|
46080
45992
|
switch (state->expressions[0]) {
|
|
@@ -48958,7 +48870,7 @@ PhysicalPerfectHashAggregate::PhysicalPerfectHashAggregate(ClientContext &contex
|
|
|
48958
48870
|
for (auto &stats : group_stats) {
|
|
48959
48871
|
D_ASSERT(stats);
|
|
48960
48872
|
auto &nstats = (NumericStatistics &)*stats;
|
|
48961
|
-
D_ASSERT(!nstats.min.
|
|
48873
|
+
D_ASSERT(!nstats.min.IsNull());
|
|
48962
48874
|
group_minima.push_back(move(nstats.min));
|
|
48963
48875
|
}
|
|
48964
48876
|
for (auto &expr : groups) {
|
|
@@ -51490,7 +51402,7 @@ SinkResultType PhysicalLimit::Sink(ExecutionContext &context, GlobalSinkState &g
|
|
|
51490
51402
|
if (limit == DConstants::INVALID_INDEX) {
|
|
51491
51403
|
limit = 1ULL << 62ULL;
|
|
51492
51404
|
Value val = GetDelimiter(input, limit_expression.get());
|
|
51493
|
-
if (!val.
|
|
51405
|
+
if (!val.IsNull()) {
|
|
51494
51406
|
limit = val.GetValue<idx_t>();
|
|
51495
51407
|
}
|
|
51496
51408
|
if (limit > 1ULL << 62ULL) {
|
|
@@ -51500,7 +51412,7 @@ SinkResultType PhysicalLimit::Sink(ExecutionContext &context, GlobalSinkState &g
|
|
|
51500
51412
|
if (offset == DConstants::INVALID_INDEX) {
|
|
51501
51413
|
offset = 0;
|
|
51502
51414
|
Value val = GetDelimiter(input, offset_expression.get());
|
|
51503
|
-
if (!val.
|
|
51415
|
+
if (!val.IsNull()) {
|
|
51504
51416
|
offset = val.GetValue<idx_t>();
|
|
51505
51417
|
}
|
|
51506
51418
|
if (offset > 1ULL << 62ULL) {
|
|
@@ -51708,7 +51620,7 @@ SinkResultType PhysicalLimitPercent::Sink(ExecutionContext &context, GlobalSinkS
|
|
|
51708
51620
|
// get the next chunk from the child
|
|
51709
51621
|
if (!state.is_limit_percent_delimited) {
|
|
51710
51622
|
Value val = PhysicalLimit::GetDelimiter(input, limit_expression.get());
|
|
51711
|
-
if (!val.
|
|
51623
|
+
if (!val.IsNull()) {
|
|
51712
51624
|
limit_percent = val.GetValue<double>();
|
|
51713
51625
|
}
|
|
51714
51626
|
if (limit_percent < 0.0) {
|
|
@@ -51718,7 +51630,7 @@ SinkResultType PhysicalLimitPercent::Sink(ExecutionContext &context, GlobalSinkS
|
|
|
51718
51630
|
}
|
|
51719
51631
|
if (!state.is_offset_delimited) {
|
|
51720
51632
|
Value val = PhysicalLimit::GetDelimiter(input, offset_expression.get());
|
|
51721
|
-
if (!val.
|
|
51633
|
+
if (!val.IsNull()) {
|
|
51722
51634
|
offset = val.GetValue<idx_t>();
|
|
51723
51635
|
}
|
|
51724
51636
|
if (offset > 1ULL << 62ULL) {
|
|
@@ -52939,7 +52851,7 @@ bool PerfectHashJoinExecutor::FillSelectionVectorSwitchBuild(Vector &source, Sel
|
|
|
52939
52851
|
template <typename T>
|
|
52940
52852
|
bool PerfectHashJoinExecutor::TemplatedFillSelectionVectorBuild(Vector &source, SelectionVector &sel_vec,
|
|
52941
52853
|
SelectionVector &seq_sel_vec, idx_t count) {
|
|
52942
|
-
if (perfect_join_statistics.build_min.
|
|
52854
|
+
if (perfect_join_statistics.build_min.IsNull() || perfect_join_statistics.build_max.IsNull()) {
|
|
52943
52855
|
return false;
|
|
52944
52856
|
}
|
|
52945
52857
|
auto min_value = perfect_join_statistics.build_min.GetValueUnsafe<T>();
|
|
@@ -54506,7 +54418,7 @@ void PhysicalIndexJoin::GetRHSMatches(ExecutionContext &context, DataChunk &inpu
|
|
|
54506
54418
|
auto equal_value = state.join_keys.GetValue(0, i);
|
|
54507
54419
|
auto index_state = art.InitializeScanSinglePredicate(transaction, equal_value, ExpressionType::COMPARE_EQUAL);
|
|
54508
54420
|
state.rhs_rows[i].clear();
|
|
54509
|
-
if (!equal_value.
|
|
54421
|
+
if (!equal_value.IsNull()) {
|
|
54510
54422
|
if (fetch_types.empty()) {
|
|
54511
54423
|
IndexLock lock;
|
|
54512
54424
|
index->InitializeLock(lock);
|
|
@@ -56688,9 +56600,9 @@ static string GetLineNumberStr(idx_t linenr, bool linenr_estimated) {
|
|
|
56688
56600
|
return to_string(linenr + 1) + estimated;
|
|
56689
56601
|
}
|
|
56690
56602
|
|
|
56691
|
-
static bool StartsWithNumericDate(string &separator, const
|
|
56692
|
-
auto begin = value.
|
|
56693
|
-
auto end = begin + value.
|
|
56603
|
+
static bool StartsWithNumericDate(string &separator, const string &value) {
|
|
56604
|
+
auto begin = value.c_str();
|
|
56605
|
+
auto end = begin + value.size();
|
|
56694
56606
|
|
|
56695
56607
|
// StrpTimeFormat::Parse will skip whitespace, so we can too
|
|
56696
56608
|
auto field1 = std::find_if_not(begin, end, StringUtil::CharacterIsSpace);
|
|
@@ -57073,12 +56985,13 @@ bool BufferedCSVReader::TryCastValue(const Value &value, const LogicalType &sql_
|
|
|
57073
56985
|
if (options.has_format[LogicalTypeId::DATE] && sql_type.id() == LogicalTypeId::DATE) {
|
|
57074
56986
|
date_t result;
|
|
57075
56987
|
string error_message;
|
|
57076
|
-
return options.date_format[LogicalTypeId::DATE].TryParseDate(string_t(value
|
|
56988
|
+
return options.date_format[LogicalTypeId::DATE].TryParseDate(string_t(StringValue::Get(value)), result,
|
|
56989
|
+
error_message);
|
|
57077
56990
|
} else if (options.has_format[LogicalTypeId::TIMESTAMP] && sql_type.id() == LogicalTypeId::TIMESTAMP) {
|
|
57078
56991
|
timestamp_t result;
|
|
57079
56992
|
string error_message;
|
|
57080
|
-
return options.date_format[LogicalTypeId::TIMESTAMP].TryParseTimestamp(string_t(value
|
|
57081
|
-
error_message);
|
|
56993
|
+
return options.date_format[LogicalTypeId::TIMESTAMP].TryParseTimestamp(string_t(StringValue::Get(value)),
|
|
56994
|
+
result, error_message);
|
|
57082
56995
|
} else {
|
|
57083
56996
|
Value new_value;
|
|
57084
56997
|
string error_message;
|
|
@@ -57314,7 +57227,7 @@ void BufferedCSVReader::DetectCandidateTypes(const vector<LogicalType> &type_can
|
|
|
57314
57227
|
// try formatting for date types if the user did not specify one and it starts with numeric values.
|
|
57315
57228
|
string separator;
|
|
57316
57229
|
if (has_format_candidates.count(sql_type.id()) && !original_options.has_format[sql_type.id()] &&
|
|
57317
|
-
StartsWithNumericDate(separator, dummy_val
|
|
57230
|
+
StartsWithNumericDate(separator, StringValue::Get(dummy_val))) {
|
|
57318
57231
|
// generate date format candidates the first time through
|
|
57319
57232
|
auto &type_format_candidates = format_candidates[sql_type.id()];
|
|
57320
57233
|
const auto had_format_candidates = has_format_candidates[sql_type.id()];
|
|
@@ -57343,7 +57256,7 @@ void BufferedCSVReader::DetectCandidateTypes(const vector<LogicalType> &type_can
|
|
|
57343
57256
|
while (!type_format_candidates.empty()) {
|
|
57344
57257
|
// avoid using exceptions for flow control...
|
|
57345
57258
|
auto ¤t_format = options.date_format[sql_type.id()];
|
|
57346
|
-
if (current_format.Parse(dummy_val
|
|
57259
|
+
if (current_format.Parse(StringValue::Get(dummy_val), result)) {
|
|
57347
57260
|
break;
|
|
57348
57261
|
}
|
|
57349
57262
|
// doesn't work - move to the next one
|
|
@@ -57430,7 +57343,7 @@ void BufferedCSVReader::DetectHeader(const vector<vector<LogicalType>> &best_sql
|
|
|
57430
57343
|
first_row_nulls = true;
|
|
57431
57344
|
for (idx_t col = 0; col < best_sql_types_candidates.size(); col++) {
|
|
57432
57345
|
auto dummy_val = best_header_row.GetValue(col, 0);
|
|
57433
|
-
if (!dummy_val.
|
|
57346
|
+
if (!dummy_val.IsNull()) {
|
|
57434
57347
|
first_row_nulls = false;
|
|
57435
57348
|
}
|
|
57436
57349
|
|
|
@@ -57451,7 +57364,7 @@ void BufferedCSVReader::DetectHeader(const vector<vector<LogicalType>> &best_sql
|
|
|
57451
57364
|
string col_name = val.ToString();
|
|
57452
57365
|
|
|
57453
57366
|
// generate name if field is empty
|
|
57454
|
-
if (col_name.empty() || val.
|
|
57367
|
+
if (col_name.empty() || val.IsNull()) {
|
|
57455
57368
|
col_name = GenerateColumnName(options.num_cols, col);
|
|
57456
57369
|
}
|
|
57457
57370
|
|
|
@@ -61573,6 +61486,123 @@ unique_ptr<GlobalSinkState> PhysicalOperator::GetGlobalSinkState(ClientContext &
|
|
|
61573
61486
|
|
|
61574
61487
|
} // namespace duckdb
|
|
61575
61488
|
|
|
61489
|
+
//===----------------------------------------------------------------------===//
|
|
61490
|
+
// DuckDB
|
|
61491
|
+
//
|
|
61492
|
+
// duckdb/common/operator/subtract.hpp
|
|
61493
|
+
//
|
|
61494
|
+
//
|
|
61495
|
+
//===----------------------------------------------------------------------===//
|
|
61496
|
+
|
|
61497
|
+
|
|
61498
|
+
|
|
61499
|
+
|
|
61500
|
+
|
|
61501
|
+
|
|
61502
|
+
namespace duckdb {
|
|
61503
|
+
|
|
61504
|
+
struct SubtractOperator {
|
|
61505
|
+
template <class TA, class TB, class TR>
|
|
61506
|
+
static inline TR Operation(TA left, TB right) {
|
|
61507
|
+
return left - right;
|
|
61508
|
+
}
|
|
61509
|
+
};
|
|
61510
|
+
|
|
61511
|
+
template <>
|
|
61512
|
+
float SubtractOperator::Operation(float left, float right);
|
|
61513
|
+
template <>
|
|
61514
|
+
double SubtractOperator::Operation(double left, double right);
|
|
61515
|
+
template <>
|
|
61516
|
+
interval_t SubtractOperator::Operation(interval_t left, interval_t right);
|
|
61517
|
+
template <>
|
|
61518
|
+
int64_t SubtractOperator::Operation(date_t left, date_t right);
|
|
61519
|
+
template <>
|
|
61520
|
+
date_t SubtractOperator::Operation(date_t left, int32_t right);
|
|
61521
|
+
template <>
|
|
61522
|
+
date_t SubtractOperator::Operation(date_t left, interval_t right);
|
|
61523
|
+
template <>
|
|
61524
|
+
timestamp_t SubtractOperator::Operation(timestamp_t left, interval_t right);
|
|
61525
|
+
template <>
|
|
61526
|
+
interval_t SubtractOperator::Operation(timestamp_t left, timestamp_t right);
|
|
61527
|
+
|
|
61528
|
+
struct TrySubtractOperator {
|
|
61529
|
+
template <class TA, class TB, class TR>
|
|
61530
|
+
static inline bool Operation(TA left, TB right, TR &result) {
|
|
61531
|
+
throw InternalException("Unimplemented type for TrySubtractOperator");
|
|
61532
|
+
}
|
|
61533
|
+
};
|
|
61534
|
+
|
|
61535
|
+
template <>
|
|
61536
|
+
bool TrySubtractOperator::Operation(uint8_t left, uint8_t right, uint8_t &result);
|
|
61537
|
+
template <>
|
|
61538
|
+
bool TrySubtractOperator::Operation(uint16_t left, uint16_t right, uint16_t &result);
|
|
61539
|
+
template <>
|
|
61540
|
+
bool TrySubtractOperator::Operation(uint32_t left, uint32_t right, uint32_t &result);
|
|
61541
|
+
template <>
|
|
61542
|
+
bool TrySubtractOperator::Operation(uint64_t left, uint64_t right, uint64_t &result);
|
|
61543
|
+
|
|
61544
|
+
template <>
|
|
61545
|
+
bool TrySubtractOperator::Operation(int8_t left, int8_t right, int8_t &result);
|
|
61546
|
+
template <>
|
|
61547
|
+
bool TrySubtractOperator::Operation(int16_t left, int16_t right, int16_t &result);
|
|
61548
|
+
template <>
|
|
61549
|
+
bool TrySubtractOperator::Operation(int32_t left, int32_t right, int32_t &result);
|
|
61550
|
+
template <>
|
|
61551
|
+
bool TrySubtractOperator::Operation(int64_t left, int64_t right, int64_t &result);
|
|
61552
|
+
|
|
61553
|
+
struct SubtractOperatorOverflowCheck {
|
|
61554
|
+
template <class TA, class TB, class TR>
|
|
61555
|
+
static inline TR Operation(TA left, TB right) {
|
|
61556
|
+
TR result;
|
|
61557
|
+
if (!TrySubtractOperator::Operation(left, right, result)) {
|
|
61558
|
+
throw OutOfRangeException("Overflow in subtraction of %s (%d - %d)!", TypeIdToString(GetTypeId<TA>()), left,
|
|
61559
|
+
right);
|
|
61560
|
+
}
|
|
61561
|
+
return result;
|
|
61562
|
+
}
|
|
61563
|
+
};
|
|
61564
|
+
|
|
61565
|
+
struct TryDecimalSubtract {
|
|
61566
|
+
template <class TA, class TB, class TR>
|
|
61567
|
+
static inline bool Operation(TA left, TB right, TR &result) {
|
|
61568
|
+
throw InternalException("Unimplemented type for TryDecimalSubtract");
|
|
61569
|
+
}
|
|
61570
|
+
};
|
|
61571
|
+
|
|
61572
|
+
template <>
|
|
61573
|
+
bool TryDecimalSubtract::Operation(int16_t left, int16_t right, int16_t &result);
|
|
61574
|
+
template <>
|
|
61575
|
+
bool TryDecimalSubtract::Operation(int32_t left, int32_t right, int32_t &result);
|
|
61576
|
+
template <>
|
|
61577
|
+
bool TryDecimalSubtract::Operation(int64_t left, int64_t right, int64_t &result);
|
|
61578
|
+
template <>
|
|
61579
|
+
bool TryDecimalSubtract::Operation(hugeint_t left, hugeint_t right, hugeint_t &result);
|
|
61580
|
+
|
|
61581
|
+
struct DecimalSubtractOverflowCheck {
|
|
61582
|
+
template <class TA, class TB, class TR>
|
|
61583
|
+
static inline TR Operation(TA left, TB right) {
|
|
61584
|
+
TR result;
|
|
61585
|
+
if (!TryDecimalSubtract::Operation<TA, TB, TR>(left, right, result)) {
|
|
61586
|
+
throw OutOfRangeException("Overflow in subtract of DECIMAL(18) (%d - %d). You might want to add an "
|
|
61587
|
+
"explicit cast to a bigger decimal.",
|
|
61588
|
+
left, right);
|
|
61589
|
+
}
|
|
61590
|
+
return result;
|
|
61591
|
+
}
|
|
61592
|
+
};
|
|
61593
|
+
|
|
61594
|
+
template <>
|
|
61595
|
+
hugeint_t DecimalSubtractOverflowCheck::Operation(hugeint_t left, hugeint_t right);
|
|
61596
|
+
|
|
61597
|
+
struct SubtractTimeOperator {
|
|
61598
|
+
template <class TA, class TB, class TR>
|
|
61599
|
+
static TR Operation(TA left, TB right);
|
|
61600
|
+
};
|
|
61601
|
+
|
|
61602
|
+
template <>
|
|
61603
|
+
dtime_t SubtractTimeOperator::Operation(dtime_t left, interval_t right);
|
|
61604
|
+
|
|
61605
|
+
} // namespace duckdb
|
|
61576
61606
|
|
|
61577
61607
|
|
|
61578
61608
|
|
|
@@ -61822,7 +61852,7 @@ static bool CanUsePerfectHashAggregate(ClientContext &context, LogicalAggregate
|
|
|
61822
61852
|
}
|
|
61823
61853
|
auto &nstats = (NumericStatistics &)*stats;
|
|
61824
61854
|
|
|
61825
|
-
if (nstats.min.
|
|
61855
|
+
if (nstats.min.IsNull() || nstats.max.IsNull()) {
|
|
61826
61856
|
return false;
|
|
61827
61857
|
}
|
|
61828
61858
|
// we have a min and a max value for the stats: use that to figure out how many bits we have
|
|
@@ -62166,7 +62196,7 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
|
|
|
62166
62196
|
|
|
62167
62197
|
// and when the build range is smaller than the threshold
|
|
62168
62198
|
auto stats_build = reinterpret_cast<NumericStatistics *>(op.join_stats[0].get()); // lhs stats
|
|
62169
|
-
if (stats_build->min.
|
|
62199
|
+
if (stats_build->min.IsNull() || stats_build->max.IsNull()) {
|
|
62170
62200
|
return;
|
|
62171
62201
|
}
|
|
62172
62202
|
int64_t min_value, max_value;
|
|
@@ -62189,7 +62219,7 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
|
|
|
62189
62219
|
join_state.build_max = stats_build->max;
|
|
62190
62220
|
join_state.estimated_cardinality = op.estimated_cardinality;
|
|
62191
62221
|
join_state.build_range = build_range;
|
|
62192
|
-
if (join_state.build_range > MAX_BUILD_SIZE || stats_probe->max.
|
|
62222
|
+
if (join_state.build_range > MAX_BUILD_SIZE || stats_probe->max.IsNull() || stats_probe->min.IsNull()) {
|
|
62193
62223
|
return;
|
|
62194
62224
|
}
|
|
62195
62225
|
if (stats_build->min <= stats_probe->min && stats_probe->max <= stats_build->max) {
|
|
@@ -69346,7 +69376,7 @@ unique_ptr<BaseStatistics> SumPropagateStats(ClientContext &context, BoundAggreg
|
|
|
69346
69376
|
NodeStatistics *node_stats) {
|
|
69347
69377
|
if (child_stats[0] && node_stats && node_stats->has_max_cardinality) {
|
|
69348
69378
|
auto &numeric_stats = (NumericStatistics &)*child_stats[0];
|
|
69349
|
-
if (numeric_stats.min.
|
|
69379
|
+
if (numeric_stats.min.IsNull() || numeric_stats.max.IsNull()) {
|
|
69350
69380
|
return nullptr;
|
|
69351
69381
|
}
|
|
69352
69382
|
auto internal_type = numeric_stats.min.type().InternalType();
|
|
@@ -70328,7 +70358,7 @@ unique_ptr<FunctionData> BindApproxQuantile(ClientContext &context, AggregateFun
|
|
|
70328
70358
|
Value quantile_val = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
70329
70359
|
auto quantile = quantile_val.GetValue<float>();
|
|
70330
70360
|
|
|
70331
|
-
if (quantile_val.
|
|
70361
|
+
if (quantile_val.IsNull() || quantile < 0 || quantile > 1) {
|
|
70332
70362
|
throw BinderException("APPROXIMATE QUANTILE can only take parameters in range [0, 1]");
|
|
70333
70363
|
}
|
|
70334
70364
|
// remove the quantile argument so we can use the unary aggregate
|
|
@@ -71840,7 +71870,7 @@ unique_ptr<FunctionData> BindMedianAbsoluteDeviationDecimal(ClientContext &conte
|
|
|
71840
71870
|
static double CheckQuantile(const Value &quantile_val) {
|
|
71841
71871
|
auto quantile = quantile_val.GetValue<double>();
|
|
71842
71872
|
|
|
71843
|
-
if (quantile_val.
|
|
71873
|
+
if (quantile_val.IsNull() || quantile < 0 || quantile > 1) {
|
|
71844
71874
|
throw BinderException("QUANTILE can only take parameters in the range [0, 1]");
|
|
71845
71875
|
}
|
|
71846
71876
|
|
|
@@ -71857,7 +71887,7 @@ unique_ptr<FunctionData> BindQuantile(ClientContext &context, AggregateFunction
|
|
|
71857
71887
|
if (quantile_val.type().id() != LogicalTypeId::LIST) {
|
|
71858
71888
|
quantiles.push_back(CheckQuantile(quantile_val));
|
|
71859
71889
|
} else {
|
|
71860
|
-
for (const auto &element_val : quantile_val
|
|
71890
|
+
for (const auto &element_val : ListValue::GetChildren(quantile_val)) {
|
|
71861
71891
|
quantiles.push_back(CheckQuantile(element_val));
|
|
71862
71892
|
}
|
|
71863
71893
|
}
|
|
@@ -72192,7 +72222,7 @@ unique_ptr<FunctionData> BindReservoirQuantile(ClientContext &context, Aggregate
|
|
|
72192
72222
|
Value quantile_val = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
72193
72223
|
auto quantile = quantile_val.GetValue<double>();
|
|
72194
72224
|
|
|
72195
|
-
if (quantile_val.
|
|
72225
|
+
if (quantile_val.IsNull() || quantile < 0 || quantile > 1) {
|
|
72196
72226
|
throw BinderException("QUANTILE can only take parameters in range [0, 1]");
|
|
72197
72227
|
}
|
|
72198
72228
|
if (arguments.size() <= 2) {
|
|
@@ -72205,7 +72235,7 @@ unique_ptr<FunctionData> BindReservoirQuantile(ClientContext &context, Aggregate
|
|
|
72205
72235
|
Value sample_size_val = ExpressionExecutor::EvaluateScalar(*arguments[2]);
|
|
72206
72236
|
auto sample_size = sample_size_val.GetValue<int32_t>();
|
|
72207
72237
|
|
|
72208
|
-
if (sample_size_val.
|
|
72238
|
+
if (sample_size_val.IsNull() || sample_size <= 0) {
|
|
72209
72239
|
throw BinderException("Percentage of the sample must be bigger than 0");
|
|
72210
72240
|
}
|
|
72211
72241
|
|
|
@@ -75694,7 +75724,7 @@ static unique_ptr<BaseStatistics> PropagateDatePartStatistics(vector<unique_ptr<
|
|
|
75694
75724
|
return nullptr;
|
|
75695
75725
|
}
|
|
75696
75726
|
auto &nstats = (NumericStatistics &)*child_stats[0];
|
|
75697
|
-
if (nstats.min.
|
|
75727
|
+
if (nstats.min.IsNull() || nstats.max.IsNull()) {
|
|
75698
75728
|
return nullptr;
|
|
75699
75729
|
}
|
|
75700
75730
|
// run the operator on both the min and the max, this gives us the [min, max] bound
|
|
@@ -76793,11 +76823,12 @@ struct StructDatePart {
|
|
|
76793
76823
|
|
|
76794
76824
|
Value parts_list = ExpressionExecutor::EvaluateScalar(*arguments[0]);
|
|
76795
76825
|
if (parts_list.type().id() == LogicalTypeId::LIST) {
|
|
76796
|
-
|
|
76826
|
+
auto &list_children = ListValue::GetChildren(parts_list);
|
|
76827
|
+
if (list_children.empty()) {
|
|
76797
76828
|
throw BinderException("%s requires non-empty lists of part names", bound_function.name);
|
|
76798
76829
|
}
|
|
76799
|
-
for (const auto &part_value :
|
|
76800
|
-
if (part_value.
|
|
76830
|
+
for (const auto &part_value : list_children) {
|
|
76831
|
+
if (part_value.IsNull()) {
|
|
76801
76832
|
throw BinderException("NULL struct entry name in %s", bound_function.name);
|
|
76802
76833
|
}
|
|
76803
76834
|
const auto part_name = part_value.ToString();
|
|
@@ -78593,7 +78624,7 @@ static unique_ptr<FunctionData> StrfTimeBindFunction(ClientContext &context, Sca
|
|
|
78593
78624
|
}
|
|
78594
78625
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
78595
78626
|
StrfTimeFormat format;
|
|
78596
|
-
if (!options_str.
|
|
78627
|
+
if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
78597
78628
|
auto format_string = options_str.GetValue<string>();
|
|
78598
78629
|
string error = StrTimeFormat::ParseFormatSpecifier(format_string, format);
|
|
78599
78630
|
if (!error.empty()) {
|
|
@@ -79102,7 +79133,7 @@ static unique_ptr<FunctionData> StrpTimeBindFunction(ClientContext &context, Sca
|
|
|
79102
79133
|
}
|
|
79103
79134
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
79104
79135
|
StrpTimeFormat format;
|
|
79105
|
-
if (!options_str.
|
|
79136
|
+
if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
79106
79137
|
string format_string = options_str.ToString();
|
|
79107
79138
|
format.format_specifier = format_string;
|
|
79108
79139
|
string error = StrTimeFormat::ParseFormatSpecifier(format_string, format);
|
|
@@ -79415,15 +79446,15 @@ static void EnumRangeBoundaryFunction(DataChunk &input, ExpressionState &state,
|
|
|
79415
79446
|
auto first_param = input.GetValue(0, 0);
|
|
79416
79447
|
auto second_param = input.GetValue(1, 0);
|
|
79417
79448
|
|
|
79418
|
-
auto &enum_vector = first_param.
|
|
79419
|
-
|
|
79449
|
+
auto &enum_vector = first_param.IsNull() ? EnumType::GetValuesInsertOrder(input.GetTypes()[1])
|
|
79450
|
+
: EnumType::GetValuesInsertOrder(input.GetTypes()[0]);
|
|
79420
79451
|
|
|
79421
|
-
if (first_param.
|
|
79452
|
+
if (first_param.IsNull()) {
|
|
79422
79453
|
start = 0;
|
|
79423
79454
|
} else {
|
|
79424
79455
|
start = first_param.GetValue<uint32_t>();
|
|
79425
79456
|
}
|
|
79426
|
-
if (second_param.
|
|
79457
|
+
if (second_param.IsNull()) {
|
|
79427
79458
|
end = EnumType::GetSize(input.GetTypes()[0]);
|
|
79428
79459
|
} else {
|
|
79429
79460
|
end = second_param.GetValue<uint32_t>() + 1;
|
|
@@ -79689,14 +79720,15 @@ unique_ptr<FunctionData> CurrentSettingBind(ClientContext &context, ScalarFuncti
|
|
|
79689
79720
|
}
|
|
79690
79721
|
Value key_val = ExpressionExecutor::EvaluateScalar(*key_child.get());
|
|
79691
79722
|
D_ASSERT(key_val.type().id() == LogicalTypeId::VARCHAR);
|
|
79692
|
-
|
|
79723
|
+
auto &key_str = StringValue::Get(key_val);
|
|
79724
|
+
if (key_val.IsNull() || key_str.empty()) {
|
|
79693
79725
|
throw ParserException("Key name for current_setting needs to be neither NULL nor empty");
|
|
79694
79726
|
}
|
|
79695
79727
|
|
|
79696
|
-
auto key = StringUtil::Lower(
|
|
79728
|
+
auto key = StringUtil::Lower(key_str);
|
|
79697
79729
|
Value val;
|
|
79698
79730
|
if (!context.TryGetCurrentSetting(key, val)) {
|
|
79699
|
-
throw InvalidInputException("unrecognized configuration parameter \"%s\"",
|
|
79731
|
+
throw InvalidInputException("unrecognized configuration parameter \"%s\"", key_str);
|
|
79700
79732
|
}
|
|
79701
79733
|
|
|
79702
79734
|
bound_function.return_type = val.type();
|
|
@@ -81032,13 +81064,14 @@ void FillResult(Value &values, Vector &result, idx_t row) {
|
|
|
81032
81064
|
//! First Initialize List Vector
|
|
81033
81065
|
idx_t current_offset = ListVector::GetListSize(result);
|
|
81034
81066
|
//! Push Values to List Vector
|
|
81035
|
-
|
|
81036
|
-
|
|
81067
|
+
auto &list_values = ListValue::GetChildren(values);
|
|
81068
|
+
for (idx_t i = 0; i < list_values.size(); i++) {
|
|
81069
|
+
ListVector::PushBack(result, list_values[i]);
|
|
81037
81070
|
}
|
|
81038
81071
|
|
|
81039
81072
|
//! now set the pointer
|
|
81040
81073
|
auto &entry = ((list_entry_t *)result.GetData())[row];
|
|
81041
|
-
entry.length =
|
|
81074
|
+
entry.length = list_values.size();
|
|
81042
81075
|
entry.offset = current_offset;
|
|
81043
81076
|
}
|
|
81044
81077
|
|
|
@@ -81757,7 +81790,7 @@ unique_ptr<FunctionData> BindDecimalRoundPrecision(ClientContext &context, Scala
|
|
|
81757
81790
|
throw NotImplementedException("ROUND(DECIMAL, INTEGER) with non-constant precision is not supported");
|
|
81758
81791
|
}
|
|
81759
81792
|
Value val = ExpressionExecutor::EvaluateScalar(*arguments[1]).CastAs(LogicalType::INTEGER);
|
|
81760
|
-
if (val.
|
|
81793
|
+
if (val.IsNull()) {
|
|
81761
81794
|
throw NotImplementedException("ROUND(DECIMAL, INTEGER) with non-constant precision is not supported");
|
|
81762
81795
|
}
|
|
81763
81796
|
// our new precision becomes the round value
|
|
@@ -81765,7 +81798,7 @@ unique_ptr<FunctionData> BindDecimalRoundPrecision(ClientContext &context, Scala
|
|
|
81765
81798
|
// but ONLY if the round value is positive
|
|
81766
81799
|
// if it is negative the scale becomes zero
|
|
81767
81800
|
// i.e. ROUND(DECIMAL(18,3), -1) -> DECIMAL(18,0)
|
|
81768
|
-
int32_t round_value = val
|
|
81801
|
+
int32_t round_value = IntegerValue::Get(val);
|
|
81769
81802
|
uint8_t target_scale;
|
|
81770
81803
|
auto width = DecimalType::GetWidth(decimal_type);
|
|
81771
81804
|
auto scale = DecimalType::GetScale(decimal_type);
|
|
@@ -82764,7 +82797,7 @@ static unique_ptr<BaseStatistics> PropagateNumericStats(ClientContext &context,
|
|
|
82764
82797
|
auto &rstats = (NumericStatistics &)*child_stats[1];
|
|
82765
82798
|
Value new_min, new_max;
|
|
82766
82799
|
bool potential_overflow = true;
|
|
82767
|
-
if (!lstats.min.
|
|
82800
|
+
if (!lstats.min.IsNull() && !lstats.max.IsNull() && !rstats.min.IsNull() && !rstats.max.IsNull()) {
|
|
82768
82801
|
switch (expr.return_type.InternalType()) {
|
|
82769
82802
|
case PhysicalType::INT8:
|
|
82770
82803
|
potential_overflow =
|
|
@@ -82979,11 +83012,16 @@ void AddFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
82979
83012
|
// - [subtract]
|
|
82980
83013
|
//===--------------------------------------------------------------------===//
|
|
82981
83014
|
struct NegateOperator {
|
|
83015
|
+
template <class T>
|
|
83016
|
+
static bool CanNegate(T input) {
|
|
83017
|
+
using Limits = std::numeric_limits<T>;
|
|
83018
|
+
return !(Limits::is_integer && Limits::is_signed && Limits::lowest() == input);
|
|
83019
|
+
}
|
|
83020
|
+
|
|
82982
83021
|
template <class TA, class TR>
|
|
82983
83022
|
static inline TR Operation(TA input) {
|
|
82984
|
-
using Limits = std::numeric_limits<TR>;
|
|
82985
83023
|
auto cast = (TR)input;
|
|
82986
|
-
if (
|
|
83024
|
+
if (!CanNegate<TR>(cast)) {
|
|
82987
83025
|
throw OutOfRangeException("Overflow in negation of integer!");
|
|
82988
83026
|
}
|
|
82989
83027
|
return -cast;
|
|
@@ -83021,11 +83059,17 @@ unique_ptr<FunctionData> DecimalNegateBind(ClientContext &context, ScalarFunctio
|
|
|
83021
83059
|
|
|
83022
83060
|
struct NegatePropagateStatistics {
|
|
83023
83061
|
template <class T>
|
|
83024
|
-
static
|
|
83062
|
+
static bool Operation(LogicalType type, NumericStatistics &istats, Value &new_min, Value &new_max) {
|
|
83063
|
+
auto max_value = istats.max.GetValueUnsafe<T>();
|
|
83064
|
+
auto min_value = istats.min.GetValueUnsafe<T>();
|
|
83065
|
+
if (!NegateOperator::CanNegate<T>(min_value) || !NegateOperator::CanNegate<T>(max_value)) {
|
|
83066
|
+
return true;
|
|
83067
|
+
}
|
|
83025
83068
|
// new min is -max
|
|
83026
|
-
new_min = Value::Numeric(type, NegateOperator::Operation<T, T>(
|
|
83069
|
+
new_min = Value::Numeric(type, NegateOperator::Operation<T, T>(max_value));
|
|
83027
83070
|
// new max is -min
|
|
83028
|
-
new_max = Value::Numeric(type, NegateOperator::Operation<T, T>(
|
|
83071
|
+
new_max = Value::Numeric(type, NegateOperator::Operation<T, T>(min_value));
|
|
83072
|
+
return false;
|
|
83029
83073
|
}
|
|
83030
83074
|
};
|
|
83031
83075
|
|
|
@@ -83039,24 +83083,33 @@ static unique_ptr<BaseStatistics> NegateBindStatistics(ClientContext &context, B
|
|
|
83039
83083
|
}
|
|
83040
83084
|
auto &istats = (NumericStatistics &)*child_stats[0];
|
|
83041
83085
|
Value new_min, new_max;
|
|
83042
|
-
|
|
83086
|
+
bool potential_overflow = true;
|
|
83087
|
+
if (!istats.min.IsNull() && !istats.max.IsNull()) {
|
|
83043
83088
|
switch (expr.return_type.InternalType()) {
|
|
83044
83089
|
case PhysicalType::INT8:
|
|
83045
|
-
|
|
83090
|
+
potential_overflow =
|
|
83091
|
+
NegatePropagateStatistics::Operation<int8_t>(expr.return_type, istats, new_min, new_max);
|
|
83046
83092
|
break;
|
|
83047
83093
|
case PhysicalType::INT16:
|
|
83048
|
-
|
|
83094
|
+
potential_overflow =
|
|
83095
|
+
NegatePropagateStatistics::Operation<int16_t>(expr.return_type, istats, new_min, new_max);
|
|
83049
83096
|
break;
|
|
83050
83097
|
case PhysicalType::INT32:
|
|
83051
|
-
|
|
83098
|
+
potential_overflow =
|
|
83099
|
+
NegatePropagateStatistics::Operation<int32_t>(expr.return_type, istats, new_min, new_max);
|
|
83052
83100
|
break;
|
|
83053
83101
|
case PhysicalType::INT64:
|
|
83054
|
-
|
|
83102
|
+
potential_overflow =
|
|
83103
|
+
NegatePropagateStatistics::Operation<int64_t>(expr.return_type, istats, new_min, new_max);
|
|
83055
83104
|
break;
|
|
83056
83105
|
default:
|
|
83057
83106
|
return nullptr;
|
|
83058
83107
|
}
|
|
83059
83108
|
}
|
|
83109
|
+
if (potential_overflow) {
|
|
83110
|
+
new_min = Value(expr.return_type);
|
|
83111
|
+
new_max = Value(expr.return_type);
|
|
83112
|
+
}
|
|
83060
83113
|
auto stats = make_unique<NumericStatistics>(expr.return_type, move(new_min), move(new_max));
|
|
83061
83114
|
if (istats.validity_stats) {
|
|
83062
83115
|
stats->validity_stats = istats.validity_stats->Copy();
|
|
@@ -84279,10 +84332,10 @@ static unique_ptr<FunctionData> NextValBind(ClientContext &context, ScalarFuncti
|
|
|
84279
84332
|
if (arguments[0]->IsFoldable()) {
|
|
84280
84333
|
// parameter to nextval function is a foldable constant
|
|
84281
84334
|
// evaluate the constant and perform the catalog lookup already
|
|
84282
|
-
|
|
84283
|
-
if (!seqname.
|
|
84335
|
+
auto seqname = ExpressionExecutor::EvaluateScalar(*arguments[0]);
|
|
84336
|
+
if (!seqname.IsNull()) {
|
|
84284
84337
|
D_ASSERT(seqname.type().id() == LogicalTypeId::VARCHAR);
|
|
84285
|
-
auto qname = QualifiedName::Parse(seqname
|
|
84338
|
+
auto qname = QualifiedName::Parse(StringValue::Get(seqname));
|
|
84286
84339
|
sequence = Catalog::GetCatalog(context).GetEntry<SequenceCatalogEntry>(context, qname.schema, qname.name);
|
|
84287
84340
|
}
|
|
84288
84341
|
}
|
|
@@ -87670,7 +87723,7 @@ static inline duckdb_re2::StringPiece CreateStringPiece(string_t &input) {
|
|
|
87670
87723
|
return duckdb_re2::StringPiece(input.GetDataUnsafe(), input.GetSize());
|
|
87671
87724
|
}
|
|
87672
87725
|
|
|
87673
|
-
static void ParseRegexOptions(string &options, duckdb_re2::RE2::Options &result, bool *global_replace = nullptr) {
|
|
87726
|
+
static void ParseRegexOptions(const string &options, duckdb_re2::RE2::Options &result, bool *global_replace = nullptr) {
|
|
87674
87727
|
for (idx_t i = 0; i < options.size(); i++) {
|
|
87675
87728
|
switch (options[i]) {
|
|
87676
87729
|
case 'c':
|
|
@@ -87781,15 +87834,15 @@ static unique_ptr<FunctionData> RegexpMatchesBind(ClientContext &context, Scalar
|
|
|
87781
87834
|
throw InvalidInputException("Regex options field must be a constant");
|
|
87782
87835
|
}
|
|
87783
87836
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[2]);
|
|
87784
|
-
if (!options_str.
|
|
87785
|
-
ParseRegexOptions(options_str
|
|
87837
|
+
if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
87838
|
+
ParseRegexOptions(StringValue::Get(options_str), options);
|
|
87786
87839
|
}
|
|
87787
87840
|
}
|
|
87788
87841
|
|
|
87789
87842
|
if (arguments[1]->IsFoldable()) {
|
|
87790
87843
|
Value pattern_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
87791
|
-
if (!pattern_str.
|
|
87792
|
-
return make_unique<RegexpMatchesBindData>(options, pattern_str
|
|
87844
|
+
if (!pattern_str.IsNull() && pattern_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
87845
|
+
return make_unique<RegexpMatchesBindData>(options, StringValue::Get(pattern_str));
|
|
87793
87846
|
}
|
|
87794
87847
|
}
|
|
87795
87848
|
return make_unique<RegexpMatchesBindData>(options, "");
|
|
@@ -87832,8 +87885,8 @@ static unique_ptr<FunctionData> RegexReplaceBind(ClientContext &context, ScalarF
|
|
|
87832
87885
|
throw InvalidInputException("Regex options field must be a constant");
|
|
87833
87886
|
}
|
|
87834
87887
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[3]);
|
|
87835
|
-
if (!options_str.
|
|
87836
|
-
ParseRegexOptions(options_str
|
|
87888
|
+
if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
87889
|
+
ParseRegexOptions(StringValue::Get(options_str), data->options, &data->global_replace);
|
|
87837
87890
|
}
|
|
87838
87891
|
}
|
|
87839
87892
|
|
|
@@ -87894,8 +87947,8 @@ static unique_ptr<FunctionData> RegexExtractBind(ClientContext &context, ScalarF
|
|
|
87894
87947
|
string pattern = "";
|
|
87895
87948
|
if (constant_pattern) {
|
|
87896
87949
|
Value pattern_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
87897
|
-
if (!pattern_str.
|
|
87898
|
-
pattern = pattern_str
|
|
87950
|
+
if (!pattern_str.IsNull() && pattern_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
87951
|
+
pattern = StringValue::Get(pattern_str);
|
|
87899
87952
|
}
|
|
87900
87953
|
}
|
|
87901
87954
|
|
|
@@ -87905,7 +87958,7 @@ static unique_ptr<FunctionData> RegexExtractBind(ClientContext &context, ScalarF
|
|
|
87905
87958
|
throw InvalidInputException("Group index field field must be a constant!");
|
|
87906
87959
|
}
|
|
87907
87960
|
Value group = ExpressionExecutor::EvaluateScalar(*arguments[2]);
|
|
87908
|
-
if (!group.
|
|
87961
|
+
if (!group.IsNull()) {
|
|
87909
87962
|
auto group_idx = group.GetValue<int32_t>();
|
|
87910
87963
|
if (group_idx < 0 || group_idx > 9) {
|
|
87911
87964
|
throw InvalidInputException("Group index must be between 0 and 9!");
|
|
@@ -89025,10 +89078,11 @@ static unique_ptr<FunctionData> StructExtractBind(ClientContext &context, Scalar
|
|
|
89025
89078
|
}
|
|
89026
89079
|
Value key_val = ExpressionExecutor::EvaluateScalar(*key_child.get());
|
|
89027
89080
|
D_ASSERT(key_val.type().id() == LogicalTypeId::VARCHAR);
|
|
89028
|
-
|
|
89081
|
+
auto &key_str = StringValue::Get(key_val);
|
|
89082
|
+
if (key_val.IsNull() || key_str.empty()) {
|
|
89029
89083
|
throw BinderException("Key name for struct_extract needs to be neither NULL nor empty");
|
|
89030
89084
|
}
|
|
89031
|
-
string key = StringUtil::Lower(
|
|
89085
|
+
string key = StringUtil::Lower(key_str);
|
|
89032
89086
|
|
|
89033
89087
|
LogicalType return_type;
|
|
89034
89088
|
idx_t key_index = 0;
|
|
@@ -89764,16 +89818,12 @@ unique_ptr<FunctionData> ArrowTableFunction::ArrowScanBind(ClientContext &contex
|
|
|
89764
89818
|
vector<LogicalType> &input_table_types,
|
|
89765
89819
|
vector<string> &input_table_names,
|
|
89766
89820
|
vector<LogicalType> &return_types, vector<string> &names) {
|
|
89767
|
-
|
|
89768
|
-
unique_ptr<ArrowArrayStreamWrapper> (*stream_factory_produce)(
|
|
89821
|
+
typedef unique_ptr<ArrowArrayStreamWrapper> (*stream_factory_produce_t)(
|
|
89769
89822
|
uintptr_t stream_factory_ptr,
|
|
89770
89823
|
std::pair<std::unordered_map<idx_t, string>, std::vector<string>> & project_columns,
|
|
89771
|
-
TableFilterCollection * filters)
|
|
89772
|
-
|
|
89773
|
-
|
|
89774
|
-
project_columns,
|
|
89775
|
-
TableFilterCollection * filters)) inputs[1]
|
|
89776
|
-
.GetPointer();
|
|
89824
|
+
TableFilterCollection * filters);
|
|
89825
|
+
auto stream_factory_ptr = inputs[0].GetPointer();
|
|
89826
|
+
auto stream_factory_produce = (stream_factory_produce_t)inputs[1].GetPointer();
|
|
89777
89827
|
auto rows_per_thread = inputs[2].GetValue<uint64_t>();
|
|
89778
89828
|
std::pair<std::unordered_map<idx_t, string>, std::vector<string>> project_columns;
|
|
89779
89829
|
#ifndef DUCKDB_NO_THREADS
|
|
@@ -90897,7 +90947,7 @@ static bool ParseBoolean(vector<Value> &set) {
|
|
|
90897
90947
|
set[0].type().id() == LogicalTypeId::DECIMAL) {
|
|
90898
90948
|
throw BinderException("Expected a boolean value (e.g. TRUE or 1)");
|
|
90899
90949
|
}
|
|
90900
|
-
return set[0].CastAs(LogicalType::BOOLEAN)
|
|
90950
|
+
return BooleanValue::Get(set[0].CastAs(LogicalType::BOOLEAN));
|
|
90901
90951
|
}
|
|
90902
90952
|
|
|
90903
90953
|
static string ParseString(vector<Value> &set) {
|
|
@@ -91430,7 +91480,7 @@ static unique_ptr<FunctionData> GlobFunctionBind(ClientContext &context, vector<
|
|
|
91430
91480
|
}
|
|
91431
91481
|
auto result = make_unique<GlobFunctionBindData>();
|
|
91432
91482
|
auto &fs = FileSystem::GetFileSystem(context);
|
|
91433
|
-
result->files = fs.Glob(inputs[0]
|
|
91483
|
+
result->files = fs.Glob(StringValue::Get(inputs[0]));
|
|
91434
91484
|
return_types.emplace_back(LogicalType::VARCHAR);
|
|
91435
91485
|
names.emplace_back("file");
|
|
91436
91486
|
return move(result);
|
|
@@ -92148,7 +92198,7 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
92148
92198
|
auto result = make_unique<ReadCSVData>();
|
|
92149
92199
|
auto &options = result->options;
|
|
92150
92200
|
|
|
92151
|
-
|
|
92201
|
+
auto &file_pattern = StringValue::Get(inputs[0]);
|
|
92152
92202
|
|
|
92153
92203
|
auto &fs = FileSystem::GetFileSystem(context);
|
|
92154
92204
|
result->files = fs.Glob(file_pattern);
|
|
@@ -92158,20 +92208,20 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
92158
92208
|
|
|
92159
92209
|
for (auto &kv : named_parameters) {
|
|
92160
92210
|
if (kv.first == "auto_detect") {
|
|
92161
|
-
options.auto_detect = kv.second
|
|
92211
|
+
options.auto_detect = BooleanValue::Get(kv.second);
|
|
92162
92212
|
} else if (kv.first == "sep" || kv.first == "delim") {
|
|
92163
|
-
options.SetDelimiter(kv.second
|
|
92213
|
+
options.SetDelimiter(StringValue::Get(kv.second));
|
|
92164
92214
|
} else if (kv.first == "header") {
|
|
92165
|
-
options.header = kv.second
|
|
92215
|
+
options.header = BooleanValue::Get(kv.second);
|
|
92166
92216
|
options.has_header = true;
|
|
92167
92217
|
} else if (kv.first == "quote") {
|
|
92168
|
-
options.quote = kv.second
|
|
92218
|
+
options.quote = StringValue::Get(kv.second);
|
|
92169
92219
|
options.has_quote = true;
|
|
92170
92220
|
} else if (kv.first == "escape") {
|
|
92171
|
-
options.escape = kv.second
|
|
92221
|
+
options.escape = StringValue::Get(kv.second);
|
|
92172
92222
|
options.has_escape = true;
|
|
92173
92223
|
} else if (kv.first == "nullstr") {
|
|
92174
|
-
options.null_str = kv.second
|
|
92224
|
+
options.null_str = StringValue::Get(kv.second);
|
|
92175
92225
|
} else if (kv.first == "sample_size") {
|
|
92176
92226
|
int64_t sample_size = kv.second.GetValue<int64_t>();
|
|
92177
92227
|
if (sample_size < 1 && sample_size != -1) {
|
|
@@ -92202,11 +92252,11 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
92202
92252
|
throw BinderException("Unsupported parameter for SAMPLE_CHUNKS: cannot be smaller than 1");
|
|
92203
92253
|
}
|
|
92204
92254
|
} else if (kv.first == "all_varchar") {
|
|
92205
|
-
options.all_varchar = kv.second
|
|
92255
|
+
options.all_varchar = BooleanValue::Get(kv.second);
|
|
92206
92256
|
} else if (kv.first == "dateformat") {
|
|
92207
92257
|
options.has_format[LogicalTypeId::DATE] = true;
|
|
92208
92258
|
auto &date_format = options.date_format[LogicalTypeId::DATE];
|
|
92209
|
-
date_format.format_specifier = kv.second
|
|
92259
|
+
date_format.format_specifier = StringValue::Get(kv.second);
|
|
92210
92260
|
string error = StrTimeFormat::ParseFormatSpecifier(date_format.format_specifier, date_format);
|
|
92211
92261
|
if (!error.empty()) {
|
|
92212
92262
|
throw InvalidInputException("Could not parse DATEFORMAT: %s", error.c_str());
|
|
@@ -92214,35 +92264,36 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
92214
92264
|
} else if (kv.first == "timestampformat") {
|
|
92215
92265
|
options.has_format[LogicalTypeId::TIMESTAMP] = true;
|
|
92216
92266
|
auto ×tamp_format = options.date_format[LogicalTypeId::TIMESTAMP];
|
|
92217
|
-
timestamp_format.format_specifier = kv.second
|
|
92267
|
+
timestamp_format.format_specifier = StringValue::Get(kv.second);
|
|
92218
92268
|
string error = StrTimeFormat::ParseFormatSpecifier(timestamp_format.format_specifier, timestamp_format);
|
|
92219
92269
|
if (!error.empty()) {
|
|
92220
92270
|
throw InvalidInputException("Could not parse TIMESTAMPFORMAT: %s", error.c_str());
|
|
92221
92271
|
}
|
|
92222
92272
|
} else if (kv.first == "normalize_names") {
|
|
92223
|
-
options.normalize_names = kv.second
|
|
92273
|
+
options.normalize_names = BooleanValue::Get(kv.second);
|
|
92224
92274
|
} else if (kv.first == "columns") {
|
|
92225
92275
|
auto &child_type = kv.second.type();
|
|
92226
92276
|
if (child_type.id() != LogicalTypeId::STRUCT) {
|
|
92227
92277
|
throw BinderException("read_csv columns requires a a struct as input");
|
|
92228
92278
|
}
|
|
92229
|
-
|
|
92230
|
-
|
|
92279
|
+
auto &struct_children = StructValue::GetChildren(kv.second);
|
|
92280
|
+
D_ASSERT(StructType::GetChildCount(child_type) == struct_children.size());
|
|
92281
|
+
for (idx_t i = 0; i < struct_children.size(); i++) {
|
|
92231
92282
|
auto &name = StructType::GetChildName(child_type, i);
|
|
92232
|
-
auto &val =
|
|
92283
|
+
auto &val = struct_children[i];
|
|
92233
92284
|
names.push_back(name);
|
|
92234
92285
|
if (val.type().id() != LogicalTypeId::VARCHAR) {
|
|
92235
92286
|
throw BinderException("read_csv requires a type specification as string");
|
|
92236
92287
|
}
|
|
92237
|
-
return_types.emplace_back(TransformStringToLogicalType(val
|
|
92288
|
+
return_types.emplace_back(TransformStringToLogicalType(StringValue::Get(val)));
|
|
92238
92289
|
}
|
|
92239
92290
|
if (names.empty()) {
|
|
92240
92291
|
throw BinderException("read_csv requires at least a single column as input!");
|
|
92241
92292
|
}
|
|
92242
92293
|
} else if (kv.first == "compression") {
|
|
92243
|
-
options.compression = FileCompressionTypeFromString(kv.second
|
|
92294
|
+
options.compression = FileCompressionTypeFromString(StringValue::Get(kv.second));
|
|
92244
92295
|
} else if (kv.first == "filename") {
|
|
92245
|
-
result->include_file_name = kv.second
|
|
92296
|
+
result->include_file_name = BooleanValue::Get(kv.second);
|
|
92246
92297
|
} else if (kv.first == "skip") {
|
|
92247
92298
|
options.skip_rows = kv.second.GetValue<int64_t>();
|
|
92248
92299
|
}
|
|
@@ -95157,7 +95208,7 @@ static vector<TestType> GetTestTypes() {
|
|
|
95157
95208
|
result.emplace_back(LogicalType::DOUBLE, "double");
|
|
95158
95209
|
result.emplace_back(LogicalType::DECIMAL(4, 1), "dec_4_1");
|
|
95159
95210
|
result.emplace_back(LogicalType::DECIMAL(9, 4), "dec_9_4");
|
|
95160
|
-
result.emplace_back(LogicalType::DECIMAL(18, 6), "
|
|
95211
|
+
result.emplace_back(LogicalType::DECIMAL(18, 6), "dec_18_6");
|
|
95161
95212
|
result.emplace_back(LogicalType::DECIMAL(38, 10), "dec38_10");
|
|
95162
95213
|
result.emplace_back(LogicalType::UUID, "uuid");
|
|
95163
95214
|
// interval
|
|
@@ -95724,23 +95775,23 @@ void TableScanPushdownComplexFilter(ClientContext &context, LogicalGet &get, Fun
|
|
|
95724
95775
|
break;
|
|
95725
95776
|
}
|
|
95726
95777
|
}
|
|
95727
|
-
if (!equal_value.
|
|
95778
|
+
if (!equal_value.IsNull() || !low_value.IsNull() || !high_value.IsNull()) {
|
|
95728
95779
|
// we can scan this index using this predicate: try a scan
|
|
95729
95780
|
auto &transaction = Transaction::GetTransaction(context);
|
|
95730
95781
|
unique_ptr<IndexScanState> index_state;
|
|
95731
|
-
if (!equal_value.
|
|
95782
|
+
if (!equal_value.IsNull()) {
|
|
95732
95783
|
// equality predicate
|
|
95733
95784
|
index_state =
|
|
95734
95785
|
index.InitializeScanSinglePredicate(transaction, equal_value, ExpressionType::COMPARE_EQUAL);
|
|
95735
|
-
} else if (!low_value.
|
|
95786
|
+
} else if (!low_value.IsNull() && !high_value.IsNull()) {
|
|
95736
95787
|
// two-sided predicate
|
|
95737
95788
|
index_state = index.InitializeScanTwoPredicates(transaction, low_value, low_comparison_type, high_value,
|
|
95738
95789
|
high_comparison_type);
|
|
95739
|
-
} else if (!low_value.
|
|
95790
|
+
} else if (!low_value.IsNull()) {
|
|
95740
95791
|
// less than predicate
|
|
95741
95792
|
index_state = index.InitializeScanSinglePredicate(transaction, low_value, low_comparison_type);
|
|
95742
95793
|
} else {
|
|
95743
|
-
D_ASSERT(!high_value.
|
|
95794
|
+
D_ASSERT(!high_value.IsNull());
|
|
95744
95795
|
index_state = index.InitializeScanSinglePredicate(transaction, high_value, high_comparison_type);
|
|
95745
95796
|
}
|
|
95746
95797
|
if (index.Scan(transaction, storage, *index_state, STANDARD_VECTOR_SIZE, bind_data.result_ids)) {
|
|
@@ -95833,7 +95884,7 @@ static void UnnestFunction(ClientContext &context, const FunctionData *bind_data
|
|
|
95833
95884
|
auto &bind_data = (UnnestFunctionData &)*bind_data_p;
|
|
95834
95885
|
auto &state = (UnnestOperatorData &)*operator_state;
|
|
95835
95886
|
|
|
95836
|
-
auto &list_value = bind_data.value
|
|
95887
|
+
auto &list_value = ListValue::GetChildren(bind_data.value);
|
|
95837
95888
|
idx_t count = 0;
|
|
95838
95889
|
for (; state.current_count < list_value.size() && count < STANDARD_VECTOR_SIZE; state.current_count++) {
|
|
95839
95890
|
output.data[0].SetValue(count, list_value[state.current_count]);
|
|
@@ -96604,7 +96655,7 @@ idx_t duckdb_arrow_rows_changed(duckdb_arrow result) {
|
|
|
96604
96655
|
idx_t row_count = wrapper->result->collection.Count();
|
|
96605
96656
|
if (row_count > 0 && StatementTypeReturnChanges(wrapper->result->statement_type)) {
|
|
96606
96657
|
auto row_changes = wrapper->result->GetValue(0, 0);
|
|
96607
|
-
if (!row_changes.
|
|
96658
|
+
if (!row_changes.IsNull() && row_changes.TryCastAs(LogicalType::BIGINT)) {
|
|
96608
96659
|
rows_changed = row_changes.GetValue<int64_t>();
|
|
96609
96660
|
}
|
|
96610
96661
|
}
|
|
@@ -97202,7 +97253,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97202
97253
|
if (out->__deprecated_row_count > 0 && StatementTypeReturnChanges(result->statement_type)) {
|
|
97203
97254
|
// update total changes
|
|
97204
97255
|
auto row_changes = result->GetValue(0, 0);
|
|
97205
|
-
if (!row_changes.
|
|
97256
|
+
if (!row_changes.IsNull() && row_changes.TryCastAs(LogicalType::BIGINT)) {
|
|
97206
97257
|
out->__deprecated_rows_changed = row_changes.GetValue<int64_t>();
|
|
97207
97258
|
}
|
|
97208
97259
|
}
|
|
@@ -108340,7 +108391,7 @@ string MaterializedQueryResult::ToString() {
|
|
|
108340
108391
|
for (idx_t j = 0; j < collection.Count(); j++) {
|
|
108341
108392
|
for (idx_t i = 0; i < collection.ColumnCount(); i++) {
|
|
108342
108393
|
auto val = collection.GetValue(i, j);
|
|
108343
|
-
result += val.
|
|
108394
|
+
result += val.IsNull() ? "NULL" : val.ToString();
|
|
108344
108395
|
result += "\t";
|
|
108345
108396
|
}
|
|
108346
108397
|
result += "\n";
|
|
@@ -113972,7 +114023,7 @@ bool FilterCombiner::HasFilters() {
|
|
|
113972
114023
|
// break;
|
|
113973
114024
|
// } else {
|
|
113974
114025
|
// auto &const_value_expr = (BoundConstantExpression &)*comp_in_exp.children[i].get();
|
|
113975
|
-
// if (const_value_expr.value.
|
|
114026
|
+
// if (const_value_expr.value.IsNull()) {
|
|
113976
114027
|
// return checks;
|
|
113977
114028
|
// }
|
|
113978
114029
|
// if (!min && !max) {
|
|
@@ -114134,18 +114185,16 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114134
114185
|
//! This is a like function.
|
|
114135
114186
|
auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get();
|
|
114136
114187
|
auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get();
|
|
114137
|
-
|
|
114188
|
+
auto like_string = StringValue::Get(constant_value_expr.value);
|
|
114138
114189
|
if (like_string.empty()) {
|
|
114139
114190
|
continue;
|
|
114140
114191
|
}
|
|
114141
114192
|
auto column_index = column_ids[column_ref.binding.column_index];
|
|
114142
|
-
auto const_value = constant_value_expr.value.Copy();
|
|
114143
|
-
const_value.str_value = like_string;
|
|
114144
114193
|
//! Here the like must be transformed to a BOUND COMPARISON geq le
|
|
114145
114194
|
auto lower_bound =
|
|
114146
|
-
make_unique<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO,
|
|
114147
|
-
|
|
114148
|
-
auto upper_bound = make_unique<ConstantFilter>(ExpressionType::COMPARE_LESSTHAN,
|
|
114195
|
+
make_unique<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO, Value(like_string));
|
|
114196
|
+
like_string[like_string.size() - 1]++;
|
|
114197
|
+
auto upper_bound = make_unique<ConstantFilter>(ExpressionType::COMPARE_LESSTHAN, Value(like_string));
|
|
114149
114198
|
table_filters.PushFilter(column_index, move(lower_bound));
|
|
114150
114199
|
table_filters.PushFilter(column_index, move(upper_bound));
|
|
114151
114200
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
@@ -114155,8 +114204,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114155
114204
|
//! This is a like function.
|
|
114156
114205
|
auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get();
|
|
114157
114206
|
auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get();
|
|
114158
|
-
|
|
114159
|
-
auto const_value = constant_value_expr.value.Copy();
|
|
114207
|
+
auto &like_string = StringValue::Get(constant_value_expr.value);
|
|
114160
114208
|
if (like_string[0] == '%' || like_string[0] == '_') {
|
|
114161
114209
|
//! We have no prefix so nothing to pushdown
|
|
114162
114210
|
break;
|
|
@@ -114170,19 +114218,18 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114170
114218
|
}
|
|
114171
114219
|
prefix += c;
|
|
114172
114220
|
}
|
|
114173
|
-
const_value.str_value = prefix;
|
|
114174
114221
|
auto column_index = column_ids[column_ref.binding.column_index];
|
|
114175
114222
|
if (equality) {
|
|
114176
114223
|
//! Here the like can be transformed to an equality query
|
|
114177
|
-
auto equal_filter = make_unique<ConstantFilter>(ExpressionType::COMPARE_EQUAL,
|
|
114224
|
+
auto equal_filter = make_unique<ConstantFilter>(ExpressionType::COMPARE_EQUAL, Value(prefix));
|
|
114178
114225
|
table_filters.PushFilter(column_index, move(equal_filter));
|
|
114179
114226
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
114180
114227
|
} else {
|
|
114181
114228
|
//! Here the like must be transformed to a BOUND COMPARISON geq le
|
|
114182
114229
|
auto lower_bound =
|
|
114183
|
-
make_unique<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO,
|
|
114184
|
-
|
|
114185
|
-
auto upper_bound = make_unique<ConstantFilter>(ExpressionType::COMPARE_LESSTHAN,
|
|
114230
|
+
make_unique<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO, Value(prefix));
|
|
114231
|
+
prefix[prefix.size() - 1]++;
|
|
114232
|
+
auto upper_bound = make_unique<ConstantFilter>(ExpressionType::COMPARE_LESSTHAN, Value(prefix));
|
|
114186
114233
|
table_filters.PushFilter(column_index, move(lower_bound));
|
|
114187
114234
|
table_filters.PushFilter(column_index, move(upper_bound));
|
|
114188
114235
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
@@ -114190,7 +114237,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114190
114237
|
}
|
|
114191
114238
|
} else if (remaining_filter->type == ExpressionType::COMPARE_IN) {
|
|
114192
114239
|
auto &func = (BoundOperatorExpression &)*remaining_filter;
|
|
114193
|
-
vector<
|
|
114240
|
+
vector<hugeint_t> in_values;
|
|
114194
114241
|
D_ASSERT(func.children.size() > 1);
|
|
114195
114242
|
if (func.children[0]->expression_class != ExpressionClass::BOUND_COLUMN_REF) {
|
|
114196
114243
|
continue;
|
|
@@ -114211,31 +114258,31 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114211
114258
|
continue;
|
|
114212
114259
|
}
|
|
114213
114260
|
auto &fst_const_value_expr = (BoundConstantExpression &)*func.children[1].get();
|
|
114261
|
+
auto &type = fst_const_value_expr.value.type();
|
|
114214
114262
|
|
|
114215
114263
|
//! Check if values are consecutive, if yes transform them to >= <= (only for integers)
|
|
114216
114264
|
// e.g. if we have x IN (1, 2, 3, 4, 5) we transform this into x >= 1 AND x <= 5
|
|
114217
|
-
if (!
|
|
114265
|
+
if (!type.IsIntegral()) {
|
|
114218
114266
|
continue;
|
|
114219
114267
|
}
|
|
114220
114268
|
|
|
114221
114269
|
bool can_simplify_in_clause = true;
|
|
114222
114270
|
for (idx_t i = 1; i < func.children.size(); i++) {
|
|
114223
114271
|
auto &const_value_expr = (BoundConstantExpression &)*func.children[i].get();
|
|
114224
|
-
if (const_value_expr.value.
|
|
114272
|
+
if (const_value_expr.value.IsNull()) {
|
|
114225
114273
|
can_simplify_in_clause = false;
|
|
114226
114274
|
break;
|
|
114227
114275
|
}
|
|
114228
|
-
in_values.push_back(const_value_expr.value);
|
|
114276
|
+
in_values.push_back(const_value_expr.value.GetValue<hugeint_t>());
|
|
114229
114277
|
}
|
|
114230
114278
|
if (!can_simplify_in_clause || in_values.empty()) {
|
|
114231
114279
|
continue;
|
|
114232
114280
|
}
|
|
114233
|
-
Value one(1);
|
|
114234
114281
|
|
|
114235
114282
|
sort(in_values.begin(), in_values.end());
|
|
114236
114283
|
|
|
114237
114284
|
for (idx_t in_val_idx = 1; in_val_idx < in_values.size(); in_val_idx++) {
|
|
114238
|
-
if (in_values[in_val_idx] - in_values[in_val_idx - 1] >
|
|
114285
|
+
if (in_values[in_val_idx] - in_values[in_val_idx - 1] > 1) {
|
|
114239
114286
|
can_simplify_in_clause = false;
|
|
114240
114287
|
break;
|
|
114241
114288
|
}
|
|
@@ -114243,9 +114290,10 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114243
114290
|
if (!can_simplify_in_clause) {
|
|
114244
114291
|
continue;
|
|
114245
114292
|
}
|
|
114246
|
-
auto lower_bound =
|
|
114247
|
-
|
|
114248
|
-
auto upper_bound = make_unique<ConstantFilter>(ExpressionType::COMPARE_LESSTHANOREQUALTO,
|
|
114293
|
+
auto lower_bound = make_unique<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO,
|
|
114294
|
+
Value::Numeric(type, in_values.front()));
|
|
114295
|
+
auto upper_bound = make_unique<ConstantFilter>(ExpressionType::COMPARE_LESSTHANOREQUALTO,
|
|
114296
|
+
Value::Numeric(type, in_values.back()));
|
|
114249
114297
|
table_filters.PushFilter(column_index, move(lower_bound));
|
|
114250
114298
|
table_filters.PushFilter(column_index, move(upper_bound));
|
|
114251
114299
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
@@ -114286,7 +114334,7 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
|
|
|
114286
114334
|
idx_t equivalence_set = GetEquivalenceSet(node);
|
|
114287
114335
|
auto scalar = left_is_scalar ? comparison.left.get() : comparison.right.get();
|
|
114288
114336
|
auto constant_value = ExpressionExecutor::EvaluateScalar(*scalar);
|
|
114289
|
-
if (constant_value.
|
|
114337
|
+
if (constant_value.IsNull()) {
|
|
114290
114338
|
// comparisons with null are always null (i.e. will never result in rows)
|
|
114291
114339
|
return FilterResult::UNSATISFIABLE;
|
|
114292
114340
|
}
|
|
@@ -114368,7 +114416,7 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) {
|
|
|
114368
114416
|
// scalar condition, evaluate it
|
|
114369
114417
|
auto result = ExpressionExecutor::EvaluateScalar(*expr).CastAs(LogicalType::BOOLEAN);
|
|
114370
114418
|
// check if the filter passes
|
|
114371
|
-
if (result.
|
|
114419
|
+
if (result.IsNull() || !BooleanValue::Get(result)) {
|
|
114372
114420
|
// the filter does not pass the scalar test, create an empty result
|
|
114373
114421
|
return FilterResult::UNSATISFIABLE;
|
|
114374
114422
|
} else {
|
|
@@ -117995,7 +118043,7 @@ static bool FilterRemovesNull(ExpressionRewriter &rewriter, Expression *expr, un
|
|
|
117995
118043
|
// if the result of the expression with all expressions replaced with NULL is "NULL" or "false"
|
|
117996
118044
|
// then any extra entries generated by the LEFT OUTER JOIN will be filtered out!
|
|
117997
118045
|
// hence the LEFT OUTER JOIN is equivalent to an inner join
|
|
117998
|
-
if (val.
|
|
118046
|
+
if (val.IsNull() || !BooleanValue::Get(val)) {
|
|
117999
118047
|
return true;
|
|
118000
118048
|
}
|
|
118001
118049
|
}
|
|
@@ -118683,7 +118731,7 @@ unique_ptr<Expression> ArithmeticSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118683
118731
|
D_ASSERT(root->children.size() == 2);
|
|
118684
118732
|
(void)root;
|
|
118685
118733
|
// any arithmetic operator involving NULL is always NULL
|
|
118686
|
-
if (constant->value.
|
|
118734
|
+
if (constant->value.IsNull()) {
|
|
118687
118735
|
return make_unique<BoundConstantExpression>(Value(root->return_type));
|
|
118688
118736
|
}
|
|
118689
118737
|
auto &func_name = root->function.name;
|
|
@@ -118748,7 +118796,7 @@ unique_ptr<Expression> CaseSimplificationRule::Apply(LogicalOperator &op, vector
|
|
|
118748
118796
|
|
|
118749
118797
|
// fold based on the constant condition
|
|
118750
118798
|
auto condition = constant_value.CastAs(LogicalType::BOOLEAN);
|
|
118751
|
-
if (condition.
|
|
118799
|
+
if (condition.IsNull() || !BooleanValue::Get(condition)) {
|
|
118752
118800
|
// the condition is always false: remove this case check
|
|
118753
118801
|
root->case_checks.erase(root->case_checks.begin() + i);
|
|
118754
118802
|
i--;
|
|
@@ -118800,8 +118848,8 @@ unique_ptr<Expression> ComparisonSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118800
118848
|
if (!ExpressionExecutor::TryEvaluateScalar(*constant_expr, constant_value)) {
|
|
118801
118849
|
return nullptr;
|
|
118802
118850
|
}
|
|
118803
|
-
if (constant_value.
|
|
118804
|
-
|
|
118851
|
+
if (constant_value.IsNull() && !(expr->type == ExpressionType::COMPARE_NOT_DISTINCT_FROM ||
|
|
118852
|
+
expr->type == ExpressionType::COMPARE_DISTINCT_FROM)) {
|
|
118805
118853
|
// comparison with constant NULL, return NULL
|
|
118806
118854
|
return make_unique<BoundConstantExpression>(Value(LogicalType::BOOLEAN));
|
|
118807
118855
|
}
|
|
@@ -118874,12 +118922,12 @@ unique_ptr<Expression> ConjunctionSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118874
118922
|
return nullptr;
|
|
118875
118923
|
}
|
|
118876
118924
|
constant_value = constant_value.CastAs(LogicalType::BOOLEAN);
|
|
118877
|
-
if (constant_value.
|
|
118925
|
+
if (constant_value.IsNull()) {
|
|
118878
118926
|
// we can't simplify conjunctions with a constant NULL
|
|
118879
118927
|
return nullptr;
|
|
118880
118928
|
}
|
|
118881
118929
|
if (conjunction->type == ExpressionType::CONJUNCTION_AND) {
|
|
118882
|
-
if (!constant_value
|
|
118930
|
+
if (!BooleanValue::Get(constant_value)) {
|
|
118883
118931
|
// FALSE in AND, result of expression is false
|
|
118884
118932
|
return make_unique<BoundConstantExpression>(Value::BOOLEAN(false));
|
|
118885
118933
|
} else {
|
|
@@ -118888,7 +118936,7 @@ unique_ptr<Expression> ConjunctionSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118888
118936
|
}
|
|
118889
118937
|
} else {
|
|
118890
118938
|
D_ASSERT(conjunction->type == ExpressionType::CONJUNCTION_OR);
|
|
118891
|
-
if (!constant_value
|
|
118939
|
+
if (!BooleanValue::Get(constant_value)) {
|
|
118892
118940
|
// FALSE in OR, remove the expression from the set
|
|
118893
118941
|
return RemoveExpression(*conjunction, constant_expr);
|
|
118894
118942
|
} else {
|
|
@@ -118932,7 +118980,6 @@ unique_ptr<Expression> ConstantFoldingRule::Apply(LogicalOperator &op, vector<Ex
|
|
|
118932
118980
|
D_ASSERT(root->IsFoldable() && root->type != ExpressionType::VALUE_CONSTANT);
|
|
118933
118981
|
|
|
118934
118982
|
// use an ExpressionExecutor to execute the expression
|
|
118935
|
-
|
|
118936
118983
|
Value result_value;
|
|
118937
118984
|
if (!ExpressionExecutor::TryEvaluateScalar(*root, result_value)) {
|
|
118938
118985
|
return nullptr;
|
|
@@ -118970,12 +119017,12 @@ unique_ptr<Expression> DatePartSimplificationRule::Apply(LogicalOperator &op, ve
|
|
|
118970
119017
|
auto &constant_expr = (BoundConstantExpression &)*bindings[1];
|
|
118971
119018
|
auto &constant = constant_expr.value;
|
|
118972
119019
|
|
|
118973
|
-
if (constant.
|
|
119020
|
+
if (constant.IsNull()) {
|
|
118974
119021
|
// NULL specifier: return constant NULL
|
|
118975
119022
|
return make_unique<BoundConstantExpression>(Value(date_part.return_type));
|
|
118976
119023
|
}
|
|
118977
119024
|
// otherwise check the specifier
|
|
118978
|
-
auto specifier = GetDatePartSpecifier(constant
|
|
119025
|
+
auto specifier = GetDatePartSpecifier(StringValue::Get(constant));
|
|
118979
119026
|
string new_function_name;
|
|
118980
119027
|
switch (specifier) {
|
|
118981
119028
|
case DatePartSpecifier::YEAR:
|
|
@@ -119222,12 +119269,12 @@ unique_ptr<Expression> EmptyNeedleRemovalRule::Apply(LogicalOperator &op, vector
|
|
|
119222
119269
|
|
|
119223
119270
|
auto prefix_value = ExpressionExecutor::EvaluateScalar(*prefix_expr);
|
|
119224
119271
|
|
|
119225
|
-
if (prefix_value.
|
|
119272
|
+
if (prefix_value.IsNull()) {
|
|
119226
119273
|
return make_unique<BoundConstantExpression>(Value(LogicalType::BOOLEAN));
|
|
119227
119274
|
}
|
|
119228
119275
|
|
|
119229
119276
|
D_ASSERT(prefix_value.type() == prefix_expr->return_type);
|
|
119230
|
-
auto needle_string = prefix_value
|
|
119277
|
+
auto &needle_string = StringValue::Get(prefix_value);
|
|
119231
119278
|
|
|
119232
119279
|
// PREFIX('xyz', '') is TRUE
|
|
119233
119280
|
// PREFIX(NULL, '') is NULL
|
|
@@ -119504,7 +119551,7 @@ unique_ptr<Expression> LikeOptimizationRule::Apply(LogicalOperator &op, vector<E
|
|
|
119504
119551
|
auto constant_expr = (BoundConstantExpression *)bindings[2];
|
|
119505
119552
|
D_ASSERT(root->children.size() == 2);
|
|
119506
119553
|
|
|
119507
|
-
if (constant_expr->value.
|
|
119554
|
+
if (constant_expr->value.IsNull()) {
|
|
119508
119555
|
return make_unique<BoundConstantExpression>(Value(root->return_type));
|
|
119509
119556
|
}
|
|
119510
119557
|
|
|
@@ -119515,7 +119562,7 @@ unique_ptr<Expression> LikeOptimizationRule::Apply(LogicalOperator &op, vector<E
|
|
|
119515
119562
|
|
|
119516
119563
|
auto constant_value = ExpressionExecutor::EvaluateScalar(*constant_expr);
|
|
119517
119564
|
D_ASSERT(constant_value.type() == constant_expr->return_type);
|
|
119518
|
-
auto patt_str = constant_value
|
|
119565
|
+
auto &patt_str = StringValue::Get(constant_value);
|
|
119519
119566
|
|
|
119520
119567
|
bool is_not_like = root->function.name == "!~~";
|
|
119521
119568
|
if (PatternIsConstant(patt_str)) {
|
|
@@ -119567,6 +119614,7 @@ unique_ptr<Expression> LikeOptimizationRule::ApplyRule(BoundFunctionExpression *
|
|
|
119567
119614
|
|
|
119568
119615
|
|
|
119569
119616
|
|
|
119617
|
+
|
|
119570
119618
|
namespace duckdb {
|
|
119571
119619
|
|
|
119572
119620
|
MoveConstantsRule::MoveConstantsRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
|
|
@@ -119594,31 +119642,63 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
|
119594
119642
|
auto outer_constant = (BoundConstantExpression *)bindings[1];
|
|
119595
119643
|
auto arithmetic = (BoundFunctionExpression *)bindings[2];
|
|
119596
119644
|
auto inner_constant = (BoundConstantExpression *)bindings[3];
|
|
119597
|
-
if (!arithmetic->return_type.
|
|
119645
|
+
if (!TypeIsIntegral(arithmetic->return_type.InternalType())) {
|
|
119598
119646
|
return nullptr;
|
|
119599
119647
|
}
|
|
119600
|
-
if (inner_constant->value.
|
|
119648
|
+
if (inner_constant->value.IsNull() || outer_constant->value.IsNull()) {
|
|
119601
119649
|
return make_unique<BoundConstantExpression>(Value(comparison->return_type));
|
|
119602
119650
|
}
|
|
119651
|
+
auto &constant_type = outer_constant->return_type;
|
|
119652
|
+
hugeint_t outer_value = IntegralValue::Get(outer_constant->value);
|
|
119653
|
+
hugeint_t inner_value = IntegralValue::Get(inner_constant->value);
|
|
119603
119654
|
|
|
119604
|
-
|
|
119655
|
+
idx_t arithmetic_child_index = arithmetic->children[0].get() == inner_constant ? 1 : 0;
|
|
119605
119656
|
auto &op_type = arithmetic->function.name;
|
|
119606
119657
|
if (op_type == "+") {
|
|
119607
119658
|
// [x + 1 COMP 10] OR [1 + x COMP 10]
|
|
119608
119659
|
// order does not matter in addition:
|
|
119609
119660
|
// simply change right side to 10-1 (outer_constant - inner_constant)
|
|
119610
|
-
|
|
119661
|
+
if (!Hugeint::SubtractInPlace(outer_value, inner_value)) {
|
|
119662
|
+
return nullptr;
|
|
119663
|
+
}
|
|
119664
|
+
auto result_value = Value::HUGEINT(outer_value);
|
|
119665
|
+
if (!result_value.TryCastAs(constant_type)) {
|
|
119666
|
+
// if the cast is not possible then the comparison is not possible
|
|
119667
|
+
// for example, if we have x + 5 = 3, where x is an unsigned number, we will get x = -2
|
|
119668
|
+
// since this is not possible we can remove the entire branch here
|
|
119669
|
+
return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]),
|
|
119670
|
+
Value::BOOLEAN(false));
|
|
119671
|
+
}
|
|
119672
|
+
outer_constant->value = move(result_value);
|
|
119611
119673
|
} else if (op_type == "-") {
|
|
119612
119674
|
// [x - 1 COMP 10] O R [1 - x COMP 10]
|
|
119613
119675
|
// order matters in subtraction:
|
|
119614
119676
|
if (arithmetic_child_index == 0) {
|
|
119615
119677
|
// [x - 1 COMP 10]
|
|
119616
119678
|
// change right side to 10+1 (outer_constant + inner_constant)
|
|
119617
|
-
|
|
119679
|
+
if (!Hugeint::AddInPlace(outer_value, inner_value)) {
|
|
119680
|
+
return nullptr;
|
|
119681
|
+
}
|
|
119682
|
+
auto result_value = Value::HUGEINT(outer_value);
|
|
119683
|
+
if (!result_value.TryCastAs(constant_type)) {
|
|
119684
|
+
// if the cast is not possible then the comparison is not possible
|
|
119685
|
+
return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]),
|
|
119686
|
+
Value::BOOLEAN(false));
|
|
119687
|
+
}
|
|
119688
|
+
outer_constant->value = move(result_value);
|
|
119618
119689
|
} else {
|
|
119619
119690
|
// [1 - x COMP 10]
|
|
119620
119691
|
// change right side to 1-10=-9
|
|
119621
|
-
|
|
119692
|
+
if (!Hugeint::SubtractInPlace(inner_value, outer_value)) {
|
|
119693
|
+
return nullptr;
|
|
119694
|
+
}
|
|
119695
|
+
auto result_value = Value::HUGEINT(inner_value);
|
|
119696
|
+
if (!result_value.TryCastAs(constant_type)) {
|
|
119697
|
+
// if the cast is not possible then the comparison is not possible
|
|
119698
|
+
return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]),
|
|
119699
|
+
Value::BOOLEAN(false));
|
|
119700
|
+
}
|
|
119701
|
+
outer_constant->value = move(result_value);
|
|
119622
119702
|
// in this case, we should also flip the comparison
|
|
119623
119703
|
// e.g. if we have [4 - x < 2] then we should have [x > 2]
|
|
119624
119704
|
comparison->type = FlipComparisionExpression(comparison->type);
|
|
@@ -119629,24 +119709,39 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
|
119629
119709
|
// order does not matter in multiplication:
|
|
119630
119710
|
// change right side to 10/2 (outer_constant / inner_constant)
|
|
119631
119711
|
// but ONLY if outer_constant is cleanly divisible by the inner_constant
|
|
119632
|
-
if (
|
|
119712
|
+
if (inner_value == 0) {
|
|
119633
119713
|
// x * 0, the result is either 0 or NULL
|
|
119634
|
-
//
|
|
119635
|
-
// on if 0 matches the comparison criteria with the RHS
|
|
119636
|
-
// for now we don't fold, but we can fold to "ConstantOrNull"
|
|
119714
|
+
// we let the arithmetic_simplification rule take care of simplifying this first
|
|
119637
119715
|
return nullptr;
|
|
119638
119716
|
}
|
|
119639
|
-
if (
|
|
119640
|
-
// not cleanly divisible
|
|
119641
|
-
|
|
119642
|
-
|
|
119717
|
+
if (outer_value % inner_value != 0) {
|
|
119718
|
+
// not cleanly divisible
|
|
119719
|
+
bool is_equality = comparison->type == ExpressionType::COMPARE_EQUAL;
|
|
119720
|
+
bool is_inequality = comparison->type == ExpressionType::COMPARE_NOTEQUAL;
|
|
119721
|
+
if (is_equality || is_inequality) {
|
|
119722
|
+
// we know the values are not equal
|
|
119723
|
+
// the result will be either FALSE or NULL (if COMPARE_EQUAL)
|
|
119724
|
+
// or TRUE or NULL (if COMPARE_NOTEQUAL)
|
|
119725
|
+
return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]),
|
|
119726
|
+
Value::BOOLEAN(is_inequality));
|
|
119727
|
+
} else {
|
|
119728
|
+
// not cleanly divisible and we are doing > >= < <=, skip the simplification for now
|
|
119729
|
+
return nullptr;
|
|
119730
|
+
}
|
|
119643
119731
|
}
|
|
119644
|
-
if (
|
|
119732
|
+
if (inner_value < 0) {
|
|
119645
119733
|
// multiply by negative value, need to flip expression
|
|
119646
119734
|
comparison->type = FlipComparisionExpression(comparison->type);
|
|
119647
119735
|
}
|
|
119648
119736
|
// else divide the RHS by the LHS
|
|
119649
|
-
|
|
119737
|
+
// we need to do a range check on the cast even though we do a division
|
|
119738
|
+
// because e.g. -128 / -1 = 128, which is out of range
|
|
119739
|
+
auto result_value = Value::HUGEINT(outer_value / inner_value);
|
|
119740
|
+
if (!result_value.TryCastAs(constant_type)) {
|
|
119741
|
+
return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]),
|
|
119742
|
+
Value::BOOLEAN(false));
|
|
119743
|
+
}
|
|
119744
|
+
outer_constant->value = move(result_value);
|
|
119650
119745
|
}
|
|
119651
119746
|
// replace left side with x
|
|
119652
119747
|
// first extract x from the arithmetic expression
|
|
@@ -119694,7 +119789,7 @@ namespace duckdb {
|
|
|
119694
119789
|
|
|
119695
119790
|
unique_ptr<Expression> CastHugeintToSmallestType(unique_ptr<Expression> expr, NumericStatistics &num_stats) {
|
|
119696
119791
|
// Compute range
|
|
119697
|
-
if (num_stats.min.
|
|
119792
|
+
if (num_stats.min.IsNull() || num_stats.max.IsNull()) {
|
|
119698
119793
|
return expr;
|
|
119699
119794
|
}
|
|
119700
119795
|
|
|
@@ -119742,7 +119837,7 @@ unique_ptr<Expression> CastHugeintToSmallestType(unique_ptr<Expression> expr, Nu
|
|
|
119742
119837
|
template <class T>
|
|
119743
119838
|
unique_ptr<Expression> TemplatedCastToSmallestType(unique_ptr<Expression> expr, NumericStatistics &num_stats) {
|
|
119744
119839
|
// Compute range
|
|
119745
|
-
if (num_stats.min.
|
|
119840
|
+
if (num_stats.min.IsNull() || num_stats.max.IsNull()) {
|
|
119746
119841
|
return expr;
|
|
119747
119842
|
}
|
|
119748
119843
|
|
|
@@ -120016,7 +120111,7 @@ FilterPropagateResult StatisticsPropagator::PropagateComparison(BaseStatistics &
|
|
|
120016
120111
|
}
|
|
120017
120112
|
auto &lstats = (NumericStatistics &)left;
|
|
120018
120113
|
auto &rstats = (NumericStatistics &)right;
|
|
120019
|
-
if (lstats.min.
|
|
120114
|
+
if (lstats.min.IsNull() || lstats.max.IsNull() || rstats.min.IsNull() || rstats.max.IsNull()) {
|
|
120020
120115
|
// no stats available: nothing to prune
|
|
120021
120116
|
return FilterPropagateResult::NO_PRUNING_POSSIBLE;
|
|
120022
120117
|
}
|
|
@@ -120142,40 +120237,42 @@ unique_ptr<BaseStatistics> StatisticsPropagator::StatisticsFromValue(const Value
|
|
|
120142
120237
|
case PhysicalType::FLOAT:
|
|
120143
120238
|
case PhysicalType::DOUBLE: {
|
|
120144
120239
|
auto result = make_unique<NumericStatistics>(input.type(), input, input);
|
|
120145
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
120240
|
+
result->validity_stats = make_unique<ValidityStatistics>(input.IsNull(), !input.IsNull());
|
|
120146
120241
|
return move(result);
|
|
120147
120242
|
}
|
|
120148
120243
|
case PhysicalType::VARCHAR: {
|
|
120149
120244
|
auto result = make_unique<StringStatistics>(input.type());
|
|
120150
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
120151
|
-
if (!input.
|
|
120152
|
-
|
|
120153
|
-
result->Update(
|
|
120245
|
+
result->validity_stats = make_unique<ValidityStatistics>(input.IsNull(), !input.IsNull());
|
|
120246
|
+
if (!input.IsNull()) {
|
|
120247
|
+
auto &string_value = StringValue::Get(input);
|
|
120248
|
+
result->Update(string_t(string_value));
|
|
120154
120249
|
}
|
|
120155
120250
|
return move(result);
|
|
120156
120251
|
}
|
|
120157
120252
|
case PhysicalType::STRUCT: {
|
|
120158
120253
|
auto result = make_unique<StructStatistics>(input.type());
|
|
120159
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
120160
|
-
if (input.
|
|
120254
|
+
result->validity_stats = make_unique<ValidityStatistics>(input.IsNull(), !input.IsNull());
|
|
120255
|
+
if (input.IsNull()) {
|
|
120161
120256
|
for (auto &child_stat : result->child_stats) {
|
|
120162
120257
|
child_stat.reset();
|
|
120163
120258
|
}
|
|
120164
120259
|
} else {
|
|
120165
|
-
|
|
120260
|
+
auto &struct_children = StructValue::GetChildren(input);
|
|
120261
|
+
D_ASSERT(result->child_stats.size() == struct_children.size());
|
|
120166
120262
|
for (idx_t i = 0; i < result->child_stats.size(); i++) {
|
|
120167
|
-
result->child_stats[i] = StatisticsFromValue(
|
|
120263
|
+
result->child_stats[i] = StatisticsFromValue(struct_children[i]);
|
|
120168
120264
|
}
|
|
120169
120265
|
}
|
|
120170
120266
|
return move(result);
|
|
120171
120267
|
}
|
|
120172
120268
|
case PhysicalType::LIST: {
|
|
120173
120269
|
auto result = make_unique<ListStatistics>(input.type());
|
|
120174
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
120175
|
-
if (input.
|
|
120270
|
+
result->validity_stats = make_unique<ValidityStatistics>(input.IsNull(), !input.IsNull());
|
|
120271
|
+
if (input.IsNull()) {
|
|
120176
120272
|
result->child_stats.reset();
|
|
120177
120273
|
} else {
|
|
120178
|
-
|
|
120274
|
+
auto &list_children = ListValue::GetChildren(input);
|
|
120275
|
+
for (auto &child_element : list_children) {
|
|
120179
120276
|
auto child_element_stats = StatisticsFromValue(child_element);
|
|
120180
120277
|
if (child_element_stats) {
|
|
120181
120278
|
result->child_stats->Merge(*child_element_stats);
|
|
@@ -120399,7 +120496,7 @@ void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &stats, Express
|
|
|
120399
120496
|
return;
|
|
120400
120497
|
}
|
|
120401
120498
|
auto &numeric_stats = (NumericStatistics &)stats;
|
|
120402
|
-
if (numeric_stats.min.
|
|
120499
|
+
if (numeric_stats.min.IsNull() || numeric_stats.max.IsNull()) {
|
|
120403
120500
|
// no stats available: skip this
|
|
120404
120501
|
return;
|
|
120405
120502
|
}
|
|
@@ -120439,7 +120536,7 @@ void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &lstats, BaseSt
|
|
|
120439
120536
|
}
|
|
120440
120537
|
auto &left_stats = (NumericStatistics &)lstats;
|
|
120441
120538
|
auto &right_stats = (NumericStatistics &)rstats;
|
|
120442
|
-
if (left_stats.min.
|
|
120539
|
+
if (left_stats.min.IsNull() || left_stats.max.IsNull() || right_stats.min.IsNull() || right_stats.max.IsNull()) {
|
|
120443
120540
|
// no stats available: skip this
|
|
120444
120541
|
return;
|
|
120445
120542
|
}
|
|
@@ -120891,7 +120988,7 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalJoin
|
|
|
120891
120988
|
// LEFT, FULL and RIGHT OUTER joins can introduce null values
|
|
120892
120989
|
// this requires us to alter the statistics after this point in the query plan
|
|
120893
120990
|
if (IsLeftOuterJoin(join_type)) {
|
|
120894
|
-
// left or full outer join: set
|
|
120991
|
+
// left or full outer join: set IsNull() to true for all rhs statistics
|
|
120895
120992
|
for (auto &binding : right_bindings) {
|
|
120896
120993
|
auto stats = statistics_map.find(binding);
|
|
120897
120994
|
if (stats != statistics_map.end()) {
|
|
@@ -120900,7 +120997,7 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalJoin
|
|
|
120900
120997
|
}
|
|
120901
120998
|
}
|
|
120902
120999
|
if (IsRightOuterJoin(join_type)) {
|
|
120903
|
-
// right or full outer join: set
|
|
121000
|
+
// right or full outer join: set IsNull() to true for all lhs statistics
|
|
120904
121001
|
for (auto &binding : left_bindings) {
|
|
120905
121002
|
auto stats = statistics_map.find(binding);
|
|
120906
121003
|
if (stats != statistics_map.end()) {
|
|
@@ -137908,7 +138005,7 @@ unique_ptr<ParsedExpression> Transformer::TransformAExpr(duckdb_libpgquery::PGAE
|
|
|
137908
138005
|
throw NotImplementedException("Custom escape in SIMILAR TO");
|
|
137909
138006
|
}
|
|
137910
138007
|
auto &constant = (ConstantExpression &)*similar_func.children[1];
|
|
137911
|
-
if (!constant.value.
|
|
138008
|
+
if (!constant.value.IsNull()) {
|
|
137912
138009
|
throw NotImplementedException("Custom escape in SIMILAR TO");
|
|
137913
138010
|
}
|
|
137914
138011
|
// take the child of the similar_func
|
|
@@ -142041,12 +142138,12 @@ static void InvertPercentileFractions(unique_ptr<ParsedExpression> &fractions) {
|
|
|
142041
142138
|
Value value = ExpressionExecutor::EvaluateScalar(*bound.expr);
|
|
142042
142139
|
if (value.type().id() == LogicalTypeId::LIST) {
|
|
142043
142140
|
vector<Value> values;
|
|
142044
|
-
for (const auto &element_val : value
|
|
142045
|
-
values.
|
|
142141
|
+
for (const auto &element_val : ListValue::GetChildren(value)) {
|
|
142142
|
+
values.push_back(Value::DOUBLE(1 - element_val.GetValue<double>()));
|
|
142046
142143
|
}
|
|
142047
142144
|
bound.expr = make_unique<BoundConstantExpression>(Value::LIST(values));
|
|
142048
142145
|
} else {
|
|
142049
|
-
bound.expr = make_unique<BoundConstantExpression>(Value(1
|
|
142146
|
+
bound.expr = make_unique<BoundConstantExpression>(Value::DOUBLE(1 - value.GetValue<double>()));
|
|
142050
142147
|
}
|
|
142051
142148
|
}
|
|
142052
142149
|
|
|
@@ -148974,7 +149071,7 @@ bool BoundConstantExpression::Equals(const BaseExpression *other_p) const {
|
|
|
148974
149071
|
|
|
148975
149072
|
hash_t BoundConstantExpression::Hash() const {
|
|
148976
149073
|
hash_t result = Expression::Hash();
|
|
148977
|
-
return CombineHash(
|
|
149074
|
+
return CombineHash(value.Hash(), result);
|
|
148978
149075
|
}
|
|
148979
149076
|
|
|
148980
149077
|
unique_ptr<Expression> BoundConstantExpression::Copy() {
|
|
@@ -156417,6 +156514,7 @@ CompressionFunction GetBitpackingFunction(PhysicalType data_type) {
|
|
|
156417
156514
|
|
|
156418
156515
|
CompressionFunction BitpackingFun::GetFunction(PhysicalType type) {
|
|
156419
156516
|
switch (type) {
|
|
156517
|
+
case PhysicalType::BOOL:
|
|
156420
156518
|
case PhysicalType::INT8:
|
|
156421
156519
|
return GetBitpackingFunction<int8_t>(type);
|
|
156422
156520
|
case PhysicalType::INT16:
|
|
@@ -156425,7 +156523,6 @@ CompressionFunction BitpackingFun::GetFunction(PhysicalType type) {
|
|
|
156425
156523
|
return GetBitpackingFunction<int32_t>(type);
|
|
156426
156524
|
case PhysicalType::INT64:
|
|
156427
156525
|
return GetBitpackingFunction<int64_t>(type);
|
|
156428
|
-
case PhysicalType::BOOL:
|
|
156429
156526
|
case PhysicalType::UINT8:
|
|
156430
156527
|
return GetBitpackingFunction<uint8_t>(type);
|
|
156431
156528
|
case PhysicalType::UINT16:
|
|
@@ -160205,7 +160302,13 @@ MetaBlockWriter::MetaBlockWriter(DatabaseInstance &db, block_id_t initial_block_
|
|
|
160205
160302
|
}
|
|
160206
160303
|
|
|
160207
160304
|
MetaBlockWriter::~MetaBlockWriter() {
|
|
160208
|
-
|
|
160305
|
+
if (Exception::UncaughtException()) {
|
|
160306
|
+
return;
|
|
160307
|
+
}
|
|
160308
|
+
try {
|
|
160309
|
+
Flush();
|
|
160310
|
+
} catch (...) {
|
|
160311
|
+
}
|
|
160209
160312
|
}
|
|
160210
160313
|
|
|
160211
160314
|
block_id_t MetaBlockWriter::GetNextBlockId() {
|
|
@@ -161002,72 +161105,6 @@ void ListStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t co
|
|
|
161002
161105
|
|
|
161003
161106
|
namespace duckdb {
|
|
161004
161107
|
|
|
161005
|
-
template <>
|
|
161006
|
-
void NumericStatistics::Update<int8_t>(SegmentStatistics &stats, int8_t new_value) {
|
|
161007
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161008
|
-
UpdateValue<int8_t>(new_value, nstats.min.value_.tinyint, nstats.max.value_.tinyint);
|
|
161009
|
-
}
|
|
161010
|
-
|
|
161011
|
-
template <>
|
|
161012
|
-
void NumericStatistics::Update<int16_t>(SegmentStatistics &stats, int16_t new_value) {
|
|
161013
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161014
|
-
UpdateValue<int16_t>(new_value, nstats.min.value_.smallint, nstats.max.value_.smallint);
|
|
161015
|
-
}
|
|
161016
|
-
|
|
161017
|
-
template <>
|
|
161018
|
-
void NumericStatistics::Update<int32_t>(SegmentStatistics &stats, int32_t new_value) {
|
|
161019
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161020
|
-
UpdateValue<int32_t>(new_value, nstats.min.value_.integer, nstats.max.value_.integer);
|
|
161021
|
-
}
|
|
161022
|
-
|
|
161023
|
-
template <>
|
|
161024
|
-
void NumericStatistics::Update<int64_t>(SegmentStatistics &stats, int64_t new_value) {
|
|
161025
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161026
|
-
UpdateValue<int64_t>(new_value, nstats.min.value_.bigint, nstats.max.value_.bigint);
|
|
161027
|
-
}
|
|
161028
|
-
|
|
161029
|
-
template <>
|
|
161030
|
-
void NumericStatistics::Update<uint8_t>(SegmentStatistics &stats, uint8_t new_value) {
|
|
161031
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161032
|
-
UpdateValue<uint8_t>(new_value, nstats.min.value_.utinyint, nstats.max.value_.utinyint);
|
|
161033
|
-
}
|
|
161034
|
-
|
|
161035
|
-
template <>
|
|
161036
|
-
void NumericStatistics::Update<uint16_t>(SegmentStatistics &stats, uint16_t new_value) {
|
|
161037
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161038
|
-
UpdateValue<uint16_t>(new_value, nstats.min.value_.usmallint, nstats.max.value_.usmallint);
|
|
161039
|
-
}
|
|
161040
|
-
|
|
161041
|
-
template <>
|
|
161042
|
-
void NumericStatistics::Update<uint32_t>(SegmentStatistics &stats, uint32_t new_value) {
|
|
161043
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161044
|
-
UpdateValue<uint32_t>(new_value, nstats.min.value_.uinteger, nstats.max.value_.uinteger);
|
|
161045
|
-
}
|
|
161046
|
-
|
|
161047
|
-
template <>
|
|
161048
|
-
void NumericStatistics::Update<uint64_t>(SegmentStatistics &stats, uint64_t new_value) {
|
|
161049
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161050
|
-
UpdateValue<uint64_t>(new_value, nstats.min.value_.ubigint, nstats.max.value_.ubigint);
|
|
161051
|
-
}
|
|
161052
|
-
|
|
161053
|
-
template <>
|
|
161054
|
-
void NumericStatistics::Update<hugeint_t>(SegmentStatistics &stats, hugeint_t new_value) {
|
|
161055
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161056
|
-
UpdateValue<hugeint_t>(new_value, nstats.min.value_.hugeint, nstats.max.value_.hugeint);
|
|
161057
|
-
}
|
|
161058
|
-
|
|
161059
|
-
template <>
|
|
161060
|
-
void NumericStatistics::Update<float>(SegmentStatistics &stats, float new_value) {
|
|
161061
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161062
|
-
UpdateValue<float>(new_value, nstats.min.value_.float_, nstats.max.value_.float_);
|
|
161063
|
-
}
|
|
161064
|
-
|
|
161065
|
-
template <>
|
|
161066
|
-
void NumericStatistics::Update<double>(SegmentStatistics &stats, double new_value) {
|
|
161067
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
161068
|
-
UpdateValue<double>(new_value, nstats.min.value_.double_, nstats.max.value_.double_);
|
|
161069
|
-
}
|
|
161070
|
-
|
|
161071
161108
|
template <>
|
|
161072
161109
|
void NumericStatistics::Update<interval_t>(SegmentStatistics &stats, interval_t new_value) {
|
|
161073
161110
|
}
|
|
@@ -161089,23 +161126,23 @@ NumericStatistics::NumericStatistics(LogicalType type_p, Value min_p, Value max_
|
|
|
161089
161126
|
void NumericStatistics::Merge(const BaseStatistics &other_p) {
|
|
161090
161127
|
BaseStatistics::Merge(other_p);
|
|
161091
161128
|
auto &other = (const NumericStatistics &)other_p;
|
|
161092
|
-
if (other.min.
|
|
161093
|
-
min
|
|
161129
|
+
if (other.min.IsNull() || min.IsNull()) {
|
|
161130
|
+
min = Value(type);
|
|
161094
161131
|
} else if (other.min < min) {
|
|
161095
161132
|
min = other.min;
|
|
161096
161133
|
}
|
|
161097
|
-
if (other.max.
|
|
161098
|
-
max
|
|
161134
|
+
if (other.max.IsNull() || max.IsNull()) {
|
|
161135
|
+
max = Value(type);
|
|
161099
161136
|
} else if (other.max > max) {
|
|
161100
161137
|
max = other.max;
|
|
161101
161138
|
}
|
|
161102
161139
|
}
|
|
161103
161140
|
|
|
161104
161141
|
FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) {
|
|
161105
|
-
if (constant.
|
|
161142
|
+
if (constant.IsNull()) {
|
|
161106
161143
|
return FilterPropagateResult::FILTER_ALWAYS_FALSE;
|
|
161107
161144
|
}
|
|
161108
|
-
if (min.
|
|
161145
|
+
if (min.IsNull() || max.IsNull()) {
|
|
161109
161146
|
return FilterPropagateResult::NO_PRUNING_POSSIBLE;
|
|
161110
161147
|
}
|
|
161111
161148
|
switch (comparison_type) {
|
|
@@ -161215,11 +161252,11 @@ void NumericStatistics::TemplatedVerify(Vector &vector, const SelectionVector &s
|
|
|
161215
161252
|
if (!vdata.validity.RowIsValid(index)) {
|
|
161216
161253
|
continue;
|
|
161217
161254
|
}
|
|
161218
|
-
if (!min.
|
|
161255
|
+
if (!min.IsNull() && LessThan::Operation(data[index], min.GetValueUnsafe<T>())) { // LCOV_EXCL_START
|
|
161219
161256
|
throw InternalException("Statistics mismatch: value is smaller than min.\nStatistics: %s\nVector: %s",
|
|
161220
161257
|
ToString(), vector.ToString(count));
|
|
161221
161258
|
} // LCOV_EXCL_STOP
|
|
161222
|
-
if (!max.
|
|
161259
|
+
if (!max.IsNull() && GreaterThan::Operation(data[index], max.GetValueUnsafe<T>())) {
|
|
161223
161260
|
throw InternalException("Statistics mismatch: value is bigger than max.\nStatistics: %s\nVector: %s",
|
|
161224
161261
|
ToString(), vector.ToString(count));
|
|
161225
161262
|
}
|
|
@@ -163764,7 +163801,7 @@ idx_t ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const
|
|
|
163764
163801
|
}
|
|
163765
163802
|
case PhysicalType::VARCHAR: {
|
|
163766
163803
|
auto result_flat = FlatVector::GetData<string_t>(result);
|
|
163767
|
-
Vector predicate_vector(constant_filter.constant
|
|
163804
|
+
Vector predicate_vector(constant_filter.constant);
|
|
163768
163805
|
auto predicate = FlatVector::GetData<string_t>(predicate_vector);
|
|
163769
163806
|
FilterSelectionSwitch<string_t>(result_flat, predicate, sel, approved_tuple_count,
|
|
163770
163807
|
constant_filter.comparison_type, mask);
|