Skip to content

Commit 65c2f1e

Browse files
committed
[CONJ-1111] ensure using same ip in place of DNS when creating a connection to kill running query
1 parent e41f024 commit 65c2f1e

File tree

6 files changed

+96
-14
lines changed

6 files changed

+96
-14
lines changed

src/main/java/org/mariadb/jdbc/Connection.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,15 @@ public void setPoolConnection(MariaDbPoolConnection poolConnection) {
9494
* @throws SQLException never thrown
9595
*/
9696
public void cancelCurrentQuery() throws SQLException {
97-
try (Client cli =
98-
new StandardClient(conf, client.getHostAddress(), new ReentrantLock(), true)) {
97+
// prefer relying on IP compare to DNS if not using Unix socket/PIPE
98+
String currentIp = client.getSocketIp();
99+
HostAddress hostAddress =
100+
currentIp == null
101+
? client.getHostAddress()
102+
: HostAddress.from(
103+
currentIp, client.getHostAddress().port, client.getHostAddress().primary);
104+
105+
try (Client cli = new StandardClient(conf, hostAddress, new ReentrantLock(), true)) {
99106
cli.execute(new QueryPacket("KILL QUERY " + client.getContext().getThreadId()), false);
100107
}
101108
}

src/main/java/org/mariadb/jdbc/client/Client.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,11 @@ void readStreamingResults(
190190
* @return connection host
191191
*/
192192
HostAddress getHostAddress();
193+
194+
/**
195+
* Get current socket IP or null (for Pipe / unix socket)
196+
*
197+
* @return Socket current IP
198+
*/
199+
String getSocketIp();
193200
}

src/main/java/org/mariadb/jdbc/client/impl/MultiPrimaryClient.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,11 @@ public HostAddress getHostAddress() {
537537
return currentClient.getHostAddress();
538538
}
539539

540+
@Override
541+
public String getSocketIp() {
542+
return currentClient.getSocketIp();
543+
}
544+
540545
public boolean isPrimary() {
541546
return true;
542547
}

src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,12 @@ public void close() {
10231023
}
10241024
}
10251025

1026+
public String getSocketIp() {
1027+
return this.socket.getInetAddress() == null
1028+
? null
1029+
: this.socket.getInetAddress().getHostAddress();
1030+
}
1031+
10261032
public boolean isPrimary() {
10271033
return hostAddress.primary;
10281034
}

src/test/java/org/mariadb/jdbc/integration/ConnectionTest.java

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import java.util.Timer;
1515
import java.util.TimerTask;
1616
import java.util.concurrent.Executor;
17+
import java.util.concurrent.ExecutorService;
18+
import java.util.concurrent.Executors;
1719
import org.junit.jupiter.api.*;
1820
import org.mariadb.jdbc.*;
1921
import org.mariadb.jdbc.integration.util.SocketFactoryBasicTest;
@@ -937,7 +939,10 @@ public void useNoDatabase() throws SQLException {
937939
public void windowsNamedPipe() throws SQLException {
938940
ResultSet rs = null;
939941
try {
940-
rs = sharedConn.createStatement().executeQuery("select @@named_pipe,@@socket,@@named_pipe_full_access_group");
942+
rs =
943+
sharedConn
944+
.createStatement()
945+
.executeQuery("select @@named_pipe,@@socket,@@named_pipe_full_access_group");
941946
} catch (SQLException sqle) {
942947
// on non Windows system, named_pipe doesn't exist.
943948
}
@@ -956,15 +961,14 @@ public void windowsNamedPipe() throws SQLException {
956961
// skip test if no namedPipeName was obtained because then we do not use a socket connection
957962
Assumptions.assumeTrue(namedPipeName != null);
958963
String connUrl =
959-
password == null || password.isEmpty()
960-
? String.format(
961-
"jdbc:mariadb:///%s?user=%s%s", database, user, defaultOther)
962-
: String.format(
963-
"jdbc:mariadb:///%s?user=%s&password=%s%s",
964-
database, user, password, defaultOther);
964+
password == null || password.isEmpty()
965+
? String.format("jdbc:mariadb:///%s?user=%s%s", database, user, defaultOther)
966+
: String.format(
967+
"jdbc:mariadb:///%s?user=%s&password=%s%s",
968+
database, user, password, defaultOther);
965969

966-
967-
try (Connection connection = DriverManager.getConnection(connUrl + "&pipe=" + namedPipeName)) {
970+
try (Connection connection =
971+
DriverManager.getConnection(connUrl + "&pipe=" + namedPipeName)) {
968972
java.sql.Statement stmt = connection.createStatement();
969973
try (ResultSet rs2 = stmt.executeQuery("SELECT 1")) {
970974
assertTrue(rs2.next());
@@ -987,6 +991,60 @@ public void windowsNamedPipe() throws SQLException {
987991
}
988992
}
989993

994+
@Test
995+
public void windowsNamedPipeCancel() throws SQLException {
996+
Assumptions.assumeFalse(isMariaDBServer());
997+
ResultSet rs = null;
998+
try {
999+
rs =
1000+
sharedConn
1001+
.createStatement()
1002+
.executeQuery("select @@named_pipe,@@socket,@@named_pipe_full_access_group");
1003+
} catch (SQLException sqle) {
1004+
// on non Windows system, named_pipe doesn't exist.
1005+
}
1006+
if (rs != null) {
1007+
assertTrue(rs.next());
1008+
System.out.println("named_pipe:" + rs.getString(1));
1009+
Assumptions.assumeTrue(rs.getBoolean(1));
1010+
String namedPipeName = rs.getString(2);
1011+
System.out.println("namedPipeName:" + namedPipeName);
1012+
if (!isMariaDBServer() && minVersion(8, 0, 14)) {
1013+
String namedPipeFullAccess = rs.getString(3);
1014+
System.out.println("namedPipeFullAccess:" + namedPipeFullAccess);
1015+
Assumptions.assumeTrue(namedPipeFullAccess != null && !namedPipeFullAccess.isEmpty());
1016+
}
1017+
1018+
// skip test if no namedPipeName was obtained because then we do not use a socket connection
1019+
Assumptions.assumeTrue(namedPipeName != null);
1020+
String connUrl =
1021+
password == null || password.isEmpty()
1022+
? String.format("jdbc:mariadb:///%s?user=%s%s", database, user, defaultOther)
1023+
: String.format(
1024+
"jdbc:mariadb:///%s?user=%s&password=%s%s",
1025+
database, user, password, defaultOther);
1026+
1027+
try (Connection connection =
1028+
DriverManager.getConnection(connUrl + "&pipe=" + namedPipeName)) {
1029+
Statement stmt = connection.createStatement();
1030+
stmt.cancel(); // will do nothing
1031+
1032+
ExecutorService exec = Executors.newFixedThreadPool(1);
1033+
1034+
Common.assertThrowsContains(
1035+
SQLTimeoutException.class,
1036+
() -> {
1037+
exec.execute(new StatementTest.CancelThread(stmt));
1038+
stmt.execute(
1039+
"select * from information_schema.columns as c1, information_schema.tables, information_schema"
1040+
+ ".tables as t2");
1041+
exec.shutdown();
1042+
},
1043+
"Query execution was interrupted");
1044+
}
1045+
}
1046+
}
1047+
9901048
@Test
9911049
public void localSocket() throws Exception {
9921050
Assumptions.assumeTrue(

src/test/java/org/mariadb/jdbc/integration/StatementTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,7 @@ public void testWarnings() throws SQLException {
619619
@Test
620620
public void cancel() throws Exception {
621621
Assumptions.assumeTrue(
622-
isMariaDBServer()
623-
&& !"maxscale".equals(System.getenv("srv"))
622+
!"maxscale".equals(System.getenv("srv"))
624623
&& !"skysql".equals(System.getenv("srv"))
625624
&& !"skysql-ha".equals(System.getenv("srv"))
626625
&& !isXpand());
@@ -937,7 +936,7 @@ public void closeOnCompletion() throws SQLException {
937936
assertTrue(stmt.isClosed());
938937
}
939938

940-
private static class CancelThread implements Runnable {
939+
static class CancelThread implements Runnable {
941940

942941
private final java.sql.Statement stmt;
943942

0 commit comments

Comments
 (0)