changeset 380:bf521f343172

Added support for new Java 8 java.sql.Types: Types.TIME_WITH_TIMEZONE and Types.TIMESTAMP_WITH_TIMEZONE.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Wed, 07 Oct 2020 18:29:02 +0200 (2020-10-07)
parents d7661075ebf7
children 11c30e3b7966
files ChangeLog src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
diffstat 5 files changed, 56 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
 # ChangeLog file for monetdb-java
 # This file is updated with Maddlog
 
+* Wed Oct  7 2020 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
+- Added support for new Java 8 java.sql.Types: Types.TIME_WITH_TIMEZONE and
+  Types.TIMESTAMP_WITH_TIMEZONE.
+
 * Wed Sep 23 2020 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
 - Updated JDBC driver to comply with JDBC 4.2 interface now we compile
   for Java 8. This includes:
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
@@ -638,7 +638,9 @@ public class MonetDatabaseMetaData
 			case Types.BLOB:
 			case Types.DATE:
 			case Types.TIME:
+			case Types.TIME_WITH_TIMEZONE:
 			case Types.TIMESTAMP:
+			case Types.TIMESTAMP_WITH_TIMEZONE:
 				return true;
 			}
 			// conversion to all other types is not supported
@@ -651,22 +653,26 @@ public class MonetDatabaseMetaData
 			case Types.CLOB:
 			case Types.DATE:
 			case Types.TIMESTAMP:
+			case Types.TIMESTAMP_WITH_TIMEZONE:
 				return true;
 			}
 			// conversion to all other types is not supported
 			return false;
 		case Types.TIME:
+		case Types.TIME_WITH_TIMEZONE:
 			switch (toType) {
 			case Types.CHAR:
 			case Types.VARCHAR:
 		/*	case Types.LONGVARCHAR: is not supported by MonetDB and will fail */
 			case Types.CLOB:
 			case Types.TIME:
+			case Types.TIME_WITH_TIMEZONE:
 				return true;
 			}
 			// conversion to all other types is not supported
 			return false;
 		case Types.TIMESTAMP:
+		case Types.TIMESTAMP_WITH_TIMEZONE:
 			switch (toType) {
 			case Types.CHAR:
 			case Types.VARCHAR:
@@ -674,7 +680,9 @@ public class MonetDatabaseMetaData
 			case Types.CLOB:
 			case Types.DATE:
 			case Types.TIME:
+			case Types.TIME_WITH_TIMEZONE:
 			case Types.TIMESTAMP:
+			case Types.TIMESTAMP_WITH_TIMEZONE:
 				return true;
 			}
 			// conversion to all other types is not supported
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java.in
@@ -323,7 +323,7 @@ final public class MonetDriver implement
 
 	/** A static Map containing the mapping between MonetDB types and Java SQL types */
 	/* use SELECT sqlname, * FROM sys.types order by 1, id; to view all MonetDB types */
-	/* see http://docs.oracle.com/javase/7/docs/api/java/sql/Types.html to view all supported java SQL types */
+	/* see http://docs.oracle.com/javase/8/docs/api/java/sql/Types.html to view all supported java SQL types */
 	private static final java.util.Map<String, Integer> typeMap = new java.util.HashMap<String, Integer>();
 	static {
 		// fill the typeMap once
@@ -354,10 +354,8 @@ final public class MonetDriver implement
 		// typeMap.put("table", Integer.valueOf(Types.???));
 		typeMap.put("time", Integer.valueOf(Types.TIME));
 		typeMap.put("timestamp", Integer.valueOf(Types.TIMESTAMP));
-		typeMap.put("timestamptz", Integer.valueOf(Types.TIMESTAMP));
-// new in Java 8: Types.TIMESTAMP_WITH_TIMEZONE (value 2014). Can't use it yet as we compile for java 7
-		typeMap.put("timetz", Integer.valueOf(Types.TIME));
-// new in Java 8: Types.TIME_WITH_TIMEZONE (value 2013). Can't use it yet as we compile for java 7
+		typeMap.put("timestamptz", Integer.valueOf(Types.TIMESTAMP_WITH_TIMEZONE));	// new in Java 8: Types.TIMESTAMP_WITH_TIMEZONE (value 2014)
+		typeMap.put("timetz", Integer.valueOf(Types.TIME_WITH_TIMEZONE));	// new in Java 8: Types.TIME_WITH_TIMEZONE (value 2013)
 		typeMap.put("tinyint", Integer.valueOf(Types.TINYINT));
 		typeMap.put("url", Integer.valueOf(Types.VARCHAR));
 		typeMap.put("uuid", Integer.valueOf(Types.VARCHAR));
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
@@ -505,11 +505,13 @@ public class MonetPreparedStatement
 								return false;
 						}
 						return true;
