Fix hashchar() and hashcharextended() to not depend on char signedness

Started by Tristan Partin25 days ago4 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253248
psql -h localhost -U postgres

Built from patchset v1 (message #1), August 23, 2026 at 08:26 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253248_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253248_1 && git checkout t253248_1

Patchset v1 (message #1) is on t253248_1

Jump to latest
#1Tristan Partin
tristan@partin.io

In bug #19587[0]/messages/by-id/19587-4416a590531c9c73@postgresql.org, the user reported that hashchar() and
hashcharextended() were not producing the same results for the same
input because of sign extension depending on the platform.

Attached are three patches:

1. A series of tests to exercise the issue in a new TAP test and
a regression test for the default path of
`default_char_signedness = true`. The TAP test will show a failure.
2. A fix for the functions to ensure they produce the same results
regardless of platform.
3. A consistency fix for charhashfast() such that it always produces the
same value regardless of platform. This patch is kind of unimportant
because the value is never persisted or sent to another process. I'll
leave it up to the committer to pull the patch in or not.

I am not sure that this can be backpatched before 19. I think it will
cause queries to produce different values. Definitely good to fix before
19 is final though.

[0]: /messages/by-id/19587-4416a590531c9c73@postgresql.org

--
Tristan Partin
PostgreSQL Contributors Team
AWS (https://aws.amazon.com)

Attachments:

t253248_1
v1-0001-Add-tests.patchtext/plain; charset=utf-8; name=v1-0001-Add-tests.patchDownload+99-1
v1-0002-Fix-hashchar-and-hashcharextended-to-not-depend-o.patchtext/plain; charset=utf-8; name=v1-0002-Fix-hashchar-and-hashcharextended-to-not-depend-o.patchDownload+23-3
v1-0003-Make-charhashfast-return-a-consistent-value-regar.patchtext/plain; charset=utf-8; name=v1-0003-Make-charhashfast-return-a-consistent-value-regar.patchDownload+11-2
#2Michael Paquier
michael@paquier.xyz
In reply to: Tristan Partin (#1)
Re: Fix hashchar() and hashcharextended() to not depend on char signedness

On Thu, Jul 30, 2026 at 06:51:32AM +0000, Tristan Partin wrote:

In bug #19587[0], the user reported that hashchar() and
hashcharextended() were not producing the same results for the same
input because of sign extension depending on the platform.

Attached are three patches:

1. A series of tests to exercise the issue in a new TAP test and
a regression test for the default path of
`default_char_signedness = true`. The TAP test will show a failure.
2. A fix for the functions to ensure they produce the same results
regardless of platform.
3. A consistency fix for charhashfast() such that it always produces the
same value regardless of platform. This patch is kind of unimportant
because the value is never persisted or sent to another process. I'll
leave it up to the committer to pull the patch in or not.

I am not sure that this can be backpatched before 19. I think it will
cause queries to produce different values. Definitely good to fix before
19 is final though.

[0]: /messages/by-id/19587-4416a590531c9c73@postgresql.org

Backpatch is out of the picture, but it also seems unwise to me to
change this computation on HEAD as well.

Assuming that this patch gets applied on HEAD, wouldn't that at least
break partitioned tables that are partitioned based on hash(char) once
a pre-v19 instance is upgraded to v20 with pg_upgrade, relying on a
new behavior which would be GUC-dependent?

I get the correctness argument, but the compatibility argument could
create quite some pain if pg_upgrade does not check for the existence
of such tables, at least, or other objects that rely on an on-disk
state that depend on the past behavior, these getting broken with the
new behavior if the GUC is incorrect flipped. Or am I missing
something obvious?
--
Michael

#3Matthias van de Meent
boekewurm+postgres@gmail.com
In reply to: Tristan Partin (#1)
Re: Fix hashchar() and hashcharextended() to not depend on char signedness

On Thu, 30 Jul 2026 at 08:51, Tristan Partin <tristan@partin.io> wrote:

In bug #19587[0], the user reported that hashchar() and
hashcharextended() were not producing the same results for the same
input because of sign extension depending on the platform.

This reminds me of [0]/messages/by-id/CB11ADBC-0C3F-4FE0-A678-666EE80CBB07@amazon.com, which saw the same difference in behaviour
cause discrepancies in indexing behaviour when replicating across
different architectures. That eventually led to a set of commits [1]30666d1857, a8238f87f9, 1aab680591, and dfd8e6c73e
that landed with PG18 that includes tracking the signedness of char in
the control file, which turned this char-signedness incompatibility
explicit.

So, I don't think we guarantee the output of all 'immutable' functions
to have no changes in output when the system is compiled on different
platforms or with different settings. Collations are one example where
the platform may change their output, char-signedness during
compilation is another.

Kind regards,

Matthias van de Meent
Databricks (https://www.databricks.com)

[0]: /messages/by-id/CB11ADBC-0C3F-4FE0-A678-666EE80CBB07@amazon.com
[1]: 30666d1857, a8238f87f9, 1aab680591, and dfd8e6c73e

#4Peter Eisentraut
peter_e@gmx.net
In reply to: Tristan Partin (#1)
Re: Fix hashchar() and hashcharextended() to not depend on char signedness

On 30.07.26 08:51, Tristan Partin wrote:

In bug #19587[0], the user reported that hashchar() and
hashcharextended() were not producing the same results for the same
input because of sign extension depending on the platform.

Is there any claim that data type hash functions are platform-independent?