PageRenderTime 66ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  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 = NIL;
  1697. /*
  1698. * We loop to allow the INTO and USING clauses to
  1699. * appear in either order, since people easily get
  1700. * that wrong. This coding also prevents "INTO foo"
  1701. * from getting absorbed into a USING expression,
  1702. * which is *really* confusing.
  1703. */
  1704. for (;;)
  1705. {
  1706. if (endtoken == K_INTO)
  1707. {
  1708. if (new->into) /* multiple INTO */
  1709. yyerror("syntax error");
  1710. new->into = true;
  1711. read_into_target(&new->rec, &new->row, &new->strict);
  1712. endtoken = yylex();
  1713. }
  1714. else if (endtoken == K_USING)
  1715. {
  1716. if (new->params) /* multiple USING */
  1717. yyerror("syntax error");
  1718. do
  1719. {
  1720. expr = read_sql_construct(',', ';', K_INTO,
  1721. ", or ; or INTO",
  1722. "SELECT ",
  1723. true, true, true,
  1724. NULL, &endtoken);
  1725. new->params = lappend(new->params, expr);
  1726. } while (endtoken == ',');
  1727. }
  1728. else if (endtoken == ';')
  1729. break;
  1730. else
  1731. yyerror("syntax error");
  1732. }
  1733. $$ = (PLpgSQL_stmt *)new;
  1734. }
  1735. ;
  1736. stmt_open : K_OPEN cursor_variable
  1737. {
  1738. PLpgSQL_stmt_open *new;
  1739. int tok;
  1740. new = palloc0(sizeof(PLpgSQL_stmt_open));
  1741. new->cmd_type = PLPGSQL_STMT_OPEN;
  1742. new->lineno = plpgsql_location_to_lineno(@1);
  1743. new->curvar = $2->dno;
  1744. new->cursor_options = CURSOR_OPT_FAST_PLAN;
  1745. if ($2->cursor_explicit_expr == NULL)
  1746. {
  1747. /* be nice if we could use opt_scrollable here */
  1748. tok = yylex();
  1749. if (tok_is_keyword(tok, &yylval,
  1750. K_NO, "no"))
  1751. {
  1752. tok = yylex();
  1753. if (tok_is_keyword(tok, &yylval,
  1754. K_SCROLL, "scroll"))
  1755. {
  1756. new->cursor_options |= CURSOR_OPT_NO_SCROLL;
  1757. tok = yylex();
  1758. }
  1759. }
  1760. else if (tok_is_keyword(tok, &yylval,
  1761. K_SCROLL, "scroll"))
  1762. {
  1763. new->cursor_options |= CURSOR_OPT_SCROLL;
  1764. tok = yylex();
  1765. }
  1766. if (tok != K_FOR)
  1767. yyerror("syntax error, expected \"FOR\"");
  1768. tok = yylex();
  1769. if (tok == K_EXECUTE)
  1770. {
  1771. int endtoken;
  1772. new->dynquery =
  1773. read_sql_expression2(K_USING, ';',
  1774. "USING or ;",
  1775. &endtoken);
  1776. /* If we found "USING", collect argument(s) */
  1777. if (endtoken == K_USING)
  1778. {
  1779. PLpgSQL_expr *expr;
  1780. do
  1781. {
  1782. expr = read_sql_expression2(',', ';',
  1783. ", or ;",
  1784. &endtoken);
  1785. new->params = lappend(new->params,
  1786. expr);
  1787. } while (endtoken == ',');
  1788. }
  1789. }
  1790. else
  1791. {
  1792. plpgsql_push_back_token(tok);
  1793. new->query = read_sql_stmt("");
  1794. }
  1795. }
  1796. else
  1797. {
  1798. /* predefined cursor query, so read args */
  1799. new->argquery = read_cursor_args($2, ';', ";");
  1800. }
  1801. $$ = (PLpgSQL_stmt *)new;
  1802. }
  1803. ;
  1804. stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO
  1805. {
  1806. PLpgSQL_stmt_fetch *fetch = $2;
  1807. PLpgSQL_rec *rec;
  1808. PLpgSQL_row *row;
  1809. /* We have already parsed everything through the INTO keyword */
  1810. read_into_target(&rec, &row, NULL);
  1811. if (yylex() != ';')
  1812. yyerror("syntax error");
  1813. /*
  1814. * We don't allow multiple rows in PL/pgSQL's FETCH
  1815. * statement, only in MOVE.
  1816. */
  1817. if (fetch->returns_multiple_rows)
  1818. ereport(ERROR,
  1819. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  1820. errmsg("FETCH statement cannot return multiple rows"),
  1821. parser_errposition(@1)));
  1822. fetch->lineno = plpgsql_location_to_lineno(@1);
  1823. fetch->rec = rec;
  1824. fetch->row = row;
  1825. fetch->curvar = $3->dno;
  1826. fetch->is_move = false;
  1827. $$ = (PLpgSQL_stmt *)fetch;
  1828. }
  1829. ;
  1830. stmt_move : K_MOVE opt_fetch_direction cursor_variable ';'
  1831. {
  1832. PLpgSQL_stmt_fetch *fetch = $2;
  1833. fetch->lineno = plpgsql_location_to_lineno(@1);
  1834. fetch->curvar = $3->dno;
  1835. fetch->is_move = true;
  1836. $$ = (PLpgSQL_stmt *)fetch;
  1837. }
  1838. ;
  1839. opt_fetch_direction :
  1840. {
  1841. $$ = read_fetch_direction();
  1842. }
  1843. ;
  1844. stmt_close : K_CLOSE cursor_variable ';'
  1845. {
  1846. PLpgSQL_stmt_close *new;
  1847. new = palloc(sizeof(PLpgSQL_stmt_close));
  1848. new->cmd_type = PLPGSQL_STMT_CLOSE;
  1849. new->lineno = plpgsql_location_to_lineno(@1);
  1850. new->curvar = $2->dno;
  1851. $$ = (PLpgSQL_stmt *)new;
  1852. }
  1853. ;
  1854. stmt_null : K_NULL ';'
  1855. {
  1856. /* We do not bother building a node for NULL */
  1857. $$ = NULL;
  1858. }
  1859. ;
  1860. cursor_variable : T_DATUM
  1861. {
  1862. if ($1.datum->dtype != PLPGSQL_DTYPE_VAR)
  1863. ereport(ERROR,
  1864. (errcode(ERRCODE_DATATYPE_MISMATCH),
  1865. errmsg("cursor variable must be a simple variable"),
  1866. parser_errposition(@1)));
  1867. if (((PLpgSQL_var *) $1.datum)->datatype->typoid != REFCURSOROID)
  1868. ereport(ERROR,
  1869. (errcode(ERRCODE_DATATYPE_MISMATCH),
  1870. errmsg("variable \"%s\" must be of type cursor or refcursor",
  1871. ((PLpgSQL_var *) $1.datum)->refname),
  1872. parser_errposition(@1)));
  1873. $$ = (PLpgSQL_var *) $1.datum;
  1874. }
  1875. | T_WORD
  1876. {
  1877. /* just to give a better message than "syntax error" */
  1878. word_is_not_variable(&($1), @1);
  1879. }
  1880. | T_CWORD
  1881. {
  1882. /* just to give a better message than "syntax error" */
  1883. cword_is_not_variable(&($1), @1);
  1884. }
  1885. ;
  1886. exception_sect :
  1887. { $$ = NULL; }
  1888. | K_EXCEPTION
  1889. {
  1890. /*
  1891. * We use a mid-rule action to add these
  1892. * special variables to the namespace before
  1893. * parsing the WHEN clauses themselves. The
  1894. * scope of the names extends to the end of the
  1895. * current block.
  1896. */
  1897. int lineno = plpgsql_location_to_lineno(@1);
  1898. PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block));
  1899. PLpgSQL_variable *var;
  1900. var = plpgsql_build_variable("sqlstate", lineno,
  1901. plpgsql_build_datatype(TEXTOID,
  1902. -1,
  1903. plpgsql_curr_compile->fn_input_collation),
  1904. true);
  1905. ((PLpgSQL_var *) var)->isconst = true;
  1906. new->sqlstate_varno = var->dno;
  1907. var = plpgsql_build_variable("sqlerrm", lineno,
  1908. plpgsql_build_datatype(TEXTOID,
  1909. -1,
  1910. plpgsql_curr_compile->fn_input_collation),
  1911. true);
  1912. ((PLpgSQL_var *) var)->isconst = true;
  1913. new->sqlerrm_varno = var->dno;
  1914. $<exception_block>$ = new;
  1915. }
  1916. proc_exceptions
  1917. {
  1918. PLpgSQL_exception_block *new = $<exception_block>2;
  1919. new->exc_list = $3;
  1920. $$ = new;
  1921. }
  1922. ;
  1923. proc_exceptions : proc_exceptions proc_exception
  1924. {
  1925. $$ = lappend($1, $2);
  1926. }
  1927. | proc_exception
  1928. {
  1929. $$ = list_make1($1);
  1930. }
  1931. ;
  1932. proc_exception : K_WHEN proc_conditions K_THEN proc_sect
  1933. {
  1934. PLpgSQL_exception *new;
  1935. new = palloc0(sizeof(PLpgSQL_exception));
  1936. new->lineno = plpgsql_location_to_lineno(@1);
  1937. new->conditions = $2;
  1938. new->action = $4;
  1939. $$ = new;
  1940. }
  1941. ;
  1942. proc_conditions : proc_conditions K_OR proc_condition
  1943. {
  1944. PLpgSQL_condition *old;
  1945. for (old = $1; old->next != NULL; old = old->next)
  1946. /* skip */ ;
  1947. old->next = $3;
  1948. $$ = $1;
  1949. }
  1950. | proc_condition
  1951. {
  1952. $$ = $1;
  1953. }
  1954. ;
  1955. proc_condition : any_identifier
  1956. {
  1957. if (strcmp($1, "sqlstate") != 0)
  1958. {
  1959. $$ = plpgsql_parse_err_condition($1);
  1960. }
  1961. else
  1962. {
  1963. PLpgSQL_condition *new;
  1964. char *sqlstatestr;
  1965. /* next token should be a string literal */
  1966. if (yylex() != SCONST)
  1967. yyerror("syntax error");
  1968. sqlstatestr = yylval.str;
  1969. if (strlen(sqlstatestr) != 5)
  1970. yyerror("invalid SQLSTATE code");
  1971. if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
  1972. yyerror("invalid SQLSTATE code");
  1973. new = palloc(sizeof(PLpgSQL_condition));
  1974. new->sqlerrstate =
  1975. MAKE_SQLSTATE(sqlstatestr[0],
  1976. sqlstatestr[1],
  1977. sqlstatestr[2],
  1978. sqlstatestr[3],
  1979. sqlstatestr[4]);
  1980. new->condname = sqlstatestr;
  1981. new->next = NULL;
  1982. $$ = new;
  1983. }
  1984. }
  1985. ;
  1986. expr_until_semi :
  1987. { $$ = read_sql_expression(';', ";"); }
  1988. ;
  1989. expr_until_rightbracket :
  1990. { $$ = read_sql_expression(']', "]"); }
  1991. ;
  1992. expr_until_then :
  1993. { $$ = read_sql_expression(K_THEN, "THEN"); }
  1994. ;
  1995. expr_until_loop :
  1996. { $$ = read_sql_expression(K_LOOP, "LOOP"); }
  1997. ;
  1998. opt_block_label :
  1999. {
  2000. plpgsql_ns_push(NULL);
  2001. $$ = NULL;
  2002. }
  2003. | LESS_LESS any_identifier GREATER_GREATER
  2004. {
  2005. plpgsql_ns_push($2);
  2006. $$ = $2;
  2007. }
  2008. ;
  2009. opt_label :
  2010. {
  2011. $$ = NULL;
  2012. }
  2013. | any_identifier
  2014. {
  2015. if (plpgsql_ns_lookup_label(plpgsql_ns_top(), $1) == NULL)
  2016. yyerror("label does not exist");
  2017. $$ = $1;
  2018. }
  2019. ;
  2020. opt_exitcond : ';'
  2021. { $$ = NULL; }
  2022. | K_WHEN expr_until_semi
  2023. { $$ = $2; }
  2024. ;
  2025. /*
  2026. * need to allow DATUM because scanner will have tried to resolve as variable
  2027. */
  2028. any_identifier : T_WORD
  2029. {
  2030. $$ = $1.ident;
  2031. }
  2032. | unreserved_keyword
  2033. {
  2034. $$ = pstrdup($1);
  2035. }
  2036. | T_DATUM
  2037. {
  2038. if ($1.ident == NULL) /* composite name not OK */
  2039. yyerror("syntax error");
  2040. $$ = $1.ident;
  2041. }
  2042. ;
  2043. unreserved_keyword :
  2044. K_ABSOLUTE
  2045. | K_ALIAS
  2046. | K_ARRAY
  2047. | K_BACKWARD
  2048. | K_COLUMN
  2049. | K_COLUMN_NAME
  2050. | K_CONSTANT
  2051. | K_CONSTRAINT
  2052. | K_CONSTRAINT_NAME
  2053. | K_CURRENT
  2054. | K_CURSOR
  2055. | K_DATATYPE
  2056. | K_DEBUG
  2057. | K_DETAIL
  2058. | K_DUMP
  2059. | K_ERRCODE
  2060. | K_ERROR
  2061. | K_FIRST
  2062. | K_FORWARD
  2063. | K_HINT
  2064. | K_INFO
  2065. | K_IS
  2066. | K_LAST
  2067. | K_LOG
  2068. | K_MESSAGE
  2069. | K_MESSAGE_TEXT
  2070. | K_NEXT
  2071. | K_NO
  2072. | K_NOTICE
  2073. | K_OPTION
  2074. | K_PG_CONTEXT
  2075. | K_PG_DATATYPE_NAME
  2076. | K_PG_EXCEPTION_CONTEXT
  2077. | K_PG_EXCEPTION_DETAIL
  2078. | K_PG_EXCEPTION_HINT
  2079. | K_PRIOR
  2080. | K_PRINT_STRICT_PARAMS
  2081. | K_QUERY
  2082. | K_RELATIVE
  2083. | K_RESULT_OID
  2084. | K_RETURNED_SQLSTATE
  2085. | K_REVERSE
  2086. | K_ROW_COUNT
  2087. | K_ROWTYPE
  2088. | K_SCHEMA
  2089. | K_SCHEMA_NAME
  2090. | K_SCROLL
  2091. | K_SLICE
  2092. | K_SQLSTATE
  2093. | K_STACKED
  2094. | K_TABLE
  2095. | K_TABLE_NAME
  2096. | K_TYPE
  2097. | K_USE_COLUMN
  2098. | K_USE_VARIABLE
  2099. | K_VARIABLE_CONFLICT
  2100. | K_WARNING
  2101. ;
  2102. %%
  2103. /*
  2104. * Check whether a token represents an "unreserved keyword".
  2105. * We have various places where we want to recognize a keyword in preference
  2106. * to a variable name, but not reserve that keyword in other contexts.
  2107. * Hence, this kluge.
  2108. */
  2109. static bool
  2110. tok_is_keyword(int token, union YYSTYPE *lval,
  2111. int kw_token, const char *kw_str)
  2112. {
  2113. if (token == kw_token)
  2114. {
  2115. /* Normal case, was recognized by scanner (no conflicting variable) */
  2116. return true;
  2117. }
  2118. else if (token == T_DATUM)
  2119. {
  2120. /*
  2121. * It's a variable, so recheck the string name. Note we will not
  2122. * match composite names (hence an unreserved word followed by "."
  2123. * will not be recognized).
  2124. */
  2125. if (!lval->wdatum.quoted && lval->wdatum.ident != NULL &&
  2126. strcmp(lval->wdatum.ident, kw_str) == 0)
  2127. return true;
  2128. }
  2129. return false; /* not the keyword */
  2130. }
  2131. /*
  2132. * Convenience routine to complain when we expected T_DATUM and got T_WORD,
  2133. * ie, unrecognized variable.
  2134. */
  2135. static void
  2136. word_is_not_variable(PLword *word, int location)
  2137. {
  2138. ereport(ERROR,
  2139. (errcode(ERRCODE_SYNTAX_ERROR),
  2140. errmsg("\"%s\" is not a known variable",
  2141. word->ident),
  2142. parser_errposition(location)));
  2143. }
  2144. /* Same, for a CWORD */
  2145. static void
  2146. cword_is_not_variable(PLcword *cword, int location)
  2147. {
  2148. ereport(ERROR,
  2149. (errcode(ERRCODE_SYNTAX_ERROR),
  2150. errmsg("\"%s\" is not a known variable",
  2151. NameListToString(cword->idents)),
  2152. parser_errposition(location)));
  2153. }
  2154. /*
  2155. * Convenience routine to complain when we expected T_DATUM and got
  2156. * something else. "tok" must be the current token, since we also
  2157. * look at yylval and yylloc.
  2158. */
  2159. static void
  2160. current_token_is_not_variable(int tok)
  2161. {
  2162. if (tok == T_WORD)
  2163. word_is_not_variable(&(yylval.word), yylloc);
  2164. else if (tok == T_CWORD)
  2165. cword_is_not_variable(&(yylval.cword), yylloc);
  2166. else
  2167. yyerror("syntax error");
  2168. }
  2169. /* Convenience routine to read an expression with one possible terminator */
  2170. static PLpgSQL_expr *
  2171. read_sql_expression(int until, const char *expected)
  2172. {
  2173. return read_sql_construct(until, 0, 0, expected,
  2174. "SELECT ", true, true, true, NULL, NULL);
  2175. }
  2176. /* Convenience routine to read an expression with two possible terminators */
  2177. static PLpgSQL_expr *
  2178. read_sql_expression2(int until, int until2, const char *expected,
  2179. int *endtoken)
  2180. {
  2181. return read_sql_construct(until, until2, 0, expected,
  2182. "SELECT ", true, true, true, NULL, endtoken);
  2183. }
  2184. /* Convenience routine to read a SQL statement that must end with ';' */
  2185. static PLpgSQL_expr *
  2186. read_sql_stmt(const char *sqlstart)
  2187. {
  2188. return read_sql_construct(';', 0, 0, ";",
  2189. sqlstart, false, true, true, NULL, NULL);
  2190. }
  2191. /*
  2192. * Read a SQL construct and build a PLpgSQL_expr for it.
  2193. *
  2194. * until: token code for expected terminator
  2195. * until2: token code for alternate terminator (pass 0 if none)
  2196. * until3: token code for another alternate terminator (pass 0 if none)
  2197. * expected: text to use in complaining that terminator was not found
  2198. * sqlstart: text to prefix to the accumulated SQL text
  2199. * isexpression: whether to say we're reading an "expression" or a "statement"
  2200. * valid_sql: whether to check the syntax of the expr (prefixed with sqlstart)
  2201. * trim: trim trailing whitespace
  2202. * startloc: if not NULL, location of first token is stored at *startloc
  2203. * endtoken: if not NULL, ending token is stored at *endtoken
  2204. * (this is only interesting if until2 or until3 isn't zero)
  2205. */
  2206. static PLpgSQL_expr *
  2207. read_sql_construct(int until,
  2208. int until2,
  2209. int until3,
  2210. const char *expected,
  2211. const char *sqlstart,
  2212. bool isexpression,
  2213. bool valid_sql,
  2214. bool trim,
  2215. int *startloc,
  2216. int *endtoken)
  2217. {
  2218. int tok;
  2219. StringInfoData ds;
  2220. IdentifierLookup save_IdentifierLookup;
  2221. int startlocation = -1;
  2222. int parenlevel = 0;
  2223. PLpgSQL_expr *expr;
  2224. initStringInfo(&ds);
  2225. appendStringInfoString(&ds, sqlstart);
  2226. /* special lookup mode for identifiers within the SQL text */
  2227. save_IdentifierLookup = plpgsql_IdentifierLookup;
  2228. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
  2229. for (;;)
  2230. {
  2231. tok = yylex();
  2232. if (startlocation < 0) /* remember loc of first token */
  2233. startlocation = yylloc;
  2234. if (tok == until && parenlevel == 0)
  2235. break;
  2236. if (tok == until2 && parenlevel == 0)
  2237. break;
  2238. if (tok == until3 && parenlevel == 0)
  2239. break;
  2240. if (tok == '(' || tok == '[')
  2241. parenlevel++;
  2242. else if (tok == ')' || tok == ']')
  2243. {
  2244. parenlevel--;
  2245. if (parenlevel < 0)
  2246. yyerror("mismatched parentheses");
  2247. }
  2248. /*
  2249. * End of function definition is an error, and we don't expect to
  2250. * hit a semicolon either (unless it's the until symbol, in which
  2251. * case we should have fallen out above).
  2252. */
  2253. if (tok == 0 || tok == ';')
  2254. {
  2255. if (parenlevel != 0)
  2256. yyerror("mismatched parentheses");
  2257. if (isexpression)
  2258. ereport(ERROR,
  2259. (errcode(ERRCODE_SYNTAX_ERROR),
  2260. errmsg("missing \"%s\" at end of SQL expression",
  2261. expected),
  2262. parser_errposition(yylloc)));
  2263. else
  2264. ereport(ERROR,
  2265. (errcode(ERRCODE_SYNTAX_ERROR),
  2266. errmsg("missing \"%s\" at end of SQL statement",
  2267. expected),
  2268. parser_errposition(yylloc)));
  2269. }
  2270. }
  2271. plpgsql_IdentifierLookup = save_IdentifierLookup;
  2272. if (startloc)
  2273. *startloc = startlocation;
  2274. if (endtoken)
  2275. *endtoken = tok;
  2276. /* give helpful complaint about empty input */
  2277. if (startlocation >= yylloc)
  2278. {
  2279. if (isexpression)
  2280. yyerror("missing expression");
  2281. else
  2282. yyerror("missing SQL statement");
  2283. }
  2284. plpgsql_append_source_text(&ds, startlocation, yylloc);
  2285. /* trim any trailing whitespace, for neatness */
  2286. if (trim)
  2287. {
  2288. while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
  2289. ds.data[--ds.len] = '\0';
  2290. }
  2291. expr = palloc0(sizeof(PLpgSQL_expr));
  2292. expr->dtype = PLPGSQL_DTYPE_EXPR;
  2293. expr->query = pstrdup(ds.data);
  2294. expr->plan = NULL;
  2295. expr->paramnos = NULL;
  2296. expr->ns = plpgsql_ns_top();
  2297. pfree(ds.data);
  2298. if (valid_sql)
  2299. check_sql_expr(expr->query, startlocation, strlen(sqlstart));
  2300. return expr;
  2301. }
  2302. static PLpgSQL_type *
  2303. read_datatype(int tok)
  2304. {
  2305. StringInfoData ds;
  2306. char *type_name;
  2307. int startlocation;
  2308. PLpgSQL_type *result;
  2309. int parenlevel = 0;
  2310. /* Should only be called while parsing DECLARE sections */
  2311. Assert(plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_DECLARE);
  2312. /* Often there will be a lookahead token, but if not, get one */
  2313. if (tok == YYEMPTY)
  2314. tok = yylex();
  2315. startlocation = yylloc;
  2316. /*
  2317. * If we have a simple or composite identifier, check for %TYPE
  2318. * and %ROWTYPE constructs.
  2319. */
  2320. if (tok == T_WORD)
  2321. {
  2322. char *dtname = yylval.word.ident;
  2323. tok = yylex();
  2324. if (tok == '%')
  2325. {
  2326. tok = yylex();
  2327. if (tok_is_keyword(tok, &yylval,
  2328. K_TYPE, "type"))
  2329. {
  2330. result = plpgsql_parse_wordtype(dtname);
  2331. if (result)
  2332. return result;
  2333. }
  2334. else if (tok_is_keyword(tok, &yylval,
  2335. K_ROWTYPE, "rowtype"))
  2336. {
  2337. result = plpgsql_parse_wordrowtype(dtname);
  2338. if (result)
  2339. return result;
  2340. }
  2341. }
  2342. }
  2343. else if (plpgsql_token_is_unreserved_keyword(tok))
  2344. {
  2345. char *dtname = pstrdup(yylval.keyword);
  2346. tok = yylex();
  2347. if (tok == '%')
  2348. {
  2349. tok = yylex();
  2350. if (tok_is_keyword(tok, &yylval,
  2351. K_TYPE, "type"))
  2352. {
  2353. result = plpgsql_parse_wordtype(dtname);
  2354. if (result)
  2355. return result;
  2356. }
  2357. else if (tok_is_keyword(tok, &yylval,
  2358. K_ROWTYPE, "rowtype"))
  2359. {
  2360. result = plpgsql_parse_wordrowtype(dtname);
  2361. if (result)
  2362. return result;
  2363. }
  2364. }
  2365. }
  2366. else if (tok == T_CWORD)
  2367. {
  2368. List *dtnames = yylval.cword.idents;
  2369. tok = yylex();
  2370. if (tok == '%')
  2371. {
  2372. tok = yylex();
  2373. if (tok_is_keyword(tok, &yylval,
  2374. K_TYPE, "type"))
  2375. {
  2376. result = plpgsql_parse_cwordtype(dtnames);
  2377. if (result)
  2378. return result;
  2379. }
  2380. else if (tok_is_keyword(tok, &yylval,
  2381. K_ROWTYPE, "rowtype"))
  2382. {
  2383. result = plpgsql_parse_cwordrowtype(dtnames);
  2384. if (result)
  2385. return result;
  2386. }
  2387. }
  2388. }
  2389. while (tok != ';')
  2390. {
  2391. if (tok == 0)
  2392. {
  2393. if (parenlevel != 0)
  2394. yyerror("mismatched parentheses");
  2395. else
  2396. yyerror("incomplete data type declaration");
  2397. }
  2398. /* Possible followers for datatype in a declaration */
  2399. if (tok == K_COLLATE || tok == K_NOT ||
  2400. tok == '=' || tok == COLON_EQUALS || tok == K_DEFAULT)
  2401. break;
  2402. /* Possible followers for datatype in a cursor_arg list */
  2403. if ((tok == ',' || tok == ')') && parenlevel == 0)
  2404. break;
  2405. if (tok == '(')
  2406. parenlevel++;
  2407. else if (tok == ')')
  2408. parenlevel--;
  2409. tok = yylex();
  2410. }
  2411. /* set up ds to contain complete typename text */
  2412. initStringInfo(&ds);
  2413. plpgsql_append_source_text(&ds, startlocation, yylloc);
  2414. type_name = ds.data;
  2415. if (type_name[0] == '\0')
  2416. yyerror("missing data type declaration");
  2417. result = parse_datatype(type_name, startlocation);
  2418. pfree(ds.data);
  2419. plpgsql_push_back_token(tok);
  2420. return result;
  2421. }
  2422. static PLpgSQL_stmt *
  2423. make_execsql_stmt(int firsttoken, int location)
  2424. {
  2425. StringInfoData ds;
  2426. IdentifierLookup save_IdentifierLookup;
  2427. PLpgSQL_stmt_execsql *execsql;
  2428. PLpgSQL_expr *expr;
  2429. PLpgSQL_row *row = NULL;
  2430. PLpgSQL_rec *rec = NULL;
  2431. int tok;
  2432. int prev_tok;
  2433. bool have_into = false;
  2434. bool have_strict = false;
  2435. int into_start_loc = -1;
  2436. int into_end_loc = -1;
  2437. initStringInfo(&ds);
  2438. /* special lookup mode for identifiers within the SQL text */
  2439. save_IdentifierLookup = plpgsql_IdentifierLookup;
  2440. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
  2441. /*
  2442. * We have to special-case the sequence INSERT INTO, because we don't want
  2443. * that to be taken as an INTO-variables clause. Fortunately, this is the
  2444. * only valid use of INTO in a pl/pgsql SQL command, and INTO is already a
  2445. * fully reserved word in the main grammar. We have to treat it that way
  2446. * anywhere in the string, not only at the start; consider CREATE RULE
  2447. * containing an INSERT statement.
  2448. */
  2449. tok = firsttoken;
  2450. for (;;)
  2451. {
  2452. prev_tok = tok;
  2453. tok = yylex();
  2454. if (have_into && into_end_loc < 0)
  2455. into_end_loc = yylloc; /* token after the INTO part */
  2456. if (tok == ';')
  2457. break;
  2458. if (tok == 0)
  2459. yyerror("unexpected end of function definition");
  2460. if (tok == K_INTO && prev_tok != K_INSERT)
  2461. {
  2462. if (have_into)
  2463. yyerror("INTO specified more than once");
  2464. have_into = true;
  2465. into_start_loc = yylloc;
  2466. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  2467. read_into_target(&rec, &row, &have_strict);
  2468. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
  2469. }
  2470. }
  2471. plpgsql_IdentifierLookup = save_IdentifierLookup;
  2472. if (have_into)
  2473. {
  2474. /*
  2475. * Insert an appropriate number of spaces corresponding to the
  2476. * INTO text, so that locations within the redacted SQL statement
  2477. * still line up with those in the original source text.
  2478. */
  2479. plpgsql_append_source_text(&ds, location, into_start_loc);
  2480. appendStringInfoSpaces(&ds, into_end_loc - into_start_loc);
  2481. plpgsql_append_source_text(&ds, into_end_loc, yylloc);
  2482. }
  2483. else
  2484. plpgsql_append_source_text(&ds, location, yylloc);
  2485. /* trim any trailing whitespace, for neatness */
  2486. while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
  2487. ds.data[--ds.len] = '\0';
  2488. expr = palloc0(sizeof(PLpgSQL_expr));
  2489. expr->dtype = PLPGSQL_DTYPE_EXPR;
  2490. expr->query = pstrdup(ds.data);
  2491. expr->plan = NULL;
  2492. expr->paramnos = NULL;
  2493. expr->ns = plpgsql_ns_top();
  2494. pfree(ds.data);
  2495. check_sql_expr(expr->query, location, 0);
  2496. execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
  2497. execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
  2498. execsql->lineno = plpgsql_location_to_lineno(location);
  2499. execsql->sqlstmt = expr;
  2500. execsql->into = have_into;
  2501. execsql->strict = have_strict;
  2502. execsql->rec = rec;
  2503. execsql->row = row;
  2504. return (PLpgSQL_stmt *) execsql;
  2505. }
  2506. /*
  2507. * Read FETCH or MOVE direction clause (everything through FROM/IN).
  2508. */
  2509. static PLpgSQL_stmt_fetch *
  2510. read_fetch_direction(void)
  2511. {
  2512. PLpgSQL_stmt_fetch *fetch;
  2513. int tok;
  2514. bool check_FROM = true;
  2515. /*
  2516. * We create the PLpgSQL_stmt_fetch struct here, but only fill in
  2517. * the fields arising from the optional direction clause
  2518. */
  2519. fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch));
  2520. fetch->cmd_type = PLPGSQL_STMT_FETCH;
  2521. /* set direction defaults: */
  2522. fetch->direction = FETCH_FORWARD;
  2523. fetch->how_many = 1;
  2524. fetch->expr = NULL;
  2525. fetch->returns_multiple_rows = false;
  2526. tok = yylex();
  2527. if (tok == 0)
  2528. yyerror("unexpected end of function definition");
  2529. if (tok_is_keyword(tok, &yylval,
  2530. K_NEXT, "next"))
  2531. {
  2532. /* use defaults */
  2533. }
  2534. else if (tok_is_keyword(tok, &yylval,
  2535. K_PRIOR, "prior"))
  2536. {
  2537. fetch->direction = FETCH_BACKWARD;
  2538. }
  2539. else if (tok_is_keyword(tok, &yylval,
  2540. K_FIRST, "first"))
  2541. {
  2542. fetch->direction = FETCH_ABSOLUTE;
  2543. }
  2544. else if (tok_is_keyword(tok, &yylval,
  2545. K_LAST, "last"))
  2546. {
  2547. fetch->direction = FETCH_ABSOLUTE;
  2548. fetch->how_many = -1;
  2549. }
  2550. else if (tok_is_keyword(tok, &yylval,
  2551. K_ABSOLUTE, "absolute"))
  2552. {
  2553. fetch->direction = FETCH_ABSOLUTE;
  2554. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2555. "FROM or IN",
  2556. NULL);
  2557. check_FROM = false;
  2558. }
  2559. else if (tok_is_keyword(tok, &yylval,
  2560. K_RELATIVE, "relative"))
  2561. {
  2562. fetch->direction = FETCH_RELATIVE;
  2563. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2564. "FROM or IN",
  2565. NULL);
  2566. check_FROM = false;
  2567. }
  2568. else if (tok_is_keyword(tok, &yylval,
  2569. K_ALL, "all"))
  2570. {
  2571. fetch->how_many = FETCH_ALL;
  2572. fetch->returns_multiple_rows = true;
  2573. }
  2574. else if (tok_is_keyword(tok, &yylval,
  2575. K_FORWARD, "forward"))
  2576. {
  2577. complete_direction(fetch, &check_FROM);
  2578. }
  2579. else if (tok_is_keyword(tok, &yylval,
  2580. K_BACKWARD, "backward"))
  2581. {
  2582. fetch->direction = FETCH_BACKWARD;
  2583. complete_direction(fetch, &check_FROM);
  2584. }
  2585. else if (tok == K_FROM || tok == K_IN)
  2586. {
  2587. /* empty direction */
  2588. check_FROM = false;
  2589. }
  2590. else if (tok == T_DATUM)
  2591. {
  2592. /* Assume there's no direction clause and tok is a cursor name */
  2593. plpgsql_push_back_token(tok);
  2594. check_FROM = false;
  2595. }
  2596. else
  2597. {
  2598. /*
  2599. * Assume it's a count expression with no preceding keyword.
  2600. * Note: we allow this syntax because core SQL does, but we don't
  2601. * document it because of the ambiguity with the omitted-direction
  2602. * case. For instance, "MOVE n IN c" will fail if n is a variable.
  2603. * Perhaps this can be improved someday, but it's hardly worth a
  2604. * lot of work.
  2605. */
  2606. plpgsql_push_back_token(tok);
  2607. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2608. "FROM or IN",
  2609. NULL);
  2610. fetch->returns_multiple_rows = true;
  2611. check_FROM = false;
  2612. }
  2613. /* check FROM or IN keyword after direction's specification */
  2614. if (check_FROM)
  2615. {
  2616. tok = yylex();
  2617. if (tok != K_FROM && tok != K_IN)
  2618. yyerror("expected FROM or IN");
  2619. }
  2620. return fetch;
  2621. }
  2622. /*
  2623. * Process remainder of FETCH/MOVE direction after FORWARD or BACKWARD.
  2624. * Allows these cases:
  2625. * FORWARD expr, FORWARD ALL, FORWARD
  2626. * BACKWARD expr, BACKWARD ALL, BACKWARD
  2627. */
  2628. static void
  2629. complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM)
  2630. {
  2631. int tok;
  2632. tok = yylex();
  2633. if (tok == 0)
  2634. yyerror("unexpected end of function definition");
  2635. if (tok == K_FROM || tok == K_IN)
  2636. {
  2637. *check_FROM = false;
  2638. return;
  2639. }
  2640. if (tok == K_ALL)
  2641. {
  2642. fetch->how_many = FETCH_ALL;
  2643. fetch->returns_multiple_rows = true;
  2644. *check_FROM = true;
  2645. return;
  2646. }
  2647. plpgsql_push_back_token(tok);
  2648. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2649. "FROM or IN",
  2650. NULL);
  2651. fetch->returns_multiple_rows = true;
  2652. *check_FROM = false;
  2653. }
  2654. static PLpgSQL_stmt *
  2655. make_return_stmt(int location)
  2656. {
  2657. PLpgSQL_stmt_return *new;
  2658. new = palloc0(sizeof(PLpgSQL_stmt_return));
  2659. new->cmd_type = PLPGSQL_STMT_RETURN;
  2660. new->lineno = plpgsql_location_to_lineno(location);
  2661. new->expr = NULL;
  2662. new->retvarno = -1;
  2663. if (plpgsql_curr_compile->fn_retset)
  2664. {
  2665. if (yylex() != ';')
  2666. ereport(ERROR,
  2667. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2668. errmsg("RETURN cannot have a parameter in function returning set"),
  2669. errhint("Use RETURN NEXT or RETURN QUERY."),
  2670. parser_errposition(yylloc)));
  2671. }
  2672. else if (plpgsql_curr_compile->out_param_varno >= 0)
  2673. {
  2674. if (yylex() != ';')
  2675. ereport(ERROR,
  2676. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2677. errmsg("RETURN cannot have a parameter in function with OUT parameters"),
  2678. parser_errposition(yylloc)));
  2679. new->retvarno = plpgsql_curr_compile->out_param_varno;
  2680. }
  2681. else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
  2682. {
  2683. if (yylex() != ';')
  2684. ereport(ERROR,
  2685. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2686. errmsg("RETURN cannot have a parameter in function returning void"),
  2687. parser_errposition(yylloc)));
  2688. }
  2689. else if (plpgsql_curr_compile->fn_retistuple)
  2690. {
  2691. /*
  2692. * We want to special-case simple row or record references for
  2693. * efficiency. So peek ahead to see if that's what we have.
  2694. */
  2695. int tok = yylex();
  2696. if (tok == T_DATUM && plpgsql_peek() == ';' &&
  2697. (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
  2698. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
  2699. {
  2700. new->retvarno = yylval.wdatum.datum->dno;
  2701. /* eat the semicolon token that we only peeked at above */
  2702. tok = yylex();
  2703. Assert(tok == ';');
  2704. }
  2705. else
  2706. {
  2707. /* Not (just) a row/record name, so treat as expression */
  2708. plpgsql_push_back_token(tok);
  2709. new->expr = read_sql_expression(';', ";");
  2710. }
  2711. }
  2712. else
  2713. {
  2714. /*
  2715. * Note that a well-formed expression is _required_ here;
  2716. * anything else is a compile-time error.
  2717. */
  2718. new->expr = read_sql_expression(';', ";");
  2719. }
  2720. return (PLpgSQL_stmt *) new;
  2721. }
  2722. static PLpgSQL_stmt *
  2723. make_return_next_stmt(int location)
  2724. {
  2725. PLpgSQL_stmt_return_next *new;
  2726. if (!plpgsql_curr_compile->fn_retset)
  2727. ereport(ERROR,
  2728. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2729. errmsg("cannot use RETURN NEXT in a non-SETOF function"),
  2730. parser_errposition(location)));
  2731. new = palloc0(sizeof(PLpgSQL_stmt_return_next));
  2732. new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
  2733. new->lineno = plpgsql_location_to_lineno(location);
  2734. new->expr = NULL;
  2735. new->retvarno = -1;
  2736. if (plpgsql_curr_compile->out_param_varno >= 0)
  2737. {
  2738. if (yylex() != ';')
  2739. ereport(ERROR,
  2740. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2741. errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"),
  2742. parser_errposition(yylloc)));
  2743. new->retvarno = plpgsql_curr_compile->out_param_varno;
  2744. }
  2745. else if (plpgsql_curr_compile->fn_retistuple)
  2746. {
  2747. /*
  2748. * We want to special-case simple row or record references for
  2749. * efficiency. So peek ahead to see if that's what we have.
  2750. */
  2751. int tok = yylex();
  2752. if (tok == T_DATUM && plpgsql_peek() == ';' &&
  2753. (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
  2754. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
  2755. {
  2756. new->retvarno = yylval.wdatum.datum->dno;
  2757. /* eat the semicolon token that we only peeked at above */
  2758. tok = yylex();
  2759. Assert(tok == ';');
  2760. }
  2761. else
  2762. {
  2763. /* Not (just) a row/record name, so treat as expression */
  2764. plpgsql_push_back_token(tok);
  2765. new->expr = read_sql_expression(';', ";");
  2766. }
  2767. }
  2768. else
  2769. new->expr = read_sql_expression(';', ";");
  2770. return (PLpgSQL_stmt *) new;
  2771. }
  2772. static PLpgSQL_stmt *
  2773. make_return_query_stmt(int location)
  2774. {
  2775. PLpgSQL_stmt_return_query *new;
  2776. int tok;
  2777. if (!plpgsql_curr_compile->fn_retset)
  2778. ereport(ERROR,
  2779. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2780. errmsg("cannot use RETURN QUERY in a non-SETOF function"),
  2781. parser_errposition(location)));
  2782. new = palloc0(sizeof(PLpgSQL_stmt_return_query));
  2783. new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
  2784. new->lineno = plpgsql_location_to_lineno(location);
  2785. /* check for RETURN QUERY EXECUTE */
  2786. if ((tok = yylex()) != K_EXECUTE)
  2787. {
  2788. /* ordinary static query */
  2789. plpgsql_push_back_token(tok);
  2790. new->query = read_sql_stmt("");
  2791. }
  2792. else
  2793. {
  2794. /* dynamic SQL */
  2795. int term;
  2796. new->dynquery = read_sql_expression2(';', K_USING, "; or USING",
  2797. &term);
  2798. if (term == K_USING)
  2799. {
  2800. do
  2801. {
  2802. PLpgSQL_expr *expr;
  2803. expr = read_sql_expression2(',', ';', ", or ;", &term);
  2804. new->params = lappend(new->params, expr);
  2805. } while (term == ',');
  2806. }
  2807. }
  2808. return (PLpgSQL_stmt *) new;
  2809. }
  2810. /* convenience routine to fetch the name of a T_DATUM */
  2811. static char *
  2812. NameOfDatum(PLwdatum *wdatum)
  2813. {
  2814. if (wdatum->ident)
  2815. return wdatum->ident;
  2816. Assert(wdatum->idents != NIL);
  2817. return NameListToString(wdatum->idents);
  2818. }
  2819. static void
  2820. check_assignable(PLpgSQL_datum *datum, int location)
  2821. {
  2822. switch (datum->dtype)
  2823. {
  2824. case PLPGSQL_DTYPE_VAR:
  2825. if (((PLpgSQL_var *) datum)->isconst)
  2826. ereport(ERROR,
  2827. (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
  2828. errmsg("\"%s\" is declared CONSTANT",
  2829. ((PLpgSQL_var *) datum)->refname),
  2830. parser_errposition(location)));
  2831. break;
  2832. case PLPGSQL_DTYPE_ROW:
  2833. /* always assignable? */
  2834. break;
  2835. case PLPGSQL_DTYPE_REC:
  2836. /* always assignable? What about NEW/OLD? */
  2837. break;
  2838. case PLPGSQL_DTYPE_RECFIELD:
  2839. /* always assignable? */
  2840. break;
  2841. case PLPGSQL_DTYPE_ARRAYELEM:
  2842. /* always assignable? */
  2843. break;
  2844. default:
  2845. elog(ERROR, "unrecognized dtype: %d", datum->dtype);
  2846. break;
  2847. }
  2848. }
  2849. /*
  2850. * Read the argument of an INTO clause. On entry, we have just read the
  2851. * INTO keyword.
  2852. */
  2853. static void
  2854. read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
  2855. {
  2856. int tok;
  2857. /* Set default results */
  2858. *rec = NULL;
  2859. *row = NULL;
  2860. if (strict)
  2861. *strict = false;
  2862. tok = yylex();
  2863. if (strict && tok == K_STRICT)
  2864. {
  2865. *strict = true;
  2866. tok = yylex();
  2867. }
  2868. /*
  2869. * Currently, a row or record variable can be the single INTO target,
  2870. * but not a member of a multi-target list. So we throw error if there
  2871. * is a comma after it, because that probably means the user tried to
  2872. * write a multi-target list. If this ever gets generalized, we should
  2873. * probably refactor read_into_scalar_list so it handles all cases.
  2874. */
  2875. switch (tok)
  2876. {
  2877. case T_DATUM:
  2878. if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW)
  2879. {
  2880. check_assignable(yylval.wdatum.datum, yylloc);
  2881. *row = (PLpgSQL_row *) yylval.wdatum.datum;
  2882. if ((tok = yylex()) == ',')
  2883. ereport(ERROR,
  2884. (errcode(ERRCODE_SYNTAX_ERROR),
  2885. errmsg("record or row variable cannot be part of multiple-item INTO list"),
  2886. parser_errposition(yylloc)));
  2887. plpgsql_push_back_token(tok);
  2888. }
  2889. else if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
  2890. {
  2891. check_assignable(yylval.wdatum.datum, yylloc);
  2892. *rec = (PLpgSQL_rec *) yylval.wdatum.datum;
  2893. if ((tok = yylex()) == ',')
  2894. ereport(ERROR,
  2895. (errcode(ERRCODE_SYNTAX_ERROR),
  2896. errmsg("record or row variable cannot be part of multiple-item INTO list"),
  2897. parser_errposition(yylloc)));
  2898. plpgsql_push_back_token(tok);
  2899. }
  2900. else
  2901. {
  2902. *row = read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
  2903. yylval.wdatum.datum, yylloc);
  2904. }
  2905. break;
  2906. default:
  2907. /* just to give a better message than "syntax error" */
  2908. current_token_is_not_variable(tok);
  2909. }
  2910. }
  2911. /*
  2912. * Given the first datum and name in the INTO list, continue to read
  2913. * comma-separated scalar variables until we run out. Then construct
  2914. * and return a fake "row" variable that represents the list of
  2915. * scalars.
  2916. */
  2917. static PLpgSQL_row *
  2918. read_into_scalar_list(char *initial_name,
  2919. PLpgSQL_datum *initial_datum,
  2920. int initial_location)
  2921. {
  2922. int nfields;
  2923. char *fieldnames[1024];
  2924. int varnos[1024];
  2925. PLpgSQL_row *row;
  2926. int tok;
  2927. check_assignable(initial_datum, initial_location);
  2928. fieldnames[0] = initial_name;
  2929. varnos[0] = initial_datum->dno;
  2930. nfields = 1;
  2931. while ((tok = yylex()) == ',')
  2932. {
  2933. /* Check for array overflow */
  2934. if (nfields >= 1024)
  2935. ereport(ERROR,
  2936. (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
  2937. errmsg("too many INTO variables specified"),
  2938. parser_errposition(yylloc)));
  2939. tok = yylex();
  2940. switch (tok)
  2941. {
  2942. case T_DATUM:
  2943. check_assignable(yylval.wdatum.datum, yylloc);
  2944. if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
  2945. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
  2946. ereport(ERROR,
  2947. (errcode(ERRCODE_SYNTAX_ERROR),
  2948. errmsg("\"%s\" is not a scalar variable",
  2949. NameOfDatum(&(yylval.wdatum))),
  2950. parser_errposition(yylloc)));
  2951. fieldnames[nfields] = NameOfDatum(&(yylval.wdatum));
  2952. varnos[nfields++] = yylval.wdatum.datum->dno;
  2953. break;
  2954. default:
  2955. /* just to give a better message than "syntax error" */
  2956. current_token_is_not_variable(tok);
  2957. }
  2958. }
  2959. /*
  2960. * We read an extra, non-comma token from yylex(), so push it
  2961. * back onto the input stream
  2962. */
  2963. plpgsql_push_back_token(tok);
  2964. row = palloc(sizeof(PLpgSQL_row));
  2965. row->dtype = PLPGSQL_DTYPE_ROW;
  2966. row->refname = pstrdup("*internal*");
  2967. row->lineno = plpgsql_location_to_lineno(initial_location);
  2968. row->rowtupdesc = NULL;
  2969. row->nfields = nfields;
  2970. row->fieldnames = palloc(sizeof(char *) * nfields);
  2971. row->varnos = palloc(sizeof(int) * nfields);
  2972. while (--nfields >= 0)
  2973. {
  2974. row->fieldnames[nfields] = fieldnames[nfields];
  2975. row->varnos[nfields] = varnos[nfields];
  2976. }
  2977. plpgsql_adddatum((PLpgSQL_datum *)row);
  2978. return row;
  2979. }
  2980. /*
  2981. * Convert a single scalar into a "row" list. This is exactly
  2982. * like read_into_scalar_list except we never consume any input.
  2983. *
  2984. * Note: lineno could be computed from location, but since callers
  2985. * have it at hand already, we may as well pass it in.
  2986. */
  2987. static PLpgSQL_row *
  2988. make_scalar_list1(char *initial_name,
  2989. PLpgSQL_datum *initial_datum,
  2990. int lineno, int location)
  2991. {
  2992. PLpgSQL_row *row;
  2993. check_assignable(initial_datum, location);
  2994. row = palloc(sizeof(PLpgSQL_row));
  2995. row->dtype = PLPGSQL_DTYPE_ROW;
  2996. row->refname = pstrdup("*internal*");
  2997. row->lineno = lineno;
  2998. row->rowtupdesc = NULL;
  2999. row->nfields = 1;
  3000. row->fieldnames = palloc(sizeof(char *));
  3001. row->varnos = palloc(sizeof(int));
  3002. row->fieldnames[0] = initial_name;
  3003. row->varnos[0] = initial_datum->dno;
  3004. plpgsql_adddatum((PLpgSQL_datum *)row);
  3005. return row;
  3006. }
  3007. /*
  3008. * When the PL/pgSQL parser expects to see a SQL statement, it is very
  3009. * liberal in what it accepts; for example, we often assume an
  3010. * unrecognized keyword is the beginning of a SQL statement. This
  3011. * avoids the need to duplicate parts of the SQL grammar in the
  3012. * PL/pgSQL grammar, but it means we can accept wildly malformed
  3013. * input. To try and catch some of the more obviously invalid input,
  3014. * we run the strings we expect to be SQL statements through the main
  3015. * SQL parser.
  3016. *
  3017. * We only invoke the raw parser (not the analyzer); this doesn't do
  3018. * any database access and does not check any semantic rules, it just
  3019. * checks for basic syntactic correctness. We do this here, rather
  3020. * than after parsing has finished, because a malformed SQL statement
  3021. * may cause the PL/pgSQL parser to become confused about statement
  3022. * borders. So it is best to bail out as early as we can.
  3023. *
  3024. * It is assumed that "stmt" represents a copy of the function source text
  3025. * beginning at offset "location", with leader text of length "leaderlen"
  3026. * (typically "SELECT ") prefixed to the source text. We use this assumption
  3027. * to transpose any error cursor position back to the function source text.
  3028. * If no error cursor is provided, we'll just point at "location".
  3029. */
  3030. static void
  3031. check_sql_expr(const char *stmt, int location, int leaderlen)
  3032. {
  3033. sql_error_callback_arg cbarg;
  3034. ErrorContextCallback syntax_errcontext;
  3035. MemoryContext oldCxt;
  3036. if (!plpgsql_check_syntax)
  3037. return;
  3038. cbarg.location = location;
  3039. cbarg.leaderlen = leaderlen;
  3040. syntax_errcontext.callback = plpgsql_sql_error_callback;
  3041. syntax_errcontext.arg = &cbarg;
  3042. syntax_errcontext.previous = error_context_stack;
  3043. error_context_stack = &syntax_errcontext;
  3044. oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
  3045. (void) raw_parser(stmt);
  3046. MemoryContextSwitchTo(oldCxt);
  3047. /* Restore former ereport callback */
  3048. error_context_stack = syntax_errcontext.previous;
  3049. }
  3050. static void
  3051. plpgsql_sql_error_callback(void *arg)
  3052. {
  3053. sql_error_callback_arg *cbarg = (sql_error_callback_arg *) arg;
  3054. int errpos;
  3055. /*
  3056. * First, set up internalerrposition to point to the start of the
  3057. * statement text within the function text. Note this converts
  3058. * location (a byte offset) to a character number.
  3059. */
  3060. parser_errposition(cbarg->location);
  3061. /*
  3062. * If the core parser provided an error position, transpose it.
  3063. * Note we are dealing with 1-based character numbers at this point.
  3064. */
  3065. errpos = geterrposition();
  3066. if (errpos > cbarg->leaderlen)
  3067. {
  3068. int myerrpos = getinternalerrposition();
  3069. if (myerrpos > 0) /* safety check */
  3070. internalerrposition(myerrpos + errpos - cbarg->leaderlen - 1);
  3071. }
  3072. /* In any case, flush errposition --- we want internalerrpos only */
  3073. errposition(0);
  3074. }
  3075. /*
  3076. * Parse a SQL datatype name and produce a PLpgSQL_type structure.
  3077. *
  3078. * The heavy lifting is done elsewhere. Here we are only concerned
  3079. * with setting up an errcontext link that will let us give an error
  3080. * cursor pointing into the plpgsql function source, if necessary.
  3081. * This is handled the same as in check_sql_expr(), and we likewise
  3082. * expect that the given string is a copy from the source text.
  3083. */
  3084. static PLpgSQL_type *
  3085. parse_datatype(const char *string, int location)
  3086. {
  3087. Oid type_id;
  3088. int32 typmod;
  3089. sql_error_callback_arg cbarg;
  3090. ErrorContextCallback syntax_errcontext;
  3091. cbarg.location = location;
  3092. cbarg.leaderlen = 0;
  3093. syntax_errcontext.callback = plpgsql_sql_error_callback;
  3094. syntax_errcontext.arg = &cbarg;
  3095. syntax_errcontext.previous = error_context_stack;
  3096. error_context_stack = &syntax_errcontext;
  3097. /* Let the main parser try to parse it under standard SQL rules */
  3098. parseTypeString(string, &type_id, &typmod);
  3099. /* Restore former ereport callback */
  3100. error_context_stack = syntax_errcontext.previous;
  3101. /* Okay, build a PLpgSQL_type data structure for it */
  3102. return plpgsql_build_datatype(type_id, typmod,
  3103. plpgsql_curr_compile->fn_input_collation);
  3104. }
  3105. /*
  3106. * Check block starting and ending labels match.
  3107. */
  3108. static void
  3109. check_labels(const char *start_label, const char *end_label, int end_location)
  3110. {
  3111. if (end_label)
  3112. {
  3113. if (!start_label)
  3114. ereport(ERROR,
  3115. (errcode(ERRCODE_SYNTAX_ERROR),
  3116. errmsg("end label \"%s\" specified for unlabelled block",
  3117. end_label),
  3118. parser_errposition(end_location)));
  3119. if (strcmp(start_label, end_label) != 0)
  3120. ereport(ERROR,
  3121. (errcode(ERRCODE_SYNTAX_ERROR),
  3122. errmsg("end label \"%s\" differs from block's label \"%s\"",
  3123. end_label, start_label),
  3124. parser_errposition(end_location)));
  3125. }
  3126. }
  3127. /*
  3128. * Read the arguments (if any) for a cursor, followed by the until token
  3129. *
  3130. * If cursor has no args, just swallow the until token and return NULL.
  3131. * If it does have args, we expect to see "( arg [, arg ...] )" followed
  3132. * by the until token, where arg may be a plain expression, or a named
  3133. * parameter assignment of the form argname := expr. Consume all that and
  3134. * return a SELECT query that evaluates the expression(s) (without the outer
  3135. * parens).
  3136. */
  3137. static PLpgSQL_expr *
  3138. read_cursor_args(PLpgSQL_var *cursor, int until, const char *expected)
  3139. {
  3140. PLpgSQL_expr *expr;
  3141. PLpgSQL_row *row;
  3142. int tok;
  3143. int argc;
  3144. char **argv;
  3145. StringInfoData ds;
  3146. char *sqlstart = "SELECT ";
  3147. bool any_named = false;
  3148. tok = yylex();
  3149. if (cursor->cursor_explicit_argrow < 0)
  3150. {
  3151. /* No arguments expected */
  3152. if (tok == '(')
  3153. ereport(ERROR,
  3154. (errcode(ERRCODE_SYNTAX_ERROR),
  3155. errmsg("cursor \"%s\" has no arguments",
  3156. cursor->refname),
  3157. parser_errposition(yylloc)));
  3158. if (tok != until)
  3159. yyerror("syntax error");
  3160. return NULL;
  3161. }
  3162. /* Else better provide arguments */
  3163. if (tok != '(')
  3164. ereport(ERROR,
  3165. (errcode(ERRCODE_SYNTAX_ERROR),
  3166. errmsg("cursor \"%s\" has arguments",
  3167. cursor->refname),
  3168. parser_errposition(yylloc)));
  3169. /*
  3170. * Read the arguments, one by one.
  3171. */
  3172. row = (PLpgSQL_row *) plpgsql_Datums[cursor->cursor_explicit_argrow];
  3173. argv = (char **) palloc0(row->nfields * sizeof(char *));
  3174. for (argc = 0; argc < row->nfields; argc++)
  3175. {
  3176. PLpgSQL_expr *item;
  3177. int endtoken;
  3178. int argpos;
  3179. int tok1,
  3180. tok2;
  3181. int arglocation;
  3182. /* Check if it's a named parameter: "param := value" */
  3183. plpgsql_peek2(&tok1, &tok2, &arglocation, NULL);
  3184. if (tok1 == IDENT && tok2 == COLON_EQUALS)
  3185. {
  3186. char *argname;
  3187. IdentifierLookup save_IdentifierLookup;
  3188. /* Read the argument name, ignoring any matching variable */
  3189. save_IdentifierLookup = plpgsql_IdentifierLookup;
  3190. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
  3191. yylex();
  3192. argname = yylval.str;
  3193. plpgsql_IdentifierLookup = save_IdentifierLookup;
  3194. /* Match argument name to cursor arguments */
  3195. for (argpos = 0; argpos < row->nfields; argpos++)
  3196. {
  3197. if (strcmp(row->fieldnames[argpos], argname) == 0)
  3198. break;
  3199. }
  3200. if (argpos == row->nfields)
  3201. ereport(ERROR,
  3202. (errcode(ERRCODE_SYNTAX_ERROR),
  3203. errmsg("cursor \"%s\" has no argument named \"%s\"",
  3204. cursor->refname, argname),
  3205. parser_errposition(yylloc)));
  3206. /*
  3207. * Eat the ":=". We already peeked, so the error should never
  3208. * happen.
  3209. */
  3210. tok2 = yylex();
  3211. if (tok2 != COLON_EQUALS)
  3212. yyerror("syntax error");
  3213. any_named = true;
  3214. }
  3215. else
  3216. argpos = argc;
  3217. if (argv[argpos] != NULL)
  3218. ereport(ERROR,
  3219. (errcode(ERRCODE_SYNTAX_ERROR),
  3220. errmsg("value for parameter \"%s\" of cursor \"%s\" specified more than once",
  3221. row->fieldnames[argpos], cursor->refname),
  3222. parser_errposition(arglocation)));
  3223. /*
  3224. * Read the value expression. To provide the user with meaningful
  3225. * parse error positions, we check the syntax immediately, instead of
  3226. * checking the final expression that may have the arguments
  3227. * reordered. Trailing whitespace must not be trimmed, because
  3228. * otherwise input of the form (param -- comment\n, param) would be
  3229. * translated into a form where the second parameter is commented
  3230. * out.
  3231. */
  3232. item = read_sql_construct(',', ')', 0,
  3233. ",\" or \")",
  3234. sqlstart,
  3235. true, true,
  3236. false, /* do not trim */
  3237. NULL, &endtoken);
  3238. argv[argpos] = item->query + strlen(sqlstart);
  3239. if (endtoken == ')' && !(argc == row->nfields - 1))
  3240. ereport(ERROR,
  3241. (errcode(ERRCODE_SYNTAX_ERROR),
  3242. errmsg("not enough arguments for cursor \"%s\"",
  3243. cursor->refname),
  3244. parser_errposition(yylloc)));
  3245. if (endtoken == ',' && (argc == row->nfields - 1))
  3246. ereport(ERROR,
  3247. (errcode(ERRCODE_SYNTAX_ERROR),
  3248. errmsg("too many arguments for cursor \"%s\"",
  3249. cursor->refname),
  3250. parser_errposition(yylloc)));
  3251. }
  3252. /* Make positional argument list */
  3253. initStringInfo(&ds);
  3254. appendStringInfoString(&ds, sqlstart);
  3255. for (argc = 0; argc < row->nfields; argc++)
  3256. {
  3257. Assert(argv[argc] != NULL);
  3258. /*
  3259. * Because named notation allows permutated argument lists, include
  3260. * the parameter name for meaningful runtime errors.
  3261. */
  3262. appendStringInfoString(&ds, argv[argc]);
  3263. if (any_named)
  3264. appendStringInfo(&ds, " AS %s",
  3265. quote_identifier(row->fieldnames[argc]));
  3266. if (argc < row->nfields - 1)
  3267. appendStringInfoString(&ds, ", ");
  3268. }
  3269. appendStringInfoChar(&ds, ';');
  3270. expr = palloc0(sizeof(PLpgSQL_expr));
  3271. expr->dtype = PLPGSQL_DTYPE_EXPR;
  3272. expr->query = pstrdup(ds.data);
  3273. expr->plan = NULL;
  3274. expr->paramnos = NULL;
  3275. expr->ns = plpgsql_ns_top();
  3276. pfree(ds.data);
  3277. /* Next we'd better find the until token */
  3278. tok = yylex();
  3279. if (tok != until)
  3280. yyerror("syntax error");
  3281. return expr;
  3282. }
  3283. /*
  3284. * Parse RAISE ... USING options
  3285. */
  3286. static List *
  3287. read_raise_options(void)
  3288. {
  3289. List *result = NIL;
  3290. for (;;)
  3291. {
  3292. PLpgSQL_raise_option *opt;
  3293. int tok;
  3294. if ((tok = yylex()) == 0)
  3295. yyerror("unexpected end of function definition");
  3296. opt = (PLpgSQL_raise_option *) palloc(sizeof(PLpgSQL_raise_option));
  3297. if (tok_is_keyword(tok, &yylval,
  3298. K_ERRCODE, "errcode"))
  3299. opt->opt_type = PLPGSQL_RAISEOPTION_ERRCODE;
  3300. else if (tok_is_keyword(tok, &yylval,
  3301. K_MESSAGE, "message"))
  3302. opt->opt_type = PLPGSQL_RAISEOPTION_MESSAGE;
  3303. else if (tok_is_keyword(tok, &yylval,
  3304. K_DETAIL, "detail"))
  3305. opt->opt_type = PLPGSQL_RAISEOPTION_DETAIL;
  3306. else if (tok_is_keyword(tok, &yylval,
  3307. K_HINT, "hint"))
  3308. opt->opt_type = PLPGSQL_RAISEOPTION_HINT;
  3309. else if (tok_is_keyword(tok, &yylval,
  3310. K_COLUMN, "column"))
  3311. opt->opt_type = PLPGSQL_RAISEOPTION_COLUMN;
  3312. else if (tok_is_keyword(tok, &yylval,
  3313. K_CONSTRAINT, "constraint"))
  3314. opt->opt_type = PLPGSQL_RAISEOPTION_CONSTRAINT;
  3315. else if (tok_is_keyword(tok, &yylval,
  3316. K_DATATYPE, "datatype"))
  3317. opt->opt_type = PLPGSQL_RAISEOPTION_DATATYPE;
  3318. else if (tok_is_keyword(tok, &yylval,
  3319. K_TABLE, "table"))
  3320. opt->opt_type = PLPGSQL_RAISEOPTION_TABLE;
  3321. else if (tok_is_keyword(tok, &yylval,
  3322. K_SCHEMA, "schema"))
  3323. opt->opt_type = PLPGSQL_RAISEOPTION_SCHEMA;
  3324. else
  3325. yyerror("unrecognized RAISE statement option");
  3326. tok = yylex();
  3327. if (tok != '=' && tok != COLON_EQUALS)
  3328. yyerror("syntax error, expected \"=\"");
  3329. opt->expr = read_sql_expression2(',', ';', ", or ;", &tok);
  3330. result = lappend(result, opt);
  3331. if (tok == ';')
  3332. break;
  3333. }
  3334. return result;
  3335. }
  3336. /*
  3337. * Fix up CASE statement
  3338. */
  3339. static PLpgSQL_stmt *
  3340. make_case(int location, PLpgSQL_expr *t_expr,
  3341. List *case_when_list, List *else_stmts)
  3342. {
  3343. PLpgSQL_stmt_case *new;
  3344. new = palloc(sizeof(PLpgSQL_stmt_case));
  3345. new->cmd_type = PLPGSQL_STMT_CASE;
  3346. new->lineno = plpgsql_location_to_lineno(location);
  3347. new->t_expr = t_expr;
  3348. new->t_varno = 0;
  3349. new->case_when_list = case_when_list;
  3350. new->have_else = (else_stmts != NIL);
  3351. /* Get rid of list-with-NULL hack */
  3352. if (list_length(else_stmts) == 1 && linitial(else_stmts) == NULL)
  3353. new->else_stmts = NIL;
  3354. else
  3355. new->else_stmts = else_stmts;
  3356. /*
  3357. * When test expression is present, we create a var for it and then
  3358. * convert all the WHEN expressions to "VAR IN (original_expression)".
  3359. * This is a bit klugy, but okay since we haven't yet done more than
  3360. * read the expressions as text. (Note that previous parsing won't
  3361. * have complained if the WHEN ... THEN expression contained multiple
  3362. * comma-separated values.)
  3363. */
  3364. if (t_expr)
  3365. {
  3366. char varname[32];
  3367. PLpgSQL_var *t_var;
  3368. ListCell *l;
  3369. /* use a name unlikely to collide with any user names */
  3370. snprintf(varname, sizeof(varname), "__Case__Variable_%d__",
  3371. plpgsql_nDatums);
  3372. /*
  3373. * We don't yet know the result datatype of t_expr. Build the
  3374. * variable as if it were INT4; we'll fix this at runtime if needed.
  3375. */
  3376. t_var = (PLpgSQL_var *)
  3377. plpgsql_build_variable(varname, new->lineno,
  3378. plpgsql_build_datatype(INT4OID,
  3379. -1,
  3380. InvalidOid),
  3381. true);
  3382. new->t_varno = t_var->dno;
  3383. foreach(l, case_when_list)
  3384. {
  3385. PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l);
  3386. PLpgSQL_expr *expr = cwt->expr;
  3387. StringInfoData ds;
  3388. /* copy expression query without SELECT keyword (expr->query + 7) */
  3389. Assert(strncmp(expr->query, "SELECT ", 7) == 0);
  3390. /* And do the string hacking */
  3391. initStringInfo(&ds);
  3392. appendStringInfo(&ds, "SELECT \"%s\" IN (%s)",
  3393. varname, expr->query + 7);
  3394. pfree(expr->query);
  3395. expr->query = pstrdup(ds.data);
  3396. /* Adjust expr's namespace to include the case variable */
  3397. expr->ns = plpgsql_ns_top();
  3398. pfree(ds.data);
  3399. }
  3400. }
  3401. return (PLpgSQL_stmt *) new;
  3402. }