firtst release
Revision | 041f948d386b093d5f34f8af4582dc2ffe084abc (tree) |
---|---|
Time | 2022-03-09 12:15:54 |
Author | Kyotaro Horiguchi <horikyota.ntt@gmai...> |
Commiter | Kyotaro Horiguchi |
Ignore non-existent prepared statement in get_query_string.
CREATE FUNCTION of SQL function uses post_parse_analyze_hook during
validation. If the function contained EXECUTE <prepared statement>,
not only that statement may be nonexistent, but also there's no need
of the query string at that point.
Since execution of nonexistent prepared statement ends with failure
sooner or later, we can safely ignore that.
Backpatch to pg_hint_plan10 that are before the core's EOL.
@@ -8388,6 +8388,12 @@ SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = ' | ||
8388 | 8388 | p1_c2 | 0 | 2 |
8389 | 8389 | (2 rows) |
8390 | 8390 | |
8391 | +-- Make sure the reference to validly non-existent prepared statement | |
8392 | +-- doesn't harm | |
8393 | +CREATE FUNCTION ppf() RETURNS void AS $$ | |
8394 | +PREPARE pp1 AS SELECT 1; | |
8395 | +EXECUTE pp1; | |
8396 | +$$ LANGUAGE sql; | |
8391 | 8397 | -- Subqueries on inheritance tables under UNION |
8392 | 8398 | EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 |
8393 | 8399 | UNION ALL |
@@ -1892,9 +1892,14 @@ get_query_string(ParseState *pstate, Query *query, Query **jumblequery) | ||
1892 | 1892 | ExecuteStmt *stmt = (ExecuteStmt *)target_query; |
1893 | 1893 | PreparedStatement *entry; |
1894 | 1894 | |
1895 | - entry = FetchPreparedStatement(stmt->name, true); | |
1895 | + /* | |
1896 | + * Silently ignore nonexistent prepared statements. This may | |
1897 | + * happen for EXECUTE within a function definition. Otherwise the | |
1898 | + * execution will fail anyway. | |
1899 | + */ | |
1900 | + entry = FetchPreparedStatement(stmt->name, false); | |
1896 | 1901 | |
1897 | - if (entry->plansource->is_valid) | |
1902 | + if (entry && entry->plansource->is_valid) | |
1898 | 1903 | { |
1899 | 1904 | p = entry->plansource->query_string; |
1900 | 1905 | target_query = (Query *) linitial (entry->plansource->query_list); |
@@ -1012,6 +1012,13 @@ SELECT pg_sleep(1); | ||
1012 | 1012 | -- the index scan happened while planning. |
1013 | 1013 | SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND (relname = 'p1_c1' OR relname = 'p1_c2'); |
1014 | 1014 | |
1015 | +-- Make sure the reference to validly non-existent prepared statement | |
1016 | +-- doesn't harm | |
1017 | +CREATE FUNCTION ppf() RETURNS void AS $$ | |
1018 | +PREPARE pp1 AS SELECT 1; | |
1019 | +EXECUTE pp1; | |
1020 | +$$ LANGUAGE sql; | |
1021 | + | |
1015 | 1022 | -- Subqueries on inheritance tables under UNION |
1016 | 1023 | EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000 |
1017 | 1024 | UNION ALL |