{"record":{"id":"122ae704b9789e10","repo":"apache/druid","slug":"reverse-lookup-not-allowed-122ae7","errorCode":null,"errorMessage":"Reverse lookup not allowed.","messagePattern":"Reverse lookup not allowed\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/data/CompressedVSizeColumnarMultiIntsSupplier.java","lineNumber":228,"sourceCode":"            throw new IAE(\"Index[%d] >= size[%d]\", index, size);\n          }\n          return values.get(index + offset);\n        }\n\n        @Override\n        public void inspectRuntimeShape(RuntimeShapeInspector inspector)\n        {\n          inspector.visit(\"values\", values);\n        }\n      }\n\n      return new UnsharedIndexedInts();\n    }\n\n    @Override\n    public int indexOf(IndexedInts value)\n    {\n      throw new UnsupportedOperationException(\"Reverse lookup not allowed.\");\n    }\n\n    @Override\n    public Iterator<IndexedInts> iterator()\n    {\n      return IndexedIterable.create(this).iterator();\n    }\n\n    @Override\n    public void inspectRuntimeShape(RuntimeShapeInspector inspector)\n    {\n      inspector.visit(\"offsets\", offsets);\n      inspector.visit(\"values\", values);\n    }\n  }\n\n}\n","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/data/CompressedVSizeColumnarMultiIntsSupplier.java#L210-L246","documentation":"CompressedVSizeColumnarMultiIntsSupplier's inner UnsharedIndexedInts deliberately rejects reverse lookups. Given a value, indexOf() would have to scan every row to find the offset list matching it, which the compressed column format does not support. Any call to indexOf on this column type throws UnsupportedOperationException.","triggerScenarios":"Calling indexOf(IndexedInts) on an IndexedInts supplier returned by a compressed vSize multi-value column, e.g. via column lookup APIs that attempt a reverse lookup.","commonSituations":"Running filter or lookup code that assumes all IndexedInts columns support indexOf (uncompressed or single-value columns often do); using dictionary-encoded reverse lookup paths against compressed multi-value columns.","solutions":["Do not call indexOf on this column type; iterate rows with iterator() or get() instead","Restructure the query to forward-look up values by row index rather than reverse-locating a value","If reverse lookup is required, use a column encoding that supports it (e.g. dictionary-encoded single-value columns)"],"exampleFix":"// before\nint idx = indexedInts.indexOf(values);\n// after\nint idx = -1;\nfor (int i = 0; i < indexedInts.size(); i++) {\n  if (indexedInts.get(i).equals(values)) { idx = i; break; }\n}","handlingStrategy":"try-catch","validationCode":"if (indexed instanceof IndexedInts && indexed.size() >= 0 && !supportsReverseLookup) { /* iterate instead */ }","typeGuard":"boolean supportsReverseLookup(Object col) {\n  return !(col instanceof org.apache.druid.segment.data.CompressedVSizeColumnarMultiIntsSupplier.UnsharedIndexedInts);\n}","tryCatchPattern":"try {\n  idx = indexedInts.indexOf(values);\n} catch (UnsupportedOperationException e) {\n  // fall back to linear scan via iterator()\n}","preventionTips":["Never assume indexOf is supported on IndexedInts implementations","Check the column type/encoding before reverse lookups","Prefer forward iteration for compressed multi-value columns"],"tags":["java","unsupported-operation","columnar-storage"],"backgroundTag":"unsupported-operation","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"}