{"record":{"id":"b470b60a83077798","repo":"risingwavelabs/risingwave","slug":"gap-interval-must-be-positive","errorCode":null,"errorMessage":"Gap interval must be positive","messagePattern":"Gap interval must be positive","errorType":"validation","errorClass":"StreamExecutorError","httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/eowc/eowc_gap_fill.rs","lineNumber":370,"sourceCode":"        } = self;\n\n        let mut input = input.execute();\n\n        let barrier = expect_first_barrier(&mut input).await?;\n        let first_epoch = barrier.epoch;\n        yield Message::Barrier(barrier);\n        this.prev_row_table.init_epoch(first_epoch).await?;\n\n        // Calculate and validate gap interval once at initialization\n        let dummy_row = OwnedRow::new(vec![]);\n        let interval_datum = this.gap_interval.eval_row_infallible(&dummy_row).await;\n        let interval = interval_datum\n            .ok_or_else(|| anyhow::anyhow!(\"Gap interval expression returned null\"))?\n            .into_interval();\n\n        // Validate that gap interval is positive.\n        if interval <= Interval::from_month_day_usec(0, 0, 0) {\n            Err(anyhow::anyhow!(\"Gap interval must be positive\"))?;\n        }\n\n        let mut vars = ExecutionVars {\n            staging_prev_rows: HashMap::new(),\n        };\n\n        #[for_await]\n        for msg in input {\n            match msg? {\n                // Drop the time watermark: a late anchor makes gap fill back-fill below it.\n                // PARTITION BY column watermarks (if any) pass through unchanged.\n                Message::Watermark(watermark)\n                    if this.partition_by_indices.contains(&watermark.col_idx) =>\n                {\n                    yield Message::Watermark(watermark);\n                }\n                Message::Watermark(_) => continue,\n                Message::Chunk(chunk) => {","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/eowc/eowc_gap_fill.rs#L352-L388","documentation":"After the gap interval is resolved (see the null check), the EOWC gap-fill executor validates that the interval is strictly greater than zero using `interval <= Interval::from_month_day_usec(0, 0, 0)`. A zero or negative gap interval would cause the fill loop to make no progress or behave nonsensically, so initialization fails fast with \"Gap interval must be positive\".","triggerScenarios":"Executing a gap-fill query whose constant gap interval evaluates to zero or negative — e.g., `INTERVAL '0 seconds'`, `INTERVAL '-5 minutes'`, or a negative computed literal that survives the constant evaluation.","commonSituations":"Templated/generated SQL where the interval parameter was substituted as 0 or a negative number; experimenting with gap fill and passing 0 to mean 'no gap' instead of omitting the option; a sign typo in an interval string.","solutions":["Set the gap interval to a strictly positive value, e.g. `INTERVAL '1 minute'`, and recreate the materialized view.","If the interval comes from application code or a template, validate it is > 0 before generating the SQL.","If zero gap is intended, remove the gap-fill option entirely instead of passing a zero interval.","Double-check negative interval strings (`-INTERVAL ...`) and unary minus in generated SQL."],"exampleFix":"// before\nWITH (gap_interval = INTERVAL '0 seconds')\n// after\nWITH (gap_interval = INTERVAL '1 minute')","handlingStrategy":"validation","validationCode":"-- Validate the interval is strictly positive before use:\nSELECT INTERVAL '5 minutes' > INTERVAL '0' AS positive; -- must be true","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate user-supplied gap intervals are > 0 in application code before generating SQL.","Use omit-the-option rather than interval 0 to mean 'no gap fill'.","Check templates for accidental unary minus on intervals."],"tags":["streaming","gap-fill","value-out-of-range","configuration","sql"],"backgroundTag":"argument-out-of-range","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}