Split out from #2168241-9: Type hints for optional methods in StatementInterface (D8) / DatabaseStatementInterface (D7), here are some bug fixes for dbtng, without any noise from docblock improvements.
Drupal\Core\Database\Driver\pgsql\Connection::createDatabase():
Replace$this->exec()with$this->connection->exec().Drupal\Core\Database\Driver\sqlite\Connection::sqlFunctionGreatest():
unset($args[$i]), instead ofunset($args).Drupal\Core\Database\Driver\sqlite\Connection::createDatabase():
SplFileInfoneeds to be prefixed with '\' for global namespace.Drupal\Core\Database\StatementPrefetch::current():
Replacearray_unshift()witharray_shift().
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | D8-2259947-10-dbtng-bugs.patch | 1.54 KB | donquixote |
Comments
Comment #1
donquixote commentedComment #2
donquixote commentedComment #3
donquixote commentedComment #4
Crell commentedThis needs manual testing on SQLite and Postgres before it can be RTBCed.
Comment #5
dcrocks commentedTried against Sqlite on current D8 clone. Install seems to be ok, but ran into unrelated issue so haven't tested further.
Comment #6
damien tournoud commented-1. GREATEST needs to return NULL if any argument is NULL.
This is not actually supported, and I doubt it works. We can support it cleanly now that we have PHP 5.4, but that requires more changes than just that. We have an existing issue for that somewhere.
Comment #7
donquixote commentedTo give some background: These were issues I ran into while fixing docblock issues and generally everything that makes my IDE complain.
The existing code in these places looked obviously wrong, but yeah, probably the fix is not always as easy as thought.
The new patch still contains all 4 attempted fixes, but I am ok to move some of this to separate issues.
@Damien (#6) / GREATEST(*, NULL)
Good to know, I was not aware. I tried to find a resource to confirm the fact, and this is the closest I got: http://bugs.mysql.com/bug.php?id=15610, but yes it confirms you are right.
Either way, I think the existing code is confusing, and it causes a count(UNDEFINED) which the IDE correctly complains about, and is likely to give us a PHP notice (I did not actually verify that).
It might incidentally do what we want, but it looks to me as if the original authors had something else in mind.
I'd say we should simply return NULL directly from the foreach() loop, and add a comment to explain why we do this. And while we are at it, clean up the rest of the method. See the new patch.
Another question is how reliable PHP's max() actually is in replicating SQL GREATEST() for non-integer values.
Open a separate issue?
@Damien (#6) / StatementPrefetch::current()
The problem with the existing code is simply that array_unshift() requires a second parameter, and it does not return anything.
The easiest explanation is that the author originally meant to do array_shift() instead.
I am ok to deal with this in another issue if someone can find it.
But what do you mean by "not actually supported"? The array_shift()? Or something in the switch/case?
EDIT: Seems that yoda is not very popular around here (to my regret).
Going to fix this in the next round.
Comment #8
damien tournoud commentedThis is a complex subject. We never could implement collations properly in SQLite because the necessary hooks were not available in PHP. I implemented them, and support is now available in PHP 5.4.
Let's open a separate issue for that, the rest of your fix is fine.
@donquixote: Sorry I was cryptic. I probably wrote this, and you are right the intent was obviously
array_shift(). But the wholePDO::FETCH_CLASS/PDO::FETCH_CLASSTYPEnever worked anyway, because to implement it properly we need to create an instance of a class without calling its constructor, which was impossible in userland PHP before 5.4.Because the rest of the database layer doesn't really support this option either as far as I remember, we never bothered.
Now it is possible to support and test this properly. But let's do that in a separate issue.
Comment #9
donquixote commented'spect!
I guess now that the hook is there, the remaining task of correctly replicating SQL's GREATEST() using max() or other PHP constructs is not that hard anymore. This needs some testing and evaluation, and we would need to check whether the behavior of GREATEST() is even consistent between MySQL, Oracle etc. This can be done as a follow-up if someone has too much time.
I'd say, we add a @todo and then commit the fix as-is. This might not fix the complete problem, but it is a clear improvement and it introduces no regression. Whatever was wrong with max() vs GREATEST(), it won't be any more or less wrong after the patch.
Again, what about we apply this simple "fix" and add a @todo? This way the IDE will be happy (*), and the harder problem can be dealt with in a follow-up.
(*) IDE will be really happy once we finish all the other cleanup issues for dbtng.
Or only use it with classes that don't have a constructor? Either way, let's do this in a follow-up.
Comment #10
donquixote commentedFollow-ups:
#2262425: Does PHP max() correctly replicate SQL GREATEST() for non-numeric values?
Existing (should have looked before):
#1814762: SQLite Greatest implementation is wrong for parameters with the value NULL
#1476782: DatabaseStatementPrefetch::current PHP function array_unshift() are used incorrectly
Looks like we should rather not touch these two problems and let the other issues handle it.
Comment #11
damien tournoud commentedComment #12
alexpottCommitted d8cdb35 and pushed to 8.x. Thanks!