Spec v0.102.0 (substrait-io/substrait#1105) deprecates the integer offset of the Preceding/Following window bounds in favour of offset_expr, an arbitrary expression. #290 bumps to v0.102.0 without changing producers: Expr.over(rows=…/range=…) still emits only offset, which remains valid.
Proposal
- Dual-write integer bounds. For an int endpoint, have
_window_bound set both offset and an equivalent int64-literal offset_expr. The spec explicitly allows this during migration, so consumers that only read offset keep working.
- Accept non-integer RANGE endpoints. Let a
range= endpoint be an expression or literal (e.g. an interval_day, a decimal), emitted as offset_expr only. This enables windows such as RANGE BETWEEN INTERVAL '7' DAY PRECEDING AND CURRENT ROW, which offset cannot express.
Spec constraints to honour
- ROWS:
offset_expr must be int64.
- RANGE with
Preceding/Following: exactly one ordering expression, not SORT_DIRECTION_CLUSTERED. The offset type D must satisfy add(T, D) -> T and subtract(T, D) -> T for the ordering type T.
- A statically-known zero offset is emitted as
CurrentRow, not as a zero offset_expr.
offset_expr must not contain window or aggregate functions. Its field references resolve against the window relation's input schema.
Open question
Should the direction of a non-literal RANGE endpoint be explicit (e.g. preceding(...) / following(...) helpers) rather than sign-based, since an expression has no sign to inspect?
Spec v0.102.0 (substrait-io/substrait#1105) deprecates the integer
offsetof thePreceding/Followingwindow bounds in favour ofoffset_expr, an arbitrary expression. #290 bumps to v0.102.0 without changing producers:Expr.over(rows=…/range=…)still emits onlyoffset, which remains valid.Proposal
_window_boundset bothoffsetand an equivalent int64-literaloffset_expr. The spec explicitly allows this during migration, so consumers that only readoffsetkeep working.range=endpoint be an expression or literal (e.g. aninterval_day, a decimal), emitted asoffset_expronly. This enables windows such asRANGE BETWEEN INTERVAL '7' DAY PRECEDING AND CURRENT ROW, whichoffsetcannot express.Spec constraints to honour
offset_exprmust beint64.Preceding/Following: exactly one ordering expression, notSORT_DIRECTION_CLUSTERED. The offset typeDmust satisfyadd(T, D) -> Tandsubtract(T, D) -> Tfor the ordering typeT.CurrentRow, not as a zerooffset_expr.offset_exprmust not contain window or aggregate functions. Its field references resolve against the window relation's input schema.Open question
Should the direction of a non-literal RANGE endpoint be explicit (e.g.
preceding(...)/following(...)helpers) rather than sign-based, since an expression has no sign to inspect?