diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/ri_triggers.c | 20 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 20 |
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) |