Skip to content

[3.x]: GraphQL collision when making two queries in different parameters #12410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
eduardoalonsoalbella opened this issue Dec 1, 2022 · 2 comments · Fixed by #12494
Closed
Assignees

Comments

@eduardoalonsoalbella
Copy link

eduardoalonsoalbella commented Dec 1, 2022

What happened?

Description

If I make a query over two parameters (featured and branches), one call takes over the other one:

Steps to reproduce

  1. Create a entry query with
featured: children(hasDescendants: false) {
   title
}
branches: children(hasDescendants: true) {
   title
}

The results of both results will be the same and it should not

Expected behavior

Both results should be different

Actual behavior

Craft CMS version

3.7.61

PHP version

8.1

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions

@brianjhanson
Copy link
Contributor

Hey @eduardoalonsoalbella! I’ve been looking into this and just wanted to provide an update.

This is a side effect of how we eager load elements when handling a graphql request. To make things as performant as possible, when a query comes in, we traverse and parse the query and look for any and all elements that we can eager load. Eager loadable elements are thrown into an eager loading plan to be executed when the query is run.

Critically, for a handful of fields we don’t differentiate the eager loading plans based on the alias. Tracking down the original reason for that is something I need to dig into further, but in the meantime the EVENT_REGISTER_GQL_EAGERLOADABLE_FIELDS event will let you enable the aliases for children if you want, which seems to resolve the issue for me.

use craft\events\RegisterGqlEagerLoadableFields;
use craft\fields\BaseRelationField;
use craft\gql\ElementQueryConditionBuilder;

Event::on(
    ElementQueryConditionBuilder::class,
    ElementQueryConditionBuilder::EVENT_REGISTER_GQL_EAGERLOADABLE_FIELDS,
    function(RegisterGqlEagerLoadableFields $event) {
        $event->fieldList['children'] = [BaseRelationField::class, 'canBeAliased' => true];
    }
);

I need to ask around internally before I know if that’s a change we can or should implement for everyone, but hopefully, it will get you over this issue for now. It will likely have performance implications, but it’s hard to know how severe they’ll be since that will depend on your particular project.

@brandonkelly
Copy link
Member

Craft 3.7.63 and 4.3.6 are out with #12494 merged in, allowing children fields to be aliased.

brianjhanson added a commit that referenced this issue Jan 9, 2023
It looks like this was an oversight initially. Aliasing a field causes
issues in [`resolveElementTypeName`](https://github.com/craftcms/cms/blob/2ffd31f504686dc28dbbe0f39a7fb84e6d012906/src/gql/base/InterfaceType.php#L37-L47) when the argument isn't an element.
This occurs when there's special logic within
[`setEagerLoadedElements`](https://github.com/craftcms/cms/blob/12651d1d61d8cdb10c27bfc140b556cdb13865fe/src/base/ElementInterface.php#L1311) handling special eager loads. However, this kind of logic doesn't exist for the `children` field, so it should be safe to eager load

Fixes #12410
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants