diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 9c7cf50ee5..dc5fc9dd51 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -958,7 +958,7 @@ - + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs index 015fb6c1fe..d811c3f021 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -6471,7 +6471,7 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete paramList.Append(size); paramList.Append(')'); } - else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt)) + else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt) && (mt.SqlDbType != SqlDbTypeExtensions.Json)) { paramList.Append("(max) "); } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index c3291e4e5d..f8865b5540 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -5178,7 +5178,7 @@ private TdsOperationStatus TryProcessTypeInfo(TdsParserStateObject stateObj, Sql } // read the collation for 7.x servers - if (col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE)) + if (col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE) && ((tdsType != TdsEnums.SQLJSON))) { result = TryProcessCollation(stateObj, out col.collation); if (result != TdsOperationStatus.Done) @@ -5958,6 +5958,7 @@ private TdsOperationStatus TryReadSqlStringValue(SqlBuffer value, byte type, int case TdsEnums.SQLVARCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: + case TdsEnums.SQLJSON: // If bigvarchar(max), we only read the first chunk here, // expecting the caller to read the rest if (encoding == null) @@ -6427,6 +6428,7 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: + case TdsEnums.SQLJSON: result = TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj); if (result != TdsOperationStatus.Done) { @@ -7964,6 +7966,7 @@ internal TdsOperationStatus TryGetDataLength(SqlMetaDataPriv colmeta, TdsParserS colmeta.tdsType == TdsEnums.SQLBIGVARCHAR || colmeta.tdsType == TdsEnums.SQLBIGVARBINARY || colmeta.tdsType == TdsEnums.SQLNVARCHAR || + colmeta.tdsType == TdsEnums.SQLJSON || // Large UDTs is WinFS-only colmeta.tdsType == TdsEnums.SQLUDT, "GetDataLength:Invalid streaming datatype"); @@ -9819,7 +9822,7 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet } else if (mt.IsPlp) { - if (mt.SqlDbType != SqlDbType.Xml) + if (mt.SqlDbType != SqlDbType.Xml && mt.SqlDbType != SqlDbTypeExtensions.Json) WriteShort(TdsEnums.SQL_USHORTVARMAXLEN, stateObj); } else if ((!mt.IsVarTime) && (mt.SqlDbType != SqlDbType.Date)) @@ -9859,53 +9862,56 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet // write out collation or xml metadata - if (_is2005 && (mt.SqlDbType == SqlDbType.Xml)) + if ((mt.SqlDbType == SqlDbType.Xml || mt.SqlDbType == SqlDbTypeExtensions.Json)) { - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) || - !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) || - !string.IsNullOrEmpty(param.XmlSchemaCollectionName)) + if (mt.SqlDbType == SqlDbType.Xml) { - stateObj.WriteByte(1); //Schema present flag - - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase)) + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) || + !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) || + !string.IsNullOrEmpty(param.XmlSchemaCollectionName)) { - tempLen = (param.XmlSchemaCollectionDatabase).Length; - stateObj.WriteByte((byte)(tempLen)); - WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj); - } - else - { - stateObj.WriteByte(0); // No dbname - } + stateObj.WriteByte(1); //Schema present flag - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema)) - { - tempLen = (param.XmlSchemaCollectionOwningSchema).Length; - stateObj.WriteByte((byte)(tempLen)); - WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj); - } - else - { - stateObj.WriteByte(0); // no xml schema name - } + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase)) + { + tempLen = (param.XmlSchemaCollectionDatabase).Length; + stateObj.WriteByte((byte)(tempLen)); + WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj); + } + else + { + stateObj.WriteByte(0); // No dbname + } + + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema)) + { + tempLen = (param.XmlSchemaCollectionOwningSchema).Length; + stateObj.WriteByte((byte)(tempLen)); + WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj); + } + else + { + stateObj.WriteByte(0); // no xml schema name + } + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName)) + { + tempLen = (param.XmlSchemaCollectionName).Length; + WriteShort((short)(tempLen), stateObj); + WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj); + } + else + { + WriteShort(0, stateObj); // No xml schema collection name + } - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName)) - { - tempLen = (param.XmlSchemaCollectionName).Length; - WriteShort((short)(tempLen), stateObj); - WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj); } else { - WriteShort(0, stateObj); // No xml schema collection name + stateObj.WriteByte(0); // No schema } } - else - { - stateObj.WriteByte(0); // No schema - } } - else if (mt.IsCharType) + else if (mt.IsCharType && mt.SqlDbType != SqlDbTypeExtensions.Json) { // if it is not supplied, simply write out our default collation, otherwise, write out the one attached to the parameter SqlCollation outCollation = (param.Collation != null) ? param.Collation : _defaultCollation; @@ -11485,10 +11491,18 @@ private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLe case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: + case TdsEnums.SQLJSON: if (type.IsPlp) { - if (IsBOMNeeded(type, value)) + if (type.NullableType == TdsEnums.SQLJSON) + { + // TODO : Performance and BOM check. Saurabh + byte[] jsonAsBytes = Encoding.UTF8.GetBytes(value.ToString()); + WriteInt(jsonAsBytes.Length, stateObj); + return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false); + } + else if (IsBOMNeeded(type, value)) { WriteInt(actualLength + 2, stateObj); // chunk length WriteShort(TdsEnums.XMLUNICODEBOM, stateObj); @@ -12135,6 +12149,7 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: + case TdsEnums.SQLJSON: { Debug.Assert(!isDataFeed || (value is TextDataFeed || value is XmlDataFeed), "Value must be a TextReader or XmlReader"); Debug.Assert(isDataFeed || (value is string || value is byte[]), "Value is a byte array or string"); @@ -12156,7 +12171,14 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int { if (type.IsPlp) { - if (IsBOMNeeded(type, value)) + if (type.NullableType == TdsEnums.SQLJSON) + { + // TODO : Performance and BOM check. Saurabh + byte[] jsonAsBytes = Encoding.UTF8.GetBytes((string)value); + WriteInt(jsonAsBytes.Length, stateObj); + return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false); + } + else if (IsBOMNeeded(type, value)) { WriteInt(actualLength + 2, stateObj); // chunk length WriteShort(TdsEnums.XMLUNICODEBOM, stateObj); @@ -12662,7 +12684,7 @@ internal void WriteParameterVarLen(MetaType type, int size, bool isNull, TdsPars WriteInt(unchecked((int)TdsEnums.VARLONGNULL), stateObj); } } - else if (type.NullableType == TdsEnums.SQLXMLTYPE || unknownLength) + else if (type.NullableType is TdsEnums.SQLXMLTYPE or TdsEnums.SQLJSON || unknownLength) { WriteUnsignedLong(TdsEnums.SQL_PLP_UNKNOWNLEN, stateObj); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 840f5b6520..9e4fffdfa1 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -756,7 +756,7 @@ - + $(SystemTextEncodingsWebVersion) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs index 00b17a0213..fcb8aaf58c 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -7180,7 +7180,7 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete paramList.Append(size); paramList.Append(')'); } - else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt)) + else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt) && (mt.SqlDbType != SqlDbTypeExtensions.Json)) { paramList.Append("(max) "); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 459b230be6..cc91798a0c 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -5876,7 +5876,7 @@ private TdsOperationStatus TryProcessTypeInfo(TdsParserStateObject stateObj, Sql } // read the collation for 7.x servers - if (_is2000 && col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE)) + if (_is2000 && col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE) && (tdsType != TdsEnums.SQLJSON)) { result = TryProcessCollation(stateObj, out col.collation); if (result != TdsOperationStatus.Done) @@ -6805,6 +6805,7 @@ private TdsOperationStatus TryReadSqlStringValue(SqlBuffer value, byte type, int case TdsEnums.SQLVARCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: + case TdsEnums.SQLJSON: // If bigvarchar(max), we only read the first chunk here, // expecting the caller to read the rest if (encoding == null) @@ -7255,6 +7256,7 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value, case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: + case TdsEnums.SQLJSON: result = TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj); if (result != TdsOperationStatus.Done) { @@ -8777,6 +8779,7 @@ internal TdsOperationStatus TryGetDataLength(SqlMetaDataPriv colmeta, TdsParserS colmeta.tdsType == TdsEnums.SQLBIGVARCHAR || colmeta.tdsType == TdsEnums.SQLBIGVARBINARY || colmeta.tdsType == TdsEnums.SQLNVARCHAR || + colmeta.tdsType == TdsEnums.SQLJSON || // Large UDTs is WinFS-only colmeta.tdsType == TdsEnums.SQLUDT, "GetDataLength:Invalid streaming datatype"); @@ -10570,7 +10573,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout } else if (mt.IsPlp) { - if (mt.SqlDbType != SqlDbType.Xml) + if (mt.SqlDbType != SqlDbType.Xml && mt.SqlDbType != SqlDbTypeExtensions.Json) WriteShort(TdsEnums.SQL_USHORTVARMAXLEN, stateObj); } else if ((!mt.IsVarTime) && (mt.SqlDbType != SqlDbType.Date)) @@ -10611,53 +10614,56 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout // write out collation or xml metadata - if (_is2005 && (mt.SqlDbType == SqlDbType.Xml)) + if ((mt.SqlDbType == SqlDbType.Xml || mt.SqlDbType == SqlDbTypeExtensions.Json)) { - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) || - !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) || - !string.IsNullOrEmpty(param.XmlSchemaCollectionName)) + if (mt.SqlDbType == SqlDbType.Xml) { - stateObj.WriteByte(1); //Schema present flag - - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase)) + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) || + !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) || + !string.IsNullOrEmpty(param.XmlSchemaCollectionName)) { - tempLen = (param.XmlSchemaCollectionDatabase).Length; - stateObj.WriteByte((byte)(tempLen)); - WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj); - } - else - { - stateObj.WriteByte(0); // No dbname - } + stateObj.WriteByte(1); //Schema present flag + + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase)) + { + tempLen = (param.XmlSchemaCollectionDatabase).Length; + stateObj.WriteByte((byte)(tempLen)); + WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj); + } + else + { + stateObj.WriteByte(0); // No dbname + } + + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema)) + { + tempLen = (param.XmlSchemaCollectionOwningSchema).Length; + stateObj.WriteByte((byte)(tempLen)); + WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj); + } + else + { + stateObj.WriteByte(0); // no xml schema name + } + if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName)) + { + tempLen = (param.XmlSchemaCollectionName).Length; + WriteShort((short)(tempLen), stateObj); + WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj); + } + else + { + WriteShort(0, stateObj); // No xml schema collection name + } - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema)) - { - tempLen = (param.XmlSchemaCollectionOwningSchema).Length; - stateObj.WriteByte((byte)(tempLen)); - WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj); - } - else - { - stateObj.WriteByte(0); // no xml schema name - } - if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName)) - { - tempLen = (param.XmlSchemaCollectionName).Length; - WriteShort((short)(tempLen), stateObj); - WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj); } else { - WriteShort(0, stateObj); // No xml schema collection name + stateObj.WriteByte(0); // No schema } - - } - else - { - stateObj.WriteByte(0); // No schema } } - else if (_is2000 && mt.IsCharType) + else if (mt.IsCharType && mt.SqlDbType != SqlDbTypeExtensions.Json) { // if it is not supplied, simply write out our default collation, otherwise, write out the one attached to the parameter SqlCollation outCollation = (param.Collation != null) ? param.Collation : _defaultCollation; @@ -12432,10 +12438,18 @@ private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLe case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: + case TdsEnums.SQLJSON: if (type.IsPlp) { - if (IsBOMNeeded(type, value)) + if (type.NullableType == TdsEnums.SQLJSON) + { + // TODO : Performance and BOM check. Saurabh + byte[] jsonAsBytes = Encoding.UTF8.GetBytes(value.ToString()); + WriteInt(jsonAsBytes.Length, stateObj); + return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false); + } + else if (IsBOMNeeded(type, value)) { WriteInt(actualLength + 2, stateObj); // chunk length WriteShort(TdsEnums.XMLUNICODEBOM, stateObj); @@ -13124,6 +13138,7 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: + case TdsEnums.SQLJSON: { Debug.Assert(!isDataFeed || (value is TextDataFeed || value is XmlDataFeed), "Value must be a TextReader or XmlReader"); Debug.Assert(isDataFeed || (value is string || value is byte[]), "Value is a byte array or string"); @@ -13145,7 +13160,14 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int { if (type.IsPlp) { - if (IsBOMNeeded(type, value)) + if (type.NullableType == TdsEnums.SQLJSON) + { + // TODO : Performance and BOM check. Saurabh + byte[] jsonAsBytes = Encoding.UTF8.GetBytes((string)value); + WriteInt(jsonAsBytes.Length, stateObj); + return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false); + } + else if (IsBOMNeeded(type, value)) { WriteInt(actualLength + 2, stateObj); // chunk length WriteShort(TdsEnums.XMLUNICODEBOM, stateObj); @@ -13652,7 +13674,7 @@ internal void WriteParameterVarLen(MetaType type, int size, bool isNull, TdsPars WriteInt(unchecked((int)TdsEnums.VARLONGNULL), stateObj); } } - else if (type.NullableType == TdsEnums.SQLXMLTYPE || unknownLength) + else if (type.NullableType is TdsEnums.SQLXMLTYPE or TdsEnums.SQLJSON || unknownLength) { WriteUnsignedLong(TdsEnums.SQL_PLP_UNKNOWNLEN, stateObj); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs index 3fbd9b112a..fe7bfc7f9a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs @@ -226,6 +226,8 @@ internal static MetaType GetMetaTypeFromSqlDbType(SqlDbType target, bool isMulti return MetaXml; case SqlDbType.Udt: return MetaUdt; + case SqlDbTypeExtensions.Json: + return s_MetaJson; case SqlDbType.Structured: if (isMultiValued) { @@ -862,6 +864,8 @@ internal static MetaType GetSqlDataType(int tdsType, uint userType, int length) return s_metaDateTime2; case TdsEnums.SQLDATETIMEOFFSET: return MetaDateTimeOffset; + case TdsEnums.SQLJSON: + return s_MetaJson; case TdsEnums.SQLVOID: default: @@ -968,6 +972,8 @@ internal static string GetStringFromXml(XmlReader xmlreader) internal static readonly MetaType MetaDateTimeOffset = new(255, 7, -1, false, false, false, TdsEnums.SQLDATETIMEOFFSET, TdsEnums.SQLDATETIMEOFFSET, MetaTypeName.DATETIMEOFFSET, typeof(System.DateTimeOffset), typeof(System.DateTimeOffset), SqlDbType.DateTimeOffset, DbType.DateTimeOffset, 1); + internal static readonly MetaType s_MetaJson = new(255, 255, -1, false, true, true, TdsEnums.SQLJSON, TdsEnums.SQLJSON, MetaTypeName.JSON, typeof(string), typeof(string), SqlDbTypeExtensions.Json, DbType.String, 0); + public static TdsDateTime FromDateTime(DateTime dateTime, byte cb) { SqlDateTime sqlDateTime; @@ -1054,6 +1060,7 @@ private static class MetaTypeName public const string TIME = "time"; public const string DATETIME2 = "datetime2"; public const string DATETIMEOFFSET = "datetimeoffset"; + public const string JSON = "json"; } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs index a7c7fa58e1..65cd5d1e9b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs @@ -1563,6 +1563,7 @@ internal int GetActualSize() case SqlDbType.NVarChar: case SqlDbType.NText: case SqlDbType.Xml: + case SqlDbTypeExtensions.Json: { coercedSize = ((!HasFlag(SqlParameterFlags.IsNull)) && (!HasFlag(SqlParameterFlags.CoercedValueIsDataFeed))) ? StringSize(val, HasFlag(SqlParameterFlags.CoercedValueIsSqlType)) : 0; _actualSize = (ShouldSerializeSize() ? Size : 0); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs index f8b320be1a..058bf51dc5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -490,6 +490,8 @@ public enum ActiveDirectoryWorkflow : byte public const int SQLDATETIME2 = 0x2a; public const int SQLDATETIMEOFFSET = 0x2b; + public const int SQLJSON = 0xF4; + public const int DEFAULT_VARTIME_SCALE = 7; //Partially length prefixed datatypes constants. These apply to XMLTYPE, BIGVARCHRTYPE,