-
Notifications
You must be signed in to change notification settings - Fork 11.7k
Description
- Laravel Version: v5.2.45
- PHP Version: 5.6
- Database Driver & Version: MySQL
Description:
I've noticed that the Query Parameter Binding gets confused with complex raw queries. I'll give an example of the horrible query (an INSERT INTO with unneeded sub selects). The parameter substution is getting confused, and mangling the query. The database throws an exception, but the error reported does NOT show the real query sent to the DB engine.
Inside QueryException, this reports the error:
protected function formatMessage($sql, $bindings, $previous)
{
return $previous->getMessage().' (SQL: '.str_replace_array('\?', $bindings, $sql).')';
}
However, this is doing a very simple string replace on the bindings. The SQL outputted in this error is actually fine and runs. However, the actual binding parameter substitution is more complex than this simple replace. My skills aren't good enough to follow exactly what it was doing, but it had a SQL Grammer somewhere in there.
So, is it possible to change the SQL in the error messages to be the actual SQL sent?
Thanks
Jon
Steps To Reproduce:
Apologies that this query is ugly!
This query fails with the error:
SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1
$raw_query = <<<"BLOCK_SQL_PENDING_EDITION_PAGES"
INSERT INTO pages(edition_id, code, title, files, body, indexed, page_updated_at, processed_at)
SELECT *
FROM (
SELECT ? as edition_id, code, title, page_files as files, body,
index_complete as indexed, page_updated_at, created_at as processed_at
FROM (
select
pending_pages.*,
pending_editions.code as edition_code
FROM pending_pages
INNER JOIN pending_editions ON pending_pages.pending_edition_id = pending_editions.id
order by pending_pages.page_updated_at desc, pending_pages.updated_at desc
) x
GROUP BY code, edition_code
ORDER BY code
) y
BLOCK_SQL_PENDING_EDITION_PAGES;
$bindings = [8];
$success = DB::insert($raw_query, $bindings);
When I see the error in the log, the query is perfectly valid. If I replace the above code and remove the binding and replace the ? with an 8 in the query, it works fine too. The problem is that the whole "? as edition_id" part is somehow being removed from the query by the parameter binding. If I just do the SELECT part I can see the edition_id column simply isn't coming back. However, the SQL I see in the error log looks perfect so for the reason I mentioned above.
So, in a nutshell, it would be lovely if the error message reported the actual SQL, not the simple version which theortically should be the same but sometimes isn't in odd circumstances?
Thanks!