duckdb 0.8.1-dev355.0 → 0.8.1-dev407.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 (56) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/extension/icu/icu-datepart.cpp +1 -1
  3. package/src/duckdb/extension/icu/icu-extension.cpp +1 -1
  4. package/src/duckdb/extension/icu/icu-strptime.cpp +1 -1
  5. package/src/duckdb/extension/icu/third_party/icu/i18n/nfsubs.cpp +0 -2
  6. package/src/duckdb/extension/json/include/json_scan.hpp +2 -1
  7. package/src/duckdb/extension/json/json_functions/json_contains.cpp +5 -0
  8. package/src/duckdb/extension/json/json_scan.cpp +3 -2
  9. package/src/duckdb/extension/parquet/parquet-extension.cpp +2 -1
  10. package/src/duckdb/src/common/exception_format_value.cpp +6 -2
  11. package/src/duckdb/src/common/random_engine.cpp +1 -1
  12. package/src/duckdb/src/common/types/time.cpp +2 -8
  13. package/src/duckdb/src/common/types.cpp +4 -0
  14. package/src/duckdb/src/core_functions/aggregate/distributive/string_agg.cpp +1 -1
  15. package/src/duckdb/src/core_functions/aggregate/holistic/approximate_quantile.cpp +1 -1
  16. package/src/duckdb/src/core_functions/aggregate/holistic/quantile.cpp +1 -1
  17. package/src/duckdb/src/core_functions/aggregate/holistic/reservoir_quantile.cpp +1 -1
  18. package/src/duckdb/src/core_functions/scalar/date/date_part.cpp +1 -1
  19. package/src/duckdb/src/core_functions/scalar/date/make_date.cpp +3 -0
  20. package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +1 -1
  21. package/src/duckdb/src/core_functions/scalar/list/list_aggregates.cpp +23 -6
  22. package/src/duckdb/src/core_functions/scalar/list/list_lambdas.cpp +1 -2
  23. package/src/duckdb/src/core_functions/scalar/math/numeric.cpp +3 -3
  24. package/src/duckdb/src/execution/index/art/leaf.cpp +1 -0
  25. package/src/duckdb/src/execution/index/art/node.cpp +1 -0
  26. package/src/duckdb/src/execution/join_hashtable.cpp +2 -0
  27. package/src/duckdb/src/execution/operator/projection/physical_tableinout_function.cpp +1 -0
  28. package/src/duckdb/src/execution/operator/projection/physical_unnest.cpp +8 -3
  29. package/src/duckdb/src/execution/reservoir_sample.cpp +18 -4
  30. package/src/duckdb/src/function/aggregate/distributive/count.cpp +1 -1
  31. package/src/duckdb/src/function/aggregate/distributive/first.cpp +2 -1
  32. package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +1 -1
  33. package/src/duckdb/src/function/scalar/list/list_extract.cpp +1 -1
  34. package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +1 -1
  35. package/src/duckdb/src/function/scalar/system/aggregate_export.cpp +2 -2
  36. package/src/duckdb/src/function/table/checkpoint.cpp +3 -0
  37. package/src/duckdb/src/function/table/read_csv.cpp +1 -1
  38. package/src/duckdb/src/function/table/table_scan.cpp +2 -2
  39. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  40. package/src/duckdb/src/include/duckdb/common/types/time.hpp +2 -0
  41. package/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +1 -1
  42. package/src/duckdb/src/include/duckdb/function/function_serialization.hpp +1 -1
  43. package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +1 -1
  44. package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +2 -1
  45. package/src/duckdb/src/include/duckdb/function/table_function.hpp +1 -1
  46. package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +142 -136
  47. package/src/duckdb/src/include/duckdb/planner/bound_result_modifier.hpp +3 -0
  48. package/src/duckdb/src/parser/transform/expression/transform_operator.cpp +3 -0
  49. package/src/duckdb/src/planner/binder/expression/bind_function_expression.cpp +0 -2
  50. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +31 -15
  51. package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +3 -0
  52. package/src/duckdb/src/planner/bound_result_modifier.cpp +14 -0
  53. package/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp +6 -5
  54. package/src/duckdb/src/planner/expression/bound_default_expression.cpp +7 -1
  55. package/src/duckdb/src/planner/expression.cpp +3 -0
  56. package/src/duckdb/src/planner/operator/logical_distinct.cpp +5 -4
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.1-dev355.0",
5
+ "version": "0.8.1-dev407.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -432,7 +432,7 @@ struct ICUDatePart : public ICUDateFunc {
432
432
  throw NotImplementedException("FIXME: serialize icu-datepart");
433
433
  }
434
434
 
