summaryrefslogtreecommitdiff
path: root/src/backend/commands/variable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/variable.c')
-rw-r--r--src/backend/commands/variable.c587
1 files changed, 0 insertions, 587 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
deleted file mode 100644
index 70e7e88d60c..00000000000
--- a/src/backend/commands/variable.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * variable.c
- * Routines for handling specialized SET variables.
- *
- *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.69 2002/06/20 20:29:27 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include <ctype.h>
-#include <time.h>
-
-#include "access/xact.h"
-#include "catalog/pg_shadow.h"
-#include "commands/variable.h"
-#include "miscadmin.h"
-#include "utils/builtins.h"
-#include "utils/guc.h"
-#include "utils/syscache.h"
-#include "utils/tqual.h"
-
-#ifdef MULTIBYTE
-#include "mb/pg_wchar.h"
-#else
-/* Grand unified hard-coded badness */
-#define pg_get_client_encoding_name() "SQL_ASCII"
-#define GetDatabaseEncodingName() "SQL_ASCII"
-#endif
-
-
-/*
- * DATESTYLE
- */
-
-/*
- * assign_datestyle: GUC assign_hook for datestyle
- */
-const char *
-assign_datestyle(const char *value, bool doit, bool interactive)
-{
- int newDateStyle = DateStyle;
- bool newEuroDates = EuroDates;
- bool ok = true;
- int dcnt = 0,
- ecnt = 0;
- char *rawstring;
- char *result;
- List *elemlist;
- List *l;
-
- /* Need a modifiable copy of string */
- rawstring = pstrdup(value);
-
- /* Parse string into list of identifiers */
- if (!SplitIdentifierString(rawstring, ',', &elemlist))
- {
- /* syntax error in list */
- pfree(rawstring);
- freeList(elemlist);
- if (interactive)
- elog(ERROR, "SET DATESTYLE: invalid list syntax");
- return NULL;
- }
-
- foreach(l, elemlist)
- {
- char *tok = (char *) lfirst(l);
-
- /* Ugh. Somebody ought to write a table driven version -- mjl */
-
- if (strcasecmp(tok, "ISO") == 0)
- {
- newDateStyle = USE_ISO_DATES;
- dcnt++;
- }
- else if (strcasecmp(tok, "SQL") == 0)
- {
- newDateStyle = USE_SQL_DATES;
- dcnt++;
- }
- else if (strncasecmp(tok, "POSTGRESQL", 8) == 0)
- {
- newDateStyle = USE_POSTGRES_DATES;
- dcnt++;
- }
- else if (strcasecmp(tok, "GERMAN") == 0)
- {
- newDateStyle = USE_GERMAN_DATES;
- dcnt++;
- if ((ecnt > 0) && (!newEuroDates))
- ok = false;
- newEuroDates = TRUE;
- }
- else if (strncasecmp(tok, "EURO", 4) == 0)
- {
- newEuroDates = TRUE;
- ecnt++;
- }
- else if (strcasecmp(tok, "US") == 0
- || strncasecmp(tok, "NONEURO", 7) == 0)
- {
- newEuroDates = FALSE;
- ecnt++;
- if ((dcnt > 0) && (newDateStyle == USE_GERMAN_DATES))
- ok = false;
- }
- else if (strcasecmp(tok, "DEFAULT") == 0)
- {
- /*
- * Easiest way to get the current DEFAULT state is to fetch
- * the DEFAULT string from guc.c and recursively parse it.
- *
- * We can't simply "return assign_datestyle(...)" because we
- * need to handle constructs like "DEFAULT, ISO".
- */
- int saveDateStyle = DateStyle;
- bool saveEuroDates = EuroDates;
- const char *subval;
-
- subval = assign_datestyle(GetConfigOptionResetString("datestyle"),
- true, interactive);
- newDateStyle = DateStyle;
- newEuroDates = EuroDates;
- DateStyle = saveDateStyle;
- EuroDates = saveEuroDates;
- if (!subval)
- {
- ok = false;
- break;
- }
- /* Here we know that our own return value is always malloc'd */
- /* when doit is true */
- free((char *) subval);
- dcnt++;
- ecnt++;
- }
- else
- {
- if (interactive)
- elog(ERROR, "SET DATESTYLE: unrecognized keyword %s", tok);
- ok = false;
- break;
- }
- }
-
- if (dcnt > 1 || ecnt > 1)
- ok = false;
-
- pfree(rawstring);
- freeList(elemlist);
-
- if (!ok)
- {
- if (interactive)
- elog(ERROR, "SET DATESTYLE: conflicting specifications");
- return NULL;
- }
-
- /*
- * If we aren't going to do the assignment, just return OK indicator.
- */
- if (!doit)
- return value;
-
- /*
- * Prepare the canonical string to return. GUC wants it malloc'd.
- */
- result = (char *) malloc(32);
- if (!result)
- return NULL;
-
- switch (newDateStyle)
- {
- case USE_ISO_DATES:
- strcpy(result, "ISO");
- break;
- case USE_SQL_DATES:
- strcpy(result, "SQL");
- break;
- case USE_GERMAN_DATES:
- strcpy(result, "GERMAN");
- break;
- default:
- strcpy(result, "POSTGRESQL");
- break;
- }
- strcat(result, newEuroDates ? ", EURO" : ", US");
-
- /*
- * Finally, it's safe to assign to the global variables;
- * the assignment cannot fail now.
- */
- DateStyle = newDateStyle;
- EuroDates = newEuroDates;
-
- return result;
-}
-
-/*
- * show_datestyle: GUC show_hook for datestyle
- */
-const char *
-show_datestyle(void)
-{
- static char buf[64];
-
- switch (DateStyle)
- {
- case USE_ISO_DATES:
- strcpy(buf, "ISO");
- break;
- case USE_SQL_DATES:
- strcpy(buf, "SQL");
- break;
- case USE_GERMAN_DATES:
- strcpy(buf, "German");
- break;
- default:
- strcpy(buf, "Postgres");
- break;
- };
- strcat(buf, " with ");
- strcat(buf, ((EuroDates) ? "European" : "US (NonEuropean)"));
- strcat(buf, " conventions");
-
- return buf;
-}
-
-
-/*
- * TIMEZONE
- */
-
-/*
- * Storage for TZ env var is allocated with an arbitrary size of 64 bytes.
- */
-static char tzbuf[64];
-
-/*
- * assign_timezone: GUC assign_hook for timezone
- */
-const char *
-assign_timezone(const char *value, bool doit, bool interactive)
-{
- char *result;
- char *endptr;
- double hours;
-
- /*
- * Check for INTERVAL 'foo'
- */
- if (strncasecmp(value, "interval", 8) == 0)
- {
- const char *valueptr = value;
- char *val;
- Interval *interval;
-
- valueptr += 8;
- while (isspace((unsigned char) *valueptr))
- valueptr++;
- if (*valueptr++ != '\'')
- return NULL;
- val = pstrdup(valueptr);
- /* Check and remove trailing quote */
- endptr = strchr(val, '\'');
- if (!endptr || endptr[1] != '\0')
- {
- pfree(val);
- return NULL;
- }
- *endptr = '\0';
- /*
- * Try to parse it. XXX an invalid interval format will result in
- * elog, which is not desirable for GUC. We did what we could to
- * guard against this in flatten_set_variable_args, but a string
- * coming in from postgresql.conf might contain anything.
- */
- interval = DatumGetIntervalP(DirectFunctionCall3(interval_in,
- CStringGetDatum(val),
- ObjectIdGetDatum(InvalidOid),
- Int32GetDatum(-1)));
- pfree(val);
- if (interval->month != 0)
- {
- if (interactive)
- elog(ERROR, "SET TIME ZONE: illegal INTERVAL; month not allowed");
- pfree(interval);
- return NULL;
- }
- if (doit)
- {
- CTimeZone = interval->time;
- HasCTZSet = true;
- }
- pfree(interval);
- }
- else
- {
- /*
- * Try it as a numeric number of hours (possibly fractional).
- */
- hours = strtod(value, &endptr);
- if (endptr != value && *endptr == '\0')
- {
- if (doit)
- {
- CTimeZone = hours * 3600;
- HasCTZSet = true;
- }
- }
- else if (strcasecmp(value, "UNKNOWN") == 0)
- {
- /*
- * Clear any TZ value we may have established.
- *
- * unsetenv() works fine, but is BSD, not POSIX, and is not
- * available under Solaris, among others. Apparently putenv()
- * called as below clears the process-specific environment
- * variables. Other reasonable arguments to putenv() (e.g.
- * "TZ=", "TZ", "") result in a core dump (under Linux anyway).
- * - thomas 1998-01-26
- */
- if (doit)
- {
- if (tzbuf[0] == 'T')
- {
- strcpy(tzbuf, "=");
- if (putenv(tzbuf) != 0)
- elog(ERROR, "Unable to clear TZ environment variable");
- tzset();
- }
- HasCTZSet = false;
- }
- }
- else
- {
- /*
- * Otherwise assume it is a timezone name.
- *
- * XXX unfortunately we have no reasonable way to check whether a
- * timezone name is good, so we have to just assume that it is.
- */
- if (doit)
- {
- strcpy(tzbuf, "TZ=");
- strncat(tzbuf, value, sizeof(tzbuf)-4);
- if (putenv(tzbuf) != 0) /* shouldn't happen? */
- elog(LOG, "assign_timezone: putenv failed");
- tzset();
- HasCTZSet = false;
- }
- }
- }
-
- /*
- * If we aren't going to do the assignment, just return OK indicator.
- */
- if (!doit)
- return value;
-
- /*
- * Prepare the canonical string to return. GUC wants it malloc'd.
- */
- result = (char *) malloc(sizeof(tzbuf));
- if (!result)
- return NULL;
-
- if (HasCTZSet)
- {
- snprintf(result, sizeof(tzbuf), "%.5f",
- (double) CTimeZone / 3600.0);
- }
- else if (tzbuf[0] == 'T')
- {
- strcpy(result, tzbuf + 3);
- }
- else
- {
- strcpy(result, "UNKNOWN");
- }
-
- return result;
-}
-
-/*
- * show_timezone: GUC show_hook for timezone
- */
-const char *
-show_timezone(void)
-{
- char *tzn;
-
- if (HasCTZSet)
- {
- Interval interval;
-
- interval.month = 0;
- interval.time = CTimeZone;
-
- tzn = DatumGetCString(DirectFunctionCall1(interval_out,
- IntervalPGetDatum(&interval)));
- }
- else
- tzn = getenv("TZ");
-
- if (tzn != NULL)
- return tzn;
-
- return "unknown";
-}
-
-
-/*
- * SET TRANSACTION ISOLATION LEVEL
- */
-
-const char *
-assign_XactIsoLevel(const char *value, bool doit, bool interactive)
-{
- if (doit && interactive && SerializableSnapshot != NULL)
- elog(ERROR, "SET TRANSACTION ISOLATION LEVEL must be called before any query");
-
- if (strcmp(value, "serializable") == 0)
- { if (doit) XactIsoLevel = XACT_SERIALIZABLE; }
- else if (strcmp(value, "read committed") == 0)
- { if (doit) XactIsoLevel = XACT_READ_COMMITTED; }
- else if (strcmp(value, "default") == 0)
- { if (doit) XactIsoLevel = DefaultXactIsoLevel; }
- else
- return NULL;
-
- return value;
-}
-
-const char *
-show_XactIsoLevel(void)
-{
- if (XactIsoLevel == XACT_SERIALIZABLE)
- return "SERIALIZABLE";
- else
- return "READ COMMITTED";
-}
-
-
-/*
- * Random number seed
- */
-
-bool
-assign_random_seed(double value, bool doit, bool interactive)
-{
- /* Can't really roll back on error, so ignore non-interactive setting */
- if (doit && interactive)
- DirectFunctionCall1(setseed, Float8GetDatum(value));
- return true;
-}
-
-const char *
-show_random_seed(void)
-{
- return "unavailable";
-}
-
-
-/*
- * MULTIBYTE-related functions
- *
- * If MULTIBYTE support was not compiled, we still allow these variables
- * to exist, but you can't set them to anything but "SQL_ASCII". This
- * minimizes interoperability problems between non-MB servers and MB-enabled
- * clients.
- */
-
-const char *
-assign_client_encoding(const char *value, bool doit, bool interactive)
-{
-#ifdef MULTIBYTE
- int encoding;
- int old_encoding = 0;
-
- encoding = pg_valid_client_encoding(value);
- if (encoding < 0)
- return NULL;
- /*
- * Ugly API here ... can't test validity without setting new encoding...
- */
- if (!doit)
- old_encoding = pg_get_client_encoding();
- if (pg_set_client_encoding(encoding) < 0)
- {
- if (interactive)
- elog(ERROR, "Conversion between %s and %s is not supported",
- value, GetDatabaseEncodingName());
- return NULL;
- }
- if (!doit)
- pg_set_client_encoding(old_encoding);
-#else
- if (strcasecmp(value, pg_get_client_encoding_name()) != 0)
- return NULL;
-#endif
-
- return value;
-}
-
-
-const char *
-assign_server_encoding(const char *value, bool doit, bool interactive)
-{
- if (interactive)
- elog(ERROR, "SET SERVER_ENCODING is not supported");
- /* Pretend never to fail in noninteractive case */
- return value;
-}
-
-const char *
-show_server_encoding(void)
-{
- return GetDatabaseEncodingName();
-}
-
-
-/*
- * SET SESSION AUTHORIZATION
- *
- * Note: when resetting session auth after an error, we can't expect to do
- * catalog lookups. Hence, the stored form of the value is always a numeric
- * userid that can be re-used directly.
- */
-const char *
-assign_session_authorization(const char *value, bool doit, bool interactive)
-{
- Oid usesysid;
- char *endptr;
- char *result;
-
- usesysid = (Oid) strtoul(value, &endptr, 10);
-
- if (endptr != value && *endptr == '\0' && OidIsValid(usesysid))
- {
- /* use the numeric user ID */
- }
- else
- {
- HeapTuple userTup;
-
- userTup = SearchSysCache(SHADOWNAME,
- PointerGetDatum(value),
- 0, 0, 0);
- if (!HeapTupleIsValid(userTup))
- {
- if (interactive)
- elog(ERROR, "user \"%s\" does not exist", value);
- return NULL;
- }
-
- usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
-
- ReleaseSysCache(userTup);
- }
-
- if (doit)
- SetSessionAuthorization(usesysid);
-
- result = (char *) malloc(32);
- if (!result)
- return NULL;
-
- snprintf(result, 32, "%lu", (unsigned long) usesysid);
-
- return result;
-}
-
-const char *
-show_session_authorization(void)
-{
- return GetUserNameFromId(GetSessionUserId());
-}