-
[ ] 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: tt-rss/rssutils.php at 42bc1620b8deda73b96b2e0029c6de79daa5ccca - tt-rss - Tiny Tiny RSS
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.