diff --git a/planner/core/rule_join_reorder_test.go b/planner/core/rule_join_reorder_test.go index 3d6aed01a52c3..55cfe66320e77 100644 --- a/planner/core/rule_join_reorder_test.go +++ b/planner/core/rule_join_reorder_test.go @@ -201,6 +201,20 @@ func TestJoinOrderHintWithBinding(t *testing.T) { require.Equal(t, res[0][0], "select * from ( `test` . `t1` join `test` . `t2` on `t1` . `a` = `t2` . `a` ) join `test` . `t3` on `t2` . `b` = `t3` . `b`") tk.MustExec("drop global binding for select * from t1 join t2 on t1.a=t2.a join t3 on t2.b=t3.b") + + // test for outer join + tk.MustExec("select * from t1 join t2 on t1.a=t2.a left join t3 on t2.b=t3.b") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, len(res), 0) + + tk.MustExec("create global binding for select * from t1 join t2 on t1.a=t2.a left join t3 on t2.b=t3.b using select /*+ leading(t2) */ * from t1 join t2 on t1.a=t2.a left join t3 on t2.b=t3.b") + tk.MustExec("select * from t1 join t2 on t1.a=t2.a left join t3 on t2.b=t3.b") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select * from ( `test` . `t1` join `test` . `t2` on `t1` . `a` = `t2` . `a` ) left join `test` . `t3` on `t2` . `b` = `t3` . `b`") + + tk.MustExec("drop global binding for select * from t1 join t2 on t1.a=t2.a join t3 on t2.b=t3.b") } func TestJoinOrderHint4StaticPartitionTable(t *testing.T) { diff --git a/planner/core/testdata/join_reorder_suite_in.json b/planner/core/testdata/join_reorder_suite_in.json index 72543de875aaf..5ef0edb64351b 100644 --- a/planner/core/testdata/join_reorder_suite_in.json +++ b/planner/core/testdata/join_reorder_suite_in.json @@ -241,7 +241,16 @@ "select /*+ leading(t3) */ * from t1 join t2 on t1.a=t2.a cross join t3", "select /*+ leading(t2, t3) */ * from t1 join t2 on t1.a=t2.a cross join t3", "select /*+ leading(t3, t2) */ * from t1 join t2 on t1.a=t2.a cross join t3", - "select /*+ leading(t3, t1) */ * from t1 join t2 on t1.a=t2.a cross join t3" + "select /*+ leading(t3, t1) */ * from t1 join t2 on t1.a=t2.a cross join t3", + + // outer join + outer join types + "select /*+ leading(t2, t1) */ * from t1 left join t2 on t1.a=t2.a cross join t3", + "select /*+ leading(t2, t1) */ * from t1 right join t2 on t1.a=t2.a cross join t3", + "select /*+ leading(t3, t1) */ * from t1 right join t2 on t1.a=t2.a right join t3 on t2.b=t3.b", + "select /*+ leading(t1) */ * from t1 left join t2 on t1.a=t2.a straight_join t3", + "select /*+ leading(t1) */ * from t1 right join t2 on t1.a=t2.a straight_join t3", + "select /*+ leading(t1) */ * from t1 left join t2 on t1.a=t2.a cross join t3", + "select /*+ leading(t1) */ * from t1 right join t2 on t1.a=t2.a cross join t3" ] }, { diff --git a/planner/core/testdata/join_reorder_suite_out.json b/planner/core/testdata/join_reorder_suite_out.json index 59c64c79a7efc..41ed45dcb3cd4 100644 --- a/planner/core/testdata/join_reorder_suite_out.json +++ b/planner/core/testdata/join_reorder_suite_out.json @@ -5277,6 +5277,119 @@ " └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" ], "Warning": null + }, + { + "SQL": "select /*+ leading(t2, t1) */ * from t1 left join t2 on t1.a=t2.a cross join t3", + "Plan": [ + "HashJoin 124875000.00 root CARTESIAN inner join", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warning": [ + "Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables" + ] + }, + { + "SQL": "select /*+ leading(t2, t1) */ * from t1 right join t2 on t1.a=t2.a cross join t3", + "Plan": [ + "HashJoin 124875000.00 root CARTESIAN inner join", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root right outer join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warning": [ + "Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables" + ] + }, + { + "SQL": "select /*+ leading(t3, t1) */ * from t1 right join t2 on t1.a=t2.a right join t3 on t2.b=t3.b", + "Plan": [ + "HashJoin 15609.38 root right outer join, equal:[eq(test.t2.b, test.t3.b)]", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root right outer join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warning": [ + "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", + "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" + ] + }, + { + "SQL": "select /*+ leading(t1) */ * from t1 left join t2 on t1.a=t2.a straight_join t3", + "Plan": [ + "HashJoin 124875000.00 root CARTESIAN inner join", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ leading(t1) */ * from t1 right join t2 on t1.a=t2.a straight_join t3", + "Plan": [ + "HashJoin 124875000.00 root CARTESIAN inner join", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root right outer join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ leading(t1) */ * from t1 left join t2 on t1.a=t2.a cross join t3", + "Plan": [ + "HashJoin 124875000.00 root CARTESIAN inner join", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ leading(t1) */ * from t1 right join t2 on t1.a=t2.a cross join t3", + "Plan": [ + "HashJoin 124875000.00 root CARTESIAN inner join", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root right outer join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warning": null } ] },