pg_plan_advice: DO_NOT_SCAN is a simple tag, not a generic one.

Generic tags allow sublists, e.g. MERGE_JOIN((x y)), but simple
tags do not, e.g. SEQ_SCAN(x) is valid but SEQ_SCAN((x)) is not.
DO_NOT_SCAN was intended to be simple tag, but was accidentally
implemented as a generic one. This could result in assertion
failures. Repair.

Reported-by: Nikita Kalinin <n.kalinin@postgrespro.ru>
Analyzed-by: Tender Wang <tndrwang@gmail.com>
Analyzed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: http://postgr.es/m/19493-5878eac7a2525c23@postgresql.org
This commit is contained in:
Robert Haas 2026-05-29 13:51:09 -04:00
parent 878839bafe
commit b1901e2895
4 changed files with 8 additions and 1 deletions

View file

@ -126,6 +126,9 @@ DETAIL: Could not parse advice: syntax error at or near "123"
SET pg_plan_advice.advice = 'SEQ_SCAN((x))';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN((x))"
DETAIL: Could not parse advice: syntax error at or near "("
SET pg_plan_advice.advice = 'DO_NOT_SCAN((x))';
ERROR: invalid value for parameter "pg_plan_advice.advice": "DO_NOT_SCAN((x))"
DETAIL: Could not parse advice: syntax error at or near "("
SET pg_plan_advice.advice = 'GATHER(((x)))';
ERROR: invalid value for parameter "pg_plan_advice.advice": "GATHER(((x)))"
DETAIL: Could not parse advice: syntax error at or near "("

View file

@ -106,6 +106,8 @@ advice_item: TOK_TAG_JOIN_ORDER '(' join_order_target_list ')'
$$ = palloc0_object(pgpa_advice_item);
if (strcmp($1, "bitmap_heap_scan") == 0)
$$->tag = PGPA_TAG_BITMAP_HEAP_SCAN;
else if (strcmp($1, "do_not_scan") == 0)
$$->tag = PGPA_TAG_DO_NOT_SCAN;
else if (strcmp($1, "no_gather") == 0)
$$->tag = PGPA_TAG_NO_GATHER;
else if (strcmp($1, "seq_scan") == 0)

View file

@ -128,7 +128,8 @@ xcinside [^*/]+
else if (tag == PGPA_TAG_SEQ_SCAN ||
tag == PGPA_TAG_TID_SCAN ||
tag == PGPA_TAG_BITMAP_HEAP_SCAN ||
tag == PGPA_TAG_NO_GATHER)
tag == PGPA_TAG_NO_GATHER ||
tag == PGPA_TAG_DO_NOT_SCAN)
return TOK_TAG_SIMPLE;
else
return TOK_TAG_GENERIC;

View file

@ -41,6 +41,7 @@ SET pg_plan_advice.advice = '123';
-- except for JOIN_ORDER, allow at most one level of sublist. Hence, these
-- examples should error out.
SET pg_plan_advice.advice = 'SEQ_SCAN((x))';
SET pg_plan_advice.advice = 'DO_NOT_SCAN((x))';
SET pg_plan_advice.advice = 'GATHER(((x)))';
-- Legal comments.