This may or may not be worth fixing -- but I figured it was worth noting here in case somebody has the same problem.

When you use a union on a query for a SQL migration, the following error is generated: "SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns". For example:

$query1 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query2 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query1->union($query2, "ALL");

$this->source = new MigrateSourceSQL($query1);

It would appear that columns are being added by the Migration Module to support what it is trying to do, but unfortunately drupal only adds the columns to the first statement in the union, and not the others. That leads to select statements with a different number of columns, and therefore a sql error.

The fix I came up with on my side was to wrap the unions up into a subquery, so added fields apply to the entire query unit:

$query1 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query2 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query1->union($query2, "ALL");

$queryx = db_select($query1,'x'); // wraps the 2 unions into 1 subselected table 'x'

$this->source = new MigrateSourceSQL($queryx);

Easy enough, but this probably should be done within the migrate module itself.

Comments

mikeryan’s picture

Seems to me we tried the subquery wrap at some point, for some other use case, and had trouble with it, but we can revisit it.

Another work-around would be setting map_joinable => FALSE in the MigrateSourceSQL options.

arscan’s picture

Good to know -- I didn't know about map_joinable. Yeah, I can imagine that doing the subquery wrapping might cause other issues.

hawthorne’s picture

I'm seeing the same behaviour as arscan. I've tried setting map_joinable => FALSE but this had no effect. I have to rely on the sub-query wrapper to get the migration to work.

mikeryan’s picture

Component: Code » Documentation
Category: bug » task
Status: Active » Fixed

Thinking about it a bit, I'm reluctant to mess around with the query construction code (which is hard enough to understand as it is) when the use case is rare (union queries when map_joinable == TRUE) and easily worked around in the source query. I've added a page to the documentation explaining the situation and work-around: /node/1712458.

Thanks.

Status: Fixed » Closed (fixed)

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