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.
On the SQLite family a reused
sqlc.argbecomes the same?Nat several use sites, whilesqlc.sliceexpands 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:
sqlc emits
IN (/*SLICE:ids*/?) AND a = ?2 AND b = ?2 AND id IN (/*SLICE:ids*/?); the plugin generatesQueryResults(conn, sql, operator.itemgetter(0), *ids, *ids, x), i.e. the slice copies beforexrather than around it.Cause: the bind order records one plain slot per
?Noccurrence, so the two?2slots want two arguments while only one exists; the ordering pass gives up and falls back to consecutive copies. Carrying the ordinal so repeated?Nmap 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):
placeholderSequencebehaved identically. Not reachable in any committed fixture.