diff --git a/Tests/ApolloCodegenTests/CodeGenIR/IRMergedSelections_FieldMergingStrategy_Tests.swift b/Tests/ApolloCodegenTests/CodeGenIR/IRMergedSelections_FieldMergingStrategy_Tests.swift
index a39efe358..3f498ecfe 100644
--- a/Tests/ApolloCodegenTests/CodeGenIR/IRMergedSelections_FieldMergingStrategy_Tests.swift
+++ b/Tests/ApolloCodegenTests/CodeGenIR/IRMergedSelections_FieldMergingStrategy_Tests.swift
@@ -46,7 +46,7 @@ class IRMergedSelections_FieldMergingStrategy_Tests: XCTestCase {
 
   // MARK: - Test MergingStrategy: Ancestors
 
-  func test__mergingStrategy_ancestors__givenFieldInAncestor_includesField() async throws {
+  func test__mergingStrategy_ancestors__givenFieldInParent_includesField() async throws {
     // given
     schemaSDL = """
     type Query {
@@ -100,6 +100,148 @@ class IRMergedSelections_FieldMergingStrategy_Tests: XCTestCase {
     expect(AllAnimals_asPet).to(shallowlyMatch(expected))
   }
 
+  func test__mergingStrategy_ancestors__givenFieldInNestedAncestor_includesField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+      bark: Boolean
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Pet {
+          petName
+          ... on Dog {
+            bark
+          }
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .ancestors
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+    let Scalar_Bool = try unwrap(self.schema[scalar: "Boolean"])
+
+    // when
+    let AllAnimals_asPet_asDog = rootField[field: "allAnimals"]?[as: "Pet"]?[as: "Dog"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[object: "Dog"]),
+      directSelections: [
+        .field("bark", type: .scalar(Scalar_Bool))
+      ],
+      mergedSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .field("petName", type: .scalar(Scalar_String))
+      ],
+      mergedSources: [
+        try .mock(rootField[field: "allAnimals"]),
+        try .mock(rootField[field: "allAnimals"]?[as: "Pet"])
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_asDog).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_ancestors__givenMatchingTypeCaseInNestedParent_includesField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    interface HousePet implements Pet & Animal {
+      species: String
+      petName: String
+      houseTrained: Boolean
+    }
+
+    type Dog implements Animal & HousePet {
+      species: String
+      petName: String
+      bark: Boolean
+      houseTrained: Boolean
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Pet {
+          petName
+          ... on HousePet {
+            houseTrained
+          }
+          ... on Dog {
+            bark
+          }
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .ancestors
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+    let Scalar_Bool = try unwrap(self.schema[scalar: "Boolean"])
+
+    // when
+    let AllAnimals_asPet_asDog = rootField[field: "allAnimals"]?[as: "Pet"]?[as: "Dog"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[object: "Dog"]),
+      directSelections: [
+        .field("bark", type: .scalar(Scalar_Bool))
+      ],
+      mergedSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .field("petName", type: .scalar(Scalar_String))
+      ],
+      mergedSources: [
+        try .mock(rootField[field: "allAnimals"]),
+        try .mock(rootField[field: "allAnimals"]?[as: "Pet"])
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_asDog).to(shallowlyMatch(expected))
+  }
+
   func test__mergingStrategy_ancestors__givenFieldInSiblingInlineFragmentThatMatchesType_doesNotIncludeField() async throws {
     // given
     schemaSDL = """
@@ -157,6 +299,1321 @@ class IRMergedSelections_FieldMergingStrategy_Tests: XCTestCase {
     expect(AllAnimals_asDog).to(shallowlyMatch(expected))
   }
 
+  func test__mergingStrategy_ancestors__givenExactMatchingTypeCaseInNestedAncestor_doesNotIncludeField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+      bark: Boolean
+      bite: Boolean
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Dog {
+          bite
+        }
+        ... on Pet {
+          petName
+          ... on Dog {
+            bark
+          }
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .ancestors
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+    let Scalar_Bool = try unwrap(self.schema[scalar: "Boolean"])
+
+    // when
+    let AllAnimals_asPet_asDog = rootField[field: "allAnimals"]?[as: "Pet"]?[as: "Dog"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[object: "Dog"]),
+      directSelections: [
+        .field("bark", type: .scalar(Scalar_Bool))
+      ],
+      mergedSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .field("petName", type: .scalar(Scalar_String)),
+      ],
+      mergedSources: [
+        try .mock(rootField[field: "allAnimals"]),
+        try .mock(rootField[field: "allAnimals"]?[as: "Pet"])
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_asDog).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_ancestors__givenConditionalInlineFragment_fieldInParent_includesField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... @include(if: $a) {
+          name
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .ancestors
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_ifA = rootField[field: "allAnimals"]?[if: "a"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      inclusionConditions: [.include(if: "a")],
+      directSelections: [
+        .field("name", type: .scalar(Scalar_String))
+      ],
+      mergedSelections: [
+        .field("species", type: .scalar(Scalar_String))
+      ],
+      mergedSources: [
+        try .mock(rootField[field:"allAnimals"])
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_ifA).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_ancestors__givenNamedFragment_doesNotIncludeFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ...Details
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .ancestors
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals = rootField[field: "allAnimals"]
+    let DetailsFragment = try unwrap(self.rootField[field: "allAnimals"]?[fragment: "Details"])
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .fragmentSpread(DetailsFragment.definition)
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals?.selectionSet).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_ancestors__givenNamedFragmentInParent_includesFragment_doesNotIncludeFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ...Details
+        ... on Pet {
+          petName
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .ancestors
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals = rootField[field: "allAnimals"]
+    let AllAnimals_asPet = AllAnimals?[as: "Pet"]
+    let DetailsFragment = try unwrap(self.rootField[field: "allAnimals"]?[fragment: "Details"])
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Pet"]),
+      directSelections: [
+        .field("petName", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .fragmentSpread(DetailsFragment.definition)
+      ],
+      mergedSources: [
+        try .mock(AllAnimals)
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet).to(shallowlyMatch(expected))
+  }
+
+  // MARK: - Siblings
+
+  func test__mergingStrategy_siblings__givenFieldInParent_doesNotIncludeField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Pet {
+          petName
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_asPet = rootField[field: "allAnimals"]?[as: "Pet"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Pet"]),
+      directSelections: [
+        .field("petName", type: .scalar(Scalar_String))
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_siblings__givenFieldInNestedAncestor_doesNotIncludeField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+      bark: Boolean
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Pet {
+          petName
+          ... on Dog {
+            bark
+          }
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_Bool = try unwrap(self.schema[scalar: "Boolean"])
+
+    // when
+    let AllAnimals_asPet_asDog = rootField[field: "allAnimals"]?[as: "Pet"]?[as: "Dog"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[object: "Dog"]),
+      directSelections: [
+        .field("bark", type: .scalar(Scalar_Bool))
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_asDog).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_siblings__givenMatchingSiblingTypeCaseInParent_includesField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        ... on Dog {
+          species
+        }
+        ... on Pet {
+          petName
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_asDog = rootField[field: "allAnimals"]?[as: "Dog"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[object: "Dog"]),
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String))
+      ],
+      mergedSelections: [
+        .field("petName", type: .scalar(Scalar_String))
+      ],
+      mergedSources: [
+        try .mock(rootField[field: "allAnimals"]?[as: "Pet"])
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asDog).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_siblings__givenMatchingSiblingTypeCaseInNestedParent_includesField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    interface HousePet implements Pet & Animal {
+      species: String
+      petName: String
+      houseTrained: Boolean
+    }
+
+    type Dog implements Animal & HousePet {
+      species: String
+      petName: String
+      bark: Boolean
+      houseTrained: Boolean
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Pet {
+          petName
+          ... on HousePet {
+            houseTrained
+          }
+          ... on Dog {
+            bark
+          }
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_Bool = try unwrap(self.schema[scalar: "Boolean"])
+
+    // when
+    let AllAnimals_asPet_asDog = rootField[field: "allAnimals"]?[as: "Pet"]?[as: "Dog"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[object: "Dog"]),
+      directSelections: [
+        .field("bark", type: .scalar(Scalar_Bool))
+      ],
+      mergedSelections: [
+        .field("houseTrained", type: .scalar(Scalar_Bool)),
+      ],
+      mergedSources: [
+        try .mock(rootField[field: "allAnimals"]?[as: "Pet"]?[as: "HousePet"])
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_asDog).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_siblings__givenExactMatchingTypeCaseInNestedAncestor_includesField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+      bark: Boolean
+      bite: Boolean
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Dog {
+          bite
+        }
+        ... on Pet {
+          petName
+          ... on Dog {
+            bark
+          }
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_Bool = try unwrap(self.schema[scalar: "Boolean"])
+
+    // when
+    let AllAnimals_asPet_asDog = rootField[field: "allAnimals"]?[as: "Pet"]?[as: "Dog"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[object: "Dog"]),
+      directSelections: [
+        .field("bark", type: .scalar(Scalar_Bool))
+      ],
+      mergedSelections: [
+        .field("bite", type: .scalar(Scalar_Bool)),
+      ],
+      mergedSources: [
+        try .mock(rootField[field: "allAnimals"]?[as: "Dog"])
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_asDog).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_siblings__givenConditionalInlineFragment_fieldInParent_doesNotIncludeField() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... @include(if: $a) {
+          name
+        }
+      }
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_ifA = rootField[field: "allAnimals"]?[if: "a"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      inclusionConditions: [.include(if: "a")],
+      directSelections: [
+        .field("name", type: .scalar(Scalar_String))
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_ifA).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_siblings__givenNamedFragment_doesNotIncludeFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ...Details
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals = rootField[field: "allAnimals"]
+    let DetailsFragment = try unwrap(self.rootField[field: "allAnimals"]?[fragment: "Details"])
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .fragmentSpread(DetailsFragment.definition)
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals?.selectionSet).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_siblings__givenNamedFragmentInParent_doesNotIncludeFragmentOrFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ...Details
+        ... on Pet {
+          petName
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .siblings
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals = rootField[field: "allAnimals"]
+    let AllAnimals_asPet = AllAnimals?[as: "Pet"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Pet"]),
+      directSelections: [
+        .field("petName", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet).to(shallowlyMatch(expected))
+  }
+
+  // MARK: - Named Fragments
+
+  func test__mergingStrategy_namedFragments__givenNamedFragment_includesFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ...Details
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .namedFragments
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals = rootField[field: "allAnimals"]
+    let DetailsFragment = try unwrap(self.rootField[field: "allAnimals"]?[fragment: "Details"])
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .fragmentSpread(DetailsFragment.definition)
+      ],
+      mergedSelections: [
+        .field("name", type: .scalar(Scalar_String)),
+      ],
+      mergedSources: [
+        try .mock(DetailsFragment)
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals?.selectionSet).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_namedFragments__givenNamedFragmentInNestedTypeCaseWithMatchingButNotExactTypeOfFragment_includesFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ... on Pet {
+          ...Details
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .namedFragments
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_asPet = rootField[field: "allAnimals"]?[as: "Pet"]
+    let DetailsFragment = try unwrap(AllAnimals_asPet?[fragment: "Details"])
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Pet"]),
+      directSelections: [
+        .fragmentSpread(DetailsFragment.definition)
+      ],
+      mergedSelections: [
+        .field("name", type: .scalar(Scalar_String)),
+      ],
+      mergedSources: [
+        try .mock(DetailsFragment)
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_namedFragments__givenNamedFragmentInParent_doesNotIncludeFragmentOrFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ...Details
+        ... on Pet {
+          petName
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .namedFragments
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals = rootField[field: "allAnimals"]
+    let AllAnimals_asPet = AllAnimals?[as: "Pet"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Pet"]),
+      directSelections: [
+        .field("petName", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_namedFragments__givenNamedFragmentOnSameEntityNestedInParent_doesNotIncludeFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+      bestFriend: Animal
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+      bestFriend: Animal
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        bestFriend {
+          ...Details
+        }
+        ... on Pet {
+          bestFriend {
+            species
+          }
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = .namedFragments
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_asPet_bestFriend = rootField[field: "allAnimals"]?[as: "Pet"]?[field: "bestFriend"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_bestFriend?.selectionSet).to(shallowlyMatch(expected))
+  }
+
+  // MARK: - Named Fragments & Ancestors
+  func test__mergingStrategy_namedFragments_ancestors__givenNamedFragmentInParent_includesFragmentAndFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      petName: String
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        species
+        ...Details
+        ... on Pet {
+          petName
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = [.namedFragments, .ancestors]
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals = rootField[field: "allAnimals"]
+    let AllAnimals_asPet = AllAnimals?[as: "Pet"]
+    let DetailsFragment = try unwrap(self.rootField[field: "allAnimals"]?[fragment: "Details"])
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Pet"]),
+      directSelections: [
+        .field("petName", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+        .field("name", type: .scalar(Scalar_String)),
+        .fragmentSpread(DetailsFragment.definition)
+      ],
+      mergedSources: [
+        try .mock(AllAnimals),
+        try .mock(DetailsFragment)
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet).to(shallowlyMatch(expected))
+  }
+
+  func test__mergingStrategy_namedFragments_ancestors__givenNamedFragmentOnSameEntityNestedInParent_doesNotIncludeFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+      bestFriend: Animal
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+      bestFriend: Animal
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        bestFriend {
+          ...Details
+        }
+        ... on Pet {
+          bestFriend {
+            species
+          }
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = [.namedFragments, .ancestors]
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_asPet = rootField[field: "allAnimals"]?[as: "Pet"]
+    let AllAnimals_asPet_bestFriend = AllAnimals_asPet?[field: "bestFriend"]
+
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_bestFriend?.selectionSet).to(shallowlyMatch(expected))
+  }
+
+  // MARK: - Named Fragments & Sibling
+
+  func test__mergingStrategy_namedFragments_siblings__givenNamedFragmentOnSameEntityNestedInParent_includeFieldsFromFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      name: String
+      bestFriend: Animal
+    }
+
+    interface Pet implements Animal {
+      species: String
+      petName: String
+      bestFriend: Animal
+    }
+    """
+
+    document = """
+    query Test {
+      allAnimals {
+        bestFriend {
+          ...Details
+        }
+        ... on Pet {
+          bestFriend {
+            species
+          }
+        }
+      }
+    }
+
+    fragment Details on Animal {
+      name
+    }
+    """
+    let mergingStrategy: MergedSelections.MergingStrategy = [.namedFragments, .siblings]
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+
+    // when
+    let AllAnimals_asPet = rootField[field: "allAnimals"]?[as: "Pet"]
+    let AllAnimals_asPet_bestFriend = AllAnimals_asPet?[field: "bestFriend"]
+    let DetailsFragment = try unwrap(
+      self.rootField[field: "allAnimals"]?[field: "bestFriend"]?[fragment: "Details"]
+    )
+    
+    let expected = SelectionSetMatcher(
+      parentType: try unwrap(self.schema[interface: "Animal"]),
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [
+        .field("name", type: .scalar(Scalar_String)),
+        .fragmentSpread(DetailsFragment.definition),
+      ],
+      mergedSources: [
+        try .mock(rootField[field: "allAnimals"]?[field: "bestFriend"]),
+        try .mock(DetailsFragment)
+      ],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(AllAnimals_asPet_bestFriend?.selectionSet).to(shallowlyMatch(expected))
+  }
+
+  // MARK: - Composite Inline Fragments - From Siblings
+
+  func test__mergingStrategy_siblings__givenMergedTypeCaseFromSiblingAsCompositeInlineFragment_includeCompositeInlineFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      predator: Animal
+    }
+
+    interface Pet implements Animal {
+      species: String
+      predator: Animal
+      name: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      predator: Animal
+      name: String
+    }
+    """
+
+    document = """
+    query TestOperation {
+      allAnimals {
+        species
+        predator {
+          ... on Pet {
+            name
+          }
+        }
+        ... on Dog {
+          name
+          predator {
+            species
+          }
+        }
+      }
+    }
+    """
+
+    let mergingStrategy: MergedSelections.MergingStrategy = [.siblings]
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+    let Interface_Animal = try unwrap(self.schema[interface: "Animal"])
+    let Interface_Pet = try unwrap(self.schema[interface: "Pet"])
+
+    // when
+    let allAnimals_asDog_predator = try XCTUnwrap(
+      rootField[field: "allAnimals"]?[as: "Dog"]?[field: "predator"]
+    )
+
+    let allAnimals_asDog_predator_asPet = try XCTUnwrap(
+      allAnimals_asDog_predator[as: "Pet"]
+    )
+
+    let expected = SelectionSetMatcher(
+      parentType: Interface_Animal,
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [
+        .inlineFragment(parentType: Interface_Pet)
+      ],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    let expected_asPet = SelectionSetMatcher(
+      parentType: Interface_Pet,
+      directSelections: nil,
+      mergedSelections: [
+        .field("name", type: .scalar(Scalar_String)),
+      ],
+      mergedSources: [try .mock(rootField[field: "allAnimals"]?[field: "predator"]?[as: "Pet"])],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(allAnimals_asDog_predator.selectionSet).to(shallowlyMatch(expected))
+    expect(allAnimals_asDog_predator_asPet).to(shallowlyMatch(expected_asPet))
+  }
+
+  func test__mergingStrategy_ancestors__givenMergedTypeCaseFromSiblingAsCompositeInlineFragment_doesNotIncludeCompositeInlineFragment() async throws {
+    // given
+    schemaSDL = """
+    type Query {
+      allAnimals: [Animal!]
+    }
+
+    interface Animal {
+      species: String
+      predator: Animal
+    }
+
+    interface Pet implements Animal {
+      species: String
+      predator: Animal
+      name: String
+    }
+
+    type Dog implements Animal & Pet {
+      species: String
+      predator: Animal
+      name: String
+    }
+    """
+
+    document = """
+    query TestOperation {
+      allAnimals {
+        species
+        predator {
+          ... on Pet {
+            name
+          }
+        }
+        ... on Dog {
+          name
+          predator {
+            species
+          }
+        }
+      }
+    }
+    """
+
+    let mergingStrategy: MergedSelections.MergingStrategy = [.ancestors]
+
+    try await buildRootField(mergingStrategy: mergingStrategy)
+
+    let Scalar_String = try unwrap(self.schema[scalar: "String"])
+    let Interface_Animal = try unwrap(self.schema[interface: "Animal"])
+
+    // when
+    let allAnimals_asDog_predator = try XCTUnwrap(
+      rootField[field: "allAnimals"]?[as: "Dog"]?[field: "predator"]
+    )
+
+    let expected = SelectionSetMatcher(
+      parentType: Interface_Animal,
+      directSelections: [
+        .field("species", type: .scalar(Scalar_String)),
+      ],
+      mergedSelections: [],
+      mergedSources: [],
+      mergingStrategy: mergingStrategy
+    )
+
+    // then
+    expect(allAnimals_asDog_predator.selectionSet).to(shallowlyMatch(expected))
+  }
+
   // MARK: - Composite Inline Fragments - From Named Fragment
 
   func test__mergingStrategy_namedFragments__givenNamedFragmentOnUnionWithTypeCase_includeFieldsInTypeCaseFromFragment() async throws {
diff --git a/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift b/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift
index 6b09b91cc..0bff859f8 100644
--- a/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift
+++ b/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift
@@ -945,7 +945,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
     /// the generated models will directly mirror the GraphQL definition.
     public static let none: FieldMerging = []
 
-    private var options: MergedSelections.MergingStrategy
+    var options: MergedSelections.MergingStrategy
 
     private init(_ options: MergedSelections.MergingStrategy) {
       self.options = options
diff --git a/apollo-ios-codegen/Sources/IR/IR+ComputedSelectionSet.swift b/apollo-ios-codegen/Sources/IR/IR+ComputedSelectionSet.swift
index 1196d8130..10384adbd 100644
--- a/apollo-ios-codegen/Sources/IR/IR+ComputedSelectionSet.swift
+++ b/apollo-ios-codegen/Sources/IR/IR+ComputedSelectionSet.swift
@@ -77,20 +77,13 @@ extension ComputedSelectionSet {
     }
 
     func mergeIn(
-      _ selections: EntityTreeScopeSelections,
+      _ selectionsToMerge: EntityTreeScopeSelections,
       from source: MergedSelections.MergedSource,
       with mergeStrategy: MergedSelections.MergingStrategy
     ) {
-      guard source != .init(typeInfo: self.typeInfo, fragment: nil) else {
-        return
-      }
-
-      let fieldsToMerge = self.fieldsToMerge(from: selections.fields.values)
-      let fragmentsToMerge = self.namedFragmentsToMerge(from: selections.namedFragments.values)
-      guard !fieldsToMerge.isEmpty || !fragmentsToMerge.isEmpty else { return }
+      guard self.mergingStrategy.contains(mergeStrategy) else { return }
 
-      mergedSelectionGroups.forEach { groupMergeStrategy, selections in
-        guard groupMergeStrategy.contains(mergeStrategy) else { return }
+      @IsEverTrue var didMergeAnySelections: Bool
 
       selectionsToMerge.fields.values.forEach { didMergeAnySelections = self.mergeIn($0) }
       selectionsToMerge.namedFragments.values.forEach { didMergeAnySelections = self.mergeIn($0) }
@@ -99,23 +92,12 @@ extension ComputedSelectionSet {
         mergedSources.append(source)
       }
     }
-    
-    private func fieldsToMerge<S: Sequence>(
-      from fields: S
-    ) -> [Field] where S.Element == Field {
-      fields.compactMap { field in
-        let keyInScope = field.hashForSelectionSetScope
-        if let directSelections = directSelections,
-           directSelections.fields.keys.contains(keyInScope) {
-          return nil
-        }
-
-        if let entityField = field as? EntityField {
-          return createShallowlyMergedNestedEntityField(from: entityField)
-
-        } else {
-          return field
-        }
+
+    private func mergeIn(_ field: Field) -> Bool {
+      let keyInScope = field.hashForSelectionSetScope
+      if let directSelections = directSelections,
+         directSelections.fields.keys.contains(keyInScope) {
+        return false
       }
 
       let fieldToMerge: Field
@@ -161,7 +143,10 @@ extension ComputedSelectionSet {
       return true
     }
 
-    func addMergedInlineFragment(with condition: ScopeCondition) {
+    func addMergedInlineFragment(
+      with condition: ScopeCondition,      
+      mergeStrategy: MergedSelections.MergingStrategy
+    ) {
       guard typeInfo.isEntityRoot else { return }
 
       if let directSelections = directSelections,
@@ -171,12 +156,7 @@ extension ComputedSelectionSet {
 
       guard !inlineFragments.keys.contains(condition) else { return }
 
-      for (groupMergeStrategy, selections) in mergedSelectionGroups {
-        guard groupMergeStrategy.contains(mergeStrategy) else { continue }
-//        guard !$0.inlineFragments.keys.contains(condition) else { return }
-
-        selections.inlineFragments[condition] = shallowInlineFragment
-      }
+      createShallowlyMergedCompositeInlineFragment(with: condition)
     }
 
     private func createShallowlyMergedCompositeInlineFragment(with condition: ScopeCondition) {
diff --git a/apollo-ios-codegen/Sources/IR/IR+EntitySelectionTree.swift b/apollo-ios-codegen/Sources/IR/IR+EntitySelectionTree.swift
index 11d772c59..bfea46c2e 100644
--- a/apollo-ios-codegen/Sources/IR/IR+EntitySelectionTree.swift
+++ b/apollo-ios-codegen/Sources/IR/IR+EntitySelectionTree.swift
@@ -117,6 +117,7 @@ class EntitySelectionTree {
     let rootTypePath = selections.typeInfo.scopePath.head
     rootNode.mergeSelections(
       matchingScopePath: rootTypePath,
+      entityTypeScopePath: rootTypePath.value.scopePath.head,
       into: selections,
       currentMergeStrategyScope: .ancestors,
       transformingSelections: nil
@@ -205,17 +206,26 @@ class EntitySelectionTree {
       self.child = .selections(entitySelections)
     }
 
+
     func mergeSelections(
-      matchingScopePath scopePathNode: LinkedList<ScopeDescriptor>.Node,
+      matchingScopePath entityPathNode: LinkedList<ScopeDescriptor>.Node,
+      entityTypeScopePath: LinkedList<ScopeCondition>.Node,
       into targetSelections: ComputedSelectionSet.Builder,
       currentMergeStrategyScope: MergedSelections.MergingStrategy,
       transformingSelections: ((Selections) -> Selections)?
     ) {
       switch child {
       case let .entity(entityNode):
-        guard let nextScopePathNode = scopePathNode.next else { return }
+        guard let nextScopePathNode = entityPathNode.next else { return }
+
+        let mergeStrategy = calculateMergeStrategyForNextEntityNode(
+          currentMergeStrategy: currentMergeStrategyScope,
+          currentEntityTypeScopePath: entityTypeScopePath
+        )
+
         entityNode.mergeSelections(
           matchingScopePath: nextScopePathNode,
+          entityTypeScopePath: nextScopePathNode.value.scopePath.head,
           into: targetSelections,
           currentMergeStrategyScope: mergeStrategy,
           transformingSelections: transformingSelections
@@ -238,25 +248,49 @@ class EntitySelectionTree {
         for (condition, node) in scopeConditions {
           guard !node.scope.isDeferred else { continue }
 
-          if scopePathNode.value.matches(condition) {
+          if let entityTypePathNextNode = entityTypeScopePath.next,
+             entityTypePathNextNode.value == condition {
+            // Ancestor
+            node.mergeSelections(
+              matchingScopePath: entityPathNode,
+              entityTypeScopePath: entityTypePathNextNode,
+              into: targetSelections,
+              currentMergeStrategyScope: .ancestors,
+              transformingSelections: transformingSelections
+            )
+
+          } else if entityPathNode.value.matches(condition) {
             node.mergeSelections(
-              matchingScopePath: scopePathNode,
+              matchingScopePath: entityPathNode,
+              entityTypeScopePath: entityTypeScopePath,
               into: targetSelections,
               currentMergeStrategyScope: .siblings,
               transformingSelections: transformingSelections
             )
+
           } else if case .selections = child {
-            targetSelections.addMergedInlineFragment(with: condition)
+            targetSelections.addMergedInlineFragment(
+              with: condition,
+              mergeStrategy: currentMergeStrategyScope
+            )
           }
         }
       }
 
       // Add selections from merged fragments
       for (fragmentSpread, mergedFragmentTree) in mergedFragmentTrees {
+        // If typeInfo is equal, we are merging the fragment's selections into the selection set
+        // that directly selected the fragment. The merge strategy should be just .namedFragments
+        let mergeStrategy: MergedSelections.MergingStrategy =
+        fragmentSpread.typeInfo == targetSelections.typeInfo
+        ? .namedFragments
+        : [currentMergeStrategyScope, .namedFragments]
+
         mergedFragmentTree.rootNode.mergeSelections(
-          matchingScopePath: scopePathNode,
+          matchingScopePath: entityPathNode,
+          entityTypeScopePath: entityTypeScopePath,
           into: targetSelections,
-          currentMergeStrategyScope: .namedFragments,
+          currentMergeStrategyScope: mergeStrategy,
           transformingSelections: {
             Self.addFragment(
               fragmentSpread,
@@ -267,6 +301,27 @@ class EntitySelectionTree {
       }
     }
 
+    private func calculateMergeStrategyForNextEntityNode(
+      currentMergeStrategy: MergedSelections.MergingStrategy,
+      currentEntityTypeScopePath: LinkedList<ScopeCondition>.Node
+    ) -> MergedSelections.MergingStrategy {
+      if currentMergeStrategy.contains(.siblings) {
+        return currentMergeStrategy
+      }
+
+      // If the current entity type scope is at the end of it's path, we are traversing a direct
+      // ancestor of the target selection set. Otherwise, we are traversing siblings.
+      var newMergeStrategy: MergedSelections.MergingStrategy =
+      currentEntityTypeScopePath.next == nil ? .ancestors : .siblings
+
+      // If we are currently traversing through a named fragment, we need to keep that as part of
+      // the merge strategy
+      if currentMergeStrategy.contains(.namedFragments) {
+        newMergeStrategy.insert(.namedFragments)
+      }
+      return newMergeStrategy
+    }
+
     private static func addFragment(
       _ fragment: IR.NamedFragmentSpread,
       toMergedSourcesOf selections: Selections
diff --git a/apollo-ios-codegen/Sources/IR/IR+RootFieldBuilder.swift b/apollo-ios-codegen/Sources/IR/IR+RootFieldBuilder.swift
index 967c46b4c..991bf2592 100644
--- a/apollo-ios-codegen/Sources/IR/IR+RootFieldBuilder.swift
+++ b/apollo-ios-codegen/Sources/IR/IR+RootFieldBuilder.swift
@@ -279,7 +279,7 @@ class RootFieldBuilder {
       return nil
     }
 
-    let type = (parentTypePath.parentType == conditionalSelectionSet.parentType)
+    let type = (parentTypePath.scope.matches(conditionalSelectionSet.parentType))
     ? nil
     : conditionalSelectionSet.parentType