Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: rename keep_order hint to order_index hint for mysql compatibility #40945

Merged
merged 12 commits into from
Feb 1, 2023
Merged
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
12 changes: 6 additions & 6 deletions parser/ast/dml.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ const (
HintUse IndexHintType = iota + 1
HintIgnore
HintForce
HintKeepOrder
HintNoKeepOrder
HintOrderIndex
HintNoOrderIndex
)

// IndexHintScope is the type for index hint for join, order by or group by.
Expand Down Expand Up @@ -390,10 +390,10 @@ func (n *IndexHint) Restore(ctx *format.RestoreCtx) error {
indexHintType = "IGNORE INDEX"
case HintForce:
indexHintType = "FORCE INDEX"
case HintKeepOrder:
indexHintType = "KEEP ORDER"
case HintNoKeepOrder:
indexHintType = "NO KEEP ORDER"
case HintOrderIndex:
indexHintType = "ORDER INDEX"
case HintNoOrderIndex:
indexHintType = "NO ORDER INDEX"
default: // Prevent accidents
return errors.New("IndexHintType has an error while matching")
}
Expand Down
2 changes: 1 addition & 1 deletion parser/ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3767,7 +3767,7 @@ func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error {
}
table.Restore(ctx)
}
case "use_index", "ignore_index", "use_index_merge", "force_index", "keep_order", "no_keep_order":
case "use_index", "ignore_index", "use_index_merge", "force_index", "order_index", "no_order_index":
n.Tables[0].Restore(ctx)
ctx.WritePlain(" ")
for i, index := range n.Indexes {
Expand Down
24 changes: 12 additions & 12 deletions parser/ast/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,18 +228,18 @@ func TestTableOptimizerHintRestore(t *testing.T) {
{"IGNORE_INDEX(@sel_1 t1 c1)", "IGNORE_INDEX(@`sel_1` `t1` `c1`)"},
{"IGNORE_INDEX(t1@sel_1 c1)", "IGNORE_INDEX(`t1`@`sel_1` `c1`)"},
{"IGNORE_INDEX(t1@sel_1 partition(p0, p1) c1)", "IGNORE_INDEX(`t1`@`sel_1` PARTITION(`p0`, `p1`) `c1`)"},
{"KEEP_ORDER(t1 c1)", "KEEP_ORDER(`t1` `c1`)"},
{"KEEP_ORDER(test.t1 c1)", "KEEP_ORDER(`test`.`t1` `c1`)"},
{"KEEP_ORDER(@sel_1 t1 c1)", "KEEP_ORDER(@`sel_1` `t1` `c1`)"},
{"KEEP_ORDER(t1@sel_1 c1)", "KEEP_ORDER(`t1`@`sel_1` `c1`)"},
{"KEEP_ORDER(test.t1@sel_1 c1)", "KEEP_ORDER(`test`.`t1`@`sel_1` `c1`)"},
{"KEEP_ORDER(test.t1@sel_1 partition(p0) c1)", "KEEP_ORDER(`test`.`t1`@`sel_1` PARTITION(`p0`) `c1`)"},
{"NO_KEEP_ORDER(t1 c1)", "NO_KEEP_ORDER(`t1` `c1`)"},
{"NO_KEEP_ORDER(test.t1 c1)", "NO_KEEP_ORDER(`test`.`t1` `c1`)"},
{"NO_KEEP_ORDER(@sel_1 t1 c1)", "NO_KEEP_ORDER(@`sel_1` `t1` `c1`)"},
{"NO_KEEP_ORDER(t1@sel_1 c1)", "NO_KEEP_ORDER(`t1`@`sel_1` `c1`)"},
{"NO_KEEP_ORDER(test.t1@sel_1 c1)", "NO_KEEP_ORDER(`test`.`t1`@`sel_1` `c1`)"},
{"NO_KEEP_ORDER(test.t1@sel_1 partition(p0) c1)", "NO_KEEP_ORDER(`test`.`t1`@`sel_1` PARTITION(`p0`) `c1`)"},
{"ORDER_INDEX(t1 c1)", "ORDER_INDEX(`t1` `c1`)"},
{"ORDER_INDEX(test.t1 c1)", "ORDER_INDEX(`test`.`t1` `c1`)"},
{"ORDER_INDEX(@sel_1 t1 c1)", "ORDER_INDEX(@`sel_1` `t1` `c1`)"},
{"ORDER_INDEX(t1@sel_1 c1)", "ORDER_INDEX(`t1`@`sel_1` `c1`)"},
{"ORDER_INDEX(test.t1@sel_1 c1)", "ORDER_INDEX(`test`.`t1`@`sel_1` `c1`)"},
{"ORDER_INDEX(test.t1@sel_1 partition(p0) c1)", "ORDER_INDEX(`test`.`t1`@`sel_1` PARTITION(`p0`) `c1`)"},
{"NO_ORDER_INDEX(t1 c1)", "NO_ORDER_INDEX(`t1` `c1`)"},
{"NO_ORDER_INDEX(test.t1 c1)", "NO_ORDER_INDEX(`test`.`t1` `c1`)"},
{"NO_ORDER_INDEX(@sel_1 t1 c1)", "NO_ORDER_INDEX(@`sel_1` `t1` `c1`)"},
{"NO_ORDER_INDEX(t1@sel_1 c1)", "NO_ORDER_INDEX(`t1`@`sel_1` `c1`)"},
{"NO_ORDER_INDEX(test.t1@sel_1 c1)", "NO_ORDER_INDEX(`test`.`t1`@`sel_1` `c1`)"},
{"NO_ORDER_INDEX(test.t1@sel_1 partition(p0) c1)", "NO_ORDER_INDEX(`test`.`t1`@`sel_1` PARTITION(`p0`) `c1`)"},
{"TIDB_SMJ(`t1`)", "TIDB_SMJ(`t1`)"},
{"TIDB_SMJ(t1)", "TIDB_SMJ(`t1`)"},
{"TIDB_SMJ(t1,t2)", "TIDB_SMJ(`t1`, `t2`)"},
Expand Down
88 changes: 44 additions & 44 deletions parser/hintparser.go

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions parser/hintparser.y
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ import (
hintSwapJoinInputs "SWAP_JOIN_INPUTS"
hintUseIndexMerge "USE_INDEX_MERGE"
hintUseIndex "USE_INDEX"
hintKeepOrder "KEEP_ORDER"
hintNoKeepOrder "NO_KEEP_ORDER"
hintOrderIndex "ORDER_INDEX"
hintNoOrderIndex "NO_ORDER_INDEX"
hintUsePlanCache "USE_PLAN_CACHE"
hintUseToja "USE_TOJA"
hintTimeRange "TIME_RANGE"
Expand Down Expand Up @@ -609,8 +609,8 @@ SupportedIndexLevelOptimizerHintName:
| "IGNORE_INDEX"
| "USE_INDEX_MERGE"
| "FORCE_INDEX"
| "KEEP_ORDER"
| "NO_KEEP_ORDER"
| "ORDER_INDEX"
| "NO_ORDER_INDEX"

SubqueryOptimizerHintName:
"SEMIJOIN"
Expand Down Expand Up @@ -703,8 +703,8 @@ Identifier:
| "SWAP_JOIN_INPUTS"
| "USE_INDEX_MERGE"
| "USE_INDEX"
| "KEEP_ORDER"
| "NO_KEEP_ORDER"
| "ORDER_INDEX"
| "NO_ORDER_INDEX"
| "USE_PLAN_CACHE"
| "USE_TOJA"
| "TIME_RANGE"
Expand Down
4 changes: 2 additions & 2 deletions parser/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -959,8 +959,8 @@ var hintTokenMap = map[string]int{
"SWAP_JOIN_INPUTS": hintSwapJoinInputs,
"USE_INDEX_MERGE": hintUseIndexMerge,
"USE_INDEX": hintUseIndex,
"KEEP_ORDER": hintKeepOrder,
"NO_KEEP_ORDER": hintNoKeepOrder,
"ORDER_INDEX": hintOrderIndex,
"NO_ORDER_INDEX": hintNoOrderIndex,
"USE_PLAN_CACHE": hintUsePlanCache,
"USE_TOJA": hintUseToja,
"TIME_RANGE": hintTimeRange,
Expand Down
16 changes: 8 additions & 8 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3899,39 +3899,39 @@ func TestOptimizerHints(t *testing.T) {
require.Len(t, hints[1].Indexes, 1)
require.Equal(t, "t4", hints[1].Indexes[0].L)

// Test KEEP_ORDER
stmt, _, err = p.Parse("select /*+ KEEP_ORDER(T1,T2), keep_order(t3,t4) */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "")
// Test ORDER_INDEX
stmt, _, err = p.Parse("select /*+ ORDER_INDEX(T1,T2), order_index(t3,t4) */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "")
require.NoError(t, err)
selectStmt = stmt[0].(*ast.SelectStmt)

hints = selectStmt.TableHints
require.Len(t, hints, 2)
require.Equal(t, "keep_order", hints[0].HintName.L)
require.Equal(t, "order_index", hints[0].HintName.L)
require.Len(t, hints[0].Tables, 1)
require.Equal(t, "t1", hints[0].Tables[0].TableName.L)
require.Len(t, hints[0].Indexes, 1)
require.Equal(t, "t2", hints[0].Indexes[0].L)

require.Equal(t, "keep_order", hints[1].HintName.L)
require.Equal(t, "order_index", hints[1].HintName.L)
require.Len(t, hints[1].Tables, 1)
require.Equal(t, "t3", hints[1].Tables[0].TableName.L)
require.Len(t, hints[1].Indexes, 1)
require.Equal(t, "t4", hints[1].Indexes[0].L)

// Test NO_KEEP_ORDER
stmt, _, err = p.Parse("select /*+ NO_KEEP_ORDER(T1,T2), no_keep_order(t3,t4) */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "")
// Test NO_ORDER_INDEX
stmt, _, err = p.Parse("select /*+ NO_ORDER_INDEX(T1,T2), no_order_index(t3,t4) */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "")
require.NoError(t, err)
selectStmt = stmt[0].(*ast.SelectStmt)

hints = selectStmt.TableHints
require.Len(t, hints, 2)
require.Equal(t, "no_keep_order", hints[0].HintName.L)
require.Equal(t, "no_order_index", hints[0].HintName.L)
require.Len(t, hints[0].Tables, 1)
require.Equal(t, "t1", hints[0].Tables[0].TableName.L)
require.Len(t, hints[0].Indexes, 1)
require.Equal(t, "t2", hints[0].Indexes[0].L)

require.Equal(t, "no_keep_order", hints[1].HintName.L)
require.Equal(t, "no_order_index", hints[1].HintName.L)
require.Len(t, hints[1].Tables, 1)
require.Equal(t, "t3", hints[1].Tables[0].TableName.L)
require.Len(t, hints[1].Indexes, 1)
Expand Down
18 changes: 9 additions & 9 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1339,18 +1339,18 @@ func TestKeepOrderHint(t *testing.T) {
tk.MustExec("create definer='root'@'localhost' view v1 as select * from t where a<10 order by a limit 1;")

// If the optimizer can not generate the keep order plan, it will report error
err := tk.ExecToErr("explain select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 limit 1;")
err := tk.ExecToErr("explain select /*+ order_index(t1, idx_a) */ * from t1 where a<10 limit 1;")
require.EqualError(t, err, "[planner:1815]Internal : Can't find a proper physical plan for this query")

err = tk.ExecToErr("explain select /*+ keep_order(t, primary) */ * from t where a<10 limit 1;")
err = tk.ExecToErr("explain select /*+ order_index(t, primary) */ * from t where a<10 limit 1;")
require.EqualError(t, err, "[planner:1815]Internal : Can't find a proper physical plan for this query")

// The partition table can not keep order
tk.MustExec("analyze table th;")
err = tk.ExecToErr("select a from th where a<1 order by a limit 1;")
require.NoError(t, err)

err = tk.ExecToErr("select /*+ keep_order(th, a) */ a from th where a<1 order by a limit 1;")
err = tk.ExecToErr("select /*+ order_index(th, a) */ a from th where a<1 order by a limit 1;")
require.EqualError(t, err, "[planner:1815]Internal : Can't find a proper physical plan for this query")

var input []string
Expand Down Expand Up @@ -1382,29 +1382,29 @@ func TestKeepOrderHintWithBinding(t *testing.T) {
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int, b int, index idx_a(a));")

// create binding for keep_order hint
// create binding for order_index hint
tk.MustExec("select * from t1 where a<10 order by a limit 1;")
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0"))
tk.MustExec("create global binding for select * from t1 where a<10 order by a limit 1 using select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;")
tk.MustExec("create global binding for select * from t1 where a<10 order by a limit 1 using select /*+ order_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;")
tk.MustExec("select * from t1 where a<10 order by a limit 1;")
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` where `a` < ? order by `a` limit ?")
require.Equal(t, res[0][1], "SELECT /*+ keep_order(`t1` `idx_a`)*/ * FROM `test`.`t1` WHERE `a` < 10 ORDER BY `a` LIMIT 1")
require.Equal(t, res[0][1], "SELECT /*+ order_index(`t1` `idx_a`)*/ * FROM `test`.`t1` WHERE `a` < 10 ORDER BY `a` LIMIT 1")

tk.MustExec("drop global binding for select * from t1 where a<10 order by a limit 1;")
tk.MustExec("select * from t1 where a<10 order by a limit 1;")
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0"))
res = tk.MustQuery("show global bindings").Rows()
require.Equal(t, len(res), 0)

// create binding for no_keep_order hint
tk.MustExec("create global binding for select * from t1 where a<10 order by a limit 1 using select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;")
// create binding for no_order_index hint
tk.MustExec("create global binding for select * from t1 where a<10 order by a limit 1 using select /*+ no_order_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;")
tk.MustExec("select * from t1 where a<10 order by a limit 1;")
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` where `a` < ? order by `a` limit ?")
require.Equal(t, res[0][1], "SELECT /*+ no_keep_order(`t1` `idx_a`)*/ * FROM `test`.`t1` WHERE `a` < 10 ORDER BY `a` LIMIT 1")
require.Equal(t, res[0][1], "SELECT /*+ no_order_index(`t1` `idx_a`)*/ * FROM `test`.`t1` WHERE `a` < 10 ORDER BY `a` LIMIT 1")

tk.MustExec("drop global binding for select * from t1 where a<10 order by a limit 1;")
tk.MustExec("select * from t1 where a<10 order by a limit 1;")
Expand Down
20 changes: 10 additions & 10 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ const (
HintIgnoreIndex = "ignore_index"
// HintForceIndex make optimizer to use this index even if it thinks a table scan is more efficient.
HintForceIndex = "force_index"
// HintKeepOrder is hint enforce using some indexes and keep the index's order.
HintKeepOrder = "keep_order"
// HintNoKeepOrder is hint enforce using some indexes and not keep the index's order.
HintNoKeepOrder = "no_keep_order"
// HintOrderIndex is hint enforce using some indexes and keep the index's order.
HintOrderIndex = "order_index"
// HintNoOrderIndex is hint enforce using some indexes and not keep the index's order.
HintNoOrderIndex = "no_order_index"
// HintAggToCop is hint enforce pushing aggregation to coprocessor.
HintAggToCop = "agg_to_cop"
// HintReadFromStorage is hint enforce some tables read from specific type of storage.
Expand Down Expand Up @@ -3617,7 +3617,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev
// Set warning for the hint that requires the table name.
switch hint.HintName.L {
case TiDBMergeJoin, HintSMJ, TiDBIndexNestedLoopJoin, HintINLJ, HintINLHJ, HintINLMJ,
TiDBHashJoin, HintHJ, HintUseIndex, HintIgnoreIndex, HintForceIndex, HintKeepOrder, HintNoKeepOrder, HintIndexMerge, HintLeading:
TiDBHashJoin, HintHJ, HintUseIndex, HintIgnoreIndex, HintForceIndex, HintOrderIndex, HintNoOrderIndex, HintIndexMerge, HintLeading:
if len(hint.Tables) == 0 {
b.pushHintWithoutTableWarning(hint)
continue
Expand Down Expand Up @@ -3653,7 +3653,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev
aggHints.preferAggType |= preferStreamAgg
case HintAggToCop:
aggHints.preferAggToCop = true
case HintUseIndex, HintIgnoreIndex, HintForceIndex, HintKeepOrder, HintNoKeepOrder:
case HintUseIndex, HintIgnoreIndex, HintForceIndex, HintOrderIndex, HintNoOrderIndex:
dbName := hint.Tables[0].DBName
if dbName.L == "" {
dbName = model.NewCIStr(b.ctx.GetSessionVars().CurrentDB)
Expand All @@ -3666,10 +3666,10 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev
hintType = ast.HintIgnore
case HintForceIndex:
hintType = ast.HintForce
case HintKeepOrder:
hintType = ast.HintKeepOrder
case HintNoKeepOrder:
hintType = ast.HintNoKeepOrder
case HintOrderIndex:
hintType = ast.HintOrderIndex
case HintNoOrderIndex:
hintType = ast.HintNoOrderIndex
}
indexHintList = append(indexHintList, indexHintInfo{
dbName: dbName,
Expand Down
4 changes: 2 additions & 2 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1420,10 +1420,10 @@ func getPossibleAccessPaths(ctx sessionctx.Context, tableHints *tableHintInfo, i
// our cost estimation is not reliable.
hasUseOrForce = true
path.Forced = true
if hint.HintType == ast.HintKeepOrder {
if hint.HintType == ast.HintOrderIndex {
path.ForceKeepOrder = true
}
if hint.HintType == ast.HintNoKeepOrder {
if hint.HintType == ast.HintNoOrderIndex {
path.ForceNoKeepOrder = true
}
available = append(available, path)
Expand Down
Loading