changeset 446:1ae0dc05bce5

Converted 12 more JDBC tests from Bug*.java into "output on exception only" tests and included them into JDBC_API_Tester.java
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 18 Feb 2021 21:12:08 +0100 (2021-02-18)
parents 8867403ec322
children 7147d1252828
files tests/JDBC_API_Tester.java
diffstat 1 files changed, 1420 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/tests/JDBC_API_Tester.java
+++ b/tests/JDBC_API_Tester.java
@@ -9,6 +9,7 @@
 import java.sql.*;
 
 import java.io.StringReader;
+import java.math.BigDecimal;
 import java.nio.charset.Charset;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -23,21 +24,21 @@ import org.monetdb.jdbc.types.URL;
 /**
  * class to test JDBC Driver API methods and behavior of MonetDB server.
  *
- * It combines 30+ tests which were previous individual test programs
+ * It combines 40+ tests which were previous individual test programs
  * into one large test program, reusing the connection.
  * This speeds up testing considerably as the overhead of starting a JVM and
  * loading the java test program class and MonetDB JDBC driver is now reduced
- * to only one time instead of 30+ times.
+ * to only one time instead of 40+ times.
  * Also all output is no longer send to system out/err but collected in a StringBuilder.
  * The contents of it is compared with the expected output at the end of each test.
  * Only when it deviates the output is sent to system out, see compareExpectedOutput().
  *
  * @author Martin van Dinther
- * @version 0.1
+ * @version 0.2
  */
 final public class JDBC_API_Tester {
 	StringBuilder sb;	// buffer to collect the test output
-	final static int sbInitLen = 3416;
+	final static int sbInitLen = 3712;
 	Connection con;	// main connection shared by all tests
 
 	public static void main(String[] args) throws Exception {
@@ -58,6 +59,7 @@ final public class JDBC_API_Tester {
 		jt.Test_Ctransaction();
 		jt.Test_Dobjects();
 		jt.Test_FetchSize();
+	//	jt.Test_Int128();
 		jt.Test_PSgeneratedkeys();
 		jt.Test_PSgetObject();
 		jt.Test_PSlargebatchval();
@@ -78,7 +80,19 @@ final public class JDBC_API_Tester {
 		jt.Test_Sbatching();
 		jt.Test_Smoreresults();
 		jt.Test_Wrapper();
+		jt.BugConcurrent_clients_SF_1504657(con_URL);
+		jt.BugConcurrent_sequences(con_URL);
+		jt.Bug_Connect_as_voc_getMetaData_Failure_Bug_6388(con_URL);
+		jt.BugDatabaseMetaData_Bug_3356();
+		jt.BugDecimalRound_Bug_3561();
+		jt.BugExecuteUpdate_Bug_3350();
+		jt.Bug_IsValid_Timeout_Bug_6782(con_URL);
+		jt.Bug_LargeQueries_6571_6693(con_URL);
+		jt.Bug_PrepStmtSetObject_CLOB_6349();
 		jt.Bug_PrepStmtSetString_6382();
+		jt.Bug_PrepStmt_With_Errors_Jira292();
+		jt.BugResultSetMetaData_Bug_6183();
+		jt.BugSetQueryTimeout_Bug_3357();
 
 		jt.closeConx(jt.con);
 	}
@@ -2643,13 +2657,13 @@ final public class JDBC_API_Tester {
 			"3. d 2004-04-24 to tm: 00:00:00\n" +
 			"3. d 2004-04-24 to dt: 2004-04-24\n" +
 			"4. vc 2004-04-24 11:43:53.654321 to ts: 2004-04-24 11:43:53.654321\n" +
-			"rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"2004-04-24 11:43:53.654321\" at pos: 5\n" +
+			"4. vc 2004-04-24 11:43:53.654321 to tm: rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"2004-04-24 11:43:53.654321\" at pos: 5\n" +
 			"4. vc 2004-04-24 11:43:53.654321 to dt: 2004-04-24\n" +
-			"rs.getTimestamp(colnm) failed with error: parsing failed, found: ':' in: \"11:43:53\" at pos: 3\n" +
+			"5. vc 11:43:53 to ts: rs.getTimestamp(colnm) failed with error: parsing failed, found: ':' in: \"11:43:53\" at pos: 3\n" +
 			"5. vc 11:43:53 to tm: 11:43:53\n" +
-			"rs.getDate(colnm) failed with error: parsing failed, found: ':' in: \"11:43:53\" at pos: 3\n" +
+			"5. vc 11:43:53 to dt: rs.getDate(colnm) failed with error: parsing failed, found: ':' in: \"11:43:53\" at pos: 3\n" +
 			"6. vc 2004-04-24 to ts: 2004-04-24 00:00:00.0\n" +
-			"rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"2004-04-24\" at pos: 5\n" +
+			"6. vc 2004-04-24 to tm: rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"2004-04-24\" at pos: 5\n" +
 			"6. vc 2004-04-24 to dt: 2004-04-24\n" +
 			"11. ts 904-04-24 11:43:53.567000 to ts: 0904-04-24 11:43:53.567\n" +
 			"11. ts 904-04-24 11:43:53.567000 to tm: 11:43:53\n" +
@@ -2670,13 +2684,13 @@ final public class JDBC_API_Tester {
 			"16. d 4-04-24 to tm: 00:00:00\n" +
 			"16. d 4-04-24 to dt: 0004-04-24\n" +
 			"17. vc 904-04-24 11:43:53.567 to ts: 0904-04-24 11:43:53.567\n" +
-			"rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"904-04-24 11:43:53.567\" at pos: 4\n" +
+			"17. vc 904-04-24 11:43:53.567 to tm: rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"904-04-24 11:43:53.567\" at pos: 4\n" +
 			"17. vc 904-04-24 11:43:53.567 to dt: 0904-04-24\n" +
 			"18. vc 74-04-24 11:43:53.567 to ts: 0074-04-24 11:43:53.567\n" +
-			"rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"74-04-24 11:43:53.567\" at pos: 3\n" +
+			"18. vc 74-04-24 11:43:53.567 to tm: rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"74-04-24 11:43:53.567\" at pos: 3\n" +
 			"18. vc 74-04-24 11:43:53.567 to dt: 0074-04-24\n" +
 			"19. vc 4-04-24 11:43:53.567 to ts: 0004-04-24 11:43:53.567\n" +
-			"rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"4-04-24 11:43:53.567\" at pos: 2\n" +
+			"19. vc 4-04-24 11:43:53.567 to tm: rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"4-04-24 11:43:53.567\" at pos: 2\n" +
 			"19. vc 4-04-24 11:43:53.567 to dt: 0004-04-24\n" +
 			"21. ts -4-04-24 11:43:53.567000 to ts: 0004-04-24 11:43:53.567\n" +
 			"21. ts -4-04-24 11:43:53.567000 to tm: 11:43:53\n" +
@@ -2691,10 +2705,10 @@ final public class JDBC_API_Tester {
 			"24. d -3004-04-24 to tm: 00:00:00\n" +
 			"24. d -3004-04-24 to dt: 3004-04-24\n" +
 			"25. vc -2004-04-24 11:43:53.654321 to ts: 2004-04-24 11:43:53.654321\n" +
-			"rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"-2004-04-24 11:43:53.654321\" at pos: 6\n" +
+			"25. vc -2004-04-24 11:43:53.654321 to tm: rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"-2004-04-24 11:43:53.654321\" at pos: 6\n" +
 			"25. vc -2004-04-24 11:43:53.654321 to dt: 2004-04-24\n" +
 			"26. vc -3004-04-24 to ts: 3004-04-24 00:00:00.0\n" +
-			"rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"-3004-04-24\" at pos: 6\n" +
+			"26. vc -3004-04-24 to tm: rs.getTime(colnm) failed with error: parsing failed, found: '-' in: \"-3004-04-24\" at pos: 6\n" +
 			"26. vc -3004-04-24 to dt: 3004-04-24\n" +
 			"0. true	true\n");
 	}
@@ -2710,7 +2724,7 @@ final public class JDBC_API_Tester {
 
 		// getTimestamp() may raise a conversion warning when the value is of type Time or a String which doesn't match format yyyy-mm-dd hh:mm:ss
 		try {
-			sb.append(data + "ts: " + rs.getTimestamp(colnm)).append("\n");
+			sb.append(data).append("ts: ").append(rs.getTimestamp(colnm)).append("\n");
 		} catch (SQLException e) {
 			sb.append("rs.getTimestamp(colnm) failed with error: ").append(e.getMessage()).append("\n");
 		}
@@ -2719,7 +2733,7 @@ final public class JDBC_API_Tester {
 
 		// getTime() may raise a conversion warning when the value is of type Date or a String which doesn't match format hh:mm:ss
 		try {
-			sb.append(data + "tm: " + rs.getTime(colnm)).append("\n");
+			sb.append(data).append("tm: ").append(rs.getTime(colnm)).append("\n");
 		} catch (SQLException e) {
 			sb.append("rs.getTime(colnm) failed with error: ").append(e.getMessage()).append("\n");
 		}
@@ -2728,7 +2742,7 @@ final public class JDBC_API_Tester {
 
 		// getDate() may raise a conversion warning when the value is of type Time or a String which doesn't match format yyyy-mm-dd
 		try {
-			sb.append(data + "dt: " + rs.getDate(colnm)).append("\n");
+			sb.append(data).append("dt: ").append(rs.getDate(colnm)).append("\n");
 		} catch (SQLException e) {
 			sb.append("rs.getDate(colnm) failed with error: ").append(e.getMessage()).append("\n");
 		}
@@ -3030,6 +3044,932 @@ final public class JDBC_API_Tester {
 		}
 	}
 
+	private void BugConcurrent_clients_SF_1504657(String arg0) {
+		sb.setLength(0);	// clear the output log buffer
+
+		Connection con1 = null, con2 = null, con3 = null;
+		Statement stmt1 = null, stmt2 = null, stmt3 = null;
+		ResultSet rs1 = null, rs2= null, rs3 = null;
+		try {
+			con1 = DriverManager.getConnection(arg0);
+			con2 = DriverManager.getConnection(arg0);
+			con3 = DriverManager.getConnection(arg0);
+			stmt1 = con1.createStatement();
+			stmt2 = con2.createStatement();
+			stmt3 = con3.createStatement();
+
+			// >> true: auto commit should be on by default
+			sb.append("0. true\t").append(con1.getAutoCommit()).append("\n");
+			sb.append("0. true\t").append(con2.getAutoCommit()).append("\n");
+			sb.append("0. true\t").append(con3.getAutoCommit()).append("\n");
+
+			// test the creation of a table with concurrent clients
+			sb.append("1.1. create table t1 using client 1...").append("\n");
+			stmt1.executeUpdate("CREATE TABLE t1 ( id int, name varchar(1024) )");
+			sb.append("passed :)").append("\n");
+
+			sb.append("1.2. check table existence in client 2...").append("\n");
+			rs2 = stmt2.executeQuery("SELECT name FROM tables where name LIKE 't1'");
+			while (rs2.next())
+				sb.append(rs2.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("1.3. check table existence in client 3...").append("\n");
+			rs3 = stmt3.executeQuery("SELECT name FROM tables where name LIKE 't1'");
+			while (rs3.next())
+				sb.append(rs3.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			// test the insertion of values with concurrent clients
+			sb.append("2 insert into t1 using client 1...").append("\n");
+			stmt1.executeUpdate("INSERT INTO t1 values( 1, 'monetdb' )");
+			sb.append("passed :)").append("\n");
+			stmt1.executeUpdate("INSERT INTO t1 values( 2, 'monet' )");
+			sb.append("passed :)").append("\n");
+			stmt1.executeUpdate("INSERT INTO t1 values( 3, 'mon' )");
+			sb.append("passed :)").append("\n");
+
+			sb.append("2.1. check table status with client 1...").append("\n");
+			rs1 = stmt1.executeQuery("SELECT * FROM t1");
+			while (rs1.next())
+				sb.append(rs1.getInt("id")).append(", ").append(rs1.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("2.2. check table status with client 2...").append("\n");
+			rs2 = stmt2.executeQuery("SELECT * FROM t1");
+			while (rs2.next())
+				sb.append(rs2.getInt("id")).append(", ").append(rs2.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("2.3. check table status with client 3...").append("\n");
+			rs3 = stmt3.executeQuery("SELECT * FROM t1");
+			while (rs3.next())
+				sb.append(rs3.getInt("id")).append(", ").append(rs3.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			// test the insertion of values with concurrent clients
+			sb.append("3 insert into t1 using client 2...").append("\n");
+			stmt2.executeUpdate("INSERT INTO t1 values( 4, 'monetdb' )");
+			sb.append("passed :)").append("\n");
+			stmt2.executeUpdate("INSERT INTO t1 values( 5, 'monet' )");
+			sb.append("passed :)").append("\n");
+			stmt2.executeUpdate("INSERT INTO t1 values( 6, 'mon' )");
+			sb.append("passed :)").append("\n");
+
+			sb.append("3.1. check table status with client 1...").append("\n");
+			rs1 = stmt1.executeQuery("SELECT * FROM t1");
+			while (rs1.next())
+				sb.append(rs1.getInt("id")).append(", ").append(rs1.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("3.2. check table status with client 2...").append("\n");
+			rs2 = stmt2.executeQuery("SELECT * FROM t1");
+			while (rs2.next())
+				sb.append(rs2.getInt("id")).append(", ").append(rs2.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("3.3. check table status with client 3...").append("\n");
+			rs3 = stmt3.executeQuery("SELECT * FROM t1");
+			while (rs3.next())
+				sb.append(rs3.getInt("id")).append(", ").append(rs3.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			// test the insertion of values with concurrent clients
+			sb.append("4 insert into t1 using client 3...").append("\n");
+			stmt3.executeUpdate("INSERT INTO t1 values( 7, 'monetdb' )");
+			sb.append("passed :)").append("\n");
+			stmt3.executeUpdate("INSERT INTO t1 values( 8, 'monet' )");
+			sb.append("passed :)").append("\n");
+			stmt3.executeUpdate("INSERT INTO t1 values( 9, 'mon' )");
+			sb.append("passed :)").append("\n");
+
+			sb.append("4.1. check table status with client 1...").append("\n");
+			rs1 = stmt1.executeQuery("SELECT * FROM t1");
+			while (rs1.next())
+				sb.append(rs1.getInt("id")).append(", ").append(rs1.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("4.2. check table status with client 2...").append("\n");
+			rs2 = stmt2.executeQuery("SELECT * FROM t1");
+			while (rs2.next())
+				sb.append(rs2.getInt("id")).append(", ").append(rs2.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("4.3. check table status with client 3...").append("\n");
+			rs3 = stmt3.executeQuery("SELECT * FROM t1");
+			while (rs3.next())
+				sb.append(rs3.getInt("id")).append(", ").append(rs3.getString("name")).append("\n");
+			sb.append("passed :)").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		// cleanup
+		try {
+			sb.append("Cleanup TABLE t1").append("\n");
+			stmt3.executeUpdate("DROP TABLE t1");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		closeStmtResSet(stmt3, rs3);
+		closeStmtResSet(stmt1, rs1);
+		closeStmtResSet(stmt2, rs2);
+
+		closeConx(con2);
+		closeConx(con1);
+		closeConx(con3);
+
+		compareExpectedOutput("BugConcurrent_clients_SF_1504657",
+				"0. true	true\n" +
+				"0. true	true\n" +
+				"0. true	true\n" +
+				"1.1. create table t1 using client 1...\n" +
+				"passed :)\n" +
+				"1.2. check table existence in client 2...\n" +
+				"t1\n" +
+				"passed :)\n" +
+				"1.3. check table existence in client 3...\n" +
+				"t1\n" +
+				"passed :)\n" +
+				"2 insert into t1 using client 1...\n" +
+				"passed :)\n" +
+				"passed :)\n" +
+				"passed :)\n" +
+				"2.1. check table status with client 1...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"passed :)\n" +
+				"2.2. check table status with client 2...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"passed :)\n" +
+				"2.3. check table status with client 3...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"passed :)\n" +
+				"3 insert into t1 using client 2...\n" +
+				"passed :)\n" +
+				"passed :)\n" +
+				"passed :)\n" +
+				"3.1. check table status with client 1...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"4, monetdb\n" +
+				"5, monet\n" +
+				"6, mon\n" +
+				"passed :)\n" +
+				"3.2. check table status with client 2...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"4, monetdb\n" +
+				"5, monet\n" +
+				"6, mon\n" +
+				"passed :)\n" +
+				"3.3. check table status with client 3...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"4, monetdb\n" +
+				"5, monet\n" +
+				"6, mon\n" +
+				"passed :)\n" +
+				"4 insert into t1 using client 3...\n" +
+				"passed :)\n" +
+				"passed :)\n" +
+				"passed :)\n" +
+				"4.1. check table status with client 1...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"4, monetdb\n" +
+				"5, monet\n" +
+				"6, mon\n" +
+				"7, monetdb\n" +
+				"8, monet\n" +
+				"9, mon\n" +
+				"passed :)\n" +
+				"4.2. check table status with client 2...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"4, monetdb\n" +
+				"5, monet\n" +
+				"6, mon\n" +
+				"7, monetdb\n" +
+				"8, monet\n" +
+				"9, mon\n" +
+				"passed :)\n" +
+				"4.3. check table status with client 3...\n" +
+				"1, monetdb\n" +
+				"2, monet\n" +
+				"3, mon\n" +
+				"4, monetdb\n" +
+				"5, monet\n" +
+				"6, mon\n" +
+				"7, monetdb\n" +
+				"8, monet\n" +
+				"9, mon\n" +
+				"passed :)\n" +
+				"Cleanup TABLE t1\n");
+	}
+
+	private void BugConcurrent_sequences(String arg0) {
+		sb.setLength(0);	// clear the output log buffer
+
+		Connection con1 = null, con2 = null;
+		Statement stmt1 = null, stmt2 = null;
+		ResultSet rs1 = null, rs2 = null;
+		try {
+			con1 = DriverManager.getConnection(arg0);
+			con2 = DriverManager.getConnection(arg0);
+			stmt1 = con1.createStatement();
+			stmt2 = con2.createStatement();
+
+			// >> true: auto commit should be on by default
+			sb.append("0. true\t").append(con1.getAutoCommit()).append("\n");
+			sb.append("0. true\t").append(con2.getAutoCommit()).append("\n");
+
+			// create a table
+			sb.append("1. create table t1 using client 1... ");
+			stmt1.executeUpdate("CREATE TABLE t1 ( id serial, who varchar(12) )");
+			sb.append("passed :)").append("\n");
+
+			// test the insertion of values with concurrent clients
+			sb.append("2. insert into t1 using client 1 and 2... ");
+			stmt1.executeUpdate("INSERT INTO t1(who) VALUES('client1')");
+			sb.append("client 1 passed :)").append("\n");
+			con2.setAutoCommit(false);
+			stmt2.executeUpdate("INSERT INTO t1(who) VALUES('client2')");
+			sb.append("transaction on client 2 :)").append("\n");
+			stmt1.executeUpdate("INSERT INTO t1(who) VALUES('client1')");
+			sb.append("client 1 passed :)").append("\n");
+			try {
+				con2.commit();
+				sb.append("transaction client 2 PASSED :(").append("\n");
+			} catch (SQLException e) {
+				sb.append("transaction client 2 failed :)").append("\n");
+			}
+			con2.setAutoCommit(true);
+			stmt2.executeUpdate("INSERT INTO t1(who) VALUES('client2')");
+			sb.append("passed :)").append("\n");
+
+			sb.append("2.1. check table status with client 1...").append("\n");
+			rs1 = stmt1.executeQuery("SELECT * FROM t1");
+			while (rs1.next())
+				sb.append(rs1.getInt("id")).append(", ").append(rs1.getString("who")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			sb.append("2.2. check table status with client 2...").append("\n");
+			rs2 = stmt2.executeQuery("SELECT * FROM t1");
+			while (rs2.next())
+				sb.append(rs2.getInt("id")).append(", ").append(rs2.getString("who")).append("\n");
+			sb.append("passed :)").append("\n");
+
+			// drop the table (not dropping the sequence) from client 1
+			sb.append("3.1. drop table t1 using client 1... ");
+			stmt1.executeUpdate("DROP TABLE t1");
+			sb.append("passed :)").append("\n");
+
+			sb.append("3.1. recreate t1 using client 1... ");
+			stmt1.executeUpdate("CREATE TABLE t1 ( id serial, who varchar(12) )");
+			sb.append("passed :)").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		try {
+			// re-establish connection
+			sb.append("x. Reconnecting client 1 and 2... ");
+			con1.close();
+			con2.close();
+			con1 = DriverManager.getConnection(arg0);
+			con2 = DriverManager.getConnection(arg0);
+			stmt1 = con1.createStatement();
+			stmt2 = con2.createStatement();
+			sb.append("passed :)").append("\n");
+
+			// insert and print, should get 1,2
+			sb.append("4. insert into t1 using client 1 and 2...").append("\n");
+			stmt1.executeUpdate("INSERT INTO t1(who) VALUES('client1')");
+			sb.append("passed :)").append("\n");
+			con2.setAutoCommit(false);
+			stmt2.executeUpdate("INSERT INTO t1(who) VALUES('client2')");
+			con2.commit();
+			con2.setAutoCommit(true);
+			sb.append("passed :)").append("\n");
+
+			sb.append("4.1. check table status with client 1...").append("\n");
+			rs1 = stmt1.executeQuery("SELECT * FROM t1 ORDER BY who");
+			for (int cntr = 1; rs1.next(); cntr++) {
+				int id = rs1.getInt("id");
+				sb.append(id).append(", ").append(rs1.getString("who")).append("\n");
+				if (id != cntr)
+					sb.append("!! expected ").append(cntr).append(", got ").append(id);
+			}
+			sb.append("passed :)").append("\n");
+
+			sb.append("4.2. check table status with client 2...").append("\n");
+			rs2 = stmt2.executeQuery("SELECT * FROM t1 ORDER BY who");
+			for (int cntr = 1; rs2.next(); cntr++) {
+				int id = rs2.getInt("id");
+				sb.append(id).append(", ").append(rs2.getString("who")).append("\n");
+				if (id != cntr)
+					sb.append("!! expected ").append(cntr).append(", got ").append(id);
+			}
+			sb.append("passed :)").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		// cleanup
+		try {
+			sb.append("Cleanup TABLE t1").append("\n");
+			stmt2.executeUpdate("DROP TABLE t1");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		closeStmtResSet(stmt1, rs1);
+		closeStmtResSet(stmt2, rs2);
+
+		closeConx(con2);
+		closeConx(con1);
+
+		compareExpectedOutput("BugConcurrent_sequences",
+				"0. true	true\n" +
+				"0. true	true\n" +
+				"1. create table t1 using client 1... passed :)\n" +
+				"2. insert into t1 using client 1 and 2... client 1 passed :)\n" +
+				"transaction on client 2 :)\n" +
+				"client 1 passed :)\n" +
+				"transaction client 2 failed :)\n" +
+				"passed :)\n" +
+				"2.1. check table status with client 1...\n" +
+				"1, client1\n" +
+				"3, client1\n" +
+				"4, client2\n" +
+				"passed :)\n" +
+				"2.2. check table status with client 2...\n" +
+				"1, client1\n" +
+				"3, client1\n" +
+				"4, client2\n" +
+				"passed :)\n" +
+				"3.1. drop table t1 using client 1... passed :)\n" +
+				"3.1. recreate t1 using client 1... passed :)\n" +
+				"x. Reconnecting client 1 and 2... passed :)\n" +
+				"4. insert into t1 using client 1 and 2...\n" +
+				"passed :)\n" +
+				"passed :)\n" +
+				"4.1. check table status with client 1...\n" +
+				"1, client1\n" +
+				"2, client2\n" +
+				"passed :)\n" +
+				"4.2. check table status with client 2...\n" +
+				"1, client1\n" +
+				"2, client2\n" +
+				"passed :)\n" +
+				"Cleanup TABLE t1\n");
+	}
+
+	private void Bug_Connect_as_voc_getMetaData_Failure_Bug_6388(String arg0) {
+		sb.setLength(0);	// clear the output log buffer
+
+		Statement stmt1 = null;
+		// create user, schema and alter schema default schema
+		try {
+			sb.append("1. CREATE USER voc").append("\n");
+			stmt1 = con.createStatement();
+			stmt1.executeUpdate("CREATE USER \"voc\" WITH PASSWORD 'voc' NAME 'VOC Explorer' SCHEMA \"sys\"");
+			sb.append("2. CREATE SCHEMA voc").append("\n");
+			stmt1.executeUpdate("CREATE SCHEMA \"voc\" AUTHORIZATION \"voc\"");
+			sb.append("3. ALTER USER voc").append("\n");
+			stmt1.executeUpdate("ALTER USER \"voc\" SET SCHEMA \"voc\"");
+			sb.append("creation succeeded :)").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED creating user and schema voc. ").append(e.getMessage()).append("\n");
+		}
+
+		Connection con2 = null;
+		ResultSet rs2 = null;
+		try {
+			sb.append("4.1. connect as user: voc").append("\n");
+			con2 = DriverManager.getConnection(arg0.replace("=monetdb", "=voc"));
+			sb.append("connected :)").append("\n");
+
+			DatabaseMetaData dbmd = con2.getMetaData();
+
+			sb.append("4.2. getUserName()").append("\n");
+			sb.append("UserName = ").append(dbmd.getUserName()).append("\n");
+
+			sb.append("4.3. getMaxConnections()").append("\n");
+			sb.append("MaxConnections = ").append(dbmd.getMaxConnections()).append("\n");
+
+			sb.append("4.4. getDatabaseProductVersion()").append("\n");
+			String dbmsVersion = dbmd.getDatabaseProductVersion();	// should be 11.35.1 or higher
+			boolean postNov2019 = ("11.35.1".compareTo(dbmsVersion) <= 0);
+			sb.append("DatabaseProductVersion = ").append((postNov2019 ? "11.35.+" : dbmsVersion)).append("\n");
+
+			sb.append("4.5. getDatabaseMajorVersion()").append("\n");
+			sb.append("DatabaseMajorVersion = ").append(dbmd.getDatabaseMajorVersion()).append("\n");	// should be 11
+
+			sb.append("4.6. getDatabaseMinorVersion()").append("\n");
+			int dbmsMinorVersion = dbmd.getDatabaseMinorVersion();	// should be 35 or higher
+			sb.append("DatabaseMinorVersion = ").append((dbmsMinorVersion >= 35 ? "35+" : dbmsMinorVersion)).append("\n");
+
+			sb.append("4.7. getTables(null, 'tmp', null, null)").append("\n");
+			rs2 = dbmd.getTables(null, "tmp", null, null);
+			if (rs2 != null) {
+				sb.append("List Tables in schema tmp:").append("\n");
+				while (rs2.next()) {
+					sb.append(rs2.getString(3)).append("\n");
+				}
+				rs2.close();
+			}
+			sb.append("completed listing Tables in schema tmp").append("\n");
+
+			sb.append("4.8. getTableTypes()").append("\n");
+			rs2 = dbmd.getTableTypes();
+			if (rs2 != null) {
+				sb.append("List TableTypes:").append("\n");
+				while (rs2.next()) {
+					// post Oct2020 releases the STREAM TABLE type is removed, so filter it out for a stable output
+					if (!"STREAM TABLE".equals(rs2.getString(1)))
+						sb.append(rs2.getString(1)).append("\n");
+				}
+				rs2.close();
+			}
+			sb.append("completed listing TableTypes").append("\n");
+
+			sb.append("voc meta data Test completed successfully").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED fetching MonetDatabaseMetaData. ").append(e.getMessage()).append("\n");
+		} finally {
+			try {
+				con2.close();
+			} catch (SQLException e) {
+				sb.append("FAILED to close voc connection. ").append(e.getMessage()).append("\n");
+			}
+		}
+
+		// cleanup: drop user, schema and alter schema default schema in reverse order
+		try {
+			sb.append("Cleanup created objects").append("\n");
+			sb.append("5. ALTER USER voc").append("\n");
+			stmt1.executeUpdate("ALTER USER \"voc\" SET SCHEMA \"sys\"");
+			sb.append("6. DROP SCHEMA voc").append("\n");
+			stmt1.executeUpdate("DROP SCHEMA \"voc\"");
+			sb.append("7. DROP USER voc").append("\n");
+			stmt1.executeUpdate("DROP USER \"voc\"");
+			sb.append("cleanup succeeded :)").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED dropping user and schema voc. ").append(e.getMessage()).append("\n");
+		}
+
+		closeConx(con2);
+		closeStmtResSet(stmt1, null);
+
+		compareExpectedOutput("Bug_Connect_as_voc_getMetaData_Failure_Bug_6388",
+				"1. CREATE USER voc\n" +
+				"2. CREATE SCHEMA voc\n" +
+				"3. ALTER USER voc\n" +
+				"creation succeeded :)\n" +
+				"4.1. connect as user: voc\n" +
+				"connected :)\n" +
+				"4.2. getUserName()\n" +
+				"UserName = voc\n" +
+				"4.3. getMaxConnections()\n" +
+				"MaxConnections = 64\n" +
+				"4.4. getDatabaseProductVersion()\n" +
+				"DatabaseProductVersion = 11.35.+\n" +
+				"4.5. getDatabaseMajorVersion()\n" +
+				"DatabaseMajorVersion = 11\n" +
+				"4.6. getDatabaseMinorVersion()\n" +
+				"DatabaseMinorVersion = 35+\n" +
+				"4.7. getTables(null, 'tmp', null, null)\n" +
+				"List Tables in schema tmp:\n" +
+				"_columns\n" +
+				"_tables\n" +
+				"idxs\n" +
+				"keys\n" +
+				"objects\n" +
+				"triggers\n" +
+				"completed listing Tables in schema tmp\n" +
+				"4.8. getTableTypes()\n" +
+				"List TableTypes:\n" +
+				"GLOBAL TEMPORARY TABLE\n" +
+				"LOCAL TEMPORARY TABLE\n" +
+				"MERGE TABLE\n" +
+				"REMOTE TABLE\n" +
+				"REPLICA TABLE\n" +
+				"SYSTEM TABLE\n" +
+				"SYSTEM VIEW\n" +
+				"TABLE\n" +
+				"VIEW\n" +
+				"completed listing TableTypes\n" +
+				"voc meta data Test completed successfully\n" +
+				"Cleanup created objects\n" +
+				"5. ALTER USER voc\n" +
+				"6. DROP SCHEMA voc\n" +
+				"7. DROP USER voc\n" +
+				"cleanup succeeded :)\n");
+	}
+
+	private void BugDatabaseMetaData_Bug_3356() {
+		sb.setLength(0);	// clear the output log buffer
+
+		ResultSet rs = null;
+		try {
+			DatabaseMetaData dbmd = con.getMetaData();
+			rs = dbmd.getColumns("", "sys", "_tables", "id");
+			rs.next();
+			String tableName1 = rs.getString("TABLE_NAME");
+			String tableName2 = rs.getString(3);
+			String isNullable1 = rs.getString("IS_NULLABLE");
+			String isNullable2 = rs.getString(18);
+			sb.append(tableName1).append("\n");
+			sb.append(tableName2).append("\n");
+			sb.append(isNullable1).append("\n");
+			sb.append(isNullable2).append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		closeStmtResSet(null, rs);
+
+		compareExpectedOutput("BugDatabaseMetaData_Bug_3356",
+				"_tables\n" +
+				"_tables\n" +
+				"YES\n" +
+				"YES\n");
+	}
+
+	private void BugDecimalRound_Bug_3561() {
+		sb.setLength(0);	// clear the output log buffer
+
+		Statement stmt1 = null;
+		PreparedStatement pst = null;
+		Statement stmt2 = null;
+		ResultSet rs = null;
+		try {
+			stmt1 = con.createStatement();
+			stmt1.executeUpdate("CREATE TABLE bug3561 (d decimal(14,4))");
+
+			pst = con.prepareStatement("INSERT INTO bug3561 VALUES (?)");
+			pst.setBigDecimal(1, new BigDecimal("112.125"));
+			pst.executeUpdate();
+			pst.setBigDecimal(1, new BigDecimal("212.12345"));
+			pst.executeUpdate();
+			pst.setBigDecimal(1, new BigDecimal("0.012345"));
+			pst.executeUpdate();
+			pst.close();
+
+			stmt2 = con.createStatement();
+			rs = stmt2.executeQuery("SELECT d FROM bug3561");
+			while (rs.next())
+				sb.append(rs.getString(1)).append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+		closeStmtResSet(stmt2, rs);
+		closeStmtResSet(pst, null);
+
+		// cleanup
+		try {
+			stmt1.executeUpdate("DROP TABLE bug3561");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+		closeStmtResSet(stmt1, null);
+
+		compareExpectedOutput("BugDecimalRound_Bug_3561",
+				"112.1250\n" +
+				"212.1235\n" +
+				"0.0123\n");
+	}
+
+	private void BugExecuteUpdate_Bug_3350() {
+		sb.setLength(0);	// clear the output log buffer
+
+		Statement stmt = null;
+		try {
+			con.setAutoCommit(false);	// disable auto commit, so we can roll back the transaction
+			stmt = con.createStatement();
+			stmt.execute("CREATE TABLE t3350 (keyword VARCHAR(30) PRIMARY KEY)");
+			con.commit();
+
+			executeDML(stmt, "INSERT INTO t3350 VALUES ('Bug_3350')"); // should insert 1 row
+			executeDML(stmt, "INSERT INTO t3350 VALUES ('Bug_3350')"); // this will result in an SQLException due to PK uniqueness violation
+			con.rollback();
+
+			executeDML(stmt, "INSERT INTO t3350 VALUES ('Bug_3350')"); // should insert 1 row
+			executeDML(stmt, "INSERT INTO t3350 VALUES ('1'), ('x'), ('3'), ('y')"); // should insert 4 rows
+			executeDML(stmt, "DELETE FROM t3350 WHERE \"keyword\" = 'Bug_3350'"); // should delete 1 row
+			executeDML(stmt, "DELETE FROM t3350 WHERE \"keyword\" = 'Bug_3350'"); // should delete 0 rows
+			executeDML(stmt, "UPDATE t3350 set \"keyword\" = keyword||'_ext'"); // should update 4 rows
+			executeDML(stmt, "DELETE FROM t3350"); // should delete 4 rows
+			con.commit();
+
+			stmt.execute("DROP TABLE t3350");
+			con.commit();
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+		closeStmtResSet(stmt, null);
+
+		// cleanup
+		try {
+			con.setAutoCommit(true);	// enable auto commit
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		compareExpectedOutput("BugExecuteUpdate_Bug_3350",
+				"executeUpdate(INSERT ...) returned: 1\n" +
+				"getUpdateCount() returned: 1\n" +
+				"INSERT INTO: PRIMARY KEY constraint 't3350.t3350_keyword_pkey' violated\n" +
+				"getUpdateCount() returned: 1\n" +
+				"executeUpdate(INSERT ...) returned: 1\n" +
+				"getUpdateCount() returned: 1\n" +
+				"executeUpdate(INSERT ...) returned: 4\n" +
+				"getUpdateCount() returned: 4\n" +
+				"executeUpdate(DELETE ...) returned: 1\n" +
+				"getUpdateCount() returned: 1\n" +
+				"executeUpdate(DELETE ...) returned: 0\n" +
+				"getUpdateCount() returned: 0\n" +
+				"executeUpdate(UPDATE ...) returned: 4\n" +
+				"getUpdateCount() returned: 4\n" +
+				"executeUpdate(DELETE ...) returned: 4\n" +
+				"getUpdateCount() returned: 4\n");
+	}
+
+	private void executeDML(Statement st, String sql) {
+		try {
+			int upd_count = st.executeUpdate(sql);
+			sb.append("executeUpdate(").append(sql.substring(0, 6)).append(" ...) returned: ").append(upd_count).append("\n");
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+
+		try {
+			sb.append("getUpdateCount() returned: ").append(st.getUpdateCount()).append("\n");
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+	}
+
+	private void Bug_IsValid_Timeout_Bug_6782(String arg0) {
+		sb.setLength(0);	// clear the output log buffer
+
+		Connection con2 = null;
+		Statement st = null;
+		try {
+			con2 = DriverManager.getConnection(arg0);
+			sb.append("connected :)").append("\n");
+
+			st = con2.createStatement();
+			st.setQueryTimeout(5);
+			sb.append("getQueryTimeout must give 5: ").append(st.getQueryTimeout()).append("\n");
+			st.close();
+
+			con.isValid(6);
+
+			st = con.createStatement();
+			sb.append("getQueryTimeout must give 0: ").append(st.getQueryTimeout()).append("\n");
+
+			con.isValid(4);
+			sb.append("getQueryTimeout must give 0: ").append(st.getQueryTimeout()).append("\n");
+			st.close();
+
+			st.setQueryTimeout(5);
+			con.isValid(3);
+			sb.append("getQueryTimeout must give 5: ").append(st.getQueryTimeout()).append("\n");
+			st.close();
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+		closeStmtResSet(st, null);
+		closeConx(con2);
+
+		compareExpectedOutput("Bug_IsValid_Timeout_Bug_6782",
+				"connected :)\n" +
+				"getQueryTimeout must give 5: 5\n" +
+				"getQueryTimeout must give 0: 0\n" +
+				"getQueryTimeout must give 0: 0\n" +
+				"getQueryTimeout must give 5: 5\n");
+	}
+
+	private void Bug_LargeQueries_6571_6693(String arg0) {
+		sb.setLength(0);	// clear the output log buffer
+
+		// construct a largedata string value. It must larger than the block size of MapiSocket
+		final int num = 9216;
+		final String repeatValue = "$-)";
+		final StringBuilder ldsb = new StringBuilder(num * repeatValue.length());
+		for (int i = 0; i < num; i++)
+			ldsb.append(repeatValue);
+		final String largedata = ldsb.toString();
+		if (largedata.length() <= 8192)
+			sb.append("Length (").append(largedata.length()).append(") of largedata value is too small! Should be larger than 8192!");
+
+		final String tbl_nm = "tbl6693";
+		Statement stmt = null;
+		try {
+			stmt = con.createStatement();
+			// create a test table.
+			stmt.executeUpdate("CREATE TABLE IF NOT EXISTS " + tbl_nm + " (attribute CLOB, value CLOB);");
+			sb.append("Created table: ").append(tbl_nm).append("\n");
+			sb.append("Inserting rows. ");
+			String insertCmd = "INSERT INTO " + tbl_nm + " VALUES ('activeset_default_fiets', '" + largedata + "');";
+			int ins = stmt.executeUpdate(insertCmd);
+			ins += stmt.executeUpdate(insertCmd);
+			ins += stmt.executeUpdate(insertCmd);
+			sb.append(ins).append(" rows inserted").append("\n");
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+		closeStmtResSet(stmt, null);
+
+		final int script_iterations = 10;
+		try {
+			run_tests(arg0, tbl_nm, script_iterations, largedata);
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+
+		try (Statement stmt2 = con.createStatement()) {
+			stmt2.executeUpdate("DROP TABLE IF EXISTS " + tbl_nm);
+			sb.append("Cleaned up TABLE ").append(tbl_nm).append("\n");
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+
+		sb.append("Test completed without hanging").append("\n");
+
+		compareExpectedOutput("Bug_LargeQueries_6571_6693",
+				"Created table: tbl6693\n" +
+				"Inserting rows. 3 rows inserted\n" +
+				"Script size is 83256\n" +
+				"First test repeat 10 times. Iteration: 1 2 3 4 5 6 7 8 9 10 \n" +
+				"Completed first test\n" +
+				"Second test repeat 10 times. Iteration: 1 2 3 4 5 6 7 8 9 10 \n" + 
+				"Completed second test\n" +
+				"Script size is 3012\n" +
+				"Third test repeat 9 times.\n" +
+				"Iteration: 1 2 3 4 5 6 7 8 9 \n" +
+				"Completed third test\n" +
+				"Cleaned up TABLE tbl6693\n" +
+				"Test completed without hanging\n");
+	}
+
+	private void run_tests(String conURL, String tbl_nm, int iterations, String largedata) throws SQLException {
+		String script =
+			  "delete from " + tbl_nm + " where attribute='activeset_default_fiets';\n"
+			+ "insert into " + tbl_nm + " values ('activeset_default_fiets', '" + largedata + "');\n"
+			+ "insert into " + tbl_nm + " values ('activeset_default_fiets', '" + largedata + "');\n"
+			+ "insert into " + tbl_nm + " values ('activeset_default_fiets', '" + largedata + "');\n"
+			+ "select value from " + tbl_nm + " where attribute='activeset_default_fiets';\n";
+		sb.append("Script size is " + script.length()).append("\n");
+
+		// first try to make the execution hang after many iterations of sending large data queries within one connection
+		sb.append("First test repeat " + iterations + " times. ");
+		try (Connection con = DriverManager.getConnection(conURL)) {
+			sb.append("Iteration: ");
+			for (int i = 1; i <= iterations; i++) {
+				sb.append(i).append(" ");
+				try (Statement stmt = con.createStatement()) {
+					process_script(stmt, script, 1, 3, 6);
+				}
+			}
+			sb.append("\n");
+		}
+		sb.append("Completed first test").append("\n");
+
+		// also try to make the execution hang after many iterations of making connections (each their own socket) and sending large scripts
+		sb.append("Second test repeat " + iterations + " times. ");
+		sb.append("Iteration: ");
+		for (int i = 1; i <= iterations; i++) {
+			try (Connection con = DriverManager.getConnection(conURL)) {
+				sb.append(i).append(" ");
+				try (Statement stmt = con.createStatement()) {
+					process_script(stmt, script, 1, 3, 6);
+					process_script(stmt, script, 1, 3, 6);
+					process_script(stmt, script, 1, 3, 6);
+					process_script(stmt, script, 1, 3, 6);
+				}
+			}
+		}
+		sb.append("\n");
+		sb.append("Completed second test").append("\n");
+
+		// next try to make the execution hang by sending very many queries combined in 1 large script
+		final int queries = 260;
+		StringBuilder qry = new StringBuilder(queries * 13);
+		for (int i = 1; i <= queries; i++)
+			qry.append(" SELECT ").append(i).append(';');
+		script = qry.toString();
+		sb.append("Script size is " + script.length()).append("\n");
+		iterations = 9;
+		sb.append("Third test repeat " + iterations + " times.").append("\n");
+		try (Connection con = DriverManager.getConnection(conURL)) {
+			sb.append("Iteration: ");
+			for (int i = 1; i <= iterations; i++) {
+				sb.append(i).append(" ");
+				try (Statement stmt = con.createStatement()) {
+					process_script(stmt, script, queries, queries, 0);
+				}
+			}
+			sb.append("\n");
+		}
+		sb.append("Completed third test").append("\n");
+	}
+
+	private void process_script(Statement stmt, String script,
+				int expectedResults, int expectedTotalRows, int expectedUpdates) throws SQLException {
+		int results = 0;
+		int rows = 0;
+		int updates = 0;
+		stmt.execute(script);
+		do {
+			ResultSet rs = stmt.getResultSet();
+			if (rs != null) {
+				results++;
+				while(rs.next()) {
+					String val = rs.getString(1);
+					rows++;
+				}
+				rs.close();
+			} else {
+				int uc = stmt.getUpdateCount();
+				if (uc > 0)
+					updates += uc;
+			}
+		} while (stmt.getMoreResults() || stmt.getUpdateCount() != -1);
+
+		/* verify nr of processed resultsets and retrieved rows are as expected */
+		if (results != expectedResults)
+			sb.append(results + "!=" + expectedResults + " ");
+		if (rows != expectedTotalRows)
+			sb.append(rows + "!=" + expectedTotalRows + " ");
+		if (updates != expectedUpdates)
+			sb.append(updates + "!=" + expectedUpdates + " ");
+	}
+
+	private void Bug_PrepStmtSetObject_CLOB_6349() {
+		sb.setLength(0);	// clear the output log buffer
+
+		Statement stmt = null;
+		PreparedStatement pstmt = null;
+		ResultSet rs = null;
+		try {
+			sb.append("0. true\t").append(con.getAutoCommit()).append("\n");
+			stmt = con.createStatement();
+			stmt.executeUpdate("CREATE TABLE PrepStmtSetObject_CLOB (myint INT, myvarchar VARCHAR(15), myclob CLOB)");
+			stmt.executeUpdate("INSERT INTO PrepStmtSetObject_CLOB VALUES (123, 'A string', 'A longer string')");
+			stmt.executeUpdate("INSERT INTO PrepStmtSetObject_CLOB VALUES (NULL, NULL, NULL)");  // all NULLs
+
+			pstmt = con.prepareStatement("SELECT myclob, myvarchar, myint FROM PrepStmtSetObject_CLOB WHERE myclob = ?");
+			ParameterMetaData pmd = pstmt.getParameterMetaData();
+			sb.append("Prepared Query has ").append(pmd.getParameterCount()).append(" parameters. Type of first is: ").append(pmd.getParameterTypeName(1)).append("\n");
+			ResultSetMetaData rsmd = pstmt.getMetaData();
+			sb.append("Prepared Query has ").append(rsmd.getColumnCount()).append(" columns. Type of first is: ").append(rsmd.getColumnTypeName(1)).append("\n");
+
+			pstmt.setObject(1, "A longer string");
+			rs = pstmt.executeQuery();
+			rsmd = rs.getMetaData();
+			sb.append("Query ResultSet has ").append(rsmd.getColumnCount()).append(" columns. Type of first is: ").append(rsmd.getColumnTypeName(1)).append("\n");
+
+			boolean has_row = rs.next();
+			boolean has_rows = rs.next();
+			if (has_row == false || has_rows == true)
+				sb.append("Fetching Query ResultSet failed").append("\n");
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+
+		// cleanup
+		try {
+			stmt.executeUpdate("DROP TABLE PrepStmtSetObject_CLOB");
+			sb.append("Table dropped").append("\n");
+		} catch (SQLException se) {
+			sb.append(se.getMessage()).append("\n");
+		}
+		closeStmtResSet(stmt, null);
+		closeStmtResSet(pstmt, rs);
+
+		compareExpectedOutput("Bug_PrepStmtSetObject_CLOB_6349",
+				"0. true	true\n" +
+				"Prepared Query has 1 parameters. Type of first is: clob\n" +
+				"Prepared Query has 3 columns. Type of first is: clob\n" +
+				"Query ResultSet has 3 columns. Type of first is: clob\n" +
+				"Table dropped\n");
+	}
+
 	private void Bug_PrepStmtSetString_6382() {
 		sb.setLength(0);	// clear the output log buffer
 
@@ -3042,7 +3982,7 @@ final public class JDBC_API_Tester {
 			sb.append("0. true\t").append(con.getAutoCommit()).append("\n");
 
 			stmt = con.createStatement();
-			sb.append("1. Creating table " + tableName);
+			sb.append("1. Creating table ").append(tableName);
 			if (stmt.executeUpdate("CREATE TABLE " + tableName + " (myint INT, myvarchar VARCHAR(15), myjson JSON, myuuid UUID, myurl URL, myinet INET)") != Statement.SUCCESS_NO_INFO)
 				sb.append("Wrong return status\n");
 
@@ -3061,9 +4001,9 @@ final public class JDBC_API_Tester {
 			pstmt = con.prepareStatement("INSERT INTO " + tableName + " VALUES (?,?, ? ,?,? , ?)");
 			ParameterMetaData pmd = pstmt.getParameterMetaData();
 			int pcount = pmd.getParameterCount();
-			sb.append("Prepared Statement has " + pcount + " parameters:" + (pcount != 6 ? " ERROR: Expected 6 parameters!" : "")).append("\n");
+			sb.append("Prepared Statement has ").append(pcount).append(" parameters:").append((pcount != 6 ? " ERROR: Expected 6 parameters!" : "")).append("\n");
 			for (int p = 1; p <= pcount; p++) {
-				sb.append(" Parameter " + p + " type is: " + pmd.getParameterTypeName(p) + ". JDBC SQL type: " + pmd.getParameterType(p)).append("\n");
+				sb.append(" Parameter ").append(p).append(" type is: ").append(pmd.getParameterTypeName(p)).append(". JDBC SQL type: ").append(pmd.getParameterType(p)).append("\n");
 			}
 
 			int row = 6;
@@ -3073,18 +4013,18 @@ final public class JDBC_API_Tester {
 			pstmt.setNull(4, 0);
 			pstmt.setNull(5, 0);
 			pstmt.setNull(6, 0);
-			sb.append("Inserting row " + row).append("\n");
+			sb.append("Inserting row ").append(row).append("\n");
 			int inserted = pstmt.executeUpdate();
-			sb.append("Inserted " + inserted + " row").append("\n");
+			sb.append("Inserted ").append(inserted).append(" row").append("\n");
 
 			row++;  // row 7
 			pstmt.setShort(1, (short)row);
 			pstmt.setNString(2, "row " + row);
 			pstmt.setNull(3, 0);
 			pstmt.setString(4, "4a148b7d-8d47-4e1e-a21e-09a71abf2215");
-			sb.append("Inserting row " + row).append("\n");
+			sb.append("Inserting row ").append(row).append("\n");
 			inserted = pstmt.executeUpdate();
-			sb.append("Inserted " + inserted + " row").append("\n");
+			sb.append("Inserted ").append(inserted).append(" row").append("\n");
 
 			row++;  // row 8
 			pstmt.setLong(1, (long)row);
@@ -3096,18 +4036,18 @@ final public class JDBC_API_Tester {
 			} catch (java.net.MalformedURLException mfe) {
 				sb.append(mfe).append("\n");
 			}
-			sb.append("Inserting row " + row).append("\n");
+			sb.append("Inserting row ").append(row).append("\n");
 			inserted = pstmt.executeUpdate();
-			sb.append("Inserted " + inserted + " row").append("\n");
+			sb.append("Inserted ").append(inserted).append(" row").append("\n");
 
 			row++;  // row 9
 			pstmt.setBigDecimal(1, new java.math.BigDecimal(row));
 			pstmt.setNString(2, "row " + row);
 			pstmt.setNull(5, 0);
 			pstmt.setString(6, "127.255.255.255");
-			sb.append("Inserting row " + row).append("\n");
+			sb.append("Inserting row ").append(row).append("\n");
 			inserted = pstmt.executeUpdate();
-			sb.append("Inserted " + inserted + " row").append("\n");
+			sb.append("Inserted ").append(inserted).append(" row").append("\n");
 
 			/* also test generic setObject(int, String) */
 			row++;  // row 10
@@ -3117,9 +4057,9 @@ final public class JDBC_API_Tester {
 			pstmt.setObject(4, "b39dc76e-4faf-4fd9-bc1e-17df48acf764");
 			pstmt.setObject(5, "https://en.wikipedia.org/wiki/IP_address");
 			pstmt.setObject(6, "223.255.255.255");
-			sb.append("Inserting row " + row).append("\n");
+			sb.append("Inserting row ").append(row).append("\n");
 			inserted = pstmt.executeUpdate();
-			sb.append("Inserted " + inserted + " row").append("\n");
+			sb.append("Inserted ").append(inserted).append(" row").append("\n");
 
 			row++;  // row 11
 			pstmt.setObject(1, new java.math.BigDecimal(row));
@@ -3136,20 +4076,20 @@ final public class JDBC_API_Tester {
 			INET myINET = new INET();
 			myINET.fromString("223.234.245.255");
 			pstmt.setObject(6, myINET);
-			sb.append("Inserting row " + row).append("\n");
+			sb.append("Inserting row ").append(row).append("\n");
 			inserted = pstmt.executeUpdate();
-			sb.append("Inserted " + inserted + " row").append("\n");
-
-			sb.append("List contents of TABLE " + tableName + " after " + row + " rows inserted").append("\n");
+			sb.append("Inserted ").append(inserted).append(" row").append("\n");
+
+			sb.append("List contents of TABLE ").append(tableName).append(" after ").append(row).append(" rows inserted").append("\n");
 			rs = stmt.executeQuery("SELECT * FROM " + tableName + " ORDER BY 1");
 			ResultSetMetaData rsmd = rs.getMetaData();
 			int colcount = rsmd.getColumnCount();
-			sb.append("Query has " + colcount + " output columns." + (colcount != 6 ? " ERROR: Expected 6 columns!" : "")).append("\n");
+			sb.append("Query has ").append(colcount).append(" output columns.").append((colcount != 6 ? " ERROR: Expected 6 columns!" : "")).append("\n");
 			row = 0;
 			while (rs.next()) {
-				sb.append("row " + ++row);
+				sb.append("row ").append(++row);
 				for (int c = 1; c <= colcount; c++) {
-					sb.append("\t" + rs.getString(c));
+					sb.append("\t").append(rs.getString(c));
 				}
 				sb.append("\n");
 			}
@@ -3158,7 +4098,7 @@ final public class JDBC_API_Tester {
 		}
 
 		try {
-			sb.append("Cleanup TABLE " + tableName).append("\n");
+			sb.append("Cleanup TABLE ").append(tableName).append("\n");
 			stmt.executeUpdate("DROP TABLE " + tableName);
 		} catch (SQLException e) {
 			sb.append("FAILED: ").append(e.getMessage()).append("\n");
@@ -3234,6 +4174,449 @@ final public class JDBC_API_Tester {
 				"Cleanup TABLE PrepStmtSetString_6382\n");
 	}
 
+	private void Bug_PrepStmt_With_Errors_Jira292() {
+		sb.setLength(0);	// clear the output log buffer
+
+		Statement stmt = null;
+		PreparedStatement pstmt = null;
+		ResultSet rs = null;
+		try {
+			sb.append("0. true\t").append(con.getAutoCommit()).append("\n");
+			con.setNetworkTimeout(null, (10 *1000));
+
+			stmt = con.createStatement();
+			stmt.executeUpdate("drop table if exists abacus;");
+			stmt.executeUpdate("create table abacus ( \"'Zeitachse'\" date,\"'Abo_ID'\" int,\"'description'\" varchar(256),\"'Klassierungs-Typ'\" clob,\"'KlassierungApplikation'\" clob,\"'EP Netto'\" decimal,\"'Nettoumsatz'\" decimal,\"'validfrom'\" date,\"'validuntil'\" date,\"'Abo_aufgeschaltet'\" int,\"'Abo_deaktiviert'\" int,\"'Differenz'\" decimal,\"'User_ID'\" int,\"'UserName'\" varchar(256),\"'client'\" varchar(256),\"'Installations_ID'\" int,\"'InstallationsName'\" varchar(256),\"'Installationsprovider_ID'\" int,\"'InstallationsproviderName'\" varchar(256),\"'INR'\" bigint,\"'NAME'\" varchar(256),\"'PLZ'\" varchar(256),\"'ORT'\" varchar(256),\"'STAAT'\" varchar(256),\"'Reseller_ID'\" int,\"'ResellerName'\" varchar(256),\"'ET_ABO'\" clob,\"'UserName_1'\" varchar(256),\"'Anzahl_Abos'\" decimal,\"'Anzahl_User'\" decimal,\"'Jahr'\" decimal,\"'Monat'\" decimal,\"'Jahr_Monat'\" clob,\"'IFJ'\" clob,\"'RECNUM$'\" int,\"'InlineCalc_Year_Zeitachse'\" int);");
+			stmt.executeUpdate("insert into abacus values ('2019-10-30',2239,'description','Klassierungs-Typ','Klassierung-Applikation',73.28,68.29,'2018-01-01','2018-12-01',563,63,56.3,852,'UserName','client',134,'InstallationsName',892,'InstallationsproviderName',9348,'NAME','PLZ','ORT','STAAT',934,'ResellerName','ET_ABO','UserName_1',849.2739,1742.718,395.824,39.824,'Jahr_Monat','IFJ',395824,3789);");
+
+			sb.append("1. table created and inserted 1 row").append("\n");
+
+			String qry = "SELECT \"'ResellerName'\" FROM abacus WHERE  ( ( (\"'InstallationsproviderName'\"='Bienz Pius Treuhand- und Revisions AG')) AND  ( (\"'validuntil'\"='2018-01-01' AND \"'description'\"='ABEA 2' AND (EXTRACT(YEAR FROM \"'Zeitachse'\")*100 + EXTRACT(MONTH FROM \"'Zeitachse'\"))/100.0='2019.010' AND \"'UserName'\"='AL - Astrid Lincke (Delphys)' AND \"'validfrom'\"='2016-12-01')) AND  ( (\"'IFJ'\"='ohne IFJ')) AND  ( (\"'InlineCalc_Year_Zeitachse'\"='2019'))) GROUP BY \"'ResellerName'\" LIMIT 1001 OFFSET 0;";
+			try {
+				sb.append("2. before select query execution").append("\n");
+				rs = stmt.executeQuery(qry);
+				sb.append("2a. select query executed").append("\n");
+				if (rs != null) {
+					if (rs.next()) {
+						sb.append("2b. select query returned: " + rs.getString(1)).append("\n");
+					}
+					rs.close();
+					rs = null;
+					sb.append("2c. closed select query resultset").append("\n");
+				}
+				sb.append("2d. normal end of select query").append("\n");
+			} catch (SQLException se) {
+				sb.append("select query Exception: "+ se.getMessage()).append("\n");
+				while ((se = se.getNextException()) != null)
+					sb.append("next Exception: "+ se.getMessage()).append("\n");
+			}
+
+			try {
+				sb.append("3. before creating a prepared select query").append("\n");
+				pstmt = con.prepareStatement(qry);
+				sb.append("3a. prepared select query").append("\n");
+
+				ParameterMetaData pmd = pstmt.getParameterMetaData();
+				sb.append("3b. Prepared Query has " + pmd.getParameterCount() + " parameters."); // "Type of first is: " + pmd.getParameterTypeName(1)).append("\n");
+				ResultSetMetaData rsmd = pstmt.getMetaData();
+				sb.append("3c. Prepared Query has " + rsmd.getColumnCount() + " columns. Type of first is: " + rsmd.getColumnTypeName(1)).append("\n");
+
+				sb.append("3d. before executing the prepared select query").append("\n");
+				rs = pstmt.executeQuery();
+				sb.append("3e. prepared select query executed").append("\n");
+				if (rs != null) {
+					rsmd = rs.getMetaData();
+					sb.append("3f. prepared Query ResultSet has " + rsmd.getColumnCount() + " columns. Type of first is: " + rsmd.getColumnTypeName(1)).append("\n");
+
+					if (rs.next()) {
+						sb.append("3g. prepared select query returned: " + rs.getString(1)).append("\n");
+					}
+					rs.close();
+					rs = null;
+					sb.append("3h. closed prepared select query resultset").append("\n");
+				}
+				sb.append("3i. normal end of prepared select query").append("\n");
+			} catch (SQLException se) {
+				sb.append("prepared select query Exception: "+ se.getMessage()).append("\n");
+				while ((se = se.getNextException()) != null)
+					sb.append("next Exception: "+ se.getMessage()).append("\n");
+			}
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		try {
+			sb.append("4. drop table").append("\n");
+			stmt.executeUpdate("drop table abacus");
+			sb.append("5. normal end of test").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		closeStmtResSet(pstmt, rs);
+		closeStmtResSet(stmt, null);
+
+		compareExpectedOutput("Bug_PrepStmt_With_Errors_Jira292",
+				"0. true	true\n" +
+				"1. table created and inserted 1 row\n" +
+				"2. before select query execution\n" +
+				"2a. select query executed\n" +
+				"2c. closed select query resultset\n" +
+				"2d. normal end of select query\n" +
+				"3. before creating a prepared select query\n" +
+				"3a. prepared select query\n" +
+				"3b. Prepared Query has 0 parameters.3c. Prepared Query has 1 columns. Type of first is: varchar\n" +
+				"3d. before executing the prepared select query\n" +
+				"3e. prepared select query executed\n" +
+				"3f. prepared Query ResultSet has 1 columns. Type of first is: varchar\n" +
+				"3h. closed prepared select query resultset\n" +
+				"3i. normal end of prepared select query\n" +
+				"4. drop table\n" +
+				"5. normal end of test\n");
+	}
+
+	private void BugResultSetMetaData_Bug_6183() {
+		sb.setLength(0);	// clear the output log buffer
+
+		final String dqTblName = "\"my dq_table\"";
+		final String[] dqColNames = { "\"my space\"", "\"my, comma_space\"", "\"my$dollar\"", "\"my#hash\"", "\"my	tab\""
+			, "\"my	,tab_comma\"", "\"my,	comma_tab\"", "\"my\"\"double_doublequote\"", "\"Abc\"", "\" \"", "\"123\"" };
+		Statement stmt = null;
+		ResultSet rs = null;
+		try {
+			StringBuilder ctsb = new StringBuilder(30 + (dqColNames.length * (30 + 15)));
+			ctsb.append("CREATE TABLE ").append(dqTblName).append(" (");
+			for (int n = 0; n < dqColNames.length; n++) {
+				ctsb.append(dqColNames[n]);
+				ctsb.append(" varchar(").append(31 + n).append(')');
+				if (n < (dqColNames.length -1))
+					ctsb.append(", ");
+			}
+			ctsb.append(')');
+
+			stmt = con.createStatement();
+			sb.append("1. create table ").append(dqTblName).append("\n");
+			int ret = stmt.executeUpdate(ctsb.toString());
+			if (ret != -2)
+				sb.append(" returned: ").append(ret).append(" (expected -2)").append("\n");
+
+			String tblName = dqTblName.substring(1, dqTblName.length() -1);	// trim the leading and trailing double quote characters
+			sb.append("2. show column names of this new table (").append(tblName).append(") via sys.columns query").append("\n");
+			rs = stmt.executeQuery("SELECT number, name, type from sys.columns where table_id in (select id from sys._tables where name = '" + tblName + "') order by number");
+			showResultAndClose_6183(rs);
+
+			sb.append("3. insert 1 row of data with values same as column names").append("\n");
+			ctsb.setLength(0);
+			ctsb.append("INSERT INTO ").append(dqTblName).append(" VALUES (");
+			for (int n = 0; n < dqColNames.length; n++) {
+				ctsb.append('\'');
+				ctsb.append(dqColNames[n]);
+				ctsb.append('\'');
+				if (n < (dqColNames.length -1))
+					ctsb.append(", ");
+			}
+			ctsb.append(')');
+			ret = stmt.executeUpdate(ctsb.toString());
+			if (ret != 1)
+				sb.append(" returned: ").append(ret).append(" (expected 1)").append("\n");
+
+			sb.append("4. insert 1 row of data with values same as column names but without enclosing double quotes").append("\n");
+			ctsb.setLength(0);
+			ctsb.append("INSERT INTO ").append(dqTblName).append(" VALUES (");
+			for (int n = 0; n < dqColNames.length; n++) {
+				ctsb.append('\'');
+				// remove enclosing double quotes
+				ctsb.append(dqColNames[n].substring(1, dqColNames[n].length() -1));
+				ctsb.append('\'');
+				if (n < (dqColNames.length -1))
+					ctsb.append(", ");
+			}
+			ctsb.append(')');
+			ret = stmt.executeUpdate(ctsb.toString());
+			if (ret != 1)
+				sb.append(" returned: ").append(ret).append(" (expected 1)").append("\n");
+
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"1. create table \"my dq_table\"\n" +
+				"2. show column names of this new table (my dq_table) via sys.columns query\n" +
+				"Resultset with 3 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	number	number\n" +
+				"2	name	name\n" +
+				"3	type	type\n" +
+				"Data rows:\n" +
+				"0	my space	varchar\n" +
+				"1	my, comma_space	varchar\n" +
+				"2	my$dollar	varchar\n" +
+				"3	my#hash	varchar\n" +
+				"4	my	tab	varchar\n" +
+				"5	my	,tab_comma	varchar\n" +
+				"6	my,	comma_tab	varchar\n" +
+				"7	my\"double_doublequote	varchar\n" +
+				"8	Abc	varchar\n" +
+				"9	 	varchar\n" +
+				"10	123	varchar\n" +
+				"Listed 11 rows\n" +
+				"3. insert 1 row of data with values same as column names\n" +
+				"4. insert 1 row of data with values same as column names but without enclosing double quotes\n");
+			sb.setLength(0);	// clear the output log buffer
+
+			// query each column separately
+			int n = 0;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"5. show content of column(s): \"my space\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my space	my space\n" +
+				"Data rows:\n" +
+				"\"my space\"\n" +
+				"my space\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"6. show content of column(s): \"my, comma_space\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my, comma_space	my, comma_space\n" +
+				"Data rows:\n" +
+				"\"my, comma_space\"\n" +
+				"my, comma_space\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"7. show content of column(s): \"my$dollar\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my$dollar	my$dollar\n" +
+				"Data rows:\n" +
+				"\"my$dollar\"\n" +
+				"my$dollar\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"8. show content of column(s): \"my#hash\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my#hash	my#hash\n" +
+				"Data rows:\n" +
+				"\"my#hash\"\n" +
+				"my#hash\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"9. show content of column(s): \"my	tab\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my	tab	my	tab\n" +
+				"Data rows:\n" +
+				"\"my	tab\"\n" +
+				"my	tab\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"10. show content of column(s): \"my	,tab_comma\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my	,tab_comma	my	,tab_comma\n" +
+				"Data rows:\n" +
+				"\"my	,tab_comma\"\n" +
+				"my	,tab_comma\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"11. show content of column(s): \"my,	comma_tab\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my,	comma_tab	my,	comma_tab\n" +
+				"Data rows:\n" +
+				"\"my,	comma_tab\"\n" +
+				"my,	comma_tab\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"12. show content of column(s): \"my\"\"double_doublequote\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my\\\"double_doublequote	my\\\"double_doublequote\n" +
+				"Data rows:\n" +
+				"\"my\"\"double_doublequote\"\n" +
+				"my\"\"double_doublequote\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"13. show content of column(s): \"Abc\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	Abc	Abc\n" +
+				"Data rows:\n" +
+				"\"Abc\"\n" +
+				"Abc\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"14. show content of column(s): \" \"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	 	 \n" +
+				"Data rows:\n" +
+				"\" \"\n" +
+				" \n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+			n++;
+			executeQueryAndShowResult_6183(stmt, dqTblName, dqColNames[n], 5 + n);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"15. show content of column(s): \"123\"\n" +
+				"Resultset with 1 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	123	123\n" +
+				"Data rows:\n" +
+				"\"123\"\n" +
+				"123\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+
+			// query all columns
+			executeQueryAndShowResult_6183(stmt, dqTblName, "*", 5 + dqColNames.length);
+			compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"16. show content of column(s): *\n" +
+				"Resultset with 11 columns\n" +
+				"	Column Name, Column Label:\n" +
+				"1	my space	my space\n" +
+				"2	my, comma_space	my, comma_space\n" +
+				"3	my$dollar	my$dollar\n" +
+				"4	my#hash	my#hash\n" +
+				"5	my	tab	my	tab\n" +
+				"6	my	,tab_comma	my	,tab_comma\n" +
+				"7	my,	comma_tab	my,	comma_tab\n" +
+				"8	my\\\"double_doublequote	my\\\"double_doublequote\n" +
+				"9	Abc	Abc\n" +
+				"10	 	 \n" +
+				"11	123	123\n" +
+				"Data rows:\n" +
+				"\"my space\"	\"my, comma_space\"	\"my$dollar\"	\"my#hash\"	\"my	tab\"	\"my	,tab_comma\"	\"my,	comma_tab\"	\"my\"\"double_doublequote\"	\"Abc\"	\" \"	\"123\"\n" +
+				"my space	my, comma_space	my$dollar	my#hash	my	tab	my	,tab_comma	my,	comma_tab	my\"\"double_doublequote	Abc	 	123\n" +
+				"Listed 2 rows\n");
+			sb.setLength(0);	// clear the output log buffer
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		// cleanup
+		try {
+			sb.append("Finally drop table ").append(dqTblName).append("\n");
+			int ret = stmt.executeUpdate("DROP TABLE " + dqTblName);
+			if (ret != -2)
+				sb.append(" returned: ").append(ret).append(" (expected -2)").append("\n");
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		closeStmtResSet(stmt, rs);
+
+		compareExpectedOutput("BugResultSetMetaData_Bug_6183",
+				"Finally drop table \"my dq_table\"\n");
+	}
+
+	private void executeQueryAndShowResult_6183(Statement st, String dqTblName, String col_list, int query_count) throws SQLException {
+		sb.append(query_count).append(". show content of column(s): ").append(col_list).append("\n");
+		ResultSet rs = st.executeQuery("SELECT " + col_list + " from " + dqTblName);
+		showResultAndClose_6183(rs);
+	}
+
+	private void showResultAndClose_6183(ResultSet rs) throws SQLException {
+		ResultSetMetaData rsmd = rs.getMetaData();
+		int rs_col_count = rsmd.getColumnCount();
+		sb.append("Resultset with ").append(rs_col_count).append(" columns").append("\n");
+		sb.append("\tColumn Name, Column Label:").append("\n");
+		for (int col = 1; col <= rs_col_count; col++) {
+			sb.append(col).append("\t").append(rsmd.getColumnName(col)).append("\t").append(rsmd.getColumnLabel(col)).append("\n");
+		}
+
+		sb.append("Data rows:").append("\n");
+		long row_count = 0;
+		while (rs.next()) {
+			row_count++;
+			for (int col = 1; col <= rs_col_count; col++) {
+				if (col > 1)
+					sb.append("\t");
+				sb.append(rs.getString(col));
+			}
+			sb.append("\n");
+		}
+		rs.close();
+		sb.append("Listed ").append(row_count).append(" rows").append("\n");
+	}
+
+	private void BugSetQueryTimeout_Bug_3357() {
+		sb.setLength(0);	// clear the output log buffer
+
+		int originalQueryTimeout = 1;
+		Statement st = null;
+		try {
+			st = con.createStatement();
+			originalQueryTimeout = st.getQueryTimeout();
+			sb.append("original getQueryTimeout = ").append(originalQueryTimeout).append("\n");
+
+			testTimeout_3357(st, 123);
+			testTimeout_3357(st, 123456);
+			testTimeout_3357(st, 2134567890);
+			testTimeout_3357(st, 0);
+			testTimeout_3357(st, 10);
+			testTimeout_3357(st, -1);	// to generate an SQLException as negative timeouts are invalid
+		} catch (SQLException se) {
+			sb.append("\n SQLException: setQueryTimeout(timeout_value) throws: ").append(se).append("\n");
+		}
+
+		// restore originalQueryTimeout
+		try {
+			testTimeout_3357(st, originalQueryTimeout);
+		} catch (SQLException se) {
+			sb.append("setQueryTimeout(timeout_value) throws: ").append(se).append("\n");
+		}
+		closeStmtResSet(st, null);
+
+		compareExpectedOutput("BugSetQueryTimeout_Bug_3357",
+				"original getQueryTimeout = 0\n" +
+				"setQueryTimeout = 123. getQueryTimeout = 123\n" +
+				"setQueryTimeout = 123456. getQueryTimeout = 123456\n" +
+				"setQueryTimeout = 2134567890. getQueryTimeout = 2134567890\n" +
+				"setQueryTimeout = 0. getQueryTimeout = 0\n" +
+				"setQueryTimeout = 10. getQueryTimeout = 10\n" +
+				"setQueryTimeout = -1. \n" +
+				" SQLException: setQueryTimeout(timeout_value) throws: java.sql.SQLException: Illegal timeout value: -1\n" +
+				"setQueryTimeout = 0. getQueryTimeout = 0\n");
+	}
+
+	private void testTimeout_3357(Statement st, int secs) throws SQLException {
+		sb.append("setQueryTimeout = ").append(secs).append(". ");
+		st.setQueryTimeout(secs);
+		// as the call to set the timeout is delayed till a statement is executed, issue a select statment
+		ResultSet rs = st.executeQuery("SELECT " + secs);
+		if (rs != null)
+			rs.close();
+		sb.append("getQueryTimeout = ").append(st.getQueryTimeout()).append("\n");
+	}
+
 
 	// some private utility methods for showing table content and params meta data
 	private void showTblContents(String tblnm) {