GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(sqlite): Keep RETURNING aliases in generated column names by manuelschoene · Pull Request #4682 · sqlc-dev/sqlc

Conversation

@manuelschoene

@manuelschoene manuelschoene commented Nov 11, 2026

Copy link
Copy Markdown

Fixes #4680

On the SQLite engine, aliases in a RETURNING clause were ignored when naming result columns. sqlc named the generated row fields after the underlying column, or ColumnN for an expression:

INSERT INTO t (name, score) VALUES (?, ?)
RETURNING id AS new_id, score * 2 AS doubled;
 type InsertReturningAliasRow struct {
-	ID      int64
-	Column2 int64
+	NewID   int64
+	Doubled int64
 }

SQLite itself reports these columns as new_id and doubled. The bug affected INSERT, INSERT … ON CONFLICT DO UPDATE, UPDATE and DELETE on both analysis paths (default and SQLCEXPERIMENT=coreanalyzer).

Commits

  • fix(sqlite): Keep RETURNING alias as column name
  • test(sqlite): Added RETURNING alias end-to-end test

Cause and fix

convertReturning (internal/engine/sqlite/convert.go) built an ast.ResTarget for each meyer.ResultColumn but only converted Expr, so ResTarget.Name stayed nil. Both analyzers prefer ResTarget.Name when they name an output column: outputColumns in internal/compiler/output_columns.go, and targetName in internal/core/analyzer/projection.go. Without it they fell back to the column name, the function name, or a positional ColumnN / ?column?.

The fix sets Name from col.Alias, the same way convertResultColumns already does for SELECT:

if col.Alias != nil {
	name := identifier(col.Alias)
	target.Name = &name
}

identifier() folds the name the way SQLite resolves it. An unquoted alias is lower-cased, and a quoted alias ("newId", [label]) keeps its spelling. RETURNING aliases now behave exactly like SELECT aliases. All three callers (INSERT, UPDATE, DELETE) share convertReturning, so a single change covers them, and no changes to the compiler or the core analyzer are needed. Columns without an alias are unaffected.

Tests

New end-to-end case internal/endtoend/testdata/returning_alias/sqlite/, one query per variant:

Query Variant Before After
InsertReturningAlias alias on a column and an expression ID, Column2 (core: Column) NewID, Doubled
InsertReturningAliasNoAs alias without AS ID, Column2 NewID, Doubled
InsertReturningQuotedAlias "newId", [label] ID, Name NewId, Label
InsertReturningSingleAlias single column, :one var id int64 var new_id int64
InsertReturningStarAndAlias * plus an alias …, Column5 …, Doubled
InsertReturningSameColumnTwice same column under two aliases ID, ID_2 OldID, RowID
UpsertReturningAlias ON CONFLICT … DO UPDATE … RETURNING ID, Score NewID, Total
UpdateReturningAlias UPDATE, :many ID, Column2 UpdatedID, Previous
DeleteReturningAlias DELETE, function call ID, Upper DeletedID, Shout

What I ran:

  • The quoted-alias query checked against sqlite3 3.54.0, which accepts it. sqlite3 -header on the first query prints the column names new_id|doubled.
  • go test ./internal/endtoend -run 'TestReplay/base/returning_alias': fails on main with the field names shown in the "Before" column, passes with the fix.
  • SQLC_TEST_CORE=1 go test ./internal/endtoend -run 'TestReplay/core/returning_alias': fails on main, passes with the fix. The core path generates byte-identical output to the default path, so a single set of goldens covers both.
  • go test ./internal/endtoend -run 'TestReplay|TestFormat|TestExamplesVet|TestJsonSchema' over the whole corpus: no failures, and no existing golden changes.
  • gofmt -l and go vet ./internal/engine/sqlite: clean.

Not run locally: the managed-db context of TestReplay and TestValidSchema against live PostgreSQL/MySQL, since no database servers were running. This change only touches the SQLite converter.

Note on #4681

#4681 was opened shortly after the issue and proposes the same change. This PR's test case was written before the issue was filed, which is why the issue already refers to it. I'm opening this PR anyway for the fuller write-up above. Feel free to close whichever one you don't need.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
manuelschoene added 2 commits November 11, 2026 15:55
@manuelschoene
fix(sqlite): Keep RETURNING alias as column name
192605e
@manuelschoene
test(sqlite): Added RETURNING alias end-to-end test
98cb55b
@manuelschoene

manuelschoene commented Nov 11, 2026

Copy link
Copy Markdown
Author

Note on the failing CI: The sqlc-test-setup script could not install the libossp-uuid16 dependency. Therefore, no tests could be run.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

sqlite: aliases in RETURNING are ignored when naming result columns

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@manuelschoene
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.