{"record":{"id":"c2eed77f8dddd686","repo":"apache/shardingsphere","slug":"unexpected-trailing-bytes-in-blr","errorCode":null,"errorMessage":"Unexpected trailing bytes in BLR","messagePattern":"Unexpected trailing bytes in BLR","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":103,"sourceCode":"        }\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)) {\n            throw new IllegalArgumentException(\"Unexpected trailing bytes in BLR\");\n        }\n    }\n    \n    private static int remainingWithinBlr(final ByteBuf buffer, final int startReaderIndex, final int blrLength) {\n        return blrLength - (buffer.readerIndex() - startReaderIndex);\n    }\n    \n    private static void validateSupported(final List<FirebirdBatchColumnDescriptor> fields) {\n        for (FirebirdBatchColumnDescriptor each : fields) {\n            if (FirebirdBinaryColumnType.BLOB == each.getType()) {\n                // TODO Implement BATCH_REGBLOB, BATCH_BLOB_STREAM and BATCH_SET_BPB before accepting BLOB fields.\n                throw new FirebirdProtocolException(\"BLOB fields are not supported in Firebird batch operations\");\n            }\n        }\n    }\n    \n    private static FirebirdParseBatchBlr parseFormat(final ByteBuf buffer) {\n        int count = buffer.readUnsignedByte();","sourceCodeStart":85,"sourceCodeEnd":121,"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#L85-L121","documentation":"SQLFeatureNotSupportedException thrown by updateClob(int, Clob) on SQL federation ResultSets. AbstractUnsupportedUpdateOperationSQLFederationResultSet declares all six updateClob overloads final and throwing: federated ResultSets are CONCUR_READ_ONLY merged views, so writing a java.sql.Clob into a column of the current row is unsupported. The exception is thrown synchronously; no part of the Clob is transferred.","triggerScenarios":"Calling rs.updateClob(columnIndex, clob) on a federation ResultSet followed by rs.updateRow(). Typical in text/document features that store large character data in CLOB columns via the cursor API.","commonSituations":"Document or report storage code written against a driver that supported updatable ResultSets; ShardingSphere JDBC/proxy adopted underneath an existing app; cross-shard JOINs newly routed through federation where cursor updates previously worked.","solutions":["Write the CLOB with an UPDATE statement using ps.setClob or ps.setCharacterStream, keyed by primary key","For very large text prefer streaming via setCharacterStream to avoid materializing the whole Clob","Branch on rs.getConcurrency() before any updateXxx call and use DML for read-only cursors","Avoid federated execution for statements whose results must be editable"],"exampleFix":"// before\nrs.updateClob(3, clob); // SQLFeatureNotSupportedException\nrs.updateRow();\n\n// after\ntry (PreparedStatement ps = conn.prepareStatement(\"UPDATE docs SET body = ? WHERE id = ?\")) {\n    ps.setClob(1, clob);\n    ps.setLong(2, rs.getLong(\"id\"));\n    ps.executeUpdate();\n}","handlingStrategy":"try-catch","validationCode":"if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) {\n    // CLOB write unsupported: use UPDATE + setClob instead\n}","typeGuard":null,"tryCatchPattern":"try {\n    rs.updateClob(columnIndex, clob);\n} catch (SQLFeatureNotSupportedException e) {\n    // federation ResultSet read-only; store CLOB via UPDATE DML\n}","preventionTips":["Write CLOBs through PreparedStatement DML, not the cursor API","Check concurrency mode before text-edit features","Re-query after DML instead of updateRow+refreshRow"],"tags":["jdbc","resultset","sql-federation","read-only","clob"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}