{"record":{"id":"4e68bcdc661d7258","repo":"risingwavelabs/risingwave","slug":"0-4e68bc","errorCode":null,"errorMessage":"{0}","messagePattern":"\\{0\\}","errorType":"exception","errorClass":"StrError","httpStatus":null,"severity":"error","filePath":"src/sqlparser/src/parser.rs","lineNumber":55,"sourceCode":"const WEBHOOK_WAIT_FOR_PERSISTENCE: &str = \"webhook.wait_for_persistence\";\nconst WEBHOOK_IS_BATCHED: &str = \"is_batched\";\n\n#[derive(Debug, Clone, PartialEq)]\npub enum ParserError {\n    TokenizerError(String),\n    ParserError(String),\n}\n\nimpl ParserError {\n    pub fn inner_msg(self) -> String {\n        match self {\n            ParserError::TokenizerError(s) | ParserError::ParserError(s) => s,\n        }\n    }\n}\n\n#[derive(Debug, thiserror::Error)]\n#[error(\"{0}\")]\npub struct StrError(pub String);\n\n// Use `Parser::expected` instead, if possible\n#[macro_export]\nmacro_rules! parser_err {\n    ($($arg:tt)*) => {\n        return Err(winnow::error::ErrMode::Backtrack(<winnow::error::ContextError as winnow::error::FromExternalError<_, _>>::from_external_error(\n            &Parser::default(),\n            $crate::parser::StrError(format!($($arg)*)),\n        )))\n    };\n}\n\nimpl From<StrError> for winnow::error::ErrMode<winnow::error::ContextError> {\n    fn from(e: StrError) -> Self {\n        winnow::error::ErrMode::Backtrack(<winnow::error::ContextError as winnow::error::FromExternalError<_, _>>::from_external_error(\n            &Parser::default(),\n            e,","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/sqlparser/src/parser.rs#L37-L73","documentation":"StrError is a thin wrapper in sqlparser's parser.rs that converts the parser's ParserError enum into a plain String-bearing std error via thiserror's #[error(\"{0}\")]. It is thrown whenever SQL parsing fails and the error is carried as a string — the message is simply the tokenizer/parser error text.","triggerScenarios":"Calling Parser::parse_sql / parse_expr (or RisingWave APIs that wrap them) with SQL that the tokenizer or grammar rejects; every parser_err!/expected failure can surface as StrError.","commonSituations":"Typos or unsupported syntax in DDL/DML; dialect mismatch (Postgres-only features vs supported subset); wrong quoting/escaping of identifiers or strings; passing non-SQL text to the parser.","solutions":["Read the wrapped message: it names the exact token/position the parser choked on","Fix the SQL syntax or quoting at that position","If the syntax is valid Postgres but unsupported, check RisingWave's supported SQL subset or use an explicit dialect","For programmatic callers, validate/escape user input SQL before parsing"],"exampleFix":"// before\nParser::parse_sql(&GenericDialect{}, \"SELCT * FROM t\") // -> StrError(\"Expected ..., found: SELCT\")\n// after\nParser::parse_sql(&PostgreSqlDialect{}, \"SELECT * FROM t\")","handlingStrategy":"validation","validationCode":"// Basic pre-parse sanity check (Rust):\nfn looks_like_sql(input: &str) -> Result<(), String> {\n    let t = input.trim();\n    if t.is_empty() { return Err(\"empty SQL statement\".into()); }\n    if t.ends_with(';') && t.matches(';').count() > 1 && !input.contains(\";\") { return Err(\"multiple statements not supported\".into()); }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"// Rust\nmatch Parser::parse_sql(dialect, sql) {\n    Ok(stmts) => stmts,\n    Err(e) => {\n        let msg: StrError = e.into(); // StrError displays the parser message\n        return Err(format!(\"SQL parse failed: {msg}\"));\n    }\n}","preventionTips":["Lint/validate SQL before parsing in programmatic paths","Match the dialect to the syntax you use (PostgreSqlDialect for RisingWave)","Escape identifiers and string literals correctly","Check the RisingWave supported-SQL docs for unsupported Postgres features"],"tags":["sql","parser","syntax"],"backgroundTag":"sql-query-failed","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"}