risingwavelabs/risingwave · error
unexpected statement: {:?}
Error message
unexpected statement: {:?} What it means
`gen_sink_plan` panics with "unexpected statement" while rewriting the query for an iceberg-engine table sink. The source query text is re-parsed and the code asserts the result is `Statement::Query`; any other statement kind (INSERT, CREATE, etc.) hits the `panic!`. It guards the invariant that sink input is always a SELECT/query at this point.
Source
Thrown at src/frontend/src/handler/create_sink.rs:304
sink_from_table_name = sink_table_name.clone();
direct_sink_from_name = None;
query
}
};
if is_iceberg_engine_internal && let Some((from_name, _)) = &direct_sink_from_name {
let (table, _) = get_table_catalog_by_table_name(session, from_name)?;
let pk_names = table.pk_column_names();
if pk_names.len() == 1 && pk_names[0].eq(ROW_ID_COLUMN_NAME) {
let [stmt]: [_; 1] = Parser::parse_sql(&format!(
"select {} as {}, * from {}",
ROW_ID_COLUMN_NAME, RISINGWAVE_ICEBERG_ROW_ID, from_name
))
.context("unable to parse query")?
.try_into()
.unwrap();
let Statement::Query(parsed_query) = stmt else {
panic!("unexpected statement: {:?}", stmt);
};
query = parsed_query;
}
}
let (sink_database_id, sink_schema_id) =
session.get_database_and_schema_id_for_create(sink_schema_name.clone())?;
if since_timestamp_epoch.is_some() {
if sink_into_table_name.is_some() {
return Err(ErrorCode::BindError(format!(
"`{SINK_SINCE_TIMESTAMP_OPTION}` does not support `CREATE SINK INTO TABLE`"
))
.into());
}
if is_iceberg_engine_internal {
return Err(ErrorCode::BindError(format!(
"`{SINK_SINCE_TIMESTAMP_OPTION}` does not support iceberg engine internal sinks"View on GitHub (pinned to 6469eb736d)
Solutions
- Check the table/source name used for the iceberg table for characters that break the generated SQL; rename to a simple identifier.
- Retry creation and capture the full SQL/log output to identify the generated statement.
- If reproducible, report a bug — the internally generated `format!("SELECT ..., {} AS {} FROM {}", ...)` string should always parse as a query.
- Verify parser behavior with the same statement via `psql` EXPLAIN to isolate parsing issues.
Example fix
// before (internal)
let Statement::Query(parsed_query) = stmt else {
panic!("unexpected statement: {:?}", stmt);
};
// after
let Statement::Query(parsed_query) = stmt else {
return Err(anyhow!("expected query for iceberg sink input, got: {:?}", stmt));
}; Defensive patterns
Strategy: try-catch
Try / catch
// when automating iceberg table creation
try {
await client.execute(createIcebergTableSql);
} catch (e) {
if (String(e).includes('unexpected statement')) {
// internal parser/plan issue: log SQL + RW version, retry or file a bug
} else { throw e; }
} Prevention
- Use simple identifiers (no quotes/special chars) for iceberg engine tables.
- Keep RisingWave updated — generated internal SQL is fixed in newer releases.
- Capture the full SQL and logs when iceberg table creation fails to ease debugging.
When it happens
Trigger: Creating an iceberg-engine table (`CREATE TABLE ... WITH (engine = 'iceberg')` path, via `create_iceberg_engine_table`) where the generated `from_name` based query fails to parse as a query — e.g. the interpolated `ROW_ID` column SQL string produces a non-query statement or the parser returns a different statement variant.
Common situations: Iceberg engine table creation with unusual table/source names that break the generated SQL; parser behavior changes after upgrades; bugs in the internally generated query string (not user SQL directly).
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- IcebergSinkWriter should be initialized before barrier
- not yet implemented
- Can't create iceberg sink write result from empty data!
- iceberg sink metadata should be an object
- schema_id should be a u64
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/e8fb069e93dad7da.
Report an issue: GitHub.