{"record":{"id":"a2fee74361353881","repo":"risingwavelabs/risingwave","slug":"file-scan-function-is-not-supported-in-streaming-m","errorCode":null,"errorMessage":"file_scan function is not supported in streaming mode","messagePattern":"file_scan function is not supported in streaming mode","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/logical_file_scan.rs","lineNumber":168,"sourceCode":"        _ctx: &mut PredicatePushdownContext,\n    ) -> PlanRef {\n        // No pushdown.\n        LogicalFilter::create(self.clone().into(), predicate)\n    }\n}\n\nimpl ToBatch for LogicalFileScan {\n    fn to_batch(&self) -> Result<crate::optimizer::plan_node::BatchPlanRef> {\n        Ok(BatchFileScan::new(self.core.clone()).into())\n    }\n}\n\nimpl ToStream for LogicalFileScan {\n    fn to_stream(\n        &self,\n        _ctx: &mut ToStreamContext,\n    ) -> Result<crate::optimizer::plan_node::StreamPlanRef> {\n        bail!(\"file_scan function is not supported in streaming mode\")\n    }\n\n    fn logical_rewrite_for_stream(\n        &self,\n        _ctx: &mut RewriteStreamContext,\n    ) -> Result<(PlanRef, ColIndexMapping)> {\n        bail!(\"file_scan function is not supported in streaming mode\")\n    }\n}\n","sourceCodeStart":150,"sourceCodeEnd":178,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/logical_file_scan.rs#L150-L178","documentation":"RisingWave's streaming engine cannot execute a file_scan (file source/function scan) node, so `ToStream for LogicalFileScan` deliberately returns an error via `bail!`. Unlike the EXCEPT stubs this is a clean, intended error: file scans are batch-only.","triggerScenarios":"Attempting to create a materialized view, or any streaming/continuous query, whose plan contains a LogicalFileScan node (a query reading from a file via file_scan function).","commonSituations":"Users try to `CREATE MATERIALIZED VIEW` over a file-based source; or run `CREATE TABLE ... FROM file` style flows expecting incremental streaming from files.","solutions":["Keep file_scan usage in batch (ad-hoc) queries only.","Ingest the file data into a table or a supported connector source (e.g. Kafka, Kinesis) and build the materialized view on that source instead.","If streaming file ingestion is needed, load files via an external pipeline into a supported source first."],"exampleFix":"-- before\nCREATE MATERIALIZED VIEW mv AS SELECT * FROM file_scan('s3://bucket/data.parquet');\n\n-- after\nCREATE SOURCE s (...) WITH (connector = 'kafka', ...);\nCREATE MATERIALIZED VIEW mv AS SELECT * FROM s;","handlingStrategy":"try-catch","validationCode":"-- reject streaming DDL that reads files directly\nif ddl.is_streaming() && ddl.references_file_scan() {\n    return Err(\"file_scan is batch-only; use a connector source\".into());\n}","typeGuard":"fn is_streamable(node: &dyn PlanTreeNode) -> bool {\n    node.node_type() != PlanNodeType::LogicalFileScan\n}","tryCatchPattern":"match to_stream(plan) {\n    Err(e) if e.to_string().contains(\"file_scan\") =>\n        advise(\"use Kafka/Kinesis source or a table for streaming\"),\n    r => r,\n}","preventionTips":["Use file_scan only for one-off batch reads","Ingest files into tables or connector sources for streaming workloads","Document batch-only operators for SQL users","Add early DDL validation for unsupported streaming sources"],"tags":["rust","streaming","file-scan","unsupported"],"backgroundTag":"unsupported-operation","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"}