Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitba6f629

Browse files
committed
Improve and simplify CREATE EXTENSION's management of GUC variables.
CREATE EXTENSION needs to transiently set search_path, as well asclient_min_messages and log_min_messages. We were doing this by theexpedient of saving the current string value of each variable, doing aSET LOCAL, and then doing another SET LOCAL with the previous value atthe end of the command. This is a bit expensive though, and it also failsbadly if there is anything funny about the existing search_path value,as seen in a recent report from Roger Niederland. Fortunately, there's amuch better way, which is to piggyback on the GUC infrastructure previouslydeveloped for functions with SET options. We just open a new GUC nestinglevel, do our assignments with GUC_ACTION_SAVE, and then close the nestinglevel when done. This automatically restores the prior settings without are-parsing pass, so (in principle anyway) there can't be an error. Andguc.c still takes care of cleanup in event of an error abort.The CREATE EXTENSION code for this was modeled on some much older code inri_triggers.c, which I also changed to use the better method, even thoughthere wasn't really much risk of failure there. Also improve the commentsin guc.c to reflect this additional usage.
1 parent3919ad8 commitba6f629

File tree

4 files changed

+34
-48
lines changed

4 files changed

+34
-48
lines changed

‎src/backend/commands/extension.c

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -774,9 +774,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
774774
constchar*schemaName,OidschemaOid)
775775
{
776776
char*filename;
777-
char*save_client_min_messages,
778-
*save_log_min_messages,
779-
*save_search_path;
777+
intsave_nestlevel;
780778
StringInfoDatapathbuf;
781779
ListCell*lc;
782780

@@ -808,22 +806,20 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
808806
* so that we won't spam the user with useless NOTICE messages from common
809807
* script actions like creating shell types.
810808
*
811-
* We use the equivalent of SET LOCAL to ensure the setting is undone upon
812-
* error.
809+
* We use the equivalent of a function SET option to allow the setting to
810+
* persist for exactly the duration of the script execution. guc.c also
811+
* takes care of undoing the setting on error.
813812
*/
814-
save_client_min_messages=
815-
pstrdup(GetConfigOption("client_min_messages", false, false));
813+
save_nestlevel=NewGUCNestLevel();
814+
816815
if (client_min_messages<WARNING)
817816
(void)set_config_option("client_min_messages","warning",
818817
PGC_USERSET,PGC_S_SESSION,
819-
GUC_ACTION_LOCAL, true,0);
820-
821-
save_log_min_messages=
822-
pstrdup(GetConfigOption("log_min_messages", false, false));
818+
GUC_ACTION_SAVE, true,0);
823819
if (log_min_messages<WARNING)
824820
(void)set_config_option("log_min_messages","warning",
825821
PGC_SUSET,PGC_S_SESSION,
826-
GUC_ACTION_LOCAL, true,0);
822+
GUC_ACTION_SAVE, true,0);
827823

828824
/*
829825
* Set up the search path to contain the target schema, then the schemas
@@ -832,10 +828,9 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
832828
*
833829
* Note: it might look tempting to use PushOverrideSearchPath for this,
834830
* but we cannot do that. We have to actually set the search_path GUC in
835-
* case the extension script examines or changes it.
831+
* case the extension script examines or changes it. In any case, the
832+
* GUC_ACTION_SAVE method is just as convenient.
836833
*/
837-
save_search_path=pstrdup(GetConfigOption("search_path", false, false));
838-
839834
initStringInfo(&pathbuf);
840835
appendStringInfoString(&pathbuf,quote_identifier(schemaName));
841836
foreach(lc,requiredSchemas)
@@ -849,7 +844,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
849844

850845
(void)set_config_option("search_path",pathbuf.data,
851846
PGC_USERSET,PGC_S_SESSION,
852-
GUC_ACTION_LOCAL, true,0);
847+
GUC_ACTION_SAVE, true,0);
853848

854849
/*
855850
* Set creating_extension and related variables so that
@@ -910,18 +905,9 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
910905
CurrentExtensionObject=InvalidOid;
911906

912907
/*
913-
* Restore GUC variables for the remainder of the current transaction.
914-
* Again use SET LOCAL, so we won't affect the session value.
908+
* Restore the GUC variables we set above.
915909
*/
916-
(void)set_config_option("search_path",save_search_path,
917-
PGC_USERSET,PGC_S_SESSION,
918-
GUC_ACTION_LOCAL, true,0);
919-
(void)set_config_option("client_min_messages",save_client_min_messages,
920-
PGC_USERSET,PGC_S_SESSION,
921-
GUC_ACTION_LOCAL, true,0);
922-
(void)set_config_option("log_min_messages",save_log_min_messages,
923-
PGC_SUSET,PGC_S_SESSION,
924-
GUC_ACTION_LOCAL, true,0);
910+
AtEOXact_GUC(true,save_nestlevel);
925911
}
926912

