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

📄 gram.y

📁 postgresql8.3.4源码,开源数据库
💻 Y
📖 第 1 页 / 共 4 页
字号:
%{/*------------------------------------------------------------------------- * * gram.y				- Parser for the PL/pgSQL *						  procedural language * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.108 2008/01/01 19:46:00 momjian Exp $ * *------------------------------------------------------------------------- */#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_execsql_stmt(const char *sqlstart, int lineno);static	PLpgSQL_stmt_fetch *read_fetch_direction(void);static	PLpgSQL_stmt	*make_return_stmt(int lineno);static	PLpgSQL_stmt	*make_return_next_stmt(int lineno);static	PLpgSQL_stmt	*make_return_query_stmt(int lineno);static	void			 check_assignable(PLpgSQL_datum *datum);static	void			 read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row,										  bool *strict);static	PLpgSQL_row		*read_into_scalar_list(const char *initial_name,											   PLpgSQL_datum *initial_datum);static PLpgSQL_row		*make_scalar_list1(const char *initial_name,										   PLpgSQL_datum *initial_datum,										   int lineno);static	void			 check_sql_expr(const char *stmt);static	void			 plpgsql_sql_error_callback(void *arg);static	char			*check_label(const char *yytxt);static	void			 check_labels(const char *start_label,									  const char *end_label);%}%name-prefix="plpgsql_yy"%union {		int32					ival;		bool					boolean;		char					*str;		struct		{			char *name;			int  lineno;		}						varname;		struct		{			char *name;			int  lineno;			PLpgSQL_datum   *scalar;			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;		PLpgSQL_stmt_fetch		*fetch;}%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%type <var>		cursor_variable%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_raise stmt_execsql stmt_execsql_insert%type <stmt>	stmt_dynexecute stmt_for stmt_perform stmt_getdiag%type <stmt>	stmt_open stmt_fetch stmt_move 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>	opt_scrollable%type <fetch>   opt_fetch_direction%type <ival>	lno		/*		 * Keyword tokens		 */%token	K_ALIAS%token	K_ASSIGN%token	K_BEGIN%token	K_BY%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_INSERT%token	K_INTO%token	K_IS%token	K_LOG%token	K_LOOP%token	K_MOVE%token	K_NOSCROLL%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_REVERSE%token	K_SCROLL%token	K_STRICT%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_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;					}				| opt_block_label decl_start					{						plpgsql_ns_setlocal(false);						$$.label	  = $1;						$$.n_initvars = 0;						$$.initvarnos = NULL;					}				| opt_block_label decl_start decl_stmts					{						plpgsql_ns_setlocal(false);						if ($3 != NULL)							$$.label = $3;						else							$$.label = $1;						/* Remember variables declared in decl_stmts */						$$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));					}				;decl_start		: K_DECLARE					{						/* Forget any variables created before block */						plpgsql_add_initdatums(NULL);						/* Make variable names be local to block */						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 opt_scrollable K_CURSOR					{ plpgsql_ns_push($1.name); }				  decl_cursor_args decl_is_for 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);						/*						 * Don't trust standard_conforming_strings here;						 * it might change before we use the string.						 */						if (strchr(cp1, '\\') != NULL)							*cp2++ = ESCAPE_STRING_SYNTAX;						*cp2++ = '\'';						while (*cp1)						{							if (SQL_STR_DOUBLE(*cp1, true))								*cp2++ = *cp1;							*cp2++ = *cp1++;						}						strcpy(cp2, "'::refcursor");						curname_def->query = pstrdup(buf);						new->default_val = curname_def;						new->cursor_explicit_expr = $7;						if ($5 == NULL)							new->cursor_explicit_argrow = -1;						else							new->cursor_explicit_argrow = $5->rowno;						new->cursor_options = CURSOR_OPT_FAST_PLAN | $2;					}				;opt_scrollable :					{						$$ = 0;					}				| K_NOSCROLL					{						$$ = CURSOR_OPT_NO_SCROLL;					}				| K_SCROLL					{						$$ = CURSOR_OPT_SCROLL;					}				;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_for		:	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 can be aliased");						plpgsql_ns_setlocal(false);						nsi = plpgsql_ns_lookup(name, NULL, NULL, 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; }				;proc_stmts		: proc_stmts proc_stmt						{							if ($2 == NULL)								$$ = $1;							else								$$ = lappend($1, $2);						}				| proc_stmt						{							if ($1 == NULL)								$$ = NULL;							else								$$ = list_make1($1);						}				;proc_stmt		: pl_block ';'						{ $$ = $1; }				| stmt_assign						{ $$ = $1; }				| stmt_if						{ $$ = $1; }				| stmt_loop						{ $$ = $1; }				| stmt_while						{ $$ = $1; }				| stmt_for						{ $$ = $1; }				| stmt_exit						{ $$ = $1; }				| stmt_return						{ $$ = $1; }				| stmt_raise						{ $$ = $1; }				| stmt_execsql						{ $$ = $1; }				| stmt_execsql_insert						{ $$ = $1; }				| stmt_dynexecute						{ $$ = $1; }				| stmt_perform						{ $$ = $1; }				| stmt_getdiag

⌨️ 快捷键说明

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