changeset 650:849f99124e32

Correcting implementation of Statement.setQueryTimeout(int seconds). According to the webdocumentation the procedures sys.settimeout(query bigint) and sys.setquerytimeout(query int) expect a timeout in milliseconds but the JDBC method Statement.setQueryTimeout(int) gets a timeout in seconds. See https://www.monetdb.org/documentation-Jan2022/admin-guide/monitoring/session-procedures/ and https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#setQueryTimeout-int- So we need to multiply the int value by 1000 before calling the procedure.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 30 Jun 2022 18:40:52 +0200 (2022-06-30)
parents 060347aa81ea
children 3b6139d35057
files src/main/java/org/monetdb/jdbc/MonetConnection.java tests/JDBC_API_Tester.java
diffstat 2 files changed, 22 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java
@@ -1730,25 +1730,27 @@ public class MonetConnection
 	 * Utility method to call sys.setquerytimeout(int); procedure on the connected server.
 	 * It is called from: MonetConnection.isValid() and MonetStatement.internalExecute()
 	 */
-	void setQueryTimeout(final int millis) throws SQLException {
-		if (millis < 0)
-			throw new SQLException("query timeout milliseconds is less than zero", "M1M05");
+	void setQueryTimeout(final int seconds) throws SQLException {
+		if (seconds < 0)
+			throw new SQLException("query timeout seconds is less than zero", "M1M05");
 
 		checkNotClosed();
 		Statement st = null;
 		try {
 			final String callstmt;
-			// as of release Jun2020 (11.37.7) the function sys.settimeout(bigint) is deprecated and replaced by new sys.setquerytimeout(int)
+			final int msecs = (seconds <= 2147483) ? seconds * 1000 : seconds;	// prevent overflow of int
+
+			// as of release Jun2020 (11.37.7) the function sys.settimeout(msecs bigint) is deprecated and replaced by new sys.setquerytimeout(msecs int)
 			if ((getDatabaseMajorVersion() == 11) && (getDatabaseMinorVersion() < 37))
-				callstmt = "CALL sys.\"settimeout\"(" + millis + ")";
+				callstmt = "CALL sys.\"settimeout\"(" + msecs + ")";
 			else
-				callstmt = "CALL sys.\"setquerytimeout\"(" + millis + ")";
+				callstmt = "CALL sys.\"setquerytimeout\"(" + msecs + ")";
 			// for debug: System.out.println("Before: " + callstmt);
 			st = createStatement();
 			st.execute(callstmt);
 			// for debug: System.out.println("After : " + callstmt);
 
-			this.lastSetQueryTimeout = millis;
+			this.lastSetQueryTimeout = seconds;
 		}
 		/* do not catch SQLException here, as we want to know it when it fails */
 		finally {
--- a/tests/JDBC_API_Tester.java
+++ b/tests/JDBC_API_Tester.java
@@ -5129,7 +5129,7 @@ final public class JDBC_API_Tester {
 	private void BugSetQueryTimeout_Bug_3357() {
 		sb.setLength(0);	// clear the output log buffer
 
-		int originalQueryTimeout = 1;
+		int originalQueryTimeout = 0;
 		Statement st = null;
 		try {
 			st = con.createStatement();
@@ -5138,16 +5138,20 @@ final public class JDBC_API_Tester {
 
 			testTimeout_3357(st, 123);
 			testTimeout_3357(st, 123456);
-			testTimeout_3357(st, 2134567890);
+			testTimeout_3357(st, 2147483);
+			testTimeout_3357(st, 2147484);
+			testTimeout_3357(st, Integer.MAX_VALUE);
 			testTimeout_3357(st, 0);
 			testTimeout_3357(st, 10);
+			testTimeout_3357(st, 1);
 			testTimeout_3357(st, -1);	// to generate an SQLException as negative timeouts are invalid
 		} catch (SQLException se) {
-			sb.append("\n SQLException: setQueryTimeout(timeout_value) throws: ").append(se).append("\n");
+			sb.append("SQLException: setQueryTimeout(timeout_value) throws: ").append(se).append("\n");
 		}
 
 		// restore originalQueryTimeout
 		try {
+			sb.append("Restore original QueryTimeout = ").append(originalQueryTimeout).append("\n");
 			testTimeout_3357(st, originalQueryTimeout);
 		} catch (SQLException se) {
 			sb.append("setQueryTimeout(timeout_value) throws: ").append(se).append("\n");
@@ -5158,11 +5162,14 @@ final public class JDBC_API_Tester {
 				"original getQueryTimeout = 0\n" +
 				"setQueryTimeout = 123. getQueryTimeout = 123\n" +
 				"setQueryTimeout = 123456. getQueryTimeout = 123456\n" +
-				"setQueryTimeout = 2134567890. getQueryTimeout = 2134567890\n" +
+				"setQueryTimeout = 2147483. getQueryTimeout = 2147483\n" +
+				"setQueryTimeout = 2147484. getQueryTimeout = 2147484\n" +
+				"setQueryTimeout = 2147483647. getQueryTimeout = 2147483647\n" +
 				"setQueryTimeout = 0. getQueryTimeout = 0\n" +
 				"setQueryTimeout = 10. getQueryTimeout = 10\n" +
-				"setQueryTimeout = -1. \n" +
-				" SQLException: setQueryTimeout(timeout_value) throws: java.sql.SQLException: Illegal timeout value: -1\n" +
+				"setQueryTimeout = 1. getQueryTimeout = 1\n" +
+				"setQueryTimeout = -1. SQLException: setQueryTimeout(timeout_value) throws: java.sql.SQLException: Illegal timeout value: -1\n" +
+				"Restore original QueryTimeout = 0\n" +
 				"setQueryTimeout = 0. getQueryTimeout = 0\n");
 	}