Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix | Align DatabaseMetadata.getColumns with JDBC 4.3 Specifications #1016

Merged
merged 23 commits into from
Jun 7, 2019
Merged
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
bc6a311
Fix | Align DatabaseMetadata.getColumns with JDBC 4.3 Specifications
rene-ye Apr 1, 2019
e8e5713
Fix | Default catalog behavior with getColumns()
rene-ye Apr 1, 2019
8b3ead2
Add | SS_IS_SPRASE and SS_IS_COLUMN_SET columns
rene-ye Apr 2, 2019
3966810
Add | Catalog switching and backwards compatibility query edit
rene-ye Apr 3, 2019
d79a075
Fix | Driver eating exception and the ability to count to 12
rene-ye Apr 4, 2019
f829427
Fix | SS_UDT_ASSEMBLY_TYPE_NAME length can be greater than 128
rene-ye Apr 4, 2019
7f755c5
Add | Handle preparedstatement closing
rene-ye Apr 4, 2019
fce00aa
Merge branch 'dev' into issue1013
rene-ye Apr 11, 2019
d1da3b2
Fix | Unhandled exception caused by merge error
rene-ye Apr 12, 2019
f582cc6
Fix | Format file
rene-ye May 16, 2019
eecdc8a
Fix | Add workaround for Azure DW
rene-ye May 21, 2019
a47b135
Fix | Flipping null comparisons according to coding standards
rene-ye May 22, 2019
16a0f39
Merge branch 'dev' of https://github.com/Microsoft/mssql-jdbc into is…
rene-ye May 22, 2019
0fd5e12
Fix | Addressing comments
rene-ye May 28, 2019
f327343
Fix | error handling
rene-ye May 30, 2019
7d900fb
Add | Logging
rene-ye May 30, 2019
087e822
comments
rene-ye May 30, 2019
3b9935f
Fix | function name in logs
rene-ye May 31, 2019
8f34907
Fix | move switchCatalogs out of if loop
rene-ye Jun 3, 2019
81bb73d
Exclude | Test from DW
rene-ye Jun 6, 2019
ef9606d
Fix | Single quote issues
rene-ye Jun 6, 2019
3e345f6
Merge branch 'dev' of https://github.com/Microsoft/mssql-jdbc into is…
rene-ye Jun 6, 2019
d85364b
Fix | Unescape tablename
rene-ye Jun 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -601,72 +601,63 @@ private static String EscapeIDName(String inID) throws SQLServerException {
return outID.toString();
}

private static final String[] getColumnsColumnNames = {/* 1 */ TABLE_CAT, /* 2 */ TABLE_SCHEM, /* 3 */ TABLE_NAME,
/* 4 */ COLUMN_NAME, /* 5 */ DATA_TYPE, /* 6 */ TYPE_NAME, /* 7 */ COLUMN_SIZE, /* 8 */ BUFFER_LENGTH,
/* 9 */ DECIMAL_DIGITS, /* 10 */ NUM_PREC_RADIX, /* 11 */ NULLABLE, /* 12 */ REMARKS, /* 13 */ COLUMN_DEF,
/* 14 */ SQL_DATA_TYPE, /* 15 */ SQL_DATETIME_SUB, /* 16 */ CHAR_OCTET_LENGTH, /* 17 */ ORDINAL_POSITION,
/* 18 */ IS_NULLABLE};
// SQL10 columns not exahustive we only need to set until the one we want to
// change
// in this case we want to change SS_IS_IDENTITY 22nd column to
// IS_AUTOINCREMENT
// to be inline with JDBC spec
private static final String[] getColumnsColumnNamesKatmai = {/* 1 */ TABLE_CAT, /* 2 */ TABLE_SCHEM,
/* 3 */ TABLE_NAME, /* 4 */ COLUMN_NAME, /* 5 */ DATA_TYPE, /* 6 */ TYPE_NAME, /* 7 */ COLUMN_SIZE,
/* 8 */ BUFFER_LENGTH, /* 9 */ DECIMAL_DIGITS, /* 10 */ NUM_PREC_RADIX, /* 11 */ NULLABLE, /* 12 */ REMARKS,
/* 13 */ COLUMN_DEF, /* 14 */ SQL_DATA_TYPE, /* 15 */ SQL_DATETIME_SUB, /* 16 */ CHAR_OCTET_LENGTH,
/* 17 */ ORDINAL_POSITION, /* 18 */ IS_NULLABLE, /* 20 */ SS_IS_SPARSE, /* 20 */ SS_IS_COLUMN_SET,
/* 21 */ IS_GENERATEDCOLUMN, /* 22 */ IS_AUTOINCREMENT};

