Skip to content

Commit

Permalink
feat: Support "LIMIT ?" in UPDATE and DELETE for MySQL (#2365)
Browse files Browse the repository at this point in the history
PostgreSQL doesn't support UPDATE-LIMIT

issue #2131
  • Loading branch information
Jille authored and andrewmbenton committed Jun 27, 2023
1 parent 1357f50 commit d2559e8
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 2 deletions.
8 changes: 8 additions & 0 deletions internal/compiler/find_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func (p paramSearch) Visit(node ast.Node) astutils.Visitor {
case *ast.CallStmt:
p.parent = n.FuncCall

case *ast.DeleteStmt:
if n.LimitCount != nil {
p.limitCount = n.LimitCount
}

case *ast.FuncCall:
p.parent = node

Expand Down Expand Up @@ -129,6 +134,9 @@ func (p paramSearch) Visit(node ast.Node) astutils.Visitor {
}
p.seen[ref.Location] = struct{}{}
}
if n.LimitCount != nil {
p.limitCount = n.LimitCount
}

case *ast.RangeVar:
p.rangeVar = n
Expand Down
31 changes: 31 additions & 0 deletions internal/endtoend/testdata/limit/mysql/go/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions internal/endtoend/testdata/limit/mysql/go/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions internal/endtoend/testdata/limit/mysql/go/query.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions internal/endtoend/testdata/limit/mysql/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE foo (bar bool not null);

-- name: LimitMe :exec
UPDATE foo SET bar='baz' LIMIT ?;

-- name: LimitMeToo :exec
DELETE FROM foo LIMIT ?;
12 changes: 12 additions & 0 deletions internal/endtoend/testdata/limit/mysql/sqlc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "1",
"packages": [
{
"path": "go",
"engine": "mysql",
"name": "querytest",
"schema": "query.sql",
"queries": "query.sql"
}
]
}
12 changes: 10 additions & 2 deletions internal/engine/dolphin/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,16 @@ func (c *cc) convertDeleteStmt(n *pcast.DeleteStmt) *ast.DeleteStmt {
relations := &ast.List{}
convertToRangeVarList(rels, relations)

return &ast.DeleteStmt{
stmt := &ast.DeleteStmt{
Relations: relations,
WhereClause: c.convert(n.Where),
ReturningList: &ast.List{},
WithClause: c.convertWithClause(n.With),
}
if n.Limit != nil {
stmt.LimitCount = c.convert(n.Limit.Count)
}
return stmt
}

func (c *cc) convertDropTableStmt(n *pcast.DropTableStmt) ast.Node {
Expand Down Expand Up @@ -574,14 +578,18 @@ func (c *cc) convertUpdateStmt(n *pcast.UpdateStmt) *ast.UpdateStmt {
for _, a := range n.List {
list.Items = append(list.Items, c.convertAssignment(a))
}
return &ast.UpdateStmt{
stmt := &ast.UpdateStmt{
Relations: relations,
TargetList: list,
WhereClause: c.convert(n.Where),
FromClause: &ast.List{},
ReturningList: &ast.List{},
WithClause: c.convertWithClause(n.With),
}
if n.Limit != nil {
stmt.LimitCount = c.convert(n.Limit.Count)
}
return stmt
}

func (c *cc) convertValueExpr(n *driver.ValueExpr) *ast.A_Const {
Expand Down
1 change: 1 addition & 0 deletions internal/sql/ast/delete_stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type DeleteStmt struct {
Relations *List
UsingClause *List
WhereClause Node
LimitCount Node
ReturningList *List
WithClause *WithClause
}
Expand Down
1 change: 1 addition & 0 deletions internal/sql/ast/update_stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type UpdateStmt struct {
TargetList *List
WhereClause Node
FromClause *List
LimitCount Node
ReturningList *List
WithClause *WithClause
}
Expand Down
6 changes: 6 additions & 0 deletions internal/sql/astutils/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,9 @@ func Walk(f Visitor, node ast.Node) {
if n.WhereClause != nil {
Walk(f, n.WhereClause)
}
if n.LimitCount != nil {
Walk(f, n.LimitCount)
}
if n.ReturningList != nil {
Walk(f, n.ReturningList)
}
Expand Down Expand Up @@ -2038,6 +2041,9 @@ func Walk(f Visitor, node ast.Node) {
if n.FromClause != nil {
Walk(f, n.FromClause)
}
if n.LimitCount != nil {
Walk(f, n.LimitCount)
}
if n.ReturningList != nil {
Walk(f, n.ReturningList)
}
Expand Down

0 comments on commit d2559e8

Please sign in to comment.