changeset 888:549225b7be85

Corrected ResultSetMetaData methods getPrecision(), getColumnDisplaySize() and ParameterMetaData method getPrecision() for the interval data types. They now return more precise information for the 13 possible interval data types.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 04 Apr 2024 15:14:53 +0200 (12 months ago)
parents 674f9ed21308
children 485c75b35cc9
files ChangeLog src/main/java/org/monetdb/jdbc/MonetParameterMetaData.java src/main/java/org/monetdb/jdbc/MonetResultSetMetaData.java tests/JDBC_API_Tester.java
diffstat 4 files changed, 138 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,9 +2,10 @@
 # This file is updated with Maddlog
 
 * Thu Apr  4 2024 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
-- Improved ResultSetMetaData.getColumnTypeName() and
-  ParameterMetaData.getParameterTypeName() for interval types. It now
-  returns more precise information for the interval data types.
+- Corrected ResultSetMetaData methods getColumnTypeName(), getPrecision(),
+  getColumnDisplaySize() and ParameterMetaData methods getParameterTypeName()
+  and getPrecision() for the interval data types. They now return
+  more precise information for the 13 possible interval data types.
 
 * Thu Mar  7 2024 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
 - Improved DatabaseMetaData.getTypeInfo(). It now also returns the serial
--- a/src/main/java/org/monetdb/jdbc/MonetParameterMetaData.java
+++ b/src/main/java/org/monetdb/jdbc/MonetParameterMetaData.java
@@ -198,6 +198,36 @@ final class MonetParameterMetaData
 			case Types.NUMERIC:
 				// these data types have a variable precision (max precision is 38)
 				try {
+					// Special handling for: day_interval and sec_interval as they are
+					// mapped to Types.NUMERIC and Types.DECIMAL types (see MonetDriver typeMap)
+					final String monettype = monetdbTypes[param];
+					if (monettype != null && monettype.endsWith("_interval")) {
+						/* for interval types, precisions[] contains the interval subtype code */
+						switch (precisions[param]) {
+							case 1: return 4;	// interval year
+							case 2: return 6;	// interval year to month
+							case 3: return 6;	// interval month
+							case 4: return 9;	// interval day
+							case 5: return 11;	// interval day to hour
+							case 6: return 13;	// interval day to minute
+							case 7: return 15;	// interval day to second
+							case 8: return 11;	// interval hour
+							case 9: return 13;	// interval hour to minute
+							case 10: return 15;	// interval hour to second
+							case 11: return 13;	// interval minute
+							case 12: return 15;	// interval minute to second
+							case 13: return 15;	// interval second
+							default:
+							{	// fall back to the 3 available monettype names
+								if ("sec_interval".equals(monettype))
+									return 15;
+								if ("day_interval".equals(monettype))
+									return 9;
+								if ("month_interval".equals(monettype))
+									return 6;
+							}
+						}
+					}
 					return precisions[param];
 				} catch (IndexOutOfBoundsException e) {
 					throw newSQLInvalidParameterIndexException(param);
@@ -293,6 +323,7 @@ final class MonetParameterMetaData
 			final String monettype = monetdbTypes[param];
 			if (monettype != null && monettype.endsWith("_interval")) {
 				/* convert the interval type names to valid SQL data type names */
+				/* for interval types, precisions[] contains the interval subtype code */
 				switch (precisions[param]) {
 					case 1: return "interval year";
 					case 2: return "interval year to month";
--- a/src/main/java/org/monetdb/jdbc/MonetResultSetMetaData.java
+++ b/src/main/java/org/monetdb/jdbc/MonetResultSetMetaData.java
@@ -411,12 +411,44 @@ final class MonetResultSetMetaData
 	public int getColumnDisplaySize(final int column) throws SQLException {
 		checkColumnIndexValidity(column);
 		try {
-			int len = lengths[column - 1];
+			// Special handling for interval types
+			final String monettype = types[column - 1];
+			if (monettype != null && monettype.endsWith("_interval")) {
+				/* for interval types, precisions[] contains the interval subtype code */
+				int prec = -1;
+ 				if (precisions != null) {
+					prec = precisions[column - 1];
+				}
+				switch (prec) {
+					case 1: return 4;	// interval year
+					case 2: return 6;	// interval year to month
+					case 3: return 6;	// interval month
+					case 4: return 9;	// interval day
+					case 5: return 11;	// interval day to hour
+					case 6: return 13;	// interval day to minute
+					case 7: return 15;	// interval day to second
+					case 8: return 11;	// interval hour
+					case 9: return 13;	// interval hour to minute
+					case 10: return 15;	// interval hour to second
+					case 11: return 13;	// interval minute
+					case 12: return 15;	// interval minute to second
+					case 13: return 15;	// interval second
+					default:
+					{	// fall back to the 3 available monettype names
+						if ("sec_interval".equals(monettype))
+							return 15;
+						if ("day_interval".equals(monettype))
+							return 9;
+						if ("month_interval".equals(monettype))
+							return 6;
+					}
+				}
+			}
+			final int len = lengths[column - 1];
 			if (len == 0) {
-				final String monettype = types[column - 1];
 				// in case of inet it always has 0 as length. we need to correct it.
 				if ("inet".equals(monettype)) {
-					len = 18;	// 128.127.126.125/24
+					return 18;	// 128.127.126.125/24
 				}
 			}
 			return len;
@@ -543,6 +575,7 @@ final class MonetResultSetMetaData
 				/* convert the interval type names to valid SQL data type names,
 				 * such that generic applications can use them in create table statements
 				 */
+				/* for interval types, precisions[] contains the interval subtype code */
 				int prec = -1;
  				if (precisions != null) {
 					prec = precisions[column - 1];
@@ -614,6 +647,36 @@ final class MonetResultSetMetaData
 				// these data types have a variable precision (max precision is 38)
 				if (precisions != null) {
 					try {
+						// Special handling for: day_interval and sec_interval as they are
+						// mapped to Types.NUMERIC and Types.DECIMAL types (see MonetDriver typeMap)
+						final String monettype = types[column - 1];
+						if (monettype != null && monettype.endsWith("_interval")) {
+							/* for interval types, precisions[] contains the interval subtype code */
+							switch (precisions[column - 1]) {
+								case 1: return 4;	// interval year
+								case 2: return 6;	// interval year to month
+								case 3: return 6;	// interval month
+								case 4: return 9;	// interval day
+								case 5: return 11;	// interval day to hour
+								case 6: return 13;	// interval day to minute
+								case 7: return 15;	// interval day to second
+								case 8: return 11;	// interval hour
+								case 9: return 13;	// interval hour to minute
+								case 10: return 15;	// interval hour to second
+								case 11: return 13;	// interval minute
+								case 12: return 15;	// interval minute to second
+								case 13: return 15;	// interval second
+								default:
+								{	// fall back to the 3 available monettype names
+									if ("sec_interval".equals(monettype))
+										return 15;
+									if ("day_interval".equals(monettype))
+										return 9;
+									if ("month_interval".equals(monettype))
+										return 6;
+								}
+							}
+						}
 						return precisions[column - 1];
 					} catch (IndexOutOfBoundsException e) {
 						throw MonetResultSet.newSQLInvalidColumnIndexException(column);
--- a/tests/JDBC_API_Tester.java
+++ b/tests/JDBC_API_Tester.java
@@ -47,7 +47,7 @@ final public class JDBC_API_Tester {
 	private boolean isPostDec2023;	// flag to support version specific output
 	private boolean foundDifferences = false;
 
-	final private static int sbInitLen = 5442;
+	final private static int sbInitLen = 5468;
 
 	/**
 	 * constructor
@@ -1891,47 +1891,47 @@ final public class JDBC_API_Tester {
 
 		compareExpectedOutput("Test_Interval_Types",
 			"Showing query ResultSetMetaData\n" +
-			"ColumnName: c1	ColumnTypeName: interval year	Precision: 10	Scale: 0	ColumnDisplaySize: 1	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
-			"ColumnName: c2	ColumnTypeName: interval month	Precision: 10	Scale: 0	ColumnDisplaySize: 1	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
-			"ColumnName: c3	ColumnTypeName: interval day	Precision: 4	Scale: 0	ColumnDisplaySize: 5	ColumnType: 2	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c4	ColumnTypeName: interval hour	Precision: 8	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c5	ColumnTypeName: interval minute	Precision: 11	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c6	ColumnTypeName: interval second	Precision: 13	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c7	ColumnTypeName: interval year to month	Precision: 10	Scale: 0	ColumnDisplaySize: 1	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
-			"ColumnName: c8	ColumnTypeName: interval day to hour	Precision: 5	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c9	ColumnTypeName: interval day to minute	Precision: 6	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c10	ColumnTypeName: interval day to second	Precision: 7	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c11	ColumnTypeName: interval hour to minute	Precision: 9	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c12	ColumnTypeName: interval hour to second	Precision: 10	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c13	ColumnTypeName: interval minute to second	Precision: 12	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c1	ColumnTypeName: interval year	Precision: 10	Scale: 0	ColumnDisplaySize: 4	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
+			"ColumnName: c2	ColumnTypeName: interval month	Precision: 10	Scale: 0	ColumnDisplaySize: 6	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
+			"ColumnName: c3	ColumnTypeName: interval day	Precision: 9	Scale: 0	ColumnDisplaySize: 9	ColumnType: 2	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c4	ColumnTypeName: interval hour	Precision: 11	Scale: 3	ColumnDisplaySize: 11	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c5	ColumnTypeName: interval minute	Precision: 13	Scale: 3	ColumnDisplaySize: 13	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c6	ColumnTypeName: interval second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c7	ColumnTypeName: interval year to month	Precision: 10	Scale: 0	ColumnDisplaySize: 6	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
+			"ColumnName: c8	ColumnTypeName: interval day to hour	Precision: 11	Scale: 3	ColumnDisplaySize: 11	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c9	ColumnTypeName: interval day to minute	Precision: 13	Scale: 3	ColumnDisplaySize: 13	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c10	ColumnTypeName: interval day to second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c11	ColumnTypeName: interval hour to minute	Precision: 13	Scale: 3	ColumnDisplaySize: 13	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c12	ColumnTypeName: interval hour to second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c13	ColumnTypeName: interval minute to second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
 			"Showing prepared query ResultSetMetaData\n" +
-			"ColumnName: c1	ColumnTypeName: interval year	Precision: 10	Scale: 0	ColumnDisplaySize: 10	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
-			"ColumnName: c2	ColumnTypeName: interval month	Precision: 10	Scale: 0	ColumnDisplaySize: 10	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
-			"ColumnName: c3	ColumnTypeName: interval day	Precision: 4	Scale: 0	ColumnDisplaySize: 4	ColumnType: 2	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c4	ColumnTypeName: interval hour	Precision: 8	Scale: 3	ColumnDisplaySize: 8	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c5	ColumnTypeName: interval minute	Precision: 11	Scale: 3	ColumnDisplaySize: 11	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c6	ColumnTypeName: interval second	Precision: 13	Scale: 3	ColumnDisplaySize: 13	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c7	ColumnTypeName: interval year to month	Precision: 10	Scale: 0	ColumnDisplaySize: 10	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
-			"ColumnName: c8	ColumnTypeName: interval day to hour	Precision: 5	Scale: 3	ColumnDisplaySize: 5	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c9	ColumnTypeName: interval day to minute	Precision: 6	Scale: 3	ColumnDisplaySize: 6	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c10	ColumnTypeName: interval day to second	Precision: 7	Scale: 3	ColumnDisplaySize: 7	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c11	ColumnTypeName: interval hour to minute	Precision: 9	Scale: 3	ColumnDisplaySize: 9	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c12	ColumnTypeName: interval hour to second	Precision: 10	Scale: 3	ColumnDisplaySize: 10	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
-			"ColumnName: c13	ColumnTypeName: interval minute to second	Precision: 12	Scale: 3	ColumnDisplaySize: 12	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c1	ColumnTypeName: interval year	Precision: 10	Scale: 0	ColumnDisplaySize: 4	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
+			"ColumnName: c2	ColumnTypeName: interval month	Precision: 10	Scale: 0	ColumnDisplaySize: 6	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
+			"ColumnName: c3	ColumnTypeName: interval day	Precision: 9	Scale: 0	ColumnDisplaySize: 9	ColumnType: 2	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c4	ColumnTypeName: interval hour	Precision: 11	Scale: 3	ColumnDisplaySize: 11	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c5	ColumnTypeName: interval minute	Precision: 13	Scale: 3	ColumnDisplaySize: 13	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c6	ColumnTypeName: interval second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c7	ColumnTypeName: interval year to month	Precision: 10	Scale: 0	ColumnDisplaySize: 6	ColumnType: 4	ColumnClassName: java.lang.Integer\n" +
+			"ColumnName: c8	ColumnTypeName: interval day to hour	Precision: 11	Scale: 3	ColumnDisplaySize: 11	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c9	ColumnTypeName: interval day to minute	Precision: 13	Scale: 3	ColumnDisplaySize: 13	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c10	ColumnTypeName: interval day to second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c11	ColumnTypeName: interval hour to minute	Precision: 13	Scale: 3	ColumnDisplaySize: 13	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c12	ColumnTypeName: interval hour to second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
+			"ColumnName: c13	ColumnTypeName: interval minute to second	Precision: 15	Scale: 3	ColumnDisplaySize: 15	ColumnType: 3	ColumnClassName: java.math.BigDecimal\n" +
 			"Showing prepared query ParameterMetaData\n" +
 			"ParameterTypeName: interval year	Precision: 10	Scale: 0	ParameterType: 4	ParameterClassName: java.lang.Integer\n" +
 			"ParameterTypeName: interval month	Precision: 10	Scale: 0	ParameterType: 4	ParameterClassName: java.lang.Integer\n" +
-			"ParameterTypeName: interval day	Precision: 4	Scale: 0	ParameterType: 2	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval hour	Precision: 8	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval minute	Precision: 11	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval second	Precision: 13	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval day	Precision: 9	Scale: 0	ParameterType: 2	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval hour	Precision: 11	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval minute	Precision: 13	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval second	Precision: 15	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
 			"ParameterTypeName: interval year to month	Precision: 10	Scale: 0	ParameterType: 4	ParameterClassName: java.lang.Integer\n" +
-			"ParameterTypeName: interval day to hour	Precision: 5	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval day to minute	Precision: 6	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval day to second	Precision: 7	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval hour to minute	Precision: 9	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval hour to second	Precision: 10	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
-			"ParameterTypeName: interval minute to second	Precision: 12	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n");
+			"ParameterTypeName: interval day to hour	Precision: 11	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval day to minute	Precision: 13	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval day to second	Precision: 15	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval hour to minute	Precision: 13	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval hour to second	Precision: 15	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n" +
+			"ParameterTypeName: interval minute to second	Precision: 15	Scale: 0	ParameterType: 3	ParameterClassName: java.math.BigDecimal\n");
 	}
 
 	private void Test_PlanExplainTraceDebugCmds() {