duckdb 0.8.2-dev2673.0 → 0.8.2-dev2809.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 (117) hide show
  1. package/binding.gyp +1 -0
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/icu/icu-makedate.cpp +12 -6
  4. package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +6 -6
  5. package/src/duckdb/src/common/adbc/adbc.cpp +52 -21
  6. package/src/duckdb/src/common/adbc/driver_manager.cpp +12 -2
  7. package/src/duckdb/src/common/enum_util.cpp +5 -0
  8. package/src/duckdb/src/common/field_writer.cpp +1 -0
  9. package/src/duckdb/src/common/local_file_system.cpp +5 -0
  10. package/src/duckdb/src/common/types/interval.cpp +3 -0
  11. package/src/duckdb/src/common/types/row/row_data_collection_scanner.cpp +35 -5
  12. package/src/duckdb/src/execution/index/art/art.cpp +6 -9
  13. package/src/duckdb/src/execution/index/art/leaf.cpp +4 -4
  14. package/src/duckdb/src/execution/index/art/node.cpp +9 -12
  15. package/src/duckdb/src/execution/index/art/node16.cpp +4 -4
  16. package/src/duckdb/src/execution/index/art/node256.cpp +4 -4
  17. package/src/duckdb/src/execution/index/art/node4.cpp +4 -5
  18. package/src/duckdb/src/execution/index/art/node48.cpp +4 -4
  19. package/src/duckdb/src/execution/index/art/prefix.cpp +4 -6
  20. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +283 -91
  21. package/src/duckdb/src/execution/operator/filter/physical_filter.cpp +1 -1
  22. package/src/duckdb/src/execution/operator/join/physical_comparison_join.cpp +1 -2
  23. package/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp +1 -1
  24. package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -6
  25. package/src/duckdb/src/execution/window_executor.cpp +10 -1
  26. package/src/duckdb/src/function/table/version/pragma_version.cpp +5 -2
  27. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
  28. package/src/duckdb/src/include/duckdb/common/adbc/adbc.hpp +2 -0
  29. package/src/duckdb/src/include/duckdb/common/enums/pending_execution_result.hpp +1 -1
  30. package/src/duckdb/src/include/duckdb/common/types/row/row_data_collection_scanner.hpp +5 -1
  31. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +2 -2
  32. package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +4 -4
  33. package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +6 -4
  34. package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +2 -2
  35. package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +2 -2
  36. package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +2 -2
  37. package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +2 -2
  38. package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +2 -2
  39. package/src/duckdb/src/include/duckdb/execution/physical_operator.hpp +0 -2
  40. package/src/duckdb/src/include/duckdb/main/pending_query_result.hpp +5 -0
  41. package/src/duckdb/src/include/duckdb/optimizer/join_order/cardinality_estimator.hpp +37 -63
  42. package/src/duckdb/src/include/duckdb/optimizer/join_order/cost_model.hpp +37 -0
  43. package/src/duckdb/src/include/duckdb/optimizer/join_order/join_node.hpp +14 -29
  44. package/src/duckdb/src/include/duckdb/optimizer/join_order/join_order_optimizer.hpp +7 -21
  45. package/src/duckdb/src/include/duckdb/optimizer/join_order/join_relation.hpp +0 -11
  46. package/src/duckdb/src/include/duckdb/optimizer/join_order/plan_enumerator.hpp +89 -0
  47. package/src/duckdb/src/include/duckdb/optimizer/join_order/query_graph.hpp +17 -31
  48. package/src/duckdb/src/include/duckdb/optimizer/join_order/query_graph_manager.hpp +113 -0
  49. package/src/duckdb/src/include/duckdb/optimizer/join_order/relation_manager.hpp +73 -0
  50. package/src/duckdb/src/include/duckdb/optimizer/join_order/relation_statistics_helper.hpp +73 -0
  51. package/src/duckdb/src/include/duckdb/parallel/task_scheduler.hpp +4 -1
  52. package/src/duckdb/src/include/duckdb/planner/logical_operator.hpp +0 -2
  53. package/src/duckdb/src/include/duckdb/storage/block.hpp +27 -4
  54. package/src/duckdb/src/include/duckdb/storage/block_manager.hpp +9 -9
  55. package/src/duckdb/src/include/duckdb/storage/checkpoint/row_group_writer.hpp +5 -5
  56. package/src/duckdb/src/include/duckdb/storage/checkpoint/table_data_reader.hpp +2 -2
  57. package/src/duckdb/src/include/duckdb/storage/checkpoint/table_data_writer.hpp +3 -3
  58. package/src/duckdb/src/include/duckdb/storage/checkpoint_manager.hpp +19 -16
  59. package/src/duckdb/src/include/duckdb/storage/data_pointer.hpp +1 -1
  60. package/src/duckdb/src/include/duckdb/storage/in_memory_block_manager.hpp +2 -2
  61. package/src/duckdb/src/include/duckdb/storage/index.hpp +2 -2
  62. package/src/duckdb/src/include/duckdb/storage/metadata/metadata_manager.hpp +88 -0
  63. package/src/duckdb/src/include/duckdb/storage/metadata/metadata_reader.hpp +54 -0
  64. package/src/duckdb/src/include/duckdb/storage/metadata/metadata_writer.hpp +45 -0
  65. package/src/duckdb/src/include/duckdb/storage/partial_block_manager.hpp +2 -2
  66. package/src/duckdb/src/include/duckdb/storage/single_file_block_manager.hpp +6 -5
  67. package/src/duckdb/src/include/duckdb/storage/storage_info.hpp +2 -2
  68. package/src/duckdb/src/include/duckdb/storage/storage_manager.hpp +2 -2
  69. package/src/duckdb/src/include/duckdb/storage/table/persistent_table_data.hpp +2 -2
  70. package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +1 -1
  71. package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +2 -0
  72. package/src/duckdb/src/include/duckdb/storage/table/row_group_segment_tree.hpp +2 -2
  73. package/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp +1 -1
  74. package/src/duckdb/src/include/duckdb/storage/table_io_manager.hpp +3 -0
  75. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +3 -4
  76. package/src/duckdb/src/include/duckdb.h +11 -1
  77. package/src/duckdb/src/main/capi/pending-c.cpp +17 -0
  78. package/src/duckdb/src/main/pending_query_result.cpp +9 -1
  79. package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +79 -325
  80. package/src/duckdb/src/optimizer/join_order/cost_model.cpp +19 -0
  81. package/src/duckdb/src/optimizer/join_order/join_node.cpp +5 -37
  82. package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +48 -1078
  83. package/src/duckdb/src/optimizer/join_order/plan_enumerator.cpp +552 -0
  84. package/src/duckdb/src/optimizer/join_order/query_graph.cpp +32 -29
  85. package/src/duckdb/src/optimizer/join_order/query_graph_manager.cpp +409 -0
  86. package/src/duckdb/src/optimizer/join_order/relation_manager.cpp +356 -0
  87. package/src/duckdb/src/optimizer/join_order/relation_statistics_helper.cpp +351 -0
  88. package/src/duckdb/src/parallel/executor.cpp +6 -0
  89. package/src/duckdb/src/parallel/task_scheduler.cpp +7 -0
  90. package/src/duckdb/src/planner/binder/statement/bind_execute.cpp +1 -1
  91. package/src/duckdb/src/planner/operator/logical_get.cpp +4 -0
  92. package/src/duckdb/src/storage/buffer/block_manager.cpp +10 -9
  93. package/src/duckdb/src/storage/checkpoint/row_group_writer.cpp +1 -1
  94. package/src/duckdb/src/storage/checkpoint/table_data_reader.cpp +3 -4
  95. package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +7 -7
  96. package/src/duckdb/src/storage/checkpoint_manager.cpp +49 -43
  97. package/src/duckdb/src/storage/index.cpp +1 -1
  98. package/src/duckdb/src/storage/metadata/metadata_manager.cpp +267 -0
  99. package/src/duckdb/src/storage/metadata/metadata_reader.cpp +80 -0
  100. package/src/duckdb/src/storage/metadata/metadata_writer.cpp +86 -0
  101. package/src/duckdb/src/storage/single_file_block_manager.cpp +47 -52
  102. package/src/duckdb/src/storage/storage_info.cpp +1 -1
  103. package/src/duckdb/src/storage/storage_manager.cpp +4 -3
  104. package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +3 -3
  105. package/src/duckdb/src/storage/table/persistent_table_data.cpp +1 -2
  106. package/src/duckdb/src/storage/table/row_group.cpp +9 -10
  107. package/src/duckdb/src/storage/table/row_group_collection.cpp +6 -3
  108. package/src/duckdb/src/storage/table_index_list.cpp +1 -1
  109. package/src/duckdb/src/storage/wal_replay.cpp +3 -2
  110. package/src/duckdb/src/storage/write_ahead_log.cpp +3 -2
  111. package/src/duckdb/ub_src_optimizer_join_order.cpp +10 -0
  112. package/src/duckdb/ub_src_storage.cpp +0 -4
  113. package/src/duckdb/ub_src_storage_metadata.cpp +6 -0
  114. package/src/duckdb/src/include/duckdb/storage/meta_block_reader.hpp +0 -46
  115. package/src/duckdb/src/include/duckdb/storage/meta_block_writer.hpp +0 -50
  116. package/src/duckdb/src/storage/meta_block_reader.cpp +0 -69
  117. package/src/duckdb/src/storage/meta_block_writer.cpp +0 -80
