Thread

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Fix estimate_array_length error with set-operation array coercions

  1. pg17: XX000: no relation entry for relid 0

    Justin Pryzby <pryzby@telsasoft.com> — 2026-04-10T10:54:42Z

    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
    
    
    
    
  2. Re: pg17: XX000: no relation entry for relid 0

    Tender Wang <tndrwang@gmail.com> — 2026-04-10T12:49:24Z

    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
    
    
    
    
  3. Re: pg17: XX000: no relation entry for relid 0

    Richard Guo <guofenglinux@gmail.com> — 2026-04-10T14:38:50Z

    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
    
    
    
    
  4. Re: pg17: XX000: no relation entry for relid 0

    Michael Paquier <michael@paquier.xyz> — 2026-04-10T20:34:34Z

    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
    
  5. Re: pg17: XX000: no relation entry for relid 0

    Tender Wang <tndrwang@gmail.com> — 2026-04-11T01:31:59Z

    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
    
  6. Re: pg17: XX000: no relation entry for relid 0

    Richard Guo <guofenglinux@gmail.com> — 2026-04-11T07:57:21Z

    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