Skip to content
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
6,266 changes: 3,135 additions & 3,131 deletions pkg/sql/parsers/dialect/mysql/mysql_sql.go

Large diffs are not rendered by default.

51 changes: 18 additions & 33 deletions pkg/sql/parsers/dialect/mysql/mysql_sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import (
orderBy tree.OrderBy
order *tree.Order
limit *tree.Limit
rankOption *tree.RankOption
unionTypeRecord *tree.UnionTypeRecord
parenTableExpr *tree.ParenTableExpr
identifierList tree.IdentifierList
Expand Down Expand Up @@ -583,7 +584,7 @@ import (
%type <order> order
%type <orderBy> order_list order_by_clause order_by_opt
%type <limit> limit_opt limit_clause
%type <limit> limit_rank_suffix
%type <rankOption> rank_opt
%type <str> insert_column optype_opt
%type <str> optype
%type <identifierList> column_list column_list_opt partition_clause_opt partition_id_list insert_column_list accounts_list
Expand Down Expand Up @@ -5359,29 +5360,29 @@ select_stmt:
}

select_no_parens:
simple_select time_window_opt order_by_opt limit_opt export_data_param_opt select_lock_opt
simple_select time_window_opt order_by_opt limit_opt rank_opt export_data_param_opt select_lock_opt
{
$$ = &tree.Select{Select: $1, TimeWindow: $2, OrderBy: $3, Limit: $4, Ep: $5, SelectLockInfo: $6}
$$ = &tree.Select{Select: $1, TimeWindow: $2, OrderBy: $3, Limit: $4, RankOption: $5, Ep: $6, SelectLockInfo: $7}
}
| select_with_parens time_window_opt order_by_clause export_data_param_opt
{
$$ = &tree.Select{Select: $1, TimeWindow: $2, OrderBy: $3, Ep: $4}
}
| select_with_parens time_window_opt order_by_opt limit_clause export_data_param_opt
| select_with_parens time_window_opt order_by_opt limit_clause rank_opt export_data_param_opt
{
$$ = &tree.Select{Select: $1, TimeWindow: $2, OrderBy: $3, Limit: $4, Ep: $5}
$$ = &tree.Select{Select: $1, TimeWindow: $2, OrderBy: $3, Limit: $4, RankOption: $5, Ep: $6}
}
| with_clause simple_select time_window_opt order_by_opt limit_opt export_data_param_opt select_lock_opt
| with_clause simple_select time_window_opt order_by_opt limit_opt rank_opt export_data_param_opt select_lock_opt
{
$$ = &tree.Select{Select: $2, TimeWindow: $3, OrderBy: $4, Limit: $5, Ep: $6, SelectLockInfo:$7, With: $1}
$$ = &tree.Select{Select: $2, TimeWindow: $3, OrderBy: $4, Limit: $5, RankOption: $6, Ep: $7, SelectLockInfo:$8, With: $1}
}
| with_clause select_with_parens order_by_clause export_data_param_opt
{
$$ = &tree.Select{Select: $2, OrderBy: $3, Ep: $4, With: $1}
}
| with_clause select_with_parens order_by_opt limit_clause export_data_param_opt
| with_clause select_with_parens order_by_opt limit_clause rank_opt export_data_param_opt
{
$$ = &tree.Select{Select: $2, OrderBy: $3, Limit: $4, Ep: $5, With: $1}
$$ = &tree.Select{Select: $2, OrderBy: $3, Limit: $4, RankOption: $5, Ep: $6, With: $1}
}

time_window_opt:
Expand Down Expand Up @@ -5531,35 +5532,20 @@ limit_opt:
}

