From c7c3f3d0d71c00fdc3d0b292a3eb18dfedfec33a Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Mon, 8 Jan 2024 10:33:17 +0800 Subject: [PATCH] log Signed-off-by: Weizhen Wang --- pkg/planner/core/casetest/hint/hint_test.go | 20 ++++++++- .../hint/testdata/integration_suite_in.json | 6 +++ .../hint/testdata/integration_suite_out.json | 43 ++++++++++++++++++- pkg/planner/core/logical_plan_builder.go | 4 +- pkg/planner/core/planbuilder.go | 2 +- pkg/util/hint/hint.go | 2 +- pkg/util/hint/hint_processor.go | 2 - 7 files changed, 69 insertions(+), 10 deletions(-) diff --git a/pkg/planner/core/casetest/hint/hint_test.go b/pkg/planner/core/casetest/hint/hint_test.go index f676231f07a7f..98916fa3383d6 100644 --- a/pkg/planner/core/casetest/hint/hint_test.go +++ b/pkg/planner/core/casetest/hint/hint_test.go @@ -341,12 +341,28 @@ func TestOptimizeHintOnPartitionTable(t *testing.T) { require.Len(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings(), 2) } -func TestIssue50067(t *testing.T) { +func TestHints(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("create table t1 (a int);") tk.MustExec("create table t2 (a int);") tk.MustExec("create table t3 (a int);") - tk.MustExec("explain select * from t1, t2, t3 union all select /*+ leading(t3, t2) */ * from t1, t2, t3 union all select * from t1, t2, t3;") + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + integrationSuiteData := GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + tt).Rows()) + output[i].Warn = testdata.ConvertRowsToStrings(tk.MustQuery("show warnings").Rows()) + }) + tk.MustQuery("explain format = 'brief' " + tt).Check(testkit.Rows(output[i].Plan...)) + tk.MustQuery("show warnings").Check(testkit.Rows(output[i].Warn...)) + } } diff --git a/pkg/planner/core/casetest/hint/testdata/integration_suite_in.json b/pkg/planner/core/casetest/hint/testdata/integration_suite_in.json index 9959c3a7ca666..9edca6deacc28 100644 --- a/pkg/planner/core/casetest/hint/testdata/integration_suite_in.json +++ b/pkg/planner/core/casetest/hint/testdata/integration_suite_in.json @@ -180,5 +180,11 @@ "explain format = 'brief' select /*+ use_index(t, idx)*/ * from t", "explain format = 'brief' select /*+ use_index(t)*/ * from t" ] + }, + { + "name": "TestHints", + "cases": [ + "select * from t1, t2, t3 union all select /*+ leading(t3, t2) */ * from t1, t2, t3 union all select * from t1, t2, t3" + ] } ] diff --git a/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json b/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json index 369189e4531db..471b39747cf4a 100644 --- a/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json +++ b/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json @@ -325,7 +325,7 @@ " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warn": [ - "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" + "[planner:1815]leading hint is inapplicable, check if the leading hint table is valid" ] }, { @@ -347,7 +347,7 @@ " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warn": [ - "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" + "[planner:1815]leading hint is inapplicable, check if the leading hint table is valid" ] }, { @@ -1862,5 +1862,44 @@ "Warn": null } ] + }, + { + "Name": "TestHints", + "Cases": [ + { + "SQL": "select * from t1, t2, t3 union all select /*+ leading(t3, t2) */ * from t1, t2, t3 union all select * from t1, t2, t3", + "Plan": [ + "Union 3000000000000.00 root ", + "├─HashJoin 1000000000000.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) 100000000.00 root CARTESIAN inner join", + "│ ├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ │ └─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", + "├─Projection 1000000000000.00 root test.t1.a->Column#19, test.t2.a->Column#20, test.t3.a->Column#21", + "│ └─HashJoin 1000000000000.00 root CARTESIAN inner join", + "│ ├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 100000000.00 root CARTESIAN inner join", + "│ ├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ │ └─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:t3 keep order:false, stats:pseudo", + "└─HashJoin 1000000000000.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) 100000000.00 root CARTESIAN inner join", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─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" + ], + "Warn": [ + "Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables" + ] + } + ] } ] diff --git a/pkg/planner/core/logical_plan_builder.go b/pkg/planner/core/logical_plan_builder.go index 364304800faf2..2eed4cbac408b 100644 --- a/pkg/planner/core/logical_plan_builder.go +++ b/pkg/planner/core/logical_plan_builder.go @@ -4114,7 +4114,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev b.ctx.GetSessionVars().StmtCtx.AppendWarning(ErrInternal.FastGen("We can only use the straight_join hint, when we use the leading hint and straight_join hint at the same time, all leading hints will be invalid")) } } - b.tableHintInfo = append(b.tableHintInfo, h.TableHintInfo{ + b.tableHintInfo = append(b.tableHintInfo, &h.TableHintInfo{ SortMergeJoinTables: sortMergeTables, BroadcastJoinTables: bcTables, ShuffleJoinTables: shuffleJoinTables, @@ -4157,7 +4157,7 @@ func (b *PlanBuilder) TableHints() *h.TableHintInfo { if len(b.tableHintInfo) == 0 { return nil } - return &(b.tableHintInfo[len(b.tableHintInfo)-1]) + return b.tableHintInfo[len(b.tableHintInfo)-1] } func (b *PlanBuilder) buildSelect(ctx context.Context, sel *ast.SelectStmt) (p LogicalPlan, err error) { diff --git a/pkg/planner/core/planbuilder.go b/pkg/planner/core/planbuilder.go index 8ef7dab4edc55..fc2347600ab01 100644 --- a/pkg/planner/core/planbuilder.go +++ b/pkg/planner/core/planbuilder.go @@ -210,7 +210,7 @@ type PlanBuilder struct { colMapper map[*ast.ColumnNameExpr]int // visitInfo is used for privilege check. visitInfo []visitInfo - tableHintInfo []hint.TableHintInfo + tableHintInfo []*hint.TableHintInfo // optFlag indicates the flags of the optimizer rules. optFlag uint64 // capFlag indicates the capability flags. diff --git a/pkg/util/hint/hint.go b/pkg/util/hint/hint.go index d7108d6bca0d3..bd6baf2bd2063 100644 --- a/pkg/util/hint/hint.go +++ b/pkg/util/hint/hint.go @@ -567,7 +567,7 @@ var ( ) // CollectUnmatchedHintWarnings collects warnings for unmatched hints from this TableHintInfo. -func CollectUnmatchedHintWarnings(hintInfo TableHintInfo) (warnings []error) { +func CollectUnmatchedHintWarnings(hintInfo *TableHintInfo) (warnings []error) { warnings = append(warnings, collectUnmatchedIndexHintWarning(hintInfo.IndexHintList, false)...) warnings = append(warnings, collectUnmatchedIndexHintWarning(hintInfo.IndexMergeHintList, true)...) warnings = append(warnings, collectUnmatchedJoinHintWarning(HintINLJ, TiDBIndexNestedLoopJoin, hintInfo.IndexNestedLoopJoinTables.INLJTables)...) diff --git a/pkg/util/hint/hint_processor.go b/pkg/util/hint/hint_processor.go index 33ff1d72dfff7..7a296e74ad943 100644 --- a/pkg/util/hint/hint_processor.go +++ b/pkg/util/hint/hint_processor.go @@ -100,8 +100,6 @@ func ExtractTableHintsFromStmtNode(node ast.Node, sctx sessionctx.Context) []*as } } return result - case *ast.ExplainStmt: - return ExtractTableHintsFromStmtNode(x.Stmt, sctx) default: return nil }