{"record":{"id":"4046734f469bee44","repo":"risingwavelabs/risingwave","slug":"call-prune-col-of-the-planref-instead-of-calling-d","errorCode":null,"errorMessage":"call prune_col of the PlanRef instead of calling directly on LogicalShare","messagePattern":"call prune_col of the PlanRef instead of calling directly on LogicalShare","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/logical_share.rs","lineNumber":133,"sourceCode":"        self.ctx()\n            .update_logical_share(self.share_id(), plan.clone());\n        Self::with_core(self.core.with_input(plan)).into()\n    }\n\n    fn fork_with_input(&self, plan: PlanRef) -> PlanRef {\n        Self::new(plan).into()\n    }\n}\n\nimpl Distill for LogicalShare {\n    fn distill<'a>(&self) -> XmlNode<'a> {\n        Self::pretty_fields(&self.base, \"LogicalShare\")\n    }\n}\n\nimpl ColPrunable for LogicalShare {\n    fn prune_col(&self, _required_cols: &[usize], _ctx: &mut ColumnPruningContext) -> PlanRef {\n        unimplemented!(\"call prune_col of the PlanRef instead of calling directly on LogicalShare\")\n    }\n}\n\nimpl ExprRewritable<Logical> for LogicalShare {}\n\nimpl ExprVisitable for LogicalShare {}\n\nimpl PredicatePushdown for LogicalShare {\n    fn predicate_pushdown(\n        &self,\n        _predicate: Condition,\n        _ctx: &mut PredicatePushdownContext,\n    ) -> PlanRef {\n        unimplemented!(\n            \"call predicate_pushdown of the PlanRef instead of calling directly on LogicalShare\"\n        )\n    }\n}","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/logical_share.rs#L115-L151","documentation":"`LogicalShare::prune_col` is deliberately `unimplemented!()`. Column pruning on a shared node must go through `PlanRef::prune_col`, which handles LogicalShare specially (pruning once, at the share root, considering all consumers). Calling the trait method directly on the LogicalShare value indicates a caller violated the module's API contract.","triggerScenarios":"Calling `logical_share.prune_col(required_cols, ctx)` on a `LogicalShare` value directly instead of converting to `PlanRef` first and calling `plan_ref.prune_col(...)`.","commonSituations":"Hit by contributors implementing or testing the column-pruning rules who operate on typed plan node values (e.g. after a `as_logical_share()` downcast) rather than on the generic `PlanRef`.","solutions":["Convert the node to `PlanRef` (`self.clone().into()`) and call `prune_col` on that; the PlanRef-level implementation handles sharing correctly.","Refactor your rule to work on `PlanRef` throughout so downcasts never yield direct LogicalShare trait calls.","If stock code reaches this, report a RisingWave optimizer bug with the query plan."],"exampleFix":"// before\nlet pruned = logical_share.prune_col(&required_cols, ctx);\n// after\nlet pruned = PlanRef::from(logical_share.clone()).prune_col(&required_cols, ctx);\n","handlingStrategy":"type-guard","validationCode":"// Ensure the node is dispatched via PlanRef, not the typed LogicalShare.\nif node.as_logical_share().is_some() {\n    let node = PlanRef::from(node.clone());\n    // proceed with node.prune_col(...)\n}","typeGuard":"fn prunable_ref(plan: PlanRef) -> PlanRef {\n    assert!(plan.as_logical_share().is_none(), \"prune via PlanRef only\");\n    plan\n}","tryCatchPattern":null,"preventionTips":["Always call column pruning on `PlanRef`, never on typed plan nodes.","Keep rule code generic over PlanRef to avoid downcast-induced trait calls.","Test pruning on plans containing shared subplans.","Note the module's unimplemented!() markers: they document which dispatch paths are forbidden."],"tags":["rust","optimizer","unimplemented","column-pruning","logical-share"],"backgroundTag":"method-not-implemented","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"}