@Override
public java.sql.ResultSet getColumns(String catalog, String schema, String table,
String col) throws SQLServerException, SQLTimeoutException {
String col) throws SQLException {
rene-ye marked this conversation as resolved.
Show resolved Hide resolved
if (loggerExternal.isLoggable(Level.FINER) && Util.isActivityTraceOn()) {
loggerExternal.finer(toString() + " ActivityId: " + ActivityCorrelator.getNext().toString());
}
checkClosed();

// sp_columns supports wild carding schema table and columns
String column = EscapeIDName(col);
table = EscapeIDName(table);
schema = EscapeIDName(schema);

/*
* sp_columns [ @table_name = ] object [ , [ @table_owner = ] owner ] [ , [ @table_qualifier = ] qualifier ] [ ,
* [ @column_name = ] column ] [ , [ @ODBCVer = ] ODBCVer ]
*/
String[] arguments;
if (connection.isKatmaiOrLater())
arguments = new String[6];
else
arguments = new String[5];
arguments[0] = table;
arguments[1] = schema;
arguments[2] = catalog;
arguments[3] = column;
if (connection.isKatmaiOrLater()) {
arguments[4] = "2"; // give information about everything including
// sparse columns
arguments[5] = "3"; // odbc version
} else
arguments[4] = "3"; // odbc version
SQLServerResultSet rs;
if (connection.isKatmaiOrLater())
rs = getResultSetWithProvidedColumnNames(catalog, CallableHandles.SP_COLUMNS, arguments,
getColumnsColumnNamesKatmai);
else
rs = getResultSetWithProvidedColumnNames(catalog, CallableHandles.SP_COLUMNS, arguments,
getColumnsColumnNames);
// Hook in a filter on the DATA_TYPE column of the result set we're
// going to return that converts the ODBC values from sp_columns
// into JDBC values.
rs.getColumn(5).setFilter(new DataTypeFilter());

if (connection.isKatmaiOrLater()) {
rs.getColumn(22).setFilter(new IntColumnIdentityFilter());
String originalCatalog = null;
originalCatalog = switchCatalogs(catalog);
ulvii marked this conversation as resolved.
Show resolved Hide resolved
String spColumnsSql = "DECLARE @mssqljdbc_temp_sp_columns_result TABLE(TABLE_QUALIFIER SYSNAME, TABLE_OWNER SYSNAME,"
+ "TABLE_NAME SYSNAME, COLUMN_NAME SYSNAME, DATA_TYPE SMALLINT, TYPE_NAME SYSNAME, PRECISION INT,"
+ "LENGTH INT, SCALE SMALLINT, RADIX SMALLINT, NULLABLE SMALLINT, REMARKS VARCHAR(254), COLUMN_DEF NVARCHAR(4000),"
+ "SQL_DATA_TYPE SMALLINT, SQL_DATETIME_SUB SMALLINT, CHAR_OCTET_LENGTH INT, ORDINAL_POSITION INT,"
+ "IS_NULLABLE VARCHAR(254), SS_IS_SPARSE SMALLINT, SS_IS_COLUMN_SET SMALLINT, SS_IS_COMPUTED SMALLINT,"
+ "SS_IS_IDENTITY SMALLINT, SS_UDT_CATALOG_NAME NVARCHAR(128), SS_UDT_SCHEMA_NAME NVARCHAR(128),"
+ "SS_UDT_ASSEMBLY_TYPE_NAME NVARCHAR(max), SS_XML_SCHEMACOLLECTION_CATALOG_NAME NVARCHAR(128),"
+ "SS_XML_SCHEMACOLLECTION_SCHEMA_NAME NVARCHAR(128), SS_XML_SCHEMACOLLECTION_NAME NVARCHAR(128),"
+ "SS_DATA_TYPE TINYINT);"

+ "INSERT INTO @mssqljdbc_temp_sp_columns_result EXEC sp_columns_100 ?,?,?,?,?,?;"

+ "SELECT TABLE_QUALIFIER AS TABLE_CAT, TABLE_OWNER AS TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE,"
+ "TYPE_NAME, PRECISION AS COLUMN_SIZE, LENGTH AS BUFFER_LENGTH, SCALE AS DECIMAL_DIGITS, RADIX AS NUM_PREC_RADIX,"
+ "NULLABLE, REMARKS, COLUMN_DEF, SQL_DATA_TYPE, SQL_DATETIME_SUB, CHAR_OCTET_LENGTH, ORDINAL_POSITION, IS_NULLABLE,"
+ "NULL AS SCOPE_CATALOG, NULL AS SCOPE_SCHEMA, NULL AS SCOPE_TABLE, SS_DATA_TYPE AS SOURCE_DATA_TYPE,"
+ "CASE SS_IS_IDENTITY WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' WHEN '' THEN '' END AS IS_AUTOINCREMENT,"
+ "CASE SS_IS_COMPUTED WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' WHEN '' THEN '' END AS IS_GENERATEDCOLUMN, "
+ "SS_IS_SPARSE, SS_IS_COLUMN_SET, SS_UDT_CATALOG_NAME, SS_UDT_SCHEMA_NAME, SS_UDT_ASSEMBLY_TYPE_NAME,"
+ "SS_XML_SCHEMACOLLECTION_CATALOG_NAME, SS_XML_SCHEMACOLLECTION_SCHEMA_NAME, SS_XML_SCHEMACOLLECTION_NAME "
+ "FROM @mssqljdbc_temp_sp_columns_result;";
SQLServerResultSet rs = null;
SQLException errorOnClose = null;
java.sql.PreparedStatement pstmt = (SQLServerPreparedStatement) this.connection.prepareStatement(spColumnsSql);
pstmt.closeOnCompletion();
try {
pstmt.setString(1, (table != null && !table.isEmpty()) ? table : "%");
pstmt.setString(2, (schema != null && !schema.isEmpty()) ? schema : "%");
pstmt.setString(3, (catalog != null && !catalog.isEmpty()) ? catalog : this.connection.getCatalog());
pstmt.setString(4, (col != null && !col.isEmpty()) ? col : "%");
pstmt.setInt(5, 2);// show sparse columns
pstmt.setInt(6, 3);// odbc version

rs = (SQLServerResultSet) pstmt.executeQuery();
rs.getColumn(5).setFilter(new DataTypeFilter());
rs.getColumn(7).setFilter(new ZeroFixupFilter());
rs.getColumn(8).setFilter(new ZeroFixupFilter());
rs.getColumn(16).setFilter(new ZeroFixupFilter());
} catch (SQLException e) {
errorOnClose = e;
pstmt.close();
peterbae marked this conversation as resolved.
Show resolved Hide resolved
} finally {
if (null != originalCatalog) {
connection.setCatalog(originalCatalog);
}
if (errorOnClose != null) {
throw errorOnClose;
}
}
return rs;
}
Expand Down Expand Up @@ -1215,12 +1206,12 @@ public ResultSet getPseudoColumns(String catalog, String schemaPattern, String t
/* 4 */ " cast(NULL as char(1)) as COLUMN_NAME," +
/* 5 */ " cast(0 as int) as DATA_TYPE," +
/* 6 */ " cast(0 as int) as COLUMN_SIZE," +
/* 8 */ " cast(0 as int) as DECIMAL_DIGITS," +
/* 9 */ " cast(0 as int) as NUM_PREC_RADIX," +
/* 10 */ " cast(NULL as char(1)) as COLUMN_USAGE," +
/* 11 */ " cast(NULL as char(1)) as REMARKS," +
/* 12 */ " cast(0 as int) as CHAR_OCTET_LENGTH," +
/* 13 */ " cast(NULL as char(1)) as IS_NULLABLE" + " where 0 = 1");
/* 7 */ " cast(0 as int) as DECIMAL_DIGITS," +
/* 8 */ " cast(0 as int) as NUM_PREC_RADIX," +
/* 9 */ " cast(NULL as char(1)) as COLUMN_USAGE," +
/* 10 */ " cast(NULL as char(1)) as REMARKS," +
/* 11 */ " cast(0 as int) as CHAR_OCTET_LENGTH," +
/* 12 */ " cast(NULL as char(1)) as IS_NULLABLE" + " where 0 = 1");
}

