> **See also:** [ROADMAP.md](../ROADMAP.md)

## v1.6.0 — Automatic Query Acceleration

> **Release Theme**
> Today an application has to know that a stream table exists and query it by
> name. This release lets the planner do that instead: when an ordinary query
> can be answered by an existing, sufficiently fresh stream table, pg_trickle
> rewrites it to read the stream table.
>
> Materialized-view query rewriting is a well-understood and widely requested
> capability in other query engines, but it is deliberately placed **after
> 1.0**: optimizer integration is both complicated and potentially surprising,
> and surprising a DBA is exactly what the 1.0 contract promises not to do.

### Concept

```sql
-- The user writes this:
SELECT region, SUM(amount) FROM orders GROUP BY region;

-- pg_trickle recognizes that sales_by_region already answers it,
-- and (if fresh enough) rewrites the scan to read the stream table.
```

| Item | Description |
|------|-------------|
| QA-1 | **Subsumption matching.** Match an incoming query's parsed tree against the OpTree of every eligible stream table: exact match first, then containment (stream table computes a superset that can be filtered/re-aggregated). Reuse the existing OpTree classifier rather than a second query representation. |
| QA-2 | **Planner hook integration.** Rewrite via `planner_hook`/`set_rel_pathlist_hook`, producing a *candidate path* costed against the original plan so the rewrite is only chosen when the planner agrees it is cheaper. |
| QA-3 | **Freshness as a correctness precondition.** A rewrite is only legal when the stream table's current lag is within the session's tolerance: `pg_trickle.acceleration_max_staleness` (default `'0'` = only if provably up to date). Never trade correctness for speed silently. |
| QA-4 | **Opt-in by default, per scope.** `pg_trickle.query_acceleration = off` globally at first; enable per database, per role, or per session. A stream table can opt out with `WITH (acceleration = false)`. |
| QA-5 | **Explainability.** `EXPLAIN` states plainly when a rewrite happened and why: which stream table, what lag, what the alternative cost was. `pgtrickle.explain_acceleration(query)` answers "why was my query *not* accelerated?" for the cases where a user expected it. |
| QA-6 | **Safety boundaries.** No rewrite when the query is inside a transaction that has already written to a source table, when RLS applies to the source but not the stream table, when the stream table is suspended, or when the query targets a source under an incompatible snapshot. Each boundary is a test. |

### Why after 1.0

- It changes plans for queries the user did not write against pg_trickle, which
  is the highest-surprise thing an extension can do.
- It requires the freshness contract from v0.90.0 to be mature and trusted.
- It benefits from a stable OpTree representation, which the 1.0 API contract
  provides.

**Exit criteria:**
- [ ] Exact and containment matching implemented over the OpTree classifier
- [ ] Rewrite is cost-based; never applied when the original plan is cheaper
- [ ] Staleness tolerance enforced; default configuration accelerates only
      provably fresh reads
- [ ] Off by default; opt-in per database/role/session and per stream table
- [ ] `EXPLAIN` discloses every rewrite; `explain_acceleration()` explains
      non-rewrites
- [ ] Every safety boundary covered by a negative test
