From: Robert Haas Date: Fri, 29 May 2026 17:51:09 +0000 (-0400) Subject: pg_plan_advice: DO_NOT_SCAN is a simple tag, not a generic one. X-Git-Tag: REL_19_BETA1~20 X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=b1901e2895e08f57a5fedfd27375babd6c633893;p=thirdparty%2Fpostgresql.git 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 Analyzed-by: Tender Wang Analyzed-by: Ayush Tiwari Discussion: http://postgr.es/m/19493-5878eac7a2525c23@postgresql.org --- diff --git a/contrib/pg_plan_advice/expected/syntax.out b/contrib/pg_plan_advice/expected/syntax.out index c3f2cbd6dca..c61fd73a385 100644 --- a/contrib/pg_plan_advice/expected/syntax.out +++ b/contrib/pg_plan_advice/expected/syntax.out @@ -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 "(" diff --git a/contrib/pg_plan_advice/pgpa_parser.y b/contrib/pg_plan_advice/pgpa_parser.y index 598974d3f22..5811a6e5e56 100644 --- a/contrib/pg_plan_advice/pgpa_parser.y +++ b/contrib/pg_plan_advice/pgpa_parser.y @@ -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) diff --git a/contrib/pg_plan_advice/pgpa_scanner.l b/contrib/pg_plan_advice/pgpa_scanner.l index 3b3be6eb727..e6d60f57e1e 100644 --- a/contrib/pg_plan_advice/pgpa_scanner.l +++ b/contrib/pg_plan_advice/pgpa_scanner.l @@ -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; diff --git a/contrib/pg_plan_advice/sql/syntax.sql b/contrib/pg_plan_advice/sql/syntax.sql index f274fa48636..3f94b5f8bf3 100644 --- a/contrib/pg_plan_advice/sql/syntax.sql +++ b/contrib/pg_plan_advice/sql/syntax.sql @@ -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.