Greetings,

We have found an issue in substituting parameters in placeholders (Dtabase API) when using nested SQL queries.

Here is a code that we have written:

  $sub_query = db_select('users', 'u');
  $sub_query->fields('u', array('uid', 'name'));
  $sub_query->condition('u.uid', '5', '>');
  dpr((string)$sub_query);

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

  $query->condition('n.type', 'page', '=');
  dpr((string)$query);

  $query->addJoin('LEFT',$sub_query, 'u', "n.uid = u.uid");
  dpr((string)$query);

And here is a debug output that dpr() functions generate here:

SELECT u.uid AS uid, u.name AS name FROM {users} u WHERE  (u.uid > :db_condition_placeholder_0) 

SELECT n.nid AS nid, n.title AS title FROM {node} n WHERE  (n.type = :db_condition_placeholder_0) 

SELECT n.nid AS nid, n.title AS title FROM {node} n
  LEFT JOIN (SELECT u.uid AS uid, u.name AS name
  FROM {users} u WHERE  (u.uid > :db_condition_placeholder_0) ) u ON n.uid = u.uid
WHERE  (n.type = :db_condition_placeholder_0) 

As you can see here, the same value is passed into two different places because there are the same placeholder which is a big problem because the first parameter is inserted into several places which produces wrong SQL query.

We propose a patch which is a "quick solution". Please review it. Is there a way how we can fix this more correctly?

Thank you.

CommentFileSizeAuthor
select.inc_.patch572 bytesardas

Comments

damien tournoud’s picture

Status: Active » Postponed (maintainer needs more info)

Please try with Drupal 7.10. Some placeholder replacement issues where fixed since 7.7.

damien tournoud’s picture

Category: bug » support
Priority: Critical » Normal

Tested in 7.10. Your particular example doesn't work because you are forcing several parts of the query to be compiled independently by the (string) $query construct. But the query itself works:

  $sub_query = db_select('users', 'u');
  $sub_query->fields('u', array('uid', 'name'));
  $sub_query->condition('u.uid', '5', '>');

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

  $query->condition('n.type', 'page', '=');

  $query->addJoin('LEFT',$sub_query, 'u', "n.uid = u.uid");
  dpr((string)$query);

Returns:

SELECT n.nid AS nid, n.title AS title
FROM 
{node} n
LEFT JOIN (SELECT u.uid AS uid, u.name AS name
FROM 
{users} u
WHERE  (u.uid > :db_condition_placeholder_1) ) u ON n.uid = u.uid
WHERE  (n.type = :db_condition_placeholder_0) 

... as expected.

dddave’s picture

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

Closing old, stale issues. Re-open if your problem persists.