Skip to content

feat: Introduce sqlc.optional for dynamic query generation #4005

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
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

copito
Copy link

@copito copito commented Jun 29, 2025

This commit introduces the sqlc.optional feature, allowing conditional inclusion of SQL query fragments at runtime.

Key changes:

  1. Parser Enhancement: The SQL parser now recognizes sqlc.optional('ConditionKey', 'SQLFragment') syntax within query files. This information is stored in the query's metadata.

  2. Code Generation:

    • Go code generation logic has been updated to process these OptionalBlocks.
    • Generated Go functions now include new parameters (typed as interface{}) corresponding to each ConditionKey.
    • Templates (stdlib/queryCode.tmpl, pgx/queryCode.tmpl) were modified to dynamically build the SQL query string and its arguments at runtime. If an optional Go parameter is non-nil, its associated SQL fragment is included in the final query, and its value is added to the list of database arguments.
  3. Parameter Handling: $N placeholders in all SQL fragments (base or optional) consistently refer to the Nth parameter in the generated Go function's signature.

  4. Documentation: Added comprehensive documentation for sqlc.optional in docs/reference/query-annotations.md, covering syntax, behavior, parameter numbering, and examples.

  5. Examples: A new runnable example has been added to examples/dynamic_query/postgresql/ to demonstrate practical usage.

  6. Tests: New end-to-end tests were added in internal/endtoend/testdata/dynamic_query/ for both stdlib and pgx drivers, ensuring the correctness of the generated code.

This commit introduces the `sqlc.optional` feature, allowing conditional inclusion of SQL query fragments at runtime.

Key changes:

1.  **Parser Enhancement**: The SQL parser now recognizes `sqlc.optional('ConditionKey', 'SQLFragment')` syntax within query files. This information is stored in the query's metadata.

2.  **Code Generation**:
    - Go code generation logic has been updated to process these `OptionalBlocks`.
    - Generated Go functions now include new parameters (typed as `interface{}`) corresponding to each `ConditionKey`.
    - Templates (`stdlib/queryCode.tmpl`, `pgx/queryCode.tmpl`) were modified to dynamically build the SQL query string and its arguments at runtime. If an optional Go parameter is non-nil, its associated SQL fragment is included in the final query, and its value is added to the list of database arguments.

3.  **Parameter Handling**: `$N` placeholders in all SQL fragments (base or optional) consistently refer to the Nth parameter in the generated Go function's signature.

4.  **Documentation**: Added comprehensive documentation for `sqlc.optional` in `docs/reference/query-annotations.md`, covering syntax, behavior, parameter numbering, and examples.

5.  **Examples**: A new runnable example has been added to `examples/dynamic_query/postgresql/` to demonstrate practical usage.

6.  **Tests**: New end-to-end tests were added in `internal/endtoend/testdata/dynamic_query/` for both `stdlib` and `pgx` drivers, ensuring the correctness of the generated code.
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. 🔧 golang labels Jun 29, 2025
@ororsatti
Copy link

Just a comment, but maybe the optional types can be something like NullString ?

struct xxxOptional {
Xxx *<type>
Valid bool
}

This way it won't have to be interface{} when ever you wanna use a optional value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size:XXL This PR changes 1000+ lines, ignoring generated files. 🔧 golang
2 participants