changeset 642:dd9b4fb14256

Added recognition of 'xml' type. Use default mapping to Types.VARCHAR for easy and fast (as java.lang.String) retrieval, display and setting data of columns of type 'xml'.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 10 Feb 2022 15:12:30 +0100 (2022-02-10)
parents fac0ed642af2
children 1f444b5ad7d2
files ChangeLog src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java src/main/java/org/monetdb/jdbc/MonetDriver.java.in src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java src/main/java/org/monetdb/jdbc/MonetResultSet.java tests/JDBC_API_Tester.java
diffstat 6 files changed, 32 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,11 @@
 # ChangeLog file for monetdb-java
 # This file is updated with Maddlog
 
+* Thu Feb 10 2022 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
+- Added recognition of 'xml' type. Use default mapping to Types.VARCHAR for
+  easy and fast (as java.lang.String) retrieval, display and setting data of
+  columns of type 'xml'.
+
 * Thu Jan 27 2022 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
 - Compiled and released new jar files: monetdb-jdbc-3.2.jre8.jar,
   monetdb-mcl-1.21.jre8.jar and jdbcclient.jre8.jar
--- a/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
+++ b/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
@@ -2964,10 +2964,10 @@ public class MonetDatabaseMetaData
 			"cast(").append(MonetDriver.getSQLTypeMap("\"sqlname\"")).append(" AS int) AS \"DATA_TYPE\", " +
 			"\"digits\" AS \"PRECISION\", " +	// note that when radix is 2 the precision shows the number of bits
 			"cast(CASE WHEN \"sqlname\" IN ('char','varchar','sec_interval','day_interval','month_interval') THEN ''''" +
-				" WHEN \"sqlname\" IN ('clob','inet','json','url','uuid','date','time','timetz','timestamp','timestamptz','blob','sqlblob') THEN \"sqlname\"||' '''" +
+				" WHEN \"sqlname\" IN ('clob','inet','json','url','uuid','date','time','timetz','timestamp','timestamptz','blob','sqlblob','xml') THEN \"sqlname\"||' '''" +
 				" ELSE NULL END AS varchar(16)) AS \"LITERAL_PREFIX\", " +
 			"cast(CASE WHEN \"sqlname\" IN ('char','varchar','sec_interval','day_interval','month_interval'" +
-						",'clob','inet','json','url','uuid','date','time','timetz','timestamp','timestamptz','blob','sqlblob') THEN ''''" +
+						",'clob','inet','json','url','uuid','date','time','timetz','timestamp','timestamptz','blob','sqlblob','xml') THEN ''''" +
 				" ELSE NULL END AS varchar(2)) AS \"LITERAL_SUFFIX\", " +
 			"CASE WHEN \"sqlname\" IN ('char','varchar') THEN 'max length'" +
 				" WHEN \"sqlname\" = 'decimal' THEN 'precision, scale'" +
@@ -2975,8 +2975,8 @@ public class MonetDatabaseMetaData
 				" ELSE NULL END AS \"CREATE_PARAMS\", " +
 			"cast(CASE WHEN \"systemname\" = 'oid' THEN ").append(DatabaseMetaData.typeNoNulls)
 				.append(" ELSE ").append(DatabaseMetaData.typeNullable).append(" END AS smallint) AS \"NULLABLE\", " +
-			"CASE WHEN \"systemname\" IN ('str','json','url') THEN true ELSE false END AS \"CASE_SENSITIVE\", " +
-			"cast(CASE WHEN \"systemname\" IN ('str','inet','json','url','uuid') THEN ").append(DatabaseMetaData.typeSearchable)
+			"CASE WHEN \"systemname\" IN ('str','json','url','xml') THEN true ELSE false END AS \"CASE_SENSITIVE\", " +
+			"cast(CASE WHEN \"systemname\" IN ('str','inet','json','url','uuid','xml') THEN ").append(DatabaseMetaData.typeSearchable)
 				.append(" ELSE ").append(DatabaseMetaData.typePredBasic).append(" END AS smallint) AS \"SEARCHABLE\", " +
 			"CASE WHEN \"sqlname\" IN ('tinyint','smallint','int','bigint','hugeint','decimal','real','double'" +
 				",'day_interval','month_interval','sec_interval') THEN false ELSE true END AS \"UNSIGNED_ATTRIBUTE\", " +
@@ -3261,8 +3261,10 @@ public class MonetDatabaseMetaData
 				" WHEN 'json' THEN 'java.lang.String'" +
 				" WHEN 'url' THEN 'org.monetdb.jdbc.types.URL'" +
 				" WHEN 'uuid' THEN 'java.lang.String'" +
+				// next UDT only when "CREATE TYPE xml EXTERNAL NAME xml;" is executed
+				" WHEN 'xml' THEN 'java.lang.String'" +
 				" ELSE 'java.lang.Object' END AS \"CLASS_NAME\", " +
-			"cast(CASE WHEN t.\"sqlname\" IN ('inet', 'json', 'url', 'uuid') THEN ").append(Types.JAVA_OBJECT)
+			"cast(CASE WHEN t.\"sqlname\" IN ('inet','json','url','uuid','xml') THEN ").append(Types.JAVA_OBJECT)
 				.append(" ELSE ").append(Types.STRUCT).append(" END AS int) AS \"DATA_TYPE\", " +
 			"t.\"systemname\" AS \"REMARKS\", " +
 			"cast(null as smallint) AS \"BASE_TYPE\" " +
--- a/src/main/java/org/monetdb/jdbc/MonetDriver.java.in
+++ b/src/main/java/org/monetdb/jdbc/MonetDriver.java.in
@@ -352,7 +352,7 @@ public class MonetDriver implements Driv
 		typeMap.put("real", Integer.valueOf(Types.REAL));
 		typeMap.put("sec_interval", Integer.valueOf(Types.DECIMAL));
 		typeMap.put("smallint", Integer.valueOf(Types.SMALLINT));
-		typeMap.put("str", Integer.valueOf(Types.VARCHAR));	// MonetDB prepare <stmt> uses type 'str' (instead of varchar) for the schema, table and column metadata output
+		typeMap.put("str", Integer.valueOf(Types.VARCHAR));	// MonetDB prepare <stmt> uses type 'str' (instead of varchar) for the schema, table and column metadata output. DO NOT REMOVE this entry!
 		// typeMap.put("table", Integer.valueOf(Types.???));
 		typeMap.put("time", Integer.valueOf(Types.TIME));
 		typeMap.put("timestamp", Integer.valueOf(Types.TIMESTAMP));
@@ -362,7 +362,8 @@ public class MonetDriver implements Driv
 		typeMap.put("url", Integer.valueOf(Types.VARCHAR));
 		typeMap.put("uuid", Integer.valueOf(Types.VARCHAR));
 		typeMap.put("varchar", Integer.valueOf(Types.VARCHAR));
-		typeMap.put("wrd", Integer.valueOf(Types.BIGINT));  // keep it in for older MonetDB servers
+		typeMap.put("wrd", Integer.valueOf(Types.BIGINT));	// keep it in for old (pre Dec2016) MonetDB servers
+		typeMap.put("xml", Integer.valueOf(Types.VARCHAR));	// used when "CREATE TYPE xml EXTERNAL NAME xml;" is executed
 	}
 
 	/**
--- a/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java
+++ b/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java
@@ -2336,9 +2336,13 @@ public class MonetPreparedStatement
 						}
 						castprefix = "uuid ";
 						break;
+					// case "xml":
+						// currently any string is accepted by MonetDB, so no validity check needed
+						// castprefix = "xml ";  also do NOT add a cast as MonetDB implicitly already converts a String to an xml String
+						// break;
 				}
 				if (castprefix != null) {
-					/* in specific cases prefix the string with: inet or json or url or uuid casting */
+					/* in specific cases prefix the string with: inet or json or url or uuid or xml casting */
 					setValue(parameterIndex, castprefix + MonetWrapper.sq(x));
 				} else {
 					setValue(parameterIndex, MonetWrapper.sq(x));
--- a/src/main/java/org/monetdb/jdbc/MonetResultSet.java
+++ b/src/main/java/org/monetdb/jdbc/MonetResultSet.java
@@ -2064,8 +2064,8 @@ public class MonetResultSet
 				return Boolean.valueOf(val);
 			case Types.VARCHAR:
 			{
-				// The MonetDB types: inet, json, url and uuid are all mapped to Types.VARCHAR in MonetDriver.typeMap
-				// For these MonetDB types (except json, see comments below) we try to create objects of the corresponding class.
+				// The MonetDB types: inet, json, url, uuid and xml are all mapped to Types.VARCHAR in MonetDriver.typeMap
+				// For these MonetDB types (except json and xml, see comments below) we try to create objects of the corresponding class.
 				final String MonetDBType = types[columnIndex - 1];
 				switch (MonetDBType.length()) {
 				case 3:
--- a/tests/JDBC_API_Tester.java
+++ b/tests/JDBC_API_Tester.java
@@ -690,6 +690,14 @@ final public class JDBC_API_Tester {
 		}
 
 		try {
+			int response = stmt.executeUpdate("CREATE TYPE xml EXTERNAL NAME xml");
+			if (response != Statement.SUCCESS_NO_INFO)
+				sb.append("Creating type xml failed to return -2!! It returned: " + response + "\n");
+		} catch (SQLException e) {
+			sb.append("failed to create type xml: ").append(e.getMessage());
+		}
+
+		try {
 			DatabaseMetaData dbmd = con.getMetaData();
 
 			// inspect the catalog by use of dbmd functions
@@ -780,7 +788,8 @@ final public class JDBC_API_Tester {
 			"null	sys	inet	org.monetdb.jdbc.types.INET	2000	inet	null\n" +
 			"null	sys	json	java.lang.String	2000	json	null\n" +
 			"null	sys	url	org.monetdb.jdbc.types.URL	2000	url	null\n" +
-			"null	sys	uuid	java.lang.String	2000	uuid	null\n");
+			"null	sys	uuid	java.lang.String	2000	uuid	null\n" +
+			"null	sys	xml	java.lang.String	2000	xml	null\n");
 
 			int[] UDTtypes = { Types.STRUCT, Types.DISTINCT };
 			compareResultSet(dbmd.getUDTs(null, "sys", null, UDTtypes), "getUDTs(null, sys, null, UDTtypes",