Skip to content

feat(protos)!: require explicit interval precision and allow picoseconds#1110

Merged
nielspardon merged 1 commit into
substrait-io:mainfrom
nielspardon:fix/interval-day-precision-required
Jul 9, 2026
Merged

feat(protos)!: require explicit interval precision and allow picoseconds#1110
nielspardon merged 1 commit into
substrait-io:mainfrom
nielspardon:fix/interval-day-precision-required

Conversation

@nielspardon

@nielspardon nielspardon commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary

Following the community sync discussion on this PR, this changes how sub-second precision is handled for interval_day (and aligns interval_compound), rather than making precision a plain required field as originally proposed.

Type.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. The optional + "treat as 6" design forced every consumer to special-case IntervalDay, 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

  • 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. INTERVAL_DAY is widened to 0 <= P <= 12 in the docs and in the dialect schema (which already capped INTERVAL_COMPOUND at 12).
  • Align the 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 with ample headroom (~40 of 63 bits). Whole seconds belong in the seconds field, not subseconds.

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 breaking will therefore not flag this PR. The grammar/SubstraitType.g4 rule already requires <P> for interval_day.

Closes #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.

🤖 Generated with AI


This change is Reviewable

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
nielspardon force-pushed the fix/interval-day-precision-required branch from 940cbf8 to b6398cc Compare July 2, 2026 08:42
@nielspardon nielspardon changed the title feat(protos)!: make IntervalDay.precision a required int32 feat(protos)!: require explicit interval precision and allow picoseconds Jul 2, 2026
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.

IntervalDay.precision is the only precision field that is optional with an implicit default of 6 — consider making it consistent

2 participants