PageRenderTime 35ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/postgresql-9.2.1/src/pl/plpgsql/src/gram.y

https://bitbucket.org/definex/4707
Happy | 3684 lines | 3276 code | 408 blank | 0 comment | 0 complexity | 1950307547486ee0b90a6cbd549bc5a9 MD5 | raw file
Possible License(s): AGPL-3.0
  1. %{
  2. /*-------------------------------------------------------------------------
  3. *
  4. * gram.y - Parser for the PL/pgSQL procedural language
  5. *
  6. * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
  7. * Portions Copyright (c) 1994, Regents of the University of California
  8. *
  9. *
  10. * IDENTIFICATION
  11. * src/pl/plpgsql/src/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
  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_CONSTANT
  227. %token <keyword> K_CONTINUE
  228. %token <keyword> K_CURRENT
  229. %token <keyword> K_CURSOR
  230. %token <keyword> K_DEBUG
  231. %token <keyword> K_DECLARE
  232. %token <keyword> K_DEFAULT
  233. %token <keyword> K_DETAIL
  234. %token <keyword> K_DIAGNOSTICS
  235. %token <keyword> K_DUMP
  236. %token <keyword> K_ELSE
  237. %token <keyword> K_ELSIF
  238. %token <keyword> K_END
  239. %token <keyword> K_ERRCODE
  240. %token <keyword> K_ERROR
  241. %token <keyword> K_EXCEPTION
  242. %token <keyword> K_EXECUTE
  243. %token <keyword> K_EXIT
  244. %token <keyword> K_FETCH
  245. %token <keyword> K_FIRST
  246. %token <keyword> K_FOR
  247. %token <keyword> K_FOREACH
  248. %token <keyword> K_FORWARD
  249. %token <keyword> K_FROM
  250. %token <keyword> K_GET
  251. %token <keyword> K_HINT
  252. %token <keyword> K_IF
  253. %token <keyword> K_IN
  254. %token <keyword> K_INFO
  255. %token <keyword> K_INSERT
  256. %token <keyword> K_INTO
  257. %token <keyword> K_IS
  258. %token <keyword> K_LAST
  259. %token <keyword> K_LOG
  260. %token <keyword> K_LOOP
  261. %token <keyword> K_MESSAGE
  262. %token <keyword> K_MESSAGE_TEXT
  263. %token <keyword> K_MOVE
  264. %token <keyword> K_NEXT
  265. %token <keyword> K_NO
  266. %token <keyword> K_NOT
  267. %token <keyword> K_NOTICE
  268. %token <keyword> K_NULL
  269. %token <keyword> K_OPEN
  270. %token <keyword> K_OPTION
  271. %token <keyword> K_OR
  272. %token <keyword> K_PERFORM
  273. %token <keyword> K_PG_EXCEPTION_CONTEXT
  274. %token <keyword> K_PG_EXCEPTION_DETAIL
  275. %token <keyword> K_PG_EXCEPTION_HINT
  276. %token <keyword> K_PRIOR
  277. %token <keyword> K_QUERY
  278. %token <keyword> K_RAISE
  279. %token <keyword> K_RELATIVE
  280. %token <keyword> K_RESULT_OID
  281. %token <keyword> K_RETURN
  282. %token <keyword> K_RETURNED_SQLSTATE
  283. %token <keyword> K_REVERSE
  284. %token <keyword> K_ROWTYPE
  285. %token <keyword> K_ROW_COUNT
  286. %token <keyword> K_SCROLL
  287. %token <keyword> K_SLICE
  288. %token <keyword> K_SQLSTATE
  289. %token <keyword> K_STACKED
  290. %token <keyword> K_STRICT
  291. %token <keyword> K_THEN
  292. %token <keyword> K_TO
  293. %token <keyword> K_TYPE
  294. %token <keyword> K_USE_COLUMN
  295. %token <keyword> K_USE_VARIABLE
  296. %token <keyword> K_USING
  297. %token <keyword> K_VARIABLE_CONFLICT
  298. %token <keyword> K_WARNING
  299. %token <keyword> K_WHEN
  300. %token <keyword> K_WHILE
  301. %%
  302. pl_function : comp_options pl_block opt_semi
  303. {
  304. plpgsql_parse_result = (PLpgSQL_stmt_block *) $2;
  305. }
  306. ;
  307. comp_options :
  308. | comp_options comp_option
  309. ;
  310. comp_option : '#' K_OPTION K_DUMP
  311. {
  312. plpgsql_DumpExecTree = true;
  313. }
  314. | '#' K_VARIABLE_CONFLICT K_ERROR
  315. {
  316. plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_ERROR;
  317. }
  318. | '#' K_VARIABLE_CONFLICT K_USE_VARIABLE
  319. {
  320. plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_VARIABLE;
  321. }
  322. | '#' K_VARIABLE_CONFLICT K_USE_COLUMN
  323. {
  324. plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_COLUMN;
  325. }
  326. ;
  327. opt_semi :
  328. | ';'
  329. ;
  330. pl_block : decl_sect K_BEGIN proc_sect exception_sect K_END opt_label
  331. {
  332. PLpgSQL_stmt_block *new;
  333. new = palloc0(sizeof(PLpgSQL_stmt_block));
  334. new->cmd_type = PLPGSQL_STMT_BLOCK;
  335. new->lineno = plpgsql_location_to_lineno(@2);
  336. new->label = $1.label;
  337. new->n_initvars = $1.n_initvars;
  338. new->initvarnos = $1.initvarnos;
  339. new->body = $3;
  340. new->exceptions = $4;
  341. check_labels($1.label, $6, @6);
  342. plpgsql_ns_pop();
  343. $$ = (PLpgSQL_stmt *)new;
  344. }
  345. ;
  346. decl_sect : opt_block_label
  347. {
  348. /* done with decls, so resume identifier lookup */
  349. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  350. $$.label = $1;
  351. $$.n_initvars = 0;
  352. $$.initvarnos = NULL;
  353. }
  354. | opt_block_label decl_start
  355. {
  356. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  357. $$.label = $1;
  358. $$.n_initvars = 0;
  359. $$.initvarnos = NULL;
  360. }
  361. | opt_block_label decl_start decl_stmts
  362. {
  363. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  364. $$.label = $1;
  365. /* Remember variables declared in decl_stmts */
  366. $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
  367. }
  368. ;
  369. decl_start : K_DECLARE
  370. {
  371. /* Forget any variables created before block */
  372. plpgsql_add_initdatums(NULL);
  373. /*
  374. * Disable scanner lookup of identifiers while
  375. * we process the decl_stmts
  376. */
  377. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
  378. }
  379. ;
  380. decl_stmts : decl_stmts decl_stmt
  381. | decl_stmt
  382. ;
  383. decl_stmt : decl_statement
  384. | K_DECLARE
  385. {
  386. /* We allow useless extra DECLAREs */
  387. }
  388. | LESS_LESS any_identifier GREATER_GREATER
  389. {
  390. /*
  391. * Throw a helpful error if user tries to put block
  392. * label just before BEGIN, instead of before DECLARE.
  393. */
  394. ereport(ERROR,
  395. (errcode(ERRCODE_SYNTAX_ERROR),
  396. errmsg("block label must be placed before DECLARE, not after"),
  397. parser_errposition(@1)));
  398. }
  399. ;
  400. decl_statement : decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval
  401. {
  402. PLpgSQL_variable *var;
  403. /*
  404. * If a collation is supplied, insert it into the
  405. * datatype. We assume decl_datatype always returns
  406. * a freshly built struct not shared with other
  407. * variables.
  408. */
  409. if (OidIsValid($4))
  410. {
  411. if (!OidIsValid($3->collation))
  412. ereport(ERROR,
  413. (errcode(ERRCODE_DATATYPE_MISMATCH),
  414. errmsg("collations are not supported by type %s",
  415. format_type_be($3->typoid)),
  416. parser_errposition(@4)));
  417. $3->collation = $4;
  418. }
  419. var = plpgsql_build_variable($1.name, $1.lineno,
  420. $3, true);
  421. if ($2)
  422. {
  423. if (var->dtype == PLPGSQL_DTYPE_VAR)
  424. ((PLpgSQL_var *) var)->isconst = $2;
  425. else
  426. ereport(ERROR,
  427. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  428. errmsg("row or record variable cannot be CONSTANT"),
  429. parser_errposition(@2)));
  430. }
  431. if ($5)
  432. {
  433. if (var->dtype == PLPGSQL_DTYPE_VAR)
  434. ((PLpgSQL_var *) var)->notnull = $5;
  435. else
  436. ereport(ERROR,
  437. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  438. errmsg("row or record variable cannot be NOT NULL"),
  439. parser_errposition(@4)));
  440. }
  441. if ($6 != NULL)
  442. {
  443. if (var->dtype == PLPGSQL_DTYPE_VAR)
  444. ((PLpgSQL_var *) var)->default_val = $6;
  445. else
  446. ereport(ERROR,
  447. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  448. errmsg("default value for row or record variable is not supported"),
  449. parser_errposition(@5)));
  450. }
  451. }
  452. | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
  453. {
  454. plpgsql_ns_additem($4->itemtype,
  455. $4->itemno, $1.name);
  456. }
  457. | decl_varname opt_scrollable K_CURSOR
  458. { plpgsql_ns_push($1.name); }
  459. decl_cursor_args decl_is_for decl_cursor_query
  460. {
  461. PLpgSQL_var *new;
  462. PLpgSQL_expr *curname_def;
  463. char buf[1024];
  464. char *cp1;
  465. char *cp2;
  466. /* pop local namespace for cursor args */
  467. plpgsql_ns_pop();
  468. new = (PLpgSQL_var *)
  469. plpgsql_build_variable($1.name, $1.lineno,
  470. plpgsql_build_datatype(REFCURSOROID,
  471. -1,
  472. InvalidOid),
  473. true);
  474. curname_def = palloc0(sizeof(PLpgSQL_expr));
  475. curname_def->dtype = PLPGSQL_DTYPE_EXPR;
  476. strcpy(buf, "SELECT ");
  477. cp1 = new->refname;
  478. cp2 = buf + strlen(buf);
  479. /*
  480. * Don't trust standard_conforming_strings here;
  481. * it might change before we use the string.
  482. */
  483. if (strchr(cp1, '\\') != NULL)
  484. *cp2++ = ESCAPE_STRING_SYNTAX;
  485. *cp2++ = '\'';
  486. while (*cp1)
  487. {
  488. if (SQL_STR_DOUBLE(*cp1, true))
  489. *cp2++ = *cp1;
  490. *cp2++ = *cp1++;
  491. }
  492. strcpy(cp2, "'::pg_catalog.refcursor");
  493. curname_def->query = pstrdup(buf);
  494. new->default_val = curname_def;
  495. new->cursor_explicit_expr = $7;
  496. if ($5 == NULL)
  497. new->cursor_explicit_argrow = -1;
  498. else
  499. new->cursor_explicit_argrow = $5->dno;
  500. new->cursor_options = CURSOR_OPT_FAST_PLAN | $2;
  501. }
  502. ;
  503. opt_scrollable :
  504. {
  505. $$ = 0;
  506. }
  507. | K_NO K_SCROLL
  508. {
  509. $$ = CURSOR_OPT_NO_SCROLL;
  510. }
  511. | K_SCROLL
  512. {
  513. $$ = CURSOR_OPT_SCROLL;
  514. }
  515. ;
  516. decl_cursor_query :
  517. {
  518. $$ = read_sql_stmt("");
  519. }
  520. ;
  521. decl_cursor_args :
  522. {
  523. $$ = NULL;
  524. }
  525. | '(' decl_cursor_arglist ')'
  526. {
  527. PLpgSQL_row *new;
  528. int i;
  529. ListCell *l;
  530. new = palloc0(sizeof(PLpgSQL_row));
  531. new->dtype = PLPGSQL_DTYPE_ROW;
  532. new->lineno = plpgsql_location_to_lineno(@1);
  533. new->rowtupdesc = NULL;
  534. new->nfields = list_length($2);
  535. new->fieldnames = palloc(new->nfields * sizeof(char *));
  536. new->varnos = palloc(new->nfields * sizeof(int));
  537. i = 0;
  538. foreach (l, $2)
  539. {
  540. PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
  541. new->fieldnames[i] = arg->refname;
  542. new->varnos[i] = arg->dno;
  543. i++;
  544. }
  545. list_free($2);
  546. plpgsql_adddatum((PLpgSQL_datum *) new);
  547. $$ = (PLpgSQL_datum *) new;
  548. }
  549. ;
  550. decl_cursor_arglist : decl_cursor_arg
  551. {
  552. $$ = list_make1($1);
  553. }
  554. | decl_cursor_arglist ',' decl_cursor_arg
  555. {
  556. $$ = lappend($1, $3);
  557. }
  558. ;
  559. decl_cursor_arg : decl_varname decl_datatype
  560. {
  561. $$ = (PLpgSQL_datum *)
  562. plpgsql_build_variable($1.name, $1.lineno,
  563. $2, true);
  564. }
  565. ;
  566. decl_is_for : K_IS | /* Oracle */
  567. K_FOR; /* SQL standard */
  568. decl_aliasitem : T_WORD
  569. {
  570. PLpgSQL_nsitem *nsi;
  571. nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
  572. $1.ident, NULL, NULL,
  573. NULL);
  574. if (nsi == NULL)
  575. ereport(ERROR,
  576. (errcode(ERRCODE_UNDEFINED_OBJECT),
  577. errmsg("variable \"%s\" does not exist",
  578. $1.ident),
  579. parser_errposition(@1)));
  580. $$ = nsi;
  581. }
  582. | T_CWORD
  583. {
  584. PLpgSQL_nsitem *nsi;
  585. if (list_length($1.idents) == 2)
  586. nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
  587. strVal(linitial($1.idents)),
  588. strVal(lsecond($1.idents)),
  589. NULL,
  590. NULL);
  591. else if (list_length($1.idents) == 3)
  592. nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
  593. strVal(linitial($1.idents)),
  594. strVal(lsecond($1.idents)),
  595. strVal(lthird($1.idents)),
  596. NULL);
  597. else
  598. nsi = NULL;
  599. if (nsi == NULL)
  600. ereport(ERROR,
  601. (errcode(ERRCODE_UNDEFINED_OBJECT),
  602. errmsg("variable \"%s\" does not exist",
  603. NameListToString($1.idents)),
  604. parser_errposition(@1)));
  605. $$ = nsi;
  606. }
  607. ;
  608. decl_varname : T_WORD
  609. {
  610. $$.name = $1.ident;
  611. $$.lineno = plpgsql_location_to_lineno(@1);
  612. /*
  613. * Check to make sure name isn't already declared
  614. * in the current block.
  615. */
  616. if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
  617. $1.ident, NULL, NULL,
  618. NULL) != NULL)
  619. yyerror("duplicate declaration");
  620. }
  621. | unreserved_keyword
  622. {
  623. $$.name = pstrdup($1);
  624. $$.lineno = plpgsql_location_to_lineno(@1);
  625. /*
  626. * Check to make sure name isn't already declared
  627. * in the current block.
  628. */
  629. if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
  630. $1, NULL, NULL,
  631. NULL) != NULL)
  632. yyerror("duplicate declaration");
  633. }
  634. ;
  635. decl_const :
  636. { $$ = false; }
  637. | K_CONSTANT
  638. { $$ = true; }
  639. ;
  640. decl_datatype :
  641. {
  642. /*
  643. * If there's a lookahead token, read_datatype
  644. * should consume it.
  645. */
  646. $$ = read_datatype(yychar);
  647. yyclearin;
  648. }
  649. ;
  650. decl_collate :
  651. { $$ = InvalidOid; }
  652. | K_COLLATE T_WORD
  653. {
  654. $$ = get_collation_oid(list_make1(makeString($2.ident)),
  655. false);
  656. }
  657. | K_COLLATE T_CWORD
  658. {
  659. $$ = get_collation_oid($2.idents, false);
  660. }
  661. ;
  662. decl_notnull :
  663. { $$ = false; }
  664. | K_NOT K_NULL
  665. { $$ = true; }
  666. ;
  667. decl_defval : ';'
  668. { $$ = NULL; }
  669. | decl_defkey
  670. {
  671. $$ = read_sql_expression(';', ";");
  672. }
  673. ;
  674. decl_defkey : assign_operator
  675. | K_DEFAULT
  676. ;
  677. assign_operator : '='
  678. | COLON_EQUALS
  679. ;
  680. proc_sect :
  681. { $$ = NIL; }
  682. | proc_stmts
  683. { $$ = $1; }
  684. ;
  685. proc_stmts : proc_stmts proc_stmt
  686. {
  687. if ($2 == NULL)
  688. $$ = $1;
  689. else
  690. $$ = lappend($1, $2);
  691. }
  692. | proc_stmt
  693. {
  694. if ($1 == NULL)
  695. $$ = NIL;
  696. else
  697. $$ = list_make1($1);
  698. }
  699. ;
  700. proc_stmt : pl_block ';'
  701. { $$ = $1; }
  702. | stmt_assign
  703. { $$ = $1; }
  704. | stmt_if
  705. { $$ = $1; }
  706. | stmt_case
  707. { $$ = $1; }
  708. | stmt_loop
  709. { $$ = $1; }
  710. | stmt_while
  711. { $$ = $1; }
  712. | stmt_for
  713. { $$ = $1; }
  714. | stmt_foreach_a
  715. { $$ = $1; }
  716. | stmt_exit
  717. { $$ = $1; }
  718. | stmt_return
  719. { $$ = $1; }
  720. | stmt_raise
  721. { $$ = $1; }
  722. | stmt_execsql
  723. { $$ = $1; }
  724. | stmt_dynexecute
  725. { $$ = $1; }
  726. | stmt_perform
  727. { $$ = $1; }
  728. | stmt_getdiag
  729. { $$ = $1; }
  730. | stmt_open
  731. { $$ = $1; }
  732. | stmt_fetch
  733. { $$ = $1; }
  734. | stmt_move
  735. { $$ = $1; }
  736. | stmt_close
  737. { $$ = $1; }
  738. | stmt_null
  739. { $$ = $1; }
  740. ;
  741. stmt_perform : K_PERFORM expr_until_semi
  742. {
  743. PLpgSQL_stmt_perform *new;
  744. new = palloc0(sizeof(PLpgSQL_stmt_perform));
  745. new->cmd_type = PLPGSQL_STMT_PERFORM;
  746. new->lineno = plpgsql_location_to_lineno(@1);
  747. new->expr = $2;
  748. $$ = (PLpgSQL_stmt *)new;
  749. }
  750. ;
  751. stmt_assign : assign_var assign_operator expr_until_semi
  752. {
  753. PLpgSQL_stmt_assign *new;
  754. new = palloc0(sizeof(PLpgSQL_stmt_assign));
  755. new->cmd_type = PLPGSQL_STMT_ASSIGN;
  756. new->lineno = plpgsql_location_to_lineno(@1);
  757. new->varno = $1;
  758. new->expr = $3;
  759. $$ = (PLpgSQL_stmt *)new;
  760. }
  761. ;
  762. stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
  763. {
  764. PLpgSQL_stmt_getdiag *new;
  765. ListCell *lc;
  766. new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
  767. new->cmd_type = PLPGSQL_STMT_GETDIAG;
  768. new->lineno = plpgsql_location_to_lineno(@1);
  769. new->is_stacked = $2;
  770. new->diag_items = $4;
  771. /*
  772. * Check information items are valid for area option.
  773. */
  774. foreach(lc, new->diag_items)
  775. {
  776. PLpgSQL_diag_item *ditem = (PLpgSQL_diag_item *) lfirst(lc);
  777. switch (ditem->kind)
  778. {
  779. /* these fields are disallowed in stacked case */
  780. case PLPGSQL_GETDIAG_ROW_COUNT:
  781. case PLPGSQL_GETDIAG_RESULT_OID:
  782. if (new->is_stacked)
  783. ereport(ERROR,
  784. (errcode(ERRCODE_SYNTAX_ERROR),
  785. errmsg("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS",
  786. plpgsql_getdiag_kindname(ditem->kind)),
  787. parser_errposition(@1)));
  788. break;
  789. /* these fields are disallowed in current case */
  790. case PLPGSQL_GETDIAG_ERROR_CONTEXT:
  791. case PLPGSQL_GETDIAG_ERROR_DETAIL:
  792. case PLPGSQL_GETDIAG_ERROR_HINT:
  793. case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
  794. case PLPGSQL_GETDIAG_MESSAGE_TEXT:
  795. if (!new->is_stacked)
  796. ereport(ERROR,
  797. (errcode(ERRCODE_SYNTAX_ERROR),
  798. errmsg("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS",
  799. plpgsql_getdiag_kindname(ditem->kind)),
  800. parser_errposition(@1)));
  801. break;
  802. default:
  803. elog(ERROR, "unrecognized diagnostic item kind: %d",
  804. ditem->kind);
  805. break;
  806. }
  807. }
  808. $$ = (PLpgSQL_stmt *)new;
  809. }
  810. ;
  811. getdiag_area_opt :
  812. {
  813. $$ = false;
  814. }
  815. | K_CURRENT
  816. {
  817. $$ = false;
  818. }
  819. | K_STACKED
  820. {
  821. $$ = true;
  822. }
  823. ;
  824. getdiag_list : getdiag_list ',' getdiag_list_item
  825. {
  826. $$ = lappend($1, $3);
  827. }
  828. | getdiag_list_item
  829. {
  830. $$ = list_make1($1);
  831. }
  832. ;
  833. getdiag_list_item : getdiag_target assign_operator getdiag_item
  834. {
  835. PLpgSQL_diag_item *new;
  836. new = palloc(sizeof(PLpgSQL_diag_item));
  837. new->target = $1;
  838. new->kind = $3;
  839. $$ = new;
  840. }
  841. ;
  842. getdiag_item :
  843. {
  844. int tok = yylex();
  845. if (tok_is_keyword(tok, &yylval,
  846. K_ROW_COUNT, "row_count"))
  847. $$ = PLPGSQL_GETDIAG_ROW_COUNT;
  848. else if (tok_is_keyword(tok, &yylval,
  849. K_RESULT_OID, "result_oid"))
  850. $$ = PLPGSQL_GETDIAG_RESULT_OID;
  851. else if (tok_is_keyword(tok, &yylval,
  852. K_PG_EXCEPTION_DETAIL, "pg_exception_detail"))
  853. $$ = PLPGSQL_GETDIAG_ERROR_DETAIL;
  854. else if (tok_is_keyword(tok, &yylval,
  855. K_PG_EXCEPTION_HINT, "pg_exception_hint"))
  856. $$ = PLPGSQL_GETDIAG_ERROR_HINT;
  857. else if (tok_is_keyword(tok, &yylval,
  858. K_PG_EXCEPTION_CONTEXT, "pg_exception_context"))
  859. $$ = PLPGSQL_GETDIAG_ERROR_CONTEXT;
  860. else if (tok_is_keyword(tok, &yylval,
  861. K_MESSAGE_TEXT, "message_text"))
  862. $$ = PLPGSQL_GETDIAG_MESSAGE_TEXT;
  863. else if (tok_is_keyword(tok, &yylval,
  864. K_RETURNED_SQLSTATE, "returned_sqlstate"))
  865. $$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE;
  866. else
  867. yyerror("unrecognized GET DIAGNOSTICS item");
  868. }
  869. ;
  870. getdiag_target : T_DATUM
  871. {
  872. check_assignable($1.datum, @1);
  873. if ($1.datum->dtype == PLPGSQL_DTYPE_ROW ||
  874. $1.datum->dtype == PLPGSQL_DTYPE_REC)
  875. ereport(ERROR,
  876. (errcode(ERRCODE_SYNTAX_ERROR),
  877. errmsg("\"%s\" is not a scalar variable",
  878. NameOfDatum(&($1))),
  879. parser_errposition(@1)));
  880. $$ = $1.datum->dno;
  881. }
  882. | T_WORD
  883. {
  884. /* just to give a better message than "syntax error" */
  885. word_is_not_variable(&($1), @1);
  886. }
  887. | T_CWORD
  888. {
  889. /* just to give a better message than "syntax error" */
  890. cword_is_not_variable(&($1), @1);
  891. }
  892. ;
  893. assign_var : T_DATUM
  894. {
  895. check_assignable($1.datum, @1);
  896. $$ = $1.datum->dno;
  897. }
  898. | assign_var '[' expr_until_rightbracket
  899. {
  900. PLpgSQL_arrayelem *new;
  901. new = palloc0(sizeof(PLpgSQL_arrayelem));
  902. new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
  903. new->subscript = $3;
  904. new->arrayparentno = $1;
  905. /* initialize cached type data to "not valid" */
  906. new->parenttypoid = InvalidOid;
  907. plpgsql_adddatum((PLpgSQL_datum *) new);
  908. $$ = new->dno;
  909. }
  910. ;
  911. stmt_if : K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';'
  912. {
  913. PLpgSQL_stmt_if *new;
  914. new = palloc0(sizeof(PLpgSQL_stmt_if));
  915. new->cmd_type = PLPGSQL_STMT_IF;
  916. new->lineno = plpgsql_location_to_lineno(@1);
  917. new->cond = $2;
  918. new->then_body = $3;
  919. new->elsif_list = $4;
  920. new->else_body = $5;
  921. $$ = (PLpgSQL_stmt *)new;
  922. }
  923. ;
  924. stmt_elsifs :
  925. {
  926. $$ = NIL;
  927. }
  928. | stmt_elsifs K_ELSIF expr_until_then proc_sect
  929. {
  930. PLpgSQL_if_elsif *new;
  931. new = palloc0(sizeof(PLpgSQL_if_elsif));
  932. new->lineno = plpgsql_location_to_lineno(@2);
  933. new->cond = $3;
  934. new->stmts = $4;
  935. $$ = lappend($1, new);
  936. }
  937. ;
  938. stmt_else :
  939. {
  940. $$ = NIL;
  941. }
  942. | K_ELSE proc_sect
  943. {
  944. $$ = $2;
  945. }
  946. ;
  947. stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';'
  948. {
  949. $$ = make_case(@1, $2, $3, $4);
  950. }
  951. ;
  952. opt_expr_until_when :
  953. {
  954. PLpgSQL_expr *expr = NULL;
  955. int tok = yylex();
  956. if (tok != K_WHEN)
  957. {
  958. plpgsql_push_back_token(tok);
  959. expr = read_sql_expression(K_WHEN, "WHEN");
  960. }
  961. plpgsql_push_back_token(K_WHEN);
  962. $$ = expr;
  963. }
  964. ;
  965. case_when_list : case_when_list case_when
  966. {
  967. $$ = lappend($1, $2);
  968. }
  969. | case_when
  970. {
  971. $$ = list_make1($1);
  972. }
  973. ;
  974. case_when : K_WHEN expr_until_then proc_sect
  975. {
  976. PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when));
  977. new->lineno = plpgsql_location_to_lineno(@1);
  978. new->expr = $2;
  979. new->stmts = $3;
  980. $$ = new;
  981. }
  982. ;
  983. opt_case_else :
  984. {
  985. $$ = NIL;
  986. }
  987. | K_ELSE proc_sect
  988. {
  989. /*
  990. * proc_sect could return an empty list, but we
  991. * must distinguish that from not having ELSE at all.
  992. * Simplest fix is to return a list with one NULL
  993. * pointer, which make_case() must take care of.
  994. */
  995. if ($2 != NIL)
  996. $$ = $2;
  997. else
  998. $$ = list_make1(NULL);
  999. }
  1000. ;
  1001. stmt_loop : opt_block_label K_LOOP loop_body
  1002. {
  1003. PLpgSQL_stmt_loop *new;
  1004. new = palloc0(sizeof(PLpgSQL_stmt_loop));
  1005. new->cmd_type = PLPGSQL_STMT_LOOP;
  1006. new->lineno = plpgsql_location_to_lineno(@2);
  1007. new->label = $1;
  1008. new->body = $3.stmts;
  1009. check_labels($1, $3.end_label, $3.end_label_location);
  1010. plpgsql_ns_pop();
  1011. $$ = (PLpgSQL_stmt *)new;
  1012. }
  1013. ;
  1014. stmt_while : opt_block_label K_WHILE expr_until_loop loop_body
  1015. {
  1016. PLpgSQL_stmt_while *new;
  1017. new = palloc0(sizeof(PLpgSQL_stmt_while));
  1018. new->cmd_type = PLPGSQL_STMT_WHILE;
  1019. new->lineno = plpgsql_location_to_lineno(@2);
  1020. new->label = $1;
  1021. new->cond = $3;
  1022. new->body = $4.stmts;
  1023. check_labels($1, $4.end_label, $4.end_label_location);
  1024. plpgsql_ns_pop();
  1025. $$ = (PLpgSQL_stmt *)new;
  1026. }
  1027. ;
  1028. stmt_for : opt_block_label K_FOR for_control loop_body
  1029. {
  1030. /* This runs after we've scanned the loop body */
  1031. if ($3->cmd_type == PLPGSQL_STMT_FORI)
  1032. {
  1033. PLpgSQL_stmt_fori *new;
  1034. new = (PLpgSQL_stmt_fori *) $3;
  1035. new->lineno = plpgsql_location_to_lineno(@2);
  1036. new->label = $1;
  1037. new->body = $4.stmts;
  1038. $$ = (PLpgSQL_stmt *) new;
  1039. }
  1040. else
  1041. {
  1042. PLpgSQL_stmt_forq *new;
  1043. Assert($3->cmd_type == PLPGSQL_STMT_FORS ||
  1044. $3->cmd_type == PLPGSQL_STMT_FORC ||
  1045. $3->cmd_type == PLPGSQL_STMT_DYNFORS);
  1046. /* forq is the common supertype of all three */
  1047. new = (PLpgSQL_stmt_forq *) $3;
  1048. new->lineno = plpgsql_location_to_lineno(@2);
  1049. new->label = $1;
  1050. new->body = $4.stmts;
  1051. $$ = (PLpgSQL_stmt *) new;
  1052. }
  1053. check_labels($1, $4.end_label, $4.end_label_location);
  1054. /* close namespace started in opt_block_label */
  1055. plpgsql_ns_pop();
  1056. }
  1057. ;
  1058. for_control : for_variable K_IN
  1059. {
  1060. int tok = yylex();
  1061. int tokloc = yylloc;
  1062. if (tok == K_EXECUTE)
  1063. {
  1064. /* EXECUTE means it's a dynamic FOR loop */
  1065. PLpgSQL_stmt_dynfors *new;
  1066. PLpgSQL_expr *expr;
  1067. int term;
  1068. expr = read_sql_expression2(K_LOOP, K_USING,
  1069. "LOOP or USING",
  1070. &term);
  1071. new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
  1072. new->cmd_type = PLPGSQL_STMT_DYNFORS;
  1073. if ($1.rec)
  1074. {
  1075. new->rec = $1.rec;
  1076. check_assignable((PLpgSQL_datum *) new->rec, @1);
  1077. }
  1078. else if ($1.row)
  1079. {
  1080. new->row = $1.row;
  1081. check_assignable((PLpgSQL_datum *) new->row, @1);
  1082. }
  1083. else if ($1.scalar)
  1084. {
  1085. /* convert single scalar to list */
  1086. new->row = make_scalar_list1($1.name, $1.scalar,
  1087. $1.lineno, @1);
  1088. /* no need for check_assignable */
  1089. }
  1090. else
  1091. {
  1092. ereport(ERROR,
  1093. (errcode(ERRCODE_DATATYPE_MISMATCH),
  1094. errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
  1095. parser_errposition(@1)));
  1096. }
  1097. new->query = expr;
  1098. if (term == K_USING)
  1099. {
  1100. do
  1101. {
  1102. expr = read_sql_expression2(',', K_LOOP,
  1103. ", or LOOP",
  1104. &term);
  1105. new->params = lappend(new->params, expr);
  1106. } while (term == ',');
  1107. }
  1108. $$ = (PLpgSQL_stmt *) new;
  1109. }
  1110. else if (tok == T_DATUM &&
  1111. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR &&
  1112. ((PLpgSQL_var *) yylval.wdatum.datum)->datatype->typoid == REFCURSOROID)
  1113. {
  1114. /* It's FOR var IN cursor */
  1115. PLpgSQL_stmt_forc *new;
  1116. PLpgSQL_var *cursor = (PLpgSQL_var *) yylval.wdatum.datum;
  1117. new = (PLpgSQL_stmt_forc *) palloc0(sizeof(PLpgSQL_stmt_forc));
  1118. new->cmd_type = PLPGSQL_STMT_FORC;
  1119. new->curvar = cursor->dno;
  1120. /* Should have had a single variable name */
  1121. if ($1.scalar && $1.row)
  1122. ereport(ERROR,
  1123. (errcode(ERRCODE_SYNTAX_ERROR),
  1124. errmsg("cursor FOR loop must have only one target variable"),
  1125. parser_errposition(@1)));
  1126. /* can't use an unbound cursor this way */
  1127. if (cursor->cursor_explicit_expr == NULL)
  1128. ereport(ERROR,
  1129. (errcode(ERRCODE_SYNTAX_ERROR),
  1130. errmsg("cursor FOR loop must use a bound cursor variable"),
  1131. parser_errposition(tokloc)));
  1132. /* collect cursor's parameters if any */
  1133. new->argquery = read_cursor_args(cursor,
  1134. K_LOOP,
  1135. "LOOP");
  1136. /* create loop's private RECORD variable */
  1137. new->rec = plpgsql_build_record($1.name,
  1138. $1.lineno,
  1139. true);
  1140. $$ = (PLpgSQL_stmt *) new;
  1141. }
  1142. else
  1143. {
  1144. PLpgSQL_expr *expr1;
  1145. int expr1loc;
  1146. bool reverse = false;
  1147. /*
  1148. * We have to distinguish between two
  1149. * alternatives: FOR var IN a .. b and FOR
  1150. * var IN query. Unfortunately this is
  1151. * tricky, since the query in the second
  1152. * form needn't start with a SELECT
  1153. * keyword. We use the ugly hack of
  1154. * looking for two periods after the first
  1155. * token. We also check for the REVERSE
  1156. * keyword, which means it must be an
  1157. * integer loop.
  1158. */
  1159. if (tok_is_keyword(tok, &yylval,
  1160. K_REVERSE, "reverse"))
  1161. reverse = true;
  1162. else
  1163. plpgsql_push_back_token(tok);
  1164. /*
  1165. * Read tokens until we see either a ".."
  1166. * or a LOOP. The text we read may not
  1167. * necessarily be a well-formed SQL
  1168. * statement, so we need to invoke
  1169. * read_sql_construct directly.
  1170. */
  1171. expr1 = read_sql_construct(DOT_DOT,
  1172. K_LOOP,
  1173. 0,
  1174. "LOOP",
  1175. "SELECT ",
  1176. true,
  1177. false,
  1178. true,
  1179. &expr1loc,
  1180. &tok);
  1181. if (tok == DOT_DOT)
  1182. {
  1183. /* Saw "..", so it must be an integer loop */
  1184. PLpgSQL_expr *expr2;
  1185. PLpgSQL_expr *expr_by;
  1186. PLpgSQL_var *fvar;
  1187. PLpgSQL_stmt_fori *new;
  1188. /* Check first expression is well-formed */
  1189. check_sql_expr(expr1->query, expr1loc, 7);
  1190. /* Read and check the second one */
  1191. expr2 = read_sql_expression2(K_LOOP, K_BY,
  1192. "LOOP",
  1193. &tok);
  1194. /* Get the BY clause if any */
  1195. if (tok == K_BY)
  1196. expr_by = read_sql_expression(K_LOOP,
  1197. "LOOP");
  1198. else
  1199. expr_by = NULL;
  1200. /* Should have had a single variable name */
  1201. if ($1.scalar && $1.row)
  1202. ereport(ERROR,
  1203. (errcode(ERRCODE_SYNTAX_ERROR),
  1204. errmsg("integer FOR loop must have only one target variable"),
  1205. parser_errposition(@1)));
  1206. /* create loop's private variable */
  1207. fvar = (PLpgSQL_var *)
  1208. plpgsql_build_variable($1.name,
  1209. $1.lineno,
  1210. plpgsql_build_datatype(INT4OID,
  1211. -1,
  1212. InvalidOid),
  1213. true);
  1214. new = palloc0(sizeof(PLpgSQL_stmt_fori));
  1215. new->cmd_type = PLPGSQL_STMT_FORI;
  1216. new->var = fvar;
  1217. new->reverse = reverse;
  1218. new->lower = expr1;
  1219. new->upper = expr2;
  1220. new->step = expr_by;
  1221. $$ = (PLpgSQL_stmt *) new;
  1222. }
  1223. else
  1224. {
  1225. /*
  1226. * No "..", so it must be a query loop. We've
  1227. * prefixed an extra SELECT to the query text,
  1228. * so we need to remove that before performing
  1229. * syntax checking.
  1230. */
  1231. char *tmp_query;
  1232. PLpgSQL_stmt_fors *new;
  1233. if (reverse)
  1234. ereport(ERROR,
  1235. (errcode(ERRCODE_SYNTAX_ERROR),
  1236. errmsg("cannot specify REVERSE in query FOR loop"),
  1237. parser_errposition(tokloc)));
  1238. Assert(strncmp(expr1->query, "SELECT ", 7) == 0);
  1239. tmp_query = pstrdup(expr1->query + 7);
  1240. pfree(expr1->query);
  1241. expr1->query = tmp_query;
  1242. check_sql_expr(expr1->query, expr1loc, 0);
  1243. new = palloc0(sizeof(PLpgSQL_stmt_fors));
  1244. new->cmd_type = PLPGSQL_STMT_FORS;
  1245. if ($1.rec)
  1246. {
  1247. new->rec = $1.rec;
  1248. check_assignable((PLpgSQL_datum *) new->rec, @1);
  1249. }
  1250. else if ($1.row)
  1251. {
  1252. new->row = $1.row;
  1253. check_assignable((PLpgSQL_datum *) new->row, @1);
  1254. }
  1255. else if ($1.scalar)
  1256. {
  1257. /* convert single scalar to list */
  1258. new->row = make_scalar_list1($1.name, $1.scalar,
  1259. $1.lineno, @1);
  1260. /* no need for check_assignable */
  1261. }
  1262. else
  1263. {
  1264. ereport(ERROR,
  1265. (errcode(ERRCODE_SYNTAX_ERROR),
  1266. errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
  1267. parser_errposition(@1)));
  1268. }
  1269. new->query = expr1;
  1270. $$ = (PLpgSQL_stmt *) new;
  1271. }
  1272. }
  1273. }
  1274. ;
  1275. /*
  1276. * Processing the for_variable is tricky because we don't yet know if the
  1277. * FOR is an integer FOR loop or a loop over query results. In the former
  1278. * case, the variable is just a name that we must instantiate as a loop
  1279. * local variable, regardless of any other definition it might have.
  1280. * Therefore, we always save the actual identifier into $$.name where it
  1281. * can be used for that case. We also save the outer-variable definition,
  1282. * if any, because that's what we need for the loop-over-query case. Note
  1283. * that we must NOT apply check_assignable() or any other semantic check
  1284. * until we know what's what.
  1285. *
  1286. * However, if we see a comma-separated list of names, we know that it
  1287. * can't be an integer FOR loop and so it's OK to check the variables
  1288. * immediately. In particular, for T_WORD followed by comma, we should
  1289. * complain that the name is not known rather than say it's a syntax error.
  1290. * Note that the non-error result of this case sets *both* $$.scalar and
  1291. * $$.row; see the for_control production.
  1292. */
  1293. for_variable : T_DATUM
  1294. {
  1295. $$.name = NameOfDatum(&($1));
  1296. $$.lineno = plpgsql_location_to_lineno(@1);
  1297. if ($1.datum->dtype == PLPGSQL_DTYPE_ROW)
  1298. {
  1299. $$.scalar = NULL;
  1300. $$.rec = NULL;
  1301. $$.row = (PLpgSQL_row *) $1.datum;
  1302. }
  1303. else if ($1.datum->dtype == PLPGSQL_DTYPE_REC)
  1304. {
  1305. $$.scalar = NULL;
  1306. $$.rec = (PLpgSQL_rec *) $1.datum;
  1307. $$.row = NULL;
  1308. }
  1309. else
  1310. {
  1311. int tok;
  1312. $$.scalar = $1.datum;
  1313. $$.rec = NULL;
  1314. $$.row = NULL;
  1315. /* check for comma-separated list */
  1316. tok = yylex();
  1317. plpgsql_push_back_token(tok);
  1318. if (tok == ',')
  1319. $$.row = read_into_scalar_list($$.name,
  1320. $$.scalar,
  1321. @1);
  1322. }
  1323. }
  1324. | T_WORD
  1325. {
  1326. int tok;
  1327. $$.name = $1.ident;
  1328. $$.lineno = plpgsql_location_to_lineno(@1);
  1329. $$.scalar = NULL;
  1330. $$.rec = NULL;
  1331. $$.row = NULL;
  1332. /* check for comma-separated list */
  1333. tok = yylex();
  1334. plpgsql_push_back_token(tok);
  1335. if (tok == ',')
  1336. word_is_not_variable(&($1), @1);
  1337. }
  1338. | T_CWORD
  1339. {
  1340. /* just to give a better message than "syntax error" */
  1341. cword_is_not_variable(&($1), @1);
  1342. }
  1343. ;
  1344. stmt_foreach_a : opt_block_label K_FOREACH for_variable foreach_slice K_IN K_ARRAY expr_until_loop loop_body
  1345. {
  1346. PLpgSQL_stmt_foreach_a *new;
  1347. new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
  1348. new->cmd_type = PLPGSQL_STMT_FOREACH_A;
  1349. new->lineno = plpgsql_location_to_lineno(@2);
  1350. new->label = $1;
  1351. new->slice = $4;
  1352. new->expr = $7;
  1353. new->body = $8.stmts;
  1354. if ($3.rec)
  1355. {
  1356. new->varno = $3.rec->dno;
  1357. check_assignable((PLpgSQL_datum *) $3.rec, @3);
  1358. }
  1359. else if ($3.row)
  1360. {
  1361. new->varno = $3.row->dno;
  1362. check_assignable((PLpgSQL_datum *) $3.row, @3);
  1363. }
  1364. else if ($3.scalar)
  1365. {
  1366. new->varno = $3.scalar->dno;
  1367. check_assignable($3.scalar, @3);
  1368. }
  1369. else
  1370. {
  1371. ereport(ERROR,
  1372. (errcode(ERRCODE_SYNTAX_ERROR),
  1373. errmsg("loop variable of FOREACH must be a known variable or list of variables"),
  1374. parser_errposition(@3)));
  1375. }
  1376. check_labels($1, $8.end_label, $8.end_label_location);
  1377. plpgsql_ns_pop();
  1378. $$ = (PLpgSQL_stmt *) new;
  1379. }
  1380. ;
  1381. foreach_slice :
  1382. {
  1383. $$ = 0;
  1384. }
  1385. | K_SLICE ICONST
  1386. {
  1387. $$ = $2;
  1388. }
  1389. ;
  1390. stmt_exit : exit_type opt_label opt_exitcond
  1391. {
  1392. PLpgSQL_stmt_exit *new;
  1393. new = palloc0(sizeof(PLpgSQL_stmt_exit));
  1394. new->cmd_type = PLPGSQL_STMT_EXIT;
  1395. new->is_exit = $1;
  1396. new->lineno = plpgsql_location_to_lineno(@1);
  1397. new->label = $2;
  1398. new->cond = $3;
  1399. $$ = (PLpgSQL_stmt *)new;
  1400. }
  1401. ;
  1402. exit_type : K_EXIT
  1403. {
  1404. $$ = true;
  1405. }
  1406. | K_CONTINUE
  1407. {
  1408. $$ = false;
  1409. }
  1410. ;
  1411. stmt_return : K_RETURN
  1412. {
  1413. int tok;
  1414. tok = yylex();
  1415. if (tok == 0)
  1416. yyerror("unexpected end of function definition");
  1417. if (tok_is_keyword(tok, &yylval,
  1418. K_NEXT, "next"))
  1419. {
  1420. $$ = make_return_next_stmt(@1);
  1421. }
  1422. else if (tok_is_keyword(tok, &yylval,
  1423. K_QUERY, "query"))
  1424. {
  1425. $$ = make_return_query_stmt(@1);
  1426. }
  1427. else
  1428. {
  1429. plpgsql_push_back_token(tok);
  1430. $$ = make_return_stmt(@1);
  1431. }
  1432. }
  1433. ;
  1434. stmt_raise : K_RAISE
  1435. {
  1436. PLpgSQL_stmt_raise *new;
  1437. int tok;
  1438. new = palloc(sizeof(PLpgSQL_stmt_raise));
  1439. new->cmd_type = PLPGSQL_STMT_RAISE;
  1440. new->lineno = plpgsql_location_to_lineno(@1);
  1441. new->elog_level = ERROR; /* default */
  1442. new->condname = NULL;
  1443. new->message = NULL;
  1444. new->params = NIL;
  1445. new->options = NIL;
  1446. tok = yylex();
  1447. if (tok == 0)
  1448. yyerror("unexpected end of function definition");
  1449. /*
  1450. * We could have just RAISE, meaning to re-throw
  1451. * the current error.
  1452. */
  1453. if (tok != ';')
  1454. {
  1455. /*
  1456. * First is an optional elog severity level.
  1457. */
  1458. if (tok_is_keyword(tok, &yylval,
  1459. K_EXCEPTION, "exception"))
  1460. {
  1461. new->elog_level = ERROR;
  1462. tok = yylex();
  1463. }
  1464. else if (tok_is_keyword(tok, &yylval,
  1465. K_WARNING, "warning"))
  1466. {
  1467. new->elog_level = WARNING;
  1468. tok = yylex();
  1469. }
  1470. else if (tok_is_keyword(tok, &yylval,
  1471. K_NOTICE, "notice"))
  1472. {
  1473. new->elog_level = NOTICE;
  1474. tok = yylex();
  1475. }
  1476. else if (tok_is_keyword(tok, &yylval,
  1477. K_INFO, "info"))
  1478. {
  1479. new->elog_level = INFO;
  1480. tok = yylex();
  1481. }
  1482. else if (tok_is_keyword(tok, &yylval,
  1483. K_LOG, "log"))
  1484. {
  1485. new->elog_level = LOG;
  1486. tok = yylex();
  1487. }
  1488. else if (tok_is_keyword(tok, &yylval,
  1489. K_DEBUG, "debug"))
  1490. {
  1491. new->elog_level = DEBUG1;
  1492. tok = yylex();
  1493. }
  1494. if (tok == 0)
  1495. yyerror("unexpected end of function definition");
  1496. /*
  1497. * Next we can have a condition name, or
  1498. * equivalently SQLSTATE 'xxxxx', or a string
  1499. * literal that is the old-style message format,
  1500. * or USING to start the option list immediately.
  1501. */
  1502. if (tok == SCONST)
  1503. {
  1504. /* old style message and parameters */
  1505. new->message = yylval.str;
  1506. /*
  1507. * We expect either a semi-colon, which
  1508. * indicates no parameters, or a comma that
  1509. * begins the list of parameter expressions,
  1510. * or USING to begin the options list.
  1511. */
  1512. tok = yylex();
  1513. if (tok != ',' && tok != ';' && tok != K_USING)
  1514. yyerror("syntax error");
  1515. while (tok == ',')
  1516. {
  1517. PLpgSQL_expr *expr;
  1518. expr = read_sql_construct(',', ';', K_USING,
  1519. ", or ; or USING",
  1520. "SELECT ",
  1521. true, true, true,
  1522. NULL, &tok);
  1523. new->params = lappend(new->params, expr);
  1524. }
  1525. }
  1526. else if (tok != K_USING)
  1527. {
  1528. /* must be condition name or SQLSTATE */
  1529. if (tok_is_keyword(tok, &yylval,
  1530. K_SQLSTATE, "sqlstate"))
  1531. {
  1532. /* next token should be a string literal */
  1533. char *sqlstatestr;
  1534. if (yylex() != SCONST)
  1535. yyerror("syntax error");
  1536. sqlstatestr = yylval.str;
  1537. if (strlen(sqlstatestr) != 5)
  1538. yyerror("invalid SQLSTATE code");
  1539. if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
  1540. yyerror("invalid SQLSTATE code");
  1541. new->condname = sqlstatestr;
  1542. }
  1543. else
  1544. {
  1545. if (tok != T_WORD)
  1546. yyerror("syntax error");
  1547. new->condname = yylval.word.ident;
  1548. plpgsql_recognize_err_condition(new->condname,
  1549. false);
  1550. }
  1551. tok = yylex();
  1552. if (tok != ';' && tok != K_USING)
  1553. yyerror("syntax error");
  1554. }
  1555. if (tok == K_USING)
  1556. new->options = read_raise_options();
  1557. }
  1558. $$ = (PLpgSQL_stmt *)new;
  1559. }
  1560. ;
  1561. loop_body : proc_sect K_END K_LOOP opt_label ';'
  1562. {
  1563. $$.stmts = $1;
  1564. $$.end_label = $4;
  1565. $$.end_label_location = @4;
  1566. }
  1567. ;
  1568. /*
  1569. * T_WORD+T_CWORD match any initial identifier that is not a known plpgsql
  1570. * variable. (The composite case is probably a syntax error, but we'll let
  1571. * the core parser decide that.) Normally, we should assume that such a
  1572. * word is a SQL statement keyword that isn't also a plpgsql keyword.
  1573. * However, if the next token is assignment or '[', it can't be a valid
  1574. * SQL statement, and what we're probably looking at is an intended variable
  1575. * assignment. Give an appropriate complaint for that, instead of letting
  1576. * the core parser throw an unhelpful "syntax error".
  1577. */
  1578. stmt_execsql : K_INSERT
  1579. {
  1580. $$ = make_execsql_stmt(K_INSERT, @1);
  1581. }
  1582. | T_WORD
  1583. {
  1584. int tok;
  1585. tok = yylex();
  1586. plpgsql_push_back_token(tok);
  1587. if (tok == '=' || tok == COLON_EQUALS || tok == '[')
  1588. word_is_not_variable(&($1), @1);
  1589. $$ = make_execsql_stmt(T_WORD, @1);
  1590. }
  1591. | T_CWORD
  1592. {
  1593. int tok;
  1594. tok = yylex();
  1595. plpgsql_push_back_token(tok);
  1596. if (tok == '=' || tok == COLON_EQUALS || tok == '[')
  1597. cword_is_not_variable(&($1), @1);
  1598. $$ = make_execsql_stmt(T_CWORD, @1);
  1599. }
  1600. ;
  1601. stmt_dynexecute : K_EXECUTE
  1602. {
  1603. PLpgSQL_stmt_dynexecute *new;
  1604. PLpgSQL_expr *expr;
  1605. int endtoken;
  1606. expr = read_sql_construct(K_INTO, K_USING, ';',
  1607. "INTO or USING or ;",
  1608. "SELECT ",
  1609. true, true, true,
  1610. NULL, &endtoken);
  1611. new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
  1612. new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
  1613. new->lineno = plpgsql_location_to_lineno(@1);
  1614. new->query = expr;
  1615. new->into = false;
  1616. new->strict = false;
  1617. new->rec = NULL;
  1618. new->row = NULL;
  1619. new->params = NIL;
  1620. /*
  1621. * We loop to allow the INTO and USING clauses to
  1622. * appear in either order, since people easily get
  1623. * that wrong. This coding also prevents "INTO foo"
  1624. * from getting absorbed into a USING expression,
  1625. * which is *really* confusing.
  1626. */
  1627. for (;;)
  1628. {
  1629. if (endtoken == K_INTO)
  1630. {
  1631. if (new->into) /* multiple INTO */
  1632. yyerror("syntax error");
  1633. new->into = true;
  1634. read_into_target(&new->rec, &new->row, &new->strict);
  1635. endtoken = yylex();
  1636. }
  1637. else if (endtoken == K_USING)
  1638. {
  1639. if (new->params) /* multiple USING */
  1640. yyerror("syntax error");
  1641. do
  1642. {
  1643. expr = read_sql_construct(',', ';', K_INTO,
  1644. ", or ; or INTO",
  1645. "SELECT ",
  1646. true, true, true,
  1647. NULL, &endtoken);
  1648. new->params = lappend(new->params, expr);
  1649. } while (endtoken == ',');
  1650. }
  1651. else if (endtoken == ';')
  1652. break;
  1653. else
  1654. yyerror("syntax error");
  1655. }
  1656. $$ = (PLpgSQL_stmt *)new;
  1657. }
  1658. ;
  1659. stmt_open : K_OPEN cursor_variable
  1660. {
  1661. PLpgSQL_stmt_open *new;
  1662. int tok;
  1663. new = palloc0(sizeof(PLpgSQL_stmt_open));
  1664. new->cmd_type = PLPGSQL_STMT_OPEN;
  1665. new->lineno = plpgsql_location_to_lineno(@1);
  1666. new->curvar = $2->dno;
  1667. new->cursor_options = CURSOR_OPT_FAST_PLAN;
  1668. if ($2->cursor_explicit_expr == NULL)
  1669. {
  1670. /* be nice if we could use opt_scrollable here */
  1671. tok = yylex();
  1672. if (tok_is_keyword(tok, &yylval,
  1673. K_NO, "no"))
  1674. {
  1675. tok = yylex();
  1676. if (tok_is_keyword(tok, &yylval,
  1677. K_SCROLL, "scroll"))
  1678. {
  1679. new->cursor_options |= CURSOR_OPT_NO_SCROLL;
  1680. tok = yylex();
  1681. }
  1682. }
  1683. else if (tok_is_keyword(tok, &yylval,
  1684. K_SCROLL, "scroll"))
  1685. {
  1686. new->cursor_options |= CURSOR_OPT_SCROLL;
  1687. tok = yylex();
  1688. }
  1689. if (tok != K_FOR)
  1690. yyerror("syntax error, expected \"FOR\"");
  1691. tok = yylex();
  1692. if (tok == K_EXECUTE)
  1693. {
  1694. int endtoken;
  1695. new->dynquery =
  1696. read_sql_expression2(K_USING, ';',
  1697. "USING or ;",
  1698. &endtoken);
  1699. /* If we found "USING", collect argument(s) */
  1700. if (endtoken == K_USING)
  1701. {
  1702. PLpgSQL_expr *expr;
  1703. do
  1704. {
  1705. expr = read_sql_expression2(',', ';',
  1706. ", or ;",
  1707. &endtoken);
  1708. new->params = lappend(new->params,
  1709. expr);
  1710. } while (endtoken == ',');
  1711. }
  1712. }
  1713. else
  1714. {
  1715. plpgsql_push_back_token(tok);
  1716. new->query = read_sql_stmt("");
  1717. }
  1718. }
  1719. else
  1720. {
  1721. /* predefined cursor query, so read args */
  1722. new->argquery = read_cursor_args($2, ';', ";");
  1723. }
  1724. $$ = (PLpgSQL_stmt *)new;
  1725. }
  1726. ;
  1727. stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO
  1728. {
  1729. PLpgSQL_stmt_fetch *fetch = $2;
  1730. PLpgSQL_rec *rec;
  1731. PLpgSQL_row *row;
  1732. /* We have already parsed everything through the INTO keyword */
  1733. read_into_target(&rec, &row, NULL);
  1734. if (yylex() != ';')
  1735. yyerror("syntax error");
  1736. /*
  1737. * We don't allow multiple rows in PL/pgSQL's FETCH
  1738. * statement, only in MOVE.
  1739. */
  1740. if (fetch->returns_multiple_rows)
  1741. ereport(ERROR,
  1742. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  1743. errmsg("FETCH statement cannot return multiple rows"),
  1744. parser_errposition(@1)));
  1745. fetch->lineno = plpgsql_location_to_lineno(@1);
  1746. fetch->rec = rec;
  1747. fetch->row = row;
  1748. fetch->curvar = $3->dno;
  1749. fetch->is_move = false;
  1750. $$ = (PLpgSQL_stmt *)fetch;
  1751. }
  1752. ;
  1753. stmt_move : K_MOVE opt_fetch_direction cursor_variable ';'
  1754. {
  1755. PLpgSQL_stmt_fetch *fetch = $2;
  1756. fetch->lineno = plpgsql_location_to_lineno(@1);
  1757. fetch->curvar = $3->dno;
  1758. fetch->is_move = true;
  1759. $$ = (PLpgSQL_stmt *)fetch;
  1760. }
  1761. ;
  1762. opt_fetch_direction :
  1763. {
  1764. $$ = read_fetch_direction();
  1765. }
  1766. ;
  1767. stmt_close : K_CLOSE cursor_variable ';'
  1768. {
  1769. PLpgSQL_stmt_close *new;
  1770. new = palloc(sizeof(PLpgSQL_stmt_close));
  1771. new->cmd_type = PLPGSQL_STMT_CLOSE;
  1772. new->lineno = plpgsql_location_to_lineno(@1);
  1773. new->curvar = $2->dno;
  1774. $$ = (PLpgSQL_stmt *)new;
  1775. }
  1776. ;
  1777. stmt_null : K_NULL ';'
  1778. {
  1779. /* We do not bother building a node for NULL */
  1780. $$ = NULL;
  1781. }
  1782. ;
  1783. cursor_variable : T_DATUM
  1784. {
  1785. if ($1.datum->dtype != PLPGSQL_DTYPE_VAR)
  1786. ereport(ERROR,
  1787. (errcode(ERRCODE_DATATYPE_MISMATCH),
  1788. errmsg("cursor variable must be a simple variable"),
  1789. parser_errposition(@1)));
  1790. if (((PLpgSQL_var *) $1.datum)->datatype->typoid != REFCURSOROID)
  1791. ereport(ERROR,
  1792. (errcode(ERRCODE_DATATYPE_MISMATCH),
  1793. errmsg("variable \"%s\" must be of type cursor or refcursor",
  1794. ((PLpgSQL_var *) $1.datum)->refname),
  1795. parser_errposition(@1)));
  1796. $$ = (PLpgSQL_var *) $1.datum;
  1797. }
  1798. | T_WORD
  1799. {
  1800. /* just to give a better message than "syntax error" */
  1801. word_is_not_variable(&($1), @1);
  1802. }
  1803. | T_CWORD
  1804. {
  1805. /* just to give a better message than "syntax error" */
  1806. cword_is_not_variable(&($1), @1);
  1807. }
  1808. ;
  1809. exception_sect :
  1810. { $$ = NULL; }
  1811. | K_EXCEPTION
  1812. {
  1813. /*
  1814. * We use a mid-rule action to add these
  1815. * special variables to the namespace before
  1816. * parsing the WHEN clauses themselves. The
  1817. * scope of the names extends to the end of the
  1818. * current block.
  1819. */
  1820. int lineno = plpgsql_location_to_lineno(@1);
  1821. PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block));
  1822. PLpgSQL_variable *var;
  1823. var = plpgsql_build_variable("sqlstate", lineno,
  1824. plpgsql_build_datatype(TEXTOID,
  1825. -1,
  1826. plpgsql_curr_compile->fn_input_collation),
  1827. true);
  1828. ((PLpgSQL_var *) var)->isconst = true;
  1829. new->sqlstate_varno = var->dno;
  1830. var = plpgsql_build_variable("sqlerrm", lineno,
  1831. plpgsql_build_datatype(TEXTOID,
  1832. -1,
  1833. plpgsql_curr_compile->fn_input_collation),
  1834. true);
  1835. ((PLpgSQL_var *) var)->isconst = true;
  1836. new->sqlerrm_varno = var->dno;
  1837. $<exception_block>$ = new;
  1838. }
  1839. proc_exceptions
  1840. {
  1841. PLpgSQL_exception_block *new = $<exception_block>2;
  1842. new->exc_list = $3;
  1843. $$ = new;
  1844. }
  1845. ;
  1846. proc_exceptions : proc_exceptions proc_exception
  1847. {
  1848. $$ = lappend($1, $2);
  1849. }
  1850. | proc_exception
  1851. {
  1852. $$ = list_make1($1);
  1853. }
  1854. ;
  1855. proc_exception : K_WHEN proc_conditions K_THEN proc_sect
  1856. {
  1857. PLpgSQL_exception *new;
  1858. new = palloc0(sizeof(PLpgSQL_exception));
  1859. new->lineno = plpgsql_location_to_lineno(@1);
  1860. new->conditions = $2;
  1861. new->action = $4;
  1862. $$ = new;
  1863. }
  1864. ;
  1865. proc_conditions : proc_conditions K_OR proc_condition
  1866. {
  1867. PLpgSQL_condition *old;
  1868. for (old = $1; old->next != NULL; old = old->next)
  1869. /* skip */ ;
  1870. old->next = $3;
  1871. $$ = $1;
  1872. }
  1873. | proc_condition
  1874. {
  1875. $$ = $1;
  1876. }
  1877. ;
  1878. proc_condition : any_identifier
  1879. {
  1880. if (strcmp($1, "sqlstate") != 0)
  1881. {
  1882. $$ = plpgsql_parse_err_condition($1);
  1883. }
  1884. else
  1885. {
  1886. PLpgSQL_condition *new;
  1887. char *sqlstatestr;
  1888. /* next token should be a string literal */
  1889. if (yylex() != SCONST)
  1890. yyerror("syntax error");
  1891. sqlstatestr = yylval.str;
  1892. if (strlen(sqlstatestr) != 5)
  1893. yyerror("invalid SQLSTATE code");
  1894. if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
  1895. yyerror("invalid SQLSTATE code");
  1896. new = palloc(sizeof(PLpgSQL_condition));
  1897. new->sqlerrstate =
  1898. MAKE_SQLSTATE(sqlstatestr[0],
  1899. sqlstatestr[1],
  1900. sqlstatestr[2],
  1901. sqlstatestr[3],
  1902. sqlstatestr[4]);
  1903. new->condname = sqlstatestr;
  1904. new->next = NULL;
  1905. $$ = new;
  1906. }
  1907. }
  1908. ;
  1909. expr_until_semi :
  1910. { $$ = read_sql_expression(';', ";"); }
  1911. ;
  1912. expr_until_rightbracket :
  1913. { $$ = read_sql_expression(']', "]"); }
  1914. ;
  1915. expr_until_then :
  1916. { $$ = read_sql_expression(K_THEN, "THEN"); }
  1917. ;
  1918. expr_until_loop :
  1919. { $$ = read_sql_expression(K_LOOP, "LOOP"); }
  1920. ;
  1921. opt_block_label :
  1922. {
  1923. plpgsql_ns_push(NULL);
  1924. $$ = NULL;
  1925. }
  1926. | LESS_LESS any_identifier GREATER_GREATER
  1927. {
  1928. plpgsql_ns_push($2);
  1929. $$ = $2;
  1930. }
  1931. ;
  1932. opt_label :
  1933. {
  1934. $$ = NULL;
  1935. }
  1936. | any_identifier
  1937. {
  1938. if (plpgsql_ns_lookup_label(plpgsql_ns_top(), $1) == NULL)
  1939. yyerror("label does not exist");
  1940. $$ = $1;
  1941. }
  1942. ;
  1943. opt_exitcond : ';'
  1944. { $$ = NULL; }
  1945. | K_WHEN expr_until_semi
  1946. { $$ = $2; }
  1947. ;
  1948. /*
  1949. * need both options because scanner will have tried to resolve as variable
  1950. */
  1951. any_identifier : T_WORD
  1952. {
  1953. $$ = $1.ident;
  1954. }
  1955. | T_DATUM
  1956. {
  1957. if ($1.ident == NULL) /* composite name not OK */
  1958. yyerror("syntax error");
  1959. $$ = $1.ident;
  1960. }
  1961. ;
  1962. unreserved_keyword :
  1963. K_ABSOLUTE
  1964. | K_ALIAS
  1965. | K_ARRAY
  1966. | K_BACKWARD
  1967. | K_CONSTANT
  1968. | K_CURRENT
  1969. | K_CURSOR
  1970. | K_DEBUG
  1971. | K_DETAIL
  1972. | K_DUMP
  1973. | K_ERRCODE
  1974. | K_ERROR
  1975. | K_FIRST
  1976. | K_FORWARD
  1977. | K_HINT
  1978. | K_INFO
  1979. | K_IS
  1980. | K_LAST
  1981. | K_LOG
  1982. | K_MESSAGE
  1983. | K_MESSAGE_TEXT
  1984. | K_NEXT
  1985. | K_NO
  1986. | K_NOTICE
  1987. | K_OPTION
  1988. | K_PG_EXCEPTION_CONTEXT
  1989. | K_PG_EXCEPTION_DETAIL
  1990. | K_PG_EXCEPTION_HINT
  1991. | K_PRIOR
  1992. | K_QUERY
  1993. | K_RELATIVE
  1994. | K_RESULT_OID
  1995. | K_RETURNED_SQLSTATE
  1996. | K_REVERSE
  1997. | K_ROW_COUNT
  1998. | K_ROWTYPE
  1999. | K_SCROLL
  2000. | K_SLICE
  2001. | K_SQLSTATE
  2002. | K_STACKED
  2003. | K_TYPE
  2004. | K_USE_COLUMN
  2005. | K_USE_VARIABLE
  2006. | K_VARIABLE_CONFLICT
  2007. | K_WARNING
  2008. ;
  2009. %%
  2010. /*
  2011. * Check whether a token represents an "unreserved keyword".
  2012. * We have various places where we want to recognize a keyword in preference
  2013. * to a variable name, but not reserve that keyword in other contexts.
  2014. * Hence, this kluge.
  2015. */
  2016. static bool
  2017. tok_is_keyword(int token, union YYSTYPE *lval,
  2018. int kw_token, const char *kw_str)
  2019. {
  2020. if (token == kw_token)
  2021. {
  2022. /* Normal case, was recognized by scanner (no conflicting variable) */
  2023. return true;
  2024. }
  2025. else if (token == T_DATUM)
  2026. {
  2027. /*
  2028. * It's a variable, so recheck the string name. Note we will not
  2029. * match composite names (hence an unreserved word followed by "."
  2030. * will not be recognized).
  2031. */
  2032. if (!lval->wdatum.quoted && lval->wdatum.ident != NULL &&
  2033. strcmp(lval->wdatum.ident, kw_str) == 0)
  2034. return true;
  2035. }
  2036. return false; /* not the keyword */
  2037. }
  2038. /*
  2039. * Convenience routine to complain when we expected T_DATUM and got T_WORD,
  2040. * ie, unrecognized variable.
  2041. */
  2042. static void
  2043. word_is_not_variable(PLword *word, int location)
  2044. {
  2045. ereport(ERROR,
  2046. (errcode(ERRCODE_SYNTAX_ERROR),
  2047. errmsg("\"%s\" is not a known variable",
  2048. word->ident),
  2049. parser_errposition(location)));
  2050. }
  2051. /* Same, for a CWORD */
  2052. static void
  2053. cword_is_not_variable(PLcword *cword, int location)
  2054. {
  2055. ereport(ERROR,
  2056. (errcode(ERRCODE_SYNTAX_ERROR),
  2057. errmsg("\"%s\" is not a known variable",
  2058. NameListToString(cword->idents)),
  2059. parser_errposition(location)));
  2060. }
  2061. /*
  2062. * Convenience routine to complain when we expected T_DATUM and got
  2063. * something else. "tok" must be the current token, since we also
  2064. * look at yylval and yylloc.
  2065. */
  2066. static void
  2067. current_token_is_not_variable(int tok)
  2068. {
  2069. if (tok == T_WORD)
  2070. word_is_not_variable(&(yylval.word), yylloc);
  2071. else if (tok == T_CWORD)
  2072. cword_is_not_variable(&(yylval.cword), yylloc);
  2073. else
  2074. yyerror("syntax error");
  2075. }
  2076. /* Convenience routine to read an expression with one possible terminator */
  2077. static PLpgSQL_expr *
  2078. read_sql_expression(int until, const char *expected)
  2079. {
  2080. return read_sql_construct(until, 0, 0, expected,
  2081. "SELECT ", true, true, true, NULL, NULL);
  2082. }
  2083. /* Convenience routine to read an expression with two possible terminators */
  2084. static PLpgSQL_expr *
  2085. read_sql_expression2(int until, int until2, const char *expected,
  2086. int *endtoken)
  2087. {
  2088. return read_sql_construct(until, until2, 0, expected,
  2089. "SELECT ", true, true, true, NULL, endtoken);
  2090. }
  2091. /* Convenience routine to read a SQL statement that must end with ';' */
  2092. static PLpgSQL_expr *
  2093. read_sql_stmt(const char *sqlstart)
  2094. {
  2095. return read_sql_construct(';', 0, 0, ";",
  2096. sqlstart, false, true, true, NULL, NULL);
  2097. }
  2098. /*
  2099. * Read a SQL construct and build a PLpgSQL_expr for it.
  2100. *
  2101. * until: token code for expected terminator
  2102. * until2: token code for alternate terminator (pass 0 if none)
  2103. * until3: token code for another alternate terminator (pass 0 if none)
  2104. * expected: text to use in complaining that terminator was not found
  2105. * sqlstart: text to prefix to the accumulated SQL text
  2106. * isexpression: whether to say we're reading an "expression" or a "statement"
  2107. * valid_sql: whether to check the syntax of the expr (prefixed with sqlstart)
  2108. * trim: trim trailing whitespace
  2109. * startloc: if not NULL, location of first token is stored at *startloc
  2110. * endtoken: if not NULL, ending token is stored at *endtoken
  2111. * (this is only interesting if until2 or until3 isn't zero)
  2112. */
  2113. static PLpgSQL_expr *
  2114. read_sql_construct(int until,
  2115. int until2,
  2116. int until3,
  2117. const char *expected,
  2118. const char *sqlstart,
  2119. bool isexpression,
  2120. bool valid_sql,
  2121. bool trim,
  2122. int *startloc,
  2123. int *endtoken)
  2124. {
  2125. int tok;
  2126. StringInfoData ds;
  2127. IdentifierLookup save_IdentifierLookup;
  2128. int startlocation = -1;
  2129. int parenlevel = 0;
  2130. PLpgSQL_expr *expr;
  2131. initStringInfo(&ds);
  2132. appendStringInfoString(&ds, sqlstart);
  2133. /* special lookup mode for identifiers within the SQL text */
  2134. save_IdentifierLookup = plpgsql_IdentifierLookup;
  2135. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
  2136. for (;;)
  2137. {
  2138. tok = yylex();
  2139. if (startlocation < 0) /* remember loc of first token */
  2140. startlocation = yylloc;
  2141. if (tok == until && parenlevel == 0)
  2142. break;
  2143. if (tok == until2 && parenlevel == 0)
  2144. break;
  2145. if (tok == until3 && parenlevel == 0)
  2146. break;
  2147. if (tok == '(' || tok == '[')
  2148. parenlevel++;
  2149. else if (tok == ')' || tok == ']')
  2150. {
  2151. parenlevel--;
  2152. if (parenlevel < 0)
  2153. yyerror("mismatched parentheses");
  2154. }
  2155. /*
  2156. * End of function definition is an error, and we don't expect to
  2157. * hit a semicolon either (unless it's the until symbol, in which
  2158. * case we should have fallen out above).
  2159. */
  2160. if (tok == 0 || tok == ';')
  2161. {
  2162. if (parenlevel != 0)
  2163. yyerror("mismatched parentheses");
  2164. if (isexpression)
  2165. ereport(ERROR,
  2166. (errcode(ERRCODE_SYNTAX_ERROR),
  2167. errmsg("missing \"%s\" at end of SQL expression",
  2168. expected),
  2169. parser_errposition(yylloc)));
  2170. else
  2171. ereport(ERROR,
  2172. (errcode(ERRCODE_SYNTAX_ERROR),
  2173. errmsg("missing \"%s\" at end of SQL statement",
  2174. expected),
  2175. parser_errposition(yylloc)));
  2176. }
  2177. }
  2178. plpgsql_IdentifierLookup = save_IdentifierLookup;
  2179. if (startloc)
  2180. *startloc = startlocation;
  2181. if (endtoken)
  2182. *endtoken = tok;
  2183. /* give helpful complaint about empty input */
  2184. if (startlocation >= yylloc)
  2185. {
  2186. if (isexpression)
  2187. yyerror("missing expression");
  2188. else
  2189. yyerror("missing SQL statement");
  2190. }
  2191. plpgsql_append_source_text(&ds, startlocation, yylloc);
  2192. /* trim any trailing whitespace, for neatness */
  2193. if (trim)
  2194. {
  2195. while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
  2196. ds.data[--ds.len] = '\0';
  2197. }
  2198. expr = palloc0(sizeof(PLpgSQL_expr));
  2199. expr->dtype = PLPGSQL_DTYPE_EXPR;
  2200. expr->query = pstrdup(ds.data);
  2201. expr->plan = NULL;
  2202. expr->paramnos = NULL;
  2203. expr->ns = plpgsql_ns_top();
  2204. pfree(ds.data);
  2205. if (valid_sql)
  2206. check_sql_expr(expr->query, startlocation, strlen(sqlstart));
  2207. return expr;
  2208. }
  2209. static PLpgSQL_type *
  2210. read_datatype(int tok)
  2211. {
  2212. StringInfoData ds;
  2213. char *type_name;
  2214. int startlocation;
  2215. PLpgSQL_type *result;
  2216. int parenlevel = 0;
  2217. /* Should only be called while parsing DECLARE sections */
  2218. Assert(plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_DECLARE);
  2219. /* Often there will be a lookahead token, but if not, get one */
  2220. if (tok == YYEMPTY)
  2221. tok = yylex();
  2222. startlocation = yylloc;
  2223. /*
  2224. * If we have a simple or composite identifier, check for %TYPE
  2225. * and %ROWTYPE constructs.
  2226. */
  2227. if (tok == T_WORD)
  2228. {
  2229. char *dtname = yylval.word.ident;
  2230. tok = yylex();
  2231. if (tok == '%')
  2232. {
  2233. tok = yylex();
  2234. if (tok_is_keyword(tok, &yylval,
  2235. K_TYPE, "type"))
  2236. {
  2237. result = plpgsql_parse_wordtype(dtname);
  2238. if (result)
  2239. return result;
  2240. }
  2241. else if (tok_is_keyword(tok, &yylval,
  2242. K_ROWTYPE, "rowtype"))
  2243. {
  2244. result = plpgsql_parse_wordrowtype(dtname);
  2245. if (result)
  2246. return result;
  2247. }
  2248. }
  2249. }
  2250. else if (tok == T_CWORD)
  2251. {
  2252. List *dtnames = yylval.cword.idents;
  2253. tok = yylex();
  2254. if (tok == '%')
  2255. {
  2256. tok = yylex();
  2257. if (tok_is_keyword(tok, &yylval,
  2258. K_TYPE, "type"))
  2259. {
  2260. result = plpgsql_parse_cwordtype(dtnames);
  2261. if (result)
  2262. return result;
  2263. }
  2264. else if (tok_is_keyword(tok, &yylval,
  2265. K_ROWTYPE, "rowtype"))
  2266. {
  2267. result = plpgsql_parse_cwordrowtype(dtnames);
  2268. if (result)
  2269. return result;
  2270. }
  2271. }
  2272. }
  2273. while (tok != ';')
  2274. {
  2275. if (tok == 0)
  2276. {
  2277. if (parenlevel != 0)
  2278. yyerror("mismatched parentheses");
  2279. else
  2280. yyerror("incomplete data type declaration");
  2281. }
  2282. /* Possible followers for datatype in a declaration */
  2283. if (tok == K_COLLATE || tok == K_NOT ||
  2284. tok == '=' || tok == COLON_EQUALS || tok == K_DEFAULT)
  2285. break;
  2286. /* Possible followers for datatype in a cursor_arg list */
  2287. if ((tok == ',' || tok == ')') && parenlevel == 0)
  2288. break;
  2289. if (tok == '(')
  2290. parenlevel++;
  2291. else if (tok == ')')
  2292. parenlevel--;
  2293. tok = yylex();
  2294. }
  2295. /* set up ds to contain complete typename text */
  2296. initStringInfo(&ds);
  2297. plpgsql_append_source_text(&ds, startlocation, yylloc);
  2298. type_name = ds.data;
  2299. if (type_name[0] == '\0')
  2300. yyerror("missing data type declaration");
  2301. result = parse_datatype(type_name, startlocation);
  2302. pfree(ds.data);
  2303. plpgsql_push_back_token(tok);
  2304. return result;
  2305. }
  2306. static PLpgSQL_stmt *
  2307. make_execsql_stmt(int firsttoken, int location)
  2308. {
  2309. StringInfoData ds;
  2310. IdentifierLookup save_IdentifierLookup;
  2311. PLpgSQL_stmt_execsql *execsql;
  2312. PLpgSQL_expr *expr;
  2313. PLpgSQL_row *row = NULL;
  2314. PLpgSQL_rec *rec = NULL;
  2315. int tok;
  2316. int prev_tok;
  2317. bool have_into = false;
  2318. bool have_strict = false;
  2319. int into_start_loc = -1;
  2320. int into_end_loc = -1;
  2321. initStringInfo(&ds);
  2322. /* special lookup mode for identifiers within the SQL text */
  2323. save_IdentifierLookup = plpgsql_IdentifierLookup;
  2324. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
  2325. /*
  2326. * We have to special-case the sequence INSERT INTO, because we don't want
  2327. * that to be taken as an INTO-variables clause. Fortunately, this is the
  2328. * only valid use of INTO in a pl/pgsql SQL command, and INTO is already a
  2329. * fully reserved word in the main grammar. We have to treat it that way
  2330. * anywhere in the string, not only at the start; consider CREATE RULE
  2331. * containing an INSERT statement.
  2332. */
  2333. tok = firsttoken;
  2334. for (;;)
  2335. {
  2336. prev_tok = tok;
  2337. tok = yylex();
  2338. if (have_into && into_end_loc < 0)
  2339. into_end_loc = yylloc; /* token after the INTO part */
  2340. if (tok == ';')
  2341. break;
  2342. if (tok == 0)
  2343. yyerror("unexpected end of function definition");
  2344. if (tok == K_INTO && prev_tok != K_INSERT)
  2345. {
  2346. if (have_into)
  2347. yyerror("INTO specified more than once");
  2348. have_into = true;
  2349. into_start_loc = yylloc;
  2350. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
  2351. read_into_target(&rec, &row, &have_strict);
  2352. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
  2353. }
  2354. }
  2355. plpgsql_IdentifierLookup = save_IdentifierLookup;
  2356. if (have_into)
  2357. {
  2358. /*
  2359. * Insert an appropriate number of spaces corresponding to the
  2360. * INTO text, so that locations within the redacted SQL statement
  2361. * still line up with those in the original source text.
  2362. */
  2363. plpgsql_append_source_text(&ds, location, into_start_loc);
  2364. appendStringInfoSpaces(&ds, into_end_loc - into_start_loc);
  2365. plpgsql_append_source_text(&ds, into_end_loc, yylloc);
  2366. }
  2367. else
  2368. plpgsql_append_source_text(&ds, location, yylloc);
  2369. /* trim any trailing whitespace, for neatness */
  2370. while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
  2371. ds.data[--ds.len] = '\0';
  2372. expr = palloc0(sizeof(PLpgSQL_expr));
  2373. expr->dtype = PLPGSQL_DTYPE_EXPR;
  2374. expr->query = pstrdup(ds.data);
  2375. expr->plan = NULL;
  2376. expr->paramnos = NULL;
  2377. expr->ns = plpgsql_ns_top();
  2378. pfree(ds.data);
  2379. check_sql_expr(expr->query, location, 0);
  2380. execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
  2381. execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
  2382. execsql->lineno = plpgsql_location_to_lineno(location);
  2383. execsql->sqlstmt = expr;
  2384. execsql->into = have_into;
  2385. execsql->strict = have_strict;
  2386. execsql->rec = rec;
  2387. execsql->row = row;
  2388. return (PLpgSQL_stmt *) execsql;
  2389. }
  2390. /*
  2391. * Read FETCH or MOVE direction clause (everything through FROM/IN).
  2392. */
  2393. static PLpgSQL_stmt_fetch *
  2394. read_fetch_direction(void)
  2395. {
  2396. PLpgSQL_stmt_fetch *fetch;
  2397. int tok;
  2398. bool check_FROM = true;
  2399. /*
  2400. * We create the PLpgSQL_stmt_fetch struct here, but only fill in
  2401. * the fields arising from the optional direction clause
  2402. */
  2403. fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch));
  2404. fetch->cmd_type = PLPGSQL_STMT_FETCH;
  2405. /* set direction defaults: */
  2406. fetch->direction = FETCH_FORWARD;
  2407. fetch->how_many = 1;
  2408. fetch->expr = NULL;
  2409. fetch->returns_multiple_rows = false;
  2410. tok = yylex();
  2411. if (tok == 0)
  2412. yyerror("unexpected end of function definition");
  2413. if (tok_is_keyword(tok, &yylval,
  2414. K_NEXT, "next"))
  2415. {
  2416. /* use defaults */
  2417. }
  2418. else if (tok_is_keyword(tok, &yylval,
  2419. K_PRIOR, "prior"))
  2420. {
  2421. fetch->direction = FETCH_BACKWARD;
  2422. }
  2423. else if (tok_is_keyword(tok, &yylval,
  2424. K_FIRST, "first"))
  2425. {
  2426. fetch->direction = FETCH_ABSOLUTE;
  2427. }
  2428. else if (tok_is_keyword(tok, &yylval,
  2429. K_LAST, "last"))
  2430. {
  2431. fetch->direction = FETCH_ABSOLUTE;
  2432. fetch->how_many = -1;
  2433. }
  2434. else if (tok_is_keyword(tok, &yylval,
  2435. K_ABSOLUTE, "absolute"))
  2436. {
  2437. fetch->direction = FETCH_ABSOLUTE;
  2438. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2439. "FROM or IN",
  2440. NULL);
  2441. check_FROM = false;
  2442. }
  2443. else if (tok_is_keyword(tok, &yylval,
  2444. K_RELATIVE, "relative"))
  2445. {
  2446. fetch->direction = FETCH_RELATIVE;
  2447. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2448. "FROM or IN",
  2449. NULL);
  2450. check_FROM = false;
  2451. }
  2452. else if (tok_is_keyword(tok, &yylval,
  2453. K_ALL, "all"))
  2454. {
  2455. fetch->how_many = FETCH_ALL;
  2456. fetch->returns_multiple_rows = true;
  2457. }
  2458. else if (tok_is_keyword(tok, &yylval,
  2459. K_FORWARD, "forward"))
  2460. {
  2461. complete_direction(fetch, &check_FROM);
  2462. }
  2463. else if (tok_is_keyword(tok, &yylval,
  2464. K_BACKWARD, "backward"))
  2465. {
  2466. fetch->direction = FETCH_BACKWARD;
  2467. complete_direction(fetch, &check_FROM);
  2468. }
  2469. else if (tok == K_FROM || tok == K_IN)
  2470. {
  2471. /* empty direction */
  2472. check_FROM = false;
  2473. }
  2474. else if (tok == T_DATUM)
  2475. {
  2476. /* Assume there's no direction clause and tok is a cursor name */
  2477. plpgsql_push_back_token(tok);
  2478. check_FROM = false;
  2479. }
  2480. else
  2481. {
  2482. /*
  2483. * Assume it's a count expression with no preceding keyword.
  2484. * Note: we allow this syntax because core SQL does, but we don't
  2485. * document it because of the ambiguity with the omitted-direction
  2486. * case. For instance, "MOVE n IN c" will fail if n is a variable.
  2487. * Perhaps this can be improved someday, but it's hardly worth a
  2488. * lot of work.
  2489. */
  2490. plpgsql_push_back_token(tok);
  2491. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2492. "FROM or IN",
  2493. NULL);
  2494. fetch->returns_multiple_rows = true;
  2495. check_FROM = false;
  2496. }
  2497. /* check FROM or IN keyword after direction's specification */
  2498. if (check_FROM)
  2499. {
  2500. tok = yylex();
  2501. if (tok != K_FROM && tok != K_IN)
  2502. yyerror("expected FROM or IN");
  2503. }
  2504. return fetch;
  2505. }
  2506. /*
  2507. * Process remainder of FETCH/MOVE direction after FORWARD or BACKWARD.
  2508. * Allows these cases:
  2509. * FORWARD expr, FORWARD ALL, FORWARD
  2510. * BACKWARD expr, BACKWARD ALL, BACKWARD
  2511. */
  2512. static void
  2513. complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM)
  2514. {
  2515. int tok;
  2516. tok = yylex();
  2517. if (tok == 0)
  2518. yyerror("unexpected end of function definition");
  2519. if (tok == K_FROM || tok == K_IN)
  2520. {
  2521. *check_FROM = false;
  2522. return;
  2523. }
  2524. if (tok == K_ALL)
  2525. {
  2526. fetch->how_many = FETCH_ALL;
  2527. fetch->returns_multiple_rows = true;
  2528. *check_FROM = true;
  2529. return;
  2530. }
  2531. plpgsql_push_back_token(tok);
  2532. fetch->expr = read_sql_expression2(K_FROM, K_IN,
  2533. "FROM or IN",
  2534. NULL);
  2535. fetch->returns_multiple_rows = true;
  2536. *check_FROM = false;
  2537. }
  2538. static PLpgSQL_stmt *
  2539. make_return_stmt(int location)
  2540. {
  2541. PLpgSQL_stmt_return *new;
  2542. new = palloc0(sizeof(PLpgSQL_stmt_return));
  2543. new->cmd_type = PLPGSQL_STMT_RETURN;
  2544. new->lineno = plpgsql_location_to_lineno(location);
  2545. new->expr = NULL;
  2546. new->retvarno = -1;
  2547. if (plpgsql_curr_compile->fn_retset)
  2548. {
  2549. if (yylex() != ';')
  2550. ereport(ERROR,
  2551. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2552. errmsg("RETURN cannot have a parameter in function returning set"),
  2553. errhint("Use RETURN NEXT or RETURN QUERY."),
  2554. parser_errposition(yylloc)));
  2555. }
  2556. else if (plpgsql_curr_compile->out_param_varno >= 0)
  2557. {
  2558. if (yylex() != ';')
  2559. ereport(ERROR,
  2560. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2561. errmsg("RETURN cannot have a parameter in function with OUT parameters"),
  2562. parser_errposition(yylloc)));
  2563. new->retvarno = plpgsql_curr_compile->out_param_varno;
  2564. }
  2565. else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
  2566. {
  2567. if (yylex() != ';')
  2568. ereport(ERROR,
  2569. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2570. errmsg("RETURN cannot have a parameter in function returning void"),
  2571. parser_errposition(yylloc)));
  2572. }
  2573. else if (plpgsql_curr_compile->fn_retistuple)
  2574. {
  2575. switch (yylex())
  2576. {
  2577. case K_NULL:
  2578. /* we allow this to support RETURN NULL in triggers */
  2579. break;
  2580. case T_DATUM:
  2581. if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
  2582. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
  2583. new->retvarno = yylval.wdatum.datum->dno;
  2584. else
  2585. ereport(ERROR,
  2586. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2587. errmsg("RETURN must specify a record or row variable in function returning row"),
  2588. parser_errposition(yylloc)));
  2589. break;
  2590. default:
  2591. ereport(ERROR,
  2592. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2593. errmsg("RETURN must specify a record or row variable in function returning row"),
  2594. parser_errposition(yylloc)));
  2595. break;
  2596. }
  2597. if (yylex() != ';')
  2598. yyerror("syntax error");
  2599. }
  2600. else
  2601. {
  2602. /*
  2603. * Note that a well-formed expression is _required_ here;
  2604. * anything else is a compile-time error.
  2605. */
  2606. new->expr = read_sql_expression(';', ";");
  2607. }
  2608. return (PLpgSQL_stmt *) new;
  2609. }
  2610. static PLpgSQL_stmt *
  2611. make_return_next_stmt(int location)
  2612. {
  2613. PLpgSQL_stmt_return_next *new;
  2614. if (!plpgsql_curr_compile->fn_retset)
  2615. ereport(ERROR,
  2616. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2617. errmsg("cannot use RETURN NEXT in a non-SETOF function"),
  2618. parser_errposition(location)));
  2619. new = palloc0(sizeof(PLpgSQL_stmt_return_next));
  2620. new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
  2621. new->lineno = plpgsql_location_to_lineno(location);
  2622. new->expr = NULL;
  2623. new->retvarno = -1;
  2624. if (plpgsql_curr_compile->out_param_varno >= 0)
  2625. {
  2626. if (yylex() != ';')
  2627. ereport(ERROR,
  2628. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2629. errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"),
  2630. parser_errposition(yylloc)));
  2631. new->retvarno = plpgsql_curr_compile->out_param_varno;
  2632. }
  2633. else if (plpgsql_curr_compile->fn_retistuple)
  2634. {
  2635. switch (yylex())
  2636. {
  2637. case T_DATUM:
  2638. if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
  2639. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
  2640. new->retvarno = yylval.wdatum.datum->dno;
  2641. else
  2642. ereport(ERROR,
  2643. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2644. errmsg("RETURN NEXT must specify a record or row variable in function returning row"),
  2645. parser_errposition(yylloc)));
  2646. break;
  2647. default:
  2648. ereport(ERROR,
  2649. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2650. errmsg("RETURN NEXT must specify a record or row variable in function returning row"),
  2651. parser_errposition(yylloc)));
  2652. break;
  2653. }
  2654. if (yylex() != ';')
  2655. yyerror("syntax error");
  2656. }
  2657. else
  2658. new->expr = read_sql_expression(';', ";");
  2659. return (PLpgSQL_stmt *) new;
  2660. }
  2661. static PLpgSQL_stmt *
  2662. make_return_query_stmt(int location)
  2663. {
  2664. PLpgSQL_stmt_return_query *new;
  2665. int tok;
  2666. if (!plpgsql_curr_compile->fn_retset)
  2667. ereport(ERROR,
  2668. (errcode(ERRCODE_DATATYPE_MISMATCH),
  2669. errmsg("cannot use RETURN QUERY in a non-SETOF function"),
  2670. parser_errposition(location)));
  2671. new = palloc0(sizeof(PLpgSQL_stmt_return_query));
  2672. new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
  2673. new->lineno = plpgsql_location_to_lineno(location);
  2674. /* check for RETURN QUERY EXECUTE */
  2675. if ((tok = yylex()) != K_EXECUTE)
  2676. {
  2677. /* ordinary static query */
  2678. plpgsql_push_back_token(tok);
  2679. new->query = read_sql_stmt("");
  2680. }
  2681. else
  2682. {
  2683. /* dynamic SQL */
  2684. int term;
  2685. new->dynquery = read_sql_expression2(';', K_USING, "; or USING",
  2686. &term);
  2687. if (term == K_USING)
  2688. {
  2689. do
  2690. {
  2691. PLpgSQL_expr *expr;
  2692. expr = read_sql_expression2(',', ';', ", or ;", &term);
  2693. new->params = lappend(new->params, expr);
  2694. } while (term == ',');
  2695. }
  2696. }
  2697. return (PLpgSQL_stmt *) new;
  2698. }
  2699. /* convenience routine to fetch the name of a T_DATUM */
  2700. static char *
  2701. NameOfDatum(PLwdatum *wdatum)
  2702. {
  2703. if (wdatum->ident)
  2704. return wdatum->ident;
  2705. Assert(wdatum->idents != NIL);
  2706. return NameListToString(wdatum->idents);
  2707. }
  2708. static void
  2709. check_assignable(PLpgSQL_datum *datum, int location)
  2710. {
  2711. switch (datum->dtype)
  2712. {
  2713. case PLPGSQL_DTYPE_VAR:
  2714. if (((PLpgSQL_var *) datum)->isconst)
  2715. ereport(ERROR,
  2716. (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
  2717. errmsg("\"%s\" is declared CONSTANT",
  2718. ((PLpgSQL_var *) datum)->refname),
  2719. parser_errposition(location)));
  2720. break;
  2721. case PLPGSQL_DTYPE_ROW:
  2722. /* always assignable? */
  2723. break;
  2724. case PLPGSQL_DTYPE_REC:
  2725. /* always assignable? What about NEW/OLD? */
  2726. break;
  2727. case PLPGSQL_DTYPE_RECFIELD:
  2728. /* always assignable? */
  2729. break;
  2730. case PLPGSQL_DTYPE_ARRAYELEM:
  2731. /* always assignable? */
  2732. break;
  2733. default:
  2734. elog(ERROR, "unrecognized dtype: %d", datum->dtype);
  2735. break;
  2736. }
  2737. }
  2738. /*
  2739. * Read the argument of an INTO clause. On entry, we have just read the
  2740. * INTO keyword.
  2741. */
  2742. static void
  2743. read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
  2744. {
  2745. int tok;
  2746. /* Set default results */
  2747. *rec = NULL;
  2748. *row = NULL;
  2749. if (strict)
  2750. *strict = false;
  2751. tok = yylex();
  2752. if (strict && tok == K_STRICT)
  2753. {
  2754. *strict = true;
  2755. tok = yylex();
  2756. }
  2757. /*
  2758. * Currently, a row or record variable can be the single INTO target,
  2759. * but not a member of a multi-target list. So we throw error if there
  2760. * is a comma after it, because that probably means the user tried to
  2761. * write a multi-target list. If this ever gets generalized, we should
  2762. * probably refactor read_into_scalar_list so it handles all cases.
  2763. */
  2764. switch (tok)
  2765. {
  2766. case T_DATUM:
  2767. if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW)
  2768. {
  2769. check_assignable(yylval.wdatum.datum, yylloc);
  2770. *row = (PLpgSQL_row *) yylval.wdatum.datum;
  2771. if ((tok = yylex()) == ',')
  2772. ereport(ERROR,
  2773. (errcode(ERRCODE_SYNTAX_ERROR),
  2774. errmsg("record or row variable cannot be part of multiple-item INTO list"),
  2775. parser_errposition(yylloc)));
  2776. plpgsql_push_back_token(tok);
  2777. }
  2778. else if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
  2779. {
  2780. check_assignable(yylval.wdatum.datum, yylloc);
  2781. *rec = (PLpgSQL_rec *) yylval.wdatum.datum;
  2782. if ((tok = yylex()) == ',')
  2783. ereport(ERROR,
  2784. (errcode(ERRCODE_SYNTAX_ERROR),
  2785. errmsg("record or row variable cannot be part of multiple-item INTO list"),
  2786. parser_errposition(yylloc)));
  2787. plpgsql_push_back_token(tok);
  2788. }
  2789. else
  2790. {
  2791. *row = read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
  2792. yylval.wdatum.datum, yylloc);
  2793. }
  2794. break;
  2795. default:
  2796. /* just to give a better message than "syntax error" */
  2797. current_token_is_not_variable(tok);
  2798. }
  2799. }
  2800. /*
  2801. * Given the first datum and name in the INTO list, continue to read
  2802. * comma-separated scalar variables until we run out. Then construct
  2803. * and return a fake "row" variable that represents the list of
  2804. * scalars.
  2805. */
  2806. static PLpgSQL_row *
  2807. read_into_scalar_list(char *initial_name,
  2808. PLpgSQL_datum *initial_datum,
  2809. int initial_location)
  2810. {
  2811. int nfields;
  2812. char *fieldnames[1024];
  2813. int varnos[1024];
  2814. PLpgSQL_row *row;
  2815. int tok;
  2816. check_assignable(initial_datum, initial_location);
  2817. fieldnames[0] = initial_name;
  2818. varnos[0] = initial_datum->dno;
  2819. nfields = 1;
  2820. while ((tok = yylex()) == ',')
  2821. {
  2822. /* Check for array overflow */
  2823. if (nfields >= 1024)
  2824. ereport(ERROR,
  2825. (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
  2826. errmsg("too many INTO variables specified"),
  2827. parser_errposition(yylloc)));
  2828. tok = yylex();
  2829. switch (tok)
  2830. {
  2831. case T_DATUM:
  2832. check_assignable(yylval.wdatum.datum, yylloc);
  2833. if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
  2834. yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
  2835. ereport(ERROR,
  2836. (errcode(ERRCODE_SYNTAX_ERROR),
  2837. errmsg("\"%s\" is not a scalar variable",
  2838. NameOfDatum(&(yylval.wdatum))),
  2839. parser_errposition(yylloc)));
  2840. fieldnames[nfields] = NameOfDatum(&(yylval.wdatum));
  2841. varnos[nfields++] = yylval.wdatum.datum->dno;
  2842. break;
  2843. default:
  2844. /* just to give a better message than "syntax error" */
  2845. current_token_is_not_variable(tok);
  2846. }
  2847. }
  2848. /*
  2849. * We read an extra, non-comma token from yylex(), so push it
  2850. * back onto the input stream
  2851. */
  2852. plpgsql_push_back_token(tok);
  2853. row = palloc(sizeof(PLpgSQL_row));
  2854. row->dtype = PLPGSQL_DTYPE_ROW;
  2855. row->refname = pstrdup("*internal*");
  2856. row->lineno = plpgsql_location_to_lineno(initial_location);
  2857. row->rowtupdesc = NULL;
  2858. row->nfields = nfields;
  2859. row->fieldnames = palloc(sizeof(char *) * nfields);
  2860. row->varnos = palloc(sizeof(int) * nfields);
  2861. while (--nfields >= 0)
  2862. {
  2863. row->fieldnames[nfields] = fieldnames[nfields];
  2864. row->varnos[nfields] = varnos[nfields];
  2865. }
  2866. plpgsql_adddatum((PLpgSQL_datum *)row);
  2867. return row;
  2868. }
  2869. /*
  2870. * Convert a single scalar into a "row" list. This is exactly
  2871. * like read_into_scalar_list except we never consume any input.
  2872. *
  2873. * Note: lineno could be computed from location, but since callers
  2874. * have it at hand already, we may as well pass it in.
  2875. */
  2876. static PLpgSQL_row *
  2877. make_scalar_list1(char *initial_name,
  2878. PLpgSQL_datum *initial_datum,
  2879. int lineno, int location)
  2880. {
  2881. PLpgSQL_row *row;
  2882. check_assignable(initial_datum, location);
  2883. row = palloc(sizeof(PLpgSQL_row));
  2884. row->dtype = PLPGSQL_DTYPE_ROW;
  2885. row->refname = pstrdup("*internal*");
  2886. row->lineno = lineno;
  2887. row->rowtupdesc = NULL;
  2888. row->nfields = 1;
  2889. row->fieldnames = palloc(sizeof(char *));
  2890. row->varnos = palloc(sizeof(int));
  2891. row->fieldnames[0] = initial_name;
  2892. row->varnos[0] = initial_datum->dno;
  2893. plpgsql_adddatum((PLpgSQL_datum *)row);
  2894. return row;
  2895. }
  2896. /*
  2897. * When the PL/pgSQL parser expects to see a SQL statement, it is very
  2898. * liberal in what it accepts; for example, we often assume an
  2899. * unrecognized keyword is the beginning of a SQL statement. This
  2900. * avoids the need to duplicate parts of the SQL grammar in the
  2901. * PL/pgSQL grammar, but it means we can accept wildly malformed
  2902. * input. To try and catch some of the more obviously invalid input,
  2903. * we run the strings we expect to be SQL statements through the main
  2904. * SQL parser.
  2905. *
  2906. * We only invoke the raw parser (not the analyzer); this doesn't do
  2907. * any database access and does not check any semantic rules, it just
  2908. * checks for basic syntactic correctness. We do this here, rather
  2909. * than after parsing has finished, because a malformed SQL statement
  2910. * may cause the PL/pgSQL parser to become confused about statement
  2911. * borders. So it is best to bail out as early as we can.
  2912. *
  2913. * It is assumed that "stmt" represents a copy of the function source text
  2914. * beginning at offset "location", with leader text of length "leaderlen"
  2915. * (typically "SELECT ") prefixed to the source text. We use this assumption
  2916. * to transpose any error cursor position back to the function source text.
  2917. * If no error cursor is provided, we'll just point at "location".
  2918. */
  2919. static void
  2920. check_sql_expr(const char *stmt, int location, int leaderlen)
  2921. {
  2922. sql_error_callback_arg cbarg;
  2923. ErrorContextCallback syntax_errcontext;
  2924. MemoryContext oldCxt;
  2925. if (!plpgsql_check_syntax)
  2926. return;
  2927. cbarg.location = location;
  2928. cbarg.leaderlen = leaderlen;
  2929. syntax_errcontext.callback = plpgsql_sql_error_callback;
  2930. syntax_errcontext.arg = &cbarg;
  2931. syntax_errcontext.previous = error_context_stack;
  2932. error_context_stack = &syntax_errcontext;
  2933. oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
  2934. (void) raw_parser(stmt);
  2935. MemoryContextSwitchTo(oldCxt);
  2936. /* Restore former ereport callback */
  2937. error_context_stack = syntax_errcontext.previous;
  2938. }
  2939. static void
  2940. plpgsql_sql_error_callback(void *arg)
  2941. {
  2942. sql_error_callback_arg *cbarg = (sql_error_callback_arg *) arg;
  2943. int errpos;
  2944. /*
  2945. * First, set up internalerrposition to point to the start of the
  2946. * statement text within the function text. Note this converts
  2947. * location (a byte offset) to a character number.
  2948. */
  2949. parser_errposition(cbarg->location);
  2950. /*
  2951. * If the core parser provided an error position, transpose it.
  2952. * Note we are dealing with 1-based character numbers at this point.
  2953. */
  2954. errpos = geterrposition();
  2955. if (errpos > cbarg->leaderlen)
  2956. {
  2957. int myerrpos = getinternalerrposition();
  2958. if (myerrpos > 0) /* safety check */
  2959. internalerrposition(myerrpos + errpos - cbarg->leaderlen - 1);
  2960. }
  2961. /* In any case, flush errposition --- we want internalerrpos only */
  2962. errposition(0);
  2963. }
  2964. /*
  2965. * Parse a SQL datatype name and produce a PLpgSQL_type structure.
  2966. *
  2967. * The heavy lifting is done elsewhere. Here we are only concerned
  2968. * with setting up an errcontext link that will let us give an error
  2969. * cursor pointing into the plpgsql function source, if necessary.
  2970. * This is handled the same as in check_sql_expr(), and we likewise
  2971. * expect that the given string is a copy from the source text.
  2972. */
  2973. static PLpgSQL_type *
  2974. parse_datatype(const char *string, int location)
  2975. {
  2976. Oid type_id;
  2977. int32 typmod;
  2978. sql_error_callback_arg cbarg;
  2979. ErrorContextCallback syntax_errcontext;
  2980. cbarg.location = location;
  2981. cbarg.leaderlen = 0;
  2982. syntax_errcontext.callback = plpgsql_sql_error_callback;
  2983. syntax_errcontext.arg = &cbarg;
  2984. syntax_errcontext.previous = error_context_stack;
  2985. error_context_stack = &syntax_errcontext;
  2986. /* Let the main parser try to parse it under standard SQL rules */
  2987. parseTypeString(string, &type_id, &typmod);
  2988. /* Restore former ereport callback */
  2989. error_context_stack = syntax_errcontext.previous;
  2990. /* Okay, build a PLpgSQL_type data structure for it */
  2991. return plpgsql_build_datatype(type_id, typmod,
  2992. plpgsql_curr_compile->fn_input_collation);
  2993. }
  2994. /*
  2995. * Check block starting and ending labels match.
  2996. */
  2997. static void
  2998. check_labels(const char *start_label, const char *end_label, int end_location)
  2999. {
  3000. if (end_label)
  3001. {
  3002. if (!start_label)
  3003. ereport(ERROR,
  3004. (errcode(ERRCODE_SYNTAX_ERROR),
  3005. errmsg("end label \"%s\" specified for unlabelled block",
  3006. end_label),
  3007. parser_errposition(end_location)));
  3008. if (strcmp(start_label, end_label) != 0)
  3009. ereport(ERROR,
  3010. (errcode(ERRCODE_SYNTAX_ERROR),
  3011. errmsg("end label \"%s\" differs from block's label \"%s\"",
  3012. end_label, start_label),
  3013. parser_errposition(end_location)));
  3014. }
  3015. }
  3016. /*
  3017. * Read the arguments (if any) for a cursor, followed by the until token
  3018. *
  3019. * If cursor has no args, just swallow the until token and return NULL.
  3020. * If it does have args, we expect to see "( arg [, arg ...] )" followed
  3021. * by the until token, where arg may be a plain expression, or a named
  3022. * parameter assignment of the form argname := expr. Consume all that and
  3023. * return a SELECT query that evaluates the expression(s) (without the outer
  3024. * parens).
  3025. */
  3026. static PLpgSQL_expr *
  3027. read_cursor_args(PLpgSQL_var *cursor, int until, const char *expected)
  3028. {
  3029. PLpgSQL_expr *expr;
  3030. PLpgSQL_row *row;
  3031. int tok;
  3032. int argc;
  3033. char **argv;
  3034. StringInfoData ds;
  3035. char *sqlstart = "SELECT ";
  3036. bool any_named = false;
  3037. tok = yylex();
  3038. if (cursor->cursor_explicit_argrow < 0)
  3039. {
  3040. /* No arguments expected */
  3041. if (tok == '(')
  3042. ereport(ERROR,
  3043. (errcode(ERRCODE_SYNTAX_ERROR),
  3044. errmsg("cursor \"%s\" has no arguments",
  3045. cursor->refname),
  3046. parser_errposition(yylloc)));
  3047. if (tok != until)
  3048. yyerror("syntax error");
  3049. return NULL;
  3050. }
  3051. /* Else better provide arguments */
  3052. if (tok != '(')
  3053. ereport(ERROR,
  3054. (errcode(ERRCODE_SYNTAX_ERROR),
  3055. errmsg("cursor \"%s\" has arguments",
  3056. cursor->refname),
  3057. parser_errposition(yylloc)));
  3058. /*
  3059. * Read the arguments, one by one.
  3060. */
  3061. row = (PLpgSQL_row *) plpgsql_Datums[cursor->cursor_explicit_argrow];
  3062. argv = (char **) palloc0(row->nfields * sizeof(char *));
  3063. for (argc = 0; argc < row->nfields; argc++)
  3064. {
  3065. PLpgSQL_expr *item;
  3066. int endtoken;
  3067. int argpos;
  3068. int tok1,
  3069. tok2;
  3070. int arglocation;
  3071. /* Check if it's a named parameter: "param := value" */
  3072. plpgsql_peek2(&tok1, &tok2, &arglocation, NULL);
  3073. if (tok1 == IDENT && tok2 == COLON_EQUALS)
  3074. {
  3075. char *argname;
  3076. IdentifierLookup save_IdentifierLookup;
  3077. /* Read the argument name, ignoring any matching variable */
  3078. save_IdentifierLookup = plpgsql_IdentifierLookup;
  3079. plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
  3080. yylex();
  3081. argname = yylval.str;
  3082. plpgsql_IdentifierLookup = save_IdentifierLookup;
  3083. /* Match argument name to cursor arguments */
  3084. for (argpos = 0; argpos < row->nfields; argpos++)
  3085. {
  3086. if (strcmp(row->fieldnames[argpos], argname) == 0)
  3087. break;
  3088. }
  3089. if (argpos == row->nfields)
  3090. ereport(ERROR,
  3091. (errcode(ERRCODE_SYNTAX_ERROR),
  3092. errmsg("cursor \"%s\" has no argument named \"%s\"",
  3093. cursor->refname, argname),
  3094. parser_errposition(yylloc)));
  3095. /*
  3096. * Eat the ":=". We already peeked, so the error should never
  3097. * happen.
  3098. */
  3099. tok2 = yylex();
  3100. if (tok2 != COLON_EQUALS)
  3101. yyerror("syntax error");
  3102. any_named = true;
  3103. }
  3104. else
  3105. argpos = argc;
  3106. if (argv[argpos] != NULL)
  3107. ereport(ERROR,
  3108. (errcode(ERRCODE_SYNTAX_ERROR),
  3109. errmsg("value for parameter \"%s\" of cursor \"%s\" specified more than once",
  3110. row->fieldnames[argpos], cursor->refname),
  3111. parser_errposition(arglocation)));
  3112. /*
  3113. * Read the value expression. To provide the user with meaningful
  3114. * parse error positions, we check the syntax immediately, instead of
  3115. * checking the final expression that may have the arguments
  3116. * reordered. Trailing whitespace must not be trimmed, because
  3117. * otherwise input of the form (param -- comment\n, param) would be
  3118. * translated into a form where the second parameter is commented
  3119. * out.
  3120. */
  3121. item = read_sql_construct(',', ')', 0,
  3122. ",\" or \")",
  3123. sqlstart,
  3124. true, true,
  3125. false, /* do not trim */
  3126. NULL, &endtoken);
  3127. argv[argpos] = item->query + strlen(sqlstart);
  3128. if (endtoken == ')' && !(argc == row->nfields - 1))
  3129. ereport(ERROR,
  3130. (errcode(ERRCODE_SYNTAX_ERROR),
  3131. errmsg("not enough arguments for cursor \"%s\"",
  3132. cursor->refname),
  3133. parser_errposition(yylloc)));
  3134. if (endtoken == ',' && (argc == row->nfields - 1))
  3135. ereport(ERROR,
  3136. (errcode(ERRCODE_SYNTAX_ERROR),
  3137. errmsg("too many arguments for cursor \"%s\"",
  3138. cursor->refname),
  3139. parser_errposition(yylloc)));
  3140. }
  3141. /* Make positional argument list */
  3142. initStringInfo(&ds);
  3143. appendStringInfoString(&ds, sqlstart);
  3144. for (argc = 0; argc < row->nfields; argc++)
  3145. {
  3146. Assert(argv[argc] != NULL);
  3147. /*
  3148. * Because named notation allows permutated argument lists, include
  3149. * the parameter name for meaningful runtime errors.
  3150. */
  3151. appendStringInfoString(&ds, argv[argc]);
  3152. if (any_named)
  3153. appendStringInfo(&ds, " AS %s",
  3154. quote_identifier(row->fieldnames[argc]));
  3155. if (argc < row->nfields - 1)
  3156. appendStringInfoString(&ds, ", ");
  3157. }
  3158. appendStringInfoChar(&ds, ';');
  3159. expr = palloc0(sizeof(PLpgSQL_expr));
  3160. expr->dtype = PLPGSQL_DTYPE_EXPR;
  3161. expr->query = pstrdup(ds.data);
  3162. expr->plan = NULL;
  3163. expr->paramnos = NULL;
  3164. expr->ns = plpgsql_ns_top();
  3165. pfree(ds.data);
  3166. /* Next we'd better find the until token */
  3167. tok = yylex();
  3168. if (tok != until)
  3169. yyerror("syntax error");
  3170. return expr;
  3171. }
  3172. /*
  3173. * Parse RAISE ... USING options
  3174. */
  3175. static List *
  3176. read_raise_options(void)
  3177. {
  3178. List *result = NIL;
  3179. for (;;)
  3180. {
  3181. PLpgSQL_raise_option *opt;
  3182. int tok;
  3183. if ((tok = yylex()) == 0)
  3184. yyerror("unexpected end of function definition");
  3185. opt = (PLpgSQL_raise_option *) palloc(sizeof(PLpgSQL_raise_option));
  3186. if (tok_is_keyword(tok, &yylval,
  3187. K_ERRCODE, "errcode"))
  3188. opt->opt_type = PLPGSQL_RAISEOPTION_ERRCODE;
  3189. else if (tok_is_keyword(tok, &yylval,
  3190. K_MESSAGE, "message"))
  3191. opt->opt_type = PLPGSQL_RAISEOPTION_MESSAGE;
  3192. else if (tok_is_keyword(tok, &yylval,
  3193. K_DETAIL, "detail"))
  3194. opt->opt_type = PLPGSQL_RAISEOPTION_DETAIL;
  3195. else if (tok_is_keyword(tok, &yylval,
  3196. K_HINT, "hint"))
  3197. opt->opt_type = PLPGSQL_RAISEOPTION_HINT;
  3198. else
  3199. yyerror("unrecognized RAISE statement option");
  3200. tok = yylex();
  3201. if (tok != '=' && tok != COLON_EQUALS)
  3202. yyerror("syntax error, expected \"=\"");
  3203. opt->expr = read_sql_expression2(',', ';', ", or ;", &tok);
  3204. result = lappend(result, opt);
  3205. if (tok == ';')
  3206. break;
  3207. }
  3208. return result;
  3209. }
  3210. /*
  3211. * Fix up CASE statement
  3212. */
  3213. static PLpgSQL_stmt *
  3214. make_case(int location, PLpgSQL_expr *t_expr,
  3215. List *case_when_list, List *else_stmts)
  3216. {
  3217. PLpgSQL_stmt_case *new;
  3218. new = palloc(sizeof(PLpgSQL_stmt_case));
  3219. new->cmd_type = PLPGSQL_STMT_CASE;
  3220. new->lineno = plpgsql_location_to_lineno(location);
  3221. new->t_expr = t_expr;
  3222. new->t_varno = 0;
  3223. new->case_when_list = case_when_list;
  3224. new->have_else = (else_stmts != NIL);
  3225. /* Get rid of list-with-NULL hack */
  3226. if (list_length(else_stmts) == 1 && linitial(else_stmts) == NULL)
  3227. new->else_stmts = NIL;
  3228. else
  3229. new->else_stmts = else_stmts;
  3230. /*
  3231. * When test expression is present, we create a var for it and then
  3232. * convert all the WHEN expressions to "VAR IN (original_expression)".
  3233. * This is a bit klugy, but okay since we haven't yet done more than
  3234. * read the expressions as text. (Note that previous parsing won't
  3235. * have complained if the WHEN ... THEN expression contained multiple
  3236. * comma-separated values.)
  3237. */
  3238. if (t_expr)
  3239. {
  3240. char varname[32];
  3241. PLpgSQL_var *t_var;
  3242. ListCell *l;
  3243. /* use a name unlikely to collide with any user names */
  3244. snprintf(varname, sizeof(varname), "__Case__Variable_%d__",
  3245. plpgsql_nDatums);
  3246. /*
  3247. * We don't yet know the result datatype of t_expr. Build the
  3248. * variable as if it were INT4; we'll fix this at runtime if needed.
  3249. */
  3250. t_var = (PLpgSQL_var *)
  3251. plpgsql_build_variable(varname, new->lineno,
  3252. plpgsql_build_datatype(INT4OID,
  3253. -1,
  3254. InvalidOid),
  3255. true);
  3256. new->t_varno = t_var->dno;
  3257. foreach(l, case_when_list)
  3258. {
  3259. PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l);
  3260. PLpgSQL_expr *expr = cwt->expr;
  3261. StringInfoData ds;
  3262. /* copy expression query without SELECT keyword (expr->query + 7) */
  3263. Assert(strncmp(expr->query, "SELECT ", 7) == 0);
  3264. /* And do the string hacking */
  3265. initStringInfo(&ds);
  3266. appendStringInfo(&ds, "SELECT \"%s\" IN (%s)",
  3267. varname, expr->query + 7);
  3268. pfree(expr->query);
  3269. expr->query = pstrdup(ds.data);
  3270. /* Adjust expr's namespace to include the case variable */
  3271. expr->ns = plpgsql_ns_top();
  3272. pfree(ds.data);
  3273. }
  3274. }
  3275. return (PLpgSQL_stmt *) new;
  3276. }