duckdb 0.3.5-dev593.0 → 0.3.5-dev604.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/package.json +1 -1
- package/src/duckdb.cpp +339 -230
- package/src/duckdb.hpp +2 -2
- package/src/parquet-amalgamation.cpp +27949 -27949
package/src/duckdb.cpp
CHANGED
|
@@ -4681,6 +4681,7 @@ CatalogEntry *CatalogSet::CreateEntryInternal(ClientContext &context, unique_ptr
|
|
|
4681
4681
|
auto entry_index = current_entry++;
|
|
4682
4682
|
auto catalog_entry = entry.get();
|
|
4683
4683
|
|
|
4684
|
+
entry->set = this;
|
|
4684
4685
|
entry->timestamp = 0;
|
|
4685
4686
|
|
|
4686
4687
|
PutMapping(context, name, entry_index);
|
|
@@ -5376,6 +5377,9 @@ void DependencyManager::AddObject(ClientContext &context, CatalogEntry *object,
|
|
|
5376
5377
|
for (auto &dependency : dependencies) {
|
|
5377
5378
|
idx_t entry_index;
|
|
5378
5379
|
CatalogEntry *catalog_entry;
|
|
5380
|
+
if (!dependency->set) {
|
|
5381
|
+
throw InternalException("Dependency has no set");
|
|
5382
|
+
}
|
|
5379
5383
|
if (!dependency->set->GetEntryInternal(context, dependency->name, entry_index, catalog_entry)) {
|
|
5380
5384
|
throw InternalException("Dependency has already been deleted?");
|
|
5381
5385
|
}
|
|
@@ -38514,11 +38518,39 @@ bool ChunkCollection::Equals(ChunkCollection &other) {
|
|
|
38514
38518
|
if (ColumnCount() != other.ColumnCount()) {
|
|
38515
38519
|
return false;
|
|
38516
38520
|
}
|
|
38517
|
-
//
|
|
38521
|
+
// first try to compare the results as-is
|
|
38522
|
+
bool compare_equals = true;
|
|
38518
38523
|
for (idx_t row_idx = 0; row_idx < count; row_idx++) {
|
|
38519
38524
|
for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
|
|
38520
38525
|
auto lvalue = GetValue(col_idx, row_idx);
|
|
38521
38526
|
auto rvalue = other.GetValue(col_idx, row_idx);
|
|
38527
|
+
if (!Value::ValuesAreEqual(lvalue, rvalue)) {
|
|
38528
|
+
compare_equals = false;
|
|
38529
|
+
break;
|
|
38530
|
+
}
|
|
38531
|
+
}
|
|
38532
|
+
if (!compare_equals) {
|
|
38533
|
+
break;
|
|
38534
|
+
}
|
|
38535
|
+
}
|
|
38536
|
+
if (compare_equals) {
|
|
38537
|
+
return true;
|
|
38538
|
+
}
|
|
38539
|
+
// if the results are not equal,
|
|
38540
|
+
// sort both chunk collections to ensure the comparison is not order insensitive
|
|
38541
|
+
vector<OrderType> desc(ColumnCount(), OrderType::DESCENDING);
|
|
38542
|
+
vector<OrderByNullType> null_order(ColumnCount(), OrderByNullType::NULLS_FIRST);
|
|
38543
|
+
auto this_order = unique_ptr<idx_t[]>(new idx_t[count]);
|
|
38544
|
+
auto other_order = unique_ptr<idx_t[]>(new idx_t[count]);
|
|
38545
|
+
Sort(desc, null_order, this_order.get());
|
|
38546
|
+
other.Sort(desc, null_order, other_order.get());
|
|
38547
|
+
|
|
38548
|
+
for (idx_t row_idx = 0; row_idx < count; row_idx++) {
|
|
38549
|
+
auto lrow = this_order[row_idx];
|
|
38550
|
+
auto rrow = other_order[row_idx];
|
|
38551
|
+
for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
|
|
38552
|
+
auto lvalue = GetValue(col_idx, lrow);
|
|
38553
|
+
auto rvalue = other.GetValue(col_idx, rrow);
|
|
38522
38554
|
if (!Value::ValuesAreEqual(lvalue, rvalue)) {
|
|
38523
38555
|
return false;
|
|
38524
38556
|
}
|
|
@@ -112991,6 +113023,7 @@ private:
|
|
|
112991
113023
|
|
|
112992
113024
|
|
|
112993
113025
|
|
|
113026
|
+
|
|
112994
113027
|
namespace duckdb {
|
|
112995
113028
|
|
|
112996
113029
|
struct ActiveQueryContext {
|
|
@@ -113698,14 +113731,16 @@ void ClientContext::DisableProfiling() {
|
|
|
113698
113731
|
}
|
|
113699
113732
|
|
|
113700
113733
|
struct VerifyStatement {
|
|
113701
|
-
VerifyStatement(unique_ptr<SelectStatement> statement_p, string statement_name_p, bool require_equality = true
|
|
113734
|
+
VerifyStatement(unique_ptr<SelectStatement> statement_p, string statement_name_p, bool require_equality = true,
|
|
113735
|
+
bool disable_optimizer = false)
|
|
113702
113736
|
: statement(move(statement_p)), statement_name(move(statement_name_p)), require_equality(require_equality),
|
|
113703
|
-
select_list(statement->node->GetSelectList()) {
|
|
113737
|
+
disable_optimizer(disable_optimizer), select_list(statement->node->GetSelectList()) {
|
|
113704
113738
|
}
|
|
113705
113739
|
|
|
113706
113740
|
unique_ptr<SelectStatement> statement;
|
|
113707
113741
|
string statement_name;
|
|
113708
113742
|
bool require_equality;
|
|
113743
|
+
bool disable_optimizer;
|
|
113709
113744
|
const vector<unique_ptr<ParsedExpression>> &select_list;
|
|
113710
113745
|
};
|
|
113711
113746
|
|
|
@@ -113733,8 +113768,9 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113733
113768
|
BufferedDeserializer source(serializer);
|
|
113734
113769
|
auto deserialized_stmt = SelectStatement::Deserialize(source);
|
|
113735
113770
|
|
|
113771
|
+
auto query_str = select_stmt->ToString();
|
|
113736
113772
|
Parser parser;
|
|
113737
|
-
parser.ParseQuery(
|
|
113773
|
+
parser.ParseQuery(query_str);
|
|
113738
113774
|
D_ASSERT(parser.statements.size() == 1);
|
|
113739
113775
|
D_ASSERT(parser.statements[0]->type == StatementType::SELECT_STATEMENT);
|
|
113740
113776
|
auto parsed_statement = move(parser.statements[0]);
|
|
@@ -113745,6 +113781,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113745
113781
|
verify_statements.emplace_back(move(deserialized_stmt), "Deserialized statement");
|
|
113746
113782
|
verify_statements.emplace_back(unique_ptr_cast<SQLStatement, SelectStatement>(move(parsed_statement)),
|
|
113747
113783
|
"Parsed statement", false);
|
|
113784
|
+
verify_statements.emplace_back(unique_ptr_cast<SQLStatement, SelectStatement>(move(unoptimized_stmt)),
|
|
113785
|
+
"Unoptimized", true, true);
|
|
113748
113786
|
|
|
113749
113787
|
// all the statements should be equal
|
|
113750
113788
|
for (idx_t i = 1; i < verify_statements.size(); i++) {
|
|
@@ -113809,9 +113847,11 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113809
113847
|
auto statement_copy_for_explain = select_stmt->Copy();
|
|
113810
113848
|
|
|
113811
113849
|
// execute the original statement
|
|
113850
|
+
auto optimizer_enabled = config.enable_optimizer;
|
|
113812
113851
|
vector<unique_ptr<MaterializedQueryResult>> results;
|
|
113813
113852
|
for (idx_t i = 0; i < verify_statements.size(); i++) {
|
|
113814
113853
|
interrupted = false;
|
|
113854
|
+
config.enable_optimizer = !verify_statements[i].disable_optimizer;
|
|
113815
113855
|
try {
|
|
113816
113856
|
auto result = RunStatementInternal(lock, query, move(verify_statements[i].statement), false, false);
|
|
113817
113857
|
results.push_back(unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result)));
|
|
@@ -113819,6 +113859,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113819
113859
|
results.push_back(make_unique<MaterializedQueryResult>(ex.what()));
|
|
113820
113860
|
}
|
|
113821
113861
|
}
|
|
113862
|
+
config.enable_optimizer = optimizer_enabled;
|
|
113822
113863
|
|
|
113823
113864
|
// check explain, only if q does not already contain EXPLAIN
|
|
113824
113865
|
if (results[0]->success) {
|
|
@@ -113831,8 +113872,6 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113831
113872
|
} // LCOV_EXCL_STOP
|
|
113832
113873
|
}
|
|
113833
113874
|
|
|
113834
|
-
config.enable_optimizer = true;
|
|
113835
|
-
|
|
113836
113875
|
if (profiling_is_enabled) {
|
|
113837
113876
|
config.enable_profiler = true;
|
|
113838
113877
|
}
|
|
@@ -129547,37 +129586,37 @@ private:
|
|
|
129547
129586
|
Expression *GetNode(Expression *expr);
|
|
129548
129587
|
idx_t GetEquivalenceSet(Expression *expr);
|
|
129549
129588
|
FilterResult AddConstantComparison(vector<ExpressionValueInformation> &info_list, ExpressionValueInformation info);
|
|
129550
|
-
|
|
129551
|
-
//! Functions used to push and generate OR Filters
|
|
129552
|
-
void LookUpConjunctions(Expression *expr);
|
|
129553
|
-
bool BFSLookUpConjunctions(BoundConjunctionExpression *conjunction);
|
|
129554
|
-
void VerifyOrsToPush(Expression &expr);
|
|
129555
|
-
|
|
129556
|
-
bool UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr);
|
|
129557
|
-
bool UpdateFilterByColumn(BoundColumnRefExpression *column_ref, BoundComparisonExpression *comparison_expr);
|
|
129558
|
-
void GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids);
|
|
129559
|
-
|
|
129560
|
-
template <typename CONJUNCTION_TYPE>
|
|
129561
|
-
void GenerateConjunctionFilter(BoundConjunctionExpression *conjunction, ConjunctionFilter *last_conj_filter) {
|
|
129562
|
-
auto new_filter = NextConjunctionFilter<CONJUNCTION_TYPE>(conjunction);
|
|
129563
|
-
auto conj_filter_ptr = (ConjunctionFilter *)new_filter.get();
|
|
129564
|
-
last_conj_filter->child_filters.push_back(move(new_filter));
|
|
129565
|
-
last_conj_filter = conj_filter_ptr;
|
|
129566
|
-
}
|
|
129567
|
-
|
|
129568
|
-
template <typename CONJUNCTION_TYPE>
|
|
129569
|
-
unique_ptr<TableFilter> NextConjunctionFilter(BoundConjunctionExpression *conjunction) {
|
|
129570
|
-
unique_ptr<ConjunctionFilter> conj_filter = make_unique<CONJUNCTION_TYPE>();
|
|
129571
|
-
for (auto &expr : conjunction->children) {
|
|
129572
|
-
auto comp_expr = (BoundComparisonExpression *)expr.get();
|
|
129573
|
-
auto &const_expr =
|
|
129574
|
-
(comp_expr->left->type == ExpressionType::VALUE_CONSTANT) ? *comp_expr->left : *comp_expr->right;
|
|
129575
|
-
auto const_value = ExpressionExecutor::EvaluateScalar(const_expr);
|
|
129576
|
-
auto const_filter = make_unique<ConstantFilter>(comp_expr->type, const_value);
|
|
129577
|
-
conj_filter->child_filters.push_back(move(const_filter));
|
|
129578
|
-
}
|
|
129579
|
-
return move(conj_filter);
|
|
129580
|
-
}
|
|
129589
|
+
//
|
|
129590
|
+
// //! Functions used to push and generate OR Filters
|
|
129591
|
+
// void LookUpConjunctions(Expression *expr);
|
|
129592
|
+
// bool BFSLookUpConjunctions(BoundConjunctionExpression *conjunction);
|
|
129593
|
+
// void VerifyOrsToPush(Expression &expr);
|
|
129594
|
+
//
|
|
129595
|
+
// bool UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr);
|
|
129596
|
+
// bool UpdateFilterByColumn(BoundColumnRefExpression *column_ref, BoundComparisonExpression *comparison_expr);
|
|
129597
|
+
// void GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids);
|
|
129598
|
+
//
|
|
129599
|
+
// template <typename CONJUNCTION_TYPE>
|
|
129600
|
+
// void GenerateConjunctionFilter(BoundConjunctionExpression *conjunction, ConjunctionFilter *last_conj_filter) {
|
|
129601
|
+
// auto new_filter = NextConjunctionFilter<CONJUNCTION_TYPE>(conjunction);
|
|
129602
|
+
// auto conj_filter_ptr = (ConjunctionFilter *)new_filter.get();
|
|
129603
|
+
// last_conj_filter->child_filters.push_back(move(new_filter));
|
|
129604
|
+
// last_conj_filter = conj_filter_ptr;
|
|
129605
|
+
// }
|
|
129606
|
+
//
|
|
129607
|
+
// template <typename CONJUNCTION_TYPE>
|
|
129608
|
+
// unique_ptr<TableFilter> NextConjunctionFilter(BoundConjunctionExpression *conjunction) {
|
|
129609
|
+
// unique_ptr<ConjunctionFilter> conj_filter = make_unique<CONJUNCTION_TYPE>();
|
|
129610
|
+
// for (auto &expr : conjunction->children) {
|
|
129611
|
+
// auto comp_expr = (BoundComparisonExpression *)expr.get();
|
|
129612
|
+
// auto &const_expr =
|
|
129613
|
+
// (comp_expr->left->type == ExpressionType::VALUE_CONSTANT) ? *comp_expr->left : *comp_expr->right;
|
|
129614
|
+
// auto const_value = ExpressionExecutor::EvaluateScalar(const_expr);
|
|
129615
|
+
// auto const_filter = make_unique<ConstantFilter>(comp_expr->type, const_value);
|
|
129616
|
+
// conj_filter->child_filters.push_back(move(const_filter));
|
|
129617
|
+
// }
|
|
129618
|
+
// return move(conj_filter);
|
|
129619
|
+
// }
|
|
129581
129620
|
|
|
129582
129621
|
private:
|
|
129583
129622
|
vector<unique_ptr<Expression>> remaining_filters;
|
|
@@ -129587,26 +129626,26 @@ private:
|
|
|
129587
129626
|
unordered_map<idx_t, vector<ExpressionValueInformation>> constant_values;
|
|
129588
129627
|
unordered_map<idx_t, vector<Expression *>> equivalence_map;
|
|
129589
129628
|
idx_t set_index = 0;
|
|
129590
|
-
|
|
129591
|
-
//! Structures used for OR Filters
|
|
129592
|
-
|
|
129593
|
-
struct ConjunctionsToPush {
|
|
129594
|
-
BoundConjunctionExpression *root_or;
|
|
129595
|
-
|
|
129596
|
-
// only preserve AND if there is a single column in the expression
|
|
129597
|
-
bool preserve_and = true;
|
|
129598
|
-
|
|
129599
|
-
// conjunction chain for this column
|
|
129600
|
-
vector<unique_ptr<BoundConjunctionExpression>> conjunctions;
|
|
129601
|
-
};
|
|
129602
|
-
|
|
129603
|
-
expression_map_t<vector<unique_ptr<ConjunctionsToPush>>> map_col_conjunctions;
|
|
129604
|
-
vector<BoundColumnRefExpression *> vec_colref_insertion_order;
|
|
129605
|
-
|
|
129606
|
-
BoundConjunctionExpression *cur_root_or;
|
|
129607
|
-
BoundConjunctionExpression *cur_conjunction;
|
|
129608
|
-
|
|
129609
|
-
BoundColumnRefExpression *cur_colref_to_push;
|
|
129629
|
+
//
|
|
129630
|
+
// //! Structures used for OR Filters
|
|
129631
|
+
//
|
|
129632
|
+
// struct ConjunctionsToPush {
|
|
129633
|
+
// BoundConjunctionExpression *root_or;
|
|
129634
|
+
//
|
|
129635
|
+
// // only preserve AND if there is a single column in the expression
|
|
129636
|
+
// bool preserve_and = true;
|
|
129637
|
+
//
|
|
129638
|
+
// // conjunction chain for this column
|
|
129639
|
+
// vector<unique_ptr<BoundConjunctionExpression>> conjunctions;
|
|
129640
|
+
// };
|
|
129641
|
+
//
|
|
129642
|
+
// expression_map_t<vector<unique_ptr<ConjunctionsToPush>>> map_col_conjunctions;
|
|
129643
|
+
// vector<BoundColumnRefExpression *> vec_colref_insertion_order;
|
|
129644
|
+
//
|
|
129645
|
+
// BoundConjunctionExpression *cur_root_or;
|
|
129646
|
+
// BoundConjunctionExpression *cur_conjunction;
|
|
129647
|
+
//
|
|
129648
|
+
// BoundColumnRefExpression *cur_colref_to_push;
|
|
129610
129649
|
};
|
|
129611
129650
|
|
|
129612
129651
|
} // namespace duckdb
|
|
@@ -129691,7 +129730,7 @@ FilterResult FilterCombiner::AddConstantComparison(vector<ExpressionValueInforma
|
|
|
129691
129730
|
}
|
|
129692
129731
|
|
|
129693
129732
|
FilterResult FilterCombiner::AddFilter(unique_ptr<Expression> expr) {
|
|
129694
|
-
LookUpConjunctions(expr.get());
|
|
129733
|
+
// LookUpConjunctions(expr.get());
|
|
129695
129734
|
// try to push the filter into the combiner
|
|
129696
129735
|
auto result = AddFilter(expr.get());
|
|
129697
129736
|
if (result == FilterResult::UNSUPPORTED) {
|
|
@@ -130161,7 +130200,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
130161
130200
|
}
|
|
130162
130201
|
}
|
|
130163
130202
|
|
|
130164
|
-
GenerateORFilters(table_filters, column_ids);
|
|
130203
|
+
// GenerateORFilters(table_filters, column_ids);
|
|
130165
130204
|
|
|
130166
130205
|
return table_filters;
|
|
130167
130206
|
}
|
|
@@ -130630,176 +130669,176 @@ ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left,
|
|
|
130630
130669
|
return InvertValueComparisonResult(CompareValueInformation(right, left));
|
|
130631
130670
|
}
|
|
130632
130671
|
}
|
|
130633
|
-
|
|
130634
|
-
void FilterCombiner::LookUpConjunctions(Expression *expr) {
|
|
130635
|
-
if (expr->GetExpressionType() == ExpressionType::CONJUNCTION_OR) {
|
|
130636
|
-
auto root_or_expr = (BoundConjunctionExpression *)expr;
|
|
130637
|
-
for (const auto &entry : map_col_conjunctions) {
|
|
130638
|
-
for (const auto &conjs_to_push : entry.second) {
|
|
130639
|
-
if (conjs_to_push->root_or->Equals(root_or_expr)) {
|
|
130640
|
-
return;
|
|
130641
|
-
}
|
|
130642
|
-
}
|
|
130643
|
-
}
|
|
130644
|
-
|
|
130645
|
-
cur_root_or = root_or_expr;
|
|
130646
|
-
cur_conjunction = root_or_expr;
|
|
130647
|
-
cur_colref_to_push = nullptr;
|
|
130648
|
-
if (!BFSLookUpConjunctions(cur_root_or)) {
|
|
130649
|
-
if (cur_colref_to_push) {
|
|
130650
|
-
auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
130651
|
-
auto &vec_conjs_to_push = entry->second;
|
|
130652
|
-
if (vec_conjs_to_push.size() == 1) {
|
|
130653
|
-
map_col_conjunctions.erase(entry);
|
|
130654
|
-
return;
|
|
130655
|
-
}
|
|
130656
|
-
vec_conjs_to_push.pop_back();
|
|
130657
|
-
}
|
|
130658
|
-
}
|
|
130659
|
-
return;
|
|
130660
|
-
}
|
|
130661
|
-
|
|
130662
|
-
// Verify if the expression has a column already pushed down by other OR expression
|
|
130663
|
-
VerifyOrsToPush(*expr);
|
|
130664
|
-
}
|
|
130665
|
-
|
|
130666
|
-
bool FilterCombiner::BFSLookUpConjunctions(BoundConjunctionExpression *conjunction) {
|
|
130667
|
-
vector<BoundConjunctionExpression *> conjunctions_to_visit;
|
|
130668
|
-
|
|
130669
|
-
for (auto &child : conjunction->children) {
|
|
130670
|
-
switch (child->GetExpressionClass()) {
|
|
130671
|
-
case ExpressionClass::BOUND_CONJUNCTION: {
|
|
130672
|
-
auto child_conjunction = (BoundConjunctionExpression *)child.get();
|
|
130673
|
-
conjunctions_to_visit.emplace_back(child_conjunction);
|
|
130674
|
-
break;
|
|
130675
|
-
}
|
|
130676
|
-
case ExpressionClass::BOUND_COMPARISON: {
|
|
130677
|
-
if (!UpdateConjunctionFilter((BoundComparisonExpression *)child.get())) {
|
|
130678
|
-
return false;
|
|
130679
|
-
}
|
|
130680
|
-
break;
|
|
130681
|
-
}
|
|
130682
|
-
default: {
|
|
130683
|
-
return false;
|
|
130684
|
-
}
|
|
130685
|
-
}
|
|
130686
|
-
}
|
|
130687
|
-
|
|
130688
|
-
for (auto child_conjunction : conjunctions_to_visit) {
|
|
130689
|
-
cur_conjunction = child_conjunction;
|
|
130690
|
-
// traverse child conjuction
|
|
130691
|
-
if (!BFSLookUpConjunctions(child_conjunction)) {
|
|
130692
|
-
return false;
|
|
130693
|
-
}
|
|
130694
|
-
}
|
|
130695
|
-
return true;
|
|
130696
|
-
}
|
|
130697
|
-
|
|
130698
|
-
void FilterCombiner::VerifyOrsToPush(Expression &expr) {
|
|
130699
|
-
if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
|
|
130700
|
-
auto colref = (BoundColumnRefExpression *)&expr;
|
|
130701
|
-
auto entry = map_col_conjunctions.find(colref);
|
|
130702
|
-
if (entry == map_col_conjunctions.end()) {
|
|
130703
|
-
return;
|
|
130704
|
-
}
|
|
130705
|
-
map_col_conjunctions.erase(entry);
|
|
130706
|
-
}
|
|
130707
|
-
ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { VerifyOrsToPush(child); });
|
|
130708
|
-
}
|
|
130709
|
-
|
|
130710
|
-
bool FilterCombiner::UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr) {
|
|
130711
|
-
bool left_is_scalar = comparison_expr->left->IsFoldable();
|
|
130712
|
-
bool right_is_scalar = comparison_expr->right->IsFoldable();
|
|
130713
|
-
|
|
130714
|
-
Expression *non_scalar_expr;
|
|
130715
|
-
if (left_is_scalar || right_is_scalar) {
|
|
130716
|
-
// only support comparison with scalar
|
|
130717
|
-
non_scalar_expr = left_is_scalar ? comparison_expr->right.get() : comparison_expr->left.get();
|
|
130718
|
-
|
|
130719
|
-
if (non_scalar_expr->GetExpressionType() == ExpressionType::BOUND_COLUMN_REF) {
|
|
130720
|
-
return UpdateFilterByColumn((BoundColumnRefExpression *)non_scalar_expr, comparison_expr);
|
|
130721
|
-
}
|
|
130722
|
-
}
|
|
130723
|
-
|
|
130724
|
-
return false;
|
|
130725
|
-
}
|
|
130726
|
-
|
|
130727
|
-
bool FilterCombiner::UpdateFilterByColumn(BoundColumnRefExpression *column_ref,
|
|
130728
|
-
BoundComparisonExpression *comparison_expr) {
|
|
130729
|
-
if (cur_colref_to_push == nullptr) {
|
|
130730
|
-
cur_colref_to_push = column_ref;
|
|
130731
|
-
|
|
130732
|
-
auto or_conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_OR);
|
|
130733
|
-
or_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130734
|
-
|
|
130735
|
-
unique_ptr<ConjunctionsToPush> conjs_to_push = make_unique<ConjunctionsToPush>();
|
|
130736
|
-
conjs_to_push->conjunctions.emplace_back(move(or_conjunction));
|
|
130737
|
-
conjs_to_push->root_or = cur_root_or;
|
|
130738
|
-
|
|
130739
|
-
auto &&vec_col_conjs = map_col_conjunctions[column_ref];
|
|
130740
|
-
vec_col_conjs.emplace_back(move(conjs_to_push));
|
|
130741
|
-
vec_colref_insertion_order.emplace_back(column_ref);
|
|
130742
|
-
return true;
|
|
130743
|
-
}
|
|
130744
|
-
|
|
130745
|
-
auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
130746
|
-
D_ASSERT(entry != map_col_conjunctions.end());
|
|
130747
|
-
auto &conjunctions_to_push = entry->second.back();
|
|
130748
|
-
|
|
130749
|
-
if (!cur_colref_to_push->Equals(column_ref)) {
|
|
130750
|
-
// check for multiple colunms in the same root OR node
|
|
130751
|
-
if (cur_root_or == cur_conjunction) {
|
|
130752
|
-
return false;
|
|
130753
|
-
}
|
|
130754
|
-
// found an AND using a different column, we should stop the look up
|
|
130755
|
-
if (cur_conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND) {
|
|
130756
|
-
return false;
|
|
130757
|
-
}
|
|
130758
|
-
|
|
130759
|
-
// found a different column, AND conditions cannot be preserved anymore
|
|
130760
|
-
conjunctions_to_push->preserve_and = false;
|
|
130761
|
-
return true;
|
|
130762
|
-
}
|
|
130763
|
-
|
|
130764
|
-
auto &last_conjunction = conjunctions_to_push->conjunctions.back();
|
|
130765
|
-
if (cur_conjunction->GetExpressionType() == last_conjunction->GetExpressionType()) {
|
|
130766
|
-
last_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130767
|
-
} else {
|
|
130768
|
-
auto new_conjunction = make_unique<BoundConjunctionExpression>(cur_conjunction->GetExpressionType());
|
|
130769
|
-
new_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130770
|
-
conjunctions_to_push->conjunctions.emplace_back(move(new_conjunction));
|
|
130771
|
-
}
|
|
130772
|
-
return true;
|
|
130773
|
-
}
|
|
130774
|
-
|
|
130775
|
-
void FilterCombiner::GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids) {
|
|
130776
|
-
for (const auto colref : vec_colref_insertion_order) {
|
|
130777
|
-
auto column_index = column_ids[colref->binding.column_index];
|
|
130778
|
-
if (column_index == COLUMN_IDENTIFIER_ROW_ID) {
|
|
130779
|
-
break;
|
|
130780
|
-
}
|
|
130781
|
-
|
|
130782
|
-
for (const auto &conjunctions_to_push : map_col_conjunctions[colref]) {
|
|
130783
|
-
// root OR filter to push into the TableFilter
|
|
130784
|
-
auto root_or_filter = make_unique<ConjunctionOrFilter>();
|
|
130785
|
-
// variable to hold the last conjuntion filter pointer
|
|
130786
|
-
// the next filter will be added into it, i.e., we create a chain of conjunction filters
|
|
130787
|
-
ConjunctionFilter *last_conj_filter = root_or_filter.get();
|
|
130788
|
-
|
|
130789
|
-
for (auto &conjunction : conjunctions_to_push->conjunctions) {
|
|
130790
|
-
if (conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND &&
|
|
130791
|
-
conjunctions_to_push->preserve_and) {
|
|
130792
|
-
GenerateConjunctionFilter<ConjunctionAndFilter>(conjunction.get(), last_conj_filter);
|
|
130793
|
-
} else {
|
|
130794
|
-
GenerateConjunctionFilter<ConjunctionOrFilter>(conjunction.get(), last_conj_filter);
|
|
130795
|
-
}
|
|
130796
|
-
}
|
|
130797
|
-
table_filter.PushFilter(column_index, move(root_or_filter));
|
|
130798
|
-
}
|
|
130799
|
-
}
|
|
130800
|
-
map_col_conjunctions.clear();
|
|
130801
|
-
vec_colref_insertion_order.clear();
|
|
130802
|
-
}
|
|
130672
|
+
//
|
|
130673
|
+
// void FilterCombiner::LookUpConjunctions(Expression *expr) {
|
|
130674
|
+
// if (expr->GetExpressionType() == ExpressionType::CONJUNCTION_OR) {
|
|
130675
|
+
// auto root_or_expr = (BoundConjunctionExpression *)expr;
|
|
130676
|
+
// for (const auto &entry : map_col_conjunctions) {
|
|
130677
|
+
// for (const auto &conjs_to_push : entry.second) {
|
|
130678
|
+
// if (conjs_to_push->root_or->Equals(root_or_expr)) {
|
|
130679
|
+
// return;
|
|
130680
|
+
// }
|
|
130681
|
+
// }
|
|
130682
|
+
// }
|
|
130683
|
+
//
|
|
130684
|
+
// cur_root_or = root_or_expr;
|
|
130685
|
+
// cur_conjunction = root_or_expr;
|
|
130686
|
+
// cur_colref_to_push = nullptr;
|
|
130687
|
+
// if (!BFSLookUpConjunctions(cur_root_or)) {
|
|
130688
|
+
// if (cur_colref_to_push) {
|
|
130689
|
+
// auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
130690
|
+
// auto &vec_conjs_to_push = entry->second;
|
|
130691
|
+
// if (vec_conjs_to_push.size() == 1) {
|
|
130692
|
+
// map_col_conjunctions.erase(entry);
|
|
130693
|
+
// return;
|
|
130694
|
+
// }
|
|
130695
|
+
// vec_conjs_to_push.pop_back();
|
|
130696
|
+
// }
|
|
130697
|
+
// }
|
|
130698
|
+
// return;
|
|
130699
|
+
// }
|
|
130700
|
+
//
|
|
130701
|
+
// // Verify if the expression has a column already pushed down by other OR expression
|
|
130702
|
+
// VerifyOrsToPush(*expr);
|
|
130703
|
+
//}
|
|
130704
|
+
//
|
|
130705
|
+
// bool FilterCombiner::BFSLookUpConjunctions(BoundConjunctionExpression *conjunction) {
|
|
130706
|
+
// vector<BoundConjunctionExpression *> conjunctions_to_visit;
|
|
130707
|
+
//
|
|
130708
|
+
// for (auto &child : conjunction->children) {
|
|
130709
|
+
// switch (child->GetExpressionClass()) {
|
|
130710
|
+
// case ExpressionClass::BOUND_CONJUNCTION: {
|
|
130711
|
+
// auto child_conjunction = (BoundConjunctionExpression *)child.get();
|
|
130712
|
+
// conjunctions_to_visit.emplace_back(child_conjunction);
|
|
130713
|
+
// break;
|
|
130714
|
+
// }
|
|
130715
|
+
// case ExpressionClass::BOUND_COMPARISON: {
|
|
130716
|
+
// if (!UpdateConjunctionFilter((BoundComparisonExpression *)child.get())) {
|
|
130717
|
+
// return false;
|
|
130718
|
+
// }
|
|
130719
|
+
// break;
|
|
130720
|
+
// }
|
|
130721
|
+
// default: {
|
|
130722
|
+
// return false;
|
|
130723
|
+
// }
|
|
130724
|
+
// }
|
|
130725
|
+
// }
|
|
130726
|
+
//
|
|
130727
|
+
// for (auto child_conjunction : conjunctions_to_visit) {
|
|
130728
|
+
// cur_conjunction = child_conjunction;
|
|
130729
|
+
// // traverse child conjuction
|
|
130730
|
+
// if (!BFSLookUpConjunctions(child_conjunction)) {
|
|
130731
|
+
// return false;
|
|
130732
|
+
// }
|
|
130733
|
+
// }
|
|
130734
|
+
// return true;
|
|
130735
|
+
//}
|
|
130736
|
+
//
|
|
130737
|
+
// void FilterCombiner::VerifyOrsToPush(Expression &expr) {
|
|
130738
|
+
// if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
|
|
130739
|
+
// auto colref = (BoundColumnRefExpression *)&expr;
|
|
130740
|
+
// auto entry = map_col_conjunctions.find(colref);
|
|
130741
|
+
// if (entry == map_col_conjunctions.end()) {
|
|
130742
|
+
// return;
|
|
130743
|
+
// }
|
|
130744
|
+
// map_col_conjunctions.erase(entry);
|
|
130745
|
+
// }
|
|
130746
|
+
// ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { VerifyOrsToPush(child); });
|
|
130747
|
+
//}
|
|
130748
|
+
//
|
|
130749
|
+
// bool FilterCombiner::UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr) {
|
|
130750
|
+
// bool left_is_scalar = comparison_expr->left->IsFoldable();
|
|
130751
|
+
// bool right_is_scalar = comparison_expr->right->IsFoldable();
|
|
130752
|
+
//
|
|
130753
|
+
// Expression *non_scalar_expr;
|
|
130754
|
+
// if (left_is_scalar || right_is_scalar) {
|
|
130755
|
+
// // only support comparison with scalar
|
|
130756
|
+
// non_scalar_expr = left_is_scalar ? comparison_expr->right.get() : comparison_expr->left.get();
|
|
130757
|
+
//
|
|
130758
|
+
// if (non_scalar_expr->GetExpressionType() == ExpressionType::BOUND_COLUMN_REF) {
|
|
130759
|
+
// return UpdateFilterByColumn((BoundColumnRefExpression *)non_scalar_expr, comparison_expr);
|
|
130760
|
+
// }
|
|
130761
|
+
// }
|
|
130762
|
+
//
|
|
130763
|
+
// return false;
|
|
130764
|
+
//}
|
|
130765
|
+
//
|
|
130766
|
+
// bool FilterCombiner::UpdateFilterByColumn(BoundColumnRefExpression *column_ref,
|
|
130767
|
+
// BoundComparisonExpression *comparison_expr) {
|
|
130768
|
+
// if (cur_colref_to_push == nullptr) {
|
|
130769
|
+
// cur_colref_to_push = column_ref;
|
|
130770
|
+
//
|
|
130771
|
+
// auto or_conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_OR);
|
|
130772
|
+
// or_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130773
|
+
//
|
|
130774
|
+
// unique_ptr<ConjunctionsToPush> conjs_to_push = make_unique<ConjunctionsToPush>();
|
|
130775
|
+
// conjs_to_push->conjunctions.emplace_back(move(or_conjunction));
|
|
130776
|
+
// conjs_to_push->root_or = cur_root_or;
|
|
130777
|
+
//
|
|
130778
|
+
// auto &&vec_col_conjs = map_col_conjunctions[column_ref];
|
|
130779
|
+
// vec_col_conjs.emplace_back(move(conjs_to_push));
|
|
130780
|
+
// vec_colref_insertion_order.emplace_back(column_ref);
|
|
130781
|
+
// return true;
|
|
130782
|
+
// }
|
|
130783
|
+
//
|
|
130784
|
+
// auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
130785
|
+
// D_ASSERT(entry != map_col_conjunctions.end());
|
|
130786
|
+
// auto &conjunctions_to_push = entry->second.back();
|
|
130787
|
+
//
|
|
130788
|
+
// if (!cur_colref_to_push->Equals(column_ref)) {
|
|
130789
|
+
// // check for multiple colunms in the same root OR node
|
|
130790
|
+
// if (cur_root_or == cur_conjunction) {
|
|
130791
|
+
// return false;
|
|
130792
|
+
// }
|
|
130793
|
+
// // found an AND using a different column, we should stop the look up
|
|
130794
|
+
// if (cur_conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND) {
|
|
130795
|
+
// return false;
|
|
130796
|
+
// }
|
|
130797
|
+
//
|
|
130798
|
+
// // found a different column, AND conditions cannot be preserved anymore
|
|
130799
|
+
// conjunctions_to_push->preserve_and = false;
|
|
130800
|
+
// return true;
|
|
130801
|
+
// }
|
|
130802
|
+
//
|
|
130803
|
+
// auto &last_conjunction = conjunctions_to_push->conjunctions.back();
|
|
130804
|
+
// if (cur_conjunction->GetExpressionType() == last_conjunction->GetExpressionType()) {
|
|
130805
|
+
// last_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130806
|
+
// } else {
|
|
130807
|
+
// auto new_conjunction = make_unique<BoundConjunctionExpression>(cur_conjunction->GetExpressionType());
|
|
130808
|
+
// new_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130809
|
+
// conjunctions_to_push->conjunctions.emplace_back(move(new_conjunction));
|
|
130810
|
+
// }
|
|
130811
|
+
// return true;
|
|
130812
|
+
//}
|
|
130813
|
+
//
|
|
130814
|
+
// void FilterCombiner::GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids) {
|
|
130815
|
+
// for (const auto colref : vec_colref_insertion_order) {
|
|
130816
|
+
// auto column_index = column_ids[colref->binding.column_index];
|
|
130817
|
+
// if (column_index == COLUMN_IDENTIFIER_ROW_ID) {
|
|
130818
|
+
// break;
|
|
130819
|
+
// }
|
|
130820
|
+
//
|
|
130821
|
+
// for (const auto &conjunctions_to_push : map_col_conjunctions[colref]) {
|
|
130822
|
+
// // root OR filter to push into the TableFilter
|
|
130823
|
+
// auto root_or_filter = make_unique<ConjunctionOrFilter>();
|
|
130824
|
+
// // variable to hold the last conjuntion filter pointer
|
|
130825
|
+
// // the next filter will be added into it, i.e., we create a chain of conjunction filters
|
|
130826
|
+
// ConjunctionFilter *last_conj_filter = root_or_filter.get();
|
|
130827
|
+
//
|
|
130828
|
+
// for (auto &conjunction : conjunctions_to_push->conjunctions) {
|
|
130829
|
+
// if (conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND &&
|
|
130830
|
+
// conjunctions_to_push->preserve_and) {
|
|
130831
|
+
// GenerateConjunctionFilter<ConjunctionAndFilter>(conjunction.get(), last_conj_filter);
|
|
130832
|
+
// } else {
|
|
130833
|
+
// GenerateConjunctionFilter<ConjunctionOrFilter>(conjunction.get(), last_conj_filter);
|
|
130834
|
+
// }
|
|
130835
|
+
// }
|
|
130836
|
+
// table_filter.PushFilter(column_index, move(root_or_filter));
|
|
130837
|
+
// }
|
|
130838
|
+
// }
|
|
130839
|
+
// map_col_conjunctions.clear();
|
|
130840
|
+
// vec_colref_insertion_order.clear();
|
|
130841
|
+
//}
|
|
130803
130842
|
|
|
130804
130843
|
} // namespace duckdb
|
|
130805
130844
|
//===----------------------------------------------------------------------===//
|
|
@@ -133238,6 +133277,7 @@ private:
|
|
|
133238
133277
|
unique_ptr<BaseStatistics> PropagateExpression(BoundBetweenExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133239
133278
|
unique_ptr<BaseStatistics> PropagateExpression(BoundCaseExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133240
133279
|
unique_ptr<BaseStatistics> PropagateExpression(BoundCastExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133280
|
+
unique_ptr<BaseStatistics> PropagateExpression(BoundConjunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133241
133281
|
unique_ptr<BaseStatistics> PropagateExpression(BoundFunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133242
133282
|
unique_ptr<BaseStatistics> PropagateExpression(BoundComparisonExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133243
133283
|
unique_ptr<BaseStatistics> PropagateExpression(BoundConstantExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
@@ -136257,6 +136297,73 @@ unique_ptr<BaseStatistics> StatisticsPropagator::PropagateExpression(BoundCompar
|
|
|
136257
136297
|
|
|
136258
136298
|
|
|
136259
136299
|
|
|
136300
|
+
|
|
136301
|
+
|
|
136302
|
+
|
|
136303
|
+
|
|
136304
|
+
|
|
136305
|
+
namespace duckdb {
|
|
136306
|
+
|
|
136307
|
+
unique_ptr<BaseStatistics> StatisticsPropagator::PropagateExpression(BoundConjunctionExpression &expr,
|
|
136308
|
+
unique_ptr<Expression> *expr_ptr) {
|
|
136309
|
+
auto is_and = expr.type == ExpressionType::CONJUNCTION_AND;
|
|
136310
|
+
for (idx_t expr_idx = 0; expr_idx < expr.children.size(); expr_idx++) {
|
|
136311
|
+
auto &child = expr.children[expr_idx];
|
|
136312
|
+
auto stats = PropagateExpression(child);
|
|
136313
|
+
if (!child->IsFoldable()) {
|
|
136314
|
+
continue;
|
|
136315
|
+
}
|
|
136316
|
+
// we have a constant in a conjunction
|
|
136317
|
+
// we (1) either prune the child
|
|
136318
|
+
// or (2) replace the entire conjunction with a constant
|
|
136319
|
+
auto constant = ExpressionExecutor::EvaluateScalar(*child);
|
|
136320
|
+
if (constant.IsNull()) {
|
|
136321
|
+
continue;
|
|
136322
|
+
}
|
|
136323
|
+
auto b = BooleanValue::Get(constant);
|
|
136324
|
+
bool prune_child = false;
|
|
136325
|
+
bool constant_value = true;
|
|
136326
|
+
if (b) {
|
|
136327
|
+
// true
|
|
136328
|
+
if (is_and) {
|
|
136329
|
+
// true in and: prune child
|
|
136330
|
+
prune_child = true;
|
|
136331
|
+
} else {
|
|
136332
|
+
// true in OR: replace with TRUE
|
|
136333
|
+
constant_value = true;
|
|
136334
|
+
}
|
|
136335
|
+
} else {
|
|
136336
|
+
// false
|
|
136337
|
+
if (is_and) {
|
|
136338
|
+
// false in AND: replace with FALSE
|
|
136339
|
+
constant_value = false;
|
|
136340
|
+
} else {
|
|
136341
|
+
// false in OR: prune child
|
|
136342
|
+
prune_child = true;
|
|
136343
|
+
}
|
|
136344
|
+
}
|
|
136345
|
+
if (prune_child) {
|
|
136346
|
+
expr.children.erase(expr.children.begin() + expr_idx);
|
|
136347
|
+
expr_idx--;
|
|
136348
|
+
continue;
|
|
136349
|
+
}
|
|
136350
|
+
*expr_ptr = make_unique<BoundConstantExpression>(Value::BOOLEAN(constant_value));
|
|
136351
|
+
return PropagateExpression(*expr_ptr);
|
|
136352
|
+
}
|
|
136353
|
+
if (expr.children.empty()) {
|
|
136354
|
+
// if there are no children left, replace the conjunction with TRUE (for AND) or FALSE (for OR)
|
|
136355
|
+
*expr_ptr = make_unique<BoundConstantExpression>(Value::BOOLEAN(is_and));
|
|
136356
|
+
return PropagateExpression(*expr_ptr);
|
|
136357
|
+
} else if (expr.children.size() == 1) {
|
|
136358
|
+
// if there is one child left, replace the conjunction with that one child
|
|
136359
|
+
*expr_ptr = move(expr.children[0]);
|
|
136360
|
+
}
|
|
136361
|
+
return nullptr;
|
|
136362
|
+
}
|
|
136363
|
+
|
|
136364
|
+
} // namespace duckdb
|
|
136365
|
+
|
|
136366
|
+
|
|
136260
136367
|
//===----------------------------------------------------------------------===//
|
|
136261
136368
|
// DuckDB
|
|
136262
136369
|
//
|
|
@@ -136577,7 +136684,7 @@ bool StatisticsPropagator::ExpressionIsConstant(Expression &expr, const Value &v
|
|
|
136577
136684
|
}
|
|
136578
136685
|
auto &bound_constant = (BoundConstantExpression &)expr;
|
|
136579
136686
|
D_ASSERT(bound_constant.value.type() == val.type());
|
|
136580
|
-
return bound_constant.value
|
|
136687
|
+
return Value::NotDistinctFrom(bound_constant.value, val);
|
|
136581
136688
|
}
|
|
136582
136689
|
|
|
136583
136690
|
bool StatisticsPropagator::ExpressionIsConstantOrNull(Expression &expr, const Value &val) {
|
|
@@ -137361,6 +137468,8 @@ unique_ptr<BaseStatistics> StatisticsPropagator::PropagateExpression(Expression
|
|
|
137361
137468
|
return PropagateExpression((BoundBetweenExpression &)expr, expr_ptr);
|
|
137362
137469
|
case ExpressionClass::BOUND_CASE:
|
|
137363
137470
|
return PropagateExpression((BoundCaseExpression &)expr, expr_ptr);
|
|
137471
|
+
case ExpressionClass::BOUND_CONJUNCTION:
|
|
137472
|
+
return PropagateExpression((BoundConjunctionExpression &)expr, expr_ptr);
|
|
137364
137473
|
case ExpressionClass::BOUND_FUNCTION:
|
|
137365
137474
|
return PropagateExpression((BoundFunctionExpression &)expr, expr_ptr);
|
|
137366
137475
|
case ExpressionClass::BOUND_CAST:
|