Skip to content
Open
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
93 changes: 90 additions & 3 deletions internal/compiler/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
// TODO: Deprecate defaultTable
var defaultTable *ast.TableName
var tables []*ast.TableName
var ctes []*ast.TableName

typeMapCte := map[string]map[string]map[string]*catalog.Column{}
typeMap := map[string]map[string]map[string]*catalog.Column{}
indexTable := func(table catalog.Table) error {
tables = append(tables, table.Rel)
Expand Down Expand Up @@ -67,9 +69,35 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
continue
}
// If the table name doesn't exist, first check if it's a CTE
if _, qcerr := qc.GetTable(fqn); qcerr != nil {
cte, qcerr := qc.GetTable(fqn)
if qcerr != nil {
return nil, err
}
// duplicated logic from indexTable()
schema := fqn.Schema
if schema == "" {
schema = c.DefaultSchema
}
if _, exists := typeMapCte[schema]; !exists {
typeMapCte[schema] = map[string]map[string]*catalog.Column{}
}
typeMapCte[schema][fqn.Name] = map[string]*catalog.Column{}
for _, col := range cte.Columns {
cc := &catalog.Column{
Name: col.Name,
IsNotNull: col.NotNull,
IsUnsigned: col.Unsigned,
IsArray: col.IsArray,
ArrayDims: col.ArrayDims,
Comment: col.Comment,
Length: col.Length,
}
if col.Type != nil {
cc.Type = *col.Type
}
typeMapCte[schema][fqn.Name][col.Name] = cc
}
ctes = append(ctes, fqn)
continue
}
err = indexTable(table)
Expand Down Expand Up @@ -195,7 +223,61 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
panic("too many field items: " + strconv.Itoa(len(items)))
}

search := tables
search := ctes
if alias != "" {
if _, ok := aliasMap[alias]; ok {
// alias maps to a real table, skip CTE search entirely
search = []*ast.TableName{}
}
}

// resolve using ctes first
var found int
for _, table := range search {
schema := table.Schema
if schema == "" {
schema = c.DefaultSchema
}
if c, ok := typeMapCte[schema][table.Name][key]; ok {
found += 1
if ref.name != "" {
key = ref.name
}

defaultP := named.NewInferredParam(key, c.IsNotNull)
p, isNamed := params.FetchMerge(ref.ref.Number, defaultP)
a = append(a, Parameter{
Number: ref.ref.Number,
Column: &Column{
Name: p.Name(),
OriginalName: c.Name,
DataType: dataType(&c.Type),
NotNull: p.NotNull(),
Unsigned: c.IsUnsigned,
IsArray: c.IsArray,
ArrayDims: c.ArrayDims,
Length: c.Length,
Table: table,
IsNamedParam: isNamed,
IsSqlcSlice: p.IsSqlcSlice(),
},
})
}
}

if found == 1 {
continue
}
if found > 1 {
return nil, &sqlerr.Error{
Code: "42703",
Message: fmt.Sprintf("column reference %q is ambiguous", key),
Location: node.Location,
}
}


search = tables
if alias != "" {
if original, ok := aliasMap[alias]; ok {
search = []*ast.TableName{original}
Expand All @@ -217,7 +299,9 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
}
}

var found int

// resolve using regular tables
found = 0
for _, table := range search {
schema := table.Schema
if schema == "" {
Expand Down Expand Up @@ -286,6 +370,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
schema = c.DefaultSchema
}

// should we use also look in CTEs?
if c, ok := typeMap[schema][table.Name][key]; ok {
defaultP := named.NewInferredParam(key, c.IsNotNull)
p, isNamed := params.FetchMerge(ref.ref.Number, defaultP)
Expand Down Expand Up @@ -475,6 +560,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
schema = c.DefaultSchema
}

// should we use also look in CTEs?
tableMap, ok := typeMap[schema][rel]
if !ok {
return nil, sqlerr.RelationNotFound(rel)
Expand Down Expand Up @@ -583,6 +669,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
}
}

// should we use also look in CTEs?
for _, table := range search {
schema := table.Schema
if schema == "" {
Expand Down

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

1 change: 1 addition & 0 deletions internal/endtoend/testdata/cte_renamed_column/issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/sqlc-dev/sqlc/issues/4288
32 changes: 32 additions & 0 deletions internal/endtoend/testdata/cte_renamed_column/postgresql/go/db.go

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

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- name: GetUser :one
WITH found AS (
SELECT id, id AS id2 FROM users WHERE id = $1
)
SELECT id2 + $2 AS result FROM found;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Schema
CREATE TABLE users (
id INT PRIMARY KEY,
name TEXT NOT NULL
);
10 changes: 10 additions & 0 deletions internal/endtoend/testdata/cte_renamed_column/postgresql/sqlc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: "2"
sql:
- engine: "postgresql"
schema: "schema.sql"
queries: "query.sql"
gen:
go:
package: "querytest"
out: "go"
sql_package: "pgx/v5"
Loading