apache/druid · warning · UnsupportedOperationException
Vectorized expression matchers not implemented for type
Error message
Vectorized expression matchers not implemented for type: [%s]
What it means
ExpressionFilter.makeVectorMatcher only implements vectorized matchers for the expression output types it handles; when the expression's ExpressionType falls through to the default case it throws this UnsupportedOperationException. It means vectorized evaluation of this expression filter is unavailable for that output type, and the query must fall back to the row-by-row matcher.
Solutions
- Disable vectorization for the affected query/segment: set query context key druid.query.vectorize=false or use forceVectorize=false so the non-vector ValueMatcher path is used
- Rewrite the expression so its output type is one of the supported vector types (e.g. cast the expression to LONG/DOUBLE/STRING)
- Upgrade Druid to a version that implements vector matchers for the expression output type
Example fix
// before (query context)
{"query":{"filter":{"type":"expression","expression":"json_value(x,'$.a') = 'b'"}},"vectorize":true}
// after
{"query":{"filter":{"type":"expression","expression":"json_value(x,'$.a') = 'b'"}},"vectorize":false} Defensive patterns
Strategy: fallback
Validate before calling
// Java: skip vector matching for unsupported expression output types
ExpressionType outputType = factory.bestEffortOutputTypeOf(theExpr);
boolean vectorSupported = outputType.is(STRING, LONG, DOUBLE);
queryContext.put("vectorize", vectorSupported ? "true" : "false"); Type guard
boolean vectorMatcherSupported(ExpressionType t) {
return ExpressionType.STRING.equals(t) || ExpressionType.LONG.equals(t)
|| ExpressionType.DOUBLE.equals(t);
} Try / catch
try {
return makeVectorMatcher(bitmapIndexSelector);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("Vectorized expression matchers not implemented")) {
return makeMatcher(rowSelectorFactory); // non-vector fallback
} else { throw e; }
} Prevention
- Cast expressions to simple types (STRING/LONG/DOUBLE) when filtering so vectorization applies
- Test expressions with vectorize=true before production rollout
- Track Druid release notes for newly supported vector expression types
When it happens
Trigger: Evaluating an ExpressionFilter with vectorized query processing where the expression's output type (outputType from ExpressionType.fromString / factory bestEffortOutputType) hits the default branch of the switch, e.g. exotic or unsupported types not covered by the implemented cases.
Common situations: Vectorized queries filtering on expressions with complex/nested or less-common output types; Druid version where a type was added to ExpressionType but not yet supported by the vector matcher.
Related errors
- attempt to get boolean[] null vector from string[] only…
- attempt to get double[] from string[] only scalar binding
- attempt to get long[] from string[] only scalar binding
- Cannot create comparator for array type
- Cannot handle column
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/b99ad49becd0dd62.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/filter/ExpressionFilter.java:133
).makeMatcher(predicateFactory);
case STRING:
return VectorValueMatcherColumnProcessorFactory.instance().makeObjectProcessor(
ColumnCapabilitiesImpl.createSimpleSingleValueStringColumnCapabilities(),
ExpressionVectorSelectors.makeVectorObjectSelector(factory, theExpr, null)
).makeMatcher(predicateFactory);
case ARRAY:
return VectorValueMatcherColumnProcessorFactory.instance().makeObjectProcessor(
ColumnCapabilitiesImpl.createDefault().setType(ExpressionType.toColumnType(outputType)).setHasNulls(true),
ExpressionVectorSelectors.makeVectorObjectSelector(factory, theExpr, null)
).makeMatcher(predicateFactory);
default:
if (ExpressionType.NESTED_DATA.equals(outputType)) {
return VectorValueMatcherColumnProcessorFactory.instance().makeObjectProcessor(
ColumnCapabilitiesImpl.createDefault().setType(ExpressionType.toColumnType(outputType)).setHasNulls(true),
ExpressionVectorSelectors.makeVectorObjectSelector(factory, theExpr, null)
).makeMatcher(predicateFactory);
}
throw new UOE("Vectorized expression matchers not implemented for type: [%s]", outputType);
}
}
@Override
public ValueMatcher makeMatcher(final ColumnSelectorFactory factory)
{
final ColumnValueSelector<ExprEval> selector = ExpressionSelectors.makeExprEvalSelector(factory, expr.get());
return new ValueMatcher()
{
@Override
public boolean matches(boolean includeUnknown)
{
final ExprEval eval = selector.getObject();
if (includeUnknown && eval.value() == null) {
return true;
}
View on GitHub (pinned to 9b90983fd2)