Skip to content

Commit 0d52b6c

Browse files
committed
misc - test addition
1 parent a6dae9f commit 0d52b6c

17 files changed

+224
-67
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ void readStreamingResults(
6969

7070
void closePrepare(PrepareResultPacket prepare) throws SQLException;
7171

72-
void transactionReplay(TransactionSaver transactionSaver) throws SQLException;
73-
7472
void abort(Executor executor) throws SQLException;
7573

7674
void close() throws SQLException;

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

Lines changed: 16 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
import java.sql.SQLException;
3232
import java.sql.SQLNonTransientConnectionException;
3333
import java.sql.SQLPermission;
34+
import java.time.Instant;
3435
import java.time.ZoneId;
36+
import java.time.ZoneOffset;
3537
import java.util.*;
3638
import java.util.concurrent.Executor;
3739
import java.util.concurrent.locks.ReentrantLock;
@@ -73,13 +75,14 @@ public class ClientImpl implements Client, AutoCloseable {
7375
private final Configuration conf;
7476
private final HostAddress hostAddress;
7577
private boolean closed = false;
76-
private ExceptionFactory exceptionFactory;
78+
protected ExceptionFactory exceptionFactory;
7779
protected PacketWriter writer;
7880
private PacketReader reader;
7981
private org.mariadb.jdbc.Statement streamStmt = null;
8082
private ClientMessage streamMsg = null;
8183
private int socketTimeout;
8284
private int waitTimeout;
85+
private boolean disablePipeline;
8386
protected Context context;
8487

8588
public ClientImpl(
@@ -90,6 +93,8 @@ public ClientImpl(
9093
this.lock = lock;
9194
this.hostAddress = hostAddress;
9295
this.exceptionFactory = new ExceptionFactory(conf, hostAddress);
96+
this.disablePipeline =
97+
Boolean.parseBoolean(conf.nonMappedOptions().getProperty("disablePipeline", "false"));
9398

9499
String host = hostAddress != null ? hostAddress.host : null;
95100
this.socketTimeout = conf.socketTimeout();
@@ -376,15 +381,17 @@ public String createSessionVariableQuery(String serverTz) {
376381
// force client timezone to connection to ensure result of now(), ...
377382
if (conf.timezone() != null && !"disable".equalsIgnoreCase(conf.timezone())) {
378383
ZoneId serverZoneId = ZoneId.of(serverTz).normalized();
379-
ZoneId clientZoneId =
380-
conf.timezone() == null
381-
? ZoneId.systemDefault().normalized()
382-
: ZoneId.of(conf.timezone()).normalized();
383-
384+
ZoneId clientZoneId = ZoneId.of(conf.timezone()).normalized();
384385
if (!serverZoneId.equals(clientZoneId)) {
385386
serverZoneId = ZoneId.of(serverTz, ZoneId.SHORT_IDS);
386387
if (!serverZoneId.equals(clientZoneId)) {
387-
sb.append(",time_zone='").append(conf.timezone()).append("'");
388+
// to ensure system not having saving time set, prefer fixed offset if possible
389+
if (clientZoneId.getRules().isFixedOffset()) {
390+
ZoneOffset zoneOffset = clientZoneId.getRules().getOffset(Instant.now());
391+
sb.append(",time_zone='").append(zoneOffset.getId()).append("'");
392+
} else {
393+
sb.append(",time_zone='").append(conf.timezone()).append("'");
394+
}
388395
}
389396
}
390397
}
@@ -460,15 +467,12 @@ public List<Completion> executePipeline(
460467

461468
int readCounter = 0;
462469
int[] responseMsg = new int[messages.length];
463-
boolean disablePipeline =
464-
Boolean.parseBoolean(conf.nonMappedOptions().getProperty("disablePipeline", "false"));
465-
466470
try {
467471
if (disablePipeline) {
468-
for (int i = 0; i < messages.length; i++) {
472+
for (readCounter = 0; readCounter < messages.length; readCounter++) {
469473
results.addAll(
470474
execute(
471-
messages[i],
475+
messages[readCounter],
472476
stmt,
473477
fetchSize,
474478
maxRows,
@@ -610,39 +614,6 @@ public void closePrepare(PrepareResultPacket prepare) throws SQLException {
610614
}
611615
}
612616

613-
public void transactionReplay(TransactionSaver transactionSaver) throws SQLException {
614-
List<RedoableClientMessage> buffers = transactionSaver.getBuffers();
615-
try {
616-
// replay all but last
617-
PrepareResultPacket prepare;
618-
for (RedoableClientMessage querySaver : buffers) {
619-
int responseNo;
620-
if (querySaver instanceof RedoableWithPrepareClientMessage) {
621-
// command is a prepare statement query
622-
// redo on new connection need to re-prepare query
623-
// and substitute statement id
624-
RedoableWithPrepareClientMessage redoable =
625-
((RedoableWithPrepareClientMessage) querySaver);
626-
String cmd = redoable.getCommand();
627-
prepare = context.getPrepareCache().get(cmd, redoable.prep());
628-
if (prepare == null) {
629-
PreparePacket preparePacket = new PreparePacket(cmd);
630-
sendQuery(preparePacket);
631-
prepare = (PrepareResultPacket) readPacket(preparePacket);
632-
}
633-
responseNo = querySaver.reEncode(writer, context, prepare);
634-
} else {
635-
responseNo = querySaver.reEncode(writer, context, null);
636-
}
637-
for (int j = 0; j < responseNo; j++) {
638-
readResponse(querySaver);
639-
}
640-
}
641-
} catch (IOException e) {
642-
throw exceptionFactory.create("Socket error during transaction replay", "08000", e);
643-
}
644-
}
645-
646617
public void readStreamingResults(
647618
List<Completion> completions,
648619
int fetchSize,

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.mariadb.jdbc.message.client.*;
3232
import org.mariadb.jdbc.message.server.Completion;
3333
import org.mariadb.jdbc.message.server.PrepareResultPacket;
34+
import org.mariadb.jdbc.util.exceptions.MaxAllowedPacketException;
3435

3536
public class ClientReplayImpl extends ClientImpl {
3637

@@ -48,11 +49,25 @@ public int sendQuery(ClientMessage message) throws SQLException {
4849
((RedoableClientMessage) message).ensureReplayable(context);
4950
return message.encode(writer, context);
5051
} catch (IOException ioException) {
52+
if (ioException instanceof MaxAllowedPacketException) {
53+
if (((MaxAllowedPacketException) ioException).isMustReconnect()) {
54+
destroySocket();
55+
throw exceptionFactory
56+
.withSql(message.description())
57+
.create(
58+
"Packet too big for current server max_allowed_packet value",
59+
"08000",
60+
ioException);
61+
}
62+
throw exceptionFactory
63+
.withSql(message.description())
64+
.create(
65+
"Packet too big for current server max_allowed_packet value", "HZ000", ioException);
66+
}
5167
destroySocket();
52-
throw context
53-
.getExceptionFactory()
54-
.withSql(message.description())
55-
.create("Socket error", "08000", ioException);
68+
throw exceptionFactory
69+
.withSql(message.description())
70+
.create("Socket error", "08000", ioException);
5671
}
5772
}
5873

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,7 @@ public static long initializeClientCapabilities(
179179
capabilities |= Capabilities.MARIADB_CLIENT_CACHE_METADATA;
180180
}
181181

182-
if ((serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) != 0
183-
&& configuration.useBulkStmts()) {
182+
if (configuration.useBulkStmts()) {
184183
capabilities |= Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS;
185184
}
186185

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ protected void executeTransactionReplay(Client oldCli) throws SQLException {
191191
// transaction replay
192192
if ((oldCli.getContext().getServerStatus() & ServerStatus.IN_TRANSACTION) > 0) {
193193
RedoContext ctx = (RedoContext) oldCli.getContext();
194-
currentClient.transactionReplay(ctx.getTransactionSaver());
194+
((ClientReplayImpl)currentClient).transactionReplay(ctx.getTransactionSaver());
195195
}
196196
}
197197

@@ -293,14 +293,15 @@ public List<Completion> execute(
293293
HostAddress hostAddress = currentClient.getHostAddress();
294294
reConnect();
295295

296+
296297
if (message instanceof QueryPacket && ((QueryPacket) message).isCommit()) {
297298
throw new SQLTransientConnectionException(
298-
String.format(
299-
"Driver has reconnect connection after a "
300-
+ "communications "
301-
+ "failure with %s during a COMMIT statement",
302-
hostAddress),
303-
"25S03");
299+
String.format(
300+
"Driver has reconnect connection after a "
301+
+ "communications "
302+
+ "failure with %s during a COMMIT statement",
303+
hostAddress),
304+
"25S03");
304305
}
305306

306307
if (message instanceof RedoableWithPrepareClientMessage) {
@@ -404,9 +405,6 @@ public void closePrepare(PrepareResultPacket prepare) throws SQLException {
404405
}
405406
}
406407

407-
@Override
408-
public void transactionReplay(TransactionSaver transactionSaver) {}
409-
410408
@Override
411409
public void abort(Executor executor) throws SQLException {
412410
if (closed) {

src/main/java/org/mariadb/jdbc/client/tls/MariaDbX509KeyManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public String[] getClientAliases(String keyType, Principal[] issuers) {
7575
@Override
7676
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
7777
List<String> accurateAlias = searchAccurateAliases(keyType, issuers);
78-
return accurateAlias.size() > 0 ? accurateAlias.get(0) : null;
78+
return accurateAlias == null || accurateAlias.isEmpty() ? null : accurateAlias.get(0);
7979
}
8080

8181
@Override

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ public void differentParameterType() throws SQLException {
113113
try (Connection con = createCon("&useServerPrepStmts&useBulkStmts&allowLocalInfile")) {
114114
differentParameterType(con);
115115
}
116+
try (Connection con = createCon("&useServerPrepStmts&useBulkStmts=false&disablePipeline=true")) {
117+
differentParameterType(con);
118+
}
119+
116120
}
117121

118122
public void differentParameterType(Connection con) throws SQLException {

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,18 @@ public void testConnection() throws Exception {
864864
}
865865
}
866866

867+
@Test
868+
public void testNoUseReadAheadInputConnection() throws Exception {
869+
try (Connection connection = createCon("useReadAheadInput=false")) {
870+
// must have succeed
871+
Statement stmt = connection.createStatement();
872+
ResultSet rs = stmt.executeQuery("SELECT * FROM mysql.user");
873+
int i = 0;
874+
while (rs.next()) i++;
875+
assertTrue(i > 0);
876+
}
877+
}
878+
867879
@Test
868880
public void useNoDatabase() throws SQLException {
869881
try (Connection con = createCon()) {
@@ -943,6 +955,15 @@ public void localSocket() throws Exception {
943955
assertTrue(rs.next());
944956
}
945957

958+
assertThrowsContains(
959+
SQLException.class,
960+
() ->
961+
DriverManager.getConnection(
962+
"jdbc:mariadb:///"
963+
+ sharedConn.getCatalog()
964+
+ "?user=testSocket&password=MySup5%rPassw@ord&localSocket=/wrongPath"),
965+
"Socket fail to connect to host");
966+
946967
if (haveSsl()) {
947968
String serverCertPath = SslTest.retrieveCertificatePath();
948969
if (serverCertPath != null) {
@@ -1019,4 +1040,29 @@ public void localSocketAddress() throws SQLException {
10191040
con.isValid(1);
10201041
}
10211042
}
1043+
1044+
@Test
1045+
public void setReadOnly() throws SQLException {
1046+
Connection con = createCon();
1047+
con.setReadOnly(true);
1048+
con.close();
1049+
assertThrowsContains(
1050+
SQLNonTransientConnectionException.class,
1051+
() -> con.setReadOnly(false),
1052+
"Connection is closed");
1053+
}
1054+
1055+
@Test
1056+
public void timezone() throws SQLException {
1057+
try (Connection con = createCon("timezone=GMT-8")) {
1058+
Statement statement = con.createStatement();
1059+
ResultSet rs = statement.executeQuery("SELECT @@time_zone");
1060+
rs.next();
1061+
assertEquals("-08:00", rs.getString(1));
1062+
}
1063+
1064+
try (Connection con = createCon("timezone=disable")) {
1065+
con.isValid(1);
1066+
}
1067+
}
10221068
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ public void testPre41ErrorFormat() throws Exception {
8787

8888
private void testPre41ErrorFormat(Connection con) throws Exception {
8989
Assumptions.assumeTrue(
90-
!"maxscale".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
90+
!"maxscale".equals(System.getenv("srv"))
91+
&& !"skysql".equals(System.getenv("srv"))
92+
&& !"skysql-ha".equals(System.getenv("srv")));
9193
SQLException exception = null;
9294
int max_connections;
9395
Statement stmt = con.createStatement();

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,56 @@ private void transactionReplay(boolean transactionReplay) throws SQLException {
100100
}
101101
}
102102

103+
@Test
104+
public void transactionReplayDuringCommit() throws SQLException {
105+
transactionReplayDuringCommit(true);
106+
transactionReplayDuringCommit(false);
107+
}
108+
109+
private void transactionReplayDuringCommit(boolean transactionReplay) throws SQLException {
110+
Assumptions.assumeTrue(
111+
!"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
112+
Statement st = sharedConn.createStatement();
113+
st.execute("DROP TABLE IF EXISTS transaction_failover");
114+
st.execute(
115+
"CREATE TABLE transaction_failover "
116+
+ "(id int not null primary key auto_increment, test varchar(20)) "
117+
+ "engine=innodb");
118+
119+
try (Connection con =
120+
createProxyCon(HaMode.SEQUENTIAL, "&transactionReplay=" + transactionReplay)) {
121+
assertEquals(Connection.TRANSACTION_REPEATABLE_READ, con.getTransactionIsolation());
122+
con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
123+
final Statement stmt = con.createStatement();
124+
con.setNetworkTimeout(Runnable::run, 200);
125+
long threadId = con.getContext().getThreadId();
126+
127+
stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test0')");
128+
con.setAutoCommit(false);
129+
stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test1')");
130+
stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test2')");
131+
proxy.restart(300);
132+
if (transactionReplay) {
133+
assertThrowsContains(SQLTransientConnectionException.class, () -> con.commit(), "Driver has reconnect connection after a communications failure");
134+
135+
ResultSet rs = stmt.executeQuery("SELECT * FROM transaction_failover");
136+
for (int i = 0; i < 1; i++) {
137+
assertTrue(rs.next());
138+
assertEquals("test" + i, rs.getString("test"));
139+
}
140+
141+
Assertions.assertTrue(con.getContext().getThreadId() != threadId);
142+
assertFalse(con.getAutoCommit());
143+
assertEquals(Connection.TRANSACTION_READ_UNCOMMITTED, con.getTransactionIsolation());
144+
} else {
145+
assertThrowsContains(
146+
SQLTransientConnectionException.class,
147+
() -> con.commit(),
148+
"In progress transaction was lost");
149+
}
150+
}
151+
}
152+
103153
@Test
104154
public void transactionReplayPreparedStatement() throws Exception {
105155
Assumptions.assumeTrue(

0 commit comments

Comments
 (0)