From 4a0e610157b0d7c6885339d9e64ff19cde14a862 Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Mon, 20 Jul 2026 12:40:20 +0800 Subject: [PATCH v1] Fix empty FOREIGN_JOIN sublist validation FOREIGN_JOIN target sublists must contain at least two relation identifiers. However, the parser checked only for sublists with exactly one identifier, so FOREIGN_JOIN(()) was accepted. Reject sublists with fewer than two relation identifiers, and add regression coverage. Author: Chao Li --- contrib/pg_plan_advice/expected/syntax.out | 3 +++ contrib/pg_plan_advice/pgpa_parser.y | 2 +- contrib/pg_plan_advice/sql/syntax.sql | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/pg_plan_advice/expected/syntax.out b/contrib/pg_plan_advice/expected/syntax.out index 3b57bb2bf57..d53d9598634 100644 --- a/contrib/pg_plan_advice/expected/syntax.out +++ b/contrib/pg_plan_advice/expected/syntax.out @@ -209,6 +209,9 @@ DETAIL: Could not parse advice: FOREIGN_JOIN targets must contain more than one SET pg_plan_advice.advice = 'FOREIGN_JOIN((a))'; ERROR: invalid value for parameter "pg_plan_advice.advice": "FOREIGN_JOIN((a))" DETAIL: Could not parse advice: FOREIGN_JOIN targets must contain more than one relation identifier at or near ")" +SET pg_plan_advice.advice = 'FOREIGN_JOIN(())'; +ERROR: invalid value for parameter "pg_plan_advice.advice": "FOREIGN_JOIN(())" +DETAIL: Could not parse advice: FOREIGN_JOIN targets must contain more than one relation identifier at or near ")" -- Tag keywords used as alias names work fine, because the 'identifier' -- nonterminal accepts all token types. SET pg_plan_advice.advice = 'SEQ_SCAN(hash_join)'; diff --git a/contrib/pg_plan_advice/pgpa_parser.y b/contrib/pg_plan_advice/pgpa_parser.y index 5811a6e5e56..295f16ad064 100644 --- a/contrib/pg_plan_advice/pgpa_parser.y +++ b/contrib/pg_plan_advice/pgpa_parser.y @@ -135,7 +135,7 @@ advice_item: TOK_TAG_JOIN_ORDER '(' join_order_target_list ')' foreach_ptr(pgpa_advice_target, target, $3) { if (target->ttype == PGPA_TARGET_IDENTIFIER || - list_length(target->children) == 1) + list_length(target->children) < 2) pgpa_yyerror(result, parse_error_msg_p, yyscanner, "FOREIGN_JOIN targets must contain more than one relation identifier"); } diff --git a/contrib/pg_plan_advice/sql/syntax.sql b/contrib/pg_plan_advice/sql/syntax.sql index 5af7607db42..de11e8c6fc2 100644 --- a/contrib/pg_plan_advice/sql/syntax.sql +++ b/contrib/pg_plan_advice/sql/syntax.sql @@ -73,6 +73,7 @@ SET pg_plan_advice.advice = '/*/* stuff */*/'; -- Foreign join requires multiple relation identifiers. SET pg_plan_advice.advice = 'FOREIGN_JOIN(a)'; SET pg_plan_advice.advice = 'FOREIGN_JOIN((a))'; +SET pg_plan_advice.advice = 'FOREIGN_JOIN(())'; -- Tag keywords used as alias names work fine, because the 'identifier' -- nonterminal accepts all token types. -- 2.50.1 (Apple Git-155)