risingwavelabs/risingwave · error

MATCH_RECOGNIZE WITHIN deadline has type {} but the ORDER BY

Error message

MATCH_RECOGNIZE WITHIN deadline has type {} but the ORDER BY column has type {}; the two are compared directly

What it means

WITHIN compares the ORDER BY column value directly against the deadline expression, so both must have the same type. The decoder found a `within_deadline` whose return type differs from the ORDER BY column type and rejects the plan. Emitting it anyway would produce a runtime comparison/cast error or wrong semantics.

Source

Thrown at src/stream/src/from_proto/match_recognize.rs:193

        // (`ScalarRefImpl::default_cmp` panics across variants — an actor crash loop that recovery
        // replays), and the span predicate is a boolean. The binder guarantees both
        // (`lower_within`); re-state it here so a skewed or corrupt plan fails at build time.
        let order_key_type = input
            .schema()
            .fields
            .get(order_key_indices[0])
            .map(|f| f.data_type())
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "MATCH_RECOGNIZE ORDER BY column {} is out of range for an input of {} columns",
                    order_key_indices[0],
                    input.schema().len()
                )
            })?;
        if let Some(deadline) = &within_deadline
            && deadline.return_type() != order_key_type
        {
            return Err(anyhow::anyhow!(
                "MATCH_RECOGNIZE WITHIN deadline has type {} but the ORDER BY column has type {}; \
                 the two are compared directly",
                deadline.return_type(),
                order_key_type,
            )
            .into());
        }
        if let Some(predicate) = &within
            && predicate.return_type() != DataType::Boolean
        {
            return Err(anyhow::anyhow!(
                "MATCH_RECOGNIZE WITHIN span predicate has type {}, expected boolean",
                predicate.return_type(),
            )
            .into());
        }

        let vnode_bitmap = params.vnode_bitmap.clone().map(std::sync::Arc::new);

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Cast the ORDER BY column or the deadline so both types match, e.g. `ORDER BY to_timestamp(ts)` or `WITHIN (deadline)::timestamptz`.
  2. Adjust the WITHIN literal to the column's type (e.g. numeric bound for a BIGINT column).
  3. If types look equal in SQL but the plan differs, report a binder type-coercion bug.

Example fix

-- before
SELECT * FROM m MATCH_RECOGNIZE ( ORDER BY ts WITHIN INTERVAL '1 hour' ... ) -- ts is BIGINT
-- after
SELECT * FROM m MATCH_RECOGNIZE ( ORDER BY to_timestamp(ts) WITHIN INTERVAL '1 hour' ... )
Defensive patterns

Strategy: validation

Validate before calling

-- SQL-level guard: ensure the WITHIN deadline type matches the ORDER BY column type
SELECT column_name, data_type FROM information_schema.columns
WHERE table_name = 'm' AND column_name = 'ts'; -- compare with your deadline type

Try / catch

// Defensive pre-check on decoded plan
if let Some(d) = &within_deadline && d.return_type() != order_key_type {
    return Err(anyhow!("WITHIN deadline type {} != ORDER BY type {}", d.return_type(), order_key_type));
}

Prevention

When it happens

Trigger: `new_boxed_executor` decodes a MatchRecognizeNode where `within_deadline.return_type() != order_key_type`, e.g. deadline is TIMESTAMP while ORDER BY column is TIMESTAMPTZ or BIGINT.

Common situations: A SQL query with `WITHIN` whose deadline expression type does not match the ORDER BY column, e.g. `ORDER BY ts ... WITHIN INTERVAL '1 hour'` where `ts` is a BIGINT epoch; frontend bugs producing mismatched types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/b7162128d8e191f3. Report an issue: GitHub.