|
You can use the following code to reproduce this regression:
public static void main(String... args) throws Throwable {
|
var reproduceThisBug = true;
|
var url = "jdbc:mariadb://localhost:3306/test?useServerPrepStmts&useBulkStmts=" + reproduceThisBug;
|
try (var conn = DriverManager.getConnection(url, "root", "password")) {
|
try (var stmt = conn.createStatement()) {
|
stmt.executeUpdate("""
|
CREATE TABLE IF NOT EXISTS testtable(
|
username VARCHAR(100) NOT NULL PRIMARY KEY,
|
timeMs BIGINT NULL DEFAULT NULL
|
)
|
""");
|
}
|
|
var sql = """
|
INSERT INTO testtable(username, timeMs) VALUES(?, ?) ON DUPLICATE KEY
|
UPDATE timeMs = IF(timeMs IS NULL, ?, IF(? IS NULL, timeMs, ?))
|
""";
|
|
try (var stmt = conn.prepareStatement(sql)) {
|
Long timeMs1 = 2140L;
|
setObjects(stmt,
|
"user1", timeMs1,
|
timeMs1, timeMs1, timeMs1
|
);
|
stmt.addBatch();
|
|
Long timeMs2 = 1000L;
|
setObjects(stmt,
|
"user2", timeMs2,
|
timeMs2, timeMs2, timeMs2
|
);
|
stmt.addBatch();
|
|
stmt.executeBatch();
|
}
|
|
try (var stmt = conn.prepareStatement(sql)) {
|
Long timeMs1 = 2030L;
|
setObjects(stmt,
|
"user1", timeMs1,
|
timeMs1, timeMs1, timeMs1
|
);
|
stmt.addBatch();
|
|
Long timeMs2 = null;
|
setObjects(stmt,
|
"user2", timeMs2,
|
timeMs2, timeMs2, timeMs2
|
);
|
stmt.addBatch();
|
|
stmt.executeBatch();
|
}
|
}
|
}
|
|
public static void setObjects(PreparedStatement stmt, Object... args) throws SQLException {
|
var offset = 0;
|
for (Object arg : args) {
|
stmt.setObject(++offset, arg);
|
}
|
}
|
When `useBulkStmts` is set to `false`, this code results in both rows having non-null `timeMs`. However, when `useBulkStmts` is set to `true`, the row for `user2` has `timeMs=NULL`. This issue only occurs in versions after 3.0.8.
|