summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/ri_triggers.c20
-rw-r--r--src/backend/utils/misc/guc.c20
2 files changed, 20 insertions, 20 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index fa7b8e6e81..f08af12a2b 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2633,7 +2633,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
RangeTblEntry *fkrte;
const char *sep;
int i;
- int old_work_mem;
+ int save_nestlevel;
char workmembuf[32];
int spi_result;
SPIPlanPtr qplan;
@@ -2772,14 +2772,16 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
* this seems to meet the criteria for being considered a "maintenance"
* operation, and accordingly we use maintenance_work_mem.
*
- * We do the equivalent of "SET LOCAL work_mem" so that transaction abort
- * will restore the old value if we lose control due to an error.
+ * We use the equivalent of a function SET option to allow the setting to
+ * persist for exactly the duration of the check query. guc.c also takes
+ * care of undoing the setting on error.
*/
- old_work_mem = work_mem;
+ save_nestlevel = NewGUCNestLevel();
+
snprintf(workmembuf, sizeof(workmembuf), "%d", maintenance_work_mem);
(void) set_config_option("work_mem", workmembuf,
PGC_USERSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true);
+ GUC_ACTION_SAVE, true);
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect failed");
@@ -2862,13 +2864,9 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
elog(ERROR, "SPI_finish failed");
/*
- * Restore work_mem for the remainder of the current transaction. This is
- * another SET LOCAL, so it won't affect the session value.
+ * Restore work_mem.
*/
- snprintf(workmembuf, sizeof(workmembuf), "%d", old_work_mem);
- (void) set_config_option("work_mem", workmembuf,
- PGC_USERSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true);
+ AtEOXact_GUC(true, save_nestlevel);
return true;
}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5cc90fbe51..e9b665095d 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4367,8 +4367,9 @@ AtStart_GUC(void)
/*
* Enter a new nesting level for GUC values. This is called at subtransaction
- * start and when entering a function that has proconfig settings. NOTE that
- * we must not risk error here, else subtransaction start will be unhappy.
+ * start, and when entering a function that has proconfig settings, and in
+ * some other places where we want to set GUC variables transiently.
+ * NOTE we must not risk error here, else subtransaction start will be unhappy.
*/
int
NewGUCNestLevel(void)
@@ -4378,8 +4379,9 @@ NewGUCNestLevel(void)
/*
* Do GUC processing at transaction or subtransaction commit or abort, or
- * when exiting a function that has proconfig settings. (The name is thus
- * a bit of a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
+ * when exiting a function that has proconfig settings, or when undoing a
+ * transient assignment to some GUC variables. (The name is thus a bit of
+ * a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
* During abort, we discard all GUC settings that were applied at nesting
* levels >= nestLevel. nestLevel == 1 corresponds to the main transaction.
*/
@@ -4412,11 +4414,11 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
GucStack *stack;
/*
- * Process and pop each stack entry within the nest level. To
- * simplify fmgr_security_definer(), we allow failure exit from a
- * function-with-SET-options to be recovered at the surrounding
- * transaction or subtransaction abort; so there could be more than
- * one stack entry to pop.
+ * Process and pop each stack entry within the nest level. To simplify
+ * fmgr_security_definer() and other places that use GUC_ACTION_SAVE,
+ * we allow failure exit from code that uses a local nest level to be
+ * recovered at the surrounding transaction or subtransaction abort;
+ * so there could be more than one stack entry to pop.
*/
while ((stack = gconf->stack) != NULL &&
stack->nest_level >= nestLevel)