Context
#1092 stops the persisted cost estimate from leaking row-security bound values by dropping every plan node's detail (and raw_plan) whenever a row-security directive was applied. That is fail-closed but costs reviewers the predicate / index-condition text on exactly the queries that are row-secured.
Proposal
For PostgreSQL, plan the row-secured statement without the bound values so the plan shows $1 instead of the literal, and keep detail / raw_plan:
Evaluate the equivalent for the other relational planners (MySQL/MariaDB have no generic-plan EXPLAIN — likely stay on stripping / redaction).
Trade-offs
- Row estimates for the RLS-filtered column become generic (selectivity guess), not specific to the submitter's value — affects
estimated_rows, the estimated_rows / scan_type routing conditions and the AI prompt summary. Measure the drift before switching.
- Needs a server-version probe per datasource.
Acceptance
- A row-secured PostgreSQL estimate persists predicate text containing only placeholders; an integration test asserts the bound value appears nowhere in
plan / raw_plan / the GET /queries/{id} response.
- Non-RLS queries unchanged.
- docs/05-backend.md → "Automatic pre-flight cost estimate" updated.
Context
#1092 stops the persisted cost estimate from leaking row-security bound values by dropping every plan node's
detail(andraw_plan) whenever a row-security directive was applied. That is fail-closed but costs reviewers the predicate / index-condition text on exactly the queries that are row-secured.Proposal
For PostgreSQL, plan the row-secured statement without the bound values so the plan shows
$1instead of the literal, and keepdetail/raw_plan:EXPLAIN (GENERIC_PLAN, FORMAT JSON) <sql>— no binds are sent at all.PREPARE+SET plan_cache_mode = force_generic_plan+EXPLAIN EXECUTE, or fall back to the proxy: cost estimate plan leaks row-security bound values #1092 stripping.Evaluate the equivalent for the other relational planners (MySQL/MariaDB have no generic-plan EXPLAIN — likely stay on stripping / redaction).
Trade-offs
estimated_rows, theestimated_rows/scan_typerouting conditions and the AI prompt summary. Measure the drift before switching.Acceptance
plan/raw_plan/ theGET /queries/{id}response.