risingwavelabs/risingwave · error · ExprError
Division by zero
Error message
Division by zero
What it means
ExprError::DivisionByZero is thrown when an expression evaluation attempts to divide a numeric value by zero (or by a value that is effectively zero, e.g. numeric 0). The expression core detects the zero divisor at evaluation time and returns this error instead of panicking or producing an undefined result. It matches Postgres semantics where division by zero raises an error rather than returning NULL.
Source
Thrown at src/expr/core/src/error.rs:67
#[error("Unsupported function: {0}")]
UnsupportedFunction(String),
#[error("Unsupported cast: {0} to {1}")]
UnsupportedCast(DataType, DataType),
#[error("Casting to {0} out of range")]
CastOutOfRange(&'static str),
#[error("Numeric out of range")]
NumericOutOfRange,
#[error("Numeric out of range: underflow")]
NumericUnderflow,
#[error("Numeric out of range: overflow")]
NumericOverflow,
#[error("Division by zero")]
DivisionByZero,
#[error("Parse error: {0}")]
// TODO(error-handling): should prefer use error types than strings.
Parse(Box<str>),
#[error("Invalid parameter {name}: {reason}")]
// TODO(error-handling): should prefer use error types than strings.
InvalidParam {
name: &'static str,
reason: Box<str>,
},
#[error("Array error: {0}")]
Array(
#[from]
#[backtrace]
ArrayError,View on GitHub (pinned to 6469eb736d)
Solutions
- Add an explicit zero check in SQL: `CASE WHEN denom = 0 THEN NULL ELSE num / denom END`.
- Use `NULLIF(denom, 0)` as the denominator: `num / NULLIF(denom, 0)` so the result becomes NULL instead of erroring.
- If this happens inside a streaming pipeline, guard the denominator expression upstream in the materialized view definition.
Example fix
// before CREATE MATERIALIZED VIEW mv AS SELECT clicks / impressions AS ctr FROM stats; // after CREATE MATERIALIZED VIEW mv AS SELECT clicks / NULLIF(impressions, 0) AS ctr FROM stats;
Defensive patterns
Strategy: validation
Validate before calling
// SQL-level guard before division SELECT num / NULLIF(denom, 0) AS ratio FROM t;
Try / catch
// Rust caller
match result {
Err(e) if matches!(e.downcast_ref::<ExprError>(), Some(ExprError::DivisionByZero)) => Some(f64::NAN), // or None
other => other.ok(),
} Prevention
- Always use NULLIF(x, 0) for denominators that derive from data or aggregates.
- Never write literal `1/0` in queries even as placeholders.
- Unit-test ratio expressions with zero-count windows/empty groups.
When it happens
Trigger: Evaluating a `/` expression (integer, decimal/numeric, or floating point depending on type semantics) where the right-hand operand evaluates to 0; also via batch/stream expression execution of user SQL like `SELECT 1/0` or `sum(x)/count(x)` when count is 0.
Common situations: Aggregate-derived denominators that can be zero (ratio of counts), user-written queries with literal 0 denominators, upstream data changes that make previously non-zero columns zero, percentile/average computations over empty windows.
Related errors
- next offset {:?} should be later than current offset {:?}
- new item epoch {} does not match current chunk offset epoch
- new item epoch {} does not exceed barrier offset epoch {}
- Numeric out of range
- Numeric out of range: underflow
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/660bb8e9f0678246.
Report an issue: GitHub.