refactor: unify value and summary-state schemas - #535
Merged
Merged
Conversation
zzylol
commented
Oct 2, 2026
- Schema deserializes the old pre-ASAP layout (`columns`, bare dtypes) and
the old post-ASAP `SummarySchema` (no `closed`, read as the closed
`Schema::lifted` shape), so saved plans survive the upgrade.
- dag-viewer render.py reads `fields` (falling back to `columns`); viewer.js
unwraps `{"Plain": ...}` dtypes for display.
- dag_export: `--table-schema` error names the `columns` key it reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selvomega
previously approved these changes
Oct 2, 2026
zzylol
force-pushed
the
stack/528-01-schema
branch
from
October 2, 2026 19:40
f57b64b to
93ed497
Compare
Contributor
Author
|
Self-reflection: This PR raises the question of how we should design and name schemas and physical layouts (e.g., tables) for ASAP primitives, or at least summaries. Calling for a single, complete design document covering schema metadata, physical data, and summary state in #545. |
This was referenced Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 1/8 of the review stack replacing #528; implements #511's common value/state schema contract (§2.1). Base: main, including #511 and #532.
Before this PR: ordinary operators used
Column/Schema, while summary edges used separateSummaryField/SummarySchema/SummaryFamilyTypetypes.After this PR: both paths use
Schema,Field, andFieldDataType. A field can represent a plain value or typed summary state; all existing planner/frontend/runtime consumers use the shared representation. The old operator graphs remain active until later stack layers.Most changed files mechanically migrate schema fields and constructors. Review the schema definition and raw-source boundary first: SQL qualifiers must survive source binding, as verified by the existing grouped-SUM execution regression. No unified operator or scalar graph is introduced here.
Validation: workspace compilation and tests, the SQL source-binding regression, formatting, and workspace/all-target/all-feature clippy. Subsequent PRs introduce operator/scalar types, graph infrastructure, language lowerings, execution, planner cutover, and legacy cleanup. #528 remains the reference implementation until the stack is complete.
Code interface design: schema, fields, and column references
One edge schema for logical and ASAP-aware plans
Ordinary values and summary state use the same ordered schema. The core declarations in this PR are:
Fielddescribes one column; it holds no row values or runtime data arrays. The defaultField<FieldDataType>is used on operator edges. Nested list and struct members useField<DataType>, so nested elements cannot carry summary state.Field.nameField.dtypeField.nullableField.tableSchema.fieldsColumnId.Schema.time_indexSchema.unique_keysSchema.closedfalsepermits additional dynamic columns, as with schemaless PromQL sources.An open schema must not be validated as if unlisted labels were absent. Unique-key and time positions must be preserved or remapped when an operator changes the output layout; matching field names alone does not establish those properties.
A field is metadata; a column reference identifies a position
Frontend expressions initially use name-based references:
Binding resolves these references against a
Schemato positionalColumnIds.ColumnId = 2means the third field in that particular scope, and the corresponding value in an execution row. It is not a globally stable identity across projections or joins and does not prescribe a storage layout.SampleValuedenotes the implicit PromQL sample column;Wildcardrepresents an all-columns/rows request such asCOUNT(*).Schema::column_id(name)returns the first matching position;column_id_qualified(table, name)matches both qualifier and name. PreservingField.tableis therefore necessary to distinguisha.kfromb.k.ASAP summary metadata lives in the field type
The shared type vocabulary is:
Plain(DataType)is an ordinary readable value.DataTypecoversNull,Int64,Float64,Utf8,Bool, timestamps, intervals, dates, lists, structs, and maps. Every otherFieldDataTypevariant describes unfinalized state, preserving its family and concrete configuration:Field.dtypeExactAggregateSketchSketchKindcontains category, concrete algorithm, and algorithm parameters; the field also carriesGroupingStrategy. Examples: KLL withk, CMS with width/depth, HLL with precision, or UnivMon with heap size, rows, columns, and layers.SampleWaveletStatModelSketchKindhas private category/algorithm/parameter fields and exposesnew(algorithm, params),category(),algorithm(), andparams(). Its constructor classifies the category and rejects algorithm/parameter-variant mismatches by assertion.GroupingStrategydistinguishesPerSubpopulationInstancefromSharedMultiSubpopulation { kind: HydraKind, params: HydraParams }. It describes the summary layout; actual group-key positions remain operator parameters and ordinary fields in the output schema.These types provide the identity needed for compatibility checks: KLL and CMS state differ, and two KLL states with different parameters differ. Defining the metadata here does not itself implement summary merging or every declared family in a runtime.
Example: grouped KLL state and its readout
This example is closed, has no time-axis field, and makes no unique-key claim because
lifteddoes not infer one. Field 0 is a readable group label; field 1 is typed KLL state. A summary readout exposes a plain result field, such asPlain(Float64)for a quantile. Exact accumulator state similarly requires a finalization boundary before ordinary value consumers use it.Schema and field metadata describe the edge's shape and state identity. Update expressions, filters, reduction/group keys, requested readout statistic, accuracy guarantees, execution timing, window framework, retention, placement, and cost estimates are separate operator or planning metadata; they are not additional
SchemaorFieldmembers in #535.Construction, inspection, and serialization
Field::new(...)accepts either vocabulary;Field::plain(...)wraps an ordinaryDataType;with_table(...)adds a qualifier.plain_dtype()returnsNonefor state;expect_plain_dtype()panics if a caller incorrectly treats state as a readable value.is_plain()andSchema::is_all_plain()allow explicit checks.Schema::new(fields)starts open with no time axis or unique keys.with_time_index(...)supplies time/key metadata and also starts open.lifted(fields, time_index)starts closed with no unique-key claim.fieldsrepresentation. Deserialization accepts both legacycolumnswith bare value types and legacy summaryfieldswith tagged types. Missingcloseddefaults to open for the legacycolumnslayout and closed for thefieldslayout; inputs containing both lists or neither are rejected.Source at this PR's reviewed head:
schema.rs,expr_ir.rs, andsketch.rs.Stack 1/8 · Previous:
main· Next: #536 · Reference/tracker: #528Rebased onto
mainat7734c68f(#544 DAG naming), preserving schema JSON compatibility and the reviewedField/ColumnIddistinction. The #511 design documents now explicitly distinguish metadata from column references: schema contract and expression contract.