From cdb3bf2b50fbdb312d98c9b029f20895ac60ede9 Mon Sep 17 00:00:00 2001 From: stsargsyan Date: Thu, 15 Jan 2026 17:00:10 +0300 Subject: [PATCH] Handle backward scan support for subquery RTEs The code incorrectly assumed that all range table entries have a valid relid. This is not true for subquery RTEs, which resulted in relid = 0 and caused cache lookup failures when cursors were used. --- src/backend/executor/execAmi.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 491d8fc0416..b0237989e03 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -579,6 +579,16 @@ ExecSupportsBackwardScan(Plan *node, List *rtable) ((Scan *) node)->scanrelid <= list_length(rtable)); rte = rt_fetch(((Scan *) node)->scanrelid, rtable); + + /* + * Subqueries and other non-table RTEs won't have a relid. They + * are already materialized or validated at this point, so + * assume backward scan is allowed and avoid calling + * TableSupportsBackwardScan with InvalidOid. + */ + if (!OidIsValid(rte->relid)) + return true; + return TableSupportsBackwardScan(rte->relid); } @@ -648,7 +658,7 @@ TableSupportsBackwardScan(Oid tableid) Form_pg_class tabrelrec; const TableAmRoutine *amroutine; - /* Fetch the pg_class tuple of the index relation */ + /* Fetch the pg_class tuple of the table relation */ ht_tabrel = SearchSysCache1(RELOID, ObjectIdGetDatum(tableid)); if (!HeapTupleIsValid(ht_tabrel)) elog(ERROR, "cache lookup failed for relation %u", tableid);