Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a0bd291
chore(deps): upgrade to .NET 10 and Microsoft.Data.SqlClient 6.x
souvikghosh04 Jun 10, 2026
1064d7f
Update SqlClient 6.1.5
RubenCerna2079 Jun 18, 2026
96f5324
Address PR review feedback and align ASP.NET Core packages to 10.x
souvikghosh04 Jun 18, 2026
3f5b597
Merge branch 'main' into Usr/sogh/upgrade-net10-sqlclient6
souvikghosh04 Jun 18, 2026
280151b
Pin MessagePack to 2.5.301 to fix NU1903 transitive vulnerability
souvikghosh04 Jun 18, 2026
1a7d309
Formatting fixes
souvikghosh04 Jun 18, 2026
a6ecbb9
Formatting fixes
souvikghosh04 Jun 18, 2026
5544ef4
Remove unused variable
souvikghosh04 Jun 18, 2026
5e3175b
Fix SqlTestHelper for Microsoft.Data.SqlClient 6.x SqlError construct…
souvikghosh04 Jun 18, 2026
f840076
Treat empty ASPNETCORE_URLS as valid in ValidateAspNetCoreUrls
souvikghosh04 Jun 18, 2026
ed820fb
Revert unrelated changes to match main (PR review feedback)
souvikghosh04 Jun 19, 2026
3735ff4
Fix .NET 10 formatter whitespace/style on Core mutation files
souvikghosh04 Jun 19, 2026
a808e13
remove unused variable due to strict check by .Net 10
souvikghosh04 Jun 19, 2026
abb49d1
Merge branch 'main' into Usr/sogh/upgrade-net10-sqlclient6
souvikghosh04 Jun 22, 2026
fbb8159
try adding DBTYPE_RESOLUTION_ERROR back
souvikghosh04 Jun 22, 2026
f3f5583
Removing unused variable which fails in pipeline
souvikghosh04 Jun 22, 2026
bd87fa0
Suppress unused variable warning
souvikghosh04 Jun 22, 2026
d19a55f
Update SqlClient to 6.1.5
RubenCerna2079 Jun 8, 2026
3cc1c0b
First additions to vector data type
RubenCerna2079 Jun 9, 2026
2fea5ce
New changes
RubenCerna2079 Jun 10, 2026
1e49376
Make vector array type
RubenCerna2079 Jun 17, 2026
98e6434
Read
RubenCerna2079 Jun 19, 2026
0137653
More changes
RubenCerna2079 Jun 22, 2026
e7d72c8
Add write abilities
RubenCerna2079 Jun 22, 2026
36ff6eb
Add writing capabilities
RubenCerna2079 Jun 22, 2026
8a0edd2
Add tests
RubenCerna2079 Jun 24, 2026
c657910
Merge branch 'main' into dev/rubencerna/first-changes-vector-type
RubenCerna2079 Jun 24, 2026
ebe6b28
Fix tests
RubenCerna2079 Jun 24, 2026
7e45fe2
Fix syntax
RubenCerna2079 Jun 24, 2026
aef7af9
Fix syntax error
RubenCerna2079 Jun 24, 2026
e479927
Changes based on copilot
RubenCerna2079 Jun 25, 2026
0e96e32
Upgrade docker sql version
RubenCerna2079 Jun 25, 2026
84b73b1
Fix utf8
RubenCerna2079 Jun 25, 2026
99954f6
Upgrade docker sql version
RubenCerna2079 Jun 25, 2026
6404bdc
Change to sql 2025 in pipeline
RubenCerna2079 Jun 25, 2026
786f98f
Merge remote-tracking branch 'refs/remotes/origin/dev/rubencerna/firs…
RubenCerna2079 Jun 25, 2026
f96fefb
Fixed how result is returned in insert
RubenCerna2079 Jun 26, 2026
8f2eb92
Changes based on comments
RubenCerna2079 Jul 1, 2026
c357a59
Fix syntax
RubenCerna2079 Jul 1, 2026
0bdbf83
Allow read request for vector data type
RubenCerna2079 Jul 2, 2026
e7bf7bb
Add support for vector data type in graphql
RubenCerna2079 Jul 9, 2026
35ca2ec
Add support to update tests
RubenCerna2079 Jul 10, 2026
b2f87b5
Add tests for graphql
RubenCerna2079 Jul 10, 2026
036141e
Fix merge conflicts
RubenCerna2079 Jul 14, 2026
a5158bf
Changes based on copilot
RubenCerna2079 Jul 14, 2026
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
2 changes: 1 addition & 1 deletion config-generators/mssql-commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ add Broker --config "dab-config.MsSql.json" --source brokers --permissions "anon
add WebsiteUser --config "dab-config.MsSql.json" --source website_users --permissions "anonymous:create,read,delete,update"
add WebsiteUser_MM --config "dab-config.MsSql.json" --source website_users_mm --graphql "websiteuser_mm:websiteusers_mm" --permissions "anonymous:*"
add SupportedType --config "dab-config.MsSql.json" --source type_table --permissions "anonymous:create,read,delete,update"
add VectorType --config "dab-config.MsSql.json" --source vector_type_table --rest true --graphql false --permissions "anonymous:create,read,delete,update"
add VectorType --config "dab-config.MsSql.json" --source vector_type_table --rest true --graphql true --permissions "anonymous:create,read,delete,update"
update VectorType --config "dab-config.MsSql.json" --permissions "authenticated:create,read,delete,update"
add stocks_price --config "dab-config.MsSql.json" --source stocks_price --permissions "authenticated:create,read,update,delete"
update stocks_price --config "dab-config.MsSql.json" --permissions "anonymous:read"
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Resolvers/MultipleCreateOrderHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ private static RelationshipFields GetRelationshipFieldsInSourceAndTarget(
foreach (ObjectFieldNode field in fieldNodes)
{
Tuple<IValueNode?, SyntaxKind> fieldDetails = GraphQLUtils.GetFieldDetails(field.Value, context.Variables);
SyntaxKind fieldKind = fieldDetails.Item2;
SyntaxKind fieldKind = metadataProvider.TryGetUnderlyingFieldKind(entityName, field.Name.Value, out SyntaxKind arrayFieldKind) ? arrayFieldKind : fieldDetails.Item2;
if (GraphQLUtils.IsScalarField(fieldKind) && metadataProvider.TryGetBackingColumn(entityName, field.Name.Value, out string? backingColumnName))
{
backingColumnData.Add(backingColumnName, fieldDetails.Item1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -698,5 +698,22 @@ protected object GetParamAsSystemType(string fieldValue, string fieldName, Type

}
}

/// <summary>
/// Transforms the value of an object as a string.
/// Array/vector columns (e.g. SQL Server 'vector') arrive as a List<IValueNode>.
/// Calling ToString() on a list/array only yields the CLR type name, so instead extract
/// the underlying element values and serialize them into a JSON array string (e.g. "[1.5,2.5,3.5]").
/// </summary>
/// <param name="value">The value to be transformed into a string.</param>
/// <returns>A string representation of the value.</returns>
protected static string GetStringifiedValue(object value)
{
return value switch
{
IEnumerable<IValueNode> valueNodes => JsonSerializer.Serialize(valueNodes.Select(TypeHelper.GetValue)),
_ => value.ToString()!
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ private void PopulateColumnsAndParams(string columnName, object? value)

if (value is not null)
{
string stringValue = GetStringifiedValue(value);
paramName = MakeDbConnectionParam(
GetParamAsSystemType(value.ToString()!, columnName, GetColumnSystemType(columnName)), columnName);
GetParamAsSystemType(stringValue, columnName, GetColumnSystemType(columnName)), columnName);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,12 @@ private Predicate CreatePredicateForParam(KeyValuePair<string, object?> param)
}
else
{
string stringValue = GetStringifiedValue(param.Value);
predicate = new(
new PredicateOperand(
new Column(tableSchema: DatabaseObject.SchemaName, tableName: DatabaseObject.Name, backingColumn)),
PredicateOperation.Equal,
new PredicateOperand($"{MakeDbConnectionParam(GetParamAsSystemType(param.Value.ToString()!, backingColumn, GetColumnSystemType(backingColumn)), backingColumn)}"));
new PredicateOperand($"{MakeDbConnectionParam(GetParamAsSystemType(stringValue, backingColumn, GetColumnSystemType(backingColumn)), backingColumn)}"));
}

return predicate;
Expand Down
33 changes: 23 additions & 10 deletions src/Core/Resolvers/SqlMutationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ await queryExecutor.ExecuteQueryAsync(
string rootFieldName = isMultipleInputType ? MULTIPLE_INPUT_ARGUEMENT_NAME : SINGLE_INPUT_ARGUEMENT_NAME;

// Parse the hotchocolate input parameters into .net object types
object? parsedInputParams = GQLMultipleCreateArgumentToDictParams(context, rootFieldName, mutationInputParamsFromGQLContext);
object? parsedInputParams = GQLMultipleCreateArgumentToDictParams(context, rootFieldName, mutationInputParamsFromGQLContext, sqlMetadataProvider, entityName);

if (parsedInputParams is null)
{
Expand Down Expand Up @@ -1758,14 +1758,16 @@ private static void PopulateCurrentAndLinkingEntityParams(
internal static object? GQLMultipleCreateArgumentToDictParams(
IMiddlewareContext context,
string rootFieldName,
IDictionary<string, object?> mutationParameters)
IDictionary<string, object?> mutationParameters,
ISqlMetadataProvider metadataProvider,
string entityName)
{
if (mutationParameters.TryGetValue(rootFieldName, out object? inputParameters))
{
ObjectField fieldSchema = context.Selection.Field;
IInputValueDefinition itemsArgumentSchema = fieldSchema.Arguments[rootFieldName];
InputObjectType inputObjectType = ExecutionHelper.InputObjectTypeFromIInputField(itemsArgumentSchema);
return GQLMultipleCreateArgumentToDictParamsHelper(context, inputObjectType, inputParameters);
return GQLMultipleCreateArgumentToDictParamsHelper(context, inputObjectType, inputParameters, metadataProvider, entityName);
}
else
{
Expand Down Expand Up @@ -1813,7 +1815,9 @@ private static void PopulateCurrentAndLinkingEntityParams(
internal static object? GQLMultipleCreateArgumentToDictParamsHelper(
IMiddlewareContext context,
InputObjectType inputObjectType,
object? inputParameters)
object? inputParameters,
ISqlMetadataProvider metadataProvider,
string entityName)
{
// This condition is met for input types that accept an array of values
// where the mutation input field is 'items' such as
Expand All @@ -1835,7 +1839,9 @@ private static void PopulateCurrentAndLinkingEntityParams(
object? parsedInputFieldItem = GQLMultipleCreateArgumentToDictParamsHelper(
context: context,
inputObjectType: inputObjectType,
inputParameters: inputField.Value);
inputParameters: inputField.Value,
metadataProvider: metadataProvider,
entityName: entityName);
if (parsedInputFieldItem is not null)
{
parsedInputFieldItems.Add((IDictionary<string, object?>)parsedInputFieldItem);
Expand All @@ -1862,33 +1868,40 @@ private static void PopulateCurrentAndLinkingEntityParams(
foreach (ObjectFieldNode inputFieldNode in inputFieldNodes)
{
string fieldName = inputFieldNode.Name.Value;
SyntaxKind fieldKind = metadataProvider.TryGetUnderlyingFieldKind(entityName, fieldName, out SyntaxKind arrayFieldKind)
? arrayFieldKind : inputFieldNode.Value.Kind;

// For the mutation pointMultipleCreateExample (outlined in the method summary),
// the following condition will evaluate to true for fields 'authors' and 'reviews'.
// Fields 'authors'/'reviews' can again consist of combination of scalar and relationship fields.
// So, the input object type for 'authors'/'reviews' is fetched and the same function is
// invoked with the fetched input object type again to parse the input fields of 'authors'/'reviews'.
if (inputFieldNode.Value.Kind == SyntaxKind.ListValue)
if (fieldKind == SyntaxKind.ListValue)
{
parsedInputFields.Add(
fieldName,
GQLMultipleCreateArgumentToDictParamsHelper(
context,
GetInputObjectTypeForAField(fieldName, inputObjectType.Fields),
inputFieldNode.Value.Value));
inputFieldNode.Value.Value,
metadataProvider,
entityName));
}
// For the mutation pointMultipleCreateExample (outlined in the method summary),
// the following condition will evaluate to true for fields 'publishers'.
// Field 'publishers' can again consist of combination of scalar and relationship fields.
// So, the input object type for 'publishers' is fetched and the same function is
// invoked with the fetched input object type again to parse the input fields of 'publishers'.
else if (inputFieldNode.Value.Kind == SyntaxKind.ObjectValue)
else if (fieldKind == SyntaxKind.ObjectValue)
{
parsedInputFields.Add(
fieldName,
GQLMultipleCreateArgumentToDictParamsHelper(
context,
GetInputObjectTypeForAField(fieldName, inputObjectType.Fields),
inputFieldNode.Value.Value));
inputFieldNode.Value.Value,
metadataProvider,
entityName));
}
// The flow enters this block for all scalar input fields.
else
Expand Down Expand Up @@ -2366,7 +2379,7 @@ private void ProcessObjectFieldNodesForAuthZ(
foreach (ObjectFieldNode field in fieldNodes)
{
Tuple<IValueNode?, SyntaxKind> fieldDetails = GraphQLUtils.GetFieldDetails(field.Value, context.Variables);
SyntaxKind underlyingFieldKind = fieldDetails.Item2;
SyntaxKind underlyingFieldKind = metadataProvider.TryGetUnderlyingFieldKind(entityName, field.Name.Value, out SyntaxKind arrayFieldKind) ? arrayFieldKind : fieldDetails.Item2;

// For a column field, we do not have to recurse to process fields in the value - which is required for relationship fields.
if (GraphQLUtils.IsScalarField(underlyingFieldKind) || underlyingFieldKind is SyntaxKind.NullValue)
Expand Down
Loading
Loading