Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
// cte hint
"explain format = 'plan_tree' select /*+ qb_name(qb_v7, v7), merge(@qb_v7) */ * from v7;",
"explain format = 'plan_tree' select /*+ qb_name(qb_v8, v8), merge(@qb_v8) */ * from v8;",
"explain format = 'plan_tree' with tt as (select * from t1 where a=2 limit 100) select /*+ qb_name(my_select, tt@sel_1), ignore_index(t1@my_select, idx_a) */ * from tt;",
"explain format = 'plan_tree' with tt as (select * from t1 where a=2 limit 100) select /*+ qb_name(my_select_i_am_unused, tt@sel_1), ignore_index(t1@my_select, idx_a) */ * from tt;",

// agg to cop hint
"explain format = 'plan_tree' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;",
Expand Down
26 changes: 26 additions & 0 deletions pkg/planner/core/casetest/hint/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,32 @@
],
"Warn": null
},
{
"SQL": "explain format = 'plan_tree' with tt as (select * from t1 where a=2 limit 100) select /*+ qb_name(my_select, tt@sel_1), ignore_index(t1@my_select, idx_a) */ * from tt;",
"Plan": [
"IndexLookUp root limit embedded(offset:0, count:100)",
"├─Limit(Build) cop[tikv] offset:0, count:100",
"│ └─IndexRangeScan cop[tikv] table:t1, index:idx_a(a) range:[2,2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) cop[tikv] table:t1 keep order:false, stats:pseudo"
],
"Warn": [
"[planner:1815]Hint ignore_index(`t1`@`my_select` `idx_a`) is ignored due to unknown query block name",
"[planner:1815]The qb_name hint my_select is unused, please check whether the table list in the qb_name hint my_select is correct"
]
},
{
"SQL": "explain format = 'plan_tree' with tt as (select * from t1 where a=2 limit 100) select /*+ qb_name(my_select_i_am_unused, tt@sel_1), ignore_index(t1@my_select, idx_a) */ * from tt;",
"Plan": [
"IndexLookUp root limit embedded(offset:0, count:100)",
"├─Limit(Build) cop[tikv] offset:0, count:100",
"│ └─IndexRangeScan cop[tikv] table:t1, index:idx_a(a) range:[2,2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) cop[tikv] table:t1 keep order:false, stats:pseudo"
],
"Warn": [
"[planner:1815]Hint ignore_index(`t1`@`my_select` `idx_a`) is ignored due to unknown query block name",
"[planner:1815]The qb_name hint my_select_i_am_unused is unused, please check whether the table list in the qb_name hint my_select_i_am_unused is correct"
]
},
{
"SQL": "explain format = 'plan_tree' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;",
"Plan": [
Expand Down
26 changes: 26 additions & 0 deletions pkg/planner/core/casetest/hint/testdata/integration_suite_xut.json
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,32 @@
],
"Warn": null
},
{
"SQL": "explain format = 'plan_tree' with tt as (select * from t1 where a=2 limit 100) select /*+ qb_name(my_select, tt@sel_1), ignore_index(t1@my_select, idx_a) */ * from tt;",
"Plan": [
"IndexLookUp root limit embedded(offset:0, count:100)",
"├─Limit(Build) cop[tikv] offset:0, count:100",
"│ └─IndexRangeScan cop[tikv] table:t1, index:idx_a(a) range:[2,2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) cop[tikv] table:t1 keep order:false, stats:pseudo"
],
"Warn": [
"[planner:1815]Hint ignore_index(`t1`@`my_select` `idx_a`) is ignored due to unknown query block name",
"[planner:1815]The qb_name hint my_select is unused, please check whether the table list in the qb_name hint my_select is correct"
]
},
{
"SQL": "explain format = 'plan_tree' with tt as (select * from t1 where a=2 limit 100) select /*+ qb_name(my_select_i_am_unused, tt@sel_1), ignore_index(t1@my_select, idx_a) */ * from tt;",
"Plan": [
"IndexLookUp root limit embedded(offset:0, count:100)",
"├─Limit(Build) cop[tikv] offset:0, count:100",
"│ └─IndexRangeScan cop[tikv] table:t1, index:idx_a(a) range:[2,2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) cop[tikv] table:t1 keep order:false, stats:pseudo"
],
"Warn": [
"[planner:1815]Hint ignore_index(`t1`@`my_select` `idx_a`) is ignored due to unknown query block name",
"[planner:1815]The qb_name hint my_select_i_am_unused is unused, please check whether the table list in the qb_name hint my_select_i_am_unused is correct"
]
},
{
"SQL": "explain format = 'plan_tree' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;",
"Plan": [
Expand Down
32 changes: 32 additions & 0 deletions pkg/planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4759,6 +4759,7 @@ func (b *PlanBuilder) tryBuildCTE(ctx context.Context, tn *ast.TableName, asName
return p, nil
}

b.warnViewStyleHintsForCTE(tn, asName)
b.handleHelper.pushMap(nil)

hasLimit := false
Expand Down Expand Up @@ -4856,6 +4857,37 @@ func (b *PlanBuilder) tryBuildCTE(ctx context.Context, tn *ast.TableName, asName
return nil, nil
}

func (b *PlanBuilder) warnViewStyleHintsForCTE(tn *ast.TableName, asName *ast.CIStr) {
if b.hintProcessor == nil || len(b.hintProcessor.ViewQBNameToTable) == 0 {
return
}

// View-style QB_NAME hints are collected before name resolution. If they
// target a CTE reference, the CTE path cannot consume the forwarded hints,
// so report them as ignored instead of silently dropping them.
cteRefName := tn.Name
if asName != nil && asName.L != "" {
cteRefName = *asName
}
currentOffset := b.getSelectOffset()
for qbName, hintedTables := range b.hintProcessor.ViewQBNameToTable {
if len(hintedTables) == 0 || hintedTables[0].TableName.L != cteRefName.L {
continue
}
hintOffset := 1
if hintedTables[0].QBName.L != "" {
hintOffset = b.hintProcessor.GetHintOffset(hintedTables[0].QBName, currentOffset)
}
if hintOffset != currentOffset {
continue
}
for _, tableHint := range b.hintProcessor.ViewQBNameToHints[qbName] {
hintStr := h.RestoreTableOptimizerHint(tableHint)
b.ctx.GetSessionVars().StmtCtx.SetHintWarning(fmt.Sprintf("Hint %s is ignored due to unknown query block name", hintStr))
}
}
}

// computeCTEInlineFlag, Combine the declaration of CTE and the use of CTE to jointly determine **whether a CTE can be inlined**
/*
There are some cases that CTE must be not inlined.
Expand Down
Loading