duckdb 0.7.2-dev16.0 → 0.7.2-dev225.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 (129) hide show
  1. package/binding.gyp +2 -0
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/icu/icu-extension.cpp +2 -0
  4. package/src/duckdb/extension/icu/icu-table-range.cpp +194 -0
  5. package/src/duckdb/extension/icu/include/icu-table-range.hpp +17 -0
  6. package/src/duckdb/extension/parquet/column_writer.cpp +0 -1
  7. package/src/duckdb/extension/parquet/parquet-extension.cpp +11 -2
  8. package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +4 -0
  9. package/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp +7 -6
  10. package/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp +20 -1
  11. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  12. package/src/duckdb/src/common/types/bit.cpp +95 -58
  13. package/src/duckdb/src/common/types/value.cpp +149 -53
  14. package/src/duckdb/src/common/types/vector.cpp +13 -10
  15. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
  16. package/src/duckdb/src/function/aggregate/algebraic/avg.cpp +0 -6
  17. package/src/duckdb/src/function/aggregate/distributive/bitagg.cpp +99 -95
  18. package/src/duckdb/src/function/aggregate/distributive/bitstring_agg.cpp +261 -0
  19. package/src/duckdb/src/function/aggregate/distributive/sum.cpp +0 -3
  20. package/src/duckdb/src/function/aggregate/distributive_functions.cpp +1 -0
  21. package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +16 -5
  22. package/src/duckdb/src/function/cast/bit_cast.cpp +0 -2
  23. package/src/duckdb/src/function/cast/blob_cast.cpp +0 -1
  24. package/src/duckdb/src/function/scalar/bit/bitstring.cpp +99 -0
  25. package/src/duckdb/src/function/scalar/map/map_entries.cpp +61 -0
  26. package/src/duckdb/src/function/scalar/map/map_keys_values.cpp +97 -0
  27. package/src/duckdb/src/function/scalar/nested_functions.cpp +3 -0
  28. package/src/duckdb/src/function/scalar/operators/add.cpp +0 -9
  29. package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +2 -14
  30. package/src/duckdb/src/function/scalar/operators/bitwise.cpp +0 -63
  31. package/src/duckdb/src/function/scalar/operators/multiply.cpp +0 -6
  32. package/src/duckdb/src/function/scalar/operators/subtract.cpp +0 -6
  33. package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
  34. package/src/duckdb/src/function/table/read_csv.cpp +9 -0
  35. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  36. package/src/duckdb/src/function/table_function.cpp +19 -0
  37. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +6 -8
  38. package/src/duckdb/src/include/duckdb/common/constants.hpp +0 -19
  39. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +2 -1
  40. package/src/duckdb/src/include/duckdb/common/enums/tableref_type.hpp +2 -1
  41. package/src/duckdb/src/include/duckdb/common/types/bit.hpp +5 -1
  42. package/src/duckdb/src/include/duckdb/common/types/value.hpp +2 -8
  43. package/src/duckdb/src/include/duckdb/common/types.hpp +1 -2
  44. package/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp +5 -0
  45. package/src/duckdb/src/include/duckdb/function/scalar/bit_functions.hpp +4 -0
  46. package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +12 -0
  47. package/src/duckdb/src/include/duckdb/function/table_function.hpp +2 -0
  48. package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +2 -0
  49. package/src/duckdb/src/include/duckdb/main/config.hpp +3 -0
  50. package/src/duckdb/src/include/duckdb/main/database.hpp +1 -0
  51. package/src/duckdb/src/include/duckdb/optimizer/join_order/cardinality_estimator.hpp +2 -2
  52. package/src/duckdb/src/include/duckdb/parser/common_table_expression_info.hpp +2 -0
  53. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +2 -1
  54. package/src/duckdb/src/include/duckdb/parser/parsed_data/{alter_function_info.hpp → alter_scalar_function_info.hpp} +13 -13
  55. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_function_info.hpp +47 -0
  56. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_table_function_info.hpp +2 -1
  57. package/src/duckdb/src/include/duckdb/parser/query_node.hpp +2 -1
  58. package/src/duckdb/src/include/duckdb/parser/statement/multi_statement.hpp +28 -0
  59. package/src/duckdb/src/include/duckdb/parser/tableref/list.hpp +1 -0
  60. package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +76 -0
  61. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +2 -0
  62. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +28 -0
  63. package/src/duckdb/src/include/duckdb/planner/binder.hpp +8 -0
  64. package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +2 -0
  65. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +76 -44
  66. package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +2 -0
  67. package/src/duckdb/src/include/duckdb/storage/statistics/node_statistics.hpp +26 -0
  68. package/src/duckdb/src/include/duckdb/storage/table/list_column_data.hpp +1 -1
  69. package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +2 -0
  70. package/src/duckdb/src/include/duckdb.h +49 -1
  71. package/src/duckdb/src/include/duckdb.hpp +0 -1
  72. package/src/duckdb/src/main/capi/pending-c.cpp +16 -3
  73. package/src/duckdb/src/main/capi/result-c.cpp +27 -1
  74. package/src/duckdb/src/main/capi/stream-c.cpp +25 -0
  75. package/src/duckdb/src/main/client_context.cpp +8 -1
  76. package/src/duckdb/src/main/database.cpp +10 -2
  77. package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +98 -66
  78. package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +16 -3
  79. package/src/duckdb/src/parser/parsed_data/alter_info.cpp +7 -3
  80. package/src/duckdb/src/parser/parsed_data/alter_scalar_function_info.cpp +56 -0
  81. package/src/duckdb/src/parser/parsed_data/alter_table_function_info.cpp +51 -0
  82. package/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp +3 -2
  83. package/src/duckdb/src/parser/parsed_data/create_table_function_info.cpp +6 -0
  84. package/src/duckdb/src/parser/parsed_expression_iterator.cpp +8 -0
  85. package/src/duckdb/src/parser/query_node.cpp +1 -1
  86. package/src/duckdb/src/parser/statement/multi_statement.cpp +18 -0
  87. package/src/duckdb/src/parser/tableref/pivotref.cpp +296 -0
  88. package/src/duckdb/src/parser/tableref.cpp +3 -0
  89. package/src/duckdb/src/parser/transform/helpers/transform_alias.cpp +12 -6
  90. package/src/duckdb/src/parser/transform/helpers/transform_cte.cpp +24 -0
  91. package/src/duckdb/src/parser/transform/statement/transform_create_function.cpp +4 -0
  92. package/src/duckdb/src/parser/transform/statement/transform_create_view.cpp +4 -0
  93. package/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +150 -0
  94. package/src/duckdb/src/parser/transform/statement/transform_select.cpp +8 -0
  95. package/src/duckdb/src/parser/transform/statement/transform_select_node.cpp +1 -1
  96. package/src/duckdb/src/parser/transform/tableref/transform_pivot.cpp +105 -0
  97. package/src/duckdb/src/parser/transform/tableref/transform_tableref.cpp +2 -0
  98. package/src/duckdb/src/parser/transformer.cpp +15 -3
  99. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +11 -3
  100. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +1 -1
  101. package/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp +17 -0
  102. package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +365 -0
  103. package/src/duckdb/src/planner/binder.cpp +5 -0
  104. package/src/duckdb/src/planner/pragma_handler.cpp +10 -2
  105. package/src/duckdb/src/storage/buffer_manager.cpp +44 -46
  106. package/src/duckdb/src/storage/compression/bitpacking.cpp +25 -21
  107. package/src/duckdb/src/storage/compression/fixed_size_uncompressed.cpp +41 -43
  108. package/src/duckdb/src/storage/compression/rle.cpp +17 -13
  109. package/src/duckdb/src/storage/statistics/base_statistics.cpp +3 -3
  110. package/src/duckdb/src/storage/storage_info.cpp +1 -1
  111. package/src/duckdb/src/storage/table/column_data.cpp +5 -2
  112. package/src/duckdb/src/storage/table/list_column_data.cpp +32 -47
  113. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +3 -0
  114. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +34 -1
  115. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +1016 -530
  116. package/src/duckdb/third_party/libpg_query/include/parser/kwlist.hpp +5 -0
  117. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +22697 -21987
  118. package/src/duckdb/ub_src_function_aggregate_distributive.cpp +2 -0
  119. package/src/duckdb/ub_src_function_scalar_bit.cpp +2 -0
  120. package/src/duckdb/ub_src_function_scalar_map.cpp +4 -0
  121. package/src/duckdb/ub_src_main_capi.cpp +2 -0
  122. package/src/duckdb/ub_src_parser_parsed_data.cpp +4 -2
  123. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  124. package/src/duckdb/ub_src_parser_tableref.cpp +2 -0
  125. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  126. package/src/duckdb/ub_src_parser_transform_tableref.cpp +2 -0
  127. package/src/duckdb/ub_src_planner_binder_tableref.cpp +2 -0
  128. package/src/duckdb/src/include/duckdb/main/loadable_extension.hpp +0 -59
  129. package/src/duckdb/src/parser/parsed_data/alter_function_info.cpp +0 -55
