Skip to content

sqlc.slice combined with a reused numbered parameter binds wrongly on SQLite #258

Description

@rayakame

On the SQLite family a reused sqlc.arg becomes the same ?N at several use sites, while sqlc.slice expands to unnumbered ?. Combining the two produces arguments in the wrong order, and arguably SQL that cannot be numbered coherently at all.

Reproduced with sqlc 1.31.1 and the current plugin:

-- name: ReusedArgAndSlice :many
SELECT id FROM t WHERE id IN (sqlc.slice(ids)) AND a = sqlc.arg(x) AND b = sqlc.arg(x) AND id IN (sqlc.slice(ids));

sqlc emits IN (/*SLICE:ids*/?) AND a = ?2 AND b = ?2 AND id IN (/*SLICE:ids*/?); the plugin generates QueryResults(conn, sql, operator.itemgetter(0), *ids, *ids, x), i.e. the slice copies before x rather than around it.

Cause: the bind order records one plain slot per ?N occurrence, so the two ?2 slots want two arguments while only one exists; the ordering pass gives up and falls back to consecutive copies. Carrying the ordinal so repeated ?N map to one argument is the obvious first step, but it is probably not sufficient on its own - after expansion the statement mixes unnumbered ? from the slice with numbered ?N, and SQLite assigns those a sequence that no longer matches the emitted tuple. Worth checking whether the expansion should emit numbered placeholders instead.

Predates the bind-order refactor (#257): placeholderSequence behaved identically. Not reachable in any committed fixture.

Metadata

Metadata

Assignees

No one assigned

    Labels

    goPull requests that update go code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions