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

📄 pl_handler.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
字号:
/********************************************************************** * pl_handler.c		- Handler for the PL/pgSQL *			  procedural language * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.26 2005/10/15 02:49:50 momjian Exp $ * *	  This software is copyrighted by Jan Wieck - Hamburg. * *	  The author hereby grants permission  to  use,  copy,	modify, *	  distribute,  and	license this software and its documentation *	  for any purpose, provided that existing copyright notices are *	  retained	in	all  copies  and  that	this notice is included *	  verbatim in any distributions. No written agreement, license, *	  or  royalty  fee	is required for any of the authorized uses. *	  Modifications to this software may be  copyrighted  by  their *	  author  and  need  not  follow  the licensing terms described *	  here, provided that the new terms are  clearly  indicated  on *	  the first page of each file where they apply. * *	  IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY *	  PARTY  FOR  DIRECT,	INDIRECT,	SPECIAL,   INCIDENTAL,	 OR *	  CONSEQUENTIAL   DAMAGES  ARISING	OUT  OF  THE  USE  OF  THIS *	  SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN *	  IF  THE  AUTHOR  HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH *	  DAMAGE. * *	  THE  AUTHOR  AND	DISTRIBUTORS  SPECIFICALLY	 DISCLAIM	ANY *	  WARRANTIES,  INCLUDING,  BUT	NOT  LIMITED  TO,  THE	IMPLIED *	  WARRANTIES  OF  MERCHANTABILITY,	FITNESS  FOR  A  PARTICULAR *	  PURPOSE,	AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON *	  AN "AS IS" BASIS, AND THE AUTHOR	AND  DISTRIBUTORS  HAVE  NO *	  OBLIGATION   TO	PROVIDE   MAINTENANCE,	 SUPPORT,  UPDATES, *	  ENHANCEMENTS, OR MODIFICATIONS. * **********************************************************************/#include "plpgsql.h"#include "pl.tab.h"#include "access/heapam.h"#include "catalog/pg_proc.h"#include "catalog/pg_type.h"#include "utils/builtins.h"#include "utils/lsyscache.h"#include "utils/syscache.h"extern DLLIMPORT bool check_function_bodies;static bool plpgsql_firstcall = true;static void plpgsql_init_all(void);/* * plpgsql_init()			- postmaster-startup safe initialization * * DO NOT make this static --- it has to be callable by preload */voidplpgsql_init(void){	/* Do initialization only once */	if (!plpgsql_firstcall)		return;	plpgsql_HashTableInit();	RegisterXactCallback(plpgsql_xact_cb, NULL);	plpgsql_firstcall = false;}/* * plpgsql_init_all()		- Initialize all */static voidplpgsql_init_all(void){	/* Execute any postmaster-startup safe initialization */	plpgsql_init();	/*	 * Any other initialization that must be done each time a new backend	 * starts -- currently none	 */}/* ---------- * plpgsql_call_handler * * The PostgreSQL function manager and trigger manager * call this function for execution of PL/pgSQL procedures. * ---------- */PG_FUNCTION_INFO_V1(plpgsql_call_handler);Datumplpgsql_call_handler(PG_FUNCTION_ARGS){	PLpgSQL_function *func;	Datum		retval;	int			rc;	/* perform initialization */	plpgsql_init_all();	/*	 * Connect to SPI manager	 */	if ((rc = SPI_connect()) != SPI_OK_CONNECT)		elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));	/* Find or compile the function */	func = plpgsql_compile(fcinfo, false);	/*	 * Determine if called as function or trigger and call appropriate	 * subhandler	 */	if (CALLED_AS_TRIGGER(fcinfo))		retval = PointerGetDatum(plpgsql_exec_trigger(func,										   (TriggerData *) fcinfo->context));	else		retval = plpgsql_exec_function(func, fcinfo);	/*	 * Disconnect from SPI manager	 */	if ((rc = SPI_finish()) != SPI_OK_FINISH)		elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));	return retval;}/* ---------- * plpgsql_validator * * This function attempts to validate a PL/pgSQL function at * CREATE FUNCTION time. * ---------- */PG_FUNCTION_INFO_V1(plpgsql_validator);Datumplpgsql_validator(PG_FUNCTION_ARGS){	Oid			funcoid = PG_GETARG_OID(0);	HeapTuple	tuple;	Form_pg_proc proc;	char		functyptype;	bool		istrigger = false;	bool		haspolyresult;	bool		haspolyarg;	int			i;	/* perform initialization */	plpgsql_init_all();	/* Get the new function's pg_proc entry */	tuple = SearchSysCache(PROCOID,						   ObjectIdGetDatum(funcoid),						   0, 0, 0);	if (!HeapTupleIsValid(tuple))		elog(ERROR, "cache lookup failed for function %u", funcoid);	proc = (Form_pg_proc) GETSTRUCT(tuple);	functyptype = get_typtype(proc->prorettype);	/* Disallow pseudotype result */	/* except for TRIGGER, RECORD, VOID, ANYARRAY, or ANYELEMENT */	if (functyptype == 'p')	{		/* we assume OPAQUE with no arguments means a trigger */		if (proc->prorettype == TRIGGEROID ||			(proc->prorettype == OPAQUEOID && proc->pronargs == 0))			istrigger = true;		else if (proc->prorettype == ANYARRAYOID ||				 proc->prorettype == ANYELEMENTOID)			haspolyresult = true;		else if (proc->prorettype != RECORDOID &&				 proc->prorettype != VOIDOID)			ereport(ERROR,					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),					 errmsg("plpgsql functions cannot return type %s",							format_type_be(proc->prorettype))));	}	/* Disallow pseudotypes in arguments */	/* except for ANYARRAY or ANYELEMENT */	haspolyarg = false;	for (i = 0; i < proc->pronargs; i++)	{		if (get_typtype(proc->proargtypes.values[i]) == 'p')		{			if (proc->proargtypes.values[i] == ANYARRAYOID ||				proc->proargtypes.values[i] == ANYELEMENTOID)				haspolyarg = true;			else				ereport(ERROR,						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),						 errmsg("plpgsql functions cannot take type %s",							  format_type_be(proc->proargtypes.values[i]))));		}	}	/* Postpone body checks if !check_function_bodies */	if (check_function_bodies)	{		FunctionCallInfoData fake_fcinfo;		FmgrInfo	flinfo;		TriggerData trigdata;		int			rc;		/*		 * Connect to SPI manager (is this needed for compilation?)		 */		if ((rc = SPI_connect()) != SPI_OK_CONNECT)			elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));		/*		 * Set up a fake fcinfo with just enough info to satisfy		 * plpgsql_compile().		 */		MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo));		MemSet(&flinfo, 0, sizeof(flinfo));		fake_fcinfo.flinfo = &flinfo;		flinfo.fn_oid = funcoid;		flinfo.fn_mcxt = CurrentMemoryContext;		if (istrigger)		{			MemSet(&trigdata, 0, sizeof(trigdata));			trigdata.type = T_TriggerData;			fake_fcinfo.context = (Node *) &trigdata;		}		/* Test-compile the function */		plpgsql_compile(&fake_fcinfo, true);		/*		 * Disconnect from SPI manager		 */		if ((rc = SPI_finish()) != SPI_OK_FINISH)			elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));	}	ReleaseSysCache(tuple);	PG_RETURN_VOID();}

⌨️ 快捷键说明

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