duckdb 0.3.3-dev534.0 → 0.3.3-dev551.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 +283 -248
- package/src/duckdb.hpp +2 -2
- package/src/parquet-amalgamation.cpp +36560 -36560
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -4212,6 +4212,10 @@ static DefaultMacro internal_macros[] = {
|
|
|
4212
4212
|
{DEFAULT_SCHEMA, "array_append", {"arr", "el", nullptr}, "list_append(arr, el)"},
|
|
4213
4213
|
{DEFAULT_SCHEMA, "list_prepend", {"e", "l", nullptr}, "list_concat(list_value(e), l)"},
|
|
4214
4214
|
{DEFAULT_SCHEMA, "array_prepend", {"el", "arr", nullptr}, "list_prepend(el, arr)"},
|
|
4215
|
+
{DEFAULT_SCHEMA, "array_pop_back", {"arr", nullptr}, "arr[:LEN(arr)-1]"},
|
|
4216
|
+
{DEFAULT_SCHEMA, "array_pop_front", {"arr", nullptr}, "arr[1:]"},
|
|
4217
|
+
{DEFAULT_SCHEMA, "array_push_back", {"arr", "e", nullptr}, "list_concat(arr, list_value(e))"},
|
|
4218
|
+
{DEFAULT_SCHEMA, "array_push_front", {"arr", "e", nullptr}, "list_concat(list_value(e), arr)"},
|
|
4215
4219
|
{DEFAULT_SCHEMA, "generate_subscripts", {"arr", "dim", nullptr}, "unnest(generate_series(1, array_length(arr, dim)))"},
|
|
4216
4220
|
{DEFAULT_SCHEMA, "fdiv", {"x", "y", nullptr}, "floor(x/y)"},
|
|
4217
4221
|
{DEFAULT_SCHEMA, "fmod", {"x", "y", nullptr}, "(x-y*floor(x/y))"},
|
|
@@ -62789,9 +62793,15 @@ OperatorResultType PhysicalUnnest::Execute(ExecutionContext &context, DataChunk
|
|
|
62789
62793
|
auto &list_vector = state.list_data.data[col_idx];
|
|
62790
62794
|
list_vector.Orrify(state.list_data.size(), state.list_vector_data[col_idx]);
|
|
62791
62795
|
|
|
62792
|
-
|
|
62793
|
-
|
|
62794
|
-
|
|
62796
|
+
if (list_vector.GetType() == LogicalType::SQLNULL) {
|
|
62797
|
+
// UNNEST(NULL)
|
|
62798
|
+
auto &child_vector = list_vector;
|
|
62799
|
+
child_vector.Orrify(0, state.list_child_data[col_idx]);
|
|
62800
|
+
} else {
|
|
62801
|
+
auto list_size = ListVector::GetListSize(list_vector);
|
|
62802
|
+
auto &child_vector = ListVector::GetEntry(list_vector);
|
|
62803
|
+
child_vector.Orrify(list_size, state.list_child_data[col_idx]);
|
|
62804
|
+
}
|
|
62795
62805
|
}
|
|
62796
62806
|
state.first_fetch = false;
|
|
62797
62807
|
}
|
|
@@ -62840,34 +62850,40 @@ OperatorResultType PhysicalUnnest::Execute(ExecutionContext &context, DataChunk
|
|
|
62840
62850
|
for (idx_t col_idx = 0; col_idx < state.list_data.ColumnCount(); col_idx++) {
|
|
62841
62851
|
auto &result_vector = chunk.data[col_idx + input.ColumnCount()];
|
|
62842
62852
|
|
|
62843
|
-
|
|
62844
|
-
|
|
62845
|
-
|
|
62846
|
-
|
|
62847
|
-
auto list_data = (list_entry_t *)vdata.data;
|
|
62848
|
-
auto list_entry = list_data[current_idx];
|
|
62849
|
-
|
|
62850
|
-
idx_t list_count;
|
|
62851
|
-
if (state.list_position >= list_entry.length) {
|
|
62852
|
-
list_count = 0;
|
|
62853
|
+
if (state.list_data.data[col_idx].GetType() == LogicalType::SQLNULL) {
|
|
62854
|
+
// UNNEST(NULL)
|
|
62855
|
+
chunk.SetCardinality(0);
|
|
62853
62856
|
} else {
|
|
62854
|
-
|
|
62855
|
-
|
|
62857
|
+
auto &vdata = state.list_vector_data[col_idx];
|
|
62858
|
+
auto &child_data = state.list_child_data[col_idx];
|
|
62859
|
+
auto current_idx = vdata.sel->get_index(state.parent_position);
|
|
62856
62860
|
|
|
62857
|
-
|
|
62858
|
-
|
|
62859
|
-
|
|
62861
|
+
auto list_data = (list_entry_t *)vdata.data;
|
|
62862
|
+
auto list_entry = list_data[current_idx];
|
|
62863
|
+
|
|
62864
|
+
idx_t list_count;
|
|
62865
|
+
if (state.list_position >= list_entry.length) {
|
|
62866
|
+
list_count = 0;
|
|
62860
62867
|
} else {
|
|
62861
|
-
|
|
62862
|
-
|
|
62863
|
-
|
|
62868
|
+
list_count = MinValue<idx_t>(this_chunk_len, list_entry.length - state.list_position);
|
|
62869
|
+
}
|
|
62870
|
+
|
|
62871
|
+
if (list_entry.length > state.list_position) {
|
|
62872
|
+
if (!vdata.validity.RowIsValid(current_idx)) {
|
|
62873
|
+
UnnestNull(0, list_count, result_vector);
|
|
62874
|
+
} else {
|
|
62875
|
+
auto &list_vector = state.list_data.data[col_idx];
|
|
62876
|
+
auto &child_vector = ListVector::GetEntry(list_vector);
|
|
62877
|
+
auto list_size = ListVector::GetListSize(list_vector);
|
|
62864
62878
|
|
|
62865
|
-
|
|
62866
|
-
|
|
62867
|
-
|
|
62879
|
+
auto base_offset = list_entry.offset + state.list_position;
|
|
62880
|
+
UnnestVector(child_data, child_vector, list_size, base_offset, base_offset + list_count,
|
|
62881
|
+
result_vector);
|
|
62882
|
+
}
|
|
62868
62883
|
}
|
|
62884
|
+
|
|
62885
|
+
UnnestNull(list_count, this_chunk_len, result_vector);
|
|
62869
62886
|
}
|
|
62870
|
-
UnnestNull(list_count, this_chunk_len, result_vector);
|
|
62871
62887
|
}
|
|
62872
62888
|
|
|
62873
62889
|
state.list_position += this_chunk_len;
|
|
@@ -75757,6 +75773,11 @@ struct ListContainsFun {
|
|
|
75757
75773
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
75758
75774
|
};
|
|
75759
75775
|
|
|
75776
|
+
struct ListPositionFun {
|
|
75777
|
+
static ScalarFunction GetFunction();
|
|
75778
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
75779
|
+
};
|
|
75780
|
+
|
|
75760
75781
|
struct CardinalityFun {
|
|
75761
75782
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
75762
75783
|
};
|
|
@@ -83759,6 +83780,232 @@ void ArraySliceFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
83759
83780
|
|
|
83760
83781
|
|
|
83761
83782
|
|
|
83783
|
+
namespace duckdb {
|
|
83784
|
+
|
|
83785
|
+
template <class T>
|
|
83786
|
+
static inline bool ValueEqualsOrNot(const T &left, const T &right) {
|
|
83787
|
+
return left == right;
|
|
83788
|
+
}
|
|
83789
|
+
|
|
83790
|
+
template <>
|
|
83791
|
+
inline bool ValueEqualsOrNot(const string_t &left, const string_t &right) {
|
|
83792
|
+
return StringComparisonOperators::EqualsOrNot<false>(left, right);
|
|
83793
|
+
}
|
|
83794
|
+
|
|
83795
|
+
struct ContainsFunctor {
|
|
83796
|
+
static inline bool Initialize() {
|
|
83797
|
+
return false;
|
|
83798
|
+
}
|
|
83799
|
+
static inline bool UpdateResultEntries(idx_t child_idx) {
|
|
83800
|
+
return true;
|
|
83801
|
+
}
|
|
83802
|
+
};
|
|
83803
|
+
|
|
83804
|
+
struct PositionFunctor {
|
|
83805
|
+
static inline int32_t Initialize() {
|
|
83806
|
+
return 0;
|
|
83807
|
+
}
|
|
83808
|
+
static inline int32_t UpdateResultEntries(idx_t child_idx) {
|
|
83809
|
+
return child_idx + 1;
|
|
83810
|
+
}
|
|
83811
|
+
};
|
|
83812
|
+
|
|
83813
|
+
template <class CHILD_TYPE, class RETURN_TYPE, class OP>
|
|
83814
|
+
static void TemplatedContainsOrPosition(DataChunk &args, ExpressionState &state, Vector &result,
|
|
83815
|
+
bool is_nested = false) {
|
|
83816
|
+
D_ASSERT(args.ColumnCount() == 2);
|
|
83817
|
+
auto count = args.size();
|
|
83818
|
+
Vector &list = args.data[0];
|
|
83819
|
+
Vector &value_vector = args.data[1];
|
|
83820
|
+
|
|
83821
|
+
// Create a result vector of type RETURN_TYPE
|
|
83822
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
83823
|
+
auto result_entries = FlatVector::GetData<RETURN_TYPE>(result);
|
|
83824
|
+
auto &result_validity = FlatVector::Validity(result);
|
|
83825
|
+
|
|
83826
|
+
if (list.GetType().id() == LogicalTypeId::SQLNULL) {
|
|
83827
|
+
result_validity.SetInvalid(0);
|
|
83828
|
+
return;
|
|
83829
|
+
}
|
|
83830
|
+
|
|
83831
|
+
auto list_size = ListVector::GetListSize(list);
|
|
83832
|
+
auto &child_vector = ListVector::GetEntry(list);
|
|
83833
|
+
|
|
83834
|
+
VectorData child_data;
|
|
83835
|
+
child_vector.Orrify(list_size, child_data);
|
|
83836
|
+
|
|
83837
|
+
VectorData list_data;
|
|
83838
|
+
list.Orrify(count, list_data);
|
|
83839
|
+
auto list_entries = (list_entry_t *)list_data.data;
|
|
83840
|
+
|
|
83841
|
+
VectorData value_data;
|
|
83842
|
+
value_vector.Orrify(count, value_data);
|
|
83843
|
+
|
|
83844
|
+
for (idx_t i = 0; i < count; i++) {
|
|
83845
|
+
auto list_index = list_data.sel->get_index(i);
|
|
83846
|
+
auto value_index = value_data.sel->get_index(i);
|
|
83847
|
+
|
|
83848
|
+
if (!list_data.validity.RowIsValid(list_index) || !value_data.validity.RowIsValid(value_index)) {
|
|
83849
|
+
result_validity.SetInvalid(i);
|
|
83850
|
+
continue;
|
|
83851
|
+
}
|
|
83852
|
+
|
|
83853
|
+
const auto &list_entry = list_entries[list_index];
|
|
83854
|
+
auto source_idx = child_data.sel->get_index(list_entry.offset);
|
|
83855
|
+
|
|
83856
|
+
// not required for a comparison of nested types
|
|
83857
|
+
auto child_value = FlatVector::GetData<CHILD_TYPE>(child_vector);
|
|
83858
|
+
auto values = FlatVector::GetData<CHILD_TYPE>(value_vector);
|
|
83859
|
+
|
|
83860
|
+
result_entries[list_index] = OP::Initialize();
|
|
83861
|
+
for (idx_t child_idx = 0; child_idx < list_entry.length; child_idx++) {
|
|
83862
|
+
auto child_value_idx = source_idx + child_idx;
|
|
83863
|
+
|
|
83864
|
+
if (!child_data.validity.RowIsValid(child_value_idx)) {
|
|
83865
|
+
continue;
|
|
83866
|
+
}
|
|
83867
|
+
|
|
83868
|
+
if (!is_nested) {
|
|
83869
|
+
if (ValueEqualsOrNot<CHILD_TYPE>(child_value[child_value_idx], values[value_index])) {
|
|
83870
|
+
result_entries[list_index] = OP::UpdateResultEntries(child_idx);
|
|
83871
|
+
break; // Found value in list, no need to look further
|
|
83872
|
+
}
|
|
83873
|
+
} else {
|
|
83874
|
+
// FIXME: using Value is less efficient than modifying the vector comparison code
|
|
83875
|
+
// to more efficiently compare nested types
|
|
83876
|
+
if (ValueEqualsOrNot<Value>(child_vector.GetValue(child_value_idx),
|
|
83877
|
+
value_vector.GetValue(value_index))) {
|
|
83878
|
+
result_entries[list_index] = OP::UpdateResultEntries(child_idx);
|
|
83879
|
+
break; // Found value in list, no need to look further
|
|
83880
|
+
}
|
|
83881
|
+
}
|
|
83882
|
+
}
|
|
83883
|
+
}
|
|
83884
|
+
}
|
|
83885
|
+
|
|
83886
|
+
template <class T, class OP>
|
|
83887
|
+
static void ListContainsOrPosition(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
83888
|
+
switch (args.data[1].GetType().InternalType()) {
|
|
83889
|
+
case PhysicalType::BOOL:
|
|
83890
|
+
case PhysicalType::INT8:
|
|
83891
|
+
TemplatedContainsOrPosition<int8_t, T, OP>(args, state, result);
|
|
83892
|
+
break;
|
|
83893
|
+
case PhysicalType::INT16:
|
|
83894
|
+
TemplatedContainsOrPosition<int16_t, T, OP>(args, state, result);
|
|
83895
|
+
break;
|
|
83896
|
+
case PhysicalType::INT32:
|
|
83897
|
+
TemplatedContainsOrPosition<int32_t, T, OP>(args, state, result);
|
|
83898
|
+
break;
|
|
83899
|
+
case PhysicalType::INT64:
|
|
83900
|
+
TemplatedContainsOrPosition<int64_t, T, OP>(args, state, result);
|
|
83901
|
+
break;
|
|
83902
|
+
case PhysicalType::INT128:
|
|
83903
|
+
TemplatedContainsOrPosition<hugeint_t, T, OP>(args, state, result);
|
|
83904
|
+
break;
|
|
83905
|
+
case PhysicalType::UINT8:
|
|
83906
|
+
TemplatedContainsOrPosition<uint8_t, T, OP>(args, state, result);
|
|
83907
|
+
break;
|
|
83908
|
+
case PhysicalType::UINT16:
|
|
83909
|
+
TemplatedContainsOrPosition<uint16_t, T, OP>(args, state, result);
|
|
83910
|
+
break;
|
|
83911
|
+
case PhysicalType::UINT32:
|
|
83912
|
+
TemplatedContainsOrPosition<uint32_t, T, OP>(args, state, result);
|
|
83913
|
+
break;
|
|
83914
|
+
case PhysicalType::UINT64:
|
|
83915
|
+
TemplatedContainsOrPosition<uint64_t, T, OP>(args, state, result);
|
|
83916
|
+
break;
|
|
83917
|
+
case PhysicalType::FLOAT:
|
|
83918
|
+
TemplatedContainsOrPosition<float, T, OP>(args, state, result);
|
|
83919
|
+
break;
|
|
83920
|
+
case PhysicalType::DOUBLE:
|
|
83921
|
+
TemplatedContainsOrPosition<double, T, OP>(args, state, result);
|
|
83922
|
+
break;
|
|
83923
|
+
case PhysicalType::VARCHAR:
|
|
83924
|
+
TemplatedContainsOrPosition<string_t, T, OP>(args, state, result);
|
|
83925
|
+
break;
|
|
83926
|
+
case PhysicalType::MAP:
|
|
83927
|
+
case PhysicalType::STRUCT:
|
|
83928
|
+
case PhysicalType::LIST:
|
|
83929
|
+
TemplatedContainsOrPosition<int8_t, T, OP>(args, state, result, true);
|
|
83930
|
+
break;
|
|
83931
|
+
default:
|
|
83932
|
+
throw NotImplementedException("This function has not been implemented for this type");
|
|
83933
|
+
}
|
|
83934
|
+
}
|
|
83935
|
+
|
|
83936
|
+
static void ListContainsFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
83937
|
+
return ListContainsOrPosition<bool, ContainsFunctor>(args, state, result);
|
|
83938
|
+
}
|
|
83939
|
+
|
|
83940
|
+
static void ListPositionFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
83941
|
+
return ListContainsOrPosition<int32_t, PositionFunctor>(args, state, result);
|
|
83942
|
+
}
|
|
83943
|
+
|
|
83944
|
+
template <LogicalTypeId RETURN_TYPE>
|
|
83945
|
+
static unique_ptr<FunctionData> ListContainsOrPositionBind(ClientContext &context, ScalarFunction &bound_function,
|
|
83946
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
83947
|
+
D_ASSERT(bound_function.arguments.size() == 2);
|
|
83948
|
+
|
|
83949
|
+
const auto &list = arguments[0]->return_type; // change to list
|
|
83950
|
+
const auto &value = arguments[1]->return_type;
|
|
83951
|
+
if (list.id() == LogicalTypeId::SQLNULL && value.id() == LogicalTypeId::SQLNULL) {
|
|
83952
|
+
bound_function.arguments[0] = LogicalType::SQLNULL;
|
|
83953
|
+
bound_function.arguments[1] = LogicalType::SQLNULL;
|
|
83954
|
+
bound_function.return_type = LogicalType::SQLNULL;
|
|
83955
|
+
} else if (list.id() == LogicalTypeId::SQLNULL || value.id() == LogicalTypeId::SQLNULL) {
|
|
83956
|
+
// In case either the list or the value is NULL, return NULL
|
|
83957
|
+
// Similar to behaviour of prestoDB
|
|
83958
|
+
bound_function.arguments[0] = list;
|
|
83959
|
+
bound_function.arguments[1] = value;
|
|
83960
|
+
bound_function.return_type = LogicalTypeId::SQLNULL;
|
|
83961
|
+
} else {
|
|
83962
|
+
auto const &child_type = ListType::GetChildType(arguments[0]->return_type);
|
|
83963
|
+
auto max_child_type = LogicalType::MaxLogicalType(child_type, value);
|
|
83964
|
+
ExpressionBinder::ResolveParameterType(max_child_type);
|
|
83965
|
+
auto list_type = LogicalType::LIST(max_child_type);
|
|
83966
|
+
|
|
83967
|
+
bound_function.arguments[0] = list_type;
|
|
83968
|
+
bound_function.arguments[1] = value == max_child_type ? value : max_child_type;
|
|
83969
|
+
|
|
83970
|
+
// list_contains and list_position only differ in their return type
|
|
83971
|
+
bound_function.return_type = RETURN_TYPE;
|
|
83972
|
+
}
|
|
83973
|
+
return make_unique<VariableReturnBindData>(bound_function.return_type);
|
|
83974
|
+
}
|
|
83975
|
+
|
|
83976
|
+
static unique_ptr<FunctionData> ListContainsBind(ClientContext &context, ScalarFunction &bound_function,
|
|
83977
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
83978
|
+
return ListContainsOrPositionBind<LogicalType::BOOLEAN>(context, bound_function, arguments);
|
|
83979
|
+
}
|
|
83980
|
+
|
|
83981
|
+
static unique_ptr<FunctionData> ListPositionBind(ClientContext &context, ScalarFunction &bound_function,
|
|
83982
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
83983
|
+
return ListContainsOrPositionBind<LogicalType::INTEGER>(context, bound_function, arguments);
|
|
83984
|
+
}
|
|
83985
|
+
|
|
83986
|
+
ScalarFunction ListContainsFun::GetFunction() {
|
|
83987
|
+
return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
|
|
83988
|
+
LogicalType::BOOLEAN, // return type
|
|
83989
|
+
ListContainsFunction, false, ListContainsBind, nullptr);
|
|
83990
|
+
}
|
|
83991
|
+
|
|
83992
|
+
ScalarFunction ListPositionFun::GetFunction() {
|
|
83993
|
+
return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
|
|
83994
|
+
LogicalType::INTEGER, // return type
|
|
83995
|
+
ListPositionFunction, false, ListPositionBind, nullptr);
|
|
83996
|
+
}
|
|
83997
|
+
|
|
83998
|
+
void ListContainsFun::RegisterFunction(BuiltinFunctions &set) {
|
|
83999
|
+
set.AddFunction({"list_contains", "array_contains", "list_has", "array_has"}, GetFunction());
|
|
84000
|
+
}
|
|
84001
|
+
|
|
84002
|
+
void ListPositionFun::RegisterFunction(BuiltinFunctions &set) {
|
|
84003
|
+
set.AddFunction({"list_position", "list_indexof", "array_position", "array_indexof"}, GetFunction());
|
|
84004
|
+
}
|
|
84005
|
+
} // namespace duckdb
|
|
84006
|
+
|
|
84007
|
+
|
|
84008
|
+
|
|
83762
84009
|
//===----------------------------------------------------------------------===//
|
|
83763
84010
|
// DuckDB
|
|
83764
84011
|
//
|
|
@@ -83931,226 +84178,6 @@ void ListConcatFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
83931
84178
|
|
|
83932
84179
|
|
|
83933
84180
|
|
|
83934
|
-
namespace duckdb {
|
|
83935
|
-
|
|
83936
|
-
template <class T>
|
|
83937
|
-
static inline bool ValueCompare(const T &left, const T &right) {
|
|
83938
|
-
return left == right;
|
|
83939
|
-
}
|
|
83940
|
-
|
|
83941
|
-
template <>
|
|
83942
|
-
inline bool ValueCompare(const string_t &left, const string_t &right) {
|
|
83943
|
-
return StringComparisonOperators::EqualsOrNot<false>(left, right);
|
|
83944
|
-
}
|
|
83945
|
-
|
|
83946
|
-
template <>
|
|
83947
|
-
inline bool ValueCompare(const Value &left, const Value &right) {
|
|
83948
|
-
return left == right;
|
|
83949
|
-
}
|
|
83950
|
-
|
|
83951
|
-
template <class T>
|
|
83952
|
-
static void TemplatedListContainsFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
83953
|
-
D_ASSERT(args.ColumnCount() == 2);
|
|
83954
|
-
auto count = args.size();
|
|
83955
|
-
Vector &list = args.data[0];
|
|
83956
|
-
Vector &value_vector = args.data[1];
|
|
83957
|
-
|
|
83958
|
-
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
83959
|
-
auto result_entries = FlatVector::GetData<bool>(result); // Create a vector of bool
|
|
83960
|
-
auto &result_validity = FlatVector::Validity(result);
|
|
83961
|
-
|
|
83962
|
-
if (list.GetType().id() == LogicalTypeId::SQLNULL) {
|
|
83963
|
-
result_validity.SetInvalid(0);
|
|
83964
|
-
return;
|
|
83965
|
-
}
|
|
83966
|
-
|
|
83967
|
-
auto list_size = ListVector::GetListSize(list);
|
|
83968
|
-
auto &child_vector = ListVector::GetEntry(list);
|
|
83969
|
-
|
|
83970
|
-
VectorData child_data;
|
|
83971
|
-
child_vector.Orrify(list_size, child_data);
|
|
83972
|
-
|
|
83973
|
-
VectorData list_data;
|
|
83974
|
-
list.Orrify(count, list_data);
|
|
83975
|
-
auto list_entries = (list_entry_t *)list_data.data;
|
|
83976
|
-
|
|
83977
|
-
VectorData value_data;
|
|
83978
|
-
value_vector.Orrify(count, value_data);
|
|
83979
|
-
|
|
83980
|
-
for (idx_t i = 0; i < count; i++) {
|
|
83981
|
-
auto list_index = list_data.sel->get_index(i);
|
|
83982
|
-
auto value_index = value_data.sel->get_index(i);
|
|
83983
|
-
|
|
83984
|
-
if (!list_data.validity.RowIsValid(list_index) || !value_data.validity.RowIsValid(value_index)) {
|
|
83985
|
-
result_validity.SetInvalid(i);
|
|
83986
|
-
continue;
|
|
83987
|
-
}
|
|
83988
|
-
|
|
83989
|
-
const auto &list_entry = list_entries[list_index];
|
|
83990
|
-
auto source_idx = child_data.sel->get_index(list_entry.offset);
|
|
83991
|
-
auto child_value = FlatVector::GetData<T>(child_vector);
|
|
83992
|
-
|
|
83993
|
-
auto values = FlatVector::GetData<T>(value_vector);
|
|
83994
|
-
result_entries[list_index] = false;
|
|
83995
|
-
for (idx_t child_idx = 0; child_idx < list_entry.length; child_idx++) {
|
|
83996
|
-
auto child_value_idx = source_idx + child_idx;
|
|
83997
|
-
|
|
83998
|
-
if (!child_data.validity.RowIsValid(child_value_idx)) {
|
|
83999
|
-
continue;
|
|
84000
|
-
}
|
|
84001
|
-
if (ValueCompare<T>(child_value[child_value_idx], values[value_index])) {
|
|
84002
|
-
result_entries[list_index] = true;
|
|
84003
|
-
break; // Found value in list, no need to look further
|
|
84004
|
-
}
|
|
84005
|
-
}
|
|
84006
|
-
}
|
|
84007
|
-
}
|
|
84008
|
-
|
|
84009
|
-
static void NestedListContainsFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
84010
|
-
D_ASSERT(args.ColumnCount() == 2);
|
|
84011
|
-
auto count = args.size();
|
|
84012
|
-
Vector &list = args.data[0];
|
|
84013
|
-
Vector &value_vector = args.data[1];
|
|
84014
|
-
|
|
84015
|
-
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
84016
|
-
auto result_entries = FlatVector::GetData<bool>(result); // Create a vector of bool
|
|
84017
|
-
auto &result_validity = FlatVector::Validity(result);
|
|
84018
|
-
|
|
84019
|
-
if (list.GetType().id() == LogicalTypeId::SQLNULL) {
|
|
84020
|
-
result_validity.SetInvalid(0);
|
|
84021
|
-
return;
|
|
84022
|
-
}
|
|
84023
|
-
|
|
84024
|
-
auto list_size = ListVector::GetListSize(list);
|
|
84025
|
-
auto &child_vector = ListVector::GetEntry(list);
|
|
84026
|
-
|
|
84027
|
-
VectorData child_data;
|
|
84028
|
-
child_vector.Orrify(list_size, child_data);
|
|
84029
|
-
|
|
84030
|
-
VectorData list_data;
|
|
84031
|
-
list.Orrify(count, list_data);
|
|
84032
|
-
auto list_entries = (list_entry_t *)list_data.data;
|
|
84033
|
-
|
|
84034
|
-
VectorData value_data;
|
|
84035
|
-
value_vector.Orrify(count, value_data);
|
|
84036
|
-
|
|
84037
|
-
for (idx_t i = 0; i < count; i++) {
|
|
84038
|
-
auto list_index = list_data.sel->get_index(i);
|
|
84039
|
-
auto value_index = value_data.sel->get_index(i);
|
|
84040
|
-
|
|
84041
|
-
if (!list_data.validity.RowIsValid(list_index) || !value_data.validity.RowIsValid(value_index)) {
|
|
84042
|
-
result_validity.SetInvalid(i);
|
|
84043
|
-
continue;
|
|
84044
|
-
}
|
|
84045
|
-
|
|
84046
|
-
const auto &list_entry = list_entries[list_index];
|
|
84047
|
-
auto source_idx = child_data.sel->get_index(list_entry.offset);
|
|
84048
|
-
|
|
84049
|
-
result_entries[list_index] = false;
|
|
84050
|
-
for (idx_t child_idx = 0; child_idx < list_entry.length; child_idx++) {
|
|
84051
|
-
auto child_value_idx = source_idx + child_idx;
|
|
84052
|
-
if (!child_data.validity.RowIsValid(child_value_idx)) {
|
|
84053
|
-
continue;
|
|
84054
|
-
}
|
|
84055
|
-
if (ValueCompare<Value>(child_vector.GetValue(child_value_idx), value_vector.GetValue(value_index))) {
|
|
84056
|
-
result_entries[list_index] = true;
|
|
84057
|
-
break; // Found value in list, no need to look further
|
|
84058
|
-
}
|
|
84059
|
-
}
|
|
84060
|
-
}
|
|
84061
|
-
}
|
|
84062
|
-
|
|
84063
|
-
static void ListContainsFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
84064
|
-
switch (args.data[1].GetType().InternalType()) {
|
|
84065
|
-
case PhysicalType::BOOL:
|
|
84066
|
-
case PhysicalType::INT8:
|
|
84067
|
-
TemplatedListContainsFunction<int8_t>(args, state, result);
|
|
84068
|
-
break;
|
|
84069
|
-
case PhysicalType::INT16:
|
|
84070
|
-
TemplatedListContainsFunction<int16_t>(args, state, result);
|
|
84071
|
-
break;
|
|
84072
|
-
case PhysicalType::INT32:
|
|
84073
|
-
TemplatedListContainsFunction<int32_t>(args, state, result);
|
|
84074
|
-
break;
|
|
84075
|
-
case PhysicalType::INT64:
|
|
84076
|
-
TemplatedListContainsFunction<int64_t>(args, state, result);
|
|
84077
|
-
break;
|
|
84078
|
-
case PhysicalType::INT128:
|
|
84079
|
-
TemplatedListContainsFunction<hugeint_t>(args, state, result);
|
|
84080
|
-
break;
|
|
84081
|
-
case PhysicalType::UINT8:
|
|
84082
|
-
TemplatedListContainsFunction<uint8_t>(args, state, result);
|
|
84083
|
-
break;
|
|
84084
|
-
case PhysicalType::UINT16:
|
|
84085
|
-
TemplatedListContainsFunction<uint16_t>(args, state, result);
|
|
84086
|
-
break;
|
|
84087
|
-
case PhysicalType::UINT32:
|
|
84088
|
-
TemplatedListContainsFunction<uint32_t>(args, state, result);
|
|
84089
|
-
break;
|
|
84090
|
-
case PhysicalType::UINT64:
|
|
84091
|
-
TemplatedListContainsFunction<uint64_t>(args, state, result);
|
|
84092
|
-
break;
|
|
84093
|
-
case PhysicalType::FLOAT:
|
|
84094
|
-
TemplatedListContainsFunction<float>(args, state, result);
|
|
84095
|
-
break;
|
|
84096
|
-
case PhysicalType::DOUBLE:
|
|
84097
|
-
TemplatedListContainsFunction<double>(args, state, result);
|
|
84098
|
-
break;
|
|
84099
|
-
case PhysicalType::VARCHAR:
|
|
84100
|
-
TemplatedListContainsFunction<string_t>(args, state, result);
|
|
84101
|
-
break;
|
|
84102
|
-
case PhysicalType::MAP:
|
|
84103
|
-
case PhysicalType::STRUCT:
|
|
84104
|
-
case PhysicalType::LIST:
|
|
84105
|
-
NestedListContainsFunction(args, state, result);
|
|
84106
|
-
break;
|
|
84107
|
-
default:
|
|
84108
|
-
throw NotImplementedException("This function has not been implemented for this type");
|
|
84109
|
-
}
|
|
84110
|
-
}
|
|
84111
|
-
|
|
84112
|
-
static unique_ptr<FunctionData> ListContainsBind(ClientContext &context, ScalarFunction &bound_function,
|
|
84113
|
-
vector<unique_ptr<Expression>> &arguments) {
|
|
84114
|
-
D_ASSERT(bound_function.arguments.size() == 2);
|
|
84115
|
-
|
|
84116
|
-
const auto &list = arguments[0]->return_type; // change to list
|
|
84117
|
-
const auto &value = arguments[1]->return_type;
|
|
84118
|
-
if (list.id() == LogicalTypeId::SQLNULL && value.id() == LogicalTypeId::SQLNULL) {
|
|
84119
|
-
bound_function.arguments[0] = LogicalType::SQLNULL;
|
|
84120
|
-
bound_function.arguments[1] = LogicalType::SQLNULL;
|
|
84121
|
-
bound_function.return_type = LogicalType::SQLNULL;
|
|
84122
|
-
} else if (list.id() == LogicalTypeId::SQLNULL || value.id() == LogicalTypeId::SQLNULL) {
|
|
84123
|
-
// In case either the list or the value is NULL, return NULL
|
|
84124
|
-
// Similar to behaviour of prestoDB
|
|
84125
|
-
bound_function.arguments[0] = list;
|
|
84126
|
-
bound_function.arguments[1] = value;
|
|
84127
|
-
bound_function.return_type = LogicalTypeId::SQLNULL;
|
|
84128
|
-
} else {
|
|
84129
|
-
auto const &child_type = ListType::GetChildType(arguments[0]->return_type);
|
|
84130
|
-
auto max_child_type = LogicalType::MaxLogicalType(child_type, value);
|
|
84131
|
-
ExpressionBinder::ResolveParameterType(max_child_type);
|
|
84132
|
-
auto list_type = LogicalType::LIST(max_child_type);
|
|
84133
|
-
|
|
84134
|
-
bound_function.arguments[0] = list_type;
|
|
84135
|
-
bound_function.arguments[1] = value == max_child_type ? value : max_child_type;
|
|
84136
|
-
bound_function.return_type = LogicalType::BOOLEAN;
|
|
84137
|
-
}
|
|
84138
|
-
return make_unique<VariableReturnBindData>(bound_function.return_type);
|
|
84139
|
-
}
|
|
84140
|
-
|
|
84141
|
-
ScalarFunction ListContainsFun::GetFunction() {
|
|
84142
|
-
return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
|
|
84143
|
-
LogicalType::BOOLEAN, // return type
|
|
84144
|
-
ListContainsFunction, false, ListContainsBind, nullptr);
|
|
84145
|
-
}
|
|
84146
|
-
|
|
84147
|
-
void ListContainsFun::RegisterFunction(BuiltinFunctions &set) {
|
|
84148
|
-
set.AddFunction({"list_contains", "array_contains", "list_has", "array_has"}, GetFunction());
|
|
84149
|
-
}
|
|
84150
|
-
} // namespace duckdb
|
|
84151
|
-
|
|
84152
|
-
|
|
84153
|
-
|
|
84154
84181
|
|
|
84155
84182
|
|
|
84156
84183
|
|
|
@@ -86202,6 +86229,7 @@ void BuiltinFunctions::RegisterNestedFunctions() {
|
|
|
86202
86229
|
Register<StructExtractFun>();
|
|
86203
86230
|
Register<ListConcatFun>();
|
|
86204
86231
|
Register<ListContainsFun>();
|
|
86232
|
+
Register<ListPositionFun>();
|
|
86205
86233
|
Register<ListValueFun>();
|
|
86206
86234
|
Register<ListExtractFun>();
|
|
86207
86235
|
Register<ListRangeFun>();
|
|
@@ -148800,13 +148828,19 @@ BindResult SelectBinder::BindUnnest(FunctionExpression &function, idx_t depth) {
|
|
|
148800
148828
|
}
|
|
148801
148829
|
auto &child = (BoundExpression &)*function.children[0];
|
|
148802
148830
|
auto &child_type = child.expr->return_type;
|
|
148803
|
-
|
|
148804
|
-
|
|
148831
|
+
|
|
148832
|
+
if (child_type.id() != LogicalTypeId::LIST && child_type.id() != LogicalTypeId::SQLNULL) {
|
|
148833
|
+
return BindResult(binder.FormatError(function, "Unnest() can only be applied to lists and NULL"));
|
|
148805
148834
|
}
|
|
148835
|
+
|
|
148806
148836
|
if (depth > 0) {
|
|
148807
148837
|
throw BinderException(binder.FormatError(function, "Unnest() for correlated expressions is not supported yet"));
|
|
148808
148838
|
}
|
|
148809
|
-
|
|
148839
|
+
|
|
148840
|
+
auto return_type = LogicalType(LogicalTypeId::SQLNULL);
|
|
148841
|
+
if (child_type.id() == LogicalTypeId::LIST) {
|
|
148842
|
+
return_type = ListType::GetChildType(child_type);
|
|
148843
|
+
}
|
|
148810
148844
|
|
|
148811
148845
|
auto result = make_unique<BoundUnnestExpression>(return_type);
|
|
148812
148846
|
result->child = move(child.expr);
|
|
@@ -148820,6 +148854,7 @@ BindResult SelectBinder::BindUnnest(FunctionExpression &function, idx_t depth) {
|
|
|
148820
148854
|
auto colref = make_unique<BoundColumnRefExpression>(
|
|
148821
148855
|
function.alias.empty() ? node.unnests[unnest_index]->ToString() : function.alias, return_type,
|
|
148822
148856
|
ColumnBinding(node.unnest_index, unnest_index), depth);
|
|
148857
|
+
|
|
148823
148858
|
return BindResult(move(colref));
|
|
148824
148859
|
}
|
|
148825
148860
|
|
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "v0.3.3-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "3af6ff8a3"
|
|
15
|
+
#define DUCKDB_VERSION "v0.3.3-dev551"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|