{"record":{"id":"4f28803c1c51dbed","repo":"apache/druid","slug":"filling-row-num-conversions-is-supported-only-with","errorCode":null,"errorMessage":"Filling row num conversions is supported only with RowCombining and Merging iterators","messagePattern":"Filling row num conversions is supported only with RowCombining and Merging iterators","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/IndexMergerBase.java","lineNumber":834,"sourceCode":"          int maxRowNum = comprisedRows.getMaxCurrentlyCombinedRowNumByOriginalIteratorIndex(originalIteratorIndex);\n\n          for (int rowNum = minRowNum; rowNum <= maxRowNum; rowNum++) {\n            while (conversionBuffer.position() < rowNum) {\n              conversionBuffer.put(INVALID_ROW);\n            }\n            conversionBuffer.put(rowCount);\n          }\n        }\n      } else if (timeAndDimsIterator instanceof MergingRowIterator) {\n        RowPointer rowPointer = (RowPointer) timeAndDims;\n        IntBuffer conversionBuffer = rowNumConversions.get(rowPointer.getIndexNum());\n        int rowNum = rowPointer.getRowNum();\n        while (conversionBuffer.position() < rowNum) {\n          conversionBuffer.put(INVALID_ROW);\n        }\n        conversionBuffer.put(rowCount);\n      } else {\n        throw new IllegalStateException(\n            \"Filling row num conversions is supported only with RowCombining and Merging iterators\"\n        );\n      }\n\n      if ((++rowCount % 500000) == 0) {\n        log.debug(\"walked 500,000/%d rows in %,d millis.\", rowCount, System.currentTimeMillis() - time);\n        time = System.currentTimeMillis();\n      }\n    }\n    for (IntBuffer rowNumConversion : rowNumConversions) {\n      rowNumConversion.rewind();\n    }\n    log.debug(\"completed walk through of %,d rows in %,d millis.\", rowCount, System.currentTimeMillis() - startTime);\n    progress.stopSection(section);\n    return new IndexMergeResult(\n        rowNumConversions,\n        rowCount,\n        rowCount == 0 ? null : minTime,","sourceCodeStart":816,"sourceCodeEnd":852,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/IndexMergerBase.java#L816-L852","documentation":"Thrown in mergeIndexesAndWriteColumns when the row-number conversion buffer is requested but the input indexable's iterator does not implement the RowCombining/RowMerging iterator interfaces needed to support it. Only those iterator types can supply per-row conversion mapping during merge.","triggerScenarios":"Calling the merge path with rowNumConversions enabled while the segment's iterator is not a RowCombiningIterator/RowMergingIterator (e.g. merging a single non-combining indexable or using an iterator wrapper lacking the interface).","commonSituations":"Custom segment adapters or pluggable storages feeding the merger; internal use of IndexMerger APIs with rowNumConversions on iterators that don't combine rows (e.g. non-rollup sources).","solutions":["Do not pass rowNumConversions when merging with plain iterators","Wrap the input in a merging/combining iterator (e.g. via the QueryableIndex/IncrementalIndex merging paths)","Use the standard mergeable index implementations (IncrementalIndex/QueryableIndex) so the merger creates combining iterators"],"exampleFix":"// before\nmerger.mergeQueryableIndex(indexes, false, aggs, ..., rowNumConversions, ...); // plain iterator lacks combining support\n// after\nmerger.mergeQueryableIndex(indexes, true /* rollup enables combining iterator */, aggs, ..., rowNumConversions, ...);","handlingStrategy":"validation","validationCode":"if (rowNumConversions.length > 0 && !(indexable.getRows() instanceof RowCombiningIterator) && !(indexable.getRows() instanceof RowMergingIterator)) { throw new IllegalStateException(\"rowNumConversions require a combining/merging iterator\"); }","typeGuard":"boolean supportsRowNumConversions(IndexableAdapter a) { return a.getRows() instanceof RowCombiningIterator || a.getRows() instanceof RowMergingIterator; }","tryCatchPattern":"try { mergeIndexesAndWriteColumns(...); } catch (IllegalStateException e) { if (e.getMessage().contains(\"RowCombining and Merging iterators\")) { /* retry without rowNumConversions or wrap adapter */ } else throw e; }","preventionTips":["Use standard IncrementalIndex/QueryableIndex inputs to the merger","Enable rollup so combining iterators are created","Only set rowNumConversions in code paths known to use merging iterators"],"tags":["druid","segment-merge","iterator"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}