duckdb 0.3.5-dev591.0 → 0.3.5-dev602.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 +335 -230
- package/src/duckdb.hpp +483 -483
- package/src/parquet-amalgamation.cpp +28257 -28257
package/src/duckdb.cpp
CHANGED
|
@@ -38514,11 +38514,39 @@ bool ChunkCollection::Equals(ChunkCollection &other) {
|
|
|
38514
38514
|
if (ColumnCount() != other.ColumnCount()) {
|
|
38515
38515
|
return false;
|
|
38516
38516
|
}
|
|
38517
|
-
//
|
|
38517
|
+
// first try to compare the results as-is
|
|
38518
|
+
bool compare_equals = true;
|
|
38518
38519
|
for (idx_t row_idx = 0; row_idx < count; row_idx++) {
|
|
38519
38520
|
for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
|
|
38520
38521
|
auto lvalue = GetValue(col_idx, row_idx);
|
|
38521
38522
|
auto rvalue = other.GetValue(col_idx, row_idx);
|
|
38523
|
+
if (!Value::ValuesAreEqual(lvalue, rvalue)) {
|
|
38524
|
+
compare_equals = false;
|
|
38525
|
+
break;
|
|
38526
|
+
}
|
|
38527
|
+
}
|
|
38528
|
+
if (!compare_equals) {
|
|
38529
|
+
break;
|
|
38530
|
+
}
|
|
38531
|
+
}
|
|
38532
|
+
if (compare_equals) {
|
|
38533
|
+
return true;
|
|
38534
|
+
}
|
|
38535
|
+
// if the results are not equal,
|
|
38536
|
+
// sort both chunk collections to ensure the comparison is not order insensitive
|
|
38537
|
+
vector<OrderType> desc(ColumnCount(), OrderType::DESCENDING);
|
|
38538
|
+
vector<OrderByNullType> null_order(ColumnCount(), OrderByNullType::NULLS_FIRST);
|
|
38539
|
+
auto this_order = unique_ptr<idx_t[]>(new idx_t[count]);
|
|
38540
|
+
auto other_order = unique_ptr<idx_t[]>(new idx_t[count]);
|
|
38541
|
+
Sort(desc, null_order, this_order.get());
|
|
38542
|
+
other.Sort(desc, null_order, other_order.get());
|
|
38543
|
+
|
|
38544
|
+
for (idx_t row_idx = 0; row_idx < count; row_idx++) {
|
|
38545
|
+
auto lrow = this_order[row_idx];
|
|
38546
|
+
auto rrow = other_order[row_idx];
|
|
38547
|
+
for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
|
|
38548
|
+
auto lvalue = GetValue(col_idx, lrow);
|
|
38549
|
+
auto rvalue = other.GetValue(col_idx, rrow);
|
|
38522
38550
|
if (!Value::ValuesAreEqual(lvalue, rvalue)) {
|
|
38523
38551
|
return false;
|
|
38524
38552
|
}
|
|
@@ -112991,6 +113019,7 @@ private:
|
|
|
112991
113019
|
|
|
112992
113020
|
|
|
112993
113021
|
|
|
113022
|
+
|
|
112994
113023
|
namespace duckdb {
|
|
112995
113024
|
|
|
112996
113025
|
struct ActiveQueryContext {
|
|
@@ -113698,14 +113727,16 @@ void ClientContext::DisableProfiling() {
|
|
|
113698
113727
|
}
|
|
113699
113728
|
|
|
113700
113729
|
struct VerifyStatement {
|
|
113701
|
-
VerifyStatement(unique_ptr<SelectStatement> statement_p, string statement_name_p, bool require_equality = true
|
|
113730
|
+
VerifyStatement(unique_ptr<SelectStatement> statement_p, string statement_name_p, bool require_equality = true,
|
|
113731
|
+
bool disable_optimizer = false)
|
|
113702
113732
|
: statement(move(statement_p)), statement_name(move(statement_name_p)), require_equality(require_equality),
|
|
113703
|
-
select_list(statement->node->GetSelectList()) {
|
|
113733
|
+
disable_optimizer(disable_optimizer), select_list(statement->node->GetSelectList()) {
|
|
113704
113734
|
}
|
|
113705
113735
|
|
|
113706
113736
|
unique_ptr<SelectStatement> statement;
|
|
113707
113737
|
string statement_name;
|
|
113708
113738
|
bool require_equality;
|
|
113739
|
+
bool disable_optimizer;
|
|
113709
113740
|
const vector<unique_ptr<ParsedExpression>> &select_list;
|
|
113710
113741
|
};
|
|
113711
113742
|
|
|
@@ -113733,8 +113764,9 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113733
113764
|
BufferedDeserializer source(serializer);
|
|
113734
113765
|
auto deserialized_stmt = SelectStatement::Deserialize(source);
|
|
113735
113766
|
|
|
113767
|
+
auto query_str = select_stmt->ToString();
|
|
113736
113768
|
Parser parser;
|
|
113737
|
-
parser.ParseQuery(
|
|
113769
|
+
parser.ParseQuery(query_str);
|
|
113738
113770
|
D_ASSERT(parser.statements.size() == 1);
|
|
113739
113771
|
D_ASSERT(parser.statements[0]->type == StatementType::SELECT_STATEMENT);
|
|
113740
113772
|
auto parsed_statement = move(parser.statements[0]);
|
|
@@ -113745,6 +113777,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113745
113777
|
verify_statements.emplace_back(move(deserialized_stmt), "Deserialized statement");
|
|
113746
113778
|
verify_statements.emplace_back(unique_ptr_cast<SQLStatement, SelectStatement>(move(parsed_statement)),
|
|
113747
113779
|
"Parsed statement", false);
|
|
113780
|
+
verify_statements.emplace_back(unique_ptr_cast<SQLStatement, SelectStatement>(move(unoptimized_stmt)),
|
|
113781
|
+
"Unoptimized", true, true);
|
|
113748
113782
|
|
|
113749
113783
|
// all the statements should be equal
|
|
113750
113784
|
for (idx_t i = 1; i < verify_statements.size(); i++) {
|
|
@@ -113809,9 +113843,11 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113809
113843
|
auto statement_copy_for_explain = select_stmt->Copy();
|
|
113810
113844
|
|
|
113811
113845
|
// execute the original statement
|
|
113846
|
+
auto optimizer_enabled = config.enable_optimizer;
|
|
113812
113847
|
vector<unique_ptr<MaterializedQueryResult>> results;
|
|
113813
113848
|
for (idx_t i = 0; i < verify_statements.size(); i++) {
|
|
113814
113849
|
interrupted = false;
|
|
113850
|
+
config.enable_optimizer = !verify_statements[i].disable_optimizer;
|
|
113815
113851
|
try {
|
|
113816
113852
|
auto result = RunStatementInternal(lock, query, move(verify_statements[i].statement), false, false);
|
|
113817
113853
|
results.push_back(unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result)));
|
|
@@ -113819,6 +113855,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113819
113855
|
results.push_back(make_unique<MaterializedQueryResult>(ex.what()));
|
|
113820
113856
|
}
|
|
113821
113857
|
}
|
|
113858
|
+
config.enable_optimizer = optimizer_enabled;
|
|
113822
113859
|
|
|
113823
113860
|
// check explain, only if q does not already contain EXPLAIN
|
|
113824
113861
|
if (results[0]->success) {
|
|
@@ -113831,8 +113868,6 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
113831
113868
|
} // LCOV_EXCL_STOP
|
|
113832
113869
|
}
|
|
113833
113870
|
|
|
113834
|
-
config.enable_optimizer = true;
|
|
113835
|
-
|
|
113836
113871
|
if (profiling_is_enabled) {
|
|
113837
113872
|
config.enable_profiler = true;
|
|
113838
113873
|
}
|
|
@@ -129547,37 +129582,37 @@ private:
|
|
|
129547
129582
|
Expression *GetNode(Expression *expr);
|
|
129548
129583
|
idx_t GetEquivalenceSet(Expression *expr);
|
|
129549
129584
|
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
|
-
}
|
|
129585
|
+
//
|
|
129586
|
+
// //! Functions used to push and generate OR Filters
|
|
129587
|
+
// void LookUpConjunctions(Expression *expr);
|
|
129588
|
+
// bool BFSLookUpConjunctions(BoundConjunctionExpression *conjunction);
|
|
129589
|
+
// void VerifyOrsToPush(Expression &expr);
|
|
129590
|
+
//
|
|
129591
|
+
// bool UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr);
|
|
129592
|
+
// bool UpdateFilterByColumn(BoundColumnRefExpression *column_ref, BoundComparisonExpression *comparison_expr);
|
|
129593
|
+
// void GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids);
|
|
129594
|
+
//
|
|
129595
|
+
// template <typename CONJUNCTION_TYPE>
|
|
129596
|
+
// void GenerateConjunctionFilter(BoundConjunctionExpression *conjunction, ConjunctionFilter *last_conj_filter) {
|
|
129597
|
+
// auto new_filter = NextConjunctionFilter<CONJUNCTION_TYPE>(conjunction);
|
|
129598
|
+
// auto conj_filter_ptr = (ConjunctionFilter *)new_filter.get();
|
|
129599
|
+
// last_conj_filter->child_filters.push_back(move(new_filter));
|
|
129600
|
+
// last_conj_filter = conj_filter_ptr;
|
|
129601
|
+
// }
|
|
129602
|
+
//
|
|
129603
|
+
// template <typename CONJUNCTION_TYPE>
|
|
129604
|
+
// unique_ptr<TableFilter> NextConjunctionFilter(BoundConjunctionExpression *conjunction) {
|
|
129605
|
+
// unique_ptr<ConjunctionFilter> conj_filter = make_unique<CONJUNCTION_TYPE>();
|
|
129606
|
+
// for (auto &expr : conjunction->children) {
|
|
129607
|
+
// auto comp_expr = (BoundComparisonExpression *)expr.get();
|
|
129608
|
+
// auto &const_expr =
|
|
129609
|
+
// (comp_expr->left->type == ExpressionType::VALUE_CONSTANT) ? *comp_expr->left : *comp_expr->right;
|
|
129610
|
+
// auto const_value = ExpressionExecutor::EvaluateScalar(const_expr);
|
|
129611
|
+
// auto const_filter = make_unique<ConstantFilter>(comp_expr->type, const_value);
|
|
129612
|
+
// conj_filter->child_filters.push_back(move(const_filter));
|
|
129613
|
+
// }
|
|
129614
|
+
// return move(conj_filter);
|
|
129615
|
+
// }
|
|
129581
129616
|
|
|
129582
129617
|
private:
|
|
129583
129618
|
vector<unique_ptr<Expression>> remaining_filters;
|
|
@@ -129587,26 +129622,26 @@ private:
|
|
|
129587
129622
|
unordered_map<idx_t, vector<ExpressionValueInformation>> constant_values;
|
|
129588
129623
|
unordered_map<idx_t, vector<Expression *>> equivalence_map;
|
|
129589
129624
|
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;
|
|
129625
|
+
//
|
|
129626
|
+
// //! Structures used for OR Filters
|
|
129627
|
+
//
|
|
129628
|
+
// struct ConjunctionsToPush {
|
|
129629
|
+
// BoundConjunctionExpression *root_or;
|
|
129630
|
+
//
|
|
129631
|
+
// // only preserve AND if there is a single column in the expression
|
|
129632
|
+
// bool preserve_and = true;
|
|
129633
|
+
//
|
|
129634
|
+
// // conjunction chain for this column
|
|
129635
|
+
// vector<unique_ptr<BoundConjunctionExpression>> conjunctions;
|
|
129636
|
+
// };
|
|
129637
|
+
//
|
|
129638
|
+
// expression_map_t<vector<unique_ptr<ConjunctionsToPush>>> map_col_conjunctions;
|
|
129639
|
+
// vector<BoundColumnRefExpression *> vec_colref_insertion_order;
|
|
129640
|
+
//
|
|
129641
|
+
// BoundConjunctionExpression *cur_root_or;
|
|
129642
|
+
// BoundConjunctionExpression *cur_conjunction;
|
|
129643
|
+
//
|
|
129644
|
+
// BoundColumnRefExpression *cur_colref_to_push;
|
|
129610
129645
|
};
|
|
129611
129646
|
|
|
129612
129647
|
} // namespace duckdb
|
|
@@ -129691,7 +129726,7 @@ FilterResult FilterCombiner::AddConstantComparison(vector<ExpressionValueInforma
|
|
|
129691
129726
|
}
|
|
129692
129727
|
|
|
129693
129728
|
FilterResult FilterCombiner::AddFilter(unique_ptr<Expression> expr) {
|
|
129694
|
-
LookUpConjunctions(expr.get());
|
|
129729
|
+
// LookUpConjunctions(expr.get());
|
|
129695
129730
|
// try to push the filter into the combiner
|
|
129696
129731
|
auto result = AddFilter(expr.get());
|
|
129697
129732
|
if (result == FilterResult::UNSUPPORTED) {
|
|
@@ -130161,7 +130196,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
130161
130196
|
}
|
|
130162
130197
|
}
|
|
130163
130198
|
|
|
130164
|
-
GenerateORFilters(table_filters, column_ids);
|
|
130199
|
+
// GenerateORFilters(table_filters, column_ids);
|
|
130165
130200
|
|
|
130166
130201
|
return table_filters;
|
|
130167
130202
|
}
|
|
@@ -130630,176 +130665,176 @@ ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left,
|
|
|
130630
130665
|
return InvertValueComparisonResult(CompareValueInformation(right, left));
|
|
130631
130666
|
}
|
|
130632
130667
|
}
|
|
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
|
-
}
|
|
130668
|
+
//
|
|
130669
|
+
// void FilterCombiner::LookUpConjunctions(Expression *expr) {
|
|
130670
|
+
// if (expr->GetExpressionType() == ExpressionType::CONJUNCTION_OR) {
|
|
130671
|
+
// auto root_or_expr = (BoundConjunctionExpression *)expr;
|
|
130672
|
+
// for (const auto &entry : map_col_conjunctions) {
|
|
130673
|
+
// for (const auto &conjs_to_push : entry.second) {
|
|
130674
|
+
// if (conjs_to_push->root_or->Equals(root_or_expr)) {
|
|
130675
|
+
// return;
|
|
130676
|
+
// }
|
|
130677
|
+
// }
|
|
130678
|
+
// }
|
|
130679
|
+
//
|
|
130680
|
+
// cur_root_or = root_or_expr;
|
|
130681
|
+
// cur_conjunction = root_or_expr;
|
|
130682
|
+
// cur_colref_to_push = nullptr;
|
|
130683
|
+
// if (!BFSLookUpConjunctions(cur_root_or)) {
|
|
130684
|
+
// if (cur_colref_to_push) {
|
|
130685
|
+
// auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
130686
|
+
// auto &vec_conjs_to_push = entry->second;
|
|
130687
|
+
// if (vec_conjs_to_push.size() == 1) {
|
|
130688
|
+
// map_col_conjunctions.erase(entry);
|
|
130689
|
+
// return;
|
|
130690
|
+
// }
|
|
130691
|
+
// vec_conjs_to_push.pop_back();
|
|
130692
|
+
// }
|
|
130693
|
+
// }
|
|
130694
|
+
// return;
|
|
130695
|
+
// }
|
|
130696
|
+
//
|
|
130697
|
+
// // Verify if the expression has a column already pushed down by other OR expression
|
|
130698
|
+
// VerifyOrsToPush(*expr);
|
|
130699
|
+
//}
|
|
130700
|
+
//
|
|
130701
|
+
// bool FilterCombiner::BFSLookUpConjunctions(BoundConjunctionExpression *conjunction) {
|
|
130702
|
+
// vector<BoundConjunctionExpression *> conjunctions_to_visit;
|
|
130703
|
+
//
|
|
130704
|
+
// for (auto &child : conjunction->children) {
|
|
130705
|
+
// switch (child->GetExpressionClass()) {
|
|
130706
|
+
// case ExpressionClass::BOUND_CONJUNCTION: {
|
|
130707
|
+
// auto child_conjunction = (BoundConjunctionExpression *)child.get();
|
|
130708
|
+
// conjunctions_to_visit.emplace_back(child_conjunction);
|
|
130709
|
+
// break;
|
|
130710
|
+
// }
|
|
130711
|
+
// case ExpressionClass::BOUND_COMPARISON: {
|
|
130712
|
+
// if (!UpdateConjunctionFilter((BoundComparisonExpression *)child.get())) {
|
|
130713
|
+
// return false;
|
|
130714
|
+
// }
|
|
130715
|
+
// break;
|
|
130716
|
+
// }
|
|
130717
|
+
// default: {
|
|
130718
|
+
// return false;
|
|
130719
|
+
// }
|
|
130720
|
+
// }
|
|
130721
|
+
// }
|
|
130722
|
+
//
|
|
130723
|
+
// for (auto child_conjunction : conjunctions_to_visit) {
|
|
130724
|
+
// cur_conjunction = child_conjunction;
|
|
130725
|
+
// // traverse child conjuction
|
|
130726
|
+
// if (!BFSLookUpConjunctions(child_conjunction)) {
|
|
130727
|
+
// return false;
|
|
130728
|
+
// }
|
|
130729
|
+
// }
|
|
130730
|
+
// return true;
|
|
130731
|
+
//}
|
|
130732
|
+
//
|
|
130733
|
+
// void FilterCombiner::VerifyOrsToPush(Expression &expr) {
|
|
130734
|
+
// if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
|
|
130735
|
+
// auto colref = (BoundColumnRefExpression *)&expr;
|
|
130736
|
+
// auto entry = map_col_conjunctions.find(colref);
|
|
130737
|
+
// if (entry == map_col_conjunctions.end()) {
|
|
130738
|
+
// return;
|
|
130739
|
+
// }
|
|
130740
|
+
// map_col_conjunctions.erase(entry);
|
|
130741
|
+
// }
|
|
130742
|
+
// ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { VerifyOrsToPush(child); });
|
|
130743
|
+
//}
|
|
130744
|
+
//
|
|
130745
|
+
// bool FilterCombiner::UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr) {
|
|
130746
|
+
// bool left_is_scalar = comparison_expr->left->IsFoldable();
|
|
130747
|
+
// bool right_is_scalar = comparison_expr->right->IsFoldable();
|
|
130748
|
+
//
|
|
130749
|
+
// Expression *non_scalar_expr;
|
|
130750
|
+
// if (left_is_scalar || right_is_scalar) {
|
|
130751
|
+
// // only support comparison with scalar
|
|
130752
|
+
// non_scalar_expr = left_is_scalar ? comparison_expr->right.get() : comparison_expr->left.get();
|
|
130753
|
+
//
|
|
130754
|
+
// if (non_scalar_expr->GetExpressionType() == ExpressionType::BOUND_COLUMN_REF) {
|
|
130755
|
+
// return UpdateFilterByColumn((BoundColumnRefExpression *)non_scalar_expr, comparison_expr);
|
|
130756
|
+
// }
|
|
130757
|
+
// }
|
|
130758
|
+
//
|
|
130759
|
+
// return false;
|
|
130760
|
+
//}
|
|
130761
|
+
//
|
|
130762
|
+
// bool FilterCombiner::UpdateFilterByColumn(BoundColumnRefExpression *column_ref,
|
|
130763
|
+
// BoundComparisonExpression *comparison_expr) {
|
|
130764
|
+
// if (cur_colref_to_push == nullptr) {
|
|
130765
|
+
// cur_colref_to_push = column_ref;
|
|
130766
|
+
//
|
|
130767
|
+
// auto or_conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_OR);
|
|
130768
|
+
// or_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130769
|
+
//
|
|
130770
|
+
// unique_ptr<ConjunctionsToPush> conjs_to_push = make_unique<ConjunctionsToPush>();
|
|
130771
|
+
// conjs_to_push->conjunctions.emplace_back(move(or_conjunction));
|
|
130772
|
+
// conjs_to_push->root_or = cur_root_or;
|
|
130773
|
+
//
|
|
130774
|
+
// auto &&vec_col_conjs = map_col_conjunctions[column_ref];
|
|
130775
|
+
// vec_col_conjs.emplace_back(move(conjs_to_push));
|
|
130776
|
+
// vec_colref_insertion_order.emplace_back(column_ref);
|
|
130777
|
+
// return true;
|
|
130778
|
+
// }
|
|
130779
|
+
//
|
|
130780
|
+
// auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
130781
|
+
// D_ASSERT(entry != map_col_conjunctions.end());
|
|
130782
|
+
// auto &conjunctions_to_push = entry->second.back();
|
|
130783
|
+
//
|
|
130784
|
+
// if (!cur_colref_to_push->Equals(column_ref)) {
|
|
130785
|
+
// // check for multiple colunms in the same root OR node
|
|
130786
|
+
// if (cur_root_or == cur_conjunction) {
|
|
130787
|
+
// return false;
|
|
130788
|
+
// }
|
|
130789
|
+
// // found an AND using a different column, we should stop the look up
|
|
130790
|
+
// if (cur_conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND) {
|
|
130791
|
+
// return false;
|
|
130792
|
+
// }
|
|
130793
|
+
//
|
|
130794
|
+
// // found a different column, AND conditions cannot be preserved anymore
|
|
130795
|
+
// conjunctions_to_push->preserve_and = false;
|
|
130796
|
+
// return true;
|
|
130797
|
+
// }
|
|
130798
|
+
//
|
|
130799
|
+
// auto &last_conjunction = conjunctions_to_push->conjunctions.back();
|
|
130800
|
+
// if (cur_conjunction->GetExpressionType() == last_conjunction->GetExpressionType()) {
|
|
130801
|
+
// last_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130802
|
+
// } else {
|
|
130803
|
+
// auto new_conjunction = make_unique<BoundConjunctionExpression>(cur_conjunction->GetExpressionType());
|
|
130804
|
+
// new_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
130805
|
+
// conjunctions_to_push->conjunctions.emplace_back(move(new_conjunction));
|
|
130806
|
+
// }
|
|
130807
|
+
// return true;
|
|
130808
|
+
//}
|
|
130809
|
+
//
|
|
130810
|
+
// void FilterCombiner::GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids) {
|
|
130811
|
+
// for (const auto colref : vec_colref_insertion_order) {
|
|
130812
|
+
// auto column_index = column_ids[colref->binding.column_index];
|
|
130813
|
+
// if (column_index == COLUMN_IDENTIFIER_ROW_ID) {
|
|
130814
|
+
// break;
|
|
130815
|
+
// }
|
|
130816
|
+
//
|
|
130817
|
+
// for (const auto &conjunctions_to_push : map_col_conjunctions[colref]) {
|
|
130818
|
+
// // root OR filter to push into the TableFilter
|
|
130819
|
+
// auto root_or_filter = make_unique<ConjunctionOrFilter>();
|
|
130820
|
+
// // variable to hold the last conjuntion filter pointer
|
|
130821
|
+
// // the next filter will be added into it, i.e., we create a chain of conjunction filters
|
|
130822
|
+
// ConjunctionFilter *last_conj_filter = root_or_filter.get();
|
|
130823
|
+
//
|
|
130824
|
+
// for (auto &conjunction : conjunctions_to_push->conjunctions) {
|
|
130825
|
+
// if (conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND &&
|
|
130826
|
+
// conjunctions_to_push->preserve_and) {
|
|
130827
|
+
// GenerateConjunctionFilter<ConjunctionAndFilter>(conjunction.get(), last_conj_filter);
|
|
130828
|
+
// } else {
|
|
130829
|
+
// GenerateConjunctionFilter<ConjunctionOrFilter>(conjunction.get(), last_conj_filter);
|
|
130830
|
+
// }
|
|
130831
|
+
// }
|
|
130832
|
+
// table_filter.PushFilter(column_index, move(root_or_filter));
|
|
130833
|
+
// }
|
|
130834
|
+
// }
|
|
130835
|
+
// map_col_conjunctions.clear();
|
|
130836
|
+
// vec_colref_insertion_order.clear();
|
|
130837
|
+
//}
|
|
130803
130838
|
|
|
130804
130839
|
} // namespace duckdb
|
|
130805
130840
|
//===----------------------------------------------------------------------===//
|
|
@@ -133238,6 +133273,7 @@ private:
|
|
|
133238
133273
|
unique_ptr<BaseStatistics> PropagateExpression(BoundBetweenExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133239
133274
|
unique_ptr<BaseStatistics> PropagateExpression(BoundCaseExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133240
133275
|
unique_ptr<BaseStatistics> PropagateExpression(BoundCastExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133276
|
+
unique_ptr<BaseStatistics> PropagateExpression(BoundConjunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133241
133277
|
unique_ptr<BaseStatistics> PropagateExpression(BoundFunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133242
133278
|
unique_ptr<BaseStatistics> PropagateExpression(BoundComparisonExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
133243
133279
|
unique_ptr<BaseStatistics> PropagateExpression(BoundConstantExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
@@ -136257,6 +136293,73 @@ unique_ptr<BaseStatistics> StatisticsPropagator::PropagateExpression(BoundCompar
|
|
|
136257
136293
|
|
|
136258
136294
|
|
|
136259
136295
|
|
|
136296
|
+
|
|
136297
|
+
|
|
136298
|
+
|
|
136299
|
+
|
|
136300
|
+
|
|
136301
|
+
namespace duckdb {
|
|
136302
|
+
|
|
136303
|
+
unique_ptr<BaseStatistics> StatisticsPropagator::PropagateExpression(BoundConjunctionExpression &expr,
|
|
136304
|
+
unique_ptr<Expression> *expr_ptr) {
|
|
136305
|
+
auto is_and = expr.type == ExpressionType::CONJUNCTION_AND;
|
|
136306
|
+
for (idx_t expr_idx = 0; expr_idx < expr.children.size(); expr_idx++) {
|
|
136307
|
+
auto &child = expr.children[expr_idx];
|
|
136308
|
+
auto stats = PropagateExpression(child);
|
|
136309
|
+
if (!child->IsFoldable()) {
|
|
136310
|
+
continue;
|
|
136311
|
+
}
|
|
136312
|
+
// we have a constant in a conjunction
|
|
136313
|
+
// we (1) either prune the child
|
|
136314
|
+
// or (2) replace the entire conjunction with a constant
|
|
136315
|
+
auto constant = ExpressionExecutor::EvaluateScalar(*child);
|
|
136316
|
+
if (constant.IsNull()) {
|
|
136317
|
+
continue;
|
|
136318
|
+
}
|
|
136319
|
+
auto b = BooleanValue::Get(constant);
|
|
136320
|
+
bool prune_child = false;
|
|
136321
|
+
bool constant_value = true;
|
|
136322
|
+
if (b) {
|
|
136323
|
+
// true
|
|
136324
|
+
if (is_and) {
|
|
136325
|
+
// true in and: prune child
|
|
136326
|
+
prune_child = true;
|
|
136327
|
+
} else {
|
|
136328
|
+
// true in OR: replace with TRUE
|
|
136329
|
+
constant_value = true;
|
|
136330
|
+
}
|
|
136331
|
+
} else {
|
|
136332
|
+
// false
|
|
136333
|
+
if (is_and) {
|
|
136334
|
+
// false in AND: replace with FALSE
|
|
136335
|
+
constant_value = false;
|
|
136336
|
+
} else {
|
|
136337
|
+
// false in OR: prune child
|
|
136338
|
+
prune_child = true;
|
|
136339
|
+
}
|
|
136340
|
+
}
|
|
136341
|
+
if (prune_child) {
|
|
136342
|
+
expr.children.erase(expr.children.begin() + expr_idx);
|
|
136343
|
+
expr_idx--;
|
|
136344
|
+
continue;
|
|
136345
|
+
}
|
|
136346
|
+
*expr_ptr = make_unique<BoundConstantExpression>(Value::BOOLEAN(constant_value));
|
|
136347
|
+
return PropagateExpression(*expr_ptr);
|
|
136348
|
+
}
|
|
136349
|
+
if (expr.children.empty()) {
|
|
136350
|
+
// if there are no children left, replace the conjunction with TRUE (for AND) or FALSE (for OR)
|
|
136351
|
+
*expr_ptr = make_unique<BoundConstantExpression>(Value::BOOLEAN(is_and));
|
|
136352
|
+
return PropagateExpression(*expr_ptr);
|
|
136353
|
+
} else if (expr.children.size() == 1) {
|
|
136354
|
+
// if there is one child left, replace the conjunction with that one child
|
|
136355
|
+
*expr_ptr = move(expr.children[0]);
|
|
136356
|
+
}
|
|
136357
|
+
return nullptr;
|
|
136358
|
+
}
|
|
136359
|
+
|
|
136360
|
+
} // namespace duckdb
|
|
136361
|
+
|
|
136362
|
+
|
|
136260
136363
|
//===----------------------------------------------------------------------===//
|
|
136261
136364
|
// DuckDB
|
|
136262
136365
|
//
|
|
@@ -136577,7 +136680,7 @@ bool StatisticsPropagator::ExpressionIsConstant(Expression &expr, const Value &v
|
|
|
136577
136680
|
}
|
|
136578
136681
|
auto &bound_constant = (BoundConstantExpression &)expr;
|
|
136579
136682
|
D_ASSERT(bound_constant.value.type() == val.type());
|
|
136580
|
-
return bound_constant.value
|
|
136683
|
+
return Value::NotDistinctFrom(bound_constant.value, val);
|
|
136581
136684
|
}
|
|
136582
136685
|
|
|
136583
136686
|
bool StatisticsPropagator::ExpressionIsConstantOrNull(Expression &expr, const Value &val) {
|
|
@@ -137361,6 +137464,8 @@ unique_ptr<BaseStatistics> StatisticsPropagator::PropagateExpression(Expression
|
|
|
137361
137464
|
return PropagateExpression((BoundBetweenExpression &)expr, expr_ptr);
|
|
137362
137465
|
case ExpressionClass::BOUND_CASE:
|
|
137363
137466
|
return PropagateExpression((BoundCaseExpression &)expr, expr_ptr);
|
|
137467
|
+
case ExpressionClass::BOUND_CONJUNCTION:
|
|
137468
|
+
return PropagateExpression((BoundConjunctionExpression &)expr, expr_ptr);
|
|
137364
137469
|
case ExpressionClass::BOUND_FUNCTION:
|
|
137365
137470
|
return PropagateExpression((BoundFunctionExpression &)expr, expr_ptr);
|
|
137366
137471
|
case ExpressionClass::BOUND_CAST:
|