• R/O
  • HTTP
  • SSH
  • HTTPS

pg_hint_plan: Commit

firtst release


Commit MetaInfo

Revision2d5b8cdad8ba623b3313b23a0b45712438ff68d8 (tree)
Time2022-03-09 12:18:04
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
@@ -1890,9 +1890,14 @@ get_query_string(ParseState *pstate, Query *query, Query **jumblequery)
18901890 ExecuteStmt *stmt = (ExecuteStmt *)target_query;
18911891 PreparedStatement *entry;
18921892
1893- entry = FetchPreparedStatement(stmt->name, true);
1893+ /*
1894+ * Silently ignore nonexistent prepared statements. This may happen
1895+ * for EXECUTE within a function definition. Otherwise the
1896+ * execution will fail anyway.
1897+ */
1898+ entry = FetchPreparedStatement(stmt->name, false);
18941899
1895- if (entry->plansource->is_valid)
1900+ if (entry && entry->plansource->is_valid)
18961901 {
18971902 p = entry->plansource->query_string;
18981903 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