Skip to content

isthmus: a fractional RANGE window offset is emitted against an integral ordering column #1230

Description

@nielspardon

normalizeIntegralOffset in WindowBoundConverter returns early when the offset is not an integral literal, so the ordering expression's type is never consulted for a fractional offset. On fb6a54ad, select sum(O_SHIPPRIORITY) over (order by O_SHIPPRIORITY range between 1.5 preceding and current row) from ORDERS converts to Preceding{DecimalLiteral{1.5}} against an i32 ordering column.

Per site/docs/expressions/window_functions.md:34 at spec v0.102.0, a RANGE offset_expr's type D must be compatible with the ordering expression's type Tadd(T, D) -> T and subtract(T, D) -> T must be defined. functions_arithmetic.yaml defines add/subtract only for matched pairs, and site/docs/types/type_system.md:17 rules out coercion ("Substrait employs a strict type system without any coercion rules"), so no add(i32, decimal<P,S>) -> i32 exists and the emitted plan is invalid.

The integral half of that rule is now handled: #1206 makes an integral offset that cannot be retyped to the ordering column throw. A fractional offset takes the early return above that check, so the two halves behave differently — an oversized integral offset is rejected while a type-mismatched fractional one is emitted. Calcite does not catch it either, since SqlWindow#validateFrameBoundary checks only the type family for a RANGE bound.

The existing tests precedingWithDecimalOffsetKeepsItsFraction and followingWithNonLiteralOffset both pass Optional.empty() for the ordering type, so neither exercises the retype path.

#1198 tracks the same rule going unchecked on the core side, for plans built directly or read from proto; this is the isthmus producer half for non-integral offsets.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions