Skip to content

Commit 9d56616

Browse files
authored
Add support for mysql optimizer hint comments (#270)
1 parent 2d3da06 commit 9d56616

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

select.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ type SelectStmt struct {
3333

3434
comments Comments
3535

36-
indexHints []Builder
36+
indexHints []Builder
37+
optimizerHints []Builder
3738
}
3839

3940
type SelectBuilder = SelectStmt
@@ -54,6 +55,17 @@ func (b *SelectStmt) Build(d Dialect, buf Buffer) error {
5455

5556
buf.WriteString("SELECT ")
5657

58+
if len(b.optimizerHints) > 0 {
59+
buf.WriteString("/*+ ")
60+
for i, hint := range b.optimizerHints {
61+
if i > 0 {
62+
buf.WriteString(" ")
63+
}
64+
hint.Build(d, buf)
65+
}
66+
buf.WriteString(" */ ")
67+
}
68+
5769
if b.IsDistinct {
5870
buf.WriteString("DISTINCT ")
5971
}
@@ -474,3 +486,16 @@ func (b *SelectStmt) IndexHint(hints ...interface{}) *SelectStmt {
474486
}
475487
return b
476488
}
489+
490+
// OptimizerHint adds a MySQL optimizer hint. Hint can be a Builder or string.
491+
func (b *SelectStmt) OptimizerHint(hints ...interface{}) *SelectStmt {
492+
for _, hint := range hints {
493+
switch hint := hint.(type) {
494+
case string:
495+
b.optimizerHints = append(b.optimizerHints, Expr(hint))
496+
case Builder:
497+
b.optimizerHints = append(b.optimizerHints, hint)
498+
}
499+
}
500+
return b
501+
}

select_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ func TestSelectStmt(t *testing.T) {
2424
Suffix("FOR UPDATE").
2525
Comment("SELECT TEST").
2626
IndexHint(UseIndex("idx_c_d").ForGroupBy(), "USE INDEX(idx_e_f)").
27-
IndexHint(IgnoreIndex("idx_a_b"))
27+
IndexHint(IgnoreIndex("idx_a_b")).
28+
OptimizerHint("NO_RANGE_OPTIMIZATION(table)").
29+
OptimizerHint("MAX_EXECUTION_TIME(1000)")
2830

2931
err := builder.Build(dialect.MySQL, buf)
3032
require.NoError(t, err)
31-
require.Equal(t, "/* SELECT TEST */\nSELECT DISTINCT a, b FROM ? USE INDEX FOR GROUP BY(`idx_c_d`) USE INDEX(idx_e_f) IGNORE INDEX(`idx_a_b`) "+
33+
require.Equal(t, "/* SELECT TEST */\nSELECT /*+ NO_RANGE_OPTIMIZATION(table) MAX_EXECUTION_TIME(1000) */ DISTINCT a, b FROM ? USE INDEX FOR GROUP BY(`idx_c_d`) USE INDEX(idx_e_f) IGNORE INDEX(`idx_a_b`) "+
3234
"LEFT JOIN `table2` USE INDEX(`idx_table2`) ON table.a1 = table.a2 WHERE (`c` = ?) GROUP BY d HAVING (`e` = ?) ORDER BY f ASC LIMIT 3 OFFSET 4 FOR UPDATE", buf.String())
3335
// two functions cannot be compared
3436
require.Equal(t, 3, len(buf.Value()))

0 commit comments

Comments
 (0)