[ ]
I’m using stock docker compose setup, unmodified.[ ]
I’m using docker compose setup, with modifications (modified.yml
files, third party plugins/themes, etc.) - if so, describe your modifications in your post. Before reporting, see if your issue can be reproduced on the unmodified setup.[x]
I’m not using docker on my primary instance, but my issue can be reproduced on the aforementioned docker setup and/or official demo.
This is a relatively minor issue, but I’m making this post in case my diagnosis is useful to someone else.
On updating my tt-rss instance to PHP 8.1, entries in my feeds became unread (that were previously marked as read).
- Tiny Tiny RSS version (including git commit id): v22.09-d47b8c849
- Platform (i.e. Linux distro, Docker, PHP, PostgreSQL, etc) versions: Ubuntu 22.04, PHP 8.1, MariaDB 10.6
I initially didn’t know it was the PHP update, as I updated several components at once but I narrowed it down to an inconsistency generating the guid
in ttrss_entries
.
Notice the difference between these two rows:
+------------------------------------------+----------------------------------------------------------------------------+
| content_hash | guid |
+------------------------------------------+----------------------------------------------------------------------------+
| 2691d5ef1110f053a4951636f31dc89f366b8f2d | {"ver":2,"uid":"2","hash":"SHA1:c1d2277bc203467347b3aedca37266ecee07b2f1"} |
| 2691d5ef1110f053a4951636f31dc89f366b8f2d | {"ver":2,"uid":2,"hash":"SHA1:c1d2277bc203467347b3aedca37266ecee07b2f1"} |
The first row is the old entry, with a string uid
, while the second has an integer uid
.
The uid
comes from owner_uid
, an int
column straight out the database: https://dev.tt-rss.org/fox/tt-rss/src/commit/42bc1620b8deda73b96b2e0029c6de79daa5ccca/classes/rssutils.php#L681
In PHP 8.1, the MySQL driver has the following backwards incompatible change:
Integers and floats in result sets will now be returned using native PHP types instead of strings when using emulated prepared statements. This matches the behavior of native prepared statements. The previous behaviour can be restored by enabling the
PDO::ATTR_STRINGIFY_FETCHES
option.
hxxps://www.php.net/manual/en/migration81.incompatible.php#migration81.incompatible.pdo.mysql
With some minor tweaking to the docker compose setup (to use MySQL instead of PostgreSQL), I can reproduce this with a simple test:
test script:
<?php
$db = new PDO(getenv('TTRSS_DB_TYPE') . ":dbname=" . getenv('TTRSS_DB_NAME') . ";host=" . getenv('TTRSS_DB_HOST'), getenv('TTRSS_DB_USER'), getenv('TTRSS_DB_PASS'));
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare('select 1');
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_ASSOC));
checkout ttrss-docker-compose using PHP 8, I chose 4ae13e8900bcf920cb0bdd873eb2d0c5b361052a
Configure with mariadb and launch (apk add php8-pdo_mysql
)
$ docker cp test.php ttrss-docker_updater_1:/
$ docker exec -it ttrss-docker_updater_1 /bin/sh
/ # php8 /test.php
array(1) {
[1]=>
string(1) "1"
}
Then checkout the latest ttrss-docker-compose (which uses PHP 8.1) 426ed93214020b26eabf3465b308c31dbffb77b6
configure and launch (apk add php81-pdo_mysql
)
$ docker cp test.php ttrss-docker_updater_1:/
$ docker exec -it ttrss-docker_updater_1 /bin/sh
/ # php81 /test.php
array(1) {
[1]=>
int(1)
}
My proposed fix is to have a migration script ensure all uid
entries are integers. Though it will cause a bit of mess due to the UNIQUE
constraint.