Changeset: 4117aa40a6b9 for monetdb-java
URL: https://dev.monetdb.org/hg/monetdb-java/rev/4117aa40a6b9
Modified Files:
        src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
        tests/JDBC_API_Tester.java
Branch: default
Log Message:

Fix the computed CHAR_OCTET_LENGTH value of resultsets returned by 
getColumns(),  getFunctionColumns() and getProcedureColumns().
It now also returns a bigint instead of int to prevent computation overflow.


diffs (127 lines):

diff --git a/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java 
b/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
--- a/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
+++ b/src/main/java/org/monetdb/jdbc/MonetDatabaseMetaData.java
@@ -1815,7 +1815,7 @@ public final class MonetDatabaseMetaData
                        "cast(null as char(1)) AS \"COLUMN_DEF\", " +
                        "cast(0 as int) AS \"SQL_DATA_TYPE\", " +
                        "cast(0 as int) AS \"SQL_DATETIME_SUB\", " +
-                       "cast(CASE WHEN a.\"type\" IN ('char','varchar','clob') 
THEN a.\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " +
+                       "cast(CASE WHEN a.\"type\" IN 
('varchar','clob','char','json','url','xml') THEN 4 * a.\"type_digits\" WHEN 
a.\"type\" = 'blob' THEN a.\"type_digits\" ELSE NULL END as bigint) AS 
\"CHAR_OCTET_LENGTH\", " +
                        // in MonetDB procedures have no return value by 
design. The arguments in sys.args are numbered from 0 so we must add 1 to 
comply with the API specification.
                        "cast(a.\"number\" + 1 as int) AS \"ORDINAL_POSITION\", 
" +
                        "cast('' as varchar(3)) AS \"IS_NULLABLE\", " +
@@ -2131,7 +2131,7 @@ public final class MonetDatabaseMetaData
                        "c.\"default\" AS \"COLUMN_DEF\", " +
                        "cast(0 as int) AS \"SQL_DATA_TYPE\", " +
                        "cast(0 as int) AS \"SQL_DATETIME_SUB\", " +
-                       "cast(CASE WHEN c.\"type\" IN ('char','varchar','clob') 
THEN c.\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " +
+                       "cast(CASE WHEN c.\"type\" IN 
('varchar','clob','char','json','url','xml') THEN 4 * c.\"type_digits\" ELSE 
NULL END as bigint) AS \"CHAR_OCTET_LENGTH\", " +
                        "cast(c.\"number\" + 1 as int) AS \"ORDINAL_POSITION\", 
" +
                        "cast(CASE c.\"null\" WHEN true THEN 'YES' WHEN false 
THEN 'NO' ELSE '' END AS varchar(3)) AS \"IS_NULLABLE\", " +
                        "cast(null AS char(1)) AS \"SCOPE_CATALOG\", " +
@@ -3034,7 +3034,9 @@ public final class MonetDatabaseMetaData
                                " WHEN 'sec_interval' THEN 'interval second'" +
                                " ELSE \"sqlname\" END AS \"TYPE_NAME\", " +
                        
"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 
('time','timetz','timestamp','timestamptz') THEN \"digits\" -1" +
+                               " WHEN \"sqlname\" IN 
('sec_interval','day_interval') THEN 3" +
+                               " WHEN \"sqlname\" = 'month_interval' THEN 0 
ELSE \"digits\" END AS int) 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','xml')
 THEN \"sqlname\"||' '''" +
                                " ELSE NULL END AS varchar(16)) AS 
\"LITERAL_PREFIX\", " +
@@ -3043,7 +3045,7 @@ public final class MonetDatabaseMetaData
                                " ELSE NULL END AS varchar(2)) AS 
\"LITERAL_SUFFIX\", " +
                        "CASE WHEN \"sqlname\" IN ('char','varchar') THEN 'max 
length'" +
                                " WHEN \"sqlname\" = 'decimal' THEN 'precision, 
scale'" +
-                               " WHEN \"sqlname\" IN 
('time','timetz','timestamp','timestamptz','sec_interval') THEN 'precision'" +
+                               " WHEN \"sqlname\" IN 
('time','timetz','timestamp','timestamptz') THEN 'precision'" +
                                " ELSE NULL END AS \"CREATE_PARAMS\", " +
                        "cast(CASE WHEN \"systemname\" = 'oid' THEN " + 
DatabaseMetaData.typeNoNulls +
                                " ELSE " + DatabaseMetaData.typeNullable + " 
