29

I have a module which is misbehaving. An EFQ is returing unexpected results, but I can't see why just by looking at the code. Is there a dpq() equivalent for EFQs? Other ways of debugging them?

2
  • Similar question: drupal.stackexchange.com/questions/33473/…. Can you cast the query object to a string to inspect it to see if the SQL gives any clues?
    – Clive
    Commented Jul 10, 2012 at 8:43
  • 1
    Great suggestions, however: Recoverable fatal error: Object of class EntityFieldQuery could not be converted to string :(
    – Letharion
    Commented Jul 10, 2012 at 8:50

6 Answers 6

38

It's a wee bit of a hack, but you could add a tag to any EntityFieldQuery you're interested in printing the query for, then implement hook_query_alter() to intercept it when it's a standard SelectQuery, then cast it to string for debugging:

function MYMODULE_query_alter($query) {
  if ($query->hasTag('efq_debug')) {
    dpm((string)$query);
  }
}

$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node')
  ->addTag('efq_debug')
  ->execute();

It's a bit of a hack but does the trick. The output for the above is:

SELECT node.nid AS entity_id, node.vid AS revision_id, node.type AS bundle, :entity_type     
AS entity_type
FROM {node} node

Presumably this will also only work when using MySQL as the field storage system.

4
  • Sounds great in theory, but what about the comments on the question? EFQ doesn't implement __toString()?
    – Letharion
    Commented Jul 20, 2012 at 11:19
  • 4
    By the time it gets to hook_query_alter() the query isn't an EntityFieldQuery any more, it's been converted down to a standard db_select(), so __tostring() works great :) Since working this out I've been using it quite a lot and it works pretty well
    – Clive
    Commented Jul 20, 2012 at 12:11
  • Confirmed that casting to string works once the query gets to hook_query_alter().
    – jhedstrom
    Commented Aug 27, 2012 at 21:09
  • To see the query argumentos (":entity_type" in the above example) you can use dpm($query->arguments());
    – sanzante
    Commented Nov 23, 2014 at 14:09
15

Rather than rolling your own hook_query_alter() you can let Devel module do the heavy lifting for you by adding the debug tag:

$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
  ->addTag('debug')
  ->execute();

This will print the query to screen, just like dpq() would.

0
4

Adding to the @Clive answer, which generally prints the query with the placeholder not along with the value. To print the value with the query use the following code under the hook_query_alter.

function hook_query_alter($query) {
  if ($query->hasTag('debug')) {
    $sql = (string)$query;
    $connection = Database::getConnection();
    foreach ((array) $query->arguments() as $key => $val) {
      $quoted[$key] = $connection->quote($val);
    }
    $sql = strtr($sql, $quoted);
    dpm($sql);
  }
}


$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
  ->addTag('debug');
  ->execute();

It is not good practice to install a module for the few lines of code. That is why I opted for the aforementioned solution.

2

If you download the dev version of Nice DPQ (or anything => 1.1), you can simply do:

$user_query = new EntityFieldQuery();
$user_query->entityCondition('entity_type','user');
$user_query->addTag('nicedpq');
$user_result = $user_query->execute();

and you will get the query dpm'ed nicely :). The important part in the code above is addTag('nicedpq') - that triggers the dpm().

1
  • nice alternate workaround to devel. Couldn't find that module directly over DO because they removed related module block which was there earliar.
    – kiranking
    Commented Oct 13, 2015 at 8:44
1

You can try to debug it via XDebug. Once installed, do xdebug_start_trace() before the code, and xdebug_stop_trace() after that, then you'll have clear trace log what was executed and where.

Also you can enable query logger in MySQL configuration.

The other method is to use strace/truss/dtruss like debuggers.

Example using dtruss:

  • all queries

    sudo dtruss -t read -n mysqld
    
  • specific queries

    sudo dtruss -t read -n mysqld 2>&1 | grep SPECIFIC_TEXT
    

Note that dtruss is just a script which uses DTrace, so you may consider a direct implementation of PHP DTrace static probes or DTracing MySQL by writing your own script.

Read more: Advanced debugging of Drupal core using the command line (strace & tcpdump)

0

Add this function to your module. Then, add the tag debug to any EFQ. Requires Devel module to be enabled in order to print the query.

/**
 * Implements hook_query_TAG_alter().
 *
 * Add the tag 'debug' to any EFQ and this will print the query to the messages.
 *
 * @param \QueryAlterableInterface $query
 */
function MYMODULE_query_debug_alter(QueryAlterableInterface $query) {
  if (function_exists('dpq') && !$query->hasTag('debug-semaphore')) {
    $query->addTag('debug-semaphore');
    dpq($query);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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