Query order when using orCondition in QueryInterface

Created on 3 December 2024, 19 days ago

Problem/Motivation

I was attempting to query some content types using the query interface (in graphql), I wanted them returning in a particular order of langcode (eg fr then en), the by created date. So the final result should return the french nodes, then the english nodes in created date order.
Digging into this, i found that the sql being produced is somewhat wrong, it seems like there is a disconnect somewhere between the select and where when a sort is being applied.
in my example,

    $storage = $this->entityTypeManager->getStorage('node');
    $entityType = $storage->getEntityType();
    $query = $storage->getQuery()
      ->currentRevision()
      ->accessCheck()
      ->condition('status', Node::PUBLISHED);

    $query->condition($entityType->getKey('bundle'), 'resource');

    if (!empty($langcode)) {
      if ($langcode !== "EN") {
        $langConditions = $query->orConditionGroup()
          ->condition('langcode', strtolower('fr')) //hard coded for debug's sake
          ->condition('langcode', strtolower("en"));
        $query->condition($langConditions);
      } else {
        $query->condition('langcode', strtolower($langcode));
      }
    }

    $query->sort('langcode', 'DESC');
    $query->sort('created', 'DESC');
    $query->range($offset, $limit);
    $metadata->addCacheTags($entityType->getListCacheTags());
    $metadata->addCacheContexts($entityType->getListCacheContexts());

    return new QueryResourceConnection($query);

Gets a generated sql output of

SELECT
    `base_table`.`vid` AS `vid`,
    `base_table`.`nid` AS `nid`,
    MAX(node_field_data_3.langcode) AS `expression`,
    MAX(node_field_data_3.created) AS `expression_2`
FROM
    `node` `base_table`
INNER JOIN `node_field_data` `node_field_data` ON
    `node_field_data`.`nid` = `base_table`.`nid`
LEFT JOIN `node_field_data` `node_field_data_2` ON
    `node_field_data_2`.`nid` = `base_table`.`nid`
INNER JOIN `node__field_resource_type` `node__field_resource_type` ON
    `node__field_resource_type`.`entity_id` = `base_table`.`nid`
LEFT OUTER JOIN `taxonomy_term_data` `taxonomy_term_data` ON
    `taxonomy_term_data`.`tid` = `node__field_resource_type`.`field_resource_type_target_id`
INNER JOIN `taxonomy_term_field_data` `taxonomy_term_field_data` ON
    `taxonomy_term_field_data`.`tid` = `taxonomy_term_data`.`tid`
LEFT JOIN `node_field_data` `node_field_data_3` ON
    `node_field_data_3`.`nid` = `base_table`.`nid`
WHERE
    (`node_field_data`.`status` = '1') AND
    (`node_field_data`.`type` = 'resource') AND
    (
        (`node_field_data_2`.`langcode` = 'fr') OR
        (`node_field_data_2`.`langcode` = 'en')
    ) AND
    (`taxonomy_term_field_data`.`name` LIKE 'My Resource' ESCAPE '\\')
GROUP BY
    `base_table`.`vid`,
    `base_table`.`nid`
ORDER BY
	`expression` DESC,
	`expression_2` DESC

the issue here being that node_field_data_2 and node_field_data_3 are joins, but the MAX() is being done on node_field_data_3 and not 2, which produces the incorrect results. like this.. https://pastebin.com/QjavJWxE

Steps to reproduce

I think the easiest would be to create multiple nodes in a few different languages, and then run the query's to see if you can get them sorting in the correct order. I probably need to make a more concrete small example however.

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Active

Version

10.3

Component

database system

Created by

🇳🇿New Zealand atowl

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024