1

I'm attempting to override the query method for a node migration in the migrate_d2d module by adding two where conditions with "OR", and the first one is being added as AND instead of OR for some reason. In this case, there is already one WHERE condition of node type, so I am adding two more, which means I'm trying to change

SELECT blah from {node} WHERE type = 'type1';

to

SELECT blah FROM {node} WHERE type IN ('type1', 'type2', 'type3');

It doesn't look like it is possible to override an existing WHERE condition without completely overriding the entire query method, so it seems that my next best bet is to add the WHERE conditions with OR so that the resulting query is

SELECT blah FROM {node} WHERE (type = 'type1') OR (type = 'type2') OR (type = 'type3');

To accomplish this, based on what I've found searching around (such as here), I used db_or():

$db_or = db_or();
$db_or->condition('type', 'type2')
  ->condition('type', 'type3');
$query->condition($db_or);

However, when I print out the resulting query what I actually get is

SELECT blah FROM {node} WHERE (type = 'type1') AND (type = 'type2') OR (type = 'type3');

and this is verified by the migration results, since the migration doesn't bring across any nodes (which makes sense, since one node can't be of two types).

I also tried it with separate additions to $db_or:

$db_or->condition('type', 'type2')
$db_or->condition('type', 'type3');

and even tried adding as one condition:

$db_or->condition('type', array('type2', 'type3'), 'IN');

but the result is still the same.

What it looks like to me is that no matter how you add a WHERE condition when there already is one, it automatically adds the next one as AND, even if you specify that it should be OR.

So my questions are:

  • Am I adding these conditions to the query object correctly (assuming I want them as OR)?
  • Is there a way to remove the initial condition so that I could just add my own WHERE condition from scratch?
  • Is there a better way to do this?

Thanks.

1

Am I adding these conditions to the query object correctly (assuming I want them as OR)?

Not quite; all components of the the OR need to be added to the condition object, so you need to do something like this:

$query = db_select('node')->fields('node', array('nid'));

$db_or = db_or();
$db_or->condition('type', 'type1')
  ->condition('type', 'type2')
  ->condition('type', 'type3');

$query->condition($db_or);

That'll give you this query string:

SELECT  node.nid AS nid
FROM 
{node} node
WHERE ( (type = :db_condition_placeholder_0) OR (type = :db_condition_placeholder_1) OR (type = :db_condition_placeholder_2) )

Is there a way to remove the initial condition so that I could just add my own WHERE condition from scratch?

Yes you can use SelectQuery::where(), but there's really no need. You can use the above, or preferably...

Is there a better way to do this?

Yes, by using IN as you originally planned:

$query = db_select('node')
  ->fields('node', array('nid'))
  ->condition('type', array('type1', 'type2', 'type3'), 'IN');

That gives:

SELECT  node.nid AS nid
FROM 
{node} node
WHERE  (type IN  (:db_condition_placeholder_0, :db_condition_placeholder_1, :db_condition_placeholder_2)) 

Note that the third parameter of "IN" to condition() isn't strictly necessary, as the DB class automatically assumes "IN" if an array is passed.

  • Are you sure this should work with an existing query object that already has a WHERE condition - type = 'type1' - by the time I get it? I tried the first and last options you suggested, and it just added the three conditions - with the first one being AND, just like before - to the existing one, not replacing it. – wonder95 Dec 13 '13 at 22:59
  • Oh, my bad I didn't pick up on that. Yeah that's a load of fun, here's one I made earlier. The edit to that answer is probably the most interesting bit for your case (looping through the conditions). Is the information in this answer of any use at all? If not I'll get rid of it – Clive Dec 13 '13 at 23:18
  • Speaking for myself, I already understood what you posted above. In regards to the other answer, I see what you're doing by rebuilding the conditions, but I don't see a step to remove the existing condition from the $query object. I can't access $query->where directly since it's protected, and I don't see a method to alter $query->where->conditions in DatabaseCondition. – wonder95 Dec 13 '13 at 23:57

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .