Problem/Motivation
We are experiencing a new warning after migration to PHP 8.1:
Warning: Undefined array key "sequence_name" in DatabaseConnection_pgsql->query() (line 120 in /xxx/includes/database/pgsql/database.inc).
PHP: 8.1
Database: PostgreSQL 11
Drupal: 7.84
This warning was not present on PHP 7.3 / PostgreSQL 11.
Steps to reproduce
Proposed resolution
It seems like that this is already fixed in D9, as the code here is:
core\lib\Drupal\Core\Database\Connection.php
case Database::RETURN_INSERT_ID:
$sequence_name = $options['sequence_name'] ?? NULL;
return $this->connection->lastInsertId($sequence_name);
However the code in D7 is following:
includes\database\pgsql\database.inc
case Database::RETURN_INSERT_ID:
return $this->connection->lastInsertId($options['sequence_name']);
It should be sufficient to implement the same change to D7 as it is in D9.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #13 | 3258185-13.patch | 727 bytes | poker10 |
Comments
Comment #2
poker10 commentedComment #3
beatrizrodriguesI will work on that
Comment #4
liam morlandComment #5
mustanggb commentedJust noting that the ?? operator is PHP 7.0 and D7 needs to be PHP 5.3 compliant, so you'll need to assign it manually.
Comment #6
beatrizrodriguesI'm trying to get that error message, but I'm not being able to. I created my environment using lando and did a recipe using PHP 8.1 and postgres 11 but no message is displayed to me. Do you have any tips for me, please? I would really enjoy get this issue done. thank you!!
Comment #7
poker10 commentedI have digged into this a little deeper and it seems like that the warning is not consistently appearing.. I tried to simulate and debug it on my local enviroment (with exact copy of the affected system and the same PHP / PostgreSQL configuration) but the warning was not there.
What I can add to this issue is backtrace which leads to this issue on our server. For example this warning appears when I open new watchdog entry (or another URL which is not in menu_cache table):
The backtrace from my local enviroment however differs in the second step:
See the difference which "InsertQuery" class is invoked on each host - on the server it is only "InsertQuery", but on the local enviroment it is correctly "InsertQuery_pgsql". This difference caused that this check (below) was not run, as it is only in InsertQuery_pgsql class, which was not invoked:
And as the cache_menu table does not have sequence, it remains with the Database::RETURN_INSERT_ID, but without $options['sequence_name'] set.
But I do not know, how this is happening. Settings.php is configured properly with pgsql driver, website is running on the PostgreSQL database without any problems (except these warnings and deprecations messages).. It is a little bit weird.
And also it is a little bit unclear to me why this was fixed / changed in D9 codebase - it implies to me that there should have been some issues with this part of the code and the case where this could happen. However I am unable to find issue in Drupal issue queue which caused this change in D8/D9.
Comment #8
liam morland$sequence_name was added to Drupal 8 in commit cfdf10c for issue #2454625: SQLite: Fix SQLITE_SCHEMA errors in web tests.
The Drupal 7 code was as it was since it was first introduced in commit 69e6f41.
Comment #9
poker10 commentedThank you @Liam Morland.
I checked that SQLite issue and there was applied some general approach in which the identical code from
core/lib/Drupal/Core/Database/Driver/pgsql/Connection.phpquery function was also moved out tocore/lib/Drupal/Core/Database/Connection.php. And this should (maybe unintentionally) fixed also the issue if (in any case) the "sequence_name" was empty.So I do not know, if this should be the correct way how to handle this also in D7, or if it will be sufficient to sanitize it in the current place in
includes\database\pgsql\database.inc. Or if the core maintainers will allow any fix at all, if this is only some weird use-case...Comment #10
beatrizrodriguesComment #11
poker10 commentedThis patch fixed the warnings for us.
Comment #12
poker10 commentedComment #13
poker10 commentedPatch re-test.
Comment #14
poker10 commentedIt seems like that there is another PHP 8.1 deprecation message directly on Drupal 7.85 install on PostgreSQL database, see this test:
https://www.drupal.org/pift-ci-job/2298354
I will create separate issue for this.
Comment #15
mcdruid commentedHmm, that patch in #13 looks like it should be mostly harmless.
However, we have a problem in that D7's core tests do not pass with PostgreSQL. In fact, they don't run properly at all at the moment.
It'd be great to fix that so that we can test changes like this properly.
It is helpful to see that the same change has been made in D8/9 though, and that makes me a lot more comfortable with the patch.
Without test coverage we're somewhat reliant on people who actually use PostrgreSQL to confirm that patches work, and @poker10 has done so in #11. AFAICS the only differences between the patches in #11 and #13 are down to whitespace.
Comment #16
mcdruid commentedI've queued tests for everything other than PostgreSQL, but this change is in the psql driver in D7 (unlike in D8/9 where it's in the shared db code) so we wouldn't expect it to cause any issues.
As @Liam Morland pointed out the exact same code as in the patch is still in Drupal 8.9 and was unchanged for several years. That suggests it works okay:
https://git.drupalcode.org/project/drupal/-/blob/8.9.20/core/lib/Drupal/...
The PHP docs confirm that passing NULL to the lastInsertId method is fine:
https://www.php.net/manual/en/pdo.lastinsertid.php
So this looks pretty safe to me. I'll commit it once all the non-PostgreSQL tests have passed.
Comment #17
mcdruid commentedConfirmed also that
sequence_nameonly seems to exist in the pgsql driver:Do any of those other occurrences require any updates?
I think #13 is okay to commit either way.
Comment #19
mcdruid commentedThanks everyone.
Incidentally, it doesn't look like we have a parent issue for "fix PostgreSQL tests in D7". There was #710858: Meta issue: fix the remaining PostgreSQL bugs but that seems very outdated now. Anyone want to file one? I'm not saying it will be prioritised any time soon, but seems like it'd be a good issue to have.
Comment #20
liam morlandThat issue is old, but it doesn't mean it can't be used. The first step would be for testing to be enabled. The automated testing page for core only tests MySQL and SQLite.
Testing won't work at all until #3259482: [D7 PHP 8.1] fwrite(): Passing null to parameter #2 ($data) of type string is deprecated in InsertQuery_pgsql->execute() is fixed.
Comment #21
poker10 commentedI think that one of the reasons why testing does not work on PostgreSQL is a new test table introduced by #2802159: [D7] SQL layer: $match_operator is vulnerable to injection attack.
More information here #3262341: [D7] Database test table TEST_UPPERCASE causes PostgreSQL tests to fail.