package/binding.gyp CHANGED
@@ -136,6 +136,7 @@
136
136
  "src/duckdb/ub_src_storage_checkpoint.cpp",
137
137
  "src/duckdb/ub_src_storage_compression.cpp",
138
138
  "src/duckdb/ub_src_storage_compression_chimp.cpp",
139
+ "src/duckdb/ub_src_storage_metadata.cpp",
139
140
  "src/duckdb/ub_src_storage_serialization.cpp",
140
141
  "src/duckdb/ub_src_storage_statistics.cpp",
141
142
  "src/duckdb/ub_src_storage_table.cpp",
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-dev2673.0",
5
+ "version": "0.8.2-dev2809.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -1,4 +1,6 @@
1
+ #include "duckdb/common/operator/add.hpp"
1
2
  #include "duckdb/common/operator/cast_operators.hpp"
3
+ #include "duckdb/common/operator/subtract.hpp"
2
4
  #include "duckdb/common/types/date.hpp"
3
5
  #include "duckdb/common/types/time.hpp"
4
6
  #include "duckdb/common/types/timestamp.hpp"
@@ -66,7 +68,11 @@ struct ICUMakeDate : public ICUDateFunc {
66
68
  struct ICUMakeTimestampTZFunc : public ICUDateFunc {
67
69
  template <typename T>
68
70
  static inline timestamp_t Operation(icu::Calendar *calendar, T yyyy, T mm, T dd, T hr, T mn, double ss) {
69
- const auto year = yyyy + (yyyy < 0);
71
+ const auto year = Cast::Operation<T, int32_t>(AddOperator::Operation<T, T, T>(yyyy, (yyyy < 0)));
72
+ const auto month = Cast::Operation<T, int32_t>(SubtractOperatorOverflowCheck::Operation<T, T, T>(mm, 1));
73
+ const auto day = Cast::Operation<T, int32_t>(dd);
74
+ const auto hour = Cast::Operation<T, int32_t>(hr);
75
+ const auto min = Cast::Operation<T, int32_t>(mn);
70
76
 
71
77
  const auto secs = Cast::Operation<double, int32_t>(ss);
72
78
  ss -= secs;
@@ -74,11 +80,11 @@ struct ICUMakeTimestampTZFunc : public ICUDateFunc {
74
80
  const auto millis = int32_t(ss);
75
81
  int64_t micros = std::round((ss - millis) * Interval::MICROS_PER_MSEC);
76
82
 
77
- calendar->set(UCAL_YEAR, int32_t(year));
78
- calendar->set(UCAL_MONTH, int32_t(mm - 1));
79
- calendar->set(UCAL_DATE, int32_t(dd));
80
- calendar->set(UCAL_HOUR_OF_DAY, int32_t(hr));
81
- calendar->set(UCAL_MINUTE, int32_t(mn));
83
+ calendar->set(UCAL_YEAR, year);
84
+ calendar->set(UCAL_MONTH, month);
85
+ calendar->set(UCAL_DATE, day);
86
+ calendar->set(UCAL_HOUR_OF_DAY, hour);
87
+ calendar->set(UCAL_MINUTE, min);
82
88
  calendar->set(UCAL_SECOND, secs);
83
89
  calendar->set(UCAL_MILLISECOND, millis);
84
90
 
@@ -23,7 +23,7 @@
23
23
  namespace duckdb {
24
24
 
25
25
  void AddDataTableIndex(DataTable &storage, const ColumnList &columns, const vector<PhysicalIndex> &keys,
26
- IndexConstraintType constraint_type, BlockPointer *index_block = nullptr) {
26
+ IndexConstraintType constraint_type, BlockPointer index_block = BlockPointer()) {
27
27
  // fetch types and create expressions for the index from the columns
28
28
  vector<column_t> column_ids;
29
29
  vector<unique_ptr<Expression>> unbound_expressions;
@@ -41,9 +41,9 @@ void AddDataTableIndex(DataTable &storage, const ColumnList &columns, const vect
41
41
  }
42
42
  unique_ptr<ART> art;
43
43
  // create an adaptive radix tree around the expressions
44
- if (index_block) {
44
+ if (index_block.IsValid()) {
45
45
  art = make_uniq<ART>(column_ids, TableIOManager::Get(storage), std::move(unbound_expressions), constraint_type,
46
- storage.db, nullptr, index_block->block_id, index_block->offset);
46
+ storage.db, nullptr, index_block);
47
47
  } else {
48
48
  art = make_uniq<ART>(column_ids, TableIOManager::Get(storage), std::move(unbound_expressions), constraint_type,
49
49
  storage.db);
@@ -55,7 +55,7 @@ void AddDataTableIndex(DataTable &storage, const ColumnList &columns, const vect
55
55
  }
56
56
 
57
57
  void AddDataTableIndex(DataTable &storage, const ColumnList &columns, vector<LogicalIndex> &keys,
58
- IndexConstraintType constraint_type, BlockPointer *index_block = nullptr) {
58
+ IndexConstraintType constraint_type, BlockPointer index_block = BlockPointer()) {
59
59
  vector<PhysicalIndex> new_keys;
60
60
  new_keys.reserve(keys.size());
61
61
  for (auto &logical_key : keys) {
@@ -92,7 +92,7 @@ DuckTableEntry::DuckTableEntry(Catalog &catalog, SchemaCatalogEntry &schema, Bou
92
92
  if (info.indexes.empty()) {
93
93
  AddDataTableIndex(*storage, columns, unique.keys, constraint_type);
94
94
  } else {
95
- AddDataTableIndex(*storage, columns, unique.keys, constraint_type, &info.indexes[indexes_idx++]);
95
+ AddDataTableIndex(*storage, columns, unique.keys, constraint_type, info.indexes[indexes_idx++]);
96
96
  }
97
97
  } else if (constraint->type == ConstraintType::FOREIGN_KEY) {
98
98
  // foreign key constraint: create a foreign key index
@@ -103,7 +103,7 @@ DuckTableEntry::DuckTableEntry(Catalog &catalog, SchemaCatalogEntry &schema, Bou
103
103
  AddDataTableIndex(*storage, columns, bfk.info.fk_keys, IndexConstraintType::FOREIGN);
104
104
  } else {
105
105
  AddDataTableIndex(*storage, columns, bfk.info.fk_keys, IndexConstraintType::FOREIGN,
106
- &info.indexes[indexes_idx++]);
106
+ info.indexes[indexes_idx++]);
107
107
  }
108
108
  }
109
109
  }
@@ -586,16 +586,14 @@ AdbcStatusCode StatementExecuteQuery(struct AdbcStatement *statement, struct Arr
586
586
 
587
587
  // this is a nop for us
588
588
  AdbcStatusCode StatementPrepare(struct AdbcStatement *statement, struct AdbcError *error) {
589
- auto status = SetErrorMaybe(statement, error, "Missing statement object");
590
- if (status != ADBC_STATUS_OK) {
591
- return status;
589
+ if (!statement) {
590
+ SetError(error, "Missing statement object");
591
+ return ADBC_STATUS_INVALID_ARGUMENT;
592
592
  }
593
-
594
- status = SetErrorMaybe(statement->private_data, error, "Invalid statement object");
595
- if (status != ADBC_STATUS_OK) {
596
- return status;
593
+ if (!error) {
594
+ SetError(error, "Missing error object");
595
+ return ADBC_STATUS_INVALID_ARGUMENT;
597
596
  }
598
-
599
597
  return ADBC_STATUS_OK;
600
598
  }
601
599
 
@@ -687,10 +685,6 @@ AdbcStatusCode QueryInternal(struct AdbcConnection *connection, struct ArrowArra
687
685
  AdbcStatusCode ConnectionGetObjects(struct AdbcConnection *connection, int depth, const char *catalog,
688
686
  const char *db_schema, const char *table_name, const char **table_type,
689
687
  const char *column_name, struct ArrowArrayStream *out, struct AdbcError *error) {
690
- if (depth != 0) {
691
- SetError(error, "Depth parameter not yet supported");
692
- return ADBC_STATUS_NOT_IMPLEMENTED;
693
- }
694
688
  if (catalog != nullptr) {
695
689
  if (strcmp(catalog, "duckdb") == 0) {
696
690
  SetError(error, "catalog must be NULL or 'duckdb'");
@@ -702,16 +696,53 @@ AdbcStatusCode ConnectionGetObjects(struct AdbcConnection *connection, int depth
702
696
  SetError(error, "Table types parameter not yet supported");
703
697
  return ADBC_STATUS_NOT_IMPLEMENTED;
704
698
  }
699
+ std::string query;
700
+ switch (depth) {
701
+ case ADBC_OBJECT_DEPTH_CATALOGS:
702
+ SetError(error, "ADBC_OBJECT_DEPTH_CATALOGS not yet supported");
703
+ return ADBC_STATUS_NOT_IMPLEMENTED;
704
+ case ADBC_OBJECT_DEPTH_DB_SCHEMAS:
705
+ // Return metadata on catalogs and schemas.
706
+ query = duckdb::StringUtil::Format(R"(
707
+ SELECT table_schema db_schema_name
708
+ FROM information_schema.columns
709
+ WHERE table_schema LIKE '%s' AND table_name LIKE '%s' AND column_name LIKE '%s' ;
710
+ )",
711
+ db_schema ? db_schema : "%", table_name ? table_name : "%",
712
+ column_name ? column_name : "%");
713
+ break;
714
+ case ADBC_OBJECT_DEPTH_TABLES:
715
+ // Return metadata on catalogs, schemas, and tables.
716
+ query = duckdb::StringUtil::Format(R"(
717
+ SELECT table_schema db_schema_name, LIST(table_schema_list) db_schema_tables
718
+ FROM (
719
+ SELECT table_schema, { table_name : table_name} table_schema_list
720
+ FROM information_schema.columns
721
+ WHERE table_schema LIKE '%s' AND table_name LIKE '%s' AND column_name LIKE '%s' GROUP BY table_schema, table_name
722
+ ) GROUP BY table_schema;
723
+ )",
724
+ db_schema ? db_schema : "%", table_name ? table_name : "%",
725
+ column_name ? column_name : "%");
726
+ break;
727
+ case ADBC_OBJECT_DEPTH_COLUMNS:
728
+ // Return metadata on catalogs, schemas, tables, and columns.
729
+ query = duckdb::StringUtil::Format(R"(
730
+ SELECT table_schema db_schema_name, LIST(table_schema_list) db_schema_tables
731
+ FROM (
732
+ SELECT table_schema, { table_name : table_name, table_columns : LIST({column_name : column_name, ordinal_position : ordinal_position + 1, remarks : ''})} table_schema_list
733
+ FROM information_schema.columns
734
+ WHERE table_schema LIKE '%s' AND table_name LIKE '%s' AND column_name LIKE '%s' GROUP BY table_schema, table_name
735
+ ) GROUP BY table_schema;
736
+ )",
737
+ db_schema ? db_schema : "%", table_name ? table_name : "%",
738
+ column_name ? column_name : "%");
739
+ break;
740
+ default:
741
+ SetError(error, "Invalid value of Depth");
742
+ return ADBC_STATUS_INVALID_ARGUMENT;
743
+ }
705
744
 
706
- auto q = duckdb::StringUtil::Format(R"(
707
- SELECT table_schema db_schema_name, LIST(table_schema_list) db_schema_tables FROM (
708
- SELECT table_schema, { table_name : table_name, table_columns : LIST({column_name : column_name, ordinal_position : ordinal_position + 1, remarks : ''})} table_schema_list FROM information_schema.columns WHERE table_schema LIKE '%s' AND table_name LIKE '%s' AND column_name LIKE '%s' GROUP BY table_schema, table_name
709
- ) GROUP BY table_schema;
710
- )",
711
- db_schema ? db_schema : "%", table_name ? table_name : "%",
712
- column_name ? column_name : "%");
713
-
714
- return QueryInternal(connection, out, q.c_str(), error);
745
+ return QueryInternal(connection, out, query.c_str(), error);
715
746
  }
716
747
 
717
748
  AdbcStatusCode ConnectionGetTableTypes(struct AdbcConnection *connection, struct ArrowArrayStream *out,
@@ -304,7 +304,12 @@ AdbcStatusCode AdbcConnectionGetObjects(struct AdbcConnection *connection, int d
304
304
  const char *db_schema, const char *table_name, const char **table_types,
305
305
  const char *column_name, struct ArrowArrayStream *stream,
306
306
  struct AdbcError *error) {
307
- if (!connection->private_driver) {
307
+ if (!connection) {
308
+ SetError(error, "connection can't be null");
309
+ return ADBC_STATUS_INVALID_STATE;
310
+ }
311
+ if (!connection->private_data) {
312
+ SetError(error, "connection must be initialized");
308
313
  return ADBC_STATUS_INVALID_STATE;
309
314
  }
310
315
  return connection->private_driver->ConnectionGetObjects(connection, depth, catalog, db_schema, table_name,
@@ -474,7 +479,12 @@ AdbcStatusCode AdbcStatementNew(struct AdbcConnection *connection, struct AdbcSt
474
479
  }
475
480
 
476
481
  AdbcStatusCode AdbcStatementPrepare(struct AdbcStatement *statement, struct AdbcError *error) {
477
- if (!statement->private_driver) {
482
+ auto status = SetErrorMaybe(statement, error, "Missing statement object");
483
+ if (status != ADBC_STATUS_OK) {
484
+ return status;
485
+ }
486
+ status = SetErrorMaybe(statement->private_data, error, "Invalid statement object");
487
+ if (status != ADBC_STATUS_OK) {
478
488
  return ADBC_STATUS_INVALID_STATE;
479
489
  }
480
490
  return statement->private_driver->StatementPrepare(statement, error);
@@ -3872,6 +3872,8 @@ const char* EnumUtil::ToChars<PendingExecutionResult>(PendingExecutionResult val
3872
3872
  return "RESULT_NOT_READY";
3873
3873
  case PendingExecutionResult::EXECUTION_ERROR:
3874
3874
  return "EXECUTION_ERROR";
3875
+ case PendingExecutionResult::NO_TASKS_AVAILABLE:
3876
+ return "NO_TASKS_AVAILABLE";
3875
3877
  default:
3876
3878
  throw NotImplementedException(StringUtil::Format("Enum value: '%d' not implemented", value));
3877
3879
  }
@@ -3888,6 +3890,9 @@ PendingExecutionResult EnumUtil::FromString<PendingExecutionResult>(const char *
3888
3890
  if (StringUtil::Equals(value, "EXECUTION_ERROR")) {
3889
3891
  return PendingExecutionResult::EXECUTION_ERROR;
3890
3892
  }
3893
+ if (StringUtil::Equals(value, "NO_TASKS_AVAILABLE")) {
3894
+ return PendingExecutionResult::NO_TASKS_AVAILABLE;
3895
+ }
3891
3896
  throw NotImplementedException(StringUtil::Format("Enum value: '%s' not implemented", value));
3892
3897
  }
3893
3898
 
@@ -72,6 +72,7 @@ FieldReader::FieldReader(Deserializer &source_p) : source(source_p), field_count
72
72
  max_field_count = source_p.Read<uint32_t>();
73
73
  total_size = source_p.Read<uint64_t>();
74
74
  D_ASSERT(max_field_count > 0);
75
+ D_ASSERT(total_size > 0);
75
76
  source.SetRemainingData(total_size);
76
77
  }
77
78
 
@@ -267,6 +267,11 @@ void LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, i
267
267
  if (bytes_read == -1) {
268
268
  throw IOException("Could not read from file \"%s\": %s", handle.path, strerror(errno));
269
269
  }
270
+ if (bytes_read == 0) {
271
+ throw IOException(
272
+ "Could not read enough bytes from file \"%s\": attempted to read %llu bytes from location %llu",
273
+ handle.path, nr_bytes, location);
274
+ }
270
275
  read_buffer += bytes_read;
271
276
  nr_bytes -= bytes_read;
272
277
  }
@@ -116,6 +116,9 @@ interval_parse_time : {
116
116
  }
117
117
  result.micros += time.micros;
118
118
  found_any = true;
119
+ if (negative) {
120
+ result.micros = -result.micros;
121
+ }
119
122
  goto end_of_string;
120
123
  }
121
124
  interval_parse_identifier:
@@ -4,6 +4,8 @@
4
4
  #include "duckdb/common/types/row/row_data_collection.hpp"
5
5
  #include "duckdb/storage/buffer_manager.hpp"
6
6
 
7
+ #include <numeric>
8
+
7
9
  namespace duckdb {
8
10
 
9
11
  void RowDataCollectionScanner::AlignHeapBlocks(RowDataCollection &swizzled_block_collection,
@@ -155,6 +157,31 @@ RowDataCollectionScanner::RowDataCollectionScanner(RowDataCollection &rows_p, Ro
155
157
  ValidateUnscannedBlock();
156
158
  }
157
159
 
160
+ RowDataCollectionScanner::RowDataCollectionScanner(RowDataCollection &rows_p, RowDataCollection &heap_p,
161
+ const RowLayout &layout_p, bool external_p, idx_t block_idx,
162
+ bool flush_p)
163
+ : rows(rows_p), heap(heap_p), layout(layout_p), read_state(*this), total_count(rows.count), total_scanned(0),
164
+ external(external_p), flush(flush_p), unswizzling(!layout.AllConstant() && external && !heap.keep_pinned) {
165
+
166
+ if (unswizzling) {
167
+ D_ASSERT(rows.blocks.size() == heap.blocks.size());
168
+ }
169
+
170
+ D_ASSERT(block_idx < rows.blocks.size());
171
+ read_state.block_idx = block_idx;
172
+ read_state.entry_idx = 0;
173
+
174
+ // Pretend that we have scanned up to the start block
175
+ // and will stop at the end
176
+ auto begin = rows.blocks.begin();
177
+ auto end = begin + block_idx;
178
+ total_scanned =
179
+ std::accumulate(begin, end, idx_t(0), [&](idx_t c, const unique_ptr<RowDataBlock> &b) { return c + b->count; });
180
+ total_count = total_scanned + (*end)->count;
181
+
182
+ ValidateUnscannedBlock();
183
+ }
184
+
158
185
  void RowDataCollectionScanner::SwizzleBlock(RowDataBlock &data_block, RowDataBlock &heap_block) {
159
186
  // Pin the data block and swizzle the pointers within the rows
160
187
  D_ASSERT(!data_block.block->IsSwizzled());
@@ -190,7 +217,7 @@ void RowDataCollectionScanner::ReSwizzle() {
190
217
  }
191
218
 
192
219
  void RowDataCollectionScanner::ValidateUnscannedBlock() const {
193
- if (unswizzling && read_state.block_idx < rows.blocks.size()) {
220
+ if (unswizzling && read_state.block_idx < rows.blocks.size() && Remaining()) {
194
221
  D_ASSERT(rows.blocks[read_state.block_idx]->block->IsSwizzled());
195
222
  }
196
223
  }
@@ -202,6 +229,9 @@ void RowDataCollectionScanner::Scan(DataChunk &chunk) {
202
229
  return;
203
230
  }
204
231
 
232
+ // Only flush blocks we processed.
233
+ const auto flush_block_idx = read_state.block_idx;
234
+
205
235
  const idx_t &row_width = layout.GetRowWidth();
206
236
  // Set up a batch of pointers to scan data from
207
237
  idx_t scanned = 0;
@@ -227,6 +257,8 @@ void RowDataCollectionScanner::Scan(DataChunk &chunk) {
227
257
  }
228
258
  // Update state indices
229
259
  read_state.entry_idx += next;
260
+ scanned += next;
261
+ total_scanned += next;
230
262
  if (read_state.entry_idx == data_block->count) {
231
263
  // Pin completed blocks so we don't lose them
232
264
  pinned_blocks.emplace_back(rows.buffer_manager.Pin(data_block->block));
@@ -238,7 +270,6 @@ void RowDataCollectionScanner::Scan(DataChunk &chunk) {
238
270
  read_state.entry_idx = 0;
239
271
  ValidateUnscannedBlock();
240
272
  }
241
- scanned += next;
242
273
  }
243
274
  D_ASSERT(scanned == count);
244
275
  // Deserialize the payload data
@@ -248,14 +279,13 @@ void RowDataCollectionScanner::Scan(DataChunk &chunk) {
248
279
  }
249
280
  chunk.SetCardinality(count);
250
281
  chunk.Verify();
251
- total_scanned += scanned;
252
282
 
253
283
  // Switch to a new set of pinned blocks
254
284
  read_state.pinned_blocks.swap(pinned_blocks);
255
285
 
256
286
  if (flush) {
257
287
  // Release blocks we have passed.
258
- for (idx_t i = 0; i < read_state.block_idx; ++i) {
288
+ for (idx_t i = flush_block_idx; i < read_state.block_idx; ++i) {
259
289
  rows.blocks[i]->block = nullptr;
260
290
  if (unswizzling) {
261
291
  heap.blocks[i]->block = nullptr;
@@ -263,7 +293,7 @@ void RowDataCollectionScanner::Scan(DataChunk &chunk) {
263
293
  }
264
294
  } else if (unswizzling) {
265
295
  // Reswizzle blocks we have passed so they can be flushed safely.
266
- for (idx_t i = 0; i < read_state.block_idx; ++i) {
296
+ for (idx_t i = flush_block_idx; i < read_state.block_idx; ++i) {
267
297
  auto &data_block = rows.blocks[i];
268
298
  if (data_block->block && !data_block->block->IsSwizzled()) {
269
299
  SwizzleBlock(*data_block, *heap.blocks[i]);
@@ -33,12 +33,9 @@ struct ARTIndexScanState : public IndexScanState {
33
33
 
34
34
  ART::ART(const vector<column_t> &column_ids, TableIOManager &table_io_manager,
35
35
  const vector<unique_ptr<Expression>> &unbound_expressions, const IndexConstraintType constraint_type,
36
- AttachedDatabase &db, const shared_ptr<vector<FixedSizeAllocator>> &allocators_ptr, const idx_t block_id,
37
- const idx_t block_offset)
38
-
36
+ AttachedDatabase &db, const shared_ptr<vector<FixedSizeAllocator>> &allocators_ptr, BlockPointer pointer)
39
37
  : Index(db, IndexType::ART, table_io_manager, column_ids, unbound_expressions, constraint_type),
40
38
  allocators(allocators_ptr), owns_data(false) {
41
-
42
39
  if (!Radix::IsLittleEndian()) {
43
40
  throw NotImplementedException("ART indexes are not supported on big endian architectures");
44
41
  }
@@ -57,12 +54,12 @@ ART::ART(const vector<column_t> &column_ids, TableIOManager &table_io_manager,
57
54
 
58
55
  // set the root node of the tree
59
56
  tree = make_uniq<Node>();
60
- if (block_id != DConstants::INVALID_INDEX) {
57
+ serialized_data_pointer = pointer;
58
+ if (pointer.IsValid()) {
61
59
  tree->SetSerialized();
62
- tree->SetPtr(block_id, block_offset);
60
+ tree->SetPtr(pointer.block_id, pointer.offset);
63
61
  tree->Deserialize(*this);
64
62
  }
65
- serialized_data_pointer = BlockPointer(block_id, block_offset);
66
63
 
67
64
  // validate the types of the key columns
68
65
  for (idx_t i = 0; i < types.size(); i++) {
@@ -974,13 +971,13 @@ void ART::CheckConstraintsForChunk(DataChunk &input, ConflictManager &conflict_m
974
971
  // Serialization
975
972
  //===--------------------------------------------------------------------===//
976
973
 
977
- BlockPointer ART::Serialize(MetaBlockWriter &writer) {
974
+ BlockPointer ART::Serialize(MetadataWriter &writer) {
978
975
 
979
976
  lock_guard<mutex> l(lock);
980
977
  if (tree->IsSet()) {
981
978
  serialized_data_pointer = tree->Serialize(*this, writer);
982
979
  } else {
983
- serialized_data_pointer = {(block_id_t)DConstants::INVALID_INDEX, (uint32_t)DConstants::INVALID_INDEX};
980
+ serialized_data_pointer = BlockPointer();
984
981
  }
985
982
 
986
983
  return serialized_data_pointer;
@@ -2,8 +2,8 @@
2
2
 
3
3
  #include "duckdb/execution/index/art/art.hpp"
4
4
  #include "duckdb/execution/index/art/node.hpp"
5
- #include "duckdb/storage/meta_block_reader.hpp"
6
- #include "duckdb/storage/meta_block_writer.hpp"
5
+ #include "duckdb/storage/metadata/metadata_reader.hpp"
6
+ #include "duckdb/storage/metadata/metadata_writer.hpp"
7
7
 
8
8
  namespace duckdb {
9
9
 
@@ -323,7 +323,7 @@ string Leaf::VerifyAndToString(ART &art, Node &node) {
323
323
  return str;
324
324
  }
325
325
 
326
- BlockPointer Leaf::Serialize(ART &art, Node &node, MetaBlockWriter &writer) {
326
+ BlockPointer Leaf::Serialize(ART &art, Node &node, MetadataWriter &writer) {
327
327
 
328
328
  if (node.GetType() == NType::LEAF_INLINED) {
329
329
  auto block_pointer = writer.GetBlockPointer();
@@ -353,7 +353,7 @@ BlockPointer Leaf::Serialize(ART &art, Node &node, MetaBlockWriter &writer) {
353
353
  return block_pointer;
354
354
  }
355
355
 
356
- void Leaf::Deserialize(ART &art, Node &node, MetaBlockReader &reader) {
356
+ void Leaf::Deserialize(ART &art, Node &node, MetadataReader &reader) {
357
357
 
358
358
  auto total_count = reader.Read<idx_t>();
359
359
  reference<Node> ref_node(node);
@@ -9,8 +9,8 @@
9
9
  #include "duckdb/execution/index/art/node4.hpp"
10
10
  #include "duckdb/execution/index/art/leaf.hpp"
11
11
  #include "duckdb/execution/index/art/prefix.hpp"
12
- #include "duckdb/storage/meta_block_reader.hpp"
13
- #include "duckdb/storage/meta_block_writer.hpp"
12
+ #include "duckdb/storage/metadata/metadata_reader.hpp"
13
+ #include "duckdb/storage/metadata/metadata_writer.hpp"
14
14
  #include "duckdb/storage/table_io_manager.hpp"
15
15
 
16
16
  namespace duckdb {
@@ -19,13 +19,12 @@ namespace duckdb {
19
19
  // Constructors / Destructors
20
20
  //===--------------------------------------------------------------------===//
21
21
 
22
- Node::Node(MetaBlockReader &reader) {
23
-
24
- idx_t block_id = reader.Read<block_id_t>();
22
+ Node::Node(MetadataReader &reader) {
23
+ block_id_t block_id = reader.Read<block_id_t>();
25
24
  auto offset = reader.Read<uint32_t>();
26
25
  Reset();
27
26
 
28
- if (block_id == DConstants::INVALID_INDEX) {
27
+ if (block_id == INVALID_BLOCK) {
29
28
  return;
30
29
  }
31
30
 
@@ -223,10 +222,9 @@ optional_ptr<Node> Node::GetNextChild(ART &art, uint8_t &byte, const bool deseri
223
222
  // (De)serialization
224
223
  //===--------------------------------------------------------------------===//
225
224
 
226
- BlockPointer Node::Serialize(ART &art, MetaBlockWriter &writer) {
227
-
225
+ BlockPointer Node::Serialize(ART &art, MetadataWriter &writer) {
228
226
  if (!IsSet()) {
229
- return {(block_id_t)DConstants::INVALID_INDEX, 0};
227
+ return BlockPointer();
230
228
  }
231
229
  if (IsSerialized()) {
232
230
  Deserialize(art);
@@ -254,11 +252,10 @@ BlockPointer Node::Serialize(ART &art, MetaBlockWriter &writer) {
254
252
  }
255
253
 
256
254
  void Node::Deserialize(ART &art) {
257
-
258
255
  D_ASSERT(IsSet() && IsSerialized());
259
256
 
260
- MetaBlockReader reader(art.table_io_manager.GetIndexBlockManager(), GetBufferId());
261
- reader.offset = GetOffset();
257
+ BlockPointer pointer(GetBufferId(), GetOffset());
258
+ MetadataReader reader(art.table_io_manager.GetMetadataManager(), pointer);
262
259
  Reset();
263
260
  SetType(reader.Read<uint8_t>());
264
261
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  #include "duckdb/execution/index/art/node4.hpp"
4
4
  #include "duckdb/execution/index/art/node48.hpp"
5
- #include "duckdb/storage/meta_block_reader.hpp"
6
- #include "duckdb/storage/meta_block_writer.hpp"
5
+ #include "duckdb/storage/metadata/metadata_reader.hpp"
6
+ #include "duckdb/storage/metadata/metadata_writer.hpp"
7
7
 
8
8
  namespace duckdb {
9
9
 
@@ -173,7 +173,7 @@ optional_ptr<Node> Node16::GetNextChild(uint8_t &byte) {
173
173
  return nullptr;
174
174
  }
175
175
 
176
- BlockPointer Node16::Serialize(ART &art, MetaBlockWriter &writer) {
176
+ BlockPointer Node16::Serialize(ART &art, MetadataWriter &writer) {
177
177
 
178
178
  // recurse into children and retrieve child block pointers
179
179
  vector<BlockPointer> child_block_pointers;
@@ -203,7 +203,7 @@ BlockPointer Node16::Serialize(ART &art, MetaBlockWriter &writer) {
203
203
  return block_pointer;
204
204
  }
205
205
 
206
- void Node16::Deserialize(MetaBlockReader &reader) {
206
+ void Node16::Deserialize(MetadataReader &reader) {
207
207
 
208
208
  count = reader.Read<uint8_t>();
209
209
 
@@ -1,8 +1,8 @@
1
1
  #include "duckdb/execution/index/art/node256.hpp"
2
2
 
3
3
  #include "duckdb/execution/index/art/node48.hpp"
4
- #include "duckdb/storage/meta_block_reader.hpp"
5
- #include "duckdb/storage/meta_block_writer.hpp"
4
+ #include "duckdb/storage/metadata/metadata_reader.hpp"
5
+ #include "duckdb/storage/metadata/metadata_writer.hpp"
6
6
 
7
7
  namespace duckdb {
8
8
 
@@ -109,7 +109,7 @@ optional_ptr<Node> Node256::GetNextChild(uint8_t &byte) {
109
109
  return nullptr;
110
110
  }
111
111
 
112
- BlockPointer Node256::Serialize(ART &art, MetaBlockWriter &writer) {
112
+ BlockPointer Node256::Serialize(ART &art, MetadataWriter &writer) {
113
113
 
114
114
  // recurse into children and retrieve child block pointers
115
115
  vector<BlockPointer> child_block_pointers;
@@ -131,7 +131,7 @@ BlockPointer Node256::Serialize(ART &art, MetaBlockWriter &writer) {
131
131
  return block_pointer;
132
132
  }
133
133
 
134
- void Node256::Deserialize(MetaBlockReader &reader) {
134
+ void Node256::Deserialize(MetadataReader &reader) {
135
135
 
136
136
  count = reader.Read<uint16_t>();
137
137
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  #include "duckdb/execution/index/art/prefix.hpp"
4
4
  #include "duckdb/execution/index/art/node16.hpp"
5
- #include "duckdb/storage/meta_block_reader.hpp"
6
- #include "duckdb/storage/meta_block_writer.hpp"
5
+ #include "duckdb/storage/metadata/metadata_reader.hpp"
6
+ #include "duckdb/storage/metadata/metadata_writer.hpp"
7
7
 
8
8
  namespace duckdb {
9
9
 
@@ -166,7 +166,7 @@ optional_ptr<Node> Node4::GetNextChild(uint8_t &byte) {
166
166
  return nullptr;
167
167
  }
168
168
 
169
- BlockPointer Node4::Serialize(ART &art, MetaBlockWriter &writer) {
169
+ BlockPointer Node4::Serialize(ART &art, MetadataWriter &writer) {
170
170
 
171
171
  // recurse into children and retrieve child block pointers
172
172
  vector<BlockPointer> child_block_pointers;
@@ -196,8 +196,7 @@ BlockPointer Node4::Serialize(ART &art, MetaBlockWriter &writer) {
196
196
  return block_pointer;
197
197
  }
198
198
 
199
- void Node4::Deserialize(MetaBlockReader &reader) {
200
-
199
+ void Node4::Deserialize(MetadataReader &reader) {
201
200
  count = reader.Read<uint8_t>();
202
201
 
203
202
  // read key values
@@ -2,8 +2,8 @@
2
2
 
3
3
  #include "duckdb/execution/index/art/node16.hpp"
4
4
  #include "duckdb/execution/index/art/node256.hpp"
5
- #include "duckdb/storage/meta_block_reader.hpp"
6
- #include "duckdb/storage/meta_block_writer.hpp"
5
+ #include "duckdb/storage/metadata/metadata_reader.hpp"
6
+ #include "duckdb/storage/metadata/metadata_writer.hpp"
7
7
 
8
8
  namespace duckdb {
9
9
 
@@ -168,7 +168,7 @@ optional_ptr<Node> Node48::GetNextChild(uint8_t &byte) {
168
168
  return nullptr;
169
169
  }
170
170
 
171
- BlockPointer Node48::Serialize(ART &art, MetaBlockWriter &writer) {
171
+ BlockPointer Node48::Serialize(ART &art, MetadataWriter &writer) {
172
172
 
173
173
  // recurse into children and retrieve child block pointers
174
174
  vector<BlockPointer> child_block_pointers;
@@ -195,7 +195,7 @@ BlockPointer Node48::Serialize(ART &art, MetaBlockWriter &writer) {
195
195
  return block_pointer;
196
196
  }
197
197
 
198
- void Node48::Deserialize(MetaBlockReader &reader) {
198
+ void Node48::Deserialize(MetadataReader &reader) {
199
199
 
200
200
  count = reader.Read<uint8_t>();
201
201