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 -- [email protected]
To unsubscribe send an email to [email protected]