microsoft / mssql-jdbc

The Microsoft JDBC Driver for SQL Server is a Type 4 JDBC driver that provides database connectivity with SQL Server through the standard JDBC application program interfaces (APIs).
MIT License
1.04k stars 421 forks source link

Bulk Copy with SQL Variant type fails due to null sourceResultSet #2442

Open hchenatsafe opened 3 weeks ago

hchenatsafe commented 3 weeks ago

Driver version

12.4.1.jre8

SQL Server version

Microsoft SQL Server 2014 (SP3-GDR) (KB5029184) - 12.0.6179.1 (X64) Jul 27 2023 21:44:30 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.3 (Build 9600: ) (Hypervisor)

Client Operating System

Ubuntu 22.04

JAVA/JVM version

openjdk version "17.0.10" 2024-01-16 OpenJDK Runtime Environment (build 17.0.10+7-Ubuntu-122.04.1) OpenJDK 64-Bit Server VM (build 17.0.10+7-Ubuntu-122.04.1, mixed mode, sharing)

Table schema

Provide the table schema to repro the issue.

Problem description

Our application supports inserting using bulk copy, and we call writeToServer(ISQLServerBulkData sourceData) to do so. We are trying to add support for sql_variant type (-156), but we run into a NullPointerException when we pass a sourceData object containing that type.

It appears that writeSqlVariant() relies on a sourceResultSet that is set to null in writeToServer(ISQLServerBulkData sourceData)

Expected behavior

Bulk source data is written successfully.

Actual behavior

See the following trace

Error message/stack trace

java.lang.NullPointerException: Cannot invoke "com.microsoft.sqlserver.jdbc.SQLServerResultSet.getVariantInternalType(int)" because "sourceResultSet" is null at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeSqlVariant(SQLServerBulkCopy.java:2614) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeColumnToTdsWriter(SQLServerBulkCopy.java:2580) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeColumn(SQLServerBulkCopy.java:3094) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeBatchData(SQLServerBulkCopy.java:3652) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.doInsertBulk(SQLServerBulkCopy.java:1582) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.access$300(SQLServerBulkCopy.java:67) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy$1InsertBulk.doExecute(SQLServerBulkCopy.java:673) at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7675) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:4137) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.sendBulkLoadBCP(SQLServerBulkCopy.java:707) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:1670) at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:630)

lilgreenbird commented 3 weeks ago

hi @hchenatsafe

We do have tests for bulkcopy using the SQL Variant type, what are you doing different? Could you please provide us with a repro of the issue?

hchenatsafe commented 3 weeks ago

Hi @lilgreenbird, thanks for following up!

Your tests seem to be using writeToServer(ResultSet sourceData), which wouldn't run into this issue since sourceResultSet would be set here.

Our application passes a source data object that implements ISQLServerBulkData, so we are using writeToServer(ISQLServerBulkData sourceData) where sourceResultSet seems to be set to null, and we run into this error when writeSqlVariant() is called

lilgreenbird commented 3 weeks ago

@hchenatsafe

Could you please include your repro code here along with the schema and connection string used

hchenatsafe commented 3 weeks ago

It seems it would be a challenge to untangle our source to provide a clean repro. We'll leave this issue up to your consideration. Thanks for your assistance!

lilgreenbird commented 3 weeks ago

thanks @hchenatsafe I can see in the code path that this would be an issue. Looks like this had been an issue since day 1, I will add this as an enhancement and add a note in the doc that this isn't supported right now. Thanks for reporting the issue to us!