Skip to content

Commit 555db50

Browse files
committed
Fix for Bug#116630 (Bug#37272802), Tests fail on Windows if test database has upper/mixed case chars.
Change-Id: Ibbd4e7abac97e4cac2baa5f82ca683035c67dec4
1 parent 3cdc8a2 commit 555db50

16 files changed

+418
-429
lines changed

CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
Version 9.2.0
55

6+
- Fix for Bug#116630 (Bug#37272802), Tests fail on Windows if test database has upper/mixed case chars.
7+
68
- Fix for Bug#71143 (Bug#17967091), Calling ResultSet.updateRow should not set all field values in UPDATE.
79

810
- Fix for Bug#103437 (Bug#32807360), Syntax error when calling PreparedStatement.getMetadata() with LIMIT placeholded.

src/main/core-impl/java/com/mysql/cj/CancelQueryTaskImpl.java

+51-52
Original file line numberDiff line numberDiff line change
@@ -74,64 +74,63 @@ public void run() {
7474
}
7575

7676
try {
77-
if (CancelQueryTaskImpl.this.queryTimeoutKillsConnection) {
78-
localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_TIMEOUT);
79-
session.invokeCleanupListeners(new OperationCancelledException(Messages.getString("Statement.ConnectionKilledDueToTimeout")));
80-
} else {
81-
localQueryToCancel.getCancelTimeoutLock().lock();
77+
localQueryToCancel.getCancelTimeoutLock().lock();
78+
try {
79+
long origConnId = session.getThreadId();
80+
HostInfo hostInfo = session.getHostInfo();
81+
String database = hostInfo.getDatabase();
82+
String user = hostInfo.getUser();
83+
String password = hostInfo.getPassword();
84+
85+
NativeSession newSession = null;
8286
try {
83-
long origConnId = session.getThreadId();
84-
HostInfo hostInfo = session.getHostInfo();
85-
String database = hostInfo.getDatabase();
86-
String user = hostInfo.getUser();
87-
String password = hostInfo.getPassword();
88-
89-
NativeSession newSession = null;
90-
try {
91-
newSession = new NativeSession(hostInfo, session.getPropertySet());
92-
93-
TelemetrySpan span = newSession.getTelemetryHandler().startSpan(TelemetrySpanName.CANCEL_QUERY);
94-
try (TelemetryScope scope = span.makeCurrent()) {
95-
span.setAttribute(TelemetryAttribute.DB_NAME, database);
96-
span.setAttribute(TelemetryAttribute.DB_OPERATION, TelemetryAttribute.OPERATION_KILL);
97-
span.setAttribute(TelemetryAttribute.DB_STATEMENT, TelemetryAttribute.OPERATION_KILL + TelemetryAttribute.STATEMENT_SUFFIX);
98-
span.setAttribute(TelemetryAttribute.DB_SYSTEM, TelemetryAttribute.DB_SYSTEM_DEFAULT);
99-
span.setAttribute(TelemetryAttribute.DB_USER, user);
100-
span.setAttribute(TelemetryAttribute.THREAD_ID, Thread.currentThread().getId());
101-
span.setAttribute(TelemetryAttribute.THREAD_NAME, Thread.currentThread().getName());
102-
103-
newSession.connect(hostInfo, user, password, database, 30000, new TransactionEventHandler() {
104-
105-
@Override
106-
public void transactionCompleted() {
107-
}
108-
109-
@Override
110-
public void transactionBegun() {
111-
}
112-
113-
});
114-
newSession.getProtocol().sendCommand(new NativeMessageBuilder(newSession.getServerSession().supportsQueryAttributes())
115-
.buildComQuery(newSession.getSharedSendPacket(), newSession, "KILL QUERY " + origConnId), false, 0);
116-
} catch (Throwable t) {
117-
span.setError(t);
118-
throw t;
119-
} finally {
120-
span.end();
121-
}
87+
newSession = new NativeSession(hostInfo, session.getPropertySet());
88+
89+
TelemetrySpan span = newSession.getTelemetryHandler().startSpan(TelemetrySpanName.CANCEL_QUERY);
90+
try (TelemetryScope scope = span.makeCurrent()) {
91+
span.setAttribute(TelemetryAttribute.DB_NAME, database);
92+
span.setAttribute(TelemetryAttribute.DB_OPERATION, TelemetryAttribute.OPERATION_KILL);
93+
span.setAttribute(TelemetryAttribute.DB_STATEMENT, TelemetryAttribute.OPERATION_KILL + TelemetryAttribute.STATEMENT_SUFFIX);
94+
span.setAttribute(TelemetryAttribute.DB_SYSTEM, TelemetryAttribute.DB_SYSTEM_DEFAULT);
95+
span.setAttribute(TelemetryAttribute.DB_USER, user);
96+
span.setAttribute(TelemetryAttribute.THREAD_ID, Thread.currentThread().getId());
97+
span.setAttribute(TelemetryAttribute.THREAD_NAME, Thread.currentThread().getName());
98+
99+
newSession.connect(hostInfo, user, password, database, 30000, new TransactionEventHandler() {
100+
101+
@Override
102+
public void transactionCompleted() {
103+
}
104+
105+
@Override
106+
public void transactionBegun() {
107+
}
108+
109+
});
110+
newSession.getProtocol().sendCommand(new NativeMessageBuilder(newSession.getServerSession().supportsQueryAttributes())
111+
.buildComQuery(newSession.getSharedSendPacket(), newSession, "KILL QUERY " + origConnId), false, 0);
112+
} catch (Throwable t) {
113+
span.setError(t);
114+
throw t;
122115
} finally {
123-
try {
124-
newSession.forceClose();
125-
} catch (Throwable t) {
126-
// no-op.
127-
}
116+
span.end();
128117
}
129-
localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_TIMEOUT);
130118
} finally {
131-
localQueryToCancel.getCancelTimeoutLock().unlock();
119+
try {
120+
newSession.forceClose();
121+
} catch (Throwable t) {
122+
// no-op.
123+
}
132124
}
125+
localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_TIMEOUT);
126+
} finally {
127+
localQueryToCancel.getCancelTimeoutLock().unlock();
128+
}
129+
130+
if (CancelQueryTaskImpl.this.queryTimeoutKillsConnection) {
131+
session.invokeCleanupListeners(new OperationCancelledException(Messages.getString("Statement.ConnectionKilledDueToTimeout")));
133132
}
134-
// } catch (NullPointerException npe) {
133+
} catch (NullPointerException npe) {
135134
// Case when connection closed while starting to cancel.
136135
// We can't easily synchronize this, because then one thread can't cancel() a running query.
137136
// Ignore, we shouldn't re-throw this, because the connection's already closed, so the statement has been timed out.

src/main/core-impl/java/com/mysql/cj/NativeSession.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ public Timer getCancelTimer() {
997997
getSessionLock().lock();
998998
try {
999999
if (this.cancelTimer == null) {
1000-
this.cancelTimer = new Timer("MySQL Statement Cancellation Timer", Boolean.TRUE);
1000+
this.cancelTimer = new Timer("MySQL Statement Cancellation Timer", true);
10011001
}
10021002
return this.cancelTimer;
10031003
} finally {

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import java.sql.SQLXML;
4040
import java.sql.Time;
4141
import java.sql.Timestamp;
42-
import java.sql.Wrapper;
4342
import java.util.ArrayList;
4443
import java.util.Calendar;
4544
import java.util.HashMap;
@@ -2279,7 +2278,7 @@ private void setInOutParamsOnServer() throws SQLException {
22792278
ClientPreparedStatement setPstmt = null;
22802279

22812280
try {
2282-
setPstmt = ((Wrapper) this.connection.clientPrepareStatement(queryBuf.toString())).unwrap(ClientPreparedStatement.class);
2281+
setPstmt = this.connection.clientPrepareStatement(queryBuf.toString()).unwrap(ClientPreparedStatement.class);
22832282
setPstmt.getQueryBindings().setFromBindValue(0, ((PreparedQuery) this.query).getQueryBindings().getBindValues()[inParamInfo.index]);
22842283
setPstmt.executeUpdate();
22852284
} finally {

src/test/java/testsuite/regression/CallableStatementRegressionTest.java

+11-5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.lang.reflect.Method;
3434
import java.sql.CallableStatement;
3535
import java.sql.Connection;
36+
import java.sql.DatabaseMetaData;
3637
import java.sql.ParameterMetaData;
3738
import java.sql.PreparedStatement;
3839
import java.sql.ResultSetMetaData;
@@ -281,7 +282,7 @@ public void testBug9682() throws Exception {
281282
}
282283

283284
/**
284-
* Tests fix forBUG#10310 - Driver doesn't support {?=CALL(...)} for calling stored functions.
285+
* Tests fix for BUG#10310 - Driver doesn't support {?=CALL(...)} for calling stored functions.
285286
* This involved adding support for function retrieval to DatabaseMetaData.getProcedures() and getProcedureColumns() as well.
286287
*
287288
* @throws Exception
@@ -411,9 +412,7 @@ public void testBug10310() throws Exception {
411412
@Test
412413
public void testBug12417() throws Exception {
413414
if (isServerRunningOnWindows()) {
414-
415415
createProcedure("testBug12417", "()\nBEGIN\nSELECT 1;end\n");
416-
417416
Connection ucCatalogConn = null;
418417

419418
try {
@@ -428,6 +427,11 @@ public void testBug12417() throws Exception {
428427
}
429428
}
430429

430+
/**
431+
* Tests fix for Bug#15121 - a faulty procedure is executed but no exception is thrown.
432+
*
433+
* @throws Exception
434+
*/
431435
@Test
432436
public void testBug15121() throws Exception {
433437
createProcedure("p_testBug15121", "()\nBEGIN\nSELECT * from idonotexist;\nEND");
@@ -438,15 +442,17 @@ public void testBug15121() throws Exception {
438442
props.setProperty(PropertyKey.DBNAME.getKeyName(), "");
439443

440444
Connection noDbConn = getConnectionWithProps(props);
445+
DatabaseMetaData dbmd = noDbConn.getMetaData();
441446

442447
StringBuilder queryBuf = new StringBuilder("{call ");
443-
String quotedId = this.conn.getMetaData().getIdentifierQuoteString();
448+
String quotedId = dbmd.getIdentifierQuoteString();
444449
queryBuf.append(quotedId);
445450
queryBuf.append(this.conn.getCatalog());
446451
queryBuf.append(quotedId);
447452
queryBuf.append(".p_testBug15121()}");
448453

449-
assertThrows(SQLException.class, "Table '" + this.conn.getCatalog() + ".idonotexist' doesn't exist", () -> {
454+
String db = dbmd.storesLowerCaseIdentifiers() ? this.conn.getCatalog().toLowerCase() : this.conn.getCatalog();
455+
assertThrows(SQLException.class, "Table '" + db + ".idonotexist' doesn't exist", () -> {
450456
noDbConn.prepareCall(queryBuf.toString()).execute();
451457
return null;
452458
});

src/test/java/testsuite/regression/CharsetRegressionTest.java

+7-15
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import com.mysql.cj.conf.PropertyDefinitions.SslMode;
5555
import com.mysql.cj.conf.PropertyKey;
5656
import com.mysql.cj.exceptions.ExceptionFactory;
57-
import com.mysql.cj.exceptions.MysqlErrorNumbers;
5857
import com.mysql.cj.interceptors.QueryInterceptor;
5958
import com.mysql.cj.jdbc.JdbcConnection;
6059
import com.mysql.cj.log.Log;
@@ -312,9 +311,12 @@ public void testBug64205() throws Exception {
312311
Properties props = getPropertiesFromTestsuiteUrl();
313312
String dbname = props.getProperty(PropertyKey.DBNAME.getKeyName());
314313
if (dbname == null) {
315-
assertTrue(false, "No database selected");
314+
fail("No database selected");
316315
}
317316

317+
boolean lowerCaseIds = this.conn.getMetaData().storesLowerCaseIdentifiers();
318+
String expectedDbName = lowerCaseIds ? dbname.toLowerCase() : dbname;
319+
318320
props = new Properties();
319321
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
320322
props.setProperty(PropertyKey.characterEncoding.getKeyName(), "EUC_JP");
@@ -328,10 +330,7 @@ public void testBug64205() throws Exception {
328330
testRs = testSt.executeQuery("SELECT * FROM `" + dbname + "`.`\u307b\u3052\u307b\u3052`");
329331
} catch (SQLException e1) {
330332
if (e1.getClass().getName().endsWith("SQLSyntaxErrorException")) {
331-
assertEquals("Table '" + dbname + ".\u307B\u3052\u307b\u3052' doesn't exist", e1.getMessage());
332-
} else if (e1.getErrorCode() == MysqlErrorNumbers.ER_FILE_NOT_FOUND) {
333-
// this could happen on Windows with 5.5 and 5.6 servers where BUG#14642248 exists
334-
assertTrue(e1.getMessage().contains("Can't find file"));
333+
assertEquals("Table '" + expectedDbName + ".\u307B\u3052\u307b\u3052' doesn't exist", e1.getMessage());
335334
} else {
336335
throw e1;
337336
}
@@ -347,12 +346,8 @@ public void testBug64205() throws Exception {
347346
testRs = testSt.executeQuery("SELECT * FROM `" + dbname + "`.`\u307b\u3052\u307b\u3052`");
348347
} catch (SQLException e2) {
349348
if (e2.getClass().getName().endsWith("SQLSyntaxErrorException")) {
350-
assertEquals("\u0422\u0430\u0431\u043b\u0438\u0446\u0430 '" + dbname
349+
assertEquals("\u0422\u0430\u0431\u043b\u0438\u0446\u0430 '" + expectedDbName
351350
+ ".\u307b\u3052\u307b\u3052' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442", e2.getMessage());
352-
} else if (e2.getErrorCode() == MysqlErrorNumbers.ER_FILE_NOT_FOUND) {
353-
// this could happen on Windows with 5.5 and 5.6 servers where BUG#14642248 exists
354-
assertTrue(e2.getMessage().indexOf("\u0444\u0430\u0439\u043b") > -1,
355-
"File not found error message should be russian but is this one: " + e2.getMessage());
356351
} else {
357352
throw e2;
358353
}
@@ -380,10 +375,7 @@ public void testBug64205() throws Exception {
380375
fail("Exception should be thrown for attemping to query non-existing table");
381376
} catch (SQLException e1) {
382377
if (e1.getClass().getName().endsWith("SQLSyntaxErrorException")) {
383-
assertEquals("Table '" + dbname + ".\u307B\u3052\u307b\u3052' doesn't exist", e1.getMessage());
384-
} else if (e1.getErrorCode() == MysqlErrorNumbers.ER_FILE_NOT_FOUND) {
385-
// this could happen on Windows with 5.5 and 5.6 servers where BUG#14642248 exists
386-
assertTrue(e1.getMessage().contains("Can't find file"));
378+
assertEquals("Table '" + expectedDbName + ".\u307B\u3052\u307b\u3052' doesn't exist", e1.getMessage());
387379
} else {
388380
throw e1;
389381
}

0 commit comments

Comments
 (0)