public inbox for [email protected]  
help / color / mirror / Atom feed
From: David Rowley <[email protected]>
To: Tender Wang <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: Fix "could not find memoization table entry"
Date: Wed, 25 Mar 2026 15:09:38 +1300
Message-ID: <CAApHDvreF-UiqBaHtRTQWQ6z1X9snstJW+dfb2DU5GOb-uPEBg@mail.gmail.com> (raw)
In-Reply-To: <CAApHDvrRR1VOk4i4CpNWeL48veFshfRAvDTuWxsiUhUqo0akwQ@mail.gmail.com>
References: <CAHewXNmcXVFdB9_WwA8Ez0P+m_TQy_KzYk5Ri5dvg+fuwjD_yw@mail.gmail.com>
	<CAApHDvrSSeLNWzQWWcLfZKWwHd=XocVs3abmTmvaSD_sx-dkNQ@mail.gmail.com>
	<CAApHDvrRR1VOk4i4CpNWeL48veFshfRAvDTuWxsiUhUqo0akwQ@mail.gmail.com>

On Wed, 25 Mar 2026 at 13:31, David Rowley <[email protected]> wrote:
> Obviously, we don't want to back-patch anything that would cause a
> user-visible change in the return value of hash_numeric(), so I've
> been experimenting to see if there's any way to get PostgreSQL to
> output any value from hash_numeric() larger than 2^31 and I've been
> unable to. I tried:

I was experimenting with a less risky fix by having the datum_image
functions force the sign-extended representation of the Datum before
hashing or comparing.

Attached is a quick PoC of what that would look like. It does fix the
reported problem. But it is a hack and doesn't fix the root cause of
the issue.

Despite the hackiness, I feel this might be better than the
whack-a-mole approach of just fixing incorrect usages of the
PG_RETURN_* macros as and when we find them.

David


Attachments:

  [application/octet-stream] hack_to_fix_datum_image_problem.patch (1.8K, 2-hack_to_fix_datum_image_problem.patch)
  download | inline diff:
diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c
index 8832785540f..ef202c83f40 100644
--- a/src/backend/utils/adt/datum.c
+++ b/src/backend/utils/adt/datum.c
@@ -271,6 +271,27 @@ datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
 
 	if (typByVal)
 	{
+		/*
+		 * XXX hack to fix issue with functions such as hash_numeric() not
+		 * returning the correct type.  Force sign-extended representation.
+		 */
+		switch (typLen)
+		{
+			case sizeof(char):
+				value1 = CharGetDatum(DatumGetChar(value1));
+				value2 = CharGetDatum(DatumGetChar(value2));
+				break;
+			case sizeof(int16):
+				value1 = Int16GetDatum(DatumGetInt16(value1));
+				value2 = Int16GetDatum(DatumGetInt16(value2));
+				break;
+			case sizeof(int32):
+				value1 = Int32GetDatum(DatumGetInt32(value1));
+				value2 = Int32GetDatum(DatumGetInt32(value2));
+				break;
+			/* Nothing needs done for 64-bit types */
+		}
+
 		result = (value1 == value2);
 	}
 	else if (typLen > 0)
@@ -341,7 +362,27 @@ datum_image_hash(Datum value, bool typByVal, int typLen)
 	uint32		result;
 
 	if (typByVal)
-		result = hash_bytes((unsigned char *) &value, sizeof(Datum));
+	{
+		/*
+		 * XXX hack to fix issue with functions such as hash_numeric() not
+		 * returning the correct type.  Force sign-extended representation.
+		 */
+		switch (typLen)
+		{
+			case sizeof(char):
+				value = CharGetDatum(DatumGetChar(value));
+				break;
+			case sizeof(int16):
+				value = Int16GetDatum(DatumGetInt16(value));
+				break;
+			case sizeof(int32):
+				value = Int32GetDatum(DatumGetInt32(value));
+				break;
+			/* Nothing needs done for 64-bit types */
+		}
+
+		result = hash_bytes((unsigned char*) &value, sizeof(Datum));
+	}
 	else if (typLen > 0)
 		result = hash_bytes((unsigned char *) DatumGetPointer(value), typLen);
 	else if (typLen == -1)


view thread (9+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected]
  Subject: Re: Fix "could not find memoization table entry"
  In-Reply-To: <CAApHDvreF-UiqBaHtRTQWQ6z1X9snstJW+dfb2DU5GOb-uPEBg@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox