• R/O
  • HTTP
  • SSH
  • HTTPS

pg_hint_plan: Commit

firtst release


Commit MetaInfo

Revision353c36562b707de07928a4acd366313926de7f35 (tree)
Time2022-03-09 12:18:44
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
@@ -8426,6 +8426,12 @@ SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = '
84268426 p1_c2 | 0 | 2
84278427 (2 rows)
84288428
8429+-- Make sure the reference to validly non-existent prepared statement
8430+-- doesn't harm
8431+CREATE FUNCTION ppf() RETURNS void AS $$
8432+PREPARE pp1 AS SELECT 1;
8433+EXECUTE pp1;
8434+$$ LANGUAGE sql;
84298435 -- Subqueries on inheritance tables under UNION
84308436 EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000
84318437 UNION ALL
--- a/pg_hint_plan.c
+++ b/pg_hint_plan.c
@@ -1894,9 +1894,14 @@ get_query_string(ParseState *pstate, Query *query, Query **jumblequery)
18941894 ExecuteStmt *stmt = (ExecuteStmt *)target_query;
18951895 PreparedStatement *entry;
18961896
1897- entry = FetchPreparedStatement(stmt->name, true);
1897+ /*
1898+ * Silently ignore nonexistent prepared statements. This may
1899+ * happen for EXECUTE within a function definition. Otherwise the
1900+ * execution will fail anyway.
1901+ */
1902+ entry = FetchPreparedStatement(stmt->name, false);
18981903
1899- if (entry->plansource->is_valid)
1904+ if (entry && entry->plansource->is_valid)
19001905 {
19011906 p = entry->plansource->query_string;
19021907 target_query = (Query *) linitial (entry->plansource->query_list);
--- a/sql/pg_hint_plan.sql
+++ b/sql/pg_hint_plan.sql
@@ -1015,6 +1015,13 @@ SELECT pg_sleep(1);
10151015 -- the index scan happened while planning.
10161016 SELECT relname, seq_scan, idx_scan FROM pg_stat_user_tables WHERE schemaname = 'public' AND (relname = 'p1_c1' OR relname = 'p1_c2');
10171017
1018+-- Make sure the reference to validly non-existent prepared statement
1019+-- doesn't harm
1020+CREATE FUNCTION ppf() RETURNS void AS $$
1021+PREPARE pp1 AS SELECT 1;
1022+EXECUTE pp1;
1023+$$ LANGUAGE sql;
1024+
10181025 -- Subqueries on inheritance tables under UNION
10191026 EXPLAIN (COSTS off) SELECT val FROM p1 WHERE val < 1000
10201027 UNION ALL
Show on old repository browser