Skip to content

adapter: Move frontend-only peek helpers out of the coordinator - #39585

Closed
ggevay wants to merge 8 commits into
MaterializeInc:mainfrom
ggevay:gabor/peek-seq-r3-move-shared-helpers
Closed

ggevay wants to merge 8 commits into
MaterializeInc:mainfrom
ggevay:gabor/peek-seq-r3-move-shared-helpers

Conversation

@ggevay

@ggevay ggevay commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #39579, #39580, #39581, #39582, #39583 and #39584. Review only the last commit.

The frontend peek sequencing reached into coord::sequencer for helpers that the coordinator peek path used to share (the module comment's TODO(peek-seq)).

  • Moved into frontend_peek, since they have no coordinator callers any more: explain_plan_inner, explain_subscribe_inner, eval_copy_to_uri, statistics_oracle, check_log_reads. Pure move apart from visibility (git show --color-moved).
  • Kept in the coordinator, which still uses them: emit_optimizer_notices, and explain_pushdown_future_inner (EXPLAIN FILTER PUSHDOWN for materialized views).
  • Docs. Dropped the comments that describe helpers as shared between the old and new peek sequencing.

No behavior change intended.

🤖 Generated with Claude Code

@ggevay
ggevay force-pushed the gabor/peek-seq-r3-move-shared-helpers branch from 255714a to 73c2fed Compare October 6, 2026 12:51
ggevay and others added 8 commits October 7, 2026 09:55
Frontend peek sequencing has been the default since December 2025, so the
coordinator's peek path only ran for sessions started with
`enable_frontend_peek_sequencing` turned off. Remove the flag and the path.

Every statement kind that plans to a SELECT, SHOW COLUMNS, COPY TO, a
side-effecting function, or an EXPLAIN (FILTER PUSHDOWN) of a SELECT is
taken over by the frontend, so the coordinator arms for them now retire with
an internal error. Delete `sequence_peek`, `sequence_copy_to`,
`explain_peek`, `sequence_side_effecting_func`, the `PeekStage` state machine
and the optimizer wrapper only it used. The coordinator keeps what the
frontend still calls into: `implement_peek_plan` for slow-path peeks,
`implement_copy_to`, `execute_side_effecting_func`, and
`sequence_peek_timestamp`, which EXPLAIN TIMESTAMP uses.

Tests that switched the flag off now run the frontend path:
`test_expected_spans` looks for frontend spans, with a new debug-level span
on `try_frontend_peek_inner`, and `test_github_25388` drops its SELECT half,
which only held for the coordinator's post-optimization dependency check.
`transactions.slt` enables its test of an AS OF query outside the
transaction's timedomain, which was commented out until CI ran the frontend
sequencing. mzcompose pins the flag for older binaries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…or SUBSCRIBE sequencing

Frontend subscribes have been on by default since MaterializeInc#35756, and with the
coordinator peek path gone the only SUBSCRIBE-related statement the
coordinator still sequenced was EXPLAIN ... SUBSCRIBE. Sequence it in the
frontend peek path, alongside EXPLAIN of a SELECT, and remove the
coordinator's SUBSCRIBE state machine, keeping `implement_subscribe`, which
the frontend uses to ship the dataflow.

EXPLAIN SUBSCRIBE keeps the coordinator's behavior: it adds no transaction
operation and does not require a replica, EXPLAIN BROKEN renders despite a
failed LIR optimization, and an `UP TO` equal to the `AS OF` still raises the
`EqualSubscribeBounds` notice. `explain_subscribe_inner` renders the rows
with the features the subscribe was optimized with, as `explain_plan_inner`
does for a SELECT.

Remove the `enable_frontend_subscribes` dyncfg. mzcompose pins it for older
binaries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rral

EXPLAIN TIMESTAMP was the last statement that the coordinator sequenced
through timestamp selection. Sequence it in the frontend peek path, which
already does everything it needs: it optimizes the query locally (so that,
as before, the dependencies that decide the timestamp are those of the
optimized query), determines the timestamp with the frontend's read holds,
and asks the coordinator for the frontier explanation through the
`ExplainTimestamp` command that the timestamp notice already uses. As on the
coordinator, it requires no replica, skips the introspection-read checks,
does not require linearization, and rejects `AS DOT` before doing anything.

Remove the coordinator's EXPLAIN TIMESTAMP state machine and
`sequence_peek_timestamp`. With that, no plan that reaches the coordinator
reads a builtin table written at session startup, so `sequence_plan` no
longer defers plans for those writes: remove `DeferredPlan`, `defer_plan`,
`sequence_deferred_plan` and `Message::DeferredPlanReady`, and drop the
dependency set from `waiting_on_startup_appends`, which only the frontend
paths call now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the coordinator peek sequencing gone, the frontend no longer has to
mirror where that path logged `execution_timestamp`. Log it once, right after
timestamp determination, for every peek and SUBSCRIBE that executes at a
timestamp:

- Constant peeks that have a timestamp now record it. Constant queries without
  a timeline still have none.
- Queries without a timestamp that execute on a cluster (timestamp-independent
  ones, e.g. over a large `generate_series` view) record none instead of the
  maximum timestamp, like constant queries without a timeline.
- Slow-path peeks no longer rely on `implement_peek_plan` to log it.
- SUBSCRIBEs record their `AS OF` again, which the coordinator path did and
  the frontend path did not.
- A statement that fails after timestamp determination keeps its timestamp.

EXPLAIN and COPY TO still record none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The frontend implements fast-path and constant peeks itself, so the
coordinator's `implement_peek_plan` only ever received slow-path plans from
`implement_slow_path_peek`. Fold its slow-path arm into
`implement_slow_path_peek`, delete its fast-path and constant arms and
`PlannedPeek`, and create the statement-logging guard only once the peek is
registered, so that no error path has to defuse it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It is a free function that both the frontend's fast path and the
coordinator's slow path use, and it touches no coordinator state. Move it to
`peek_client`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…away

`execute_attempts` passes the frontend peek sequencing the future that
resolves when the client connection closes, which the coordinator path
already selects on. Waiting for the optimizer now gives up on it, the same
way it gives up on a statement timeout: the statement ends as canceled and
the optimization task finishes in the background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The frontend peek sequencing reached into `coord::sequencer` for helpers that
the coordinator peek path used to share. With that path gone,
`explain_plan_inner`, `explain_subscribe_inner`, `eval_copy_to_uri`,
`statistics_oracle` and `check_log_reads` have no coordinator callers, so
move them into `frontend_peek`. `emit_optimizer_notices` and
`explain_pushdown_future_inner` stay, the coordinator still uses them. Drop
the docs that describe helpers as shared between the old and new peek
sequencing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ggevay
ggevay force-pushed the gabor/peek-seq-r3-move-shared-helpers branch from 73c2fed to d267e31 Compare October 7, 2026 08:06
@ggevay ggevay closed this Oct 7, 2026
@ggevay

ggevay commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #39630, which is part of a native GitHub stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant