Ensure config changes caused by functions are rolled back correctly.
authorPavan Deolasee <[email protected]>
Fri, 28 Sep 2018 09:24:11 +0000 (14:54 +0530)
committerPavan Deolasee <[email protected]>
Fri, 28 Sep 2018 09:24:11 +0000 (14:54 +0530)
When a function body has SET clauses attached to it, the function
validation/execution reflects those config changes locally as well as on the
remote nodes. But we were failing to restore the old values back when the
command ends. This had gone unnoticed so far for the lack of any test case
exercising this code. Note that there were existing test cases in this area,
but the bug got unmasked only after we added a temporary table in the session.
When a temporary table is accessed in a session, we don't reset the session at
the end of the transaction and hence the issue surfaced.

This was causing failure in a new test added in the 'rules' test. This patch
fixes that.

src/backend/utils/misc/guc.c

index 261a6d9f909c482d7ad7248527a856920cb99d02..bd21b10c7553a4a6a0c4af60c06e7e31d05f703e 100644 (file)
@@ -5835,8 +5835,20 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
                                newvalStr = GetConfigOptionByName(gconf->name, NULL, true);
 
                                if (newvalStr)
-                                       PGXCNodeSetParam((stack->state == GUC_LOCAL), gconf->name,
-                                                       newvalStr, gconf->flags);
+                               {
+                                       /*
+                                        * If we're unwinding changes caused by SET clauses
+                                        * attached to a function, reset those changes at the
+                                        * remote nodes immediately. Otherwise, we just remember
+                                        * the changes locally and send them to the remote nodes at
+                                        * next transaction/session.
+                                        */
+                                       if (stack->state == GUC_SAVE)
+                                               set_remote_config_option(gconf->name, newvalStr, false);
+                                       else
+                                               PGXCNodeSetParam((stack->state == GUC_LOCAL), gconf->name,
+                                                               newvalStr, gconf->flags);
+                               }
                        }
 
                        /* Finish popping the state stack */