diff options
Diffstat (limited to 'src/backend/utils/misc/guc.c')
-rw-r--r-- | src/backend/utils/misc/guc.c | 188 |
1 files changed, 176 insertions, 12 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 482423f805f..d63d603b1db 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -5,7 +5,7 @@ * command, configuration file, and command line options. * See src/backend/utils/misc/README for more information. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.72 2002/07/18 02:02:30 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.73 2002/07/20 05:49:27 momjian Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -23,8 +23,10 @@ #include "access/xlog.h" #include "catalog/namespace.h" +#include "catalog/pg_type.h" #include "commands/async.h" #include "commands/variable.h" +#include "executor/executor.h" #include "fmgr.h" #include "libpq/auth.h" #include "libpq/pqcomm.h" @@ -826,7 +828,7 @@ static char *guc_string_workspace; /* for avoiding memory leaks */ static int guc_var_compare(const void *a, const void *b); -static void _ShowOption(struct config_generic *record); +static char *_ShowOption(struct config_generic *record); /* @@ -2168,6 +2170,57 @@ SetPGVariable(const char *name, List *args, bool is_local) } /* + * SET command wrapped as a SQL callable function. + */ +Datum +set_config_by_name(PG_FUNCTION_ARGS) +{ + char *name; + char *value; + char *new_value; + bool is_local; + text *result_text; + + if (PG_ARGISNULL(0)) + elog(ERROR, "SET variable name is required"); + + /* Get the GUC variable name */ + name = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); + + /* Get the desired value or set to NULL for a reset request */ + if (PG_ARGISNULL(1)) + value = NULL; + else + value = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); + + /* + * Get the desired state of is_local. Default to false + * if provided value is NULL + */ + if (PG_ARGISNULL(2)) + is_local = false; + else + is_local = PG_GETARG_BOOL(2); + + /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */ + set_config_option(name, + value, + (superuser() ? PGC_SUSET : PGC_USERSET), + PGC_S_SESSION, + is_local, + true); + + /* get the new current value */ + new_value = GetConfigOptionByName(name); + + /* Convert return string to text */ + result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(new_value))); + + /* return it */ + PG_RETURN_TEXT_P(result_text); +} + +/* * SHOW command */ void @@ -2203,13 +2256,26 @@ ResetPGVariable(const char *name) void ShowGUCConfigOption(const char *name) { - struct config_generic *record; + TupOutputState *tstate; + TupleDesc tupdesc; + CommandDest dest = whereToSendOutput; + char *value; - record = find_option(name); - if (record == NULL) - elog(ERROR, "Option '%s' is not recognized", name); + /* need a tuple descriptor representing a single TEXT column */ + tupdesc = CreateTemplateTupleDesc(1); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, (char *) name, + TEXTOID, -1, 0, false); + + /* prepare for projection of tuples */ + tstate = begin_tup_output_tupdesc(dest, tupdesc); - _ShowOption(record); + /* Get the value */ + value = GetConfigOptionByName(name); + + /* Send it */ + PROJECT_LINE_OF_TEXT(value); + + end_tup_output(tstate); } /* @@ -2219,17 +2285,115 @@ void ShowAllGUCConfig(void) { int i; + TupOutputState *tstate; + TupleDesc tupdesc; + CommandDest dest = whereToSendOutput; + char *name; + char *value; + char *values[2]; + + /* need a tuple descriptor representing two TEXT columns */ + tupdesc = CreateTemplateTupleDesc(2); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", + TEXTOID, -1, 0, false); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", + TEXTOID, -1, 0, false); + + /* prepare for projection of tuples */ + tstate = begin_tup_output_tupdesc(dest, tupdesc); for (i = 0; i < num_guc_variables; i++) { - struct config_generic *conf = guc_variables[i]; + /* Get the next GUC variable name and value */ + value = GetConfigOptionByNum(i, &name); + + /* assign to the values array */ + values[0] = name; + values[1] = value; - if ((conf->flags & GUC_NO_SHOW_ALL) == 0) - _ShowOption(conf); + /* send it to dest */ + do_tup_output(tstate, values); + + /* + * clean up + */ + /* we always should have a name */ + pfree(name); + + /* but value can be returned to us as a NULL */ + if (value != NULL) + pfree(value); } + + end_tup_output(tstate); } -static void +/* + * Return GUC variable value by name + */ +char * +GetConfigOptionByName(const char *name) +{ + struct config_generic *record; + + record = find_option(name); + if (record == NULL) + elog(ERROR, "Option '%s' is not recognized", name); + + return _ShowOption(record); +} + +/* + * Return GUC variable value and set varname for a specific + * variable by number. + */ +char * +GetConfigOptionByNum(int varnum, char **varname) +{ + struct config_generic *conf = guc_variables[varnum]; + + *varname = pstrdup(conf->name); + + if ((conf->flags & GUC_NO_SHOW_ALL) == 0) + return _ShowOption(conf); + else + return NULL; +} + +/* + * Return the total number of GUC variables + */ +int +GetNumConfigOptions(void) +{ + return num_guc_variables; +} + +/* + * show_config_by_name - equiv to SHOW X command but implemented as + * a function. + */ +Datum +show_config_by_name(PG_FUNCTION_ARGS) +{ + char *varname; + char *varval; + text *result_text; + + /* Get the GUC variable name */ + varname = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); + + /* Get the value */ + varval = GetConfigOptionByName(varname); + + /* Convert to text */ + result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(varval))); + + /* return it */ + PG_RETURN_TEXT_P(result_text); +} + +static char * _ShowOption(struct config_generic *record) { char buffer[256]; @@ -2297,7 +2461,7 @@ _ShowOption(struct config_generic *record) break; } - elog(INFO, "%s is %s", record->name, val); + return pstrdup(val); } |