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

📄 gram.y

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 Y
📖 第 1 页 / 共 4 页
字号:
%{/********************************************************************** * gram.y				- Parser for the PL/pgSQL *						  procedural language * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.82.2.1 2006/03/23 04:22:44 tgl 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 "parser/parser.h"static PLpgSQL_expr		*read_sql_construct(int until,											int until2,											const char *expected,											const char *sqlstart,											bool isexpression,											bool valid_sql,											int *endtoken);static	PLpgSQL_expr	*read_sql_stmt(const char *sqlstart);static	PLpgSQL_type	*read_datatype(int tok);static	PLpgSQL_stmt	*make_select_stmt(void);static	PLpgSQL_stmt	*make_fetch_stmt(void);static	void			 check_assignable(PLpgSQL_datum *datum);static	PLpgSQL_row		*read_into_scalar_list(const char *initial_name,											   PLpgSQL_datum *initial_datum);static	void			 check_sql_expr(const char *stmt);static	void			 plpgsql_sql_error_callback(void *arg);static	void			 check_labels(const char *start_label,									  const char *end_label);%}%union {		int32					ival;		bool					boolean;		char					*str;		struct		{			char *name;			int  lineno;		}						varname;		struct		{			char *name;			int  lineno;			PLpgSQL_rec     *rec;			PLpgSQL_row     *row;		}						forvariable;		struct		{			char *label;			int  n_initvars;			int  *initvarnos;		}						declhdr;		struct		{			char *end_label;			List *stmts;		}						loop_body;		List					*list;		PLpgSQL_type			*dtype;		PLpgSQL_datum			*scalar;	/* a VAR, RECFIELD, or TRIGARG */		PLpgSQL_variable		*variable;	/* a VAR, REC, or ROW */		PLpgSQL_var				*var;		PLpgSQL_row				*row;		PLpgSQL_rec				*rec;		PLpgSQL_expr			*expr;		PLpgSQL_stmt			*stmt;		PLpgSQL_stmt_block		*program;		PLpgSQL_condition		*condition;		PLpgSQL_exception		*exception;		PLpgSQL_exception_block	*exception_block;		PLpgSQL_nsitem			*nsitem;		PLpgSQL_diag_item		*diagitem;}%type <declhdr> decl_sect%type <varname> decl_varname%type <str>		decl_renname%type <boolean>	decl_const decl_notnull exit_type%type <expr>	decl_defval decl_cursor_query%type <dtype>	decl_datatype%type <row>		decl_cursor_args%type <list>	decl_cursor_arglist%type <nsitem>	decl_aliasitem%type <str>		decl_stmts decl_stmt%type <expr>	expr_until_semi expr_until_rightbracket%type <expr>	expr_until_then expr_until_loop%type <expr>	opt_exitcond%type <ival>	assign_var cursor_variable%type <var>		cursor_varptr%type <variable>	decl_cursor_arg%type <forvariable>	for_variable%type <stmt>	for_control%type <str>		opt_lblname opt_block_label opt_label%type <str>		execsql_start%type <list>	proc_sect proc_stmts stmt_else%type <loop_body>	loop_body%type <stmt>	proc_stmt pl_block%type <stmt>	stmt_assign stmt_if stmt_loop stmt_while stmt_exit%type <stmt>	stmt_return stmt_return_next stmt_raise stmt_execsql%type <stmt>	stmt_for stmt_select stmt_perform%type <stmt>	stmt_dynexecute stmt_getdiag%type <stmt>	stmt_open stmt_fetch stmt_close stmt_null%type <list>	proc_exceptions%type <exception_block> exception_sect%type <exception>	proc_exception%type <condition>	proc_conditions%type <ival>	raise_level%type <str>		raise_msg%type <list>	getdiag_list%type <diagitem> getdiag_list_item%type <ival>	getdiag_kind getdiag_target%type <ival>	lno		/*		 * Keyword tokens		 */%token	K_ALIAS%token	K_ASSIGN%token	K_BEGIN%token	K_CLOSE%token	K_CONSTANT%token	K_CONTINUE%token	K_CURSOR%token	K_DEBUG%token	K_DECLARE%token	K_DEFAULT%token	K_DIAGNOSTICS%token	K_DOTDOT%token	K_ELSE%token	K_ELSIF%token	K_END%token	K_EXCEPTION%token	K_EXECUTE%token	K_EXIT%token	K_FOR%token	K_FETCH%token	K_FROM%token	K_GET%token	K_IF%token	K_IN%token	K_INFO%token	K_INTO%token	K_IS%token	K_LOG%token	K_LOOP%token	K_NEXT%token	K_NOT%token	K_NOTICE%token	K_NULL%token	K_OPEN%token	K_OR%token	K_PERFORM%token	K_ROW_COUNT%token	K_RAISE%token	K_RENAME%token	K_RESULT_OID%token	K_RETURN%token	K_RETURN_NEXT%token	K_REVERSE%token	K_SELECT%token	K_THEN%token	K_TO%token	K_TYPE%token	K_WARNING%token	K_WHEN%token	K_WHILE		/*		 * Other tokens		 */%token	T_FUNCTION%token	T_TRIGGER%token	T_STRING%token	T_NUMBER%token	T_SCALAR				/* a VAR, RECFIELD, or TRIGARG */%token	T_ROW%token	T_RECORD%token	T_DTYPE%token	T_LABEL%token	T_WORD%token	T_ERROR%token	O_OPTION%token	O_DUMP%%pl_function		: T_FUNCTION comp_optsect pl_block opt_semi					{						yylval.program = (PLpgSQL_stmt_block *)$3;					}				| T_TRIGGER comp_optsect pl_block opt_semi					{						yylval.program = (PLpgSQL_stmt_block *)$3;					}				;comp_optsect	:				| comp_options				;comp_options	: comp_options comp_option				| comp_option				;comp_option		: O_OPTION O_DUMP					{						plpgsql_DumpExecTree = true;					}				;opt_semi		:				| ';'				;pl_block		: decl_sect K_BEGIN lno proc_sect exception_sect K_END opt_label					{						PLpgSQL_stmt_block *new;						new = palloc0(sizeof(PLpgSQL_stmt_block));						new->cmd_type	= PLPGSQL_STMT_BLOCK;						new->lineno		= $3;						new->label		= $1.label;						new->n_initvars = $1.n_initvars;						new->initvarnos = $1.initvarnos;						new->body		= $4;						new->exceptions	= $5;						check_labels($1.label, $7);						plpgsql_ns_pop();						$$ = (PLpgSQL_stmt *)new;					}				;decl_sect		: opt_block_label					{						plpgsql_ns_setlocal(false);						$$.label	  = $1;						$$.n_initvars = 0;						$$.initvarnos = NULL;						plpgsql_add_initdatums(NULL);					}				| opt_block_label decl_start					{						plpgsql_ns_setlocal(false);						$$.label	  = $1;						$$.n_initvars = 0;						$$.initvarnos = NULL;						plpgsql_add_initdatums(NULL);					}				| opt_block_label decl_start decl_stmts					{						plpgsql_ns_setlocal(false);						if ($3 != NULL)							$$.label = $3;						else							$$.label = $1;						$$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));					}				;decl_start		: K_DECLARE					{						plpgsql_ns_setlocal(true);					}				;decl_stmts		: decl_stmts decl_stmt					{	$$ = $2;	}				| decl_stmt					{	$$ = $1;	}				;decl_stmt		: '<' '<' opt_lblname '>' '>'					{	$$ = $3;	}				| K_DECLARE					{	$$ = NULL;	}				| decl_statement					{	$$ = NULL;	}				;decl_statement	: decl_varname decl_const decl_datatype decl_notnull decl_defval					{						PLpgSQL_variable	*var;						var = plpgsql_build_variable($1.name, $1.lineno,													 $3, true);						if ($2)						{							if (var->dtype == PLPGSQL_DTYPE_VAR)								((PLpgSQL_var *) var)->isconst = $2;							else								ereport(ERROR,										(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),										 errmsg("row or record variable cannot be CONSTANT")));						}						if ($4)						{							if (var->dtype == PLPGSQL_DTYPE_VAR)								((PLpgSQL_var *) var)->notnull = $4;							else								ereport(ERROR,										(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),										 errmsg("row or record variable cannot be NOT NULL")));						}						if ($5 != NULL)						{							if (var->dtype == PLPGSQL_DTYPE_VAR)								((PLpgSQL_var *) var)->default_val = $5;							else								ereport(ERROR,										(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),										 errmsg("default value for row or record variable is not supported")));						}					}				| decl_varname K_ALIAS K_FOR decl_aliasitem ';'					{						plpgsql_ns_additem($4->itemtype,										   $4->itemno, $1.name);					}				| K_RENAME decl_renname K_TO decl_renname ';'					{						plpgsql_ns_rename($2, $4);					}				| decl_varname K_CURSOR					{ plpgsql_ns_push(NULL); }				  decl_cursor_args decl_is_from decl_cursor_query					{						PLpgSQL_var *new;						PLpgSQL_expr *curname_def;						char		buf[1024];						char		*cp1;						char		*cp2;						/* pop local namespace for cursor args */						plpgsql_ns_pop();						new = (PLpgSQL_var *)							plpgsql_build_variable($1.name, $1.lineno,												   plpgsql_build_datatype(REFCURSOROID,																		  -1),												   true);						curname_def = palloc0(sizeof(PLpgSQL_expr));						curname_def->dtype = PLPGSQL_DTYPE_EXPR;						strcpy(buf, "SELECT ");						cp1 = new->refname;						cp2 = buf + strlen(buf);						if (strchr(cp1, '\\') != NULL)							*cp2++ = ESCAPE_STRING_SYNTAX;						*cp2++ = '\'';						while (*cp1)						{							if (SQL_STR_DOUBLE(*cp1))								*cp2++ = *cp1;							*cp2++ = *cp1++;						}						strcpy(cp2, "'::refcursor");						curname_def->query = pstrdup(buf);						new->default_val = curname_def;						new->cursor_explicit_expr = $6;						if ($4 == NULL)							new->cursor_explicit_argrow = -1;						else							new->cursor_explicit_argrow = $4->rowno;					}				;decl_cursor_query :					{						PLpgSQL_expr *query;						plpgsql_ns_setlocal(false);						query = read_sql_stmt("");						plpgsql_ns_setlocal(true);						$$ = query;					}				;decl_cursor_args :					{						$$ = NULL;					}				| '(' decl_cursor_arglist ')'					{						PLpgSQL_row *new;						int i;						ListCell *l;						new = palloc0(sizeof(PLpgSQL_row));						new->dtype = PLPGSQL_DTYPE_ROW;						new->lineno = plpgsql_scanner_lineno();						new->rowtupdesc = NULL;						new->nfields = list_length($2);						new->fieldnames = palloc(new->nfields * sizeof(char *));						new->varnos = palloc(new->nfields * sizeof(int));						i = 0;						foreach (l, $2)						{							PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);							new->fieldnames[i] = arg->refname;							new->varnos[i] = arg->dno;							i++;						}						list_free($2);						plpgsql_adddatum((PLpgSQL_datum *) new);						$$ = new;					}				;decl_cursor_arglist : decl_cursor_arg					{						$$ = list_make1($1);					}				| decl_cursor_arglist ',' decl_cursor_arg					{						$$ = lappend($1, $3);					}				;decl_cursor_arg : decl_varname decl_datatype					{						$$ = plpgsql_build_variable($1.name, $1.lineno,													$2, true);					}				;decl_is_from	:	K_IS |		/* Oracle */					K_FOR;		/* ANSI */decl_aliasitem	: T_WORD					{						char	*name;						PLpgSQL_nsitem *nsi;						plpgsql_convert_ident(yytext, &name, 1);						if (name[0] != '$')							yyerror("only positional parameters may be aliased");						plpgsql_ns_setlocal(false);						nsi = plpgsql_ns_lookup(name, NULL);						if (nsi == NULL)						{							plpgsql_error_lineno = plpgsql_scanner_lineno();							ereport(ERROR,									(errcode(ERRCODE_UNDEFINED_PARAMETER),									 errmsg("function has no parameter \"%s\"",											name)));						}						plpgsql_ns_setlocal(true);						pfree(name);						$$ = nsi;					}				;decl_varname	: T_WORD					{						char	*name;						plpgsql_convert_ident(yytext, &name, 1);						$$.name = name;						$$.lineno  = plpgsql_scanner_lineno();					}				;decl_renname	: T_WORD					{						char	*name;						plpgsql_convert_ident(yytext, &name, 1);						/* the result must be palloc'd, see plpgsql_ns_rename */						$$ = name;					}				;decl_const		:					{ $$ = false; }				| K_CONSTANT					{ $$ = true; }				;decl_datatype	:					{						/*						 * If there's a lookahead token, read_datatype						 * should consume it.						 */						$$ = read_datatype(yychar);						yyclearin;					}				;decl_notnull	:					{ $$ = false; }				| K_NOT K_NULL					{ $$ = true; }				;decl_defval		: ';'					{ $$ = NULL; }				| decl_defkey					{						plpgsql_ns_setlocal(false);						$$ = plpgsql_read_expression(';', ";");						plpgsql_ns_setlocal(true);					}				;decl_defkey		: K_ASSIGN				| K_DEFAULT				;proc_sect		:					{						$$ = NIL;					}				| proc_stmts					{ $$ = $1; }				;

⌨️ 快捷键说明

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