PageRenderTime 58ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/postgresql-9.1.4/postgresql-9.0.8/src/pl/plpgsql/src/gram.y

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