Skip to content

fix(core): name an unnamed result column by position - #4663

Open
xen0l wants to merge 1 commit into
sqlc-dev:mainfrom
xen0l:duckdb-unnamed-column
Open

xen0l wants to merge 1 commit into
sqlc-dev:mainfrom
xen0l:duckdb-unnamed-column

Conversation

@xen0l

@xen0l xen0l commented Oct 24, 2026

Copy link
Copy Markdown

Fixes #4657

Problem

targetName returned "?column?" for a result column with no alias that is not a column reference or a function call. The Go generator uses a non-empty name as written, so it emitted var ?column? ... and sqlc generate failed with illegal character U+003F '?'.

The PostgreSQL and SQLite engines name such a column by position (column_1).

Change

targetName (internal/core/analyzer/projection.go) returns an empty name for such a target. The Go generator already falls back to column_N for an empty name (columnName in internal/codegen/golang/result.go). ?column? was the only place in non-test Go code that produced the string.

Tests

New end-to-end case: duckdb_unnamed_columns/duckdb (sqlc generate, output committed). It covers an unaliased CAST, a || expression, two unnamed columns, and a mix of named and unnamed columns. It fails without the change (illegal character U+003F '?') and passes with it.

go test ./internal/endtoend -run TestReplay/base: 971 pass, 58 skip, 0 fail before; 972 pass, 58 skip, 0 fail after. The only difference is the new case. No existing golden contained ?column?.
go test ./internal/engine/... ./internal/core/... ./internal/compiler/... ./internal/codegen/... ./internal/cmd/... ./internal/metadata/... ./internal/sql/...: all ok.

Not run: the managed-db context, --tags=examples, and the internal/goldeneye checks.

Notes

With this change, SELECT * EXCLUDE (...) no longer fails at generate time. It used to fail only because it produced an unnamed column. It now generates []any and fails at run time (expected 3 destination arguments in Scan, not 1). That is a separate problem with its own cause (convertStar returns a TODO node), described in #4660.

targetName returned "?column?" for a result column with no alias that is
not a column reference or a function call. The Go generator uses a
non-empty name as written, so it emitted "var ?column? ..." and
sqlc generate failed with "illegal character U+003F".

Return an empty name. The generator already falls back to column_N for
an empty name, which is what the PostgreSQL and SQLite engines produce.

Adds the duckdb_unnamed_columns end-to-end case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

duckdb: a result column without a name is called ?column?, which is not valid Go

1 participant