{"record":{"id":"18d3ecf6045c55b7","repo":"apache/flink","slug":"only-support-seek-at-first-18d3ec","errorCode":null,"errorMessage":"Only support seek at first.","messagePattern":"Only support seek at first\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/vector/ParquetColumnarRowSplitReader.java","lineNumber":345,"sourceCode":"        columnReaders = new ColumnReader[types.size()];\n        for (int i = 0; i < types.size(); ++i) {\n            columnReaders[i] =\n                    createColumnReader(\n                            utcTimestamp,\n                            selectedTypes[i],\n                            types.get(i),\n                            requestedSchema.getColumns(),\n                            pages,\n                            fieldList.get(i),\n                            0);\n        }\n        totalCountLoadedSoFar += pages.getRowCount();\n    }\n\n    /** Seek to a particular row number. */\n    public void seekToRow(long rowCount) throws IOException {\n        if (totalCountLoadedSoFar != 0) {\n            throw new UnsupportedOperationException(\"Only support seek at first.\");\n        }\n\n        List<BlockMetaData> blockMetaData = reader.getRowGroups();\n\n        for (BlockMetaData metaData : blockMetaData) {\n            if (metaData.getRowCount() > rowCount) {\n                break;\n            } else {\n                reader.skipNextRowGroup();\n                rowsReturned += metaData.getRowCount();\n                totalCountLoadedSoFar += metaData.getRowCount();\n                rowsInBatch = (int) metaData.getRowCount();\n                nextRow = (int) metaData.getRowCount();\n                rowCount -= metaData.getRowCount();\n            }\n        }\n        for (int i = 0; i < rowCount; i++) {\n            boolean end = reachedEnd();","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/vector/ParquetColumnarRowSplitReader.java#L327-L363","documentation":"UnsupportedOperationException from seekToRow(long) in ParquetColumnarRowSplitReader: seeking is only allowed before any row group has been loaded. The guard is totalCountLoadedSoFar != 0, which becomes non-zero as soon as a row group is read or a previous seek skipped row groups. The design is one-shot: position once, then stream forward.","triggerScenarios":"Calling seekToRow(rowCount) a second time, or calling it after nextRecord()/reachedEnd() has already caused a row group to load, on the same reader instance.","commonSituations":"Reusing a reader for random access (e.g. implementing sampling or offset-based retries); upper layers assuming a seekable cursor API like a JDBC result set; iterator wrappers that rewind and re-seek on the same split.","solutions":["Create a fresh ParquetColumnarRowSplitReader per seek: close the old one, reopen on the same InputFile, then seekToRow","Restructure the consumer to do a single seek up front and only read forward afterwards","For repeated random access, cache the rows you need instead of re-seeking the streaming reader"],"exampleFix":"// before\nreader.seekToRow(100);\n... read ...\nreader.seekToRow(500); // UnsupportedOperationException\n\n// after\nreader.close();\nreader = newReader(inputFile, ...);\nreader.seekToRow(500);","handlingStrategy":"validation","validationCode":"if (reader.hasLoadedData()) { throw new IllegalStateException(\"seekToRow only valid before reading - recreate the reader\"); } // or track your own 'readStarted' flag","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat ParquetColumnarRowSplitReader as forward-only: one seek, then stream","Create a new reader instance per reposition instead of re-seeking"],"tags":["parquet","seek","api-misuse","flink"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}