changeset 134:890dce2d5305 embedded

Merged changes for Bug 6183
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Thu, 13 Jul 2017 16:56:02 +0200 (2017-07-13)
parents 507913b9d126 (current diff) 1ea2ee3b946c (diff)
children 477c4de0eda2
files build.properties jdbc-3_0-fr-spec.pdf jdbc4.0-fr-spec.pdf pom.xml src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java tests/build.xml
diffstat 8 files changed, 342 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,19 @@
+syntax: glob
+
+# files created by the normal build process
+*.class
+*.jar
+build/META-INF/services/java.sql.Driver
+src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java
+
+# files generated by various editors
+*.swp
+*~
+\#*
+.#*
+
+# other files we don't want
+TAGS
+tags
+*.rej
+*.orig
--- a/build.properties
+++ b/build.properties
@@ -19,7 +19,7 @@ MCL_MINOR=14
 # major release number
 JDBC_MAJOR=2
 # minor release number
-JDBC_MINOR=30
+JDBC_MINOR=31
 # an additional identifying string
 JDBC_VER_SUFFIX=Liberica
 # the default port to connect on, if no port given when using SQL
deleted file mode 100644
index 6ac85a733bcf33556961662141bb1bcf7abbd996..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 61a3a4507dc615fcebb61f61ae05c4a537b03a88..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 
     <groupId>monetdb</groupId>
     <artifactId>monetdb-jdbc-new</artifactId>
-    <version>2.30</version>
+    <version>2.31</version>
     <name>MonetDB JDBC new</name>
     <description>MonetDB Adapted JDBC driver for embedded connection</description>
     <url>https://www.monetdb.org</url>
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
@@ -16,6 +16,7 @@ import java.io.InputStream;
 import java.io.Reader;
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.math.RoundingMode;
 import java.net.URL;
 import java.nio.CharBuffer;
@@ -364,7 +365,7 @@ public class MonetPreparedStatement exte
 			public boolean isCurrency(int column) {
 				return false;
 			}
-			
+
 			/**
 			 * Indicates whether values in the designated column are signed numbers.
 			 * Within MonetDB all numeric types (except oid and ptr) are signed.
@@ -637,7 +638,7 @@ public class MonetPreparedStatement exte
 					if (column[i] == null)
 						cnt++;
 				}
-				
+
 				return cnt;
 			}
 
@@ -1067,7 +1068,7 @@ public class MonetPreparedStatement exte
 	 */
 	@Override
 	public void setBoolean(int parameterIndex, boolean x) throws SQLException {
-		setValue(parameterIndex, "" + x);
+		setValue(parameterIndex, Boolean.toString(x));
 	}
 
 	/**
@@ -1080,7 +1081,7 @@ public class MonetPreparedStatement exte
 	 */
 	@Override
 	public void setByte(int parameterIndex, byte x) throws SQLException {
-		setValue(parameterIndex, "" + x);
+		setValue(parameterIndex, Byte.toString(x));
 	}
 
 	private static final String HEXES = "0123456789ABCDEF";
@@ -1322,7 +1323,7 @@ public class MonetPreparedStatement exte
 	 */
 	@Override
 	public void setDouble(int parameterIndex, double x) throws SQLException {
-		setValue(parameterIndex, "" + x);
+		setValue(parameterIndex, Double.toString(x));
 	}
 
 	/**
@@ -1335,7 +1336,7 @@ public class MonetPreparedStatement exte
 	 */
 	@Override
 	public void setFloat(int parameterIndex, float x) throws SQLException {
-		setValue(parameterIndex, "" + x);
+		setValue(parameterIndex, Float.toString(x));
 	}
 
 	/**
@@ -1348,7 +1349,7 @@ public class MonetPreparedStatement exte
 	 */
 	@Override
 	public void setInt(int parameterIndex, int x) throws SQLException {
-		setValue(parameterIndex, "" + x);
+		setValue(parameterIndex, Integer.toString(x));
 	}
 
 	/**
@@ -1361,7 +1362,7 @@ public class MonetPreparedStatement exte
 	 */
 	@Override
 	public void setLong(int parameterIndex, long x) throws SQLException {
-		setValue(parameterIndex, "" + x);
+		setValue(parameterIndex, Long.toString(x));
 	}
 
 	/**
@@ -1599,123 +1600,120 @@ public class MonetPreparedStatement exte
 	 * @see Types
 	 */
 	@Override