END AS smallint) AS \"NULLABLE\", " +
@@ -3057,7 +3059,8 @@ public final class MonetDatabaseMetaData
                        "CASE WHEN \"sqlname\" IN 
('sec_interval','day_interval','month_interval') THEN \"sqlname\" ELSE 
\"systemname\" END AS \"LOCAL_TYPE_NAME\", " +
                        "cast(0 AS smallint) AS \"MINIMUM_SCALE\", " +
                        "cast(CASE WHEN \"sqlname\" = 'decimal' THEN (CASE 
\"systemname\" WHEN 'int' THEN 9 WHEN 'lng' THEN 18 WHEN 'sht' THEN 4 WHEN 
'hge' THEN 38 WHEN 'bte' THEN 2 ELSE 0 END)" +
-                               " WHEN \"sqlname\" IN 
('time','timetz','timestamp','timestamptz','sec_interval') THEN 6 ELSE 0 END AS 
smallint) AS \"MAXIMUM_SCALE\", " +
+                               " WHEN \"sqlname\" IN 
('time','timetz','timestamp','timestamptz') THEN 6" +
+                               " WHEN \"sqlname\" IN 
('day_interval','sec_interval') THEN 3 ELSE 0 END AS smallint) AS 
\"MAXIMUM_SCALE\", " +
                        "cast(0 AS int) AS \"SQL_DATA_TYPE\", " +
                        "cast(0 AS int) AS \"SQL_DATETIME_SUB\", " +
                        "cast(CASE WHEN \"sqlname\" IN 
('time','timetz','timestamp','timestamptz','sec_interval') THEN 10 ELSE 
\"radix\" END AS int) AS \"NUM_PREC_RADIX\" " +
@@ -4043,7 +4046,7 @@ public final class MonetDatabaseMetaData
                        // mvd: do not remove next append. The String above is 
same as used by getProcedureColumns, so shared in class file.
                        