@Override
Expand Down Expand Up @@ -1330,34 +1321,26 @@ public String getSQLKeywords() throws SQLServerException {
}

private static String createSqlKeyWords() {
return "ADD,ALL,ALTER,AND,ANY,AS,ASC,AUTHORIZATION," +
"BACKUP,BEGIN,BETWEEN,BREAK,BROWSE,BULK,BY," +
"CASCADE,CASE,CHECK,CHECKPOINT,CLOSE,CLUSTERED,COALESCE,COLLATE,COLUMN,COMMIT," +
"COMPUTE,CONSTRAINT,CONTAINS,CONTAINSTABLE,CONTINUE,CONVERT,CREATE,CROSS,CURRENT," +
"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR," +
"DATABASE,DBCC,DEALLOCATE,DECLARE,DEFAULT,DELETE,DENY,DESC,DISK," +
"DISTINCT,DISTRIBUTED,DOUBLE,DROP,DUMP," +
"ELSE,END,ERRLVL,ESCAPE,EXCEPT,EXEC,EXECUTE,EXISTS,EXIT,EXTERNAL," +
"FETCH,FILE,FILLFACTOR,FOR,FOREIGN,FREETEXT,FREETEXTTABLE,FROM,FULL,FUNCTION," +
"GOTO,GRANT,GROUP," +
"HAVING,HOLDLOCK," +
"IDENTITY,IDENTITY_INSERT,IDENTITYCOL,IF,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS," +
"JOIN," +
"KEY,KILL," +
"LEFT,LIKE,LINENO,LOAD," +
"MERGE," +
"NATIONAL,NOCHECK,NONCLUSTERED,NOT,NULL,NULLIF," +
"OF,OFF,OFFSETS,ON,OPEN,OPENDATASOURCE,OPENQUERY," +
"OPENROWSET,OPENXML,OPTION,OR,ORDER,OUTER,OVER," +
"PERCENT,PIVOT,PLAN,PRECISION,PRIMARY,PRINT,PROC,PROCEDURE,PUBLIC," +
"RAISERROR,READ,READTEXT,RECONFIGURE,REFERENCES,REPLICATION,RESTORE,RESTRICT," +
"RETURN,REVERT,REVOKE,RIGHT,ROLLBACK,ROWCOUNT,ROWGUIDCOL,RULE," +
"SAVE,SCHEMA,SECURITYAUDIT,SELECT,SEMANTICKEYPHRASETABLE,SEMANTICSIMILARITYDETAILSTABLE," +
"SEMANTICSIMILARITYTABLE,SESSION_USER,SET,SETUSER,SHUTDOWN,SOME,STATISTICS,SYSTEM_USER," +
"TABLE,TABLESAMPLE,TEXTSIZE,THEN,TO,TOP,TRAN,TRANSACTION,TRIGGER,TRUNCATE,TRY_CONVERT,TSEQUAL," +
"UNION,UNIQUE,UNPIVOT,UPDATE,UPDATETEXT,USE,USER," +
"VALUES,VARYING,VIEW," +
"WAITFOR,WHEN,WHERE,WHILE,WITH,WITHIN GROUP,WRITETEXT";
return "ADD,ALL,ALTER,AND,ANY,AS,ASC,AUTHORIZATION," + "BACKUP,BEGIN,BETWEEN,BREAK,BROWSE,BULK,BY,"
+ "CASCADE,CASE,CHECK,CHECKPOINT,CLOSE,CLUSTERED,COALESCE,COLLATE,COLUMN,COMMIT,"
+ "COMPUTE,CONSTRAINT,CONTAINS,CONTAINSTABLE,CONTINUE,CONVERT,CREATE,CROSS,CURRENT,"
+ "CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"
+ "DATABASE,DBCC,DEALLOCATE,DECLARE,DEFAULT,DELETE,DENY,DESC,DISK,"
+ "DISTINCT,DISTRIBUTED,DOUBLE,DROP,DUMP,"
+ "ELSE,END,ERRLVL,ESCAPE,EXCEPT,EXEC,EXECUTE,EXISTS,EXIT,EXTERNAL,"
+ "FETCH,FILE,FILLFACTOR,FOR,FOREIGN,FREETEXT,FREETEXTTABLE,FROM,FULL,FUNCTION," + "GOTO,GRANT,GROUP,"
+ "HAVING,HOLDLOCK,"
+ "IDENTITY,IDENTITY_INSERT,IDENTITYCOL,IF,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS," + "JOIN,"
+ "KEY,KILL," + "LEFT,LIKE,LINENO,LOAD," + "MERGE," + "NATIONAL,NOCHECK,NONCLUSTERED,NOT,NULL,NULLIF,"
+ "OF,OFF,OFFSETS,ON,OPEN,OPENDATASOURCE,OPENQUERY," + "OPENROWSET,OPENXML,OPTION,OR,ORDER,OUTER,OVER,"
+ "PERCENT,PIVOT,PLAN,PRECISION,PRIMARY,PRINT,PROC,PROCEDURE,PUBLIC,"
+ "RAISERROR,READ,READTEXT,RECONFIGURE,REFERENCES,REPLICATION,RESTORE,RESTRICT,"
+ "RETURN,REVERT,REVOKE,RIGHT,ROLLBACK,ROWCOUNT,ROWGUIDCOL,RULE,"
+ "SAVE,SCHEMA,SECURITYAUDIT,SELECT,SEMANTICKEYPHRASETABLE,SEMANTICSIMILARITYDETAILSTABLE,"
+ "SEMANTICSIMILARITYTABLE,SESSION_USER,SET,SETUSER,SHUTDOWN,SOME,STATISTICS,SYSTEM_USER,"
+ "TABLE,TABLESAMPLE,TEXTSIZE,THEN,TO,TOP,TRAN,TRANSACTION,TRIGGER,TRUNCATE,TRY_CONVERT,TSEQUAL,"
+ "UNION,UNIQUE,UNPIVOT,UPDATE,UPDATETEXT,USE,USER," + "VALUES,VARYING,VIEW,"
+ "WAITFOR,WHEN,WHERE,WHILE,WITH,WITHIN GROUP,WRITETEXT";
}

@Override
Expand Down Expand Up @@ -2392,12 +2375,10 @@ int oneValueToAnother(int odbcType) {
return SSType.XML.getJDBCType().asJavaSqlType();
case ODBC_SQL_UDT:
return SSType.UDT.getJDBCType().asJavaSqlType();

default:
return odbcType;
}
}

}


Expand Down