{"record":{"id":"06a9a428e9e126fb","repo":"apache/druid","slug":"column-s-is-multi-value-do-not-ask-for-a-single","errorCode":null,"errorMessage":"Column[%s] is multi-value, do not ask for a single-value selector","messagePattern":"Column\\[(.+?)\\] is multi-value, do not ask for a single-value selector","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/vector/QueryableIndexVectorColumnSelectorFactory.java","lineNumber":147,"sourceCode":"    }\n\n    Function<DimensionSpec, SingleValueDimensionVectorSelector> mappingFunction = spec -> {\n      final String name = spec.getDimension();\n      if (virtualColumns.exists(name)) {\n        return virtualColumns.makeSingleValueDimensionVectorSelector(dimensionSpec, this, columnSelector, offset);\n      }\n\n      final ColumnHolder holder = columnSelector.getColumnHolder(name);\n      if (holder == null\n          || !holder.getCapabilities().isDictionaryEncoded().isTrue()\n          || !holder.getCapabilities().is(ValueType.STRING)) {\n        // Asking for a single-value dimension selector on a non-string column gets you a bunch of nulls.\n        return NilVectorSelector.create(offset);\n      }\n\n      if (holder.getCapabilities().hasMultipleValues().isMaybeTrue()) {\n        // Asking for a single-value dimension selector on a multi-value column gets you an error.\n        throw new ISE(\"Column[%s] is multi-value, do not ask for a single-value selector\", name);\n      }\n\n      final BaseColumn column = (BaseColumn) holder.getColumn(); // if not VirtualColumn, must be BaseColumn.\n      final SingleValueDimensionVectorSelector selector;\n      if (column instanceof DictionaryEncodedColumn) {\n        selector = ((DictionaryEncodedColumn<?>) column).makeSingleValueDimensionVectorSelector(offset);\n      } else {\n        final NestedVectorColumnSelectorFactory nestedColumnSelectorFactory =\n            column.as(NestedVectorColumnSelectorFactory.class);\n        if (nestedColumnSelectorFactory != null) {\n          selector = nestedColumnSelectorFactory.makeSingleValueDimensionVectorSelector(List.of(), this, offset);\n        } else {\n          selector = NilVectorSelector.create(offset);\n        }\n      }\n\n      return spec.decorate(selector);\n    };","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/vector/QueryableIndexVectorColumnSelectorFactory.java#L129-L165","documentation":"Vectorized single-value dimension selectors assume each row contributes exactly one value. If the underlying column can hold multiple values (hasMultipleValues().isMaybeTrue()), the factory throws this ISE because silently taking the first value would change query semantics.","triggerScenarios":"makeSingleValueDimensionSelector called on a column that is (or may be, in some segments) multi-value string; heterogeneous segments where a column is MV in one segment and SV in another.","commonSituations":"Schema drift after changing ingestion from single to multi-value; query planner choosing single-value path based on a different segment's schema; extension code building selectors directly.","solutions":["Use a multi-value dimension selector or MV/ARRAY-aware aggregators for this column","Force a consistent column type by re-ingesting with an explicit dimensionsSpec (single-value string)","Query with ARRAY functions or flatten the MV column into separate rows at ingest","Disable vectorization as an interim workaround"],"exampleFix":"// before\nfactory.makeSingleValueDimensionSelector(DefaultDimensionSpec.of(\"mvCol\"));\n// after\nfactory.makeMultiValueDimensionSelector(DefaultDimensionSpec.of(\"mvCol\"));","handlingStrategy":"validation","validationCode":"// before requesting single-value selector\nif (holder.getCapabilities().hasMultipleValues().isMaybeTrue()) {\n  useMultiValueSelector();\n} else {\n  useSingleValueSelector();\n}","typeGuard":"boolean definitelySingleValue = !caps.hasMultipleValues().isMaybeTrue();","tryCatchPattern":"try { sel = factory.makeSingleValueDimensionSelector(spec); } catch (IllegalStateException e) { sel = factory.makeMultiValueDimensionSelector(spec); }","preventionTips":["Check hasMultipleValues() before choosing selector kind","Pin column types via dimensionsSpec so segments never drift between SV/MV","Handle MV columns with MV-aware aggregators"],"tags":["vectorization","multi-value","schema-drift","selector"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}