sqlc-dev / sqlc

Generate type-safe code from SQL
https://sqlc.dev
MIT License
13.45k stars 804 forks source link

Cannot pass empty values for sqlc.slice #3327

Open pengux opened 7 months ago

pengux commented 7 months ago

Version

1.25.0

What happened?

For the query:

-- name: List :many
SELECT *
FROM table
WHERE (id IN (sqlc.slice('ids')) OR sqlc.slice('ids') == NULL)
ORDER BY id;

call querier.List(ctx, nil) will results in the error not enough args to execute query: want 1 got 0

Relevant log output

No response

Database schema

No response

SQL queries

No response

Configuration

No response

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

pengux commented 4 months ago

this seems to be because the generated code only replace one occurrence of /*SLICE:ids*/?:

    if len(ids) > 0 {
        for _, v := range ids {
            queryParams = append(queryParams, v)
        }
        query = strings.Replace(query, "/*SLICE:ids*/?", strings.Repeat(",?", len(ids))[1:], 1)
    } else {
        query = strings.Replace(query, "/*SLICE:ids*/?", "NULL", 1)
    }
ahembergssc commented 3 days ago

Having the same problem. For this type of query, would it be possible to recognize that sqlc.slice('ids') appears twice and change the generated code output to:

if len(ids) > 0 {
    for _, v := range ids {
        queryParams = append(queryParams, v)
    }
    query = strings.Replace(query, "/*SLICE:ids*/?", strings.Repeat(",?", len(ids))[1:], 2)
} else {
    query = strings.Replace(query, "/*SLICE:ids*/?", "NULL", 2)
}

If I manually make that change in the generated code I get the expected behaviour for a very similar query.