Skip to content

Commit 4663aab

Browse files
authored
fix(compiler): Support nullable fields in joins on same table (#1270)
1 parent 724ab37 commit 4663aab

File tree

12 files changed

+264
-16
lines changed

12 files changed

+264
-16
lines changed

internal/compiler/output_columns.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, error) {
261261
continue
262262
}
263263
for _, f := range n.FromClause.Items {
264-
if res := isTableRequired(f, col.Table.Name, tableRequired); res != tableNotFound {
264+
if res := isTableRequired(f, col, tableRequired); res != tableNotFound {
265265
col.NotNull = res == tableRequired
266266
break
267267
}
@@ -278,18 +278,21 @@ const (
278278
tableOptional
279279
)
280280

281-
func isTableRequired(n ast.Node, tableName string, prior int) int {
281+
func isTableRequired(n ast.Node, col *Column, prior int) int {
282282
switch n := n.(type) {
283283
case *ast.RangeVar:
284-
if *n.Relname == tableName {
284+
if n.Alias == nil && *n.Relname == col.Table.Name {
285+
return prior
286+
}
287+
if n.Alias != nil && *n.Alias.Aliasname == col.TableAlias && *n.Relname == col.Table.Name {
285288
return prior
286289
}
287290
case *ast.JoinExpr:
288291
helper := func(l, r int) int {
289-
if res := isTableRequired(n.Larg, tableName, l); res != tableNotFound {
292+
if res := isTableRequired(n.Larg, col, l); res != tableNotFound {
290293
return res
291294
}
292-
if res := isTableRequired(n.Rarg, tableName, r); res != tableNotFound {
295+
if res := isTableRequired(n.Rarg, col, r); res != tableNotFound {
293296
return res
294297
}
295298
return tableNotFound
@@ -304,7 +307,7 @@ func isTableRequired(n ast.Node, tableName string, prior int) int {
304307
}
305308
case *ast.List:
306309
for _, item := range n.Items {
307-
if res := isTableRequired(item, tableName, prior); res != tableNotFound {
310+
if res := isTableRequired(item, col, prior); res != tableNotFound {
308311
return res
309312
}
310313
}
@@ -439,13 +442,14 @@ func outputColumnRefs(res *ast.ResTarget, tables []*Table, node *ast.ColumnRef)
439442
cname = *res.Name
440443
}
441444
cols = append(cols, &Column{
442-
Name: cname,
443-
Type: c.Type,
444-
Table: c.Table,
445-
DataType: c.DataType,
446-
NotNull: c.NotNull,
447-
IsArray: c.IsArray,
448-
Length: c.Length,
445+
Name: cname,
446+
Type: c.Type,
447+
Table: c.Table,
448+
TableAlias: alias,
449+
DataType: c.DataType,
450+
NotNull: c.NotNull,
451+
IsArray: c.IsArray,
452+
Length: c.Length,
449453
})
450454
}
451455
}

internal/compiler/query.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ type Column struct {
2323
Length *int
2424

2525
// XXX: Figure out what PostgreSQL calls `foo.id`
26-
Scope string
27-
Table *ast.TableName
28-
Type *ast.TypeName
26+
Scope string
27+
Table *ast.TableName
28+
TableAlias string
29+
Type *ast.TypeName
2930

3031
skipTableRequiredCheck bool
3132
}

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

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

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

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

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

Lines changed: 54 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CREATE TABLE authors (
2+
id INT(10) NOT NULL,
3+
name VARCHAR(255) NOT NULL,
4+
parent_id INT(10),
5+
PRIMARY KEY (id)
6+
);
7+
8+
-- name: AllAuthors :many
9+
SELECT a.id,
10+
a.name,
11+
p.id as alias_id,
12+
p.name as alias_name
13+
FROM authors a
14+
LEFT JOIN authors p
15+
ON (authors.parent_id = p.id);
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/endtoend/testdata/join_left_same_table/postgres/go/db.go

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

internal/endtoend/testdata/join_left_same_table/postgres/go/models.go

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

internal/endtoend/testdata/join_left_same_table/postgres/go/query.sql.go

Lines changed: 53 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CREATE TABLE authors (
2+
id INT PRIMARY KEY,
3+
name TEXT NOT NULL,
4+
parent_id INT -- nullable
5+
);
6+
7+
-- name: AllAuthors :many
8+
SELECT a.id,
9+
a.name,
10+
p.id as alias_id,
11+
p.name as alias_name
12+
FROM authors a
13+
LEFT JOIN authors p USING (parent_id);
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": "postgresql",
7+
"name": "querytest",
8+
"schema": "query.sql",
9+
"queries": "query.sql"
10+
}
11+
]
12+
}

0 commit comments

Comments
 (0)