changeset 277:4face9f42efc embedded

Merge with default.
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Thu, 18 Jul 2019 11:22:55 +0200 (2019-07-18)
parents 96057ee68017 (current diff) fab4e6165be9 (diff)
children 2ad7f42f141d
files build.xml example/MJDBCTest.java example/PreparedExample.java example/SQLImport.java release.txt src/main/java/nl/cwi/monetdb/client/JMonetDB.java src/main/java/nl/cwi/monetdb/client/JdbcClient.java src/main/java/nl/cwi/monetdb/jdbc/MonetBlob.java src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java src/main/java/nl/cwi/monetdb/jdbc/MonetDataSource.java src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in src/main/java/nl/cwi/monetdb/jdbc/MonetINET.java src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java src/main/java/nl/cwi/monetdb/jdbc/MonetSavepoint.java src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java src/main/java/nl/cwi/monetdb/jdbc/MonetURL.java src/main/java/nl/cwi/monetdb/mcl/connection/ControlCommands.java src/main/java/nl/cwi/monetdb/mcl/connection/IMonetDBLanguage.java src/main/java/nl/cwi/monetdb/mcl/connection/MCLException.java src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java src/main/java/nl/cwi/monetdb/mcl/connection/helpers/ChannelSecurity.java src/main/java/nl/cwi/monetdb/mcl/connection/helpers/GregorianCalendarParser.java src/main/java/nl/cwi/monetdb/mcl/connection/helpers/TimestampHelper.java src/main/java/nl/cwi/monetdb/mcl/connection/mapi/AbstractSocket.java src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiLanguage.java src/main/java/nl/cwi/monetdb/mcl/connection/mapi/OldMapiSocket.java src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/ProtocolException.java src/main/java/nl/cwi/monetdb/mcl/protocol/ServerResponses.java src/main/java/nl/cwi/monetdb/mcl/protocol/StarterHeaders.java src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiDataBlockResponse.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParserHelper.java src/main/java/nl/cwi/monetdb/mcl/responses/AbstractDataBlockResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/AutoCommitResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/IIncompleteResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/IResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/SchemaResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/UpdateResponse.java src/main/java/nl/cwi/monetdb/merovingian/Control.java src/main/java/nl/cwi/monetdb/merovingian/SabaothDB.java src/main/java/nl/cwi/monetdb/util/CmdLineOpts.java src/main/java/nl/cwi/monetdb/util/Exporter.java src/main/java/nl/cwi/monetdb/util/Extract.java src/main/java/nl/cwi/monetdb/util/SQLExporter.java src/main/java/nl/cwi/monetdb/util/SQLRestore.java src/main/java/nl/cwi/monetdb/util/XMLExporter.java tests/Bug_PrepStmtSetString_6382.java tests/SQLcopyinto.java tests/Test_Clargequery.java tests/Test_Cmanycon.java tests/Test_Int128.java tests/Test_PSmanycon.java tests/Test_PSmetadata.java tests/Test_PSsqldata.java tests/Test_PStimedate.java tests/Test_PStimezone.java tests/Test_PStypes.java tests/Test_Rbooleans.java tests/Test_Rmetadata.java tests/Test_Rsqldata.java tests/Test_Rtimedate.java tests/Test_Smoreresults.java tests/build.xml version.sh
diffstat 111 files changed, 1332 insertions(+), 398 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,26 @@
 # ChangeLog file for monetdb-java
 # This file is updated with Maddlog
 
+* Thu Mar 21 2019 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
+- Added implementation of java.sql.CallableStatement interface. Some standard
+  Java applications require this JDBC interface for executing SQL stored procedures.
+  This implementation resolves request: https://www.monetdb.org/bugzilla/show_bug.cgi?id=6402
+
+* Thu Mar  7 2019 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
+- Improved MonetDatabaseMetaData methods:
+  - getNumericFunctions(): it now includes functions: degrees, fuse, ms_round, ms_str, ms_trunc and radians.
+  - getStringFunctions(): it now includes function: position.
+  - supportsIntegrityEnhancementFacility() now returns false, as we do not enforce CHECK constraints yet.
+
+* Thu Feb  7 2019 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
+- Improved MonetDatabaseMetaData methods:
+  - getNumericFunctions(): it no longer lists aggregate functions: avg, prod and sum
+  - getSystemFunctions(): it no longer lists timedate function: extract
+  - getTimeDateFunctions(): it now also lists functions: date_trunc, epoch
+- Corrected MonetDatabaseMetaData method getTypeInfo() for result column
+  SEARCHABLE. It now returns DatabaseMetaData.typeSearchable for all
+  string data types including 'inet','json','url','uuid' and 'blob'.
+
 * Thu Sep 20 2018 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
 - Improved example program SQLcopyinto.java and moved it to tests directory
   for automatic testing.
--- a/SQLSTATEs
+++ b/SQLSTATEs
@@ -67,5 +67,5 @@ JDBC 4.1 defines the following SQLExcept
    null SQLTimeoutException
 
 See also: http://docs.oracle.com/javase/7/docs/api/java/sql/SQLException.html
-See also: https://en.wikibooks.org/wiki/Structured_Query_Language/SQLSTATE
+See also: https://en.wikipedia.org/wiki/SQLSTATE
 
--- a/build.xml
+++ b/build.xml
@@ -5,7 +5,7 @@ This Source Code Form is subject to the 
 License, v. 2.0.  If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
 -->
 
 <!--
