PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/src/pl/plpgsql/src/pl_gram.y

https://github.com/42penguins/postgres
Happy | 3812 lines | 3402 code | 410 blank | 0 comment | 0 complexity | 0c857c83e7255487b10e656c1efaf497 MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. %{
  2. /*-------------------------------------------------------------------------
  3. *
  4. * pl_gram.y - Parser for the PL/pgSQL procedural language
  5. *
  6. * Portions Copyright (c) 1996-2013, 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. #include "plpgsql.h"
  16. #include "catalog/namespace.h"
  17. #include "catalog/pg_type.h"
  18. #include "parser/parser.h"
  19. #include "parser/parse_type.h"
  20. #include "parser/scanner.h"
  21. #include "parser/scansup.h"
  22. #include "utils/builtins.h"
  23. /* Location tracking support --- simpler than bison's default */
  24. #define YYLLOC_DEFAULT(Current, Rhs, N) \
  25. do { \
  26. if (N) \
  27. (Current) = (Rhs)[1]; \
  28. else \
  29. (Current) = (Rhs)[0]; \
  30. } while (0)
  31. /*
  32. * Bison doesn't allocate anything that needs to live across parser calls,
  33. * so we can easily have it use palloc instead of malloc. This prevents
  34. * memory leaks if we error out during parsing. Note this only works with
  35. * bison >= 2.0. However, in bison 1.875 the default is to use alloca()
  36. * if possible, so there's not really much problem anyhow, at least if
  37. * you're building with gcc.
  38. */
  39. #define YYMALLOC palloc
  40. #define YYFREE pfree
  41. typedef struct
  42. {
  43. int location;
  44. int leaderlen;
  45. } sql_error_callback_arg;
  46. #define parser_errposition(pos) plpgsql_scanner_errposition(pos)
  47. union YYSTYPE; /* need forward reference for tok_is_keyword */
  48. static bool tok_is_keyword(int token, union YYSTYPE *lval,
  49. int kw_token, const char *kw_str);
  50. static void word_is_not_variable(PLword *word, int location);
  51. static void cword_is_not_variable(PLcword *cword, int location);
  52. static void current_token_is_not_variable(int tok);
  53. static PLpgSQL_expr *read_sql_construct(int until,
  54. int until2,
  55. int until3,
  56. const char *expected,
  57. const char *sqlstart,
  58. bool isexpression,
  59. bool valid_sql,
  60. bool trim,
  61. int *startloc,
  62. int *endtoken);
  63. static PLpgSQL_expr *read_sql_expression(int until,
  64. const char *expected);
  65. static PLpgSQL_expr *read_sql_expression2(int until, int until2,
  66. const char *expected,
  67. int *endtoken);
  68. static PLpgSQL_expr *read_sql_stmt(const char *sqlstart);
  69. static PLpgSQL_type *read_datatype(int tok);
  70. static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location);
  71. static PLpgSQL_stmt_fetch *read_fetch_direction(void);
  72. static void complete_direction(PLpgSQL_stmt_fetch *fetch,
  73. bool *check_FROM);
  74. static PLpgSQL_stmt *make_return_stmt(int location);
  75. static PLpgSQL_stmt *make_return_next_stmt(int location);
  76. static PLpgSQL_stmt *make_return_query_stmt(int location);
  77. static PLpgSQL_stmt *make_case(int location, PLpgSQL_expr *t_expr,
  78. List *case_when_list, List *else_stmts);
  79. static char *NameOfDatum(PLwdatum *wdatum);
  80. static void check_assignable(PLpgSQL_datum *datum, int location);
  81. static void read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row,
  82. bool *strict);
  83. static PLpgSQL_row *read_into_scalar_list(char *initial_name,
  84. PLpgSQL_datum *initial_datum,
  85. int initial_location);
  86. static PLpgSQL_row *make_scalar_list1(char *initial_name,
  87. PLpgSQL_datum *initial_datum,
  88. int lineno, int location);
  89. static void check_sql_expr(const char *stmt, int location,
  90. int leaderlen);
  91. static void plpgsql_sql_error_callback(void *arg);
  92. static PLpgSQL_type *parse_datatype(const char *string, int location);
  93. static void check_labels(const char *start_label,
  94. const char *end_label,
  95. int end_location);
  96. static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor,
  97. int until, const char *expected);
  98. static List *read_raise_options(void);
  99. %}
  100. %expect 0
  101. %name-prefix="plpgsql_yy"
  102. %locations
  103. %union {
  104. core_YYSTYPE core_yystype;
  105. /* these fields must match core_YYSTYPE: */
  106. int ival;
  107. char *str;
  108. const char *keyword;
  109. PLword word;
  110. PLcword cword;
  111. PLwdatum wdatum;
  112. bool boolean;
  113. Oid oid;
  114. struct
  115. {
  116. char *name;
  117. int lineno;
  118. } varname;
  119. struct
  120. {
  121. char *name;
  122. int lineno;
  123. PLpgSQL_datum *scalar;
  124. PLpgSQL_rec *rec;
  125. PLpgSQL_row *row;
  126. } forvariable;
  127. struct
  128. {
  129. char *label;
  130. int n_initvars;
  131. int *initvarnos;
  132. } declhdr;
  133. struct
  134. {
  135. List *stmts;
  136. char *end_label;
  137. int end_label_location;
  138. } loop_body;
  139. List *list;
  140. PLpgSQL_type *dtype;
  141. PLpgSQL_datum *datum;
  142. PLpgSQL_var *var;
  143. PLpgSQL_expr *expr;
  144. PLpgSQL_stmt *stmt;
  145. PLpgSQL_condition *condition;
  146. PLpgSQL_exception *exception;
  147. PLpgSQL_exception_block *exception_block;
  148. PLpgSQL_nsitem *nsitem;
  149. PLpgSQL_diag_item *diagitem;
  150. PLpgSQL_stmt_fetch *fetch;
  151. PLpgSQL_case_when *casewhen;
  152. }
  153. %type <declhdr> decl_sect
  154. %type <varname> decl_varname
  155. %type <boolean> decl_const decl_notnull exit_type
  156. %type <expr> decl_defval decl_cursor_query
  157. %type <dtype> decl_datatype
  158. %type <oid> decl_collate
  159. %type <datum> decl_cursor_args
  160. %type <list> decl_cursor_arglist
  161. %type <nsitem> decl_aliasitem
  162. %type <expr> expr_until_semi expr_until_rightbracket
  163. %type <expr> expr_until_then expr_until_loop opt_expr_until_when
  164. %type <expr> opt_exitcond
  165. %type <ival> assign_var foreach_slice
  166. %type <var> cursor_variable
  167. %type <datum> decl_cursor_arg
  168. %type <forvariable> for_variable
  169. %type <stmt> for_control
  170. %type <str> any_identifier opt_block_label opt_label option_value
  171. %type <list> proc_sect proc_stmts stmt_elsifs stmt_else
  172. %type <loop_body> loop_body
  173. %type <stmt> proc_stmt pl_block
  174. %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
  175. %type <stmt> stmt_return stmt_raise stmt_execsql
  176. %type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_getdiag
  177. %type <stmt> stmt_open stmt_fetch stmt_move stmt_close stmt_null
  178. %type <stmt> stmt_case stmt_foreach_a
  179. %type <list> proc_exceptions
  180. %type <exception_block> exception_sect
  181. %type <exception> proc_exception
  182. %type <condition> proc_conditions proc_condition
  183. %type <casewhen> case_when
  184. %type <list> case_when_list opt_case_else
  185. %type <boolean> getdiag_area_opt
  186. %type <list> getdiag_list
  187. %type <diagitem> getdiag_list_item
  188. %type <ival> getdiag_item getdiag_target
  189. %type <ival> opt_scrollable
  190. %type <fetch> opt_fetch_direction
  191. %type <keyword> unreserved_keyword
  192. /*
  193. * Basic non-keyword token types. These are hard-wired into the core lexer.
  194. * They must be listed first so that their numeric codes do not depend on
  195. * the set of keywords. Keep this list in sync with backend/parser/gram.y!
  196. *
  197. * Some of these are not directly referenced in this file, but they must be
  198. * here anyway.
  199. */
  200. %token <str> IDENT FCONST SCONST BCONST XCONST Op
  201. %token <ival> ICONST PARAM
  202. %token TYPECAST DOT_DOT COLON_EQUALS
  203. /*
  204. * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c).
  205. */
  206. %token <word> T_WORD /* unrecognized simple identifier */
  207. %token <cword> T_CWORD /* unrecognized composite identifier */
  208. %token <wdatum> T_DATUM /* a VAR, ROW, REC, or RECFIELD variable */
  209. %token LESS_LESS
  210. %token GREATER_GREATER
  211. /*
  212. * Keyword tokens. Some of these are reserved and some are not;
  213. * see pl_scanner.c for info. Be sure unreserved keywords are listed
  214. * in the "unreserved_keyword" production below.
  215. */
  216. %token <keyword> K_ABSOLUTE
  217. %token <keyword> K_ALIAS
  218. %token <keyword> K_ALL
  219. %token <keyword> K_ARRAY
  220. %token <keyword> K_BACKWARD
  221. %token <keyword> K_BEGIN
  222. %token <keyword> K_BY
  223. %token <keyword> K_CASE
  224. %token <keyword> K_CLOSE
  225. %token <keyword> K_COLLATE
  226. %token <keyword> K_COLUMN
  227. %token <keyword> K_COLUMN_NAME
  228. %token <keyword> K_CONSTANT
  229. %token <keyword> K_CONSTRAINT
  230. %token <keyword> K_CONSTRAINT_NAME
  231. %token <keyword> K_CONTINUE
  232. %token <keyword> K_CURRENT
  233. %token <keyword> K_CURSOR
  234. %token <keyword> K_DATATYPE
  235. %token <keyword> K_DEBUG
  236. %token <keyword> K_DECLARE
  237. %token <keyword> K_DEFAULT
  238. %token <keyword> K_DETAIL
  239. %token <keyword> K_DIAGNOSTICS
  240. %token <keyword> K_DUMP
  241. %token <keyword> K_ELSE
  242. %token <keyword> K_ELSIF
  243. %token <keyword> K_END
  244. %token <keyword> K_ERRCODE
  245. %token <keyword> K_ERROR
  246. %token <keyword> K_EXCEPTION
  247. %token <keyword> K_EXECUTE
  248. %token <keyword> K_EXIT
  249. %token <keyword> K_FETCH
  250. %token <keyword> K_FIRST
  251. %token <keyword> K_FOR
  252. %token <keyword> K_FOREACH
  253. %token <keyword> K_FORWARD
  254. %token <keyword> K_FROM
  255. %token <keyword> K_GET
  256. %token <keyword> K_HINT
  257. %token <keyword> K_IF
  258. %token <keyword> K_IN
  259. %token <keyword> K_INFO
  260. %token <keyword> K_INSERT
  261. %token <keyword> K_INTO
  262. %token <keyword> K_IS
  263. %token <keyword> K_LAST
  264. %token <keyword> K_LOG
  265. %token <keyword> K_LOOP
  266. %token <keyword> K_MESSAGE
  267. %token <keyword> K_MESSAGE_TEXT
  268. %token <keyword> K_MOVE
  269. %token <keyword> K_NEXT
  270. %token <keyword> K_NO
  271. %token <keyword> K_NOT
  272. %token <keyword> K_NOTICE
  273. %token <keyword> K_NULL
  274. %token <keyword> K_OPEN
  275. %token <keyword> K_OPTION
  276. %token <keyword> K_OR
  277. %token <keyword> K_PERFORM
  278. %token <keyword> K_PG_CONTEXT
  279. %token <keyword> K_PG_DATATYPE_NAME
  280. %token <keyword> K_PG_EXCEPTION_CONTEXT
  281. %token <keyword> K_PG_EXCEPTION_DETAIL
  282. %token <keyword> K_PG_EXCEPTION_HINT
  283. %token <keyword> K_PRINT_STRICT_PARAMS
  284. %token <keyword> K_PRIOR
  285. %token <keyword> K_QUERY
  286. %token <keyword> K_RAISE
  287. %token <keyword> K_RELATIVE
  288. %token <keyword> K_RESULT_OID
  289. %token <keyword> K_RETURN
  290. %token <keyword> K_RETURNED_SQLSTATE
  291. %token <keyword> K_REVERSE
  292. %token <keyword> K_ROWTYPE
  293. %token <keyword> K_ROW_COUNT
  294. %token <keyword> K_SCHEMA
  295. %token <keyword> K_SCHEMA_NAME
  296. %token <keyword> K_SCROLL
  297. %token <keyword> K_SLICE
  298. %token <keyword> K_SQLSTATE
  299. %token <keyword> K_STACKED
  300. %token <keyword> K_STRICT
  301. %token <keyword> K_TABLE
  302. %token <keyword> K_TABLE_NAME
  303. %token <keyword> K_THEN
  304. %token <keyword> K_TO
  305. %token <keyword> K_TYPE
  306. %token <keyword> K_USE_COLUMN
  307. %token <keyword> K_USE_VARIABLE
  308. %token <keyword> K_USING
  309. %token <keyword> K_VARIABLE_CONFLICT
  310. %token <keyword> K_WARNING
  311. %token <keyword> K_WHEN
  312. %token <keyword> K_WHILE
  313. %%
  314. pl_function : comp_options pl_block opt_semi
  315. {
  316. plpgsql_parse_result = (PLpgSQL_stmt_block *) $2;
  317. }
  318. ;
  319. comp_options :
  320. | comp_options comp_option
  321. ;
  322. comp_option : '#' K_OPTION K_DUMP
  323. {
  324. plpgsql_DumpExecTree = true;
  325. }
  326. | '#' K_PRINT_STRICT_PARAMS option_value
  327. {
  328. if (strcmp($3, "on") == 0)
  329. plpgsql_curr_compile->print_strict_params = true;
  330. else if (strcmp($3, "off") == 0)
  331. plpgsql_curr_compile->print_strict_params = false;
  332. else
  333. elog(ERROR, "unrecognized print_strict_params option %s", $3);
  334. }
  335. | '#' K_VARIABLE_CONFLICT K_ERROR
  336. {
  337. plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_ERROR;
  338. }
  339. | '#' K_VARIABLE_CONFLICT K_USE_VARIABLE
  340. {
  341. plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_VARIABLE;
  342. }
  343. | '#' K_VARIABLE_CONFLICT K_USE_COLUMN
  344. {
  345. plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_COLUMN;
  346. }
  347. ;
  348. option_value : T_WORD
  349. {
  350. $$ = $1.ident;
  351. }
  352. | unreserved_keyword
  353. {
  354. $$ = pstrdup($1);
  355. }
  356. opt_semi :
  357. | ';'
  358. ;
  359. pl_block : decl_sect K_BEGIN proc_sect exception_sect K_END opt_label
  360. {
  361. PLpgSQL_stmt_block *new;
  362. new = palloc0(sizeof(PLpgSQL_stmt_block));
  363. new->cmd_type = PLPGSQL_STMT_BLOCK;
  364. new->lineno = plpgsql_location_to_lineno(@2);
  365. new->label = $1.label;
  366. new->n_initvars = $1.n_initvars;
  367. new->initvarnos = $1.initvarnos;
  368. new->body = $3;
  369. new->exceptions = $4;
  370. check_labels($1.label, $6, @6);
  371. plpgsql_ns_pop();
  372. $$ = (PLpgSQL_stmt *)new;
  373. }
  374. ;
  375. decl_sect : opt_block_label
  376. {
  377. /* done with decls, so resume identifier lookup */
  378. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  379. $$.label = $1;
  380. $$.n_initvars = 0;
  381. $$.initvarnos = NULL;
  382. }
  383. | opt_block_label decl_start
  384. {
  385. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  386. $$.label = $1;
  387. $$.n_initvars = 0;
  388. $$.initvarnos = NULL;
  389. }
  390. | opt_block_label decl_start decl_stmts
  391. {
  392. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  393. $$.label = $1;
  394. /* Remember variables declared in decl_stmts */
  395. $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
  396. }
  397. ;
  398. decl_start : K_DECLARE
  399. {
  400. /* Forget any variables created before block */
  401. plpgsql_add_initdatums(NULL);
  402. /*
  403. * Disable scanner lookup of identifiers while
  404. * we process the decl_stmts
  405. */
  406. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
  407. }
  408. ;
  409. decl_stmts : decl_stmts decl_stmt
  410. | decl_stmt
  411. ;
  412. decl_stmt : decl_statement
  413. | K_DECLARE
  414. {
  415. /* We allow useless extra DECLAREs */
  416. }
  417. | LESS_LESS any_identifier GREATER_GREATER
  418. {
  419. /*
  420. * Throw a helpful error if user tries to put block
  421. * label just before BEGIN, instead of before DECLARE.
  422. */
  423. ereport(ERROR,
  424. (errcode(ERRCODE_SYNTAX_ERROR),
  425. errmsg("block label must be placed before DECLARE, not after"),
  426. parser_errposition(@1)));
  427. }
  428. ;
  429. decl_statement : decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval
  430. {
  431. PLpgSQL_variable *var;
  432. /*
  433. * If a collation is supplied, insert it into the
  434. * datatype. We assume decl_datatype always returns
  435. * a freshly built struct not shared with other
  436. * variables.
  437. */
  438. if (OidIsValid($4))
  439. {
  440. if (!OidIsValid($3->collation))
  441. ereport(ERROR,
  442. (errcode(ERRCODE_DATATYPE_MISMATCH),
  443. errmsg("collations are not supported by type %s",
  444. format_type_be($3->typoid)),
  445. parser_errposition(@4)));
  446. $3->collation = $4;
  447. }
  448. var = plpgsql_build_variable($1.name, $1.lineno,
  449. $3, true);
  450. if ($2)
  451. {
  452. if (var->dtype == PLPGSQL_DTYPE_VAR)
  453. ((PLpgSQL_var *) var)->isconst = $2;
  454. else
  455. ereport(ERROR,
  456. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  457. errmsg("row or record variable cannot be CONSTANT"),
  458. parser_errposition(@2)));
  459. }
  460. if ($5)
  461. {
  462. if (var->dtype == PLPGSQL_DTYPE_VAR)
  463. ((PLpgSQL_var *) var)->notnull = $5;
  464. else
  465. ereport(ERROR,
  466. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  467. errmsg("row or record variable cannot be NOT NULL"),
  468. parser_errposition(@4)));
  469. }
  470. if ($6 != NULL)
  471. {
  472. if (var->dtype == PLPGSQL_DTYPE_VAR)
  473. ((PLpgSQL_var *) var)->default_val = $6;
  474. else
  475. ereport(ERROR,
  476. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  477. errmsg("default value for row or record variable is not supported"),
  478. parser_errposition(@5)));
  479. }
  480. }
  481. | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
  482. {
  483. plpgsql_ns_additem($4->itemtype,
  484. $4->itemno, $1.name);
  485. }
  486. | decl_varname opt_scrollable K_CURSOR
  487. { plpgsql_ns_push($1.name); }
  488. decl_cursor_args decl_is_for decl_cursor_query
  489. {
  490. PLpgSQL_var *new;
  491. PLpgSQL_expr *curname_def;
  492. char buf[1024];
  493. char *cp1;
  494. char *cp2;
  495. /* pop local namespace for cursor args */
  496. plpgsql_ns_pop();
  497. new = (PLpgSQL_var *)
  498. plpgsql_build_variable($1.name, $1.lineno,
  499. plpgsql_build_datatype(REFCURSOROID,
  500. -1,
  501. InvalidOid),
  502. true);
  503. curname_def = palloc0(sizeof(PLpgSQL_expr));
  504. curname_def->dtype = PLPGSQL_DTYPE_EXPR;
  505. strcpy(buf, "SELECT ");
  506. cp1 = new->refname;
  507. cp2 = buf + strlen(buf);
  508. /*
  509. * Don't trust standard_conforming_strings here;
  510. * it might change before we use the string.
  511. */
  512. if (strchr(cp1, '\\') != NULL)
  513. *cp2++ = ESCAPE_STRING_SYNTAX;
  514. *cp2++ = '\'';
  515. while (*cp1)
  516. {
  517. if (SQL_STR_DOUBLE(*cp1, true))
  518. *cp2++ = *cp1;
  519. *cp2++ = *cp1++;
  520. }
  521. strcpy(cp2, "'::pg_catalog.refcursor");
  522. curname_def->query = pstrdup(buf);
  523. new->default_val = curname_def;
  524. new->cursor_explicit_expr = $7;
  525. if ($5 == NULL)
  526. new->cursor_explicit_argrow = -1;
  527. else
  528. new->cursor_explicit_argrow = $5->dno;
  529. new->cursor_options = CURSOR_OPT_FAST_PLAN | $2;
  530. }
  531. ;
  532. opt_scrollable :
  533. {
  534. $$ = 0;
  535. }
  536. | K_NO K_SCROLL
  537. {
  538. $$ = CURSOR_OPT_NO_SCROLL;
  539. }
  540. | K_SCROLL
  541. {
  542. $$ = CURSOR_OPT_SCROLL;
  543. }
  544. ;
  545. decl_cursor_query :
  546. {
  547. $$ = read_sql_stmt("");
  548. }
  549. ;
  550. decl_cursor_args :
  551. {
  552. $$ = NULL;
  553. }
  554. | '(' decl_cursor_arglist ')'
  555. {
  556. PLpgSQL_row *new;
  557. int i;
  558. ListCell *l;
  559. new = palloc0(sizeof(PLpgSQL_row));
  560. new->dtype = PLPGSQL_DTYPE_ROW;
  561. new->lineno = plpgsql_location_to_lineno(@1);
  562. new->rowtupdesc = NULL;
  563. new->nfields = list_length($2);
  564. new->fieldnames = palloc(new->nfields * sizeof(char *));
  565. new->varnos = palloc(new->nfields * sizeof(int));
  566. i = 0;
  567. foreach (l, $2)
  568. {
  569. PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
  570. new->fieldnames[i] = arg->refname;
  571. new->varnos[i] = arg->dno;
  572. i++;
  573. }
  574. list_free($2);
  575. plpgsql_adddatum((PLpgSQL_datum *) new);
  576. $$ = (PLpgSQL_datum *) new;
  577. }
  578. ;
  579. decl_cursor_arglist : decl_cursor_arg
  580. {
  581. $$ = list_make1($1);
  582. }
  583. | decl_cursor_arglist ',' decl_cursor_arg
  584. {
  585. $$ = lappend($1, $3);
  586. }
  587. ;
  588. decl_cursor_arg : decl_varname decl_datatype
  589. {
  590. $$ = (PLpgSQL_datum *)
  591. plpgsql_build_variable($1.name, $1.lineno,
  592. $2, true);
  593. }
  594. ;
  595. decl_is_for : K_IS | /* Oracle */
  596. K_FOR; /* SQL standard */
  597. decl_aliasitem : T_WORD
  598. {
  599. PLpgSQL_nsitem *nsi;
  600. nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
  601. $1.ident, NULL, NULL,
  602. NULL);
  603. if (nsi == NULL)
  604. ereport(ERROR,
  605. (errcode(ERRCODE_UNDEFINED_OBJECT),
  606. errmsg("variable \"%s\" does not exist",
  607. $1.ident),
  608. parser_errposition(@1)));
  609. $$ = nsi;
  610. }
  611. | unreserved_keyword
  612. {
  613. PLpgSQL_nsitem *nsi;
  614. nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
  615. $1, NULL, NULL,
  616. NULL);
  617. if (nsi == NULL)
  618. ereport(ERROR,
  619. (errcode(ERRCODE_UNDEFINED_OBJECT),
  620. errmsg("variable \"%s\" does not exist",
  621. $1),
  622. parser_errposition(@1)));
  623. $$ = nsi;
  624. }
  625. | T_CWORD
  626. {
  627. PLpgSQL_nsitem *nsi;
  628. if (list_length($1.idents) == 2)
  629. nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
  630. strVal(linitial($1.idents)),
  631. strVal(lsecond($1.idents)),
  632. NULL,
  633. NULL);
  634. else if (list_length($1.idents) == 3)
  635. nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
  636. strVal(linitial($1.idents)),
  637. strVal(lsecond($1.idents)),
  638. strVal(lthird($1.idents)),
  639. NULL);
  640. else
  641. nsi = NULL;
  642. if (nsi == NULL)
  643. ereport(ERROR,
  644. (errcode(ERRCODE_UNDEFINED_OBJECT),
  645. errmsg("variable \"%s\" does not exist",
  646. NameListToString($1.idents)),
  647. parser_errposition(@1)));
  648. $$ = nsi;
  649. }
  650. ;
  651. decl_varname : T_WORD
  652. {
  653. $$.name = $1.ident;
  654. $$.lineno = plpgsql_location_to_lineno(@1);
  655. /*
  656. * Check to make sure name isn't already declared
  657. * in the current block.
  658. */
  659. if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
  660. $1.ident, NULL, NULL,
  661. NULL) != NULL)
  662. yyerror("duplicate declaration");
  663. }
  664. | unreserved_keyword
  665. {
  666. $$.name = pstrdup($1);
  667. $$.lineno = plpgsql_location_to_lineno(@1);
  668. /*
  669. * Check to make sure name isn't already declared
  670. * in the current block.
  671. */
  672. if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
  673. $1, NULL, NULL,
  674. NULL) != NULL)
  675. yyerror("duplicate declaration");
  676. }
  677. ;
  678. decl_const :
  679. { $$ = false; }
  680. | K_CONSTANT
  681. { $$ = true; }
  682. ;
  683. decl_datatype :
  684. {
  685. /*
  686. * If there's a lookahead token, read_datatype
  687. * should consume it.
  688. */
  689. $$ = read_datatype(yychar);
  690. yyclearin;
  691. }
  692. ;
  693. decl_collate :
  694. { $$ = InvalidOid; }
  695. | K_COLLATE T_WORD
  696. {
  697. $$ = get_collation_oid(list_make1(makeString($2.ident)),
  698. false);
  699. }
  700. | K_COLLATE unreserved_keyword
  701. {
  702. $$ = get_collation_oid(list_make1(makeString(pstrdup($2))),
  703. false);
  704. }
  705. | K_COLLATE T_CWORD
  706. {
  707. $$ = get_collation_oid($2.idents, false);
  708. }
  709. ;
  710. decl_notnull :
  711. { $$ = false; }
  712. | K_NOT K_NULL
  713. { $$ = true; }
  714. ;
  715. decl_defval : ';'
  716. { $$ = NULL; }
  717. | decl_defkey
  718. {
  719. $$ = read_sql_expression(';', ";");
  720. }
  721. ;
  722. decl_defkey : assign_operator
  723. | K_DEFAULT
  724. ;
  725. assign_operator : '=' /* not documented because it might be removed someday */
  726. | COLON_EQUALS
  727. ;
  728. proc_sect :
  729. { $$ = NIL; }
  730. | proc_stmts
  731. { $$ = $1; }
  732. ;
  733. proc_stmts : proc_stmts proc_stmt
  734. {
  735. if ($2 == NULL)
  736. $$ = $1;
  737. else
  738. $$ = lappend($1, $2);
  739. }
  740. | proc_stmt
  741. {
  742. if ($1 == NULL)
  743. $$ = NIL;
  744. else
  745. $$ = list_make1($1);
  746. }
  747. ;
  748. proc_stmt : pl_block ';'
  749. { $$ = $1; }
  750. | stmt_assign
  751. { $$ = $1; }
  752. | stmt_if
  753. { $$ = $1; }
  754. | stmt_case
  755. { $$ = $1; }
  756. | stmt_loop
  757. { $$ = $1; }
  758. | stmt_while
  759. { $$ = $1; }
  760. | stmt_for
  761. { $$ = $1; }
  762. | stmt_foreach_a
  763. { $$ = $1; }
  764. | stmt_exit
  765. { $$ = $1; }
  766. | stmt_return
  767. { $$ = $1; }
  768. | stmt_raise
  769. { $$ = $1; }
  770. | stmt_execsql
  771. { $$ = $1; }
  772. | stmt_dynexecute
  773. { $$ = $1; }
  774. | stmt_perform
  775. { $$ = $1; }
  776. | stmt_getdiag
  777. { $$ = $1; }
  778. | stmt_open
  779. { $$ = $1; }
  780. | stmt_fetch
  781. { $$ = $1; }
  782. | stmt_move
  783. { $$ = $1; }
  784. | stmt_close
  785. { $$ = $1; }
  786. | stmt_null
  787. { $$ = $1; }
  788. ;
  789. stmt_perform : K_PERFORM expr_until_semi
  790. {
  791. PLpgSQL_stmt_perform *new;
  792. new = palloc0(sizeof(PLpgSQL_stmt_perform));
  793. new->cmd_type = PLPGSQL_STMT_PERFORM;
  794. new->lineno = plpgsql_location_to_lineno(@1);
  795. new->expr = $2;
  796. $$ = (PLpgSQL_stmt *)new;
  797. }
  798. ;
  799. stmt_assign : assign_var assign_operator expr_until_semi
  800. {
  801. PLpgSQL_stmt_assign *new;
  802. new = palloc0(sizeof(PLpgSQL_stmt_assign));
  803. new->cmd_type = PLPGSQL_STMT_ASSIGN;
  804. new->lineno = plpgsql_location_to_lineno(@1);
  805. new->varno = $1;
  806. new->expr = $3;
  807. $$ = (PLpgSQL_stmt *)new;
  808. }
  809. ;
  810. stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
  811. {
  812. PLpgSQL_stmt_getdiag *new;
  813. ListCell *lc;
  814. new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
  815. new->cmd_type = PLPGSQL_STMT_GETDIAG;
  816. new->lineno = plpgsql_location_to_lineno(@1);
  817. new->is_stacked = $2;
  818. new->diag_items = $4;
  819. /*
  820. * Check information items are valid for area option.
  821. */
  822. foreach(lc, new->diag_items)
  823. {
  824. PLpgSQL_diag_item *ditem = (PLpgSQL_diag_item *) lfirst(lc);
  825. switch (ditem->kind)
  826. {
  827. /* these fields are disallowed in stacked case */
  828. case PLPGSQL_GETDIAG_ROW_COUNT:
  829. case PLPGSQL_GETDIAG_RESULT_OID:
  830. if (new->is_stacked)
  831. ereport(ERROR,
  832. (errcode(ERRCODE_SYNTAX_ERROR),
  833. errmsg("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS",
  834. plpgsql_getdiag_kindname(ditem->kind)),
  835. parser_errposition(@1)));
  836. break;
  837. /* these fields are disallowed in current case */
  838. case PLPGSQL_GETDIAG_ERROR_CONTEXT:
  839. case PLPGSQL_GETDIAG_ERROR_DETAIL:
  840. case PLPGSQL_GETDIAG_ERROR_HINT:
  841. case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
  842. case PLPGSQL_GETDIAG_COLUMN_NAME:
  843. case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
  844. case PLPGSQL_GETDIAG_DATATYPE_NAME:
  845. case PLPGSQL_GETDIAG_MESSAGE_TEXT:
  846. case PLPGSQL_GETDIAG_TABLE_NAME:
  847. case PLPGSQL_GETDIAG_SCHEMA_NAME:
  848. if (!new->is_stacked)
  849. ereport(ERROR,
  850. (errcode(ERRCODE_SYNTAX_ERROR),
  851. errmsg("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS",
  852. plpgsql_getdiag_kindname(ditem->kind)),
  853. parser_errposition(@1)));
  854. break;
  855. /* these fields are allowed in either case */
  856. case PLPGSQL_GETDIAG_CONTEXT:
  857. break;
  858. default:
  859. elog(ERROR, "unrecognized diagnostic item kind: %d",
  860. ditem->kind);
  861. break;
  862. }
  863. }
  864. $$ = (PLpgSQL_stmt *)new;
  865. }
  866. ;
  867. getdiag_area_opt :
  868. {
  869. $$ = false;
  870. }
  871. | K_CURRENT
  872. {
  873. $$ = false;
  874. }
  875. | K_STACKED
  876. {
  877. $$ = true;
  878. }
  879. ;
  880. getdiag_list : getdiag_list ',' getdiag_list_item
  881. {
  882. $$ = lappend($1, $3);
  883. }
  884. | getdiag_list_item
  885. {
  886. $$ = list_make1($1);
  887. }
  888. ;
  889. getdiag_list_item : getdiag_target assign_operator getdiag_item
  890. {
  891. PLpgSQL_diag_item *new;
  892. new = palloc(sizeof(PLpgSQL_diag_item));
  893. new->target = $1;
  894. new->kind = $3;
  895. $$ = new;
  896. }
  897. ;
  898. getdiag_item :
  899. {
  900. int tok = yylex();
  901. if (tok_is_keyword(tok, &yylval,
  902. K_ROW_COUNT, "row_count"))
  903. $$ = PLPGSQL_GETDIAG_ROW_COUNT;
  904. else if (tok_is_keyword(tok, &yylval,
  905. K_RESULT_OID, "result_oid"))
  906. $$ = PLPGSQL_GETDIAG_RESULT_OID;
  907. else if (tok_is_keyword(tok, &yylval,
  908. K_PG_CONTEXT, "pg_context"))
  909. $$ = PLPGSQL_GETDIAG_CONTEXT;
  910. else if (tok_is_keyword(tok, &yylval,
  911. K_PG_EXCEPTION_DETAIL, "pg_exception_detail"))
  912. $$ = PLPGSQL_GETDIAG_ERROR_DETAIL;
  913. else if (tok_is_keyword(tok, &yylval,
  914. K_PG_EXCEPTION_HINT, "pg_exception_hint"))
  915. $$ = PLPGSQL_GETDIAG_ERROR_HINT;
  916. else if (tok_is_keyword(tok, &yylval,
  917. K_PG_EXCEPTION_CONTEXT, "pg_exception_context"))
  918. $$ = PLPGSQL_GETDIAG_ERROR_CONTEXT;
  919. else if (tok_is_keyword(tok, &yylval,
  920. K_COLUMN_NAME, "column_name"))
  921. $$ = PLPGSQL_GETDIAG_COLUMN_NAME;
  922. else if (tok_is_keyword(tok, &yylval,
  923. K_CONSTRAINT_NAME, "constraint_name"))
  924. $$ = PLPGSQL_GETDIAG_CONSTRAINT_NAME;
  925. else if (tok_is_keyword(tok, &yylval,
  926. K_PG_DATATYPE_NAME, "pg_datatype_name"))
  927. $$ = PLPGSQL_GETDIAG_DATATYPE_NAME;
  928. else if (tok_is_keyword(tok, &yylval,
  929. K_MESSAGE_TEXT, "message_text"))
  930. $$ = PLPGSQL_GETDIAG_MESSAGE_TEXT;
  931. else if (tok_is_keyword(tok, &yylval,
  932. K_TABLE_NAME, "table_name"))
  933. $$ = PLPGSQL_GETDIAG_TABLE_NAME;
  934. else if (tok_is_keyword(tok, &yylval,
  935. K_SCHEMA_NAME, "schema_name"))
  936. $$ = PLPGSQL_GETDIAG_SCHEMA_NAME;
  937. else if (tok_is_keyword(tok, &yylval,
  938. K_RETURNED_SQLSTATE, "returned_sqlstate"))
  939. $$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE;
  940. else
  941. yyerror("unrecognized GET DIAGNOSTICS item");
  942. }
  943. ;
  944. getdiag_target : T_DATUM
  945. {
  946. check_assignable($1.datum, @1);
  947. if ($1.datum->dtype == PLPGSQL_DTYPE_ROW ||
  948. $1.datum->dtype == PLPGSQL_DTYPE_REC)
  949. ereport(ERROR,
  950. (errcode(ERRCODE_SYNTAX_ERROR),
  951. errmsg("\"%s\" is not a scalar variable",
  952. NameOfDatum(&($1))),
  953. parser_errposition(@1)));
  954. $$ = $1.datum->dno;
  955. }
  956. | T_WORD
  957. {
  958. /* just to give a better message than "syntax error" */
  959. word_is_not_variable(&($1), @1);
  960. }
  961. | T_CWORD
  962. {
  963. /* just to give a better message than "syntax error" */
  964. cword_is_not_variable(&($1), @1);
  965. }
  966. ;
  967. assign_var : T_DATUM
  968. {
  969. check_assignable($1.datum, @1);
  970. $$ = $1.datum->dno;
  971. }
  972. | assign_var '[' expr_until_rightbracket
  973. {
  974. PLpgSQL_arrayelem *new;
  975. new = palloc0(sizeof(PLpgSQL_arrayelem));
  976. new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
  977. new->subscript = $3;
  978. new->arrayparentno = $1;
  979. /* initialize cached type data to "not valid" */
  980. new->parenttypoid = InvalidOid;
  981. plpgsql_adddatum((PLpgSQL_datum *) new);
  982. $$ = new->dno;
  983. }
  984. ;
  985. stmt_if : K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';'
  986. {
  987. PLpgSQL_stmt_if *new;
  988. new = palloc0(sizeof(PLpgSQL_stmt_if));
  989. new->cmd_type = PLPGSQL_STMT_IF;
  990. new->lineno = plpgsql_location_to_lineno(@1);
  991. new->cond = $2;
  992. new->then_body = $3;
  993. new->elsif_list = $4;
  994. new->else_body = $5;
  995. $$ = (PLpgSQL_stmt *)new;
  996. }
  997. ;
  998. stmt_elsifs :
  999. {
  1000. $$ = NIL;
  1001. }
  1002. | stmt_elsifs K_ELSIF expr_until_then proc_sect
  1003. {
  1004. PLpgSQL_if_elsif *new;
  1005. new = palloc0(sizeof(PLpgSQL_if_elsif));
  1006. new->lineno = plpgsql_location_to_lineno(@2);
  1007. new->cond = $3;
  1008. new->stmts = $4;
  1009. $$ = lappend($1, new);
  1010. }
  1011. ;
  1012. stmt_else :
  1013. {
  1014. $$ = NIL;
  1015. }
  1016. | K_ELSE proc_sect
  1017. {
  1018. $$ = $2;
  1019. }
  1020. ;
  1021. stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';'
  1022. {
  1023. $$ = make_case(@1, $2, $3, $4);
  1024. }
  1025. ;
  1026. opt_expr_until_when :
  1027. {
  1028. PLpgSQL_expr *expr = NULL;
  1029. int tok = yylex();
  1030. if (tok != K_WHEN)
  1031. {
  1032. plpgsql_push_back_token(tok);
  1033. expr = read_sql_expression(K_WHEN, "WHEN");
  1034. }
  1035. plpgsql_push_back_token(K_WHEN);
  1036. $$ = expr;
  1037. }
  1038. ;
  1039. case_when_list : case_when_list case_when
  1040. {
  1041. $$ = lappend($1, $2);
  1042. }
  1043. | case_when
  1044. {
  1045. $$ = list_make1($1);
  1046. }
  1047. ;
  1048. case_when : K_WHEN expr_until_then proc_sect
  1049. {
  1050. PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when));
  1051. new->lineno = plpgsql_location_to_lineno(@1);
  1052. new->expr = $2;
  1053. new->stmts = $3;
  1054. $$ = new;
  1055. }
  1056. ;
  1057. opt_case_else :
  1058. {
  1059. $$ = NIL;
  1060. }
  1061. | K_ELSE proc_sect
  1062. {
  1063. /*
  1064. * proc_sect could return an empty list, but we
  1065. * must distinguish that from not having ELSE at all.
  1066. * Simplest fix is to return a list with one NULL
  1067. * pointer, which make_case() must take care of.
  1068. */
  1069. if ($2 != NIL)
  1070. $$ = $2;
  1071. else
  1072. $$ = list_make1(NULL);
  1073. }
  1074. ;
  1075. stmt_loop : opt_block_label K_LOOP loop_body
  1076. {
  1077. PLpgSQL_stmt_loop *new;
  1078. new = palloc0(sizeof(PLpgSQL_stmt_loop));
  1079. new->cmd_type = PLPGSQL_STMT_LOOP;
  1080. new->lineno = plpgsql_location_to_lineno(@2);
  1081. new->label = $1;
  1082. new->body = $3.stmts;
  1083. check_labels($1, $3.end_label, $3.end_label_location);
  1084. plpgsql_ns_pop();
  1085. $$ = (PLpgSQL_stmt *)new;
  1086. }
  1087. ;
  1088. stmt_while : opt_block_label K_WHILE expr_until_loop loop_body
  1089. {
  1090. PLpgSQL_stmt_while *new;
  1091. new = palloc0(sizeof(PLpgSQL_stmt_while));
  1092. new->cmd_type = PLPGSQL_STMT_WHILE;
  1093. new->lineno = plpgsql_location_to_lineno(@2);
  1094. new->label = $1;
  1095. new->cond = $3;
  1096. new->body = $4.stmts;
  1097. check_labels($1, $4.end_label, $4.end_label_location);
  1098. plpgsql_ns_pop();
  1099. $$ = (PLpgSQL_stmt *)new;
  1100. }
  1101. ;
  1102. stmt_for : opt_block_label K_FOR for_control loop_body
  1103. {
  1104. /* This runs after we've scanned the loop body */
  1105. if ($3->cmd_type == PLPGSQL_STMT_FORI)
  1106. {
  1107. PLpgSQL_stmt_fori *new;
  1108. new = (PLpgSQL_stmt_fori *) $3;
  1109. new->lineno = plpgsql_location_to_lineno(@2);
  1110. new->label = $1;
  1111. new->body = $4.stmts;
  1112. $$ = (PLpgSQL_stmt *) new;
  1113. }
  1114. else
  1115. {
  1116. PLpgSQL_stmt_forq *new;
  1117. Assert($3->cmd_type == PLPGSQL_STMT_FORS ||
  1118. $3->cmd_type == PLPGSQL_STMT_FORC ||
  1119. $3->cmd_type == PLPGSQL_STMT_DYNFORS);
  1120. /* forq is the common supertype of all three */
  1121. new = (PLpgSQL_stmt_forq *) $3;
  1122. new->lineno = plpgsql_location_to_lineno(@2);
  1123. new->label = $1;
  1124. new->body = $4.stmts;
  1125. $$ = (PLpgSQL_stmt *) new;
  1126. }
  1127. check_labels($1, $4.end_label, $4.end_label_location);
  1128. /* close namespace started in opt_block_label */
  1129. plpgsql_ns_pop();
  1130. }
  1131. ;
  1132. for_control : for_variable K_IN
  1133. {
  1134. int tok = yylex();
  1135. int tokloc = yylloc;
  1136. if (tok == K_EXECUTE)
  1137. {
  1138. /* EXECUTE means it's a dynamic FOR loop */
  1139. PLpgSQL_stmt_dynfors *new;
  1140. PLpgSQL_expr *expr;
  1141. int term;
  1142. expr = read_sql_expression2(K_LOOP, K_USING,
  1143. "LOOP or USING",
  1144. &term);
  1145. new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
  1146. new->cmd_type = PLPGSQL_STMT_DYNFORS;
  1147. if ($1.rec)
  1148. {
  1149. new->rec = $1.rec;
  1150. check_assignable((PLpgSQL_datum *) new->rec, @1);
  1151. }
  1152. else if ($1.row)
  1153. {
  1154. new->row = $1.row;
  1155. check_assignable((PLpgSQL_datum *) new->row, @1);
  1156. }
  1157. else if ($1.scalar)
  1158. {
  1159. /* convert single scalar to list */
  1160. new->row = make_scalar_list1($1.name, $1.scalar,
  1161. $1.lineno, @1);
  1162. /* no need for check_assignable */
  1163. }
  1164. else
  1165. {
  1166. ereport(ERROR,
  1167. (errcode(ERRCODE_DATATYPE_MISMATCH),
  1168. errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
  1169. parser_errposition(@1)));
  1170. }
  1171. new->query = expr;
  1172. if (term == K_USING)
  1173. {
  1174. do
  1175. {
  1176. expr = read_sql_expression2(',', K_LOOP,
  1177. ", or LOOP",
  1178. &term);
  1179. new->params = lappend(new->params, expr);
  1180. } while (term == ',');
  1181. }
  1182. $$ = (PLpgSQL_stmt *) new;
  1183. }
  1184. else if (tok == T_DATUM &&
  1185. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR &&
  1186. ((PLpgSQL_var *) yylval.wdatum.datum)->datatype->typoid == REFCURSOROID)
  1187. {
  1188. /* It's FOR var IN cursor */
  1189. PLpgSQL_stmt_forc *new;
  1190. PLpgSQL_var *cursor = (PLpgSQL_var *) yylval.wdatum.datum;
  1191. new = (PLpgSQL_stmt_forc *) palloc0(sizeof(PLpgSQL_stmt_forc));
  1192. new->cmd_type = PLPGSQL_STMT_FORC;
  1193. new->curvar = cursor->dno;
  1194. /* Should have had a single variable name */
  1195. if ($1.scalar && $1.row)
  1196. ereport(ERROR,
  1197. (errcode(ERRCODE_SYNTAX_ERROR),
  1198. errmsg("cursor FOR loop must have only one target variable"),
  1199. parser_errposition(@1)));
  1200. /* can't use an unbound cursor this way */
  1201. if (cursor->cursor_explicit_expr == NULL)
  1202. ereport(ERROR,
  1203. (errcode(ERRCODE_SYNTAX_ERROR),
  1204. errmsg("cursor FOR loop must use a bound cursor variable"),
  1205. parser_errposition(tokloc)));
  1206. /* collect cursor's parameters if any */
  1207. new->argquery = read_cursor_args(cursor,
  1208. K_LOOP,
  1209. "LOOP");
  1210. /* create loop's private RECORD variable */
  1211. new->rec = plpgsql_build_record($1.name,
  1212. $1.lineno,
  1213. true);
  1214. $$ = (PLpgSQL_stmt *) new;
  1215. }
  1216. else
  1217. {
  1218. PLpgSQL_expr *expr1;
  1219. int expr1loc;
  1220. bool reverse = false;
  1221. /*
  1222. * We have to distinguish between two
  1223. * alternatives: FOR var IN a .. b and FOR
  1224. * var IN query. Unfortunately this is
  1225. * tricky, since the query in the second
  1226. * form needn't start with a SELECT
  1227. * keyword. We use the ugly hack of
  1228. * looking for two periods after the first
  1229. * token. We also check for the REVERSE
  1230. * keyword, which means it must be an
  1231. * integer loop.
  1232. */
  1233. if (tok_is_keyword(tok, &yylval,
  1234. K_REVERSE, "reverse"))
  1235. reverse = true;
  1236. else
  1237. plpgsql_push_back_token(tok);
  1238. /*
  1239. * Read tokens until we see either a ".."
  1240. * or a LOOP. The text we read may not
  1241. * necessarily be a well-formed SQL
  1242. * statement, so we need to invoke
  1243. * read_sql_construct directly.
  1244. */
  1245. expr1 = read_sql_construct(DOT_DOT,
  1246. K_LOOP,
  1247. 0,
  1248. "LOOP",
  1249. "SELECT ",
  1250. true,
  1251. false,
  1252. true,
  1253. &expr1loc,
  1254. &tok);
  1255. if (tok == DOT_DOT)
  1256. {
  1257. /* Saw "..", so it must be an integer loop */
  1258. PLpgSQL_expr *expr2;
  1259. PLpgSQL_expr *expr_by;
  1260. PLpgSQL_var *fvar;
  1261. PLpgSQL_stmt_fori *new;
  1262. /* Check first expression is well-formed */
  1263. check_sql_expr(expr1->query, expr1loc, 7);
  1264. /* Read and check the second one */
  1265. expr2 = read_sql_expression2(K_LOOP, K_BY,
  1266. "LOOP",
  1267. &tok);
  1268. /* Get the BY clause if any */
  1269. if (tok == K_BY)
  1270. expr_by = read_sql_expression(K_LOOP,
  1271. "LOOP");
  1272. else
  1273. expr_by = NULL;
  1274. /* Should have had a single variable name */
  1275. if ($1.scalar && $1.row)
  1276. ereport(ERROR,
  1277. (errcode(ERRCODE_SYNTAX_ERROR),
  1278. errmsg("integer FOR loop must have only one target variable"),
  1279. parser_errposition(@1)));
  1280. /* create loop's private variable */
  1281. fvar = (PLpgSQL_var *)
  1282. plpgsql_build_variable($1.name,
  1283. $1.lineno,
  1284. plpgsql_build_datatype(INT4OID,
  1285. -1,
  1286. InvalidOid),
  1287. true);
  1288. new = palloc0(sizeof(PLpgSQL_stmt_fori));
  1289. new->cmd_type = PLPGSQL_STMT_FORI;
  1290. new->var = fvar;
  1291. new->reverse = reverse;
  1292. new->lower = expr1;
  1293. new->upper = expr2;
  1294. new->step = expr_by;
  1295. $$ = (PLpgSQL_stmt *) new;
  1296. }
  1297. else
  1298. {
  1299. /*
  1300. * No "..", so it must be a query loop. We've
  1301. * prefixed an extra SELECT to the query text,
  1302. * so we need to remove that before performing
  1303. * syntax checking.
  1304. */
  1305. char *tmp_query;
  1306. PLpgSQL_stmt_fors *new;
  1307. if (reverse)
  1308. ereport(ERROR,
  1309. (errcode(ERRCODE_SYNTAX_ERROR),
  1310. errmsg("cannot specify REVERSE in query FOR loop"),
  1311. parser_errposition(tokloc)));
  1312. Assert(strncmp(expr1->query, "SELECT ", 7) == 0);
  1313. tmp_query = pstrdup(expr1->query + 7);
  1314. pfree(expr1->query);
  1315. expr1->query = tmp_query;
  1316. check_sql_expr(expr1->query, expr1loc, 0);
  1317. new = palloc0(sizeof(PLpgSQL_stmt_fors));
  1318. new->cmd_type = PLPGSQL_STMT_FORS;
  1319. if ($1.rec)
  1320. {
  1321. new->rec = $1.rec;
  1322. check_assignable((PLpgSQL_datum *) new->rec, @1);
  1323. }
  1324. else if ($1.row)
  1325. {
  1326. new->row = $1.row;
  1327. check_assignable((PLpgSQL_datum *) new->row, @1);
  1328. }
  1329. else if ($1.scalar)
  1330. {
  1331. /* convert single scalar to list */
  1332. new->row = make_scalar_list1($1.name, $1.scalar,
  1333. $1.lineno, @1);
  1334. /* no need for check_assignable */
  1335. }
  1336. else
  1337. {
  1338. ereport(ERROR,
  1339. (errcode(ERRCODE_SYNTAX_ERROR),
  1340. errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
  1341. parser_errposition(@1)));
  1342. }
  1343. new->query = expr1;
  1344. $$ = (PLpgSQL_stmt *) new;
  1345. }
  1346. }
  1347. }
  1348. ;
  1349. /*
  1350. * Processing the for_variable is tricky because we don't yet know if the
  1351. * FOR is an integer FOR loop or a loop over query results. In the former
  1352. * case, the variable is just a name that we must instantiate as a loop
  1353. * local variable, regardless of any other definition it might have.
  1354. * Therefore, we always save the actual identifier into $$.name where it
  1355. * can be used for that case. We also save the outer-variable definition,
  1356. * if any, because that's what we need for the loop-over-query case. Note
  1357. * that we must NOT apply check_assignable() or any other semantic check
  1358. * until we know what's what.
  1359. *
  1360. * However, if we see a comma-separated list of names, we know that it
  1361. * can't be an integer FOR loop and so it's OK to check the variables
  1362. * immediately. In particular, for T_WORD followed by comma, we should
  1363. * complain that the name is not known rather than say it's a syntax error.
  1364. * Note that the non-error result of this case sets *both* $$.scalar and
  1365. * $$.row; see the for_control production.
  1366. */
  1367. for_variable : T_DATUM
  1368. {
  1369. $$.name = NameOfDatum(&($1));
  1370. $$.lineno = plpgsql_location_to_lineno(@1);
  1371. if ($1.datum->dtype == PLPGSQL_DTYPE_ROW)
  1372. {
  1373. $$.scalar = NULL;
  1374. $$.rec = NULL;
  1375. $$.row = (PLpgSQL_row *) $1.datum;
  1376. }
  1377. else if ($1.datum->dtype == PLPGSQL_DTYPE_REC)
  1378. {
  1379. $$.scalar = NULL;
  1380. $$.rec = (PLpgSQL_rec *) $1.datum;
  1381. $$.row = NULL;
  1382. }
  1383. else
  1384. {
  1385. int tok;
  1386. $$.scalar = $1.datum;
  1387. $$.rec = NULL;
  1388. $$.row = NULL;
  1389. /* check for comma-separated list */
  1390. tok = yylex();
  1391. plpgsql_push_back_token(tok);
  1392. if (tok == ',')
  1393. $$.row = read_into_scalar_list($$.name,
  1394. $$.scalar,
  1395. @1);
  1396. }
  1397. }
  1398. | T_WORD
  1399. {
  1400. int tok;
  1401. $$.name = $1.ident;
  1402. $$.lineno = plpgsql_location_to_lineno(@1);
  1403. $$.scalar = NULL;
  1404. $$.rec = NULL;
  1405. $$.row = NULL;
  1406. /* check for comma-separated list */
  1407. tok = yylex();
  1408. plpgsql_push_back_token(tok);
  1409. if (tok == ',')
  1410. word_is_not_variable(&($1), @1);
  1411. }
  1412. | T_CWORD
  1413. {
  1414. /* just to give a better message than "syntax error" */
  1415. cword_is_not_variable(&($1), @1);
  1416. }
  1417. ;
  1418. stmt_foreach_a : opt_block_label K_FOREACH for_variable foreach_slice K_IN K_ARRAY expr_until_loop loop_body
  1419. {
  1420. PLpgSQL_stmt_foreach_a *new;
  1421. new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
  1422. new->cmd_type = PLPGSQL_STMT_FOREACH_A;
  1423. new->lineno = plpgsql_location_to_lineno(@2);
  1424. new->label = $1;
  1425. new->slice = $4;
  1426. new->expr = $7;
  1427. new->body = $8.stmts;
  1428. if ($3.rec)
  1429. {
  1430. new->varno = $3.rec->dno;
  1431. check_assignable((PLpgSQL_datum *) $3.rec, @3);
  1432. }
  1433. else if ($3.row)
  1434. {
  1435. new->varno = $3.row->dno;
  1436. check_assignable((PLpgSQL_datum *) $3.row, @3);
  1437. }
  1438. else if ($3.scalar)
  1439. {
  1440. new->varno = $3.scalar->dno;
  1441. check_assignable($3.scalar, @3);
  1442. }
  1443. else
  1444. {
  1445. ereport(ERROR,
  1446. (errcode(ERRCODE_SYNTAX_ERROR),
  1447. errmsg("loop variable of FOREACH must be a known variable or list of variables"),
  1448. parser_errposition(@3)));
  1449. }
  1450. check_labels($1, $8.end_label, $8.end_label_location);
  1451. plpgsql_ns_pop();
  1452. $$ = (PLpgSQL_stmt *) new;
  1453. }
  1454. ;
  1455. foreach_slice :
  1456. {
  1457. $$ = 0;
  1458. }
  1459. | K_SLICE ICONST
  1460. {
  1461. $$ = $2;
  1462. }
  1463. ;
  1464. stmt_exit : exit_type opt_label opt_exitcond
  1465. {
  1466. PLpgSQL_stmt_exit *new;
  1467. new = palloc0(sizeof(PLpgSQL_stmt_exit));
  1468. new->cmd_type = PLPGSQL_STMT_EXIT;
  1469. new->is_exit = $1;
  1470. new->lineno = plpgsql_location_to_lineno(@1);
  1471. new->label = $2;
  1472. new->cond = $3;
  1473. $$ = (PLpgSQL_stmt *)new;
  1474. }
  1475. ;
  1476. exit_type : K_EXIT
  1477. {
  1478. $$ = true;
  1479. }
  1480. | K_CONTINUE
  1481. {
  1482. $$ = false;
  1483. }
  1484. ;
  1485. stmt_return : K_RETURN
  1486. {
  1487. int tok;
  1488. tok = yylex();
  1489. if (tok == 0)
  1490. yyerror("unexpected end of function definition");
  1491. if (tok_is_keyword(tok, &yylval,
  1492. K_NEXT, "next"))
  1493. {
  1494. $$ = make_return_next_stmt(@1);
  1495. }
  1496. else if (tok_is_keyword(tok, &yylval,
  1497. K_QUERY, "query"))
  1498. {
  1499. $$ = make_return_query_stmt(@1);
  1500. }
  1501. else
  1502. {
  1503. plpgsql_push_back_token(tok);
  1504. $$ = make_return_stmt(@1);
  1505. }
  1506. }
  1507. ;
  1508. stmt_raise : K_RAISE
  1509. {
  1510. PLpgSQL_stmt_raise *new;
  1511. int tok;
  1512. new = palloc(sizeof(PLpgSQL_stmt_raise));
  1513. new->cmd_type = PLPGSQL_STMT_RAISE;
  1514. new->lineno = plpgsql_location_to_lineno(@1);
  1515. new->elog_level = ERROR; /* default */
  1516. new->condname = NULL;
  1517. new->message = NULL;
  1518. new->params = NIL;
  1519. new->options = NIL;
  1520. tok = yylex();
  1521. if (tok == 0)
  1522. yyerror("unexpected end of function definition");
  1523. /*
  1524. * We could have just RAISE, meaning to re-throw
  1525. * the current error.
  1526. */
  1527. if (tok != ';')
  1528. {
  1529. /*
  1530. * First is an optional elog severity level.
  1531. */
  1532. if (tok_is_keyword(tok, &yylval,
  1533. K_EXCEPTION, "exception"))
  1534. {
  1535. new->elog_level = ERROR;
  1536. tok = yylex();
  1537. }
  1538. else if (tok_is_keyword(tok, &yylval,
  1539. K_WARNING, "warning"))
  1540. {
  1541. new->elog_level = WARNING;
  1542. tok = yylex();
  1543. }
  1544. else if (tok_is_keyword(tok, &yylval,
  1545. K_NOTICE, "notice"))
  1546. {
  1547. new->elog_level = NOTICE;
  1548. tok = yylex();
  1549. }
  1550. else if (tok_is_keyword(tok, &yylval,
  1551. K_INFO, "info"))
  1552. {
  1553. new->elog_level = INFO;
  1554. tok = yylex();
  1555. }
  1556. else if (tok_is_keyword(tok, &yylval,
  1557. K_LOG, "log"))
  1558. {
  1559. new->elog_level = LOG;
  1560. tok = yylex();
  1561. }
  1562. else if (tok_is_keyword(tok, &yylval,
  1563. K_DEBUG, "debug"))
  1564. {
  1565. new->elog_level = DEBUG1;
  1566. tok = yylex();
  1567. }
  1568. if (tok == 0)
  1569. yyerror("unexpected end of function definition");
  1570. /*
  1571. * Next we can have a condition name, or
  1572. * equivalently SQLSTATE 'xxxxx', or a string
  1573. * literal that is the old-style message format,
  1574. * or USING to start the option list immediately.
  1575. */
  1576. if (tok == SCONST)
  1577. {
  1578. /* old style message and parameters */
  1579. new->message = yylval.str;
  1580. /*
  1581. * We expect either a semi-colon, which
  1582. * indicates no parameters, or a comma that
  1583. * begins the list of parameter expressions,
  1584. * or USING to begin the options list.
  1585. */
  1586. tok = yylex();
  1587. if (tok != ',' && tok != ';' && tok != K_USING)
  1588. yyerror("syntax error");
  1589. while (tok == ',')
  1590. {
  1591. PLpgSQL_expr *expr;
  1592. expr = read_sql_construct(',', ';', K_USING,
  1593. ", or ; or USING",
  1594. "SELECT ",
  1595. true, true, true,
  1596. NULL, &tok);
  1597. new->params = lappend(new->params, expr);
  1598. }
  1599. }
  1600. else if (tok != K_USING)
  1601. {
  1602. /* must be condition name or SQLSTATE */
  1603. if (tok_is_keyword(tok, &yylval,
  1604. K_SQLSTATE, "sqlstate"))
  1605. {
  1606. /* next token should be a string literal */
  1607. char *sqlstatestr;
  1608. if (yylex() != SCONST)
  1609. yyerror("syntax error");
  1610. sqlstatestr = yylval.str;
  1611. if (strlen(sqlstatestr) != 5)
  1612. yyerror("invalid SQLSTATE code");
  1613. if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
  1614. yyerror("invalid SQLSTATE code");
  1615. new->condname = sqlstatestr;
  1616. }
  1617. else
  1618. {
  1619. if (tok == T_WORD)
  1620. new->condname = yylval.word.ident;
  1621. else if (plpgsql_token_is_unreserved_keyword(tok))
  1622. new->condname = pstrdup(yylval.keyword);
  1623. else
  1624. yyerror("syntax error");
  1625. plpgsql_recognize_err_condition(new->condname,
  1626. false);
  1627. }
  1628. tok = yylex();
  1629. if (tok != ';' && tok != K_USING)
  1630. yyerror("syntax error");
  1631. }
  1632. if (tok == K_USING)
  1633. new->options = read_raise_options();
  1634. }
  1635. $$ = (PLpgSQL_stmt *)new;
  1636. }
  1637. ;
  1638. loop_body : proc_sect K_END K_LOOP opt_label ';'
  1639. {
  1640. $$.stmts = $1;
  1641. $$.end_label = $4;
  1642. $$.end_label_location = @4;
  1643. }
  1644. ;
  1645. /*
  1646. * T_WORD+T_CWORD match any initial identifier that is not a known plpgsql
  1647. * variable. (The composite case is probably a syntax error, but we'll let
  1648. * the core parser decide that.) Normally, we should assume that such a
  1649. * word is a SQL statement keyword that isn't also a plpgsql keyword.
  1650. * However, if the next token is assignment or '[', it can't be a valid
  1651. * SQL statement, and what we're probably looking at is an intended variable
  1652. * assignment. Give an appropriate complaint for that, instead of letting
  1653. * the core parser throw an unhelpful "syntax error".
  1654. */
  1655. stmt_execsql : K_INSERT
  1656. {
  1657. $$ = make_execsql_stmt(K_INSERT, @1);
  1658. }
  1659. | T_WORD
  1660. {
  1661. int tok;
  1662. tok = yylex();
  1663. plpgsql_push_back_token(tok);
  1664. if (tok == '=' || tok == COLON_EQUALS || tok == '[')
  1665. word_is_not_variable(&($1), @1);
  1666. $$ = make_execsql_stmt(T_WORD, @1);
  1667. }
  1668. | T_CWORD
  1669. {
  1670. int tok;
  1671. tok = yylex();
  1672. plpgsql_push_back_token(tok);
  1673. if (tok == '=' || tok == COLON_EQUALS || tok == '[')
  1674. cword_is_not_variable(&($1), @1);
  1675. $$ = make_execsql_stmt(T_CWORD, @1);
  1676. }
  1677. ;
  1678. stmt_dynexecute : K_EXECUTE
  1679. {
  1680. PLpgSQL_stmt_dynexecute *new;
  1681. PLpgSQL_expr *expr;
  1682. int endtoken;
  1683. expr = read_sql_construct(K_INTO, K_USING, ';',
  1684. "INTO or USING or ;",
  1685. "SELECT ",
  1686. true, true, true,
  1687. NULL, &endtoken);
  1688. new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
  1689. new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
  1690. new->lineno = plpgsql_location_to_lineno(@1);
  1691. new->query = expr;
  1692. new->into = false;
  1693. new->strict = false;
  1694. new->rec = NULL;
  1695. new->row = NULL;
  1696. new->params

Large files files are truncated, but you can click here to view the full file