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

  1. Cast the operand to a numeric type before negating: "-CAST(x AS LONG)" or "-CAST(x AS DOUBLE)".
  2. Fix the ingestion spec so the column is declared LONG/DOUBLE instead of STRING.
  3. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/74d1566bf4d14411. Report an issue: GitHub.