diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 03133ae8ce963..fa0b9866166d2 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -3907,7 +3907,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev b.ctx.GetSessionVars().StmtCtx.AppendWarning(ErrInternal.GenWithStack("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, tableHintInfo{ + b.tableHintInfo = append(b.tableHintInfo, &tableHintInfo{ sortMergeJoinTables: sortMergeTables, broadcastJoinTables: bcTables, shuffleJoinTables: shuffleJoinTables, @@ -4006,7 +4006,7 @@ func (b *PlanBuilder) TableHints() *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/planner/core/planbuilder.go b/planner/core/planbuilder.go index 274ff4ed4dbfe..e9fb114b7c6f9 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -528,7 +528,7 @@ type PlanBuilder struct { colMapper map[*ast.ColumnNameExpr]int // visitInfo is used for privilege check. visitInfo []visitInfo - tableHintInfo []tableHintInfo + tableHintInfo []*tableHintInfo // optFlag indicates the flags of the optimizer rules. optFlag uint64 // capFlag indicates the capability flags. diff --git a/planner/core/rule_join_reorder_greedy.go b/planner/core/rule_join_reorder_greedy.go index 4b648a9254960..a4853fe959722 100644 --- a/planner/core/rule_join_reorder_greedy.go +++ b/planner/core/rule_join_reorder_greedy.go @@ -79,6 +79,9 @@ func (s *joinReorderGreedySolver) solve(joinNodePlans []LogicalPlan, tracer *joi // Getting here means that there is no join condition between the table used in the leading hint and other tables // For example: select /*+ leading(t3) */ * from t1 join t2 on t1.a=t2.a cross join t3 // We can not let table t3 join first. + // TODO(hawkingrei): we find the problem in the TestHint. + // `select * from t1, t2, t3 union all select /*+ leading(t3, t2) */ * from t1, t2, t3 union all select * from t1, t2, t3` + // this sql should not return the warning. but It will not affect the result. so we will fix it as soon as possible. s.ctx.GetSessionVars().StmtCtx.AppendWarning(ErrInternal.GenWithStack("leading hint is inapplicable, check if the leading hint table has join conditions with other tables")) } cartesianGroup = append(cartesianGroup, newNode.p) diff --git a/planner/core/testdata/integration_suite_out.json b/planner/core/testdata/integration_suite_out.json index ffd1acd853717..f772708cf5368 100644 --- a/planner/core/testdata/integration_suite_out.json +++ b/planner/core/testdata/integration_suite_out.json @@ -6129,7 +6129,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" ] }, { @@ -6150,7 +6150,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" ] }, { diff --git a/planner/core/testdata/join_reorder_suite_out.json b/planner/core/testdata/join_reorder_suite_out.json index bd6e06d73ac23..c6adcc79eeaf6 100644 --- a/planner/core/testdata/join_reorder_suite_out.json +++ b/planner/core/testdata/join_reorder_suite_out.json @@ -7829,24 +7829,21 @@ { "SQL": "select /*+ leading(t2, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", - "│ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ │ └─IndexReader 3.00 root index:StreamAgg", - "│ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", - "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", - "│ └─IndexLookUp(Probe) 3.75 root ", - "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 4.69 root ", - " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" + "Projection 37462.50 root test.t1.a, test.t1.b, test.t2.a, test.t2.b", + "└─HashJoin 37462.50 root inner join, equal:[eq(test.t2.a, test.t1.a) eq(test.t3.a, test.t1.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", + " └─HashJoin(Probe) 29970.00 root CARTESIAN inner join", + " ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + " │ └─IndexReader 3.00 root index:StreamAgg", + " │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + " └─TableReader(Probe) 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" ], - "Warning": [ - "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t1, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", @@ -7866,31 +7863,26 @@ " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], - "Warning": [ - "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t3@sel_2, t2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", - "│ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ │ └─IndexReader 3.00 root index:StreamAgg", - "│ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", - "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", - "│ └─IndexLookUp(Probe) 3.75 root ", - "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 4.69 root ", - " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" + "Projection 37462.50 root test.t1.a, test.t1.b, test.t2.a, test.t2.b", + "└─HashJoin 37462.50 root inner join, equal:[eq(test.t2.a, test.t1.a) eq(test.t3.a, test.t1.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", + " └─HashJoin(Probe) 29970.00 root CARTESIAN inner join", + " ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + " │ └─IndexReader 3.00 root index:StreamAgg", + " │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + " └─TableReader(Probe) 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" ], - "Warning": [ - "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t3@sel_2, t1) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", @@ -7910,9 +7902,7 @@ " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], - "Warning": [ - "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t4) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a not in (select t3.a from t3)", @@ -9912,22 +9902,21 @@ { "SQL": "select /*+ leading(t2, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "HashJoin 12487.50 root inner join, equal:[eq(test.t1.a, test.t3.a)]", - "├─StreamAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ └─IndexReader 7992.00 root index:StreamAgg", - "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t3.a, ", - "│ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:true, stats:pseudo", - "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", + "Projection 99800100.00 root test.t1.a, test.t1.b, test.t2.a, test.t2.b", + "└─HashJoin 99800100.00 root inner join, equal:[eq(test.t2.a, test.t1.a) eq(test.t3.a, test.t1.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) 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" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 79840080.00 root CARTESIAN inner join", + " ├─StreamAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + " │ └─IndexReader 7992.00 root index:StreamAgg", + " │ └─StreamAgg 7992.00 cop[tikv] group by:test.t3.a, ", + " │ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:true, stats:pseudo", + " └─TableReader(Probe) 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" ], - "Warning": [ - "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t4) */ * from t1 left join t2 on t1.a=t2.a right join t4 on t1.b = t4.b where t1.a not in (select t3.a from t3)",