postgresql/contrib/pg_plan_advice/expected/syntax.out
Robert Haas 5e72ce2467 pg_plan_advice: Fix failures to accept identifier keywords.
TOK_IDENT allows only non-keywords; identifier should be used
any place where either keywords or non-keywords should be accepted.
Hence, without this commit, any string that happens to be a keyword
can't be used as a partition schema, partition name, or plan name,
which is incorrect.

Author: Lukas Fittl <lukas@fittl.com>
Discussion: http://postgr.es/m/CAP53PkzKeD=t90OfeMsniYrcRe2THQbUx3g6wV17Y=ZtiwmWTQ@mail.gmail.com
2026-03-16 14:46:50 -04:00

237 lines
8.4 KiB
Text

LOAD 'pg_plan_advice';
-- An empty string is allowed. Empty target lists are allowed for most advice
-- tags, but not for JOIN_ORDER. "Supplied Plan Advice" should be omitted in
-- text format when there is no actual advice, but not in non-text format.
SET pg_plan_advice.advice = '';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
------------
Result
(1 row)
SET pg_plan_advice.advice = 'SEQ_SCAN()';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
------------
Result
(1 row)
SET pg_plan_advice.advice = 'NESTED_LOOP_PLAIN()';
EXPLAIN (COSTS OFF, FORMAT JSON) SELECT 1;
QUERY PLAN
--------------------------------
[ +
{ +
"Plan": { +
"Node Type": "Result", +
"Parallel Aware": false,+
"Async Capable": false, +
"Disabled": false +
}, +
"Supplied Plan Advice": ""+
} +
]
(1 row)
SET pg_plan_advice.advice = 'JOIN_ORDER()';
ERROR: invalid value for parameter "pg_plan_advice.advice": "JOIN_ORDER()"
DETAIL: Could not parse advice: JOIN_ORDER must have at least one target at or near ")"
-- Test assorted variations in capitalization, whitespace, and which parts of
-- the relation identifier are included. These should all work.
SET pg_plan_advice.advice = 'SEQ_SCAN(x)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
---------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(x) /* not matched */
(3 rows)
SET pg_plan_advice.advice = 'seq_scan(x@y)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
-----------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(x@y) /* not matched */
(3 rows)
SET pg_plan_advice.advice = 'SEQ_scan(x#2)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
-----------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(x#2) /* not matched */
(3 rows)
SET pg_plan_advice.advice = 'SEQ_SCAN (x/y)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
-----------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(x/y) /* not matched */
(3 rows)
SET pg_plan_advice.advice = ' SEQ_SCAN ( x / y . z ) ';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
-------------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(x/y.z) /* not matched */
(3 rows)
SET pg_plan_advice.advice = 'SEQ_SCAN("x"#2/"y"."z"@"t")';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
-----------------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(x#2/y.z@t) /* not matched */
(3 rows)
-- Syntax errors.
SET pg_plan_advice.advice = 'SEQUENTIAL_SCAN(x)';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQUENTIAL_SCAN(x)"
DETAIL: Could not parse advice: syntax error at or near "SEQUENTIAL_SCAN"
SET pg_plan_advice.advice = 'SEQ_SCAN';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN"
DETAIL: Could not parse advice: syntax error at end of input
SET pg_plan_advice.advice = 'SEQ_SCAN(';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN("
DETAIL: Could not parse advice: syntax error at end of input
SET pg_plan_advice.advice = 'SEQ_SCAN("';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN(""
DETAIL: Could not parse advice: unterminated quoted identifier at end of input
SET pg_plan_advice.advice = 'SEQ_SCAN("")';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN("")"
DETAIL: Could not parse advice: zero-length delimited identifier at or near """
SET pg_plan_advice.advice = 'SEQ_SCAN("a"';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN("a""
DETAIL: Could not parse advice: syntax error at end of input
SET pg_plan_advice.advice = 'SEQ_SCAN(#';
ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN(#"
DETAIL: Could not parse advice: syntax error at or near "#"
SET pg_plan_advice.advice = '()';
ERROR: invalid value for parameter "pg_plan_advice.advice": "()"
DETAIL: Could not parse advice: syntax error at or near "("
SET pg_plan_advice.advice = '123';
ERROR: invalid value for parameter "pg_plan_advice.advice": "123"
DETAIL: Could not parse advice: syntax error at or near "123"
-- 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.
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 = 'GATHER(((x)))';
ERROR: invalid value for parameter "pg_plan_advice.advice": "GATHER(((x)))"
DETAIL: Could not parse advice: syntax error at or near "("
-- Legal comments.
SET pg_plan_advice.advice = '/**/';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
------------
Result
(1 row)
SET pg_plan_advice.advice = 'HASH_JOIN(_)/***/';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
----------------------------------
Result
Supplied Plan Advice:
HASH_JOIN(_) /* not matched */
(3 rows)
SET pg_plan_advice.advice = '/* comment */ HASH_JOIN(/*x*/y)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
----------------------------------
Result
Supplied Plan Advice:
HASH_JOIN(y) /* not matched */
(3 rows)
SET pg_plan_advice.advice = '/* comment */ HASH_JOIN(y//*x*/z)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
------------------------------------
Result
Supplied Plan Advice:
HASH_JOIN(y/z) /* not matched */
(3 rows)
-- Unterminated comments.
SET pg_plan_advice.advice = '/*';
ERROR: invalid value for parameter "pg_plan_advice.advice": "/*"
DETAIL: Could not parse advice: unterminated comment at end of input
SET pg_plan_advice.advice = 'JOIN_ORDER("fOO") /* oops';
ERROR: invalid value for parameter "pg_plan_advice.advice": "JOIN_ORDER("fOO") /* oops"
DETAIL: Could not parse advice: unterminated comment at end of input
-- Nested comments are not supported, so the first of these is legal and
-- the second is not.
SET pg_plan_advice.advice = '/*/*/';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
------------
Result
(1 row)
SET pg_plan_advice.advice = '/*/* stuff */*/';
ERROR: invalid value for parameter "pg_plan_advice.advice": "/*/* stuff */*/"
DETAIL: Could not parse advice: syntax error at or near "*"
-- Foreign join requires multiple relation identifiers.
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((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 ")"
-- 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)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
-----------------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(hash_join) /* not matched */
(3 rows)
SET pg_plan_advice.advice = 'SEQ_SCAN(seq_scan)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
----------------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(seq_scan) /* not matched */
(3 rows)
SET pg_plan_advice.advice = 'SEQ_SCAN(gather)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
--------------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(gather) /* not matched */
(3 rows)
SET pg_plan_advice.advice = 'SEQ_SCAN(join_order)';
EXPLAIN (COSTS OFF) SELECT 1;
QUERY PLAN
------------------------------------------
Result
Supplied Plan Advice:
SEQ_SCAN(join_order) /* not matched */
(3 rows)
-- Tag keywords used as partition names or plan names should also work,
-- since pgpa_identifier_string() can generate these from real partition
-- and subquery names.
SET pg_plan_advice.advice = 'SEQ_SCAN(t/public.hash_join)';
SET pg_plan_advice.advice = 'SEQ_SCAN(t/hash_join.foo)';
SET pg_plan_advice.advice = 'SEQ_SCAN(t@hash_join)';
SET pg_plan_advice.advice = 'SEQ_SCAN(t@seq_scan)';