⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variable.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/* * Routines for handling of 'SET var TO', *	'SHOW var' and 'RESET var' statements. * * $Id: variable.c,v 1.23.2.1 1999/08/02 05:57:00 scrappy Exp $ * */#include <ctype.h>#include <time.h>#include "postgres.h"#include "access/xact.h"#include "commands/variable.h"#include "miscadmin.h"#include "optimizer/internal.h"#include "utils/builtins.h"#include "utils/tqual.h"#ifdef MULTIBYTE#include "mb/pg_wchar.h"#endifstatic bool show_date(void);static bool reset_date(void);static bool parse_date(const char *);static bool show_timezone(void);static bool reset_timezone(void);static bool parse_timezone(const char *);static bool show_cost_heap(void);static bool reset_cost_heap(void);static bool parse_cost_heap(const char *);static bool show_cost_index(void);static bool reset_cost_index(void);static bool parse_cost_index(const char *);static bool reset_geqo(void);static bool show_geqo(void);static bool parse_geqo(const char *);static bool show_ksqo(void);static bool reset_ksqo(void);static bool parse_ksqo(const char *);static bool show_XactIsoLevel(void);static bool reset_XactIsoLevel(void);static bool parse_XactIsoLevel(const char *);extern Cost _cpu_page_weight_;extern Cost _cpu_index_page_weight_;extern bool _use_geqo_;extern int32 _use_geqo_rels_;extern bool _use_keyset_query_optimizer;/* * * Get_Token * */static const char *get_token(char **tok, char **val, const char *str){	const char *start;	int			len = 0;	*tok = NULL;	if (val != NULL)		*val = NULL;	if (!(*str))		return NULL;	/* skip white spaces */	while (isspace(*str))		str++;	if (*str == ',' || *str == '=')		elog(ERROR, "Syntax error near (%s): empty setting", str);	/* end of string? then return NULL */	if (!(*str))		return NULL;	/* OK, at beginning of non-NULL string... */	start = str;	/*	 * count chars in token until we hit white space or comma or '=' or	 * end of string	 */	while (*str && (!isspace(*str))		   && *str != ',' && *str != '=')	{		str++;		len++;	}	*tok = (char *) palloc(len + 1);	StrNCpy(*tok, start, len + 1);	/* skip white spaces */	while (isspace(*str))		str++;	/* end of string? */	if (!(*str))	{		return str;		/* delimiter? */	}	else if (*str == ',')	{		return ++str;	}	else if ((val == NULL) || (*str != '='))	{		elog(ERROR, "Syntax error near (%s)", str);	};	str++;						/* '=': get value */	len = 0;	/* skip white spaces */	while (isspace(*str))		str++;	if (*str == ',' || !(*str))		elog(ERROR, "Syntax error near (=%s)", str);	start = str;	/*	 * count chars in token's value until we hit white space or comma or	 * end of string	 */	while (*str && (!isspace(*str)) && *str != ',')	{		str++;		len++;	}	*val = (char *) palloc(len + 1);	StrNCpy(*val, start, len + 1);	/* skip white spaces */	while (isspace(*str))		str++;	if (!(*str))		return NULL;	if (*str == ',')		return ++str;	elog(ERROR, "Syntax error near (%s)", str);	return str;}/* * * GEQO * */static boolparse_geqo(const char *value){	const char *rest;	char	   *tok,			   *val;	if (value == NULL)	{		reset_geqo();		return TRUE;	}	rest = get_token(&tok, &val, value);	if (tok == NULL)		elog(ERROR, "Value undefined");	if ((rest) && (*rest != '\0'))		elog(ERROR, "Unable to parse '%s'", value);	if (strcasecmp(tok, "on") == 0)	{		int32		geqo_rels = GEQO_RELS;		if (val != NULL)		{			geqo_rels = pg_atoi(val, sizeof(int32), '\0');			if (geqo_rels <= 1)				elog(ERROR, "Bad value for # of relations (%s)", val);			pfree(val);		}		_use_geqo_ = true;		_use_geqo_rels_ = geqo_rels;	}	else if (strcasecmp(tok, "off") == 0)	{		if ((val != NULL) && (*val != '\0'))			elog(ERROR, "%s does not allow a parameter", tok);		_use_geqo_ = false;	}	else		elog(ERROR, "Bad value for GEQO (%s)", value);	pfree(tok);	return TRUE;}static boolshow_geqo(){	if (_use_geqo_)		elog(NOTICE, "GEQO is ON beginning with %d relations", _use_geqo_rels_);	else		elog(NOTICE, "GEQO is OFF");	return TRUE;}static boolreset_geqo(void){#ifdef GEQO	_use_geqo_ = true;#else	_use_geqo_ = false;#endif	_use_geqo_rels_ = GEQO_RELS;	return TRUE;}/* * * COST_HEAP * */static boolparse_cost_heap(const char *value){	float32		res;	if (value == NULL)	{		reset_cost_heap();		return TRUE;	}	res = float4in((char *) value);	_cpu_page_weight_ = *res;	return TRUE;}static boolshow_cost_heap(){	elog(NOTICE, "COST_HEAP is %f", _cpu_page_weight_);	return TRUE;}static boolreset_cost_heap(){	_cpu_page_weight_ = _CPU_PAGE_WEIGHT_;	return TRUE;}/* * * COST_INDEX * */static boolparse_cost_index(const char *value){	float32		res;	if (value == NULL)	{		reset_cost_index();		return TRUE;	}	res = float4in((char *) value);	_cpu_index_page_weight_ = *res;	return TRUE;}static boolshow_cost_index(){	elog(NOTICE, "COST_INDEX is %f", _cpu_index_page_weight_);	return TRUE;}static boolreset_cost_index(){	_cpu_index_page_weight_ = _CPU_INDEX_PAGE_WEIGHT_;	return TRUE;}/* * * DATE_STYLE * */static boolparse_date(const char *value){	char	   *tok;	int			dcnt = 0,				ecnt = 0;	if (value == NULL)	{		reset_date();		return TRUE;	}	while ((value = get_token(&tok, NULL, value)) != 0)	{		/* Ugh. Somebody ought to write a table driven version -- mjl */		if (!strcasecmp(tok, "ISO"))		{			DateStyle = USE_ISO_DATES;			dcnt++;		}		else if (!strcasecmp(tok, "SQL"))		{			DateStyle = USE_SQL_DATES;			dcnt++;		}		else if (!strcasecmp(tok, "POSTGRES"))		{			DateStyle = USE_POSTGRES_DATES;			dcnt++;		}		else if (!strcasecmp(tok, "GERMAN"))		{			DateStyle = USE_GERMAN_DATES;			dcnt++;			EuroDates = TRUE;			if ((ecnt > 0) && (!EuroDates))				ecnt++;		}		else if (!strncasecmp(tok, "EURO", 4))		{			EuroDates = TRUE;			if ((dcnt <= 0) || (DateStyle != USE_GERMAN_DATES))				ecnt++;		}		else if ((!strcasecmp(tok, "US"))				 || (!strncasecmp(tok, "NONEURO", 7)))		{			EuroDates = FALSE;			if ((dcnt <= 0) || (DateStyle == USE_GERMAN_DATES))				ecnt++;		}		else if (!strcasecmp(tok, "DEFAULT"))		{			DateStyle = USE_POSTGRES_DATES;			EuroDates = FALSE;			ecnt++;		}		else			elog(ERROR, "Bad value for date style (%s)", tok);		pfree(tok);	}	if (dcnt > 1 || ecnt > 1)		elog(NOTICE, "Conflicting settings for date");	return TRUE;}static boolshow_date(){	char		buf[64];	strcpy(buf, "DateStyle is ");	switch (DateStyle)	{		case USE_ISO_DATES:			strcat(buf, "ISO");			break;		case USE_SQL_DATES:			strcat(buf, "SQL");			break;		case USE_GERMAN_DATES:			strcat(buf, "German");			break;		default:			strcat(buf, "Postgres");			break;	};	strcat(buf, " with ");	strcat(buf, ((EuroDates) ? "European" : "US (NonEuropean)"));	strcat(buf, " conventions");	elog(NOTICE, buf, NULL);	return TRUE;}static boolreset_date(){	DateStyle = USE_POSTGRES_DATES;	EuroDates = FALSE;	return TRUE;}/* Timezone support * Working storage for strings is allocated with an arbitrary size of 64 bytes. */static char *defaultTZ = NULL;static char TZvalue[64];static char tzbuf[64];/* * * TIMEZONE * *//* parse_timezone() * Handle SET TIME ZONE... * Try to save existing TZ environment variable for later use in RESET TIME ZONE. * - thomas 1997-11-10 */static boolparse_timezone(const char *value){	char	   *tok;	if (value == NULL)	{		reset_timezone();		return TRUE;	}	while ((value = get_token(&tok, NULL, value)) != 0)	{		/* Not yet tried to save original value from environment? */		if (defaultTZ == NULL)		{			/* found something? then save it for later */			if ((defaultTZ = getenv("TZ")) != NULL)				strcpy(TZvalue, defaultTZ);			/* found nothing so mark with an invalid pointer */			else				defaultTZ = (char *) -1;		}		strcpy(tzbuf, "TZ=");		strcat(tzbuf, tok);		if (putenv(tzbuf) != 0)			elog(ERROR, "Unable to set TZ environment variable to %s", tok);		tzset();		pfree(tok);	}	return TRUE;}	/* parse_timezone() */static boolshow_timezone(){	char	   *tz;	tz = getenv("TZ");	elog(NOTICE, "Time zone is %s", ((tz != NULL) ? tz : "unknown"));	return TRUE;}	/* show_timezone() *//* reset_timezone() * Set TZ environment variable to original value. * Note that if TZ was originally not set, TZ should be cleared. * 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 */static boolreset_timezone(){	/* no time zone has been set in this session? */	if (defaultTZ == NULL)	{	}	/* time zone was set and original explicit time zone available? */	else if (defaultTZ != (char *) -1)	{		strcpy(tzbuf, "TZ=");		strcat(tzbuf, TZvalue);		if (putenv(tzbuf) != 0)			elog(ERROR, "Unable to set TZ environment variable to %s", TZvalue);		tzset();	}	/*	 * otherwise, time zone was set but no original explicit time zone	 * available	 */	else	{		strcpy(tzbuf, "=");		if (putenv(tzbuf) != 0)			elog(ERROR, "Unable to clear TZ environment variable", NULL);		tzset();	}	return TRUE;}	/* reset_timezone() *//*-----------------------------------------------------------------------*/struct VariableParsers{	const char *name;	bool		(*parser) (const char *);	bool		(*show) ();	bool		(*reset) ();}			VariableParsers[] ={	{		"datestyle", parse_date, show_date, reset_date	},	{		"timezone", parse_timezone, show_timezone, reset_timezone	},	{		"cost_heap", parse_cost_heap, show_cost_heap, reset_cost_heap	},	{		"cost_index", parse_cost_index, show_cost_index, reset_cost_index	},	{		"geqo", parse_geqo, show_geqo, reset_geqo	},#ifdef MULTIBYTE	{		"client_encoding", parse_client_encoding, show_client_encoding, reset_client_encoding	},	{		"server_encoding", parse_server_encoding, show_server_encoding, reset_server_encoding	},#endif	{		"ksqo", parse_ksqo, show_ksqo, reset_ksqo	},	{		"XactIsoLevel", parse_XactIsoLevel, show_XactIsoLevel, reset_XactIsoLevel	},	{		NULL, NULL, NULL, NULL	}};/*-----------------------------------------------------------------------*/boolSetPGVariable(const char *name, const char *value){	struct VariableParsers *vp;	for (vp = VariableParsers; vp->name; vp++)	{		if (!strcasecmp(vp->name, name))			return (vp->parser) (value);	}	elog(NOTICE, "Unrecognized variable %s", name);	return TRUE;}/*-----------------------------------------------------------------------*/boolGetPGVariable(const char *name){	struct VariableParsers *vp;	for (vp = VariableParsers; vp->name; vp++)	{		if (!strcasecmp(vp->name, name))			return (vp->show) ();	}	elog(NOTICE, "Unrecognized variable %s", name);	return TRUE;}/*-----------------------------------------------------------------------*/boolResetPGVariable(const char *name){	struct VariableParsers *vp;	for (vp = VariableParsers; vp->name; vp++)	{		if (!strcasecmp(vp->name, name))			return (vp->reset) ();	}	elog(NOTICE, "Unrecognized variable %s", name);	return TRUE;}/*-----------------------------------------------------------------------KSQO code will one day be unnecessary when the optimizer makes use ofindexes when multiple ORs are specified in the where clause.See optimizer/prep/prepkeyset.c for more on this.	daveh@insightdist.com	 6/16/98-----------------------------------------------------------------------*/static boolparse_ksqo(const char *value){	if (value == NULL)	{		reset_ksqo();		return TRUE;	}	if (strcasecmp(value, "on") == 0)		_use_keyset_query_optimizer = true;	else if (strcasecmp(value, "off") == 0)		_use_keyset_query_optimizer = false;	else		elog(ERROR, "Bad value for Key Set Query Optimizer (%s)", value);	return TRUE;}static boolshow_ksqo(){	if (_use_keyset_query_optimizer)		elog(NOTICE, "Key Set Query Optimizer is ON");	else		elog(NOTICE, "Key Set Query Optimizer is OFF");	return TRUE;}static boolreset_ksqo(){	_use_keyset_query_optimizer = false;	return TRUE;}/* SET TRANSACTION */static boolparse_XactIsoLevel(const char *value){	if (value == NULL)	{		reset_XactIsoLevel();		return TRUE;	}	if (SerializableSnapshot != NULL)	{		elog(ERROR, "SET TRANSACTION ISOLATION LEVEL must be called before any query");		return TRUE;	}	if (strcasecmp(value, "SERIALIZABLE") == 0)		XactIsoLevel = XACT_SERIALIZABLE;	else if (strcasecmp(value, "COMMITTED") == 0)		XactIsoLevel = XACT_READ_COMMITTED;	else		elog(ERROR, "Bad TRANSACTION ISOLATION LEVEL (%s)", value);	return TRUE;}static boolshow_XactIsoLevel(){	if (XactIsoLevel == XACT_SERIALIZABLE)		elog(NOTICE, "TRANSACTION ISOLATION LEVEL is SERIALIZABLE");	else		elog(NOTICE, "TRANSACTION ISOLATION LEVEL is READ COMMITTED");	return TRUE;}static boolreset_XactIsoLevel(){	if (SerializableSnapshot != NULL)	{		elog(ERROR, "SET TRANSACTION ISOLATION LEVEL must be called before any query");		return TRUE;	}	XactIsoLevel = DefaultXactIsoLevel;	return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -