Skip to content

sqlite: aliases in RETURNING are ignored when naming result columns #4680

Description

@manuelschoene

Version

1.31.1

What happened?

On the SQLite engine, aliases in a RETURNING clause are ignored. The generated row struct (or scalar variable) is named after the underlying column, or ColumnN for an expression, instead of the alias:

INSERT INTO t (name, score) VALUES (?, ?)
RETURNING id AS new_id, score * 2 AS doubled;
type InsertReturningRow struct {
	ID      int64 // expected: NewID
	Column2 int64 // expected: Doubled
}

SQLite itself reports the column names new_id and doubled:

$ sqlite3 :memory: -header "CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT NOT NULL, score INTEGER NOT NULL, created TEXT); INSERT INTO t (name, score) VALUES ('a', 2) RETURNING id AS new_id, score * 2 AS doubled;"
new_id|doubled
1|4

This affects INSERT, INSERT … ON CONFLICT DO UPDATE, UPDATE and DELETE, and both the default analyzer and the core analyzer (SQLCEXPERIMENT=coreanalyzer). The same aliases in a SELECT list work.

Variant Generated Expected
RETURNING id AS new_id, score * 2 AS doubled ID, Column2 (core: Column) NewID, Doubled
RETURNING id new_id, score * 2 doubled (no AS) ID, Column2 NewID, Doubled
RETURNING id AS "newId", name AS [label] ID, Name NewId, Label
RETURNING id AS new_id (:one, single column) var id int64 var new_id int64
RETURNING *, score * 2 AS doubled …, Column5 …, Doubled
RETURNING id AS old_id, id AS row_id ID, ID_2 OldID, RowID
ON CONFLICT … RETURNING id AS new_id, score AS total ID, Score NewID, Total
UPDATE … RETURNING id AS updated_id, score - 1 AS previous ID, Column2 UpdatedID, Previous
DELETE … RETURNING id AS deleted_id, upper(name) AS shout ID, Upper DeletedID, Shout

The generated code compiles and runs, but the field names do not match the SQL. If the alias is added later, every caller breaks. Two aliases on the same column can't be told apart (ID / ID_2).

Relevant log output

Database schema

CREATE TABLE t (
    id      INTEGER PRIMARY KEY,
    name    TEXT    NOT NULL,
    score   INTEGER NOT NULL,
    created TEXT
);

CREATE UNIQUE INDEX t_name ON t (name);

SQL queries

-- name: InsertReturningAlias :one
INSERT INTO t (name, score) VALUES (?, ?)
RETURNING id AS new_id, score * 2 AS doubled;

-- name: UpsertReturningAlias :one
INSERT INTO t (name, score) VALUES (?, ?)
ON CONFLICT (name) DO UPDATE SET score = score + excluded.score
RETURNING id AS new_id, score AS total;

-- name: UpdateReturningAlias :many
UPDATE t SET score = ? WHERE name = ?
RETURNING id AS updated_id, score - 1 AS previous;

-- name: DeleteReturningAlias :many
DELETE FROM t WHERE score < ?
RETURNING id AS deleted_id, upper(name) AS shout;

Configuration

version: "2"
sql:
  - engine: "sqlite"
    schema: "schema.sql"
    queries: "query.sql"
    gen:
      go:
        package: "db"
        out: "db"

Playground URL

No response

What operating system are you using?

Linux

What database engines are you using?

SQLite

What type of code are you generating?

Go

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions