Problem/Motivation
With reference to #1222150: dpq() only works for SELECT and INSERT queries (a devel module issue), an outstanding issue with the output of its dpq()
function on \Drupal::database()->update()
queries is that the update field placeholders are still rendered as the placeholder name, not the value.
Steps to reproduce
Proposed resolution
Implement arguments() in the Update.php to support update field placeholders.
Remaining tasks
Review
Commit
User interface changes
API changes
Data model changes
Release notes snippet
Original report by [jweowu]
With reference to #1222150: dpq() only works for SELECT and INSERT queries (a devel module issue), an outstanding issue with the output of its dpq()
function on db_update()
queries is that the field placeholders are still rendered as the placeholder name, not the value.
e.g. dpq(db_update('node')->fields(array('uid' => 1))->condition('nid', 50));
produces:
UPDATE {node} SET uid=:db_update_placeholder_0
WHERE (nid = '50')
With arguments()
returning:
Array
(
[:db_condition_placeholder_0] => 50
)
This is because UpdateQuery::arguments()
returns the db_condition_placeholder
values, but does not return the db_update_placeholder
values.
The reason the query still works is that UpdateQuery::execute()
deals with these field placeholders separately; however it access them directly, and no public API analogous to arguments()
is provided, so the likes of devel's dpq()
have no way of obtaining them.
Now the docstring for arguments()
is "Gets a complete list of all values to insert into the prepared statement.", and that's obviously not the case here, but given how the execute method works, I can't tell whether it's the docstring or the code which is incorrect. I can't actually see a reason not to include the field placeholders, though; because...
Unless I'm mis-reading my grep results, I don't think anything in core calls UpdateQuery::arguments()
at all? SelectQuery::arguments()
is certainly used, and $condition->arguments()
is called directly in lots of places, but nothing in my code base save for devel's dpq()
seems like it would ever to call this method on an update query.
Experimentally (using code from UpdateQuery::__toString()
), if instead of only returning $this->condition->arguments()
, I modify UpdateQuery::arguments()
like so:
/**
* Implements QueryConditionInterface::arguments().
*/
public function arguments() {
$args = $this->condition->arguments();
$fields = $this->fields;
$max_placeholder = 0;
foreach ($fields as $field => $value) {
$args[':db_update_placeholder_' . ($max_placeholder++)] = $value;
}
return $args;
}
Then arguments()
returns:
Array
(
[:db_condition_placeholder_0] => 50
[:db_update_placeholder_0] => 1
)
and dpq()
gives me:
UPDATE {node} SET uid='1'
WHERE (nid = '50')
So that seems like a viable solution?