{"record":{"id":"4b7323918fe7cafb","repo":"risingwavelabs/risingwave","slug":"subquery-must-return-only-one-column","errorCode":null,"errorMessage":"subquery must return only one column","messagePattern":"subquery must return only one column","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/mod.rs","lineNumber":355,"sourceCode":"            return self.plan;\n        }\n        LogicalProject::with_out_fields(self.plan, &self.out_fields).into()\n    }\n\n    /// Transform the [`PlanRoot`] wrapped in an array-construction subquery to a [`PlanRef`]\n    /// supported by `ARRAY_AGG`. Similar to the unordered version, this abstracts away internal\n    /// `self.plan` which is further modified by `self.required_order` then `self.out_fields`.\n    pub fn into_array_agg(self) -> Result<LogicalPlanRef> {\n        use generic::Agg;\n        use plan_node::PlanAggCall;\n        use risingwave_common::types::ListValue;\n        use risingwave_expr::aggregate::PbAggKind;\n\n        use crate::expr::{ExprImpl, ExprType, FunctionCall, InputRef};\n        use crate::utils::{Condition, IndexSet};\n\n        let Ok(select_idx) = Itertools::exactly_one(self.out_fields.ones()) else {\n            bail!(\"subquery must return only one column\");\n        };\n        let input_column_type = self.plan.schema().fields()[select_idx].data_type();\n        let return_type = DataType::list(input_column_type.clone());\n        let agg = Agg::new(\n            vec![PlanAggCall {\n                agg_type: PbAggKind::ArrayAgg.into(),\n                return_type: return_type.clone(),\n                inputs: vec![InputRef::new(select_idx, input_column_type.clone())],\n                distinct: false,\n                order_by: self.required_order.column_orders,\n                filter: Condition::true_cond(),\n                direct_args: vec![],\n            }],\n            IndexSet::empty(),\n            self.plan,\n        );\n        Ok(LogicalProject::create(\n            agg.into(),","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/mod.rs#L337-L373","documentation":"into_array_agg converts a subquery expression into an ARRAY_AGG aggregate, but an array can only be built from a single column. If the subquery's schema has more (or fewer) than exactly one output column — detected via exactly_one(out_fields.ones()) — this error is thrown.","triggerScenarios":"Using a subquery in an array-producing context (e.g. `= ANY(subquery)`, IN-unnesting converted to array agg, or expression forms that become array_agg) where the subquery selects multiple columns, such as `SELECT a, b FROM t`.","commonSituations":"Writing `col = ANY(SELECT a, b FROM t)` or similar multi-column subqueries in predicates; forgetting to project exactly one column inside the subquery.","solutions":["Select exactly one column inside the subquery.","If multiple columns are needed, use a tuple/row comparison or rewrite with a JOIN instead of a subquery.","Move extra columns into a WHERE/JOIN condition instead of the SELECT list."],"exampleFix":"// before\nSELECT * FROM s WHERE s.x = ANY(SELECT a, b FROM t);\n// after\nSELECT * FROM s WHERE s.x = ANY(SELECT a FROM t);","handlingStrategy":"validation","validationCode":"-- the subquery used with ANY/IN-style predicates must select exactly one column\nSELECT a FROM t;  -- not SELECT a, b FROM t","typeGuard":null,"tryCatchPattern":"match query_result {\n    Err(e) if e.to_string().contains(\"subquery must return only one column\") => {\n        eprintln!(\"Project exactly one column inside the subquery\");\n    }\n    other => other?,\n}","preventionTips":["Always project a single column in subqueries used as value expressions.","Use JOINs instead of multi-column subquery comparisons.","Lint SQL for `ANY(SELECT *` and multi-column subquery selects."],"tags":["subquery","planner","sql","array"],"backgroundTag":"unexpected-response-shape","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"}