{"record":{"id":"feffd782368742b4","repo":"apache/druid","slug":"map-column-doesn-t-support-getrow","errorCode":null,"errorMessage":"Map column doesn't support getRow()","messagePattern":"Map column doesn't support getRow\\(\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"extensions-contrib/virtual-columns/src/main/java/org/apache/druid/segment/MapTypeMapVirtualColumnDimensionSelector.java","lineNumber":49,"sourceCode":"\n/**\n * {@link DimensionSelector} for {@link Map} type {@link MapVirtualColumn}. This dimensionSelector only supports\n * {@link #getObject()} currently.\n */\nfinal class MapTypeMapVirtualColumnDimensionSelector extends MapVirtualColumnDimensionSelector\n{\n  MapTypeMapVirtualColumnDimensionSelector(\n      DimensionSelector keySelector,\n      DimensionSelector valueSelector\n  )\n  {\n    super(keySelector, valueSelector);\n  }\n\n  @Override\n  public IndexedInts getRow()\n  {\n    throw new UnsupportedOperationException(\"Map column doesn't support getRow()\");\n  }\n\n  @Override\n  public ValueMatcher makeValueMatcher(@Nullable String value)\n  {\n    return new ValueMatcher()\n    {\n      @Override\n      public boolean matches(boolean includeUnknown)\n      {\n        // Map column doesn't match with any string\n        return false;\n      }\n\n      @Override\n      public void inspectRuntimeShape(RuntimeShapeInspector inspector)\n      {\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/virtual-columns/src/main/java/org/apache/druid/segment/MapTypeMapVirtualColumnDimensionSelector.java#L31-L67","documentation":"MapTypeMapVirtualColumnDimensionSelector wraps a map-typed virtual column and only supports map-style access (getKeySelector/getObject). The DimensionSelector contract's row-oriented and dictionary-lookup methods are meaningless for a map column, so this class deliberately throws UnsupportedOperationException instead of returning wrong data.","triggerScenarios":"Calling getRow() on a dimension selector obtained from a map-type virtual column (e.g. using MAP_KEYS/MAP_VALUES-backed virtual columns) in any query path that expects an array/list dimension: group-by on the column directly, filter code that iterates IndexedInts, or any engine/operator that reads the selector row-wise instead of via getObject().","commonSituations":"Users try to group by or filter directly on a map virtual column expression; query planners or custom extensions assume every DimensionSelector supports getRow; older query engines or community code paths written before map-typed columns existed reach this selector.","solutions":["Do not use the map virtual column as a scalar/array dimension; use its keys/values via MAP_KEYS() or MAP_VALUES() functions or index into it instead.","Rewrite the query so the map column is only consumed through getObject()/map-aware operators (e.g. SELECT it as JSON, or extract a specific key).","If you own custom query code, detect map-typed columns and avoid calling getRow()/lookupName()/idLookup() on their selectors.","Contribute upstream support (return an IndexedInts of the key/value selector) if a legitimate row-wise use is needed."],"exampleFix":"// before\nDimValHolder v = selector.getRow(); // throws UnsupportedOperationException\n// after\nObject mapVal = selector.getObject(); // map-aware access\n// or extract a key in SQL: SELECT MAP_EXTRACT('k', mapCol) AS k FROM ...","handlingStrategy":"type-guard","validationCode":"// Java: before using the selector row-wise\nif (selector instanceof MapTypeMapVirtualColumnDimensionSelector) {\n  // use map-aware path\n  Object mapValue = ((BaseMapVirtualColumnDimensionSelector) selector).getObject();\n} else {\n  IndexedInts row = selector.getRow();\n}","typeGuard":"boolean supportsRowAccess(DimensionSelector s) {\n  return !(s instanceof MapTypeMapVirtualColumnDimensionSelector);\n}","tryCatchPattern":"try {\n  IndexedInts row = selector.getRow();\n  process(row);\n} catch (UnsupportedOperationException e) {\n  processMapAware(selector.getObject());\n}","preventionTips":["Never call getRow()/lookupName()/idLookup() on selectors from map-typed virtual columns.","Check nameLookupPossibleInAdvance() before dictionary operations.","Consume map columns via getObject() or MAP_KEYS/MAP_VALUES SQL functions.","Test custom query operators against map virtual columns, not just string dimensions."],"tags":["java","virtual-columns","unsupported-operation","map-column"],"backgroundTag":"unsupported-operation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}