Skip to content

Commit

Permalink
Support FLOAT data type for bulk copy operation using RowSet (#986)
Browse files Browse the repository at this point in the history
Fix | Support FLOAT data type for bulk copy operation using RowSet (#986)
  • Loading branch information
peterbae authored Mar 15, 2019
1 parent 408b614 commit e52ea2c
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import java.util.logging.Level;

import javax.sql.RowSet;
import javax.sql.XAConnection;

import microsoft.sql.DateTimeOffset;

Expand Down Expand Up @@ -888,6 +887,7 @@ private void writeTypeInfo(TDSWriter tdsWriter, int srcJdbcType, int srcScale, i
}
break;

case java.sql.Types.FLOAT:
case java.sql.Types.DOUBLE: // (FLT8TYPE) 0x3E
if (!srcNullable) {
tdsWriter.writeByte(TDSType.FLOAT8.byteValue());
Expand Down Expand Up @@ -1244,6 +1244,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
case java.sql.Types.TINYINT:
return "tinyint";

case java.sql.Types.FLOAT:
case java.sql.Types.DOUBLE:
return "float";

Expand Down Expand Up @@ -1929,6 +1930,7 @@ private void writeNullToTdsWriter(TDSWriter tdsWriter, int srcJdbcType,
case java.sql.Types.BIGINT:
case java.sql.Types.REAL:
case java.sql.Types.DOUBLE:
case java.sql.Types.FLOAT:
case java.sql.Types.DECIMAL:
case java.sql.Types.NUMERIC:
case java.sql.Types.TIMESTAMP:
Expand Down Expand Up @@ -2051,6 +2053,17 @@ else if (null != sourceCryptoMeta) {
}
break;

case java.sql.Types.FLOAT:
if (null == colValue) {
writeNullToTdsWriter(tdsWriter, bulkJdbcType, isStreaming);
} else {
if (bulkNullable) {
tdsWriter.writeByte((byte) 0x08);
}
tdsWriter.writeDouble((float) colValue);
}
break;

case java.sql.Types.DOUBLE:
if (null == colValue) {
writeNullToTdsWriter(tdsWriter, bulkJdbcType, isStreaming);
Expand Down Expand Up @@ -2701,6 +2714,7 @@ private Object readColumnFromResultSet(int srcColOrdinal, int srcJdbcType, boole
case java.sql.Types.TINYINT:
case java.sql.Types.DOUBLE:
case java.sql.Types.REAL:
case java.sql.Types.FLOAT:
return sourceResultSet.getObject(srcColOrdinal);

case microsoft.sql.Types.MONEY:
Expand Down Expand Up @@ -3334,12 +3348,11 @@ private byte[] normalizedValue(JDBCType destJdbcType, Object value, JDBCType src
return ((String) value).getBytes(UTF_16LE);

case REAL:
case FLOAT:

Float floatValue = (value instanceof String) ? Float.parseFloat((String) value) : (Float) value;
return ByteBuffer.allocate((Float.SIZE / Byte.SIZE)).order(ByteOrder.LITTLE_ENDIAN)
.putFloat(floatValue).array();


case FLOAT:
case DOUBLE:
Double doubleValue = (value instanceof String) ? Double.parseDouble((String) value)
: (Double) value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.microsoft.sqlserver.jdbc.bulkCopy;

import static org.junit.Assert.assertEquals;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.RowSetMetaData;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetMetaDataImpl;
import javax.sql.rowset.RowSetProvider;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.opentest4j.TestAbortedException;

import com.microsoft.sqlserver.jdbc.RandomData;
import com.microsoft.sqlserver.jdbc.RandomUtil;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
import com.microsoft.sqlserver.jdbc.TestUtils;
import com.microsoft.sqlserver.testframework.AbstractSQLGenerator;
import com.microsoft.sqlserver.testframework.AbstractTest;

public class BulkCopyRowSetTest extends AbstractTest {

private static String tableName = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("BulkCopyFloatTest"));

@Test
public void testBulkCopyFloatRowSet() throws SQLException {
try (Connection con = DriverManager.getConnection(connectionString);
Statement stmt = connection.createStatement()) {
RowSetFactory rsf = RowSetProvider.newFactory();
CachedRowSet crs = rsf.createCachedRowSet();
RowSetMetaData rsmd = new RowSetMetaDataImpl();
rsmd.setColumnCount(2);
rsmd.setColumnName(1, "c1");
rsmd.setColumnName(2, "c2");
rsmd.setColumnType(1, java.sql.Types.FLOAT);
rsmd.setColumnType(2, java.sql.Types.FLOAT);

Float floatData = RandomData.generateReal(false);

crs.setMetaData(rsmd);
crs.moveToInsertRow();
crs.updateFloat(1, floatData);
crs.updateFloat(2, floatData);
crs.insertRow();
crs.moveToCurrentRow();

try (SQLServerBulkCopy bcOperation = new SQLServerBulkCopy(con)) {
bcOperation.setDestinationTableName(tableName);
bcOperation.writeToServer(crs);
}

ResultSet rs = stmt.executeQuery("select * from " + tableName);
rs.next();
assertEquals(floatData, (Float) rs.getFloat(1));
assertEquals(floatData, (Float) rs.getFloat(2));
}
}

@BeforeAll
public static void testSetup() throws TestAbortedException, Exception {
try (Connection connection = DriverManager.getConnection(connectionString);
Statement stmt = connection.createStatement()) {
String sql1 = "create table " + tableName + " (c1 float, c2 real)";
stmt.execute(sql1);
}
}

@AfterAll
public static void terminateVariation() throws SQLException {
try (Connection connection = DriverManager.getConnection(connectionString);
Statement stmt = connection.createStatement()) {
TestUtils.dropTableIfExists(tableName, stmt);
}
}
}

0 comments on commit e52ea2c

Please sign in to comment.