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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.3.3-dev534.0",
4
+ "version": "0.3.3-dev551.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
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
- auto &child_vector = ListVector::GetEntry(list_vector);
62793
- auto list_size = ListVector::GetListSize(list_vector);
62794
- child_vector.Orrify(list_size, state.list_child_data[col_idx]);
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
- auto &vdata = state.list_vector_data[col_idx];
62844
- auto &child_data = state.list_child_data[col_idx];
62845
- auto current_idx = vdata.sel->get_index(state.parent_position);
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
- list_count = MinValue<idx_t>(this_chunk_len, list_entry.length - state.list_position);
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
- if (list_entry.length > state.list_position) {
62858
- if (!vdata.validity.RowIsValid(current_idx)) {
62859
- UnnestNull(0, list_count, result_vector);
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
- auto &list_vector = state.list_data.data[col_idx];
62862
- auto &child_vector = ListVector::GetEntry(list_vector);
62863
- auto list_size = ListVector::GetListSize(list_vector);
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
- auto base_offset = list_entry.offset + state.list_position;
62866
- UnnestVector(child_data, child_vector, list_size, base_offset, base_offset + list_count,
62867
- result_vector);
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
- if (child_type.id() != LogicalTypeId::LIST) {
148804
- return BindResult(binder.FormatError(function, "Unnest() can only be applied to lists"));
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
- auto &return_type = ListType::GetChildType(child_type);
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 "c47290a22"
15
- #define DUCKDB_VERSION "v0.3.3-dev534"
14
+ #define DUCKDB_SOURCE_ID "3af6ff8a3"
15
+ #define DUCKDB_VERSION "v0.3.3-dev551"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //