apache/druid · error · IllegalStateException

Selector of class[%s] does not have a dictionary, cannot use

Error message

Selector of class[%s] does not have a dictionary, cannot use it.

What it means

Vector counterpart of the same constraint: SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector needs a vector dimension selector with a working dictionary (known cardinality and advance name lookup) to map vector rows to string values. Selectors without dictionaries are rejected with an ISE that includes the selector's class name.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/virtual/SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector.java:58

 *
 * @see SingleStringInputDeferredEvaluationExpressionDimensionSelector for the non-vectorized version of this selector.
 */
public class SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector
    implements SingleValueDimensionVectorSelector
{
  private final SingleValueDimensionVectorSelector selector;
  private final ExprVectorProcessor<Object[]> stringProcessor;
  private final StringLookupVectorInputBindings inputBinding;

  public SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector(
      SingleValueDimensionVectorSelector selector,
      Expr expression
  )
  {
    // Verify selector has a working dictionary.
    if (selector.getValueCardinality() == DimensionDictionarySelector.CARDINALITY_UNKNOWN
        || !selector.nameLookupPossibleInAdvance()) {
      throw new ISE(
          "Selector of class[%s] does not have a dictionary, cannot use it.",
          selector.getClass().getName()
      );
    }
    this.selector = selector;
    this.inputBinding = new StringLookupVectorInputBindings();
    this.stringProcessor = expression.asVectorProcessor(inputBinding);
  }

  @Override
  public int getValueCardinality()
  {
    return CARDINALITY_UNKNOWN;
  }

  @Nullable
  @Override
  public String lookupName(int id)

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Use a dictionary-encoded column/vector dimension selector
  2. Disable vectorization (vectorize=false in query context) as a workaround
  3. Fall back to the non-vector deferred selector for non-dictionary inputs
  4. Implement nameLookupPossibleInAdvance() correctly in custom vector dimension selectors

Example fix

// before
new SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector(unknownCardSelector, expr)
// after
if (sel.getValueCardinality() == CARDINALITY_UNKNOWN) {
  return singleInputDeferredColumnSelector(sel, expr); // non-dictionary fallback
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (sel.getValueCardinality() == CARDINALITY_UNKNOWN || !sel.nameLookupPossibleInAdvance()) {
  // use non-vector path or disable vectorization
}

Type guard

static boolean vectorDictionaryUsable(VectorDimensionSelector sel) {
  return sel.getValueCardinality() != CARDINALITY_UNKNOWN && sel.nameLookupPossibleInAdvance();
}

Try / catch

try {
  return new SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector(sel, expr);
} catch (ISE e) {
  queryContext.put("vectorize", "false");
  return nonVectorSelector(sel, expr);
}

Prevention

When it happens

Trigger: Vectorized query planning constructs this selector with a selector reporting CARDINALITY_UNKNOWN or nameLookupPossibleInAdvance()==false.

Common situations: Vector engine encountering non-dictionary-encoded string columns under expression virtual columns; switching a column's encoding between versions can flip which selector path is chosen and expose this.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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