OSDN Git Service

Fix to remove plpgsql query string on non-local exit.
authorKyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Tue, 16 Dec 2014 05:45:13 +0000 (14:45 +0900)
committerKyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Wed, 17 Dec 2014 01:47:23 +0000 (10:47 +0900)
Pl/pgsql query string stored internally squatted after an execution
error then pg_hint_plan afterward read it for hints and ignores really
given ones. This commit makes it erased at the end of transaction.

pg_hint_plan.c

index 240a128..87cf0d8 100644 (file)
@@ -32,6 +32,7 @@
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/syscache.h"
+#include "utils/resowner.h"
 #if PG_VERSION_NUM >= 90200
 #include "catalog/pg_class.h"
 #endif
@@ -409,6 +410,10 @@ static void pg_hint_plan_plpgsql_stmt_beg(PLpgSQL_execstate *estate,
                                                                                  PLpgSQL_stmt *stmt);
 static void pg_hint_plan_plpgsql_stmt_end(PLpgSQL_execstate *estate,
                                                                                  PLpgSQL_stmt *stmt);
+static void plpgsql_query_erase_callback(ResourceReleasePhase phase,
+                                                                                bool isCommit,
+                                                                                bool isTopLevel,
+                                                                                void *arg);
 
 /* GUC variables */
 static bool    pg_hint_plan_enable_hint = true;
@@ -573,6 +578,8 @@ _PG_init(void)
        /* setup PL/pgSQL plugin hook */
        var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin");
        *var_ptr = &plugin_funcs;
+
+       RegisterResourceReleaseCallback(plpgsql_query_erase_callback, NULL);
 }
 
 /*
@@ -3703,6 +3710,17 @@ pg_hint_plan_plpgsql_stmt_end(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
                plpgsql_query_string = NULL;
 }
 
+void plpgsql_query_erase_callback(ResourceReleasePhase phase,
+                                                                 bool isCommit,
+                                                                 bool isTopLevel,
+                                                                 void *arg)
+{
+       if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
+               return;
+       /* Force erase stored plpgsql query string */
+       plpgsql_query_string = NULL;
+}
+
 #define standard_join_search pg_hint_plan_standard_join_search
 #define join_search_one_level pg_hint_plan_join_search_one_level
 #define make_join_rel make_join_rel_wrapper