https://github.com/pgx-contrib/pgxquery
pgx QueryRewriter that injects dynamic WHERE and ORDER BY clauses via SQL sentinel comments — safe, parameterised, zero-magic
https://github.com/pgx-contrib/pgxquery
dynamic-filtering dynamic-ordering go golang order-by pgx postgres postgresql query-rewriter sqlc where-clause
Last synced: 6 days ago
JSON representation
pgx QueryRewriter that injects dynamic WHERE and ORDER BY clauses via SQL sentinel comments — safe, parameterised, zero-magic
- Host: GitHub
- URL: https://github.com/pgx-contrib/pgxquery
- Owner: pgx-contrib
- License: mit
- Created: 2026-04-24T13:39:25.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-05T21:24:09.000Z (13 days ago)
- Last Synced: 2026-06-05T23:10:13.142Z (13 days ago)
- Topics: dynamic-filtering, dynamic-ordering, go, golang, order-by, pgx, postgres, postgresql, query-rewriter, sqlc, where-clause
- Language: Go
- Homepage:
- Size: 69.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# pgxquery
[](https://github.com/pgx-contrib/pgxquery/actions/workflows/ci.yml)
[](https://github.com/pgx-contrib/pgxquery/releases)
[](https://pkg.go.dev/github.com/pgx-contrib/pgxquery)
[](LICENSE)
[](https://go.dev)
[](https://github.com/jackc/pgx)
A [pgx](https://github.com/jackc/pgx) `QueryRewriter` adapter that substitutes
sentinel comments in your SQL with dynamic `WHERE` and `ORDER BY` fragments at
query time. Write your SQL with `/* AND query.where */` and `/* , query.order_by */`
markers, set the `Where` / `OrderBy` strings on a `QueryRewriter`, and let it
splice them in — preserving your chosen connective or separator verbatim.
## Installation
```bash
go get github.com/pgx-contrib/pgxquery
```
## Usage
Place sentinel comments in your SQL at the positions where dynamic fragments
should appear. Each sentinel has the form `/* query. */`.
The prefix and suffix (whitespace, connectives like `AND`/`OR`, separators like
`,`) are preserved around the substituted value; when the value is empty the
whole sentinel is dropped.
```go
type User struct {
ID int `db:"id"`
Name string `db:"name"`
Role string `db:"role"`
}
rows, err := pool.Query(ctx,
`SELECT id, name, role
FROM users
WHERE tenant_id = $1
/* AND query.where */
ORDER BY id
/* , query.order_by */`,
&pgxquery.QueryRewriter{
Where: "role = 'admin'",
OrderBy: "name asc",
Args: []any{42},
},
)
```
Recognised sentinel names are `where` and `order_by`. `Args` are appended to
the positional parameters passed to `pool.Query` — so the `$1` above is filled
from `Args[0]`. When `Where` or `OrderBy` is empty, its sentinel is stripped
entirely, leaving the surrounding SQL valid.
`$N` placeholders inside `Where` and `OrderBy` use **local numbering**: `$1`
refers to `Args[0]`, `$2` to `Args[1]`, and so on. The rewriter shifts them
by the count of base args so they hit the right slots in the final flat
parameter list. Placeholders inside string literals, quoted identifiers,
dollar-quoted bodies and SQL comments are left untouched.
## Development
### DevContainer
Open in VS Code with the Dev Containers extension. The environment provides Go,
PostgreSQL 18, and Nix automatically.
```
PGX_DATABASE_URL=postgres://vscode@postgres:5432/pgxquery?sslmode=disable
```
### Nix
```bash
nix develop # enter shell with Go
go tool ginkgo run -r
```
### Run tests
```bash
# Unit tests only (no database required)
go tool ginkgo run -r
# With integration tests
export PGX_DATABASE_URL="postgres://localhost/pgxquery?sslmode=disable"
go tool ginkgo run -r
```
## License
[MIT](LICENSE)