Skip to content

Commit

Permalink
Fixed Store procedure output param TDS metadata and fixed bulk copy t…
Browse files Browse the repository at this point in the history
…ype conversion
  • Loading branch information
Divang Sharma committed Jan 29, 2025
1 parent 508a1b9 commit fd21d1a
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 8 deletions.
7 changes: 4 additions & 3 deletions src/main/java/com/microsoft/sqlserver/jdbc/DataTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ enum SSType {
TIMESTAMP(Category.TIMESTAMP, "timestamp", JDBCType.BINARY),
GEOMETRY(Category.UDT, "geometry", JDBCType.GEOMETRY),
GEOGRAPHY(Category.UDT, "geography", JDBCType.GEOGRAPHY),
JSON(Category.JSON, "json", JDBCType.LONGNVARCHAR);
JSON(Category.JSON, "json", JDBCType.JSON);

final Category category;
private final String name;
Expand Down Expand Up @@ -458,10 +458,11 @@ JDBCType getJDBCType(SSType ssType, JDBCType jdbcTypeFromApp) {
case NVARCHAR:
case NVARCHARMAX:
case NTEXT:
case JSON:
jdbcType = JDBCType.LONGVARCHAR;
break;

case JSON:
jdbcType = JDBCType.JSON;
break;
case XML:
default:
jdbcType = JDBCType.LONGVARBINARY;
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4864,6 +4864,12 @@ void writeRPCStringUnicode(String sValue) throws SQLServerException {
writeRPCStringUnicode(null, sValue, false, null);
}

void writeRPCJson(String sName, String sValue, boolean bOut,
SQLCollation collation) throws SQLServerException {
writeRPCNameValType(sName, bOut, TDSType.JSON);
writeLong(0xFFFFFFFFFFFFFFFFL);
}

/**
* Writes a string value as Unicode for RPC
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,10 @@ else if ((null != columnNames) && (columnNames.length >= positionInSource))
columnMetadata.put(positionInSource,
new ColumnMetadata(colName, java.sql.Types.LONGNVARCHAR, precision, scale, dateTimeFormatter));
break;
case microsoft.sql.Types.JSON:
columnMetadata.put(positionInSource,
new ColumnMetadata(colName, microsoft.sql.Types.JSON, precision, scale, dateTimeFormatter));
break;
/*
* Redirecting Float as Double based on data type mapping
* https://msdn.microsoft.com/library/ms378878%28v=sql.110%29.aspx
Expand Down
23 changes: 19 additions & 4 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,14 @@ private void writeTypeInfo(TDSWriter tdsWriter, int srcJdbcType, int srcScale, i
}
collation.writeCollation(tdsWriter);
break;

case microsoft.sql.Types.JSON: // 0x62
tdsWriter.writeByte(TDSType.JSON.byteValue());
if (isStreaming) {
tdsWriter.writeShort((short) 0xFFFF);
} else {
tdsWriter.writeShort(isBaseType ? (short) (srcPrecision) : (short) (2 * srcPrecision));
}
break;
case java.sql.Types.BINARY: // 0xAD
tdsWriter.writeByte(TDSType.BIGBINARY.byteValue());
tdsWriter.writeShort((short) (srcPrecision));
Expand Down Expand Up @@ -1127,7 +1134,7 @@ private void writeTypeInfo(TDSWriter tdsWriter, int srcJdbcType, int srcScale, i
case microsoft.sql.Types.SQL_VARIANT: // 0x62
tdsWriter.writeByte(TDSType.SQL_VARIANT.byteValue());
tdsWriter.writeInt(TDS.SQL_VARIANT_LENGTH);
break;
break;
default:
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_BulkTypeNotSupported"));
String unsupportedDataType = JDBCType.of(srcJdbcType).toString().toLowerCase(Locale.ENGLISH);
Expand Down Expand Up @@ -1470,6 +1477,8 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
}
case microsoft.sql.Types.SQL_VARIANT:
return SSType.SQL_VARIANT.toString();
case microsoft.sql.Types.JSON:
return SSType.JSON.toString();
default: {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_BulkTypeNotSupported"));
Object[] msgArgs = {JDBCType.of(bulkJdbcType).toString().toLowerCase(Locale.ENGLISH)};
Expand Down Expand Up @@ -2090,6 +2099,7 @@ private void writeNullToTdsWriter(TDSWriter tdsWriter, int srcJdbcType,
case java.sql.Types.LONGVARCHAR:
case java.sql.Types.LONGNVARCHAR:
case java.sql.Types.LONGVARBINARY:
case microsoft.sql.Types.JSON:
if (isStreaming) {
tdsWriter.writeLong(PLPInputStream.PLP_NULL);
} else {
Expand Down Expand Up @@ -2161,6 +2171,7 @@ else if (null != sourceCryptoMeta) {
case java.sql.Types.TIME:
case java.sql.Types.TIMESTAMP:
case microsoft.sql.Types.DATETIMEOFFSET:
case microsoft.sql.Types.JSON:
bulkJdbcType = java.sql.Types.VARCHAR;
break;
default:
Expand Down Expand Up @@ -2419,6 +2430,7 @@ else if (null != sourceCryptoMeta) {
case java.sql.Types.LONGNVARCHAR:
case java.sql.Types.NCHAR:
case java.sql.Types.NVARCHAR:
case microsoft.sql.Types.JSON:
if (isStreaming) {
// PLP_BODY rule in TDS
// Use ResultSet.getString for non-streaming data and ResultSet.getNCharacterStream() for
Expand Down Expand Up @@ -2986,6 +2998,7 @@ private Object readColumnFromResultSet(int srcColOrdinal, int srcJdbcType, boole
case java.sql.Types.LONGNVARCHAR:
case java.sql.Types.NCHAR:
case java.sql.Types.NVARCHAR:
case microsoft.sql.Types.JSON:
// PLP if stream type and both the source and destination are not encrypted
// This is because AE does not support streaming types.
// Therefore an encrypted source or destination means the data must not actually be streaming data
Expand Down Expand Up @@ -3060,7 +3073,8 @@ private void writeColumn(TDSWriter tdsWriter, int srcColOrdinal, int destColOrdi
destPrecision = destColumnMetadata.get(destColOrdinal).precision;

if ((java.sql.Types.NCHAR == srcJdbcType) || (java.sql.Types.NVARCHAR == srcJdbcType)
|| (java.sql.Types.LONGNVARCHAR == srcJdbcType)) {
|| (java.sql.Types.LONGNVARCHAR == srcJdbcType)
|| (microsoft.sql.Types.JSON == srcJdbcType)) {
isStreaming = (DataTypes.SHORT_VARTYPE_MAX_CHARS < srcPrecision)
|| (DataTypes.SHORT_VARTYPE_MAX_CHARS < destPrecision);
} else {
Expand Down Expand Up @@ -3771,6 +3785,7 @@ void setDestinationTableMetadata(SQLServerResultSet rs) {
private boolean unicodeConversionRequired(int jdbcType, SSType ssType) {
return ((java.sql.Types.CHAR == jdbcType || java.sql.Types.VARCHAR == jdbcType
|| java.sql.Types.LONGNVARCHAR == jdbcType)
&& (SSType.NCHAR == ssType || SSType.NVARCHAR == ssType || SSType.NVARCHARMAX == ssType));
&& (SSType.NCHAR == ssType || SSType.NVARCHAR == ssType || SSType.NVARCHARMAX == ssType
|| SSType.JSON == ssType));
}
}
5 changes: 4 additions & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/dtv.java
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,10 @@ final class SendByRPCOp extends DTVExecuteOp {
void execute(DTV dtv, String strValue) throws SQLServerException {
if (dtv.getJdbcType() == JDBCType.GUID) {
tdsWriter.writeRPCUUID(name, UUID.fromString(strValue), isOutParam);
} else {
} else if (dtv.getJdbcType() == JDBCType.JSON) {
tdsWriter.writeRPCJson(name, strValue, isOutParam, collation);
}
else {
tdsWriter.writeRPCStringUnicode(name, strValue, isOutParam, collation);
}
}
Expand Down

0 comments on commit fd21d1a

Please sign in to comment.