risingwavelabs/risingwave · error

for frame order column of type `timestamptz`, offset should…

Error message

for frame order column of type `timestamptz`, offset should not have non-zero `month` and `day`

What it means

When the RANGE frame order column is of type timestamptz, RisingWave only supports interval offsets that are pure microsecond durations; offsets with non-zero month or day fields cannot be added to a timestamptz in a timezone-independent way, so validate rejects them.

Solutions

  1. Rewrite the offset in pure time units, e.g. `INTERVAL '30 days'` -> approximate with seconds (`INTERVAL '2592000 seconds'`) only if semantics allow, or better use a days-based column type.
  2. Cast the order column to timestamp (without tz) if calendar semantics are acceptable and the type supports it.
  3. Use ROWS frames with an explicit row count instead of RANGE with calendar intervals.

Example fix

-- before
SELECT sum(x) OVER (ORDER BY ts_at_tz RANGE BETWEEN INTERVAL '1 month' PRECEDING AND CURRENT ROW) FROM t;
-- after
SELECT sum(x) OVER (ORDER BY ts RANGE BETWEEN INTERVAL '30 days' PRECEDING AND CURRENT ROW) FROM t; -- order col must be non-timestamptz, or use seconds-based offset
Defensive patterns

Strategy: validation

Validate before calling

fn offset_ok_for_timestamptz(order_type: &DataType, i: &Interval) -> bool {
    order_type != &DataType::Timestamptz || (i.months() == 0 && i.days() == 0)
}

Type guard

fn is_pure_duration(i: &Interval) -> bool { i.months() == 0 && i.days() == 0 }

Prevention

When it happens

Trigger: RANGE frame over a timestamptz order column with an offset like `INTERVAL '1 month'` or `INTERVAL '1 day'` (months() or days() != 0).

Common situations: `OVER (ORDER BY ts RANGE BETWEEN INTERVAL '1 month' PRECEDING AND CURRENT ROW)` on a timestamptz column; DST/calendar ambiguity makes such offsets unsupported.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/98ef84c64e91b489. Report an issue: GitHub.

Appendix: source

Thrown at src/expr/core/src/window_function/range.rs:126

            match offset.as_scalar_ref_impl() {
                // TODO(rc): use decl macro?
                ScalarRefImpl::Int16(val) => validate_non_negative(val)?,
                ScalarRefImpl::Int32(val) => validate_non_negative(val)?,
                ScalarRefImpl::Int64(val) => validate_non_negative(val)?,
                ScalarRefImpl::Float32(val) => validate_non_negative(val)?,
                ScalarRefImpl::Float64(val) => validate_non_negative(val)?,
                ScalarRefImpl::Decimal(val) => validate_non_negative(val)?,
                ScalarRefImpl::Interval(val) => {
                    if !val.is_never_negative() {
                        bail!(
                            "for frame bound offset of type `interval`, each field should be non-negative, but {} is given",
                            val
                        );
                    }
                    if matches!(self.order_data_type, DataType::Timestamptz) {
                        // for `timestamptz`, we only support offset without `month` and `day` fields
                        if val.months() != 0 || val.days() != 0 {
                            bail!(
                                "for frame order column of type `timestamptz`, offset should not have non-zero `month` and `day`",
                            );
                        }
                    }
                }
                _ => unreachable!(
                    "other order column data types are not supported and should be banned in frontend"
                ),
            }
            Ok(())
        })
    }
}

impl RangeFrameBounds {
    /// Get the frame start for a given order column value.
    ///
    /// ## Examples

View on GitHub (pinned to 6469eb736d)