-	public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException {
+	public void setObject(
+			int parameterIndex,
+			Object x,
+			int targetSqlType,
+			int scale)
+			throws SQLException
+	{
 		// this is according to table B-5
 		if (x instanceof String) {
 			switch (targetSqlType) {
+				case Types.CHAR:
+				case Types.VARCHAR:
+				case Types.LONGVARCHAR:
+				case Types.CLOB:
+					setString(parameterIndex, (String)x);
+					break;
 				case Types.TINYINT:
-					byte val1;
+				case Types.SMALLINT:
+				case Types.INTEGER:
+				{
+					int val;
 					try {
-						val1 = Byte.parseByte((String)x);
-					} catch (NumberFormatException e) {
-						val1 = 0;
-					}
-					setByte(parameterIndex, val1);
-					break;
-				case Types.SMALLINT:
-					short val2;
-					try {
-						val2 = Short.parseShort((String)x);
+						val = Integer.parseInt((String)x);
 					} catch (NumberFormatException e) {
-						val2 = 0;
+						val = 0;
 					}
-					setShort(parameterIndex, val2);
-					break;
-				case Types.INTEGER:
-					int val3;
-					try {
-						val3 = Integer.parseInt((String)x);
-					} catch (NumberFormatException e) {
-						val3 = 0;
-					}
-					setInt(parameterIndex, val3);
-					break;
+					setInt(parameterIndex, val);
+				} break;
 				case Types.BIGINT:
-					long val4;
+				{
+					long val;
 					try {
-						val4 = Long.parseLong((String)x);
+						val = Long.parseLong((String)x);
 					} catch (NumberFormatException e) {
-						val4 = 0;
+						val = 0;
 					}
-					setLong(parameterIndex, val4);
-					break;
+					setLong(parameterIndex, val);
+				} break;
 				case Types.REAL:
-					float val5;
+				{
+					float val;
 					try {
-						val5 = Float.parseFloat((String)x);
+						val = Float.parseFloat((String)x);
 					} catch (NumberFormatException e) {
-						val5 = 0;
+						val = 0;
 					}
-					setFloat(parameterIndex, val5);
-					break;
+					setFloat(parameterIndex, val);
+				} break;
+				case Types.FLOAT:
 				case Types.DOUBLE:
-					double val6;
+				{
+					double val;
 					try {
-						val6 = Double.parseDouble((String)x);
+						val = Double.parseDouble((String)x);
 					} catch (NumberFormatException e) {
-						val6 = 0;
+						val = 0;
 					}
-					setDouble(parameterIndex, val6);
-					break;
+					setDouble(parameterIndex, val);
+				} break;
+				case Types.DECIMAL:
 				case Types.NUMERIC:
-				case Types.DECIMAL:
-					BigDecimal val8;
+				{
+					BigDecimal val;
 					try {
-						val8 = new BigDecimal((String)x);
+						val = new BigDecimal((String)x);
 					} catch (NumberFormatException e) {
 						try {
-							val8 = BigDecimal.ZERO;
+							val = new BigDecimal(0.0);
 						} catch (NumberFormatException ex) {
 							throw new SQLException("Internal error: unable to create template BigDecimal: " + ex.getMessage(), "M0M03");
 						}
 					}
-					val8 = val8.setScale(scale, BigDecimal.ROUND_HALF_UP);
-					setBigDecimal(parameterIndex, val8);
-					break;
+					val = val.setScale(scale, BigDecimal.ROUND_HALF_UP);
+					setBigDecimal(parameterIndex, val);
+				} break;
+				case Types.BIT:
 				case Types.BOOLEAN:
-					setBoolean(parameterIndex, Boolean.valueOf((String) x));
+					setBoolean(parameterIndex, (Boolean.valueOf((String)x)).booleanValue());
 					break;
-				case Types.CHAR:
-				case Types.VARCHAR:
-				case Types.LONGVARCHAR:
-					setString(parameterIndex, (String)x);
-					break;
+				case Types.BINARY:
+				case Types.VARBINARY:
 				case Types.LONGVARBINARY:
 					setBytes(parameterIndex, ((String)x).getBytes());
 					break;
-				case Types.BLOB:
-					setBlob(parameterIndex, new MonetBlob(((String)x).getBytes()));
-					break;
-				case Types.CLOB:
-					setClob(parameterIndex, new MonetClob((String)x));
-					break;
 				case Types.DATE:
-					Date val9;
+				{
+					java.sql.Date val;
 					try {
-						val9 = Date.valueOf((String)x);
+						val = java.sql.Date.valueOf((String)x);
 					} catch (IllegalArgumentException e) {
-						val9 = new Date(0L);
+						val = new java.sql.Date(0L);
 					}
-					setDate(parameterIndex, val9);
-					break;
+					setDate(parameterIndex, val);
+				} break;
 				case Types.TIME:
-					Time val10;
+				{
+					Time val;
 					try {
-						val10 = Time.valueOf((String)x);
+						val = Time.valueOf((String)x);
 					} catch (IllegalArgumentException e) {
-						val10 = new Time(0L);
+						val = new Time(0L);
 					}
-					setTime(parameterIndex, val10);
-					break;
+					setTime(parameterIndex, val);
+				} break;
 				case Types.TIMESTAMP:
-					Timestamp val11;
+				{
+					Timestamp val;
 					try {
-						val11 = Timestamp.valueOf((String)x);
+						val = Timestamp.valueOf((String)x);
 					} catch (IllegalArgumentException e) {
-						val11 = new Timestamp(0L);
+						val = new Timestamp(0L);
 					}
-					setTimestamp(parameterIndex, val11);
-					break;
+					setTimestamp(parameterIndex, val);
+				} break;
 				case Types.NCHAR:
 				case Types.NVARCHAR:
 				case Types.LONGNVARCHAR:
@@ -1723,7 +1721,14 @@ public class MonetPreparedStatement exte
 				default:
 					throw new SQLException("Conversion not allowed", "M1M05");
 			}
-		} else if (x instanceof BigDecimal || x instanceof Byte || x instanceof Short || x instanceof Integer || x instanceof Long || x instanceof Float || x instanceof Double) {
+		} else if (x instanceof BigDecimal ||
+				x instanceof Byte ||
+				x instanceof Short ||
+				x instanceof Integer ||
+				x instanceof Long ||
+				x instanceof Float ||
+				x instanceof Double)
+		{
 			Number num = (Number)x;
 			switch (targetSqlType) {
 				case Types.TINYINT:
@@ -1736,22 +1741,30 @@ public class MonetPreparedStatement exte
 					setInt(parameterIndex, num.intValue());
 					break;
 				case Types.BIGINT:
-					setLong(parameterIndex, num.longValue());
+					if (x instanceof BigDecimal) {
+						BigDecimal bd = (BigDecimal)x;
+						setLong(parameterIndex, bd.setScale(scale, BigDecimal.ROUND_HALF_UP).longValue());
+					} else {
+						setLong(parameterIndex, num.longValue());
+					}
 					break;
 				case Types.REAL:
 					setFloat(parameterIndex, num.floatValue());
 					break;
+				case Types.FLOAT:
 				case Types.DOUBLE:
 					setDouble(parameterIndex, num.doubleValue());
 					break;
+				case Types.DECIMAL:
 				case Types.NUMERIC:
-				case Types.DECIMAL:
 					if (x instanceof BigDecimal) {
 						setBigDecimal(parameterIndex, (BigDecimal)x);
 					} else {
-						setBigDecimal(parameterIndex, new BigDecimal(num.doubleValue()));
+						setBigDecimal(parameterIndex,
+								new BigDecimal(num.doubleValue()));
 					}
 					break;
+				case Types.BIT:
 				case Types.BOOLEAN:
 					if (num.doubleValue() != 0.0) {
 						setBoolean(parameterIndex, true);
@@ -1762,13 +1775,14 @@ public class MonetPreparedStatement exte
 				case Types.CHAR:
 				case Types.VARCHAR:
 				case Types.LONGVARCHAR:
+				case Types.CLOB:
 					setString(parameterIndex, x.toString());
 					break;
 				default:
 					throw new SQLException("Conversion not allowed", "M1M05");
 			}
 		} else if (x instanceof Boolean) {
-			boolean val = (Boolean) x;
+			boolean val = ((Boolean)x).booleanValue();
 			switch (targetSqlType) {
 				case Types.TINYINT:
 					setByte(parameterIndex, (byte)(val ? 1 : 0));
@@ -1785,13 +1799,21 @@ public class MonetPreparedStatement exte
 				case Types.REAL:
 					setFloat(parameterIndex, (float)(val ? 1.0 : 0.0));
 					break;
+				case Types.FLOAT:
 				case Types.DOUBLE:
 					setDouble(parameterIndex, (val ? 1.0 : 0.0));  // do no cast to (double) as it generates a compiler warning
 					break;
+				case Types.DECIMAL:
 				case Types.NUMERIC:
-				case Types.DECIMAL:
-					setBigDecimal(parameterIndex, val ? BigDecimal.ONE : BigDecimal.ZERO);
-				 	break;
+				{
+					BigDecimal dec;
+					try {
+						dec = new BigDecimal(val ? 1.0 : 0.0);
+					} catch (NumberFormatException e) {
+						throw new SQLException("Internal error: unable to create template BigDecimal: " + e.getMessage(), "M0M03");
+					}
+					setBigDecimal(parameterIndex, dec);
+				} break;
 				case Types.BIT:
 				case Types.BOOLEAN:
 					setBoolean(parameterIndex, val);
@@ -1799,68 +1821,106 @@ public class MonetPreparedStatement exte
 				case Types.CHAR:
 				case Types.VARCHAR:
 				case Types.LONGVARCHAR:
-					setString(parameterIndex, "" + val);
+				case Types.CLOB:
+					setString(parameterIndex, x.toString());
+					break;
+				default:
+					throw new SQLException("Conversion not allowed", "M1M05");
+			}
+		} else if (x instanceof BigInteger) {
+			BigInteger num = (BigInteger)x;
+			switch (targetSqlType) {
+				case Types.BIGINT:
+					setLong(parameterIndex, num.longValue());
+					break;
+				case Types.DECIMAL:
+				case Types.NUMERIC:
+				{
+					BigDecimal dec;
+					try {
+						dec = new BigDecimal(num);
+					} catch (NumberFormatException e) {
+						throw new SQLException("Internal error: unable to create template BigDecimal: " + e.getMessage(), "M0M03");
+					}
+					setBigDecimal(parameterIndex, dec);
+				} break;
+				case Types.CHAR:
+				case Types.VARCHAR:
+				case Types.LONGVARCHAR:
+				case Types.CLOB:
+					setString(parameterIndex, x.toString());
 					break;
 				default:
 					throw new SQLException("Conversion not allowed", "M1M05");
 			}
 		} else if (x instanceof byte[]) {
 			switch (targetSqlType) {
+				case Types.BINARY:
+				case Types.VARBINARY:
 				case Types.LONGVARBINARY:
-					setBytes(parameterIndex, (byte[]) x);
-					break;
-				case Types.BLOB:
-					setBlob(parameterIndex, new MonetBlob((byte[]) x));
+					setBytes(parameterIndex, (byte[])x);
 					break;
 				default:
 					throw new SQLException("Conversion not allowed", "M1M05");
 			}
-		} else if (x instanceof Date || x instanceof Timestamp || x instanceof Time || x instanceof Calendar || x instanceof java.util.Date) {
+		} else if (x instanceof java.sql.Date ||
+				x instanceof Timestamp ||
+				x instanceof Time ||
+				x instanceof Calendar ||
+				x instanceof java.util.Date)
+		{
 			switch (targetSqlType) {
-				case Types.CHAR:
-				case Types.VARCHAR:
-				case Types.LONGVARCHAR:
-					setString(parameterIndex, x.toString());
-					break;
 				case Types.DATE:
-					if (x instanceof Time) {
-						throw new SQLException("Conversion not allowed", "M1M05");
-					} else if (x instanceof Date) {
-						setDate(parameterIndex, (Date)x);
+					if (x instanceof java.sql.Date) {
+						setDate(parameterIndex, (java.sql.Date)x);
 					} else if (x instanceof Timestamp) {
-						setDate(parameterIndex, new Date(((Timestamp)x).getTime()));
+						setDate(parameterIndex, new java.sql.Date(((Timestamp)x).getTime()));
 					} else if (x instanceof java.util.Date) {
-						setDate(parameterIndex, new Date(((java.util.Date)x).getTime()));
-					} else { //Calendar
-						setDate(parameterIndex, new Date(((Calendar)x).getTimeInMillis()));
+						setDate(parameterIndex, new java.sql.Date(
+								((java.util.Date)x).getTime()));
+					} else if (x instanceof Calendar) {
+						setDate(parameterIndex, new java.sql.Date(
+								((Calendar)x).getTimeInMillis()));
+					} else {
+						throw new SQLException("Conversion not allowed", "M1M05");
 					}
 					break;
 				case Types.TIME:
 					if (x instanceof Time) {
 						setTime(parameterIndex, (Time)x);
-					} else if (x instanceof Date) {
-						throw new SQLException("Conversion not allowed", "M1M05");
 					} else if (x instanceof Timestamp) {
 						setTime(parameterIndex, new Time(((Timestamp)x).getTime()));
 					} else if (x instanceof java.util.Date) {
-						setTime(parameterIndex, new Time(((java.util.Date)x).getTime()));
-					} else { //Calendar
-						setTime(parameterIndex, new Time(((Calendar)x).getTimeInMillis()));
+						setTime(parameterIndex, new java.sql.Time(
+								((java.util.Date)x).getTime()));
+					} else if (x instanceof Calendar) {
+						setTime(parameterIndex, new java.sql.Time(
+								((Calendar)x).getTimeInMillis()));
+					} else {
+						throw new SQLException("Conversion not allowed", "M1M05");
 					}
 					break;
 				case Types.TIMESTAMP:
-					if (x instanceof Time) {
-						throw new SQLException("Conversion not allowed", "M1M05");
-					} else if (x instanceof Date) {
-						setTimestamp(parameterIndex, new Timestamp(((Date)x).getTime()));
-					} else if (x instanceof Timestamp) {
+					if (x instanceof Timestamp) {
 						setTimestamp(parameterIndex, (Timestamp)x);
+					} else if (x instanceof java.sql.Date) {
+						setTimestamp(parameterIndex, new Timestamp(((java.sql.Date)x).getTime()));
 					} else if (x instanceof java.util.Date) {
-						setTimestamp(parameterIndex, new Timestamp(((java.util.Date)x).getTime()));
-					} else { //Calendar
-						setTimestamp(parameterIndex, new Timestamp(((Calendar)x).getTimeInMillis()));
+						setTimestamp(parameterIndex, new java.sql.Timestamp(
+								((java.util.Date)x).getTime()));
+					} else if (x instanceof Calendar) {
+						setTimestamp(parameterIndex, new java.sql.Timestamp(
+								((Calendar)x).getTimeInMillis()));
+					} else {
+						throw new SQLException("Conversion not allowed", "M1M05");
 					}
 					break;
+				case Types.CHAR:
+				case Types.VARCHAR:
+				case Types.LONGVARCHAR:
+				case Types.CLOB:
+					setString(parameterIndex, x.toString());
+					break;
 				default:
 					throw new SQLException("Conversion not allowed", "M1M05");
 			}
@@ -1879,6 +1939,8 @@ public class MonetPreparedStatement exte
 			setURL(parameterIndex, (java.net.URL)x);
 		} else if (x instanceof RowId) {
 			setRowId(parameterIndex, (RowId)x);
+		} else if (x instanceof NClob) {
+			throw newSQLFeatureNotSupportedException("setObject() with object of type NClob");
 		} else if (x instanceof SQLXML) {
 			throw newSQLFeatureNotSupportedException("setObject() with object of type SQLXML");
 		} else if (x instanceof SQLData) { // not in JDBC4.1???
@@ -1892,8 +1954,10 @@ public class MonetPreparedStatement exte
 					// representation is given, but we need to prefix it
 					// with the actual sqltype the server expects, or we
 					// will get an error back
-					setValue(paramnr,
-						sqltype + " '" + x.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'") + "'");
+					setValue(
+							paramnr,
+							sqltype + " '" + x.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'") + "'"
+					);
 				}
 
 				@Override
@@ -1920,7 +1984,7 @@ public class MonetPreparedStatement exte
 				public void writeLong(long x) throws SQLException {
 					setLong(paramnr, x);
 				}
-				
+
 				@Override
 				public void writeFloat(float x) throws SQLException {
 					setFloat(paramnr, x);
@@ -1942,12 +2006,12 @@ public class MonetPreparedStatement exte
 				}
 
 				@Override
-				public void writeDate(Date x) throws SQLException {
+				public void writeDate(java.sql.Date x) throws SQLException {
 					setDate(paramnr, x);
 				}
 
 				@Override
-				public void writeTime(Time x) throws SQLException {
+				public void writeTime(java.sql.Time x) throws SQLException {
 					setTime(paramnr, x);
 				}
 
@@ -2074,7 +2138,7 @@ public class MonetPreparedStatement exte
 	 */
 	@Override
 	public void setShort(int parameterIndex, short x) throws SQLException {
-		setValue(parameterIndex, "" + x);
+		setValue(parameterIndex, Short.toString(x));
 	}
 
 	/**
new file mode 100644
--- /dev/null
+++ b/tests/BugResultSetMetaData_Bug_6183.java
@@ -0,0 +1,123 @@
+/*
+ * 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 - 2017 MonetDB B.V.
+ */
+
+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\""};
+
+	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]);
+		Statement stmt = con.createStatement();
+		ResultSet rs = null;
+		try {
+			System.out.println("1. create table " + dqTblName);
+			StringBuilder sb = new StringBuilder(30 + (dqColNames.length * (30 + 15)));
+			sb.append("CREATE TABLE ").append(dqTblName).append(" (");
+			for (int n = 0; n < dqColNames.length; n++) {
+				sb.append(dqColNames[n]);
+				sb.append(" varchar(").append(31 + n).append(')');
+				if (n < (dqColNames.length -1))
+					sb.append(", ");
+			}
+			sb.append(')');
+			int ret = stmt.executeUpdate(sb.toString());
+			System.out.println(" returned: " + ret + " (expected -2)");
+			System.out.println();
+
+			String tblName = dqTblName.substring(1, dqTblName.length() -1);	// trim the leading and trailing double quote characters
+			System.out.println("2. show column names of this new table (" + tblName + ") via sys.columns query");
+			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(rs);
+
+			System.out.println("3. insert 1 row of data with values same as column names");
+			sb.setLength(0);
+			sb.append("INSERT INTO ").append(dqTblName).append(" VALUES (");
+			for (int n = 0; n < dqColNames.length; n++) {
+				sb.append('\'');
+				sb.append(dqColNames[n]);
+				sb.append('\'');
+				if (n < (dqColNames.length -1))
+					sb.append(", ");
+			}
+			sb.append(')');
+			ret = stmt.executeUpdate(sb.toString());
+			System.out.println(" returned: " + ret + " (expected 1)");
+			System.out.println();
+
+			System.out.println("4. insert 1 row of data with values same as column names but without enclosing double quotes");
+			sb.setLength(0);
+			sb.append("INSERT INTO ").append(dqTblName).append(" VALUES (");
+			for (int n = 0; n < dqColNames.length; n++) {
+				sb.append('\'');
+				// remove enclosing double quotes
+				sb.append(dqColNames[n].substring(1, dqColNames[n].length() -1));
+				sb.append('\'');
+				if (n < (dqColNames.length -1))
+					sb.append(", ");
+			}
+			sb.append(')');
+			ret = stmt.executeUpdate(sb.toString());
+			System.out.println(" returned: " + ret + " (expected 1)");
+			System.out.println();
+
+			// query each column separately
+			for (int n = 0; n < dqColNames.length; n++) {
+				executeQueryAndShowResult(stmt, dqColNames[n], 5 + n);
+			}
+			// query all columns
+			executeQueryAndShowResult(stmt, "*", 5 + dqColNames.length);
+
+			System.out.println("Finally drop table " + dqTblName);
+			ret = stmt.executeUpdate("DROP TABLE " + dqTblName);
+			System.out.println(" returned: " + ret + " (expected -2)");
+			System.out.println();
+		} catch (SQLException se) {
+			System.out.println("Failure occurred: " + se);
+		} finally {
+			if (rs != null)
+				rs.close();
+			stmt.close();
+		}
+		con.close();
+	}
+
+	private static void executeQueryAndShowResult(Statement st, String col_list, int query_count) throws SQLException {
+		System.out.print(query_count);
+		System.out.println(". show content of column(s): " + col_list);
+		ResultSet rs = st.executeQuery("SELECT " + col_list + " from " + dqTblName);
+		showResultAndClose(rs);
+	}
+
+	private static void showResultAndClose(ResultSet rs) throws SQLException {
+		ResultSetMetaData rsmd = rs.getMetaData();
+		int rs_col_count = rsmd.getColumnCount();
+		System.out.println("Resultset with " + rs_col_count + " columns");
+		System.out.println("\tColumn Name, Column Label:");
+		for (int col = 1; col <= rs_col_count; col++) {
+			System.out.println(col + "\t" + rsmd.getColumnName(col) + "\t" +rsmd.getColumnLabel(col));
+		}
+
+		System.out.println("Data rows:");
+		long row_count = 0;
+		while (rs.next()) {
+			row_count++;
+			for (int col = 1; col <= rs_col_count; col++) {
+				if (col > 1)
+					System.out.print("\t");
+				System.out.print(rs.getString(col));
+			}
+			System.out.println();
+		}
+		rs.close();
+		System.out.println("Listed " + row_count + " rows");
+		System.out.println();
+	}
+}
--- a/tests/build.xml
+++ b/tests/build.xml
@@ -131,6 +131,7 @@ Copyright 1997 - July 2008 CWI, August 2
     <antcall target="BugDecimalRound_Bug_3561" />
     <antcall target="BugExecuteUpdate_Bug_3350" />
     <antcall target="BugSetQueryTimeout_Bug_3357" />
+    <antcall target="BugResultSetMetaData_Bug_6183" />
   </target>
 
   <target name="test_class" depends="compile,jdbc">
@@ -374,4 +375,10 @@ Copyright 1997 - July 2008 CWI, August 2
     </antcall>
   </target>
 
+  <target name="BugResultSetMetaData_Bug_6183">
+    <antcall target="test_class">
+      <param name="test.class" value="BugResultSetMetaData_Bug_6183" />
+    </antcall>
+  </target>
+
 </project>