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

📄 pl_comp.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************************************** * pl_comp.c		- Compiler part of the PL/pgSQL *			  procedural language * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.7 1999/05/25 16:15:17 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 <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <ctype.h>#include "plpgsql.h"#include "pl.tab.h"#include "executor/spi.h"#include "commands/trigger.h"#include "utils/elog.h"#include "utils/builtins.h"#include "fmgr.h"#include "access/heapam.h"#include "utils/syscache.h"#include "utils/catcache.h"#include "catalog/catname.h"#include "catalog/pg_proc.h"#include "catalog/pg_type.h"#include "catalog/pg_class.h"#include "catalog/pg_attribute.h"#include "catalog/pg_attrdef.h"/* ---------- * Variables in the parser that shouldn't go into plpgsql.h * ---------- */extern PLPGSQL_YYSTYPE plpgsql_yylval;extern int	plpgsql_yylineno;extern char plpgsql_yytext[];void		plpgsql_yyerror(const char *s);/* ---------- * Our own local and global variables * ---------- */static int	datums_alloc;int			plpgsql_nDatums;PLpgSQL_datum **plpgsql_Datums;static int	datums_last = 0;int			plpgsql_error_lineno;char	   *plpgsql_error_funcname;int			plpgsql_DumpExecTree = 0;PLpgSQL_function *plpgsql_curr_compile;/* ---------- * Local function declarations * ---------- */static char *xlateSqlType(char *name);/* ---------- * plpgsql_compile		Given a pg_proc's oid, make *				an execution tree for it. * ---------- */PLpgSQL_function *plpgsql_compile(Oid fn_oid, int functype){	int			parse_rc;	HeapTuple	procTup;	Form_pg_proc procStruct;	HeapTuple	typeTup;	Form_pg_type typeStruct;	char	   *proc_source;	PLpgSQL_function *function;	PLpgSQL_var *var;	PLpgSQL_row *row;	PLpgSQL_rec *rec;	int			i;	int			arg_varnos[MAXFMGRARGS];	/* ----------	 * Initialize the compiler	 * ----------	 */	plpgsql_ns_init();	plpgsql_ns_push(NULL);	plpgsql_DumpExecTree = 0;	datums_alloc = 128;	plpgsql_nDatums = 0;	plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);	datums_last = 0;	/* ----------	 * Lookup the pg_proc tuple by Oid	 * ----------	 */	procTup = SearchSysCacheTuple(PROOID,								  ObjectIdGetDatum(fn_oid),								  0, 0, 0);	if (!HeapTupleIsValid(procTup))		elog(ERROR, "plpgsql: cache lookup from pg_proc failed");	/* ----------	 * Setup the scanner input and error info	 * ----------	 */	procStruct = (Form_pg_proc) GETSTRUCT(procTup);	proc_source = textout(&(procStruct->prosrc));	plpgsql_setinput(proc_source, functype);	plpgsql_error_funcname = nameout(&(procStruct->proname));	plpgsql_error_lineno = 0;	/* ----------	 * Create the new function node	 * ----------	 */	function = malloc(sizeof(PLpgSQL_function));	memset(function, 0, sizeof(PLpgSQL_function));	plpgsql_curr_compile = function;	function->fn_functype = functype;	function->fn_oid = fn_oid;	function->fn_name = strdup(nameout(&(procStruct->proname)));	switch (functype)	{		case T_FUNCTION:			/* ----------			 * Normal function has a defined returntype			 * ----------			 */			function->fn_rettype = procStruct->prorettype;			function->fn_retset = procStruct->proretset;			/* ----------			 * Lookup the functions return type			 * ----------			 */			typeTup = SearchSysCacheTuple(TYPOID,					  ObjectIdGetDatum(procStruct->prorettype), 0, 0, 0);			if (!HeapTupleIsValid(typeTup))			{				plpgsql_comperrinfo();				elog(ERROR, "cache lookup for return type %u failed",					 procStruct->prorettype);			}			typeStruct = (Form_pg_type) GETSTRUCT(typeTup);			if (typeStruct->typrelid != InvalidOid)				function->fn_retistuple = true;			else			{				function->fn_retbyval = typeStruct->typbyval;				function->fn_rettyplen = typeStruct->typlen;				fmgr_info(typeStruct->typinput, &(function->fn_retinput));			}			/* ----------			 * Create the variables for the procedures parameters			 * ----------			 */			for (i = 0; i < procStruct->pronargs; i++)			{				char		buf[256];				/* ----------				 * Get the parameters type				 * ----------				 */				typeTup = SearchSysCacheTuple(TYPOID,				  ObjectIdGetDatum(procStruct->proargtypes[i]), 0, 0, 0);				if (!HeapTupleIsValid(typeTup))				{					plpgsql_comperrinfo();					elog(ERROR, "cache lookup for argument type %u failed",						 procStruct->proargtypes[i]);				}				typeStruct = (Form_pg_type) GETSTRUCT(typeTup);				if (typeStruct->typrelid != InvalidOid)				{					/* ----------					 * For tuple type parameters, we set up a record					 * of that type					 * ----------					 */					sprintf(buf, "%s%%rowtype", nameout(&(typeStruct->typname)));					if (plpgsql_parse_wordrowtype(buf) != T_ROW)					{						plpgsql_comperrinfo();						elog(ERROR, "cannot get tuple struct of argument %d", i + 1);					}					row = plpgsql_yylval.row;					sprintf(buf, "$%d", i + 1);					row->refname = strdup(buf);					plpgsql_adddatum((PLpgSQL_datum *) row);					plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, row->rowno, buf);					arg_varnos[i] = row->rowno;				}				else				{					/* ----------					 * Normal parameters get a var node					 * ----------					 */					var = malloc(sizeof(PLpgSQL_var));					memset(var, 0, sizeof(PLpgSQL_var));					var->datatype = malloc(sizeof(PLpgSQL_type));					memset(var->datatype, 0, sizeof(PLpgSQL_type));					sprintf(buf, "$%d", i + 1);					var->dtype = PLPGSQL_DTYPE_VAR;					var->refname = strdup(buf);					var->lineno = 0;					var->datatype->typname = strdup(nameout(&(typeStruct->typname)));					var->datatype->typoid = procStruct->proargtypes[i];					fmgr_info(typeStruct->typinput, &(var->datatype->typinput));					var->datatype->typbyval = typeStruct->typbyval;					var->datatype->atttypmod = -1;					var->isconst = true;					var->notnull = false;					var->default_val = NULL;					plpgsql_adddatum((PLpgSQL_datum *) var);					plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, buf);					arg_varnos[i] = var->varno;				}			}			break;		case T_TRIGGER:			/* ----------			 * Trigger procedures return type is unknown yet			 * ----------			 */			function->fn_rettype = InvalidOid;			function->fn_retbyval = false;			function->fn_retistuple = true;			function->fn_retset = false;			/* ----------			 * Add the record for referencing NEW			 * ----------			 */			rec = malloc(sizeof(PLpgSQL_rec));			memset(rec, 0, sizeof(PLpgSQL_rec));			rec->dtype = PLPGSQL_DTYPE_REC;			rec->refname = strdup("new");			plpgsql_adddatum((PLpgSQL_datum *) rec);			plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);			function->new_varno = rec->recno;			/* ----------			 * Add the record for referencing OLD			 * ----------			 */			rec = malloc(sizeof(PLpgSQL_rec));			memset(rec, 0, sizeof(PLpgSQL_rec));			rec->dtype = PLPGSQL_DTYPE_REC;			rec->refname = strdup("old");			plpgsql_adddatum((PLpgSQL_datum *) rec);			plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);			function->old_varno = rec->recno;			/* ----------			 * Add the variable tg_name			 * ----------			 */			var = malloc(sizeof(PLpgSQL_var));			memset(var, 0, sizeof(PLpgSQL_var));			var->dtype = PLPGSQL_DTYPE_VAR;			var->refname = strdup("tg_name");			var->lineno = 0;			plpgsql_parse_word("name");			var->datatype = plpgsql_yylval.dtype;			var->isconst = false;			var->notnull = false;			var->default_val = NULL;			plpgsql_adddatum((PLpgSQL_datum *) var);			plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);			function->tg_name_varno = var->varno;			/* ----------			 * Add the variable tg_when			 * ----------			 */			var = malloc(sizeof(PLpgSQL_var));			memset(var, 0, sizeof(PLpgSQL_var));			var->dtype = PLPGSQL_DTYPE_VAR;			var->refname = strdup("tg_when");			var->lineno = 0;			plpgsql_parse_word("text");			var->datatype = plpgsql_yylval.dtype;			var->isconst = false;			var->notnull = false;			var->default_val = NULL;			plpgsql_adddatum((PLpgSQL_datum *) var);			plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);			function->tg_when_varno = var->varno;			/* ----------			 * Add the variable tg_level			 * ----------			 */			var = malloc(sizeof(PLpgSQL_var));			memset(var, 0, sizeof(PLpgSQL_var));			var->dtype = PLPGSQL_DTYPE_VAR;			var->refname = strdup("tg_level");			var->lineno = 0;			plpgsql_parse_word("text");			var->datatype = plpgsql_yylval.dtype;			var->isconst = false;			var->notnull = false;			var->default_val = NULL;			plpgsql_adddatum((PLpgSQL_datum *) var);			plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);			function->tg_level_varno = var->varno;			/* ----------			 * Add the variable tg_op			 * ----------			 */			var = malloc(sizeof(PLpgSQL_var));			memset(var, 0, sizeof(PLpgSQL_var));			var->dtype = PLPGSQL_DTYPE_VAR;			var->refname = strdup("tg_op");			var->lineno = 0;			plpgsql_parse_word("text");			var->datatype = plpgsql_yylval.dtype;			var->isconst = false;			var->notnull = false;			var->default_val = NULL;			plpgsql_adddatum((PLpgSQL_datum *) var);			plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);			function->tg_op_varno = var->varno;			/* ----------			 * Add the variable tg_relid			 * ----------			 */			var = malloc(sizeof(PLpgSQL_var));			memset(var, 0, sizeof(PLpgSQL_var));			var->dtype = PLPGSQL_DTYPE_VAR;			var->refname = strdup("tg_relid");			var->lineno = 0;			plpgsql_parse_word("oid");			var->datatype = plpgsql_yylval.dtype;			var->isconst = false;			var->notnull = false;			var->default_val = NULL;			plpgsql_adddatum((PLpgSQL_datum *) var);			plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);			function->tg_relid_varno = var->varno;			/* ----------			 * Add the variable tg_relname			 * ----------			 */			var = malloc(sizeof(PLpgSQL_var));			memset(var, 0, sizeof(PLpgSQL_var));			var->dtype = PLPGSQL_DTYPE_VAR;			var->refname = strdup("tg_relname");			var->lineno = 0;			plpgsql_parse_word("name");			var->datatype = plpgsql_yylval.dtype;			var->isconst = false;			var->notnull = false;			var->default_val = NULL;			plpgsql_adddatum((PLpgSQL_datum *) var);			plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);			function->tg_relname_varno = var->varno;			/* ----------			 * Add the variable tg_nargs			 * ----------			 */			var = malloc(sizeof(PLpgSQL_var));			memset(var, 0, sizeof(PLpgSQL_var));			var->dtype = PLPGSQL_DTYPE_VAR;			var->refname = strdup("tg_nargs");			var->lineno = 0;			plpgsql_parse_word("int4");			var->datatype = plpgsql_yylval.dtype;			var->isconst = false;			var->notnull = false;			var->default_val = NULL;			plpgsql_adddatum((PLpgSQL_datum *) var);			plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);			function->tg_nargs_varno = var->varno;			break;		default:			elog(ERROR, "unknown function type %u in plpgsql_compile()",				 functype);			break;	}

⌨️ 快捷键说明

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