Skip to content

[3.0] Makes the settings counters increment on PostgreSQL too - #9340

Merged
jdarwood007 merged 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/pg-settings-increment
Aug 2, 2026
Merged

[3.0] Makes the settings counters increment on PostgreSQL too#9340
jdarwood007 merged 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/pg-settings-increment

Conversation

@albertlast

@albertlast albertlast commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Description

Config::updateModSettings($array, true) supports true and false as values, meaning "increment" and "decrement". It builds this:

UPDATE {db_prefix}settings
SET value = value + 1
WHERE variable = {string:variable}

settings.value is a text column. MySQL coerces it and the counter goes up. PostgreSQL refuses:

ERROR:  operator does not exist: text + integer
HINT:  No operator matches the given name and argument types.

Nothing then happens. The PostgreSQL API discards failed statements without logging or raising (see #9341), so the query simply does nothing and the request carries on. Four counters go through this path — totalMessages, totalTopics, totalMembers and unapprovedMembers — and on PostgreSQL none of them have been moving. They only ever look right after a manual recount in Forum Maintenance, until the next post pushes them out of step again.

Easy to see on a PostgreSQL install:

smf=# SELECT (SELECT value FROM smf_settings WHERE variable='totalMessages'),
smf-#        (SELECT COUNT(*)::text FROM smf_messages);
 value | count
-------+-------
 4     | 5

Casting into DECIMAL and back out through CONCAT() is accepted by both databases and keeps the increment a single atomic statement, so two simultaneous posts still cannot lose a count:

SET value = CONCAT(CAST(value AS DECIMAL) + 1, '')

Testing

Docker environment, PostgreSQL 17. Before the change, posting a reply left totalMessages at 4 with 5 rows in smf_messages. After it, each new post moves the counter, a new topic moves totalTopics, and Forum Maintenance → recount agrees with the live totals (7 and 7).

Verified the expression on both engines directly:

postgres:  SELECT CONCAT(CAST('4' AS DECIMAL) + 1, '');  ->  5  (text)
mysql:     SELECT CONCAT(CAST('4' AS DECIMAL) + 1, '');  ->  5

vendor/bin/phpunit — 108 tests, 157 assertions, OK.

Issues References (Fixes|Related|Closes)

Related to #9341

updateModSettings($x, true) emits SET value = value + 1 against settings.value,
which is a text column. MySQL coerces that silently; PostgreSQL rejects it
with "operator does not exist: text + integer", and since the PostgreSQL
API discards failed queries without a word, the statement simply did
nothing.

So on PostgreSQL every counter that goes through this path - totalMessages,
totalTopics, totalMembers, unapprovedMembers - has been frozen at whatever
value the last full recount produced. This install had totalMessages stuck
at 4 with 5 messages in the table.

Casting into DECIMAL and back out through CONCAT() keeps the increment a
single atomic statement and is accepted by both databases.

Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
@jdarwood007 jdarwood007 added this to the 3.0 Alpha 5 milestone Aug 2, 2026
@jdarwood007
jdarwood007 merged commit 6d3d6b3 into SimpleMachines:release-3.0 Aug 2, 2026
4 checks passed
@albertlast
albertlast deleted the 3.0/pg-settings-increment branch August 2, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants