Changeset: 15f11c880d5c for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=15f11c880d5c
Added Files:
        
sql/test/BugTracker-2016/Tests/RELEASE_SAVEPOINT_after_UPDATE_crash.Bug-4010.sql
        
sql/test/BugTracker-2016/Tests/RELEASE_SAVEPOINT_after_UPDATE_crash.Bug-4010.stable.err
        
sql/test/BugTracker-2016/Tests/RELEASE_SAVEPOINT_after_UPDATE_crash.Bug-4010.stable.out
Modified Files:
        java/ChangeLog.Jun2016
        java/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
        sql/test/BugTracker-2016/Tests/All
Branch: default
Log Message:

Merge with Jun2016 branch.


diffs (truncated from 579 to 300 lines):

diff --git a/java/ChangeLog.Jun2016 b/java/ChangeLog.Jun2016
--- a/java/ChangeLog.Jun2016
+++ b/java/ChangeLog.Jun2016
@@ -1,6 +1,12 @@
 # ChangeLog file for java
 # This file is updated with Maddlog
 
+* Thu May 19 2016 Martin van Dinther <martin.van.dint...@monetdbsolutions.com>
+- Implemented MonetDatabaseMetaData.supportsConvert() and
+  MonetDatabaseMetaData.supportsConvert(int fromType, int toType) methods.
+  It used to always return false. Now it returns true for the supported 
conversions.
+  This fixes Bug 3460.
+
 * Sun May  8 2016 Jennie Zhang <y.zh...@cwi.nl>
 - ResultSet.setFetchSize(): added a dummy implementation to get rid
   of the SQLFeatureNotSupportedException. In MonetDB, it does not
diff --git a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java 
b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
--- a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
+++ b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
@@ -396,48 +396,16 @@ public class MonetDatabaseMetaData exten
        /**
         * Get a comma separated list of all a database's SQL keywords that
         * are NOT also SQL:2003 keywords.
-        * 
         *
         * @return a comma separated list of MonetDB keywords
         */
        @Override
        public String getSQLKeywords() {
-               StringBuilder sb = new StringBuilder(1000);
-               Statement st = null;
-               ResultSet rs = null;
-               try {
-                       st = con.createStatement();
-                       rs = st.executeQuery("SELECT \"keyword\" FROM 
\"sys\".\"keywords\" ORDER BY 1");
-                       // Fetch the keywords and concatenate them into a 
StringBuffer separated by comma's
-                       boolean isfirst = true;
-                       while (rs.next()) {
-                               String keyword = rs.getString(1);
-                               if (keyword != null) {
-                                       if (isfirst) {
-                                               isfirst = false;
-                                       } else {
-                                               sb.append(",");
-                                       }
-                                       sb.append(keyword);
-                               }
-                       }
-               } catch (SQLException e) {
-                       /* This may occur for old (before Jul2015 release) 
MonetDB servers which do not have the sys.keywords table. */
-               } finally {
-                       if (rs != null) {
-                               try {
-                                       rs.close();
-                               } catch (SQLException e) { /* ignore */ }
-                       }
-                       if (st != null) {
-                               try {
-                                        st.close();
-                               } catch (SQLException e) { /* ignore */ }
-                       }
-               }
-
-               return (sb.length() > 0) ? sb.toString() :
-                       /* else fallback and return old static list (as 
returned in clients/odbc/driver/SQLGetInfo.c case SQL_KEYWORDS:) */
+               String keywords = getConcatenatedStringFromQuery("SELECT 
\"keyword\" FROM \"sys\".\"keywords\" ORDER BY 1");
+
+               /* An old MonetDB server (pre Jul2015 release) will not have a 
table sys.keywords and return an empty String */
+               return (keywords.length() > 0) ? keywords :
+                       /* for old servers return static list (as returned in 
clients/odbc/driver/SQLGetInfo.c case SQL_KEYWORDS:) */
                        "ADMIN,AFTER,AGGREGATE,ALWAYS,ASYMMETRIC,ATOMIC," +
                        "AUTO_INCREMENT,BEFORE,BIGINT,BIGSERIAL,BINARY,BLOB," +
                        "CALL,CHAIN,CLOB,COMMITTED,COPY,CORR,CUME_DIST," +
@@ -460,68 +428,32 @@ public class MonetDatabaseMetaData exten
        }
 
        /**
-        * getMonetDBSysFunctions(int kind)
-        * args: int kind, value must be 1 or 2 or 3 or 4.
-        * internal utility method to query the MonetDB sys.functions table
-        * to dynamically get the function names (for a specific kind) and
-        * concatenate the function names into a comma separated list.
+        * Internal utility method getConcatenatedStringFromQuery(String query)
+        * args: query: SQL SELECT query. Only the output of the first column 
is concatenated.
+        * @return a String of query result values concatenated into one 
string, and values separated by comma's
         */
-       private String getMonetDBSysFunctions(int kind) {
-               // where clause part (for num/str/timedate to match only 
functions whose 1 arg exists and is of a certain type
-               String part1 = "WHERE \"id\" IN (SELECT \"func_id\" FROM 
\"sys\".\"args\" WHERE \"number\" = 1 AND \"name\" = 'arg_1' AND \"type\" IN ";
-               String whereClause = "";
-               switch (kind) {
-                       case 1: /* numeric functions */
-                               whereClause = part1 +
-                               "('tinyint', 'smallint', 'int', 'bigint', 
'decimal', 'real', 'double') )" +
-                               // exclude 2 functions which take an int as arg 
but returns a char or str
-                               " AND \"name\" NOT IN ('code', 'space')";
-                               break;
-                       case 2: /* string functions */
-                               whereClause = part1 +
-                               "('char', 'varchar', 'clob') )" +
-                               // include 2 functions which take an int as arg 
but returns a char or str
-                               " OR \"name\" IN ('code', 'space')";
-                               break;
-                       case 3: /* system functions */
-                               whereClause = "WHERE \"id\" NOT IN (SELECT 
\"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1)" +
-                               " AND \"func\" NOT LIKE '%function%(% %)%'" +
-                               " AND \"func\" NOT LIKE '%procedure%(% %)%'" +
-                               " AND \"func\" NOT LIKE '%CREATE 
FUNCTION%RETURNS TABLE(% %)%'" +
-                               // the next names are also not usable so 
exclude them
-                               " AND \"name\" NOT LIKE 'querylog_%'" +
-                               " AND \"name\" NOT IN ('analyze', 'count', 
'count_no_nil', 'initializedictionary', 'times')";
-                               break;
-                       case 4: /* time date functions */
-                               whereClause = part1 +
-                               "('date', 'time', 'timestamp', 'timetz', 
'timestamptz', 'sec_interval', 'month_interval') )";
-                               break;
-                       default: /* internal function called with an invalid 
kind value */
-                               return "";
-               }
-
-               StringBuilder sb = new StringBuilder(400);
+       private String getConcatenatedStringFromQuery(String query) {
+               StringBuilder sb = new StringBuilder(1024);
                Statement st = null;
                ResultSet rs = null;
                try {
-                       String select = "SELECT DISTINCT \"name\" FROM 
\"sys\".\"functions\" " + whereClause + " ORDER BY 1";
                        st = con.createStatement();
-                       rs = st.executeQuery(select);
-                       // Fetch the function names and concatenate them into a 
StringBuffer separated by comma's
+                       rs = st.executeQuery(query);
+                       // Fetch the first column output and concatenate the 
values into a StringBuffer separated by comma's
                        boolean isfirst = true;
                        while (rs.next()) {
-                               String name = rs.getString(1);
-                               if (name != null) {
+                               String value = rs.getString(1);
+                               if (value != null) {
                                        if (isfirst) {
                                                isfirst = false;
                                        } else {
-                                               sb.append(",");
+                                               sb.append(',');
                                        }
-                                       sb.append(name);
+                                       sb.append(value);
                                }
                        }
                } catch (SQLException e) {
-                       // ignore
+                       /* ignore */
                } finally {
                        if (rs != null) {
                                try {
@@ -534,28 +466,50 @@ public class MonetDatabaseMetaData exten
                                } catch (SQLException e) { /* ignore */ }
                        }
                }
-
+               // for debug: System.out.println("SQL query: " + query + 
"\nResult string: " + sb.toString());
                return sb.toString();
        }
 
+       // SQL query parts shared in below four getXxxxFunctions() methods
+       private final static String FunctionsSelect = "SELECT DISTINCT \"name\" 
FROM \"sys\".\"functions\" ";
+       private final static String FunctionsWhere = "WHERE \"id\" IN (SELECT 
\"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1 AND \"name\" = 'arg_1' 
AND \"type\" IN ";
+
        @Override
        public String getNumericFunctions() {
-               return getMonetDBSysFunctions(1);
+               String match =
+                       "('tinyint', 'smallint', 'int', 'bigint', 'hugeint', 
'decimal', 'double', 'real') )" +
+                       // exclude functions which belong to the 'str' module
+                       " AND \"mod\" <> 'str'";
+               return getConcatenatedStringFromQuery(FunctionsSelect + 
FunctionsWhere + match + " ORDER BY 1");
        }
 
        @Override
        public String getStringFunctions() {
-               return getMonetDBSysFunctions(2);
+               String match =
+                       "('char', 'varchar', 'clob', 'json') )" +
+                       // include functions which belong to the 'str' module
+                       " OR \"mod\" = 'str'";
+               return getConcatenatedStringFromQuery(FunctionsSelect + 
FunctionsWhere + match + " ORDER BY 1");
        }
 
        @Override
        public String getSystemFunctions() {
-               return getMonetDBSysFunctions(3);
+               String wherePart =
+                       "WHERE \"id\" NOT IN (SELECT \"func_id\" FROM 
\"sys\".\"args\" WHERE \"number\" = 1)" +
+                       " AND \"func\" NOT LIKE '%function%(% %)%'" +
+                       " AND \"func\" NOT LIKE '%procedure%(% %)%'" +
+                       " AND \"func\" NOT LIKE '%CREATE FUNCTION%RETURNS 
TABLE(% %)%'" +
+                       // the next names are also not usable so exclude them
+                       " AND \"name\" NOT LIKE 'querylog_%'" +
+                       " AND \"name\" NOT IN ('analyze', 'count', 
'count_no_nil', 'initializedictionary', 'times')";
+               return getConcatenatedStringFromQuery(FunctionsSelect + 
wherePart + " ORDER BY 1");
        }
 
        @Override
        public String getTimeDateFunctions() {
-               return getMonetDBSysFunctions(4);
+               String match =
+                       "('date', 'time', 'timestamp', 'timetz', 'timestamptz', 
'sec_interval', 'month_interval') )";
+               return getConcatenatedStringFromQuery(FunctionsSelect + 
FunctionsWhere + match + " ORDER BY 1");
        }
 
        /**
@@ -634,13 +588,158 @@ public class MonetDatabaseMetaData exten
                return true;
        }
 
+       /**
+        * Retrieves whether this database supports the JDBC scalar function
+        * CONVERT for the conversion of one JDBC type to another.
+        * The JDBC types are the generic SQL data types defined in 
java.sql.Types.
+        *
+        * @return true if so; false otherwise
+        */
        @Override
        public boolean supportsConvert() {
-               return false;
+               return true;
        }
 
+       /**
+        * Retrieves whether this database supports the JDBC scalar function
+        * CONVERT for conversions between the JDBC types fromType and toType.
+        * The JDBC types are the generic SQL data types defined in 
java.sql.Types.
+        *
+        * @return true if so; false otherwise
+        */
        @Override
        public boolean supportsConvert(int fromType, int toType) {
+               switch (fromType) {
+               case Types.BOOLEAN:
+                       switch (toType) {
+                       case Types.BOOLEAN:
+               /*      case Types.BIT: is not supported by MonetDB and will 
fail */
+                       case Types.TINYINT:
+                       case Types.SMALLINT:
+                       case Types.INTEGER:
+                       case Types.BIGINT:
+               /* conversion to FLOAT, REAL, DOUBLE, NUMERIC and DECIMAL is 
not supported by MonetDB */
+                       case Types.CHAR:
+                       case Types.VARCHAR:
+               /*      case Types.LONGVARCHAR: is not supported by MonetDB and 
will fail */
+                       case Types.CLOB:
+                               return true;
+                       }
+                       // conversion to all other types is not supported
+                       return false;
+       /*      case Types.BIT: is not supported by MonetDB and will fail */
+       /*      case Types.BINARY: is not supported by MonetDB and will fail */
+       /*      case Types.VARBINARY: is not supported by MonetDB and will fail 
*/
+       /*      case Types.LONGVARBINARY: is not supported by MonetDB and will 
fail */
+               case Types.BLOB:
+                       switch (toType) {
+               /*      case Types.BINARY: is not supported by MonetDB and will 
fail */
+               /*      case Types.VARBINARY: is not supported by MonetDB and 
will fail */
+               /*      case Types.LONGVARBINARY: is not supported by MonetDB 
and will fail */
+                       case Types.BLOB:
+                       case Types.VARCHAR:
+               /*      case Types.LONGVARCHAR: is not supported by MonetDB and 
will fail */
+                       case Types.CLOB:
+                               return true;
+                       }
+                       // conversion to all other types is not supported
+                       return false;
+               case Types.TINYINT:
+               case Types.SMALLINT:
+               case Types.INTEGER:
+               case Types.BIGINT:
+               case Types.FLOAT:
+               case Types.REAL:
+               case Types.DOUBLE:
+               case Types.NUMERIC:
+               case Types.DECIMAL:
+                       switch (toType) {
+                       case Types.BOOLEAN:
+               /*      case Types.BIT: is not supported by MonetDB and will 
fail */
+                       case Types.TINYINT:
+                       case Types.SMALLINT:
+                       case Types.INTEGER:
+                       case Types.BIGINT:
+                       case Types.FLOAT:
+                       case Types.REAL:
+                       case Types.DOUBLE:
+                       case Types.NUMERIC:
+                       case Types.DECIMAL:
+                       case Types.CHAR:
+                       case Types.VARCHAR:
+               /*      case Types.LONGVARCHAR: is not supported by MonetDB and 
will fail */
+                       case Types.CLOB:
+                               return true;
+                       }
+                       // conversion to all other types is not supported
+                       return false;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to