Skip to content

Commit 06a1f72

Browse files
committed
Fix for Bug#35811592, Missing implementation for Connection.releaseSavepoint().
Change-Id: Ibf392dc4e4a00f8fd04406cbefdd93096995c112
1 parent 9df3820 commit 06a1f72

File tree

3 files changed

+69
-75
lines changed

3 files changed

+69
-75
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
Version 8.2.0
55

6+
- Fix for Bug#35811592, Missing implementation for Connection.releaseSavepoint().
7+
68
- Fix for Bug#91351 (Bug#28225464), MysqlConnectionPoolDataSource - autocommit status lost if global autocommit = 0.
79

810
- WL#15197, Support WebauthN in fido authentication plugin.

src/main/user-impl/java/com/mysql/cj/jdbc/ConnectionImpl.java

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,8 +1741,21 @@ public void registerStatement(JdbcStatement stmt) {
17411741
}
17421742

17431743
@Override
1744-
public void releaseSavepoint(Savepoint arg0) throws SQLException {
1745-
// this is a no-op
1744+
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
1745+
synchronized (getConnectionMutex()) {
1746+
checkClosed();
1747+
1748+
StringBuilder releaseSavepointQuery = new StringBuilder("RELEASE SAVEPOINT ");
1749+
releaseSavepointQuery
1750+
.append(StringUtils.quoteIdentifier(savepoint.getSavepointName(), this.session.getIdentifierQuoteString(), this.pedantic.getValue()));
1751+
java.sql.Statement stmt = null;
1752+
try {
1753+
stmt = getMetadataSafeStatement();
1754+
stmt.executeUpdate(releaseSavepointQuery.toString());
1755+
} finally {
1756+
closeStatement(stmt);
1757+
}
1758+
}
17461759
}
17471760

17481761
@Override
@@ -1836,25 +1849,18 @@ void forEach(ConnectionLifecycleInterceptor each) throws SQLException {
18361849
}
18371850

