Skip to content

Conversation

@s3inlc
Copy link
Member

@s3inlc s3inlc commented Jan 19, 2026

A prepared statement like this

UPDATE table SET value = (CASE WHEN id=$1 THEN value=$2 WHEN id=$3 THEN value=$4 END) WHERE id IN ($1, $3);

does fail in postgres when the type of value is int/bigint as postgres is not able to determine the type of the value to be expected and throws a typing error.

There would be multiple ways to tell postgres that it's an integer, e.g. by casting the whole case statement like:

UPDATE table SET value = (CASE WHEN id=$1 THEN value=$2 WHEN id=$3 THEN value=$4 END)::bigint WHERE id IN ($1, $3);

The problem is, that this would not be compatible with mysql and we would have to build the query depending on the db system.
Another option to tell the db what type the case values will have, is by providing an ELSE with a static integer. The problem is, that even if you provide ... ELSE 0.. , postgres will only interpret it as integer, which will then again not work with a bigint column.

The trick which works is by setting the ELSE value to something bigger than 32bit max int. This way the db system is prepared to accept bigints (if there are), if the column is only integer, that is not a problem, as they way we build these massSingleUpdate statements, the ELSE clause never will be reached.
Both db systems (mysql and postgres), work with this ELSE (2^32) statement, with both int and bigint columns.

@s3inlc s3inlc requested a review from jessevz January 19, 2026 10:56
@s3inlc s3inlc requested a review from jessevz January 19, 2026 12:56
@s3inlc s3inlc merged commit 197cc96 into dev Jan 19, 2026
3 checks passed
@s3inlc s3inlc deleted the mass-single-update-case-casting branch January 19, 2026 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants