[10.x] In MySQL, harvest last insert ID immediately after query is executed #52390
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I work on an app whose database is MySQL, and its
sql_mode
is set to''
; the primary impact of this is that "strict mode" is off, and too long/large data is truncated and inserted, instead of rejected. As you can imagine, this leads to problems later on, when we try to query that truncated data and we're missing pieces, or an integer/decimal is set to a max/min value.In an attempt to log the warnings that are emitted from the DB in these scenarios, I set up a listener for
QueryExecuted
, and calledSHOW WARNINGS
to get the list of warnings, and report them to our error reporting system. This allows us to see the warnings, in the context of the executing query and the PHP stack trace, without crashing our app. We hoped to work these warnings down to an acceptable level, then turn on strict mode.However, I discovered that executing any queries during the
QueryExecuted
event causes PDO to drop the last insert ID, and so all tests that insert any data broke, due to getting'0'
back from PDO, rather than the actually generated ID. After some Googling, I found this PHP bug report, that claims this is not a bug, but the intended behavior:In order to still fetch the last insert ID, but also be able to execute queries during the
QueryExecuted
event, I've modified the MySQL specific Processor and Connection classes. The test added fails without the changes applies.It is possible to accomplish this without framework changes, because we can extend the MySQL classes, and register a customer driver via
\Illuminate\Database\Connection::resolverFor()
and\Illuminate\Database\Connection::getResolver()
. In fact, we will probably be doing that until this is merged and we can update to the version its released with. However, I feel it is beneficial to add it to the framework anyway. The other PDO compatible drivers don't seem to have this problem. I did some local testing with PostgreSQL, and it behaved fine without any additional changes: I could execute queries duringQueryExecuted
and the last insert ID was still harvested correctly.I acknowledge that my use case is niche, but this should help any future devs who happen to need to execute queries during that event.
I'm targeting 10.x because it's just barely still in "bug support" dates, and this does seem like a bug. I'm happy to rebase to 11.x if it's considered a minor feature, or 12.x, due to the change in signature to
\Illuminate\Database\MySqlConnection::insert()
. I think that change would affect devs who extendMySQLConnection
.