Skip to content

Commit 3d652d4

Browse files
Ignore processing collation for JSON output params and enhance test coverage (#3168)
This commit fixes #3167 where reading output parameter of type JSON resulted in an error. Additionally, test coverage has been enhanced to include tests for insertions and reads with SqlJson and output parameters of type JSON.
1 parent 0be2756 commit 3d652d4

File tree

5 files changed

+81
-4
lines changed

5 files changed

+81
-4
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4342,7 +4342,7 @@ internal TdsOperationStatus TryProcessReturnValue(int length, TdsParserStateObje
43424342
}
43434343
}
43444344
}
4345-
else if (rec.metaType.IsCharType)
4345+
else if (rec.metaType.IsCharType && rec.metaType.SqlDbType != SqlDbTypeExtensions.Json)
43464346
{
43474347
// read the collation for 8.x servers
43484348
result = TryProcessCollation(stateObj, out rec.collation);

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4571,7 +4571,7 @@ internal TdsOperationStatus TryProcessReturnValue(int length,
45714571
}
45724572
}
45734573
}
4574-
else if (_is2000 && rec.metaType.IsCharType)
4574+
else if (_is2000 && rec.metaType.IsCharType && rec.metaType.SqlDbType != SqlDbTypeExtensions.Json)
45754575
{
45764576
// read the collation for 8.x servers
45774577
result = TryProcessCollation(stateObj, out rec.collation);

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1993,7 +1993,7 @@ internal void Validate(int index, bool isCommandProc)
19931993
(SqlDbType != SqlDbType.Udt) &&
19941994
// BUG: (VSTFDevDiv - 479609): Output parameter with size 0 throws for XML, TEXT, NTEXT, IMAGE.
19951995
// NOTE: (VSTFDevDiv - 479609): Not Fixed for TEXT, NTEXT, IMAGE as these are deprecated LOB types.
1996-
(SqlDbType != SqlDbType.Xml) &&
1996+
(SqlDbType != SqlDbType.Xml && SqlDbType != SqlDbTypeExtensions.Json) &&
19971997
!metaType.IsVarTime
19981998
)
19991999
{

src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,17 @@ public static void CreateTable(SqlConnection sqlConnection, string tableName, st
603603
}
604604
}
605605

606+
public static void CreateSP(SqlConnection sqlConnection, string spName, string spBody)
607+
{
608+
DropStoredProcedure(sqlConnection, spName);
609+
string spCreate = "CREATE PROCEDURE " + spName + spBody;
610+
using (SqlCommand command = sqlConnection.CreateCommand())
611+
{
612+
command.CommandText = spCreate;
613+
command.ExecuteNonQuery();
614+
}
615+
}
616+
606617
public static void DropTable(SqlConnection sqlConnection, string tableName)
607618
{
608619
ResurrectConnection(sqlConnection);

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Xunit;
1111
using Xunit.Abstractions;
1212
using System.Text.Json;
13+
using Microsoft.Data.SqlTypes;
1314

1415
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
1516
{
@@ -124,6 +125,12 @@ public void TestJsonWrite()
124125
ValidateRowsAffected(rowsAffected3);
125126
}
126127

128+
//Test 4
129+
// Write json value using a parameterized query with SqlJson type
130+
parameter.Value = new SqlJson(JsonDataString);
131+
int rowsAffected4 = command.ExecuteNonQuery();
132+
ValidateRowsAffected(rowsAffected4);
133+
127134
DataTestUtility.DropTable(connection, tableName);
128135
DataTestUtility.DropStoredProcedure(connection, spName);
129136
}
@@ -182,6 +189,12 @@ public async Task TestJsonWriteAsync()
182189
ValidateRowsAffected(rowsAffected3);
183190
}
184191

192+
//Test 4
193+
// Write json value using a parameterized query with SqlJson type
194+
parameter.Value = new SqlJson(JsonDataString);
195+
int rowsAffected4 = await command.ExecuteNonQueryAsync();
196+
ValidateRowsAffected(rowsAffected4);
197+
185198
DataTestUtility.DropTable(connection, tableName);
186199
DataTestUtility.DropStoredProcedure(connection, spName);
187200
}
@@ -354,7 +367,7 @@ public void TestJsonAPIs()
354367
// Create Table
355368
DataTestUtility.CreateTable(connection, tableName, "(Data json)");
356369

357-
// Insert Null value
370+
//Insert
358371
command.CommandText = tableInsert;
359372
var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
360373
parameter.Value = JsonDataString;
@@ -373,6 +386,7 @@ public void TestJsonAPIs()
373386
Assert.Equal(JsonDataString, jsonDocument.RootElement.ToString());
374387
Assert.Equal("json", reader.GetDataTypeName(0));
375388
Assert.Equal("System.String", reader.GetFieldType(0).ToString());
389+
Assert.Equal(JsonDataString, reader.GetSqlJson(0).Value);
376390
}
377391
}
378392
}
@@ -439,5 +453,57 @@ public void TestJsonWithMARS()
439453
}
440454
}
441455
}
456+
457+
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
458+
public void TestJsonSPParams()
459+
{
460+
string tableName = DataTestUtility.GenerateObjectName();
461+
string procName = DataTestUtility.GenerateObjectName();
462+
string tableInsert = $"INSERT INTO {tableName} VALUES (@id, @jsonData)";
463+
string tableRead = $"SELECT * FROM {tableName}";
464+
465+
using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
466+
{
467+
connection.Open();
468+
try
469+
{
470+
// Create Table
471+
DataTestUtility.CreateTable(connection, tableName, "(Id int, Data json)");
472+
473+
// Create Stored Procedure
474+
string createSP = $@"
475+
@id int,
476+
@jsonData json OUTPUT
477+
AS
478+
BEGIN
479+
SELECT @jsonData = (SELECT Data FROM {tableName} WHERE Id = @id)
480+
END;";
481+
DataTestUtility.CreateSP(connection, procName, createSP);
482+
483+
// Insert Data
484+
using (SqlCommand command = new SqlCommand(tableInsert, connection))
485+
{
486+
command.Parameters.Add(new SqlParameter("@id", SqlDbType.Int) { Value = 1 });
487+
command.Parameters.Add(new SqlParameter("@jsonData", SqlDbTypeExtensions.Json) { Value = JsonDataString });
488+
command.ExecuteNonQuery();
489+
}
490+
491+
// Execute Stored Procedure
492+
using (SqlCommand spCommand = new SqlCommand(procName, connection))
493+
{
494+
spCommand.CommandType = CommandType.StoredProcedure;
495+
spCommand.Parameters.Add(new SqlParameter("@id", SqlDbType.Int) { Direction = ParameterDirection.Input, Value = 1 });
496+
SqlParameter outputParam = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json) { Direction = ParameterDirection.Output };
497+
spCommand.Parameters.Add(outputParam);
498+
spCommand.ExecuteNonQuery();
499+
Assert.Equal(JsonDataString, (string)outputParam.Value);
500+
}
501+
}
502+
finally
503+
{
504+
DataTestUtility.DropTable(connection, tableName);
505+
}
506+
}
507+
}
442508
}
443509
}

0 commit comments

Comments
 (0)