• R/O
  • HTTP
  • SSH
  • HTTPS

pg_hint_plan: Commit

firtst release


Commit MetaInfo

Revision041f948d386b093d5f34f8af4582dc2ffe084abc (tree)
Time2022-03-09 12:15:54
AuthorKyotaro Horiguchi <horikyota.ntt@gmai...>
CommiterKyotaro Horiguchi

Log Message

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.

Change Summary

Incremental Difference

--- a/expected/pg_hint_plan.out
+++ b/expected/pg_hint_plan.out
@@ -8388,6 +8388,12 @@ SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = '
83888388 p1_c2 | 0 | 2
83898389 (2 rows)
83908390
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;
83918397 -- Subqueries on inheritance tables under UNION
83928398 EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000
83938399 UNION ALL
--- a/pg_hint_plan.c
+++ b/pg_hint_plan.c
@@ -1892,9 +1892,14 @@ get_query_string(ParseState *pstate, Query *query, Query **jumblequery)
18921892 ExecuteStmt *stmt = (ExecuteStmt *)target_query;
18931893 PreparedStatement *entry;
18941894
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);
18961901
1897- if (entry->plansource->is_valid)
1902+ if (entry && entry->plansource->is_valid)
18981903 {
18991904 p = entry->plansource->query_string;
19001905 target_query = (Query *) linitial (entry->plansource->query_list);
--- a/sql/pg_hint_plan.sql
+++ b/sql/pg_hint_plan.sql
@@ -1012,6 +1012,13 @@ SELECT pg_sleep(1);
10121012 -- the index scan happened while planning.
10131013 SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND (relname = 'p1_c1' OR relname = 'p1_c2');
10141014
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+
10151022 -- Subqueries on inheritance tables under UNION
10161023 EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000
10171024 UNION ALL
Show on old repository browser