apache/druid · error · QueryUnsupportedException

Joining against a ARRAY columns is not supported.

Error message

Joining against a ARRAY columns is not supported.

What it means

Lookup joins only support scalar single-value key comparisons. If the join matcher is asked to build a processor for an ARRAY-typed column, it immediately throws QueryUnsupportedException because arrays are not supported as join operands against lookups.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/join/lookup/LookupJoinMatcher.java:109

        @Override
        public Supplier<String> makeDoubleProcessor(BaseDoubleColumnValueSelector selector)
        {
          return () -> selector.isNull() ? null : DimensionHandlerUtils.convertObjectToString(selector.getDouble());
        }

        @Override
        public Supplier<String> makeLongProcessor(BaseLongColumnValueSelector selector)
        {
          return () -> selector.isNull() ? null : DimensionHandlerUtils.convertObjectToString(selector.getLong());
        }

        @Override
        public Supplier<String> makeArrayProcessor(
            BaseObjectColumnValueSelector<?> selector,
            @Nullable ColumnCapabilities columnCapabilities
        )
        {
          throw new QueryUnsupportedException("Joining against a ARRAY columns is not supported.");
        }

        @Override
        public Supplier<String> makeComplexProcessor(BaseObjectColumnValueSelector<?> selector)
        {
          return () -> null;
        }
      };

  // currentIterator and currentEntry track iteration position through the currently-matched-rows.
  // 1) currentEntry is the entry that our column selector factory is looking at right now.
  // 2) currentIterator contains future matches that it _will_ be looking at after nextMatch() is called.
  @Nullable
  private Iterator<Map.Entry<String, String>> currentIterator = null;
  private final SettableSupplier<Pair<String, String>> currentEntry = new SettableSupplier<>();

  private final LookupExtractor extractor;
  private final JoinConditionAnalysis condition;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Cast the join column to a scalar type (e.g. VARCHAR) in SQL instead of ARRAY
  2. Re-ingest the data so the join key is a single-value string/long column
  3. Use a different join strategy (not lookup join) if array semantics are truly required

Example fix

// before
JOIN lookup l ON t.arr_col = l.k -- arr_col is ARRAY
// after
JOIN lookup l ON ARRAY_TO_STRING(t.arr_col, ',') = l.k -- or cast to VARCHAR
Defensive patterns

Strategy: type-guard

Validate before calling

ColumnCapabilities caps = selectorFactory.getColumnCapabilities(col);
if (caps != null && caps.getType().equals(ColumnCapabilitiesImpl.CommandType.ARRAY)) throw new IllegalArgumentException("array join key unsupported");

Type guard

boolean isNotArray(ColumnCapabilities caps) { return caps == null || !ColumnType.ARRAY.equals(caps.toColumnType()); }

Try / catch

try { runJoin(query); } catch (QueryUnsupportedException e) { if (e.getMessage().contains("ARRAY")) { /* cast column to scalar and retry */ } }

Prevention

When it happens

Trigger: Running a join whose right-hand (lookup) column, or the matched column type, is an ARRAY; the DimensionDictionarySelector's makeArrayProcessor is invoked during selector creation.

Common situations: Joining on a column that was ingested as an array type (native array columns) or cast to ARRAY in SQL; schema drift turning a string column into an array.

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/50d4271113fa967c. Report an issue: GitHub.