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

📄 regproc.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/*------------------------------------------------------------------------- * * regproc.c *	  Functions for the built-in types regproc, regclass, regtype, etc. * * These types are all binary-compatible with type Oid, and rely on Oid * for comparison and so forth.  Their only interesting behavior is in * special I/O conversion routines. * * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.105 2008/01/01 19:45:52 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include <ctype.h>#include "access/genam.h"#include "access/heapam.h"#include "catalog/indexing.h"#include "catalog/namespace.h"#include "catalog/pg_operator.h"#include "catalog/pg_proc.h"#include "catalog/pg_ts_config.h"#include "catalog/pg_ts_dict.h"#include "catalog/pg_type.h"#include "miscadmin.h"#include "parser/parse_type.h"#include "utils/builtins.h"#include "utils/fmgroids.h"#include "utils/lsyscache.h"#include "utils/syscache.h"static void parseNameAndArgTypes(const char *string, bool allowNone,					 List **names, int *nargs, Oid *argtypes);/***************************************************************************** *	 USER I/O ROUTINES														 * *****************************************************************************//* * regprocin		- converts "proname" to proc OID * * We also accept a numeric OID, for symmetry with the output routine. * * '-' signifies unknown (OID 0).  In all other cases, the input must * match an existing pg_proc entry. */Datumregprocin(PG_FUNCTION_ARGS){	char	   *pro_name_or_oid = PG_GETARG_CSTRING(0);	RegProcedure result = InvalidOid;	List	   *names;	FuncCandidateList clist;	/* '-' ? */	if (strcmp(pro_name_or_oid, "-") == 0)		PG_RETURN_OID(InvalidOid);	/* Numeric OID? */	if (pro_name_or_oid[0] >= '0' &&		pro_name_or_oid[0] <= '9' &&		strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))	{		result = DatumGetObjectId(DirectFunctionCall1(oidin,										  CStringGetDatum(pro_name_or_oid)));		PG_RETURN_OID(result);	}	/* Else it's a name, possibly schema-qualified */	/*	 * In bootstrap mode we assume the given name is not schema-qualified, and	 * just search pg_proc for a unique match.	This is needed for	 * initializing other system catalogs (pg_namespace may not exist yet, and	 * certainly there are no schemas other than pg_catalog).	 */	if (IsBootstrapProcessingMode())	{		int			matches = 0;		Relation	hdesc;		ScanKeyData skey[1];		SysScanDesc sysscan;		HeapTuple	tuple;		ScanKeyInit(&skey[0],					Anum_pg_proc_proname,					BTEqualStrategyNumber, F_NAMEEQ,					CStringGetDatum(pro_name_or_oid));		hdesc = heap_open(ProcedureRelationId, AccessShareLock);		sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndexId, true,									 SnapshotNow, 1, skey);		while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))		{			result = (RegProcedure) HeapTupleGetOid(tuple);			if (++matches > 1)				break;		}		systable_endscan(sysscan);		heap_close(hdesc, AccessShareLock);		if (matches == 0)			ereport(ERROR,					(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("function \"%s\" does not exist", pro_name_or_oid)));		else if (matches > 1)			ereport(ERROR,					(errcode(ERRCODE_AMBIGUOUS_FUNCTION),					 errmsg("more than one function named \"%s\"",							pro_name_or_oid)));		PG_RETURN_OID(result);	}	/*	 * Normal case: parse the name into components and see if it matches any	 * pg_proc entries in the current search path.	 */	names = stringToQualifiedNameList(pro_name_or_oid);	clist = FuncnameGetCandidates(names, -1);	if (clist == NULL)		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("function \"%s\" does not exist", pro_name_or_oid)));	else if (clist->next != NULL)		ereport(ERROR,				(errcode(ERRCODE_AMBIGUOUS_FUNCTION),				 errmsg("more than one function named \"%s\"",						pro_name_or_oid)));	result = clist->oid;	PG_RETURN_OID(result);}/* * regprocout		- converts proc OID to "pro_name" */Datumregprocout(PG_FUNCTION_ARGS){	RegProcedure proid = PG_GETARG_OID(0);	char	   *result;	HeapTuple	proctup;	if (proid == InvalidOid)	{		result = pstrdup("-");		PG_RETURN_CSTRING(result);	}	proctup = SearchSysCache(PROCOID,							 ObjectIdGetDatum(proid),							 0, 0, 0);	if (HeapTupleIsValid(proctup))	{		Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);		char	   *proname = NameStr(procform->proname);		/*		 * In bootstrap mode, skip the fancy namespace stuff and just return		 * the proc name.  (This path is only needed for debugging output		 * anyway.)		 */		if (IsBootstrapProcessingMode())			result = pstrdup(proname);		else		{			char	   *nspname;			FuncCandidateList clist;			/*			 * Would this proc be found (uniquely!) by regprocin? If not,			 * qualify it.			 */			clist = FuncnameGetCandidates(list_make1(makeString(proname)), -1);			if (clist != NULL && clist->next == NULL &&				clist->oid == proid)				nspname = NULL;			else				nspname = get_namespace_name(procform->pronamespace);			result = quote_qualified_identifier(nspname, proname);		}		ReleaseSysCache(proctup);	}	else	{		/* If OID doesn't match any pg_proc entry, return it numerically */		result = (char *) palloc(NAMEDATALEN);		snprintf(result, NAMEDATALEN, "%u", proid);	}	PG_RETURN_CSTRING(result);}/* *		regprocrecv			- converts external binary format to regproc */Datumregprocrecv(PG_FUNCTION_ARGS){	/* Exactly the same as oidrecv, so share code */	return oidrecv(fcinfo);}/* *		regprocsend			- converts regproc to binary format */Datumregprocsend(PG_FUNCTION_ARGS){	/* Exactly the same as oidsend, so share code */	return oidsend(fcinfo);}/* * regprocedurein		- converts "proname(args)" to proc OID * * We also accept a numeric OID, for symmetry with the output routine. * * '-' signifies unknown (OID 0).  In all other cases, the input must * match an existing pg_proc entry. */Datumregprocedurein(PG_FUNCTION_ARGS){	char	   *pro_name_or_oid = PG_GETARG_CSTRING(0);	RegProcedure result = InvalidOid;	List	   *names;	int			nargs;	Oid			argtypes[FUNC_MAX_ARGS];	FuncCandidateList clist;	/* '-' ? */	if (strcmp(pro_name_or_oid, "-") == 0)		PG_RETURN_OID(InvalidOid);	/* Numeric OID? */	if (pro_name_or_oid[0] >= '0' &&		pro_name_or_oid[0] <= '9' &&		strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))	{		result = DatumGetObjectId(DirectFunctionCall1(oidin,										  CStringGetDatum(pro_name_or_oid)));		PG_RETURN_OID(result);	}	/*	 * Else it's a name and arguments.  Parse the name and arguments, look up	 * potential matches in the current namespace search list, and scan to see	 * which one exactly matches the given argument types.	(There will not be	 * more than one match.)	 *	 * XXX at present, this code will not work in bootstrap mode, hence this	 * datatype cannot be used for any system column that needs to receive	 * data during bootstrap.	 */	parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes);	clist = FuncnameGetCandidates(names, nargs);	for (; clist; clist = clist->next)	{		if (memcmp(clist->args, argtypes, nargs * sizeof(Oid)) == 0)			break;	}	if (clist == NULL)		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("function \"%s\" does not exist", pro_name_or_oid)));	result = clist->oid;	PG_RETURN_OID(result);}/* * format_procedure		- converts proc OID to "pro_name(args)" * * This exports the useful functionality of regprocedureout for use * in other backend modules.  The result is a palloc'd string. */char *format_procedure(Oid procedure_oid){	char	   *result;	HeapTuple	proctup;	proctup = SearchSysCache(PROCOID,							 ObjectIdGetDatum(procedure_oid),							 0, 0, 0);	if (HeapTupleIsValid(proctup))	{		Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);		char	   *proname = NameStr(procform->proname);		int			nargs = procform->pronargs;		int			i;		char	   *nspname;		StringInfoData buf;		/* XXX no support here for bootstrap mode */		initStringInfo(&buf);		/*		 * Would this proc be found (given the right args) by regprocedurein?		 * If not, we need to qualify it.		 */		if (FunctionIsVisible(procedure_oid))			nspname = NULL;		else			nspname = get_namespace_name(procform->pronamespace);		appendStringInfo(&buf, "%s(",						 quote_qualified_identifier(nspname, proname));		for (i = 0; i < nargs; i++)		{			Oid			thisargtype = procform->proargtypes.values[i];			if (i > 0)				appendStringInfoChar(&buf, ',');			appendStringInfoString(&buf, format_type_be(thisargtype));		}		appendStringInfoChar(&buf, ')');		result = buf.data;		ReleaseSysCache(proctup);	}	else	{		/* If OID doesn't match any pg_proc entry, return it numerically */		result = (char *) palloc(NAMEDATALEN);		snprintf(result, NAMEDATALEN, "%u", procedure_oid);	}	return result;}/* * regprocedureout		- converts proc OID to "pro_name(args)" */Datumregprocedureout(PG_FUNCTION_ARGS){	RegProcedure proid = PG_GETARG_OID(0);	char	   *result;	if (proid == InvalidOid)		result = pstrdup("-");	else		result = format_procedure(proid);	PG_RETURN_CSTRING(result);}/* *		regprocedurerecv			- converts external binary format to regprocedure */Datumregprocedurerecv(PG_FUNCTION_ARGS){	/* Exactly the same as oidrecv, so share code */	return oidrecv(fcinfo);}/* *		regproceduresend			- converts regprocedure to binary format */Datumregproceduresend(PG_FUNCTION_ARGS){	/* Exactly the same as oidsend, so share code */	return oidsend(fcinfo);}/* * regoperin		- converts "oprname" to operator OID * * We also accept a numeric OID, for symmetry with the output routine. * * '0' signifies unknown (OID 0).  In all other cases, the input must * match an existing pg_operator entry. */Datumregoperin(PG_FUNCTION_ARGS){	char	   *opr_name_or_oid = PG_GETARG_CSTRING(0);	Oid			result = InvalidOid;	List	   *names;	FuncCandidateList clist;	/* '0' ? */	if (strcmp(opr_name_or_oid, "0") == 0)		PG_RETURN_OID(InvalidOid);	/* Numeric OID? */	if (opr_name_or_oid[0] >= '0' &&		opr_name_or_oid[0] <= '9' &&		strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))	{		result = DatumGetObjectId(DirectFunctionCall1(oidin,										  CStringGetDatum(opr_name_or_oid)));		PG_RETURN_OID(result);	}	/* Else it's a name, possibly schema-qualified */	/*	 * In bootstrap mode we assume the given name is not schema-qualified, and	 * just search pg_operator for a unique match.	This is needed for	 * initializing other system catalogs (pg_namespace may not exist yet, and	 * certainly there are no schemas other than pg_catalog).	 */	if (IsBootstrapProcessingMode())	{		int			matches = 0;		Relation	hdesc;		ScanKeyData skey[1];		SysScanDesc sysscan;		HeapTuple	tuple;		ScanKeyInit(&skey[0],					Anum_pg_operator_oprname,					BTEqualStrategyNumber, F_NAMEEQ,					CStringGetDatum(opr_name_or_oid));		hdesc = heap_open(OperatorRelationId, AccessShareLock);		sysscan = systable_beginscan(hdesc, OperatorNameNspIndexId, true,									 SnapshotNow, 1, skey);		while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))		{			result = HeapTupleGetOid(tuple);			if (++matches > 1)				break;		}		systable_endscan(sysscan);		heap_close(hdesc, AccessShareLock);		if (matches == 0)			ereport(ERROR,					(errcode(ERRCODE_UNDEFINED_FUNCTION),					 errmsg("operator does not exist: %s", opr_name_or_oid)));		else if (matches > 1)			ereport(ERROR,					(errcode(ERRCODE_AMBIGUOUS_FUNCTION),					 errmsg("more than one operator named %s",							opr_name_or_oid)));		PG_RETURN_OID(result);	}	/*	 * Normal case: parse the name into components and see if it matches any	 * pg_operator entries in the current search path.	 */	names = stringToQualifiedNameList(opr_name_or_oid);	clist = OpernameGetCandidates(names, '\0');	if (clist == NULL)		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("operator does not exist: %s", opr_name_or_oid)));	else if (clist->next != NULL)		ereport(ERROR,				(errcode(ERRCODE_AMBIGUOUS_FUNCTION),				 errmsg("more than one operator named %s",						opr_name_or_oid)));	result = clist->oid;	PG_RETURN_OID(result);}/* * regoperout		- converts operator OID to "opr_name" */Datumregoperout(PG_FUNCTION_ARGS){

⌨️ 快捷键说明

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