Environment
- OceanBase Version (SeekDB): 5.7.25-OceanBase seekdb-v
- Observer Revision: 1-f84169fbd80d020887d038cdb0892703e28833f3
- Observer Build Time: Aug 10 2026 10:45:34
- Observer Build Flags: RelWithDebInfo
- JDBC Driver: com.oceanbase:oceanbase-client:2.4.16-SERVER_LITE-SNAPSHOT
- Test Pipeline: [INTERNAL_URL]
- Test Job: [INTERNAL_URL]
- seekdb_test SHA: a1a3df9543b0a778bad60a0e4574d522fc473c4e
- oceanbase-lite SHA: f84169fbd80d020887d038cdb0892703e28833f3
Description
When running the objdbctest GeneratedKeysTest.testBatchedError on SeekDB 1.3, the test fails only in text protocol.
Test Scenario Configuration:
useServerPrepStmts=false
rewriteBatchedStatements=true
allowMultiQueries=true
continueBatchOnError=false
Statement.RETURN_GENERATED_KEYS
A batch of 5 inserts is executed. The third item intentionally writes the string "a" into an INT column to trigger a type conversion error. After executeLargeBatch throws a BatchUpdateException, ps.getGeneratedKeys() returns 0 rows, while the existing historical regression test case expects it to return 2 keys (for the first two successful inserts).
The test annotation references a historical issue: "When an error occurs in the middle of a JDBC multi-statement insert with batched_multi_statement enabled, the returned last_insert_id is incorrect" (workItemId=2024080100104016016). Therefore, the expectation of "2" is likely an intentional regression check.
Steps to Reproduce
- Create the test table:
CREATE TABLE t_br (
id INT AUTO_INCREMENT PRIMARY KEY,
n INT
);
- Use a JDBC connection with the parameters listed above.
- Prepare a statement:
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO t_br (n) VALUES (?)",
Statement.RETURN_GENERATED_KEYS);
- Add batch parameters in order:
1, 2, "a", 4, 5.
- Execute:
ps.executeLargeBatch(); (This throws a BatchUpdateException).
- Call:
ps.getGeneratedKeys();
Actual Results:
BatchUpdateException.getLargeUpdateCounts() outputs: [-3, -3, -3, -3]
getGeneratedKeys() returns row count: 0
- Test assertion fails:
java.lang.AssertionError: expected:<0> but was:<2> (Note: The test is written as assertEquals(num, 2), so the correct interpretation is num=0 but the test requires num=2).
Protocol Comparison:
| Protocol |
useServerPrepStmts |
Test Result |
GeneratedKeys Expectation |
| prepare_execute_protocol |
true |
PASS |
Test explicitly expects empty |
| prepare_protocol |
true |
PASS |
Test explicitly expects empty |
| text_protocol |
false |
FAIL |
Historical test expects 2, actual 0 |
Other related tests (testRewriteBatched, testStmtGetGeneratedKeys, testPrepStmtGeneratedKeys) in the same run pass, so not all GeneratedKeys functionality is broken.
Impact
This issue blocks the complete physical regression of the SeekDB Linux objdbctest.
Analysis & Questions for Developers
Key observations from the database state after failure:
SHOW CREATE TABLE t_br shows: AUTO_INCREMENT = 6
SELECT COUNT(*) FROM t_br; returns: 0
This suggests:
- 5 auto-increment values have been allocated.
- No records were committed from the entire statement.
- JDBC
getGeneratedKeys returns 0 rows.
This behavior is closer to "a single multi-value INSERT that fails atomically", while the historical test expectation is closer to "multi-statement where the first two succeed and two keys are returned".
Questions for JDBC/Connector developers (priority) and database kernel:
-
In OceanBase JDBC with text protocol + rewriteBatchedStatements=true, is the above batch ultimately sent as:
a) A single multi-value INSERT statement, or
b) A multi-statement composed of multiple INSERTs?
This determines whether 0 or 2 GeneratedKeys is the correct compatible behavior.
-
With continueBatchOnError=false and the third item failing, what is the MySQL-compatible semantic?
a) The entire batch fails atomically, getGeneratedKeys returns 0; or
b) The first two items succeed, getGeneratedKeys returns 2?
-
Are the error packet, affected rows, and last_insert_id returned by the server sufficient for the driver to correctly generate the GeneratedKeys?
-
Why does getLargeUpdateCounts for a five-item batch only return four -3 values?
-
Please perform a control test using the same driver version on MySQL to confirm the compatibility baseline.
Proposed Solution / Acceptance Criteria
Before simply changing the test expectation from 2 to 0, the compatible semantics for the above scenario must be clearly defined. It is recommended to supplement regression tests for the following matrix:
useServerPrepStmts=true/false
rewriteBatchedStatements=true/false
continueBatchOnError=true/false
- Error located at the beginning, middle, or end of the batch
- Validate
updateCounts, GeneratedKeys, table records, and AUTO_INCREMENT values.
Logs & Evidence
- Failure Time: 2026-08-10 10:54:17.483 - 10:54:17.510
- Server Trace ID: YB427F000001-000658A860426632-0-0
- Server Error Codes:
ob_error=-4226, client error=1366
- Server Transaction Log Indicates:
context.exec_error_=-4226, context.is_rollback_=true, rollback=true, need_rollback=true, trans_result.touched_storage=false
- Corresponding Error Packet:
sending error packet( ob_error=-4226, client error=1366 )
Log Locations:
- Workload complete log:
/obdata/data/hudson/seekdb-gitlab/objdbctest/runs/pipeline-189961-job-919123/singlejob-logs/objdbctest-cycle-1-text_protocol.log
- Observer log:
/obdata/data/hudson/seekdb-gitlab/objdbctest/log/pipeline-189961-job-919123/seekdb.log.20260810110209777 (precise lines: 233317-233320)
- Database data directory:
/obdata/data/hudson/seekdb-gitlab/objdbctest/data/pipeline-189961-job-919123
- Clog directory:
/obdata/data/hudson/seekdb-gitlab/objdbctest/clog/pipeline-189961-job-919123
- Database PID: 2187220
Database Connection Info (Preserved):
- CLI:
obclient -h -P5044 -uroot@sys -Dtest (password is empty)
- JDBC:
jdbc:oceanbase://:5044/test?user=root@sys&password=&useServerPrepStmts=false&rewriteBatchedStatements=true&allowMultiQueries=true&continueBatchOnError=false&useAffectedRows=true
Environment
Description
When running the
objdbctestGeneratedKeysTest.testBatchedErroron SeekDB 1.3, the test fails only in text protocol.Test Scenario Configuration:
useServerPrepStmts=falserewriteBatchedStatements=trueallowMultiQueries=truecontinueBatchOnError=falseStatement.RETURN_GENERATED_KEYSA batch of 5 inserts is executed. The third item intentionally writes the string
"a"into an INT column to trigger a type conversion error. AfterexecuteLargeBatchthrows aBatchUpdateException,ps.getGeneratedKeys()returns 0 rows, while the existing historical regression test case expects it to return 2 keys (for the first two successful inserts).The test annotation references a historical issue: "When an error occurs in the middle of a JDBC multi-statement insert with
batched_multi_statementenabled, the returnedlast_insert_idis incorrect" (workItemId=2024080100104016016). Therefore, the expectation of "2" is likely an intentional regression check.Steps to Reproduce
1,2,"a",4,5.ps.executeLargeBatch();(This throws aBatchUpdateException).ps.getGeneratedKeys();Actual Results:
BatchUpdateException.getLargeUpdateCounts()outputs:[-3, -3, -3, -3]getGeneratedKeys()returns row count:0java.lang.AssertionError: expected:<0> but was:<2>(Note: The test is written asassertEquals(num, 2), so the correct interpretation isnum=0but the test requiresnum=2).Protocol Comparison:
Other related tests (
testRewriteBatched,testStmtGetGeneratedKeys,testPrepStmtGeneratedKeys) in the same run pass, so not all GeneratedKeys functionality is broken.Impact
This issue blocks the complete physical regression of the SeekDB Linux
objdbctest.Analysis & Questions for Developers
Key observations from the database state after failure:
SHOW CREATE TABLE t_brshows:AUTO_INCREMENT = 6SELECT COUNT(*) FROM t_br;returns:0This suggests:
getGeneratedKeysreturns 0 rows.This behavior is closer to "a single multi-value INSERT that fails atomically", while the historical test expectation is closer to "multi-statement where the first two succeed and two keys are returned".
Questions for JDBC/Connector developers (priority) and database kernel:
In OceanBase JDBC with
text protocol+rewriteBatchedStatements=true, is the above batch ultimately sent as:a) A single multi-value INSERT statement, or
b) A multi-statement composed of multiple INSERTs?
This determines whether 0 or 2 GeneratedKeys is the correct compatible behavior.
With
continueBatchOnError=falseand the third item failing, what is the MySQL-compatible semantic?a) The entire batch fails atomically,
getGeneratedKeysreturns 0; orb) The first two items succeed,
getGeneratedKeysreturns 2?Are the error packet, affected rows, and
last_insert_idreturned by the server sufficient for the driver to correctly generate the GeneratedKeys?Why does
getLargeUpdateCountsfor a five-item batch only return four-3values?Please perform a control test using the same driver version on MySQL to confirm the compatibility baseline.
Proposed Solution / Acceptance Criteria
Before simply changing the test expectation from 2 to 0, the compatible semantics for the above scenario must be clearly defined. It is recommended to supplement regression tests for the following matrix:
useServerPrepStmts=true/falserewriteBatchedStatements=true/falsecontinueBatchOnError=true/falseupdateCounts,GeneratedKeys, table records, andAUTO_INCREMENTvalues.Logs & Evidence
ob_error=-4226,client error=1366context.exec_error_=-4226,context.is_rollback_=true,rollback=true,need_rollback=true,trans_result.touched_storage=falsesending error packet( ob_error=-4226, client error=1366 )Log Locations:
/obdata/data/hudson/seekdb-gitlab/objdbctest/runs/pipeline-189961-job-919123/singlejob-logs/objdbctest-cycle-1-text_protocol.log/obdata/data/hudson/seekdb-gitlab/objdbctest/log/pipeline-189961-job-919123/seekdb.log.20260810110209777(precise lines: 233317-233320)/obdata/data/hudson/seekdb-gitlab/objdbctest/data/pipeline-189961-job-919123/obdata/data/hudson/seekdb-gitlab/objdbctest/clog/pipeline-189961-job-919123Database Connection Info (Preserved):
obclient -h -P5044 -uroot@sys -Dtest(password is empty)jdbc:oceanbase://:5044/test?user=root@sys&password=&useServerPrepStmts=false&rewriteBatchedStatements=true&allowMultiQueries=true&continueBatchOnError=false&useAffectedRows=true