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

📄 define.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * define.c * *	  These routines execute some of the CREATE statements.  In an earlier *	  version of Postgres, these were "define" statements. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/commands/define.c,v 1.29 1999/05/25 16:08:22 momjian Exp $ * * DESCRIPTION *	  The "DefineFoo" routines take the parse tree and pick out the *	  appropriate arguments/flags, passing the results to the *	  corresponding "FooDefine" routines (in src/catalog) that do *	  the actual catalog-munging.  These routines also verify permission *	  of the user to execute the command. * * NOTES *	  These things must be defined and committed in the following order: *		"create function": *				input/output, recv/send procedures *		"create type": *				type *		"create operator": *				operators * *		Most of the parse-tree manipulation routines are defined in *		commands/manip.c. * *------------------------------------------------------------------------- */#include <stdio.h>#include <ctype.h>#include <string.h>#include <math.h>#include <postgres.h>#include <access/heapam.h>#include <catalog/catname.h>#include <catalog/pg_aggregate.h>#include <catalog/pg_operator.h>#include <catalog/pg_proc.h>#include <catalog/pg_type.h>#include <catalog/pg_language.h>#include <utils/syscache.h>#include <fmgr.h>				/* for fmgr */#include <utils/builtins.h>		/* prototype for textin() */#include <commands/defrem.h>#include <optimizer/xfunc.h>#include <tcop/dest.h>#include <catalog/pg_shadow.h>static char *defGetString(DefElem *def);static int	defGetTypeLength(DefElem *def);#define DEFAULT_TYPDELIM		','static voidcase_translate_language_name(const char *input, char *output){/*-------------------------------------------------------------------------  Translate the input language name to lower case, except if it's C,  translate to upper case.--------------------------------------------------------------------------*/	int			i;	for (i = 0; i < NAMEDATALEN && input[i]; ++i)		output[i] = tolower(input[i]);	output[i] = '\0';	if (strcmp(output, "c") == 0)		output[0] = 'C';}static voidcompute_return_type(const Node *returnType,					char **prorettype_p, bool *returnsSet_p){/*---------------------------------------------------------------------------   Examine the "returns" clause returnType of the CREATE FUNCTION statement   and return information about it as **prorettype_p and **returnsSet.----------------------------------------------------------------------------*/	if (nodeTag(returnType) == T_TypeName)	{		/* a set of values */		TypeName   *setType = (TypeName *) returnType;		*prorettype_p = setType->name;		*returnsSet_p = setType->setof;	}	else	{		/* singleton */		*prorettype_p = strVal(returnType);		*returnsSet_p = false;	}}static voidcompute_full_attributes(const List *parameters, int32 *byte_pct_p,						int32 *perbyte_cpu_p, int32 *percall_cpu_p,						int32 *outin_ratio_p, bool *canCache_p){/*--------------------------------------------------------------------------  Interpret the parameters *parameters and return their contents as  *byte_pct_p, etc.  These are the full parameters of a C or internal function.---------------------------------------------------------------------------*/	List	   *pl;	/* the defaults */	*byte_pct_p = BYTE_PCT;	*perbyte_cpu_p = PERBYTE_CPU;	*percall_cpu_p = PERCALL_CPU;	*outin_ratio_p = OUTIN_RATIO;	foreach(pl, (List *) parameters)	{		ParamString *param = (ParamString *) lfirst(pl);		if (strcasecmp(param->name, "iscachable") == 0)			*canCache_p = true;		else if (strcasecmp(param->name, "trusted") == 0)		{			/*			 * we don't have untrusted functions any more. The 4.2			 * implementation is lousy anyway so I took it out. -ay 10/94			 */			elog(ERROR, "untrusted function has been decommissioned.");		}		else if (strcasecmp(param->name, "byte_pct") == 0)		{			/*			 * * handle expensive function parameters			 */			*byte_pct_p = atoi(param->val);		}		else if (strcasecmp(param->name, "perbyte_cpu") == 0)		{			if (sscanf(param->val, "%d", perbyte_cpu_p) == 0)			{				int			count;				char	   *ptr;				for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)					if (*ptr == '!')						count++;				*perbyte_cpu_p = (int) pow(10.0, (double) count);			}		}		else if (strcasecmp(param->name, "percall_cpu") == 0)		{			if (sscanf(param->val, "%d", percall_cpu_p) == 0)			{				int			count;				char	   *ptr;				for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)					if (*ptr == '!')						count++;				*percall_cpu_p = (int) pow(10.0, (double) count);			}		}		else if (strcasecmp(param->name, "outin_ratio") == 0)			*outin_ratio_p = atoi(param->val);	}}static voidinterpret_AS_clause(const char *languageName, const char *as,					char **prosrc_str_p, char **probin_str_p){	if (strcmp(languageName, "C") == 0)	{		/* For "C" language, store the given string in probin */		*prosrc_str_p = "-";		*probin_str_p = (char *) as;	}	else	{		/* Everything else wants the given string in prosrc */		*prosrc_str_p = (char *) as;		*probin_str_p = "-";	}}/* * CreateFunction *	 Execute a CREATE FUNCTION utility statement. * */voidCreateFunction(ProcedureStmt *stmt, CommandDest dest){	char	   *probin_str;	/* pathname of executable file that executes this function, if any */	char	   *prosrc_str;	/* SQL that executes this function, if any */	char	   *prorettype;	/* Type of return value (or member of set of values) from function */	char		languageName[NAMEDATALEN];	/*	 * name of language of function, with case adjusted: "C", "internal",	 * or "SQL"	 */	/*	 * The following are attributes of the function, as expressed in the	 * CREATE FUNCTION statement, where applicable.	 */	int32		byte_pct,				perbyte_cpu,				percall_cpu,				outin_ratio;	bool		canCache;	bool		returnsSet;	bool		lanisPL = false;	/* The function returns a set of values, as opposed to a singleton. */	case_translate_language_name(stmt->language, languageName);	compute_return_type(stmt->returnType, &prorettype, &returnsSet);	if (strcmp(languageName, "C") == 0 ||		strcmp(languageName, "internal") == 0)	{		compute_full_attributes(stmt->withClause,								&byte_pct, &perbyte_cpu, &percall_cpu,								&outin_ratio, &canCache);	}	else if (strcmp(languageName, "sql") == 0)	{		/* query optimizer groks sql, these are meaningless */		perbyte_cpu = percall_cpu = 0;		byte_pct = outin_ratio = 100;		canCache = false;	}	else	{		HeapTuple	languageTuple;		Form_pg_language languageStruct;		/* Lookup the language in the system cache */		languageTuple = SearchSysCacheTuple(LANNAME,											PointerGetDatum(languageName),											0, 0, 0);		if (!HeapTupleIsValid(languageTuple))		{			elog(ERROR,				 "Unrecognized language specified in a CREATE FUNCTION: "				 "'%s'.  Recognized languages are sql, C, internal "				 "and the created procedural languages.",				 languageName);		}		/* Check that this language is a PL */		languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);		if (!(languageStruct->lanispl))		{			elog(ERROR,				 "Language '%s' isn't defined as PL", languageName);		}		/*		 * Functions in untrusted procedural languages are restricted to		 * be defined by postgres superusers only		 */		if (languageStruct->lanpltrusted == false && !superuser())		{			elog(ERROR, "Only users with Postgres superuser privilege "				 "are permitted to create a function in the '%s' "				 "language.",				 languageName);		}		lanisPL = true;		/*		 * These are meaningless		 */		perbyte_cpu = percall_cpu = 0;		byte_pct = outin_ratio = 100;		canCache = false;	}	interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);	if (strcmp(languageName, "sql") != 0 && lanisPL == false && !superuser())		elog(ERROR,			 "Only users with Postgres superuser privilege are permitted "			 "to create a function "			 "in the '%s' language.  Others may use the 'sql' language "			 "or the created procedural languages.",			 languageName);	/* Above does not return. */	else	{		/*		 * And now that we have all the parameters, and know we're		 * permitted to do so, go ahead and create the function.		 */		ProcedureCreate(stmt->funcname,						returnsSet,						prorettype,						languageName,						prosrc_str,		/* converted to text later */						probin_str,		/* converted to text later */						canCache,						true,	/* (obsolete "trusted") */						byte_pct,						perbyte_cpu,						percall_cpu,						outin_ratio,						stmt->defArgs,						dest);	}}/* -------------------------------- * DefineOperator * *		this function extracts all the information from the *		parameter list generated by the parser and then has *		OperatorCreate() do all the actual work. * * 'parameters' is a list of DefElem * -------------------------------- */voidDefineOperator(char *oprName,			   List *parameters){	uint16		precedence = 0; /* operator precedence */	bool		canHash = false;/* operator hashes */	bool		isLeftAssociative = true;		/* operator is left

⌨️ 快捷键说明

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