Skip to content

Commit d03f09f

Browse files
committed
Merge branch 'main' into dev/machavan/useragentfields
2 parents 154d2ca + ad31dfb commit d03f09f

File tree

4 files changed

+74
-4
lines changed

4 files changed

+74
-4
lines changed

build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ dependencies {
209209
'org.mockito:mockito-inline:4.11.0',
210210
'net.bytebuddy:byte-buddy:1.15.11',
211211
'net.bytebuddy:byte-buddy-agent:1.15.11'
212+
} else if (hasProperty('buildProfile') && buildProfile == "jre25") {
213+
// JRE 25 profile
214+
testImplementation 'org.mockito:mockito-core:5.20.0',
215+
'org.mockito:mockito-inline:5.20.0',
216+
'net.bytebuddy:byte-buddy:1.18.2',
217+
'net.bytebuddy:byte-buddy-agent:1.18.2'
212218
} else {
213219
// JRE 11, 17, 21, 25 profiles (all use same versions)
214220
testImplementation 'org.mockito:mockito-core:5.14.2',

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,19 +497,19 @@
497497
<dependency>
498498
<groupId>org.mockito</groupId>
499499
<artifactId>mockito-core</artifactId>
500-
<version>5.14.2</version>
500+
<version>5.20.0</version>
501501
<scope>test</scope>
502502
</dependency>
503503
<dependency>
504504
<groupId>net.bytebuddy</groupId>
505505
<artifactId>byte-buddy</artifactId>
506-
<version>1.17.5</version>
506+
<version>1.18.2</version>
507507
<scope>test</scope>
508508
</dependency>
509509
<dependency>
510510
<groupId>net.bytebuddy</groupId>
511511
<artifactId>byte-buddy-agent</artifactId>
512-
<version>1.17.5</version>
512+
<version>1.18.2</version>
513513
<scope>test</scope>
514514
</dependency>
515515
</dependencies>

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2092,7 +2092,7 @@ private void validateColumnMappings() throws SQLServerException {
20922092
throw new SQLServerException(form.format(msgArgs), SQLState.COL_NOT_FOUND,
20932093
DriverError.NOT_SET, null);
20942094
}
2095-
} else if (0 > cm.destinationColumnOrdinal || destColumnCount < cm.destinationColumnOrdinal) {
2095+
} else if (0 > cm.destinationColumnOrdinal || !destColumnMetadata.containsKey(cm.destinationColumnOrdinal)) {
20962096
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidColumn"));
20972097
Object[] msgArgs = {cm.destinationColumnOrdinal};
20982098
throw new SQLServerException(form.format(msgArgs), SQLState.COL_NOT_FOUND, DriverError.NOT_SET,

src/test/java/com/microsoft/sqlserver/jdbc/preparedStatement/BatchExecutionWithBulkCopyTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,70 @@ public void testInsertWithBulkCopyPerformance() throws SQLException {
14011401
System.out.println("Insert for " + recordCount + " records in " + durationMs + " ms.");
14021402
}
14031403

1404+
/**
1405+
* GitHub issue 2847: Persisted computed columns break useBulkCopyForBatchInsert.
1406+
*
1407+
* Verifies that batch inserts using bulk copy work correctly when the target table
1408+
* contains a persisted computed column. The computed column is not included in the
1409+
* INSERT statement, and the bulk copy operation correctly ignores it while
1410+
* inserting the remaining data.
1411+
*
1412+
* @throws Exception
1413+
*/
1414+
@Test
1415+
public void testBulkCopyBatchInsertWithPersistedComputedColumn() throws Exception {
1416+
1417+
String tableName = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("BulkCopyPersistedComputed"));
1418+
String insertSQL = "INSERT INTO " + tableName + " (QtyAvailable, UnitPrice) VALUES (?, ?)";
1419+
1420+
try (Connection connection = PrepUtil.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;");
1421+
SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection.prepareStatement(insertSQL);
1422+
Statement stmt = connection.createStatement()) {
1423+
1424+
TestUtils.dropTableIfExists(tableName, stmt);
1425+
1426+
// Create table with persisted computed column
1427+
String createTable = "CREATE TABLE " + tableName + " ("
1428+
+ "ProductID int IDENTITY(1,1) NOT NULL, "
1429+
+ "QtyAvailable SMALLINT, "
1430+
+ "InventoryValue AS QtyAvailable * UnitPrice PERSISTED, "
1431+
+ "UnitPrice MONEY)";
1432+
stmt.execute(createTable);
1433+
1434+
// Test batch insert
1435+
pstmt.setInt(1, 10);
1436+
pstmt.setBigDecimal(2, new BigDecimal("15.99"));
1437+
pstmt.addBatch();
1438+
1439+
pstmt.setInt(1, 20);
1440+
pstmt.setBigDecimal(2, new BigDecimal("25.50"));
1441+
pstmt.addBatch();
1442+
1443+
int[] updateCounts = pstmt.executeBatch();
1444+
assertEquals(2, updateCounts.length);
1445+
1446+
// Validate inserted rows, including computed values
1447+
try (ResultSet rs = stmt.executeQuery("SELECT ProductID, QtyAvailable, InventoryValue, UnitPrice FROM "
1448+
+ tableName + " ORDER BY ProductID")) {
1449+
assertTrue(rs.next());
1450+
assertEquals(1, rs.getInt(1));
1451+
assertEquals(10, rs.getInt(2));
1452+
assertEquals(new BigDecimal("159.9000"), rs.getBigDecimal(3));
1453+
assertEquals(new BigDecimal("15.9900"), rs.getBigDecimal(4));
1454+
1455+
assertTrue(rs.next());
1456+
assertEquals(2, rs.getInt(1));
1457+
assertEquals(20, rs.getInt(2));
1458+
assertEquals(new BigDecimal("510.0000"), rs.getBigDecimal(3));
1459+
assertEquals(new BigDecimal("25.5000"), rs.getBigDecimal(4));
1460+
}
1461+
} finally {
1462+
try (Connection connection = getConnection(); Statement stmt = connection.createStatement()) {
1463+
TestUtils.dropTableIfExists(tableName, stmt);
1464+
}
1465+
}
1466+
}
1467+
14041468
private void getCreateTableTemporalSQL(String tableName) throws SQLException {
14051469
try (Statement stmt = connection.createStatement()) {
14061470
TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt);

0 commit comments

Comments
 (0)