FmgrInfo flinfo; /* lookup info for target function */
Oid userid; /* userid to set, or InvalidOid */
List *configNames; /* GUC names to set, or NIL */
+ List *configHandles; /* GUC handles to set, or NIL */
List *configValues; /* GUC values to set, or NIL */
Datum arg; /* passthrough argument for plugin modules */
};
FmgrInfo *save_flinfo;
Oid save_userid;
int save_sec_context;
- ListCell *lc1;
- ListCell *lc2;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
volatile int save_nestlevel;
PgStat_FunctionCallUsage fcusage;
if (!isnull)
{
ArrayType *array;
+ ListCell *lc;
oldcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
array = DatumGetArrayTypeP(datum);
TransformGUCArray(array, &fcache->configNames,
&fcache->configValues);
+
+ /* transform names to config handles to avoid lookup cost */
+ fcache->configHandles = NIL;
+ foreach(lc, fcache->configNames)
+ {
+ char *name = (char *) lfirst(lc);
+
+ fcache->configHandles = lappend(fcache->configHandles,
+ get_config_handle(name));
+ }
+
MemoryContextSwitchTo(oldcxt);
}
SetUserIdAndSecContext(fcache->userid,
save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
- forboth(lc1, fcache->configNames, lc2, fcache->configValues)
+ forthree(lc1, fcache->configNames,
+ lc2, fcache->configHandles,
+ lc3, fcache->configValues)
{
GucContext context = superuser() ? PGC_SUSET : PGC_USERSET;
GucSource source = PGC_S_SESSION;
GucAction action = GUC_ACTION_SAVE;
char *name = lfirst(lc1);
- char *value = lfirst(lc2);
+ config_handle *handle = lfirst(lc2);
+ char *value = lfirst(lc3);
- (void) set_config_option(name, value,
- context, source,
- action, true, 0, false);
+ (void) set_config_with_handle(name, handle, value,
+ context, source, GetUserId(),
+ action, true, 0, false);
}
/* function manager hook */
else
srole = BOOTSTRAP_SUPERUSERID;
- return set_config_option_ext(name, value,
- context, source, srole,
- action, changeVal, elevel,
- is_reload);
+ return set_config_with_handle(name, NULL, value,
+ context, source, srole,
+ action, changeVal, elevel,
+ is_reload);
}
/*
GucContext context, GucSource source, Oid srole,
GucAction action, bool changeVal, int elevel,
bool is_reload)
+{
+ return set_config_with_handle(name, NULL, value,
+ context, source, srole,
+ action, changeVal, elevel,
+ is_reload);
+}
+
+
+/*
+ * set_config_with_handle: takes an optional 'handle' argument, which can be
+ * obtained by the caller from get_config_handle().
+ *
+ * This should be used by callers which repeatedly set the same config
+ * option(s), and want to avoid the overhead of a hash lookup each time.
+ */
+int
+set_config_with_handle(const char *name, config_handle *handle,
+ const char *value,
+ GucContext context, GucSource source, Oid srole,
+ GucAction action, bool changeVal, int elevel,
+ bool is_reload)
{
struct config_generic *record;
union config_var_val newval_union;
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot set parameters during a parallel operation")));
- record = find_option(name, true, false, elevel);
- if (record == NULL)
- return 0;
+ /* if handle is specified, no need to look up option */
+ if (!handle)
+ {
+ record = find_option(name, true, false, elevel);
+ if (record == NULL)
+ return 0;
+ }
+ else
+ record = handle;
/*
* Check if the option can be set at this time. See guc.h for the precise
}
+/*
+ * Retrieve a config_handle for the given name, suitable for calling
+ * set_config_with_handle(). Only return handle to permanent GUC.
+ */
+config_handle *
+get_config_handle(const char *name)
+{
+ struct config_generic *gen = find_option(name, false, false, 0);
+
+ if (gen && ((gen->flags & GUC_CUSTOM_PLACEHOLDER) == 0))
+ return gen;
+
+ return NULL;
+}
+
+
/*
* Set the fields for source file and line number the setting came from.
*/
struct ConfigVariable *next;
} ConfigVariable;
+typedef struct config_generic config_handle;
+
extern bool ParseConfigFile(const char *config_file, bool strict,
const char *calling_file, int calling_lineno,
int depth, int elevel,
Oid srole,
GucAction action, bool changeVal, int elevel,
bool is_reload);
+extern int set_config_with_handle(const char *name, config_handle *handle,
+ const char *value,
+ GucContext context, GucSource source,
+ Oid srole,
+ GucAction action, bool changeVal,
+ int elevel, bool is_reload);
+extern config_handle *get_config_handle(const char *name);
extern void AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt);
extern char *GetConfigOptionByName(const char *name, const char **varname,
bool missing_ok);
color
colormaprange
compare_context
+config_handle
config_var_value
contain_aggs_of_level_context
contain_placeholder_references_context