{"record":{"id":"c44a6ec470ad0a64","repo":"apache/shardingsphere","slug":"expected-blr-begin","errorCode":null,"errorMessage":"Expected blr_begin","messagePattern":"Expected blr_begin","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdParseBatchBlr.java","lineNumber":84,"sourceCode":"     * rejection happens later on the command/error path rather than as a codec-level channel close.</p>\n     *\n     * @param blr BLR buffer\n     * @param blrLength BLR length\n     * @return parsed message format\n     * @throws IllegalArgumentException when BLR format is structurally invalid\n     */\n    public static FirebirdParseBatchBlr parseForFraming(final ByteBuf blr, final int blrLength) {\n        if (blrLength < HEADER_LENGTH) {\n            throw new IllegalArgumentException(\"BLR is too short: \" + blrLength);\n        }\n        ByteBuf buffer = blr.duplicate();\n        final int startReaderIndex = buffer.readerIndex();\n        int version = buffer.readUnsignedByte();\n        if (BlrConstants.blr_version4 != version && BlrConstants.blr_version5 != version) {\n            throw new IllegalArgumentException(\"Unsupported BLR version: \" + version);\n        }\n        if (BlrConstants.blr_begin != buffer.readUnsignedByte()) {\n            throw new IllegalArgumentException(\"Expected blr_begin\");\n        }\n        if (BlrConstants.blr_message != buffer.readUnsignedByte()) {\n            throw new IllegalArgumentException(\"Expected blr_message\");\n        }\n        buffer.skipBytes(1);\n        FirebirdParseBatchBlr result = parseFormat(buffer);\n        validateTermination(buffer, startReaderIndex, blrLength);\n        return result;\n    }\n    \n    private static void validateTermination(final ByteBuf buffer, final int startReaderIndex, final int blrLength) {\n        if (remainingWithinBlr(buffer, startReaderIndex, blrLength) < 1 || BlrConstants.blr_end != buffer.readUnsignedByte()) {\n            throw new IllegalArgumentException(\"Expected blr_end\");\n        }\n        if (remainingWithinBlr(buffer, startReaderIndex, blrLength) < 1 || BlrConstants.blr_eoc != buffer.readUnsignedByte()) {\n            throw new IllegalArgumentException(\"Expected blr_eoc\");\n        }\n        if (0 != remainingWithinBlr(buffer, startReaderIndex, blrLength)) {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdParseBatchBlr.java#L66-L102","documentation":"SQLFeatureNotSupportedException thrown by updateBlob(int, InputStream) on SQL federation ResultSets. This is the stream-based overload of updateBlob among six, all declared final and throwing in AbstractUnsupportedUpdateOperationSQLFederationResultSet. Federation returns CONCUR_READ_ONLY in-memory merged results, so streaming bytes into a column of the current row is not possible; the throw occurs immediately, before the stream is read.","triggerScenarios":"Calling rs.updateBlob(columnIndex, inputStream) on a federation ResultSet and then rs.updateRow(). Seen in upload pipelines that stream a file straight into the current row.","commonSituations":"Web upload handlers streaming multipart data into BLOB columns via the cursor API; code ported from drivers where CONCUR_UPDATABLE ResultSets accepted streams; ShardingSphere adopted as a proxy in front of an existing app without auditing cursor-update usage.","solutions":["Use an UPDATE with ps.setBinaryStream(index, stream) so the data flows through normal DML","Close/skip the stream properly in error paths since the federation call never consumes it","Check rs.getConcurrency() upfront and choose DML for read-only cursors","Sidestep federation for this statement if updatable behavior is required"],"exampleFix":"// before\nrs.updateBlob(2, uploadInputStream); // SQLFeatureNotSupportedException\nrs.updateRow();\n\n// after\ntry (PreparedStatement ps = conn.prepareStatement(\"UPDATE files SET content = ? WHERE id = ?\")) {\n    ps.setBinaryStream(1, uploadInputStream);\n    ps.setLong(2, rs.getLong(\"id\"));\n    ps.executeUpdate();\n}","handlingStrategy":"try-catch","validationCode":"if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) {\n    // stream upload via UPDATE + setBinaryStream instead of updateBlob(index, stream)\n}","typeGuard":null,"tryCatchPattern":"try {\n    rs.updateBlob(columnIndex, inputStream);\n} catch (SQLFeatureNotSupportedException e) {\n    // caller must close/consume the stream; retry as UPDATE DML\n}","preventionTips":["Remember the throwing call never reads the stream: close it yourself","Use setBinaryStream on PreparedStatement for streaming uploads","Check getConcurrency() before iterating with edit intent"],"tags":["jdbc","resultset","sql-federation","read-only","blob","streaming"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}