duckdb 0.7.2-dev14.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.
- package/binding.gyp +2 -0
- package/package.json +1 -1
- package/src/duckdb/extension/icu/icu-extension.cpp +2 -0
- package/src/duckdb/extension/icu/icu-table-range.cpp +194 -0
- package/src/duckdb/extension/icu/include/icu-table-range.hpp +17 -0
- package/src/duckdb/extension/parquet/column_writer.cpp +0 -1
- package/src/duckdb/extension/parquet/parquet-extension.cpp +11 -2
- package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +4 -0
- package/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp +7 -6
- package/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp +20 -1
- package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
- package/src/duckdb/src/common/types/bit.cpp +95 -58
- package/src/duckdb/src/common/types/value.cpp +149 -53
- package/src/duckdb/src/common/types/vector.cpp +13 -10
- package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
- package/src/duckdb/src/function/aggregate/algebraic/avg.cpp +0 -6
- package/src/duckdb/src/function/aggregate/distributive/bitagg.cpp +99 -95
- package/src/duckdb/src/function/aggregate/distributive/bitstring_agg.cpp +261 -0
- package/src/duckdb/src/function/aggregate/distributive/sum.cpp +0 -3
- package/src/duckdb/src/function/aggregate/distributive_functions.cpp +1 -0
- package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +16 -5
- package/src/duckdb/src/function/cast/bit_cast.cpp +0 -2
- package/src/duckdb/src/function/cast/blob_cast.cpp +0 -1
- package/src/duckdb/src/function/scalar/bit/bitstring.cpp +99 -0
- package/src/duckdb/src/function/scalar/map/map_entries.cpp +61 -0
- package/src/duckdb/src/function/scalar/map/map_keys_values.cpp +97 -0
- package/src/duckdb/src/function/scalar/nested_functions.cpp +3 -0
- package/src/duckdb/src/function/scalar/operators/add.cpp +0 -9
- package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +2 -14
- package/src/duckdb/src/function/scalar/operators/bitwise.cpp +0 -63
- package/src/duckdb/src/function/scalar/operators/multiply.cpp +0 -6
- package/src/duckdb/src/function/scalar/operators/subtract.cpp +0 -6
- package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
- package/src/duckdb/src/function/table/read_csv.cpp +9 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/function/table_function.cpp +19 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +6 -8
- package/src/duckdb/src/include/duckdb/common/constants.hpp +0 -19
- package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/enums/tableref_type.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/types/bit.hpp +5 -1
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +2 -8
- package/src/duckdb/src/include/duckdb/common/types.hpp +1 -2
- package/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp +5 -0
- package/src/duckdb/src/include/duckdb/function/scalar/bit_functions.hpp +4 -0
- package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +12 -0
- package/src/duckdb/src/include/duckdb/function/table_function.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/config.hpp +3 -0
- package/src/duckdb/src/include/duckdb/main/database.hpp +1 -0
- package/src/duckdb/src/include/duckdb/optimizer/join_order/cardinality_estimator.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/common_table_expression_info.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/{alter_function_info.hpp → alter_scalar_function_info.hpp} +13 -13
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_function_info.hpp +47 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_table_function_info.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/query_node.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/statement/multi_statement.hpp +28 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +76 -0
- package/src/duckdb/src/include/duckdb/parser/tokens.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +28 -0
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +8 -0
- package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +76 -44
- package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/statistics/node_statistics.hpp +26 -0
- package/src/duckdb/src/include/duckdb/storage/table/list_column_data.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +2 -0
- package/src/duckdb/src/include/duckdb.h +49 -1
- package/src/duckdb/src/include/duckdb.hpp +0 -1
- package/src/duckdb/src/main/capi/pending-c.cpp +16 -3
- package/src/duckdb/src/main/capi/result-c.cpp +27 -1
- package/src/duckdb/src/main/capi/stream-c.cpp +25 -0
- package/src/duckdb/src/main/client_context.cpp +8 -1
- package/src/duckdb/src/main/database.cpp +10 -2
- package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +98 -66
- package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +16 -3
- package/src/duckdb/src/parser/parsed_data/alter_info.cpp +7 -3
- package/src/duckdb/src/parser/parsed_data/alter_scalar_function_info.cpp +56 -0
- package/src/duckdb/src/parser/parsed_data/alter_table_function_info.cpp +51 -0
- package/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp +3 -2
- package/src/duckdb/src/parser/parsed_data/create_table_function_info.cpp +6 -0
- package/src/duckdb/src/parser/parsed_expression_iterator.cpp +8 -0
- package/src/duckdb/src/parser/query_node.cpp +1 -1
- package/src/duckdb/src/parser/statement/multi_statement.cpp +18 -0
- package/src/duckdb/src/parser/tableref/pivotref.cpp +296 -0
- package/src/duckdb/src/parser/tableref.cpp +3 -0
- package/src/duckdb/src/parser/transform/helpers/transform_alias.cpp +12 -6
- package/src/duckdb/src/parser/transform/helpers/transform_cte.cpp +24 -0
- package/src/duckdb/src/parser/transform/statement/transform_create_function.cpp +4 -0
- package/src/duckdb/src/parser/transform/statement/transform_create_view.cpp +4 -0
- package/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +150 -0
- package/src/duckdb/src/parser/transform/statement/transform_select.cpp +8 -0
- package/src/duckdb/src/parser/transform/statement/transform_select_node.cpp +1 -1
- package/src/duckdb/src/parser/transform/tableref/transform_pivot.cpp +105 -0
- package/src/duckdb/src/parser/transform/tableref/transform_tableref.cpp +2 -0
- package/src/duckdb/src/parser/transformer.cpp +15 -3
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +11 -3
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +1 -1
- package/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp +17 -0
- package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +365 -0
- package/src/duckdb/src/planner/binder.cpp +5 -0
- package/src/duckdb/src/planner/pragma_handler.cpp +10 -2
- package/src/duckdb/src/storage/buffer_manager.cpp +44 -46
- package/src/duckdb/src/storage/compression/bitpacking.cpp +25 -21
- package/src/duckdb/src/storage/compression/fixed_size_uncompressed.cpp +41 -43
- package/src/duckdb/src/storage/compression/rle.cpp +17 -13
- package/src/duckdb/src/storage/statistics/base_statistics.cpp +3 -3
- package/src/duckdb/src/storage/storage_info.cpp +1 -1
- package/src/duckdb/src/storage/table/column_data.cpp +5 -2
- package/src/duckdb/src/storage/table/list_column_data.cpp +32 -47
- package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +3 -0
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +34 -1
- package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +1016 -530
- package/src/duckdb/third_party/libpg_query/include/parser/kwlist.hpp +5 -0
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +22697 -21987
- package/src/duckdb/ub_src_function_aggregate_distributive.cpp +2 -0
- package/src/duckdb/ub_src_function_scalar_bit.cpp +2 -0
- package/src/duckdb/ub_src_function_scalar_map.cpp +4 -0
- package/src/duckdb/ub_src_main_capi.cpp +2 -0
- package/src/duckdb/ub_src_parser_parsed_data.cpp +4 -2
- package/src/duckdb/ub_src_parser_statement.cpp +2 -0
- package/src/duckdb/ub_src_parser_tableref.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_tableref.cpp +2 -0
- package/src/duckdb/ub_src_planner_binder_tableref.cpp +2 -0
- package/src/duckdb/src/include/duckdb/main/loadable_extension.hpp +0 -59
- 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
|
16
|
-
|
17
|
-
TableCatalogEntry *entry = get->GetTable();
|
18
|
-
return entry;
|
15
|
+
if (!op) {
|
16
|
+
return nullptr;
|
19
17
|
}
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
//
|
374
|
-
//
|
375
|
-
//
|
376
|
-
//
|
377
|
-
//
|
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
|
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
|
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 (
|
410
|
-
|
411
|
-
|
412
|
-
auto actual_binding = relation_column_to_original_column[key];
|
427
|
+
if (get_updated) {
|
428
|
+
catalog_table = GetCatalogTableEntry(get);
|
429
|
+
}
|
413
430
|
|
414
|
-
|
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
|
-
|
435
|
+
distinct_count = base_stats->GetDistinctCount();
|
417
436
|
}
|
418
437
|
|
419
|
-
// means you have a direct filter on a column. The
|
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
|
-
|
443
|
+
distinct_count = node->GetCardinality<idx_t>();
|
425
444
|
}
|
426
445
|
|
427
|
-
// HLL has estimation error,
|
428
|
-
if (
|
429
|
-
|
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
|
433
|
-
//
|
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
|
-
|
454
|
+
distinct_count = node->GetCardinality<idx_t>();
|
436
455
|
} else {
|
437
|
-
|
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 <
|
448
|
-
relation_to_tdom.tdom_hll =
|
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 >
|
452
|
-
relation_to_tdom.tdom_no_hll =
|
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 >
|
460
|
-
relation_to_tdom.tdom_no_hll =
|
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
|
-
|
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
|
-
|
584
|
+
D_ASSERT(node->set->count == 1);
|
585
|
+
auto relation_id = node->set->relations[0];
|
566
586
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
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(
|
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
|
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
|
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
|
-
|
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/
|
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::
|
37
|
-
result =
|
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/
|
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,
|
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
|
-
|
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
|