435
- static duckdb::unique_ptr<FunctionData> DeserializeFunction(ClientContext &context, FieldReader &reader,
435
+ static duckdb::unique_ptr<FunctionData> DeserializeFunction(PlanDeserializationState &state, FieldReader &reader,
436
436
  ScalarFunction &bound_function) {
437
437
  throw NotImplementedException("FIXME: serialize icu-datepart");
438
438
  }
@@ -145,7 +145,7 @@ static void ICUCollateSerialize(FieldWriter &writer, const FunctionData *bind_da
145
145
  throw NotImplementedException("FIXME: serialize icu-collate");
146
146
  }
147
147
 
148
- static duckdb::unique_ptr<FunctionData> ICUCollateDeserialize(ClientContext &context, FieldReader &reader,
148
+ static duckdb::unique_ptr<FunctionData> ICUCollateDeserialize(PlanDeserializationState &state, FieldReader &reader,
149
149
  ScalarFunction &bound_function) {
150
150
  throw NotImplementedException("FIXME: serialize icu-collate");
151
151
  }
@@ -53,7 +53,7 @@ struct ICUStrptime : public ICUDateFunc {
53
53
  throw NotImplementedException("FIXME: serialize icu-strptime");
54
54
  }
55
55
 
56
- static duckdb::unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader,
56
+ static duckdb::unique_ptr<FunctionData> Deserialize(PlanDeserializationState &state, FieldReader &reader,
57
57
  ScalarFunction &bound_function) {
58
58
  throw NotImplementedException("FIXME: serialize icu-strptime");
59
59
  }
@@ -1310,10 +1310,8 @@ NumeratorSubstitution::doParse(const UnicodeString& text,
1310
1310
  // compute the 'effective' base and prescale the value down
1311
1311
  int64_t n = result.getLong(status); // force conversion!
1312
1312
  int64_t d = 1;
1313
- int32_t pow = 0;
1314
1313
  while (d <= n) {
1315
1314
  d *= 10;
1316
- ++pow;
1317
1315
  }
1318
1316
  // now add the zeros
1319
1317
  while (zeroCount > 0) {
@@ -292,7 +292,8 @@ public:
292
292
  vector<unique_ptr<Expression>> &filters);
293
293
 
294
294
  static void Serialize(FieldWriter &writer, const FunctionData *bind_data_p, const TableFunction &function);
295
- static unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader, TableFunction &function);
295
+ static unique_ptr<FunctionData> Deserialize(PlanDeserializationState &state, FieldReader &reader,
296
+ TableFunction &function);
296
297
 
297
298
  static void TableFunctionDefaults(TableFunction &table_function);
298
299
  };
@@ -114,6 +114,11 @@ static void JSONContainsFunction(DataChunk &args, ExpressionState &state, Vector
114
114
  auto &needles = args.data[1];
115
115
 
116
116
  if (needles.GetVectorType() == VectorType::CONSTANT_VECTOR) {
117
+ if (ConstantVector::IsNull(needles)) {
118
+ result.SetVectorType(VectorType::CONSTANT_VECTOR);
119
+ ConstantVector::SetNull(result, true);
120
+ return;
121
+ }
117
122
  auto &needle_str = *ConstantVector::GetData<string_t>(needles);
118
123
  auto needle_doc = JSONCommon::ReadDocument(needle_str, JSONCommon::READ_FLAG, lstate.json_allocator.GetYYAlc());
119
124
  UnaryExecutor::Execute<string_t, bool>(haystacks, result, args.size(), [&](string_t haystack_str) {
@@ -962,9 +962,10 @@ void JSONScan::Serialize(FieldWriter &writer, const FunctionData *bind_data_p, c
962
962
  bind_data.Serialize(writer);
963
963
  }
964
964
 
965
- unique_ptr<FunctionData> JSONScan::Deserialize(ClientContext &context, FieldReader &reader, TableFunction &function) {
965
+ unique_ptr<FunctionData> JSONScan::Deserialize(PlanDeserializationState &state, FieldReader &reader,
966
+ TableFunction &function) {
966
967
  auto result = make_uniq<JSONScanData>();
967
- result->Deserialize(context, reader);
968
+ result->Deserialize(state.context, reader);
968
969
  return std::move(result);
969
970
  }
970
971
 
@@ -411,8 +411,9 @@ public:
411
411
  bind_data.parquet_options.Serialize(writer);
412
412
  }
413
413
 
414
- static unique_ptr<FunctionData> ParquetScanDeserialize(ClientContext &context, FieldReader &reader,
414
+ static unique_ptr<FunctionData> ParquetScanDeserialize(PlanDeserializationState &state, FieldReader &reader,
415
415
  TableFunction &function) {
416
+ auto &context = state.context;
416
417
  auto files = reader.ReadRequiredList<string>();
417
418
  auto types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
418
419
  auto names = reader.ReadRequiredList<string>();
@@ -85,10 +85,14 @@ string ExceptionFormatValue::Format(const string &msg, std::vector<ExceptionForm
85
85
  }
86
86
  return duckdb_fmt::vsprintf(msg, duckdb_fmt::basic_format_args<duckdb_fmt::printf_context>(
87
87
  format_args.data(), static_cast<int>(format_args.size())));
88
- } catch (std::exception &ex) {
88
+ } catch (std::exception &ex) { // LCOV_EXCL_START
89
+ // work-around for oss-fuzz limiting memory which causes issues here
90
+ if (StringUtil::Contains(ex.what(), "fuzz mode")) {
91
+ throw Exception(msg);
92
+ }
89
93
  throw InternalException(std::string("Primary exception: ") + msg +
90
94
  "\nSecondary exception in ExceptionFormatValue: " + ex.what());
91
- }
95
+ } // LCOV_EXCL_STOP
92
96
  }
93
97
 
94
98
  } // namespace duckdb
@@ -28,7 +28,7 @@ double RandomEngine::NextRandom(double min, double max) {
28
28
  }
29
29
 
30
30
  double RandomEngine::NextRandom() {
31
- return random_state->pcg() / double(std::numeric_limits<uint32_t>::max());
31
+ return std::ldexp(random_state->pcg(), -32);
32
32
  }
33
33
  uint32_t RandomEngine::NextRandomInteger() {
34
34
  return random_state->pcg();
@@ -194,9 +194,7 @@ dtime_t Time::FromTime(int32_t hour, int32_t minute, int32_t second, int32_t mic
194
194
  return dtime_t(result);
195
195
  }
196
196
 
197
- // LCOV_EXCL_START
198
- #ifdef DEBUG
199
- static bool AssertValidTime(int32_t hour, int32_t minute, int32_t second, int32_t microseconds) {
197
+ bool Time::IsValidTime(int32_t hour, int32_t minute, int32_t second, int32_t microseconds) {
200
198
  if (hour < 0 || hour >= 24) {
201
199
  return false;
202
200
  }
@@ -211,8 +209,6 @@ static bool AssertValidTime(int32_t hour, int32_t minute, int32_t second, int32_
211
209
  }
212
210
  return true;
213
211
  }
214
- #endif
215
- // LCOV_EXCL_STOP
216
212
 
217
213
  void Time::Convert(dtime_t dtime, int32_t &hour, int32_t &min, int32_t &sec, int32_t &micros) {
218
214
  int64_t time = dtime.micros;
@@ -223,9 +219,7 @@ void Time::Convert(dtime_t dtime, int32_t &hour, int32_t &min, int32_t &sec, int
223
219
  sec = int32_t(time / Interval::MICROS_PER_SEC);
224
220
  time -= int64_t(sec) * Interval::MICROS_PER_SEC;
225
221
  micros = int32_t(time);
226
- #ifdef DEBUG
227
- D_ASSERT(AssertValidTime(hour, min, sec, micros));
228
- #endif
222
+ D_ASSERT(Time::IsValidTime(hour, min, sec, micros));
229
223
  }
230
224
 
231
225
  dtime_t Time::FromTimeMs(int64_t time_ms) {
@@ -559,6 +559,10 @@ bool LogicalType::GetDecimalProperties(uint8_t &width, uint8_t &scale) const {
559
559
  scale = DecimalType::GetScale(*this);
560
560
  break;
561
561
  default:
562
+ // Nonsense values to ensure initialization
563
+ width = 255u;
564
+ scale = 255u;
565
+ // FIXME(carlo): This should be probably a throw, requires checkign the various call-sites
562
566
  return false;
563
567
  }
564
568
  return true;
@@ -147,7 +147,7 @@ static void StringAggSerialize(FieldWriter &writer, const FunctionData *bind_dat
147
147
  writer.WriteString(bind_data.sep);
148
148
  }
149
149
 
150
- unique_ptr<FunctionData> StringAggDeserialize(ClientContext &context, FieldReader &reader,
150
+ unique_ptr<FunctionData> StringAggDeserialize(PlanDeserializationState &state, FieldReader &reader,
151
151
  AggregateFunction &bound_function) {
152
152
  auto sep = reader.ReadRequired<string>();
153
153
  return make_uniq<StringAggBindData>(std::move(sep));
@@ -42,7 +42,7 @@ struct ApproximateQuantileBindData : public FunctionData {
42
42
  writer.WriteList<float>(bind_data.quantiles);
43
43
  }
44
44
 
45
- static unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader,
45
+ static unique_ptr<FunctionData> Deserialize(PlanDeserializationState &state, FieldReader &reader,
46
46
  AggregateFunction &bound_function) {
47
47
  auto quantiles = reader.ReadRequiredList<float>();
48
48
  return make_uniq<ApproximateQuantileBindData>(std::move(quantiles));
@@ -1160,7 +1160,7 @@ static void QuantileSerialize(FieldWriter &writer, const FunctionData *bind_data
1160
1160
  writer.WriteField<bool>(bind_data->desc);
1161
1161
  }
1162
1162
 
1163
- unique_ptr<FunctionData> QuantileDeserialize(ClientContext &context, FieldReader &reader,
1163
+ unique_ptr<FunctionData> QuantileDeserialize(PlanDeserializationState &state, FieldReader &reader,
1164
1164
  AggregateFunction &bound_function) {
1165
1165
  auto quantiles = reader.ReadRequiredSerializableList<Value, Value>();
1166
1166
  auto bind_data = make_uniq<QuantileBindData>(quantiles);
@@ -71,7 +71,7 @@ struct ReservoirQuantileBindData : public FunctionData {
71
71
  writer.WriteField<int32_t>(bind_data.sample_size);
72
72
  }
73
73
 
74
- static unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader,
74
+ static unique_ptr<FunctionData> Deserialize(PlanDeserializationState &state, FieldReader &reader,
75
75
  AggregateFunction &bound_function) {
76
76
  auto quantiles = reader.ReadRequiredList<double>();
77
77
  auto sample_size = reader.ReadRequired<int32_t>();
@@ -1377,7 +1377,7 @@ struct StructDatePart {
1377
1377
  writer.WriteList<DatePartSpecifier>(info.part_codes);
1378
1378
  }
1379
1379
 
1380
- static unique_ptr<FunctionData> DeserializeFunction(ClientContext &context, FieldReader &reader,
1380
+ static unique_ptr<FunctionData> DeserializeFunction(PlanDeserializationState &state, FieldReader &reader,
1381
1381
  ScalarFunction &bound_function) {
1382
1382
  auto stype = reader.ReadRequiredSerializable<LogicalType, LogicalType>();
1383
1383
  auto part_codes = reader.ReadRequiredList<DatePartSpecifier>();
@@ -47,6 +47,9 @@ struct MakeTimeOperator {
47
47
  static RESULT_TYPE Operation(HH hh, MM mm, SS ss) {
48
48
  int64_t secs = ss;
49
49
  int64_t micros = std::round((ss - secs) * Interval::MICROS_PER_SEC);
50
+ if (!Time::IsValidTime(hh, mm, secs, micros)) {
51
+ throw ConversionException("Time out of range: %d:%d:%d.%d", hh, mm, secs, micros);
52
+ }
50
53
  return Time::FromTime(hh, mm, secs, micros);
51
54
  }
52
55
  };
@@ -28,7 +28,7 @@ template <typename INPUT_TYPE, typename INDEX_TYPE>
28
28
  bool ClampIndex(INDEX_TYPE &index, const INPUT_TYPE &value) {
29
29
  const auto length = ValueLength<INPUT_TYPE, INDEX_TYPE>(value);
30
30
  if (index < 0) {
31
- if (-index > length) {
31
+ if (index < -length) {
32
32
  return false;
33
33
  }
34
34
  index = length + index;
@@ -15,6 +15,12 @@ namespace duckdb {
15
15
  // FIXME: use a local state for each thread to increase performance?
16
16
  // FIXME: benchmark the use of simple_update against using update (if applicable)
17
17
 
18
+ static unique_ptr<FunctionData> ListAggregatesBindFailure(ScalarFunction &bound_function) {
19
+ bound_function.arguments[0] = LogicalType::SQLNULL;
20
+ bound_function.return_type = LogicalType::SQLNULL;
21
+ return make_uniq<VariableReturnBindData>(LogicalType::SQLNULL);
22
+ }
23
+
18
24
  struct ListAggregatesBindData : public FunctionData {
19
25
  ListAggregatesBindData(const LogicalType &stype_p, unique_ptr<Expression> aggr_expr_p);
20
26
  ~ListAggregatesBindData() override;
@@ -31,11 +37,24 @@ struct ListAggregatesBindData : public FunctionData {
31
37
  return stype == other.stype && aggr_expr->Equals(*other.aggr_expr);
32
38
  }
33
39
  static void Serialize(FieldWriter &writer, const FunctionData *bind_data_p, const ScalarFunction &function) {
34
- throw NotImplementedException("FIXME: list aggr serialize");
40
+ auto bind_data = dynamic_cast<const ListAggregatesBindData *>(bind_data_p);
41
+ if (!bind_data) {
42
+ writer.WriteField<bool>(false);
43
+ } else {
44
+ writer.WriteField<bool>(true);
45
+ writer.WriteSerializable(bind_data->stype);
46
+ writer.WriteSerializable(*bind_data->aggr_expr);
47
+ }
35
48
  }
36
- static unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader,
49
+ static unique_ptr<FunctionData> Deserialize(PlanDeserializationState &state, FieldReader &reader,
37
50
  ScalarFunction &bound_function) {
38
- throw NotImplementedException("FIXME: list aggr deserialize");
51
+ if (reader.ReadRequired<bool>()) {
52
+ auto s_type = reader.ReadRequiredSerializable<LogicalType, LogicalType>();
53
+ auto expr = reader.ReadRequiredSerializable<Expression>(state);
54
+ return make_uniq<ListAggregatesBindData>(s_type, std::move(expr));
55
+ } else {
56
+ return ListAggregatesBindFailure(bound_function);
57
+ }
39
58
  }
40
59
  };
41
60
 
@@ -396,9 +415,7 @@ template <bool IS_AGGR = false>
396
415
  static unique_ptr<FunctionData> ListAggregatesBind(ClientContext &context, ScalarFunction &bound_function,
397
416
  vector<unique_ptr<Expression>> &arguments) {
398
417
  if (arguments[0]->return_type.id() == LogicalTypeId::SQLNULL) {
399
- bound_function.arguments[0] = LogicalType::SQLNULL;
400
- bound_function.return_type = LogicalType::SQLNULL;
401
- return make_uniq<VariableReturnBindData>(bound_function.return_type);
418
+ return ListAggregatesBindFailure(bound_function);
402
419
  }
403
420
 
404
421
  bool is_parameter = arguments[0]->return_type.id() == LogicalTypeId::UNKNOWN;
@@ -24,7 +24,7 @@ public:
24
24
  static void Serialize(FieldWriter &writer, const FunctionData *bind_data_p, const ScalarFunction &function) {
25
25
  throw NotImplementedException("FIXME: list lambda serialize");
26
26
  }
27
- static unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader,
27
+ static unique_ptr<FunctionData> Deserialize(PlanDeserializationState &state, FieldReader &reader,
28
28
  ScalarFunction &bound_function) {
29
29
  throw NotImplementedException("FIXME: list lambda deserialize");
30
30
  }
@@ -328,7 +328,6 @@ static unique_ptr<FunctionData> ListLambdaBind(ClientContext &context, ScalarFun
328
328
  }
329
329
 
330
330
  if (arguments[0]->return_type.id() == LogicalTypeId::SQLNULL) {
331
- bound_function.arguments.pop_back();
332
331
  bound_function.arguments[0] = LogicalType::SQLNULL;
333
332
  bound_function.return_type = LogicalType::SQLNULL;
334
333
  return make_uniq<VariableReturnBindData>(bound_function.return_type);
@@ -502,13 +502,13 @@ struct RoundOperatorPrecision {
502
502
  static inline TR Operation(TA input, TB precision) {
503
503
  double rounded_value;
504
504
  if (precision < 0) {
505
- double modifier = std::pow(10, -precision);
505
+ double modifier = std::pow(10, -TA(precision));
506
506
  rounded_value = (std::round(input / modifier)) * modifier;
507
507
  if (std::isinf(rounded_value) || std::isnan(rounded_value)) {
508
508
  return 0;
509
509
  }
510
510
  } else {
511
- double modifier = std::pow(10, precision);
511
+ double modifier = std::pow(10, TA(precision));
512
512
  rounded_value = (std::round(input * modifier)) / modifier;
513
513
  if (std::isinf(rounded_value) || std::isnan(rounded_value)) {
514
514
  return input;
@@ -574,7 +574,7 @@ static void DecimalRoundNegativePrecisionFunction(DataChunk &input, ExpressionSt
574
574
  auto &info = func_expr.bind_info->Cast<RoundPrecisionFunctionData>();
575
575
  auto source_scale = DecimalType::GetScale(func_expr.children[0]->return_type);
576
576
  auto width = DecimalType::GetWidth(func_expr.children[0]->return_type);
577
- if (-info.target_scale >= width) {
577
+ if (info.target_scale <= -int32_t(width)) {
578
578
  // scale too big for width
579
579
  result.SetVectorType(VectorType::CONSTANT_VECTOR);
580
580
  result.SetValue(0, Value::INTEGER(0));
@@ -292,6 +292,7 @@ string Leaf::VerifyAndToString(const ART &art, const bool only_verify) const {
292
292
  }
293
293
 
294
294
  D_ASSERT(remaining == 0);
295
+ (void)this_count;
295
296
  D_ASSERT(this_count == count);
296
297
  return only_verify ? "" : "Leaf [count: " + to_string(count) + ", row IDs: " + str + "] \n";
297
298
  }
@@ -313,6 +313,7 @@ string Node::VerifyAndToString(ART &art, const bool only_verify) {
313
313
  child = GetNextChild(art, byte, false);
314
314
  }
315
315
 
316
+ (void)child_count;
316
317
  // ensure that the child count is at least two
317
318
  D_ASSERT(child_count > 1);
318
319
  return only_verify ? "" : "\n" + str + "]";
@@ -627,6 +627,8 @@ void ScanStructure::NextMarkJoin(DataChunk &keys, DataChunk &input, DataChunk &r
627
627
  ConstructMarkJoinResult(keys, input, result);
628
628
  } else {
629
629
  auto &info = ht.correlated_mark_join_info;
630
+ lock_guard<mutex> mj_lock(info.mj_lock);
631
+
630
632
  // there are correlated columns
631
633
  // first we fetch the counts from the aggregate hashtable corresponding to these entries
632
634
  D_ASSERT(keys.ColumnCount() == info.group_chunk.ColumnCount() + 1);
@@ -70,6 +70,7 @@ OperatorResultType PhysicalTableInOutFunction::Execute(ExecutionContext &context
70
70
  return OperatorResultType::NEED_MORE_INPUT;
71
71
  }
72
72
  // we are processing a new row: fetch the data for the current row
73
+ state.input_chunk.Reset();
73
74
  D_ASSERT(input.ColumnCount() == state.input_chunk.ColumnCount());
74
75
  // set up the input data to the table in-out function
75
76
  for (idx_t col_idx = 0; col_idx < input.ColumnCount(); col_idx++) {
@@ -65,8 +65,8 @@ void UnnestOperatorState::SetLongestListLength() {
65
65
  if (vector_data.validity.RowIsValid(current_idx)) {
66
66
 
67
67
  // check if this list is longer
68
- auto list_data = UnifiedVectorFormat::GetData<list_entry_t>(vector_data);
69
- auto list_entry = list_data[current_idx];
68
+ auto list_data_entries = UnifiedVectorFormat::GetData<list_entry_t>(vector_data);
69
+ auto list_entry = list_data_entries[current_idx];
70
70
  if (list_entry.length > longest_list_length) {
71
71
  longest_list_length = list_entry.length;
72
72
  }
@@ -259,6 +259,11 @@ OperatorResultType PhysicalUnnest::ExecuteInternal(ExecutionContext &context, Da
259
259
  auto &state = state_p.Cast<UnnestOperatorState>();
260
260
 
261
261
  do {
262
+ // reset validities, if previous loop iteration contained UNNEST(NULL)
263
+ if (include_input) {
264
+ chunk.Reset();
265
+ }
266
+
262
267
  // prepare the input data by executing any expressions and getting the
263
268
  // UnifiedVectorFormat of each LIST vector (list_vector_data) and its child vector (list_child_data)
264
269
  if (state.first_fetch) {
@@ -271,7 +276,7 @@ OperatorResultType PhysicalUnnest::ExecuteInternal(ExecutionContext &context, Da
271
276
  return OperatorResultType::NEED_MORE_INPUT;
272
277
  }
273
278
 
274
- // each UNNEST in the select_list contains a list (or NULL) for this row, find longest list
279
+ // each UNNEST in the select_list contains a list (or NULL) for this row, find the longest list
275
280
  // because this length determines how many times we need to repeat for the current row
276
281
  if (state.longest_list_length == DConstants::INVALID_INDEX) {
277
282
  state.SetLongestListLength();
@@ -104,10 +104,24 @@ void ReservoirSamplePercentage::AddToReservoir(DataChunk &input) {
104
104
  idx_t append_to_next_sample = input.size() - append_to_current_sample_count;
105
105
  if (append_to_current_sample_count > 0) {
106
106
  // we have elements remaining, first add them to the current sample
107
- input.Flatten();
108
-
109
- input.SetCardinality(append_to_current_sample_count);
110
- current_sample->AddToReservoir(input);
107
+ if (append_to_next_sample > 0) {
108
+ // we need to also add to the next sample
109
+ DataChunk new_chunk;
110
+ new_chunk.Initialize(allocator, input.GetTypes());
111
+ SelectionVector sel(append_to_current_sample_count);
112
+ for (idx_t r = 0; r < append_to_current_sample_count; r++) {
113
+ sel.set_index(r, r);
114
+ }
115
+ new_chunk.Slice(sel, append_to_current_sample_count);
116
+ new_chunk.Flatten();
117
+
118
+ current_sample->AddToReservoir(new_chunk);
119
+ } else {
120
+ input.Flatten();
121
+
122
+ input.SetCardinality(append_to_current_sample_count);
123
+ current_sample->AddToReservoir(input);
124
+ }
111
125
  }
112
126
  if (append_to_next_sample > 0) {
113
127
  // slice the input for the remainder
@@ -221,7 +221,7 @@ AggregateFunction CountFun::GetFunction() {
221
221
  static void CountStarSerialize(FieldWriter &writer, const FunctionData *bind_data, const AggregateFunction &function) {
222
222
  }
223
223
 
224
- static unique_ptr<FunctionData> CountStarDeserialize(ClientContext &context, FieldReader &reader,
224
+ static unique_ptr<FunctionData> CountStarDeserialize(PlanDeserializationState &state, FieldReader &reader,
225
225
  AggregateFunction &function) {
226
226
  return nullptr;
227
227
  }
@@ -297,8 +297,9 @@ template <bool LAST, bool SKIP_NULLS>
297
297
  unique_ptr<FunctionData> BindDecimalFirst(ClientContext &context, AggregateFunction &function,
298
298
  vector<unique_ptr<Expression>> &arguments) {
299
299
  auto decimal_type = arguments[0]->return_type;
300
+ auto name = std::move(function.name);
300
301
  function = GetFirstFunction<LAST, SKIP_NULLS>(decimal_type);
301
- function.name = "first";
302
+ function.name = std::move(name);
302
303
  function.return_type = decimal_type;
303
304
  return nullptr;
304
305
  }
@@ -519,7 +519,7 @@ struct SortedAggregateFunction {
519
519
  static void Serialize(FieldWriter &writer, const FunctionData *bind_data, const AggregateFunction &function) {
520
520
  throw NotImplementedException("FIXME: serialize sorted aggregate not supported");
521
521
  }
522
- static unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader,
522
+ static unique_ptr<FunctionData> Deserialize(PlanDeserializationState &state, FieldReader &reader,
523
523
  AggregateFunction &function) {
524
524
  throw NotImplementedException("FIXME: deserialize sorted aggregate not supported");
525
525
  }
@@ -56,7 +56,7 @@ void ListExtractTemplate(idx_t count, UnifiedVectorFormat &list_data, UnifiedVec
56
56
 
57
57
  idx_t child_offset;
58
58
  if (offsets_entry < 0) {
59
- if ((idx_t)-offsets_entry > list_entry.length) {
59
+ if (offsets_entry < -int64_t(list_entry.length)) {
60
60
  result_mask.SetInvalid(i);
61
61
  continue;
62
62
  }
@@ -257,7 +257,7 @@ static void SerializeDecimalArithmetic(FieldWriter &writer, const FunctionData *
257
257
 
258
258
  // TODO this is partially duplicated from the bind
259
259
  template <class OP, class OPOVERFLOWCHECK, bool IS_SUBTRACT = false>
260
- unique_ptr<FunctionData> DeserializeDecimalArithmetic(ClientContext &context, FieldReader &reader,
260
+ unique_ptr<FunctionData> DeserializeDecimalArithmetic(PlanDeserializationState &state, FieldReader &reader,
261
261
  ScalarFunction &bound_function) {
262
262
  // re-change the function pointers
263
263
  auto check_overflow = reader.ReadRequired<bool>();
@@ -274,7 +274,7 @@ static void ExportStateAggregateSerialize(FieldWriter &writer, const FunctionDat
274
274
  const AggregateFunction &function) {
275
275
  throw NotImplementedException("FIXME: export state serialize");
276
276
  }
277
- static unique_ptr<FunctionData> ExportStateAggregateDeserialize(ClientContext &context, FieldReader &reader,
277
+ static unique_ptr<FunctionData> ExportStateAggregateDeserialize(PlanDeserializationState &state, FieldReader &reader,
278
278
  AggregateFunction &bound_function) {
279
279
  throw NotImplementedException("FIXME: export state deserialize");
280
280
  }
@@ -283,7 +283,7 @@ static void ExportStateScalarSerialize(FieldWriter &writer, const FunctionData *
283
283
  const ScalarFunction &function) {
284
284
  throw NotImplementedException("FIXME: export state serialize");
285
285
  }
286
- static unique_ptr<FunctionData> ExportStateScalarDeserialize(ClientContext &context, FieldReader &reader,
286
+ static unique_ptr<FunctionData> ExportStateScalarDeserialize(PlanDeserializationState &state, FieldReader &reader,
287
287
  ScalarFunction &bound_function) {
288
288
  throw NotImplementedException("FIXME: export state deserialize");
289
289
  }
@@ -32,6 +32,9 @@ static unique_ptr<FunctionData> CheckpointBind(ClientContext &context, TableFunc
32
32
  optional_ptr<AttachedDatabase> db;
33
33
  auto &db_manager = DatabaseManager::Get(context);
34
34
  if (!input.inputs.empty()) {
35
+ if (input.inputs[0].IsNull()) {
36
+ throw BinderException("Database cannot be NULL");
37
+ }
35
38
  auto &db_name = StringValue::Get(input.inputs[0]);
36
39
  db = db_manager.GetDatabase(context, db_name);
37
40
  if (!db) {
@@ -1129,7 +1129,7 @@ static void CSVReaderSerialize(FieldWriter &writer, const FunctionData *bind_dat
1129
1129
  }
1130
1130
  }
1131
1131
 
1132
- static unique_ptr<FunctionData> CSVReaderDeserialize(ClientContext &context, FieldReader &reader,
1132
+ static unique_ptr<FunctionData> CSVReaderDeserialize(PlanDeserializationState &state, FieldReader &reader,
1133
1133
  TableFunction &function) {
1134
1134
  function.extra_info = reader.ReadRequired<string>();
1135
1135
  auto result_data = make_uniq<ReadCSVData>();
@@ -417,7 +417,7 @@ static void TableScanSerialize(FieldWriter &writer, const FunctionData *bind_dat
417
417
  writer.WriteString(bind_data.table.schema.catalog.GetName());
418
418
  }
419
419
 
420
- static unique_ptr<FunctionData> TableScanDeserialize(ClientContext &context, FieldReader &reader,
420
+ static unique_ptr<FunctionData> TableScanDeserialize(PlanDeserializationState &state, FieldReader &reader,
421
421
  TableFunction &function) {
422
422
  auto schema_name = reader.ReadRequired<string>();
423
423
  auto table_name = reader.ReadRequired<string>();
@@ -426,7 +426,7 @@ static unique_ptr<FunctionData> TableScanDeserialize(ClientContext &context, Fie
426
426
  auto result_ids = reader.ReadRequiredList<row_t>();
427
427
  auto catalog_name = reader.ReadField<string>(INVALID_CATALOG);
428
428
 
429
- auto &catalog_entry = Catalog::GetEntry<TableCatalogEntry>(context, catalog_name, schema_name, table_name);
429
+ auto &catalog_entry = Catalog::GetEntry<TableCatalogEntry>(state.context, catalog_name, schema_name, table_name);
430
430
  if (catalog_entry.type != CatalogType::TABLE_ENTRY) {
431
431
  throw SerializationException("Cant find table for %s.%s", schema_name, table_name);
432
432
  }
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.8.1-dev355"
2
+ #define DUCKDB_VERSION "0.8.1-dev407"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "e9b683ce15"
5
+ #define DUCKDB_SOURCE_ID "01e2ae9e8b"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -42,6 +42,8 @@ public:
42
42
  DUCKDB_API static dtime_t FromTimeMs(int64_t time_ms);
43
43
  DUCKDB_API static dtime_t FromTimeNs(int64_t time_ns);
44
44
 
45
+ DUCKDB_API static bool IsValidTime(int32_t hour, int32_t minute, int32_t second, int32_t microseconds);
46
+
45
47
  private:
46
48
  static bool TryConvertInternal(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict);
47
49
  };
@@ -49,7 +49,7 @@ typedef void (*aggregate_window_t)(Vector inputs[], const ValidityMask &filter_m
49
49
 
50
50
  typedef void (*aggregate_serialize_t)(FieldWriter &writer, const FunctionData *bind_data,
51
51
  const AggregateFunction &function);
52
- typedef unique_ptr<FunctionData> (*aggregate_deserialize_t)(ClientContext &context, FieldReader &reader,
52
+ typedef unique_ptr<FunctionData> (*aggregate_deserialize_t)(PlanDeserializationState &context, FieldReader &reader,
53
53
  AggregateFunction &function);
54
54
 
55
55
  class AggregateFunction : public BaseScalarFunction {
@@ -66,7 +66,7 @@ public:
66
66
  throw SerializationException("Function requires deserialization but no deserialization function for %s",
67
67
  function.name);
68
68
  }
69
- bind_info = function.deserialize(context, reader, function);
69
+ bind_info = function.deserialize(state, reader, function);
70
70
  } else {
71
71
  D_ASSERT(!function.serialize);
72
72
  D_ASSERT(!function.deserialize);
@@ -68,7 +68,7 @@ struct VariableReturnBindData : public FunctionData {
68
68
  writer.WriteSerializable(info.stype);
69
69
  }
70
70
 
71
- static unique_ptr<FunctionData> Deserialize(ClientContext &context, FieldReader &reader,
71
+ static unique_ptr<FunctionData> Deserialize(PlanDeserializationState &context, FieldReader &reader,
72
72
  ScalarFunction &bound_function) {
73
73
  auto stype = reader.ReadRequiredSerializable<LogicalType, LogicalType>();
74
74
  return make_uniq<VariableReturnBindData>(std::move(stype));