{"record":{"id":"0bf5f4e153da8f94","repo":"risingwavelabs/risingwave","slug":"unreachable","errorCode":null,"errorMessage":"unreachable","messagePattern":"unreachable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/logical_iceberg_scan.rs","lineNumber":100,"sourceCode":"            vec![\n                (\"source\", src),\n                (\"columns\", column_names_pretty(self.schema())),\n                (\n                    \"iceberg_scan_type\",\n                    Pretty::debug(&self.iceberg_scan_type()),\n                ),\n            ]\n        } else {\n            vec![]\n        };\n        childless_record(\"LogicalIcebergScan\", fields)\n    }\n}\n\nimpl ColPrunable for LogicalIcebergScan {\n    fn prune_col(&self, _: &[usize], _: &mut ColumnPruningContext) -> PlanRef {\n        // Column pruning should have been done in LogicalIcebergIntermediateScan.\n        unreachable!()\n    }\n}\n\nimpl ExprRewritable<Logical> for LogicalIcebergScan {}\n\nimpl ExprVisitable for LogicalIcebergScan {}\n\nimpl PredicatePushdown for LogicalIcebergScan {\n    fn predicate_pushdown(\n        &self,\n        predicate: Condition,\n        _ctx: &mut PredicatePushdownContext,\n    ) -> PlanRef {\n        // Predicate pushdown should have been done in LogicalIcebergIntermediateScan.\n        LogicalFilter::create(self.clone().into(), predicate)\n    }\n}\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/logical_iceberg_scan.rs#L82-L118","documentation":"LogicalIcebergScan is an internal optimizer node whose column pruning is expected to have already been performed by LogicalIcebergIntermediateScan. When prune_col is nevertheless invoked on it, the code declares the situation unreachable and panics with 'unreachable'. This is an internal invariant: seeing it indicates an optimizer rule ordering bug, not user error.","triggerScenarios":"The column pruning pass calls prune_col on a LogicalIcebergScan node — possible when an Iceberg query's plan is not correctly rewritten into LogicalIcebergIntermediateScan before pruning, or when new optimizer rules route Iceberg scans through pruning.","commonSituations":"Optimizer bug after changes to Iceberg source planning; a query shape over an Iceberg source that skips the intermediate-scan rewrite; local patches to the frontend that add pruning rules matching Iceberg scans.","solutions":["Reproduce the SQL and file a bug / check recent changes: LogicalIcebergScan should be replaced by LogicalIcebergIntermediateScan before column pruning.","Upgrade RisingWave to a version where the Iceberg planning pipeline handles pruning correctly.","If developing, change the rule pipeline so Iceberg scans are converted before ColPrunable runs, or implement prune_col properly (delegate to LogicalIcebergIntermediateScan) instead of unreachable!()."],"exampleFix":"// before\nfn prune_col(&self, _: &[usize], _: &mut ColumnPruningContext) -> PlanRef {\n    unreachable!()\n}\n// after\nfn prune_col(&self, required_cols: &[usize], ctx: &mut ColumnPruningContext) -> PlanRef {\n    LogicalIcebergIntermediateScan::new(self.core.clone(), self.ctx()).prune_col(required_cols, ctx)\n}","handlingStrategy":"try-catch","validationCode":"// Not applicable to users: this is an internal optimizer invariant panic.\n// For developers: assert the rewrite happened before pruning.\ndebug_assert!(matches!(plan, PlanRef::LogicalIcebergIntermediateScan(_) | _), \"Iceberg scan must be converted before pruning\");","typeGuard":"fn is_iceberg_intermediate_scan(node: &PlanRef) -> bool {\n    matches!(node.as_logical(), Some(LogicalNode::IcebergIntermediateScan(_)))\n}","tryCatchPattern":"// In Rust, catch_unwind around planner invocations in services that must not crash\nlet result = std::panic::catch_unwind(|| planner.prune_cols(plan));\nmatch result {\n    Ok(r) => r?,\n    Err(_) => return Err(anyhow!(\"optimizer panicked on Iceberg scan; report this bug\")),\n}","preventionTips":["Report this panic upstream with the SQL — it indicates an optimizer bug, not user error.","Avoid local patches that add pruning rules matching LogicalIcebergScan.","Ensure Iceberg-to-IntermediateScan rewrite ordering in the rule pipeline.","Pin to a RisingWave release where Iceberg column pruning is handled by LogicalIcebergIntermediateScan."],"tags":["rust","query-optimizer","iceberg","column-pruning","panic"],"backgroundTag":"internal-invariant-violation","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"}