diff --git a/src/main/java/org/mariadb/jdbc/ClientPreparedStatement.java b/src/main/java/org/mariadb/jdbc/ClientPreparedStatement.java
index 12b66df0d..452edb1e3 100644
--- a/src/main/java/org/mariadb/jdbc/ClientPreparedStatement.java
+++ b/src/main/java/org/mariadb/jdbc/ClientPreparedStatement.java
@@ -251,9 +251,8 @@ public ResultSet executeQuery() throws SQLException {
if (currResult instanceof Result) {
return (Result) currResult;
}
- if (Boolean.parseBoolean(
- con.getContext().getConf().nonMappedOptions().getProperty("permitNoResults", "false"))) {
- // for compatibility with pre 3.4.0 version
+
+ if (con.getContext().getConf().permitNoResults()) {
return new CompleteResult(
new ColumnDecoder[0], new byte[0][], con.getContext(), resultSetType);
}
diff --git a/src/main/java/org/mariadb/jdbc/Configuration.java b/src/main/java/org/mariadb/jdbc/Configuration.java
index 6c9035245..06c6fb6e1 100644
--- a/src/main/java/org/mariadb/jdbc/Configuration.java
+++ b/src/main/java/org/mariadb/jdbc/Configuration.java
@@ -118,6 +118,7 @@ public class Configuration {
private String restrictedAuth;
private String initSql;
private boolean pinGlobalTxToPhysicalConnection;
+ private boolean permitNoResults;
// socket
private String socketFactory;
@@ -386,6 +387,7 @@ private void initializeDatabaseConfig(Builder builder) {
this.permitRedirect = builder.permitRedirect == null || builder.permitRedirect;
this.pinGlobalTxToPhysicalConnection =
builder.pinGlobalTxToPhysicalConnection != null && builder.pinGlobalTxToPhysicalConnection;
+ this.permitNoResults = builder.permitNoResults == null || builder.permitNoResults;
this.blankTableNameMeta = builder.blankTableNameMeta != null && builder.blankTableNameMeta;
this.disconnectOnExpiredPasswords =
builder.disconnectOnExpiredPasswords == null || builder.disconnectOnExpiredPasswords;
@@ -554,6 +556,7 @@ public Builder toBuilder() {
.jdbcCompliantTruncation(this.jdbcCompliantTruncation)
.permitRedirect(this.permitRedirect)
.pinGlobalTxToPhysicalConnection(this.pinGlobalTxToPhysicalConnection)
+ .permitNoResults(this.permitNoResults)
.transactionIsolation(
transactionIsolation == null ? null : this.transactionIsolation.getValue())
.defaultFetchSize(this.defaultFetchSize)
@@ -1969,6 +1972,19 @@ public boolean pinGlobalTxToPhysicalConnection() {
return pinGlobalTxToPhysicalConnection;
}
+ /**
+ * Indicate if Statement/PreparedStatement.executeQuery for command that produce no result will
+ * return an exception or just an empty result-set
+ *
+ *
When enabled, command not returning no data will end returning an empty result-set When
+ * disabled, command not returning no data will end throwing an exception
+ *
+ * @return permitNoResults
+ */
+ public boolean permitNoResults() {
+ return permitNoResults;
+ }
+
/**
* On deadlock exception, must driver execute additional commands to show innodb status in error
* description.
@@ -2287,6 +2303,7 @@ public static final class Builder implements Cloneable {
private Boolean jdbcCompliantTruncation;
private Boolean permitRedirect;
private Boolean pinGlobalTxToPhysicalConnection;
+ private Boolean permitNoResults;
private Integer defaultFetchSize;
private Integer maxQuerySizeToLog;
private Integer maxAllowedPacket;
@@ -3240,6 +3257,20 @@ public Builder pinGlobalTxToPhysicalConnection(Boolean pinGlobalTxToPhysicalConn
return this;
}
+ /**
+ * Indicate if Statement/PreparedStatement.executeQuery for command that produce no result will
+ * return an exception or just an empty result-set When enabled, command not returning no data
+ * will end returning an empty result-set When disabled, command not returning no data will end
+ * throwing an exception
+ *
+ * @param permitNoResults force reuse of same connection
+ * @return this {@link Builder}
+ */
+ public Builder permitNoResults(Boolean permitNoResults) {
+ this.permitNoResults = permitNoResults;
+ return this;
+ }
+
/**
* On dead-lock exception must add innodb status in exception error message. If enabled, an
* additional command will be done to retrieve innodb status when dead-lock occurs.
diff --git a/src/main/java/org/mariadb/jdbc/DatabaseMetaData.java b/src/main/java/org/mariadb/jdbc/DatabaseMetaData.java
index 18a7e662a..ca57e5e70 100644
--- a/src/main/java/org/mariadb/jdbc/DatabaseMetaData.java
+++ b/src/main/java/org/mariadb/jdbc/DatabaseMetaData.java
@@ -3645,7 +3645,7 @@ public ResultSet getTypeInfo() {
String[][] data = baseData;
if (connection.getContext().getVersion().isMariaDBServer()
&& connection.getContext().getVersion().versionGreaterOrEqual(10, 7, 0)) {
- List datalist = new ArrayList<>(Arrays.asList(baseData));
+ List datalist = new ArrayList<>(Arrays.asList(baseData));
datalist.add(
new String[] {
diff --git a/src/main/java/org/mariadb/jdbc/ServerPreparedStatement.java b/src/main/java/org/mariadb/jdbc/ServerPreparedStatement.java
index e80d63018..7bf18274c 100644
--- a/src/main/java/org/mariadb/jdbc/ServerPreparedStatement.java
+++ b/src/main/java/org/mariadb/jdbc/ServerPreparedStatement.java
@@ -379,9 +379,8 @@ public ResultSet executeQuery() throws SQLException {
if ((currResult instanceof Result)) {
return (Result) currResult;
}
- if (Boolean.parseBoolean(
- con.getContext().getConf().nonMappedOptions().getProperty("permitNoResults", "false"))) {
- // for compatibility with pre 3.4.0 version
+
+ if (con.getContext().getConf().permitNoResults()) {
return new CompleteResult(
new ColumnDecoder[0], new byte[0][], con.getContext(), resultSetType);
}
diff --git a/src/main/java/org/mariadb/jdbc/Statement.java b/src/main/java/org/mariadb/jdbc/Statement.java
index 3e7de2d63..8c4264a7b 100644
--- a/src/main/java/org/mariadb/jdbc/Statement.java
+++ b/src/main/java/org/mariadb/jdbc/Statement.java
@@ -139,9 +139,8 @@ public ResultSet executeQuery(String sql) throws SQLException {
if (currResult instanceof Result) {
return (Result) currResult;
}
- if (Boolean.parseBoolean(
- con.getContext().getConf().nonMappedOptions().getProperty("permitNoResults", "false"))) {
- // for compatibility with pre 3.4.0 version
+
+ if (con.getContext().getConf().permitNoResults()) {
return new CompleteResult(
new ColumnDecoder[0], new byte[0][], con.getContext(), resultSetType);
}
diff --git a/src/main/resources/driver.properties b/src/main/resources/driver.properties
index ee3e4a0c5..979bf09f8 100644
--- a/src/main/resources/driver.properties
+++ b/src/main/resources/driver.properties
@@ -86,3 +86,4 @@ connectionCollation=indicate what utf8mb4 collation to use. if not set, server d
trustStore=File path of the trustStore file (similar to java System property \"javax.net.ssl.trustStore\". (legacy alias trustCertificateKeyStoreUrl). Use the specified file for trusted root certificates. When set, overrides serverSslCert.
trustStorePassword=Password for the trusted root certificate file (similar to java System property \"javax.net.ssl.trustStorePassword\").(legacy alias trustCertificateKeyStorePassword).
disconnectOnExpiredPasswords=On connection creation, indicate behavior when password is expired. When true (default) throw an expired password error. When false, connection succeed in "sandbox" mode, only queries related to password change are allowed.
+permitNoResults=Indicate if Statement/PreparedStatement.executeQuery for command that produce no result will return an exception or just an empty result-set. When enabled, command not returning no data will end returning an empty result-set, when disabled, command not returning no data will end throwing an exception
diff --git a/src/test/java/org/mariadb/jdbc/integration/ProcedureTest.java b/src/test/java/org/mariadb/jdbc/integration/ProcedureTest.java
index 96899e39e..d09d7df30 100644
--- a/src/test/java/org/mariadb/jdbc/integration/ProcedureTest.java
+++ b/src/test/java/org/mariadb/jdbc/integration/ProcedureTest.java
@@ -50,12 +50,13 @@ public void settingParameterBeforeOutRegistration() throws SQLException {
cstmt.setLong(1, 43L);
cstmt.executeUpdate();
assertEquals(86, cstmt.getLong(1));
- Common.assertThrowsContains(
- SQLException.class,
- () -> cstmt.executeQuery(),
- "PrepareStatement.executeQuery() command does NOT return a result-set as expected");
+ cstmt.setLong(1, 44L);
+ cstmt.execute();
+ assertEquals(88, cstmt.getLong(1));
+ ResultSet rs = cstmt.executeQuery();
+ assertFalse(rs.next());
}
- try (Connection con = createCon("&permitNoResults=true")) {
+ try (Connection con = createCon("&permitNoResults=false")) {
try (CallableStatement cstmt = con.prepareCall("{ CALL multiply_by_2(?) }")) {
cstmt.setLong(1, 42L);
cstmt.registerOutParameter(1, Types.NUMERIC);
@@ -64,11 +65,10 @@ public void settingParameterBeforeOutRegistration() throws SQLException {
cstmt.setLong(1, 43L);
cstmt.executeUpdate();
assertEquals(86, cstmt.getLong(1));
- cstmt.setLong(1, 44L);
- cstmt.execute();
- assertEquals(88, cstmt.getLong(1));
- ResultSet rs = cstmt.executeQuery();
- assertFalse(rs.next());
+ Common.assertThrowsContains(
+ SQLException.class,
+ () -> cstmt.executeQuery(),
+ "PrepareStatement.executeQuery() command does NOT return a result-set as expected");
}
}
}
diff --git a/src/test/java/org/mariadb/jdbc/integration/StatementTest.java b/src/test/java/org/mariadb/jdbc/integration/StatementTest.java
index 76f74ccc1..4fd7d2c3f 100644
--- a/src/test/java/org/mariadb/jdbc/integration/StatementTest.java
+++ b/src/test/java/org/mariadb/jdbc/integration/StatementTest.java
@@ -75,25 +75,26 @@ public void ensureGetGeneratedKeysReturnsEmptyResult() throws SQLException {
@Test
public void ensureJdbcErrorWhenNoResultset() throws SQLException {
- Statement stmt = sharedConn.createStatement();
- stmt.execute("DO 1");
- assertThrowsContains(
- SQLException.class,
- () -> stmt.executeQuery("DO 1"),
- "Statement.executeQuery() command does NOT return a result-set as expected. Either use"
- + " Statement.execute(), Statement.executeUpdate(), or correct command");
- stmt.execute("DO 1");
- try (PreparedStatement ps =
- sharedConn.prepareStatement("DO ?", Statement.RETURN_GENERATED_KEYS)) {
- ps.setInt(1, 1);
- ps.execute();
+ try (Connection con = createCon("&permitNoResults=false")) {
+ Statement stmt = con.createStatement();
+ stmt.execute("DO 1");
assertThrowsContains(
SQLException.class,
- () -> ps.executeQuery(),
- "PrepareStatement.executeQuery() command does NOT return a result-set as expected. Either"
- + " use PrepareStatement.execute(), PrepareStatement.executeUpdate(), or correct"
- + " command");
- ps.execute();
+ () -> stmt.executeQuery("DO 1"),
+ "Statement.executeQuery() command does NOT return a result-set as expected. Either use"
+ + " Statement.execute(), Statement.executeUpdate(), or correct command");
+ stmt.execute("DO 1");
+ try (PreparedStatement ps = con.prepareStatement("DO ?", Statement.RETURN_GENERATED_KEYS)) {
+ ps.setInt(1, 1);
+ ps.execute();
+ assertThrowsContains(
+ SQLException.class,
+ () -> ps.executeQuery(),
+ "PrepareStatement.executeQuery() command does NOT return a result-set as expected."
+ + " Either use PrepareStatement.execute(), PrepareStatement.executeUpdate(), or"
+ + " correct command");
+ ps.execute();
+ }
}
try (Connection con = createCon("&permitNoResults=true")) {
try (PreparedStatement ps = con.prepareStatement("DO ?", Statement.RETURN_GENERATED_KEYS)) {
@@ -104,17 +105,18 @@ public void ensureJdbcErrorWhenNoResultset() throws SQLException {
ps.execute();
}
}
- try (PreparedStatement ps =
- sharedConnBinary.prepareStatement("DO ?", Statement.RETURN_GENERATED_KEYS)) {
- ps.setInt(1, 1);
- ps.execute();
- assertThrowsContains(
- SQLException.class,
- () -> ps.executeQuery(),
- "PrepareStatement.executeQuery() command does NOT return a result-set as expected. Either"
- + " use PrepareStatement.execute(), PrepareStatement.executeUpdate(), or correct"
- + " command");
- ps.execute();
+ try (Connection con = createCon("permitNoResults=false&useServerPrepStmts=true")) {
+ try (PreparedStatement ps = con.prepareStatement("DO ?", Statement.RETURN_GENERATED_KEYS)) {
+ ps.setInt(1, 1);
+ ps.execute();
+ assertThrowsContains(
+ SQLException.class,
+ () -> ps.executeQuery(),
+ "PrepareStatement.executeQuery() command does NOT return a result-set as expected."
+ + " Either use PrepareStatement.execute(), PrepareStatement.executeUpdate(), or"
+ + " correct command");
+ ps.execute();
+ }
}
try (Connection con = createCon("permitNoResults=true&useServerPrepStmts=true")) {
try (PreparedStatement ps = con.prepareStatement("DO ?", Statement.RETURN_GENERATED_KEYS)) {