Skip to content

sqlc.slice() breaks SQLite queries that contain other parameters. #2452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
SoMuchForSubtlety opened this issue Jul 13, 2023 · 4 comments
Open

Comments

@SoMuchForSubtlety
Copy link
Contributor

SoMuchForSubtlety commented Jul 13, 2023

Version

1.18.0

What happened?

sqlc generates queries using numbered parameters, but if a sqlc.slice comes before other parameters, the numbers will no longer match.

Relevant log output

No response

Database schema

CREATE TABLE authors (
  id   integer PRIMARY KEY,
  name text      NOT NULL,
  age  ingeger
);

SQL queries

-- name: SomeQuery :many
select * from authors
where name in (sqlc.slice(names)) 
  and age = $age;

Configuration

{
  "version": "1",
  "packages": [
    {
      "path": "db",
      "engine": "sqlite",
      "schema": "query.sql",
      "queries": "query.sql"
    }
  ]
}

Playground URL

https://play.sqlc.dev/p/009df3b554022fd08ed62f1940e1ec63303e165e7e95182eb702d4b9351a56c4

What operating system are you using?

Linux

What database engines are you using?

SQLite

What type of code are you generating?

Go

@SoMuchForSubtlety SoMuchForSubtlety added bug Something isn't working triage New issues that hasn't been reviewed labels Jul 13, 2023
@kyleconroy kyleconroy reopened this Aug 2, 2023
@ciarand
Copy link

ciarand commented Sep 7, 2023

Just ran into this. Is there a reason the SQLite engine can't use named parameters? If I were to submit a PR to switch to using named params for both non-slice params and generated names for slice params ((sqlc.slice('my_slice')) => (@my_slice__1, @my_slice__2, @my_slice__3)) would that be considered for acceptance?

@bengesoff
Copy link

I've run into the same issue. I have this SQL code:

-- name: GetRuns :many
SELECT runs.*, scenarios.name AS scenario_name
FROM runs
JOIN scenarios
ON scenarios.id = runs.scenario_id
WHERE
    (timestamp > sqlc.narg('run_date_after') OR @run_date_after IS NULL)
    AND (timestamp < sqlc.narg('run_date_before') OR @run_date_before IS NULL)
    AND (status IN (sqlc.slice('filter_run_status')))
    AND (scenarios.name = sqlc.narg('filter_scenario_name') OR @filter_scenario_name IS NULL);

And it gets compiled into this query:

-- name: GetRuns :many
SELECT runs.id, runs.timestamp, runs.status, scenarios.name AS scenario_name
FROM runs
JOIN scenarios
ON scenarios.id = runs.scenario_id
WHERE
    (timestamp > ?1 OR ?1 IS NULL)
    AND (timestamp < ?2 OR ?2 IS NULL)
    AND (status IN (?,?,?,?))
    AND (scenarios.name = ?4 OR ?4 IS NULL)

The whole ?2, ?, ?4 causes the query to not match anything when the parameters are substituted, and no error is thrown. However if I rearrange the WHERE clause so that the sqlc.slice comes at the end, things seem to work as expected.

@sybrenstuvel
Copy link

I'm running into the same thing. IMO this should at least be included in the documentation as something to be cautious about.

@traut
Copy link

traut commented May 23, 2025

I'm hitting the same issue. This looks like a major bug! I hope it will get resolved.

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

No branches or pull requests

6 participants