{"record":{"id":"8b759a190f8e8b5a","repo":"risingwavelabs/risingwave","slug":"unsupported-plan-node","errorCode":null,"errorMessage":"Unsupported Plan Node","messagePattern":"Unsupported Plan Node","errorType":"error_code","errorClass":"GenDataFusionPlanError","httpStatus":null,"severity":"error","filePath":"src/frontend/src/datafusion/execute/mod.rs","lineNumber":64,"sourceCode":"\nmod memory_ctx;\nmod query_planner;\n\npub(crate) use memory_ctx::create_df_spillable_budget_ctx;\nconst DF_MANAGED_SPILL_DIR: &str = \"df_batch_spill/\";\n\n#[derive(Clone)]\npub struct DfBatchQueryPlanResult {\n    pub(crate) plan: Arc<LogicalPlan>,\n    pub(crate) schema: RwSchema,\n    pub(crate) stmt_type: StatementType,\n}\n\n#[derive(Debug, Error)]\npub enum GenDataFusionPlanError {\n    #[error(\"Missing Iceberg Scan\")]\n    MissingIcebergScan,\n    #[error(\"Unsupported Plan Node\")]\n    UnsupportedPlanNode,\n    #[error(\"Generating plan error: {0}\")]\n    Generating(#[source] RwError),\n}\n\npub fn try_gen_datafusion_plan(\n    optimized_logical: &BatchOptimizedLogicalPlanRoot,\n) -> Result<Arc<LogicalPlan>, GenDataFusionPlanError> {\n    use crate::optimizer::DataFusionExecuteCheckerExt;\n\n    let check_result = optimized_logical.plan.check_for_datafusion();\n    if !check_result.have_iceberg_scan {\n        return Err(GenDataFusionPlanError::MissingIcebergScan);\n    }\n    if !check_result.supported {\n        return Err(GenDataFusionPlanError::UnsupportedPlanNode);\n    }\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/datafusion/execute/mod.rs#L46-L82","documentation":"Variant of `GenDataFusionPlanError` thrown during DataFusion plan generation when the converter encounters a RisingWave logical plan node kind it does not know how to translate into a DataFusion `LogicalPlan`. Only a subset of batch plan nodes is supported for the Iceberg/DataFusion execution path.","triggerScenarios":"Calling `try_gen_datafusion_plan` on an optimized plan containing unsupported operators (e.g. joins, aggregations, or exchange nodes not mapped in the translator's match on plan node types).","commonSituations":"Running complex queries (joins, window functions, aggregations) against Iceberg tables via the DataFusion path where only simple scans/projections/filters are supported; new batch plan nodes added without updating the translator.","solutions":["Simplify the query to only supported operators (scan, filter, projection) for the DataFusion/Iceberg path.","Execute the query via the regular RisingWave batch engine instead of the DataFusion path.","Extend the plan translator's match to map the unsupported node to a DataFusion equivalent."],"exampleFix":"// before\nlet df_plan = try_gen_datafusion_plan(&optimized_plan)?; // plan contains HashAgg\n// after\n// push aggregation out of the datafusion path, or handle it:\nmatch node {\n    PlanNode::IcebergScan(..) => translate_scan(node),\n    other => return Err(GenDataFusionPlanError::UnsupportedPlanNode), // handled upstream\n}","handlingStrategy":"fallback","validationCode":"// check the query only uses supported operators before taking the DataFusion path\nconst unsupported = /JOIN|GROUP BY|OVER \\(/i.test(sql);\nif (unsupported) useRegularBatchEngine(sql);","typeGuard":"function planIsSupported(node) {\n  return [\"IcebergScan\", \"Project\", \"Filter\"].includes(node.kind);\n}","tryCatchPattern":"match try_gen_datafusion_plan(&plan) {\n    Err(GenDataFusionPlanError::UnsupportedPlanNode) => {\n      // fall back to RisingWave batch execution\n    }\n    r => r?,\n}","preventionTips":["Restrict DataFusion-path queries to scan/filter/projection shapes","Default complex queries (joins, aggregates, windows) to the native batch engine","Update the translator whenever new batch plan nodes are introduced"],"tags":["datafusion","iceberg","query-planning","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-23T08:17:48.524Z"}