Skip to content

Commit 04e2695

Browse files
authored
fix(mysql): Prevent UPDATE ... JOIN panic #1590 (#2154)
* fix: update panic * fix: add test data
1 parent e5d4fba commit 04e2695

File tree

7 files changed

+159
-22
lines changed

7 files changed

+159
-22
lines changed

internal/endtoend/testdata/update_two_table/mysql/go/db.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/update_two_table/mysql/go/models.go

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/update_two_table/mysql/go/query.sql.go

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-- https://github.com/kyleconroy/sqlc/issues/1590
2+
CREATE TABLE authors (
3+
name text NOT NULL,
4+
deleted_at datetime NOT NULL,
5+
created_at datetime NOT NULL,
6+
updated_at datetime NOT NULL
7+
);
8+
9+
CREATE TABLE books (
10+
is_amazing tinyint(1) NOT NULL,
11+
deleted_at datetime NOT NULL,
12+
created_at datetime NOT NULL,
13+
updated_at datetime NOT NULL
14+
);
15+
16+
-- name: DeleteAuthor :exec
17+
UPDATE
18+
authors,
19+
books
20+
SET
21+
authors.deleted_at = now(),
22+
books.deleted_at = now()
23+
WHERE
24+
books.is_amazing = 1
25+
AND authors.name = sqlc.arg(name);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": "1",
3+
"packages": [
4+
{
5+
"path": "go",
6+
"engine": "mysql",
7+
"name": "querytest",
8+
"schema": "query.sql",
9+
"queries": "query.sql"
10+
}
11+
]
12+
}

internal/engine/dolphin/convert.go

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -565,28 +565,7 @@ func (c *cc) convertUpdateStmt(n *pcast.UpdateStmt) *ast.UpdateStmt {
565565
}
566566

567567
relations := &ast.List{}
568-
switch rel := rels.Items[0].(type) {
569-
570-
// Special case for joins in updates
571-
case *ast.JoinExpr:
572-
left, ok := rel.Larg.(*ast.RangeVar)
573-
if !ok {
574-
panic("expected range var")
575-
}
576-
relations.Items = append(relations.Items, left)
577-
578-
right, ok := rel.Rarg.(*ast.RangeVar)
579-
if !ok {
580-
panic("expected range var")
581-
}
582-
relations.Items = append(relations.Items, right)
583-
584-
case *ast.RangeVar:
585-
relations.Items = append(relations.Items, rel)
586-
587-
default:
588-
panic("expected range var")
589-
}
568+
convertToRangeVarList(rels, relations)
590569

591570
// TargetList
592571
list := &ast.List{}

internal/engine/dolphin/utils.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,43 @@ func isNotNull(n *pcast.ColumnDef) bool {
9696
}
9797
return false
9898
}
99+
100+
func convertToRangeVarList(list *ast.List, result *ast.List) {
101+
if len(list.Items) == 0 {
102+
return
103+
}
104+
switch rel := list.Items[0].(type) {
105+
106+
// Special case for joins in updates
107+
case *ast.JoinExpr:
108+
left, ok := rel.Larg.(*ast.RangeVar)
109+
if !ok {
110+
if list, check := rel.Larg.(*ast.List); check {
111+
convertToRangeVarList(list, result)
112+
} else {
113+
panic("expected range var")
114+
}
115+
}
116+
if left != nil {
117+
result.Items = append(result.Items, left)
118+
}
119+
120+
right, ok := rel.Rarg.(*ast.RangeVar)
121+
if !ok {
122+
if list, check := rel.Rarg.(*ast.List); check {
123+
convertToRangeVarList(list, result)
124+
} else {
125+
panic("expected range var")
126+
}
127+
}
128+
if right != nil {
129+
result.Items = append(result.Items, right)
130+
}
131+
132+
case *ast.RangeVar:
133+
result.Items = append(result.Items, rel)
134+
135+
default:
136+
panic("expected range var")
137+
}
138+
}

0 commit comments

Comments
 (0)