Problem/Motivation

Using a database condition as fourth argument ($condition) of SelectQuery::addJoin() leads to a blank ON clause and a notice: Recoverable fatal error: Method DatabaseCondition::__toString() must return a string value in __toString() (line 1543 of /home/roman/code/www/camp/htdocs/includes/database/select.inc).

Without this feature it is very difficult to add advanced conditions (e.g., EXISTS) to a join.

Proposed resolution

Modify the Database/Query/Select class to check whether $condition is an object when compiling and executing a query, and recursively apply any processing to the object. (Essentially treat join conditions the same way as other possible objects, such as subquery tables.)

Remaining tasks

  • Create tests
  • Get feedback on patch
  • Backport to d7

User interface changes

None

API changes

None

Data model changes

None

Steps to reproduce

Use the following snippet and execute it in a drupal environment (ie. use drush php-script).

$cond = db_and();
$cond->condition('n1.nid', 1);
$cond->condition('n2.nid', 1);

$query = db_select('node', 'n1');
$query->addJoin('INNER', 'node', 'n2', $cond);

print $query->__toString();

Expected result

SELECT 
FROM 
{node} n1
INNER JOIN {node} n2 ON  (n1.nid = :db_condition_placeholder_0) AND (n2.nid = :db_condition_placeholder_1)

Actual result

SELECT 
FROM 
{node} n1
INNER JOIN {node} n2 ON

Additional observations

When the same condition is additionally passed as $query->condition both conditions work!

$cond = db_and();
$cond->condition('n1.nid', 1);
$cond->condition('n2.nid', 1);

$query = db_select('node', 'n1');
$query->addJoin('INNER', 'node', 'n2', $cond);
$query->condition($cond);

print $query->__toString();

leads to

SELECT 
FROM 
{node} n1
INNER JOIN {node} n2 ON  (n1.nid = :db_condition_placeholder_0) AND (n2.nid = :db_condition_placeholder_1) 
WHERE ( (n1.nid = :db_condition_placeholder_0) AND (n2.nid = :db_condition_placeholder_1) )

Comments

damien tournoud’s picture

Version: 7.x-dev » 8.x-dev
Category: Bug report » Feature request

This is actually by design, $conditions is a string, and you have $arguments for replacement.

Moving as a feature request to Drupal 8, because we should actually be able to support this relatively easily.

Nephele’s picture

A duplicate of this issue was created at #2582069: [D7] Unable to use Condition objects with joins, where a d7 patch was provided.

Also, this issue is an obstacle for fixing the major bug #1349080: node_access filters out accessible nodes when node is left joined -- where a DatabaseCondition object needs to be added appended to a join. Attempting to fix that bug without this feature requires somewhat hacky code, in particular manually naming the argument placeholders, which has been error prone.

Nephele’s picture

Status: Active » Needs review
Issue tags: +Needs tests
StatusFileSize
new2.87 KB
new2.78 KB

The patch provided in #2582069: [D7] Unable to use Condition objects with joins didn't work for me, so I put together a more comprehensive d7 patch that did work. I tried to find all the places in the code where extra processing would be needed.

I then ported the patch into d8, since the relevant code hasn't changed too dramatically. Although I can't work in d8 yet, hopefully the patch can at least serve as a starting point for someone else.

The last submitted patch, 3: join_condition_as_object_d7-do-not-test-2275519-3.patch, failed testing.

Nephele’s picture

Title: Unable to use DatabaseCondition with joins » Unable to use Condition objects with joins
Issue tags: -Needs tests
StatusFileSize
new5.15 KB

I'm uploading new patch providing the needed tests. I've added a test that redoes a standard join test but uses an object for the condition; a second test is an adaptation of the scenario from the issue summary.

Also note that I'm currently including this patch in patches submitted to #1349080: node_access filters out accessible nodes when node is left joined, since it's needed there and that's a higher-priority issue.

Nephele’s picture

Issue summary: View changes
Issue tags: +Needs backport to D7

Status: Needs review » Needs work

The last submitted patch, 5: join_condition_as_object_d8-2275519-5.patch, failed testing.

Nephele’s picture

Status: Needs work » Needs review
StatusFileSize
new5.16 KB

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.

daffie’s picture

StatusFileSize
new2.4 KB
new5.17 KB

The SelectComplexTest has been moved. So I did a reroll.
I have added an extra patch with only the tests in it. And that patch should fail. So we are sure that the main patch will fix the problem.

The last submitted patch, 10: 2275519-10-tests-only-should-fail.patch, failed testing.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

I did not change the code, with the exception for the moved SelectComplexTests and a double space that I changed to a single space.

The patch looks good to me.
There is no bc api break.
This patch seems to be needed by #1349080: node_access filters out accessible nodes when node is left joined and that one is D8 triaged major.
The patch fixes the problem from the issue summery.
It gets a RTBC from me.

alexpott’s picture

As this is a precursor to fixing #1349080: node_access filters out accessible nodes when node is left joined and it is an API widening rather than restricting I think we should commit this to 8.1.x - ping to @catch for a second opinion.

catch’s picture

This looks harmless to me for 8.1.x, not even adding a method.

alexpott’s picture

Status: Reviewed & tested by the community » Patch (to be ported)

Committed b68e5ba and pushed to 8.1.x and 8.2.x. Thanks!

Committed to 8.1.x since this is a precursor to fixing #1349080: node_access filters out accessible nodes when node is left joined

If we're going to port this to Drupal 7.x then we need to open a new issue. However since that has not been done yet setting status to 'Pathch (to be ported)'. Once the 7.x issue exists this one should be closed so @daffie and @Nephele get the credit they deserve.

  • alexpott committed b6c1866 on 8.2.x
    Issue #2275519 by Nephele, daffie: Unable to use Condition objects with...

  • alexpott committed b68e5ba on 8.1.x
    Issue #2275519 by Nephele, daffie: Unable to use Condition objects with...
daffie’s picture

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

Lets move it to Drupal 7.

  • alexpott committed b6c1866 on 8.3.x
    Issue #2275519 by Nephele, daffie: Unable to use Condition objects with...

  • alexpott committed b6c1866 on 8.3.x
    Issue #2275519 by Nephele, daffie: Unable to use Condition objects with...

  • alexpott committed b6c1866 on 8.4.x
    Issue #2275519 by Nephele, daffie: Unable to use Condition objects with...

  • alexpott committed b6c1866 on 8.4.x
    Issue #2275519 by Nephele, daffie: Unable to use Condition objects with...
plach’s picture

Version: 7.x-dev » 8.2.x-dev
Status: Patch (to be ported) » Fixed
Issue tags: -Needs backport to D7

This D7 issue was closed as duplicate: #2582069: [D7] Unable to use Condition objects with joins.

I guess we could revive it.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.