optimizer hint restore position wrong cause binding failed or hint ignored after binding
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
Please answer these questions before submitting your issue. Thanks!
### 1. Minimal reproduce step (Required)
```
create table t1 (a bigint, b bigint, key a_idx(a));
insert into t1 values (1, 2);
insert into t1 select * from t1; // repeat 20 times
select /*+ MAX_EXECUTION_TIME(5000) */ /*!40001 SQL_NO_CACHE */ * from t1;
create global binding for select /*+ MAX_EXECUTION_TIME(5000) */ /*!40001 SQL_NO_CACHE */ * from t1 using select /*+ MAX_EXECUTION_TIME(1) */ /*!40001 SQL_NO_CACHE */ * from t1;
```
### 2. What did you expect to see? (Required)
Binding successful
### 3. What did you see instead (Required)
`
ERROR 8066 (HY000): Optimizer hint can only be followed by certain keywords like SELECT, INSERT, etc.
`
### 4. What is your TiDB version? (Required)
Release Version: v9.0.0-alpha-789-g5a3bf795f7
Edition: Community
Git Commit Hash: 5a3bf795f7cf2e16f1d69dac4f65db9f1efce2f0
Git Branch: HEAD
UTC Build Time: 2025-05-23 10:14:26
GoVersion: go1.23.9
Race Enabled: false
Check Table Before Drop: false
Store: unistore
In fact, affect all version before.
possible solution:
```
---
ast/dml.go | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/ast/dml.go b/ast/dml.go
index 629a2e2e17..73136c35d9 100644
--- a/ast/dml.go
+++ b/ast/dml.go
@@ -1072,6 +1072,20 @@ func (n *SelectStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WritePlain(" ")
switch n.Kind {
case SelectStmtKindSelect:
+ // Optimizer hint must be the first part after `SELECT` keyword. Otherwise, it will be ignored.
+ if n.TableHints != nil && len(n.TableHints) != 0 {
+ ctx.WritePlain("/*+ ")
+ for i, tableHint := range n.TableHints {
+ if i != 0 {
+ ctx.WritePlain(" ")
+ }
+ if err := tableHint.Restore(ctx); err != nil {
+ return errors.Annotatef(err, "An error occurred while restore SelectStmt.TableHints[%d]", i)
+ }
+ }
+ ctx.WritePlain("*/ ")
+ }
+
if n.SelectStmtOpts.Priority > 0 {
ctx.WriteKeyWord(mysql.Priority2Str[n.SelectStmtOpts.Priority])
ctx.WritePlain(" ")
@@ -1097,19 +1111,6 @@ func (n *SelectStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("SQL_CALC_FOUND_ROWS ")
}
- if n.TableHints != nil && len(n.TableHints) != 0 {
- ctx.WritePlain("/*+ ")
- for i, tableHint := range n.TableHints {
- if i != 0 {
- ctx.WritePlain(" ")
- }
- if err := tableHint.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SelectStmt.TableHints[%d]", i)
- }
- }
- ctx.WritePlain("*/ ")
- }
-
if n.Distinct {
ctx.WriteKeyWord("DISTINCT ")
} else if n.SelectStmtOpts.ExplicitAll {
```
Contributor guide
Assessment
This issue has not been assessed yet.