I have an EntityFieldQuery that uses tableSort() including a header for an integer type field. Before any click sorting, the table displays fine, inclduing some nodes which have no value for the integer field. When I click to sort by the integer field, nodes without a value are excluded in the new results.

This does NOT occur for text fields when there is no string.

Here's an example of my code. The integer field is 'field_year_implemented':

  $header = array(
    'title' => array('field' => 'title', 'type' => 'property', 'data' => 'Program Name', 'sort' => 'asc', 'specifier' => 'title'),
    'field_year_implemented' => array('field' => 'field_year_implemented', 'type' => 'field', 'data' => 'Year', 'specifier' => array('field' => 'field_year_implemented', 'column' => 'value')),
  );
    $query = new EntityFieldQuery();
    $query->entityCondition('entity_type', 'node')
      ->entityCondition('bundle', $nodetype)
      ->fieldCondition('field_nodereference', 'nid', $id)
      ->tableSort($header)
      ;

    $result = $query->execute();

Comments

matt2000’s picture

Title: EntityFieldQuery::tableSort fails sometimes for empty fields » EntityFieldQuery::tableSort fails for empty interger field

The $header/$headers typo above is not relevant. I just pasted the important parts in here. In the real code, the headers are passed to the $query with the correct name. edit: Typo fixed.

matt2000’s picture

Title: EntityFieldQuery::tableSort fails for empty interger field » EntityFieldQuery::tableSort fails sometimes for empty fields

Correction:

This problem CAN be replicated with a text field instead of an integer. I thought it was the integer field because I use the same EFQ building function for other tables with only text fields, and don't experience this issue.

I'll keep digging, but any help would be appreciated....

matt2000’s picture

More findings:

It works when there is a row for the nodes in field table in the database, even if there's nothing in the value column.

But if the node does not have a row in field table for the field being sorted, it will not be included in the EFQ results.

(Feeds module will apparently create rows with no value for empty fields being imported, so I have a number of them.)

bojanz’s picture

This is normal behavior since EFQ uses an INNER JOIN, if there are no matching rows in the field table, no row produced.
(a sort adds the join if it's not there)
Not sure if a LEFT JOIN could be used instead (what the consequences would be). chx?

chx’s picture

Wait, how can be there no row in the field table?

bojanz’s picture

I just created a node and didn't fill any fields, got no rows created in the field tables.

leksat’s picture

If I sort a query by a text field, only nodes with non empty field are present in result.
Is there some workaround?

leksat’s picture

Title: EntityFieldQuery::tableSort fails for empty interger field » EntityFieldQuery::tableSort fails sometimes for empty fields
Version: 7.0 » 7.x-dev
Status: Active » Needs review
StatusFileSize
new926 bytes

I didn't find a workaround.
Maybe leftJoin is appropriate solution?
(field_sql_storage_field_storage_query())

leksat’s picture

Can someone explain why innerJoin is the default join method?

matt2000’s picture

Ran into this issue again today, because the following code does not behave as expected:

$query = new EntityFieldQuery();
$query->entityCondition('entity_type','node')
  ->entityCondition('bundle','my_node')
  //...more conditions
  ->fieldCondition('some_field', 'value', NULL, 'IS NULL')
;

My hope was that this would allow me to retrieve records where 'some_field' is not set. I've not yet figured out any other way to do this, (but I have tried very hard yet) but I believe switching to a LEFT JOIN would allow it. So I'd like to renew Leksat's request: Is there a reason for not using LEFT JOIN as the default?

matt2000’s picture

Title: EntityFieldQuery::tableSort fails sometimes for empty fields » There's no way to LEFT JOIN with an EntityFieldQuery.

Re-titling to draw attention to the real problem.

chx’s picture

Version: 7.x-dev » 8.x-dev
Status: Needs review » Closed (duplicate)
matt2000’s picture

Status: Closed (duplicate) » Needs review
StatusFileSize
new3.2 KB

Really? By design a developer should NEVER be permitted to designate a condition that should be LEFT JOIN'd rather than using the default inner JOIN? What if it's been determined that a single LEFT JOIN'd query is faster than the two separate queries that would be required otherwise?

Would it really be so heinous to add to EntityFieldQuery a property for specifying which tables should be LEFT JOIN'd (or abstractly, which fields should be included with NULL values) which can be read by hook_field_storage_query()?

Demonstration of concept patch attached.

matt2000’s picture

Category: bug » feature
chx’s picture

chx’s picture

matt2000’s picture

Status: Closed (duplicate) » Needs work

That issue is about Ordering specifically. This issue is about allowing **optional** LEFT JOINS for other purposes regardless of ordering, and as per #1611438-19: fieldOrderBy filters out results with empty field values the performance issues is not tied primarily to what kind of join you use, but rather what table comes first.

As for benchmarking INNER vs. LEFT, I tested several different fields myself, and the worst penalty I saw for LEFT JOIN rather than INNER JOIN was .03 sec for ~130k nodes. Most of my tests had a difference of .01 sec. One table with very few rows was faster as a LEFT JOIN. So it seems that performance is tied to the specific data, which is why the option to use a LEFT JOIN for specific tables should be provided to the developer.

This is a DX feature request, because using a LEFT JOIN is already possible via hook_query_tag_alter(), but it makes for over-complicated code that is difficult to read and maintain.

So I'd like to request that my 2-line code patch (most of it is doc) in #13 actually be reviewed on it's merits before this issue is closed without consideration. I would expect there might be a more elegant way to implement the idea, but I'm not yet convinced the idea is a bad one.

Or if an alternate solution can be proposed for allowing developers to include entities with NULL values in a single dynamic query, I will happily withdraw my proposed solution. Of course, that solution should be just as easy to implement, and have reproducible performance tests if it claims to perform better.

chx’s picture

Status: Needs work » Needs review

Let's put it to CNR then.

j0rd’s picture

I'm particularly interested in this feature for "ORing" over multiple fields in my entity. This would require a left join. If there's another way to do this, please let me know.

Example use case:

  $query = new EntityFieldQuery;
  $result = $query
    ->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'event')
    ->propertyCondition('status', 1)
    ->fieldCondition('field_teachers', 'target_id', $relation_node->nid)
    ->OR() /* Not sure what the syntax would be */
    ->fieldCondition('field_organizer', 'target_id', $relation_node->nid)
    ->execute();

I've read phase2's post regarding "ORs" with EntityFieldQuery, but it's hackish and would become difficult to maintain over time. They do demonstrate how it could be done though:
http://www.phase2technology.com/blog/or-queries-with-entityfieldquery/

As for performance. Depends on your storage engine. I assume this would be very fast with MongoDB as there would be no joins involved. At least I assume, never looked at MongoDB storage engine.

Personally I'm interested in having this functionality for code maintenance and not SQL performance, as I could simply do this with a normal gross SQL query which grows and grows and grows with every field I need to check against. Which is why entityfieldquery is here to help us isn't it?

amateescu’s picture

Component: field system » entity system
amateescu’s picture

Issue summary: View changes

fixed typo

Status: Needs review » Needs work

The last submitted patch, 13: 1662942-EFQ-doesnt-allow-left-join.patch, failed testing.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Issue summary: View changes
Status: Needs work » Postponed (maintainer needs more info)
Issue tags: +stale-issue-cleanup

Thank you for sharing your idea for improving Drupal.

We are working to decide if this proposal meets the Criteria for evaluating proposed changes. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or there is no community support. Your thoughts on this will allow a decision to be made.

Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.

Thanks!

smustgrave’s picture

Wanted to bump 1 more time before closing.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

smustgrave’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

Since there's been no follow up and was a feature request going to close out. Can always be re-opened though! Am assigning credit for the work 14 years ago.

Thanks

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.