public inbox for [email protected]  
help / color / mirror / Atom feed
From: Tender Wang <[email protected]>
To: PostgreSQL Hackers <[email protected]>
Cc: David Rowley <[email protected]>
Subject: Fix "could not find memoization table entry"
Date: Mon, 23 Mar 2026 14:29:58 +0800
Message-ID: <CAHewXNmcXVFdB9_WwA8Ez0P+m_TQy_KzYk5Ri5dvg+fuwjD_yw@mail.gmail.com> (raw)

Hi,


Recently, I encountered an error: could not find memoization table
entry on TPCH(S=1) test.
The query was as follows:
psql (19devel)
Type "help" for help.

postgres=#  SELECT
FROM partsupp AS ref_0,
     LATERAL (SELECT ref_0.ps_suppkey AS c3,
                     (SELECT n_regionkey
                      FROM nation
                      LIMIT 1) AS c4
              LIMIT ALL) AS subq_0
WHERE hash_numeric(ref_0.ps_supplycost) = subq_0.c4;
ERROR:  could not find memoization table entry
postgres=# explain SELECT
FROM partsupp AS ref_0,
     LATERAL (SELECT ref_0.ps_suppkey AS c3,
                     (SELECT n_regionkey
                      FROM nation
                      LIMIT 1) AS c4
              LIMIT ALL) AS subq_0
WHERE hash_numeric(ref_0.ps_supplycost) = subq_0.c4;
                                       QUERY PLAN
-----------------------------------------------------------------------------------------
 Nested Loop  (cost=0.06..57942.04 rows=4000 width=0)
   ->  Seq Scan on partsupp ref_0  (cost=0.00..25560.00 rows=800000 width=10)
   ->  Memoize  (cost=0.06..0.09 rows=1 width=4)
         Cache Key: hash_numeric(ref_0.ps_supplycost), ref_0.ps_suppkey
         Cache Mode: binary
         Estimates: capacity=80659 distinct keys=88915 lookups=800000
hit percent=80.63%
         ->  Subquery Scan on subq_0  (cost=0.05..0.08 rows=1 width=4)
               Filter: (hash_numeric(ref_0.ps_supplycost) = subq_0.c4)
               ->  Result  (cost=0.05..0.06 rows=1 width=8)
                     InitPlan expr_1
                       ->  Limit  (cost=0.00..0.05 rows=1 width=4)
                             ->  Seq Scan on nation  (cost=0.00..1.25
rows=25 width=4)
(12 rows)



The hash_numeric result type is int.  If I forced binary_mode to
logical, there was no error anymore.
So I think this may be a bug.

How to easily reproduce:
1.  prepare tpch(s=1) data
2. Using gdb to set the mstate->mem_limit to 170 after the first tuple
was put into the cache in func cache_lookup()
3. When putting the second tuple into the cache, the mem_used will
exceed the mem_limit, so
calling the cache_reduce_memory() to remove the first tuple. But it
cannot find the first tuple in the hash table.

I did some research about this issue. When we insert the first tuple
into the cache, the first column(hash_numeric(ref_0.ps_supplycost))
value is:
(gdb) p /x pslot->tts_values[i]
$2 = 0xaf27c7c7

(gdb) p hkey
$2 = 38469220

But in the cache_reduce_memory(), its value is like this:
(gdb) p /x pslot->tts_values[i]
$5 = 0xffffffffaf27c7c7

(gdb) p hkey
$7 = 288723292

The hkeys returned by datum_image_hash() are different, so we can't
find the entry in the hash table.

In the datum_image_hash(), if typByVal is true, calling
result = hash_bytes((unsigned char *) &value, sizeof(Datum));

I think we should use typLen here, not sizeof(Datum).
I tried this way and didn't encounter any errors again.

I added David to the cc list. He may know more about this module.

-- 
Thanks,
Tender Wang


Attachments:

  [application/octet-stream] 0001-Fix-could-not-find-memoization-table-entry.patch (856B, 2-0001-Fix-could-not-find-memoization-table-entry.patch)
  download | inline diff:
From 4e53f75e46fcb497028c7c63fb3fb9367d7e5e5d Mon Sep 17 00:00:00 2001
From: Tender Wang <[email protected]>
Date: Mon, 23 Mar 2026 13:59:59 +0800
Subject: [PATCH] Fix "could not find memoization table entry"

---
 src/backend/utils/adt/datum.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c
index 8832785540f..e85fb88220c 100644
--- a/src/backend/utils/adt/datum.c
+++ b/src/backend/utils/adt/datum.c
@@ -341,7 +341,7 @@ datum_image_hash(Datum value, bool typByVal, int typLen)
 	uint32		result;
 
 	if (typByVal)
-		result = hash_bytes((unsigned char *) &value, sizeof(Datum));
+		result = hash_bytes((unsigned char *) &value, typLen);
 	else if (typLen > 0)
 		result = hash_bytes((unsigned char *) DatumGetPointer(value), typLen);
 	else if (typLen == -1)
-- 
2.34.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: <CAHewXNmcXVFdB9_WwA8Ez0P+m_TQy_KzYk5Ri5dvg+fuwjD_yw@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