{"record":{"id":"39eeb0d1e4772028","repo":"apache/shardingsphere","slug":"expected-blr-eoc","errorCode":null,"errorMessage":"Expected blr_eoc","messagePattern":"Expected blr_eoc","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":100,"sourceCode":"        }\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)) {\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    }","sourceCodeStart":82,"sourceCodeEnd":118,"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#L82-L118","documentation":"SQLFeatureNotSupportedException thrown by updateBlob(String, InputStream, long) on SQL federation ResultSets. This label+stream+length overload is final and throws in AbstractUnsupportedUpdateOperationSQLFederationResultSet like every update method in the class. The design intent is explicit: federation ResultSets expose merged, read-only data, and the entire updatable-ResultSet API surface throws SQLFeatureNotSupportedException naming the operation.","triggerScenarios":"Calling rs.updateBlob(\"content\", inputStream, length) on a federated ResultSet before rs.updateRow(). Occurs in label-based binary writers that also pass an exact length.","commonSituations":"Media pipelines that stream known-size assets into columns by name; application onboarding onto ShardingSphere where federation now serves previously simple queries; generic JDBC wrappers that expose all update overloads.","solutions":["Execute UPDATE ... SET content = ? WHERE ... with ps.setBinaryStream(1, stream, length)","Treat rs.getConcurrency() == CONCUR_READ_ONLY as the signal to use statement-based writes","Adjust the SQL or federation configuration so this query is routed instead of federated"],"exampleFix":"// before\nrs.updateBlob(\"content\", in, fileSize); // SQLFeatureNotSupportedException\n\n// after\ntry (PreparedStatement ps = conn.prepareStatement(\"UPDATE files SET content = ? WHERE id = ?\")) {\n    ps.setBinaryStream(1, in, fileSize);\n    ps.setLong(2, rs.getLong(\"id\"));\n    ps.executeUpdate();\n}","handlingStrategy":"try-catch","validationCode":"if (rs.getConcurrency() == ResultSet.CONCUR_READ_ONLY) {\n    // label+length stream write unsupported: use UPDATE + setBinaryStream with length\n}","typeGuard":null,"tryCatchPattern":"try {\n    rs.updateBlob(\"content\", inputStream, length);\n} catch (SQLFeatureNotSupportedException e) {\n    // federation cursor read-only; perform bounded UPDATE DML\n}","preventionTips":["Centralize binary writes in one DML-based helper","Close streams in caller code after any exception","Avoid mixing read iteration and row editing over federation"],"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"}