Details
-
Bug
-
Status: Stalled (View Workflow)
-
Major
-
Resolution: Unresolved
-
11.4, 11.8
-
None
-
None
Description
With MARIADB_CLIENT_BULK_UNIT_RESULTS, the (Id, Affected_rows) result set is expected to hold one row per bulk unit.
THD::collect_unit_results() is called from the INSERT/UPDATE/DELETE code paths, which are also executed by triggers on the target table and by stored functions called from the statement; each such statement adds an (0, its affected rows) row before the row of the unit that ran it. Clients cannot map the rows back to units, Connector/J crashed with ArrayIndexOutOfBoundsException (CONJ-1352).
Minimal repro code :
stmt.execute("CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY, val INT)"); |
stmt.execute("CREATE TABLE t2 (val INT)"); |
stmt.execute("INSERT INTO t2 VALUES (1), (2), (2)"); |
// per inserted row, the trigger deletes 1, 2 and 0 rows of t2
|
stmt.execute("CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW DELETE FROM t2 WHERE val = NEW.val"); |
 |
PreparedStatement prep = con.prepareStatement("INSERT INTO t1 (val) VALUES (?)"); // useBulkStmts=true |
for (int val = 1; val <= 3; val++) { prep.setInt(1, val); prep.addBatch(); } |
System.out.println(Arrays.toString(prep.executeBatch()));
|
|
results are :
seq 1 01 00 00 01 02 column count = 2
|
seq 2 ... 49 64 ... column def "Id" (BIGINT unsigned)
|
seq 3 ... 41 66 66 65 63 74 65 64 ... column def "Affected_rows" (BIGINT unsigned)
|
binary rows: 00 | null-bitmap 00 | Id int64 LE | Affected_rows int64 LE
|
seq 4 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 Id 0 affected 1 <- trigger DELETE (val=1)
|
seq 5 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 Id 1 affected 1 <- entry 1
|
seq 6 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 Id 0 affected 2 <- trigger DELETE (val=2, 2 rows)
|
seq 7 00 00 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 Id 2 affected 1 <- entry 2
|
seq 8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Id 0 affected 0 <- trigger DELETE (val=3, nothing)
|
seq 9 00 00 03 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 Id 3 affected 1 <- entry 3
|
seq 10 FE 00 00 22 00 00 00 EOF/OK terminator, 0 warnings, status 0x0022
|
Six rows for three entries, trigger row before its entry's row each time (the trigger's my_ok completes before the INSERT's iteration does). Against the patched server the same request yields exactly:
Fix: ignore collect_unit_results() while thd->in_sub_stmt is set. No mysql-test coverage possible as the bundled libmariadb does not implement the capability; covered by Connector/J BatchTest.batchWithTriggerDml.