-
-
Notifications
You must be signed in to change notification settings - Fork 37
Add support for duplicate named query parameters to the mysqli driver #301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for duplicate named query parameters to the mysqli driver #301
Conversation
|
Our mysql implementation of named prepared statement matches the support by other drivers (especially postgres). Does this also work in the other supported drivers? edit: |
|
I had been inadvertently using multiples of same-named parameters with the You do not necessarily have feature parity with other PDO providers as you're using PDO::ATTR_EMULATE_PREPARES which is only available on MySQL (among the DB servers you support). No idea why, not explained in the commit message either, and Michael who wrote the code has quit and gone no-contact with the project a long time ago. I can check if Postgres and SQLite also support multiple substitutions. Give me a couple of hours, I'll get back to you on that. |
|
I did a quick check, duplicate keys work perfectly fine with SQLite. Interesting. I guess the SF answer was probably outdated or wrong, as you said. Once I get some time later today I'll test with Postgres and, if I am masochistic enough, MS SQL Server. |
|
j4i named prepared statements for mysqli has been written by me, michael did the prepared statement stuff without named parameters. But that doesn't matter, if the same thing works for postgres, I'm sure we get a mssql server test too for this. |
|
Sorry, I was unclear in my wording. Michael committed the I will try to install PostgreSQL and MS SQL Server later, and port the tests to be certain. As far as I can see trawling through old PHP issues, multiple instances of the same named parameter in PDO prepared statements have been supported since PHP 5.2.1. |
* PostgreSQL * SQLite * Microsoft SQL Server
This is necessary if you want to use the driver with Microsoft SQL Server for Linux, i.e. what you get when using Docker (even under Windows).
|
I tested with all available drivers. As I suspected, all PDO drivers worked perfectly out of the box. Support for this feature was added in PHP 5.2.1. The information claiming otherwise appears to be people remembering the situation before PHP 5.2.1, repeating their memory as a fact, without having checked if it's still true 🤷♂️ MS SQL Server does not use PDO, so I had to modify its statement class as well. |
Hi, I'm the no-contact guy 😆 Believe it or not, the PDO-based MySQL driver has always used Everything I did years ago was modeled around what the It looks like the only thing I did there was update that line to use an internal method for setting attributes instead of calling the PDO connection directly, and I don't think that config has been challenged at all since the driver's introduction. So you're probably looking at a case of "this worked fine when implemented in 2013, and nobody's touched it since". |
|
@mbabker I thought you were no longer commenting on Joomla! repos 😄 Yes, it makes sense copying Doctrine, they have a far higher installation base than Joomla! ever will and they know what they're doing. Well, intentional or not, PDO drivers work great thanks to this one little trick. The mysqli and sqlsrv drivers, not so much. If someone is really interested in fixing it I have submitted the code which addresses the issue. It wasn't too hard to get there, once you know what you're looking for. And I can totally see why nobody looked at it before; it's not exactly a common use case. |
I couldn't convince anyone to block me on this org so there are still rare occasions that I might be convinced to drop a nugget of knowledge (or just flat out call something out for the bad decision it is, I have one of those issues too 😅) |
|
Thanks for the fix! Can't tag it right now as on a phone but will try and sort it out when im home later if someone doesn't step in before then |
|
thanks george but looking at the test would be helpful... @nikosdion are you willing to fix the tests? CS, Postgres nd MSSQL? https://ci.joomla.org/joomla-framework/database/1459/1/3 |
Summary of Changes
Added support for duplicate named query parameters to the
mysqliandsqlsrvdrivers. What I mean is something like this:Note how
:searchis used twice in the above query.This had always worked with all PDO-based drivers:
mysql,pgsql, andsqlite. This feature was added to PDO back in PHP 5.2.1.The two non-PDO drivers use userland code to emulate prepared statements, but the userland code didn't support multiple uses of the same named parameter.
Testing Instructions
Run the tests contained in this PR before and after applying the patch for each of the
mysql,mysqli,sqlite,sqlsrv, andpgsqldatabase drivers.Before the PR changes are applied:
mysql: Fails with an exception about mismatched number of argumentsmysqli: Workspgsql: Workssqlite: Workssqlsrv: Fails with an exception about mismatched number of argumentsAfter the PR changes are applied:
mysql: Worksmysqli: Workspgsql: Workssqlite: Workssqlsrv: WorksDocumentation Changes Required
None.
Notes
I have inadvertently been using this feature since Joomla! 4.0 beta 2 was released with the
mysqldriver. It was only when I received bug reports from users using themysqlidriver I figured out something is wrong, which is how I ended up with this PR.PDO has supported multiple uses of the same named parameter since PHP 5.2.1. However, because many people remembered the prior situation you will see a lot of wrong information online stating that PDO does not support this feature.
I have tested the
mysqlandmysqlidrivers using MySQL 8 installed directly on my host OS. I testedsqlitedirectly, using an in-memory database as per the default configuration. I testedpgsqlagainst a Dockerized PostgreSQL server, using thepostgresql:latestimage. I testedsqlsrvagainst a Dockerized Microsoft SQL Server Express 2019 installation -- but I had to change\Joomla\Database\Sqlsrv\SqlsrvDriver::connectto setEncrypttofalse, since the Dockerized server does not have a valid TLS certificate. All my tests have been against PHP 8.3 using the PHPUnit version pulled into thevendorfolder oncomposer installto keep things clean and simple.The current MS SQL Server driver uses the
sqlsrvPHP extension. If it used thepdo_sqlsrvextension, available since PHP 7.1, it wouldn't need a custom SqlsrvStatement class, nor would it have a problem with this feature to begin with. Maybe it's worth adding apdosqlsrvdriver?