{"record":{"id":"8d3edf6308fd8b09","repo":"risingwavelabs/risingwave","slug":"more-than-one-row-returned-by-0-used-as-an-expre","errorCode":null,"errorMessage":"More than one row returned by {0} used as an expression","messagePattern":"More than one row returned by (.+?) used as an expression","errorType":"exception","errorClass":"ExprError","httpStatus":null,"severity":"error","filePath":"src/expr/core/src/error.rs","lineNumber":88,"sourceCode":"    #[error(\"Parse error: {0}\")]\n    // TODO(error-handling): should prefer use error types than strings.\n    Parse(Box<str>),\n\n    #[error(\"Invalid parameter {name}: {reason}\")]\n    // TODO(error-handling): should prefer use error types than strings.\n    InvalidParam {\n        name: &'static str,\n        reason: Box<str>,\n    },\n\n    #[error(\"Array error: {0}\")]\n    Array(\n        #[from]\n        #[backtrace]\n        ArrayError,\n    ),\n\n    #[error(\"More than one row returned by {0} used as an expression\")]\n    MaxOneRow(&'static str),\n\n    /// TODO: deprecate in favor of `Function`\n    #[error(transparent)]\n    Internal(\n        #[from]\n        #[backtrace]\n        anyhow::Error,\n    ),\n\n    #[error(\"not a constant\")]\n    NotConstant,\n\n    #[error(\"Context {0} not found\")]\n    Context(&'static str),\n\n    #[error(\"field name must not be null\")]\n    FieldNameNull,","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/core/src/error.rs#L70-L106","documentation":"ExprError::MaxOneRow(&'static str) is thrown when a scalar subquery (or similar row-yielding expression) returns more than one row. The message interpolates what construct ('{0}') was used as an expression, mirroring Postgres's 'more than one row returned by a subquery used as an expression'. A scalar context can only consume a single row.","triggerScenarios":"A scalar subquery on the right side of `=`, in a SELECT list, or in a SET clause produces 2+ rows, e.g. `SELECT x = (SELECT id FROM t WHERE k = 1)` where the WHERE clause matches multiple rows.","commonSituations":"Subqueries written against a uniqueness assumption that no longer holds after data changes, missing DISTINCT/LIMIT, join fan-out in upstream tables making lookups non-unique.","solutions":["Add `LIMIT 1` if any single row is acceptable.","Add `DISTINCT` when duplicates are spurious.","Tighten the subquery's WHERE clause (or add a unique constraint) so it provably returns at most one row."],"exampleFix":"// before\nSELECT * FROM a WHERE id = (SELECT a_id FROM b WHERE flag = true);\n// after\nSELECT * FROM a WHERE id = (SELECT a_id FROM b WHERE flag = true LIMIT 1);","handlingStrategy":"validation","validationCode":"-- ensure scalar subquery yields at most one row\nSELECT * FROM a WHERE id = (SELECT DISTINCT a_id FROM b WHERE flag = true LIMIT 1);","typeGuard":null,"tryCatchPattern":"// Postgres-compatible error; catch and rewrite with LIMIT at retry\nif err.to_string().contains(\"More than one row returned\") {\n    return run(query_with_limit_1);\n}","preventionTips":["Add LIMIT 1 or DISTINCT to every scalar subquery unless uniqueness is guaranteed.","Back scalar-subquery columns with unique constraints.","Watch for fan-out joins upstream that break single-row assumptions."],"tags":["sql","subquery","cardinality"],"backgroundTag":"empty-result-set","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"}