{"record":{"id":"9bef9670f19fd10d","repo":"risingwavelabs/risingwave","slug":"gap-interval-expression-returned-null","errorCode":null,"errorMessage":"Gap interval expression returned null","messagePattern":"Gap interval expression returned null","errorType":"validation","errorClass":"StreamExecutorError","httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/eowc/eowc_gap_fill.rs","lineNumber":365,"sourceCode":"    #[try_stream(ok = Message, error = StreamExecutorError)]\n    async fn execute_inner(self) {\n        let Self {\n            input,\n            inner: mut this,\n        } = 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) =>","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/eowc/eowc_gap_fill.rs#L347-L383","documentation":"During gap-fill executor initialization (`execute_inner`), the gap interval expression is evaluated once against an empty dummy row. Because the interval expression must be constant, evaluating to NULL is a fatal configuration error, so the executor returns an anyhow error \"Gap interval expression returned null\" instead of proceeding. Gap fill needs a concrete positive interval to know how far to advance the time column for each missing window.","triggerScenarios":"Creating an EMIT ON WINDOW CLOSE query with a gap-fill `gap_interval` (or `GAP`/interval argument) expression that evaluates to NULL at runtime — e.g., the interval literal is NULL, or the expression references a column/value that is NULL on an empty row.","commonSituations":"Typing `gap_interval => NULL` in the WITH options; using a parameterized or computed expression that is non-constant or NULL rather than a literal like `INTERVAL '5 minutes'`; copy-pasting config where the interval value was lost.","solutions":["Replace the gap interval expression with a non-null constant literal such as `INTERVAL '1 minute'` in the gap-fill options.","If the interval is computed, precompute the value and inline the literal; the executor only evaluates against an empty row, so anything row-dependent yields NULL.","Check the MV WITH clause/options for a typo that drops the interval value so it defaults to NULL.","Recreate the materialized view with a corrected gap interval."],"exampleFix":"// before\nWITH (gap_interval = NULL)\n// after\nWITH (gap_interval = INTERVAL '5 minutes')","handlingStrategy":"validation","validationCode":"-- Ensure the gap interval is a non-null constant:\nSELECT INTERVAL '5 minutes' IS NOT NULL AS gap_ok; -- true\n-- Use only constant literals in gap_fill options, never column references.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass a literal interval (e.g., INTERVAL '1 minute') as the gap interval.","Never reference columns or session variables in the gap interval expression.","Review generated SQL templates so the interval value is never dropped or NULL."],"tags":["streaming","gap-fill","null-value","configuration","sql"],"backgroundTag":"null-argument","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}