Skip to content

Commit

Permalink
Add order Hints for Bulk Copy operations (microsoft#1481)
Browse files Browse the repository at this point in the history
  • Loading branch information
mobilebilly committed Jul 7, 2024
1 parent e9b1fec commit 442c816
Showing 1 changed file with 97 additions and 2 deletions.
99 changes: 97 additions & 2 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
*/
Expand All @@ -138,6 +155,11 @@ private class ColumnMapping implements Serializable {
*/
private List<ColumnMapping> columnMappings;

/**
* Column order hints describe the sort order of columns in the clustered index of the destination
*/
private List<ColumnOrderHint> columnOrderHints;

/**
* Flag if SQLServerBulkCopy owns the connection and should close it when Close is called
*/
Expand Down Expand Up @@ -459,6 +481,43 @@ public void clearColumnMappings() {
loggerExternal.exiting(loggerClassName, "clearColumnMappings");
}

/**
* Adds a new column mapping, using column names to specify both source and destination columns.
*
* @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
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1482,6 +1542,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
private String createInsertBulkCommand(TDSWriter tdsWriter) throws SQLServerException {
StringBuilder bulkCmd = new StringBuilder();
List<String> bulkOptions = new ArrayList<>();
Set<String> destColumns = new HashSet<>();
String endColumn = " , ";
bulkCmd.append("INSERT BULK ").append(destinationTableName).append(" (");

Expand All @@ -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,
Expand Down Expand Up @@ -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(escapedColumnName).append(" ").append(sortOrderText).append(", ");
} else {
orderHintText.append(columnName).append(" ").append(sortOrderText).append(", ");
}
}

orderHintText.setLength(orderHintText.length() - 2);
orderHintText.append(")");

bulkOptions.add(orderHintText.toString());
}

Iterator<String> it = bulkOptions.iterator();
if (it.hasNext()) {
bulkCmd.append(" with (");
Expand Down

0 comments on commit 442c816

Please sign in to comment.