927913
/*

‎src/backend/utils/adt/ri_triggers.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2633,7 +2633,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
26332633
RangeTblEntry*fkrte;
26342634
constchar*sep;
26352635
inti;
2636-
intold_work_mem;
2636+
intsave_nestlevel;
26372637
charworkmembuf[32];
26382638
intspi_result;
26392639
SPIPlanPtrqplan;
@@ -2772,14 +2772,16 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
27722772
* this seems to meet the criteria for being considered a "maintenance"
27732773
* operation, and accordingly we use maintenance_work_mem.
27742774
*
2775-
* We do the equivalent of "SET LOCAL work_mem" so that transaction abort
2776-
* will restore the old value if we lose control due to an error.
2775+
* We use the equivalent of a function SET option to allow the setting to
2776+
* persist for exactly the duration of the check query. guc.c also takes
2777+
* care of undoing the setting on error.
27772778
*/
2778-
old_work_mem=work_mem;
2779+
save_nestlevel=NewGUCNestLevel();
2780+
27792781
snprintf(workmembuf,sizeof(workmembuf),"%d",maintenance_work_mem);
27802782
(void)set_config_option("work_mem",workmembuf,
27812783
PGC_USERSET,PGC_S_SESSION,
2782-
GUC_ACTION_LOCAL, true,0);
2784+
GUC_ACTION_SAVE, true,0);
27832785

27842786
if (SPI_connect()!=SPI_OK_CONNECT)
27852787
elog(ERROR,"SPI_connect failed");
@@ -2862,13 +2864,9 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
28622864
elog(ERROR,"SPI_finish failed");
28632865

28642866
/*
2865-
* Restore work_mem for the remainder of the current transaction. This is
2866-
* another SET LOCAL, so it won't affect the session value.
2867+
* Restore work_mem.
28672868
*/
2868-
snprintf(workmembuf,sizeof(workmembuf),"%d",old_work_mem);
2869-
(void)set_config_option("work_mem",workmembuf,
2870-
PGC_USERSET,PGC_S_SESSION,
2871-
GUC_ACTION_LOCAL, true,0);
2869+
AtEOXact_GUC(true,save_nestlevel);
28722870

28732871
return true;
28742872
}

‎src/backend/utils/misc/guc.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4329,8 +4329,9 @@ AtStart_GUC(void)
43294329

43304330
/*
43314331
* Enter a new nesting level for GUC values. This is called at subtransaction
4332-
* start and when entering a function that has proconfig settings.NOTE that
4333-
* we must not risk error here, else subtransaction start will be unhappy.
4332+
* start, and when entering a function that has proconfig settings, and in
4333+
* some other places where we want to set GUC variables transiently.
4334+
* NOTE we must not risk error here, else subtransaction start will be unhappy.
43344335
*/
43354336
int
43364337
NewGUCNestLevel(void)
@@ -4340,8 +4341,9 @@ NewGUCNestLevel(void)
43404341

43414342
/*
43424343
* Do GUC processing at transaction or subtransaction commit or abort, or
4343-
* when exiting a function that has proconfig settings. (The name is thus
4344-
* a bit of a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
4344+
* when exiting a function that has proconfig settings, or when undoing a
4345+
* transient assignment to some GUC variables. (The name is thus a bit of
4346+
* a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
43454347
* During abort, we discard all GUC settings that were applied at nesting
43464348
* levels >= nestLevel. nestLevel == 1 corresponds to the main transaction.
43474349
*/
@@ -4374,11 +4376,11 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
43744376
GucStack*stack;
43754377

43764378
/*
4377-
* Process and pop each stack entry within the nest level.To
4378-
*simplifyfmgr_security_definer(), we allow failure exit from a
4379-
*function-with-SET-options to be recovered at the surrounding
4380-
* transaction or subtransaction abort; so there could be more than
4381-
* one stack entry to pop.
4379+
* Process and pop each stack entry within the nest level. To simplify
4380+
* fmgr_security_definer() and other places that use GUC_ACTION_SAVE,
4381+
*we allow failure exit from code that uses a local nest level to be
4382+
*recovered at the surroundingtransaction or subtransaction abort;
4383+
*so there could be more thanone stack entry to pop.
43824384
*/
43834385
while ((stack=gconf->stack)!=NULL&&
43844386
stack->nest_level >=nestLevel)

‎src/include/utils/guc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ typedef enum
155155
/* Types of set_config_option actions */
156156
GUC_ACTION_SET,/* regular SET command */
157157
GUC_ACTION_LOCAL,/* SET LOCAL command */
158-
GUC_ACTION_SAVE/* function SET option */
158+
GUC_ACTION_SAVE/* function SET option, or temp assignment */
159159
}GucAction;
160160

161161
#defineGUC_QUALIFIER_SEPARATOR '.'

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp