Skip to content

Commit eda4341

Browse files
Update selection path with type refinement
1 parent 37eb310 commit eda4341

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Planning/OperationDefinitionBuilder.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ internal sealed class OperationDefinitionBuilder
1212
private string? _name;
1313
private string? _description;
1414
private Lookup? _lookup;
15+
private bool _isAbstractLookup;
1516
private string? _requirementKey;
1617
private SelectionSetNode? _selectionSet;
1718

@@ -40,9 +41,10 @@ public OperationDefinitionBuilder SetDescription(string? description)
4041
return this;
4142
}
4243

43-
public OperationDefinitionBuilder SetLookup(Lookup? lookup, string? requirementKey)
44+
public OperationDefinitionBuilder SetLookup(Lookup? lookup, bool isAbstractLookup, string? requirementKey)
4445
{
4546
_lookup = lookup;
47+
_isAbstractLookup = isAbstractLookup;
4648
_requirementKey = requirementKey;
4749
return this;
4850
}
@@ -88,6 +90,11 @@ public OperationDefinitionBuilder SetSelectionSet(SelectionSetNode selectionSet)
8890
indexBuilder.Register(selectionSet);
8991
index = indexBuilder;
9092
selectionPath = selectionPath.AppendField(_lookup.FieldName);
93+
94+
if (_isAbstractLookup)
95+
{
96+
selectionPath = selectionPath.AppendFragment(_lookup.FieldType);
97+
}
9198
}
9299

93100
var definition = new OperationDefinitionNode(

src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Planning/OperationPlanner.cs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,11 @@ lookup is null
293293
requirements = requirements.Add(argumentRequirementKey, operationRequirement);
294294
}
295295

296-
// If the lookup returns an abstract type, we might need to insert a type refinement
297-
// around our selection set.
296+
var isAbstractLookup = false;
298297
if (_schema.Types.TryGetType(lookup.FieldType, out var lookupFieldType)
299-
&& lookupFieldType != workItem.SelectionSet.Type)
298+
&& lookupFieldType != workItem.SelectionSet.Type
299+
&& !resolvable.Selections.All(s => s is InlineFragmentNode inlineFragment
300+
&& inlineFragment.TypeCondition?.Name.Value == workItem.SelectionSet.Type.Name))
300301
{
301302
var typeRefinement =
302303
new InlineFragmentNode(
@@ -313,9 +314,11 @@ lookup is null
313314
index = indexBuilder;
314315

315316
operationBuilder.SetSelectionSet(selectionSetWithTypeRefinement);
317+
318+
isAbstractLookup = true;
316319
}
317320

318-
operationBuilder.SetLookup(lookup, requirementKey);
321+
operationBuilder.SetLookup(lookup, isAbstractLookup, requirementKey);
319322
}
320323

321324
(var definition, index, var source) = operationBuilder.Build(index);
@@ -686,7 +689,32 @@ private void PlanFieldWithRequirement(
686689
requirements = requirements.Add(argumentRequirementKey, operationRequirement);
687690
}
688691

689-
operationBuilder.SetLookup(workItem.Lookup, requirementKey);
692+
var isAbstractLookup = false;
693+
if (_schema.Types.TryGetType(lookup.FieldType, out var lookupFieldType)
694+
&& lookupFieldType != selectionSetStub.Type
695+
&& !selectionSetNode.Selections.All(s => s is InlineFragmentNode inlineFragment
696+
&& inlineFragment.TypeCondition?.Name.Value == selectionSetStub.Type.Name))
697+
{
698+
var typeRefinement =
699+
new InlineFragmentNode(
700+
null,
701+
new NamedTypeNode(selectionSetStub.Type.Name),
702+
[],
703+
selectionSetNode);
704+
var selectionSetWithTypeRefinement = new SelectionSetNode(null, [typeRefinement]);
705+
706+
var indexBuilder = index.ToBuilder();
707+
708+
indexBuilder.Register(selectionSetNode, selectionSetWithTypeRefinement);
709+
710+
index = indexBuilder;
711+
712+
operationBuilder.SetSelectionSet(selectionSetWithTypeRefinement);
713+
714+
isAbstractLookup = true;
715+
}
716+
717+
operationBuilder.SetLookup(workItem.Lookup, isAbstractLookup, requirementKey);
690718

691719
var (definition, _, source) = operationBuilder.Build(index);
692720

0 commit comments

Comments
 (0)