{"record":{"id":"5808972cf658c23c","repo":"risingwavelabs/risingwave","slug":"for-frame-bound-offset-of-type-interval-each-fi","errorCode":null,"errorMessage":"for frame bound offset of type `interval`, each field should be non-negative, but {} is given","messagePattern":"for frame bound offset of type `interval`, each field should be non-negative, but (.+?) is given","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/core/src/window_function/range.rs","lineNumber":118,"sourceCode":"                    \"frame bound offset should be non-negative, but {} is given\",\n                    val\n                );\n            }\n            Ok(())\n        }\n\n        FrameBound::validate_bounds(&self.start, &self.end, |offset| {\n            match offset.as_scalar_ref_impl() {\n                // TODO(rc): use decl macro?\n                ScalarRefImpl::Int16(val) => validate_non_negative(val)?,\n                ScalarRefImpl::Int32(val) => validate_non_negative(val)?,\n                ScalarRefImpl::Int64(val) => validate_non_negative(val)?,\n                ScalarRefImpl::Float32(val) => validate_non_negative(val)?,\n                ScalarRefImpl::Float64(val) => validate_non_negative(val)?,\n                ScalarRefImpl::Decimal(val) => validate_non_negative(val)?,\n                ScalarRefImpl::Interval(val) => {\n                    if !val.is_never_negative() {\n                        bail!(\n                            \"for frame bound offset of type `interval`, each field should be non-negative, but {} is given\",\n                            val\n                        );\n                    }\n                    if matches!(self.order_data_type, DataType::Timestamptz) {\n                        // for `timestamptz`, we only support offset without `month` and `day` fields\n                        if val.months() != 0 || val.days() != 0 {\n                            bail!(\n                                \"for frame order column of type `timestamptz`, offset should not have non-zero `month` and `day`\",\n                            );\n                        }\n                    }\n                }\n                _ => unreachable!(\n                    \"other order column data types are not supported and should be banned in frontend\"\n                ),\n            }\n            Ok(())","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/core/src/window_function/range.rs#L100-L136","documentation":"For RANGE frames whose offset is an Interval, every field of the interval (months, days, microseconds) must be non-negative. validate in RangeFrameBounds rejects intervals where any component is negative, because mixed-sign intervals make frame comparisons ambiguous.","triggerScenarios":"RANGE frame with an Interval offset that is not never-negative, e.g. `RANGE BETWEEN INTERVAL '-1 day' PRECEDING ...` or `INTERVAL '1 month -1 day'`, when validate runs on the constructed bounds.","commonSituations":"SQL with signed interval literals like `'-1 day'`, or computed interval offsets that can go negative depending on input.","solutions":["Use positive interval literals and express direction via PRECEDING/FOLLOWING, e.g. `INTERVAL '1 day' PRECEDING`.","Normalize computed intervals so all fields are non-negative before building the frame.","Reject or rewrite such frames in the frontend binder/planner."],"exampleFix":"-- before\nSELECT sum(x) OVER (ORDER BY ts RANGE BETWEEN INTERVAL '-1 day' PRECEDING AND CURRENT ROW) FROM t;\n-- after\nSELECT sum(x) OVER (ORDER BY ts RANGE BETWEEN INTERVAL '1 day' PRECEDING AND CURRENT ROW) FROM t;","handlingStrategy":"validation","validationCode":"fn interval_fields_non_negative(i: &Interval) -> bool { i.is_never_negative() }","typeGuard":"fn is_valid_interval_offset(i: Interval) -> bool { i.is_never_negative() }","tryCatchPattern":null,"preventionTips":["Avoid signed interval literals like '-1 day' in RANGE frames.","Normalize computed intervals so every field is non-negative.","Reject mixed-sign intervals in the frontend planner."],"tags":["window-function","range-frame","interval","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}