diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index 1c09a5bae..142bdb767 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "1-dev3764" +#define DUCKDB_PATCH_VERSION "1-dev3769" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 0 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 1 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v1.0.1-dev3764" +#define DUCKDB_VERSION "v1.0.1-dev3769" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "186e4b5255" +#define DUCKDB_SOURCE_ID "1feb0424de" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/include/duckdb/planner/subquery/flatten_dependent_join.hpp b/src/duckdb/src/include/duckdb/planner/subquery/flatten_dependent_join.hpp index 991e084c4..9b7ad0353 100644 --- a/src/duckdb/src/include/duckdb/planner/subquery/flatten_dependent_join.hpp +++ b/src/duckdb/src/include/duckdb/planner/subquery/flatten_dependent_join.hpp @@ -29,7 +29,8 @@ struct FlattenDependentJoins { bool MarkSubtreeCorrelated(LogicalOperator &op); //! Push the dependent join down a LogicalOperator - unique_ptr PushDownDependentJoin(unique_ptr plan); + unique_ptr PushDownDependentJoin(unique_ptr plan, + bool propagates_null_values = true); Binder &binder; ColumnBinding base_binding; diff --git a/src/duckdb/src/planner/binder/query_node/plan_subquery.cpp b/src/duckdb/src/planner/binder/query_node/plan_subquery.cpp index af70d7e03..860b17914 100644 --- a/src/duckdb/src/planner/binder/query_node/plan_subquery.cpp +++ b/src/duckdb/src/planner/binder/query_node/plan_subquery.cpp @@ -429,7 +429,7 @@ unique_ptr Binder::PlanLateralJoin(unique_ptr // first we check which logical operators have correlated expressions in the first place flatten.DetectCorrelatedExpressions(*right, true); // now we push the dependent join down - auto dependent_join = flatten.PushDownDependentJoin(std::move(right)); + auto dependent_join = flatten.PushDownDependentJoin(std::move(right), join_type != JoinType::INNER); // now the dependent join is fully eliminated // we only need to create the join conditions between the LHS and the RHS diff --git a/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp b/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp index 4c60d299d..ac36e9eae 100644 --- a/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +++ b/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp @@ -87,8 +87,8 @@ bool FlattenDependentJoins::MarkSubtreeCorrelated(LogicalOperator &op) { return has_correlation; } -unique_ptr FlattenDependentJoins::PushDownDependentJoin(unique_ptr plan) { - bool propagate_null_values = true; +unique_ptr FlattenDependentJoins::PushDownDependentJoin(unique_ptr plan, + bool propagate_null_values) { auto result = PushDownDependentJoinInternal(std::move(plan), propagate_null_values, 0); if (!replacement_map.empty()) { // check if we have to replace any COUNT aggregates into "CASE WHEN X IS NULL THEN 0 ELSE COUNT END" @@ -255,18 +255,32 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal delim_column_offset = aggr.groups.size() - correlated_columns.size(); delim_data_offset = aggr.groups.size(); } - if (aggr.groups.size() == new_group_count) { - // we have to perform a LEFT OUTER JOIN between the result of this aggregate and the delim scan - // FIXME: this does not always have to be a LEFT OUTER JOIN, depending on whether aggr.expressions return + bool ungrouped_join = false; + if (aggr.grouping_sets.empty()) { + ungrouped_join = aggr.groups.size() == new_group_count; + } else { + for (auto &grouping_set : aggr.grouping_sets) { + if (grouping_set.size() == new_group_count) { + ungrouped_join = true; + } + } + } + if (ungrouped_join) { + // we have to perform an INNER or LEFT OUTER JOIN between the result of this aggregate and the delim scan + // this does not always have to be a LEFT OUTER JOIN, depending on whether aggr.expressions return // NULL or a value - unique_ptr join = make_uniq(JoinType::INNER); + JoinType join_type = JoinType::INNER; + if (any_join || !parent_propagate_null_values) { + join_type = JoinType::LEFT; + } for (auto &aggr_exp : aggr.expressions) { auto &b_aggr_exp = aggr_exp->Cast(); - if (!b_aggr_exp.PropagatesNullValues() || any_join || !parent_propagate_null_values) { - join = make_uniq(JoinType::LEFT); + if (!b_aggr_exp.PropagatesNullValues()) { + join_type = JoinType::LEFT; break; } } + unique_ptr join = make_uniq(join_type); auto left_index = binder.GenerateTableIndex(); delim_scan = make_uniq(left_index, delim_types); join->children.push_back(std::move(delim_scan));