changeset 736:f317b37bad30

In MonetCallableStatement constructor skip calling removeEscapes() when the connected server supports ODBC/JDBC escape sequence syntax.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 16 Feb 2023 20:35:09 +0100 (2023-02-16)
parents 3dd0d43014e8
children f03c1e47d819
files src/main/java/org/monetdb/jdbc/MonetCallableStatement.java src/main/java/org/monetdb/jdbc/MonetConnection.java src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
diffstat 3 files changed, 47 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/monetdb/jdbc/MonetCallableStatement.java
+++ b/src/main/java/org/monetdb/jdbc/MonetCallableStatement.java
@@ -35,26 +35,31 @@ import java.util.Map;
  * A {@link CallableStatement} suitable for the MonetDB database.
  *
  * The interface used to execute SQL stored procedures.
- * The JDBC API provides a stored procedure SQL escape syntax that allows stored procedures to be called in a standard way for all RDBMSs.
- * This escape syntax has one form that includes a result parameter (MonetDB does not support this) and one that does not.
- * If used, the result parameter must be registered as an OUT parameter (MonetDB does not support this).
- * The other parameters can be used for input, output or both. Parameters are referred to sequentially, by number, with the first parameter being 1.
- *
- *  { call procedure-name [ (arg1, arg2, ...) ] }
- *  { ?= call procedure-name [ (arg1, arg2, ...) ] }
+ * The JDBC API provides a stored procedure SQL escape syntax that allows
+ * stored procedures to be called in a standard way for all RDBMSs.
+ * This escape syntax has one form that includes a result parameter (MonetDB
+ * does not support this) and one that does not. If used, the result parameter
+ * must be registered as an OUT parameter (MonetDB does not support this).
+ * The other parameters can be used for input, output or both.
+ * Parameters are referred to sequentially, by number, with the first parameter being 1.
+ *  {?= call &lt;procedure-name&gt; [ (&lt;arg1&gt;, &lt;arg2&gt;, ...) ] }
+ *  {call &lt;procedure-name&gt; [ (&lt;arg1&gt;, &lt;arg2&gt;, ...) ] }
  *
  * IN parameter values are set using the set methods inherited from PreparedStatement.
  * The type of all OUT parameters must be registered prior to executing the stored procedure;
  * their values are retrieved after execution via the get methods provided here.
- * <b>Note</b>: MonetDB does not support OUT or INOUT parameters. Only input parameters are supported.
+ * <b>Note</b>: MonetDB does NOT support OUT or INOUT parameters. Only IN parameters are supported.
  *
  * A CallableStatement can return one ResultSet object or multiple ResultSet objects.
  * Multiple ResultSet objects are handled using operations inherited from Statement.
  *
- * For maximum portability, a call's ResultSet objects and update counts should be processed prior to getting the values of output parameters.
+ * For maximum portability, a call's ResultSet objects and update counts
+ * should be processed prior to getting the values of output parameters.
  *
- * This implementation of the CallableStatement interface reuses the implementation of MonetPreparedStatement for
- * preparing the call statement, bind parameter values and execute the call, possibly multiple times with different parameter values.
+ * This implementation of the CallableStatement interface reuses the
+ * implementation of MonetPreparedStatement for preparing the call statement,
+ * bind parameter values and execute the call, possibly multiple times with
+ * different parameter values.
  *
  * Note: currently we can not implement:
  * - all getXyz(parameterIndex/parameterName, ...) methods
@@ -64,7 +69,7 @@ import java.util.Map;
  *</pre>
  *
  * @author Martin van Dinther
- * @version 1.1
+ * @version 1.2
  */
 
 public final class MonetCallableStatement
@@ -82,9 +87,9 @@ public final class MonetCallableStatemen
 	 * @param resultSetHoldability holdability of ResultSet to produce
 	 * @param callQuery - an SQL CALL statement that may contain one or more '?' parameter placeholders.
 	 *	Typically this statement is specified using JDBC call escape syntax:
-	 *	{ call procedure_name [(?,?, ...)] }
+	 *	{ call &lt;procedure_name&gt; [(?,?, ...)] }
 	 *	or
-	 *	{ ?= call procedure_name [(?,?, ...)] }
+	 *	{ ?= call &lt;procedure_name&gt; [(?,?, ...)] }
 	 * @throws SQLException if an error occurs during creation
 	 * @throws IllegalArgumentException is one of the arguments is null or empty
 	 */
@@ -101,11 +106,12 @@ public final class MonetCallableStatemen
 			resultSetType,
 			resultSetConcurrency,
 			resultSetHoldability,
-			removeEscapes(callQuery)
+			connection.supportsEscapeSequenceSyntax() ? callQuery : removeEscapes(callQuery)
 		);
 	}
 
-	/** parse call query string on
+	/**
+	 * Parse call query string on
 	 *  { [?=] call &lt;procedure-name&gt; [(&lt;arg1&gt;,&lt;arg2&gt;, ...)] }
 	 * and remove the JDBC escapes pairs: { and }
 	 *
--- a/src/main/java/org/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java
@@ -2055,6 +2055,25 @@ public class MonetConnection
 		return databaseMinorVersion;
 	}
 
+	/**
+	 * Get whether the MonetDB SQL parser supports ODBC/JDBC escape sequence syntax.
+	 * See also: https://docs.oracle.com/javadb/10.6.2.1/ref/rrefjdbc1020262.html
+	 * It does when the server version is 11.46 or higher.
+	 * This method is called from: MonetDatabaseMetaData and MonetCallableStatement.
+	 *
+	 * @return true when the server supports ODBC/JDBC escape sequence syntax else false.
+	 */
+	boolean supportsEscapeSequenceSyntax() {
+		try {
+			if ((getDatabaseMajorVersion() == 11) && (getDatabaseMinorVersion() <= 45))
+				// older servers do not support it
+				return false;
+		} catch (SQLException e) {
+			return false;
+		}
+		return true;
+	}
+
 
 	// Internal cache for determining if system table sys.privilege_codes (new as of Jul2017 release) exists on connected server
 	private boolean queriedPrivilege_codesTable = false;
--- a/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
+++ b/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
@@ -30,6 +30,10 @@ public final class MonetDatabaseMetaData
 {
 	private final MonetConnection con;
 
+	/**
+	 * Constructor
+	 * @param parent the parent MonetConnection object.
+	 */
 	public MonetDatabaseMetaData(final MonetConnection parent) {
 		con = parent;
 	}
@@ -3865,13 +3869,10 @@ public final class MonetDatabaseMetaData
 	 * vendor functions using the stored procedure escape syntax.
 	 *
 	 * @return true if so; false otherwise
-	 * @throws SQLException if a database error occurs
 	 */
 	@Override
-	public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
-		if ((getDatabaseMajorVersion() == 11) && (getDatabaseMinorVersion() <= 45))
-			return false;
-		return true;
+	public boolean supportsStoredFunctionsUsingCallSyntax() {
+		return con.supportsEscapeSequenceSyntax();
 	}
 
 	/**