diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java index 35f239608..0fc23c8e6 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java @@ -41,6 +41,7 @@ import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -113,6 +114,22 @@ private class ColumnMapping implements Serializable { } } + private class ColumnOrderHint implements Serializable { + /** + * Always update serialVersionUID when prompted. + */ + private static final long serialVersionUID = 6132627333120344137L; + + String columnName = null; + + SQLServerSortOrder sortOrder; + + ColumnOrderHint(String columnName, SQLServerSortOrder sortOrder) { + this.columnName = columnName; + this.sortOrder = sortOrder; + } + } + /** * Class name for logging. */ @@ -138,6 +155,11 @@ private class ColumnMapping implements Serializable { */ private List columnMappings; + /** + * Column order hints describe the sort order of columns in the clustered index of the destination + */ + private List columnOrderHints; + /** * Flag if SQLServerBulkCopy owns the connection and should close it when Close is called */ @@ -459,6 +481,43 @@ public void clearColumnMappings() { loggerExternal.exiting(loggerClassName, "clearColumnMappings"); } + /** + * Adds a new column order hint, specify the column name and sort order + * + * @param columnName + * Column name. + * @param sortOrder + * Column sort order. + * @throws SQLServerException + * If the column order hint is invalid + */ + public void addColumnOrderHint(String columnName, SQLServerSortOrder sortOrder) throws SQLServerException { + if (loggerExternal.isLoggable(java.util.logging.Level.FINER)) { + loggerExternal.entering(loggerClassName, "addColumnOrderHint", + new Object[] {columnName, sortOrder}); + } + + if (null == columnName || columnName.isEmpty()) { + throwInvalidArgument("columnName"); + } else if (null == sortOrder || SQLServerSortOrder.UNSPECIFIED == sortOrder) { + throwInvalidArgument("sortOrder"); + } + columnOrderHints.add(new ColumnOrderHint(columnName, sortOrder)); + + loggerExternal.exiting(loggerClassName, "addColumnOrderHint"); + } + + /** + * Clears the contents of the column order hints + */ + public void clearColumnOrderHints() { + loggerExternal.entering(loggerClassName, "clearColumnOrderHints"); + + columnOrderHints.clear(); + + loggerExternal.exiting(loggerClassName, "clearColumnOrderHints"); + } + /** * Closes the SQLServerBulkCopy instance */ @@ -648,6 +707,7 @@ public void writeToServer(ISQLServerBulkData sourceData) throws SQLServerExcepti */ private void initializeDefaults() { columnMappings = new ArrayList<>(); + columnOrderHints = new ArrayList<>(); destinationTableName = null; serverBulkData = null; sourceResultSet = null; @@ -1482,6 +1542,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx, private String createInsertBulkCommand(TDSWriter tdsWriter) throws SQLServerException { StringBuilder bulkCmd = new StringBuilder(); List bulkOptions = new ArrayList<>(); + Set destColumns = new HashSet<>(); String endColumn = " , "; bulkCmd.append("INSERT BULK ").append(destinationTableName).append(" ("); @@ -1490,8 +1551,12 @@ private String createInsertBulkCommand(TDSWriter tdsWriter) throws SQLServerExce endColumn = " ) "; } ColumnMapping colMapping = columnMappings.get(i); - String columnCollation = destColumnMetadata - .get(columnMappings.get(i).destinationColumnOrdinal).collationName; + + BulkColumnMetaData columnMetaData = destColumnMetadata + .get(columnMappings.get(i).destinationColumnOrdinal); + destColumns.add(columnMetaData.columnName); + + String columnCollation = columnMetaData.collationName; String addCollate = ""; String destType = getDestTypeFromSrcType(colMapping.sourceColumnOrdinal, @@ -1536,6 +1601,36 @@ private String createInsertBulkCommand(TDSWriter tdsWriter) throws SQLServerExce bulkOptions.add("ALLOW_ENCRYPTED_VALUE_MODIFICATIONS"); } + if (0 < columnOrderHints.size()) { + StringBuilder orderHintText = new StringBuilder("ORDER("); + + for (ColumnOrderHint columnOrderHint : columnOrderHints) { + String columnName = columnOrderHint.columnName; + + if (!destColumns.contains(columnName)) { + MessageFormat form = new MessageFormat( + SQLServerException.getErrString("R_invalidColumn")); + Object[] msgArgs = { columnName }; + throw new SQLServerException(form.format(msgArgs), SQLState.COL_NOT_FOUND, + DriverError.NOT_SET, null); + } + + String sortOrderText = columnOrderHint.sortOrder == SQLServerSortOrder.DESCENDING ? "DESC" : "ASC"; + + if (columnName.contains("]")) { + String escapedColumnName = columnName.replaceAll("]", "]]"); + orderHintText.append("[").append(escapedColumnName).append("] ").append(sortOrderText).append(", "); + } else { + orderHintText.append("[").append(columnName).append("] ").append(sortOrderText).append(", "); + } + } + + orderHintText.setLength(orderHintText.length() - 2); + orderHintText.append(")"); + + bulkOptions.add(orderHintText.toString()); + } + Iterator it = bulkOptions.iterator(); if (it.hasNext()) { bulkCmd.append(" with ("); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnOrderHintTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnOrderHintTest.java new file mode 100644 index 000000000..6901a815b --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnOrderHintTest.java @@ -0,0 +1,251 @@ +/* + * Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made + * available under the terms of the MIT License. See the LICENSE file in the project root for more information. + */ +package com.microsoft.sqlserver.jdbc.bulkCopy; + +import com.microsoft.sqlserver.jdbc.*; +import com.microsoft.sqlserver.testframework.*; +import com.microsoft.sqlserver.testframework.sqlType.SqlVarChar; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import java.sql.*; +import static org.junit.jupiter.api.Assertions.fail; + + +/** + * Test BulkCopy Column Order Hints + */ +@RunWith(JUnitPlatform.class) +@DisplayName("BulkCopy Column Order Hints Test") +public class BulkCopyColumnOrderHintTest extends BulkCopyTestSetUp { + private String prcdb = RandomUtil.getIdentifier("BulkCopy_PRC_DB"); + + @Test + @DisplayName("BulkCopy:test no column order hints") + @Tag(Constants.xAzureSQLDW) + public void testNoCOH() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable destTable = null; + try { + // create destination table + destTable = sourceTable.cloneSchema(); + stmt.createTable(destTable); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTable, destTable); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(destTable.getEscapedTableName(), (Statement) stmt.product()); + } + } + } + + @Test + @DisplayName("BulkCopy:test column order hints") + @Tag(Constants.xAzureSQLDW) + public void testCOH() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable destTable = null; + try { + // create destination table + destTable = sourceTable.cloneSchema(); + stmt.createTable(destTable); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + + bulkWrapper.setColumnOrderHint(destTable.getColumnName(0), SQLServerSortOrder.ASCENDING); + + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTable, destTable); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(destTable.getEscapedTableName(), (Statement) stmt.product()); + } + } + } + + @Test + @DisplayName("BulkCopy:test column order hints with multiple columns") + @Tag(Constants.xAzureSQLDW) + public void testMultiColumnsCOH() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable destTable = null; + try { + // create destination table + destTable = sourceTable.cloneSchema(); + stmt.createTable(destTable); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + + bulkWrapper.setColumnOrderHint(destTable.getColumnName(0), SQLServerSortOrder.ASCENDING); + bulkWrapper.setColumnOrderHint(destTable.getColumnName(1), SQLServerSortOrder.ASCENDING); + + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTable, destTable); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(destTable.getEscapedTableName(), (Statement) stmt.product()); + } + } + } + + @Test + @DisplayName("BulkCopy:test unicode column name") + public void testUnicodeCOH() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable sourceTableUnicode = null; + DBTable destTableUnicode = null; + try { + // create source unicode table + sourceTableUnicode = new DBTable(true, true); + stmt.createTable(sourceTableUnicode); + + // create destination unicode table with same schema as source + destTableUnicode = sourceTableUnicode.cloneSchema(); + stmt.createTable(destTableUnicode); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + + bulkWrapper.setColumnOrderHint(destTableUnicode.getColumnName(1), SQLServerSortOrder.ASCENDING); + + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTableUnicode, destTableUnicode); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(sourceTableUnicode.getEscapedTableName(), (Statement) stmt.product()); + TestUtils.dropTableIfExists(destTableUnicode.getEscapedTableName(), (Statement) stmt.product()); + } + } + } + + @Test + @DisplayName("BulkCopy:test column name with escape character") + public void testCOHWithEscapeChar() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable sourceTableEscape = null; + DBTable destTableEscape = null; + try { + // create source unicode table + sourceTableEscape = new DBTable(true); + sourceTableEscape.addColumn(new SqlVarChar(), "COLUMN_NAME]"); + stmt.createTable(sourceTableEscape); + + // create destination unicode table with same schema as source + destTableEscape = sourceTableEscape.cloneSchema(); + stmt.createTable(destTableEscape); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + + bulkWrapper.setColumnOrderHint(destTableEscape.getColumnName(destTableEscape.totalColumns() - 1), SQLServerSortOrder.ASCENDING); + + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTableEscape, destTableEscape); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(sourceTableEscape.getEscapedTableName(), (Statement) stmt.product()); + TestUtils.dropTableIfExists(destTableEscape.getEscapedTableName(), (Statement) stmt.product()); + } + } + } + + @Test + @DisplayName("BulkCopy:test column order hints in descending order") + @Tag(Constants.xAzureSQLDW) + public void testCOHDescOrder() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable destTable = null; + try { + // create destination table + destTable = sourceTable.cloneSchema(); + stmt.createTable(destTable); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + + bulkWrapper.setColumnOrderHint(destTable.getColumnName(0), SQLServerSortOrder.DESCENDING); + + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTable, destTable); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(destTable.getEscapedTableName(), (Statement) stmt.product()); + } + } + } + + + + @Test + @DisplayName("BulkCopy:test colmun order hints with unspecified sort order") + public void testInvalidCOHWithUnspecifiedSortOrder() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable destTable = null; + try { + // create destination table + destTable = sourceTable.cloneSchema(); + stmt.createTable(destTable); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + + bulkWrapper.setColumnOrderHint(destTable.getColumnName(0), SQLServerSortOrder.UNSPECIFIED); + + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTable, destTable, true, true); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(destTable.getEscapedTableName(), (Statement) stmt.product()); + } + } + } + + @Test + @DisplayName("BulkCopy:test colmun order hints with invalid column name") + public void testInvalidCOHWithInvalidColumnName() throws SQLException { + try (DBConnection con = new DBConnection(connectionString); DBStatement stmt = con.createStatement()) { + DBTable destTable = null; + try { + // create destination table + destTable = sourceTable.cloneSchema(); + stmt.createTable(destTable); + + BulkCopyTestWrapper bulkWrapper = new BulkCopyTestWrapper(connectionString); + bulkWrapper.setUsingConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, ds); + bulkWrapper.setUsingXAConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsXA); + bulkWrapper.setUsingPooledConnection((0 == Constants.RANDOM.nextInt(2)) ? true : false, dsPool); + + bulkWrapper.setColumnOrderHint("INVALID_COLUMN_NAME", SQLServerSortOrder.ASCENDING); + + BulkCopyTestUtil.performBulkCopy(bulkWrapper, sourceTable, destTable, true, true); + } catch (Exception e) { + fail(e.getMessage()); + } finally { + TestUtils.dropTableIfExists(destTable.getEscapedTableName(), (Statement) stmt.product()); + } + } + } +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestUtil.java b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestUtil.java index 57c8bdf50..243dbc5b6 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestUtil.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestUtil.java @@ -87,6 +87,12 @@ static void performBulkCopy(BulkCopyTestWrapper wrapper, DBTable sourceTable, bo } } } + if(wrapper.isUsingColumnOrderHints()) { + for (int i = 0; i < wrapper.coh.size(); i++) { + BulkCopyTestWrapper.ColumnOrderHint columnOrderHint = wrapper.coh.get(i); + bulkCopy.addColumnOrderHint(columnOrderHint.columnName, columnOrderHint.sortOrder); + } + } bulkCopy.writeToServer((ResultSet) srcResultSet.product()); if (validateResult) { validateValues(con, sourceTable, destinationTable); @@ -138,6 +144,13 @@ static void performBulkCopy(BulkCopyTestWrapper wrapper, DBTable sourceTable, DB } } } + if(wrapper.isUsingColumnOrderHints()) { + for (int i = 0; i < wrapper.coh.size(); i++) { + BulkCopyTestWrapper.ColumnOrderHint columnOrderHint = wrapper.coh.get(i); + bulkCopy.addColumnOrderHint(columnOrderHint.columnName, columnOrderHint.sortOrder); + } + } + bulkCopy.writeToServer((ResultSet) srcResultSet.product()); if (validateResult) { validateValues(con, sourceTable, destinationTable); @@ -184,6 +197,12 @@ static void performBulkCopy(BulkCopyTestWrapper wrapper, DBTable sourceTable, DB } } } + if(wrapper.isUsingColumnOrderHints()) { + for (int i = 0; i < wrapper.coh.size(); i++) { + BulkCopyTestWrapper.ColumnOrderHint columnOrderHint = wrapper.coh.get(i); + bulkCopy.addColumnOrderHint(columnOrderHint.columnName, columnOrderHint.sortOrder); + } + } bulkCopy.writeToServer((ResultSet) srcResultSet.product()); if (fail) fail(TestResource.getResource("R_expectedExceptionNotThrown")); @@ -244,6 +263,12 @@ static void performBulkCopy(BulkCopyTestWrapper wrapper, DBTable sourceTable, DB } } } + if(wrapper.isUsingColumnOrderHints()) { + for (int i = 0; i < wrapper.coh.size(); i++) { + BulkCopyTestWrapper.ColumnOrderHint columnOrderHint = wrapper.coh.get(i); + bulkCopy.addColumnOrderHint(columnOrderHint.columnName, columnOrderHint.sortOrder); + } + } bulkCopy.writeToServer((ResultSet) srcResultSet.product()); if (fail) fail(TestResource.getResource("R_expectedExceptionNotThrown")); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestWrapper.java b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestWrapper.java index 62b51e5a7..5db217db3 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestWrapper.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestWrapper.java @@ -8,6 +8,7 @@ import com.microsoft.sqlserver.jdbc.ISQLServerDataSource; import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions; +import com.microsoft.sqlserver.jdbc.SQLServerSortOrder; /** @@ -44,8 +45,15 @@ class BulkCopyTestWrapper { */ private boolean isUsingColumnMapping = false; + /** + * true if SQLServerBulkCopy should use column order hints + */ + private boolean isUsingColumnOrderHints = false; + public LinkedList cm = new LinkedList<>(); + public LinkedList coh = new LinkedList<>(); + private SQLServerBulkCopyOptions bulkOptions; private String connectionString; @@ -167,10 +175,18 @@ public void setUsingColumnMapping() { this.isUsingColumnMapping = true; } + public void setUsingColumnOrderHints() { + this.isUsingColumnOrderHints = true; + } + public boolean isUsingColumnMapping() { return isUsingColumnMapping; } + public boolean isUsingColumnOrderHints() { + return isUsingColumnOrderHints; + } + public void setColumnMapping(int sourceColOrdinal, int destColOrdinal) { setUsingColumnMapping(); cm.add(new ColumnMap(sourceColOrdinal, destColOrdinal)); @@ -191,6 +207,11 @@ public void setColumnMapping(String sourceColName, int destColOrdinal) { cm.add(new ColumnMap(sourceColName, destColOrdinal)); } + public void setColumnOrderHint(String columnName, SQLServerSortOrder sortOrder) { + setUsingColumnOrderHints(); + coh.add(new ColumnOrderHint(columnName, sortOrder)); + } + class ColumnMap { boolean sourceIsInt = false; boolean destIsInt = false; @@ -232,4 +253,14 @@ class ColumnMap { this.destString = dest; } } + + class ColumnOrderHint { + String columnName; + + SQLServerSortOrder sortOrder; + ColumnOrderHint(String columnName, SQLServerSortOrder sortOrder) { + this.columnName = columnName; + this.sortOrder = sortOrder; + } + } } diff --git a/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java b/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java index 1cff7b37c..acf08434b 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java @@ -66,6 +66,10 @@ public static void setEscapeIdentifier(String openIdentifier, String closeIdenti * @return escaped literal */ public static String escapeIdentifier(String value) { + if(value != null && value.contains(CLOSE_ESCAPE_IDENTIFIER)) { + value = value.replace(CLOSE_ESCAPE_IDENTIFIER, CLOSE_ESCAPE_IDENTIFIER + CLOSE_ESCAPE_IDENTIFIER); + } + return OPEN_ESCAPE_IDENTIFIER + value + CLOSE_ESCAPE_IDENTIFIER; } diff --git a/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java b/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java index 42e25d303..fc8cc214c 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java @@ -435,8 +435,18 @@ String dropTableSql() { * @param sqlType */ public void addColumn(SqlType sqlType) { + this.addColumn(sqlType, RandomUtil.getIdentifier(sqlType.getName())); + } + + /** + * new column to add to DBTable based on the SqlType and column name + * + * @param sqlType + * @param columnName + */ + public void addColumn(SqlType sqlType, String columnName) { schema.addSqlTpe(sqlType); - DBColumn column = new DBColumn(RandomUtil.getIdentifier(sqlType.getName()), sqlType); + DBColumn column = new DBColumn(columnName, sqlType); columns.add(column); ++totalColumns; }