1 %{ 2 /*------------------------------------------------------------------------- 3 * 4 * pl_gram.y - Parser for the PL/pgSQL procedural language 5 * 6 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group 7 * Portions Copyright (c) 1994, Regents of the University of California 8 * 9 * 10 * IDENTIFICATION 11 * src/pl/plpgsql/src/pl_gram.y 12 * 13 *------------------------------------------------------------------------- 14 */ 15 16 #include "postgres.h" 17 18 #include "catalog/namespace.h" 19 #include "catalog/pg_proc.h" 20 #include "catalog/pg_type.h" 21 #include "parser/parser.h" 22 #include "parser/parse_type.h" 23 #include "parser/scanner.h" 24 #include "parser/scansup.h" 25 #include "utils/builtins.h" 26 27 #include "plpgsql.h" 28 29 30 /* Location tracking support --- simpler than bison's default */ 31 #define YYLLOC_DEFAULT(Current, Rhs, N) \ 32 do { \ 33 if (N) \ 34 (Current) = (Rhs)[1]; \ 35 else \ 36 (Current) = (Rhs)[0]; \ 37 } while (0) 38 39 /* 40 * Bison doesn't allocate anything that needs to live across parser calls, 41 * so we can easily have it use palloc instead of malloc. This prevents 42 * memory leaks if we error out during parsing. Note this only works with 43 * bison >= 2.0. However, in bison 1.875 the default is to use alloca() 44 * if possible, so there's not really much problem anyhow, at least if 45 * you're building with gcc. 46 */ 47 #define YYMALLOC palloc 48 #define YYFREE pfree 49 50 51 typedef struct 52 { 53 int location; 54 int leaderlen; 55 } sql_error_callback_arg; 56 57 #define parser_errposition(pos) plpgsql_scanner_errposition(pos) 58 59 union YYSTYPE; /* need forward reference for tok_is_keyword */ 60 61 static bool tok_is_keyword(int token, union YYSTYPE *lval, 62 int kw_token, const char *kw_str); 63 static void word_is_not_variable(PLword *word, int location); 64 static void cword_is_not_variable(PLcword *cword, int location); 65 static void current_token_is_not_variable(int tok); 66 static PLpgSQL_expr *read_sql_construct(int until, 67 int until2, 68 int until3, 69 const char *expected, 70 const char *sqlstart, 71 bool isexpression, 72 bool valid_sql, 73 bool trim, 74 int *startloc, 75 int *endtoken); 76 static PLpgSQL_expr *read_sql_expression(int until, 77 const char *expected); 78 static PLpgSQL_expr *read_sql_expression2(int until, int until2, 79 const char *expected, 80 int *endtoken); 81 static PLpgSQL_expr *read_sql_stmt(const char *sqlstart); 82 static PLpgSQL_type *read_datatype(int tok); 83 static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location); 84 static PLpgSQL_stmt_fetch *read_fetch_direction(void); 85 static void complete_direction(PLpgSQL_stmt_fetch *fetch, 86 bool *check_FROM); 87 static PLpgSQL_stmt *make_return_stmt(int location); 88 static PLpgSQL_stmt *make_return_next_stmt(int location); 89 static PLpgSQL_stmt *make_return_query_stmt(int location); 90 static PLpgSQL_stmt *make_case(int location, PLpgSQL_expr *t_expr, 91 List *case_when_list, List *else_stmts); 92 static char *NameOfDatum(PLwdatum *wdatum); 93 static void check_assignable(PLpgSQL_datum *datum, int location); 94 static void read_into_target(PLpgSQL_variable **target, 95 bool *strict); 96 static PLpgSQL_row *read_into_scalar_list(char *initial_name, 97 PLpgSQL_datum *initial_datum, 98 int initial_location); 99 static PLpgSQL_row *make_scalar_list1(char *initial_name, 100 PLpgSQL_datum *initial_datum, 101 int lineno, int location); 102 static void check_sql_expr(const char *stmt, int location, 103 int leaderlen); 104 static void plpgsql_sql_error_callback(void *arg); 105 static PLpgSQL_type *parse_datatype(const char *string, int location); 106 static void check_labels(const char *start_label, 107 const char *end_label, 108 int end_location); 109 static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor, 110 int until, const char *expected); 111 static List *read_raise_options(void); 112 static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); 113 114 %} 115 116 %expect 0 117 %name-prefix="plpgsql_yy" 118 %locations 119 120 %union { 121 core_YYSTYPE core_yystype; 122 /* these fields must match core_YYSTYPE: */ 123 int ival; 124 char *str; 125 const char *keyword; 126 127 PLword word; 128 PLcword cword; 129 PLwdatum wdatum; 130 bool boolean; 131 Oid oid; 132 struct 133 { 134 char *name; 135 int lineno; 136 } varname; 137 struct 138 { 139 char *name; 140 int lineno; 141 PLpgSQL_datum *scalar; 142 PLpgSQL_datum *row; 143 } forvariable; 144 struct 145 { 146 char *label; 147 int n_initvars; 148 int *initvarnos; 149 } declhdr; 150 struct 151 { 152 List *stmts; 153 char *end_label; 154 int end_label_location; 155 } loop_body; 156 List *list; 157 PLpgSQL_type *dtype; 158 PLpgSQL_datum *datum; 159 PLpgSQL_var *var; 160 PLpgSQL_expr *expr; 161 PLpgSQL_stmt *stmt; 162 PLpgSQL_condition *condition; 163 PLpgSQL_exception *exception; 164 PLpgSQL_exception_block *exception_block; 165 PLpgSQL_nsitem *nsitem; 166 PLpgSQL_diag_item *diagitem; 167 PLpgSQL_stmt_fetch *fetch; 168 PLpgSQL_case_when *casewhen; 169 } 170 171 %type <declhdr> decl_sect 172 %type <varname> decl_varname 173 %type <boolean> decl_const decl_notnull exit_type 174 %type <expr> decl_defval decl_cursor_query 175 %type <dtype> decl_datatype 176 %type <oid> decl_collate 177 %type <datum> decl_cursor_args 178 %type <list> decl_cursor_arglist 179 %type <nsitem> decl_aliasitem 180 181 %type <expr> expr_until_semi expr_until_rightbracket 182 %type <expr> expr_until_then expr_until_loop opt_expr_until_when 183 %type <expr> opt_exitcond 184 185 %type <datum> assign_var 186 %type <var> cursor_variable 187 %type <datum> decl_cursor_arg 188 %type <forvariable> for_variable 189 %type <ival> foreach_slice 190 %type <stmt> for_control 191 192 %type <str> any_identifier opt_block_label opt_loop_label opt_label 193 %type <str> option_value 194 195 %type <list> proc_sect stmt_elsifs stmt_else 196 %type <loop_body> loop_body 197 %type <stmt> proc_stmt pl_block 198 %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit 199 %type <stmt> stmt_return stmt_raise stmt_assert stmt_execsql 200 %type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_call stmt_getdiag 201 %type <stmt> stmt_open stmt_fetch stmt_move stmt_close stmt_null 202 %type <stmt> stmt_commit stmt_rollback stmt_set 203 %type <stmt> stmt_case stmt_foreach_a 204 205 %type <list> proc_exceptions 206 %type <exception_block> exception_sect 207 %type <exception> proc_exception 208 %type <condition> proc_conditions proc_condition 209 210 %type <casewhen> case_when 211 %type <list> case_when_list opt_case_else 212 213 %type <boolean> getdiag_area_opt 214 %type <list> getdiag_list 215 %type <diagitem> getdiag_list_item 216 %type <datum> getdiag_target 217 %type <ival> getdiag_item 218 219 %type <ival> opt_scrollable 220 %type <fetch> opt_fetch_direction 221 222 %type <keyword> unreserved_keyword 223 224 225 /* 226 * Basic non-keyword token types. These are hard-wired into the core lexer. 227 * They must be listed first so that their numeric codes do not depend on 228 * the set of keywords. Keep this list in sync with backend/parser/gram.y! 229 * 230 * Some of these are not directly referenced in this file, but they must be 231 * here anyway. 232 */ 233 %token <str> IDENT FCONST SCONST BCONST XCONST Op 234 %token <ival> ICONST PARAM 235 %token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER 236 %token LESS_EQUALS GREATER_EQUALS NOT_EQUALS 237 238 /* 239 * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c). 240 */ 241 %token <word> T_WORD /* unrecognized simple identifier */ 242 %token <cword> T_CWORD /* unrecognized composite identifier */ 243 %token <wdatum> T_DATUM /* a VAR, ROW, REC, or RECFIELD variable */ 244 %token LESS_LESS 245 %token GREATER_GREATER 246 247 /* 248 * Keyword tokens. Some of these are reserved and some are not; 249 * see pl_scanner.c for info. Be sure unreserved keywords are listed 250 * in the "unreserved_keyword" production below. 251 */ 252 %token <keyword> K_ABSOLUTE 253 %token <keyword> K_ALIAS 254 %token <keyword> K_ALL 255 %token <keyword> K_ARRAY 256 %token <keyword> K_ASSERT 257 %token <keyword> K_BACKWARD 258 %token <keyword> K_BEGIN 259 %token <keyword> K_BY 260 %token <keyword> K_CALL 261 %token <keyword> K_CASE 262 %token <keyword> K_CLOSE 263 %token <keyword> K_COLLATE 264 %token <keyword> K_COLUMN 265 %token <keyword> K_COLUMN_NAME 266 %token <keyword> K_COMMIT 267 %token <keyword> K_CONSTANT 268 %token <keyword> K_CONSTRAINT 269 %token <keyword> K_CONSTRAINT_NAME 270 %token <keyword> K_CONTINUE 271 %token <keyword> K_CURRENT 272 %token <keyword> K_CURSOR 273 %token <keyword> K_DATATYPE 274 %token <keyword> K_DEBUG 275 %token <keyword> K_DECLARE 276 %token <keyword> K_DEFAULT 277 %token <keyword> K_DETAIL 278 %token <keyword> K_DIAGNOSTICS 279 %token <keyword> K_DO 280 %token <keyword> K_DUMP 281 %token <keyword> K_ELSE 282 %token <keyword> K_ELSIF 283 %token <keyword> K_END 284 %token <keyword> K_ERRCODE 285 %token <keyword> K_ERROR 286 %token <keyword> K_EXCEPTION 287 %token <keyword> K_EXECUTE 288 %token <keyword> K_EXIT 289 %token <keyword> K_FETCH 290 %token <keyword> K_FIRST 291 %token <keyword> K_FOR 292 %token <keyword> K_FOREACH 293 %token <keyword> K_FORWARD 294 %token <keyword> K_FROM 295 %token <keyword> K_GET 296 %token <keyword> K_HINT 297 %token <keyword> K_IF 298 %token <keyword> K_IMPORT 299 %token <keyword> K_IN 300 %token <keyword> K_INFO 301 %token <keyword> K_INSERT 302 %token <keyword> K_INTO 303 %token <keyword> K_IS 304 %token <keyword> K_LAST 305 %token <keyword> K_LOG 306 %token <keyword> K_LOOP 307 %token <keyword> K_MESSAGE 308 %token <keyword> K_MESSAGE_TEXT 309 %token <keyword> K_MOVE 310 %token <keyword> K_NEXT 311 %token <keyword> K_NO 312 %token <keyword> K_NOT 313 %token <keyword> K_NOTICE 314 %token <keyword> K_NULL 315 %token <keyword> K_OPEN 316 %token <keyword> K_OPTION 317 %token <keyword> K_OR 318 %token <keyword> K_PERFORM 319 %token <keyword> K_PG_CONTEXT 320 %token <keyword> K_PG_DATATYPE_NAME 321 %token <keyword> K_PG_EXCEPTION_CONTEXT 322 %token <keyword> K_PG_EXCEPTION_DETAIL 323 %token <keyword> K_PG_EXCEPTION_HINT 324 %token <keyword> K_PRINT_STRICT_PARAMS 325 %token <keyword> K_PRIOR 326 %token <keyword> K_QUERY 327 %token <keyword> K_RAISE 328 %token <keyword> K_RELATIVE 329 %token <keyword> K_RESET 330 %token <keyword> K_RESULT_OID 331 %token <keyword> K_RETURN 332 %token <keyword> K_RETURNED_SQLSTATE 333 %token <keyword> K_REVERSE 334 %token <keyword> K_ROLLBACK 335 %token <keyword> K_ROW_COUNT 336 %token <keyword> K_ROWTYPE 337 %token <keyword> K_SCHEMA 338 %token <keyword> K_SCHEMA_NAME 339 %token <keyword> K_SCROLL 340 %token <keyword> K_SET 341 %token <keyword> K_SLICE 342 %token <keyword> K_SQLSTATE 343 %token <keyword> K_STACKED 344 %token <keyword> K_STRICT 345 %token <keyword> K_TABLE 346 %token <keyword> K_TABLE_NAME 347 %token <keyword> K_THEN 348 %token <keyword> K_TO 349 %token <keyword> K_TYPE 350 %token <keyword> K_USE_COLUMN 351 %token <keyword> K_USE_VARIABLE 352 %token <keyword> K_USING 353 %token <keyword> K_VARIABLE_CONFLICT 354 %token <keyword> K_WARNING 355 %token <keyword> K_WHEN 356 %token <keyword> K_WHILE 357 358 %% 359 360 pl_function : comp_options pl_block opt_semi 361 { 362 plpgsql_parse_result = (PLpgSQL_stmt_block *) $2; 363 } 364 ; 365 366 comp_options : 367 | comp_options comp_option 368 ; 369 370 comp_option : '#' K_OPTION K_DUMP 371 { 372 plpgsql_DumpExecTree = true; 373 } 374 | '#' K_PRINT_STRICT_PARAMS option_value 375 { 376 if (strcmp($3, "on") == 0) 377 plpgsql_curr_compile->print_strict_params = true; 378 else if (strcmp($3, "off") == 0) 379 plpgsql_curr_compile->print_strict_params = false; 380 else 381 elog(ERROR, "unrecognized print_strict_params option %s", $3); 382 } 383 | '#' K_VARIABLE_CONFLICT K_ERROR 384 { 385 plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_ERROR; 386 } 387 | '#' K_VARIABLE_CONFLICT K_USE_VARIABLE 388 { 389 plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_VARIABLE; 390 } 391 | '#' K_VARIABLE_CONFLICT K_USE_COLUMN 392 { 393 plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_COLUMN; 394 } 395 ; 396 397 option_value : T_WORD 398 { 399 $$ = $1.ident; 400 } 401 | unreserved_keyword 402 { 403 $$ = pstrdup($1); 404 } 405 406 opt_semi : 407 | ';' 408 ; 409 410 pl_block : decl_sect K_BEGIN proc_sect exception_sect K_END opt_label 411 { 412 PLpgSQL_stmt_block *new; 413 414 new = palloc0(sizeof(PLpgSQL_stmt_block)); 415 416 new->cmd_type = PLPGSQL_STMT_BLOCK; 417 new->lineno = plpgsql_location_to_lineno(@2); 418 new->label = $1.label; 419 new->n_initvars = $1.n_initvars; 420 new->initvarnos = $1.initvarnos; 421 new->body = $3; 422 new->exceptions = $4; 423 424 check_labels($1.label, $6, @6); 425 plpgsql_ns_pop(); 426 427 $$ = (PLpgSQL_stmt *)new; 428 } 429 ; 430 431 432 decl_sect : opt_block_label 433 { 434 /* done with decls, so resume identifier lookup */ 435 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; 436 $$.label = $1; 437 $$.n_initvars = 0; 438 $$.initvarnos = NULL; 439 } 440 | opt_block_label decl_start 441 { 442 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; 443 $$.label = $1; 444 $$.n_initvars = 0; 445 $$.initvarnos = NULL; 446 } 447 | opt_block_label decl_start decl_stmts 448 { 449 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; 450 $$.label = $1; 451 /* Remember variables declared in decl_stmts */ 452 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos)); 453 } 454 ; 455 456 decl_start : K_DECLARE 457 { 458 /* Forget any variables created before block */ 459 plpgsql_add_initdatums(NULL); 460 /* 461 * Disable scanner lookup of identifiers while 462 * we process the decl_stmts 463 */ 464 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE; 465 } 466 ; 467 468 decl_stmts : decl_stmts decl_stmt 469 | decl_stmt 470 ; 471 472 decl_stmt : decl_statement 473 | K_DECLARE 474 { 475 /* We allow useless extra DECLAREs */ 476 } 477 | LESS_LESS any_identifier GREATER_GREATER 478 { 479 /* 480 * Throw a helpful error if user tries to put block 481 * label just before BEGIN, instead of before DECLARE. 482 */ 483 ereport(ERROR, 484 (errcode(ERRCODE_SYNTAX_ERROR), 485 errmsg("block label must be placed before DECLARE, not after"), 486 parser_errposition(@1))); 487 } 488 ; 489 490 decl_statement : decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval 491 { 492 PLpgSQL_variable *var; 493 494 /* 495 * If a collation is supplied, insert it into the 496 * datatype. We assume decl_datatype always returns 497 * a freshly built struct not shared with other 498 * variables. 499 */ 500 if (OidIsValid($4)) 501 { 502 if (!OidIsValid($3->collation)) 503 ereport(ERROR, 504 (errcode(ERRCODE_DATATYPE_MISMATCH), 505 errmsg("collations are not supported by type %s", 506 format_type_be($3->typoid)), 507 parser_errposition(@4))); 508 $3->collation = $4; 509 } 510 511 var = plpgsql_build_variable($1.name, $1.lineno, 512 $3, true); 513 var->isconst = $2; 514 var->notnull = $5; 515 var->default_val = $6; 516 517 /* 518 * The combination of NOT NULL without an initializer 519 * can't work, so let's reject it at compile time. 520 */ 521 if (var->notnull && var->default_val == NULL) 522 ereport(ERROR, 523 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 524 errmsg("variable \"%s\" must have a default value, since it's declared NOT NULL", 525 var->refname), 526 parser_errposition(@5))); 527 } 528 | decl_varname K_ALIAS K_FOR decl_aliasitem ';' 529 { 530 plpgsql_ns_additem($4->itemtype, 531 $4->itemno, $1.name); 532 } 533 | decl_varname opt_scrollable K_CURSOR 534 { plpgsql_ns_push($1.name, PLPGSQL_LABEL_OTHER); } 535 decl_cursor_args decl_is_for decl_cursor_query 536 { 537 PLpgSQL_var *new; 538 PLpgSQL_expr *curname_def; 539 char buf[1024]; 540 char *cp1; 541 char *cp2; 542 543 /* pop local namespace for cursor args */ 544 plpgsql_ns_pop(); 545 546 new = (PLpgSQL_var *) 547 plpgsql_build_variable($1.name, $1.lineno, 548 plpgsql_build_datatype(REFCURSOROID, 549 -1, 550 InvalidOid, 551 NULL), 552 true); 553 554 curname_def = palloc0(sizeof(PLpgSQL_expr)); 555 556 strcpy(buf, "SELECT "); 557 cp1 = new->refname; 558 cp2 = buf + strlen(buf); 559 /* 560 * Don't trust standard_conforming_strings here; 561 * it might change before we use the string. 562 */ 563 if (strchr(cp1, '\\') != NULL) 564 *cp2++ = ESCAPE_STRING_SYNTAX; 565 *cp2++ = '\''; 566 while (*cp1) 567 { 568 if (SQL_STR_DOUBLE(*cp1, true)) 569 *cp2++ = *cp1; 570 *cp2++ = *cp1++; 571 } 572 strcpy(cp2, "'::pg_catalog.refcursor"); 573 curname_def->query = pstrdup(buf); 574 new->default_val = curname_def; 575 576 new->cursor_explicit_expr = $7; 577 if ($5 == NULL) 578 new->cursor_explicit_argrow = -1; 579 else 580 new->cursor_explicit_argrow = $5->dno; 581 new->cursor_options = CURSOR_OPT_FAST_PLAN | $2; 582 } 583 ; 584 585 opt_scrollable : 586 { 587 $$ = 0; 588 } 589 | K_NO K_SCROLL 590 { 591 $$ = CURSOR_OPT_NO_SCROLL; 592 } 593 | K_SCROLL 594 { 595 $$ = CURSOR_OPT_SCROLL; 596 } 597 ; 598 599 decl_cursor_query : 600 { 601 $$ = read_sql_stmt(""); 602 } 603 ; 604 605 decl_cursor_args : 606 { 607 $$ = NULL; 608 } 609 | '(' decl_cursor_arglist ')' 610 { 611 PLpgSQL_row *new; 612 int i; 613 ListCell *l; 614 615 new = palloc0(sizeof(PLpgSQL_row)); 616 new->dtype = PLPGSQL_DTYPE_ROW; 617 new->refname = "(unnamed row)"; 618 new->lineno = plpgsql_location_to_lineno(@1); 619 new->rowtupdesc = NULL; 620 new->nfields = list_length($2); 621 new->fieldnames = palloc(new->nfields * sizeof(char *)); 622 new->varnos = palloc(new->nfields * sizeof(int)); 623 624 i = 0; 625 foreach (l, $2) 626 { 627 PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l); 628 Assert(!arg->isconst); 629 new->fieldnames[i] = arg->refname; 630 new->varnos[i] = arg->dno; 631 i++; 632 } 633 list_free($2); 634 635 plpgsql_adddatum((PLpgSQL_datum *) new); 636 $$ = (PLpgSQL_datum *) new; 637 } 638 ; 639 640 decl_cursor_arglist : decl_cursor_arg 641 { 642 $$ = list_make1($1); 643 } 644 | decl_cursor_arglist ',' decl_cursor_arg 645 { 646 $$ = lappend($1, $3); 647 } 648 ; 649 650 decl_cursor_arg : decl_varname decl_datatype 651 { 652 $$ = (PLpgSQL_datum *) 653 plpgsql_build_variable($1.name, $1.lineno, 654 $2, true); 655 } 656 ; 657 658 decl_is_for : K_IS | /* Oracle */ 659 K_FOR; /* SQL standard */ 660 661 decl_aliasitem : T_WORD 662 { 663 PLpgSQL_nsitem *nsi; 664 665 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, 666 $1.ident, NULL, NULL, 667 NULL); 668 if (nsi == NULL) 669 ereport(ERROR, 670 (errcode(ERRCODE_UNDEFINED_OBJECT), 671 errmsg("variable \"%s\" does not exist", 672 $1.ident), 673 parser_errposition(@1))); 674 $$ = nsi; 675 } 676 | unreserved_keyword 677 { 678 PLpgSQL_nsitem *nsi; 679 680 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, 681 $1, NULL, NULL, 682 NULL); 683 if (nsi == NULL) 684 ereport(ERROR, 685 (errcode(ERRCODE_UNDEFINED_OBJECT), 686 errmsg("variable \"%s\" does not exist", 687 $1), 688 parser_errposition(@1))); 689 $$ = nsi; 690 } 691 | T_CWORD 692 { 693 PLpgSQL_nsitem *nsi; 694 695 if (list_length($1.idents) == 2) 696 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, 697 strVal(linitial($1.idents)), 698 strVal(lsecond($1.idents)), 699 NULL, 700 NULL); 701 else if (list_length($1.idents) == 3) 702 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, 703 strVal(linitial($1.idents)), 704 strVal(lsecond($1.idents)), 705 strVal(lthird($1.idents)), 706 NULL); 707 else 708 nsi = NULL; 709 if (nsi == NULL) 710 ereport(ERROR, 711 (errcode(ERRCODE_UNDEFINED_OBJECT), 712 errmsg("variable \"%s\" does not exist", 713 NameListToString($1.idents)), 714 parser_errposition(@1))); 715 $$ = nsi; 716 } 717 ; 718 719 decl_varname : T_WORD 720 { 721 $$.name = $1.ident; 722 $$.lineno = plpgsql_location_to_lineno(@1); 723 /* 724 * Check to make sure name isn't already declared 725 * in the current block. 726 */ 727 if (plpgsql_ns_lookup(plpgsql_ns_top(), true, 728 $1.ident, NULL, NULL, 729 NULL) != NULL) 730 yyerror("duplicate declaration"); 731 732 if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR || 733 plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR) 734 { 735 PLpgSQL_nsitem *nsi; 736 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, 737 $1.ident, NULL, NULL, NULL); 738 if (nsi != NULL) 739 ereport(plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR ? ERROR : WARNING, 740 (errcode(ERRCODE_DUPLICATE_ALIAS), 741 errmsg("variable \"%s\" shadows a previously defined variable", 742 $1.ident), 743 parser_errposition(@1))); 744 } 745 746 } 747 | unreserved_keyword 748 { 749 $$.name = pstrdup($1); 750 $$.lineno = plpgsql_location_to_lineno(@1); 751 /* 752 * Check to make sure name isn't already declared 753 * in the current block. 754 */ 755 if (plpgsql_ns_lookup(plpgsql_ns_top(), true, 756 $1, NULL, NULL, 757 NULL) != NULL) 758 yyerror("duplicate declaration"); 759 760 if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR || 761 plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR) 762 { 763 PLpgSQL_nsitem *nsi; 764 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, 765 $1, NULL, NULL, NULL); 766 if (nsi != NULL) 767 ereport(plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR ? ERROR : WARNING, 768 (errcode(ERRCODE_DUPLICATE_ALIAS), 769 errmsg("variable \"%s\" shadows a previously defined variable", 770 $1), 771 parser_errposition(@1))); 772 } 773 774 } 775 ; 776 777 decl_const : 778 { $$ = false; } 779 | K_CONSTANT 780 { $$ = true; } 781 ; 782 783 decl_datatype : 784 { 785 /* 786 * If there's a lookahead token, read_datatype 787 * should consume it. 788 */ 789 $$ = read_datatype(yychar); 790 yyclearin; 791 } 792 ; 793 794 decl_collate : 795 { $$ = InvalidOid; } 796 | K_COLLATE T_WORD 797 { 798 $$ = get_collation_oid(list_make1(makeString($2.ident)), 799 false); 800 } 801 | K_COLLATE unreserved_keyword 802 { 803 $$ = get_collation_oid(list_make1(makeString(pstrdup($2))), 804 false); 805 } 806 | K_COLLATE T_CWORD 807 { 808 $$ = get_collation_oid($2.idents, false); 809 } 810 ; 811 812 decl_notnull : 813 { $$ = false; } 814 | K_NOT K_NULL 815 { $$ = true; } 816 ; 817 818 decl_defval : ';' 819 { $$ = NULL; } 820 | decl_defkey 821 { 822 $$ = read_sql_expression(';', ";"); 823 } 824 ; 825 826 decl_defkey : assign_operator 827 | K_DEFAULT 828 ; 829 830 /* 831 * Ada-based PL/SQL uses := for assignment and variable defaults, while 832 * the SQL standard uses equals for these cases and for GET 833 * DIAGNOSTICS, so we support both. FOR and OPEN only support :=. 834 */ 835 assign_operator : '=' 836 | COLON_EQUALS 837 ; 838 839 proc_sect : 840 { $$ = NIL; } 841 | proc_sect proc_stmt 842 { 843 /* don't bother linking null statements into list */ 844 if ($2 == NULL) 845 $$ = $1; 846 else 847 $$ = lappend($1, $2); 848 } 849 ; 850 851 proc_stmt : pl_block ';' 852 { $$ = $1; } 853 | stmt_assign 854 { $$ = $1; } 855 | stmt_if 856 { $$ = $1; } 857 | stmt_case 858 { $$ = $1; } 859 | stmt_loop 860 { $$ = $1; } 861 | stmt_while 862 { $$ = $1; } 863 | stmt_for 864 { $$ = $1; } 865 | stmt_foreach_a 866 { $$ = $1; } 867 | stmt_exit 868 { $$ = $1; } 869 | stmt_return 870 { $$ = $1; } 871 | stmt_raise 872 { $$ = $1; } 873 | stmt_assert 874 { $$ = $1; } 875 | stmt_execsql 876 { $$ = $1; } 877 | stmt_dynexecute 878 { $$ = $1; } 879 | stmt_perform 880 { $$ = $1; } 881 | stmt_call 882 { $$ = $1; } 883 | stmt_getdiag 884 { $$ = $1; } 885 | stmt_open 886 { $$ = $1; } 887 | stmt_fetch 888 { $$ = $1; } 889 | stmt_move 890 { $$ = $1; } 891 | stmt_close 892 { $$ = $1; } 893 | stmt_null 894 { $$ = $1; } 895 | stmt_commit 896 { $$ = $1; } 897 | stmt_rollback 898 { $$ = $1; } 899 | stmt_set 900 { $$ = $1; } 901 ; 902 903 stmt_perform : K_PERFORM expr_until_semi 904 { 905 PLpgSQL_stmt_perform *new; 906 907 new = palloc0(sizeof(PLpgSQL_stmt_perform)); 908 new->cmd_type = PLPGSQL_STMT_PERFORM; 909 new->lineno = plpgsql_location_to_lineno(@1); 910 new->expr = $2; 911 912 $$ = (PLpgSQL_stmt *)new; 913 } 914 ; 915 916 stmt_call : K_CALL 917 { 918 PLpgSQL_stmt_call *new; 919 920 new = palloc0(sizeof(PLpgSQL_stmt_call)); 921 new->cmd_type = PLPGSQL_STMT_CALL; 922 new->lineno = plpgsql_location_to_lineno(@1); 923 new->expr = read_sql_stmt("CALL "); 924 new->is_call = true; 925 926 $$ = (PLpgSQL_stmt *)new; 927 928 } 929 | K_DO 930 { 931 /* use the same structures as for CALL, for simplicity */ 932 PLpgSQL_stmt_call *new; 933 934 new = palloc0(sizeof(PLpgSQL_stmt_call)); 935 new->cmd_type = PLPGSQL_STMT_CALL; 936 new->lineno = plpgsql_location_to_lineno(@1); 937 new->expr = read_sql_stmt("DO "); 938 new->is_call = false; 939 940 $$ = (PLpgSQL_stmt *)new; 941 942 } 943 ; 944 945 stmt_assign : assign_var assign_operator expr_until_semi 946 { 947 PLpgSQL_stmt_assign *new; 948 949 new = palloc0(sizeof(PLpgSQL_stmt_assign)); 950 new->cmd_type = PLPGSQL_STMT_ASSIGN; 951 new->lineno = plpgsql_location_to_lineno(@1); 952 new->varno = $1->dno; 953 new->expr = $3; 954 955 $$ = (PLpgSQL_stmt *)new; 956 } 957 ; 958 959 stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';' 960 { 961 PLpgSQL_stmt_getdiag *new; 962 ListCell *lc; 963 964 new = palloc0(sizeof(PLpgSQL_stmt_getdiag)); 965 new->cmd_type = PLPGSQL_STMT_GETDIAG; 966 new->lineno = plpgsql_location_to_lineno(@1); 967 new->is_stacked = $2; 968 new->diag_items = $4; 969 970 /* 971 * Check information items are valid for area option. 972 */ 973 foreach(lc, new->diag_items) 974 { 975 PLpgSQL_diag_item *ditem = (PLpgSQL_diag_item *) lfirst(lc); 976 977 switch (ditem->kind) 978 { 979 /* these fields are disallowed in stacked case */ 980 case PLPGSQL_GETDIAG_ROW_COUNT: 981 case PLPGSQL_GETDIAG_RESULT_OID: 982 if (new->is_stacked) 983 ereport(ERROR, 984 (errcode(ERRCODE_SYNTAX_ERROR), 985 errmsg("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS", 986 plpgsql_getdiag_kindname(ditem->kind)), 987 parser_errposition(@1))); 988 break; 989 /* these fields are disallowed in current case */ 990 case PLPGSQL_GETDIAG_ERROR_CONTEXT: 991 case PLPGSQL_GETDIAG_ERROR_DETAIL: 992 case PLPGSQL_GETDIAG_ERROR_HINT: 993 case PLPGSQL_GETDIAG_RETURNED_SQLSTATE: 994 case PLPGSQL_GETDIAG_COLUMN_NAME: 995 case PLPGSQL_GETDIAG_CONSTRAINT_NAME: 996 case PLPGSQL_GETDIAG_DATATYPE_NAME: 997 case PLPGSQL_GETDIAG_MESSAGE_TEXT: 998 case PLPGSQL_GETDIAG_TABLE_NAME: 999 case PLPGSQL_GETDIAG_SCHEMA_NAME: 1000 if (!new->is_stacked) 1001 ereport(ERROR, 1002 (errcode(ERRCODE_SYNTAX_ERROR), 1003 errmsg("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS", 1004 plpgsql_getdiag_kindname(ditem->kind)), 1005 parser_errposition(@1))); 1006 break; 1007 /* these fields are allowed in either case */ 1008 case PLPGSQL_GETDIAG_CONTEXT: 1009 break; 1010 default: 1011 elog(ERROR, "unrecognized diagnostic item kind: %d", 1012 ditem->kind); 1013 break; 1014 } 1015 } 1016 1017 $$ = (PLpgSQL_stmt *)new; 1018 } 1019 ; 1020 1021 getdiag_area_opt : 1022 { 1023 $$ = false; 1024 } 1025 | K_CURRENT 1026 { 1027 $$ = false; 1028 } 1029 | K_STACKED 1030 { 1031 $$ = true; 1032 } 1033 ; 1034 1035 getdiag_list : getdiag_list ',' getdiag_list_item 1036 { 1037 $$ = lappend($1, $3); 1038 } 1039 | getdiag_list_item 1040 { 1041 $$ = list_make1($1); 1042 } 1043 ; 1044 1045 getdiag_list_item : getdiag_target assign_operator getdiag_item 1046 { 1047 PLpgSQL_diag_item *new; 1048 1049 new = palloc(sizeof(PLpgSQL_diag_item)); 1050 new->target = $1->dno; 1051 new->kind = $3; 1052 1053 $$ = new; 1054 } 1055 ; 1056 1057 getdiag_item : 1058 { 1059 int tok = yylex(); 1060 1061 if (tok_is_keyword(tok, &yylval, 1062 K_ROW_COUNT, "row_count")) 1063 $$ = PLPGSQL_GETDIAG_ROW_COUNT; 1064 else if (tok_is_keyword(tok, &yylval, 1065 K_RESULT_OID, "result_oid")) 1066 $$ = PLPGSQL_GETDIAG_RESULT_OID; 1067 else if (tok_is_keyword(tok, &yylval, 1068 K_PG_CONTEXT, "pg_context")) 1069 $$ = PLPGSQL_GETDIAG_CONTEXT; 1070 else if (tok_is_keyword(tok, &yylval, 1071 K_PG_EXCEPTION_DETAIL, "pg_exception_detail")) 1072 $$ = PLPGSQL_GETDIAG_ERROR_DETAIL; 1073 else if (tok_is_keyword(tok, &yylval, 1074 K_PG_EXCEPTION_HINT, "pg_exception_hint")) 1075 $$ = PLPGSQL_GETDIAG_ERROR_HINT; 1076 else if (tok_is_keyword(tok, &yylval, 1077 K_PG_EXCEPTION_CONTEXT, "pg_exception_context")) 1078 $$ = PLPGSQL_GETDIAG_ERROR_CONTEXT; 1079 else if (tok_is_keyword(tok, &yylval, 1080 K_COLUMN_NAME, "column_name")) 1081 $$ = PLPGSQL_GETDIAG_COLUMN_NAME; 1082 else if (tok_is_keyword(tok, &yylval, 1083 K_CONSTRAINT_NAME, "constraint_name")) 1084 $$ = PLPGSQL_GETDIAG_CONSTRAINT_NAME; 1085 else if (tok_is_keyword(tok, &yylval, 1086 K_PG_DATATYPE_NAME, "pg_datatype_name")) 1087 $$ = PLPGSQL_GETDIAG_DATATYPE_NAME; 1088 else if (tok_is_keyword(tok, &yylval, 1089 K_MESSAGE_TEXT, "message_text")) 1090 $$ = PLPGSQL_GETDIAG_MESSAGE_TEXT; 1091 else if (tok_is_keyword(tok, &yylval, 1092 K_TABLE_NAME, "table_name")) 1093 $$ = PLPGSQL_GETDIAG_TABLE_NAME; 1094 else if (tok_is_keyword(tok, &yylval, 1095 K_SCHEMA_NAME, "schema_name")) 1096 $$ = PLPGSQL_GETDIAG_SCHEMA_NAME; 1097 else if (tok_is_keyword(tok, &yylval, 1098 K_RETURNED_SQLSTATE, "returned_sqlstate")) 1099 $$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE; 1100 else 1101 yyerror("unrecognized GET DIAGNOSTICS item"); 1102 } 1103 ; 1104 1105 getdiag_target : assign_var 1106 { 1107 if ($1->dtype == PLPGSQL_DTYPE_ROW || 1108 $1->dtype == PLPGSQL_DTYPE_REC) 1109 ereport(ERROR, 1110 (errcode(ERRCODE_SYNTAX_ERROR), 1111 errmsg("\"%s\" is not a scalar variable", 1112 ((PLpgSQL_variable *) $1)->refname), 1113 parser_errposition(@1))); 1114 $$ = $1; 1115 } 1116 | T_WORD 1117 { 1118 /* just to give a better message than "syntax error" */ 1119 word_is_not_variable(&($1), @1); 1120 } 1121 | T_CWORD 1122 { 1123 /* just to give a better message than "syntax error" */ 1124 cword_is_not_variable(&($1), @1); 1125 } 1126 ; 1127 1128 1129 assign_var : T_DATUM 1130 { 1131 check_assignable($1.datum, @1); 1132 $$ = $1.datum; 1133 } 1134 | assign_var '[' expr_until_rightbracket 1135 { 1136 PLpgSQL_arrayelem *new; 1137 1138 new = palloc0(sizeof(PLpgSQL_arrayelem)); 1139 new->dtype = PLPGSQL_DTYPE_ARRAYELEM; 1140 new->subscript = $3; 1141 new->arrayparentno = $1->dno; 1142 /* initialize cached type data to "not valid" */ 1143 new->parenttypoid = InvalidOid; 1144 1145 plpgsql_adddatum((PLpgSQL_datum *) new); 1146 1147 $$ = (PLpgSQL_datum *) new; 1148 } 1149 ; 1150 1151 stmt_if : K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';' 1152 { 1153 PLpgSQL_stmt_if *new; 1154 1155 new = palloc0(sizeof(PLpgSQL_stmt_if)); 1156 new->cmd_type = PLPGSQL_STMT_IF; 1157 new->lineno = plpgsql_location_to_lineno(@1); 1158 new->cond = $2; 1159 new->then_body = $3; 1160 new->elsif_list = $4; 1161 new->else_body = $5; 1162 1163 $$ = (PLpgSQL_stmt *)new; 1164 } 1165 ; 1166 1167 stmt_elsifs : 1168 { 1169 $$ = NIL; 1170 } 1171 | stmt_elsifs K_ELSIF expr_until_then proc_sect 1172 { 1173 PLpgSQL_if_elsif *new; 1174 1175 new = palloc0(sizeof(PLpgSQL_if_elsif)); 1176 new->lineno = plpgsql_location_to_lineno(@2); 1177 new->cond = $3; 1178 new->stmts = $4; 1179 1180 $$ = lappend($1, new); 1181 } 1182 ; 1183 1184 stmt_else : 1185 { 1186 $$ = NIL; 1187 } 1188 | K_ELSE proc_sect 1189 { 1190 $$ = $2; 1191 } 1192 ; 1193 1194 stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';' 1195 { 1196 $$ = make_case(@1, $2, $3, $4); 1197 } 1198 ; 1199 1200 opt_expr_until_when : 1201 { 1202 PLpgSQL_expr *expr = NULL; 1203 int tok = yylex(); 1204 1205 if (tok != K_WHEN) 1206 { 1207 plpgsql_push_back_token(tok); 1208 expr = read_sql_expression(K_WHEN, "WHEN"); 1209 } 1210 plpgsql_push_back_token(K_WHEN); 1211 $$ = expr; 1212 } 1213 ; 1214 1215 case_when_list : case_when_list case_when 1216 { 1217 $$ = lappend($1, $2); 1218 } 1219 | case_when 1220 { 1221 $$ = list_make1($1); 1222 } 1223 ; 1224 1225 case_when : K_WHEN expr_until_then proc_sect 1226 { 1227 PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when)); 1228 1229 new->lineno = plpgsql_location_to_lineno(@1); 1230 new->expr = $2; 1231 new->stmts = $3; 1232 $$ = new; 1233 } 1234 ; 1235 1236 opt_case_else : 1237 { 1238 $$ = NIL; 1239 } 1240 | K_ELSE proc_sect 1241 { 1242 /* 1243 * proc_sect could return an empty list, but we 1244 * must distinguish that from not having ELSE at all. 1245 * Simplest fix is to return a list with one NULL 1246 * pointer, which make_case() must take care of. 1247 */ 1248 if ($2 != NIL) 1249 $$ = $2; 1250 else 1251 $$ = list_make1(NULL); 1252 } 1253 ; 1254 1255 stmt_loop : opt_loop_label K_LOOP loop_body 1256 { 1257 PLpgSQL_stmt_loop *new; 1258 1259 new = palloc0(sizeof(PLpgSQL_stmt_loop)); 1260 new->cmd_type = PLPGSQL_STMT_LOOP; 1261 new->lineno = plpgsql_location_to_lineno(@2); 1262 new->label = $1; 1263 new->body = $3.stmts; 1264 1265 check_labels($1, $3.end_label, $3.end_label_location); 1266 plpgsql_ns_pop(); 1267 1268 $$ = (PLpgSQL_stmt *)new; 1269 } 1270 ; 1271 1272 stmt_while : opt_loop_label K_WHILE expr_until_loop loop_body 1273 { 1274 PLpgSQL_stmt_while *new; 1275 1276 new = palloc0(sizeof(PLpgSQL_stmt_while)); 1277 new->cmd_type = PLPGSQL_STMT_WHILE; 1278 new->lineno = plpgsql_location_to_lineno(@2); 1279 new->label = $1; 1280 new->cond = $3; 1281 new->body = $4.stmts; 1282 1283 check_labels($1, $4.end_label, $4.end_label_location); 1284 plpgsql_ns_pop(); 1285 1286 $$ = (PLpgSQL_stmt *)new; 1287 } 1288 ; 1289 1290 stmt_for : opt_loop_label K_FOR for_control loop_body 1291 { 1292 /* This runs after we've scanned the loop body */ 1293 if ($3->cmd_type == PLPGSQL_STMT_FORI) 1294 { 1295 PLpgSQL_stmt_fori *new; 1296 1297 new = (PLpgSQL_stmt_fori *) $3; 1298 new->lineno = plpgsql_location_to_lineno(@2); 1299 new->label = $1; 1300 new->body = $4.stmts; 1301 $$ = (PLpgSQL_stmt *) new; 1302 } 1303 else 1304 { 1305 PLpgSQL_stmt_forq *new; 1306 1307 Assert($3->cmd_type == PLPGSQL_STMT_FORS || 1308 $3->cmd_type == PLPGSQL_STMT_FORC || 1309 $3->cmd_type == PLPGSQL_STMT_DYNFORS); 1310 /* forq is the common supertype of all three */ 1311 new = (PLpgSQL_stmt_forq *) $3; 1312 new->lineno = plpgsql_location_to_lineno(@2); 1313 new->label = $1; 1314 new->body = $4.stmts; 1315 $$ = (PLpgSQL_stmt *) new; 1316 } 1317 1318 check_labels($1, $4.end_label, $4.end_label_location); 1319 /* close namespace started in opt_loop_label */ 1320 plpgsql_ns_pop(); 1321 } 1322 ; 1323 1324 for_control : for_variable K_IN 1325 { 1326 int tok = yylex(); 1327 int tokloc = yylloc; 1328 1329 if (tok == K_EXECUTE) 1330 { 1331 /* EXECUTE means it's a dynamic FOR loop */ 1332 PLpgSQL_stmt_dynfors *new; 1333 PLpgSQL_expr *expr; 1334 int term; 1335 1336 expr = read_sql_expression2(K_LOOP, K_USING, 1337 "LOOP or USING", 1338 &term); 1339 1340 new = palloc0(sizeof(PLpgSQL_stmt_dynfors)); 1341 new->cmd_type = PLPGSQL_STMT_DYNFORS; 1342 if ($1.row) 1343 { 1344 new->var = (PLpgSQL_variable *) $1.row; 1345 check_assignable($1.row, @1); 1346 } 1347 else if ($1.scalar) 1348 { 1349 /* convert single scalar to list */ 1350 new->var = (PLpgSQL_variable *) 1351 make_scalar_list1($1.name, $1.scalar, 1352 $1.lineno, @1); 1353 /* make_scalar_list1 did check_assignable */ 1354 } 1355 else 1356 { 1357 ereport(ERROR, 1358 (errcode(ERRCODE_DATATYPE_MISMATCH), 1359 errmsg("loop variable of loop over rows must be a record variable or list of scalar variables"), 1360 parser_errposition(@1))); 1361 } 1362 new->query = expr; 1363 1364 if (term == K_USING) 1365 { 1366 do 1367 { 1368 expr = read_sql_expression2(',', K_LOOP, 1369 ", or LOOP", 1370 &term); 1371 new->params = lappend(new->params, expr); 1372 } while (term == ','); 1373 } 1374 1375 $$ = (PLpgSQL_stmt *) new; 1376 } 1377 else if (tok == T_DATUM && 1378 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR && 1379 ((PLpgSQL_var *) yylval.wdatum.datum)->datatype->typoid == REFCURSOROID) 1380 { 1381 /* It's FOR var IN cursor */ 1382 PLpgSQL_stmt_forc *new; 1383 PLpgSQL_var *cursor = (PLpgSQL_var *) yylval.wdatum.datum; 1384 1385 new = (PLpgSQL_stmt_forc *) palloc0(sizeof(PLpgSQL_stmt_forc)); 1386 new->cmd_type = PLPGSQL_STMT_FORC; 1387 new->curvar = cursor->dno; 1388 1389 /* Should have had a single variable name */ 1390 if ($1.scalar && $1.row) 1391 ereport(ERROR, 1392 (errcode(ERRCODE_SYNTAX_ERROR), 1393 errmsg("cursor FOR loop must have only one target variable"), 1394 parser_errposition(@1))); 1395 1396 /* can't use an unbound cursor this way */ 1397 if (cursor->cursor_explicit_expr == NULL) 1398 ereport(ERROR, 1399 (errcode(ERRCODE_SYNTAX_ERROR), 1400 errmsg("cursor FOR loop must use a bound cursor variable"), 1401 parser_errposition(tokloc))); 1402 1403 /* collect cursor's parameters if any */ 1404 new->argquery = read_cursor_args(cursor, 1405 K_LOOP, 1406 "LOOP"); 1407 1408 /* create loop's private RECORD variable */ 1409 new->var = (PLpgSQL_variable *) 1410 plpgsql_build_record($1.name, 1411 $1.lineno, 1412 NULL, 1413 RECORDOID, 1414 true); 1415 1416 $$ = (PLpgSQL_stmt *) new; 1417 } 1418 else 1419 { 1420 PLpgSQL_expr *expr1; 1421 int expr1loc; 1422 bool reverse = false; 1423 1424 /* 1425 * We have to distinguish between two 1426 * alternatives: FOR var IN a .. b and FOR 1427 * var IN query. Unfortunately this is 1428 * tricky, since the query in the second 1429 * form needn't start with a SELECT 1430 * keyword. We use the ugly hack of 1431 * looking for two periods after the first 1432 * token. We also check for the REVERSE 1433 * keyword, which means it must be an 1434 * integer loop. 1435 */ 1436 if (tok_is_keyword(tok, &yylval, 1437 K_REVERSE, "reverse")) 1438 reverse = true; 1439 else 1440 plpgsql_push_back_token(tok); 1441 1442 /* 1443 * Read tokens until we see either a ".." 1444 * or a LOOP. The text we read may not 1445 * necessarily be a well-formed SQL 1446 * statement, so we need to invoke 1447 * read_sql_construct directly. 1448 */ 1449 expr1 = read_sql_construct(DOT_DOT, 1450 K_LOOP, 1451 0, 1452 "LOOP", 1453 "SELECT ", 1454 true, 1455 false, 1456 true, 1457 &expr1loc, 1458 &tok); 1459 1460 if (tok == DOT_DOT) 1461 { 1462 /* Saw "..", so it must be an integer loop */ 1463 PLpgSQL_expr *expr2; 1464 PLpgSQL_expr *expr_by; 1465 PLpgSQL_var *fvar; 1466 PLpgSQL_stmt_fori *new; 1467 1468 /* Check first expression is well-formed */ 1469 check_sql_expr(expr1->query, expr1loc, 7); 1470 1471 /* Read and check the second one */ 1472 expr2 = read_sql_expression2(K_LOOP, K_BY, 1473 "LOOP", 1474 &tok); 1475 1476 /* Get the BY clause if any */ 1477 if (tok == K_BY) 1478 expr_by = read_sql_expression(K_LOOP, 1479 "LOOP"); 1480 else 1481 expr_by = NULL; 1482 1483 /* Should have had a single variable name */ 1484 if ($1.scalar && $1.row) 1485 ereport(ERROR, 1486 (errcode(ERRCODE_SYNTAX_ERROR), 1487 errmsg("integer FOR loop must have only one target variable"), 1488 parser_errposition(@1))); 1489 1490 /* create loop's private variable */ 1491 fvar = (PLpgSQL_var *) 1492 plpgsql_build_variable($1.name, 1493 $1.lineno, 1494 plpgsql_build_datatype(INT4OID, 1495 -1, 1496 InvalidOid, 1497 NULL), 1498 true); 1499 1500 new = palloc0(sizeof(PLpgSQL_stmt_fori)); 1501 new->cmd_type = PLPGSQL_STMT_FORI; 1502 new->var = fvar; 1503 new->reverse = reverse; 1504 new->lower = expr1; 1505 new->upper = expr2; 1506 new->step = expr_by; 1507 1508 $$ = (PLpgSQL_stmt *) new; 1509 } 1510 else 1511 { 1512 /* 1513 * No "..", so it must be a query loop. We've 1514 * prefixed an extra SELECT to the query text, 1515 * so we need to remove that before performing 1516 * syntax checking. 1517 */ 1518 char *tmp_query; 1519 PLpgSQL_stmt_fors *new; 1520 1521 if (reverse) 1522 ereport(ERROR, 1523 (errcode(ERRCODE_SYNTAX_ERROR), 1524 errmsg("cannot specify REVERSE in query FOR loop"), 1525 parser_errposition(tokloc))); 1526 1527 Assert(strncmp(expr1->query, "SELECT ", 7) == 0); 1528 tmp_query = pstrdup(expr1->query + 7); 1529 pfree(expr1->query); 1530 expr1->query = tmp_query; 1531 1532 check_sql_expr(expr1->query, expr1loc, 0); 1533 1534 new = palloc0(sizeof(PLpgSQL_stmt_fors)); 1535 new->cmd_type = PLPGSQL_STMT_FORS; 1536 if ($1.row) 1537 { 1538 new->var = (PLpgSQL_variable *) $1.row; 1539 check_assignable($1.row, @1); 1540 } 1541 else if ($1.scalar) 1542 { 1543 /* convert single scalar to list */ 1544 new->var = (PLpgSQL_variable *) 1545 make_scalar_list1($1.name, $1.scalar, 1546 $1.lineno, @1); 1547 /* make_scalar_list1 did check_assignable */ 1548 } 1549 else 1550 { 1551 ereport(ERROR, 1552 (errcode(ERRCODE_SYNTAX_ERROR), 1553 errmsg("loop variable of loop over rows must be a record variable or list of scalar variables"), 1554 parser_errposition(@1))); 1555 } 1556 1557 new->query = expr1; 1558 $$ = (PLpgSQL_stmt *) new; 1559 } 1560 } 1561 } 1562 ; 1563 1564 /* 1565 * Processing the for_variable is tricky because we don't yet know if the 1566 * FOR is an integer FOR loop or a loop over query results. In the former 1567 * case, the variable is just a name that we must instantiate as a loop 1568 * local variable, regardless of any other definition it might have. 1569 * Therefore, we always save the actual identifier into $$.name where it 1570 * can be used for that case. We also save the outer-variable definition, 1571 * if any, because that's what we need for the loop-over-query case. Note 1572 * that we must NOT apply check_assignable() or any other semantic check 1573 * until we know what's what. 1574 * 1575 * However, if we see a comma-separated list of names, we know that it 1576 * can't be an integer FOR loop and so it's OK to check the variables 1577 * immediately. In particular, for T_WORD followed by comma, we should 1578 * complain that the name is not known rather than say it's a syntax error. 1579 * Note that the non-error result of this case sets *both* $$.scalar and 1580 * $$.row; see the for_control production. 1581 */ 1582 for_variable : T_DATUM 1583 { 1584 $$.name = NameOfDatum(&($1)); 1585 $$.lineno = plpgsql_location_to_lineno(@1); 1586 if ($1.datum->dtype == PLPGSQL_DTYPE_ROW || 1587 $1.datum->dtype == PLPGSQL_DTYPE_REC) 1588 { 1589 $$.scalar = NULL; 1590 $$.row = $1.datum; 1591 } 1592 else 1593 { 1594 int tok; 1595 1596 $$.scalar = $1.datum; 1597 $$.row = NULL; 1598 /* check for comma-separated list */ 1599 tok = yylex(); 1600 plpgsql_push_back_token(tok); 1601 if (tok == ',') 1602 $$.row = (PLpgSQL_datum *) 1603 read_into_scalar_list($$.name, 1604 $$.scalar, 1605 @1); 1606 } 1607 } 1608 | T_WORD 1609 { 1610 int tok; 1611 1612 $$.name = $1.ident; 1613 $$.lineno = plpgsql_location_to_lineno(@1); 1614 $$.scalar = NULL; 1615 $$.row = NULL; 1616 /* check for comma-separated list */ 1617 tok = yylex(); 1618 plpgsql_push_back_token(tok); 1619 if (tok == ',') 1620 word_is_not_variable(&($1), @1); 1621 } 1622 | T_CWORD 1623 { 1624 /* just to give a better message than "syntax error" */ 1625 cword_is_not_variable(&($1), @1); 1626 } 1627 ; 1628 1629 stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRAY expr_until_loop loop_body 1630 { 1631 PLpgSQL_stmt_foreach_a *new; 1632 1633 new = palloc0(sizeof(PLpgSQL_stmt_foreach_a)); 1634 new->cmd_type = PLPGSQL_STMT_FOREACH_A; 1635 new->lineno = plpgsql_location_to_lineno(@2); 1636 new->label = $1; 1637 new->slice = $4; 1638 new->expr = $7; 1639 new->body = $8.stmts; 1640 1641 if ($3.row) 1642 { 1643 new->varno = $3.row->dno; 1644 check_assignable($3.row, @3); 1645 } 1646 else if ($3.scalar) 1647 { 1648 new->varno = $3.scalar->dno; 1649 check_assignable($3.scalar, @3); 1650 } 1651 else 1652 { 1653 ereport(ERROR, 1654 (errcode(ERRCODE_SYNTAX_ERROR), 1655 errmsg("loop variable of FOREACH must be a known variable or list of variables"), 1656 parser_errposition(@3))); 1657 } 1658 1659 check_labels($1, $8.end_label, $8.end_label_location); 1660 plpgsql_ns_pop(); 1661 1662 $$ = (PLpgSQL_stmt *) new; 1663 } 1664 ; 1665 1666 foreach_slice : 1667 { 1668 $$ = 0; 1669 } 1670 | K_SLICE ICONST 1671 { 1672 $$ = $2; 1673 } 1674 ; 1675 1676 stmt_exit : exit_type opt_label opt_exitcond 1677 { 1678 PLpgSQL_stmt_exit *new; 1679 1680 new = palloc0(sizeof(PLpgSQL_stmt_exit)); 1681 new->cmd_type = PLPGSQL_STMT_EXIT; 1682 new->is_exit = $1; 1683 new->lineno = plpgsql_location_to_lineno(@1); 1684 new->label = $2; 1685 new->cond = $3; 1686 1687 if ($2) 1688 { 1689 /* We have a label, so verify it exists */ 1690 PLpgSQL_nsitem *label; 1691 1692 label = plpgsql_ns_lookup_label(plpgsql_ns_top(), $2); 1693 if (label == NULL) 1694 ereport(ERROR, 1695 (errcode(ERRCODE_SYNTAX_ERROR), 1696 errmsg("there is no label \"%s\" " 1697 "attached to any block or loop enclosing this statement", 1698 $2), 1699 parser_errposition(@2))); 1700 /* CONTINUE only allows loop labels */ 1701 if (label->itemno != PLPGSQL_LABEL_LOOP && !new->is_exit) 1702 ereport(ERROR, 1703 (errcode(ERRCODE_SYNTAX_ERROR), 1704 errmsg("block label \"%s\" cannot be used in CONTINUE", 1705 $2), 1706 parser_errposition(@2))); 1707 } 1708 else 1709 { 1710 /* 1711 * No label, so make sure there is some loop (an 1712 * unlabelled EXIT does not match a block, so this 1713 * is the same test for both EXIT and CONTINUE) 1714 */ 1715 if (plpgsql_ns_find_nearest_loop(plpgsql_ns_top()) == NULL) 1716 ereport(ERROR, 1717 (errcode(ERRCODE_SYNTAX_ERROR), 1718 new->is_exit ? 1719 errmsg("EXIT cannot be used outside a loop, unless it has a label") : 1720 errmsg("CONTINUE cannot be used outside a loop"), 1721 parser_errposition(@1))); 1722 } 1723 1724 $$ = (PLpgSQL_stmt *)new; 1725 } 1726 ; 1727 1728 exit_type : K_EXIT 1729 { 1730 $$ = true; 1731 } 1732 | K_CONTINUE 1733 { 1734 $$ = false; 1735 } 1736 ; 1737 1738 stmt_return : K_RETURN 1739 { 1740 int tok; 1741 1742 tok = yylex(); 1743 if (tok == 0) 1744 yyerror("unexpected end of function definition"); 1745 1746 if (tok_is_keyword(tok, &yylval, 1747 K_NEXT, "next")) 1748 { 1749 $$ = make_return_next_stmt(@1); 1750 } 1751 else if (tok_is_keyword(tok, &yylval, 1752 K_QUERY, "query")) 1753 { 1754 $$ = make_return_query_stmt(@1); 1755 } 1756 else 1757 { 1758 plpgsql_push_back_token(tok); 1759 $$ = make_return_stmt(@1); 1760 } 1761 } 1762 ; 1763 1764 stmt_raise : K_RAISE 1765 { 1766 PLpgSQL_stmt_raise *new; 1767 int tok; 1768 1769 new = palloc(sizeof(PLpgSQL_stmt_raise)); 1770 1771 new->cmd_type = PLPGSQL_STMT_RAISE; 1772 new->lineno = plpgsql_location_to_lineno(@1); 1773 new->elog_level = ERROR; /* default */ 1774 new->condname = NULL; 1775 new->message = NULL; 1776 new->params = NIL; 1777 new->options = NIL; 1778 1779 tok = yylex(); 1780 if (tok == 0) 1781 yyerror("unexpected end of function definition"); 1782 1783 /* 1784 * We could have just RAISE, meaning to re-throw 1785 * the current error. 1786 */ 1787 if (tok != ';') 1788 { 1789 /* 1790 * First is an optional elog severity level. 1791 */ 1792 if (tok_is_keyword(tok, &yylval, 1793 K_EXCEPTION, "exception")) 1794 { 1795 new->elog_level = ERROR; 1796 tok = yylex(); 1797 } 1798 else if (tok_is_keyword(tok, &yylval, 1799 K_WARNING, "warning")) 1800 { 1801 new->elog_level = WARNING; 1802 tok = yylex(); 1803 } 1804 else if (tok_is_keyword(tok, &yylval, 1805 K_NOTICE, "notice")) 1806 { 1807 new->elog_level = NOTICE; 1808 tok = yylex(); 1809 } 1810 else if (tok_is_keyword(tok, &yylval, 1811 K_INFO, "info")) 1812 { 1813 new->elog_level = INFO; 1814 tok = yylex(); 1815 } 1816 else if (tok_is_keyword(tok, &yylval, 1817 K_LOG, "log")) 1818 { 1819 new->elog_level = LOG; 1820 tok = yylex(); 1821 } 1822 else if (tok_is_keyword(tok, &yylval, 1823 K_DEBUG, "debug")) 1824 { 1825 new->elog_level = DEBUG1; 1826 tok = yylex(); 1827 } 1828 if (tok == 0) 1829 yyerror("unexpected end of function definition"); 1830 1831 /* 1832 * Next we can have a condition name, or 1833 * equivalently SQLSTATE 'xxxxx', or a string 1834 * literal that is the old-style message format, 1835 * or USING to start the option list immediately. 1836 */ 1837 if (tok == SCONST) 1838 { 1839 /* old style message and parameters */ 1840 new->message = yylval.str; 1841 /* 1842 * We expect either a semi-colon, which 1843 * indicates no parameters, or a comma that 1844 * begins the list of parameter expressions, 1845 * or USING to begin the options list. 1846 */ 1847 tok = yylex(); 1848 if (tok != ',' && tok != ';' && tok != K_USING) 1849 yyerror("syntax error"); 1850 1851 while (tok == ',') 1852 { 1853 PLpgSQL_expr *expr; 1854 1855 expr = read_sql_construct(',', ';', K_USING, 1856 ", or ; or USING", 1857 "SELECT ", 1858 true, true, true, 1859 NULL, &tok); 1860 new->params = lappend(new->params, expr); 1861 } 1862 } 1863 else if (tok != K_USING) 1864 { 1865 /* must be condition name or SQLSTATE */ 1866 if (tok_is_keyword(tok, &yylval, 1867 K_SQLSTATE, "sqlstate")) 1868 { 1869 /* next token should be a string literal */ 1870 char *sqlstatestr; 1871 1872 if (yylex() != SCONST) 1873 yyerror("syntax error"); 1874 sqlstatestr = yylval.str; 1875 1876 if (strlen(sqlstatestr) != 5) 1877 yyerror("invalid SQLSTATE code"); 1878 if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5) 1879 yyerror("invalid SQLSTATE code"); 1880 new->condname = sqlstatestr; 1881 } 1882 else 1883 { 1884 if (tok == T_WORD) 1885 new->condname = yylval.word.ident; 1886 else if (plpgsql_token_is_unreserved_keyword(tok)) 1887 new->condname = pstrdup(yylval.keyword); 1888 else 1889 yyerror("syntax error"); 1890 plpgsql_recognize_err_condition(new->condname, 1891 false); 1892 } 1893 tok = yylex(); 1894 if (tok != ';' && tok != K_USING) 1895 yyerror("syntax error"); 1896 } 1897 1898 if (tok == K_USING) 1899 new->options = read_raise_options(); 1900 } 1901 1902 check_raise_parameters(new); 1903 1904 $$ = (PLpgSQL_stmt *)new; 1905 } 1906 ; 1907 1908 stmt_assert : K_ASSERT 1909 { 1910 PLpgSQL_stmt_assert *new; 1911 int tok; 1912 1913 new = palloc(sizeof(PLpgSQL_stmt_assert)); 1914 1915 new->cmd_type = PLPGSQL_STMT_ASSERT; 1916 new->lineno = plpgsql_location_to_lineno(@1); 1917 1918 new->cond = read_sql_expression2(',', ';', 1919 ", or ;", 1920 &tok); 1921 1922 if (tok == ',') 1923 new->message = read_sql_expression(';', ";"); 1924 else 1925 new->message = NULL; 1926 1927 $$ = (PLpgSQL_stmt *) new; 1928 } 1929 ; 1930 1931 loop_body : proc_sect K_END K_LOOP opt_label ';' 1932 { 1933 $$.stmts = $1; 1934 $$.end_label = $4; 1935 $$.end_label_location = @4; 1936 } 1937 ; 1938 1939 /* 1940 * T_WORD+T_CWORD match any initial identifier that is not a known plpgsql 1941 * variable. (The composite case is probably a syntax error, but we'll let 1942 * the core parser decide that.) Normally, we should assume that such a 1943 * word is a SQL statement keyword that isn't also a plpgsql keyword. 1944 * However, if the next token is assignment or '[', it can't be a valid 1945 * SQL statement, and what we're probably looking at is an intended variable 1946 * assignment. Give an appropriate complaint for that, instead of letting 1947 * the core parser throw an unhelpful "syntax error". 1948 */ 1949 stmt_execsql : K_IMPORT 1950 { 1951 $$ = make_execsql_stmt(K_IMPORT, @1); 1952 } 1953 | K_INSERT 1954 { 1955 $$ = make_execsql_stmt(K_INSERT, @1); 1956 } 1957 | T_WORD 1958 { 1959 int tok; 1960 1961 tok = yylex(); 1962 plpgsql_push_back_token(tok); 1963 if (tok == '=' || tok == COLON_EQUALS || tok == '[') 1964 word_is_not_variable(&($1), @1); 1965 $$ = make_execsql_stmt(T_WORD, @1); 1966 } 1967 | T_CWORD 1968 { 1969 int tok; 1970 1971 tok = yylex(); 1972 plpgsql_push_back_token(tok); 1973 if (tok == '=' || tok == COLON_EQUALS || tok == '[') 1974 cword_is_not_variable(&($1), @1); 1975 $$ = make_execsql_stmt(T_CWORD, @1); 1976 } 1977 ; 1978 1979 stmt_dynexecute : K_EXECUTE 1980 { 1981 PLpgSQL_stmt_dynexecute *new; 1982 PLpgSQL_expr *expr; 1983 int endtoken; 1984 1985 expr = read_sql_construct(K_INTO, K_USING, ';', 1986 "INTO or USING or ;", 1987 "SELECT ", 1988 true, true, true, 1989 NULL, &endtoken); 1990 1991 new = palloc(sizeof(PLpgSQL_stmt_dynexecute)); 1992 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE; 1993 new->lineno = plpgsql_location_to_lineno(@1); 1994 new->query = expr; 1995 new->into = false; 1996 new->strict = false; 1997 new->target = NULL; 1998 new->params = NIL; 1999 2000 /* 2001 * We loop to allow the INTO and USING clauses to 2002 * appear in either order, since people easily get 2003 * that wrong. This coding also prevents "INTO foo" 2004 * from getting absorbed into a USING expression, 2005 * which is *really* confusing. 2006 */ 2007 for (;;) 2008 { 2009 if (endtoken == K_INTO) 2010 { 2011 if (new->into) /* multiple INTO */ 2012 yyerror("syntax error"); 2013 new->into = true; 2014 read_into_target(&new->target, &new->strict); 2015 endtoken = yylex(); 2016 } 2017 else if (endtoken == K_USING) 2018 { 2019 if (new->params) /* multiple USING */ 2020 yyerror("syntax error"); 2021 do 2022 { 2023 expr = read_sql_construct(',', ';', K_INTO, 2024 ", or ; or INTO", 2025 "SELECT ", 2026 true, true, true, 2027 NULL, &endtoken); 2028 new->params = lappend(new->params, expr); 2029 } while (endtoken == ','); 2030 } 2031 else if (endtoken == ';') 2032 break; 2033 else 2034 yyerror("syntax error"); 2035 } 2036 2037 $$ = (PLpgSQL_stmt *)new; 2038 } 2039 ; 2040 2041 2042 stmt_open : K_OPEN cursor_variable 2043 { 2044 PLpgSQL_stmt_open *new; 2045 int tok; 2046 2047 new = palloc0(sizeof(PLpgSQL_stmt_open)); 2048 new->cmd_type = PLPGSQL_STMT_OPEN; 2049 new->lineno = plpgsql_location_to_lineno(@1); 2050 new->curvar = $2->dno; 2051 new->cursor_options = CURSOR_OPT_FAST_PLAN; 2052 2053 if ($2->cursor_explicit_expr == NULL) 2054 { 2055 /* be nice if we could use opt_scrollable here */ 2056 tok = yylex(); 2057 if (tok_is_keyword(tok, &yylval, 2058 K_NO, "no")) 2059 { 2060 tok = yylex(); 2061 if (tok_is_keyword(tok, &yylval, 2062 K_SCROLL, "scroll")) 2063 { 2064 new->cursor_options |= CURSOR_OPT_NO_SCROLL; 2065 tok = yylex(); 2066 } 2067 } 2068 else if (tok_is_keyword(tok, &yylval, 2069 K_SCROLL, "scroll")) 2070 { 2071 new->cursor_options |= CURSOR_OPT_SCROLL; 2072 tok = yylex(); 2073 } 2074 2075 if (tok != K_FOR) 2076 yyerror("syntax error, expected \"FOR\""); 2077 2078 tok = yylex(); 2079 if (tok == K_EXECUTE) 2080 { 2081 int endtoken; 2082 2083 new->dynquery = 2084 read_sql_expression2(K_USING, ';', 2085 "USING or ;", 2086 &endtoken); 2087 2088 /* If we found "USING", collect argument(s) */ 2089 if (endtoken == K_USING) 2090 { 2091 PLpgSQL_expr *expr; 2092 2093 do 2094 { 2095 expr = read_sql_expression2(',', ';', 2096 ", or ;", 2097 &endtoken); 2098 new->params = lappend(new->params, 2099 expr); 2100 } while (endtoken == ','); 2101 } 2102 } 2103 else 2104 { 2105 plpgsql_push_back_token(tok); 2106 new->query = read_sql_stmt(""); 2107 } 2108 } 2109 else 2110 { 2111 /* predefined cursor query, so read args */ 2112 new->argquery = read_cursor_args($2, ';', ";"); 2113 } 2114 2115 $$ = (PLpgSQL_stmt *)new; 2116 } 2117 ; 2118 2119 stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO 2120 { 2121 PLpgSQL_stmt_fetch *fetch = $2; 2122 PLpgSQL_variable *target; 2123 2124 /* We have already parsed everything through the INTO keyword */ 2125 read_into_target(&target, NULL); 2126 2127 if (yylex() != ';') 2128 yyerror("syntax error"); 2129 2130 /* 2131 * We don't allow multiple rows in PL/pgSQL's FETCH 2132 * statement, only in MOVE. 2133 */ 2134 if (fetch->returns_multiple_rows) 2135 ereport(ERROR, 2136 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), 2137 errmsg("FETCH statement cannot return multiple rows"), 2138 parser_errposition(@1))); 2139 2140 fetch->lineno = plpgsql_location_to_lineno(@1); 2141 fetch->target = target; 2142 fetch->curvar = $3->dno; 2143 fetch->is_move = false; 2144 2145 $$ = (PLpgSQL_stmt *)fetch; 2146 } 2147 ; 2148 2149 stmt_move : K_MOVE opt_fetch_direction cursor_variable ';' 2150 { 2151 PLpgSQL_stmt_fetch *fetch = $2; 2152 2153 fetch->lineno = plpgsql_location_to_lineno(@1); 2154 fetch->curvar = $3->dno; 2155 fetch->is_move = true; 2156 2157 $$ = (PLpgSQL_stmt *)fetch; 2158 } 2159 ; 2160 2161 opt_fetch_direction : 2162 { 2163 $$ = read_fetch_direction(); 2164 } 2165 ; 2166 2167 stmt_close : K_CLOSE cursor_variable ';' 2168 { 2169 PLpgSQL_stmt_close *new; 2170 2171 new = palloc(sizeof(PLpgSQL_stmt_close)); 2172 new->cmd_type = PLPGSQL_STMT_CLOSE; 2173 new->lineno = plpgsql_location_to_lineno(@1); 2174 new->curvar = $2->dno; 2175 2176 $$ = (PLpgSQL_stmt *)new; 2177 } 2178 ; 2179 2180 stmt_null : K_NULL ';' 2181 { 2182 /* We do not bother building a node for NULL */ 2183 $$ = NULL; 2184 } 2185 ; 2186 2187 stmt_commit : K_COMMIT ';' 2188 { 2189 PLpgSQL_stmt_commit *new; 2190 2191 new = palloc(sizeof(PLpgSQL_stmt_commit)); 2192 new->cmd_type = PLPGSQL_STMT_COMMIT; 2193 new->lineno = plpgsql_location_to_lineno(@1); 2194 2195 $$ = (PLpgSQL_stmt *)new; 2196 } 2197 ; 2198 2199 stmt_rollback : K_ROLLBACK ';' 2200 { 2201 PLpgSQL_stmt_rollback *new; 2202 2203 new = palloc(sizeof(PLpgSQL_stmt_rollback)); 2204 new->cmd_type = PLPGSQL_STMT_ROLLBACK; 2205 new->lineno = plpgsql_location_to_lineno(@1); 2206 2207 $$ = (PLpgSQL_stmt *)new; 2208 } 2209 ; 2210 2211 stmt_set : K_SET 2212 { 2213 PLpgSQL_stmt_set *new; 2214 2215 new = palloc0(sizeof(PLpgSQL_stmt_set)); 2216 new->cmd_type = PLPGSQL_STMT_SET; 2217 new->lineno = plpgsql_location_to_lineno(@1); 2218 new->expr = read_sql_stmt("SET "); 2219 2220 $$ = (PLpgSQL_stmt *)new; 2221 } 2222 | K_RESET 2223 { 2224 PLpgSQL_stmt_set *new; 2225 2226 new = palloc0(sizeof(PLpgSQL_stmt_set)); 2227 new->cmd_type = PLPGSQL_STMT_SET; 2228 new->lineno = plpgsql_location_to_lineno(@1); 2229 new->expr = read_sql_stmt("RESET "); 2230 2231 $$ = (PLpgSQL_stmt *)new; 2232 } 2233 ; 2234 2235 2236 cursor_variable : T_DATUM 2237 { 2238 /* 2239 * In principle we should support a cursor_variable 2240 * that is an array element, but for now we don't, so 2241 * just throw an error if next token is '['. 2242 */ 2243 if ($1.datum->dtype != PLPGSQL_DTYPE_VAR || 2244 plpgsql_peek() == '[') 2245 ereport(ERROR, 2246 (errcode(ERRCODE_DATATYPE_MISMATCH), 2247 errmsg("cursor variable must be a simple variable"), 2248 parser_errposition(@1))); 2249 2250 if (((PLpgSQL_var *) $1.datum)->datatype->typoid != REFCURSOROID) 2251 ereport(ERROR, 2252 (errcode(ERRCODE_DATATYPE_MISMATCH), 2253 errmsg("variable \"%s\" must be of type cursor or refcursor", 2254 ((PLpgSQL_var *) $1.datum)->refname), 2255 parser_errposition(@1))); 2256 $$ = (PLpgSQL_var *) $1.datum; 2257 } 2258 | T_WORD 2259 { 2260 /* just to give a better message than "syntax error" */ 2261 word_is_not_variable(&($1), @1); 2262 } 2263 | T_CWORD 2264 { 2265 /* just to give a better message than "syntax error" */ 2266 cword_is_not_variable(&($1), @1); 2267 } 2268 ; 2269 2270 exception_sect : 2271 { $$ = NULL; } 2272 | K_EXCEPTION 2273 { 2274 /* 2275 * We use a mid-rule action to add these 2276 * special variables to the namespace before 2277 * parsing the WHEN clauses themselves. The 2278 * scope of the names extends to the end of the 2279 * current block. 2280 */ 2281 int lineno = plpgsql_location_to_lineno(@1); 2282 PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block)); 2283 PLpgSQL_variable *var; 2284 2285 var = plpgsql_build_variable("sqlstate", lineno, 2286 plpgsql_build_datatype(TEXTOID, 2287 -1, 2288 plpgsql_curr_compile->fn_input_collation, 2289 NULL), 2290 true); 2291 var->isconst = true; 2292 new->sqlstate_varno = var->dno; 2293 2294 var = plpgsql_build_variable("sqlerrm", lineno, 2295 plpgsql_build_datatype(TEXTOID, 2296 -1, 2297 plpgsql_curr_compile->fn_input_collation, 2298 NULL), 2299 true); 2300 var->isconst = true; 2301 new->sqlerrm_varno = var->dno; 2302 2303 $<exception_block>$ = new; 2304 } 2305 proc_exceptions 2306 { 2307 PLpgSQL_exception_block *new = $<exception_block>2; 2308 new->exc_list = $3; 2309 2310 $$ = new; 2311 } 2312 ; 2313 2314 proc_exceptions : proc_exceptions proc_exception 2315 { 2316 $$ = lappend($1, $2); 2317 } 2318 | proc_exception 2319 { 2320 $$ = list_make1($1); 2321 } 2322 ; 2323 2324 proc_exception : K_WHEN proc_conditions K_THEN proc_sect 2325 { 2326 PLpgSQL_exception *new; 2327 2328 new = palloc0(sizeof(PLpgSQL_exception)); 2329 new->lineno = plpgsql_location_to_lineno(@1); 2330 new->conditions = $2; 2331 new->action = $4; 2332 2333 $$ = new; 2334 } 2335 ; 2336 2337 proc_conditions : proc_conditions K_OR proc_condition 2338 { 2339 PLpgSQL_condition *old; 2340 2341 for (old = $1; old->next != NULL; old = old->next) 2342 /* skip */ ; 2343 old->next = $3; 2344 $$ = $1; 2345 } 2346 | proc_condition 2347 { 2348 $$ = $1; 2349 } 2350 ; 2351 2352 proc_condition : any_identifier 2353 { 2354 if (strcmp($1, "sqlstate") != 0) 2355 { 2356 $$ = plpgsql_parse_err_condition($1); 2357 } 2358 else 2359 { 2360 PLpgSQL_condition *new; 2361 char *sqlstatestr; 2362 2363 /* next token should be a string literal */ 2364 if (yylex() != SCONST) 2365 yyerror("syntax error"); 2366 sqlstatestr = yylval.str; 2367 2368 if (strlen(sqlstatestr) != 5) 2369 yyerror("invalid SQLSTATE code"); 2370 if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5) 2371 yyerror("invalid SQLSTATE code"); 2372 2373 new = palloc(sizeof(PLpgSQL_condition)); 2374 new->sqlerrstate = 2375 MAKE_SQLSTATE(sqlstatestr[0], 2376 sqlstatestr[1], 2377 sqlstatestr[2], 2378 sqlstatestr[3], 2379 sqlstatestr[4]); 2380 new->condname = sqlstatestr; 2381 new->next = NULL; 2382 2383 $$ = new; 2384 } 2385 } 2386 ; 2387 2388 expr_until_semi : 2389 { $$ = read_sql_expression(';', ";"); } 2390 ; 2391 2392 expr_until_rightbracket : 2393 { $$ = read_sql_expression(']', "]"); } 2394 ; 2395 2396 expr_until_then : 2397 { $$ = read_sql_expression(K_THEN, "THEN"); } 2398 ; 2399 2400 expr_until_loop : 2401 { $$ = read_sql_expression(K_LOOP, "LOOP"); } 2402 ; 2403 2404 opt_block_label : 2405 { 2406 plpgsql_ns_push(NULL, PLPGSQL_LABEL_BLOCK); 2407 $$ = NULL; 2408 } 2409 | LESS_LESS any_identifier GREATER_GREATER 2410 { 2411 plpgsql_ns_push($2, PLPGSQL_LABEL_BLOCK); 2412 $$ = $2; 2413 } 2414 ; 2415 2416 opt_loop_label : 2417 { 2418 plpgsql_ns_push(NULL, PLPGSQL_LABEL_LOOP); 2419 $$ = NULL; 2420 } 2421 | LESS_LESS any_identifier GREATER_GREATER 2422 { 2423 plpgsql_ns_push($2, PLPGSQL_LABEL_LOOP); 2424 $$ = $2; 2425 } 2426 ; 2427 2428 opt_label : 2429 { 2430 $$ = NULL; 2431 } 2432 | any_identifier 2433 { 2434 /* label validity will be checked by outer production */ 2435 $$ = $1; 2436 } 2437 ; 2438 2439 opt_exitcond : ';' 2440 { $$ = NULL; } 2441 | K_WHEN expr_until_semi 2442 { $$ = $2; } 2443 ; 2444 2445 /* 2446 * need to allow DATUM because scanner will have tried to resolve as variable 2447 */ 2448 any_identifier : T_WORD 2449 { 2450 $$ = $1.ident; 2451 } 2452 | unreserved_keyword 2453 { 2454 $$ = pstrdup($1); 2455 } 2456 | T_DATUM 2457 { 2458 if ($1.ident == NULL) /* composite name not OK */ 2459 yyerror("syntax error"); 2460 $$ = $1.ident; 2461 } 2462 ; 2463 2464 unreserved_keyword : 2465 K_ABSOLUTE 2466 | K_ALIAS 2467 | K_ARRAY 2468 | K_ASSERT 2469 | K_BACKWARD 2470 | K_CALL 2471 | K_CLOSE 2472 | K_COLLATE 2473 | K_COLUMN 2474 | K_COLUMN_NAME 2475 | K_COMMIT 2476 | K_CONSTANT 2477 | K_CONSTRAINT 2478 | K_CONSTRAINT_NAME 2479 | K_CONTINUE 2480 | K_CURRENT 2481 | K_CURSOR 2482 | K_DATATYPE 2483 | K_DEBUG 2484 | K_DEFAULT 2485 | K_DETAIL 2486 | K_DIAGNOSTICS 2487 | K_DO 2488 | K_DUMP 2489 | K_ELSIF 2490 | K_ERRCODE 2491 | K_ERROR 2492 | K_EXCEPTION 2493 | K_EXIT 2494 | K_FETCH 2495 | K_FIRST 2496 | K_FORWARD 2497 | K_GET 2498 | K_HINT 2499 | K_IMPORT 2500 | K_INFO 2501 | K_INSERT 2502 | K_IS 2503 | K_LAST 2504 | K_LOG 2505 | K_MESSAGE 2506 | K_MESSAGE_TEXT 2507 | K_MOVE 2508 | K_NEXT 2509 | K_NO 2510 | K_NOTICE 2511 | K_OPEN 2512 | K_OPTION 2513 | K_PERFORM 2514 | K_PG_CONTEXT 2515 | K_PG_DATATYPE_NAME 2516 | K_PG_EXCEPTION_CONTEXT 2517 | K_PG_EXCEPTION_DETAIL 2518 | K_PG_EXCEPTION_HINT 2519 | K_PRINT_STRICT_PARAMS 2520 | K_PRIOR 2521 | K_QUERY 2522 | K_RAISE 2523 | K_RELATIVE 2524 | K_RESET 2525 | K_RESULT_OID 2526 | K_RETURN 2527 | K_RETURNED_SQLSTATE 2528 | K_REVERSE 2529 | K_ROLLBACK 2530 | K_ROW_COUNT 2531 | K_ROWTYPE 2532 | K_SCHEMA 2533 | K_SCHEMA_NAME 2534 | K_SCROLL 2535 | K_SET 2536 | K_SLICE 2537 | K_SQLSTATE 2538 | K_STACKED 2539 | K_TABLE 2540 | K_TABLE_NAME 2541 | K_TYPE 2542 | K_USE_COLUMN 2543 | K_USE_VARIABLE 2544 | K_VARIABLE_CONFLICT 2545 | K_WARNING 2546 ; 2547 2548 %% 2549 2550 /* 2551 * Check whether a token represents an "unreserved keyword". 2552 * We have various places where we want to recognize a keyword in preference 2553 * to a variable name, but not reserve that keyword in other contexts. 2554 * Hence, this kluge. 2555 */ 2556 static bool 2557 tok_is_keyword(int token, union YYSTYPE *lval, 2558 int kw_token, const char *kw_str) 2559 { 2560 if (token == kw_token) 2561 { 2562 /* Normal case, was recognized by scanner (no conflicting variable) */ 2563 return true; 2564 } 2565 else if (token == T_DATUM) 2566 { 2567 /* 2568 * It's a variable, so recheck the string name. Note we will not 2569 * match composite names (hence an unreserved word followed by "." 2570 * will not be recognized). 2571 */ 2572 if (!lval->wdatum.quoted && lval->wdatum.ident != NULL && 2573 strcmp(lval->wdatum.ident, kw_str) == 0) 2574 return true; 2575 } 2576 return false; /* not the keyword */ 2577 } 2578 2579 /* 2580 * Convenience routine to complain when we expected T_DATUM and got T_WORD, 2581 * ie, unrecognized variable. 2582 */ 2583 static void 2584 word_is_not_variable(PLword *word, int location) 2585 { 2586 ereport(ERROR, 2587 (errcode(ERRCODE_SYNTAX_ERROR), 2588 errmsg("\"%s\" is not a known variable", 2589 word->ident), 2590 parser_errposition(location))); 2591 } 2592 2593 /* Same, for a CWORD */ 2594 static void 2595 cword_is_not_variable(PLcword *cword, int location) 2596 { 2597 ereport(ERROR, 2598 (errcode(ERRCODE_SYNTAX_ERROR), 2599 errmsg("\"%s\" is not a known variable", 2600 NameListToString(cword->idents)), 2601 parser_errposition(location))); 2602 } 2603 2604 /* 2605 * Convenience routine to complain when we expected T_DATUM and got 2606 * something else. "tok" must be the current token, since we also 2607 * look at yylval and yylloc. 2608 */ 2609 static void 2610 current_token_is_not_variable(int tok) 2611 { 2612 if (tok == T_WORD) 2613 word_is_not_variable(&(yylval.word), yylloc); 2614 else if (tok == T_CWORD) 2615 cword_is_not_variable(&(yylval.cword), yylloc); 2616 else 2617 yyerror("syntax error"); 2618 } 2619 2620 /* Convenience routine to read an expression with one possible terminator */ 2621 static PLpgSQL_expr * 2622 read_sql_expression(int until, const char *expected) 2623 { 2624 return read_sql_construct(until, 0, 0, expected, 2625 "SELECT ", true, true, true, NULL, NULL); 2626 } 2627 2628 /* Convenience routine to read an expression with two possible terminators */ 2629 static PLpgSQL_expr * 2630 read_sql_expression2(int until, int until2, const char *expected, 2631 int *endtoken) 2632 { 2633 return read_sql_construct(until, until2, 0, expected, 2634 "SELECT ", true, true, true, NULL, endtoken); 2635 } 2636 2637 /* Convenience routine to read a SQL statement that must end with ';' */ 2638 static PLpgSQL_expr * 2639 read_sql_stmt(const char *sqlstart) 2640 { 2641 return read_sql_construct(';', 0, 0, ";", 2642 sqlstart, false, true, true, NULL, NULL); 2643 } 2644 2645 /* 2646 * Read a SQL construct and build a PLpgSQL_expr for it. 2647 * 2648 * until: token code for expected terminator 2649 * until2: token code for alternate terminator (pass 0 if none) 2650 * until3: token code for another alternate terminator (pass 0 if none) 2651 * expected: text to use in complaining that terminator was not found 2652 * sqlstart: text to prefix to the accumulated SQL text 2653 * isexpression: whether to say we're reading an "expression" or a "statement" 2654 * valid_sql: whether to check the syntax of the expr (prefixed with sqlstart) 2655 * trim: trim trailing whitespace 2656 * startloc: if not NULL, location of first token is stored at *startloc 2657 * endtoken: if not NULL, ending token is stored at *endtoken 2658 * (this is only interesting if until2 or until3 isn't zero) 2659 */ 2660 static PLpgSQL_expr * 2661 read_sql_construct(int until, 2662 int until2, 2663 int until3, 2664 const char *expected, 2665 const char *sqlstart, 2666 bool isexpression, 2667 bool valid_sql, 2668 bool trim, 2669 int *startloc, 2670 int *endtoken) 2671 { 2672 int tok; 2673 StringInfoData ds; 2674 IdentifierLookup save_IdentifierLookup; 2675 int startlocation = -1; 2676 int parenlevel = 0; 2677 PLpgSQL_expr *expr; 2678 2679 initStringInfo(&ds); 2680 appendStringInfoString(&ds, sqlstart); 2681 2682 /* special lookup mode for identifiers within the SQL text */ 2683 save_IdentifierLookup = plpgsql_IdentifierLookup; 2684 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; 2685 2686 for (;;) 2687 { 2688 tok = yylex(); 2689 if (startlocation < 0) /* remember loc of first token */ 2690 startlocation = yylloc; 2691 if (tok == until && parenlevel == 0) 2692 break; 2693 if (tok == until2 && parenlevel == 0) 2694 break; 2695 if (tok == until3 && parenlevel == 0) 2696 break; 2697 if (tok == '(' || tok == '[') 2698 parenlevel++; 2699 else if (tok == ')' || tok == ']') 2700 { 2701 parenlevel--; 2702 if (parenlevel < 0) 2703 yyerror("mismatched parentheses"); 2704 } 2705 /* 2706 * End of function definition is an error, and we don't expect to 2707 * hit a semicolon either (unless it's the until symbol, in which 2708 * case we should have fallen out above). 2709 */ 2710 if (tok == 0 || tok == ';') 2711 { 2712 if (parenlevel != 0) 2713 yyerror("mismatched parentheses"); 2714 if (isexpression) 2715 ereport(ERROR, 2716 (errcode(ERRCODE_SYNTAX_ERROR), 2717 errmsg("missing \"%s\" at end of SQL expression", 2718 expected), 2719 parser_errposition(yylloc))); 2720 else 2721 ereport(ERROR, 2722 (errcode(ERRCODE_SYNTAX_ERROR), 2723 errmsg("missing \"%s\" at end of SQL statement", 2724 expected), 2725 parser_errposition(yylloc))); 2726 } 2727 } 2728 2729 plpgsql_IdentifierLookup = save_IdentifierLookup; 2730 2731 if (startloc) 2732 *startloc = startlocation; 2733 if (endtoken) 2734 *endtoken = tok; 2735 2736 /* give helpful complaint about empty input */ 2737 if (startlocation >= yylloc) 2738 { 2739 if (isexpression) 2740 yyerror("missing expression"); 2741 else 2742 yyerror("missing SQL statement"); 2743 } 2744 2745 plpgsql_append_source_text(&ds, startlocation, yylloc); 2746 2747 /* trim any trailing whitespace, for neatness */ 2748 if (trim) 2749 { 2750 while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1])) 2751 ds.data[--ds.len] = '\0'; 2752 } 2753 2754 expr = palloc0(sizeof(PLpgSQL_expr)); 2755 expr->query = pstrdup(ds.data); 2756 expr->plan = NULL; 2757 expr->paramnos = NULL; 2758 expr->rwparam = -1; 2759 expr->ns = plpgsql_ns_top(); 2760 pfree(ds.data); 2761 2762 if (valid_sql) 2763 check_sql_expr(expr->query, startlocation, strlen(sqlstart)); 2764 2765 return expr; 2766 } 2767 2768 static PLpgSQL_type * 2769 read_datatype(int tok) 2770 { 2771 StringInfoData ds; 2772 char *type_name; 2773 int startlocation; 2774 PLpgSQL_type *result; 2775 int parenlevel = 0; 2776 2777 /* Should only be called while parsing DECLARE sections */ 2778 Assert(plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_DECLARE); 2779 2780 /* Often there will be a lookahead token, but if not, get one */ 2781 if (tok == YYEMPTY) 2782 tok = yylex(); 2783 2784 startlocation = yylloc; 2785 2786 /* 2787 * If we have a simple or composite identifier, check for %TYPE 2788 * and %ROWTYPE constructs. 2789 */ 2790 if (tok == T_WORD) 2791 { 2792 char *dtname = yylval.word.ident; 2793 2794 tok = yylex(); 2795 if (tok == '%') 2796 { 2797 tok = yylex(); 2798 if (tok_is_keyword(tok, &yylval, 2799 K_TYPE, "type")) 2800 { 2801 result = plpgsql_parse_wordtype(dtname); 2802 if (result) 2803 return result; 2804 } 2805 else if (tok_is_keyword(tok, &yylval, 2806 K_ROWTYPE, "rowtype")) 2807 { 2808 result = plpgsql_parse_wordrowtype(dtname); 2809 if (result) 2810 return result; 2811 } 2812 } 2813 } 2814 else if (plpgsql_token_is_unreserved_keyword(tok)) 2815 { 2816 char *dtname = pstrdup(yylval.keyword); 2817 2818 tok = yylex(); 2819 if (tok == '%') 2820 { 2821 tok = yylex(); 2822 if (tok_is_keyword(tok, &yylval, 2823 K_TYPE, "type")) 2824 { 2825 result = plpgsql_parse_wordtype(dtname); 2826 if (result) 2827 return result; 2828 } 2829 else if (tok_is_keyword(tok, &yylval, 2830 K_ROWTYPE, "rowtype")) 2831 { 2832 result = plpgsql_parse_wordrowtype(dtname); 2833 if (result) 2834 return result; 2835 } 2836 } 2837 } 2838 else if (tok == T_CWORD) 2839 { 2840 List *dtnames = yylval.cword.idents; 2841 2842 tok = yylex(); 2843 if (tok == '%') 2844 { 2845 tok = yylex(); 2846 if (tok_is_keyword(tok, &yylval, 2847 K_TYPE, "type")) 2848 { 2849 result = plpgsql_parse_cwordtype(dtnames); 2850 if (result) 2851 return result; 2852 } 2853 else if (tok_is_keyword(tok, &yylval, 2854 K_ROWTYPE, "rowtype")) 2855 { 2856 result = plpgsql_parse_cwordrowtype(dtnames); 2857 if (result) 2858 return result; 2859 } 2860 } 2861 } 2862 2863 while (tok != ';') 2864 { 2865 if (tok == 0) 2866 { 2867 if (parenlevel != 0) 2868 yyerror("mismatched parentheses"); 2869 else 2870 yyerror("incomplete data type declaration"); 2871 } 2872 /* Possible followers for datatype in a declaration */ 2873 if (tok == K_COLLATE || tok == K_NOT || 2874 tok == '=' || tok == COLON_EQUALS || tok == K_DEFAULT) 2875 break; 2876 /* Possible followers for datatype in a cursor_arg list */ 2877 if ((tok == ',' || tok == ')') && parenlevel == 0) 2878 break; 2879 if (tok == '(') 2880 parenlevel++; 2881 else if (tok == ')') 2882 parenlevel--; 2883 2884 tok = yylex(); 2885 } 2886 2887 /* set up ds to contain complete typename text */ 2888 initStringInfo(&ds); 2889 plpgsql_append_source_text(&ds, startlocation, yylloc); 2890 type_name = ds.data; 2891 2892 if (type_name[0] == '\0') 2893 yyerror("missing data type declaration"); 2894 2895 result = parse_datatype(type_name, startlocation); 2896 2897 pfree(ds.data); 2898 2899 plpgsql_push_back_token(tok); 2900 2901 return result; 2902 } 2903 2904 static PLpgSQL_stmt * 2905 make_execsql_stmt(int firsttoken, int location) 2906 { 2907 StringInfoData ds; 2908 IdentifierLookup save_IdentifierLookup; 2909 PLpgSQL_stmt_execsql *execsql; 2910 PLpgSQL_expr *expr; 2911 PLpgSQL_variable *target = NULL; 2912 int tok; 2913 int prev_tok; 2914 bool have_into = false; 2915 bool have_strict = false; 2916 int into_start_loc = -1; 2917 int into_end_loc = -1; 2918 2919 initStringInfo(&ds); 2920 2921 /* special lookup mode for identifiers within the SQL text */ 2922 save_IdentifierLookup = plpgsql_IdentifierLookup; 2923 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; 2924 2925 /* 2926 * Scan to the end of the SQL command. Identify any INTO-variables 2927 * clause lurking within it, and parse that via read_into_target(). 2928 * 2929 * Because INTO is sometimes used in the main SQL grammar, we have to be 2930 * careful not to take any such usage of INTO as a PL/pgSQL INTO clause. 2931 * There are currently three such cases: 2932 * 2933 * 1. SELECT ... INTO. We don't care, we just override that with the 2934 * PL/pgSQL definition. 2935 * 2936 * 2. INSERT INTO. This is relatively easy to recognize since the words 2937 * must appear adjacently; but we can't assume INSERT starts the command, 2938 * because it can appear in CREATE RULE or WITH. Unfortunately, INSERT is 2939 * *not* fully reserved, so that means there is a chance of a false match; 2940 * but it's not very likely. 2941 * 2942 * 3. IMPORT FOREIGN SCHEMA ... INTO. This is not allowed in CREATE RULE 2943 * or WITH, so we just check for IMPORT as the command's first token. 2944 * (If IMPORT FOREIGN SCHEMA returned data someone might wish to capture 2945 * with an INTO-variables clause, we'd have to work much harder here.) 2946 * 2947 * Fortunately, INTO is a fully reserved word in the main grammar, so 2948 * at least we need not worry about it appearing as an identifier. 2949 * 2950 * Any future additional uses of INTO in the main grammar will doubtless 2951 * break this logic again ... beware! 2952 */ 2953 tok = firsttoken; 2954 for (;;) 2955 { 2956 prev_tok = tok; 2957 tok = yylex(); 2958 if (have_into && into_end_loc < 0) 2959 into_end_loc = yylloc; /* token after the INTO part */ 2960 if (tok == ';') 2961 break; 2962 if (tok == 0) 2963 yyerror("unexpected end of function definition"); 2964 if (tok == K_INTO) 2965 { 2966 if (prev_tok == K_INSERT) 2967 continue; /* INSERT INTO is not an INTO-target */ 2968 if (firsttoken == K_IMPORT) 2969 continue; /* IMPORT ... INTO is not an INTO-target */ 2970 if (have_into) 2971 yyerror("INTO specified more than once"); 2972 have_into = true; 2973 into_start_loc = yylloc; 2974 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; 2975 read_into_target(&target, &have_strict); 2976 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; 2977 } 2978 } 2979 2980 plpgsql_IdentifierLookup = save_IdentifierLookup; 2981 2982 if (have_into) 2983 { 2984 /* 2985 * Insert an appropriate number of spaces corresponding to the 2986 * INTO text, so that locations within the redacted SQL statement 2987 * still line up with those in the original source text. 2988 */ 2989 plpgsql_append_source_text(&ds, location, into_start_loc); 2990 appendStringInfoSpaces(&ds, into_end_loc - into_start_loc); 2991 plpgsql_append_source_text(&ds, into_end_loc, yylloc); 2992 } 2993 else 2994 plpgsql_append_source_text(&ds, location, yylloc); 2995 2996 /* trim any trailing whitespace, for neatness */ 2997 while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1])) 2998 ds.data[--ds.len] = '\0'; 2999 3000 expr = palloc0(sizeof(PLpgSQL_expr)); 3001 expr->query = pstrdup(ds.data); 3002 expr->plan = NULL; 3003 expr->paramnos = NULL; 3004 expr->rwparam = -1; 3005 expr->ns = plpgsql_ns_top(); 3006 pfree(ds.data); 3007 3008 check_sql_expr(expr->query, location, 0); 3009 3010 execsql = palloc0(sizeof(PLpgSQL_stmt_execsql)); 3011 execsql->cmd_type = PLPGSQL_STMT_EXECSQL; 3012 execsql->lineno = plpgsql_location_to_lineno(location); 3013 execsql->sqlstmt = expr; 3014 execsql->into = have_into; 3015 execsql->strict = have_strict; 3016 execsql->target = target; 3017 3018 return (PLpgSQL_stmt *) execsql; 3019 } 3020 3021 3022 /* 3023 * Read FETCH or MOVE direction clause (everything through FROM/IN). 3024 */ 3025 static PLpgSQL_stmt_fetch * 3026 read_fetch_direction(void) 3027 { 3028 PLpgSQL_stmt_fetch *fetch; 3029 int tok; 3030 bool check_FROM = true; 3031 3032 /* 3033 * We create the PLpgSQL_stmt_fetch struct here, but only fill in 3034 * the fields arising from the optional direction clause 3035 */ 3036 fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch)); 3037 fetch->cmd_type = PLPGSQL_STMT_FETCH; 3038 /* set direction defaults: */ 3039 fetch->direction = FETCH_FORWARD; 3040 fetch->how_many = 1; 3041 fetch->expr = NULL; 3042 fetch->returns_multiple_rows = false; 3043 3044 tok = yylex(); 3045 if (tok == 0) 3046 yyerror("unexpected end of function definition"); 3047 3048 if (tok_is_keyword(tok, &yylval, 3049 K_NEXT, "next")) 3050 { 3051 /* use defaults */ 3052 } 3053 else if (tok_is_keyword(tok, &yylval, 3054 K_PRIOR, "prior")) 3055 { 3056 fetch->direction = FETCH_BACKWARD; 3057 } 3058 else if (tok_is_keyword(tok, &yylval, 3059 K_FIRST, "first")) 3060 { 3061 fetch->direction = FETCH_ABSOLUTE; 3062 } 3063 else if (tok_is_keyword(tok, &yylval, 3064 K_LAST, "last")) 3065 { 3066 fetch->direction = FETCH_ABSOLUTE; 3067 fetch->how_many = -1; 3068 } 3069 else if (tok_is_keyword(tok, &yylval, 3070 K_ABSOLUTE, "absolute")) 3071 { 3072 fetch->direction = FETCH_ABSOLUTE; 3073 fetch->expr = read_sql_expression2(K_FROM, K_IN, 3074 "FROM or IN", 3075 NULL); 3076 check_FROM = false; 3077 } 3078 else if (tok_is_keyword(tok, &yylval, 3079 K_RELATIVE, "relative")) 3080 { 3081 fetch->direction = FETCH_RELATIVE; 3082 fetch->expr = read_sql_expression2(K_FROM, K_IN, 3083 "FROM or IN", 3084 NULL); 3085 check_FROM = false; 3086 } 3087 else if (tok_is_keyword(tok, &yylval, 3088 K_ALL, "all")) 3089 { 3090 fetch->how_many = FETCH_ALL; 3091 fetch->returns_multiple_rows = true; 3092 } 3093 else if (tok_is_keyword(tok, &yylval, 3094 K_FORWARD, "forward")) 3095 { 3096 complete_direction(fetch, &check_FROM); 3097 } 3098 else if (tok_is_keyword(tok, &yylval, 3099 K_BACKWARD, "backward")) 3100 { 3101 fetch->direction = FETCH_BACKWARD; 3102 complete_direction(fetch, &check_FROM); 3103 } 3104 else if (tok == K_FROM || tok == K_IN) 3105 { 3106 /* empty direction */ 3107 check_FROM = false; 3108 } 3109 else if (tok == T_DATUM) 3110 { 3111 /* Assume there's no direction clause and tok is a cursor name */ 3112 plpgsql_push_back_token(tok); 3113 check_FROM = false; 3114 } 3115 else 3116 { 3117 /* 3118 * Assume it's a count expression with no preceding keyword. 3119 * Note: we allow this syntax because core SQL does, but we don't 3120 * document it because of the ambiguity with the omitted-direction 3121 * case. For instance, "MOVE n IN c" will fail if n is a variable. 3122 * Perhaps this can be improved someday, but it's hardly worth a 3123 * lot of work. 3124 */ 3125 plpgsql_push_back_token(tok); 3126 fetch->expr = read_sql_expression2(K_FROM, K_IN, 3127 "FROM or IN", 3128 NULL); 3129 fetch->returns_multiple_rows = true; 3130 check_FROM = false; 3131 } 3132 3133 /* check FROM or IN keyword after direction's specification */ 3134 if (check_FROM) 3135 { 3136 tok = yylex(); 3137 if (tok != K_FROM && tok != K_IN) 3138 yyerror("expected FROM or IN"); 3139 } 3140 3141 return fetch; 3142 } 3143 3144 /* 3145 * Process remainder of FETCH/MOVE direction after FORWARD or BACKWARD. 3146 * Allows these cases: 3147 * FORWARD expr, FORWARD ALL, FORWARD 3148 * BACKWARD expr, BACKWARD ALL, BACKWARD 3149 */ 3150 static void 3151 complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM) 3152 { 3153 int tok; 3154 3155 tok = yylex(); 3156 if (tok == 0) 3157 yyerror("unexpected end of function definition"); 3158 3159 if (tok == K_FROM || tok == K_IN) 3160 { 3161 *check_FROM = false; 3162 return; 3163 } 3164 3165 if (tok == K_ALL) 3166 { 3167 fetch->how_many = FETCH_ALL; 3168 fetch->returns_multiple_rows = true; 3169 *check_FROM = true; 3170 return; 3171 } 3172 3173 plpgsql_push_back_token(tok); 3174 fetch->expr = read_sql_expression2(K_FROM, K_IN, 3175 "FROM or IN", 3176 NULL); 3177 fetch->returns_multiple_rows = true; 3178 *check_FROM = false; 3179 } 3180 3181 3182 static PLpgSQL_stmt * 3183 make_return_stmt(int location) 3184 { 3185 PLpgSQL_stmt_return *new; 3186 3187 new = palloc0(sizeof(PLpgSQL_stmt_return)); 3188 new->cmd_type = PLPGSQL_STMT_RETURN; 3189 new->lineno = plpgsql_location_to_lineno(location); 3190 new->expr = NULL; 3191 new->retvarno = -1; 3192 3193 if (plpgsql_curr_compile->fn_retset) 3194 { 3195 if (yylex() != ';') 3196 ereport(ERROR, 3197 (errcode(ERRCODE_DATATYPE_MISMATCH), 3198 errmsg("RETURN cannot have a parameter in function returning set"), 3199 errhint("Use RETURN NEXT or RETURN QUERY."), 3200 parser_errposition(yylloc))); 3201 } 3202 else if (plpgsql_curr_compile->fn_rettype == VOIDOID) 3203 { 3204 if (yylex() != ';') 3205 { 3206 if (plpgsql_curr_compile->fn_prokind == PROKIND_PROCEDURE) 3207 ereport(ERROR, 3208 (errcode(ERRCODE_SYNTAX_ERROR), 3209 errmsg("RETURN cannot have a parameter in a procedure"), 3210 parser_errposition(yylloc))); 3211 else 3212 ereport(ERROR, 3213 (errcode(ERRCODE_DATATYPE_MISMATCH), 3214 errmsg("RETURN cannot have a parameter in function returning void"), 3215 parser_errposition(yylloc))); 3216 } 3217 } 3218 else if (plpgsql_curr_compile->out_param_varno >= 0) 3219 { 3220 if (yylex() != ';') 3221 ereport(ERROR, 3222 (errcode(ERRCODE_DATATYPE_MISMATCH), 3223 errmsg("RETURN cannot have a parameter in function with OUT parameters"), 3224 parser_errposition(yylloc))); 3225 new->retvarno = plpgsql_curr_compile->out_param_varno; 3226 } 3227 else 3228 { 3229 /* 3230 * We want to special-case simple variable references for efficiency. 3231 * So peek ahead to see if that's what we have. 3232 */ 3233 int tok = yylex(); 3234 3235 if (tok == T_DATUM && plpgsql_peek() == ';' && 3236 (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR || 3237 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE || 3238 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || 3239 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)) 3240 { 3241 new->retvarno = yylval.wdatum.datum->dno; 3242 /* eat the semicolon token that we only peeked at above */ 3243 tok = yylex(); 3244 Assert(tok == ';'); 3245 } 3246 else 3247 { 3248 /* 3249 * Not (just) a variable name, so treat as expression. 3250 * 3251 * Note that a well-formed expression is _required_ here; 3252 * anything else is a compile-time error. 3253 */ 3254 plpgsql_push_back_token(tok); 3255 new->expr = read_sql_expression(';', ";"); 3256 } 3257 } 3258 3259 return (PLpgSQL_stmt *) new; 3260 } 3261 3262 3263 static PLpgSQL_stmt * 3264 make_return_next_stmt(int location) 3265 { 3266 PLpgSQL_stmt_return_next *new; 3267 3268 if (!plpgsql_curr_compile->fn_retset) 3269 ereport(ERROR, 3270 (errcode(ERRCODE_DATATYPE_MISMATCH), 3271 errmsg("cannot use RETURN NEXT in a non-SETOF function"), 3272 parser_errposition(location))); 3273 3274 new = palloc0(sizeof(PLpgSQL_stmt_return_next)); 3275 new->cmd_type = PLPGSQL_STMT_RETURN_NEXT; 3276 new->lineno = plpgsql_location_to_lineno(location); 3277 new->expr = NULL; 3278 new->retvarno = -1; 3279 3280 if (plpgsql_curr_compile->out_param_varno >= 0) 3281 { 3282 if (yylex() != ';') 3283 ereport(ERROR, 3284 (errcode(ERRCODE_DATATYPE_MISMATCH), 3285 errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"), 3286 parser_errposition(yylloc))); 3287 new->retvarno = plpgsql_curr_compile->out_param_varno; 3288 } 3289 else 3290 { 3291 /* 3292 * We want to special-case simple variable references for efficiency. 3293 * So peek ahead to see if that's what we have. 3294 */ 3295 int tok = yylex(); 3296 3297 if (tok == T_DATUM && plpgsql_peek() == ';' && 3298 (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR || 3299 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE || 3300 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || 3301 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)) 3302 { 3303 new->retvarno = yylval.wdatum.datum->dno; 3304 /* eat the semicolon token that we only peeked at above */ 3305 tok = yylex(); 3306 Assert(tok == ';'); 3307 } 3308 else 3309 { 3310 /* 3311 * Not (just) a variable name, so treat as expression. 3312 * 3313 * Note that a well-formed expression is _required_ here; 3314 * anything else is a compile-time error. 3315 */ 3316 plpgsql_push_back_token(tok); 3317 new->expr = read_sql_expression(';', ";"); 3318 } 3319 } 3320 3321 return (PLpgSQL_stmt *) new; 3322 } 3323 3324 3325 static PLpgSQL_stmt * 3326 make_return_query_stmt(int location) 3327 { 3328 PLpgSQL_stmt_return_query *new; 3329 int tok; 3330 3331 if (!plpgsql_curr_compile->fn_retset) 3332 ereport(ERROR, 3333 (errcode(ERRCODE_DATATYPE_MISMATCH), 3334 errmsg("cannot use RETURN QUERY in a non-SETOF function"), 3335 parser_errposition(location))); 3336 3337 new = palloc0(sizeof(PLpgSQL_stmt_return_query)); 3338 new->cmd_type = PLPGSQL_STMT_RETURN_QUERY; 3339 new->lineno = plpgsql_location_to_lineno(location); 3340 3341 /* check for RETURN QUERY EXECUTE */ 3342 if ((tok = yylex()) != K_EXECUTE) 3343 { 3344 /* ordinary static query */ 3345 plpgsql_push_back_token(tok); 3346 new->query = read_sql_stmt(""); 3347 } 3348 else 3349 { 3350 /* dynamic SQL */ 3351 int term; 3352 3353 new->dynquery = read_sql_expression2(';', K_USING, "; or USING", 3354 &term); 3355 if (term == K_USING) 3356 { 3357 do 3358 { 3359 PLpgSQL_expr *expr; 3360 3361 expr = read_sql_expression2(',', ';', ", or ;", &term); 3362 new->params = lappend(new->params, expr); 3363 } while (term == ','); 3364 } 3365 } 3366 3367 return (PLpgSQL_stmt *) new; 3368 } 3369 3370 3371 /* convenience routine to fetch the name of a T_DATUM */ 3372 static char * 3373 NameOfDatum(PLwdatum *wdatum) 3374 { 3375 if (wdatum->ident) 3376 return wdatum->ident; 3377 Assert(wdatum->idents != NIL); 3378 return NameListToString(wdatum->idents); 3379 } 3380 3381 static void 3382 check_assignable(PLpgSQL_datum *datum, int location) 3383 { 3384 switch (datum->dtype) 3385 { 3386 case PLPGSQL_DTYPE_VAR: 3387 case PLPGSQL_DTYPE_PROMISE: 3388 case PLPGSQL_DTYPE_REC: 3389 if (((PLpgSQL_variable *) datum)->isconst) 3390 ereport(ERROR, 3391 (errcode(ERRCODE_ERROR_IN_ASSIGNMENT), 3392 errmsg("variable \"%s\" is declared CONSTANT", 3393 ((PLpgSQL_variable *) datum)->refname), 3394 parser_errposition(location))); 3395 break; 3396 case PLPGSQL_DTYPE_ROW: 3397 /* always assignable; member vars were checked at compile time */ 3398 break; 3399 case PLPGSQL_DTYPE_RECFIELD: 3400 /* assignable if parent record is */ 3401 check_assignable(plpgsql_Datums[((PLpgSQL_recfield *) datum)->recparentno], 3402 location); 3403 break; 3404 case PLPGSQL_DTYPE_ARRAYELEM: 3405 /* assignable if parent array is */ 3406 check_assignable(plpgsql_Datums[((PLpgSQL_arrayelem *) datum)->arrayparentno], 3407 location); 3408 break; 3409 default: 3410 elog(ERROR, "unrecognized dtype: %d", datum->dtype); 3411 break; 3412 } 3413 } 3414 3415 /* 3416 * Read the argument of an INTO clause. On entry, we have just read the 3417 * INTO keyword. 3418 */ 3419 static void 3420 read_into_target(PLpgSQL_variable **target, bool *strict) 3421 { 3422 int tok; 3423 3424 /* Set default results */ 3425 *target = NULL; 3426 if (strict) 3427 *strict = false; 3428 3429 tok = yylex(); 3430 if (strict && tok == K_STRICT) 3431 { 3432 *strict = true; 3433 tok = yylex(); 3434 } 3435 3436 /* 3437 * Currently, a row or record variable can be the single INTO target, 3438 * but not a member of a multi-target list. So we throw error if there 3439 * is a comma after it, because that probably means the user tried to 3440 * write a multi-target list. If this ever gets generalized, we should 3441 * probably refactor read_into_scalar_list so it handles all cases. 3442 */ 3443 switch (tok) 3444 { 3445 case T_DATUM: 3446 if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || 3447 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC) 3448 { 3449 check_assignable(yylval.wdatum.datum, yylloc); 3450 *target = (PLpgSQL_variable *) yylval.wdatum.datum; 3451 3452 if ((tok = yylex()) == ',') 3453 ereport(ERROR, 3454 (errcode(ERRCODE_SYNTAX_ERROR), 3455 errmsg("record variable cannot be part of multiple-item INTO list"), 3456 parser_errposition(yylloc))); 3457 plpgsql_push_back_token(tok); 3458 } 3459 else 3460 { 3461 *target = (PLpgSQL_variable *) 3462 read_into_scalar_list(NameOfDatum(&(yylval.wdatum)), 3463 yylval.wdatum.datum, yylloc); 3464 } 3465 break; 3466 3467 default: 3468 /* just to give a better message than "syntax error" */ 3469 current_token_is_not_variable(tok); 3470 } 3471 } 3472 3473 /* 3474 * Given the first datum and name in the INTO list, continue to read 3475 * comma-separated scalar variables until we run out. Then construct 3476 * and return a fake "row" variable that represents the list of 3477 * scalars. 3478 */ 3479 static PLpgSQL_row * 3480 read_into_scalar_list(char *initial_name, 3481 PLpgSQL_datum *initial_datum, 3482 int initial_location) 3483 { 3484 int nfields; 3485 char *fieldnames[1024]; 3486 int varnos[1024]; 3487 PLpgSQL_row *row; 3488 int tok; 3489 3490 check_assignable(initial_datum, initial_location); 3491 fieldnames[0] = initial_name; 3492 varnos[0] = initial_datum->dno; 3493 nfields = 1; 3494 3495 while ((tok = yylex()) == ',') 3496 { 3497 /* Check for array overflow */ 3498 if (nfields >= 1024) 3499 ereport(ERROR, 3500 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), 3501 errmsg("too many INTO variables specified"), 3502 parser_errposition(yylloc))); 3503 3504 tok = yylex(); 3505 switch (tok) 3506 { 3507 case T_DATUM: 3508 check_assignable(yylval.wdatum.datum, yylloc); 3509 if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || 3510 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC) 3511 ereport(ERROR, 3512 (errcode(ERRCODE_SYNTAX_ERROR), 3513 errmsg("\"%s\" is not a scalar variable", 3514 NameOfDatum(&(yylval.wdatum))), 3515 parser_errposition(yylloc))); 3516 fieldnames[nfields] = NameOfDatum(&(yylval.wdatum)); 3517 varnos[nfields++] = yylval.wdatum.datum->dno; 3518 break; 3519 3520 default: 3521 /* just to give a better message than "syntax error" */ 3522 current_token_is_not_variable(tok); 3523 } 3524 } 3525 3526 /* 3527 * We read an extra, non-comma token from yylex(), so push it 3528 * back onto the input stream 3529 */ 3530 plpgsql_push_back_token(tok); 3531 3532 row = palloc0(sizeof(PLpgSQL_row)); 3533 row->dtype = PLPGSQL_DTYPE_ROW; 3534 row->refname = "(unnamed row)"; 3535 row->lineno = plpgsql_location_to_lineno(initial_location); 3536 row->rowtupdesc = NULL; 3537 row->nfields = nfields; 3538 row->fieldnames = palloc(sizeof(char *) * nfields); 3539 row->varnos = palloc(sizeof(int) * nfields); 3540 while (--nfields >= 0) 3541 { 3542 row->fieldnames[nfields] = fieldnames[nfields]; 3543 row->varnos[nfields] = varnos[nfields]; 3544 } 3545 3546 plpgsql_adddatum((PLpgSQL_datum *)row); 3547 3548 return row; 3549 } 3550 3551 /* 3552 * Convert a single scalar into a "row" list. This is exactly 3553 * like read_into_scalar_list except we never consume any input. 3554 * 3555 * Note: lineno could be computed from location, but since callers 3556 * have it at hand already, we may as well pass it in. 3557 */ 3558 static PLpgSQL_row * 3559 make_scalar_list1(char *initial_name, 3560 PLpgSQL_datum *initial_datum, 3561 int lineno, int location) 3562 { 3563 PLpgSQL_row *row; 3564 3565 check_assignable(initial_datum, location); 3566 3567 row = palloc0(sizeof(PLpgSQL_row)); 3568 row->dtype = PLPGSQL_DTYPE_ROW; 3569 row->refname = "(unnamed row)"; 3570 row->lineno = lineno; 3571 row->rowtupdesc = NULL; 3572 row->nfields = 1; 3573 row->fieldnames = palloc(sizeof(char *)); 3574 row->varnos = palloc(sizeof(int)); 3575 row->fieldnames[0] = initial_name; 3576 row->varnos[0] = initial_datum->dno; 3577 3578 plpgsql_adddatum((PLpgSQL_datum *)row); 3579 3580 return row; 3581 } 3582 3583 /* 3584 * When the PL/pgSQL parser expects to see a SQL statement, it is very 3585 * liberal in what it accepts; for example, we often assume an 3586 * unrecognized keyword is the beginning of a SQL statement. This 3587 * avoids the need to duplicate parts of the SQL grammar in the 3588 * PL/pgSQL grammar, but it means we can accept wildly malformed 3589 * input. To try and catch some of the more obviously invalid input, 3590 * we run the strings we expect to be SQL statements through the main 3591 * SQL parser. 3592 * 3593 * We only invoke the raw parser (not the analyzer); this doesn't do 3594 * any database access and does not check any semantic rules, it just 3595 * checks for basic syntactic correctness. We do this here, rather 3596 * than after parsing has finished, because a malformed SQL statement 3597 * may cause the PL/pgSQL parser to become confused about statement 3598 * borders. So it is best to bail out as early as we can. 3599 * 3600 * It is assumed that "stmt" represents a copy of the function source text 3601 * beginning at offset "location", with leader text of length "leaderlen" 3602 * (typically "SELECT ") prefixed to the source text. We use this assumption 3603 * to transpose any error cursor position back to the function source text. 3604 * If no error cursor is provided, we'll just point at "location". 3605 */ 3606 static void 3607 check_sql_expr(const char *stmt, int location, int leaderlen) 3608 { 3609 sql_error_callback_arg cbarg; 3610 ErrorContextCallback syntax_errcontext; 3611 MemoryContext oldCxt; 3612 3613 if (!plpgsql_check_syntax) 3614 return; 3615 3616 cbarg.location = location; 3617 cbarg.leaderlen = leaderlen; 3618 3619 syntax_errcontext.callback = plpgsql_sql_error_callback; 3620 syntax_errcontext.arg = &cbarg; 3621 syntax_errcontext.previous = error_context_stack; 3622 error_context_stack = &syntax_errcontext; 3623 3624 oldCxt = MemoryContextSwitchTo(plpgsql_compile_tmp_cxt); 3625 (void) raw_parser(stmt); 3626 MemoryContextSwitchTo(oldCxt); 3627 3628 /* Restore former ereport callback */ 3629 error_context_stack = syntax_errcontext.previous; 3630 } 3631 3632 static void 3633 plpgsql_sql_error_callback(void *arg) 3634 { 3635 sql_error_callback_arg *cbarg = (sql_error_callback_arg *) arg; 3636 int errpos; 3637 3638 /* 3639 * First, set up internalerrposition to point to the start of the 3640 * statement text within the function text. Note this converts 3641 * location (a byte offset) to a character number. 3642 */ 3643 parser_errposition(cbarg->location); 3644 3645 /* 3646 * If the core parser provided an error position, transpose it. 3647 * Note we are dealing with 1-based character numbers at this point. 3648 */ 3649 errpos = geterrposition(); 3650 if (errpos > cbarg->leaderlen) 3651 { 3652 int myerrpos = getinternalerrposition(); 3653 3654 if (myerrpos > 0) /* safety check */ 3655 internalerrposition(myerrpos + errpos - cbarg->leaderlen - 1); 3656 } 3657 3658 /* In any case, flush errposition --- we want internalerrpos only */ 3659 errposition(0); 3660 } 3661 3662 /* 3663 * Parse a SQL datatype name and produce a PLpgSQL_type structure. 3664 * 3665 * The heavy lifting is done elsewhere. Here we are only concerned 3666 * with setting up an errcontext link that will let us give an error 3667 * cursor pointing into the plpgsql function source, if necessary. 3668 * This is handled the same as in check_sql_expr(), and we likewise 3669 * expect that the given string is a copy from the source text. 3670 */ 3671 static PLpgSQL_type * 3672 parse_datatype(const char *string, int location) 3673 { 3674 TypeName *typeName; 3675 Oid type_id; 3676 int32 typmod; 3677 sql_error_callback_arg cbarg; 3678 ErrorContextCallback syntax_errcontext; 3679 3680 cbarg.location = location; 3681 cbarg.leaderlen = 0; 3682 3683 syntax_errcontext.callback = plpgsql_sql_error_callback; 3684 syntax_errcontext.arg = &cbarg; 3685 syntax_errcontext.previous = error_context_stack; 3686 error_context_stack = &syntax_errcontext; 3687 3688 /* Let the main parser try to parse it under standard SQL rules */ 3689 typeName = typeStringToTypeName(string); 3690 typenameTypeIdAndMod(NULL, typeName, &type_id, &typmod); 3691 3692 /* Restore former ereport callback */ 3693 error_context_stack = syntax_errcontext.previous; 3694 3695 /* Okay, build a PLpgSQL_type data structure for it */ 3696 return plpgsql_build_datatype(type_id, typmod, 3697 plpgsql_curr_compile->fn_input_collation, 3698 typeName); 3699 } 3700 3701 /* 3702 * Check block starting and ending labels match. 3703 */ 3704 static void 3705 check_labels(const char *start_label, const char *end_label, int end_location) 3706 { 3707 if (end_label) 3708 { 3709 if (!start_label) 3710 ereport(ERROR, 3711 (errcode(ERRCODE_SYNTAX_ERROR), 3712 errmsg("end label \"%s\" specified for unlabelled block", 3713 end_label), 3714 parser_errposition(end_location))); 3715 3716 if (strcmp(start_label, end_label) != 0) 3717 ereport(ERROR, 3718 (errcode(ERRCODE_SYNTAX_ERROR), 3719 errmsg("end label \"%s\" differs from block's label \"%s\"", 3720 end_label, start_label), 3721 parser_errposition(end_location))); 3722 } 3723 } 3724 3725 /* 3726 * Read the arguments (if any) for a cursor, followed by the until token 3727 * 3728 * If cursor has no args, just swallow the until token and return NULL. 3729 * If it does have args, we expect to see "( arg [, arg ...] )" followed 3730 * by the until token, where arg may be a plain expression, or a named 3731 * parameter assignment of the form argname := expr. Consume all that and 3732 * return a SELECT query that evaluates the expression(s) (without the outer 3733 * parens). 3734 */ 3735 static PLpgSQL_expr * 3736 read_cursor_args(PLpgSQL_var *cursor, int until, const char *expected) 3737 { 3738 PLpgSQL_expr *expr; 3739 PLpgSQL_row *row; 3740 int tok; 3741 int argc; 3742 char **argv; 3743 StringInfoData ds; 3744 char *sqlstart = "SELECT "; 3745 bool any_named = false; 3746 3747 tok = yylex(); 3748 if (cursor->cursor_explicit_argrow < 0) 3749 { 3750 /* No arguments expected */ 3751 if (tok == '(') 3752 ereport(ERROR, 3753 (errcode(ERRCODE_SYNTAX_ERROR), 3754 errmsg("cursor \"%s\" has no arguments", 3755 cursor->refname), 3756 parser_errposition(yylloc))); 3757 3758 if (tok != until) 3759 yyerror("syntax error"); 3760 3761 return NULL; 3762 } 3763 3764 /* Else better provide arguments */ 3765 if (tok != '(') 3766 ereport(ERROR, 3767 (errcode(ERRCODE_SYNTAX_ERROR), 3768 errmsg("cursor \"%s\" has arguments", 3769 cursor->refname), 3770 parser_errposition(yylloc))); 3771 3772 /* 3773 * Read the arguments, one by one. 3774 */ 3775 row = (PLpgSQL_row *) plpgsql_Datums[cursor->cursor_explicit_argrow]; 3776 argv = (char **) palloc0(row->nfields * sizeof(char *)); 3777 3778 for (argc = 0; argc < row->nfields; argc++) 3779 { 3780 PLpgSQL_expr *item; 3781 int endtoken; 3782 int argpos; 3783 int tok1, 3784 tok2; 3785 int arglocation; 3786 3787 /* Check if it's a named parameter: "param := value" */ 3788 plpgsql_peek2(&tok1, &tok2, &arglocation, NULL); 3789 if (tok1 == IDENT && tok2 == COLON_EQUALS) 3790 { 3791 char *argname; 3792 IdentifierLookup save_IdentifierLookup; 3793 3794 /* Read the argument name, ignoring any matching variable */ 3795 save_IdentifierLookup = plpgsql_IdentifierLookup; 3796 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE; 3797 yylex(); 3798 argname = yylval.str; 3799 plpgsql_IdentifierLookup = save_IdentifierLookup; 3800 3801 /* Match argument name to cursor arguments */ 3802 for (argpos = 0; argpos < row->nfields; argpos++) 3803 { 3804 if (strcmp(row->fieldnames[argpos], argname) == 0) 3805 break; 3806 } 3807 if (argpos == row->nfields) 3808 ereport(ERROR, 3809 (errcode(ERRCODE_SYNTAX_ERROR), 3810 errmsg("cursor \"%s\" has no argument named \"%s\"", 3811 cursor->refname, argname), 3812 parser_errposition(yylloc))); 3813 3814 /* 3815 * Eat the ":=". We already peeked, so the error should never 3816 * happen. 3817 */ 3818 tok2 = yylex(); 3819 if (tok2 != COLON_EQUALS) 3820 yyerror("syntax error"); 3821 3822 any_named = true; 3823 } 3824 else 3825 argpos = argc; 3826 3827 if (argv[argpos] != NULL) 3828 ereport(ERROR, 3829 (errcode(ERRCODE_SYNTAX_ERROR), 3830 errmsg("value for parameter \"%s\" of cursor \"%s\" specified more than once", 3831 row->fieldnames[argpos], cursor->refname), 3832 parser_errposition(arglocation))); 3833 3834 /* 3835 * Read the value expression. To provide the user with meaningful 3836 * parse error positions, we check the syntax immediately, instead of 3837 * checking the final expression that may have the arguments 3838 * reordered. Trailing whitespace must not be trimmed, because 3839 * otherwise input of the form (param -- comment\n, param) would be 3840 * translated into a form where the second parameter is commented 3841 * out. 3842 */ 3843 item = read_sql_construct(',', ')', 0, 3844 ",\" or \")", 3845 sqlstart, 3846 true, true, 3847 false, /* do not trim */ 3848 NULL, &endtoken); 3849 3850 argv[argpos] = item->query + strlen(sqlstart); 3851 3852 if (endtoken == ')' && !(argc == row->nfields - 1)) 3853 ereport(ERROR, 3854 (errcode(ERRCODE_SYNTAX_ERROR), 3855 errmsg("not enough arguments for cursor \"%s\"", 3856 cursor->refname), 3857 parser_errposition(yylloc))); 3858 3859 if (endtoken == ',' && (argc == row->nfields - 1)) 3860 ereport(ERROR, 3861 (errcode(ERRCODE_SYNTAX_ERROR), 3862 errmsg("too many arguments for cursor \"%s\"", 3863 cursor->refname), 3864 parser_errposition(yylloc))); 3865 } 3866 3867 /* Make positional argument list */ 3868 initStringInfo(&ds); 3869 appendStringInfoString(&ds, sqlstart); 3870 for (argc = 0; argc < row->nfields; argc++) 3871 { 3872 Assert(argv[argc] != NULL); 3873 3874 /* 3875 * Because named notation allows permutated argument lists, include 3876 * the parameter name for meaningful runtime errors. 3877 */ 3878 appendStringInfoString(&ds, argv[argc]); 3879 if (any_named) 3880 appendStringInfo(&ds, " AS %s", 3881 quote_identifier(row->fieldnames[argc])); 3882 if (argc < row->nfields - 1) 3883 appendStringInfoString(&ds, ", "); 3884 } 3885 appendStringInfoChar(&ds, ';'); 3886 3887 expr = palloc0(sizeof(PLpgSQL_expr)); 3888 expr->query = pstrdup(ds.data); 3889 expr->plan = NULL; 3890 expr->paramnos = NULL; 3891 expr->rwparam = -1; 3892 expr->ns = plpgsql_ns_top(); 3893 pfree(ds.data); 3894 3895 /* Next we'd better find the until token */ 3896 tok = yylex(); 3897 if (tok != until) 3898 yyerror("syntax error"); 3899 3900 return expr; 3901 } 3902 3903 /* 3904 * Parse RAISE ... USING options 3905 */ 3906 static List * 3907 read_raise_options(void) 3908 { 3909 List *result = NIL; 3910 3911 for (;;) 3912 { 3913 PLpgSQL_raise_option *opt; 3914 int tok; 3915 3916 if ((tok = yylex()) == 0) 3917 yyerror("unexpected end of function definition"); 3918 3919 opt = (PLpgSQL_raise_option *) palloc(sizeof(PLpgSQL_raise_option)); 3920 3921 if (tok_is_keyword(tok, &yylval, 3922 K_ERRCODE, "errcode")) 3923 opt->opt_type = PLPGSQL_RAISEOPTION_ERRCODE; 3924 else if (tok_is_keyword(tok, &yylval, 3925 K_MESSAGE, "message")) 3926 opt->opt_type = PLPGSQL_RAISEOPTION_MESSAGE; 3927 else if (tok_is_keyword(tok, &yylval, 3928 K_DETAIL, "detail")) 3929 opt->opt_type = PLPGSQL_RAISEOPTION_DETAIL; 3930 else if (tok_is_keyword(tok, &yylval, 3931 K_HINT, "hint")) 3932 opt->opt_type = PLPGSQL_RAISEOPTION_HINT; 3933 else if (tok_is_keyword(tok, &yylval, 3934 K_COLUMN, "column")) 3935 opt->opt_type = PLPGSQL_RAISEOPTION_COLUMN; 3936 else if (tok_is_keyword(tok, &yylval, 3937 K_CONSTRAINT, "constraint")) 3938 opt->opt_type = PLPGSQL_RAISEOPTION_CONSTRAINT; 3939 else if (tok_is_keyword(tok, &yylval, 3940 K_DATATYPE, "datatype")) 3941 opt->opt_type = PLPGSQL_RAISEOPTION_DATATYPE; 3942 else if (tok_is_keyword(tok, &yylval, 3943 K_TABLE, "table")) 3944 opt->opt_type = PLPGSQL_RAISEOPTION_TABLE; 3945 else if (tok_is_keyword(tok, &yylval, 3946 K_SCHEMA, "schema")) 3947 opt->opt_type = PLPGSQL_RAISEOPTION_SCHEMA; 3948 else 3949 yyerror("unrecognized RAISE statement option"); 3950 3951 tok = yylex(); 3952 if (tok != '=' && tok != COLON_EQUALS) 3953 yyerror("syntax error, expected \"=\""); 3954 3955 opt->expr = read_sql_expression2(',', ';', ", or ;", &tok); 3956 3957 result = lappend(result, opt); 3958 3959 if (tok == ';') 3960 break; 3961 } 3962 3963 return result; 3964 } 3965 3966 /* 3967 * Check that the number of parameter placeholders in the message matches the 3968 * number of parameters passed to it, if a message was given. 3969 */ 3970 static void 3971 check_raise_parameters(PLpgSQL_stmt_raise *stmt) 3972 { 3973 char *cp; 3974 int expected_nparams = 0; 3975 3976 if (stmt->message == NULL) 3977 return; 3978 3979 for (cp = stmt->message; *cp; cp++) 3980 { 3981 if (cp[0] == '%') 3982 { 3983 /* ignore literal % characters */ 3984 if (cp[1] == '%') 3985 cp++; 3986 else 3987 expected_nparams++; 3988 } 3989 } 3990 3991 if (expected_nparams < list_length(stmt->params)) 3992 ereport(ERROR, 3993 (errcode(ERRCODE_SYNTAX_ERROR), 3994 errmsg("too many parameters specified for RAISE"))); 3995 if (expected_nparams > list_length(stmt->params)) 3996 ereport(ERROR, 3997 (errcode(ERRCODE_SYNTAX_ERROR), 3998 errmsg("too few parameters specified for RAISE"))); 3999 } 4000 4001 /* 4002 * Fix up CASE statement 4003 */ 4004 static PLpgSQL_stmt * 4005 make_case(int location, PLpgSQL_expr *t_expr, 4006 List *case_when_list, List *else_stmts) 4007 { 4008 PLpgSQL_stmt_case *new; 4009 4010 new = palloc(sizeof(PLpgSQL_stmt_case)); 4011 new->cmd_type = PLPGSQL_STMT_CASE; 4012 new->lineno = plpgsql_location_to_lineno(location); 4013 new->t_expr = t_expr; 4014 new->t_varno = 0; 4015 new->case_when_list = case_when_list; 4016 new->have_else = (else_stmts != NIL); 4017 /* Get rid of list-with-NULL hack */ 4018 if (list_length(else_stmts) == 1 && linitial(else_stmts) == NULL) 4019 new->else_stmts = NIL; 4020 else 4021 new->else_stmts = else_stmts; 4022 4023 /* 4024 * When test expression is present, we create a var for it and then 4025 * convert all the WHEN expressions to "VAR IN (original_expression)". 4026 * This is a bit klugy, but okay since we haven't yet done more than 4027 * read the expressions as text. (Note that previous parsing won't 4028 * have complained if the WHEN ... THEN expression contained multiple 4029 * comma-separated values.) 4030 */ 4031 if (t_expr) 4032 { 4033 char varname[32]; 4034 PLpgSQL_var *t_var; 4035 ListCell *l; 4036 4037 /* use a name unlikely to collide with any user names */ 4038 snprintf(varname, sizeof(varname), "__Case__Variable_%d__", 4039 plpgsql_nDatums); 4040 4041 /* 4042 * We don't yet know the result datatype of t_expr. Build the 4043 * variable as if it were INT4; we'll fix this at runtime if needed. 4044 */ 4045 t_var = (PLpgSQL_var *) 4046 plpgsql_build_variable(varname, new->lineno, 4047 plpgsql_build_datatype(INT4OID, 4048 -1, 4049 InvalidOid, 4050 NULL), 4051 true); 4052 new->t_varno = t_var->dno; 4053 4054 foreach(l, case_when_list) 4055 { 4056 PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l); 4057 PLpgSQL_expr *expr = cwt->expr; 4058 StringInfoData ds; 4059 4060 /* copy expression query without SELECT keyword (expr->query + 7) */ 4061 Assert(strncmp(expr->query, "SELECT ", 7) == 0); 4062 4063 /* And do the string hacking */ 4064 initStringInfo(&ds); 4065 4066 appendStringInfo(&ds, "SELECT \"%s\" IN (%s)", 4067 varname, expr->query + 7); 4068 4069 pfree(expr->query); 4070 expr->query = pstrdup(ds.data); 4071 /* Adjust expr's namespace to include the case variable */ 4072 expr->ns = plpgsql_ns_top(); 4073 4074 pfree(ds.data); 4075 } 4076 } 4077 4078 return (PLpgSQL_stmt *) new; 4079 } 4080