fix(codegen): no spurious lib/pq import for MySQL with sqlc.narg + sqlc.slice (#3783)#4460
Open
luongs3 wants to merge 1 commit into
Open
fix(codegen): no spurious lib/pq import for MySQL with sqlc.narg + sqlc.slice (#3783)#4460luongs3 wants to merge 1 commit into
luongs3 wants to merge 1 commit into
Conversation
…lc.slice (sqlc-dev#3783) Problem ------- A MySQL query that references the same named parameter as both a regular argument (e.g. `sqlc.narg('x') IS NULL`) and a `sqlc.slice('x')` expansion produced Go code that imports `github.com/lib/pq` even though the import is unused — the runtime path expands the slice in-place via the `/*SLICE:...*/?` placeholder and never calls `pq.Array`. Root cause ---------- The two references generate two `goColumn` entries with the same name and type; only the slice variant carries the `IsSqlcSlice` flag. The non-slice duplicate field still satisfies the `[]T && !sqlc.slice` condition in `sliceScan()` inside `internal/codegen/golang/imports.go`, which causes `lib/pq` to be added to the import set. The struct itself is rendered through `UniqueFields` so only one field is emitted, but the import-bookkeeping pass sees both. Fix --- In `sliceScan()`, collect the names of all fields carrying `IsSqlcSlice` first, then skip any field whose name matches one of those when deciding whether to require `lib/pq`. The duplicate is already handled by the slice-expansion code path and does not need `pq.Array`. Tests ----- - New endtoend fixture `mysql_slice_narg_no_pq_3783/mysql` mirrors the issue's repro; golden files confirm no `lib/pq` import in the generated code. - Full `internal/endtoend` TestReplay suite passes. - `go test ./internal/codegen/... ./internal/compiler/... ./internal/sql/...` clean. What does NOT change -------------------- - Postgres / pgx output is unaffected (the field-name filter only suppresses lib/pq when a sqlc.slice with the same name exists, and pgx never went through the lib/pq branch anyway). - MySQL queries that use `sqlc.slice` alone, or a plain `[]T` argument, are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A MySQL query that references the same named parameter as both a regular argument (e.g.
sqlc.narg('x') IS NULL) and assqlc.slice('x')produces Go code that importsgithub.com/lib/pq(a Postgres library) even though the import is unused — the runtime path expands the slice in-place via the/*SLICE:...*/?placeholder and never callspq.Array.Closes #3783.
Minimal repro (from the issue)
Generated MySQL output on
maincontains:Root cause
The two references to
author_idsproduce twogoColumnentries with the same name and type; only the slice variant carries theIsSqlcSliceflag. The non-slice duplicate field still satisfies the[]T && !sqlc.slicecondition insliceScan()insideinternal/codegen/golang/imports.go, which addslib/pqto the import set. The struct itself is rendered throughUniqueFieldsso only one field is emitted, but the import-bookkeeping pass sees both fields.Fix
In
sliceScan(), first collect the names of all fields carryingIsSqlcSlice, then skip any field whose name matches one of those when deciding whether to requirelib/pq. The duplicate is already handled by the slice-expansion code path and does not needpq.Array.Tests
internal/endtoend/testdata/mysql_slice_narg_no_pq_3783/mysqlmirrors the issue's repro; golden files confirm nolib/pqimport in the generated code.internal/endtoendTestReplaysuite passes.go test ./internal/codegen/... ./internal/compiler/... ./internal/sql/...clean.gofmt -lclean,go vetclean on touched files.What does NOT change
lib/pqwhen asqlc.slicewith the same name exists in the same query, and pgx never went through thelib/pqbranch anyway.sqlc.slicealone, a plain[]Targument, or asqlc.nargwithout a matchingsqlc.sliceare unchanged.