risingwavelabs/risingwave · error · StrError
{0}
Error message
{0} What it means
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.
Source
Thrown at src/sqlparser/src/parser.rs:55
const WEBHOOK_WAIT_FOR_PERSISTENCE: &str = "webhook.wait_for_persistence";
const WEBHOOK_IS_BATCHED: &str = "is_batched";
#[derive(Debug, Clone, PartialEq)]
pub enum ParserError {
TokenizerError(String),
ParserError(String),
}
impl ParserError {
pub fn inner_msg(self) -> String {
match self {
ParserError::TokenizerError(s) | ParserError::ParserError(s) => s,
}
}
}
#[derive(Debug, thiserror::Error)]
#[error("{0}")]
pub struct StrError(pub String);
// Use `Parser::expected` instead, if possible
#[macro_export]
macro_rules! parser_err {
($($arg:tt)*) => {
return Err(winnow::error::ErrMode::Backtrack(<winnow::error::ContextError as winnow::error::FromExternalError<_, _>>::from_external_error(
&Parser::default(),
$crate::parser::StrError(format!($($arg)*)),
)))
};
}
impl From<StrError> for winnow::error::ErrMode<winnow::error::ContextError> {
fn from(e: StrError) -> Self {
winnow::error::ErrMode::Backtrack(<winnow::error::ContextError as winnow::error::FromExternalError<_, _>>::from_external_error(
&Parser::default(),
e,View on GitHub (pinned to 6469eb736d)
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
Example fix
// before
Parser::parse_sql(&GenericDialect{}, "SELCT * FROM t") // -> StrError("Expected ..., found: SELCT")
// after
Parser::parse_sql(&PostgreSqlDialect{}, "SELECT * FROM t") Defensive patterns
Strategy: validation
Validate before calling
// Basic pre-parse sanity check (Rust):
fn looks_like_sql(input: &str) -> Result<(), String> {
let t = input.trim();
if t.is_empty() { return Err("empty SQL statement".into()); }
if t.ends_with(';') && t.matches(';').count() > 1 && !input.contains(";") { return Err("multiple statements not supported".into()); }
Ok(())
} Try / catch
// Rust
match Parser::parse_sql(dialect, sql) {
Ok(stmts) => stmts,
Err(e) => {
let msg: StrError = e.into(); // StrError displays the parser message
return Err(format!("SQL parse failed: {msg}"));
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- ROWS, RANGE, or GROUPS
- BOTH, LEADING, or TRAILING
- date/time field
- parameter value
- backfill order strategy
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/4e68bcdc661d7258.
Report an issue: GitHub.