- Issue created by @Charlie ChX Negyesi
- ๐ฎ๐นItaly mondrake ๐ฎ๐น
Maybe we could just move the call to
expandArguments
to withinprepareStatement
instead of withinquery
. It's protected and it's not called anywhere else within Connection.Also, make it public looks a viable alternative.
It was made difficult to make a generic
query
return AFFECTED_ROWS to keep up with https://git.drupalcode.org/project/drupal/-/blob/10.1.x/core/lib/Drupal/... - ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
Thanks! That's a great suggestion. If I might add, maybe make it optional? Add an "expand_arguments" option to prepareStatement $options? This way no surprises can happen.
- Status changed to Needs review
over 1 year ago 10:00pm 22 March 2023 - Status changed to Needs work
over 1 year ago 10:34pm 22 March 2023 - ๐ฎ๐นItaly mondrake ๐ฎ๐น
So back in #2345451: Introduce a Connection::prepareStatement method allowing to pass options to the Statement, deprecate Connection::prepareQuery() and Connection::prepare() โ I was already proposing to pass $args to
prepareStatement
, see my comment at #67. Now it seems we may have a good case to revise the decision to leave it out.If we pass $args to prepareStatement with a NULL default in the signature, we wonโt even need to bother with the $options.
- Status changed to Active
over 1 year ago 10:40pm 22 March 2023 - ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
When I tried to code this up and write the comment for this it makes it clear it is a side effect of calling prepareStatement which is usually not desired. Maybe let's get back to making expandArguments public?
- ๐ฎ๐นItaly mondrake ๐ฎ๐น
Yes, probably #6 is the best option.
Conceptually, one 'prepares a statement' independently from its 'arguments', than 'executes' one or more times the 'prepared argument' with one or more sets of 'arguments' to obtain a 'result' in each execution. So the idea in #2 of mixing the arguments with the statement preparation is a break in the separation of concerns and therefore not a good idea in the first place.
That said, this probably opens up a question of how currently 'reusable' is a statement prepared by
query()
, that callsexpandArguments()
on the arguments and modifies them. Trying to re-execute that with a new set of similarly formed arguments should(?) require to runexpandArguments()
on the additional sets indpendently. But that is probably not a case in core, a test would be needed. That would be a separate issue probably though. - Status changed to Needs review
over 1 year ago 6:03am 24 March 2023 - ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
Certainly not the most complex core patch I've ever written.
The last submitted patch, 8: 3349753_8.patch, failed testing. View results โ
- ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
Unrelated random testing failure.
- Status changed to Needs work
over 1 year ago 9:44pm 24 March 2023 - ๐ณ๐ฑNetherlands daffie
I get that we cannot support all queries that are possible with SQL in our DBTNG. What I am worried about is that those complicated SQL queries will only work on a specific type of database. For instance: it works on MariaDB, mostly on MySQL and not on PostgreSQL and SQLite.
Another way to fix this is to split the complicated SQL query up into multiple "simpler" queries. I have seen the example given by @chx. In that case we could split into a select query with a join to get the data and use the result to do the update queries. His example was also for a cron job and then it does not matter if they take a bit more time to run.
I do not want to give a hard no, but I can imagine that in some cases having the ability to run complicated SQL queries is important.
If we are going to do this we are going to need a CR, we also need testing for the "new" public method and I think we should also update the file database.api.php with an example.
- ๐ฎ๐นItaly mondrake ๐ฎ๐น
Maybe issue title and summary here should be reworked like "Make Connection::expandArguments() public to allow array argument expansion outside of Connection::query()". This would abstract away from @Charlie ChX Negyesi use case which IMHO should not be part of the discussion here.
And yes, we need tests to make this method part of the public API - actually I tried to find test coverage for it and could not find it; it may be indirect but then it's very hidden. Such tests here would also address #7.
- Status changed to Needs review
over 1 year ago 5:36pm 25 March 2023 - ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
I made a striking discovery when trying to write a test: this is static. Could be anywhere else even, has nothing to do with Connection at all. Once that realization is made, testing is easy.
The last submitted patch, 14: 3349753_14.patch, failed testing. View results โ
- ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
Sorry I can't resist properly fixing the failing line.
- ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
Except phpcs doesn't recognize that...
- Status changed to RTBC
over 1 year ago 5:32am 26 March 2023 - ๐ฎ๐นItaly mondrake ๐ฎ๐น
Looks good to me; we have now test coverage for the method we did not have before.
- Status changed to Needs work
over 1 year ago 9:40am 26 March 2023 - ๐ณ๐ฑNetherlands daffie
We are adding a new method to the public API, therefor we need to add a change record. Can we put a good example in the CR with how to use this method in custom code.
- ๐จ๐ฆCanada Charlie ChX Negyesi ๐Canada
Can we put a good example in the CR with how to use this method in custom code.
I will be honest with you: no. There are no good, clean examples for this. Anything neat is handled by DBTNG all fine. Any usage of this goes against the documented best practices of not using query for UPDATE/INSERT/DELETE.
But it is a necessary evil. I see no way out.
Except for undeprecating RETURN_AFFECTED and let it fly under the radar.
- Status changed to Needs review
over 1 year ago 2:54am 2 April 2023 - Status changed to Needs work
over 1 year ago 10:13pm 2 April 2023 - ๐บ๐ธUnited States smustgrave
The issue summary mentions two approaches. Can it be highlighted the approach taken.
Appears to be the function was made pubic can that be mentioned in the CR too please.
- Status changed to Needs review
over 1 year ago 6:52pm 3 April 2023 - Status changed to RTBC
over 1 year ago 7:35pm 3 April 2023 - ๐ฎ๐นItaly mondrake ๐ฎ๐น
Thank you. Besides addressing the need in the IS, this also adds explicit tests for
expandArguments()
, which is good. - Status changed to Needs work
over 1 year ago 1:00am 4 April 2023 - ๐ฆ๐บAustralia larowlan ๐ฆ๐บ๐.au GMT+10
Not supporting a particular use case doesn't necessarily make this a bug, I think now the solution/approach has changed this is better classified as a task
One of the fails above on PHP 8.2 relates to the changes here (see the sqlite run)
https://www.drupal.org/pift-ci-job/2634061 โ
Fine to self RTBC after that change.
I spent some time reviewing the security implications of this and I can't see any issue.
I'd like to see an additional test case covering the drupalgeddon fix, i.e. a case where the arguments are an array, the placeholder uses [], but the keys to the argument array are not numerically indexed, something like this
/** * Tests the sanitizing of placeholders. */ public function testExpandKeyedArguments(): void { $query = '(:x[])'; $args = [':x[]' => [' where 1=1 OR ' => 1, ' nefarious ' => 2]]; $modified = Connection::expandArguments($query, $args); $this->assertSame(TRUE, $modified); $this->assertSame('(:x__0, :x__1)', $query); $this->assertSame([':x__0' => 1, ':x__1' => 2], $args); }
That little array_values in there is one of the most significant in Drupal's history
- last update
about 1 year ago Patch Failed to Apply