diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java index ae98a220c..d34822aa2 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java @@ -76,6 +76,7 @@ enum CallableHandles { SP_STORED_PROCEDURES("{call sp_stored_procedures(?, ?, ?) }", "{call sp_stored_procedures(?, ?, ?) }"), SP_TABLE_PRIVILEGES("{call sp_table_privileges(?,?,?) }", "{call sp_table_privileges(?,?,?) }"), SP_PKEYS("{ call sp_pkeys (?, ?, ?)}", "{ call sp_pkeys (?, ?, ?)}"); + // stored procs before Katmai ie SS10 private final String preKatProc; // procs on or after katmai @@ -755,8 +756,6 @@ public java.sql.ResultSet getColumns(String catalog, String schema, String table userRs.getColumn(7).setFilter(new ZeroFixupFilter()); userRs.getColumn(8).setFilter(new ZeroFixupFilter()); userRs.getColumn(16).setFilter(new ZeroFixupFilter()); - userRs.getColumn(23).setFilter(new IntColumnIdentityFilter()); - userRs.getColumn(24).setFilter(new IntColumnIdentityFilter()); } catch (SQLException e) { if (null != resultPstmt) { try { @@ -785,7 +784,13 @@ private String generateAzureDWSelect(ResultSet rs, Map columns) if (null == o) { sb.append("NULL"); } else if (o instanceof Number) { - sb.append(o.toString()); + if ("IS_AUTOINCREMENT".equalsIgnoreCase(p.getValue()) + || "IS_GENERATEDCOLUMN".equalsIgnoreCase(p.getValue())) { + sb.append("'").append(Util.escapeSingleQuotes(Util.zeroOneToYesNo(((Number) o).intValue()))) + .append("'"); + } else { + sb.append(o.toString()); + } } else { sb.append("'").append(Util.escapeSingleQuotes(o.toString())).append("'"); } @@ -2630,10 +2635,6 @@ final Object apply(Object value, JDBCType asJDBCType) throws SQLServerException * proc returns and what the JDBC spec expects. */ class IntColumnIdentityFilter extends ColumnFilter { - private static String zeroOneToYesNo(int i) { - return 0 == i ? "NO" : "YES"; - } - final Object apply(Object value, JDBCType asJDBCType) throws SQLServerException { if (null == value) return value; @@ -2658,12 +2659,12 @@ final Object apply(Object value, JDBCType asJDBCType) throws SQLServerException // anyways. Only thing is that // the user will get a cast exception in this case. assert (value instanceof Number); - return zeroOneToYesNo(((Number) value).intValue()); + return Util.zeroOneToYesNo(((Number) value).intValue()); case CHAR: case VARCHAR: case LONGVARCHAR: assert (value instanceof String); - return zeroOneToYesNo(Integer.parseInt((String) value)); + return Util.zeroOneToYesNo(Integer.parseInt((String) value)); default: DataTypes.throwConversionError("char", asJDBCType.toString()); return value; diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/Util.java b/src/main/java/com/microsoft/sqlserver/jdbc/Util.java index a9914aa4e..b1c26f18c 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/Util.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/Util.java @@ -1019,6 +1019,10 @@ static String convertInputStreamToString(java.io.InputStream is) throws IOExcept } return result.toString(); } + + static String zeroOneToYesNo(int i) { + return 0 == i ? "NO" : "YES"; + } } @@ -1077,8 +1081,8 @@ final String asEscapedString() { fullName.append("[").append(databaseName).append("]."); else assert 0 == serverName.length(); - if (schemaName.length() > 0) + fullName.append("[").append(schemaName).append("]."); else if (databaseName.length() > 0) fullName.append('.'); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java index 21e382705..8aabd4ede 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java @@ -24,8 +24,11 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Types; import java.text.MessageFormat; +import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.Map; import java.util.UUID; import java.util.jar.Attributes; import java.util.jar.Manifest; @@ -56,8 +59,8 @@ public class DatabaseMetaDataTest extends AbstractTest { private static final String tableName = RandomUtil.getIdentifier("DBMetadataTable"); private static final String functionName = RandomUtil.getIdentifier("DBMetadataFunction"); - private static LinkedHashMap getColumnsDWColumns = null; - private static LinkedHashMap getImportedKeysDWColumns = null; + private static Map getColumnsDWColumns = null; + private static Map getImportedKeysDWColumns = null; /** * Verify DatabaseMetaData#isWrapperFor and DatabaseMetaData#unwrap. @@ -613,7 +616,7 @@ public void testGetMaxConnections() throws SQLException { } @Test - public void testGetColumn() throws SQLException { + public void testGetColumns() throws SQLException { try (Connection conn = getConnection();) { DatabaseMetaData databaseMetaData = conn.getMetaData(); @@ -651,12 +654,66 @@ public void testGetColumn() throws SQLException { getColumnsDWColumns.put(27, "SS_XML_SCHEMACOLLECTION_SCHEMA_NAME"); getColumnsDWColumns.put(28, "SS_XML_SCHEMACOLLECTION_NAME"); + Map firstRow = new HashMap(); + String dbName = ds.getDatabaseName(); + if (null == dbName) { + firstRow.put("TABLE_CAT", "master"); + } else { + firstRow.put("TABLE_CAT", ds.getDatabaseName()); + } + firstRow.put("TABLE_SCHEM", "dbo"); + firstRow.put("TABLE_NAME", tableName); + firstRow.put("COLUMN_NAME", "col_1"); + firstRow.put("DATA_TYPE", 4); + firstRow.put("TYPE_NAME", "int"); + firstRow.put("COLUMN_SIZE", 10); + firstRow.put("BUFFER_LENGTH", 4); + firstRow.put("DECIMAL_DIGITS", 0); + firstRow.put("NUM_PREC_RADIX", 10); + firstRow.put("NULLABLE", 0); + firstRow.put("REMARKS", null); + firstRow.put("COLUMN_DEF", null); + firstRow.put("SQL_DATA_TYPE", 4); + firstRow.put("SQL_DATETIME_SUB", null); + firstRow.put("CHAR_OCTET_LENGTH", null); + firstRow.put("ORDINAL_POSITION", 1); + firstRow.put("IS_NULLABLE", "NO"); + firstRow.put("SCOPE_CATALOG", null); + firstRow.put("SCOPE_SCHEMA", null); + firstRow.put("SCOPE_TABLE", null); + firstRow.put("SOURCE_DATA_TYPE", 56); + firstRow.put("IS_AUTOINCREMENT", "NO"); + firstRow.put("IS_GENERATEDCOLUMN", "NO"); + firstRow.put("SS_IS_SPARSE", 0); + firstRow.put("SS_IS_COLUMN_SET", 0); + firstRow.put("SS_UDT_CATALOG_NAME", null); + firstRow.put("SS_UDT_SCHEMA_NAME", null); + firstRow.put("SS_UDT_ASSEMBLY_TYPE_NAME", null); + firstRow.put("SS_XML_SCHEMACOLLECTION_CATALOG_NAME", null); + firstRow.put("SS_XML_SCHEMACOLLECTION_SCHEMA_NAME", null); + firstRow.put("SS_XML_SCHEMACOLLECTION_NAME", null); + try (ResultSet resultSet = databaseMetaData.getColumns(null, null, tableName, "%");) { ResultSetMetaData rsmd = resultSet.getMetaData(); int rowCount = 0; while (resultSet.next()) { for (int i = 1; i < rsmd.getColumnCount(); i++) { - assertEquals(rsmd.getColumnName(i), getColumnsDWColumns.values().toArray()[i - 1]); + String columnName = rsmd.getColumnName(i); + Object value = resultSet.getObject(columnName); + if (0 == rowCount) { + int expectedType = rsmd.getColumnType(i); + if (null != firstRow.get(columnName) + && (Types.VARCHAR == expectedType || Types.NVARCHAR == expectedType)) { + assertEquals(firstRow.get(columnName).toString().toLowerCase(), + resultSet.getString(columnName).toLowerCase()); + } else if (null != firstRow.get(columnName) && (Types.TINYINT == expectedType + || Types.SMALLINT == expectedType || Types.INTEGER == expectedType)) { + assertEquals(firstRow.get(columnName), resultSet.getInt(columnName)); + } else { + assertEquals(firstRow.get(columnName), value); + } + } + assertEquals(getColumnsDWColumns.values().toArray()[i - 1], columnName); } rowCount++; }