6

I need to retrieve all nodes whose node ID is equal to their tnid, or whose tnid is equal to 0. I am using the following code.

$db_or = db_or();
$db_or->condition('nid','tnid','=');
$db_or->condition('tnid',0,'=');

$query = db_select('node', 'n')
  ->condition($db_or)
  ->fields('n',array('title','nid','tnid','type','language'))
  ->extend('PagerDefault')->limit(50)
  ->condition('type','article','=')
  ->orderBy('created', 'DESC');

It does not work. It returns 0 node IDs, which is not the expected result, since the following code returns a different result.

db_query_range("select * from {node} where (nid = tnid or tnid = 0) and type = 'article' order by created DESC",0,1000);

If I remove $db_or->condition('nid','tnid','='); the first query returns only nodes with tnid equal to 0.

So, why does the first OR condition break my code?

3

You need a where, condition always uses the value literally:

$db_or = db_or();
$db_or->where('nid = tnid');
$db_or->condition('tnid',0,'=');
2

The code you are showing doesn't work because $db_or->condition('nid','tnid','='); is comparing the value of the nid field with the literal string 'tnid', not with the value of the tnid field.
When you need a more complex condition, you need to use SelectQuery::where(), not SelectQuery::condition().

$query = db_select('node', 'n')
  ->fields('n',array('title','nid','tnid','type','language'))
  ->condition('n.type','article','=')
  ->where('n.nid = n.tnid OR n.tnid = 0')
  ->orderBy('n.created', 'DESC')
  ->extend('PagerDefault')
  ->limit(50);

Keep also in mind that, if you don't need to get only the nodes to which the currently logged-in user has access, or your query is not supposed to be altered from other modules, you should use db_query(), which is faster than db_select().

In the case you were interested only to the nodes to which the currently logged-in user has access, the code to use should be the following one.

$query = db_select('node', 'n')
  ->fields('n',array('title','nid','tnid','type','language'))
  ->where('n.nid = n.tnid OR n.tnid = 0')
  ->condition('n.type','article','=')
  ->orderBy('n.created', 'DESC')
  ->addTag('node_access')
  ->extend('PagerDefault')
  ->limit(50);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.