Skip to content

Conversation

@artem-schander
Copy link
Contributor

Problem

AliasArguments::getAliasesInFields() has exponential time complexity when processing input types with circular references, causing severe performance degradation in mutations.

Root Cause: The method traverses ALL possible fields in the type schema, not just fields present in the request data. With circular type references (e.g., PageInputSectionInput) and a depth limit calculated from request data, this creates exponential traversal.

Evidence

Real-world example:

  • Before fix: Mutation taking 11+ seconds
  • After fix: Same mutation taking ~150ms
  • Improvement: 98.7% reduction in execution time

Debug logging revealed:

  • 6 million recursive calls before timeout
  • Depth reaching 12-13 levels with circular paths like: newsletter.page.reference.page.redirect.page.translationOrigin.translationOrigin.translations.*.redirect.page...

Solution

Only traverse fields that exist in the actual request data. This prevents exponential explosion while preserving full alias functionality.

Changes

Modified signature:

protected function getAliasesInFields(array $fields, ?array $requestData = null, string $prefix = ''): array

Key addition:

// Skip fields not present in actual request data
if ($requestData !== null && !array_key_exists($name, $requestData)) {
    continue;
}

Recursive calls now pass data:

$pathAndAlias = $pathAndAlias + $this->getAliasesInFields(
    $type->getFields(),
    $fieldData,  // Pass actual data instead of all possible fields
    $newPrefix
);

Testing

  • ✅ Tested with deeply nested input types (11 levels)
  • ✅ Tested with circular type references (PageInput ↔ SectionInput)
  • ✅ Verified alias functionality preserved (deprecated field name mapping)
  • ✅ Verified legitimate nested types work (e.g., Page->translations array)
  • ✅ 124 production mutations tested successfully

Impact

This fix affects any application with:

  • Circular type references in input types (common in CMS/e-commerce)
  • Deeply nested input data
  • Alias usage for backward compatibility

Backward Compatibility

✅ Fully backward compatible - the fix only changes the traversal strategy, not the API or functionality.

…references

**Problem:**
`getAliasesInFields()` traverses ALL possible fields in the type schema, not just fields present in the request data. With circular type references (e.g., PageInput ↔ SectionInput) and a depth limit calculated from request data, this causes exponential traversal.

**Evidence:**
- Mutations taking 11+ seconds instead of milliseconds
- Logging showed 6 million recursive calls before timeout
- Depth reaching 12-13 levels with circular paths

**Solution:**
Only traverse fields that exist in the actual request data. This prevents exponential explosion while preserving full alias functionality.

**Performance:**
- Before: 11+ seconds per mutation
- After: ~150ms per mutation
- Improvement: 98.7% reduction

**Testing:**
- Tested with deeply nested input types (11 levels)
- Tested with circular type references
- Verified alias functionality preserved (deprecated field name mapping)
- Verified legitimate nested types work (e.g., Page->translations array)
- Add proper type annotation for $requestData parameter
- Fix code style to match project standards
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant