From b522279734d2df80b3d556dc1fde839b19397711 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 9 Nov 2022 17:14:21 +0800 Subject: [PATCH 1/3] fixup --- planner/core/integration_test.go | 13 +++++++++++++ planner/core/rule_join_elimination.go | 23 +++++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 87f7642be569c..3addc331cdba4 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -1538,6 +1538,19 @@ func (s *testIntegrationSuite) TestIndexMergeHint4CNF(c *C) { } } +func (s *testIntegrationSuite) TestOuterJoinEliminationForIssue18216(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2;") + tk.MustExec("create table t1 (a int, c int);") + tk.MustExec("insert into t1 values (1, 1), (1, 2), (2, 3), (2, 4);") + tk.MustExec("create table t2 (a int, c int);") + tk.MustExec("insert into t2 values (1, 1), (1, 2), (2, 3), (2, 4);") + // The output might be unstable. + tk.MustExec("select group_concat(c order by (select group_concat(c order by a) from t2 where a=t1.a)) from t1; ") + tk.MustQuery("select group_concat(c order by (select group_concat(c order by c) from t2 where a=t1.a), c desc) from t1;").Check(testkit.Rows("2,1,4,3")) +} + func (s *testIntegrationSuite) TestInvisibleIndex(c *C) { tk := testkit.NewTestKit(c, s.store) diff --git a/planner/core/rule_join_elimination.go b/planner/core/rule_join_elimination.go index 025d538aafbc3..538e3a1e70cb8 100644 --- a/planner/core/rule_join_elimination.go +++ b/planner/core/rule_join_elimination.go @@ -26,12 +26,12 @@ type outerJoinEliminator struct { } // tryToEliminateOuterJoin will eliminate outer join plan base on the following rules -// 1. outer join elimination: For example left outer join, if the parent only use the -// columns from left table and the join key of right table(the inner table) is a unique -// key of the right table. the left outer join can be eliminated. -// 2. outer join elimination with duplicate agnostic aggregate functions: For example left outer join. -// If the parent only use the columns from left table with 'distinct' label. The left outer join can -// be eliminated. +// 1. outer join elimination: For example left outer join, if the parent only use the +// columns from left table and the join key of right table(the inner table) is a unique +// key of the right table. the left outer join can be eliminated. +// 2. outer join elimination with duplicate agnostic aggregate functions: For example left outer join. +// If the parent only use the columns from left table with 'distinct' label. The left outer join can +// be eliminated. func (o *outerJoinEliminator) tryToEliminateOuterJoin(p *LogicalJoin, aggCols []*expression.Column, parentCols []*expression.Column) (LogicalPlan, bool, error) { var innerChildIdx int switch p.JoinType { @@ -148,10 +148,10 @@ func (o *outerJoinEliminator) isInnerJoinKeysContainIndex(innerPlan LogicalPlan, // It extracts all the columns from the duplicate agnostic aggregate functions. // The returned column set is nil if not all the aggregate functions are duplicate agnostic. // Only the following functions are considered to be duplicate agnostic: -// 1. MAX(arg) -// 2. MIN(arg) -// 3. FIRST_ROW(arg) -// 4. Other agg functions with DISTINCT flag, like SUM(DISTINCT arg) +// 1. MAX(arg) +// 2. MIN(arg) +// 3. FIRST_ROW(arg) +// 4. Other agg functions with DISTINCT flag, like SUM(DISTINCT arg) func GetDupAgnosticAggCols( p LogicalPlan, oldAggCols []*expression.Column, // Reuse the original buffer. @@ -206,6 +206,9 @@ func (o *outerJoinEliminator) doOptimize(p LogicalPlan, aggCols []*expression.Co for _, expr := range aggDesc.Args { parentCols = append(parentCols, expression.ExtractColumns(expr)...) } + for _, byItem := range aggDesc.OrderByItems { + parentCols = append(parentCols, expression.ExtractColumns(byItem.Expr)...) + } } default: parentCols = append(parentCols[:0], p.Schema().Columns...) From f66cc5c384d983dea4d4adf2c50eff2e8d8e21a6 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 9 Nov 2022 17:17:05 +0800 Subject: [PATCH 2/3] fixup --- planner/core/rule_join_elimination.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/planner/core/rule_join_elimination.go b/planner/core/rule_join_elimination.go index 538e3a1e70cb8..1638774d42210 100644 --- a/planner/core/rule_join_elimination.go +++ b/planner/core/rule_join_elimination.go @@ -26,12 +26,12 @@ type outerJoinEliminator struct { } // tryToEliminateOuterJoin will eliminate outer join plan base on the following rules -// 1. outer join elimination: For example left outer join, if the parent only use the -// columns from left table and the join key of right table(the inner table) is a unique -// key of the right table. the left outer join can be eliminated. -// 2. outer join elimination with duplicate agnostic aggregate functions: For example left outer join. -// If the parent only use the columns from left table with 'distinct' label. The left outer join can -// be eliminated. +// 1. outer join elimination: For example left outer join, if the parent only use the +// columns from left table and the join key of right table(the inner table) is a unique +// key of the right table. the left outer join can be eliminated. +// 2. outer join elimination with duplicate agnostic aggregate functions: For example left outer join. +// If the parent only use the columns from left table with 'distinct' label. The left outer join can +// be eliminated. func (o *outerJoinEliminator) tryToEliminateOuterJoin(p *LogicalJoin, aggCols []*expression.Column, parentCols []*expression.Column) (LogicalPlan, bool, error) { var innerChildIdx int switch p.JoinType { @@ -148,10 +148,10 @@ func (o *outerJoinEliminator) isInnerJoinKeysContainIndex(innerPlan LogicalPlan, // It extracts all the columns from the duplicate agnostic aggregate functions. // The returned column set is nil if not all the aggregate functions are duplicate agnostic. // Only the following functions are considered to be duplicate agnostic: -// 1. MAX(arg) -// 2. MIN(arg) -// 3. FIRST_ROW(arg) -// 4. Other agg functions with DISTINCT flag, like SUM(DISTINCT arg) +// 1. MAX(arg) +// 2. MIN(arg) +// 3. FIRST_ROW(arg) +// 4. Other agg functions with DISTINCT flag, like SUM(DISTINCT arg) func GetDupAgnosticAggCols( p LogicalPlan, oldAggCols []*expression.Column, // Reuse the original buffer. From e58d1ebd0bdc9546860dfc3b7a101b6e8ea371a6 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 9 Nov 2022 17:17:39 +0800 Subject: [PATCH 3/3] fixup --- planner/core/rule_join_elimination.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/planner/core/rule_join_elimination.go b/planner/core/rule_join_elimination.go index 1638774d42210..495b8d989e628 100644 --- a/planner/core/rule_join_elimination.go +++ b/planner/core/rule_join_elimination.go @@ -148,10 +148,10 @@ func (o *outerJoinEliminator) isInnerJoinKeysContainIndex(innerPlan LogicalPlan, // It extracts all the columns from the duplicate agnostic aggregate functions. // The returned column set is nil if not all the aggregate functions are duplicate agnostic. // Only the following functions are considered to be duplicate agnostic: -// 1. MAX(arg) -// 2. MIN(arg) -// 3. FIRST_ROW(arg) -// 4. Other agg functions with DISTINCT flag, like SUM(DISTINCT arg) +// 1. MAX(arg) +// 2. MIN(arg) +// 3. FIRST_ROW(arg) +// 4. Other agg functions with DISTINCT flag, like SUM(DISTINCT arg) func GetDupAgnosticAggCols( p LogicalPlan, oldAggCols []*expression.Column, // Reuse the original buffer.