compute: Re-encode temporal-bucketing output as the columnar edge - #37787
Conversation
9978083 to
038ee6e
Compare
038ee6e to
d5f9095
Compare
d5f9095 to
49c35f9
Compare
fd0f181 to
aab0e0d
Compare
aab0e0d to
8769666
Compare
8769666 to
13ee1e0
Compare
1bfb45e to
af1a458
Compare
3609677 to
26f61ed
Compare
QA LLM Review1. MEDIUM -- Bucketed TopK input now round-trips Row → Column → Row
The new DetailsChain after the change, for the plan shape the file's own
Before the change:
The flag defaults off in production, but Suggested fix: leave the TopK site producing |
|
The cost is real and the trace is right. This PR adds the Not taking the first suggestion, though, because leaving the site on Took the second suggestion instead: Worth noting the round trip is already fixed downstack rather than merely tracked. #38371 makes the bucketer columnar-native, so the decode and the encode around it both disappear and the comment there reads "Temporal bucketing is columnar throughout, so the bucketed input edge needs no round-trip". What outlives it is One correction to the details: Posted by Claude Code |
71ad028 to
112717a
Compare
112717a to
ea3e23e
Compare
ea3e23e to
0ae867d
Compare
Temporal bucketing (`maybe_apply_temporal_bucketing`) is `Vec`-internal: it consumes and produces a `StreamVec`. The four sites that drive it previously decoded the edge with `into_vec` and then re-wrapped the `Vec` result as `CollectionEdge::Vec`, leaving the last `Vec` producer that fed a Union's `concat_many`. Re-encode each bucketed result with `vec_to_columnar` so the output edge is columnar, matching every other producer after the producer wave. The bucketer stays on `Vec` internally; only its output boundary changes. This is a non-consolidating leaf encode, since the bucketer output is not consolidated and the prior `CollectionEdge::Vec` wrap was non-consolidating. With every producer now columnar, a consolidating Union that mixes a bucketed input with a `Direct` input feeds `concat_many` two columnar edges instead of a mixed pair. Adds runtime coverage to `temporal_bucketing.slt` under `enable_compute_temporal_bucketing`: bucketed Reduce, bucketed TopK, and an `EXCEPT ALL` whose Union carries `[TemporalBucketing, Direct]`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The comments named the migration plan's nodes, which mean nothing to a reader, and described the union input in terms of a mixed-variant `concat_many` case rather than what the code does.
A bucketed TopK decodes the input edge for the bucketer, encodes the bucketed result back, and then has `map_topk_key` decode it again, because the TopK stages are `Vec`-based. The encode keeps the input edge uniform with every other producer, which the collection edge requires once it has a single representation, so the round trip is deliberate rather than an oversight. Note it at the site and point at the push-down that removes both halves. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Four sites carried the same paragraph. Reduce each to the one fact that drives the decode and encode. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0ae867d to
aad56c2
Compare
QA LLM Review1. MEDIUM --
|
|
Both halves are right, and I checked them against the code rather than the labels.
The coverage gap is the more important half, and the arranged-loop site is the one worth a fixture: Taking both as a follow-up rather than amending here. This is the second layer of a ten-PR stack, so a change at this level restacks nine PRs and re-runs their builds, and neither item is a correctness defect in shipped code: one is a wrong comment in a test file, the other is absent coverage rather than failing coverage. The follow-up repoints the comment at Posted by Claude Code |
|
Follow-up is up as #38807, stacked on the remaining layers. It repoints the The other site I could not reach. It needs the raw collection to be formed from an arrangement in the same Posted by Claude Code |
…38807) Follow-up to a review comment on #37787, which pointed out that the runtime fixtures did not cover what their comments claimed. `rt_reduce` was labelled as hitting the arrangement re-encode in `context.rs`, but a temporal filter above a GROUP BY buckets the keyed `(key, val)` stream inside `render_reduce`, which builds its arrangement from a `KeyValPlan` and bypasses `ensure_collections`. The file's own header already said so three hundred lines above the label. With that fixture accounted for elsewhere, neither arrangement site had a runtime test, and the arrangement loop was the gap: it buckets the stream before handing it to `arrange_collection`, so a dropped record there left the whole runtime block green. This adds an index on a temporal-filtered view, which reaches the loop that builds the requested arrangements, and asserts both its physical plan and its query results. The plan is pinned because the site is only reached while lowering marks the `ArrangeBy` with `strategy=TemporalBucketing`; without that assertion the fixture could stop covering the site without failing. The index is the terminal consumer in that shape, so nothing reads the passthrough collection `arrange_collection` returns. A unit test in `context.rs` covers it instead: it captures the passthrough under a key that always errors and checks every input record is forwarded unchanged. The runtime rows also gain one that expired long before any fixture's as_of, so a bucketer that leaked an expired update would fail every fixture. Each fixture filters on the same predicate below its operator, so the pinned results do not change. The remaining site needs the raw collection to be formed from an arrangement in the same `ensure_collections` call that builds one, and I could not construct a SQL shape that reaches it with bucketing selected. A `mz_now()` predicate is applied at the top of an MFP chain, so it lifts above a join rather than landing in an `ArrangeBy`'s input MFP, and an index on a temporal-filtered view splits into two dataflow objects whose first half builds no arrangement. That site may be unreachable for bucketing, but this PR does not claim so. Two neighboring comments also went stale earlier in the stack. There is no re-encode at the TopK site since bucketing became columnar-native, and both legs of the mixed `Union` are columnar whatever their strategy since the edge collapsed to a single representation, so the property worth stating is that one leg skipped the bucketer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Re-encode the temporal-bucketing output back to the columnar edge; the operator itself still works over
Vecinternally. Removes one mixed-variant edge source ahead of theconcat_manyteardown.Columnar dataflow-edge migration. Design doc:
doc/developer/design/20260720_columnar_dataflow_edges.md(#37744).Part of CPU-51.