duckdb 0.8.2-dev4871.0 → 0.8.2-dev5002.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.
Files changed (54) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/src/common/operator/cast_operators.cpp +18 -0
  3. package/src/duckdb/src/common/row_operations/row_matcher.cpp +5 -38
  4. package/src/duckdb/src/common/types/data_chunk.cpp +48 -11
  5. package/src/duckdb/src/common/types/vector.cpp +0 -1
  6. package/src/duckdb/src/common/types.cpp +1 -1
  7. package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +5 -1
  8. package/src/duckdb/src/core_functions/scalar/list/list_sort.cpp +10 -1
  9. package/src/duckdb/src/core_functions/scalar/map/map_concat.cpp +0 -2
  10. package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_inner.cpp +20 -27
  11. package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp +21 -9
  12. package/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp +7 -7
  13. package/src/duckdb/src/execution/operator/csv_scanner/csv_reader_options.cpp +1 -1
  14. package/src/duckdb/src/function/cast/time_casts.cpp +12 -0
  15. package/src/duckdb/src/function/pragma/pragma_queries.cpp +3 -0
  16. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  17. package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +5 -0
  18. package/src/duckdb/src/include/duckdb/common/operator/cast_operators.hpp +27 -0
  19. package/src/duckdb/src/include/duckdb/common/operator/comparison_operators.hpp +38 -2
  20. package/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp +4 -4
  21. package/src/duckdb/src/include/duckdb/core_functions/scalar/blob_functions.hpp +4 -4
  22. package/src/duckdb/src/include/duckdb/core_functions/scalar/date_functions.hpp +5 -5
  23. package/src/duckdb/src/include/duckdb/core_functions/scalar/enum_functions.hpp +7 -7
  24. package/src/duckdb/src/include/duckdb/core_functions/scalar/generic_functions.hpp +12 -12
  25. package/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +12 -12
  26. package/src/duckdb/src/include/duckdb/core_functions/scalar/map_functions.hpp +3 -3
  27. package/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp +33 -33
  28. package/src/duckdb/src/include/duckdb/core_functions/scalar/operators_functions.hpp +2 -2
  29. package/src/duckdb/src/include/duckdb/core_functions/scalar/random_functions.hpp +3 -3
  30. package/src/duckdb/src/include/duckdb/core_functions/scalar/string_functions.hpp +12 -12
  31. package/src/duckdb/src/include/duckdb/core_functions/scalar/struct_functions.hpp +2 -2
  32. package/src/duckdb/src/include/duckdb/core_functions/scalar/union_functions.hpp +2 -2
  33. package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -0
  34. package/src/duckdb/src/include/duckdb/planner/operator/logical_create_table.hpp +1 -2
  35. package/src/duckdb/src/include/duckdb/planner/operator/logical_delete.hpp +1 -1
  36. package/src/duckdb/src/include/duckdb/planner/operator/logical_insert.hpp +1 -1
  37. package/src/duckdb/src/include/duckdb/planner/operator/logical_update.hpp +1 -1
  38. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
  39. package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +1 -1
  40. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +28 -6
  41. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +3 -0
  42. package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +14 -6
  43. package/src/duckdb/src/planner/operator/logical_create_table.cpp +3 -3
  44. package/src/duckdb/src/planner/operator/logical_delete.cpp +3 -2
  45. package/src/duckdb/src/planner/operator/logical_insert.cpp +3 -2
  46. package/src/duckdb/src/planner/operator/logical_update.cpp +3 -2
  47. package/src/duckdb/src/storage/data_table.cpp +8 -8
  48. package/src/duckdb/src/storage/local_storage.cpp +2 -3
  49. package/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +64 -80
  50. package/src/duckdb/src/storage/storage_manager.cpp +6 -2
  51. package/src/duckdb/src/storage/table/row_group.cpp +6 -0
  52. package/src/duckdb/src/storage/table/row_group_collection.cpp +4 -3
  53. package/src/duckdb/src/storage/table/struct_column_data.cpp +2 -0
  54. package/src/duckdb/src/transaction/duck_transaction.cpp +1 -0
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.8.2-dev4871.0",
5
+ "version": "0.8.2-dev5002.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -1373,6 +1373,12 @@ timestamp_t CastTimestampMsToUs::Operation(timestamp_t input) {
1373
1373
  return Timestamp::FromEpochMs(input.value);
1374
1374
  }
1375
1375
 
1376
+ template <>
1377
+ timestamp_t CastTimestampMsToNs::Operation(timestamp_t input) {
1378
+ auto us = CastTimestampMsToUs::Operation<timestamp_t, timestamp_t>(input);
1379
+ return CastTimestampUsToNs::Operation<timestamp_t, timestamp_t>(us);
1380
+ }
1381
+
1376
1382
  template <>
