Problem/Motivation

From #3265086-129: Implement statement classes using \Iterator to fix memory usage regression and prevent rewinding.

I noted that StatementWrapperIterator implements fetchAllAssoc() and fetchAllKeyed() incorrectly since they run a foreach loop on the statement itself - which in case a statement is already partially fetched requires a rewind that is not allowed in our implementation. This is not a case for StatementPrefetchIterartor that keeps fetching records while there are available.

IMHO we should fix it to align all fetchAll* methods to the standard PDO fetchAll() behaviour which is

PDOStatement::fetchAll() returns an array containing all of the remaining rows in the result set.

See https://www.php.net/manual/en/pdostatement.fetchall.php#refsect1-pdostat...

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Issue fork drupal-3350375

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mondrake created an issue. See original summary.

mondrake’s picture

Status: Active » Needs review
Issue tags: +Novice
StatusFileSize
new2.79 KB

A test-only patch to demonstrate the issue.

Status: Needs review » Needs work

The last submitted patch, 2: 3350375-2-test-only.patch, failed testing. View results

mondrake’s picture

Status: Needs work » Needs review

Fix would be avoiding to use foreach.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

Ran the tests without the fix locally and they passed unfortunately.

mondrake’s picture

Status: Needs work » Needs review

@smustgrave on which db type did you test?

smustgrave’s picture

Tested on fresh installs of mariaDb, mysql, and postgres and the tests pass each time without the fix.

Won't move to NW though because clearly they are failing here.

Status: Needs review » Needs work

The last submitted patch, 2: 3350375-2-test-only.patch, failed testing. View results

mondrake’s picture

Status: Needs work » Needs review

Just rerun tests in #2, and mysql and pgsql fail as expected - sqlite is not failing, expected as well, since that driver is not using StatementWrapperIterator.

Will try on github, in the meantime NR by anyone else that can reproduce @smustgrave results and figure out why.

mondrake’s picture

I setup a Github Action test workflow - https://github.com/mondrake/d8-unit/blob/test-3350375/.github/workflows/...

and I get the test failures - https://github.com/mondrake/d8-unit/actions/runs/4630185826

So I cannot replicate #6 and #8

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

I won't be the hold up as my local could be different and change isn't so large I must get a failure. Will let the committers decide on this one but don't mind marking as #2 shows the tests do fail (reran earlier).

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: -Novice +Bug Smash Initiative, +Needs release manager review

Whilst this seems logical to me, I have a concern that this may disrupt someone who has written existing code that relies on the current behaviour.

Is this something we can make opt-in (e.g. via settings.php flag) that we default to on for new installs?

Would like a release manager to have a look at this and assess the possible risk of disruption, so tagging as such.

larowlan’s picture

Issue tags: +Needs change record

Can we get a change record here too, will make it easier for a release manager to review as well.

catch’s picture

It seems unlikely that someone would start fetching individual records and then call fetchAll() half way through... but also you never know.

Is there some way we can detect that iteration has already begun? But then I guess the new code allows for this, just with different results, so it's not really a deprecation as such, just a behaviour change.

Overall I feel like this is probably OK in a minor release with a change record and release note, although it might be better to commit early in 10.2 to give the maximum time for anyone to run into issues (which won't be long now before 10.2 is open really).

alexpott’s picture

Title: fetchAllAssoc() and fetchAllKeyed() behave inconsistently » [regression] fetchAllAssoc() and fetchAllKeyed() behave inconsistently
Priority: Normal » Major
Status: Needs review » Reviewed & tested by the community

@mondrake what was the behaviour prior to #3265086: Implement statement classes using \Iterator to fix memory usage regression and prevent rewinding?

Answering my own question. This is a regression introduced by #3265086: Implement statement classes using \Iterator to fix memory usage regression and prevent rewinding and should be fixed prior to 10.1.x being released.

I reverted c6532d8c5c the commit hash for 3265086 and added @mondrake's new tests. They pass - whereas on head they fail. This is for both mysql and sqlite (so both flavours of statement class we have).

@mondrake can you confirm my findings? If this is the case I don't think we need a change record or a release manager review.

mondrake’s picture

This is an edge case, I do not think anyone was actually starting to fetch single records to then fetchAll* the remaining part. I am not sure what the situation was before #3265086: Implement statement classes using \Iterator to fix memory usage regression and prevent rewinding; I will try a test-only patch run on 10.0 and 9.5 to discover (I tried running the one in #2 but that does not apply).

I also think we should consider this a completion of #3265086: Implement statement classes using \Iterator to fix memory usage regression and prevent rewinding.

alexpott’s picture

StatusFileSize
new2.83 KB

Here's proof that this is a regression on 10.1.x - here's the test-only patch but for 10.0.x.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs release manager review, -Needs change record

The postgres fails on 10.0.x are due to a regression caused by #3191391: Schema::changeField() has bug when changing regular serial field to big serial field that's been fixed due to a revert. As #18 shows us this fixes a regression caused by #3265086: Implement statement classes using \Iterator to fix memory usage regression and prevent rewinding therefore this does not need a CR or release manager review as we're fixing an accidental behaviour change in 10.1.x and the original RTBC in #12can stand.

Committed 1057a39 and pushed to 10.1.x. Thanks!

  • alexpott committed 1057a397 on 10.1.x
    Issue #3350375 by mondrake, alexpott, smustgrave, larowlan, catch: [...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.