18381851
StringBuilder rollbackQuery = new StringBuilder("ROLLBACK TO SAVEPOINT ");
1839-
rollbackQuery.append('`');
1840-
rollbackQuery.append(savepoint.getSavepointName());
1841-
rollbackQuery.append('`');
1842-
1852+
rollbackQuery
1853+
.append(StringUtils.quoteIdentifier(savepoint.getSavepointName(), this.session.getIdentifierQuoteString(), this.pedantic.getValue()));
18431854
java.sql.Statement stmt = null;
1844-
18451855
try {
18461856
stmt = getMetadataSafeStatement();
1847-
18481857
stmt.executeUpdate(rollbackQuery.toString());
18491858
} catch (SQLException sqlEx) {
18501859
int errno = sqlEx.getErrorCode();
1851-
18521860
if (errno == 1181) {
18531861
String msg = sqlEx.getMessage();
1854-
18551862
if (msg != null) {
18561863
int indexOfError153 = msg.indexOf("153");
1857-
18581864
if (indexOfError153 != -1) {
18591865
throw SQLError.createSQLException(Messages.getString("Connection.22", new Object[] { savepoint.getSavepointName() }),
18601866
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, errno, getExceptionInterceptor());
@@ -2064,10 +2070,6 @@ void forEach(ConnectionLifecycleInterceptor each) throws SQLException {
20642070

20652071
String quotedId = this.session.getIdentifierQuoteString();
20662072

2067-
if (quotedId == null || quotedId.equals(" ")) {
2068-
quotedId = "";
2069-
}
2070-
20712073
StringBuilder query = new StringBuilder("USE ");
20722074
query.append(StringUtils.quoteIdentifier(db, quotedId, this.pedantic.getValue()));
20732075

@@ -2122,9 +2124,7 @@ public void setReadOnlyInternal(boolean readOnlyFlag) throws SQLException {
21222124
@Override
21232125
public java.sql.Savepoint setSavepoint() throws SQLException {
21242126
MysqlSavepoint savepoint = new MysqlSavepoint(getExceptionInterceptor());
2125-
21262127
setSavepoint(savepoint);
2127-
21282128
return savepoint;
21292129
}
21302130

@@ -2133,15 +2133,10 @@ private void setSavepoint(MysqlSavepoint savepoint) throws SQLException {
21332133
checkClosed();
21342134

21352135
StringBuilder savePointQuery = new StringBuilder("SAVEPOINT ");
2136-
savePointQuery.append('`');
2137-
savePointQuery.append(savepoint.getSavepointName());
2138-
savePointQuery.append('`');
2139-
2136+
savePointQuery.append(StringUtils.quoteIdentifier(savepoint.getSavepointName(), this.session.getIdentifierQuoteString(), this.pedantic.getValue()));
21402137
java.sql.Statement stmt = null;
2141-
21422138
try {
21432139
stmt = getMetadataSafeStatement();
2144-
21452140
stmt.executeUpdate(savePointQuery.toString());
21462141
} finally {
21472142
closeStatement(stmt);
@@ -2153,9 +2148,7 @@ private void setSavepoint(MysqlSavepoint savepoint) throws SQLException {
21532148
public java.sql.Savepoint setSavepoint(String name) throws SQLException {
21542149
synchronized (getConnectionMutex()) {
21552150
MysqlSavepoint savepoint = new MysqlSavepoint(name, getExceptionInterceptor());
2156-
21572151
setSavepoint(savepoint);
2158-
21592152
return savepoint;
21602153
}
21612154
}

src/test/java/testsuite/simple/ConnectionTest.java

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -322,58 +322,57 @@ public void testIsolationLevel() throws Exception {
322322
*/
323323
@Test
324324
public void testSavepoint() throws Exception {
325-
DatabaseMetaData dbmd = this.conn.getMetaData();
325+
assumeTrue(this.conn.getMetaData().supportsSavepoints(), "Savepoints not supported");
326326

327-
if (dbmd.supportsSavepoints()) {
328-
System.out.println("Testing SAVEPOINTs");
327+
try {
328+
this.conn.setAutoCommit(true);
329329

330-
try {
331-
this.conn.setAutoCommit(true);
332-
333-
createTable("testSavepoints", "(field1 int)", "InnoDB");
334-
335-
// Try with named save points
336-
this.conn.setAutoCommit(false);
337-
this.stmt.executeUpdate("INSERT INTO testSavepoints VALUES (1)");
338-
339-
Savepoint afterInsert = this.conn.setSavepoint("afterInsert");
340-
this.stmt.executeUpdate("UPDATE testSavepoints SET field1=2");
341-
342-
Savepoint afterUpdate = this.conn.setSavepoint("afterUpdate");
343-
this.stmt.executeUpdate("DELETE FROM testSavepoints");
344-
345-
assertTrue(getRowCount("testSavepoints") == 0, "Row count should be 0");
346-
this.conn.rollback(afterUpdate);
347-
assertTrue(getRowCount("testSavepoints") == 1, "Row count should be 1");
348-
assertTrue("2".equals(getSingleValue("testSavepoints", "field1", null).toString()), "Value should be 2");
349-
this.conn.rollback(afterInsert);
350-
assertTrue("1".equals(getSingleValue("testSavepoints", "field1", null).toString()), "Value should be 1");
351-
this.conn.rollback();
352-
assertTrue(getRowCount("testSavepoints") == 0, "Row count should be 0");
353-
354-
// Try with 'anonymous' save points
355-
this.conn.rollback();
356-
357-
this.stmt.executeUpdate("INSERT INTO testSavepoints VALUES (1)");
358-
afterInsert = this.conn.setSavepoint();
359-
this.stmt.executeUpdate("UPDATE testSavepoints SET field1=2");
360-
afterUpdate = this.conn.setSavepoint();
361-
this.stmt.executeUpdate("DELETE FROM testSavepoints");
362-
363-
assertTrue(getRowCount("testSavepoints") == 0, "Row count should be 0");
364-
this.conn.rollback(afterUpdate);
365-
assertTrue(getRowCount("testSavepoints") == 1, "Row count should be 1");
366-
assertTrue("2".equals(getSingleValue("testSavepoints", "field1", null).toString()), "Value should be 2");
367-
this.conn.rollback(afterInsert);
368-
assertTrue("1".equals(getSingleValue("testSavepoints", "field1", null).toString()), "Value should be 1");
369-
this.conn.rollback();
370-
371-
this.conn.releaseSavepoint(this.conn.setSavepoint());
372-
} finally {
373-
this.conn.setAutoCommit(true);
374-
}
375-
} else {
376-
System.out.println("MySQL version does not support SAVEPOINTs");
330+
createTable("testSavepoints", "(field1 int)", "InnoDB");
331+
332+
// Try with named save points
333+
this.conn.setAutoCommit(false);
334+
this.stmt.executeUpdate("INSERT INTO testSavepoints VALUES (1)");
335+
336+
Savepoint afterInsert = this.conn.setSavepoint("afterInsert");
337+
this.stmt.executeUpdate("UPDATE testSavepoints SET field1=2");
338+
339+
Savepoint afterUpdate = this.conn.setSavepoint("afterUpdate");
340+
this.stmt.executeUpdate("DELETE FROM testSavepoints");
341+
342+
assertEquals(0, getRowCount("testSavepoints"), "Row count should be 0");
343+
this.conn.rollback(afterUpdate);
344+
assertEquals(1, getRowCount("testSavepoints"), "Row count should be 1");
345+
assertEquals("2", getSingleValue("testSavepoints", "field1", null).toString(), "Value should be 2");
346+
this.conn.rollback(afterInsert);
347+
assertEquals("1", getSingleValue("testSavepoints", "field1", null).toString(), "Value should be 1");
348+
this.conn.rollback();
349+
assertEquals(0, getRowCount("testSavepoints"), "Row count should be 0");
350+
351+
// Try with 'anonymous' save points
352+
this.conn.rollback();
353+
354+
this.stmt.executeUpdate("INSERT INTO testSavepoints VALUES (1)");
355+
afterInsert = this.conn.setSavepoint();
356+
this.stmt.executeUpdate("UPDATE testSavepoints SET field1=2");
357+
afterUpdate = this.conn.setSavepoint();
358+
this.stmt.executeUpdate("DELETE FROM testSavepoints");
359+
360+
assertEquals(0, getRowCount("testSavepoints"), "Row count should be 0");
361+
this.conn.rollback(afterUpdate);
362+
assertEquals(1, getRowCount("testSavepoints"), "Row count should be 1");
363+
assertEquals("2", getSingleValue("testSavepoints", "field1", null).toString(), "Value should be 2");
364+
this.conn.rollback(afterInsert);
365+
assertEquals("1", getSingleValue("testSavepoints", "field1", null).toString(), "Value should be 1");
366+
this.conn.rollback();
367+
368+
Savepoint savepoint = this.conn.setSavepoint();
369+
this.conn.releaseSavepoint(savepoint);
370+
assertThrows(SQLException.class, "SAVEPOINT .* does not exist", () -> {
371+
this.conn.rollback(savepoint);
372+
return null;
373+
});
374+
} finally {
375+
this.conn.setAutoCommit(true);
377376
}
378377
}
379378

0 commit comments

Comments
 (0)