-					case Types.BIT: // we don't use type BIT, it's here for completeness
-					case Types.BOOLEAN:
-					case Types.DATE:
-					case Types.TIME:
-					case Types.TIMESTAMP:
+				//	All other types should return false
+				//	case Types.BOOLEAN:
+				//	case Types.DATE:
+				//	case Types.TIME:
+				//	case Types.TIME_WITH_TIMEZONE:
+				//	case Types.TIMESTAMP:
+				//	case Types.TIMESTAMP_WITH_TIMEZONE:
 					default:
 						return false;
 				}
@@ -841,11 +843,13 @@ public class MonetPreparedStatement
 								return false;
 						}
 						return true;
-					case Types.BIT: // we don't use type BIT, it's here for completeness
-					case Types.BOOLEAN:
-					case Types.DATE:
-					case Types.TIME:
-					case Types.TIMESTAMP:
+				//	All other types should return false
+				//	case Types.BOOLEAN:
+				//	case Types.DATE:
+				//	case Types.TIME:
+				//	case Types.TIME_WITH_TIMEZONE:
+				//	case Types.TIMESTAMP:
+				//	case Types.TIMESTAMP_WITH_TIMEZONE:
 					default:
 						return false;
 				}
@@ -1945,6 +1949,7 @@ public class MonetPreparedStatement
 					}
 				break;
 				case Types.TIME:
+				case Types.TIME_WITH_TIMEZONE:
 					if (x instanceof Time) {
 						setTime(parameterIndex, (Time)x);
 					} else if (x instanceof Timestamp) {
@@ -1960,6 +1965,7 @@ public class MonetPreparedStatement
 					}
 				break;
 				case Types.TIMESTAMP:
+				case Types.TIMESTAMP_WITH_TIMEZONE:
 					if (x instanceof Timestamp) {
 						setTimestamp(parameterIndex, (Timestamp)x);
 					} else if (x instanceof java.sql.Date) {
@@ -2332,17 +2338,19 @@ public class MonetPreparedStatement
 				break;
 			case Types.DATE:
 			case Types.TIME:
+			case Types.TIME_WITH_TIMEZONE:
 			case Types.TIMESTAMP:
+			case Types.TIMESTAMP_WITH_TIMEZONE:
 				try {
 					// check if the string represents a valid calendar date or time or timestamp to prevent
 					// failing exec #(..., ...) calls which destroy the prepared statement, see bug 6351
 					if (paramJdbcType == Types.DATE) {
 						java.sql.Date datum = java.sql.Date.valueOf(x);
 					} else
-					if (paramJdbcType == Types.TIME) {
+					if (paramJdbcType == Types.TIME || paramJdbcType == Types.TIME_WITH_TIMEZONE) {
 						Time tijdstip = Time.valueOf(x);
 					} else
-					if (paramJdbcType == Types.TIMESTAMP) {
+					if (paramJdbcType == Types.TIMESTAMP || paramJdbcType == Types.TIMESTAMP_WITH_TIMEZONE) {
 						Timestamp tijdstip = Timestamp.valueOf(x);
 					}
 				} catch (IllegalArgumentException iae) {
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
@@ -1433,11 +1433,13 @@ public class MonetResultSet
 								return false;
 						}
 						return true;
-					case Types.BIT: // we don't use type BIT, it's here for completeness
-					case Types.BOOLEAN:
-					case Types.DATE:
-					case Types.TIME:
-					case Types.TIMESTAMP:
+				//	All other types should return false
+				//	case Types.BOOLEAN:
+				//	case Types.DATE:
+				//	case Types.TIME:
+				//	case Types.TIME_WITH_TIMEZONE:
+				//	case Types.TIMESTAMP:
+				//	case Types.TIMESTAMP_WITH_TIMEZONE:
 					default:
 						return false;
 				}
@@ -1573,9 +1575,11 @@ public class MonetResultSet
 								_precision[column] = 10;
 								break;
 							case Types.TIME:
+							case Types.TIME_WITH_TIMEZONE:
 								_precision[column] = 8;
 								break;
 							case Types.TIMESTAMP:
+							case Types.TIMESTAMP_WITH_TIMEZONE:
 								_precision[column] = 19;
 								break;
 							default:
@@ -1943,8 +1947,10 @@ public class MonetResultSet
 			case Types.DATE:
 				return getDate(columnIndex, null);
 			case Types.TIME:
+			case Types.TIME_WITH_TIMEZONE:
 				return getTime(columnIndex, null);
 			case Types.TIMESTAMP:
+			case Types.TIMESTAMP_WITH_TIMEZONE:
 				return getTimestamp(columnIndex, null);
 			case Types.BINARY:
 			case Types.VARBINARY:
@@ -2257,8 +2263,10 @@ public class MonetResultSet
 			case Types.DATE:
 				return java.sql.Date.class;
 			case Types.TIME:
+			case Types.TIME_WITH_TIMEZONE:
 				return Time.class;
 			case Types.TIMESTAMP:
+			case Types.TIMESTAMP_WITH_TIMEZONE:
 				return Timestamp.class;
 			case Types.CLOB:
 				return Clob.class;
@@ -2572,7 +2580,8 @@ public class MonetResultSet
 				JdbcType = type;
 			}
 
-			if ((JdbcType == Types.DATE || JdbcType == Types.TIMESTAMP) && monetDateStr.startsWith("-")) {
+			if ((JdbcType == Types.DATE || JdbcType == Types.TIMESTAMP || JdbcType == Types.TIMESTAMP_WITH_TIMEZONE)
+			 && monetDateStr.startsWith("-")) {
 				// the SimpleDateFormat parsers do not support to parse negative year numbers, deal with it separately
 				negativeYear = true;
 				monetDate = monetDateStr.substring(1);
@@ -2608,6 +2617,7 @@ public class MonetResultSet
 				pdate = dateFormat.parse(monetDate, ppos);
 				break;
 			case Types.TIME:
+			case Types.TIME_WITH_TIMEZONE:
 				if (timeFormat == null) {
 					// first time usage, create and keep the timeFormat object for next usage
 					timeFormat = new SimpleDateFormat("HH:mm:ss");
@@ -2616,6 +2626,7 @@ public class MonetResultSet
 				pdate = timeFormat.parse(monetDate, ppos);
 				break;
 			case Types.TIMESTAMP:
+			case Types.TIMESTAMP_WITH_TIMEZONE:
 				if (timestampFormat == null) {
 					// first time usage, create and keep the timestampFormat object for next usage
 					timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -2660,7 +2671,10 @@ public class MonetResultSet
 			// System.out.println("Corrected cal: " + cal.toString());
 		}
 
-		if (JdbcType == Types.TIME || JdbcType == Types.TIMESTAMP) {
+		if (JdbcType == Types.TIME
+		 || JdbcType == Types.TIME_WITH_TIMEZONE
+		 || JdbcType == Types.TIMESTAMP
+		 || JdbcType == Types.TIMESTAMP_WITH_TIMEZONE) {
 			// parse additional nanos (if any)
 			int nanos = 0;
 			int pos = ppos.getIndex();