risingwavelabs/risingwave · error

{} does not support struct, array, map, vector, jsonb for co

Error message

{} does not support struct, array, map, vector, jsonb for comparison argument, got {}

What it means

Certain aggregate call rewrites (in general_rewrite_agg_call) compare arguments (e.g. MIN/MAX-style comparison), and composite types are not comparable there. When the comparison argument's DataType is Struct, List, Map, Vector, or Jsonb, the planner bails with this error naming the aggregate type and the offending type.

Source

Thrown at src/frontend/src/optimizer/plan_node/logical_agg.rs:808

                } else {
                    let new_agg_call = AggCall {
                        order_by: OrderBy::any(),
                        ..agg_call
                    };
                    Ok(push_agg_call(new_agg_call)?.into())
                }
            }
            AggType::Builtin(PbAggKind::ArgMin | PbAggKind::ArgMax) => {
                let mut agg_call = agg_call;

                let comparison_arg_type = agg_call.args[1].return_type();
                match comparison_arg_type {
                    DataType::Struct(_)
                    | DataType::List(_)
                    | DataType::Map(_)
                    | DataType::Vector(_)
                    | DataType::Jsonb => {
                        bail!(format!(
                            "{} does not support struct, array, map, vector, jsonb for comparison argument, got {}",
                            agg_call.agg_type.to_string(),
                            comparison_arg_type
                        ));
                    }
                    _ => {}
                }

                let not_null_exprs: Vec<ExprImpl> = agg_call
                    .args
                    .iter()
                    .map(|arg| -> Result<ExprImpl> {
                        Ok(FunctionCall::new(ExprType::IsNotNull, vec![arg.clone()])?.into())
                    })
                    .try_collect()?;

                let comparison_expr = agg_call.args[1].clone();
                let mut order_exprs = vec![OrderByExpr {

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Extract a comparable scalar field before aggregating, e.g. min((obj).field) or min(jsonb_col->>'key').
  2. Cast the column to a comparable type if semantics allow (e.g. jsonb ->> 'k' as text).
  3. Use a different aggregate or window/ORDER BY pattern that supports the type.

Example fix

// before
SELECT max(data) FROM t; -- data is jsonb
// after
SELECT max(data->>'created_at') FROM t;
Defensive patterns

Strategy: validation

Validate before calling

// Check column types before using MIN/MAX-style comparison aggregates
const unsupported = new Set(['struct', 'list', 'map', 'vector', 'jsonb']);
if (unsupported.has(colType)) {
  throw new Error(`Cannot aggregate ${colName} of type ${colType} with a comparison aggregate; extract a scalar field first`);
}

Type guard

const isComparableScalar = (t: string): boolean => !['struct','list','map','vector','jsonb'].includes(t);

Try / catch

try {
  await client.query('SELECT min(data) FROM t');
} catch (e) {
  if (String(e.message).includes('does not support struct, array, map, vector, jsonb')) {
    await client.query("SELECT min(data->>'key') FROM t");
  } else throw e;
}

Prevention

When it happens

Trigger: A query such as SELECT min(struct_col) FROM ... (or max/other comparison-based agg over a nested/array/map/jsonb column) planned through the frontend.

Common situations: Aggregating JSONB payloads from CDC sources; MIN/MAX over ARRAY or STRUCT columns produced by row() literals; schema drift making a column jsonb.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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