@@ -12,18 +12,13 @@
12
12
  namespace duckdb {
13
13
 
14
14
  static TableCatalogEntry *GetCatalogTableEntry(LogicalOperator *op) {
15
- if (op->type == LogicalOperatorType::LOGICAL_GET) {
16
- auto get = (LogicalGet *)op;
17
- TableCatalogEntry *entry = get->GetTable();
18
- return entry;
15
+ if (!op) {
16
+ return nullptr;
19
17
  }
20
- for (auto &child : op->children) {
21
- TableCatalogEntry *entry = GetCatalogTableEntry(child.get());
22
- if (entry != nullptr) {
23
- return entry;
24
- }
25
- }
26
- return nullptr;
18
+ D_ASSERT(op->type == LogicalOperatorType::LOGICAL_GET);
19
+ auto get = (LogicalGet *)op;
20
+ TableCatalogEntry *entry = get->GetTable();
21
+ return entry;
27
22
  }
28
23
 
29
24
  // The filter was made on top of a logical sample or other projection,
@@ -304,23 +299,36 @@ static bool IsLogicalFilter(LogicalOperator *op) {
304
299
  return op->type == LogicalOperatorType::LOGICAL_FILTER;
305
300
  }
306
301
 
307
- static LogicalGet *GetLogicalGet(LogicalOperator *op) {
302
+ static LogicalGet *GetLogicalGet(LogicalOperator *op, idx_t table_index = DConstants::INVALID_INDEX) {
308
303
  LogicalGet *get = nullptr;
309
304
  switch (op->type) {
310
305
  case LogicalOperatorType::LOGICAL_GET:
311
306
  get = (LogicalGet *)op;
312
307
  break;
313
308
  case LogicalOperatorType::LOGICAL_FILTER:
314
- get = GetLogicalGet(op->children.at(0).get());
309
+ get = GetLogicalGet(op->children.at(0).get(), table_index);
315
310
  break;
316
311
  case LogicalOperatorType::LOGICAL_PROJECTION:
317
- get = GetLogicalGet(op->children.at(0).get());
312
+ get = GetLogicalGet(op->children.at(0).get(), table_index);
318
313
  break;
319
314
  case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: {
320
315
  LogicalComparisonJoin *join = (LogicalComparisonJoin *)op;
316
+ // We should never be calling GetLogicalGet without a valid table_index.
317
+ // We are attempting to get the catalog table for a relation (for statistics/cardinality estimation)
318
+ // A logical join means there is a non-reorderable relation in the join plan. This means we need
319
+ // to know the exact table index to return.
320
+ D_ASSERT(table_index != DConstants::INVALID_INDEX);
321
321
  if (join->join_type == JoinType::MARK || join->join_type == JoinType::LEFT) {
322
322
  auto child = join->children.at(0).get();
323
- get = GetLogicalGet(child);
323
+ get = GetLogicalGet(child, table_index);
324
+ if (get && get->table_index == table_index) {
325
+ return get;
326
+ }
327
+ child = join->children.at(1).get();
328
+ get = GetLogicalGet(child, table_index);
329
+ if (get && get->table_index == table_index) {
330
+ return get;
331
+ }
324
332
  }
325
333
  break;
326
334
  }
@@ -370,16 +378,17 @@ void CardinalityEstimator::InitCardinalityEstimatorProps(vector<NodeOp> *node_op
370
378
  if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) {
371
379
  auto &join = (LogicalComparisonJoin &)*op;
372
380
  if (join.join_type == JoinType::LEFT) {
373
- // TODO: inspect child operators to get a more accurate cost
374
- // and cardinality estimation. If an base op is a Logical Comparison join
375
- // it is probably a left join, so cost of the larger table is a fine
376
- // estimate
377
- // No need to update a mark join cost because I say so.
381
+ // If a base op is a Logical Comparison join it is probably a left join,
382
+ // so the cost of the larger table is a fine estimate.
383
+ // TODO: provide better estimates for cost of mark joins
384
+ // MARK joins are used for anti and semi joins, so the cost can conceivably be
385
+ // less than the base table cardinality.
378
386
  join_node->SetCost(join_node->GetBaseTableCardinality());
379
387
  }
380
388
  }
381
- // update cardinality with filters
389
+ // Total domains can be affected by filters. So we update base table cardinality first
382
390
  EstimateBaseTableCardinality(join_node, op);
391
+ // Then update total domains.
383
392
  UpdateTotalDomains(join_node, op);
384
393
  }
385
394
 
@@ -390,74 +399,84 @@ void CardinalityEstimator::InitCardinalityEstimatorProps(vector<NodeOp> *node_op
390
399
  void CardinalityEstimator::UpdateTotalDomains(JoinNode *node, LogicalOperator *op) {
391
400
  auto relation_id = node->set->relations[0];
392
401
  relation_attributes[relation_id].cardinality = node->GetCardinality<double>();
402
+ //! Initialize the distinct count for all columns used in joins with the current relation.
403
+ idx_t distinct_count = node->GetBaseTableCardinality();
393
404
  TableCatalogEntry *catalog_table = nullptr;
394
- auto get = GetLogicalGet(op);
395
- if (get) {
396
- catalog_table = GetCatalogTableEntry(get);
397
- }
398
-
399
- //! Initialize the tdoms for all columns the relation uses in join conditions.
400
- unordered_set<idx_t>::iterator ite;
401
- idx_t count = node->GetBaseTableCardinality();
402
405
 
403
406
  bool direct_filter = false;
407
+ LogicalGet *get = nullptr;
408
+ bool get_updated = true;
404
409
  for (auto &column : relation_attributes[relation_id].columns) {
405
- //! for every column in the relation, get the count via either HLL, or assume it to be
410
+ //! for every column used in a filter in the relation, get the distinct count via HLL, or assume it to be
406
411
  //! the cardinality
407
412
  ColumnBinding key = ColumnBinding(relation_id, column);
413
+ auto actual_binding = relation_column_to_original_column.find(key);
414
+ // each relation has columns that are either projected or used as filters
415
+ // In order to get column statistics we need to make sure the actual binding still
416
+ // refers to the same base table relation, as non-reorderable joins may involve 2+
417
+ // base table relations and therefore the columns may also refer to 2 different
418
+ // base table relations
419
+ if (actual_binding != relation_column_to_original_column.end() &&
420
+ (!get || get->table_index != actual_binding->second.table_index)) {
421
+ get = GetLogicalGet(op, actual_binding->second.table_index);
422
+ get_updated = true;
423
+ } else {
424
+ get_updated = false;
425
+ }
408
426
 
409
- if (catalog_table) {
410
- relation_attributes[relation_id].original_name = catalog_table->name;
411
- // Get HLL stats here
412
- auto actual_binding = relation_column_to_original_column[key];
427
+ if (get_updated) {
428
+ catalog_table = GetCatalogTableEntry(get);
429
+ }
413
430
 
414
- auto base_stats = catalog_table->GetStatistics(context, actual_binding.column_index);
431
+ if (catalog_table && actual_binding != relation_column_to_original_column.end()) {
432
+ // Get HLL stats here
433
+ auto base_stats = catalog_table->GetStatistics(context, actual_binding->second.column_index);
415
434
  if (base_stats) {
416
- count = base_stats->GetDistinctCount();
435
+ distinct_count = base_stats->GetDistinctCount();
417
436
  }
418
437
 
419
- // means you have a direct filter on a column. The count/total domain for the column
438
+ // means you have a direct filter on a column. The distinct_count/total domain for the column
420
439
  // should be decreased to match the predicted total domain matching the filter.
421
440
  // We decrease the total domain for all columns in the equivalence set because filter pushdown
422
441
  // will mean all columns are affected.
423
442
  if (direct_filter) {
424
- count = node->GetCardinality<idx_t>();
443
+ distinct_count = node->GetCardinality<idx_t>();
425
444
  }
426
445
 
427
- // HLL has estimation error, count can't be greater than cardinality of the table before filters
428
- if (count > node->GetBaseTableCardinality()) {
429
- count = node->GetBaseTableCardinality();
446
+ // HLL has estimation error, distinct_count can't be greater than cardinality of the table before filters
447
+ if (distinct_count > node->GetBaseTableCardinality()) {
448
+ distinct_count = node->GetBaseTableCardinality();
430
449
  }
431
450
  } else {
432
- // No HLL. So if we know there is a direct filter, reduce count to cardinality with filter
433
- // otherwise assume the total domain is still the cardinality
451
+ // No HLL. So if we know there is a direct filter, reduce the distinct count to the cardinality
452
+ // with filter effects. Otherwise assume the distinct count is still the cardinality
434
453
  if (direct_filter) {
435
- count = node->GetCardinality<idx_t>();
454
+ distinct_count = node->GetCardinality<idx_t>();
436
455
  } else {
437
- count = node->GetBaseTableCardinality();
456
+ distinct_count = node->GetBaseTableCardinality();
438
457
  }
439
458
  }
440
-
459
+ // Update the relation_to_tdom set with the estimated distinct count (or tdom) calculated above
441
460
  for (auto &relation_to_tdom : relations_to_tdoms) {
442
461
  column_binding_set_t i_set = relation_to_tdom.equivalent_relations;
443
462
  if (i_set.count(key) != 1) {
444
463
  continue;
445
464
  }
446
465
  if (catalog_table) {
447
- if (relation_to_tdom.tdom_hll < count) {
448
- relation_to_tdom.tdom_hll = count;
466
+ if (relation_to_tdom.tdom_hll < distinct_count) {
467
+ relation_to_tdom.tdom_hll = distinct_count;
449
468
  relation_to_tdom.has_tdom_hll = true;
450
469
  }
451
- if (relation_to_tdom.tdom_no_hll > count) {
452
- relation_to_tdom.tdom_no_hll = count;
470
+ if (relation_to_tdom.tdom_no_hll > distinct_count) {
471
+ relation_to_tdom.tdom_no_hll = distinct_count;
453
472
  }
454
473
  } else {
455
474
  // Here we don't have catalog statistics, and the following is how we determine
456
475
  // the tdom
457
476
  // 1. If there is any hll data in the equivalence set, use that
458
477
  // 2. Otherwise, use the table with the smallest cardinality
459
- if (relation_to_tdom.tdom_no_hll > count && !relation_to_tdom.has_tdom_hll) {
460
- relation_to_tdom.tdom_no_hll = count;
478
+ if (relation_to_tdom.tdom_no_hll > distinct_count && !relation_to_tdom.has_tdom_hll) {
479
+ relation_to_tdom.tdom_no_hll = distinct_count;
461
480
  }
462
481
  }
463
482
  break;
@@ -465,9 +484,8 @@ void CardinalityEstimator::UpdateTotalDomains(JoinNode *node, LogicalOperator *o
465
484
  }
466
485
  }
467
486
 
468
- TableFilterSet *CardinalityEstimator::GetTableFilters(LogicalOperator *op) {
469
- // First check table filters
470
- auto get = GetLogicalGet(op);
487
+ TableFilterSet *CardinalityEstimator::GetTableFilters(LogicalOperator *op, idx_t table_index) {
488
+ auto get = GetLogicalGet(op, table_index);
471
489
  return get ? &get->table_filters : nullptr;
472
490
  }
473
491
 
@@ -529,9 +547,10 @@ idx_t CardinalityEstimator::InspectConjunctionOR(idx_t cardinality, idx_t column
529
547
  return cardinality_after_filters;
530
548
  }
531
549
 
532
- idx_t CardinalityEstimator::InspectTableFilters(idx_t cardinality, LogicalOperator *op, TableFilterSet *table_filters) {
550
+ idx_t CardinalityEstimator::InspectTableFilters(idx_t cardinality, LogicalOperator *op, TableFilterSet *table_filters,
551
+ idx_t table_index) {
533
552
  idx_t cardinality_after_filters = cardinality;
534
- auto get = GetLogicalGet(op);
553
+ auto get = GetLogicalGet(op, table_index);
535
554
  unique_ptr<BaseStatistics> column_statistics;
536
555
  for (auto &it : table_filters->filters) {
537
556
  column_statistics = nullptr;
@@ -562,17 +581,30 @@ idx_t CardinalityEstimator::InspectTableFilters(idx_t cardinality, LogicalOperat
562
581
 
563
582
  void CardinalityEstimator::EstimateBaseTableCardinality(JoinNode *node, LogicalOperator *op) {
564
583
  auto has_logical_filter = IsLogicalFilter(op);
565
- auto table_filters = GetTableFilters(op);
584
+ D_ASSERT(node->set->count == 1);
585
+ auto relation_id = node->set->relations[0];
566
586
 
567
- auto card_after_filters = node->GetBaseTableCardinality();
568
- if (table_filters) {
569
- double inspect_result = (double)InspectTableFilters(card_after_filters, op, table_filters);
570
- card_after_filters = MinValue(inspect_result, (double)card_after_filters);
571
- }
572
- if (has_logical_filter) {
573
- card_after_filters *= DEFAULT_SELECTIVITY;
587
+ double lowest_card_found = NumericLimits<double>::Maximum();
588
+ for (auto &column : relation_attributes[relation_id].columns) {
589
+ auto card_after_filters = node->GetBaseTableCardinality();
590
+ ColumnBinding key = ColumnBinding(relation_id, column);
591
+ TableFilterSet *table_filters = nullptr;
592
+ auto actual_binding = relation_column_to_original_column.find(key);
593
+ if (actual_binding != relation_column_to_original_column.end()) {
594
+ table_filters = GetTableFilters(op, actual_binding->second.table_index);
595
+ }
596
+
597
+ if (table_filters) {
598
+ double inspect_result =
599
+ (double)InspectTableFilters(card_after_filters, op, table_filters, actual_binding->second.table_index);
600
+ card_after_filters = MinValue(inspect_result, (double)card_after_filters);
601
+ }
602
+ if (has_logical_filter) {
603
+ card_after_filters *= DEFAULT_SELECTIVITY;
604
+ }
605
+ lowest_card_found = MinValue(card_after_filters, lowest_card_found);
574
606
  }
575
- node->SetEstimatedCardinality(card_after_filters);
607
+ node->SetEstimatedCardinality(lowest_card_found);
576
608
  }
577
609
 
578
610
  } // namespace duckdb
@@ -152,7 +152,7 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<
152
152
  // new NULL values in the right side, so pushing this condition through the join leads to incorrect results
153
153
  // for this reason, we just start a new JoinOptimizer pass in each of the children of the join
154
154
 
155
- // Keep track of all of the filter bindings the new join order optimizer makes
155
+ // Keep track of all filter bindings the new join order optimizer makes
156
156
  vector<column_binding_map_t<ColumnBinding>> child_binding_maps;
157
157
  idx_t child_bindings_it = 0;
158
158
  for (auto &child : op->children) {
@@ -222,12 +222,25 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<
222
222
  }
223
223
  case LogicalOperatorType::LOGICAL_PROJECTION: {
224
224
  auto proj = (LogicalProjection *)op;
225
- // we run the join order optimizer witin the subquery as well
225
+ // we run the join order optimizer within the subquery as well
226
226
  JoinOrderOptimizer optimizer(context);
227
227
  op->children[0] = optimizer.Optimize(std::move(op->children[0]));
228
228
  // projection, add to the set of relations
229
229
  auto relation = make_unique<SingleJoinRelation>(&input_op, parent);
230
- relation_mapping[proj->table_index] = relations.size();
230
+ auto relation_id = relations.size();
231
+ // push one child column binding map back.
232
+ vector<column_binding_map_t<ColumnBinding>> child_binding_maps;
233
+ child_binding_maps.emplace_back(column_binding_map_t<ColumnBinding>());
234
+ optimizer.cardinality_estimator.CopyRelationMap(child_binding_maps.at(0));
235
+ // This logical projection may sit on top of a logical comparison join that has been pushed down
236
+ // we want to copy the binding info of both tables
237
+ relation_mapping[proj->table_index] = relation_id;
238
+ for (auto &binding_info : child_binding_maps.at(0)) {
239
+ cardinality_estimator.AddRelationToColumnMapping(
240
+ ColumnBinding(proj->table_index, binding_info.first.column_index), binding_info.second);
241
+ cardinality_estimator.AddColumnToRelationMap(binding_info.second.table_index,
242
+ binding_info.second.column_index);
243
+ }
231
244
  relations.push_back(std::move(relation));
232
245
  return true;
233
246
  }
@@ -1,6 +1,7 @@
1
1
  #include "duckdb/parser/parsed_data/alter_info.hpp"
2
2
  #include "duckdb/parser/parsed_data/alter_table_info.hpp"
3
- #include "duckdb/parser/parsed_data/alter_function_info.hpp"
3
+ #include "duckdb/parser/parsed_data/alter_scalar_function_info.hpp"
4
+ #include "duckdb/parser/parsed_data/alter_table_function_info.hpp"
4
5
 
5
6
  #include "duckdb/common/field_writer.hpp"
6
7
 
@@ -33,8 +34,11 @@ unique_ptr<AlterInfo> AlterInfo::Deserialize(Deserializer &source) {
33
34
  case AlterType::ALTER_VIEW:
34
35
  result = AlterViewInfo::Deserialize(reader);
35
36
  break;
36
- case AlterType::ALTER_FUNCTION:
37
- result = AlterFunctionInfo::Deserialize(reader);
37
+ case AlterType::ALTER_SCALAR_FUNCTION:
38
+ result = AlterScalarFunctionInfo::Deserialize(reader);
39
+ break;
40
+ case AlterType::ALTER_TABLE_FUNCTION:
41
+ result = AlterTableFunctionInfo::Deserialize(reader);
38
42
  break;
39
43
  default:
40
44
  throw SerializationException("Unknown alter type for deserialization!");
@@ -0,0 +1,56 @@
1
+ #include "duckdb/parser/parsed_data/alter_scalar_function_info.hpp"
2
+
3
+ #include "duckdb/common/field_writer.hpp"
4
+ #include "duckdb/parser/constraint.hpp"
5
+
6
+ namespace duckdb {
7
+
8
+ //===--------------------------------------------------------------------===//
9
+ // AlterScalarFunctionInfo
10
+ //===--------------------------------------------------------------------===//
11
+ AlterScalarFunctionInfo::AlterScalarFunctionInfo(AlterScalarFunctionType type, AlterEntryData data)
12
+ : AlterInfo(AlterType::ALTER_SCALAR_FUNCTION, std::move(data.catalog), std::move(data.schema), std::move(data.name),
13
+ data.if_exists),
14
+ alter_scalar_function_type(type) {
15
+ }
16
+ AlterScalarFunctionInfo::~AlterScalarFunctionInfo() {
17
+ }
18
+
19
+ CatalogType AlterScalarFunctionInfo::GetCatalogType() const {
20
+ return CatalogType::SCALAR_FUNCTION_ENTRY;
21
+ }
22
+
23
+ void AlterScalarFunctionInfo::Serialize(FieldWriter &writer) const {
24
+ writer.WriteField<AlterScalarFunctionType>(alter_scalar_function_type);
25
+ writer.WriteString(catalog);
26
+ writer.WriteString(schema);
27
+ writer.WriteString(name);
28
+ writer.WriteField(if_exists);
29
+ }
30
+
31
+ unique_ptr<AlterInfo> AlterScalarFunctionInfo::Deserialize(FieldReader &reader) {
32
+ // auto type = reader.ReadRequired<AlterScalarFunctionType>();
33
+ // auto schema = reader.ReadRequired<string>();
34
+ // auto table = reader.ReadRequired<string>();
35
+ // auto if_exists = reader.ReadRequired<bool>();
36
+
37
+ throw NotImplementedException("AlterScalarFunctionInfo cannot be deserialized");
38
+ }
39
+
40
+ //===--------------------------------------------------------------------===//
41
+ // AddScalarFunctionOverloadInfo
42
+ //===--------------------------------------------------------------------===//
43
+ AddScalarFunctionOverloadInfo::AddScalarFunctionOverloadInfo(AlterEntryData data, ScalarFunctionSet new_overloads_p)
44
+ : AlterScalarFunctionInfo(AlterScalarFunctionType::ADD_FUNCTION_OVERLOADS, std::move(data)),
45
+ new_overloads(std::move(new_overloads_p)) {
46
+ this->allow_internal = true;
47
+ }
48
+
49
+ AddScalarFunctionOverloadInfo::~AddScalarFunctionOverloadInfo() {
50
+ }
51
+
52
+ unique_ptr<AlterInfo> AddScalarFunctionOverloadInfo::Copy() const {
53
+ return make_unique_base<AlterInfo, AddScalarFunctionOverloadInfo>(GetAlterEntryData(), new_overloads);
54
+ }
55
+
56
+ } // namespace duckdb
@@ -0,0 +1,51 @@
1
+ #include "duckdb/parser/parsed_data/alter_table_function_info.hpp"
2
+
3
+ #include "duckdb/common/field_writer.hpp"
4
+ #include "duckdb/parser/constraint.hpp"
5
+
6
+ namespace duckdb {
7
+
8
+ //===--------------------------------------------------------------------===//
9
+ // AlterTableFunctionInfo
10
+ //===--------------------------------------------------------------------===//
11
+ AlterTableFunctionInfo::AlterTableFunctionInfo(AlterTableFunctionType type, AlterEntryData data)
12
+ : AlterInfo(AlterType::ALTER_TABLE_FUNCTION, std::move(data.catalog), std::move(data.schema), std::move(data.name),
13
+ data.if_exists),
14
+ alter_table_function_type(type) {
15
+ }
16
+ AlterTableFunctionInfo::~AlterTableFunctionInfo() {
17
+ }
18
+
19
+ CatalogType AlterTableFunctionInfo::GetCatalogType() const {
20
+ return CatalogType::TABLE_FUNCTION_ENTRY;
21
+ }
22
+
23
+ void AlterTableFunctionInfo::Serialize(FieldWriter &writer) const {
24
+ writer.WriteField<AlterTableFunctionType>(alter_table_function_type);
25
+ writer.WriteString(catalog);
26
+ writer.WriteString(schema);
27
+ writer.WriteString(name);
28
+ writer.WriteField(if_exists);
29
+ }
30
+
31
+ unique_ptr<AlterInfo> AlterTableFunctionInfo::Deserialize(FieldReader &reader) {
32
+ throw NotImplementedException("AlterTableFunctionInfo cannot be deserialized");
33
+ }
34
+
35
+ //===--------------------------------------------------------------------===//
36
+ // AddTableFunctionOverloadInfo
37
+ //===--------------------------------------------------------------------===//
38
+ AddTableFunctionOverloadInfo::AddTableFunctionOverloadInfo(AlterEntryData data, TableFunctionSet new_overloads_p)
39
+ : AlterTableFunctionInfo(AlterTableFunctionType::ADD_FUNCTION_OVERLOADS, std::move(data)),
40
+ new_overloads(std::move(new_overloads_p)) {
41
+ this->allow_internal = true;
42
+ }
43
+
44
+ AddTableFunctionOverloadInfo::~AddTableFunctionOverloadInfo() {
45
+ }
46
+
47
+ unique_ptr<AlterInfo> AddTableFunctionOverloadInfo::Copy() const {
48
+ return make_unique_base<AlterInfo, AddTableFunctionOverloadInfo>(GetAlterEntryData(), new_overloads);
49
+ }
50
+
51
+ } // namespace duckdb
@@ -1,5 +1,5 @@
1
1
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
2
- #include "duckdb/parser/parsed_data/alter_function_info.hpp"
2
+ #include "duckdb/parser/parsed_data/alter_scalar_function_info.hpp"
3
3
 
4
4
  namespace duckdb {
5
5
 
@@ -27,7 +27,8 @@ unique_ptr<CreateInfo> CreateScalarFunctionInfo::Copy() const {
27
27
  }
28
28
 
29
29
  unique_ptr<AlterInfo> CreateScalarFunctionInfo::GetAlterInfo() const {
30
- return make_unique_base<AlterInfo, AddFunctionOverloadInfo>(AlterEntryData(catalog, schema, name, true), functions);
30
+ return make_unique_base<AlterInfo, AddScalarFunctionOverloadInfo>(AlterEntryData(catalog, schema, name, true),
31
+ functions);
31
32
  }
32
33
 
33
34
  } // namespace duckdb
@@ -1,4 +1,5 @@
1
1
  #include "duckdb/parser/parsed_data/create_table_function_info.hpp"
2
+ #include "duckdb/parser/parsed_data/alter_table_function_info.hpp"
2
3
 
3
4
  namespace duckdb {
4
5
 
@@ -25,4 +26,9 @@ unique_ptr<CreateInfo> CreateTableFunctionInfo::Copy() const {
25
26
  return std::move(result);
26
27
  }
27
28
 
29
+ unique_ptr<AlterInfo> CreateTableFunctionInfo::GetAlterInfo() const {
30
+ return make_unique_base<AlterInfo, AddTableFunctionOverloadInfo>(AlterEntryData(catalog, schema, name, true),
31
+ functions);
32
+ }
33
+
28
34
  } // namespace duckdb
@@ -213,6 +213,14 @@ void ParsedExpressionIterator::EnumerateTableRefChildren(
213
213
  }
214
214
  break;
215
215
  }
216
+ case TableReferenceType::PIVOT: {
217
+ auto &p_ref = (PivotRef &)ref;
218
+ EnumerateTableRefChildren(*p_ref.source, callback);
219
+ for (auto &aggr : p_ref.aggregates) {
220
+ callback(aggr);
221
+ }
222
+ break;
223
+ }
216
224
  case TableReferenceType::SUBQUERY: {
217
225
  auto &sq_ref = (SubqueryRef &)ref;
218
226
  EnumerateQueryNodeChildren(*sq_ref.subquery->node, callback);
@@ -174,7 +174,7 @@ unique_ptr<QueryNode> QueryNode::Deserialize(Deserializer &main_source) {
174
174
  // cte_map
175
175
  auto cte_count = reader.ReadRequired<uint32_t>();
176
176
  auto &source = reader.GetSource();
177
- unordered_map<string, unique_ptr<CommonTableExpressionInfo>> new_map;
177
+ case_insensitive_map_t<unique_ptr<CommonTableExpressionInfo>> new_map;
178
178
  for (idx_t i = 0; i < cte_count; i++) {
179
179
  auto name = source.Read<string>();
180
180
  auto info = make_unique<CommonTableExpressionInfo>();
@@ -0,0 +1,18 @@
1
+ #include "duckdb/parser/statement/multi_statement.hpp"
2
+
3
+ namespace duckdb {
4
+
5
+ MultiStatement::MultiStatement() : SQLStatement(StatementType::MULTI_STATEMENT) {
6
+ }
7
+
8
+ MultiStatement::MultiStatement(const MultiStatement &other) : SQLStatement(other) {
9
+ for (auto &stmt : other.statements) {
10
+ statements.push_back(stmt->Copy());
11
+ }
12
+ }
13
+
14
+ unique_ptr<SQLStatement> MultiStatement::Copy() const {
15
+ return unique_ptr<MultiStatement>(new MultiStatement(*this));
16
+ }
17
+
18
+ } // namespace duckdb