Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Core/Models/SqlTypeConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static class SqlTypeConstants
{ "time", true }, // SqlDbType.Time
{ "datetime2", true }, // SqlDbType.DateTime2
{ "datetimeoffset", true }, // SqlDbType.DateTimeOffset
{ "json", true }, // SqlDbType.Json (SQL Server 2025+) treated as string
{ "", false }, // SqlDbType.Udt and SqlDbType.Structured provided by SQL as empty strings (unsupported)
{ "numeric", true} // Not present in SqlDbType, however can be returned by sql functions like LAG and should map to decimal.
};
Expand Down
5 changes: 4 additions & 1 deletion src/Core/Resolvers/MsSqlDbExceptionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ public MsSqlDbExceptionParser(RuntimeConfigProvider configProvider) : base(confi
"4435", "4436", "4437", "4438", "4439", "4440", "4441",
"4442", "4443", "4444", "4445", "4446", "4447", "4448",
"4450", "4451", "4452", "4453", "4454", "4455", "4456",
"4457", "4933", "4934", "4936", "4988", "8102"
"4457", "4933", "4934", "4936", "4988", "8102",
// JSON data type validation errors (SQL Server 2025+). Invalid JSON
// supplied for a json column is a client error, mapped to HTTP 400.
"13608", "13609", "13610", "13611", "13612", "13613", "13614"
Comment on lines +33 to +36
});

TransientExceptionCodes.UnionWith(new List<string>
Expand Down
1 change: 1 addition & 0 deletions src/Core/Services/TypeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public static class TypeHelper
[SqlDbType.Float] = typeof(double),
[SqlDbType.Image] = typeof(byte[]),
[SqlDbType.Int] = typeof(int),
[SqlDbType.Json] = typeof(string),
[SqlDbType.Money] = typeof(decimal),
[SqlDbType.NChar] = typeof(char),
[SqlDbType.NText] = typeof(string),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,17 @@ public void ResolveUnderlyingTypeForNullableValueType(Type nullableType)
Assert.AreNotEqual(notExpected: JsonDataType.Undefined, actual: TypeHelper.GetJsonDataTypeFromSystemType(nullableType));
Assert.IsNotNull(TypeHelper.GetDbTypeFromSystemType(nullableType));
}

/// <summary>
/// Validates that the SQL Server 2025+ 'json' data type literal resolves to the
/// CLR string type and maps to JsonDataType.String, i.e. DAB treats a JSON column
/// just like a string column.
/// </summary>
[TestMethod]
public void JsonSqlDbTypeResolvesToString()
{
Type resolvedType = TypeHelper.GetSystemTypeFromSqlDbType("json");
Assert.AreEqual(typeof(string), resolvedType);
Assert.AreEqual(JsonDataType.String, TypeHelper.GetJsonDataTypeFromSystemType(resolvedType));
}
}
37 changes: 37 additions & 0 deletions src/Service.Tests/UnitTests/DbExceptionParserUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,42 @@ public void TestIsTransientExceptionMethod(bool expected, int number)

Assert.AreEqual(expected, dbExceptionParser.IsTransientException(SqlTestHelper.CreateSqlException(number)));
}

/// <summary>
/// Validates that JSON data type validation error codes raised by SQL Server 2025+
/// when invalid JSON is supplied for a json column are mapped to HTTP 400 Bad Request.
/// </summary>
/// <param name="number">SQL error code populated in SqlException.Number.</param>
[DataTestMethod]
[DataRow(13608, DisplayName = "JSON validation error code 13608 maps to 400")]
[DataRow(13609, DisplayName = "JSON validation error code 13609 maps to 400")]
[DataRow(13610, DisplayName = "JSON validation error code 13610 maps to 400")]
[DataRow(13611, DisplayName = "JSON validation error code 13611 maps to 400")]
[DataRow(13612, DisplayName = "JSON validation error code 13612 maps to 400")]
[DataRow(13613, DisplayName = "JSON validation error code 13613 maps to 400")]
[DataRow(13614, DisplayName = "JSON validation error code 13614 maps to 400")]
public void TestJsonValidationErrorsMapToBadRequest(int number)
{
RuntimeConfig mockConfig = new(
Schema: "",
DataSource: new(DatabaseType.MSSQL, "", new()),
Runtime: new(
Rest: new(),
GraphQL: new(),
Mcp: new(),
Host: new(null, null, HostMode.Development)
),
Entities: new(new Dictionary<string, Entity>())
);
MockFileSystem fileSystem = new();
fileSystem.AddFile(FileSystemRuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME, new MockFileData(mockConfig.ToJson()));
FileSystemRuntimeConfigLoader loader = new(fileSystem);
RuntimeConfigProvider provider = new(loader);
DbExceptionParser dbExceptionParser = new MsSqlDbExceptionParser(provider);

Assert.AreEqual(
System.Net.HttpStatusCode.BadRequest,
dbExceptionParser.GetHttpStatusCodeForException(SqlTestHelper.CreateSqlException(number)));
}
Comment on lines +130 to +133
}
}
Loading