--- a/example/MJDBCTest.java
+++ b/example/MJDBCTest.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
@@ -18,7 +18,7 @@ import java.sql.*;
 public class MJDBCTest {
 	public static void main(String[] args) throws Exception {
 		String MonetDB_JDBC_URL = "jdbc:monetdb://localhost:50000/demo";	// change host, port and databasename
-		Connection con;
+		Connection con = null;
 		try {
 			con = DriverManager.getConnection(MonetDB_JDBC_URL, "monetdb", "monetdb");
 		} catch (SQLException e) {
--- a/example/PreparedExample.java
+++ b/example/PreparedExample.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/example/SQLImport.java
+++ b/example/SQLImport.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
@@ -14,7 +14,7 @@ import java.io.*;
  * it's simpleness it only supports SQL queries which entirely are on one line.
  *
  * This program reads a file line by line, and feeds the line into a running
- * Mserver on the localhost. Upon error, the error is reported and the program
+ * Mserver5 on the localhost. Upon error, the error is reported and the program
  * continues reading and executing lines.
  * A very lousy way of implementing options is used to somewhat configure the
  * behaviour of the program in order to be a bit more verbose or commit after
@@ -37,11 +37,11 @@ public class SQLImport {
 		// open the file
 		BufferedReader fr = new BufferedReader(new FileReader(args[0]));
 
-		// request a connection suitable for Monet from the driver manager
+		// request a connection suitable for MonetDB from the driver manager
 		// note that the database specifier is currently not implemented, for
-		// Monet itself can't access multiple databases.
+		// MonetDB itself can't access multiple databases.
 		// turn on debugging
-		Connection con = DriverManager.getConnection("jdbc:monetdb://localhost/database?debug=true", "monetdb", "monetdb");
+		Connection con = DriverManager.getConnection("jdbc:monetdb://localhost/demo?debug=true", "monetdb", "monetdb");
 
 		boolean beVerbose = false;
 		if (args.length == 3) {
@@ -58,13 +58,15 @@ public class SQLImport {
 
 		String query;
 		for (int i = 1; (query = fr.readLine()) != null; i++) {
-			if (beVerbose) System.out.println(query);
+			if (beVerbose)
+				System.out.println(query);
 			try {
 				// execute the query, no matter what it is
 				stmt.execute(query);
 			} catch (SQLException e) {
 				System.out.println("Error on line " + i + ": " + e.getMessage());
-				if (!beVerbose) System.out.println(query);
+				if (!beVerbose)
+					System.out.println(query);
 			}
 		}
 
--- a/release.txt
+++ b/release.txt
@@ -55,11 +55,9 @@ Currently implemented JDBC 4.1 interface
   * java.sql.Driver
 
   * java.sql.Connection
-    The next features/methods are NOT implemented:
+    The next features/methods are NOT useable/supported:
     - createArrayOf, createNClob, createStruct, createSQLXML
     - createStatement with result set holdability
-    - prepareCall (CallableStatement is not supported)
-       see also: https://www.monetdb.org/bugzilla/show_bug.cgi?id=6402
     - prepareStatement with array of column indices or column names
     - setHoldability (close/hold cursors over commit is not configurable)
 
@@ -70,7 +68,7 @@ Currently implemented JDBC 4.1 interface
   * java.sql.DatabaseMetaData
 
   * java.sql.Statement
-    The next features/methods are NOT implemented:
+    The next features/methods are NOT useable/supported:
     - cancel (query execution cannot be terminated, once started)
        see also: https://www.monetdb.org/bugzilla/show_bug.cgi?id=6222
     - execute with column indices or names
@@ -80,7 +78,7 @@ Currently implemented JDBC 4.1 interface
     - setEscapeProcessing on
 
   * java.sql.PreparedStatement
-    The next features/methods are NOT implemented:
+    The next features/methods are NOT useable/supported:
     - setArray
     - setAsciiStream, setBinaryStream, setUnicodeStream
     - setBlob
@@ -89,8 +87,17 @@ Currently implemented JDBC 4.1 interface
 
   * java.sql.ParameterMetaData
 
+  * java.sql.CallableStatement
+    The next methods are NOT useable/supported:
+    - all getXyz(parameterIndex/parameterName, ...) methods because
+      output parameters in stored procedures are not supported by MonetDB
+    - all registerOutParameter(parameterIndex/parameterName, int sqlType, ...) methods
+      because output parameters in stored procedures are not supported by MonetDB
+    - wasNull() method because output parameters in stored procedures are
+      not supported by MonetDB
+
   * java.sql.ResultSet
-    The next features/methods are NOT implemented:
+    The next features/methods are NOT useable/supported:
     - getArray
     - getAsciiStream, getUnicodeStream
     - getNClob
@@ -105,12 +112,12 @@ Currently implemented JDBC 4.1 interface
 
   * java.sql.Blob
     A simple implementation using a byte[] to store the whole BLOB
-    The next features/methods are NOT implemented:
+    The next features/methods are NOT useable/supported:
     - setBinaryStream
 
   * java.sql.Clob
     A simple implementation using a StringBuilder to store the whole CLOB
-    The next features/methods are NOT implemented:
+    The next features/methods are NOT useable/supported:
     - getAsciiStream
     - setAsciiStream
     - setCharacterStream
@@ -124,8 +131,6 @@ Currently implemented JDBC 4.1 interface
 
 The next java.sql.* interfaces are NOT implemented:
   * java.sql.Array
-  * java.sql.CallableStatement  (use Statement or PreparedStatement instead)
-     see also: https://www.monetdb.org/bugzilla/show_bug.cgi?id=6402
   * java.sql.NClob
   * java.sql.Ref
   * java.sql.Rowid
--- a/src/main/java/nl/cwi/monetdb/client/JMonetDB.java
+++ b/src/main/java/nl/cwi/monetdb/client/JMonetDB.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.client;
--- a/src/main/java/nl/cwi/monetdb/client/JdbcClient.java
+++ b/src/main/java/nl/cwi/monetdb/client/JdbcClient.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.client;
@@ -444,7 +444,7 @@ public final class JdbcClient {
 							" v" + dbmd.getDriverVersion());
 					}
 					out.println("Current Schema: " + con.getSchema());
-					out.println("Type \\q to quit, \\h for a list of available commands");
+					out.println("Type \\q to quit (you can also use: quit or exit), \\? or \\h for a list of available commands");
 					out.flush();
 				}
 				processInteractive(false, doEcho, scolonterm, user);
@@ -605,76 +605,85 @@ public final class JdbcClient {
 				doProcess = true;
 				if (wasComplete) {
 					doProcess = false;
-					// check for commands only when the previous row was
-					// complete
-					if (command.equals("\\q")) {
+					// check for commands only when the previous row was complete
+					if (command.equals("\\q") || command.equals("quit") || command.equals("exit")) {
 						// quit
 						break;
-					} else if (command.startsWith("\\h")) {
+					} else if (command.equals("\\?") || command.equals("\\h")) {
 						out.println("Available commands:");
-						out.println("\\q      quits this program");
-						out.println("\\h      this help screen");
-						if (dbmd != null)
-							out.println("\\d      list available tables and views in current schema");
-						out.println("\\d<obj> describes the given table or view");
-						out.println("\\l<uri> executes the contents of the given file or URL");
-						out.println("\\i<uri> batch executes the inserts from the given file or URL");
+						out.println("\\q       quits this program (you can also use: quit or exit)");
+						if (dbmd != null) {
+							out.println("\\d       list available tables and views in current schema");
+							out.println("\\dS      list available system tables and views in sys schema");
+							out.println("\\d <obj> describes the given table or view");
+						}
+						out.println("\\l<uri>  executes the contents of the given file or URL");
+						out.println("\\i<uri>  batch executes the inserts from the given file or URL");
+						out.println("\\? or \\h this help screen");
 					} else if (dbmd != null && command.startsWith("\\d")) {
 						ResultSet tbl = null;
 						try {
-							String object = command.substring(2).trim();
-							if (scolonterm && object.endsWith(";"))
-								object = object.substring(0, object.length() - 1);
-							if (object.isEmpty()) {
-								// list available tables and views in current schema
-								String current_schema = con.getSchema();
-								tbl = dbmd.getTables(null, current_schema, null, null);
+							if (command.equals("\\dS")) {
+								// list available system tables and views in sys schema
+								tbl = dbmd.getTables(null, "sys", null, null);
 
 								// give us a list of all non-system tables and views (including temp ones)
 								while (tbl.next()) {
 									String tableType = tbl.getString(4);	// 4 = "TABLE_TYPE"
-									if (tableType != null && !tableType.startsWith("SYSTEM "))
+									if (tableType != null && tableType.startsWith("SYSTEM "))
 										out.println(tableType + "\t" +
 											tbl.getString(2) + "." +	// 2 = "TABLE_SCHEM"
 											tbl.getString(3));	// 3 = "TABLE_NAME"
 								}
-								tbl.close();
-								tbl = null;
 							} else {
-								// describes the given table or view
-								String schema;
-								String obj_nm = object;
-								boolean found = false;
-								int dot = object.indexOf(".");
-								if (dot > 0) {
-									// use specified schema
-									schema = object.substring(0, dot);
-									obj_nm = object.substring(dot + 1);
+								String object = command.substring(2).trim();
+								if (scolonterm && object.endsWith(";"))
+									object = object.substring(0, object.length() - 1);
+								if (object.isEmpty()) {
+									// list available user tables and views in current schema
+									tbl = dbmd.getTables(null, con.getSchema(), null, null);
+
+									// give us a list of all non-system tables and views (including temp ones)
+									while (tbl.next()) {
+										String tableType = tbl.getString(4);	// 4 = "TABLE_TYPE"
+										if (tableType != null && !tableType.startsWith("SYSTEM "))
+											out.println(tableType + "\t" +
+												tbl.getString(2) + "." +	// 2 = "TABLE_SCHEM"
+												tbl.getString(3));	// 3 = "TABLE_NAME"
+									}
 								} else {
-									// use current schema
-									schema = con.getSchema();
-								}
-								tbl = dbmd.getTables(null, schema, obj_nm, null);
-								while (tbl.next() && !found) {
-									String tableName = tbl.getString(3);	// 3 = "TABLE_NAME"
-									String schemaName = tbl.getString(2);	// 2 = "TABLE_SCHEM"
-									if (obj_nm.equals(tableName) && schema.equals(schemaName)) {
-										// we found it, describe it
-										exporter.dumpSchema(dbmd,
+									// describes the given table or view
+									String schema;
+									String obj_nm = object;
+									boolean found = false;
+									int dot = object.indexOf(".");
+									if (dot > 0) {
+										// use specified schema
+										schema = object.substring(0, dot);
+										obj_nm = object.substring(dot + 1);
+									} else {
+										// use current schema
+										schema = con.getSchema();
+									}
+									tbl = dbmd.getTables(null, schema, obj_nm, null);
+									while (tbl.next() && !found) {
+										String tableName = tbl.getString(3);	// 3 = "TABLE_NAME"
+										String schemaName = tbl.getString(2);	// 2 = "TABLE_SCHEM"
+										if (obj_nm.equals(tableName) && schema.equals(schemaName)) {
+											// we found it, describe it
+											exporter.dumpSchema(dbmd,
 												tbl.getString(4),	// 4 = "TABLE_TYPE"
 												tbl.getString(1),	// 1 = "TABLE_CAT"
 												schemaName,
 												tableName);
 
-										found = true;
-										break;
+											found = true;
+											break;
+										}
 									}
+									if (!found)
+										System.err.println("Unknown table or view: " + object);
 								}
-								tbl.close();
-								tbl = null;
-
-								if (!found)
-									System.err.println("Unknown table or view: " + object);
 							}
 						} catch (SQLException e) {
 							out.flush();
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetBlob.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetBlob.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -226,7 +226,7 @@ public final class MonetBlob implements 
 	 */
 	@Override
 	public OutputStream setBinaryStream(long pos) throws SQLException {
-		throw new SQLFeatureNotSupportedException("Method setBinaryStream(long pos) not supported", "0A000");
+		throw MonetWrapper.newSQLFeatureNotSupportedException("setBinaryStream");
 	}
 
 	/**
new file mode 100644
--- /dev/null
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetCallableStatement.java
@@ -0,0 +1,635 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
+ */
+
+package nl.cwi.monetdb.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+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.
+ *
+ * <code>
+ *  { call procedure-name [ (arg1, arg2, ...) ] }
+ *  { ?= call procedure-name [ (arg1, arg2, ...) ] }
+ * </code>
+ *
+ * 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.
+ * Note: MonetDB does not support OUT or INOUT parameters. Only input 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.
+ *
+ * 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
+ * - all registerOutParameter(parameterIndex/parameterName, int sqlType, ...) methods
+ * - wasNull() method
+ * because output parameters in stored procedures are not supported by MonetDB.
+ *
+ * @author Martin van Dinther
+ * @version 1.0
+ */
+
+public class MonetCallableStatement
+	extends MonetPreparedStatement
+	implements CallableStatement
+{
+	/**
+	 * MonetCallableStatement constructor which checks the arguments for validity.
+	 * A MonetCallableStatement is backed by a {@link MonetPreparedStatement},
+	 * which deals with most of the required stuff of this class.
+	 *
+	 * @param connection the connection that created this Statement
+	 * @param resultSetType type of {@link ResultSet} to produce
+	 * @param resultSetConcurrency concurrency 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 [(?,?, ...)] }
+	 *	or
+	 *	{ ?= call procedure_name [(?,?, ...)] }
+	 * @throws SQLException if an error occurs during creation
+	 * @throws IllegalArgumentException is one of the arguments is null or empty
+	 */
+	MonetCallableStatement(
+			MonetConnection connection,
+			int resultSetType,
+			int resultSetConcurrency,
+			int resultSetHoldability,
+			String callQuery)
+		throws SQLException, IllegalArgumentException
+	{
+		super(
+			connection,
+			resultSetType,
+			resultSetConcurrency,
+			resultSetHoldability,
+			removeEscapes(callQuery)
+		);
+	}
+
+	/** parse call query string on
+	 *  { [?=] call <procedure-name> [(<arg1>,<arg2>, ...)] }
+	 * and remove the JDBC escapes pairs: { and }
+	 */
+	private static String removeEscapes(String query) {
+		if (query == null)
+			return null;
+
+		int firstAccOpen = query.indexOf("{");
+		if (firstAccOpen == -1)
+			// nothing to remove
+			return query;
+
+		int len = query.length();
+		StringBuilder buf = new StringBuilder(len);
+		int countAccolades = 0;
+		// simple scanner which copies all characters except the first '{' and matching '}' character
+		// we currently do not check if 'call' appears after the first '{' and before the '}' character
+		// we currently also do not deal correctly with { or } appearing as comment or as part of a string value
+		for (int i = 0; i < len; i++) {
+			char c = query.charAt(i);
+			switch (c) {
+			case '{':
+				countAccolades++;
+				if (i == firstAccOpen)
+					continue;
+				else
+					buf.append(c);
+				break;
+			case '}':
+				countAccolades--;
+				if (i > firstAccOpen && countAccolades == 0)
+					continue;
+				else
+					buf.append(c);
+				break;
+			default:
+				buf.append(c);
+			}
+		}
+		return buf.toString();
+	}
+
+	/** utility method to convert a parameter name to an int (which represents the parameter index)
+	 *  this will only succeed for strings like: "1", "2", "3", etc
+	 *  throws SQLException if it cannot convert the string to an integer number
+	 */
+	private int nameToIndex(String parameterName) throws SQLException {
+		if (parameterName == null)
+			throw new SQLException("Missing parameterName value", "22002");
+		try {
+			return Integer.parseInt(parameterName);
+		} catch (NumberFormatException nfe) {
+			throw new SQLException("Cannot convert parameterName '" + parameterName + "' to integer value", "22010");
+		}
+	}
+
+
+	// methods of interface CallableStatement
+
+	// all getXyz(parameterIndex/parameterName, ...) methods are NOT supported
+	// because output parameters in stored procedures are not supported by MonetDB
+	@Override
+	public Array getArray(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getArray");
+	}
+	@Override
+	public Array getArray(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getArray");
+	}
+	@Override
+	public BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBigDecimal");
+	}
+	@Override
+	@Deprecated
+	public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBigDecimal");
+	}
+	@Override
+	public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBigDecimal");
+	}
+	@Override
+	public Blob getBlob(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBlob");
+	}
+	@Override
+	public Blob getBlob(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBlob");
+	}
+	@Override
+	public boolean getBoolean(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBoolean");
+	}
+	@Override
+	public boolean getBoolean(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBoolean");
+	}
+	@Override
+	public byte getByte(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getByte");
+	}
+	@Override
+	public byte getByte(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getByte");
+	}
+	@Override
+	public byte[] getBytes(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBytes");
+	}
+	@Override
+	public byte[] getBytes(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getBytes");
+	}
+	@Override
+	public Reader getCharacterStream(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getCharacterStream");
+	}
+	@Override
+	public Reader getCharacterStream(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getCharacterStream");
+	}
+	@Override
+	public Clob getClob(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getClob");
+	}
+	@Override
+	public Clob getClob(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getClob");
+	}
+	@Override
+	public Date getDate(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getDate");
+	}
+	@Override
+	public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getDate");
+	}
+	@Override
+	public Date getDate(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getDate");
+	}
+	@Override
+	public Date getDate(String parameterName, Calendar cal) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getDate");
+	}
+	@Override
+	public double getDouble(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getDouble");
+	}
+	@Override
+	public double getDouble(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getDouble");
+	}
+	@Override
+	public float getFloat(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getFloat");
+	}
+	@Override
+	public float getFloat(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getFloat");
+	}
+	@Override
+	public int getInt(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getInt");
+	}
+	@Override
+	public int getInt(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getInt");
+	}
+	@Override
+	public long getLong(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getLong");
+	}
+	@Override
+	public long getLong(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getLong");
+	}
+	@Override
+	public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getNCharacterStream");
+	}
+	@Override
+	public Reader getNCharacterStream(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getNCharacterStream");
+	}
+	@Override
+	public NClob getNClob(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getNClob");
+	}
+	@Override
+	public NClob getNClob(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getNClob");
+	}
+	@Override
+	public String getNString(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getNString");
+	}
+	@Override
+	public String getNString(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getNString");
+	}
+	@Override
+	public Object getObject(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getObject");
+	}
+	@Override
+	public <T> T getObject(int parameterIndex, Class<T> type) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getObject");
+	}
+	@Override
+	public Object getObject(int parameterIndex, Map<String,Class<?>> map) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getObject");
+	}
+	@Override
+	public Object getObject(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getObject");
+	}
+	@Override
+	public <T> T getObject(String parameterName, Class<T> type) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getObject");
+	}
+	@Override
+	public Object getObject(String parameterName, Map<String,Class<?>> map) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getObject");
+	}
+	@Override
+	public Ref getRef(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getRef");
+	}
+	@Override
+	public Ref getRef(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getRef");
+	}
+	@Override
+	public RowId getRowId(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getRowId");
+	}
+	@Override
+	public RowId getRowId(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getRowId");
+	}
+	@Override
+	public short getShort(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getShort");
+	}
+	@Override
+	public short getShort(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getShort");
+	}
+	@Override
+	public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getSQLXML");
+	}
+	@Override
+	public SQLXML getSQLXML(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getSQLXML");
+	}
+	@Override
+	public String getString(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getString");
+	}
+	@Override
+	public String getString(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getString");
+	}
+	@Override
+	public Time getTime(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTime");
+	}
+	@Override
+	public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTime");
+	}
+	@Override
+	public Time getTime(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTime");
+	}
+	@Override
+	public Time getTime(String parameterName, Calendar cal) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTime");
+	}
+	@Override
+	public Timestamp getTimestamp(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTimestamp");
+	}
+	@Override
+	public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTimestamp");
+	}
+	@Override
+	public Timestamp getTimestamp(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTimestamp");
+	}
+	@Override
+	public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getTimestamp");
+	}
+	@Override
+	public URL getURL(int parameterIndex) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getURL");
+	}
+	@Override
+	public URL getURL(String parameterName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("getURL");
+	}
+
+
+	// all registerOutParameter(parameterIndex/parameterName, int sqlType, ...) methods are NOT supported
+	// because output parameters in stored procedures are not supported by MonetDB
+	@Override
+	public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
+		throw newSQLFeatureNotSupportedException("registerOutParameter");
+	}
+	@Override
+	public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException {
+		throw newSQLFeatureNotSupportedException("registerOutParameter");
+	}
+	@Override
+	public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("registerOutParameter");
+	}
+	@Override
+	public void registerOutParameter(String parameterName, int sqlType) throws SQLException {
+		throw newSQLFeatureNotSupportedException("registerOutParameter");
+	}
+	@Override
+	public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException {
+		throw newSQLFeatureNotSupportedException("registerOutParameter");
+	}
+	@Override
+	public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException {
+		throw newSQLFeatureNotSupportedException("registerOutParameter");
+	}
+
+
+	// all setXyz(parameterName, ...) methods are mapped to setXyz(nameToIndex(parameterName), ...) methods
+	// this only works for parameter names "1", "2", "3", etc.
+	@Override
+	public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
+		setAsciiStream(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException {
+		setAsciiStream(nameToIndex(parameterName), x, length);
+	}
+	@Override
+	public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
+		setAsciiStream(nameToIndex(parameterName), x, length);
+	}
+	@Override
+	public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
+		setBigDecimal(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
+		setBinaryStream(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException {
+		setBinaryStream(nameToIndex(parameterName), x, length);
+	}
+	@Override
+	public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException {
+		setBinaryStream(nameToIndex(parameterName), x, length);
+	}
+	@Override
+	public void setBlob(String parameterName, Blob x) throws SQLException {
+		setBlob(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
+		setBlob(nameToIndex(parameterName), inputStream);
+	}
+	@Override
+	public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
+		setBlob(nameToIndex(parameterName), inputStream, length);
+	}
+	@Override
+	public void setBoolean(String parameterName, boolean x) throws SQLException {
+		setBoolean(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setByte(String parameterName, byte x) throws SQLException {
+		setByte(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setBytes(String parameterName, byte[] x) throws SQLException {
+		setBytes(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
+		setCharacterStream(nameToIndex(parameterName), reader);
+	}
+	@Override
+	public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException {
+		setCharacterStream(nameToIndex(parameterName), reader, length);
+	}
+	@Override
+	public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
+		setCharacterStream(nameToIndex(parameterName), reader, length);
+	}
+	@Override
+	public void setClob(String parameterName, Clob x) throws SQLException {
+		setClob(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setClob(String parameterName, Reader reader) throws SQLException {
+		setClob(nameToIndex(parameterName), reader);
+	}
+	@Override
+	public void setClob(String parameterName, Reader reader, long length) throws SQLException {
+		setClob(nameToIndex(parameterName), reader, length);
+	}
+	@Override
+	public void setDate(String parameterName, Date x) throws SQLException {
+		setDate(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setDate(String parameterName, Date x, Calendar cal) throws SQLException {
+		setDate(nameToIndex(parameterName), x, cal);
+	}
+	@Override
+	public void setDouble(String parameterName, double x) throws SQLException {
+		setDouble(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setFloat(String parameterName, float x) throws SQLException {
+		setFloat(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setInt(String parameterName, int x) throws SQLException {
+		setInt(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setLong(String parameterName, long x) throws SQLException {
+		setLong(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setNCharacterStream(String parameterName, Reader value) throws SQLException {
+		setNCharacterStream(nameToIndex(parameterName), value);
+	}
+	@Override
+	public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException {
+		setNCharacterStream(nameToIndex(parameterName), value, length);
+	}
+	@Override
+	public void setNClob(String parameterName, NClob value) throws SQLException {
+		setNClob(nameToIndex(parameterName), value);
+	}
+	@Override
+	public void setNClob(String parameterName, Reader reader) throws SQLException {
+		setNClob(nameToIndex(parameterName), reader);
+	}
+	@Override
+	public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
+		setNClob(nameToIndex(parameterName), reader, length);
+	}
+	@Override
+	public void setNString(String parameterName, String value) throws SQLException {
+		setNString(nameToIndex(parameterName), value);
+	}
+	@Override
+	public void setNull(String parameterName, int sqlType) throws SQLException {
+		setNull(nameToIndex(parameterName), sqlType);
+	}
+	@Override
+	public void setNull(String parameterName, int sqlType, String typeName) throws SQLException {
+		setNull(nameToIndex(parameterName), sqlType, typeName);
+	}
+	@Override
+	public void setObject(String parameterName, Object x) throws SQLException {
+		setObject(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException {
+		setObject(nameToIndex(parameterName), x, targetSqlType);
+	}
+	@Override
+	public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException {
+		setObject(nameToIndex(parameterName), x, targetSqlType, scale);
+	}
+	@Override
+	public void setRowId(String parameterName, RowId x) throws SQLException {
+		setRowId(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setShort(String parameterName, short x) throws SQLException {
+		setShort(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {
+		setSQLXML(nameToIndex(parameterName), xmlObject);
+	}
+	@Override
+	public void setString(String parameterName, String x) throws SQLException {
+		setString(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setTime(String parameterName, Time x) throws SQLException {
+		setTime(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setTime(String parameterName, Time x, Calendar cal) throws SQLException {
+		setTime(nameToIndex(parameterName), x, cal);
+	}
+	@Override
+	public void setTimestamp(String parameterName, Timestamp x) throws SQLException {
+		setTimestamp(nameToIndex(parameterName), x);
+	}
+	@Override
+	public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException {
+		setTimestamp(nameToIndex(parameterName), x, cal);
+	}
+	@Override
+	public void setURL(String parameterName, URL val) throws SQLException {
+		setURL(nameToIndex(parameterName), val);
+	}
+
+	/* Retrieves whether the last OUT parameter read had the value of SQL NULL. */
+	@Override
+	public boolean wasNull() throws SQLException {
+		// wasNull() method is NOT supported
+		// because output parameters in stored procedures are not supported by MonetDB
+		throw newSQLFeatureNotSupportedException("wasNull");
+	}
+
+	// end methods interface CallableStatement
+}
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -71,10 +71,7 @@ public final class MonetClob implements 
 	 */
 	@Override
 	public InputStream getAsciiStream() throws SQLException {
-		checkBufIsNotNull();
-		if (buffer.length() == 0)
-			throw new SQLException("This Clob has been freed", "M1M20");
-		return new ByteArrayInputStream(buffer.toString().getBytes());
+		throw MonetWrapper.newSQLFeatureNotSupportedException("getAsciiStream");
 	}
 
 	/**
@@ -215,7 +212,7 @@ public final class MonetClob implements 
 	 */
 	@Override
 	public OutputStream setAsciiStream(long pos) throws SQLException {
-		throw new SQLFeatureNotSupportedException("Method setAsciiStream(long pos) not supported", "0A000");
+		throw MonetWrapper.newSQLFeatureNotSupportedException("setAsciiStream");
 	}
 
 	/**
@@ -236,7 +233,7 @@ public final class MonetClob implements 
 	 */
 	@Override
 	public Writer setCharacterStream(long pos) throws SQLException {
-		throw new SQLFeatureNotSupportedException("Method setCharacterStream(long pos) not supported", "0A000");
+		throw MonetWrapper.newSQLFeatureNotSupportedException("setCharacterStream");
 	}
 
 	/**
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -178,7 +178,7 @@ public abstract class MonetConnection ex
 	private boolean queriedCommentsTable = false;
 	private boolean hasCommentsTable = false;
 
-	/** The last set query timeout on the server as used by Statement and PreparedStatement (and CallableStatement in future) */
+	/** The last set query timeout on the server as used by Statement, PreparedStatement and CallableStatement */
 	protected int lastSetQueryTimeout = 0;	// 0 means no timeout, which is the default on the server
 
 	/**
@@ -374,8 +374,7 @@ public abstract class MonetConnection ex
 		} catch (IllegalArgumentException e) {
 			throw new SQLException(e.toString(), "M0M03");
 		}
-		// we don't have to catch SQLException because that is declared to
-		// be thrown
+		// we don't have to catch SQLException because that is declared to be thrown
 	}
 
 	/**
@@ -385,7 +384,7 @@ public abstract class MonetConnection ex
 	 * @see #setAutoCommit(boolean)
 	 */
 	@Override
-	public boolean getAutoCommit() throws SQLException {
+	public boolean getAutoCommit() {
 		return autoCommit;
 	}
 
@@ -393,10 +392,9 @@ public abstract class MonetConnection ex
 	 * Retrieves this Connection object's current catalog name.
 	 *
 	 * @return the current catalog name or null if there is none
-	 * @throws SQLException if a database access error occurs or the current language is not SQL
 	 */
 	@Override
-	public String getCatalog() throws SQLException {
+	public String getCatalog() {
 		// MonetDB does NOT support catalogs
 		return null;
 	}
@@ -513,10 +511,8 @@ public abstract class MonetConnection ex
 	 * A driver may convert the JDBC SQL grammar into its system's native SQL grammar prior to sending it.
 	 * This method returns the native form of the statement that the driver would have sent.
 	 *
-	 * Parameters:
-	 *   sql - an SQL statement that may contain one or more '?' parameter placeholders.
-	 * Returns: the native form of this statement
-	 * Throws: SQLException - if a database access error occurs or this method is called on a closed connection
+	 * @param sql - an SQL statement that may contain one or more '?' parameter placeholders.
+	 * @return the native form of this statement
 	 */
 	@Override
 	public String nativeSQL(String sql) {
@@ -539,11 +535,11 @@ public abstract class MonetConnection ex
 	 * and have a concurrency level of CONCUR_READ_ONLY.
 	 * The holdability of the created result sets can be determined by calling getHoldability().
 	 *
-	 * Parameters:
-	 *   sql - an SQL statement that may contain one or more '?' parameter placeholders.
+	 * @param sql - an SQL statement that may contain one or more '?' parameter placeholders.
 	 *	Typically this statement is specified using JDBC call escape syntax.
-	 * Returns: a new default CallableStatement object containing the pre-compiled SQL statement
-	 * Throws: SQLException - if a database access error occurs or this method is called on a closed connection
+	 * @return a new default CallableStatement object containing the pre-compiled SQL statement
+	 * @throws SQLException - if a database access error occurs or this method is called on a closed connection
+	 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method.
 	 */
 	@Override
 	public CallableStatement prepareCall(String sql) throws SQLException {
@@ -555,18 +551,16 @@ public abstract class MonetConnection ex
 	 * This method is the same as the prepareCall method above, but it allows the default result set type and concurrency to be overridden.
 	 * The holdability of the created result sets can be determined by calling getHoldability().
 	 *
-	 * Parameters:
-	 *   sql - a String object that is the SQL statement to be sent to the database; may contain on or more '?' parameters
+	 * @param sql - a String object that is the SQL statement to be sent to the database; may contain on or more '?' parameters
 	 *	Typically this statement is specified using JDBC call escape syntax.
-	 *   resultSetType - a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE
-	 *   resultSetConcurrency - a concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE
-	 * Returns: a new CallableStatement object containing the pre-compiled SQL statement that
+	 * @param resultSetType - a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE
+	 * @param resultSetConcurrency - a concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE
+	 * @return a new CallableStatement object containing the pre-compiled SQL statement that
 	 *	will produce ResultSet objects with the given type and concurrency
-	 * Throws:
-	 *   SQLException - if a database access error occurs, this method is called on a closed connection or
-	 *		the given parameters are not ResultSet constants indicating type and concurrency
-	 *   SQLFeatureNotSupportedException - if the JDBC driver does not support this method or
-	 *		this method is not supported for the specified result set type and result set concurrency.
+	 * @throws SQLException - if a database access error occurs, this method is called on a closed connection or
+	 *	the given parameters are not ResultSet constants indicating type and concurrency
+	 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method or
+	 *	this method is not supported for the specified result set type and result set concurrency.
 	 */
 	@Override
 	public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
@@ -577,25 +571,36 @@ public abstract class MonetConnection ex
 	 * Creates a CallableStatement object that will generate ResultSet objects with the given type and concurrency.
 	 * This method is the same as the prepareCall method above, but it allows the default result set type, result set concurrency type and holdability to be overridden.
 	 *
-	 * Parameters:
-	 *   sql - a String object that is the SQL statement to be sent to the database; may contain on or more '?' parameters
+	 * @param sql - a String object that is the SQL statement to be sent to the database; may contain on or more '?' parameters
 	 *	Typically this statement is specified using JDBC call escape syntax.
-	 *   resultSetType - a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE
-	 *   resultSetConcurrency - a concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE
-	 *   resultSetHoldability - one of the following ResultSet constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
-	 * Returns: a new CallableStatement object, containing the pre-compiled SQL statement, that will generate ResultSet objects with the given type, concurrency, and holdability
-	 * Throws:
-	 *   SQLException - if a database access error occurs, this method is called on a closed connection or
-	 *		the given parameters are not ResultSet constants indicating type, concurrency, and holdability
-	 *   SQLFeatureNotSupportedException - if the JDBC driver does not support this method or
-	 *		this method is not supported for the specified result set type, result set holdability and result set concurrency.
+	 * @param resultSetType - a result set type; one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE
+	 * @param resultSetConcurrency - a concurrency type; one of ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE
+	 * @param resultSetHoldability - one of the following ResultSet constants: ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
+	 * @return a new CallableStatement object, containing the pre-compiled SQL statement, that will generate ResultSet objects with the given type, concurrency, and holdability
+	 * @throws SQLException - if a database access error occurs, this method is called on a closed connection or
+	 *	the given parameters are not ResultSet constants indicating type, concurrency, and holdability
+	 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method or
+	 *	this method is not supported for the specified result set type, result set holdability and result set concurrency.
 	 */
 	@Override
 	public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
 		throws SQLException
 	{
-		throw new SQLFeatureNotSupportedException("prepareCall() not yet supported", "0A000");
-		/* a request to implement prepareCall() has already been logged, see https://www.monetdb.org/bugzilla/show_bug.cgi?id=6402 */
+		try {
+			CallableStatement ret = new MonetCallableStatement(
+				this,
+				resultSetType,
+				resultSetConcurrency,
+				resultSetHoldability,
+				sql
+			);
+			// store it in the map for when we close...
+			statements.put(ret, null);
+			return ret;
+		} catch (IllegalArgumentException e) {
+			throw new SQLException(e.toString(), "M0M03");
+		}
+		// we don't have to catch SQLException because that is declared to be thrown
 	}
 
 	/**
@@ -693,8 +698,7 @@ public abstract class MonetConnection ex
 		} catch (IllegalArgumentException e) {
 			throw new SQLException(e.toString(), "M0M03");
 		}
-		// we don't have to catch SQLException because that is declared to
-		// be thrown
+		// we don't have to catch SQLException because that is declared to be thrown
 	}
 
 	/**
@@ -733,11 +737,10 @@ public abstract class MonetConnection ex
 	@Override
 	public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
 		if (autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS &&
-				autoGeneratedKeys != Statement.NO_GENERATED_KEYS)
+		    autoGeneratedKeys != Statement.NO_GENERATED_KEYS)
 			throw new SQLException("Invalid argument, expected RETURN_GENERATED_KEYS or NO_GENERATED_KEYS", "M1M05");
 
-		/* MonetDB has no way to disable this, so just do the normal
-		 * thing ;) */
+		/* MonetDB has no way to disable this, so just do the normal thing ;) */
 		return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
 	}
 
@@ -758,19 +761,16 @@ public abstract class MonetConnection ex
 	 * Result sets created using the returned PreparedStatement object will by default be type TYPE_FORWARD_ONLY and have
 	 * a concurrency level of CONCUR_READ_ONLY. The holdability of the created result sets can be determined by calling getHoldability().
 	 *
-	 * Parameters:
-	 *     sql - an SQL statement that may contain one or more '?' IN parameter placeholders
-	 *     columnIndexes - an array of column indexes indicating the columns that should be returned from the inserted row or rows
-	 * Returns:
-	 *     a new PreparedStatement object, containing the pre-compiled statement, that is capable of
-	 *     returning the auto-generated keys designated by the given array of column indexes
-	 * Throws:
-	 *     SQLException - if a database access error occurs or this method is called on a closed connection
-	 *     SQLFeatureNotSupportedException - if the JDBC driver does not support this method
+	 * @param sql - an SQL statement that may contain one or more '?' IN parameter placeholders
+	 * @param columnIndexes - an array of column indexes indicating the columns that should be returned from the inserted row or rows
+	 * @return a new PreparedStatement object, containing the pre-compiled statement, that is capable of
+	 * 	returning the auto-generated keys designated by the given array of column indexes
+	 * @throws SQLException - if a database access error occurs or this method is called on a closed connection
+	 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method
 	 */
 	@Override
 	public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
-		throw new SQLFeatureNotSupportedException("prepareStatement(String sql, int[] columnIndexes) not supported", "0A000");
+		throw newSQLFeatureNotSupportedException("prepareStatement(String sql, int[] columnIndexes)");
 	}
 
 	/**
@@ -790,19 +790,16 @@ public abstract class MonetConnection ex
 	 * Result sets created using the returned PreparedStatement object will by default be type TYPE_FORWARD_ONLY and have
 	 * a concurrency level of CONCUR_READ_ONLY. The holdability of the created result sets can be determined by calling getHoldability().
 	 *
-	 * Parameters:
-	 *     sql - an SQL statement that may contain one or more '?' IN parameter placeholders
-	 *     columnNames - an array of column names indicating the columns that should be returned from the inserted row or rows
-	 * Returns:
-	 *     a new PreparedStatement object, containing the pre-compiled statement, that is capable of
-	 *     returning the auto-generated keys designated by the given array of column names
-	 * Throws:
-	 *     SQLException - if a database access error occurs or this method is called on a closed connection
-	 *     SQLFeatureNotSupportedException - if the JDBC driver does not support this method
+	 * @param sql - an SQL statement that may contain one or more '?' IN parameter placeholders
+	 * @param columnNames - an array of column names indicating the columns that should be returned from the inserted row or rows
+	 * @return a new PreparedStatement object, containing the pre-compiled statement, that is capable of
+	 * 	returning the auto-generated keys designated by the given array of column names
+	 * @throws SQLException - if a database access error occurs or this method is called on a closed connection
+	 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method
 	 */
 	@Override
 	public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
-		throw new SQLFeatureNotSupportedException("prepareStatement(String sql, String[] columnNames) not supported", "0A000");
+		throw newSQLFeatureNotSupportedException("prepareStatement(String sql, String[] columnNames)");
 	}
 
 	/**
@@ -907,8 +904,8 @@ public abstract class MonetConnection ex
 	 * does not support catalogs, it will silently ignore this request.
 	 */
 	@Override
-	public void setCatalog(String catalog) throws SQLException {
-		throw new SQLFeatureNotSupportedException("setCatalog(String catalog) not supported", "0A000");
+	public void setCatalog(String catalog) {
+		// silently ignore this request as MonetDB does not support catalogs
 	}
 
 	/**
@@ -919,13 +916,15 @@ public abstract class MonetConnection ex
 	 * @param holdability - a ResultSet holdability constant; one of
 	 *	ResultSet.HOLD_CURSORS_OVER_COMMIT or
 	 *	ResultSet.CLOSE_CURSORS_AT_COMMIT
+	 * @throws SQLException - if a database access error occurs or this method is called on a closed connection
+	 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method or argument
 	 * @see #getHoldability()
 	 */
 	@Override
 	public void setHoldability(int holdability) throws SQLException {
 		// we only support ResultSet.HOLD_CURSORS_OVER_COMMIT
 		if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
-			throw new SQLFeatureNotSupportedException("setHoldability(CLOSE_CURSORS_AT_COMMIT) not supported", "0A000");
+			throw newSQLFeatureNotSupportedException("setHoldability(CLOSE_CURSORS_AT_COMMIT)");
 	}
 
 	/**
@@ -1064,7 +1063,7 @@ public abstract class MonetConnection ex
 	 */
 	@Override
 	public java.sql.Array createArrayOf(String typeName, Object[] elements) throws SQLException {
-		throw new SQLFeatureNotSupportedException("createArrayOf() not supported", "0A000");
+		throw newSQLFeatureNotSupportedException("createArrayOf");
 	}
 
 
@@ -1115,7 +1114,7 @@ public abstract class MonetConnection ex
 	 */
 	@Override
 	public java.sql.NClob createNClob() throws SQLException {
-		throw new SQLFeatureNotSupportedException("createNClob() not supported", "0A000");
+		throw newSQLFeatureNotSupportedException("createNClob");
 	}
 
 	/**
@@ -1136,7 +1135,7 @@ public abstract class MonetConnection ex
 	 */
 	@Override
 	public java.sql.Struct createStruct(String typeName, Object[] attributes) throws SQLException {
-		throw new SQLFeatureNotSupportedException("createStruct() not supported", "0A000");
+		throw newSQLFeatureNotSupportedException("createStruct");
 	}
 
 	/**
@@ -1152,7 +1151,7 @@ public abstract class MonetConnection ex
 	 */
 	@Override
 	public java.sql.SQLXML createSQLXML() throws SQLException {
-		throw new SQLFeatureNotSupportedException("createSQLXML() not supported", "0A000");
+		throw newSQLFeatureNotSupportedException("createSQLXML");
 	}
 
 	/**
@@ -1708,9 +1707,8 @@ public abstract class MonetConnection ex
 				// free resources if we're running forward only
 				if (curResponse >= 0 && curResponse < responses.size()) {
 					IResponse tmp = responses.get(curResponse);
-					if (tmp != null) {
+					if (tmp != null)
 						tmp.close();
-					}
 					responses.set(curResponse, null);
 				}
 			}
@@ -1730,7 +1728,8 @@ public abstract class MonetConnection ex
 		 * @param i the index position of the header to close
 		 */
 		void closeResponse(int i) {
-			if (i < 0 || i >= responses.size()) return;
+			if (i < 0 || i >= responses.size())
+				return;
 			IResponse tmp = responses.set(i, null);
 			if (tmp != null)
 				tmp.close();
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDataSource.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDataSource.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -224,6 +224,6 @@ public class MonetDataSource extends Mon
 	 */
 	@Override
 	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-		throw new SQLFeatureNotSupportedException("java.util.logging not in use", "0A000");
+		throw newSQLFeatureNotSupportedException("getParentLogger");
 	}
 }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -481,20 +481,21 @@ public class MonetDatabaseMetaData exten
 	}
 
 	// SQL query parts shared by four get<Type>Functions() below
-	private static final String FunctionsSelect = "SELECT DISTINCT \"name\" FROM \"sys\".\"functions\" ";
-	private static final String FunctionsWhere = "WHERE \"id\" IN (SELECT \"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1 AND \"name\" = 'arg_1' AND \"type\" IN ";
-	// Scalar functions sql_max(x, y) and sql_min(x, y) are defined in sys.args only for type 'any'.
-	// Easiest way to include them in the Num, Str and TimeDate lists is to add them explicitly via UNION SQL:
-	private static final String AddFunctionsMaxMin = " UNION SELECT 'sql_max' UNION SELECT 'sql_min'";
+	private static final String FunctionsSelect = "SELECT DISTINCT \"name\" FROM \"sys\".\"functions\" WHERE ";
+	private static final String FunctionsWhere = "(\"id\" IN (SELECT \"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1 AND \"name\" = 'arg_1' AND \"type\" IN ";
+	// Scalar functions sql_max(x,y), sql_min(x,y), greatest(x,y) and least(x,y) are defined in sys.args for type 'any' and usable as num, str and timedate functions.
+	private static final String OrFunctionsMaxMin = " OR \"name\" IN ('sql_max','sql_min','least','greatest')";
 	private static final String FunctionsOrderBy1 = " ORDER BY 1";
 
 	@Override
 	public String getNumericFunctions() {
 		String match =
 			"('tinyint', 'smallint', 'int', 'bigint', 'hugeint', 'decimal', 'double', 'real') )" +
+			" AND \"type\" = 1" +	// only scalar functions
 			// exclude functions which belong to the 'str' module
-			" AND \"mod\" <> 'str'";
-		return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + AddFunctionsMaxMin + FunctionsOrderBy1);
+			" AND \"mod\" <> 'str')" +	// to filter out string functions: 'code' and 'space'
+			" OR \"name\" IN ('degrees','fuse','ms_round','ms_str','ms_trunc','radians')";
+		return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + OrFunctionsMaxMin + FunctionsOrderBy1);
 	}
 
 	@Override
@@ -502,24 +503,26 @@ public class MonetDatabaseMetaData exten
 		String match =
 			"('char', 'varchar', 'clob', 'json') )" +
 			// include functions which belong to the 'str' module
-			" OR \"mod\" = 'str'";
-		return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + AddFunctionsMaxMin + FunctionsOrderBy1);
+			" OR \"mod\" = 'str')";
+		String unionPart =
+			// add system functions which are not listed in sys.functions but implemented in the SQL parser (see sql/server/sql_parser.y)
+			" UNION SELECT 'position'";
+		return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + OrFunctionsMaxMin + unionPart + FunctionsOrderBy1);
 	}
 
 	@Override
 	public String getSystemFunctions() {
 		String wherePart =
-			"WHERE \"id\" NOT IN (SELECT \"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1)" +
-			" AND \"id\" IN (SELECT \"function_id\" FROM \"sys\".\"systemfunctions\")" +
+			"\"id\" NOT IN (SELECT \"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1)" +	// without any args
+			" AND \"id\" IN (SELECT \"function_id\" FROM \"sys\".\"systemfunctions\")" +	// only functions marked as system
 			" AND \"type\" = 1" +	// only scalar functions
 			// exclude functions which belong to the 'mtime' module
 			" AND \"mod\" <> 'mtime'" +
-			" AND \"name\" NOT IN ('localtime', 'localtimestamp')" +
+			" AND \"name\" NOT IN ('localtime','localtimestamp')" +
 			// add system functions which are not listed in sys.functions but implemented in the SQL parser (see sql/server/sql_parser.y)
 			" UNION SELECT 'cast'" +
+			" UNION SELECT 'coalesce'" +
 			" UNION SELECT 'convert'" +
-			" UNION SELECT 'coalesce'" +
-			" UNION SELECT 'extract'" +
 			" UNION SELECT 'ifthenelse'" +
 			" UNION SELECT 'isnull'" +
 			" UNION SELECT 'nullif'";
@@ -528,8 +531,13 @@ public class MonetDatabaseMetaData exten
 
 	@Override
 	public String getTimeDateFunctions() {
-		String wherePart = "WHERE \"mod\" = 'mtime' OR \"name\" IN ('localtime', 'localtimestamp') UNION SELECT 'extract' UNION SELECT 'now'";
-		return getConcatenatedStringFromQuery(FunctionsSelect + wherePart + AddFunctionsMaxMin + FunctionsOrderBy1);
+		String wherePart =
+			 "\"mod\" IN ('mtime','timestamp') OR \"name\" IN ('localtime','localtimestamp','date_trunc')";
+		String unionPart =
+			// add time date functions which are not listed in sys.functions but implemented in the SQL parser (see sql/server/sql_parser.y)
+			" UNION SELECT 'extract'" +
+			" UNION SELECT 'now'";
+		return getConcatenatedStringFromQuery(FunctionsSelect + wherePart + OrFunctionsMaxMin + unionPart + FunctionsOrderBy1);
 	}
 
 	/**
@@ -961,13 +969,21 @@ public class MonetDatabaseMetaData exten
 
 	/**
 	 * Is the SQL Integrity Enhancement Facility supported?
-	 * Our best guess is that this means support for constraints
+	 *
+	 * The SQL Integrity Enhancement facility offers additional tools for referential integrity,
+	 * CHECK constraint clauses, and DEFAULT clauses. Referential integrity allows specification of
+	 * primary and foreign keys with the requirement that no foreign key row may be inserted or
+	 * updated unless a matching primary key row exists. Check clauses allow specification of
+	 * inter-column constraints to be maintained by the database system.
+	 * Default clauses provide optional default values for missing data. 
+	 *
+	 * We currently do not supprt CHECK constraints (see bug 3568) nor deferrable FK constraints.
 	 *
 	 * @return true if so
 	 */
 	@Override
 	public boolean supportsIntegrityEnhancementFacility() {
-		return true;
+		return false;
 	}
 
 	/**
@@ -3045,9 +3061,9 @@ public class MonetDatabaseMetaData exten
 		query.append("SELECT \"sqlname\" AS \"TYPE_NAME\", " +
 			"cast(").append(MonetDriver.getSQLTypeMap("\"sqlname\"")).append(" AS int) AS \"DATA_TYPE\", " +
 			"\"digits\" AS \"PRECISION\", " +	// note that when radix is 2 the precision shows the number of bits
-			"cast(CASE WHEN \"systemname\" IN ('str', 'inet', 'json', 'url', 'uuid') THEN ''''" +
+			"cast(CASE WHEN \"systemname\" IN ('str','inet','json','url','uuid','blob','sqlblob') THEN ''''" +
 				" ELSE NULL END AS varchar(2)) AS \"LITERAL_PREFIX\", " +
-			"cast(CASE WHEN \"systemname\" IN ('str', 'inet', 'json', 'url', 'uuid') THEN ''''" +
+			"cast(CASE WHEN \"systemname\" IN ('str','inet','json','url','uuid','blob','sqlblob') THEN ''''" +
 				" ELSE NULL END AS varchar(2)) AS \"LITERAL_SUFFIX\", " +
 			"CASE WHEN \"sqlname\" IN ('char', 'varchar') THEN 'max length'" +
 				" WHEN \"sqlname\" = 'decimal' THEN 'precision, scale'" +
@@ -3055,10 +3071,8 @@ public class MonetDatabaseMetaData exten
 				" ELSE NULL END AS \"CREATE_PARAMS\", " +
 			"cast(CASE WHEN \"systemname\" = 'oid' THEN ").append(DatabaseMetaData.typeNoNulls)
 				.append(" ELSE ").append(DatabaseMetaData.typeNullable).append(" END AS smallint) AS \"NULLABLE\", " +
-			"CASE WHEN \"systemname\" IN ('str', 'json', 'url') THEN true ELSE false END AS \"CASE_SENSITIVE\", " +
-			"cast(CASE \"systemname\" WHEN 'table' THEN ").append(DatabaseMetaData.typePredNone)
-				.append(" WHEN 'str' THEN ").append(DatabaseMetaData.typePredChar)
-				.append(" WHEN 'sqlblob' THEN ").append(DatabaseMetaData.typePredChar)
+			"CASE WHEN \"systemname\" IN ('str','json','url') THEN true ELSE false END AS \"CASE_SENSITIVE\", " +
+			"cast(CASE WHEN \"systemname\" IN ('str','inet','json','url','uuid','blob','sqlblob') THEN ").append(DatabaseMetaData.typeSearchable)
 				.append(" ELSE ").append(DatabaseMetaData.typePredBasic).append(" END AS smallint) AS \"SEARCHABLE\", " +
 			"CASE WHEN \"sqlname\" IN ('tinyint','smallint','int','bigint','hugeint','decimal','real','double','sec_interval','month_interval') THEN false ELSE true END AS \"UNSIGNED_ATTRIBUTE\", " +
 			"CASE \"sqlname\" WHEN 'decimal' THEN true ELSE false END AS \"FIXED_PREC_SCALE\", " +
@@ -4174,5 +4188,27 @@ public class MonetDatabaseMetaData exten
 		return true;
 	}
 
+	//== 1.8 methods (JDBC 4.2)
+
+	/**
+	 * Retrieves the maximum number of bytes this database allows for the logical size for a LOB.
+	 * The default implementation will return 0
+	 * @return the maximum number of bytes
+	 */
+	@Override
+	public long getMaxLogicalLobSize() {
+		return 0;
+	}
+
+	/**
+	 * Retrieves whether this database supports REF CURSOR.
+	 * The default implementation will return false
+	 * @return true if so, false otherwise
+	 */
+	@Override
+	public boolean supportsRefCursors() {
+		return false;
+	}
+
 	//== end methods interface DatabaseMetaData
 }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -240,6 +240,24 @@ public final class MonetDriver implement
 		return MONETJDBCCOMPLIANT;
 	}
 
+	/**
+	 * Return the parent Logger of all the Loggers used by this data source.
+	 * This should be the Logger farthest from the root Logger that is
+	 * still an ancestor of all of the Loggers used by this data source.
+	 * Configuring this Logger will affect all of the log messages
+	 * generated by the data source.
+	 * In the worst case, this may be the root Logger.
+	 *
+	 * @return the parent Logger for this data source
+	 * @throws SQLFeatureNotSupportedException if the data source does
+	 *         not use java.util.logging
+	 * @since 1.7
+	 */
+	@Override
+	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+		throw MonetWrapper.newSQLFeatureNotSupportedException("getParentLogger");
+	}
+
 	//== end methods of interface driver
 
 	/** A static Map containing the mapping between MonetDB types and Java SQL types */
@@ -344,22 +362,6 @@ public final class MonetDriver implement
 	}
 
 	/**
-	 * Return the parent Logger of all the Loggers used by this data source.
-	 * This should be the Logger farthest from the root Logger that is
-	 * still an ancestor of all of the Loggers used by this data source.
-	 * Configuring this Logger will affect all of the log messages
-	 * generated by the data source. In the worst case, this may be the root Logger.
-	 *
-	 * @return the parent Logger for this data source
-	 * @throws SQLFeatureNotSupportedException if the data source does not use java.util.logging
-	 * @since 1.7
-	 */
-	@Override
-	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-		throw new SQLFeatureNotSupportedException("java.util.logging not in use", "0A000");
-	}
-
-	/**
 	 * Attempts to make a database connection to the given URL. The driver
 	 * should return "null" if it realizes it is the wrong kind of driver to
 	 * connect to the given URL. This will be common, as when the JDBC driver
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetINET.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetINET.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -30,7 +30,7 @@ import java.util.Map;
  *
  * This implementation of the PreparedStatement interface uses the
  * capabilities of the MonetDB/SQL backend to prepare and execute
- * queries.  The backend takes care of finding the '?'s in the input and
+ * statements.  The backend takes care of finding the '?'s in the input and
  * returns the types it expects for them.
  *
  * An example of a server response on a prepare query is:
@@ -566,7 +566,15 @@ public class MonetPreparedStatement exte
 			 */
 			@Override
 			public String getColumnClassName(int column) throws SQLException {
-				return MonetResultSet.getClassForType(getColumnType(column)).getName();
+				String typeName = getColumnTypeName(column);
+				Map<String,Class<?>> map = getConnection().getTypeMap();
+				Class<?> c;
+				if (map.containsKey(typeName)) {
+					c = (Class)map.get(typeName);
+				} else {
+					c = MonetResultSet.getClassForType(getColumnType(column));
+				}
+				return c.getName();
 			}
 
 			/**
@@ -660,7 +668,6 @@ public class MonetPreparedStatement exte
 					if (column[i] == null)
 						cnt++;
 				}
-
 				return cnt;
 			}
 
@@ -694,11 +701,22 @@ public class MonetPreparedStatement exte
 					case Types.SMALLINT:
 					case Types.INTEGER:
 					case Types.REAL:
+					case Types.FLOAT:
 					case Types.DOUBLE:
+						return true;
 					case Types.BIGINT:
-					case Types.NUMERIC:
-					case Types.DECIMAL:
+						String monettype = getParameterTypeName(param);
+						if (monettype != null) {
+							if ("oid".equals(monettype)
+							 || "ptr".equals(monettype))
+								return false;
+						}
 						return true;
+					case Types.BIT: // we don't use type BIT, it's here for completeness
+					case Types.BOOLEAN:
+					case Types.DATE:
+					case Types.TIME:
+					case Types.TIMESTAMP:
 					default:
 						return false;
 				}
@@ -801,7 +819,7 @@ public class MonetPreparedStatement exte
 
 			/**
 			 * Retrieves the designated parameter's mode.
-			 * For MonetDB/SQL this is currently always unknown.
+			 * For MonetDB/SQL we currently only support INput parameters.
 			 *
 			 * @param param - the first parameter is 1, the second is 2, ...
 			 * @return mode of the parameter; one of
@@ -813,7 +831,7 @@ public class MonetPreparedStatement exte
 			 */
 			@Override
 			public int getParameterMode(int param) throws SQLException {
-				return ParameterMetaData.parameterModeUnknown;
+				return ParameterMetaData.parameterModeIn;
 			}
 		};
 	}
@@ -826,6 +844,8 @@ public class MonetPreparedStatement exte
 	 * @param parameterIndex the first parameter is 1, the second is 2, ...
 	 * @param x an Array object that maps an SQL ARRAY value
 	 * @throws SQLException if a database access error occurs
+	 * @throws SQLFeatureNotSupportedException the JDBC driver does
+	 *         not support this method
 	 */
 	@Override
 	public void setArray(int parameterIndex, Array x) throws SQLException {
@@ -869,6 +889,8 @@ public class MonetPreparedStatement exte
 	 * @param x the Java input stream that contains the ASCII parameter value
 	 * @param length the number of bytes in the stream
 	 * @throws SQLException if a database access error occurs
+	 * @throws SQLFeatureNotSupportedException the JDBC driver does
+	 *         not support this method
 	 */
 	@Override
 	public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
@@ -1396,8 +1418,6 @@ public class MonetPreparedStatement exte
 	 * @param parameterIndex the first parameter is 1, the second is 2, ...
 	 * @param value the parameter value
 	 * @throws SQLException if a database access error occurs
-	 * @throws SQLFeatureNotSupportedException the JDBC driver does
-	 *         not support this method
 	 */
 	@Override
 	public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
@@ -1414,8 +1434,6 @@ public class MonetPreparedStatement exte
 	 * @param value the parameter value
 	 * @param length the number of characters in the parameter data.
 	 * @throws SQLException if a database access error occurs
-	 * @throws SQLFeatureNotSupportedException the JDBC driver does
-	 *         not support this method
 	 */
 	@Override
 	public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
@@ -1487,8 +1505,6 @@ public class MonetPreparedStatement exte
 	 * @param parameterIndex the first parameter is 1, the second is 2, ...
 	 * @param value the parameter value
 	 * @throws SQLException if a database access error occurs
-	 * @throws SQLFeatureNotSupportedException the JDBC driver does
-	 *         not support this method
 	 */
 	@Override
 	public void setNString(int parameterIndex, String value) throws SQLException {
@@ -1619,6 +1635,8 @@ public class MonetPreparedStatement exte
 	 *              reader.  For all other types, this value will be
 	 *              ignored.
 	 * @throws SQLException if a database access error occurs
+	 * @throws SQLFeatureNotSupportedException the JDBC driver does
+	 *         not support this method
 	 * @see Types
 	 */
 	@Override
@@ -2377,6 +2395,8 @@ public class MonetPreparedStatement exte
 	 *          parameter value as two-byte Unicode characters
 	 * @param length the number of bytes in the stream
 	 * @throws SQLException if a database access error occurs
+	 * @throws SQLFeatureNotSupportedException the JDBC driver does
+	 *         not support this method
 	 */
 	@Override
 	@Deprecated
@@ -2493,16 +2513,4 @@ public class MonetPreparedStatement exte
 	private static final SQLDataException newSQLInvalidParameterIndexException(int paramIdx) {
 		return new SQLDataException("Invalid Parameter Index number: " + paramIdx, "22010");
 	}
-
-	/**
-	 * Small helper method that formats the "Method ... not implemented" message
-	 * and creates a new SQLFeatureNotSupportedException object
-	 * whose SQLState is set to "0A000": feature not supported.
-	 *
-	 * @param name the method name
-	 * @return a new created SQLFeatureNotSupportedException object with SQLState 0A000
-	 */
-	private static final SQLFeatureNotSupportedException newSQLFeatureNotSupportedException(String name) {
-		return new SQLFeatureNotSupportedException("Method " + name + " not implemented", "0A000");
-	}
 }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -474,7 +474,6 @@ public class MonetResultSet extends Mone
 	 * @return a java.io.Reader object that contains the column value; if the value is SQL NULL, the value returned is
 	 * null in the Java programming language.
 	 * @throws SQLException if a database access error occurs
-	 * @throws SQLFeatureNotSupportedException the JDBC driver does not support this method
 	 */
 	@Override
 	public Reader getNCharacterStream(int columnIndex) throws SQLException {
@@ -489,8 +488,6 @@ public class MonetResultSet extends Mone
 	 * @return a java.io.Reader object that contains the column value; if the value is SQL NULL, the value returned is
 	 * null in the Java programming language.
 	 * @throws SQLException if a database access error occurs
-	 * @throws SQLFeatureNotSupportedException the JDBC driver does
-	 *         not support this method
 	 */
 	@Override
 	public Reader getNCharacterStream(String columnLabel) throws SQLException {
@@ -2266,8 +2263,12 @@ public class MonetResultSet extends Mone
 	 * @param columnIndex the first column is 1, the second is 2, ...
 	 * @param type Class representing the Java data type to convert the designated column to
 	 * @return an instance of type holding the column value
-	 * @throws SQLException if conversion is not supported, type is null or another error occurs. The getCause() method
-	 * of the exception may provide a more detailed exception, for example, if a conversion error occurs
+	 * @throws SQLException if conversion is not supported, type is
+	 *         null or another error occurs. The getCause() method of
+	 *         the exception may provide a more detailed exception, for
+	 *         example, if a conversion error occurs
+	 * @throws SQLFeatureNotSupportedException the JDBC driver does
+	 *         not support this method
 	 */
 	@Override
 	@SuppressWarnings("unchecked")
@@ -2293,8 +2294,12 @@ public class MonetResultSet extends Mone
 	 * specified, then the label is the name of the column
 	 * @param type Class representing the Java data type to convert the designated column to
 	 * @return an instance of type holding the column value
-	 * @throws SQLException if conversion is not supported, type is null or another error occurs. The getCause() method
-	 * of the exception may provide a more detailed exception, for example, if a conversion error occurs
+	 * @throws SQLException if conversion is not supported, type is
+	 *         null or another error occurs. The getCause() method of
+	 *         the exception may provide a more detailed exception, for
+	 *         example, if a conversion error occurs
+	 * @throws SQLFeatureNotSupportedException the JDBC driver does
+	 *         not support this method
 	 */
 	@Override
 	public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
@@ -2568,7 +2573,6 @@ public class MonetResultSet extends Mone
 	 * @param columnIndex the first column is 1, the second is 2, ...
 	 * @return the column value; if the value is SQL NULL, the value returned is null
 	 * @throws SQLException if there is no such column
-	 * @throws SQLFeatureNotSupportedException the JDBC driver does not support this method
 	 */
 	@Override
 	public String getNString(int columnIndex) throws SQLException {
@@ -2584,7 +2588,6 @@ public class MonetResultSet extends Mone
 	 * @param columnLabel the SQL name of the column
 	 * @return the column value; if the value is SQL NULL, the value returned is null
 	 * @throws SQLException if the ResultSet object does not contain columnLabel
-	 * @throws SQLFeatureNotSupportedException the JDBC driver does not support this method
 	 */
 	@Override
 	public String getNString(String columnLabel) throws SQLException {
@@ -3208,7 +3211,6 @@ public class MonetResultSet extends Mone
 	 *
 	 * Throws:
 	 *     SQLException - if a database access error occurs or this method is called on a closed result set
-	 *     SQLFeatureNotSupportedException - if the JDBC driver does not support this method
 	 * Since: 1.2
 	 * See Also: DatabaseMetaData.deletesAreDetected(int)
 	 */
@@ -3228,7 +3230,6 @@ public class MonetResultSet extends Mone
 	 *
 	 * Throws:
 	 *     SQLException - if a database access error occurs or this method is called on a closed result set
-	 *     SQLFeatureNotSupportedException - if the JDBC driver does not support this method
 	 * Since: 1.2
 	 * See Also: DatabaseMetaData.insertsAreDetected(int)
 	 */
@@ -3248,7 +3249,6 @@ public class MonetResultSet extends Mone
 	 *
 	 * Throws:
 	 *     SQLException - if a database access error occurs or this method is called on a closed result set
-	 *     SQLFeatureNotSupportedException - if the JDBC driver does not support this method
 	 * Since: 1.2
 	 * See Also: DatabaseMetaData.updatesAreDetected(int)
 	 */
@@ -3258,7 +3258,9 @@ public class MonetResultSet extends Mone
 		return false;
 	}
 
-	/* the next methods are all related to updateable result sets, which we currently do not support */
+	/* Next methods are all related to updateable result sets, which we do not support.
+	 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+	 */
 	@Override
 	public void cancelRowUpdates() throws SQLException {
 		throw newSQLFeatureNotSupportedException("cancelRowUpdates");
@@ -3300,7 +3302,7 @@ public class MonetResultSet extends Mone
 	}
 
 	@Override
-	public void updateAsciiStream(int columnIndex, InputStream xh) throws SQLException {
+	public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
 		throw newSQLFeatureNotSupportedException("updateAsciiStream");
 	}
 
@@ -3675,12 +3677,12 @@ public class MonetResultSet extends Mone
 	}
 
 	@Override
-	public void updateSQLXML(String columnLabel, SQLXML x) throws SQLException {
+	public void updateSQLXML(int columnIndex, SQLXML x) throws SQLException {
 		throw newSQLFeatureNotSupportedException("updateSQLXML");
 	}
 
 	@Override
-	public void updateSQLXML(int columnIndex, SQLXML x) throws SQLException {
+	public void updateSQLXML(String columnLabel, SQLXML x) throws SQLException {
 		throw newSQLFeatureNotSupportedException("updateSQLXML");
 	}
 
@@ -3758,17 +3760,6 @@ public class MonetResultSet extends Mone
 	}
 
 	/**
-	 * Small helper method that formats the "Method ... not implemented" message
-	 * and creates a new SQLFeatureNotSupportedException object whose SQLState is set to "0A000": feature not supported.
-	 *
-	 * @param name the method name
-	 * @return a new created SQLFeatureNotSupportedException object with SQLState 0A000
-	 */
-	private static final SQLFeatureNotSupportedException newSQLFeatureNotSupportedException(String name) {
-		return new SQLFeatureNotSupportedException("Method " + name + " not implemented", "0A000");
-	}
-
-	/**
 	 * Small helper method that formats the "Could not convert value to a number" message
 	 * and creates a new SQLDataException object whose SQLState is set
 	 * to "22003": Numeric value out of range.
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetSavepoint.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetSavepoint.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
@@ -39,7 +39,7 @@ import java.util.concurrent.locks.Reentr
  * 
  * The current state of this Statement is that it only implements the
  * executeQuery() which returns a ResultSet where from results can be
- * read and executeUpdate() which doesn't return the affected rows.
+ * read and executeUpdate() which returns the affected rows for DML.
  * Commit and rollback are implemented, as is the autoCommit mechanism
  * which relies on server side auto commit.
  * Multi-result queries are supported using the getMoreResults() method.
@@ -335,7 +335,7 @@ public class MonetStatement extends Mone
 	 *        using the method getGeneratedKeys; one of the following
 	 *        constants: Statement.RETURN_GENERATED_KEYS or
 	 *        Statement.NO_GENERATED_KEYS
-	 * @return true if the first result is a ResultSet  object; false if
+	 * @return true if the first result is a ResultSet object; false if
 	 *         it is an update count or there are no results
 	 * @throws SQLException - if a database access error occurs or the
 	 *         second parameter supplied to this method is not
@@ -368,7 +368,7 @@ public class MonetStatement extends Mone
 	 *
 	 * The execute method executes an SQL statement and indicates the
 	 * form of the first result. You must then use the methods
-	 * getResultSet or getUpdateCount  to retrieve the result, and
+	 * getResultSet or getUpdateCount to retrieve the result, and
 	 * getMoreResults to move to any subsequent result(s).
 	 *
 	 * MonetDB only supports returing the generated key for one column,
@@ -410,7 +410,7 @@ public class MonetStatement extends Mone
 	 *
 	 * The execute method executes an SQL statement and indicates the
 	 * form of the first result. You must then use the methods
-	 * getResultSet or getUpdateCount  to retrieve the result, and
+	 * getResultSet or getUpdateCount to retrieve the result, and
 	 * getMoreResults to move to any subsequent result(s).
 	 *
 	 * MonetDB only supports returing the generated key for one column,
@@ -668,7 +668,7 @@ public class MonetStatement extends Mone
 		types[0] = "STRING";
 		jdbcTypes[0] = MonetDriver.getJdbcSQLType(types[0]);
 
-		if (header instanceof UpdateResponse) {
+		if (header != null && header instanceof UpdateResponse) {
 			long lastid = ((UpdateResponse)header).getLastid();
 			if (lastid == -1) {
 				results = new String[0][1];
@@ -700,7 +700,6 @@ public class MonetStatement extends Mone
 	 *
 	 * @return the current column size limit for columns storing
 	 *         character and binary values; zero means there is no limit
-	 * @throws SQLException if a database access error occurs
 	 * @see #setMaxFieldSize(int max)
 	 */
 	@Override
@@ -715,7 +714,6 @@ public class MonetStatement extends Mone
 	 *
 	 * @return the current maximum number of rows for a ResultSet object
 	 *         produced by this Statement object; zero means there is no limit
-	 * @throws SQLException if a database access error occurs
 	 * @see #setMaxRows(int max)
 	 */
 	@Override
@@ -772,16 +770,15 @@ public class MonetStatement extends Mone
 		}
 		// we default to keep current result, which requires no action
 		header = lastResponseList.getNextResponse();
-
-		return header instanceof ResultSetResponse;
+		return (header != null && header instanceof ResultSetResponse);
 	}
 
 	/**
 	 * Retrieves the number of seconds the driver will wait for a Statement object to execute. If the limit is exceeded,
 	 * a SQLException is thrown.
 	 *
-	 * @return the current query timeout limit in seconds; zero means there is no limit
-	 * @throws SQLException if a database access error occurs
+	 * @return the current query timeout limit in seconds; zero means
+	 *         there is no limit
 	 * @see #setQueryTimeout(int)
 	 */
 	@Override
@@ -798,8 +795,8 @@ public class MonetStatement extends Mone
 	 */
 	@Override
 	public ResultSet getResultSet() throws SQLException {
-		return (header instanceof ResultSetResponse) ? new MonetResultSet(this, (ResultSetResponse)header)
-				: null;
+		return (header != null && header instanceof ResultSetResponse) ?
+				new MonetResultSet(this, (ResultSetResponse)header) : null;
 	}
 
 	/**
@@ -815,8 +812,8 @@ public class MonetStatement extends Mone
 	/**
 	 * Retrieves the result set holdability for ResultSet objects generated by this Statement object.
 	 *
-	 * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
-	 * @throws SQLException if a database access error occurs
+	 * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or
+	 *         ResultSet.CLOSE_CURSORS_AT_COMMIT
 	 */
 	@Override
 	public int getResultSetHoldability() {
@@ -845,10 +842,12 @@ public class MonetStatement extends Mone
 	@Override
 	public int getUpdateCount() throws SQLException {
 		int ret = -1;
-		if (header instanceof UpdateResponse) {
-			ret =  ((UpdateResponse)header).getCount();
-		} else if (header instanceof SchemaResponse) {
-			ret = ((SchemaResponse)header).getState();
+		if (header != null) {
+			if (header instanceof UpdateResponse) {
+				ret =  ((UpdateResponse)header).getCount();
+			} else if (header instanceof SchemaResponse) {
+				ret = ((SchemaResponse)header).getState();
+			}
 		}
 		return ret;
 	}
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetURL.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetURL.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetWrapper.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetWrapper.java
@@ -3,12 +3,13 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.jdbc;
 
 import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
 
 /**
  * A Wrapper class which provide the ability to retrieve the delegate instance
@@ -75,4 +76,16 @@ public class MonetWrapper implements jav
 		}
 		throw new SQLException("Cannot unwrap to interface: " + (iface != null ? iface.getName() : ""), "0A000");
 	}
+
+	/**
+	 * Small helper method that formats the "Method ... not implemented" message
+	 * and creates a new SQLFeatureNotSupportedException object
+	 * whose SQLState is set to "0A000": feature not supported.
+	 *
+	 * @param name the method name
+	 * @return a new created SQLFeatureNotSupportedException object with SQLState 0A000
+	 */
+	static final SQLFeatureNotSupportedException newSQLFeatureNotSupportedException(String name) {
+		return new SQLFeatureNotSupportedException("Method " + name + " not implemented", "0A000");
+	}
 }
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/ControlCommands.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/ControlCommands.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/IMonetDBLanguage.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/IMonetDBLanguage.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/MCLException.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/MCLException.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.helpers;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/ChannelSecurity.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/ChannelSecurity.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.helpers;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/GregorianCalendarParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/GregorianCalendarParser.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.helpers;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/TimestampHelper.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/TimestampHelper.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.helpers;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/AbstractSocket.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/AbstractSocket.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.mapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.mapi;
@@ -323,7 +323,7 @@ public class MapiConnection extends Mone
 		return res;
 	}
 
-	private List<String> connect(String host, int port, String user, String pass, boolean makeConnection)
+	public List<String> connect(String host, int port, String user, String pass, boolean makeConnection)
 			throws IOException, ProtocolException, MCLException {
 		if (ttl-- <= 0)
 			throw new MCLException("Maximum number of redirects reached, aborting connection attempt. Sorry.");
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiLanguage.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiLanguage.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.mapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/OldMapiSocket.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/OldMapiSocket.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.connection.mapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/ProtocolException.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/ProtocolException.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/ServerResponses.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/ServerResponses.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/StarterHeaders.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/StarterHeaders.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiDataBlockResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiDataBlockResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParserHelper.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParserHelper.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/AbstractDataBlockResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/AbstractDataBlockResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.responses;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/AutoCommitResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/AutoCommitResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.responses;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/IIncompleteResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/IIncompleteResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.responses;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/IResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/IResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.responses;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.responses;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/SchemaResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/SchemaResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.responses;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/UpdateResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/UpdateResponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.mcl.responses;
--- a/src/main/java/nl/cwi/monetdb/merovingian/Control.java
+++ b/src/main/java/nl/cwi/monetdb/merovingian/Control.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.merovingian;
--- a/src/main/java/nl/cwi/monetdb/merovingian/MerovingianException.java
+++ b/src/main/java/nl/cwi/monetdb/merovingian/MerovingianException.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.merovingian;
--- a/src/main/java/nl/cwi/monetdb/merovingian/SabaothDB.java
+++ b/src/main/java/nl/cwi/monetdb/merovingian/SabaothDB.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.merovingian;
--- a/src/main/java/nl/cwi/monetdb/util/CmdLineOpts.java
+++ b/src/main/java/nl/cwi/monetdb/util/CmdLineOpts.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.util;
--- a/src/main/java/nl/cwi/monetdb/util/Exporter.java
+++ b/src/main/java/nl/cwi/monetdb/util/Exporter.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.util;
--- a/src/main/java/nl/cwi/monetdb/util/Extract.java
+++ b/src/main/java/nl/cwi/monetdb/util/Extract.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.util;
--- a/src/main/java/nl/cwi/monetdb/util/OptionsException.java
+++ b/src/main/java/nl/cwi/monetdb/util/OptionsException.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.util;
--- a/src/main/java/nl/cwi/monetdb/util/SQLExporter.java
+++ b/src/main/java/nl/cwi/monetdb/util/SQLExporter.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.util;
--- a/src/main/java/nl/cwi/monetdb/util/SQLRestore.java
+++ b/src/main/java/nl/cwi/monetdb/util/SQLRestore.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.util;
--- a/src/main/java/nl/cwi/monetdb/util/XMLExporter.java
+++ b/src/main/java/nl/cwi/monetdb/util/XMLExporter.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 package nl.cwi.monetdb.util;
--- a/tests/BugConcurrent_clients_SF_1504657.java
+++ b/tests/BugConcurrent_clients_SF_1504657.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/BugConcurrent_sequences.java
+++ b/tests/BugConcurrent_sequences.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/BugDatabaseMetaData_Bug_3356.java
+++ b/tests/BugDatabaseMetaData_Bug_3356.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/BugDecimalRound_Bug_3561.java
+++ b/tests/BugDecimalRound_Bug_3561.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/BugExecuteUpdate_Bug_3350.java
+++ b/tests/BugExecuteUpdate_Bug_3350.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/BugResultSetMetaData_Bug_6183.java
+++ b/tests/BugResultSetMetaData_Bug_6183.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
@@ -11,7 +11,7 @@ import java.sql.*;
 public class BugResultSetMetaData_Bug_6183 {
 	static final String dqTblName = "\"my dq_table\"";
 	static final String[] dqColNames = { "\"my space\"", "\"my, comma_space\"", "\"my$dollar\"", "\"my#hash\"", "\"my	tab\""
-			, "\"my	,tab_comma\"", "\"my,	comma_tab\"", "\"my\\\"backslash_doublequote\"", "\"Abc\"", "\" \"", "\"123\"" };
+			, "\"my	,tab_comma\"", "\"my,	comma_tab\"", "\"my\"\"double_doublequote\"", "\"Abc\"", "\" \"", "\"123\"" };
 
 	public static void main(String[] args) throws Exception {
 		// Class.forName("nl.cwi.monetdb.jdbc.MonetDriver");	// not needed anymore for self registering JDBC drivers
--- a/tests/BugSetQueryTimeout_Bug_3357.java
+++ b/tests/BugSetQueryTimeout_Bug_3357.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Bug_Connect_as_voc_getMetaData_Failure_Bug_6388.java
+++ b/tests/Bug_Connect_as_voc_getMetaData_Failure_Bug_6388.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Bug_PrepStmtSetObject_CLOB_6349.java
+++ b/tests/Bug_PrepStmtSetObject_CLOB_6349.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Bug_PrepStmtSetString_6382.java
+++ b/tests/Bug_PrepStmtSetString_6382.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
@@ -14,17 +14,16 @@ import nl.cwi.monetdb.jdbc.MonetURL;
 public class Bug_PrepStmtSetString_6382 {
 	public static void main(String[] args) throws Exception {
 		// Class.forName("nl.cwi.monetdb.jdbc.MonetDriver");	// not needed anymore for self registering JDBC drivers
-		Connection con = DriverManager.getConnection(args[0]);
-		System.out.println("0. true\t" + con.getAutoCommit());
-
+		Connection con = null;
 		Statement stmt = null;
 		PreparedStatement pstmt = null;
-		ParameterMetaData pmd = null;
 		ResultSet rs = null;
-		ResultSetMetaData rsmd = null;
+		final String tableName = "PrepStmtSetString_6382";
 		try {
+			con = DriverManager.getConnection(args[0]);
+			System.out.println("0. true\t" + con.getAutoCommit());
+
 			stmt = con.createStatement();
-			String tableName = "PrepStmtSetString_6382";
 			System.out.println("Creating table " + tableName);
 			stmt.executeUpdate("CREATE TABLE " + tableName + " (myint INT, myvarchar VARCHAR(15), myjson JSON, myuuid UUID, myurl URL, myinet INET)");
 
@@ -37,7 +36,7 @@ public class Bug_PrepStmtSetString_6382 
 
 			System.out.println("Creating a prepared statement with 6 parameters and inserting rows using setInt(), setString(), setNull(), setNString(), setURL(), setObject().");
 			pstmt = con.prepareStatement("INSERT INTO " + tableName + " VALUES (?,?, ? ,?,? , ?)");
-			pmd = pstmt.getParameterMetaData();
+			ParameterMetaData pmd = pstmt.getParameterMetaData();
 			int pcount = pmd.getParameterCount();
 			System.out.println("Prepared Statement has " + pcount + " parameters:" + (pcount != 6 ? " ERROR: Expected 6 parameters!" : ""));
 			for (int p = 1; p <= pcount; p++) {
@@ -65,7 +64,7 @@ public class Bug_PrepStmtSetString_6382 
 			System.out.println("Inserted " + inserted + " row");
 
 			row++;  // row 5
-			pstmt.setLong(1, row);
+			pstmt.setLong(1, (long)row);
 			pstmt.setString(2, "row " + row);
 			pstmt.setNull(4, 0);
 			pstmt.setURL(5, new java.net.URL("https://www.cwi.nl/"));
@@ -110,7 +109,7 @@ public class Bug_PrepStmtSetString_6382 
 
 			System.out.println("List contents of TABLE " + tableName + " after " + row + " rows inserted");
 			rs = stmt.executeQuery("SELECT * FROM " + tableName + " ORDER BY 1");
-			rsmd = rs.getMetaData();
+			ResultSetMetaData rsmd = rs.getMetaData();
 			int colcount = rsmd.getColumnCount();
 			System.out.println("Query has " + colcount + " output columns." + (colcount != 6 ? " ERROR: Expected 6 columns!" : ""));
 			row = 0;
@@ -132,13 +131,10 @@ public class Bug_PrepStmtSetString_6382 
 				System.err.println("FAILED :( " + e.getMessage());
 			System.err.println("ABORTING TEST!!!");
 		} finally {
-			if (rs != null)
-				rs.close();
-			if (pstmt != null)
-				pstmt.close();
-			if (stmt != null)
-				stmt.close();
-			con.close();
+			try { if (rs != null)    rs.close(); } catch (SQLException e) { /* ignore */ }
+			try { if (pstmt != null) pstmt.close(); } catch (SQLException e) { /* ignore */ }
+			try { if (stmt != null)  stmt.close(); } catch (SQLException e) { /* ignore */ }
+			try { if (con != null)   con.close(); } catch (SQLException e) { /* ignore */ }
 		}
 	}
 }
--- a/tests/SQLcopyinto.java
+++ b/tests/SQLcopyinto.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
@@ -90,9 +90,9 @@ public class SQLcopyinto {
 			// System.out.println("host: " + host + " port: " + port + " login: " + login + " passwd: " + passw);
 
 			System.out.println("Before connecting to MonetDB server via MapiSocket");
-			List warning =  server.connect("monetdb", "monetdb");
+			List<String> warning = server.connect(host, port, login, passw, true);
 			if (warning != null) {
-				for (Iterator it = warning.iterator(); it.hasNext(); ) {
+				for (Iterator<String> it = warning.iterator(); it.hasNext(); ) {
 					System.out.println("Warning: " + it.next().toString());
 				}
 			}
new file mode 100644
--- /dev/null
+++ b/tests/Test_CallableStmt.java
@@ -0,0 +1,182 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
+ */
+
+import java.sql.*;
+
+public class Test_CallableStmt {
+	public static void main(String[] args) throws Exception {
+		Connection con = DriverManager.getConnection(args[0]);
+		Statement stmt = null;
+		CallableStatement cstmt = null;
+		try {
+			String tbl_nm = "tbl6402";
+			String proc_nm = "proc6402";
+
+			stmt = con.createStatement();
+
+			// create a test table.
+			stmt.executeUpdate("CREATE TABLE IF NOT EXISTS " + tbl_nm + " (tint int, tdouble double, tbool boolean, tvarchar varchar(15), tclob clob, turl url, tclen int);");
+			System.out.println("Created table: " + tbl_nm);
+
+			// create a procedure with multiple different IN parameters which inserts a row into a table of which one column is computed.
+			stmt.executeUpdate("CREATE PROCEDURE " + proc_nm + " (myint int, mydouble double, mybool boolean, myvarchar varchar(15), myclob clob, myurl url) BEGIN" +
+				" INSERT INTO " + tbl_nm + " (tint, tdouble, tbool, tvarchar, tclob, turl, tclen) VALUES (myint, mydouble, mybool, myvarchar, myclob, myurl, LENGTH(myvarchar) + LENGTH(myclob)); " +
+				"END;");
+			System.out.println("Created procedure: " + proc_nm);
+
+			// make sure we can call the procedure the old way (as string)
+			stmt.executeUpdate("call " + proc_nm + "(1, 1.1, true,'one','ONE', 'www.monetdb.org');");
+			System.out.println("Called procedure (1): " + proc_nm);
+			showContents(con, tbl_nm);
+
+
+			// now use a CallableStament object
+			cstmt = con.prepareCall(" { call " + proc_nm + " (?,?, ?, ? , ?,?) } ;");
+			System.out.println("Prepared Callable procedure: " + proc_nm);
+
+			// specify first set of params
+			cstmt.setInt(1, 2);
+			cstmt.setDouble(2, 2.02);
+			cstmt.setBoolean(3, true);
+			cstmt.setString(4, "Two");
+			Clob myclob = con.createClob();
+			myclob.setString(1, "TWOs");
+			cstmt.setClob(5, myclob);
+			cstmt.setString(6, "http://www.monetdb.org/");
+			cstmt.execute();
+			System.out.println("Called Prepared procedure (1): " + proc_nm);
+			showParams(cstmt);
+			showContents(con, tbl_nm);
+
+			myclob.setString(1, "TREEs");
+			// specify second set of params (some (1 and 3 and 5) are left the same)
+			cstmt.setDouble(2, 3.02);
+			cstmt.setString(4, "Tree");
+			cstmt.setURL(6, new java.net.URL("https://www.monetdb.org/"));
+			cstmt.execute();
+			System.out.println("Called Prepared procedure (2): " + proc_nm);
+			// showParams(cstmt);
+			showContents(con, tbl_nm);
+
+			// specify third set of params (some (1 and 2) are left the same)
+			cstmt.setInt(1, 4);
+			cstmt.setBoolean(3, false);
+			cstmt.setString(4, "Four");
+			cstmt.executeUpdate();
+			System.out.println("Called Prepared procedure (3): " + proc_nm);
+			showContents(con, tbl_nm);
+
+			// test setNull() also
+			cstmt.setNull(3, Types.BOOLEAN);
+			cstmt.setNull(5, Types.CLOB);
+			cstmt.setNull(2, Types.DOUBLE);
+			cstmt.setNull(4, Types.VARCHAR);
+			cstmt.setNull(1, Types.INTEGER);
+			cstmt.executeUpdate();
+			System.out.println("Called Prepared procedure (with NULLs): " + proc_nm);
+			showContents(con, tbl_nm);
+
+
+			System.out.println("Test completed. Cleanup procedure and table.");
+			stmt.execute("DROP PROCEDURE IF EXISTS " + proc_nm + ";");
+			stmt.execute("DROP TABLE     IF EXISTS " + tbl_nm + ";");
+
+		} catch (SQLException e) {
+			System.out.println("main failed: " + e.getMessage());
+			System.out.println("ABORTING TEST");
+		} finally {
+			try {
+				if (cstmt != null)
+					cstmt.close();
+				if (stmt != null)
+					stmt.close();
+			} catch (SQLException e) { /* ignore */ }
+		}
+
+		con.close();
+	}
+
+
+	// some utility methods for showing table content and params meta data
+	static void showContents(Connection con, String tblnm) {
+		Statement stmt = null;
+		ResultSet rs = null;
+		try {
+			stmt = con.createStatement();
+			rs = stmt.executeQuery("SELECT * FROM " + tblnm);
+			if (rs != null) {
+				ResultSetMetaData rsmd = rs.getMetaData();
+				System.out.println("Table " + tblnm + " has " + rsmd.getColumnCount() + " columns:");
+				for (int col = 1; col <= rsmd.getColumnCount(); col++) {
+					System.out.print("\t" + rsmd.getColumnLabel(col));
+				}
+				System.out.println();
+				while (rs.next()) {
+					for (int col = 1; col <= rsmd.getColumnCount(); col++) {
+						System.out.print("\t" + rs.getString(col));
+					}
+					System.out.println();
+				}
+			} else
+				System.out.println("failed to execute query: SELECT * FROM " + tblnm);
+		} catch (SQLException e) {
+			System.out.println("showContents failed: " + e.getMessage());
+		} finally {
+			try {
+				if (rs != null)
+					rs.close();
+				if (stmt != null)
+					stmt.close();
+			} catch (SQLException e) { /* ignore */ }
+		}
+	}
+
+	static void showParams(PreparedStatement stmt) {
+		try {
+			ParameterMetaData pmd = stmt.getParameterMetaData();
+			System.out.println(pmd.getParameterCount() + " parameters reported:");
+			for (int parm = 1; parm <= pmd.getParameterCount(); parm++) {
+				System.out.print(parm + ".");
+				int nullable = pmd.isNullable(parm);
+				System.out.println("\tnullable  " + nullable + " (" + paramNullableName(nullable) + ")");
+				System.out.println("\tsigned    " + pmd.isSigned(parm));
+				System.out.println("\tprecision " + pmd.getPrecision(parm));
+				System.out.println("\tscale     " + pmd.getScale(parm));
+				System.out.println("\ttype      " + pmd.getParameterType(parm));
+				System.out.println("\ttypename  " + pmd.getParameterTypeName(parm));
+				System.out.println("\tclassname " + pmd.getParameterClassName(parm));
+				int mode = pmd.getParameterMode(parm);
+				System.out.println("\tmode      " + mode + " (" + paramModeName(mode) + ")");
+			}
+		} catch (SQLException e) {
+			System.out.println("showParams failed: " + e.getMessage());
+		}
+	}
+
+	static String paramNullableName(int nullable) {
+		if (nullable == ParameterMetaData.parameterNoNulls)
+			return "NO";
+		if (nullable == ParameterMetaData.parameterNullable)
+			return "YA";
+		if (nullable == ParameterMetaData.parameterNullableUnknown)
+			return "UNKNOWN";
+		return "INVALID" + nullable;
+	}
+
+	static String paramModeName(int mode) {
+		if (mode == ParameterMetaData.parameterModeIn)
+			return "IN";
+		if (mode == ParameterMetaData.parameterModeInOut)
+			return "INOUT";
+		if (mode == ParameterMetaData.parameterModeOut)
+			return "OUT";
+		if (mode == ParameterMetaData.parameterModeUnknown)
+			return "UNKNOWN";
+		return "INVALID" + mode;
+	}
+}
--- a/tests/Test_Cautocommit.java
+++ b/tests/Test_Cautocommit.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Cforkbomb.java
+++ b/tests/Test_Cforkbomb.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_CisValid.java
+++ b/tests/Test_CisValid.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Clargequery.java
+++ b/tests/Test_Clargequery.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Cmanycon.java
+++ b/tests/Test_Cmanycon.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Creplysize.java
+++ b/tests/Test_Creplysize.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Csavepoints.java
+++ b/tests/Test_Csavepoints.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Csendthread.java
+++ b/tests/Test_Csendthread.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Ctransaction.java
+++ b/tests/Test_Ctransaction.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Dobjects.java
+++ b/tests/Test_Dobjects.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_FetchSize.java
+++ b/tests/Test_FetchSize.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Int128.java
+++ b/tests/Test_Int128.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.math.BigDecimal;
--- a/tests/Test_PSgeneratedkeys.java
+++ b/tests/Test_PSgeneratedkeys.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PSgetObject.java
+++ b/tests/Test_PSgetObject.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PSlargeamount.java
+++ b/tests/Test_PSlargeamount.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PSlargebatchval.java
+++ b/tests/Test_PSlargebatchval.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PSlargeresponse.java
+++ b/tests/Test_PSlargeresponse.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PSmanycon.java
+++ b/tests/Test_PSmanycon.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PSmetadata.java
+++ b/tests/Test_PSmetadata.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
@@ -56,19 +56,7 @@ public class Test_PSmetadata {
 				System.out.println("\twritable      " + rsmd.isWritable(col));
 			}
 
-			pmd = pstmt.getParameterMetaData();
-			System.out.println("1. 1 parameter:\t" + pmd.getParameterCount());
-			for (int col = 1; col <= pmd.getParameterCount(); col++) {
-				System.out.println("" + col + ".");
-				System.out.println("\tnullable      " + pmd.isNullable(col));
-				System.out.println("\tsigned        " + pmd.isSigned(col));
-				System.out.println("\tprecision     " + pmd.getPrecision(col));
-				System.out.println("\tscale         " + pmd.getScale(col));
-				System.out.println("\ttype          " + pmd.getParameterType(col));
-				System.out.println("\ttypename      " + pmd.getParameterTypeName(col));
-				System.out.println("\tclassname     " + pmd.getParameterClassName(col));
-				System.out.println("\tmode          " + pmd.getParameterMode(col));
-			}
+			showParams(pstmt);
 		} catch (SQLException e) {
 			System.out.println("failed :( "+ e.getMessage());
 			System.out.println("ABORTING TEST!!!");
@@ -77,4 +65,49 @@ public class Test_PSmetadata {
 		con.rollback();
 		con.close();
 	}
+
+	// some utility methods for showing table content and params meta data
+	static void showParams(PreparedStatement stmt) {
+		try {
+			ParameterMetaData pmd = stmt.getParameterMetaData();
+			System.out.println(pmd.getParameterCount() + " parameters reported:");
+			for (int parm = 1; parm <= pmd.getParameterCount(); parm++) {
+				System.out.print(parm + ".");
+				int nullable = pmd.isNullable(parm);
+				System.out.println("\tnullable  " + nullable + " (" + paramNullableName(nullable) + ")");
+				System.out.println("\tsigned    " + pmd.isSigned(parm));
+				System.out.println("\tprecision " + pmd.getPrecision(parm));
+				System.out.println("\tscale     " + pmd.getScale(parm));
+				System.out.println("\ttype      " + pmd.getParameterType(parm));
+				System.out.println("\ttypename  " + pmd.getParameterTypeName(parm));
+				System.out.println("\tclassname " + pmd.getParameterClassName(parm));
+				int mode = pmd.getParameterMode(parm);
+				System.out.println("\tmode      " + mode + " (" + paramModeName(mode) + ")");
+			}
+		} catch (SQLException e) {
+			System.out.println("showParams failed: " + e.getMessage());
+		}
+	}
+
+	static String paramNullableName(int nullable) {
+		if (nullable == ParameterMetaData.parameterNoNulls)
+			return "NO";
+		if (nullable == ParameterMetaData.parameterNullable)
+			return "YA";
+		if (nullable == ParameterMetaData.parameterNullableUnknown)
+			return "UNKNOWN";
+		return "INVALID" + nullable;
+	}
+
+	static String paramModeName(int mode) {
+		if (mode == ParameterMetaData.parameterModeIn)
+			return "IN";
+		if (mode == ParameterMetaData.parameterModeInOut)
+			return "INOUT";
+		if (mode == ParameterMetaData.parameterModeOut)
+			return "OUT";
+		if (mode == ParameterMetaData.parameterModeUnknown)
+			return "UNKNOWN";
+		return "INVALID" + mode;
+	}
 }
--- a/tests/Test_PSsomeamount.java
+++ b/tests/Test_PSsomeamount.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PSsqldata.java
+++ b/tests/Test_PSsqldata.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.net.URL;
--- a/tests/Test_PStimedate.java
+++ b/tests/Test_PStimedate.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PStimezone.java
+++ b/tests/Test_PStimezone.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_PStypes.java
+++ b/tests/Test_PStypes.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Rbooleans.java
+++ b/tests/Test_Rbooleans.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Rmetadata.java
+++ b/tests/Test_Rmetadata.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
@@ -73,10 +73,10 @@ public class Test_Rmetadata {
 	}
 
 	private static String isInstance(Object obj, String type) {
-		if (obj == null)
+		if (obj == null || type == null)
 			return("(null)");
 		try {
-			Class c = Class.forName(type);
+			Class<?> c = Class.forName(type);
 			if (c.isInstance(obj)) {
 				return(obj.getClass().getName() + " is an instance of " + type);
 			} else {
--- a/tests/Test_Rpositioning.java
+++ b/tests/Test_Rpositioning.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Rsqldata.java
+++ b/tests/Test_Rsqldata.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.net.URL;
--- a/tests/Test_Rtimedate.java
+++ b/tests/Test_Rtimedate.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Sbatching.java
+++ b/tests/Test_Sbatching.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Smoreresults.java
+++ b/tests/Test_Smoreresults.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/Test_Wrapper.java
+++ b/tests/Test_Wrapper.java
@@ -3,7 +3,7 @@
  * License, v. 2.0.  If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
  */
 
 import java.sql.*;
--- a/tests/build.xml
+++ b/tests/build.xml
@@ -5,7 +5,7 @@ This Source Code Form is subject to the 
 License, v. 2.0.  If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
 -->
 
 <!--
@@ -120,6 +120,7 @@ Copyright 1997 - July 2008 CWI, August 2
     <antcall target="Test_PStimedate" />
     <antcall target="Test_PStimezone" />
     <antcall target="Test_PStypes" />
+    <antcall target="Test_CallableStmt" />
     <antcall target="Test_Rbooleans" />
     <antcall target="Test_Rmetadata" />
     <antcall target="Test_Rpositioning" />
@@ -159,6 +160,12 @@ Copyright 1997 - July 2008 CWI, August 2
     </antcall>
   </target>
 
+  <target name="Test_CallableStmt">
+    <antcall target="test_class">
+      <param name="test.class" value="Test_CallableStmt" />
+    </antcall>
+  </target>
+
   <target name="Test_Cautocommit">
     <antcall target="test_class">
       <param name="test.class" value="Test_Cautocommit" />
--- a/tests/drop.sql
+++ b/tests/drop.sql
@@ -2,7 +2,7 @@
 -- License, v. 2.0.  If a copy of the MPL was not distributed with this
 -- file, You can obtain one at http://mozilla.org/MPL/2.0/.
 --
--- Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+-- Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
 
 drop table "foreign";
 drop table allnewtriples;
--- a/version.sh
+++ b/version.sh
@@ -4,7 +4,7 @@
 # License, v. 2.0.  If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 #
-# Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
+# Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
 
 if [[ -z $1 ]] ; then
 	echo "Usage: $0 [-w] <(jdbc|mcl)> <(major|minor|suffix|snapshot)=newversion> [...]"