Re: BUG #19493: Assertion failure in pg_plan_advice with EXISTS subquery and DO_NOT_SCAN advice

From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Tender Wang <tndrwang(at)gmail(dot)com>
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>, Калинин Никита <n(dot)kalinin(at)postgrespro(dot)ru>, Michael Paquier <michael(at)paquier(dot)xyz>, Pierre Forstmann <pierre(dot)forstmann(at)gmail(dot)com>
Subject: Re: BUG #19493: Assertion failure in pg_plan_advice with EXISTS subquery and DO_NOT_SCAN advice
Date: 2026-05-29 18:02:25
Message-ID: CA+TgmoZC23qe+-wWr0gjxU=4knqehX2-tZik=CR3tFXDuTiWxw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Thu, May 28, 2026 at 10:04 PM Tender Wang <tndrwang(at)gmail(dot)com> wrote:
> -- Tags like SEQ_SCAN and NO_GATHER don't allow sublists at all; other tags,
> -- except for JOIN_ORDER, allow at most one level of sublist. Hence, these
> -- examples should error out.
> "
> So 'DO_NOT_SCAN((x))' is valid syntax. The original codes in
> pgpa_build_trove() may
> forget about this case. I added this syntax case to the syntax.sql.
>
> I also added the query to scan.sql and adjusted the original comments.

Thanks for the analysis and the patch, but in fact DO_NOT_SCAN() was
intended to be a "simple" tag, not a "generic" one, and I just messed
up. This makes sense if you think through how it actually works. For a
tag like GATHER, GATHER((x y)) means something different form GATHER(x
y): the former means that there should be a Gather node on top of the
join between x and y, while the latter means that there should be two
separate Gather nodes, one atop x and the other atop y. On the other
hand, NO_GATHER(x y) means that no Gather node can appear anywhere
above x or y, and there is no such thing as NO_GATHER((x y)) because
it couldn't mean anything different. Likewise, SEQ_SCAN(x) means use a
sequential scan on x, and SEQ_SCAN((x)) or SEQ_SCAN((x y)) is refused
because you can't use a sequential scan on a group of tables.

Extending that reasoning to the current case, DO_NOT_SCAN() is like
SEQ_SCAN() or NO_GATHER(): it applies to a single relation, not to a
list of relations. However, for things to actually work that way,
pgpa_scanner.l needs to classify it as TOK_TAG_SIMPLE, and a
corresponding adjustment is needed in pgpa_parser.y. I overlooked the
need for this in the patch that introduced DO_NOT_SCAN.

I have committed a fix.

--
Robert Haas
EDB: http://www.enterprisedb.com

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Andrey Borodin 2026-05-29 18:06:46 Re: BUG #19490: Streaming standby on 16.14 stops applying WAL on MultiXactOffsetSLRU when primary is 16.8
Previous Message PG Bug reporting form 2026-05-29 15:35:05 BUG #19501: btree_gist: use float4/float8 comparison functions to handle NaN correctly