apache/druid · error · UnsupportedOperationException

Map column doesn't support idLookup()

Error message

Map column doesn't support idLookup()

What it means

idLookup() should return an IdLookup that maps string values to dictionary ids without boxing; because this map-backed selector has no dictionary, the method throws UnsupportedOperationException rather than returning a bogus lookup.

Source

Thrown at extensions-contrib/virtual-columns/src/main/java/org/apache/druid/segment/MapTypeMapVirtualColumnDimensionSelector.java:114

  @Nullable
  @Override
  public String lookupName(int id)
  {
    throw new UnsupportedOperationException("Map column doesn't support lookupName()");
  }

  @Override
  public boolean nameLookupPossibleInAdvance()
  {
    return false;
  }

  @Nullable
  @Override
  public IdLookup idLookup()
  {
    throw new UnsupportedOperationException("Map column doesn't support idLookup()");
  }

  @Override
  public Object getObject()
  {
    final DimensionSelector keySelector = getKeySelector();
    final DimensionSelector valueSelector = getValueSelector();

    final IndexedInts keyIndices = keySelector.getRow();
    final IndexedInts valueIndices = valueSelector.getRow();

    final int limit = Math.min(keyIndices.size(), valueIndices.size());
    return IntStream
        .range(0, limit)
        .boxed()
        .collect(
            Collectors.toMap(
                i -> keySelector.lookupName(keyIndices.get(i)),

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Guard the call: only use idLookup() when the selector supports it; for map virtual columns use value-based matchers via getObject() instead.
  2. Avoid using the map virtual column in scenarios that require id-based optimization (direct group-by, string-keyed filters).
  3. Project the desired map key into a normal column/expression before filtering or grouping.

Example fix

// before
IdLookup lookup = selector.idLookup(); // throws
// after
if (selector.nameLookupPossibleInAdvance()) {
  IdLookup lookup = selector.idLookup();
} else {
  ValueMatcher matcher = selector.makeValueMatcher(expectedValue);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (selector.nameLookupPossibleInAdvance() && selector.idLookup() != null) { /* id-based optimization */ }

Type guard

IdLookup safeIdLookup(DimensionSelector s) {
  try { return s.idLookup(); } catch (UnsupportedOperationException e) { return null; }
}

Try / catch

try {
  IdLookup lookup = selector.idLookup();
  optimizeWithIds(lookup);
} catch (UnsupportedOperationException e) {
  optimizeWithValues(selector); // string/value based path
}

Prevention

When it happens

Trigger: Query engines that call idLookup() to optimize filters or to obtain ids directly from string values (e.g. in some group-by or filter implementations) when the selector wraps a map virtual column.

Common situations: Filter pushdown or integer-optimization code paths hitting a map virtual column; third-party/custom extensions assuming all DimensionSelectors provide IdLookup.

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 apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/ef442103d076878a. Report an issue: GitHub.