The direct answer
Keep the report’s SQL grammar trusted, map an admitted sort label to an application-owned identifier, and bind filter values separately through the selected driver contract. A value placeholder does not represent a column name, and identifier quoting does not authorize choosing that column. Two preselected static statements remain a valid simpler alternative.
Decide whether composition is needed at all
A fictional reporting tool supports one bounded catalogue report. A person can choose ordering by creation time or title and filter by an ordinary title value. The assistant may propose those bounded choices; it cannot provide a statement, relation, projection, direction or function.
The read-only reporting profile already selects trusted statements and excludes model-selected SQL identifiers. Preserve that baseline. If two reviewed static statements meet this interface, use that simpler design. This worksheet examines the alternative where a trusted application deliberately composes one reviewed column choice within a fixed report.
Name three different inputs to the driver
The selected Psycopg parameter guide and SQL composition reference identify 3.3.7.dev1 documentation. That development-doc snapshot does not establish an installed or recommended production release. Pin and review the actual supported implementation before relying on this profile.
The parameter guide describes execute() receiving the query and a separate value sequence. Positional binding needs a sequence even for one value, uses an unquoted %s placeholder, and does not bind table or field names. Do not substitute Python interpolation or concatenation.
The composition reference describes SQL.format() preserving %s value placeholders while composing other parts. SQL template text is not escaped. Identifier represents identifiers using their distinct quoting rules. Its format API can also wrap ordinary objects as Literal; the narrower Identifier-only branch below is application policy, not a claimed library rejection.
Trusted grammar, owned identifier and data value consequently need separate review entries. A string being short or schema-valid does not determine which role it may occupy. The application chooses that role before passing the proposal onward.
Write the owned mapping before accepting a proposal
Invent report R-A and trusted template revision T-A. Its relation, selected public report fields, equality filter, ascending direction and bounded result policy are fixed in application code. It uses no caller-selected relation, schema, join, operator or direction. A separately reviewed execution profile must constrain database identity, accessible rows and columns, callable code and resources.
The allowed sort labels are CREATED and TITLE. Application-owned mapping M-A maps CREATED to its reviewed creation-time column and TITLE to its reviewed title column. These names describe fictional metadata; they are not a database inspected here. CREATED is a neutral label for ascending creation-time order, not a promise of newest-first ordering.
For the ordinary positive, proposal P-A selects CREATED and value “Draft A.” Trusted code resolves the enum through M-A, represents only the resulting owned column with the selected Identifier branch, and keeps the title value in the separate execute argument sequence. No assembled SQL or driver object is constructed in this article.
| Role | Owner and permitted input | Required evidence |
|---|---|---|
| Grammar | T-A owns operation, relation, projection, filter and direction | Fixed reviewed template, no caller fragment |
| Identifier | M-A resolves CREATED or TITLE to one owned column | Exact mapping revision and selected composition branch |
| Value | P-A proposes bounded ordinary title text | Admitted value bound separately; no SQL interpolation |
| Execution | Trusted executor owns connection and report authorization | Complete current execution profile, bounds and rights |
The positive remains conditional on every actual prerequisite. It establishes the intended three-way handoff, not observed database access, correct output or permission to execute arbitrary SQL.
Reject the wrong role before applying a quoting tool
If the proposal supplies a column-looking string instead of an allowed enum, reject it before composition. Quoting that string would change its syntax treatment without establishing membership in M-A. Likewise, a model-supplied direction or operator must not be wrapped as SQL and accepted as trusted grammar.
The composition reference distinguishes an Identifier containing one name from a qualified sequence of names. This profile permits only its mapped single-column branch; arbitrary dotted input cannot select a new schema or relation. Do not broaden the interface merely because the library can represent more forms.
Do not use a rendered query preview as the permission check. The same reference warns that as_string() without a context gives generic output rather than target-specific encoding and escaping details. This worksheet supplies no rendering or adaptation recipe and no claim that an attractive preview matches an actual supported connection.
Review eight inert composition cards
All cards are PROPOSED_UNRUN. There is no SQL statement, cursor, Identifier or connection behind the labels.
| Card | Condition | Proposed disposition |
|---|---|---|
| 1. Ordinary report | P-A uses CREATED and Draft A; M-A/T-A and all actual prerequisites established. | Conditionally ready for separately authorized bounded reporting. |
| 2. Unknown sort string | Proposal names an unlisted column-shaped value. | Reject before composition; quoting is not admission. |
| 3. Identifier through value binding | A value placeholder is offered for the sort column. | Selected identifier contract is not established; no guessed server result. |
| 4. Value enters grammar | Title text is merged into template text. | Reject the value-binding bypass. |
| 5. Caller fragment | Proposal supplies SQL, operator or direction. | Reject even if another field uses Identifier correctly. |
| 6. Quoted but unapproved | A syntactically quoted object lies outside the owned mapping. | Reject query scope; syntax handling is not authorization. |
| 7. Changed report profile | Projection, relation, grants or template revision changes. | Require a new complete execution review. |
| 8. Unknown effective implementation | Driver, mapping, bounds or current report rights cannot be established. | Hold the positive; no preview or library name fills the gap. |
Keep composition evidence narrower than database safety
The useful decision is whether each variable belongs in an admitted identifier position or a separate data position while grammar stays application-owned. That does not settle row policies, pool/session state, snapshots, query cost or consistency of returned rows. The fixed result policy is not a measured database-work bound.
Actual driver applicability, immutable T-A/M-A association, value bounds, effective database identity and grants, supported connection handling and current report authority remain unimplemented prerequisites. Unknowns block admission. No driver import, SQL assembly, query, database operation, parser, API or model experiment occurred for these cases.
Boundary remains prelaunch with planned request-path checks. It does not ship this query composer, database authorization service or SQL sandbox. Its separate synthetic policy evidence does not validate the composition worksheet.
Primary sources
Official references supporting the guidance. Examples in this guide are synthetic and are not reports of a production incident.