Skip to content

Commit 7098e18

Browse files
authored
fix: Broken interaction between query_parameter_limit and pq.Array() (#2383)
* Understand sqlc.slice() in more expression types This was needed to understand PostgreSQL IN() which doens't surface as an *ast.In * Fix interaction between query_parameter_limit and sqlc.slice() The sqlc.slice() templating code needed to understand how to refer to a variable when query_parameter_limit prevented struct emission. issue #2268 * Fix imports if a file has both sqlc.slice() and regular arrays The pq import was missing in those cases. I ran into this while writing a test case for #2268 comment 2. * Fix broken interaction between query_parameter_limit and pq.Array() issue #2268
1 parent 76d0a78 commit 7098e18

File tree

8 files changed

+121
-24
lines changed

8 files changed

+121
-24
lines changed

internal/codegen/golang/imports.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,12 @@ func (i *importer) queryImports(filename string) fileImports {
344344
if !q.Arg.isEmpty() {
345345
if q.Arg.IsStruct() {
346346
for _, f := range q.Arg.Struct.Fields {
347-
if strings.HasPrefix(f.Type, "[]") && f.Type != "[]byte" {
347+
if strings.HasPrefix(f.Type, "[]") && f.Type != "[]byte" && !f.HasSqlcSlice() {
348348
return true
349349
}
350350
}
351351
} else {
352-
if strings.HasPrefix(q.Arg.Type(), "[]") && q.Arg.Type() != "[]byte" {
352+
if strings.HasPrefix(q.Arg.Type(), "[]") && q.Arg.Type() != "[]byte" && !q.Arg.HasSqlcSlices() {
353353
return true
354354
}
355355
}
@@ -375,7 +375,8 @@ func (i *importer) queryImports(filename string) fileImports {
375375
sqlpkg := parseDriver(i.Settings.Go.SqlPackage)
376376
if sqlcSliceScan() {
377377
std["strings"] = struct{}{}
378-
} else if sliceScan() && !sqlpkg.IsPGX() {
378+
}
379+
if sliceScan() && !sqlpkg.IsPGX() {
379380
pkg[ImportSpec{Path: "github.com/lib/pq"}] = struct{}{}
380381
}
381382

internal/codegen/golang/query.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,9 @@ func (v QueryValue) Params() string {
116116
} else {
117117
for _, f := range v.Struct.Fields {
118118
if !f.HasSqlcSlice() && strings.HasPrefix(f.Type, "[]") && f.Type != "[]byte" && !v.SQLDriver.IsPGX() {
119-
out = append(out, "pq.Array("+v.Name+"."+f.Name+")")
120-
} else if !v.EmitStruct() && v.IsStruct() {
121-
out = append(out, toLowerCase(f.Name))
119+
out = append(out, "pq.Array("+v.VariableForField(f)+")")
122120
} else {
123-
out = append(out, v.Name+"."+f.Name)
121+
out = append(out, v.VariableForField(f))
124122
}
125123
}
126124
}
@@ -189,6 +187,16 @@ func (v QueryValue) Scan() string {
189187
return "\n" + strings.Join(out, ",\n")
190188
}
191189

190+
func (v QueryValue) VariableForField(f Field) string {
191+
if !v.IsStruct() {
192+
return v.Name
193+
}
194+
if !v.EmitStruct() {
195+
return toLowerCase(f.Name)
196+
}
197+
return v.Name + "." + f.Name
198+
}
199+
192200
// A struct used to generate methods and fields on the Queries struct
193201
type Query struct {
194202
Cmd string

internal/codegen/golang/templates/stdlib/queryCode.tmpl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,16 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{ dbarg }} {{.Arg.Pair}}
126126
{{- $arg := .Arg }}
127127
{{- range .Arg.Struct.Fields }}
128128
{{- if .HasSqlcSlice }}
129-
if len({{$arg.Name}}.{{.Name}}) > 0 {
130-
for _, v := range {{$arg.Name}}.{{.Name}} {
129+
if len({{$arg.VariableForField .}}) > 0 {
130+
for _, v := range {{$arg.VariableForField .}} {
131131
queryParams = append(queryParams, v)
132132
}
133-
query = strings.Replace(query, "/*SLICE:{{.Column.Name}}*/?", strings.Repeat(",?", len({{$arg.Name}}.{{.Name}}))[1:], 1)
133+
query = strings.Replace(query, "/*SLICE:{{.Column.Name}}*/?", strings.Repeat(",?", len({{$arg.VariableForField .}}))[1:], 1)
134134
} else {
135135
query = strings.Replace(query, "/*SLICE:{{.Column.Name}}*/?", "NULL", 1)
136136
}
137137
{{- else }}
138-
queryParams = append(queryParams, {{$arg.Name}}.{{.Name}})
138+
queryParams = append(queryParams, {{$arg.VariableForField .}})
139139
{{- end }}
140140
{{- end }}
141141
{{- else }}

internal/compiler/resolve.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
153153
DataType: dataType,
154154
IsNamedParam: isNamed,
155155
NotNull: p.NotNull(),
156+
IsSqlcSlice: p.IsSqlcSlice(),
156157
},
157158
})
158159
continue
@@ -220,6 +221,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
220221
Length: c.Length,
221222
Table: table,
222223
IsNamedParam: isNamed,
224+
IsSqlcSlice: p.IsSqlcSlice(),
223225
},
224226
})
225227
}
@@ -284,6 +286,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
284286
IsArray: c.IsArray,
285287
Table: table,
286288
IsNamedParam: isNamed,
289+
IsSqlcSlice: p.IsSqlcSlice(),
287290
},
288291
})
289292
}
@@ -352,6 +355,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
352355
DataType: "any",
353356
IsNamedParam: isNamed,
354357
NotNull: p.NotNull(),
358+
IsSqlcSlice: p.IsSqlcSlice(),
355359
},
356360
})
357361
continue
@@ -392,6 +396,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
392396
DataType: dataType(paramType),
393397
NotNull: p.NotNull(),
394398
IsNamedParam: isNamed,
399+
IsSqlcSlice: p.IsSqlcSlice(),
395400
},
396401
})
397402
}
@@ -457,6 +462,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
457462
Table: &ast.TableName{Schema: schema, Name: rel},
458463
Length: c.Length,
459464
IsNamedParam: isNamed,
465+
IsSqlcSlice: p.IsSqlcSlice(),
460466
},
461467
})
462468
} else {

internal/endtoend/testdata/query_parameter_limit_to_two/postgresql/go/models.go

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

internal/endtoend/testdata/query_parameter_limit_to_two/postgresql/go/query.sql.go

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

internal/endtoend/testdata/query_parameter_limit_to_two/postgresql/query.sql

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ CREATE TABLE authors (
33
id BIGSERIAL PRIMARY KEY,
44
name text NOT NULL,
55
bio text,
6-
country_code CHAR(2) NOT NULL
6+
country_code CHAR(2) NOT NULL,
7+
titles TEXT[]
78
);
89

910
-- name: GetAuthor :one
@@ -16,12 +17,19 @@ ORDER BY name;
1617

1718
-- name: CreateAuthor :one
1819
INSERT INTO authors (
19-
name, bio, country_code
20+
name, bio, country_code, titles
2021
) VALUES (
21-
$1, $2, $3
22+
$1, $2, $3, $4
2223
)
2324
RETURNING *;
2425

2526
-- name: DeleteAuthor :exec
2627
DELETE FROM authors
2728
WHERE id = $1;
29+
30+
-- name: DeleteAuthors :exec
31+
DELETE FROM authors
32+
WHERE id IN (sqlc.slice(ids)) AND name = $1;
33+
34+
-- name: CreateAuthorOnlyTitles :one
35+
INSERT INTO authors (name, titles) VALUES ($1, $2) RETURNING *;

internal/endtoend/testdata/sqlc_slice/postgresql/stdlib/go/query.sql.go

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

0 commit comments

Comments
 (0)