limit_clause:
LIMIT expression limit_rank_suffix
LIMIT expression
{
l := &tree.Limit{Count: $2}
if $3 != nil {
l.ByRank = $3.ByRank
l.Option = $3.Option
}
$$ = l
$$ = &tree.Limit{Count: $2}
}
| LIMIT expression ',' expression limit_rank_suffix
| LIMIT expression ',' expression
{
l := &tree.Limit{Offset: $2, Count: $4}
if $5 != nil {
l.ByRank = $5.ByRank
l.Option = $5.Option
}
$$ = l
$$ = &tree.Limit{Offset: $2, Count: $4}
}
| LIMIT expression OFFSET expression limit_rank_suffix
| LIMIT expression OFFSET expression
{
l := &tree.Limit{Offset: $4, Count: $2}
if $5 != nil {
l.ByRank = $5.ByRank
l.Option = $5.Option
}
$$ = l
$$ = &tree.Limit{Offset: $4, Count: $2}
}

limit_rank_suffix:
rank_opt:
{
$$ = nil
}
Expand Down Expand Up @@ -5593,8 +5579,7 @@ limit_rank_suffix:
}
}

$$ = &tree.Limit{
ByRank: true,
$$ = &tree.RankOption{
Option: optionMap,
}
}
Expand Down
36 changes: 18 additions & 18 deletions pkg/sql/parsers/dialect/mysql/mysql_sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3513,10 +3513,10 @@ func TestLimitByRank(t *testing.T) {
selectStmt, ok := stmt.(*tree.Select)
require.True(t, ok)
require.NotNil(t, selectStmt.Limit)
require.True(t, selectStmt.Limit.ByRank)
require.NotNil(t, selectStmt.Limit.Option)
require.Equal(t, "3.0", selectStmt.Limit.Option["fudge_factor"])
require.Equal(t, "10", selectStmt.Limit.Option["nprobe"])
require.NotNil(t, selectStmt.RankOption)
require.NotNil(t, selectStmt.RankOption.Option)
require.Equal(t, "3.0", selectStmt.RankOption.Option["fudge_factor"])
require.Equal(t, "10", selectStmt.RankOption.Option["nprobe"])
},
},
{
Expand All @@ -3526,10 +3526,10 @@ func TestLimitByRank(t *testing.T) {
selectStmt, ok := stmt.(*tree.Select)
require.True(t, ok)
require.NotNil(t, selectStmt.Limit)
require.True(t, selectStmt.Limit.ByRank)
require.NotNil(t, selectStmt.Limit.Option)
require.Equal(t, "2.5", selectStmt.Limit.Option["fudge_factor"])
require.Equal(t, "pre", selectStmt.Limit.Option["mode"])
require.NotNil(t, selectStmt.RankOption)
require.NotNil(t, selectStmt.RankOption.Option)
require.Equal(t, "2.5", selectStmt.RankOption.Option["fudge_factor"])
require.Equal(t, "pre", selectStmt.RankOption.Option["mode"])
},
},
{
Expand All @@ -3539,10 +3539,10 @@ func TestLimitByRank(t *testing.T) {
selectStmt, ok := stmt.(*tree.Select)
require.True(t, ok)
require.NotNil(t, selectStmt.Limit)
require.True(t, selectStmt.Limit.ByRank)
require.NotNil(t, selectStmt.Limit.Option)
require.Equal(t, "1.0", selectStmt.Limit.Option["fudge_factor"])
require.Equal(t, "post", selectStmt.Limit.Option["mode"])
require.NotNil(t, selectStmt.RankOption)
require.NotNil(t, selectStmt.RankOption.Option)
require.Equal(t, "1.0", selectStmt.RankOption.Option["fudge_factor"])
require.Equal(t, "post", selectStmt.RankOption.Option["mode"])
},
},
{
Expand All @@ -3552,9 +3552,9 @@ func TestLimitByRank(t *testing.T) {
selectStmt, ok := stmt.(*tree.Select)
require.True(t, ok)
require.NotNil(t, selectStmt.Limit)
require.True(t, selectStmt.Limit.ByRank)
require.NotNil(t, selectStmt.Limit.Option)
require.Equal(t, "20", selectStmt.Limit.Option["nprobe"])
require.NotNil(t, selectStmt.RankOption)
require.NotNil(t, selectStmt.RankOption.Option)
require.Equal(t, "20", selectStmt.RankOption.Option["nprobe"])
require.NotNil(t, selectStmt.Limit.Offset)
},
},
Expand All @@ -3565,9 +3565,9 @@ func TestLimitByRank(t *testing.T) {
selectStmt, ok := stmt.(*tree.Select)
require.True(t, ok)
require.NotNil(t, selectStmt.Limit)
require.True(t, selectStmt.Limit.ByRank)
require.NotNil(t, selectStmt.Limit.Option)
require.Equal(t, "4.0", selectStmt.Limit.Option["fudge_factor"])
require.NotNil(t, selectStmt.RankOption)
require.NotNil(t, selectStmt.RankOption.Option)
require.Equal(t, "4.0", selectStmt.RankOption.Option["fudge_factor"])
require.NotNil(t, selectStmt.Limit.Offset)
},
},
Expand Down
72 changes: 37 additions & 35 deletions pkg/sql/parsers/tree/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Select struct {
TimeWindow *TimeWindow
OrderBy OrderBy
Limit *Limit
RankOption *RankOption
With *With
Ep *ExportParam
SelectLockInfo *SelectLockInfo
Expand All @@ -55,6 +56,10 @@ func (node *Select) Format(ctx *FmtCtx) {
ctx.WriteByte(' ')
node.Limit.Format(ctx)
}
if node.RankOption != nil {
ctx.WriteByte(' ')
node.RankOption.Format(ctx)
}
if node.Ep != nil {
ctx.WriteByte(' ')
node.Ep.Format(ctx)
Expand Down Expand Up @@ -269,9 +274,6 @@ func (np NullsPosition) String() string {
// the LIMIT clause.
type Limit struct {
Offset, Count Expr
ByRank bool
Option map[string]string // parsed options like {"fudge_factor": "3.0", "nprobe": "10", "mode": "pre"}
Mode string // "pre" or "post"
}

func (node *Limit) Format(ctx *FmtCtx) {
Expand All @@ -287,38 +289,6 @@ func (node *Limit) Format(ctx *FmtCtx) {
}
ctx.WriteString("offset ")
node.Offset.Format(ctx)
needSpace = true
}
if node != nil && node.ByRank {
if needSpace {
ctx.WriteByte(' ')
}
ctx.WriteString("by rank")
needSpace = true
}
if node != nil && node.Option != nil && len(node.Option) > 0 {
if needSpace {
ctx.WriteByte(' ')
}
ctx.WriteString("with option ")
// Sort keys to ensure deterministic output order
keys := make([]string, 0, len(node.Option))
for key := range node.Option {
keys = append(keys, key)
}
sort.Strings(keys)
first := true
for _, key := range keys {
if !first {
ctx.WriteString(", ")
}
ctx.WriteString("'")
ctx.WriteString(key)
ctx.WriteString("=")
ctx.WriteString(node.Option[key])
ctx.WriteString("'")
first = false
}
}
}

Expand All @@ -329,6 +299,38 @@ func NewLimit(o, c Expr) *Limit {
}
}

type RankOption struct {
Option map[string]string
}

func (node *RankOption) Format(ctx *FmtCtx) {
if node == nil {
return
}

ctx.WriteString("by rank")
if len(node.Option) == 0 {
return
}

ctx.WriteString(" with option ")
keys := make([]string, 0, len(node.Option))
for key := range node.Option {
keys = append(keys, key)
}
sort.Strings(keys)
for idx, key := range keys {
if idx > 0 {
ctx.WriteString(", ")
}
ctx.WriteByte('\'')
ctx.WriteString(key)
ctx.WriteString("=")
ctx.WriteString(node.Option[key])
ctx.WriteByte('\'')
}
}

// the parenthesized SELECT/UNION/VALUES statement.
type ParenSelect struct {
SelectStatement
Expand Down
Loading
Loading