Skip to content

Commit e8fd916

Browse files
AilinKidti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#44409
Signed-off-by: ti-chi-bot <[email protected]>
1 parent e954f27 commit e8fd916

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

planner/core/rule_join_reorder.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func extractJoinGroup(p LogicalPlan) (group []LogicalPlan, eqEdges []*expression
133133
tmpOtherConds = append(tmpOtherConds, join.OtherConditions...)
134134
tmpOtherConds = append(tmpOtherConds, join.LeftConditions...)
135135
tmpOtherConds = append(tmpOtherConds, join.RightConditions...)
136-
if join.JoinType == LeftOuterJoin || join.JoinType == RightOuterJoin {
136+
if join.JoinType == LeftOuterJoin || join.JoinType == RightOuterJoin || join.JoinType == LeftOuterSemiJoin || join.JoinType == AntiLeftOuterSemiJoin {
137137
for range join.EqualConditions {
138138
abType := &joinTypeWithExtMsg{JoinType: join.JoinType}
139139
// outer join's other condition should be bound with the connecting edge.
@@ -426,6 +426,13 @@ func (s *baseSingleGroupJoinOrderSolver) makeJoin(leftPlan, rightPlan LogicalPla
426426
remainOtherConds, otherConds = expression.FilterOutInPlace(remainOtherConds, func(expr expression.Expression) bool {
427427
return expression.ExprFromSchema(expr, mergedSchema)
428428
})
429+
if (joinType.JoinType == LeftOuterJoin || joinType.JoinType == RightOuterJoin || joinType.JoinType == LeftOuterSemiJoin || joinType.JoinType == AntiLeftOuterSemiJoin) && len(otherConds) > 0 {
430+
// the original outer join's other conditions has been bound to the outer join Edge,
431+
// these remained other condition here shouldn't be appended to it because on-mismatch
432+
// logic will produce more append-null rows which is banned in original semantic.
433+
remainOtherConds = append(remainOtherConds, otherConds...) // nozero
434+
otherConds = otherConds[:0]
435+
}
429436
if len(joinType.outerBindCondition) > 0 {
430437
remainOBOtherConds := make([]expression.Expression, len(joinType.outerBindCondition))
431438
copy(remainOBOtherConds, joinType.outerBindCondition)
@@ -469,6 +476,14 @@ func (s *baseSingleGroupJoinOrderSolver) makeBushyJoin(cartesianJoinGroup []Logi
469476
}
470477
cartesianJoinGroup, resultJoinGroup = resultJoinGroup, cartesianJoinGroup
471478
}
479+
// other conditions may be possible to exist across different cartesian join group, resolving cartesianJoin first then adding another selection.
480+
if len(s.otherConds) > 0 {
481+
additionSelection := LogicalSelection{
482+
Conditions: s.otherConds,
483+
}.Init(cartesianJoinGroup[0].SCtx(), cartesianJoinGroup[0].SelectBlockOffset())
484+
additionSelection.SetChildren(cartesianJoinGroup[0])
485+
cartesianJoinGroup[0] = additionSelection
486+
}
472487
return cartesianJoinGroup[0]
473488
}
474489

planner/core/rule_join_reorder_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ func TestJoinOrderHintWithBinding(t *testing.T) {
216216
tk.MustExec("drop global binding for select * from t1 join t2 on t1.a=t2.a join t3 on t2.b=t3.b")
217217
}
218218

219+
<<<<<<< HEAD
219220
func TestJoinOrderHint4StaticPartitionTable(t *testing.T) {
220221
store := testkit.CreateMockStore(t)
221222

@@ -351,6 +352,36 @@ func TestLeadingJoinHint4OuterJoin(t *testing.T) {
351352
tk.MustExec("create table t8(a int, b int, key(a));")
352353
tk.MustExec("set @@tidb_enable_outer_join_reorder=true")
353354
runJoinReorderTestData(t, tk, "TestLeadingJoinHint4OuterJoin")
355+
=======
356+
func TestAdditionOtherConditionsRemained4OuterJoin(t *testing.T) {
357+
store, _ := testkit.CreateMockStoreAndDomain(t)
358+
tk := testkit.NewTestKit(t, store)
359+
360+
tk.MustExec("use test")
361+
tk.MustExec("CREATE TABLE `queries_identifier` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL,\n PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */\n ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;")
362+
tk.MustExec("CREATE TABLE `queries_program` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `identifier_id` int(11) NOT NULL,\n PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n UNIQUE KEY `identifier_id` (`identifier_id`),\n CONSTRAINT `queries_program_identifier_id_70ff12a6_fk_queries_identifier_id` FOREIGN KEY (`identifier_id`) REFERENCES `test`.`queries_identifier` (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;")
363+
tk.MustExec("CREATE TABLE `queries_channel` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `identifier_id` int(11) NOT NULL,\n PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n UNIQUE KEY `identifier_id` (`identifier_id`),\n CONSTRAINT `queries_channel_identifier_id_06ac3513_fk_queries_identifier_id` FOREIGN KEY (`identifier_id`) REFERENCES `test`.`queries_identifier` (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;")
364+
365+
tk.MustExec("INSERT INTO queries_identifier(`id`, `name`) values(13, 'i1'), (14, 'i2'), (15, 'i3');")
366+
tk.MustExec("INSERT INTO queries_program(`id`, `identifier_id`) values(8, 13), (9, 14);")
367+
tk.MustExec("INSERT INTO queries_channel(`id`, `identifier_id`) values(5, 13);")
368+
369+
tk.MustQuery("SELECT `queries_identifier`.`id`, `queries_identifier`.`name` FROM `queries_identifier` LEFT OUTER JOIN `queries_channel` ON (`queries_identifier`.`id` = `queries_channel`.`identifier_id`) INNER JOIN `queries_program` ON (`queries_identifier`.`id` = `queries_program`.`identifier_id`) WHERE ((`queries_channel`.`id` = 5 AND `queries_program`.`id` = 9) OR `queries_program`.`id` = 8) ORDER BY `queries_identifier`.`id` ASC;").Check(testkit.Rows("" +
370+
"13 i1"))
371+
tk.MustQuery("SELECT `queries_identifier`.`id`, `queries_identifier`.`name` FROM `queries_identifier` RIGHT OUTER JOIN `queries_channel` ON (`queries_identifier`.`id` = `queries_channel`.`identifier_id`) INNER JOIN `queries_program` ON (`queries_identifier`.`id` = `queries_program`.`identifier_id`) WHERE ((`queries_channel`.`id` = 5 AND `queries_program`.`id` = 9) OR `queries_program`.`id` = 8) ORDER BY `queries_identifier`.`id` ASC;").Check(testkit.Rows("" +
372+
"13 i1"))
373+
tk.MustQuery("explain format = 'brief' SELECT `queries_identifier`.`id`, `queries_identifier`.`name` FROM `queries_identifier` LEFT OUTER JOIN `queries_channel` ON (`queries_identifier`.`id` = `queries_channel`.`identifier_id`) INNER JOIN `queries_program` ON (`queries_identifier`.`id` = `queries_program`.`identifier_id`) WHERE ((`queries_channel`.`id` = 5 AND `queries_program`.`id` = 9) OR `queries_program`.`id` = 8) ORDER BY `queries_identifier`.`id` ASC;").Check(testkit.Rows(""+
374+
"Sort 2.50 root test.queries_identifier.id",
375+
"└─Projection 2.50 root test.queries_identifier.id, test.queries_identifier.name",
376+
" └─Selection 2.50 root or(and(eq(test.queries_channel.id, 5), eq(test.queries_program.id, 9)), eq(test.queries_program.id, 8))",
377+
" └─IndexJoin 3.12 root left outer join, inner:IndexReader, outer key:test.queries_identifier.id, inner key:test.queries_channel.identifier_id, equal cond:eq(test.queries_identifier.id, test.queries_channel.identifier_id)",
378+
" ├─IndexHashJoin(Build) 2.50 root inner join, inner:TableReader, outer key:test.queries_program.identifier_id, inner key:test.queries_identifier.id, equal cond:eq(test.queries_program.identifier_id, test.queries_identifier.id)",
379+
" │ ├─Batch_Point_Get(Build) 2.00 root table:queries_program handle:[8 9], keep order:false, desc:false",
380+
" │ └─TableReader(Probe) 2.00 root data:TableRangeScan",
381+
" │ └─TableRangeScan 2.00 cop[tikv] table:queries_identifier range: decided by [test.queries_program.identifier_id], keep order:false, stats:pseudo",
382+
" └─IndexReader(Probe) 2.50 root index:IndexRangeScan",
383+
" └─IndexRangeScan 2.50 cop[tikv] table:queries_channel, index:identifier_id(identifier_id) range: decided by [eq(test.queries_channel.identifier_id, test.queries_identifier.id)], keep order:false, stats:pseudo"))
384+
>>>>>>> 0cd5372afb8 (planner: fix join reorder will append remained other condition to an outer join (#44409))
354385
}
355386

356387
func TestOuterJoinWIthEqCondCrossInnerJoin(t *testing.T) {

0 commit comments

Comments
 (0)