diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index b34715b35d..06b5b3fc3e 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -347,6 +347,8 @@ func isTableRequired(n ast.Node, col *Column, prior int) int { return helper(tableOptional, tableRequired) case ast.JoinTypeFull: return helper(tableOptional, tableOptional) + case ast.JoinTypeInner: + return helper(tableRequired, tableRequired) } case *ast.List: for _, item := range n.Items { diff --git a/internal/endtoend/testdata/join_clauses_order/postgresql/go/db.go b/internal/endtoend/testdata/join_clauses_order/postgresql/go/db.go new file mode 100644 index 0000000000..02974bda59 --- /dev/null +++ b/internal/endtoend/testdata/join_clauses_order/postgresql/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.17.2 + +package querytest + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/join_clauses_order/postgresql/go/models.go b/internal/endtoend/testdata/join_clauses_order/postgresql/go/models.go new file mode 100644 index 0000000000..0e9de4fb09 --- /dev/null +++ b/internal/endtoend/testdata/join_clauses_order/postgresql/go/models.go @@ -0,0 +1,36 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.17.2 + +package querytest + +import () + +type A struct { + ID int64 + A string +} + +type B struct { + ID int64 + B string + AID int64 +} + +type C struct { + ID int64 + C string + AID int64 +} + +type D struct { + ID int64 + D string + AID int64 +} + +type E struct { + ID int64 + E string + AID int64 +} diff --git a/internal/endtoend/testdata/join_clauses_order/postgresql/go/query.sql.go b/internal/endtoend/testdata/join_clauses_order/postgresql/go/query.sql.go new file mode 100644 index 0000000000..fdee971bd4 --- /dev/null +++ b/internal/endtoend/testdata/join_clauses_order/postgresql/go/query.sql.go @@ -0,0 +1,175 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.17.2 +// source: query.sql + +package querytest + +import ( + "context" + "database/sql" +) + +const testInnerLeft = `-- name: TestInnerLeft :many +SELECT a.a, b.b, c.c +FROM a +INNER JOIN b ON b.a_id = a.id +LEFT JOIN c ON c.a_id = a.id +` + +type TestInnerLeftRow struct { + A string + B string + C sql.NullString +} + +func (q *Queries) TestInnerLeft(ctx context.Context) ([]TestInnerLeftRow, error) { + rows, err := q.db.QueryContext(ctx, testInnerLeft) + if err != nil { + return nil, err + } + defer rows.Close() + var items []TestInnerLeftRow + for rows.Next() { + var i TestInnerLeftRow + if err := rows.Scan(&i.A, &i.B, &i.C); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const testInnerLeftInnerLeft = `-- name: TestInnerLeftInnerLeft :many +SELECT a.a, b.b, c.c, d.d, e.e +FROM a +INNER JOIN b ON b.a_id = a.id +LEFT JOIN c ON c.a_id = a.id +INNER JOIN d ON d.a_id = a.id +LEFT JOIN e ON e.a_id = a.id +` + +type TestInnerLeftInnerLeftRow struct { + A string + B string + C sql.NullString + D string + E sql.NullString +} + +func (q *Queries) TestInnerLeftInnerLeft(ctx context.Context) ([]TestInnerLeftInnerLeftRow, error) { + rows, err := q.db.QueryContext(ctx, testInnerLeftInnerLeft) + if err != nil { + return nil, err + } + defer rows.Close() + var items []TestInnerLeftInnerLeftRow + for rows.Next() { + var i TestInnerLeftInnerLeftRow + if err := rows.Scan( + &i.A, + &i.B, + &i.C, + &i.D, + &i.E, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const testLeftInner = `-- name: TestLeftInner :many +SELECT a.a, b.b, c.c +FROM a +LEFT JOIN b ON b.a_id = a.id +INNER JOIN c ON c.a_id = a.id +` + +type TestLeftInnerRow struct { + A string + B sql.NullString + C string +} + +func (q *Queries) TestLeftInner(ctx context.Context) ([]TestLeftInnerRow, error) { + rows, err := q.db.QueryContext(ctx, testLeftInner) + if err != nil { + return nil, err + } + defer rows.Close() + var items []TestLeftInnerRow + for rows.Next() { + var i TestLeftInnerRow + if err := rows.Scan(&i.A, &i.B, &i.C); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const testLeftInnerLeftInner = `-- name: TestLeftInnerLeftInner :many +SELECT a.a, b.b, c.c, d.d, e.e +FROM a +LEFT JOIN b ON b.a_id = a.id +INNER JOIN c ON c.a_id = a.id +LEFT JOIN d ON d.a_id = a.id +INNER JOIN e ON e.a_id = a.id +` + +type TestLeftInnerLeftInnerRow struct { + A string + B sql.NullString + C string + D sql.NullString + E string +} + +func (q *Queries) TestLeftInnerLeftInner(ctx context.Context) ([]TestLeftInnerLeftInnerRow, error) { + rows, err := q.db.QueryContext(ctx, testLeftInnerLeftInner) + if err != nil { + return nil, err + } + defer rows.Close() + var items []TestLeftInnerLeftInnerRow + for rows.Next() { + var i TestLeftInnerLeftInnerRow + if err := rows.Scan( + &i.A, + &i.B, + &i.C, + &i.D, + &i.E, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/join_clauses_order/postgresql/query.sql b/internal/endtoend/testdata/join_clauses_order/postgresql/query.sql new file mode 100644 index 0000000000..c86a022018 --- /dev/null +++ b/internal/endtoend/testdata/join_clauses_order/postgresql/query.sql @@ -0,0 +1,56 @@ +CREATE TABLE a ( + id BIGSERIAL PRIMARY KEY, + a TEXT NOT NULL +); + +CREATE TABLE b ( + id BIGSERIAL PRIMARY KEY, + b TEXT NOT NULL, + a_id BIGINT NOT NULL REFERENCES a (id) +); + +CREATE TABLE c ( + id BIGSERIAL PRIMARY KEY, + c TEXT NOT NULL, + a_id BIGINT NOT NULL REFERENCES a (id) +); + +CREATE TABLE d ( + id BIGSERIAL PRIMARY KEY, + d TEXT NOT NULL, + a_id BIGINT NOT NULL REFERENCES a (id) +); + +CREATE TABLE e ( + id BIGSERIAL PRIMARY KEY, + e TEXT NOT NULL, + a_id BIGINT NOT NULL REFERENCES a (id) +); + +-- name: TestLeftInner :many +SELECT a.a, b.b, c.c +FROM a +LEFT JOIN b ON b.a_id = a.id +INNER JOIN c ON c.a_id = a.id; + +-- name: TestInnerLeft :many +SELECT a.a, b.b, c.c +FROM a +INNER JOIN b ON b.a_id = a.id +LEFT JOIN c ON c.a_id = a.id; + +-- name: TestLeftInnerLeftInner :many +SELECT a.a, b.b, c.c, d.d, e.e +FROM a +LEFT JOIN b ON b.a_id = a.id +INNER JOIN c ON c.a_id = a.id +LEFT JOIN d ON d.a_id = a.id +INNER JOIN e ON e.a_id = a.id; + +-- name: TestInnerLeftInnerLeft :many +SELECT a.a, b.b, c.c, d.d, e.e +FROM a +INNER JOIN b ON b.a_id = a.id +LEFT JOIN c ON c.a_id = a.id +INNER JOIN d ON d.a_id = a.id +LEFT JOIN e ON e.a_id = a.id; diff --git a/internal/endtoend/testdata/join_clauses_order/postgresql/sqlc.json b/internal/endtoend/testdata/join_clauses_order/postgresql/sqlc.json new file mode 100644 index 0000000000..c72b6132d5 --- /dev/null +++ b/internal/endtoend/testdata/join_clauses_order/postgresql/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +}