{"record":{"id":"286cc31b33184eb5","repo":"risingwavelabs/risingwave","slug":"unimplemented","errorCode":null,"errorMessage":"unimplemented","messagePattern":"unimplemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/logical_except.rs","lineNumber":101,"sourceCode":"\nimpl PredicatePushdown for LogicalExcept {\n    fn predicate_pushdown(\n        &self,\n        predicate: Condition,\n        ctx: &mut PredicatePushdownContext,\n    ) -> PlanRef {\n        let new_inputs = self\n            .inputs()\n            .iter()\n            .map(|input| input.predicate_pushdown(predicate.clone(), ctx))\n            .collect_vec();\n        self.clone_with_inputs(&new_inputs)\n    }\n}\n\nimpl ToBatch for LogicalExcept {\n    fn to_batch(&self) -> Result<BatchPlanRef> {\n        unimplemented!()\n    }\n}\n\nimpl ToStream for LogicalExcept {\n    fn to_stream(&self, _ctx: &mut ToStreamContext) -> Result<StreamPlanRef> {\n        unimplemented!()\n    }\n\n    fn logical_rewrite_for_stream(\n        &self,\n        _ctx: &mut RewriteStreamContext,\n    ) -> Result<(PlanRef, ColIndexMapping)> {\n        unimplemented!()\n    }\n}\n","sourceCodeStart":83,"sourceCodeEnd":117,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/logical_except.rs#L83-L117","documentation":"LogicalExcept::to_batch unconditionally calls unimplemented!(): EXCEPT has no batch physical implementation in the optimizer, so planning EXCEPT as a batch query always panics. Fires whenever a batch plan conversion reaches a LogicalExcept node.","triggerScenarios":"Running a query using the EXCEPT set operator, e.g. SELECT a FROM t1 EXCEPT SELECT a FROM t2, which reaches LogicalExcept::to_batch (or to_stream).","commonSituations":"Migrating Postgres queries containing EXCEPT; test scripts using EXCEPT for diffing results.","solutions":["Rewrite EXCEPT using NOT EXISTS or LEFT JOIN ... WHERE rhs IS NULL with DISTINCT.","Use EXCEPT ALL semantics via an anti-join with grouping and count if needed.","Check RisingWave release notes for EXCEPT support before using it."],"exampleFix":"// before\nSELECT id FROM t1 EXCEPT SELECT id FROM t2;\n// after\nSELECT DISTINCT t1.id FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t2.id = t1.id);","handlingStrategy":"fallback","validationCode":"// Detect EXCEPT before sending to RisingWave\nif (/\\bEXCEPT\\b/i.test(sql)) {\n  throw new Error('EXCEPT is not supported by this RisingWave planner path; rewrite with NOT EXISTS');\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await rw.query(sql);\n} catch (e) {\n  if (e instanceof Error && /unimplemented/i.test(e.message)) {\n    return await rw.query(rewriteExceptToAntiJoin(sql));\n  }\n  throw e;\n}","preventionTips":["Ban EXCEPT in query review for RisingWave targets.","Provide NOT EXISTS-based rewrite templates in your SQL layer.","Check the supported SQL features page/version notes before porting Postgres queries."],"tags":["risingwave","sql","planner","unimplemented","except"],"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"}