summaryrefslogtreecommitdiff
path: root/src/backend/commands/extension.c
diff options
context:
space:
mode:
authorTom Lane2011-10-06 00:44:16 +0000
committerTom Lane2011-10-06 00:44:16 +0000
commitba6f629326be365a3124dc80aa5d303e2b0bf46b (patch)
treef103794eff5aa9bdfc893e178520a62a826eacab /src/backend/commands/extension.c
parent3919ad864d7040361fd4b44719acaa1ec0f87bbd (diff)
Improve and simplify CREATE EXTENSION's management of GUC variables.
CREATE EXTENSION needs to transiently set search_path, as well as client_min_messages and log_min_messages. We were doing this by the expedient of saving the current string value of each variable, doing a SET LOCAL, and then doing another SET LOCAL with the previous value at the end of the command. This is a bit expensive though, and it also fails badly if there is anything funny about the existing search_path value, as seen in a recent report from Roger Niederland. Fortunately, there's a much better way, which is to piggyback on the GUC infrastructure previously developed for functions with SET options. We just open a new GUC nesting level, do our assignments with GUC_ACTION_SAVE, and then close the nesting level when done. This automatically restores the prior settings without a re-parsing pass, so (in principle anyway) there can't be an error. And guc.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 in ri_triggers.c, which I also changed to use the better method, even though there wasn't really much risk of failure there. Also improve the comments in guc.c to reflect this additional usage.
Diffstat (limited to 'src/backend/commands/extension.c')
-rw-r--r--src/backend/commands/extension.c40
1 files changed, 13 insertions, 27 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 5da5981726c..3af15dd38bb 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -774,9 +774,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
const char *schemaName, Oid schemaOid)
{
char *filename;
- char *save_client_min_messages,
- *save_log_min_messages,
- *save_search_path;
+ int save_nestlevel;
StringInfoData pathbuf;
ListCell *lc;
@@ -808,22 +806,20 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
* so that we won't spam the user with useless NOTICE messages from common
* script actions like creating shell types.
*
- * We use the equivalent of SET LOCAL to ensure the setting is undone upon
- * error.
+ * We use the equivalent of a function SET option to allow the setting to
+ * persist for exactly the duration of the script execution. guc.c also
+ * takes care of undoing the setting on error.
*/
- save_client_min_messages =
- pstrdup(GetConfigOption("client_min_messages", false, false));
+ save_nestlevel = NewGUCNestLevel();
+
if (client_min_messages < WARNING)
(void) set_config_option("client_min_messages", "warning",
PGC_USERSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true, 0);
-
- save_log_min_messages =
- pstrdup(GetConfigOption("log_min_messages", false, false));
+ GUC_ACTION_SAVE, true, 0);
if (log_min_messages < WARNING)
(void) set_config_option("log_min_messages", "warning",
PGC_SUSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true, 0);
+ GUC_ACTION_SAVE, true, 0);
/*
* Set up the search path to contain the target schema, then the schemas
@@ -832,10 +828,9 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
*
* Note: it might look tempting to use PushOverrideSearchPath for this,
* but we cannot do that. We have to actually set the search_path GUC in
- * case the extension script examines or changes it.
+ * case the extension script examines or changes it. In any case, the
+ * GUC_ACTION_SAVE method is just as convenient.
*/
- save_search_path = pstrdup(GetConfigOption("search_path", false, false));
-
initStringInfo(&pathbuf);
appendStringInfoString(&pathbuf, quote_identifier(schemaName));
foreach(lc, requiredSchemas)
@@ -849,7 +844,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
(void) set_config_option("search_path", pathbuf.data,
PGC_USERSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true, 0);
+ GUC_ACTION_SAVE, true, 0);
/*
* Set creating_extension and related variables so that
@@ -910,18 +905,9 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
CurrentExtensionObject = InvalidOid;
/*
- * Restore GUC variables for the remainder of the current transaction.
- * Again use SET LOCAL, so we won't affect the session value.
+ * Restore the GUC variables we set above.
*/
- (void) set_config_option("search_path", save_search_path,
- PGC_USERSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true, 0);
- (void) set_config_option("client_min_messages", save_client_min_messages,
- PGC_USERSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true, 0);
- (void) set_config_option("log_min_messages", save_log_min_messages,
- PGC_SUSET, PGC_S_SESSION,
- GUC_ACTION_LOCAL, true, 0);
+ AtEOXact_GUC(true, save_nestlevel);
}
/*