Repository navigation
fix(sqlite): Keep RETURNING aliases in generated column names - #4682
Open
manuelschoene wants to merge 2 commits into
Open
manuelschoene wants to merge 2 commits into
manuelschoene wants to merge 2 commits into
Conversation
Author
|
Note on the failing CI: The sqlc-test-setup script could not install the libossp-uuid16 dependency. Therefore, no tests could be run. |
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.
Fixes #4680
On the SQLite engine, aliases in a
RETURNINGclause were ignored when naming result columns. sqlc named the generated row fields after the underlying column, orColumnNfor an expression:type InsertReturningAliasRow struct { - ID int64 - Column2 int64 + NewID int64 + Doubled int64 }SQLite itself reports these columns as
new_idanddoubled. The bug affectedINSERT,INSERT … ON CONFLICT DO UPDATE,UPDATEandDELETEon both analysis paths (default andSQLCEXPERIMENT=coreanalyzer).Commits
Cause and fix
convertReturning(internal/engine/sqlite/convert.go) built anast.ResTargetfor eachmeyer.ResultColumnbut only convertedExpr, soResTarget.Namestayednil. Both analyzers preferResTarget.Namewhen they name an output column:outputColumnsininternal/compiler/output_columns.go, andtargetNameininternal/core/analyzer/projection.go. Without it they fell back to the column name, the function name, or a positionalColumnN/?column?.The fix sets
Namefromcol.Alias, the same wayconvertResultColumnsalready does forSELECT:identifier()folds the name the way SQLite resolves it. An unquoted alias is lower-cased, and a quoted alias ("newId",[label]) keeps its spelling.RETURNINGaliases now behave exactly likeSELECTaliases. All three callers (INSERT, UPDATE, DELETE) shareconvertReturning, 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:InsertReturningAliasID,Column2(core:Column)NewID,DoubledInsertReturningAliasNoAsASID,Column2NewID,DoubledInsertReturningQuotedAlias"newId",[label]ID,NameNewId,LabelInsertReturningSingleAlias:onevar id int64var new_id int64InsertReturningStarAndAlias*plus an aliasColumn5DoubledInsertReturningSameColumnTwiceID,ID_2OldID,RowIDUpsertReturningAliasON CONFLICT … DO UPDATE … RETURNINGID,ScoreNewID,TotalUpdateReturningAliasUPDATE,:manyID,Column2UpdatedID,PreviousDeleteReturningAliasDELETE, function callID,UpperDeletedID,ShoutWhat I ran:
sqlite33.54.0, which accepts it.sqlite3 -headeron the first query prints the column namesnew_id|doubled.go test ./internal/endtoend -run 'TestReplay/base/returning_alias': fails onmainwith 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 onmain, 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 -landgo vet ./internal/engine/sqlite: clean.Not run locally: the
managed-dbcontext ofTestReplayandTestValidSchemaagainst 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.