duckdb 0.3.2-dev890.0 → 0.3.2-dev930.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 +1140 -912
- package/src/duckdb.hpp +236 -69
- package/src/parquet-amalgamation.cpp +36625 -36642
- 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
|
|
|
@@ -75010,6 +75040,10 @@ struct EpochFun {
|
|
|
75010
75040
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
75011
75041
|
};
|
|
75012
75042
|
|
|
75043
|
+
struct MakeDateFun {
|
|
75044
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
75045
|
+
};
|
|
75046
|
+
|
|
75013
75047
|
struct StrfTimeFun {
|
|
75014
75048
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
75015
75049
|
};
|
|
@@ -75690,7 +75724,7 @@ static unique_ptr<BaseStatistics> PropagateDatePartStatistics(vector<unique_ptr<
|
|
|
75690
75724
|
return nullptr;
|
|
75691
75725
|
}
|
|
75692
75726
|
auto &nstats = (NumericStatistics &)*child_stats[0];
|
|
75693
|
-
if (nstats.min.
|
|
75727
|
+
if (nstats.min.IsNull() || nstats.max.IsNull()) {
|
|
75694
75728
|
return nullptr;
|
|
75695
75729
|
}
|
|
75696
75730
|
// run the operator on both the min and the max, this gives us the [min, max] bound
|
|
@@ -76789,11 +76823,12 @@ struct StructDatePart {
|
|
|
76789
76823
|
|
|
76790
76824
|
Value parts_list = ExpressionExecutor::EvaluateScalar(*arguments[0]);
|
|
76791
76825
|
if (parts_list.type().id() == LogicalTypeId::LIST) {
|
|
76792
|
-
|
|
76826
|
+
auto &list_children = ListValue::GetChildren(parts_list);
|
|
76827
|
+
if (list_children.empty()) {
|
|
76793
76828
|
throw BinderException("%s requires non-empty lists of part names", bound_function.name);
|
|
76794
76829
|
}
|
|
76795
|
-
for (const auto &part_value :
|
|
76796
|
-
if (part_value.
|
|
76830
|
+
for (const auto &part_value : list_children) {
|
|
76831
|
+
if (part_value.IsNull()) {
|
|
76797
76832
|
throw BinderException("NULL struct entry name in %s", bound_function.name);
|
|
76798
76833
|
}
|
|
76799
76834
|
const auto part_name = part_value.ToString();
|
|
@@ -77822,6 +77857,189 @@ void EpochFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
77822
77857
|
|
|
77823
77858
|
|
|
77824
77859
|
|
|
77860
|
+
//===----------------------------------------------------------------------===//
|
|
77861
|
+
// DuckDB
|
|
77862
|
+
//
|
|
77863
|
+
// duckdb/common/vector_operations/senary_executor.hpp
|
|
77864
|
+
//
|
|
77865
|
+
//
|
|
77866
|
+
//===----------------------------------------------------------------------===//
|
|
77867
|
+
|
|
77868
|
+
|
|
77869
|
+
|
|
77870
|
+
|
|
77871
|
+
|
|
77872
|
+
namespace duckdb {
|
|
77873
|
+
|
|
77874
|
+
struct SenaryExecutor {
|
|
77875
|
+
static const size_t NCOLS = 6;
|
|
77876
|
+
|
|
77877
|
+
template <class TA, class TB, class TC, class TD, class TE, class TF, class TR,
|
|
77878
|
+
class FUN = std::function<TR(TA, TB, TC, TD, TE, TF)>>
|
|
77879
|
+
static void Execute(DataChunk &input, Vector &result, FUN fun) {
|
|
77880
|
+
D_ASSERT(input.ColumnCount() >= NCOLS);
|
|
77881
|
+
const auto count = input.size();
|
|
77882
|
+
|
|
77883
|
+
bool all_constant = true;
|
|
77884
|
+
bool any_null = false;
|
|
77885
|
+
for (const auto &v : input.data) {
|
|
77886
|
+
if (v.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
77887
|
+
if (ConstantVector::IsNull(v)) {
|
|
77888
|
+
any_null = true;
|
|
77889
|
+
}
|
|
77890
|
+
} else {
|
|
77891
|
+
all_constant = false;
|
|
77892
|
+
break;
|
|
77893
|
+
}
|
|
77894
|
+
}
|
|
77895
|
+
|
|
77896
|
+
if (all_constant) {
|
|
77897
|
+
result.SetVectorType(VectorType::CONSTANT_VECTOR);
|
|
77898
|
+
if (any_null) {
|
|
77899
|
+
ConstantVector::SetNull(result, true);
|
|
77900
|
+
} else {
|
|
77901
|
+
auto adata = ConstantVector::GetData<TA>(input.data[0]);
|
|
77902
|
+
auto bdata = ConstantVector::GetData<TB>(input.data[1]);
|
|
77903
|
+
auto cdata = ConstantVector::GetData<TC>(input.data[2]);
|
|
77904
|
+
auto ddata = ConstantVector::GetData<TD>(input.data[3]);
|
|
77905
|
+
auto edata = ConstantVector::GetData<TE>(input.data[4]);
|
|
77906
|
+
auto fdata = ConstantVector::GetData<TF>(input.data[5]);
|
|
77907
|
+
auto result_data = ConstantVector::GetData<TR>(result);
|
|
77908
|
+
result_data[0] = fun(*adata, *bdata, *cdata, *ddata, *edata, *fdata);
|
|
77909
|
+
}
|
|
77910
|
+
} else {
|
|
77911
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
77912
|
+
auto result_data = FlatVector::GetData<TR>(result);
|
|
77913
|
+
auto &result_validity = FlatVector::Validity(result);
|
|
77914
|
+
|
|
77915
|
+
bool all_valid = true;
|
|
77916
|
+
vector<VectorData> vdata(NCOLS);
|
|
77917
|
+
for (size_t c = 0; c < NCOLS; ++c) {
|
|
77918
|
+
input.data[c].Orrify(count, vdata[c]);
|
|
77919
|
+
all_valid = all_valid && vdata[c].validity.AllValid();
|
|
77920
|
+
}
|
|
77921
|
+
|
|
77922
|
+
auto adata = (const TA *)(vdata[0].data);
|
|
77923
|
+
auto bdata = (const TB *)(vdata[1].data);
|
|
77924
|
+
auto cdata = (const TC *)(vdata[2].data);
|
|
77925
|
+
auto ddata = (const TD *)(vdata[3].data);
|
|
77926
|
+
auto edata = (const TE *)(vdata[4].data);
|
|
77927
|
+
auto fdata = (const TF *)(vdata[5].data);
|
|
77928
|
+
|
|
77929
|
+
vector<idx_t> idx(NCOLS);
|
|
77930
|
+
if (all_valid) {
|
|
77931
|
+
for (idx_t r = 0; r < count; ++r) {
|
|
77932
|
+
for (size_t c = 0; c < NCOLS; ++c) {
|
|
77933
|
+
idx[c] = vdata[c].sel->get_index(r);
|
|
77934
|
+
}
|
|
77935
|
+
result_data[r] =
|
|
77936
|
+
fun(adata[idx[0]], bdata[idx[1]], cdata[idx[2]], ddata[idx[3]], edata[idx[4]], fdata[idx[5]]);
|
|
77937
|
+
}
|
|
77938
|
+
} else {
|
|
77939
|
+
for (idx_t r = 0; r < count; ++r) {
|
|
77940
|
+
all_valid = true;
|
|
77941
|
+
for (size_t c = 0; c < NCOLS; ++c) {
|
|
77942
|
+
idx[c] = vdata[c].sel->get_index(r);
|
|
77943
|
+
if (!vdata[c].validity.RowIsValid(idx[c])) {
|
|
77944
|
+
result_validity.SetInvalid(r);
|
|
77945
|
+
all_valid = false;
|
|
77946
|
+
break;
|
|
77947
|
+
}
|
|
77948
|
+
}
|
|
77949
|
+
if (all_valid) {
|
|
77950
|
+
result_data[r] = fun(adata[idx[0]], bdata[idx[1]], cdata[idx[2]], ddata[idx[3]], edata[idx[4]],
|
|
77951
|
+
fdata[idx[5]]);
|
|
77952
|
+
}
|
|
77953
|
+
}
|
|
77954
|
+
}
|
|
77955
|
+
}
|
|
77956
|
+
}
|
|
77957
|
+
};
|
|
77958
|
+
|
|
77959
|
+
} // namespace duckdb
|
|
77960
|
+
|
|
77961
|
+
|
|
77962
|
+
namespace duckdb {
|
|
77963
|
+
|
|
77964
|
+
struct MakeDateOperator {
|
|
77965
|
+
template <typename YYYY, typename MM, typename DD, typename RESULT_TYPE>
|
|
77966
|
+
static RESULT_TYPE Operation(YYYY yyyy, MM mm, DD dd) {
|
|
77967
|
+
return Date::FromDate(yyyy, mm, dd);
|
|
77968
|
+
}
|
|
77969
|
+
};
|
|
77970
|
+
|
|
77971
|
+
template <typename T>
|
|
77972
|
+
static void ExecuteMakeDate(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
77973
|
+
D_ASSERT(input.ColumnCount() == 3);
|
|
77974
|
+
auto &yyyy = input.data[0];
|
|
77975
|
+
auto &mm = input.data[1];
|
|
77976
|
+
auto &dd = input.data[2];
|
|
77977
|
+
|
|
77978
|
+
TernaryExecutor::Execute<T, T, T, date_t>(yyyy, mm, dd, result, input.size(),
|
|
77979
|
+
MakeDateOperator::Operation<T, T, T, date_t>);
|
|
77980
|
+
}
|
|
77981
|
+
|
|
77982
|
+
struct MakeTimeOperator {
|
|
77983
|
+
template <typename HH, typename MM, typename SS, typename RESULT_TYPE>
|
|
77984
|
+
static RESULT_TYPE Operation(HH hh, MM mm, SS ss) {
|
|
77985
|
+
int64_t secs = ss;
|
|
77986
|
+
int64_t micros = std::round((ss - secs) * Interval::MICROS_PER_SEC);
|
|
77987
|
+
return Time::FromTime(hh, mm, secs, micros);
|
|
77988
|
+
}
|
|
77989
|
+
};
|
|
77990
|
+
|
|
77991
|
+
template <typename T>
|
|
77992
|
+
static void ExecuteMakeTime(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
77993
|
+
D_ASSERT(input.ColumnCount() == 3);
|
|
77994
|
+
auto &yyyy = input.data[0];
|
|
77995
|
+
auto &mm = input.data[1];
|
|
77996
|
+
auto &dd = input.data[2];
|
|
77997
|
+
|
|
77998
|
+
TernaryExecutor::Execute<T, T, double, dtime_t>(yyyy, mm, dd, result, input.size(),
|
|
77999
|
+
MakeTimeOperator::Operation<T, T, double, dtime_t>);
|
|
78000
|
+
}
|
|
78001
|
+
|
|
78002
|
+
struct MakeTimestampOperator {
|
|
78003
|
+
template <typename YYYY, typename MM, typename DD, typename HR, typename MN, typename SS, typename RESULT_TYPE>
|
|
78004
|
+
static RESULT_TYPE Operation(YYYY yyyy, MM mm, DD dd, HR hr, MN mn, SS ss) {
|
|
78005
|
+
const auto d = MakeDateOperator::Operation<YYYY, MM, DD, date_t>(yyyy, mm, dd);
|
|
78006
|
+
const auto t = MakeTimeOperator::Operation<HR, MN, SS, dtime_t>(hr, mn, ss);
|
|
78007
|
+
return Timestamp::FromDatetime(d, t);
|
|
78008
|
+
}
|
|
78009
|
+
};
|
|
78010
|
+
|
|
78011
|
+
template <typename T>
|
|
78012
|
+
static void ExecuteMakeTimestamp(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
78013
|
+
D_ASSERT(input.ColumnCount() == 6);
|
|
78014
|
+
|
|
78015
|
+
auto func = MakeTimestampOperator::Operation<T, T, T, T, T, double, timestamp_t>;
|
|
78016
|
+
SenaryExecutor::Execute<T, T, T, T, T, double, timestamp_t>(input, result, func);
|
|
78017
|
+
}
|
|
78018
|
+
|
|
78019
|
+
void MakeDateFun::RegisterFunction(BuiltinFunctions &set) {
|
|
78020
|
+
ScalarFunctionSet make_date("make_date");
|
|
78021
|
+
make_date.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT},
|
|
78022
|
+
LogicalType::DATE, ExecuteMakeDate<int64_t>));
|
|
78023
|
+
set.AddFunction(make_date);
|
|
78024
|
+
|
|
78025
|
+
ScalarFunctionSet make_time("make_time");
|
|
78026
|
+
make_time.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::DOUBLE},
|
|
78027
|
+
LogicalType::TIME, ExecuteMakeTime<int64_t>));
|
|
78028
|
+
set.AddFunction(make_time);
|
|
78029
|
+
|
|
78030
|
+
ScalarFunctionSet make_timestamp("make_timestamp");
|
|
78031
|
+
make_timestamp.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT,
|
|
78032
|
+
LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::DOUBLE},
|
|
78033
|
+
LogicalType::TIMESTAMP, ExecuteMakeTimestamp<int64_t>));
|
|
78034
|
+
set.AddFunction(make_timestamp);
|
|
78035
|
+
}
|
|
78036
|
+
|
|
78037
|
+
} // namespace duckdb
|
|
78038
|
+
|
|
78039
|
+
|
|
78040
|
+
|
|
78041
|
+
|
|
78042
|
+
|
|
77825
78043
|
|
|
77826
78044
|
|
|
77827
78045
|
|
|
@@ -78406,7 +78624,7 @@ static unique_ptr<FunctionData> StrfTimeBindFunction(ClientContext &context, Sca
|
|
|
78406
78624
|
}
|
|
78407
78625
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
78408
78626
|
StrfTimeFormat format;
|
|
78409
|
-
if (!options_str.
|
|
78627
|
+
if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
78410
78628
|
auto format_string = options_str.GetValue<string>();
|
|
78411
78629
|
string error = StrTimeFormat::ParseFormatSpecifier(format_string, format);
|
|
78412
78630
|
if (!error.empty()) {
|
|
@@ -78915,7 +79133,7 @@ static unique_ptr<FunctionData> StrpTimeBindFunction(ClientContext &context, Sca
|
|
|
78915
79133
|
}
|
|
78916
79134
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
78917
79135
|
StrpTimeFormat format;
|
|
78918
|
-
if (!options_str.
|
|
79136
|
+
if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
78919
79137
|
string format_string = options_str.ToString();
|
|
78920
79138
|
format.format_specifier = format_string;
|
|
78921
79139
|
string error = StrTimeFormat::ParseFormatSpecifier(format_string, format);
|
|
@@ -79152,6 +79370,7 @@ void BuiltinFunctions::RegisterDateFunctions() {
|
|
|
79152
79370
|
Register<CurrentDateFun>();
|
|
79153
79371
|
Register<CurrentTimestampFun>();
|
|
79154
79372
|
Register<EpochFun>();
|
|
79373
|
+
Register<MakeDateFun>();
|
|
79155
79374
|
Register<StrfTimeFun>();
|
|
79156
79375
|
Register<StrpTimeFun>();
|
|
79157
79376
|
Register<ToIntervalFun>();
|
|
@@ -79227,15 +79446,15 @@ static void EnumRangeBoundaryFunction(DataChunk &input, ExpressionState &state,
|
|
|
79227
79446
|
auto first_param = input.GetValue(0, 0);
|
|
79228
79447
|
auto second_param = input.GetValue(1, 0);
|
|
79229
79448
|
|
|
79230
|
-
auto &enum_vector = first_param.
|
|
79231
|
-
|
|
79449
|
+
auto &enum_vector = first_param.IsNull() ? EnumType::GetValuesInsertOrder(input.GetTypes()[1])
|
|
79450
|
+
: EnumType::GetValuesInsertOrder(input.GetTypes()[0]);
|
|
79232
79451
|
|
|
79233
|
-
if (first_param.
|
|
79452
|
+
if (first_param.IsNull()) {
|
|
79234
79453
|
start = 0;
|
|
79235
79454
|
} else {
|
|
79236
79455
|
start = first_param.GetValue<uint32_t>();
|
|
79237
79456
|
}
|
|
79238
|
-
if (second_param.
|
|
79457
|
+
if (second_param.IsNull()) {
|
|
79239
79458
|
end = EnumType::GetSize(input.GetTypes()[0]);
|
|
79240
79459
|
} else {
|
|
79241
79460
|
end = second_param.GetValue<uint32_t>() + 1;
|
|
@@ -79501,14 +79720,15 @@ unique_ptr<FunctionData> CurrentSettingBind(ClientContext &context, ScalarFuncti
|
|
|
79501
79720
|
}
|
|
79502
79721
|
Value key_val = ExpressionExecutor::EvaluateScalar(*key_child.get());
|
|
79503
79722
|
D_ASSERT(key_val.type().id() == LogicalTypeId::VARCHAR);
|
|
79504
|
-
|
|
79723
|
+
auto &key_str = StringValue::Get(key_val);
|
|
79724
|
+
if (key_val.IsNull() || key_str.empty()) {
|
|
79505
79725
|
throw ParserException("Key name for current_setting needs to be neither NULL nor empty");
|
|
79506
79726
|
}
|
|
79507
79727
|
|
|
79508
|
-
auto key = StringUtil::Lower(
|
|
79728
|
+
auto key = StringUtil::Lower(key_str);
|
|
79509
79729
|
Value val;
|
|
79510
79730
|
if (!context.TryGetCurrentSetting(key, val)) {
|
|
79511
|
-
throw InvalidInputException("unrecognized configuration parameter \"%s\"",
|
|
79731
|
+
throw InvalidInputException("unrecognized configuration parameter \"%s\"", key_str);
|
|
79512
79732
|
}
|
|
79513
79733
|
|
|
79514
79734
|
bound_function.return_type = val.type();
|
|
@@ -80844,13 +81064,14 @@ void FillResult(Value &values, Vector &result, idx_t row) {
|
|
|
80844
81064
|
//! First Initialize List Vector
|
|
80845
81065
|
idx_t current_offset = ListVector::GetListSize(result);
|
|
80846
81066
|
//! Push Values to List Vector
|
|
80847
|
-
|
|
80848
|
-
|
|
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]);
|
|
80849
81070
|
}
|
|
80850
81071
|
|
|
80851
81072
|
//! now set the pointer
|
|
80852
81073
|
auto &entry = ((list_entry_t *)result.GetData())[row];
|
|
80853
|
-
entry.length =
|
|
81074
|
+
entry.length = list_values.size();
|
|
80854
81075
|
entry.offset = current_offset;
|
|
80855
81076
|
}
|
|
80856
81077
|
|
|
@@ -81569,7 +81790,7 @@ unique_ptr<FunctionData> BindDecimalRoundPrecision(ClientContext &context, Scala
|
|
|
81569
81790
|
throw NotImplementedException("ROUND(DECIMAL, INTEGER) with non-constant precision is not supported");
|
|
81570
81791
|
}
|
|
81571
81792
|
Value val = ExpressionExecutor::EvaluateScalar(*arguments[1]).CastAs(LogicalType::INTEGER);
|
|
81572
|
-
if (val.
|
|
81793
|
+
if (val.IsNull()) {
|
|
81573
81794
|
throw NotImplementedException("ROUND(DECIMAL, INTEGER) with non-constant precision is not supported");
|
|
81574
81795
|
}
|
|
81575
81796
|
// our new precision becomes the round value
|
|
@@ -81577,7 +81798,7 @@ unique_ptr<FunctionData> BindDecimalRoundPrecision(ClientContext &context, Scala
|
|
|
81577
81798
|
// but ONLY if the round value is positive
|
|
81578
81799
|
// if it is negative the scale becomes zero
|
|
81579
81800
|
// i.e. ROUND(DECIMAL(18,3), -1) -> DECIMAL(18,0)
|
|
81580
|
-
int32_t round_value = val
|
|
81801
|
+
int32_t round_value = IntegerValue::Get(val);
|
|
81581
81802
|
uint8_t target_scale;
|
|
81582
81803
|
auto width = DecimalType::GetWidth(decimal_type);
|
|
81583
81804
|
auto scale = DecimalType::GetScale(decimal_type);
|
|
@@ -82576,7 +82797,7 @@ static unique_ptr<BaseStatistics> PropagateNumericStats(ClientContext &context,
|
|
|
82576
82797
|
auto &rstats = (NumericStatistics &)*child_stats[1];
|
|
82577
82798
|
Value new_min, new_max;
|
|
82578
82799
|
bool potential_overflow = true;
|
|
82579
|
-
if (!lstats.min.
|
|
82800
|
+
if (!lstats.min.IsNull() && !lstats.max.IsNull() && !rstats.min.IsNull() && !rstats.max.IsNull()) {
|
|
82580
82801
|
switch (expr.return_type.InternalType()) {
|
|
82581
82802
|
case PhysicalType::INT8:
|
|
82582
82803
|
potential_overflow =
|
|
@@ -82791,11 +83012,16 @@ void AddFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
82791
83012
|
// - [subtract]
|
|
82792
83013
|
//===--------------------------------------------------------------------===//
|
|
82793
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
|
+
|
|
82794
83021
|
template <class TA, class TR>
|
|
82795
83022
|
static inline TR Operation(TA input) {
|
|
82796
|
-
using Limits = std::numeric_limits<TR>;
|
|
82797
83023
|
auto cast = (TR)input;
|
|
82798
|
-
if (
|
|
83024
|
+
if (!CanNegate<TR>(cast)) {
|
|
82799
83025
|
throw OutOfRangeException("Overflow in negation of integer!");
|
|
82800
83026
|
}
|
|
82801
83027
|
return -cast;
|
|
@@ -82833,11 +83059,17 @@ unique_ptr<FunctionData> DecimalNegateBind(ClientContext &context, ScalarFunctio
|
|
|
82833
83059
|
|
|
82834
83060
|
struct NegatePropagateStatistics {
|
|
82835
83061
|
template <class T>
|
|
82836
|
-
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
|
+
}
|
|
82837
83068
|
// new min is -max
|
|
82838
|
-
new_min = Value::Numeric(type, NegateOperator::Operation<T, T>(
|
|
83069
|
+
new_min = Value::Numeric(type, NegateOperator::Operation<T, T>(max_value));
|
|
82839
83070
|
// new max is -min
|
|
82840
|
-
new_max = Value::Numeric(type, NegateOperator::Operation<T, T>(
|
|
83071
|
+
new_max = Value::Numeric(type, NegateOperator::Operation<T, T>(min_value));
|
|
83072
|
+
return false;
|
|
82841
83073
|
}
|
|
82842
83074
|
};
|
|
82843
83075
|
|
|
@@ -82851,24 +83083,33 @@ static unique_ptr<BaseStatistics> NegateBindStatistics(ClientContext &context, B
|
|
|
82851
83083
|
}
|
|
82852
83084
|
auto &istats = (NumericStatistics &)*child_stats[0];
|
|
82853
83085
|
Value new_min, new_max;
|
|
82854
|
-
|
|
83086
|
+
bool potential_overflow = true;
|
|
83087
|
+
if (!istats.min.IsNull() && !istats.max.IsNull()) {
|
|
82855
83088
|
switch (expr.return_type.InternalType()) {
|
|
82856
83089
|
case PhysicalType::INT8:
|
|
82857
|
-
|
|
83090
|
+
potential_overflow =
|
|
83091
|
+
NegatePropagateStatistics::Operation<int8_t>(expr.return_type, istats, new_min, new_max);
|
|
82858
83092
|
break;
|
|
82859
83093
|
case PhysicalType::INT16:
|
|
82860
|
-
|
|
83094
|
+
potential_overflow =
|
|
83095
|
+
NegatePropagateStatistics::Operation<int16_t>(expr.return_type, istats, new_min, new_max);
|
|
82861
83096
|
break;
|
|
82862
83097
|
case PhysicalType::INT32:
|
|
82863
|
-
|
|
83098
|
+
potential_overflow =
|
|
83099
|
+
NegatePropagateStatistics::Operation<int32_t>(expr.return_type, istats, new_min, new_max);
|
|
82864
83100
|
break;
|
|
82865
83101
|
case PhysicalType::INT64:
|
|
82866
|
-
|
|
83102
|
+
potential_overflow =
|
|
83103
|
+
NegatePropagateStatistics::Operation<int64_t>(expr.return_type, istats, new_min, new_max);
|
|
82867
83104
|
break;
|
|
82868
83105
|
default:
|
|
82869
83106
|
return nullptr;
|
|
82870
83107
|
}
|
|
82871
83108
|
}
|
|
83109
|
+
if (potential_overflow) {
|
|
83110
|
+
new_min = Value(expr.return_type);
|
|
83111
|
+
new_max = Value(expr.return_type);
|
|
83112
|
+
}
|
|
82872
83113
|
auto stats = make_unique<NumericStatistics>(expr.return_type, move(new_min), move(new_max));
|
|
82873
83114
|
if (istats.validity_stats) {
|
|
82874
83115
|
stats->validity_stats = istats.validity_stats->Copy();
|
|
@@ -84091,10 +84332,10 @@ static unique_ptr<FunctionData> NextValBind(ClientContext &context, ScalarFuncti
|
|
|
84091
84332
|
if (arguments[0]->IsFoldable()) {
|
|
84092
84333
|
// parameter to nextval function is a foldable constant
|
|
84093
84334
|
// evaluate the constant and perform the catalog lookup already
|
|
84094
|
-
|
|
84095
|
-
if (!seqname.
|
|
84335
|
+
auto seqname = ExpressionExecutor::EvaluateScalar(*arguments[0]);
|
|
84336
|
+
if (!seqname.IsNull()) {
|
|
84096
84337
|
D_ASSERT(seqname.type().id() == LogicalTypeId::VARCHAR);
|
|
84097
|
-
auto qname = QualifiedName::Parse(seqname
|
|
84338
|
+
auto qname = QualifiedName::Parse(StringValue::Get(seqname));
|
|
84098
84339
|
sequence = Catalog::GetCatalog(context).GetEntry<SequenceCatalogEntry>(context, qname.schema, qname.name);
|
|
84099
84340
|
}
|
|
84100
84341
|
}
|
|
@@ -87482,7 +87723,7 @@ static inline duckdb_re2::StringPiece CreateStringPiece(string_t &input) {
|
|
|
87482
87723
|
return duckdb_re2::StringPiece(input.GetDataUnsafe(), input.GetSize());
|
|
87483
87724
|
}
|
|
87484
87725
|
|
|
87485
|
-
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) {
|
|
87486
87727
|
for (idx_t i = 0; i < options.size(); i++) {
|
|
87487
87728
|
switch (options[i]) {
|
|
87488
87729
|
case 'c':
|
|
@@ -87593,15 +87834,15 @@ static unique_ptr<FunctionData> RegexpMatchesBind(ClientContext &context, Scalar
|
|
|
87593
87834
|
throw InvalidInputException("Regex options field must be a constant");
|
|
87594
87835
|
}
|
|
87595
87836
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[2]);
|
|
87596
|
-
if (!options_str.
|
|
87597
|
-
ParseRegexOptions(options_str
|
|
87837
|
+
if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
87838
|
+
ParseRegexOptions(StringValue::Get(options_str), options);
|
|
87598
87839
|
}
|
|
87599
87840
|
}
|
|
87600
87841
|
|
|
87601
87842
|
if (arguments[1]->IsFoldable()) {
|
|
87602
87843
|
Value pattern_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
87603
|
-
if (!pattern_str.
|
|
87604
|
-
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));
|
|
87605
87846
|
}
|
|
87606
87847
|
}
|
|
87607
87848
|
return make_unique<RegexpMatchesBindData>(options, "");
|
|
@@ -87644,8 +87885,8 @@ static unique_ptr<FunctionData> RegexReplaceBind(ClientContext &context, ScalarF
|
|
|
87644
87885
|
throw InvalidInputException("Regex options field must be a constant");
|
|
87645
87886
|
}
|
|
87646
87887
|
Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[3]);
|
|
87647
|
-
if (!options_str.
|
|
87648
|
-
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);
|
|
87649
87890
|
}
|
|
87650
87891
|
}
|
|
87651
87892
|
|
|
@@ -87706,8 +87947,8 @@ static unique_ptr<FunctionData> RegexExtractBind(ClientContext &context, ScalarF
|
|
|
87706
87947
|
string pattern = "";
|
|
87707
87948
|
if (constant_pattern) {
|
|
87708
87949
|
Value pattern_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
87709
|
-
if (!pattern_str.
|
|
87710
|
-
pattern = pattern_str
|
|
87950
|
+
if (!pattern_str.IsNull() && pattern_str.type().id() == LogicalTypeId::VARCHAR) {
|
|
87951
|
+
pattern = StringValue::Get(pattern_str);
|
|
87711
87952
|
}
|
|
87712
87953
|
}
|
|
87713
87954
|
|
|
@@ -87717,7 +87958,7 @@ static unique_ptr<FunctionData> RegexExtractBind(ClientContext &context, ScalarF
|
|
|
87717
87958
|
throw InvalidInputException("Group index field field must be a constant!");
|
|
87718
87959
|
}
|
|
87719
87960
|
Value group = ExpressionExecutor::EvaluateScalar(*arguments[2]);
|
|
87720
|
-
if (!group.
|
|
87961
|
+
if (!group.IsNull()) {
|
|
87721
87962
|
auto group_idx = group.GetValue<int32_t>();
|
|
87722
87963
|
if (group_idx < 0 || group_idx > 9) {
|
|
87723
87964
|
throw InvalidInputException("Group index must be between 0 and 9!");
|
|
@@ -88837,10 +89078,11 @@ static unique_ptr<FunctionData> StructExtractBind(ClientContext &context, Scalar
|
|
|
88837
89078
|
}
|
|
88838
89079
|
Value key_val = ExpressionExecutor::EvaluateScalar(*key_child.get());
|
|
88839
89080
|
D_ASSERT(key_val.type().id() == LogicalTypeId::VARCHAR);
|
|
88840
|
-
|
|
89081
|
+
auto &key_str = StringValue::Get(key_val);
|
|
89082
|
+
if (key_val.IsNull() || key_str.empty()) {
|
|
88841
89083
|
throw BinderException("Key name for struct_extract needs to be neither NULL nor empty");
|
|
88842
89084
|
}
|
|
88843
|
-
string key = StringUtil::Lower(
|
|
89085
|
+
string key = StringUtil::Lower(key_str);
|
|
88844
89086
|
|
|
88845
89087
|
LogicalType return_type;
|
|
88846
89088
|
idx_t key_index = 0;
|
|
@@ -89576,16 +89818,12 @@ unique_ptr<FunctionData> ArrowTableFunction::ArrowScanBind(ClientContext &contex
|
|
|
89576
89818
|
vector<LogicalType> &input_table_types,
|
|
89577
89819
|
vector<string> &input_table_names,
|
|
89578
89820
|
vector<LogicalType> &return_types, vector<string> &names) {
|
|
89579
|
-
|
|
89580
|
-
unique_ptr<ArrowArrayStreamWrapper> (*stream_factory_produce)(
|
|
89821
|
+
typedef unique_ptr<ArrowArrayStreamWrapper> (*stream_factory_produce_t)(
|
|
89581
89822
|
uintptr_t stream_factory_ptr,
|
|
89582
89823
|
std::pair<std::unordered_map<idx_t, string>, std::vector<string>> & project_columns,
|
|
89583
|
-
TableFilterCollection * filters)
|
|
89584
|
-
|
|
89585
|
-
|
|
89586
|
-
project_columns,
|
|
89587
|
-
TableFilterCollection * filters)) inputs[1]
|
|
89588
|
-
.GetPointer();
|
|
89824
|
+
TableFilterCollection * filters);
|
|
89825
|
+
auto stream_factory_ptr = inputs[0].GetPointer();
|
|
89826
|
+
auto stream_factory_produce = (stream_factory_produce_t)inputs[1].GetPointer();
|
|
89589
89827
|
auto rows_per_thread = inputs[2].GetValue<uint64_t>();
|
|
89590
89828
|
std::pair<std::unordered_map<idx_t, string>, std::vector<string>> project_columns;
|
|
89591
89829
|
#ifndef DUCKDB_NO_THREADS
|
|
@@ -90709,7 +90947,7 @@ static bool ParseBoolean(vector<Value> &set) {
|
|
|
90709
90947
|
set[0].type().id() == LogicalTypeId::DECIMAL) {
|
|
90710
90948
|
throw BinderException("Expected a boolean value (e.g. TRUE or 1)");
|
|
90711
90949
|
}
|
|
90712
|
-
return set[0].CastAs(LogicalType::BOOLEAN)
|
|
90950
|
+
return BooleanValue::Get(set[0].CastAs(LogicalType::BOOLEAN));
|
|
90713
90951
|
}
|
|
90714
90952
|
|
|
90715
90953
|
static string ParseString(vector<Value> &set) {
|
|
@@ -91242,7 +91480,7 @@ static unique_ptr<FunctionData> GlobFunctionBind(ClientContext &context, vector<
|
|
|
91242
91480
|
}
|
|
91243
91481
|
auto result = make_unique<GlobFunctionBindData>();
|
|
91244
91482
|
auto &fs = FileSystem::GetFileSystem(context);
|
|
91245
|
-
result->files = fs.Glob(inputs[0]
|
|
91483
|
+
result->files = fs.Glob(StringValue::Get(inputs[0]));
|
|
91246
91484
|
return_types.emplace_back(LogicalType::VARCHAR);
|
|
91247
91485
|
names.emplace_back("file");
|
|
91248
91486
|
return move(result);
|
|
@@ -91960,7 +92198,7 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
91960
92198
|
auto result = make_unique<ReadCSVData>();
|
|
91961
92199
|
auto &options = result->options;
|
|
91962
92200
|
|
|
91963
|
-
|
|
92201
|
+
auto &file_pattern = StringValue::Get(inputs[0]);
|
|
91964
92202
|
|
|
91965
92203
|
auto &fs = FileSystem::GetFileSystem(context);
|
|
91966
92204
|
result->files = fs.Glob(file_pattern);
|
|
@@ -91970,20 +92208,20 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
91970
92208
|
|
|
91971
92209
|
for (auto &kv : named_parameters) {
|
|
91972
92210
|
if (kv.first == "auto_detect") {
|
|
91973
|
-
options.auto_detect = kv.second
|
|
92211
|
+
options.auto_detect = BooleanValue::Get(kv.second);
|
|
91974
92212
|
} else if (kv.first == "sep" || kv.first == "delim") {
|
|
91975
|
-
options.SetDelimiter(kv.second
|
|
92213
|
+
options.SetDelimiter(StringValue::Get(kv.second));
|
|
91976
92214
|
} else if (kv.first == "header") {
|
|
91977
|
-
options.header = kv.second
|
|
92215
|
+
options.header = BooleanValue::Get(kv.second);
|
|
91978
92216
|
options.has_header = true;
|
|
91979
92217
|
} else if (kv.first == "quote") {
|
|
91980
|
-
options.quote = kv.second
|
|
92218
|
+
options.quote = StringValue::Get(kv.second);
|
|
91981
92219
|
options.has_quote = true;
|
|
91982
92220
|
} else if (kv.first == "escape") {
|
|
91983
|
-
options.escape = kv.second
|
|
92221
|
+
options.escape = StringValue::Get(kv.second);
|
|
91984
92222
|
options.has_escape = true;
|
|
91985
92223
|
} else if (kv.first == "nullstr") {
|
|
91986
|
-
options.null_str = kv.second
|
|
92224
|
+
options.null_str = StringValue::Get(kv.second);
|
|
91987
92225
|
} else if (kv.first == "sample_size") {
|
|
91988
92226
|
int64_t sample_size = kv.second.GetValue<int64_t>();
|
|
91989
92227
|
if (sample_size < 1 && sample_size != -1) {
|
|
@@ -92014,11 +92252,11 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
92014
92252
|
throw BinderException("Unsupported parameter for SAMPLE_CHUNKS: cannot be smaller than 1");
|
|
92015
92253
|
}
|
|
92016
92254
|
} else if (kv.first == "all_varchar") {
|
|
92017
|
-
options.all_varchar = kv.second
|
|
92255
|
+
options.all_varchar = BooleanValue::Get(kv.second);
|
|
92018
92256
|
} else if (kv.first == "dateformat") {
|
|
92019
92257
|
options.has_format[LogicalTypeId::DATE] = true;
|
|
92020
92258
|
auto &date_format = options.date_format[LogicalTypeId::DATE];
|
|
92021
|
-
date_format.format_specifier = kv.second
|
|
92259
|
+
date_format.format_specifier = StringValue::Get(kv.second);
|
|
92022
92260
|
string error = StrTimeFormat::ParseFormatSpecifier(date_format.format_specifier, date_format);
|
|
92023
92261
|
if (!error.empty()) {
|
|
92024
92262
|
throw InvalidInputException("Could not parse DATEFORMAT: %s", error.c_str());
|
|
@@ -92026,35 +92264,36 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
92026
92264
|
} else if (kv.first == "timestampformat") {
|
|
92027
92265
|
options.has_format[LogicalTypeId::TIMESTAMP] = true;
|
|
92028
92266
|
auto ×tamp_format = options.date_format[LogicalTypeId::TIMESTAMP];
|
|
92029
|
-
timestamp_format.format_specifier = kv.second
|
|
92267
|
+
timestamp_format.format_specifier = StringValue::Get(kv.second);
|
|
92030
92268
|
string error = StrTimeFormat::ParseFormatSpecifier(timestamp_format.format_specifier, timestamp_format);
|
|
92031
92269
|
if (!error.empty()) {
|
|
92032
92270
|
throw InvalidInputException("Could not parse TIMESTAMPFORMAT: %s", error.c_str());
|
|
92033
92271
|
}
|
|
92034
92272
|
} else if (kv.first == "normalize_names") {
|
|
92035
|
-
options.normalize_names = kv.second
|
|
92273
|
+
options.normalize_names = BooleanValue::Get(kv.second);
|
|
92036
92274
|
} else if (kv.first == "columns") {
|
|
92037
92275
|
auto &child_type = kv.second.type();
|
|
92038
92276
|
if (child_type.id() != LogicalTypeId::STRUCT) {
|
|
92039
92277
|
throw BinderException("read_csv columns requires a a struct as input");
|
|
92040
92278
|
}
|
|
92041
|
-
|
|
92042
|
-
|
|
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++) {
|
|
92043
92282
|
auto &name = StructType::GetChildName(child_type, i);
|
|
92044
|
-
auto &val =
|
|
92283
|
+
auto &val = struct_children[i];
|
|
92045
92284
|
names.push_back(name);
|
|
92046
92285
|
if (val.type().id() != LogicalTypeId::VARCHAR) {
|
|
92047
92286
|
throw BinderException("read_csv requires a type specification as string");
|
|
92048
92287
|
}
|
|
92049
|
-
return_types.emplace_back(TransformStringToLogicalType(val
|
|
92288
|
+
return_types.emplace_back(TransformStringToLogicalType(StringValue::Get(val)));
|
|
92050
92289
|
}
|
|
92051
92290
|
if (names.empty()) {
|
|
92052
92291
|
throw BinderException("read_csv requires at least a single column as input!");
|
|
92053
92292
|
}
|
|
92054
92293
|
} else if (kv.first == "compression") {
|
|
92055
|
-
options.compression = FileCompressionTypeFromString(kv.second
|
|
92294
|
+
options.compression = FileCompressionTypeFromString(StringValue::Get(kv.second));
|
|
92056
92295
|
} else if (kv.first == "filename") {
|
|
92057
|
-
result->include_file_name = kv.second
|
|
92296
|
+
result->include_file_name = BooleanValue::Get(kv.second);
|
|
92058
92297
|
} else if (kv.first == "skip") {
|
|
92059
92298
|
options.skip_rows = kv.second.GetValue<int64_t>();
|
|
92060
92299
|
}
|
|
@@ -94969,7 +95208,7 @@ static vector<TestType> GetTestTypes() {
|
|
|
94969
95208
|
result.emplace_back(LogicalType::DOUBLE, "double");
|
|
94970
95209
|
result.emplace_back(LogicalType::DECIMAL(4, 1), "dec_4_1");
|
|
94971
95210
|
result.emplace_back(LogicalType::DECIMAL(9, 4), "dec_9_4");
|
|
94972
|
-
result.emplace_back(LogicalType::DECIMAL(18, 6), "
|
|
95211
|
+
result.emplace_back(LogicalType::DECIMAL(18, 6), "dec_18_6");
|
|
94973
95212
|
result.emplace_back(LogicalType::DECIMAL(38, 10), "dec38_10");
|
|
94974
95213
|
result.emplace_back(LogicalType::UUID, "uuid");
|
|
94975
95214
|
// interval
|
|
@@ -95536,23 +95775,23 @@ void TableScanPushdownComplexFilter(ClientContext &context, LogicalGet &get, Fun
|
|
|
95536
95775
|
break;
|
|
95537
95776
|
}
|
|
95538
95777
|
}
|
|
95539
|
-
if (!equal_value.
|
|
95778
|
+
if (!equal_value.IsNull() || !low_value.IsNull() || !high_value.IsNull()) {
|
|
95540
95779
|
// we can scan this index using this predicate: try a scan
|
|
95541
95780
|
auto &transaction = Transaction::GetTransaction(context);
|
|
95542
95781
|
unique_ptr<IndexScanState> index_state;
|
|
95543
|
-
if (!equal_value.
|
|
95782
|
+
if (!equal_value.IsNull()) {
|
|
95544
95783
|
// equality predicate
|
|
95545
95784
|
index_state =
|
|
95546
95785
|
index.InitializeScanSinglePredicate(transaction, equal_value, ExpressionType::COMPARE_EQUAL);
|
|
95547
|
-
} else if (!low_value.
|
|
95786
|
+
} else if (!low_value.IsNull() && !high_value.IsNull()) {
|
|
95548
95787
|
// two-sided predicate
|
|
95549
95788
|
index_state = index.InitializeScanTwoPredicates(transaction, low_value, low_comparison_type, high_value,
|
|
95550
95789
|
high_comparison_type);
|
|
95551
|
-
} else if (!low_value.
|
|
95790
|
+
} else if (!low_value.IsNull()) {
|
|
95552
95791
|
// less than predicate
|
|
95553
95792
|
index_state = index.InitializeScanSinglePredicate(transaction, low_value, low_comparison_type);
|
|
95554
95793
|
} else {
|
|
95555
|
-
D_ASSERT(!high_value.
|
|
95794
|
+
D_ASSERT(!high_value.IsNull());
|
|
95556
95795
|
index_state = index.InitializeScanSinglePredicate(transaction, high_value, high_comparison_type);
|
|
95557
95796
|
}
|
|
95558
95797
|
if (index.Scan(transaction, storage, *index_state, STANDARD_VECTOR_SIZE, bind_data.result_ids)) {
|
|
@@ -95645,7 +95884,7 @@ static void UnnestFunction(ClientContext &context, const FunctionData *bind_data
|
|
|
95645
95884
|
auto &bind_data = (UnnestFunctionData &)*bind_data_p;
|
|
95646
95885
|
auto &state = (UnnestOperatorData &)*operator_state;
|
|
95647
95886
|
|
|
95648
|
-
auto &list_value = bind_data.value
|
|
95887
|
+
auto &list_value = ListValue::GetChildren(bind_data.value);
|
|
95649
95888
|
idx_t count = 0;
|
|
95650
95889
|
for (; state.current_count < list_value.size() && count < STANDARD_VECTOR_SIZE; state.current_count++) {
|
|
95651
95890
|
output.data[0].SetValue(count, list_value[state.current_count]);
|
|
@@ -96416,7 +96655,7 @@ idx_t duckdb_arrow_rows_changed(duckdb_arrow result) {
|
|
|
96416
96655
|
idx_t row_count = wrapper->result->collection.Count();
|
|
96417
96656
|
if (row_count > 0 && StatementTypeReturnChanges(wrapper->result->statement_type)) {
|
|
96418
96657
|
auto row_changes = wrapper->result->GetValue(0, 0);
|
|
96419
|
-
if (!row_changes.
|
|
96658
|
+
if (!row_changes.IsNull() && row_changes.TryCastAs(LogicalType::BIGINT)) {
|
|
96420
96659
|
rows_changed = row_changes.GetValue<int64_t>();
|
|
96421
96660
|
}
|
|
96422
96661
|
}
|
|
@@ -96980,7 +97219,7 @@ namespace duckdb {
|
|
|
96980
97219
|
template <class T>
|
|
96981
97220
|
void WriteData(duckdb_result *out, ChunkCollection &source, idx_t col) {
|
|
96982
97221
|
idx_t row = 0;
|
|
96983
|
-
auto target = (T *)out->
|
|
97222
|
+
auto target = (T *)out->__deprecated_columns[col].__deprecated_data;
|
|
96984
97223
|
for (auto &chunk : source.Chunks()) {
|
|
96985
97224
|
auto source = FlatVector::GetData<T>(chunk->data[col]);
|
|
96986
97225
|
auto &mask = FlatVector::Validity(chunk->data[col]);
|
|
@@ -97003,46 +97242,49 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97003
97242
|
memset(out, 0, sizeof(duckdb_result));
|
|
97004
97243
|
if (!result->success) {
|
|
97005
97244
|
// write the error message
|
|
97006
|
-
out->
|
|
97245
|
+
out->__deprecated_error_message = strdup(result->error.c_str());
|
|
97007
97246
|
return DuckDBError;
|
|
97008
97247
|
}
|
|
97009
97248
|
// copy the data
|
|
97010
97249
|
// first write the meta data
|
|
97011
|
-
out->
|
|
97012
|
-
out->
|
|
97013
|
-
out->
|
|
97014
|
-
if (out->
|
|
97250
|
+
out->__deprecated_column_count = result->types.size();
|
|
97251
|
+
out->__deprecated_row_count = result->collection.Count();
|
|
97252
|
+
out->__deprecated_rows_changed = 0;
|
|
97253
|
+
if (out->__deprecated_row_count > 0 && StatementTypeReturnChanges(result->statement_type)) {
|
|
97015
97254
|
// update total changes
|
|
97016
97255
|
auto row_changes = result->GetValue(0, 0);
|
|
97017
|
-
if (!row_changes.
|
|
97018
|
-
out->
|
|
97256
|
+
if (!row_changes.IsNull() && row_changes.TryCastAs(LogicalType::BIGINT)) {
|
|
97257
|
+
out->__deprecated_rows_changed = row_changes.GetValue<int64_t>();
|
|
97019
97258
|
}
|
|
97020
97259
|
}
|
|
97021
|
-
out->
|
|
97022
|
-
if (!out->
|
|
97260
|
+
out->__deprecated_columns = (duckdb_column *)duckdb_malloc(sizeof(duckdb_column) * out->__deprecated_column_count);
|
|
97261
|
+
if (!out->__deprecated_columns) { // LCOV_EXCL_START
|
|
97023
97262
|
// malloc failure
|
|
97024
97263
|
return DuckDBError;
|
|
97025
97264
|
} // LCOV_EXCL_STOP
|
|
97026
97265
|
|
|
97027
97266
|
// zero initialize the columns (so we can cleanly delete it in case a malloc fails)
|
|
97028
|
-
memset(out->
|
|
97029
|
-
for (idx_t i = 0; i < out->
|
|
97030
|
-
out->
|
|
97031
|
-
out->
|
|
97032
|
-
out->
|
|
97033
|
-
|
|
97034
|
-
|
|
97267
|
+
memset(out->__deprecated_columns, 0, sizeof(duckdb_column) * out->__deprecated_column_count);
|
|
97268
|
+
for (idx_t i = 0; i < out->__deprecated_column_count; i++) {
|
|
97269
|
+
out->__deprecated_columns[i].__deprecated_type = ConvertCPPTypeToC(result->types[i]);
|
|
97270
|
+
out->__deprecated_columns[i].__deprecated_name = strdup(result->names[i].c_str());
|
|
97271
|
+
out->__deprecated_columns[i].__deprecated_nullmask =
|
|
97272
|
+
(bool *)duckdb_malloc(sizeof(bool) * out->__deprecated_row_count);
|
|
97273
|
+
out->__deprecated_columns[i].__deprecated_data =
|
|
97274
|
+
duckdb_malloc(GetCTypeSize(out->__deprecated_columns[i].__deprecated_type) * out->__deprecated_row_count);
|
|
97275
|
+
if (!out->__deprecated_columns[i].__deprecated_nullmask || !out->__deprecated_columns[i].__deprecated_name ||
|
|
97276
|
+
!out->__deprecated_columns[i].__deprecated_data) { // LCOV_EXCL_START
|
|
97035
97277
|
// malloc failure
|
|
97036
97278
|
return DuckDBError;
|
|
97037
97279
|
} // LCOV_EXCL_STOP
|
|
97038
97280
|
}
|
|
97039
97281
|
// now write the data
|
|
97040
|
-
for (idx_t col = 0; col < out->
|
|
97282
|
+
for (idx_t col = 0; col < out->__deprecated_column_count; col++) {
|
|
97041
97283
|
// first set the nullmask
|
|
97042
97284
|
idx_t row = 0;
|
|
97043
97285
|
for (auto &chunk : result->collection.Chunks()) {
|
|
97044
97286
|
for (idx_t k = 0; k < chunk->size(); k++) {
|
|
97045
|
-
out->
|
|
97287
|
+
out->__deprecated_columns[col].__deprecated_nullmask[row++] = FlatVector::IsNull(chunk->data[col], k);
|
|
97046
97288
|
}
|
|
97047
97289
|
}
|
|
97048
97290
|
// then write the data
|
|
@@ -97093,7 +97335,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97093
97335
|
break;
|
|
97094
97336
|
case LogicalTypeId::VARCHAR: {
|
|
97095
97337
|
idx_t row = 0;
|
|
97096
|
-
auto target = (const char **)out->
|
|
97338
|
+
auto target = (const char **)out->__deprecated_columns[col].__deprecated_data;
|
|
97097
97339
|
for (auto &chunk : result->collection.Chunks()) {
|
|
97098
97340
|
auto source = FlatVector::GetData<string_t>(chunk->data[col]);
|
|
97099
97341
|
for (idx_t k = 0; k < chunk->size(); k++) {
|
|
@@ -97113,7 +97355,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97113
97355
|
}
|
|
97114
97356
|
case LogicalTypeId::BLOB: {
|
|
97115
97357
|
idx_t row = 0;
|
|
97116
|
-
auto target = (duckdb_blob *)out->
|
|
97358
|
+
auto target = (duckdb_blob *)out->__deprecated_columns[col].__deprecated_data;
|
|
97117
97359
|
for (auto &chunk : result->collection.Chunks()) {
|
|
97118
97360
|
auto source = FlatVector::GetData<string_t>(chunk->data[col]);
|
|
97119
97361
|
for (idx_t k = 0; k < chunk->size(); k++) {
|
|
@@ -97135,7 +97377,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97135
97377
|
case LogicalTypeId::TIMESTAMP_MS:
|
|
97136
97378
|
case LogicalTypeId::TIMESTAMP_SEC: {
|
|
97137
97379
|
idx_t row = 0;
|
|
97138
|
-
auto target = (timestamp_t *)out->
|
|
97380
|
+
auto target = (timestamp_t *)out->__deprecated_columns[col].__deprecated_data;
|
|
97139
97381
|
for (auto &chunk : result->collection.Chunks()) {
|
|
97140
97382
|
auto source = FlatVector::GetData<timestamp_t>(chunk->data[col]);
|
|
97141
97383
|
|
|
@@ -97157,7 +97399,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97157
97399
|
}
|
|
97158
97400
|
case LogicalTypeId::HUGEINT: {
|
|
97159
97401
|
idx_t row = 0;
|
|
97160
|
-
auto target = (duckdb_hugeint *)out->
|
|
97402
|
+
auto target = (duckdb_hugeint *)out->__deprecated_columns[col].__deprecated_data;
|
|
97161
97403
|
for (auto &chunk : result->collection.Chunks()) {
|
|
97162
97404
|
auto source = FlatVector::GetData<hugeint_t>(chunk->data[col]);
|
|
97163
97405
|
for (idx_t k = 0; k < chunk->size(); k++) {
|
|
@@ -97172,7 +97414,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97172
97414
|
}
|
|
97173
97415
|
case LogicalTypeId::INTERVAL: {
|
|
97174
97416
|
idx_t row = 0;
|
|
97175
|
-
auto target = (duckdb_interval *)out->
|
|
97417
|
+
auto target = (duckdb_interval *)out->__deprecated_columns[col].__deprecated_data;
|
|
97176
97418
|
for (auto &chunk : result->collection.Chunks()) {
|
|
97177
97419
|
auto source = FlatVector::GetData<interval_t>(chunk->data[col]);
|
|
97178
97420
|
for (idx_t k = 0; k < chunk->size(); k++) {
|
|
@@ -97198,101 +97440,101 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
|
|
|
97198
97440
|
} // namespace duckdb
|
|
97199
97441
|
|
|
97200
97442
|
static void DuckdbDestroyColumn(duckdb_column column, idx_t count) {
|
|
97201
|
-
if (column.
|
|
97202
|
-
if (column.
|
|
97443
|
+
if (column.__deprecated_data) {
|
|
97444
|
+
if (column.__deprecated_type == DUCKDB_TYPE_VARCHAR) {
|
|
97203
97445
|
// varchar, delete individual strings
|
|
97204
|
-
auto data = (char **)column.
|
|
97446
|
+
auto data = (char **)column.__deprecated_data;
|
|
97205
97447
|
for (idx_t i = 0; i < count; i++) {
|
|
97206
97448
|
if (data[i]) {
|
|
97207
97449
|
duckdb_free(data[i]);
|
|
97208
97450
|
}
|
|
97209
97451
|
}
|
|
97210
|
-
} else if (column.
|
|
97452
|
+
} else if (column.__deprecated_type == DUCKDB_TYPE_BLOB) {
|
|
97211
97453
|
// blob, delete individual blobs
|
|
97212
|
-
auto data = (duckdb_blob *)column.
|
|
97454
|
+
auto data = (duckdb_blob *)column.__deprecated_data;
|
|
97213
97455
|
for (idx_t i = 0; i < count; i++) {
|
|
97214
97456
|
if (data[i].data) {
|
|
97215
97457
|
duckdb_free((void *)data[i].data);
|
|
97216
97458
|
}
|
|
97217
97459
|
}
|
|
97218
97460
|
}
|
|
97219
|
-
duckdb_free(column.
|
|
97461
|
+
duckdb_free(column.__deprecated_data);
|
|
97220
97462
|
}
|
|
97221
|
-
if (column.
|
|
97222
|
-
duckdb_free(column.
|
|
97463
|
+
if (column.__deprecated_nullmask) {
|
|
97464
|
+
duckdb_free(column.__deprecated_nullmask);
|
|
97223
97465
|
}
|
|
97224
|
-
if (column.
|
|
97225
|
-
duckdb_free(column.
|
|
97466
|
+
if (column.__deprecated_name) {
|
|
97467
|
+
duckdb_free(column.__deprecated_name);
|
|
97226
97468
|
}
|
|
97227
97469
|
}
|
|
97228
97470
|
|
|
97229
97471
|
void duckdb_destroy_result(duckdb_result *result) {
|
|
97230
|
-
if (result->
|
|
97231
|
-
duckdb_free(result->
|
|
97472
|
+
if (result->__deprecated_error_message) {
|
|
97473
|
+
duckdb_free(result->__deprecated_error_message);
|
|
97232
97474
|
}
|
|
97233
|
-
if (result->
|
|
97234
|
-
for (idx_t i = 0; i < result->
|
|
97235
|
-
DuckdbDestroyColumn(result->
|
|
97475
|
+
if (result->__deprecated_columns) {
|
|
97476
|
+
for (idx_t i = 0; i < result->__deprecated_column_count; i++) {
|
|
97477
|
+
DuckdbDestroyColumn(result->__deprecated_columns[i], result->__deprecated_row_count);
|
|
97236
97478
|
}
|
|
97237
|
-
duckdb_free(result->
|
|
97479
|
+
duckdb_free(result->__deprecated_columns);
|
|
97238
97480
|
}
|
|
97239
97481
|
memset(result, 0, sizeof(duckdb_result));
|
|
97240
97482
|
}
|
|
97241
97483
|
|
|
97242
97484
|
const char *duckdb_column_name(duckdb_result *result, idx_t col) {
|
|
97243
|
-
if (!result || col >= result->
|
|
97485
|
+
if (!result || col >= result->__deprecated_column_count) {
|
|
97244
97486
|
return nullptr;
|
|
97245
97487
|
}
|
|
97246
|
-
return result->
|
|
97488
|
+
return result->__deprecated_columns[col].__deprecated_name;
|
|
97247
97489
|
}
|
|
97248
97490
|
|
|
97249
97491
|
duckdb_type duckdb_column_type(duckdb_result *result, idx_t col) {
|
|
97250
|
-
if (!result || col >= result->
|
|
97492
|
+
if (!result || col >= result->__deprecated_column_count) {
|
|
97251
97493
|
return DUCKDB_TYPE_INVALID;
|
|
97252
97494
|
}
|
|
97253
|
-
return result->
|
|
97495
|
+
return result->__deprecated_columns[col].__deprecated_type;
|
|
97254
97496
|
}
|
|
97255
97497
|
|
|
97256
97498
|
idx_t duckdb_column_count(duckdb_result *result) {
|
|
97257
97499
|
if (!result) {
|
|
97258
97500
|
return 0;
|
|
97259
97501
|
}
|
|
97260
|
-
return result->
|
|
97502
|
+
return result->__deprecated_column_count;
|
|
97261
97503
|
}
|
|
97262
97504
|
|
|
97263
97505
|
idx_t duckdb_row_count(duckdb_result *result) {
|
|
97264
97506
|
if (!result) {
|
|
97265
97507
|
return 0;
|
|
97266
97508
|
}
|
|
97267
|
-
return result->
|
|
97509
|
+
return result->__deprecated_row_count;
|
|
97268
97510
|
}
|
|
97269
97511
|
|
|
97270
97512
|
idx_t duckdb_rows_changed(duckdb_result *result) {
|
|
97271
97513
|
if (!result) {
|
|
97272
97514
|
return 0;
|
|
97273
97515
|
}
|
|
97274
|
-
return result->
|
|
97516
|
+
return result->__deprecated_rows_changed;
|
|
97275
97517
|
}
|
|
97276
97518
|
|
|
97277
97519
|
void *duckdb_column_data(duckdb_result *result, idx_t col) {
|
|
97278
|
-
if (!result || col >= result->
|
|
97520
|
+
if (!result || col >= result->__deprecated_column_count) {
|
|
97279
97521
|
return nullptr;
|
|
97280
97522
|
}
|
|
97281
|
-
return result->
|
|
97523
|
+
return result->__deprecated_columns[col].__deprecated_data;
|
|
97282
97524
|
}
|
|
97283
97525
|
|
|
97284
97526
|
bool *duckdb_nullmask_data(duckdb_result *result, idx_t col) {
|
|
97285
|
-
if (!result || col >= result->
|
|
97527
|
+
if (!result || col >= result->__deprecated_column_count) {
|
|
97286
97528
|
return nullptr;
|
|
97287
97529
|
}
|
|
97288
|
-
return result->
|
|
97530
|
+
return result->__deprecated_columns[col].__deprecated_nullmask;
|
|
97289
97531
|
}
|
|
97290
97532
|
|
|
97291
97533
|
char *duckdb_result_error(duckdb_result *result) {
|
|
97292
97534
|
if (!result) {
|
|
97293
97535
|
return nullptr;
|
|
97294
97536
|
}
|
|
97295
|
-
return result->
|
|
97537
|
+
return result->__deprecated_error_message;
|
|
97296
97538
|
}
|
|
97297
97539
|
|
|
97298
97540
|
|
|
@@ -97323,8 +97565,8 @@ namespace duckdb {
|
|
|
97323
97565
|
//===--------------------------------------------------------------------===//
|
|
97324
97566
|
template <class T>
|
|
97325
97567
|
T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) {
|
|
97326
|
-
D_ASSERT(row < result->
|
|
97327
|
-
return ((T *)result->
|
|
97568
|
+
D_ASSERT(row < result->__deprecated_row_count);
|
|
97569
|
+
return ((T *)result->__deprecated_columns[col].__deprecated_data)[row];
|
|
97328
97570
|
}
|
|
97329
97571
|
|
|
97330
97572
|
//===--------------------------------------------------------------------===//
|
|
@@ -97445,10 +97687,10 @@ RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) {
|
|
|
97445
97687
|
}
|
|
97446
97688
|
|
|
97447
97689
|
static bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row) {
|
|
97448
|
-
if (!result || col >= result->
|
|
97690
|
+
if (!result || col >= result->__deprecated_column_count || row >= result->__deprecated_row_count) {
|
|
97449
97691
|
return false;
|
|
97450
97692
|
}
|
|
97451
|
-
if (result->
|
|
97693
|
+
if (result->__deprecated_columns[col].__deprecated_nullmask[row]) {
|
|
97452
97694
|
return false;
|
|
97453
97695
|
}
|
|
97454
97696
|
return true;
|
|
@@ -97459,7 +97701,7 @@ static RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row
|
|
|
97459
97701
|
if (!CanFetchValue(result, col, row)) {
|
|
97460
97702
|
return FetchDefaultValue::Operation<RESULT_TYPE>();
|
|
97461
97703
|
}
|
|
97462
|
-
switch (result->
|
|
97704
|
+
switch (result->__deprecated_columns[col].__deprecated_type) {
|
|
97463
97705
|
case DUCKDB_TYPE_BOOLEAN:
|
|
97464
97706
|
return TryCastCInternal<bool, RESULT_TYPE, OP>(result, col, row);
|
|
97465
97707
|
case DUCKDB_TYPE_TINYINT:
|
|
@@ -97600,7 +97842,7 @@ char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row)
|
|
|
97600
97842
|
}
|
|
97601
97843
|
|
|
97602
97844
|
duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row) {
|
|
97603
|
-
if (CanFetchValue(result, col, row) && result->
|
|
97845
|
+
if (CanFetchValue(result, col, row) && result->__deprecated_columns[col].__deprecated_type == DUCKDB_TYPE_BLOB) {
|
|
97604
97846
|
auto internal_result = UnsafeFetch<duckdb_blob>(result, col, row);
|
|
97605
97847
|
|
|
97606
97848
|
duckdb_blob result_blob;
|
|
@@ -97613,10 +97855,10 @@ duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row) {
|
|
|
97613
97855
|
}
|
|
97614
97856
|
|
|
97615
97857
|
bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row) {
|
|
97616
|
-
if (!result || col >= result->
|
|
97858
|
+
if (!result || col >= result->__deprecated_column_count || row >= result->__deprecated_row_count) {
|
|
97617
97859
|
return false;
|
|
97618
97860
|
}
|
|
97619
|
-
return result->
|
|
97861
|
+
return result->__deprecated_columns[col].__deprecated_nullmask[row];
|
|
97620
97862
|
}
|
|
97621
97863
|
|
|
97622
97864
|
//===----------------------------------------------------------------------===//
|
|
@@ -108149,7 +108391,7 @@ string MaterializedQueryResult::ToString() {
|
|
|
108149
108391
|
for (idx_t j = 0; j < collection.Count(); j++) {
|
|
108150
108392
|
for (idx_t i = 0; i < collection.ColumnCount(); i++) {
|
|
108151
108393
|
auto val = collection.GetValue(i, j);
|
|
108152
|
-
result += val.
|
|
108394
|
+
result += val.IsNull() ? "NULL" : val.ToString();
|
|
108153
108395
|
result += "\t";
|
|
108154
108396
|
}
|
|
108155
108397
|
result += "\n";
|
|
@@ -113781,7 +114023,7 @@ bool FilterCombiner::HasFilters() {
|
|
|
113781
114023
|
// break;
|
|
113782
114024
|
// } else {
|
|
113783
114025
|
// auto &const_value_expr = (BoundConstantExpression &)*comp_in_exp.children[i].get();
|
|
113784
|
-
// if (const_value_expr.value.
|
|
114026
|
+
// if (const_value_expr.value.IsNull()) {
|
|
113785
114027
|
// return checks;
|
|
113786
114028
|
// }
|
|
113787
114029
|
// if (!min && !max) {
|
|
@@ -113943,18 +114185,16 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
113943
114185
|
//! This is a like function.
|
|
113944
114186
|
auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get();
|
|
113945
114187
|
auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get();
|
|
113946
|
-
|
|
114188
|
+
auto like_string = StringValue::Get(constant_value_expr.value);
|
|
113947
114189
|
if (like_string.empty()) {
|
|
113948
114190
|
continue;
|
|
113949
114191
|
}
|
|
113950
114192
|
auto column_index = column_ids[column_ref.binding.column_index];
|
|
113951
|
-
auto const_value = constant_value_expr.value.Copy();
|
|
113952
|
-
const_value.str_value = like_string;
|
|
113953
114193
|
//! Here the like must be transformed to a BOUND COMPARISON geq le
|
|
113954
114194
|
auto lower_bound =
|
|
113955
|
-
make_unique<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO,
|
|
113956
|
-
|
|
113957
|
-
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));
|
|
113958
114198
|
table_filters.PushFilter(column_index, move(lower_bound));
|
|
113959
114199
|
table_filters.PushFilter(column_index, move(upper_bound));
|
|
113960
114200
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
@@ -113964,8 +114204,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
113964
114204
|
//! This is a like function.
|
|
113965
114205
|
auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get();
|
|
113966
114206
|
auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get();
|
|
113967
|
-
|
|
113968
|
-
auto const_value = constant_value_expr.value.Copy();
|
|
114207
|
+
auto &like_string = StringValue::Get(constant_value_expr.value);
|
|
113969
114208
|
if (like_string[0] == '%' || like_string[0] == '_') {
|
|
113970
114209
|
//! We have no prefix so nothing to pushdown
|
|
113971
114210
|
break;
|
|
@@ -113979,19 +114218,18 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
113979
114218
|
}
|
|
113980
114219
|
prefix += c;
|
|
113981
114220
|
}
|
|
113982
|
-
const_value.str_value = prefix;
|
|
113983
114221
|
auto column_index = column_ids[column_ref.binding.column_index];
|
|
113984
114222
|
if (equality) {
|
|
113985
114223
|
//! Here the like can be transformed to an equality query
|
|
113986
|
-
auto equal_filter = make_unique<ConstantFilter>(ExpressionType::COMPARE_EQUAL,
|
|
114224
|
+
auto equal_filter = make_unique<ConstantFilter>(ExpressionType::COMPARE_EQUAL, Value(prefix));
|
|
113987
114225
|
table_filters.PushFilter(column_index, move(equal_filter));
|
|
113988
114226
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
113989
114227
|
} else {
|
|
113990
114228
|
//! Here the like must be transformed to a BOUND COMPARISON geq le
|
|
113991
114229
|
auto lower_bound =
|
|
113992
|
-
make_unique<ConstantFilter>(ExpressionType::COMPARE_GREATERTHANOREQUALTO,
|
|
113993
|
-
|
|
113994
|
-
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));
|
|
113995
114233
|
table_filters.PushFilter(column_index, move(lower_bound));
|
|
113996
114234
|
table_filters.PushFilter(column_index, move(upper_bound));
|
|
113997
114235
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
@@ -113999,7 +114237,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
113999
114237
|
}
|
|
114000
114238
|
} else if (remaining_filter->type == ExpressionType::COMPARE_IN) {
|
|
114001
114239
|
auto &func = (BoundOperatorExpression &)*remaining_filter;
|
|
114002
|
-
vector<
|
|
114240
|
+
vector<hugeint_t> in_values;
|
|
114003
114241
|
D_ASSERT(func.children.size() > 1);
|
|
114004
114242
|
if (func.children[0]->expression_class != ExpressionClass::BOUND_COLUMN_REF) {
|
|
114005
114243
|
continue;
|
|
@@ -114020,31 +114258,31 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114020
114258
|
continue;
|
|
114021
114259
|
}
|
|
114022
114260
|
auto &fst_const_value_expr = (BoundConstantExpression &)*func.children[1].get();
|
|
114261
|
+
auto &type = fst_const_value_expr.value.type();
|
|
114023
114262
|
|
|
114024
114263
|
//! Check if values are consecutive, if yes transform them to >= <= (only for integers)
|
|
114025
114264
|
// e.g. if we have x IN (1, 2, 3, 4, 5) we transform this into x >= 1 AND x <= 5
|
|
114026
|
-
if (!
|
|
114265
|
+
if (!type.IsIntegral()) {
|
|
114027
114266
|
continue;
|
|
114028
114267
|
}
|
|
114029
114268
|
|
|
114030
114269
|
bool can_simplify_in_clause = true;
|
|
114031
114270
|
for (idx_t i = 1; i < func.children.size(); i++) {
|
|
114032
114271
|
auto &const_value_expr = (BoundConstantExpression &)*func.children[i].get();
|
|
114033
|
-
if (const_value_expr.value.
|
|
114272
|
+
if (const_value_expr.value.IsNull()) {
|
|
114034
114273
|
can_simplify_in_clause = false;
|
|
114035
114274
|
break;
|
|
114036
114275
|
}
|
|
114037
|
-
in_values.push_back(const_value_expr.value);
|
|
114276
|
+
in_values.push_back(const_value_expr.value.GetValue<hugeint_t>());
|
|
114038
114277
|
}
|
|
114039
114278
|
if (!can_simplify_in_clause || in_values.empty()) {
|
|
114040
114279
|
continue;
|
|
114041
114280
|
}
|
|
114042
|
-
Value one(1);
|
|
114043
114281
|
|
|
114044
114282
|
sort(in_values.begin(), in_values.end());
|
|
114045
114283
|
|
|
114046
114284
|
for (idx_t in_val_idx = 1; in_val_idx < in_values.size(); in_val_idx++) {
|
|
114047
|
-
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) {
|
|
114048
114286
|
can_simplify_in_clause = false;
|
|
114049
114287
|
break;
|
|
114050
114288
|
}
|
|
@@ -114052,9 +114290,10 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
114052
114290
|
if (!can_simplify_in_clause) {
|
|
114053
114291
|
continue;
|
|
114054
114292
|
}
|
|
114055
|
-
auto lower_bound =
|
|
114056
|
-
|
|
114057
|
-
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()));
|
|
114058
114297
|
table_filters.PushFilter(column_index, move(lower_bound));
|
|
114059
114298
|
table_filters.PushFilter(column_index, move(upper_bound));
|
|
114060
114299
|
table_filters.PushFilter(column_index, make_unique<IsNotNullFilter>());
|
|
@@ -114095,7 +114334,7 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
|
|
|
114095
114334
|
idx_t equivalence_set = GetEquivalenceSet(node);
|
|
114096
114335
|
auto scalar = left_is_scalar ? comparison.left.get() : comparison.right.get();
|
|
114097
114336
|
auto constant_value = ExpressionExecutor::EvaluateScalar(*scalar);
|
|
114098
|
-
if (constant_value.
|
|
114337
|
+
if (constant_value.IsNull()) {
|
|
114099
114338
|
// comparisons with null are always null (i.e. will never result in rows)
|
|
114100
114339
|
return FilterResult::UNSATISFIABLE;
|
|
114101
114340
|
}
|
|
@@ -114177,7 +114416,7 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) {
|
|
|
114177
114416
|
// scalar condition, evaluate it
|
|
114178
114417
|
auto result = ExpressionExecutor::EvaluateScalar(*expr).CastAs(LogicalType::BOOLEAN);
|
|
114179
114418
|
// check if the filter passes
|
|
114180
|
-
if (result.
|
|
114419
|
+
if (result.IsNull() || !BooleanValue::Get(result)) {
|
|
114181
114420
|
// the filter does not pass the scalar test, create an empty result
|
|
114182
114421
|
return FilterResult::UNSATISFIABLE;
|
|
114183
114422
|
} else {
|
|
@@ -117804,7 +118043,7 @@ static bool FilterRemovesNull(ExpressionRewriter &rewriter, Expression *expr, un
|
|
|
117804
118043
|
// if the result of the expression with all expressions replaced with NULL is "NULL" or "false"
|
|
117805
118044
|
// then any extra entries generated by the LEFT OUTER JOIN will be filtered out!
|
|
117806
118045
|
// hence the LEFT OUTER JOIN is equivalent to an inner join
|
|
117807
|
-
if (val.
|
|
118046
|
+
if (val.IsNull() || !BooleanValue::Get(val)) {
|
|
117808
118047
|
return true;
|
|
117809
118048
|
}
|
|
117810
118049
|
}
|
|
@@ -118492,7 +118731,7 @@ unique_ptr<Expression> ArithmeticSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118492
118731
|
D_ASSERT(root->children.size() == 2);
|
|
118493
118732
|
(void)root;
|
|
118494
118733
|
// any arithmetic operator involving NULL is always NULL
|
|
118495
|
-
if (constant->value.
|
|
118734
|
+
if (constant->value.IsNull()) {
|
|
118496
118735
|
return make_unique<BoundConstantExpression>(Value(root->return_type));
|
|
118497
118736
|
}
|
|
118498
118737
|
auto &func_name = root->function.name;
|
|
@@ -118557,7 +118796,7 @@ unique_ptr<Expression> CaseSimplificationRule::Apply(LogicalOperator &op, vector
|
|
|
118557
118796
|
|
|
118558
118797
|
// fold based on the constant condition
|
|
118559
118798
|
auto condition = constant_value.CastAs(LogicalType::BOOLEAN);
|
|
118560
|
-
if (condition.
|
|
118799
|
+
if (condition.IsNull() || !BooleanValue::Get(condition)) {
|
|
118561
118800
|
// the condition is always false: remove this case check
|
|
118562
118801
|
root->case_checks.erase(root->case_checks.begin() + i);
|
|
118563
118802
|
i--;
|
|
@@ -118609,8 +118848,8 @@ unique_ptr<Expression> ComparisonSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118609
118848
|
if (!ExpressionExecutor::TryEvaluateScalar(*constant_expr, constant_value)) {
|
|
118610
118849
|
return nullptr;
|
|
118611
118850
|
}
|
|
118612
|
-
if (constant_value.
|
|
118613
|
-
|
|
118851
|
+
if (constant_value.IsNull() && !(expr->type == ExpressionType::COMPARE_NOT_DISTINCT_FROM ||
|
|
118852
|
+
expr->type == ExpressionType::COMPARE_DISTINCT_FROM)) {
|
|
118614
118853
|
// comparison with constant NULL, return NULL
|
|
118615
118854
|
return make_unique<BoundConstantExpression>(Value(LogicalType::BOOLEAN));
|
|
118616
118855
|
}
|
|
@@ -118683,12 +118922,12 @@ unique_ptr<Expression> ConjunctionSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118683
118922
|
return nullptr;
|
|
118684
118923
|
}
|
|
118685
118924
|
constant_value = constant_value.CastAs(LogicalType::BOOLEAN);
|
|
118686
|
-
if (constant_value.
|
|
118925
|
+
if (constant_value.IsNull()) {
|
|
118687
118926
|
// we can't simplify conjunctions with a constant NULL
|
|
118688
118927
|
return nullptr;
|
|
118689
118928
|
}
|
|
118690
118929
|
if (conjunction->type == ExpressionType::CONJUNCTION_AND) {
|
|
118691
|
-
if (!constant_value
|
|
118930
|
+
if (!BooleanValue::Get(constant_value)) {
|
|
118692
118931
|
// FALSE in AND, result of expression is false
|
|
118693
118932
|
return make_unique<BoundConstantExpression>(Value::BOOLEAN(false));
|
|
118694
118933
|
} else {
|
|
@@ -118697,7 +118936,7 @@ unique_ptr<Expression> ConjunctionSimplificationRule::Apply(LogicalOperator &op,
|
|
|
118697
118936
|
}
|
|
118698
118937
|
} else {
|
|
118699
118938
|
D_ASSERT(conjunction->type == ExpressionType::CONJUNCTION_OR);
|
|
118700
|
-
if (!constant_value
|
|
118939
|
+
if (!BooleanValue::Get(constant_value)) {
|
|
118701
118940
|
// FALSE in OR, remove the expression from the set
|
|
118702
118941
|
return RemoveExpression(*conjunction, constant_expr);
|
|
118703
118942
|
} else {
|
|
@@ -118741,7 +118980,6 @@ unique_ptr<Expression> ConstantFoldingRule::Apply(LogicalOperator &op, vector<Ex
|
|
|
118741
118980
|
D_ASSERT(root->IsFoldable() && root->type != ExpressionType::VALUE_CONSTANT);
|
|
118742
118981
|
|
|
118743
118982
|
// use an ExpressionExecutor to execute the expression
|
|
118744
|
-
|
|
118745
118983
|
Value result_value;
|
|
118746
118984
|
if (!ExpressionExecutor::TryEvaluateScalar(*root, result_value)) {
|
|
118747
118985
|
return nullptr;
|
|
@@ -118779,12 +119017,12 @@ unique_ptr<Expression> DatePartSimplificationRule::Apply(LogicalOperator &op, ve
|
|
|
118779
119017
|
auto &constant_expr = (BoundConstantExpression &)*bindings[1];
|
|
118780
119018
|
auto &constant = constant_expr.value;
|
|
118781
119019
|
|
|
118782
|
-
if (constant.
|
|
119020
|
+
if (constant.IsNull()) {
|
|
118783
119021
|
// NULL specifier: return constant NULL
|
|
118784
119022
|
return make_unique<BoundConstantExpression>(Value(date_part.return_type));
|
|
118785
119023
|
}
|
|
118786
119024
|
// otherwise check the specifier
|
|
118787
|
-
auto specifier = GetDatePartSpecifier(constant
|
|
119025
|
+
auto specifier = GetDatePartSpecifier(StringValue::Get(constant));
|
|
118788
119026
|
string new_function_name;
|
|
118789
119027
|
switch (specifier) {
|
|
118790
119028
|
case DatePartSpecifier::YEAR:
|
|
@@ -119031,12 +119269,12 @@ unique_ptr<Expression> EmptyNeedleRemovalRule::Apply(LogicalOperator &op, vector
|
|
|
119031
119269
|
|
|
119032
119270
|
auto prefix_value = ExpressionExecutor::EvaluateScalar(*prefix_expr);
|
|
119033
119271
|
|
|
119034
|
-
if (prefix_value.
|
|
119272
|
+
if (prefix_value.IsNull()) {
|
|
119035
119273
|
return make_unique<BoundConstantExpression>(Value(LogicalType::BOOLEAN));
|
|
119036
119274
|
}
|
|
119037
119275
|
|
|
119038
119276
|
D_ASSERT(prefix_value.type() == prefix_expr->return_type);
|
|
119039
|
-
auto needle_string = prefix_value
|
|
119277
|
+
auto &needle_string = StringValue::Get(prefix_value);
|
|
119040
119278
|
|
|
119041
119279
|
// PREFIX('xyz', '') is TRUE
|
|
119042
119280
|
// PREFIX(NULL, '') is NULL
|
|
@@ -119313,7 +119551,7 @@ unique_ptr<Expression> LikeOptimizationRule::Apply(LogicalOperator &op, vector<E
|
|
|
119313
119551
|
auto constant_expr = (BoundConstantExpression *)bindings[2];
|
|
119314
119552
|
D_ASSERT(root->children.size() == 2);
|
|
119315
119553
|
|
|
119316
|
-
if (constant_expr->value.
|
|
119554
|
+
if (constant_expr->value.IsNull()) {
|
|
119317
119555
|
return make_unique<BoundConstantExpression>(Value(root->return_type));
|
|
119318
119556
|
}
|
|
119319
119557
|
|
|
@@ -119324,7 +119562,7 @@ unique_ptr<Expression> LikeOptimizationRule::Apply(LogicalOperator &op, vector<E
|
|
|
119324
119562
|
|
|
119325
119563
|
auto constant_value = ExpressionExecutor::EvaluateScalar(*constant_expr);
|
|
119326
119564
|
D_ASSERT(constant_value.type() == constant_expr->return_type);
|
|
119327
|
-
auto patt_str = constant_value
|
|
119565
|
+
auto &patt_str = StringValue::Get(constant_value);
|
|
119328
119566
|
|
|
119329
119567
|
bool is_not_like = root->function.name == "!~~";
|
|
119330
119568
|
if (PatternIsConstant(patt_str)) {
|
|
@@ -119376,6 +119614,7 @@ unique_ptr<Expression> LikeOptimizationRule::ApplyRule(BoundFunctionExpression *
|
|
|
119376
119614
|
|
|
119377
119615
|
|
|
119378
119616
|
|
|
119617
|
+
|
|
119379
119618
|
namespace duckdb {
|
|
119380
119619
|
|
|
119381
119620
|
MoveConstantsRule::MoveConstantsRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
|
|
@@ -119403,31 +119642,63 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
|
119403
119642
|
auto outer_constant = (BoundConstantExpression *)bindings[1];
|
|
119404
119643
|
auto arithmetic = (BoundFunctionExpression *)bindings[2];
|
|
119405
119644
|
auto inner_constant = (BoundConstantExpression *)bindings[3];
|
|
119406
|
-
if (!arithmetic->return_type.
|
|
119645
|
+
if (!TypeIsIntegral(arithmetic->return_type.InternalType())) {
|
|
119407
119646
|
return nullptr;
|
|
119408
119647
|
}
|
|
119409
|
-
if (inner_constant->value.
|
|
119648
|
+
if (inner_constant->value.IsNull() || outer_constant->value.IsNull()) {
|
|
119410
119649
|
return make_unique<BoundConstantExpression>(Value(comparison->return_type));
|
|
119411
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);
|
|
119412
119654
|
|
|
119413
|
-
|
|
119655
|
+
idx_t arithmetic_child_index = arithmetic->children[0].get() == inner_constant ? 1 : 0;
|
|
119414
119656
|
auto &op_type = arithmetic->function.name;
|
|
119415
119657
|
if (op_type == "+") {
|
|
119416
119658
|
// [x + 1 COMP 10] OR [1 + x COMP 10]
|
|
119417
119659
|
// order does not matter in addition:
|
|
119418
119660
|
// simply change right side to 10-1 (outer_constant - inner_constant)
|
|
119419
|
-
|
|
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);
|
|
119420
119673
|
} else if (op_type == "-") {
|
|
119421
119674
|
// [x - 1 COMP 10] O R [1 - x COMP 10]
|
|
119422
119675
|
// order matters in subtraction:
|
|
119423
119676
|
if (arithmetic_child_index == 0) {
|
|
119424
119677
|
// [x - 1 COMP 10]
|
|
119425
119678
|
// change right side to 10+1 (outer_constant + inner_constant)
|
|
119426
|
-
|
|
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);
|
|
119427
119689
|
} else {
|
|
119428
119690
|
// [1 - x COMP 10]
|
|
119429
119691
|
// change right side to 1-10=-9
|
|
119430
|
-
|
|
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);
|
|
119431
119702
|
// in this case, we should also flip the comparison
|
|
119432
119703
|
// e.g. if we have [4 - x < 2] then we should have [x > 2]
|
|
119433
119704
|
comparison->type = FlipComparisionExpression(comparison->type);
|
|
@@ -119438,24 +119709,39 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
|
119438
119709
|
// order does not matter in multiplication:
|
|
119439
119710
|
// change right side to 10/2 (outer_constant / inner_constant)
|
|
119440
119711
|
// but ONLY if outer_constant is cleanly divisible by the inner_constant
|
|
119441
|
-
if (
|
|
119712
|
+
if (inner_value == 0) {
|
|
119442
119713
|
// x * 0, the result is either 0 or NULL
|
|
119443
|
-
//
|
|
119444
|
-
// on if 0 matches the comparison criteria with the RHS
|
|
119445
|
-
// 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
|
|
119446
119715
|
return nullptr;
|
|
119447
119716
|
}
|
|
119448
|
-
if (
|
|
119449
|
-
// not cleanly divisible
|
|
119450
|
-
|
|
119451
|
-
|
|
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
|
+
}
|
|
119452
119731
|
}
|
|
119453
|
-
if (
|
|
119732
|
+
if (inner_value < 0) {
|
|
119454
119733
|
// multiply by negative value, need to flip expression
|
|
119455
119734
|
comparison->type = FlipComparisionExpression(comparison->type);
|
|
119456
119735
|
}
|
|
119457
119736
|
// else divide the RHS by the LHS
|
|
119458
|
-
|
|
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);
|
|
119459
119745
|
}
|
|
119460
119746
|
// replace left side with x
|
|
119461
119747
|
// first extract x from the arithmetic expression
|
|
@@ -119503,7 +119789,7 @@ namespace duckdb {
|
|
|
119503
119789
|
|
|
119504
119790
|
unique_ptr<Expression> CastHugeintToSmallestType(unique_ptr<Expression> expr, NumericStatistics &num_stats) {
|
|
119505
119791
|
// Compute range
|
|
119506
|
-
if (num_stats.min.
|
|
119792
|
+
if (num_stats.min.IsNull() || num_stats.max.IsNull()) {
|
|
119507
119793
|
return expr;
|
|
119508
119794
|
}
|
|
119509
119795
|
|
|
@@ -119551,7 +119837,7 @@ unique_ptr<Expression> CastHugeintToSmallestType(unique_ptr<Expression> expr, Nu
|
|
|
119551
119837
|
template <class T>
|
|
119552
119838
|
unique_ptr<Expression> TemplatedCastToSmallestType(unique_ptr<Expression> expr, NumericStatistics &num_stats) {
|
|
119553
119839
|
// Compute range
|
|
119554
|
-
if (num_stats.min.
|
|
119840
|
+
if (num_stats.min.IsNull() || num_stats.max.IsNull()) {
|
|
119555
119841
|
return expr;
|
|
119556
119842
|
}
|
|
119557
119843
|
|
|
@@ -119825,7 +120111,7 @@ FilterPropagateResult StatisticsPropagator::PropagateComparison(BaseStatistics &
|
|
|
119825
120111
|
}
|
|
119826
120112
|
auto &lstats = (NumericStatistics &)left;
|
|
119827
120113
|
auto &rstats = (NumericStatistics &)right;
|
|
119828
|
-
if (lstats.min.
|
|
120114
|
+
if (lstats.min.IsNull() || lstats.max.IsNull() || rstats.min.IsNull() || rstats.max.IsNull()) {
|
|
119829
120115
|
// no stats available: nothing to prune
|
|
119830
120116
|
return FilterPropagateResult::NO_PRUNING_POSSIBLE;
|
|
119831
120117
|
}
|
|
@@ -119951,40 +120237,42 @@ unique_ptr<BaseStatistics> StatisticsPropagator::StatisticsFromValue(const Value
|
|
|
119951
120237
|
case PhysicalType::FLOAT:
|
|
119952
120238
|
case PhysicalType::DOUBLE: {
|
|
119953
120239
|
auto result = make_unique<NumericStatistics>(input.type(), input, input);
|
|
119954
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
120240
|
+
result->validity_stats = make_unique<ValidityStatistics>(input.IsNull(), !input.IsNull());
|
|
119955
120241
|
return move(result);
|
|
119956
120242
|
}
|
|
119957
120243
|
case PhysicalType::VARCHAR: {
|
|
119958
120244
|
auto result = make_unique<StringStatistics>(input.type());
|
|
119959
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
119960
|
-
if (!input.
|
|
119961
|
-
|
|
119962
|
-
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));
|
|
119963
120249
|
}
|
|
119964
120250
|
return move(result);
|
|
119965
120251
|
}
|
|
119966
120252
|
case PhysicalType::STRUCT: {
|
|
119967
120253
|
auto result = make_unique<StructStatistics>(input.type());
|
|
119968
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
119969
|
-
if (input.
|
|
120254
|
+
result->validity_stats = make_unique<ValidityStatistics>(input.IsNull(), !input.IsNull());
|
|
120255
|
+
if (input.IsNull()) {
|
|
119970
120256
|
for (auto &child_stat : result->child_stats) {
|
|
119971
120257
|
child_stat.reset();
|
|
119972
120258
|
}
|
|
119973
120259
|
} else {
|
|
119974
|
-
|
|
120260
|
+
auto &struct_children = StructValue::GetChildren(input);
|
|
120261
|
+
D_ASSERT(result->child_stats.size() == struct_children.size());
|
|
119975
120262
|
for (idx_t i = 0; i < result->child_stats.size(); i++) {
|
|
119976
|
-
result->child_stats[i] = StatisticsFromValue(
|
|
120263
|
+
result->child_stats[i] = StatisticsFromValue(struct_children[i]);
|
|
119977
120264
|
}
|
|
119978
120265
|
}
|
|
119979
120266
|
return move(result);
|
|
119980
120267
|
}
|
|
119981
120268
|
case PhysicalType::LIST: {
|
|
119982
120269
|
auto result = make_unique<ListStatistics>(input.type());
|
|
119983
|
-
result->validity_stats = make_unique<ValidityStatistics>(input.
|
|
119984
|
-
if (input.
|
|
120270
|
+
result->validity_stats = make_unique<ValidityStatistics>(input.IsNull(), !input.IsNull());
|
|
120271
|
+
if (input.IsNull()) {
|
|
119985
120272
|
result->child_stats.reset();
|
|
119986
120273
|
} else {
|
|
119987
|
-
|
|
120274
|
+
auto &list_children = ListValue::GetChildren(input);
|
|
120275
|
+
for (auto &child_element : list_children) {
|
|
119988
120276
|
auto child_element_stats = StatisticsFromValue(child_element);
|
|
119989
120277
|
if (child_element_stats) {
|
|
119990
120278
|
result->child_stats->Merge(*child_element_stats);
|
|
@@ -120208,7 +120496,7 @@ void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &stats, Express
|
|
|
120208
120496
|
return;
|
|
120209
120497
|
}
|
|
120210
120498
|
auto &numeric_stats = (NumericStatistics &)stats;
|
|
120211
|
-
if (numeric_stats.min.
|
|
120499
|
+
if (numeric_stats.min.IsNull() || numeric_stats.max.IsNull()) {
|
|
120212
120500
|
// no stats available: skip this
|
|
120213
120501
|
return;
|
|
120214
120502
|
}
|
|
@@ -120248,7 +120536,7 @@ void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &lstats, BaseSt
|
|
|
120248
120536
|
}
|
|
120249
120537
|
auto &left_stats = (NumericStatistics &)lstats;
|
|
120250
120538
|
auto &right_stats = (NumericStatistics &)rstats;
|
|
120251
|
-
if (left_stats.min.
|
|
120539
|
+
if (left_stats.min.IsNull() || left_stats.max.IsNull() || right_stats.min.IsNull() || right_stats.max.IsNull()) {
|
|
120252
120540
|
// no stats available: skip this
|
|
120253
120541
|
return;
|
|
120254
120542
|
}
|
|
@@ -120700,7 +120988,7 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalJoin
|
|
|
120700
120988
|
// LEFT, FULL and RIGHT OUTER joins can introduce null values
|
|
120701
120989
|
// this requires us to alter the statistics after this point in the query plan
|
|
120702
120990
|
if (IsLeftOuterJoin(join_type)) {
|
|
120703
|
-
// left or full outer join: set
|
|
120991
|
+
// left or full outer join: set IsNull() to true for all rhs statistics
|
|
120704
120992
|
for (auto &binding : right_bindings) {
|
|
120705
120993
|
auto stats = statistics_map.find(binding);
|
|
120706
120994
|
if (stats != statistics_map.end()) {
|
|
@@ -120709,7 +120997,7 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalJoin
|
|
|
120709
120997
|
}
|
|
120710
120998
|
}
|
|
120711
120999
|
if (IsRightOuterJoin(join_type)) {
|
|
120712
|
-
// right or full outer join: set
|
|
121000
|
+
// right or full outer join: set IsNull() to true for all lhs statistics
|
|
120713
121001
|
for (auto &binding : left_bindings) {
|
|
120714
121002
|
auto stats = statistics_map.find(binding);
|
|
120715
121003
|
if (stats != statistics_map.end()) {
|
|
@@ -137717,7 +138005,7 @@ unique_ptr<ParsedExpression> Transformer::TransformAExpr(duckdb_libpgquery::PGAE
|
|
|
137717
138005
|
throw NotImplementedException("Custom escape in SIMILAR TO");
|
|
137718
138006
|
}
|
|
137719
138007
|
auto &constant = (ConstantExpression &)*similar_func.children[1];
|
|
137720
|
-
if (!constant.value.
|
|
138008
|
+
if (!constant.value.IsNull()) {
|
|
137721
138009
|
throw NotImplementedException("Custom escape in SIMILAR TO");
|
|
137722
138010
|
}
|
|
137723
138011
|
// take the child of the similar_func
|
|
@@ -141850,12 +142138,12 @@ static void InvertPercentileFractions(unique_ptr<ParsedExpression> &fractions) {
|
|
|
141850
142138
|
Value value = ExpressionExecutor::EvaluateScalar(*bound.expr);
|
|
141851
142139
|
if (value.type().id() == LogicalTypeId::LIST) {
|
|
141852
142140
|
vector<Value> values;
|
|
141853
|
-
for (const auto &element_val : value
|
|
141854
|
-
values.
|
|
142141
|
+
for (const auto &element_val : ListValue::GetChildren(value)) {
|
|
142142
|
+
values.push_back(Value::DOUBLE(1 - element_val.GetValue<double>()));
|
|
141855
142143
|
}
|
|
141856
142144
|
bound.expr = make_unique<BoundConstantExpression>(Value::LIST(values));
|
|
141857
142145
|
} else {
|
|
141858
|
-
bound.expr = make_unique<BoundConstantExpression>(Value(1
|
|
142146
|
+
bound.expr = make_unique<BoundConstantExpression>(Value::DOUBLE(1 - value.GetValue<double>()));
|
|
141859
142147
|
}
|
|
141860
142148
|
}
|
|
141861
142149
|
|
|
@@ -148783,7 +149071,7 @@ bool BoundConstantExpression::Equals(const BaseExpression *other_p) const {
|
|
|
148783
149071
|
|
|
148784
149072
|
hash_t BoundConstantExpression::Hash() const {
|
|
148785
149073
|
hash_t result = Expression::Hash();
|
|
148786
|
-
return CombineHash(
|
|
149074
|
+
return CombineHash(value.Hash(), result);
|
|
148787
149075
|
}
|
|
148788
149076
|
|
|
148789
149077
|
unique_ptr<Expression> BoundConstantExpression::Copy() {
|
|
@@ -156226,6 +156514,7 @@ CompressionFunction GetBitpackingFunction(PhysicalType data_type) {
|
|
|
156226
156514
|
|
|
156227
156515
|
CompressionFunction BitpackingFun::GetFunction(PhysicalType type) {
|
|
156228
156516
|
switch (type) {
|
|
156517
|
+
case PhysicalType::BOOL:
|
|
156229
156518
|
case PhysicalType::INT8:
|
|
156230
156519
|
return GetBitpackingFunction<int8_t>(type);
|
|
156231
156520
|
case PhysicalType::INT16:
|
|
@@ -156234,7 +156523,6 @@ CompressionFunction BitpackingFun::GetFunction(PhysicalType type) {
|
|
|
156234
156523
|
return GetBitpackingFunction<int32_t>(type);
|
|
156235
156524
|
case PhysicalType::INT64:
|
|
156236
156525
|
return GetBitpackingFunction<int64_t>(type);
|
|
156237
|
-
case PhysicalType::BOOL:
|
|
156238
156526
|
case PhysicalType::UINT8:
|
|
156239
156527
|
return GetBitpackingFunction<uint8_t>(type);
|
|
156240
156528
|
case PhysicalType::UINT16:
|
|
@@ -160014,7 +160302,13 @@ MetaBlockWriter::MetaBlockWriter(DatabaseInstance &db, block_id_t initial_block_
|
|
|
160014
160302
|
}
|
|
160015
160303
|
|
|
160016
160304
|
MetaBlockWriter::~MetaBlockWriter() {
|
|
160017
|
-
|
|
160305
|
+
if (Exception::UncaughtException()) {
|
|
160306
|
+
return;
|
|
160307
|
+
}
|
|
160308
|
+
try {
|
|
160309
|
+
Flush();
|
|
160310
|
+
} catch (...) {
|
|
160311
|
+
}
|
|
160018
160312
|
}
|
|
160019
160313
|
|
|
160020
160314
|
block_id_t MetaBlockWriter::GetNextBlockId() {
|
|
@@ -160811,72 +161105,6 @@ void ListStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t co
|
|
|
160811
161105
|
|
|
160812
161106
|
namespace duckdb {
|
|
160813
161107
|
|
|
160814
|
-
template <>
|
|
160815
|
-
void NumericStatistics::Update<int8_t>(SegmentStatistics &stats, int8_t new_value) {
|
|
160816
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160817
|
-
UpdateValue<int8_t>(new_value, nstats.min.value_.tinyint, nstats.max.value_.tinyint);
|
|
160818
|
-
}
|
|
160819
|
-
|
|
160820
|
-
template <>
|
|
160821
|
-
void NumericStatistics::Update<int16_t>(SegmentStatistics &stats, int16_t new_value) {
|
|
160822
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160823
|
-
UpdateValue<int16_t>(new_value, nstats.min.value_.smallint, nstats.max.value_.smallint);
|
|
160824
|
-
}
|
|
160825
|
-
|
|
160826
|
-
template <>
|
|
160827
|
-
void NumericStatistics::Update<int32_t>(SegmentStatistics &stats, int32_t new_value) {
|
|
160828
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160829
|
-
UpdateValue<int32_t>(new_value, nstats.min.value_.integer, nstats.max.value_.integer);
|
|
160830
|
-
}
|
|
160831
|
-
|
|
160832
|
-
template <>
|
|
160833
|
-
void NumericStatistics::Update<int64_t>(SegmentStatistics &stats, int64_t new_value) {
|
|
160834
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160835
|
-
UpdateValue<int64_t>(new_value, nstats.min.value_.bigint, nstats.max.value_.bigint);
|
|
160836
|
-
}
|
|
160837
|
-
|
|
160838
|
-
template <>
|
|
160839
|
-
void NumericStatistics::Update<uint8_t>(SegmentStatistics &stats, uint8_t new_value) {
|
|
160840
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160841
|
-
UpdateValue<uint8_t>(new_value, nstats.min.value_.utinyint, nstats.max.value_.utinyint);
|
|
160842
|
-
}
|
|
160843
|
-
|
|
160844
|
-
template <>
|
|
160845
|
-
void NumericStatistics::Update<uint16_t>(SegmentStatistics &stats, uint16_t new_value) {
|
|
160846
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160847
|
-
UpdateValue<uint16_t>(new_value, nstats.min.value_.usmallint, nstats.max.value_.usmallint);
|
|
160848
|
-
}
|
|
160849
|
-
|
|
160850
|
-
template <>
|
|
160851
|
-
void NumericStatistics::Update<uint32_t>(SegmentStatistics &stats, uint32_t new_value) {
|
|
160852
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160853
|
-
UpdateValue<uint32_t>(new_value, nstats.min.value_.uinteger, nstats.max.value_.uinteger);
|
|
160854
|
-
}
|
|
160855
|
-
|
|
160856
|
-
template <>
|
|
160857
|
-
void NumericStatistics::Update<uint64_t>(SegmentStatistics &stats, uint64_t new_value) {
|
|
160858
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160859
|
-
UpdateValue<uint64_t>(new_value, nstats.min.value_.ubigint, nstats.max.value_.ubigint);
|
|
160860
|
-
}
|
|
160861
|
-
|
|
160862
|
-
template <>
|
|
160863
|
-
void NumericStatistics::Update<hugeint_t>(SegmentStatistics &stats, hugeint_t new_value) {
|
|
160864
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160865
|
-
UpdateValue<hugeint_t>(new_value, nstats.min.value_.hugeint, nstats.max.value_.hugeint);
|
|
160866
|
-
}
|
|
160867
|
-
|
|
160868
|
-
template <>
|
|
160869
|
-
void NumericStatistics::Update<float>(SegmentStatistics &stats, float new_value) {
|
|
160870
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160871
|
-
UpdateValue<float>(new_value, nstats.min.value_.float_, nstats.max.value_.float_);
|
|
160872
|
-
}
|
|
160873
|
-
|
|
160874
|
-
template <>
|
|
160875
|
-
void NumericStatistics::Update<double>(SegmentStatistics &stats, double new_value) {
|
|
160876
|
-
auto &nstats = (NumericStatistics &)*stats.statistics;
|
|
160877
|
-
UpdateValue<double>(new_value, nstats.min.value_.double_, nstats.max.value_.double_);
|
|
160878
|
-
}
|
|
160879
|
-
|
|
160880
161108
|
template <>
|
|
160881
161109
|
void NumericStatistics::Update<interval_t>(SegmentStatistics &stats, interval_t new_value) {
|
|
160882
161110
|
}
|
|
@@ -160898,23 +161126,23 @@ NumericStatistics::NumericStatistics(LogicalType type_p, Value min_p, Value max_
|
|
|
160898
161126
|
void NumericStatistics::Merge(const BaseStatistics &other_p) {
|
|
160899
161127
|
BaseStatistics::Merge(other_p);
|
|
160900
161128
|
auto &other = (const NumericStatistics &)other_p;
|
|
160901
|
-
if (other.min.
|
|
160902
|
-
min
|
|
161129
|
+
if (other.min.IsNull() || min.IsNull()) {
|
|
161130
|
+
min = Value(type);
|
|
160903
161131
|
} else if (other.min < min) {
|
|
160904
161132
|
min = other.min;
|
|
160905
161133
|
}
|
|
160906
|
-
if (other.max.
|
|
160907
|
-
max
|
|
161134
|
+
if (other.max.IsNull() || max.IsNull()) {
|
|
161135
|
+
max = Value(type);
|
|
160908
161136
|
} else if (other.max > max) {
|
|
160909
161137
|
max = other.max;
|
|
160910
161138
|
}
|
|
160911
161139
|
}
|
|
160912
161140
|
|
|
160913
161141
|
FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) {
|
|
160914
|
-
if (constant.
|
|
161142
|
+
if (constant.IsNull()) {
|
|
160915
161143
|
return FilterPropagateResult::FILTER_ALWAYS_FALSE;
|
|
160916
161144
|
}
|
|
160917
|
-
if (min.
|
|
161145
|
+
if (min.IsNull() || max.IsNull()) {
|
|
160918
161146
|
return FilterPropagateResult::NO_PRUNING_POSSIBLE;
|
|
160919
161147
|
}
|
|
160920
161148
|
switch (comparison_type) {
|
|
@@ -161024,11 +161252,11 @@ void NumericStatistics::TemplatedVerify(Vector &vector, const SelectionVector &s
|
|
|
161024
161252
|
if (!vdata.validity.RowIsValid(index)) {
|
|
161025
161253
|
continue;
|
|
161026
161254
|
}
|
|
161027
|
-
if (!min.
|
|
161255
|
+
if (!min.IsNull() && LessThan::Operation(data[index], min.GetValueUnsafe<T>())) { // LCOV_EXCL_START
|
|
161028
161256
|
throw InternalException("Statistics mismatch: value is smaller than min.\nStatistics: %s\nVector: %s",
|
|
161029
161257
|
ToString(), vector.ToString(count));
|
|
161030
161258
|
} // LCOV_EXCL_STOP
|
|
161031
|
-
if (!max.
|
|
161259
|
+
if (!max.IsNull() && GreaterThan::Operation(data[index], max.GetValueUnsafe<T>())) {
|
|
161032
161260
|
throw InternalException("Statistics mismatch: value is bigger than max.\nStatistics: %s\nVector: %s",
|
|
161033
161261
|
ToString(), vector.ToString(count));
|
|
161034
161262
|
}
|
|
@@ -163573,7 +163801,7 @@ idx_t ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const
|
|
|
163573
163801
|
}
|
|
163574
163802
|
case PhysicalType::VARCHAR: {
|
|
163575
163803
|
auto result_flat = FlatVector::GetData<string_t>(result);
|
|
163576
|
-
Vector predicate_vector(constant_filter.constant
|
|
163804
|
+
Vector predicate_vector(constant_filter.constant);
|
|
163577
163805
|
auto predicate = FlatVector::GetData<string_t>(predicate_vector);
|
|
163578
163806
|
FilterSelectionSwitch<string_t>(result_flat, predicate, sel, approved_tuple_count,
|
|
163579
163807
|
constant_filter.comparison_type, mask);
|