Re: ERROR: wrong varnullingrels (b 3) (expected (b)) for Var 2/1

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Markus Winand <markus(dot)winand(at)winand(dot)at>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ERROR: wrong varnullingrels (b 3) (expected (b)) for Var 2/1
Date: 2023-06-14 06:55:36
Message-ID: CAMbWs48Jcw-NvnxT23WiHP324wG44DvzcH1j4hc0Zn+3sR9cfg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, Jun 14, 2023 at 6:02 AM Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> I wrote:
> > Richard Guo <guofenglinux(at)gmail(dot)com> writes:
> >> Oh, wait ... It occurred to me that we may have this same issue with
> >> Memoize cache keys.
>
> > Good catch --- I'll take a closer look tomorrow.
>
> Pushed after a little more fiddling with the comments.

I just realized that we may still have holes in this area. Until now
we're mainly focusing on LATERAL subquery, in which case the lateral
reference Vars are copied into rel->subplan_params and we've already
adjusted the nulling bitmaps there. But what about the lateral
reference Vars in other cases?

In extract_lateral_references() we consider 5 cases,

/* Fetch the appropriate variables */
if (rte->rtekind == RTE_RELATION)
vars = pull_vars_of_level((Node *) rte->tablesample, 0);
else if (rte->rtekind == RTE_SUBQUERY)
vars = pull_vars_of_level((Node *) rte->subquery, 1);
else if (rte->rtekind == RTE_FUNCTION)
vars = pull_vars_of_level((Node *) rte->functions, 0);
else if (rte->rtekind == RTE_TABLEFUNC)
vars = pull_vars_of_level((Node *) rte->tablefunc, 0);
else if (rte->rtekind == RTE_VALUES)
vars = pull_vars_of_level((Node *) rte->values_lists, 0);
else
{
Assert(false);
return; /* keep compiler quiet */
}

We've handled the second case, i.e., RTE_SUBQUERY. It's not hard to
compose a query for each of the other 4 cases that shows that we need to
adjust the nulling bitmaps for them too.

1. RTE_RELATION with tablesample

explain (costs off)
select * from int8_tbl t1
left join int8_tbl t2 on true
left join lateral
(select * from int8_tbl t3 TABLESAMPLE SYSTEM (t2.q1)) s
on t2.q1 = 1;
ERROR: wrong varnullingrels (b 3) (expected (b)) for Var 2/1

2. RTE_FUNCTION

explain (costs off)
select * from int8_tbl t1
left join int8_tbl t2 on true
left join lateral
(select * from generate_series(t2.q1, 100)) s
on t2.q1 = 1;
ERROR: wrong varnullingrels (b 3) (expected (b)) for Var 2/1

3. RTE_TABLEFUNC

explain (costs off)
select * from xmltest2 t1
left join xmltest2 t2 on true
left join lateral
xmltable('/d/r' PASSING t2.x COLUMNS a int)
on t2._path = 'a';
ERROR: wrong varnullingrels (b 3) (expected (b)) for Var 2/1

4. RTE_VALUES

explain (costs off)
select * from int8_tbl t1
left join int8_tbl t2 on true
left join lateral
(select q1 from (values(t2.q1), (t2.q1)) v(q1)) s
on t2.q1 = 1;
ERROR: wrong varnullingrels (b 3) (expected (b)) for Var 2/1

So it seems that we need to do nullingrel adjustments in a more common
place.

Also, there might be lateral references in the tlist, so the query below
is supposed to also encounter the 'wrong varnullingrels' error.

explain (costs off)
select * from int8_tbl t1
left join int8_tbl t2 on true
left join lateral
(select t2.q1 from int8_tbl t3) s
on t2.q1 = 1;
server closed the connection unexpectedly

But as we can see, it triggers the Assert in try_nestloop_path.

/* If we got past that, we shouldn't have any unsafe outer-join refs */
Assert(!have_unsafe_outer_join_ref(root, outerrelids, inner_paramrels));

I think it exposes a new issue. It seems that we extract a problematic
lateral_relids from lateral references within PlaceHolderVars in
create_lateral_join_info. I doubt that we should use ph_lateral
directly. It seems more reasonable to me that we strip outer-join
relids from ph_lateral and then use that for lateral_relids.

Any thoughts?

Thanks
Richard

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Kyotaro Horiguchi 2023-06-14 07:01:33 Re: Let's make PostgreSQL multi-threaded
Previous Message Etsuro Fujita 2023-06-14 06:49:37 Re: postgres_fdw: wrong results with self join + enable_nestloop off