1377
1383
  timestamp_t CastTimestampNsToUs::Operation(timestamp_t input) {
1378
1384
  return Timestamp::FromEpochNanoSeconds(input.value);
@@ -1383,6 +1389,18 @@ timestamp_t CastTimestampSecToUs::Operation(timestamp_t input) {
1383
1389
  return Timestamp::FromEpochSeconds(input.value);
1384
1390
  }
1385
1391
 
1392
+ template <>
1393
+ timestamp_t CastTimestampSecToMs::Operation(timestamp_t input) {
1394
+ auto us = CastTimestampSecToUs::Operation<timestamp_t, timestamp_t>(input);
1395
+ return CastTimestampUsToMs::Operation<timestamp_t, timestamp_t>(us);
1396
+ }
1397
+
1398
+ template <>
1399
+ timestamp_t CastTimestampSecToNs::Operation(timestamp_t input) {
1400
+ auto us = CastTimestampSecToUs::Operation<timestamp_t, timestamp_t>(input);
1401
+ return CastTimestampUsToNs::Operation<timestamp_t, timestamp_t>(us);
1402
+ }
1403
+
1386
1404
  //===--------------------------------------------------------------------===//
1387
1405
  // Cast To Timestamp
1388
1406
  //===--------------------------------------------------------------------===//
@@ -8,44 +8,11 @@ namespace duckdb {
8
8
 
9
9
  using ValidityBytes = TupleDataLayout::ValidityBytes;
10
10
 
11
- template <class OP>
12
- struct RowMatchOperator {
13
- static constexpr const bool COMPARE_NULL = false;
14
-
15
- template <class T>
16
- static inline bool Operation(const T &left, const T &right, bool left_null, bool right_null) {
17
- if (right_null || left_null) {
18
- return false;
19
- }
20
- return OP::template Operation<T>(left, right);
21
- }
22
- };
23
-
24
- template <>
25
- struct RowMatchOperator<DistinctFrom> {
26
- static constexpr const bool COMPARE_NULL = true;
27
-
28
- template <class T>
29
- static inline bool Operation(const T &left, const T &right, bool left_null, bool right_null) {
30
- return DistinctFrom::template Operation<T>(left, right, left_null, right_null);
31
- }
32
- };
33
-
34
- template <>
35
- struct RowMatchOperator<NotDistinctFrom> {
36
- static constexpr const bool COMPARE_NULL = true;
37
-
38
- template <class T>
39
- static inline bool Operation(const T &left, const T &right, bool left_null, bool right_null) {
40
- return NotDistinctFrom::template Operation<T>(left, right, left_null, right_null);
41
- }
42
- };
43
-
44
11
  template <bool NO_MATCH_SEL, class T, class OP>
45
12
  static idx_t TemplatedMatch(Vector &, const TupleDataVectorFormat &lhs_format, SelectionVector &sel, const idx_t count,
46
13
  const TupleDataLayout &rhs_layout, Vector &rhs_row_locations, const idx_t col_idx,
47
14
  const vector<MatchFunction> &, SelectionVector *no_match_sel, idx_t &no_match_count) {
48
- using MATCH_OP = RowMatchOperator<OP>;
15
+ using COMPARISON_OP = ComparisonOperationWrapper<OP>;
49
16
 
50
17
  // LHS
51
18
  const auto &lhs_sel = *lhs_format.unified.sel;
@@ -70,8 +37,8 @@ static idx_t TemplatedMatch(Vector &, const TupleDataVectorFormat &lhs_format, S
70
37
  const ValidityBytes rhs_mask(rhs_location);
71
38
  const auto rhs_null = !rhs_mask.RowIsValid(rhs_mask.GetValidityEntryUnsafe(entry_idx), idx_in_entry);
72
39
 
73
- if (MATCH_OP::template Operation<T>(lhs_data[lhs_idx], Load<T>(rhs_location + rhs_offset_in_row), lhs_null,
74
- rhs_null)) {
40
+ if (COMPARISON_OP::template Operation<T>(lhs_data[lhs_idx], Load<T>(rhs_location + rhs_offset_in_row), lhs_null,
41
+ rhs_null)) {
75
42
  sel.set_index(match_count++, idx);
76
43
  } else if (NO_MATCH_SEL) {
77
44
  no_match_sel->set_index(no_match_count++, idx);
@@ -85,7 +52,7 @@ static idx_t StructMatchEquality(Vector &lhs_vector, const TupleDataVectorFormat
85
52
  const idx_t count, const TupleDataLayout &rhs_layout, Vector &rhs_row_locations,
86
53
  const idx_t col_idx, const vector<MatchFunction> &child_functions,
87
54
  SelectionVector *no_match_sel, idx_t &no_match_count) {
88
- using MATCH_OP = RowMatchOperator<OP>;
55
+ using COMPARISON_OP = ComparisonOperationWrapper<OP>;
89
56
 
90
57
  // LHS
91
58
  const auto &lhs_sel = *lhs_format.unified.sel;
@@ -111,7 +78,7 @@ static idx_t StructMatchEquality(Vector &lhs_vector, const TupleDataVectorFormat
111
78
  // For structs there is no value to compare, here we match NULLs and let recursion do the rest
112
79
  // So we use the comparison only if rhs or LHS is NULL and COMPARE_NULL is true
113
80
  if (!(lhs_null || rhs_null) ||
114
- (MATCH_OP::COMPARE_NULL && MATCH_OP::template Operation<uint32_t>(0, 0, lhs_null, rhs_null))) {
81
+ (COMPARISON_OP::COMPARE_NULL && COMPARISON_OP::template Operation<uint32_t>(0, 0, lhs_null, rhs_null))) {
115
82
  sel.set_index(match_count++, idx);
116
83
  } else if (NO_MATCH_SEL) {
117
84
  no_match_sel->set_index(no_match_count++, idx);
@@ -13,6 +13,10 @@
13
13
  #include "duckdb/common/vector_operations/vector_operations.hpp"
14
14
  #include "duckdb/execution/execution_context.hpp"
15
15
 
16
+ #include "duckdb/common/serializer/memory_stream.hpp"
17
+ #include "duckdb/common/serializer/binary_serializer.hpp"
18
+ #include "duckdb/common/serializer/binary_deserializer.hpp"
19
+
16
20
  namespace duckdb {
17
21
 
18
22
  DataChunk::DataChunk() : count(0), capacity(STANDARD_VECTOR_SIZE) {
@@ -231,16 +235,20 @@ string DataChunk::ToString() const {
231
235
  }
232
236
 
233
237
  void DataChunk::Serialize(Serializer &serializer) const {
238
+
234
239
  // write the count
235
240
  auto row_count = size();
236
241
  serializer.WriteProperty<sel_t>(100, "rows", row_count);
242
+
243
+ // we should never try to serialize empty data chunks
237
244
  auto column_count = ColumnCount();
245
+ D_ASSERT(column_count);
238
246
 
239
- // Write the types
247
+ // write the types
240
248
  serializer.WriteList(101, "types", column_count,
241
249
  [&](Serializer::List &list, idx_t i) { list.WriteElement(data[i].GetType()); });
242
250
 
243
- // Write the data
251
+ // write the data
244
252
  serializer.WriteList(102, "columns", column_count, [&](Serializer::List &list, idx_t i) {
245
253
  list.WriteObject([&](Serializer &object) {
246
254
  // Reference the vector to avoid potentially mutating it during serialization
@@ -252,21 +260,23 @@ void DataChunk::Serialize(Serializer &serializer) const {
252
260
  }
253
261
 
254
262
  void DataChunk::Deserialize(Deserializer &deserializer) {
255
- // read the count
263
+
264
+ // read and set the row count
256
265
  auto row_count = deserializer.ReadProperty<sel_t>(100, "rows");
266
+ SetCardinality(row_count);
257
267
 
258
- // Read the types
268
+ // read the types
259
269
  vector<LogicalType> types;
260
270
  deserializer.ReadList(101, "types", [&](Deserializer::List &list, idx_t i) {
261
271
  auto type = list.ReadElement<LogicalType>();
262
272
  types.push_back(type);
263
273
  });
264
- Initialize(Allocator::DefaultAllocator(), types);
265
274
 
266
- // now load the column data
267
- SetCardinality(row_count);
275
+ // initialize the data chunk
276
+ D_ASSERT(!types.empty());
277
+ Initialize(Allocator::DefaultAllocator(), types);
268
278
 
269
- // Read the data
279
+ // read the data
270
280
  deserializer.ReadList(102, "columns", [&](Deserializer::List &list, idx_t i) {
271
281
  list.ReadObject([&](Deserializer &object) { data[i].Deserialize(object, row_count); });
272
282
  });
@@ -296,11 +306,11 @@ void DataChunk::Slice(DataChunk &other, const SelectionVector &sel, idx_t count_
296
306
  }
297
307
 
298
308
  unsafe_unique_array<UnifiedVectorFormat> DataChunk::ToUnifiedFormat() {
299
- auto orrified_data = make_unsafe_uniq_array<UnifiedVectorFormat>(ColumnCount());
309
+ auto unified_data = make_unsafe_uniq_array<UnifiedVectorFormat>(ColumnCount());
300
310
  for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
301
- data[col_idx].ToUnifiedFormat(size(), orrified_data[col_idx]);
311
+ data[col_idx].ToUnifiedFormat(size(), unified_data[col_idx]);
302
312
  }
303
- return orrified_data;
313
+ return unified_data;
304
314
  }
305
315
 
306
316
  void DataChunk::Hash(Vector &result) {
@@ -324,10 +334,37 @@ void DataChunk::Hash(vector<idx_t> &column_ids, Vector &result) {
324
334
  void DataChunk::Verify() {
325
335
  #ifdef DEBUG
326
336
  D_ASSERT(size() <= capacity);
337
+
327
338
  // verify that all vectors in this chunk have the chunk selection vector
328
339
  for (idx_t i = 0; i < ColumnCount(); i++) {
329
340
  data[i].Verify(size());
330
341
  }
342
+
343
+ if (!ColumnCount()) {
344
+ // don't try to round-trip dummy data chunks with no data
345
+ // e.g., these exist in queries like 'SELECT distinct(col0, col1) FROM tbl', where we have groups, but no
346
+ // payload so the payload will be such an empty data chunk
347
+ return;
348
+ }
349
+
350
+ // verify that we can round-trip chunk serialization
351
+ MemoryStream mem_stream;
352
+ BinarySerializer serializer(mem_stream);
353
+
354
+ serializer.Begin();
355
+ Serialize(serializer);
356
+ serializer.End();
357
+
358
+ mem_stream.Rewind();
359
+
360
+ BinaryDeserializer deserializer(mem_stream);
361
+ DataChunk new_chunk;
362
+
363
+ deserializer.Begin();
364
+ new_chunk.Deserialize(deserializer);
365
+ deserializer.End();
366
+
367
+ D_ASSERT(size() == new_chunk.size());
331
368
  #endif
332
369
  }
333
370
 
@@ -960,7 +960,6 @@ void Vector::Serialize(Serializer &serializer, idx_t count) {
960
960
  break;
961
961
  }
962
962
  case PhysicalType::STRUCT: {
963
- Flatten(count);
964
963
  auto &entries = StructVector::GetEntries(*this);
965
964
 
966
965
  // Serialize entries as a list
@@ -434,7 +434,7 @@ LogicalType TransformStringToLogicalType(const string &str) {
434
434
 
435
435
  LogicalType GetUserTypeRecursive(const LogicalType &type, ClientContext &context) {
436
436
  if (type.id() == LogicalTypeId::USER && type.HasAlias()) {
437
- return Catalog::GetSystemCatalog(context).GetType(context, SYSTEM_CATALOG, DEFAULT_SCHEMA, type.GetAlias());
437
+ return Catalog::GetType(context, INVALID_CATALOG, INVALID_SCHEMA, type.GetAlias());
438
438
  }
439
439
  // Look for LogicalTypeId::USER in nested types
440
440
  if (type.id() == LogicalTypeId::STRUCT) {
@@ -191,9 +191,11 @@ static void ExecuteConstantSlice(Vector &result, Vector &str_vector, Vector &beg
191
191
  }
192
192
 
193
193
  auto sel_length = 0;
194
+ bool sel_valid = false;
194
195
  if (step_vector && step_valid && str_valid && begin_valid && end_valid && step != 1 && end - begin > 0) {
195
196
  sel_length = CalculateSliceLength(begin, end, step, step_valid);
196
197
  sel.Initialize(sel_length);
198
+ sel_valid = true;
197
199
  }
198
200
 
199
201
  // Try to slice
@@ -205,8 +207,9 @@ static void ExecuteConstantSlice(Vector &result, Vector &str_vector, Vector &beg
205
207
  result_data[0] = SliceValueWithSteps<INPUT_TYPE, INDEX_TYPE>(result, sel, str, begin, end, step, sel_idx);
206
208
  }
207
209
 
208
- if (step_vector && step != 0 && end - begin > 0) {
210
+ if (sel_valid) {
209
211
  result_child_vector->Slice(sel, sel_length);
212
+ ListVector::SetListSize(result, sel_length);
210
213
  }
211
214
  }
212
215
 
@@ -276,6 +279,7 @@ static void ExecuteFlatSlice(Vector &result, Vector &list_vector, Vector &begin_
276
279
  new_sel.set_index(i, sel.get_index(i));
277
280
  }
278
281
  result_child_vector->Slice(new_sel, sel_length);
282
+ ListVector::SetListSize(result, sel_length);
279
283
  }
280
284
  }
281
285
 
@@ -236,9 +236,18 @@ static void ListSortFunction(DataChunk &args, ExpressionState &state, Vector &re
236
236
  static unique_ptr<FunctionData> ListSortBind(ClientContext &context, ScalarFunction &bound_function,
237
237
  vector<unique_ptr<Expression>> &arguments, OrderType &order,
238
238
  OrderByNullType &null_order) {
239
+
240
+ LogicalType child_type;
241
+ if (arguments[0]->return_type == LogicalTypeId::UNKNOWN) {
242
+ bound_function.arguments[0] = LogicalTypeId::UNKNOWN;
243
+ bound_function.return_type = LogicalType::SQLNULL;
244
+ child_type = bound_function.return_type;
245
+ return make_uniq<ListSortBindData>(order, null_order, bound_function.return_type, child_type, context);
246
+ }
247
+
239
248
  bound_function.arguments[0] = arguments[0]->return_type;
240
249
  bound_function.return_type = arguments[0]->return_type;
241
- auto child_type = ListType::GetChildType(arguments[0]->return_type);
250
+ child_type = ListType::GetChildType(arguments[0]->return_type);
242
251
 
243
252
  return make_uniq<ListSortBindData>(order, null_order, bound_function.return_type, child_type, context);
244
253
  }
@@ -97,7 +97,6 @@ static void MapConcatFunction(DataChunk &args, ExpressionState &state, Vector &r
97
97
  auto &values = MapVector::GetValues(map);
98
98
  values_list.push_back(values.GetValue(mapping.key_index));
99
99
  }
100
- idx_t entries_count = keys_list.size();
101
100
  D_ASSERT(values_list.size() == keys_list.size());
102
101
  result_entry.offset = ListVector::GetListSize(result);
103
102
  result_entry.length = values_list.size();
@@ -105,7 +104,6 @@ static void MapConcatFunction(DataChunk &args, ExpressionState &state, Vector &r
105
104
  for (auto &list_entry : list_entries) {
106
105
  ListVector::PushBack(result, list_entry);
107
106
  }
108
- ListVector::SetListSize(result, ListVector::GetListSize(result) + entries_count);
109
107
  }
110
108
 
111
109
  if (args.AllConstant()) {
@@ -3,21 +3,12 @@
3
3
 
4
4
  namespace duckdb {
5
5
 
6
- template <class OP>
7
- struct ComparisonOperationWrapper {
8
- template <class T>
9
- static inline bool Operation(T left, T right, bool left_is_null, bool right_is_null) {
10
- if (left_is_null || right_is_null) {
11
- return false;
12
- }
13
- return OP::Operation(left, right);
14
- }
15
- };
16
-
17
6
  struct InitialNestedLoopJoin {
18
7
  template <class T, class OP>
19
8
  static idx_t Operation(Vector &left, Vector &right, idx_t left_size, idx_t right_size, idx_t &lpos, idx_t &rpos,
20
9
  SelectionVector &lvector, SelectionVector &rvector, idx_t current_match_count) {
10
+ using MATCH_OP = ComparisonOperationWrapper<OP>;
11
+
21
12
  // initialize phase of nested loop join
22
13
  // fill lvector and rvector with matches from the base vectors
23
14
  UnifiedVectorFormat left_data, right_data;
@@ -37,7 +28,7 @@ struct InitialNestedLoopJoin {
37
28
  }
38
29
  idx_t left_position = left_data.sel->get_index(lpos);
39
30
  bool left_is_valid = left_data.validity.RowIsValid(left_position);
40
- if (OP::Operation(ldata[left_position], rdata[right_position], !left_is_valid, !right_is_valid)) {
31
+ if (MATCH_OP::Operation(ldata[left_position], rdata[right_position], !left_is_valid, !right_is_valid)) {
41
32
  // emit tuple
42
33
  lvector.set_index(result_count, lpos);
43
34
  rvector.set_index(result_count, rpos);
@@ -54,6 +45,8 @@ struct RefineNestedLoopJoin {
54
45
  template <class T, class OP>
55
46
  static idx_t Operation(Vector &left, Vector &right, idx_t left_size, idx_t right_size, idx_t &lpos, idx_t &rpos,
56
47
  SelectionVector &lvector, SelectionVector &rvector, idx_t current_match_count) {
48
+ using MATCH_OP = ComparisonOperationWrapper<OP>;
49
+
57
50
  UnifiedVectorFormat left_data, right_data;
58
51
  left.ToUnifiedFormat(left_size, left_data);
59
52
  right.ToUnifiedFormat(right_size, right_data);
@@ -72,7 +65,7 @@ struct RefineNestedLoopJoin {
72
65
  auto right_idx = right_data.sel->get_index(ridx);
73
66
  bool left_is_valid = left_data.validity.RowIsValid(left_idx);
74
67
  bool right_is_valid = right_data.validity.RowIsValid(right_idx);
75
- if (OP::Operation(ldata[left_idx], rdata[right_idx], !left_is_valid, !right_is_valid)) {
68
+ if (MATCH_OP::Operation(ldata[left_idx], rdata[right_idx], !left_is_valid, !right_is_valid)) {
76
69
  lvector.set_index(result_count, lidx);
77
70
  rvector.set_index(result_count, ridx);
78
71
  result_count++;
@@ -139,26 +132,26 @@ idx_t NestedLoopJoinComparisonSwitch(Vector &left, Vector &right, idx_t left_siz
139
132
  D_ASSERT(left.GetType() == right.GetType());
140
133
  switch (comparison_type) {
141
134
  case ExpressionType::COMPARE_EQUAL:
142
- return NestedLoopJoinTypeSwitch<NLTYPE, ComparisonOperationWrapper<duckdb::Equals>>(
143
- left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
135
+ return NestedLoopJoinTypeSwitch<NLTYPE, Equals>(left, right, left_size, right_size, lpos, rpos, lvector,
136
+ rvector, current_match_count);
144
137
  case ExpressionType::COMPARE_NOTEQUAL:
145
- return NestedLoopJoinTypeSwitch<NLTYPE, ComparisonOperationWrapper<duckdb::NotEquals>>(
146
- left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
138
+ return NestedLoopJoinTypeSwitch<NLTYPE, NotEquals>(left, right, left_size, right_size, lpos, rpos, lvector,
139
+ rvector, current_match_count);
147
140
  case ExpressionType::COMPARE_LESSTHAN:
148
- return NestedLoopJoinTypeSwitch<NLTYPE, ComparisonOperationWrapper<duckdb::LessThan>>(
149
- left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
141
+ return NestedLoopJoinTypeSwitch<NLTYPE, LessThan>(left, right, left_size, right_size, lpos, rpos, lvector,
142
+ rvector, current_match_count);
150
143
  case ExpressionType::COMPARE_GREATERTHAN:
151
- return NestedLoopJoinTypeSwitch<NLTYPE, ComparisonOperationWrapper<duckdb::GreaterThan>>(
152
- left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
144
+ return NestedLoopJoinTypeSwitch<NLTYPE, GreaterThan>(left, right, left_size, right_size, lpos, rpos, lvector,
145
+ rvector, current_match_count);
153
146
  case ExpressionType::COMPARE_LESSTHANOREQUALTO:
154
- return NestedLoopJoinTypeSwitch<NLTYPE, ComparisonOperationWrapper<duckdb::LessThanEquals>>(
155
- left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
147
+ return NestedLoopJoinTypeSwitch<NLTYPE, LessThanEquals>(left, right, left_size, right_size, lpos, rpos, lvector,
148
+ rvector, current_match_count);
156
149
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
157
- return NestedLoopJoinTypeSwitch<NLTYPE, ComparisonOperationWrapper<duckdb::GreaterThanEquals>>(
158
- left, right, left_size, right_size, lpos, rpos, lvector, rvector, current_match_count);
150
+ return NestedLoopJoinTypeSwitch<NLTYPE, GreaterThanEquals>(left, right, left_size, right_size, lpos, rpos,
151
+ lvector, rvector, current_match_count);
159
152
  case ExpressionType::COMPARE_DISTINCT_FROM:
160
- return NestedLoopJoinTypeSwitch<NLTYPE, duckdb::DistinctFrom>(left, right, left_size, right_size, lpos, rpos,
161
- lvector, rvector, current_match_count);
153
+ return NestedLoopJoinTypeSwitch<NLTYPE, DistinctFrom>(left, right, left_size, right_size, lpos, rpos, lvector,
154
+ rvector, current_match_count);
162
155
  default:
163
156
  throw NotImplementedException("Unimplemented comparison type for join!");
164
157
  }
@@ -6,6 +6,8 @@ namespace duckdb {
6
6
 
7
7
  template <class T, class OP>
8
8
  static void TemplatedMarkJoin(Vector &left, Vector &right, idx_t lcount, idx_t rcount, bool found_match[]) {
9
+ using MATCH_OP = ComparisonOperationWrapper<OP>;
10
+
9
11
  UnifiedVectorFormat left_data, right_data;
10
12
  left.ToUnifiedFormat(lcount, left_data);
11
13
  right.ToUnifiedFormat(rcount, right_data);
@@ -17,15 +19,17 @@ static void TemplatedMarkJoin(Vector &left, Vector &right, idx_t lcount, idx_t r
17
19
  continue;
18
20
  }
19
21
  auto lidx = left_data.sel->get_index(i);
20
- if (!left_data.validity.RowIsValid(lidx)) {
22
+ const auto left_null = !left_data.validity.RowIsValid(lidx);
23
+ if (!MATCH_OP::COMPARE_NULL && left_null) {
21
24
  continue;
22
25
  }
23
26
  for (idx_t j = 0; j < rcount; j++) {
24
27
  auto ridx = right_data.sel->get_index(j);
25
- if (!right_data.validity.RowIsValid(ridx)) {
28
+ const auto right_null = !right_data.validity.RowIsValid(ridx);
29
+ if (!MATCH_OP::COMPARE_NULL && right_null) {
26
30
  continue;
27
31
  }
28
- if (OP::Operation(ldata[lidx], rdata[ridx])) {
32
+ if (MATCH_OP::template Operation<T>(ldata[lidx], rdata[ridx], left_null, right_null)) {
29
33
  found_match[i] = true;
30
34
  break;
31
35
  }
@@ -62,6 +66,12 @@ static void MarkJoinNested(Vector &left, Vector &right, idx_t lcount, idx_t rcou
62
66
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
63
67
  count = VectorOperations::GreaterThanEquals(left_reference, right, nullptr, rcount, nullptr, nullptr);
64
68
  break;
69
+ case ExpressionType::COMPARE_DISTINCT_FROM:
70
+ count = VectorOperations::DistinctFrom(left_reference, right, nullptr, rcount, nullptr, nullptr);
71
+ break;
72
+ case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
73
+ count = VectorOperations::NotDistinctFrom(left_reference, right, nullptr, rcount, nullptr, nullptr);
74
+ break;
65
75
  default:
66
76
  throw InternalException("Unsupported comparison type for MarkJoinNested");
67
77
  }
@@ -116,17 +126,19 @@ static void MarkJoinComparisonSwitch(Vector &left, Vector &right, idx_t lcount,
116
126
  D_ASSERT(left.GetType() == right.GetType());
117
127
  switch (comparison_type) {
118
128
  case ExpressionType::COMPARE_EQUAL:
119
- return MarkJoinSwitch<duckdb::Equals>(left, right, lcount, rcount, found_match);
129
+ return MarkJoinSwitch<Equals>(left, right, lcount, rcount, found_match);
120
130
  case ExpressionType::COMPARE_NOTEQUAL:
121
- return MarkJoinSwitch<duckdb::NotEquals>(left, right, lcount, rcount, found_match);
131
+ return MarkJoinSwitch<NotEquals>(left, right, lcount, rcount, found_match);
122
132
  case ExpressionType::COMPARE_LESSTHAN:
123
- return MarkJoinSwitch<duckdb::LessThan>(left, right, lcount, rcount, found_match);
133
+ return MarkJoinSwitch<LessThan>(left, right, lcount, rcount, found_match);
124
134
  case ExpressionType::COMPARE_GREATERTHAN:
125
- return MarkJoinSwitch<duckdb::GreaterThan>(left, right, lcount, rcount, found_match);
135
+ return MarkJoinSwitch<GreaterThan>(left, right, lcount, rcount, found_match);
126
136
  case ExpressionType::COMPARE_LESSTHANOREQUALTO:
127
- return MarkJoinSwitch<duckdb::LessThanEquals>(left, right, lcount, rcount, found_match);
137
+ return MarkJoinSwitch<LessThanEquals>(left, right, lcount, rcount, found_match);
128
138
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
129
- return MarkJoinSwitch<duckdb::GreaterThanEquals>(left, right, lcount, rcount, found_match);
139
+ return MarkJoinSwitch<GreaterThanEquals>(left, right, lcount, rcount, found_match);
140
+ case ExpressionType::COMPARE_DISTINCT_FROM:
141
+ return MarkJoinSwitch<DistinctFrom>(left, right, lcount, rcount, found_match);
130
142
  default:
131
143
  throw NotImplementedException("Unimplemented comparison type for join!");
132
144
  }
@@ -343,8 +343,8 @@ void PhysicalHashAggregate::SinkDistinct(ExecutionContext &context, DataChunk &c
343
343
 
344
344
  SinkResultType PhysicalHashAggregate::Sink(ExecutionContext &context, DataChunk &chunk,
345
345
  OperatorSinkInput &input) const {
346
- auto &llstate = input.local_state.Cast<HashAggregateLocalSinkState>();
347
- auto &gstate = input.global_state.Cast<HashAggregateGlobalSinkState>();
346
+ auto &local_state = input.local_state.Cast<HashAggregateLocalSinkState>();
347
+ auto &global_state = input.global_state.Cast<HashAggregateGlobalSinkState>();
348
348
 
349
349
  if (distinct_collection_info) {
350
350
  SinkDistinct(context, chunk, input);
@@ -354,8 +354,7 @@ SinkResultType PhysicalHashAggregate::Sink(ExecutionContext &context, DataChunk
354
354
  return SinkResultType::NEED_MORE_INPUT;
355
355
  }
356
356
 
357
- DataChunk &aggregate_input_chunk = llstate.aggregate_input_chunk;
358
-
357
+ DataChunk &aggregate_input_chunk = local_state.aggregate_input_chunk;
359
358
  auto &aggregates = grouped_aggregate_data.aggregates;
360
359
  idx_t aggregate_input_idx = 0;
361
360
 
@@ -385,10 +384,11 @@ SinkResultType PhysicalHashAggregate::Sink(ExecutionContext &context, DataChunk
385
384
 
386
385
  // For every grouping set there is one radix_table
387
386
  for (idx_t i = 0; i < groupings.size(); i++) {
388
- auto &grouping_gstate = gstate.grouping_states[i];
389
- auto &grouping_lstate = llstate.grouping_states[i];
387
+ auto &grouping_local_state = global_state.grouping_states[i];
388
+ auto &grouping_global_state = local_state.grouping_states[i];
390
389
  InterruptState interrupt_state;
391
- OperatorSinkInput sink_input {*grouping_gstate.table_state, *grouping_lstate.table_state, interrupt_state};
390
+ OperatorSinkInput sink_input {*grouping_local_state.table_state, *grouping_global_state.table_state,
391
+ interrupt_state};
392
392
 
393
393
  auto &grouping = groupings[i];
394
394
  auto &table = grouping.table_data;
@@ -437,7 +437,7 @@ void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientCont
437
437
  }
438
438
  sql_type_list.reserve(sql_type_names.size());
439
439
  for (auto &sql_type : sql_type_names) {
440
- auto def_type = TransformStringToLogicalType(sql_type);
440
+ auto def_type = TransformStringToLogicalType(sql_type, context);
441
441
  if (def_type.id() == LogicalTypeId::USER) {
442
442
  throw BinderException("Unrecognized type \"%s\" for read_csv_auto %s definition", sql_type,
443
443
  kv.first);
@@ -134,6 +134,10 @@ BoundCastInfo DefaultCasts::TimestampMsCastSwitch(BindCastInput &input, const Lo
134
134
  // timestamp (ms) to timestamp (us)
135
135
  return BoundCastInfo(
136
136
  &VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampMsToUs>);
137
+ case LogicalTypeId::TIMESTAMP_NS:
138
+ // timestamp (ms) to timestamp (ns)
139
+ return BoundCastInfo(
140
+ &VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampMsToNs>);
137
141
  default:
138
142
  return TryVectorNullCast;
139
143
  }
@@ -146,10 +150,18 @@ BoundCastInfo DefaultCasts::TimestampSecCastSwitch(BindCastInput &input, const L
146
150
  case LogicalTypeId::VARCHAR:
147
151
  // timestamp (sec) to varchar
148
152
  return BoundCastInfo(&VectorCastHelpers::StringCast<timestamp_t, duckdb::CastFromTimestampSec>);
153
+ case LogicalTypeId::TIMESTAMP_MS:
154
+ // timestamp (s) to timestamp (ms)
155
+ return BoundCastInfo(
156
+ &VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampSecToMs>);
149
157
  case LogicalTypeId::TIMESTAMP:
150
158
  // timestamp (s) to timestamp (us)
151
159
  return BoundCastInfo(
152
160
  &VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampSecToUs>);
161
+ case LogicalTypeId::TIMESTAMP_NS:
162
+ // timestamp (s) to timestamp (ns)
163
+ return BoundCastInfo(
164
+ &VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampSecToNs>);
153
165
  default:
154
166
  return TryVectorNullCast;
155
167
  }
@@ -124,12 +124,15 @@ string PragmaShow(ClientContext &context, const FunctionParameters &parameters)
124
124
  ON cols.column_name = pragma_table_info.name
125
125
  AND cols.table_name='%table_name%'
126
126
  AND cols.schema_name='%table_schema%'
127
+ AND cols.database_name = '%table_database%'
127
128
  ORDER BY column_index;)";
128
129
  // clang-format on
129
130
 
130
131
  sql = StringUtil::Replace(sql, "%func_param_table%", parameters.values[0].ToString());
131
132
  sql = StringUtil::Replace(sql, "%table_name%", table.name);
132
133
  sql = StringUtil::Replace(sql, "%table_schema%", table.schema.empty() ? DEFAULT_SCHEMA : table.schema);
134
+ sql = StringUtil::Replace(sql, "%table_database%",
135
+ table.catalog.empty() ? DatabaseManager::GetDefaultDatabase(context) : table.catalog);
133
136
  return sql;
134
137
  }
135
138
 
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.8.2-dev4871"
2
+ #define DUCKDB_VERSION "0.8.2-dev5002"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "5a29c99891"
5
+ #define DUCKDB_SOURCE_ID "239f51293c"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -182,6 +182,11 @@ struct MultiFileReader {
182
182
  }
183
183
  }
184
184
  for (idx_t r = 0; r < data.union_readers.size(); r++) {
185
+ if (!data.union_readers[r]) {
186
+ data.union_readers.erase(data.union_readers.begin() + r);
187
+ r--;
188
+ continue;
189
+ }
185
190
  // check if the union reader should still be read or not
186
191
  auto entry = file_set.find(data.union_readers[r]->GetFileName());
187
192
  if (entry == file_set.end()) {
@@ -632,6 +632,13 @@ struct CastTimestampMsToUs {
632
632
  }
633
633
  };
634
634
 
635
+ struct CastTimestampMsToNs {
636
+ template <class SRC, class DST>
637
+ static inline DST Operation(SRC input) {
638
+ throw duckdb::NotImplementedException("Cast to TIMESTAMP_NS could not be performed!");
639
+ }
640
+ };
641
+
635
642
  struct CastTimestampNsToUs {
636
643
  template <class SRC, class DST>
637
644
  static inline DST Operation(SRC input) {
@@ -639,6 +646,13 @@ struct CastTimestampNsToUs {
639
646
  }
640
647
  };
641
648
 
649
+ struct CastTimestampSecToMs {
650
+ template <class SRC, class DST>
651
+ static inline DST Operation(SRC input) {
652
+ throw duckdb::NotImplementedException("Cast to TIMESTAMP_MS could not be performed!");
653
+ }
654
+ };
655
+
642
656
  struct CastTimestampSecToUs {
643
657
  template <class SRC, class DST>
644
658
  static inline DST Operation(SRC input) {
@@ -646,6 +660,13 @@ struct CastTimestampSecToUs {
646
660
  }
647
661
  };
648
662
 
663
+ struct CastTimestampSecToNs {
664
+ template <class SRC, class DST>
665
+ static inline DST Operation(SRC input) {
666
+ throw duckdb::NotImplementedException("Cast to TIMESTAMP_NS could not be performed!");
667
+ }
668
+ };
669
+
649
670
  template <>
650
671
  duckdb::timestamp_t CastTimestampUsToMs::Operation(duckdb::timestamp_t input);
651
672
  template <>
@@ -655,9 +676,15 @@ duckdb::timestamp_t CastTimestampUsToSec::Operation(duckdb::timestamp_t input);
655
676
  template <>
656
677
  duckdb::timestamp_t CastTimestampMsToUs::Operation(duckdb::timestamp_t input);
657
678
  template <>
679
+ duckdb::timestamp_t CastTimestampMsToNs::Operation(duckdb::timestamp_t input);
680
+ template <>
658
681
  duckdb::timestamp_t CastTimestampNsToUs::Operation(duckdb::timestamp_t input);
659
682
  template <>
683
+ duckdb::timestamp_t CastTimestampSecToMs::Operation(duckdb::timestamp_t input);
684
+ template <>
660
685
  duckdb::timestamp_t CastTimestampSecToUs::Operation(duckdb::timestamp_t input);
686
+ template <>
687
+ duckdb::timestamp_t CastTimestampSecToNs::Operation(duckdb::timestamp_t input);
661
688
 
662
689
  template <>
663
690
  duckdb::string_t CastFromTimestampNS::Operation(duckdb::timestamp_t input, Vector &result);