pg17: XX000: no relation entry for relid 0

Started by Justin Pryzby4 days ago6 messageshackers
Jump to latest
#1Justin Pryzby
pryzby@telsasoft.com

CREATE VIEW x AS SELECT NULL::int[]
UNION ALL SELECT NULL::int[]
UNION ALL SELECT ARRAY[NULL::bigint];

SELECT FROM x;
ERROR: XX000: no relation entry for relid 0

Since 9391f7152.

--
Justin

#2Tender Wang
tndrwang@gmail.com
In reply to: Justin Pryzby (#1)
Re: pg17: XX000: no relation entry for relid 0

Justin Pryzby <pryzby@telsasoft.com> 于2026年4月10日周五 18:54写道:

CREATE VIEW x AS SELECT NULL::int[]
UNION ALL SELECT NULL::int[]
UNION ALL SELECT ARRAY[NULL::bigint];

SELECT FROM x;
ERROR: XX000: no relation entry for relid 0

Since 9391f7152.

The varno = 0 is from below code:

*pTargetList = generate_setop_tlist(colTypes, colCollations,
0,
false,
*pTargetList,
refnames_tlist,
&trivial_tlist);
*istrivial_tlist = trivial_tlist;
target = create_pathtarget(root, *pTargetList);

in recurse_set_operations().
When calling set_pathtarget_cost_width(), we estimate the length of
the array that would enter estimate_array_length().
Before 9391f7152, we returned 10 directly. But now, we see if we can
find any statistics about it.
In examine_variable(), try to find base_rel in find_base_rel(), error
reported. Because the varno of the Var is 0.

I didn't think too much at now, a quick fix as below:
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 4160d2d6e24..ff93fc3ac8a 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -2265,6 +2265,9 @@ estimate_array_length(PlannerInfo *root, Node *arrayexpr)
                AttStatsSlot sslot;
                double          nelem = 0;
+               if (IsA(arrayexpr, Var) && ((Var *) arrayexpr)->varno == 0)
+                       return 10;
+
                examine_variable(root, arrayexpr, 0, &vardata);
                if (HeapTupleIsValid(vardata.statsTuple))
                {

Any thoughts?

--
Thanks,
Tender Wang

#3Richard Guo
guofenglinux@gmail.com
In reply to: Tender Wang (#2)
Re: pg17: XX000: no relation entry for relid 0

On Fri, Apr 10, 2026 at 9:49 PM Tender Wang <tndrwang@gmail.com> wrote:

Justin Pryzby <pryzby@telsasoft.com> 于2026年4月10日周五 18:54写道:

CREATE VIEW x AS SELECT NULL::int[]
UNION ALL SELECT NULL::int[]
UNION ALL SELECT ARRAY[NULL::bigint];

SELECT FROM x;
ERROR: XX000: no relation entry for relid 0

Nice catch. It seems that we need at least three branches to
reproduce this, so that there's a nested UNION ALL whose output type
doesn't match the parent's expected type. At the outer branch maybe
we can use NULL::bigint[] instead to be a little simpler.

SELECT NULL::int[] UNION ALL SELECT NULL::int[] UNION ALL SELECT NULL::bigint[];
ERROR: no relation entry for relid 0

I didn't think too much at now, a quick fix as below:
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 4160d2d6e24..ff93fc3ac8a 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -2265,6 +2265,9 @@ estimate_array_length(PlannerInfo *root, Node *arrayexpr)
AttStatsSlot sslot;
double          nelem = 0;
+               if (IsA(arrayexpr, Var) && ((Var *) arrayexpr)->varno == 0)
+                       return 10;
+
examine_variable(root, arrayexpr, 0, &vardata);
if (HeapTupleIsValid(vardata.statsTuple))
{

Any thoughts?

This looks like the right fix to me. We can use some comment here.

- Richard

#4Michael Paquier
michael@paquier.xyz
In reply to: Richard Guo (#3)
Re: pg17: XX000: no relation entry for relid 0

On Fri, Apr 10, 2026 at 11:38:50PM +0900, Richard Guo wrote:

Nice catch. It seems that we need at least three branches to
reproduce this, so that there's a nested UNION ALL whose output type
doesn't match the parent's expected type. At the outer branch maybe
we can use NULL::bigint[] instead to be a little simpler.

Indeed, three branches:
$ git branch --contains 9391f7152
+ REL_17_STABLE
+ REL_18_STABLE
* master
--
Michael

#5Tender Wang
tndrwang@gmail.com
In reply to: Richard Guo (#3)
Re: pg17: XX000: no relation entry for relid 0

Richard Guo <guofenglinux@gmail.com> 于2026年4月10日周五 22:39写道:

On Fri, Apr 10, 2026 at 9:49 PM Tender Wang <tndrwang@gmail.com> wrote:

Justin Pryzby <pryzby@telsasoft.com> 于2026年4月10日周五 18:54写道:

CREATE VIEW x AS SELECT NULL::int[]
UNION ALL SELECT NULL::int[]
UNION ALL SELECT ARRAY[NULL::bigint];

SELECT FROM x;
ERROR: XX000: no relation entry for relid 0

Nice catch. It seems that we need at least three branches to
reproduce this, so that there's a nested UNION ALL whose output type
doesn't match the parent's expected type. At the outer branch maybe
we can use NULL::bigint[] instead to be a little simpler.

SELECT NULL::int[] UNION ALL SELECT NULL::int[] UNION ALL SELECT NULL::bigint[];
ERROR: no relation entry for relid 0

Yes, add it to the test case.

I didn't think too much at now, a quick fix as below:
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 4160d2d6e24..ff93fc3ac8a 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -2265,6 +2265,9 @@ estimate_array_length(PlannerInfo *root, Node *arrayexpr)
AttStatsSlot sslot;
double          nelem = 0;
+               if (IsA(arrayexpr, Var) && ((Var *) arrayexpr)->varno == 0)
+                       return 10;
+
examine_variable(root, arrayexpr, 0, &vardata);
if (HeapTupleIsValid(vardata.statsTuple))
{

Any thoughts?

This looks like the right fix to me. We can use some comment here.

comments added.
Please see the attached patch.

--
Thanks,
Tender Wang

Attachments:

0001-Fix-no-relation-entry-for-relid-0-in-nested-UNION-AL.patchapplication/octet-stream; name=0001-Fix-no-relation-entry-for-relid-0-in-nested-UNION-AL.patchDownload+25-1
#6Richard Guo
guofenglinux@gmail.com
In reply to: Tender Wang (#5)
Re: pg17: XX000: no relation entry for relid 0

On Sat, Apr 11, 2026 at 10:32 AM Tender Wang <tndrwang@gmail.com> wrote:

Richard Guo <guofenglinux@gmail.com> 于2026年4月10日周五 22:39写道:

This looks like the right fix to me. We can use some comment here.

comments added.
Please see the attached patch.

I've pushed and back-patched the fix after some tweaks to the comment
and commit message. I also used explain (verbose, costs off) in the
test case so that we can observe that the inner UNION ALL's output
type doesn't match the outer's.

Thanks for the report and the patch.

- Richard