feat(protos)!: require explicit interval precision and allow picoseconds#1110
Merged
nielspardon merged 1 commit intoJul 9, 2026
Merged
Conversation
nielspardon
requested review from
EpsilonPrime,
benbellick,
cpcloud,
jacques-n,
vbarua,
westonpace and
yongchul
as code owners
June 26, 2026 07:55
IntervalDay.precision was the only sub-second precision field declared optional with an implicit "if unset, treat as 6" default. Every other precision-bearing type (PrecisionTimestamp, PrecisionTimestampTZ, PrecisionTime, IntervalCompound) uses a plain int32 where 0 means seconds and there is no meaningful unset state. This forced consumers to special-case IntervalDay, and implementations diverged on whether they honored the unset->6 rule. Following the community sync discussion on substrait-io#1110: - Drop the "if unset, treat as 6" default. The field stays optional but implementations should reject an unset precision rather than assuming a default. - Allow picoseconds (precision 12) for interval_day and interval_compound by aligning their precision comments with the precision timestamp types, and widen INTERVAL_DAY to 0 <= P <= 12 in the docs and the dialect schema (which already capped INTERVAL_COMPOUND at 12). - Align the interval_day/interval_compound literal comment (IntervalDayToSecond.precision) to mention picoseconds, and clarify that the int64 subseconds field carries only the sub-second component in 1e(-precision) units (below 1e12 at picosecond precision, so it fits int64 comfortably); whole seconds belong in the seconds field. Closes substrait-io#1109 BREAKING CHANGE: An unset IntervalDay.precision no longer has a defined meaning. Previously an unset precision was treated as 6 (microseconds); implementations should now reject an unset precision instead of applying a default. Producers must set precision explicitly.
nielspardon
force-pushed
the
fix/interval-day-precision-required
branch
from
July 2, 2026 08:42
940cbf8 to
b6398cc
Compare
yongchul
approved these changes
Jul 2, 2026
This was referenced Jul 16, 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.
Summary
Following the community sync discussion on this PR, this changes how sub-second precision is handled for
interval_day(and alignsinterval_compound), rather than makingprecisiona plain required field as originally proposed.Type.IntervalDay.precisionwas the only sub-second precision field declaredoptionalwith an implicit "if unset, treat as 6" default. Every other precision-bearing type (PrecisionTimestamp,PrecisionTimestampTZ,PrecisionTime,IntervalCompound) uses a plainint32where0means seconds and there is no meaningful unset state. Theoptional+ "treat as 6" design forced every consumer to special-caseIntervalDay, and implementations diverged on whether they honored the unset→6 rule (substrait-java and substrait-go relied on it; substrait-python and substrait-rs did not — see the cross-library survey in #1109).Changes
optional, but implementations should reject an unset precision rather than assuming a default.12) forinterval_dayandinterval_compoundby aligning their precision comments with the precision-timestamp types.INTERVAL_DAYis widened to0 <= P <= 12in the docs and in the dialect schema (which already cappedINTERVAL_COMPOUNDat12).IntervalDayToSecond.precision) to mention picoseconds, and clarify that theint64subsecondsfield carries only the sub-second component in1e(-precision)units — below1e12at picosecond precision, so it fitsint64with ample headroom (~40 of 63 bits). Whole seconds belong in thesecondsfield, notsubseconds.Notes for reviewers
The field keeps
optional(implicit presence retained), so there is no wire-cardinality change — this is a semantic breaking change (the meaning of an unset precision changes), which we still want to announce.buf breakingwill therefore not flag this PR. Thegrammar/SubstraitType.g4rule already requires<P>forinterval_day.Closes #1109
BREAKING CHANGE: An unset
IntervalDay.precisionno longer has a defined meaning. Previously an unset precision was treated as6(microseconds); implementations should now reject an unset precision instead of applying a default. Producers must setprecisionexplicitly.🤖 Generated with AI
This change is