"cast(").append(DatabaseMetaData.functionNullableUnknown).append(" AS smallint) 
AS \"NULLABLE\", " +
                        "cast(null as char(1)) AS \"REMARKS\", " +
-                       "cast(CASE WHEN a.\"type\" IN ('char','varchar','clob') 
THEN a.\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " +
+                       "cast(CASE WHEN a.\"type\" IN 
('varchar','clob','char','json','url','xml') THEN 4 * a.\"type_digits\" WHEN 
a.\"type\" = 'blob' THEN a.\"type_digits\" ELSE NULL END as bigint) AS 
\"CHAR_OCTET_LENGTH\", " +
                        "cast(a.\"number\" as int) AS \"ORDINAL_POSITION\", " +
                        "cast('' as varchar(3)) AS \"IS_NULLABLE\", " +
                        // the specific name contains the function id, in order 
to be able to match the args to the correct overloaded function name
diff --git a/tests/JDBC_API_Tester.java b/tests/JDBC_API_Tester.java
--- a/tests/JDBC_API_Tester.java
+++ b/tests/JDBC_API_Tester.java
@@ -774,9 +774,9 @@ final public class JDBC_API_Tester {
                        compareResultSet(dbmd.getColumns(null, "sys", 
"table\\_types", null), "getColumns(null, sys, table\\_types, null)",
                        "Resultset with 24 columns\n" +
                        "TABLE_CAT      TABLE_SCHEM     TABLE_NAME      
COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   
DECIMAL_DIGITS  NUM_PREC_RADIX  NULLABLE        REMARKS COLUMN_DEF      
SQL_DATA_TYPE   SQL_DATETIME_SUB        CHAR_OCTET_LENGTH       
ORDINAL_POSITION        IS_NULLABLE     SCOPE_CATALOG   SCOPE_SCHEMA    
SCOPE_TABLE     SOURCE_DATA_TYPE        IS_AUTOINCREMENT        
IS_GENERATEDCOLUMN\n" +
-                       "char(1)        varchar(1024)   varchar(1024)   
varchar(1024)   int     varchar(1024)   int     int     int     int     int     
varchar(65000)  varchar(2048)   int     int     int     int     varchar(3)      
char(1) char(1) char(1) smallint        char(3) varchar(3)\n" +
+                       "char(1)        varchar(1024)   varchar(1024)   
varchar(1024)   int     varchar(1024)   int     int     int     int     int     
varchar(65000)  varchar(2048)   int     int     bigint  int     varchar(3)      
char(1) char(1) char(1) smallint        char(3) varchar(3)\n" +
                        "null   sys     table_types     table_type_id   5       
smallint        16      0       0       2       0       null    null    0       
0       null    1       NO      null    null    null    null    NO      NO\n" +
-                       "null   sys     table_types     table_type_name 12      
varchar 25      0       0       0       0       null    null    0       0       
25      2       NO      null    null    null    null    NO      NO\n");
+                       "null   sys     table_types     table_type_name 12      
varchar 25      0       0       0       0       null    null    0       0       
100     2       NO      null    null    null    null    NO      NO\n");
 
                        compareResultSet(dbmd.getPrimaryKeys(null, "sys", 
"table\\_types"), "getPrimaryKeys(null, sys, table\\_types)",
                        "Resultset with 6 columns\n" +
@@ -1028,6 +1028,8 @@ final public class JDBC_API_Tester {
                        "CREATE LOCAL TEMP TABLE tmp.tmp_nopk_twoucs (id2 INT 
NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);");
                handleExecuteDDL(stmt, action, objtype, "tmp.glbl_nopk_twoucs",
                        "CREATE GLOBAL TEMP TABLE tmp.glbl_nopk_twoucs (id2 INT 
NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);");
+               handleExecuteDDL(stmt, action, objtype, "tmp.tlargechar",
+                       "CREATE TEMP TABLE tlargechar (c1 varchar(2147483647), 
c2 char(2147483646), c3 clob(2147483645), c4 json(2147483644), c5 
url(2147483643)) ON COMMIT PRESERVE ROWS;");
                /* next 3 tables copied from example in 
https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function?view=sql-server-ver15
 */
                handleExecuteDDL(stmt, action, objtype, "\"CUSTOMERS\"",
                        "CREATE TABLE \"CUSTOMERS\" (\"CUSTID\" INT PRIMARY 
KEY, \"NAME\" VARCHAR(60) NOT NULL, \"ADDRESS\" VARCHAR(90), \"PHONE\" 
VARCHAR(20));");
@@ -1155,6 +1157,12 @@ final public class JDBC_API_Tester {
                        "null   jdbctst pk2c    TABLE   null    null    null    
null    null    null\n" +
                        "null   jdbctst pk_uc   TABLE   jdbctst.pk_uc table 
comment     null    null    null    null    null\n");
 
+                       compareResultSet(dbmd.getTables(null, "tmp", 
"tlargechar", null), "getTables(null, tmp, tlargechar, null)",
+                       "Resultset with 10 columns\n" +
+                       "TABLE_CAT      TABLE_SCHEM     TABLE_NAME      
TABLE_TYPE      REMARKS TYPE_CAT        TYPE_SCHEM      TYPE_NAME       
SELF_REFERENCING_COL_NAME       REF_GENERATION\n" +
+                       "char(1)        varchar(1024)   varchar(1024)   
varchar(25)     varchar(1048576)        char(1) char(1) char(1) char(1) 
char(1)\n" +
+                       "null   tmp     tlargechar      LOCAL TEMPORARY TABLE   
null    null    null    null    null    null\n");
+
                        compareResultSet(dbmd.getTables(null, "jdbctst", 
"schemas", null), "getTables(null, jdbctst, schemas, null)",
                        "Resultset with 10 columns\n" +
                        "TABLE_CAT      TABLE_SCHEM     TABLE_NAME      
TABLE_TYPE      REMARKS TYPE_CAT        TYPE_SCHEM      TYPE_NAME       
SELF_REFERENCING_COL_NAME       REF_GENERATION\n" +
@@ -1163,9 +1171,19 @@ final public class JDBC_API_Tester {
                        compareResultSet(dbmd.getColumns(null, "jdbctst", 
"pk\\_uc", null), "getColumns(null, jdbctst, pk\\_uc, null)",
                        "Resultset with 24 columns\n" +
                        "TABLE_CAT      TABLE_SCHEM     TABLE_NAME      
COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   
DECIMAL_DIGITS  NUM_PREC_RADIX  NULLABLE        REMARKS COLUMN_DEF      
SQL_DATA_TYPE   SQL_DATETIME_SUB        CHAR_OCTET_LENGTH       
ORDINAL_POSITION        IS_NULLABLE     SCOPE_CATALOG   SCOPE_SCHEMA    
SCOPE_TABLE     SOURCE_DATA_TYPE        IS_AUTOINCREMENT        
IS_GENERATEDCOLUMN\n" +
-                       "char(1)        varchar(1024)   varchar(1024)   
varchar(1024)   int     varchar(1024)   int     int     int     int     int     
varchar(65000)  varchar(2048)   int     int     int     int     varchar(3)      
char(1) char(1) char(1) smallint        char(3) varchar(3)\n" +
+                       "char(1)        varchar(1024)   varchar(1024)   
varchar(1024)   int     varchar(1024)   int     int     int     int     int     
varchar(65000)  varchar(2048)   int     int     bigint  int     varchar(3)      
char(1) char(1) char(1) smallint        char(3) varchar(3)\n" +
                        "null   jdbctst pk_uc   id1     4       int     32      
0       0       2       0       null    null    0       0       null    1       
NO      null    null    null    null    NO      NO\n" +
-                       "null   jdbctst pk_uc   name1   12      varchar 99      
0       0       0       1       null    null    0       0       99      2       
YES     null    null    null    null    NO      NO\n");
+                       "null   jdbctst pk_uc   name1   12      varchar 99      
0       0       0       1       null    null    0       0       396     2       
YES     null    null    null    null    NO      NO\n");
+
+                       compareResultSet(dbmd.getColumns(null, "tmp", 
"tlargechar", null), "getColumns(null, tmp, tlargechar, null)",
+                       "Resultset with 24 columns\n" +
+                       "TABLE_CAT      TABLE_SCHEM     TABLE_NAME      
COLUMN_NAME     DATA_TYPE       TYPE_NAME       COLUMN_SIZE     BUFFER_LENGTH   
DECIMAL_DIGITS  NUM_PREC_RADIX  NULLABLE        REMARKS COLUMN_DEF      
SQL_DATA_TYPE   SQL_DATETIME_SUB        CHAR_OCTET_LENGTH       
ORDINAL_POSITION        IS_NULLABLE     SCOPE_CATALOG   SCOPE_SCHEMA    
SCOPE_TABLE     SOURCE_DATA_TYPE        IS_AUTOINCREMENT        
IS_GENERATEDCOLUMN\n" +
+                       "char(1)        varchar(1024)   varchar(1024)   
varchar(1024)   int     varchar(1024)   int     int     int     int     int     
varchar(65000)  varchar(2048)   int     int     bigint  int     varchar(3)      
char(1) char(1) char(1) smallint        char(3) varchar(3)\n" +
+                       "null   tmp     tlargechar      c1      12      varchar 
2147483647      0       0       0       1       null    null    0       0       
8589934588      1       YES     null    null    null    null    NO      NO\n" +
+                       "null   tmp     tlargechar      c2      1       char    
2147483646      0       0       0       1       null    null    0       0       
8589934584      2       YES     null    null    null    null    NO      NO\n" +
+                       "null   tmp     tlargechar      c3      2005    clob    
2147483645      0       0       0       1       null    null    0       0       
8589934580      3       YES     null    null    null    null    NO      NO\n" +
+                       "null   tmp     tlargechar      c4      12      json    
2147483644      0       0       0       1       null    null    0       0       
8589934576      4       YES     null    null    null    null    NO      NO\n" +
+                       "null   tmp     tlargechar      c5      12      url     
2147483643      0       0       0       1       null    null    0       0       
8589934572      5       YES     null    null    null    null    NO      NO\n");
 
                        compareResultSet(dbmd.getPrimaryKeys(null, "jdbctst", 
"pk\\_uc"), "getPrimaryKeys(null, jdbctst, pk\\_uc)",
                        "Resultset with 6 columns\n" +
@@ -1398,6 +1416,7 @@ final public class JDBC_API_Tester {
                handleExecuteDDL(stmt, action, objtype, "jdbctst.nopk_twoucs", 
"DROP TABLE jdbctst.nopk_twoucs;");
                handleExecuteDDL(stmt, action, objtype, "tmp.tmp_nopk_twoucs", 
"DROP TABLE tmp.tmp_nopk_twoucs;");
                handleExecuteDDL(stmt, action, objtype, "tmp.glbl_nopk_twoucs", 
"DROP TABLE tmp.glbl_nopk_twoucs;");
+               handleExecuteDDL(stmt, action, objtype, "tmp.tlargechar", "DROP 
TABLE tmp.tlargechar;");
                handleExecuteDDL(stmt, action, objtype, "jdbctst.\"LINES\"", 
"DROP TABLE jdbctst.\"LINES\";");
                handleExecuteDDL(stmt, action, objtype, "jdbctst.\"ORDERS\"", 
"DROP TABLE jdbctst.\"ORDERS\";");
                handleExecuteDDL(stmt, action, objtype, 
"jdbctst.\"CUSTOMERS\"", "DROP TABLE jdbctst.\"CUSTOMERS\";");
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to