apache/druid · error · IAE
unsupported type
Error message
unsupported type
What it means
UnaryOperatorExpr.Neg evaluates its operand and negates it; it only supports LONG and DOUBLE result types. If the operand's ExprEval type is neither (e.g. STRING or an array type), IAE 'unsupported type <type>' is thrown at evaluation time.
Source
Thrown at processing/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java:146
@Override
public ExprEval eval(ObjectBinding bindings)
{
if (expr instanceof BigIntegerExpr) {
// Special case to handle unary minus for Long.MIN_VALUE: converting the literal to long directly is impossible
return ExprEval.of(((BigInteger) expr.getLiteralValue()).multiply(BigInteger.valueOf(-1)).longValueExact());
}
ExprEval ret = expr.eval(bindings);
if (ret.value() == null) {
return ExprEval.ofType(ret.type(), null);
}
if (ret.type().is(ExprType.LONG)) {
return ExprEval.of(-ret.asLong());
}
if (ret.type().is(ExprType.DOUBLE)) {
return ExprEval.of(-ret.asDouble());
}
throw new IAE("unsupported type " + ret.type());
}
@Override
public boolean canVectorize(InputBindingInspector inspector)
{
return inspector.areNumeric(expr) && expr.canVectorize(inspector);
}
@Override
public <T> ExprVectorProcessor<T> asVectorProcessor(VectorInputBindingInspector inspector)
{
return VectorMathProcessors.negate().asProcessor(inspector, expr);
}
}
@SuppressWarnings("ClassName")
class UnaryNotExpr extends UnaryExpr
{View on GitHub (pinned to 9b90983fd2)
Solutions
- Cast the operand to a numeric type before negating: "-CAST(x AS LONG)" or "-CAST(x AS DOUBLE)".
- Fix the ingestion spec so the column is declared LONG/DOUBLE instead of STRING.
- Guard non-numeric rows with a filter or COALESCE/default value before applying unary minus.
Example fix
// before "-x" // x is STRING // after "-CAST(x AS DOUBLE)"
Defensive patterns
Strategy: type-guard
Validate before calling
Expr.BindingAnalysis a = expr.analyzeInputs(); // ensure inputs are numeric-typed, or wrap operand in CAST(x AS DOUBLE)
Type guard
// in expression form: only negate after an explicit numeric cast
"-CAST(x AS DOUBLE)" // or check output type before negating in code
if (!ret.type().is(ExprType.LONG) && !ret.type().is(ExprType.DOUBLE)) { /* coerce or reject */ } Try / catch
try { result = eval(negExpr, bindings); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("unsupported type")) { result = eval(negWithCast, bindings); } } Prevention
- Declare numeric columns as LONG/DOUBLE in ingestion specs, not STRING
- Always CAST before arithmetic on possibly-string inputs
- Watch for schema drift turning numeric columns into strings
When it happens
Trigger: Evaluating a negation expression like "-x" where x resolves to a non-numeric type — a string column (even numeric-looking, e.g. '-5' as STRING), a NULL-only/string-typed virtual column, or an array-typed input.
Common situations: Negating columns ingested as strings from CSV/Kafka without explicit numeric type declarations; applying '-' to a timestamp/STRING cast result; schema drift where a column changed from numeric to string.
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
- attempt to get long[] from string[] only scalar binding
- attempt to get double[] from string[] only scalar binding
- attempt to get boolean[] null vector from string[] only scal
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Expected a number or an instance of MergingDigest, but recei
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/74d1566bf4d14411.
Report an issue: GitHub.