PostgreSQL Source Code  git master
pl_funcs.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pl_funcs.c - Misc functions for the PL/pgSQL
4  * procedural language
5  *
6  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/pl/plpgsql/src/pl_funcs.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include "plpgsql.h"
19 #include "utils/memutils.h"
20 
21 /* ----------
22  * Local variables for namespace handling
23  *
24  * The namespace structure actually forms a tree, of which only one linear
25  * list or "chain" (from the youngest item to the root) is accessible from
26  * any one plpgsql statement. During initial parsing of a function, ns_top
27  * points to the youngest item accessible from the block currently being
28  * parsed. We store the entire tree, however, since at runtime we will need
29  * to access the chain that's relevant to any one statement.
30  *
31  * Block boundaries in the namespace chain are marked by PLPGSQL_NSTYPE_LABEL
32  * items.
33  * ----------
34  */
35 static PLpgSQL_nsitem *ns_top = NULL;
36 
37 
38 /* ----------
39  * plpgsql_ns_init Initialize namespace processing for a new function
40  * ----------
41  */
42 void
44 {
45  ns_top = NULL;
46 }
47 
48 
49 /* ----------
50  * plpgsql_ns_push Create a new namespace level
51  * ----------
52  */
53 void
54 plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
55 {
56  if (label == NULL)
57  label = "";
58  plpgsql_ns_additem(PLPGSQL_NSTYPE_LABEL, (int) label_type, label);
59 }
60 
61 
62 /* ----------
63  * plpgsql_ns_pop Pop entries back to (and including) the last label
64  * ----------
65  */
66 void
68 {
69  Assert(ns_top != NULL);
70  while (ns_top->itemtype != PLPGSQL_NSTYPE_LABEL)
71  ns_top = ns_top->prev;
72  ns_top = ns_top->prev;
73 }
74 
75 
76 /* ----------
77  * plpgsql_ns_top Fetch the current namespace chain end
78  * ----------
79  */
82 {
83  return ns_top;
84 }
85 
86 
87 /* ----------
88  * plpgsql_ns_additem Add an item to the current namespace chain
89  * ----------
90  */
91 void
92 plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
93 {
94  PLpgSQL_nsitem *nse;
95 
96  Assert(name != NULL);
97  /* first item added must be a label */
98  Assert(ns_top != NULL || itemtype == PLPGSQL_NSTYPE_LABEL);
99 
100  nse = palloc(offsetof(PLpgSQL_nsitem, name) + strlen(name) + 1);
101  nse->itemtype = itemtype;
102  nse->itemno = itemno;
103  nse->prev = ns_top;
104  strcpy(nse->name, name);
105  ns_top = nse;
106 }
107 
108 
109 /* ----------
110  * plpgsql_ns_lookup Lookup an identifier in the given namespace chain
111  *
112  * Note that this only searches for variables, not labels.
113  *
114  * If localmode is true, only the topmost block level is searched.
115  *
116  * name1 must be non-NULL. Pass NULL for name2 and/or name3 if parsing a name
117  * with fewer than three components.
118  *
119  * If names_used isn't NULL, *names_used receives the number of names
120  * matched: 0 if no match, 1 if name1 matched an unqualified variable name,
121  * 2 if name1 and name2 matched a block label + variable name.
122  *
123  * Note that name3 is never directly matched to anything. However, if it
124  * isn't NULL, we will disregard qualified matches to scalar variables.
125  * Similarly, if name2 isn't NULL, we disregard unqualified matches to
126  * scalar variables.
127  * ----------
128  */
130 plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode,
131  const char *name1, const char *name2, const char *name3,
132  int *names_used)
133 {
134  /* Outer loop iterates once per block level in the namespace chain */
135  while (ns_cur != NULL)
136  {
137  PLpgSQL_nsitem *nsitem;
138 
139  /* Check this level for unqualified match to variable name */
140  for (nsitem = ns_cur;
141  nsitem->itemtype != PLPGSQL_NSTYPE_LABEL;
142  nsitem = nsitem->prev)
143  {
144  if (strcmp(nsitem->name, name1) == 0)
145  {
146  if (name2 == NULL ||
147  nsitem->itemtype != PLPGSQL_NSTYPE_VAR)
148  {
149  if (names_used)
150  *names_used = 1;
151  return nsitem;
152  }
153  }
154  }
155 
156  /* Check this level for qualified match to variable name */
157  if (name2 != NULL &&
158  strcmp(nsitem->name, name1) == 0)
159  {
160  for (nsitem = ns_cur;
161  nsitem->itemtype != PLPGSQL_NSTYPE_LABEL;
162  nsitem = nsitem->prev)
163  {
164  if (strcmp(nsitem->name, name2) == 0)
165  {
166  if (name3 == NULL ||
167  nsitem->itemtype != PLPGSQL_NSTYPE_VAR)
168  {
169  if (names_used)
170  *names_used = 2;
171  return nsitem;
172  }
173  }
174  }
175  }
176 
177  if (localmode)
178  break; /* do not look into upper levels */
179 
180  ns_cur = nsitem->prev;
181  }
182 
183  /* This is just to suppress possibly-uninitialized-variable warnings */
184  if (names_used)
185  *names_used = 0;
186  return NULL; /* No match found */
187 }
188 
189 
190 /* ----------
191  * plpgsql_ns_lookup_label Lookup a label in the given namespace chain
192  * ----------
193  */
196 {
197  while (ns_cur != NULL)
198  {
199  if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
200  strcmp(ns_cur->name, name) == 0)
201  return ns_cur;
202  ns_cur = ns_cur->prev;
203  }
204 
205  return NULL; /* label not found */
206 }
207 
208 
209 /* ----------
210  * plpgsql_ns_find_nearest_loop Find innermost loop label in namespace chain
211  * ----------
212  */
215 {
216  while (ns_cur != NULL)
217  {
218  if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
219  ns_cur->itemno == PLPGSQL_LABEL_LOOP)
220  return ns_cur;
221  ns_cur = ns_cur->prev;
222  }
223 
224  return NULL; /* no loop found */
225 }
226 
227 
228 /*
229  * Statement type as a string, for use in error messages etc.
230  */
231 const char *
233 {
234  switch (stmt->cmd_type)
235  {
236  case PLPGSQL_STMT_BLOCK:
237  return _("statement block");
238  case PLPGSQL_STMT_ASSIGN:
239  return _("assignment");
240  case PLPGSQL_STMT_IF:
241  return "IF";
242  case PLPGSQL_STMT_CASE:
243  return "CASE";
244  case PLPGSQL_STMT_LOOP:
245  return "LOOP";
246  case PLPGSQL_STMT_WHILE:
247  return "WHILE";
248  case PLPGSQL_STMT_FORI:
249  return _("FOR with integer loop variable");
250  case PLPGSQL_STMT_FORS:
251  return _("FOR over SELECT rows");
252  case PLPGSQL_STMT_FORC:
253  return _("FOR over cursor");
255  return _("FOREACH over array");
256  case PLPGSQL_STMT_EXIT:
257  return ((PLpgSQL_stmt_exit *) stmt)->is_exit ? "EXIT" : "CONTINUE";
258  case PLPGSQL_STMT_RETURN:
259  return "RETURN";
261  return "RETURN NEXT";
263  return "RETURN QUERY";
264  case PLPGSQL_STMT_RAISE:
265  return "RAISE";
266  case PLPGSQL_STMT_ASSERT:
267  return "ASSERT";
269  return _("SQL statement");
271  return "EXECUTE";
273  return _("FOR over EXECUTE statement");
275  return ((PLpgSQL_stmt_getdiag *) stmt)->is_stacked ?
276  "GET STACKED DIAGNOSTICS" : "GET DIAGNOSTICS";
277  case PLPGSQL_STMT_OPEN:
278  return "OPEN";
279  case PLPGSQL_STMT_FETCH:
280  return ((PLpgSQL_stmt_fetch *) stmt)->is_move ? "MOVE" : "FETCH";
281  case PLPGSQL_STMT_CLOSE:
282  return "CLOSE";
284  return "PERFORM";
285  case PLPGSQL_STMT_CALL:
286  return ((PLpgSQL_stmt_call *) stmt)->is_call ? "CALL" : "DO";
287  case PLPGSQL_STMT_COMMIT:
288  return "COMMIT";
290  return "ROLLBACK";
291  case PLPGSQL_STMT_SET:
292  return "SET";
293  }
294 
295  return "unknown";
296 }
297 
298 /*
299  * GET DIAGNOSTICS item name as a string, for use in error messages etc.
300  */
301 const char *
303 {
304  switch (kind)
305  {
307  return "ROW_COUNT";
309  return "PG_CONTEXT";
311  return "PG_EXCEPTION_CONTEXT";
313  return "PG_EXCEPTION_DETAIL";
315  return "PG_EXCEPTION_HINT";
317  return "RETURNED_SQLSTATE";
319  return "COLUMN_NAME";
321  return "CONSTRAINT_NAME";
323  return "PG_DATATYPE_NAME";
325  return "MESSAGE_TEXT";
327  return "TABLE_NAME";
329  return "SCHEMA_NAME";
330  }
331 
332  return "unknown";
333 }
334 
335 
336 /**********************************************************************
337  * Release memory when a PL/pgSQL function is no longer needed
338  *
339  * The code for recursing through the function tree is really only
340  * needed to locate PLpgSQL_expr nodes, which may contain references
341  * to saved SPI Plans that must be freed. The function tree itself,
342  * along with subsidiary data, is freed in one swoop by freeing the
343  * function's permanent memory context.
344  **********************************************************************/
345 static void free_stmt(PLpgSQL_stmt *stmt);
346 static void free_block(PLpgSQL_stmt_block *block);
347 static void free_assign(PLpgSQL_stmt_assign *stmt);
348 static void free_if(PLpgSQL_stmt_if *stmt);
349 static void free_case(PLpgSQL_stmt_case *stmt);
350 static void free_loop(PLpgSQL_stmt_loop *stmt);
351 static void free_while(PLpgSQL_stmt_while *stmt);
352 static void free_fori(PLpgSQL_stmt_fori *stmt);
353 static void free_fors(PLpgSQL_stmt_fors *stmt);
354 static void free_forc(PLpgSQL_stmt_forc *stmt);
355 static void free_foreach_a(PLpgSQL_stmt_foreach_a *stmt);
356 static void free_exit(PLpgSQL_stmt_exit *stmt);
357 static void free_return(PLpgSQL_stmt_return *stmt);
358 static void free_return_next(PLpgSQL_stmt_return_next *stmt);
360 static void free_raise(PLpgSQL_stmt_raise *stmt);
361 static void free_assert(PLpgSQL_stmt_assert *stmt);
362 static void free_execsql(PLpgSQL_stmt_execsql *stmt);
363 static void free_dynexecute(PLpgSQL_stmt_dynexecute *stmt);
364 static void free_dynfors(PLpgSQL_stmt_dynfors *stmt);
365 static void free_getdiag(PLpgSQL_stmt_getdiag *stmt);
366 static void free_open(PLpgSQL_stmt_open *stmt);
367 static void free_fetch(PLpgSQL_stmt_fetch *stmt);
368 static void free_close(PLpgSQL_stmt_close *stmt);
369 static void free_perform(PLpgSQL_stmt_perform *stmt);
370 static void free_call(PLpgSQL_stmt_call *stmt);
371 static void free_commit(PLpgSQL_stmt_commit *stmt);
372 static void free_rollback(PLpgSQL_stmt_rollback *stmt);
373 static void free_set(PLpgSQL_stmt_set *stmt);
374 static void free_expr(PLpgSQL_expr *expr);
375 
376 
377 static void
379 {
380  switch (stmt->cmd_type)
381  {
382  case PLPGSQL_STMT_BLOCK:
383  free_block((PLpgSQL_stmt_block *) stmt);
384  break;
385  case PLPGSQL_STMT_ASSIGN:
387  break;
388  case PLPGSQL_STMT_IF:
389  free_if((PLpgSQL_stmt_if *) stmt);
390  break;
391  case PLPGSQL_STMT_CASE:
392  free_case((PLpgSQL_stmt_case *) stmt);
393  break;
394  case PLPGSQL_STMT_LOOP:
395  free_loop((PLpgSQL_stmt_loop *) stmt);
396  break;
397  case PLPGSQL_STMT_WHILE:
398  free_while((PLpgSQL_stmt_while *) stmt);
399  break;
400  case PLPGSQL_STMT_FORI:
401  free_fori((PLpgSQL_stmt_fori *) stmt);
402  break;
403  case PLPGSQL_STMT_FORS:
404  free_fors((PLpgSQL_stmt_fors *) stmt);
405  break;
406  case PLPGSQL_STMT_FORC:
407  free_forc((PLpgSQL_stmt_forc *) stmt);
408  break;
411  break;
412  case PLPGSQL_STMT_EXIT:
413  free_exit((PLpgSQL_stmt_exit *) stmt);
414  break;
415  case PLPGSQL_STMT_RETURN:
417  break;
420  break;
423  break;
424  case PLPGSQL_STMT_RAISE:
425  free_raise((PLpgSQL_stmt_raise *) stmt);
426  break;
427  case PLPGSQL_STMT_ASSERT:
429  break;
432  break;
435  break;
438  break;
441  break;
442  case PLPGSQL_STMT_OPEN:
443  free_open((PLpgSQL_stmt_open *) stmt);
444  break;
445  case PLPGSQL_STMT_FETCH:
446  free_fetch((PLpgSQL_stmt_fetch *) stmt);
447  break;
448  case PLPGSQL_STMT_CLOSE:
449  free_close((PLpgSQL_stmt_close *) stmt);
450  break;
453  break;
454  case PLPGSQL_STMT_CALL:
455  free_call((PLpgSQL_stmt_call *) stmt);
456  break;
457  case PLPGSQL_STMT_COMMIT:
459  break;
462  break;
463  case PLPGSQL_STMT_SET:
464  free_set((PLpgSQL_stmt_set *) stmt);
465  break;
466  default:
467  elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
468  break;
469  }
470 }
471 
472 static void
474 {
475  ListCell *s;
476 
477  foreach(s, stmts)
478  {
479  free_stmt((PLpgSQL_stmt *) lfirst(s));
480  }
481 }
482 
483 static void
485 {
486  free_stmts(block->body);
487  if (block->exceptions)
488  {
489  ListCell *e;
490 
491  foreach(e, block->exceptions->exc_list)
492  {
494 
495  free_stmts(exc->action);
496  }
497  }
498 }
499 
500 static void
502 {
503  free_expr(stmt->expr);
504 }
505 
506 static void
508 {
509  ListCell *l;
510 
511  free_expr(stmt->cond);
512  free_stmts(stmt->then_body);
513  foreach(l, stmt->elsif_list)
514  {
516 
517  free_expr(elif->cond);
518  free_stmts(elif->stmts);
519  }
520  free_stmts(stmt->else_body);
521 }
522 
523 static void
525 {
526  ListCell *l;
527 
528  free_expr(stmt->t_expr);
529  foreach(l, stmt->case_when_list)
530  {
532 
533  free_expr(cwt->expr);
534  free_stmts(cwt->stmts);
535  }
536  free_stmts(stmt->else_stmts);
537 }
538 
539 static void
541 {
542  free_stmts(stmt->body);
543 }
544 
545 static void
547 {
548  free_expr(stmt->cond);
549  free_stmts(stmt->body);
550 }
551 
552 static void
554 {
555  free_expr(stmt->lower);
556  free_expr(stmt->upper);
557  free_expr(stmt->step);
558  free_stmts(stmt->body);
559 }
560 
561 static void
563 {
564  free_stmts(stmt->body);
565  free_expr(stmt->query);
566 }
567 
568 static void
570 {
571  free_stmts(stmt->body);
572  free_expr(stmt->argquery);
573 }
574 
575 static void
577 {
578  free_expr(stmt->expr);
579  free_stmts(stmt->body);
580 }
581 
582 static void
584 {
585  ListCell *lc;
586 
587  free_expr(stmt->argquery);
588  free_expr(stmt->query);
589  free_expr(stmt->dynquery);
590  foreach(lc, stmt->params)
591  {
592  free_expr((PLpgSQL_expr *) lfirst(lc));
593  }
594 }
595 
596 static void
598 {
599  free_expr(stmt->expr);
600 }
601 
602 static void
604 {
605 }
606 
607 static void
609 {
610  free_expr(stmt->expr);
611 }
612 
613 static void
615 {
616  free_expr(stmt->expr);
617 }
618 
619 static void
621 {
622 }
623 
624 static void
626 {
627 }
628 
629 static void
631 {
632  free_expr(stmt->expr);
633 }
634 
635 static void
637 {
638  free_expr(stmt->cond);
639 }
640 
641 static void
643 {
644  free_expr(stmt->expr);
645 }
646 
647 static void
649 {
650  free_expr(stmt->expr);
651 }
652 
653 static void
655 {
656  ListCell *lc;
657 
658  free_expr(stmt->query);
659  free_expr(stmt->dynquery);
660  foreach(lc, stmt->params)
661  {
662  free_expr((PLpgSQL_expr *) lfirst(lc));
663  }
664 }
665 
666 static void
668 {
669  ListCell *lc;
670 
671  foreach(lc, stmt->params)
672  {
673  free_expr((PLpgSQL_expr *) lfirst(lc));
674  }
675  foreach(lc, stmt->options)
676  {
678 
679  free_expr(opt->expr);
680  }
681 }
682 
683 static void
685 {
686  free_expr(stmt->cond);
687  free_expr(stmt->message);
688 }
689 
690 static void
692 {
693  free_expr(stmt->sqlstmt);
694 }
695 
696 static void
698 {
699  ListCell *lc;
700 
701  free_expr(stmt->query);
702  foreach(lc, stmt->params)
703  {
704  free_expr((PLpgSQL_expr *) lfirst(lc));
705  }
706 }
707 
708 static void
710 {
711  ListCell *lc;
712 
713  free_stmts(stmt->body);
714  free_expr(stmt->query);
715  foreach(lc, stmt->params)
716  {
717  free_expr((PLpgSQL_expr *) lfirst(lc));
718  }
719 }
720 
721 static void
723 {
724 }
725 
726 static void
728 {
729  if (expr && expr->plan)
730  {
731  SPI_freeplan(expr->plan);
732  expr->plan = NULL;
733  }
734 }
735 
736 void
738 {
739  int i;
740 
741  /* Better not call this on an in-use function */
742  Assert(func->use_count == 0);
743 
744  /* Release plans associated with variable declarations */
745  for (i = 0; i < func->ndatums; i++)
746  {
747  PLpgSQL_datum *d = func->datums[i];
748 
749  switch (d->dtype)
750  {
751  case PLPGSQL_DTYPE_VAR:
753  {
754  PLpgSQL_var *var = (PLpgSQL_var *) d;
755 
756  free_expr(var->default_val);
758  }
759  break;
760  case PLPGSQL_DTYPE_ROW:
761  break;
762  case PLPGSQL_DTYPE_REC:
763  {
764  PLpgSQL_rec *rec = (PLpgSQL_rec *) d;
765 
766  free_expr(rec->default_val);
767  }
768  break;
770  break;
771  default:
772  elog(ERROR, "unrecognized data type: %d", d->dtype);
773  }
774  }
775  func->ndatums = 0;
776 
777  /* Release plans in statement tree */
778  if (func->action)
779  free_block(func->action);
780  func->action = NULL;
781 
782  /*
783  * And finally, release all memory except the PLpgSQL_function struct
784  * itself (which has to be kept around because there may be multiple
785  * fn_extra pointers to it).
786  */
787  if (func->fn_cxt)
789  func->fn_cxt = NULL;
790 }
791 
792 
793 /**********************************************************************
794  * Debug functions for analyzing the compiled code
795  **********************************************************************/
796 static int dump_indent;
797 
798 static void dump_ind(void);
799 static void dump_stmt(PLpgSQL_stmt *stmt);
800 static void dump_block(PLpgSQL_stmt_block *block);
801 static void dump_assign(PLpgSQL_stmt_assign *stmt);
802 static void dump_if(PLpgSQL_stmt_if *stmt);
803 static void dump_case(PLpgSQL_stmt_case *stmt);
804 static void dump_loop(PLpgSQL_stmt_loop *stmt);
805 static void dump_while(PLpgSQL_stmt_while *stmt);
806 static void dump_fori(PLpgSQL_stmt_fori *stmt);
807 static void dump_fors(PLpgSQL_stmt_fors *stmt);
808 static void dump_forc(PLpgSQL_stmt_forc *stmt);
809 static void dump_foreach_a(PLpgSQL_stmt_foreach_a *stmt);
810 static void dump_exit(PLpgSQL_stmt_exit *stmt);
811 static void dump_return(PLpgSQL_stmt_return *stmt);
812 static void dump_return_next(PLpgSQL_stmt_return_next *stmt);
814 static void dump_raise(PLpgSQL_stmt_raise *stmt);
815 static void dump_assert(PLpgSQL_stmt_assert *stmt);
816 static void dump_execsql(PLpgSQL_stmt_execsql *stmt);
817 static void dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt);
818 static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt);
819 static void dump_getdiag(PLpgSQL_stmt_getdiag *stmt);
820 static void dump_open(PLpgSQL_stmt_open *stmt);
821 static void dump_fetch(PLpgSQL_stmt_fetch *stmt);
822 static void dump_cursor_direction(PLpgSQL_stmt_fetch *stmt);
823 static void dump_close(PLpgSQL_stmt_close *stmt);
824 static void dump_perform(PLpgSQL_stmt_perform *stmt);
825 static void dump_call(PLpgSQL_stmt_call *stmt);
826 static void dump_commit(PLpgSQL_stmt_commit *stmt);
827 static void dump_rollback(PLpgSQL_stmt_rollback *stmt);
828 static void dump_set(PLpgSQL_stmt_set *stmt);
829 static void dump_expr(PLpgSQL_expr *expr);
830 
831 
832 static void
833 dump_ind(void)
834 {
835  int i;
836 
837  for (i = 0; i < dump_indent; i++)
838  printf(" ");
839 }
840 
841 static void
843 {
844  printf("%3d:", stmt->lineno);
845  switch (stmt->cmd_type)
846  {
847  case PLPGSQL_STMT_BLOCK:
848  dump_block((PLpgSQL_stmt_block *) stmt);
849  break;
850  case PLPGSQL_STMT_ASSIGN:
852  break;
853  case PLPGSQL_STMT_IF:
854  dump_if((PLpgSQL_stmt_if *) stmt);
855  break;
856  case PLPGSQL_STMT_CASE:
857  dump_case((PLpgSQL_stmt_case *) stmt);
858  break;
859  case PLPGSQL_STMT_LOOP:
860  dump_loop((PLpgSQL_stmt_loop *) stmt);
861  break;
862  case PLPGSQL_STMT_WHILE:
863  dump_while((PLpgSQL_stmt_while *) stmt);
864  break;
865  case PLPGSQL_STMT_FORI:
866  dump_fori((PLpgSQL_stmt_fori *) stmt);
867  break;
868  case PLPGSQL_STMT_FORS:
869  dump_fors((PLpgSQL_stmt_fors *) stmt);
870  break;
871  case PLPGSQL_STMT_FORC:
872  dump_forc((PLpgSQL_stmt_forc *) stmt);
873  break;
876  break;
877  case PLPGSQL_STMT_EXIT:
878  dump_exit((PLpgSQL_stmt_exit *) stmt);
879  break;
880  case PLPGSQL_STMT_RETURN:
882  break;
885  break;
888  break;
889  case PLPGSQL_STMT_RAISE:
890  dump_raise((PLpgSQL_stmt_raise *) stmt);
891  break;
892  case PLPGSQL_STMT_ASSERT:
894  break;
897  break;
900  break;
903  break;
906  break;
907  case PLPGSQL_STMT_OPEN:
908  dump_open((PLpgSQL_stmt_open *) stmt);
909  break;
910  case PLPGSQL_STMT_FETCH:
911  dump_fetch((PLpgSQL_stmt_fetch *) stmt);
912  break;
913  case PLPGSQL_STMT_CLOSE:
914  dump_close((PLpgSQL_stmt_close *) stmt);
915  break;
918  break;
919  case PLPGSQL_STMT_CALL:
920  dump_call((PLpgSQL_stmt_call *) stmt);
921  break;
922  case PLPGSQL_STMT_COMMIT:
924  break;
927  break;
928  case PLPGSQL_STMT_SET:
929  dump_set((PLpgSQL_stmt_set *) stmt);
930  break;
931  default:
932  elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
933  break;
934  }
935 }
936 
937 static void
939 {
940  ListCell *s;
941 
942  dump_indent += 2;
943  foreach(s, stmts)
944  dump_stmt((PLpgSQL_stmt *) lfirst(s));
945  dump_indent -= 2;
946 }
947 
948 static void
950 {
951  char *name;
952 
953  if (block->label == NULL)
954  name = "*unnamed*";
955  else
956  name = block->label;
957 
958  dump_ind();
959  printf("BLOCK <<%s>>\n", name);
960 
961  dump_stmts(block->body);
962 
963  if (block->exceptions)
964  {
965  ListCell *e;
966 
967  foreach(e, block->exceptions->exc_list)
968  {
970  PLpgSQL_condition *cond;
971 
972  dump_ind();
973  printf(" EXCEPTION WHEN ");
974  for (cond = exc->conditions; cond; cond = cond->next)
975  {
976  if (cond != exc->conditions)
977  printf(" OR ");
978  printf("%s", cond->condname);
979  }
980  printf(" THEN\n");
981  dump_stmts(exc->action);
982  }
983  }
984 
985  dump_ind();
986  printf(" END -- %s\n", name);
987 }
988 
989 static void
991 {
992  dump_ind();
993  printf("ASSIGN var %d := ", stmt->varno);
994  dump_expr(stmt->expr);
995  printf("\n");
996 }
997 
998 static void
1000 {
1001  ListCell *l;
1002 
1003  dump_ind();
1004  printf("IF ");
1005  dump_expr(stmt->cond);
1006  printf(" THEN\n");
1007  dump_stmts(stmt->then_body);
1008  foreach(l, stmt->elsif_list)
1009  {
1010  PLpgSQL_if_elsif *elif = (PLpgSQL_if_elsif *) lfirst(l);
1011 
1012  dump_ind();
1013  printf(" ELSIF ");
1014  dump_expr(elif->cond);
1015  printf(" THEN\n");
1016  dump_stmts(elif->stmts);
1017  }
1018  if (stmt->else_body != NIL)
1019  {
1020  dump_ind();
1021  printf(" ELSE\n");
1022  dump_stmts(stmt->else_body);
1023  }
1024  dump_ind();
1025  printf(" ENDIF\n");
1026 }
1027 
1028 static void
1030 {
1031  ListCell *l;
1032 
1033  dump_ind();
1034  printf("CASE %d ", stmt->t_varno);
1035  if (stmt->t_expr)
1036  dump_expr(stmt->t_expr);
1037  printf("\n");
1038  dump_indent += 6;
1039  foreach(l, stmt->case_when_list)
1040  {
1042 
1043  dump_ind();
1044  printf("WHEN ");
1045  dump_expr(cwt->expr);
1046  printf("\n");
1047  dump_ind();
1048  printf("THEN\n");
1049  dump_indent += 2;
1050  dump_stmts(cwt->stmts);
1051  dump_indent -= 2;
1052  }
1053  if (stmt->have_else)
1054  {
1055  dump_ind();
1056  printf("ELSE\n");
1057  dump_indent += 2;
1058  dump_stmts(stmt->else_stmts);
1059  dump_indent -= 2;
1060  }
1061  dump_indent -= 6;
1062  dump_ind();
1063  printf(" ENDCASE\n");
1064 }
1065 
1066 static void
1068 {
1069  dump_ind();
1070  printf("LOOP\n");
1071 
1072  dump_stmts(stmt->body);
1073 
1074  dump_ind();
1075  printf(" ENDLOOP\n");
1076 }
1077 
1078 static void
1080 {
1081  dump_ind();
1082  printf("WHILE ");
1083  dump_expr(stmt->cond);
1084  printf("\n");
1085 
1086  dump_stmts(stmt->body);
1087 
1088  dump_ind();
1089  printf(" ENDWHILE\n");
1090 }
1091 
1092 static void
1094 {
1095  dump_ind();
1096  printf("FORI %s %s\n", stmt->var->refname, (stmt->reverse) ? "REVERSE" : "NORMAL");
1097 
1098  dump_indent += 2;
1099  dump_ind();
1100  printf(" lower = ");
1101  dump_expr(stmt->lower);
1102  printf("\n");
1103  dump_ind();
1104  printf(" upper = ");
1105  dump_expr(stmt->upper);
1106  printf("\n");
1107  if (stmt->step)
1108  {
1109  dump_ind();
1110  printf(" step = ");
1111  dump_expr(stmt->step);
1112  printf("\n");
1113  }
1114  dump_indent -= 2;
1115 
1116  dump_stmts(stmt->body);
1117 
1118  dump_ind();
1119  printf(" ENDFORI\n");
1120 }
1121 
1122 static void
1124 {
1125  dump_ind();
1126  printf("FORS %s ", stmt->var->refname);
1127  dump_expr(stmt->query);
1128  printf("\n");
1129 
1130  dump_stmts(stmt->body);
1131 
1132  dump_ind();
1133  printf(" ENDFORS\n");
1134 }
1135 
1136 static void
1138 {
1139  dump_ind();
1140  printf("FORC %s ", stmt->var->refname);
1141  printf("curvar=%d\n", stmt->curvar);
1142 
1143  dump_indent += 2;
1144  if (stmt->argquery != NULL)
1145  {
1146  dump_ind();
1147  printf(" arguments = ");
1148  dump_expr(stmt->argquery);
1149  printf("\n");
1150  }
1151  dump_indent -= 2;
1152 
1153  dump_stmts(stmt->body);
1154 
1155  dump_ind();
1156  printf(" ENDFORC\n");
1157 }
1158 
1159 static void
1161 {
1162  dump_ind();
1163  printf("FOREACHA var %d ", stmt->varno);
1164  if (stmt->slice != 0)
1165  printf("SLICE %d ", stmt->slice);
1166  printf("IN ");
1167  dump_expr(stmt->expr);
1168  printf("\n");
1169 
1170  dump_stmts(stmt->body);
1171 
1172  dump_ind();
1173  printf(" ENDFOREACHA");
1174 }
1175 
1176 static void
1178 {
1179  dump_ind();
1180  printf("OPEN curvar=%d\n", stmt->curvar);
1181 
1182  dump_indent += 2;
1183  if (stmt->argquery != NULL)
1184  {
1185  dump_ind();
1186  printf(" arguments = '");
1187  dump_expr(stmt->argquery);
1188  printf("'\n");
1189  }
1190  if (stmt->query != NULL)
1191  {
1192  dump_ind();
1193  printf(" query = '");
1194  dump_expr(stmt->query);
1195  printf("'\n");
1196  }
1197  if (stmt->dynquery != NULL)
1198  {
1199  dump_ind();
1200  printf(" execute = '");
1201  dump_expr(stmt->dynquery);
1202  printf("'\n");
1203 
1204  if (stmt->params != NIL)
1205  {
1206  ListCell *lc;
1207  int i;
1208 
1209  dump_indent += 2;
1210  dump_ind();
1211  printf(" USING\n");
1212  dump_indent += 2;
1213  i = 1;
1214  foreach(lc, stmt->params)
1215  {
1216  dump_ind();
1217  printf(" parameter $%d: ", i++);
1218  dump_expr((PLpgSQL_expr *) lfirst(lc));
1219  printf("\n");
1220  }
1221  dump_indent -= 4;
1222  }
1223  }
1224  dump_indent -= 2;
1225 }
1226 
1227 static void
1229 {
1230  dump_ind();
1231 
1232  if (!stmt->is_move)
1233  {
1234  printf("FETCH curvar=%d\n", stmt->curvar);
1235  dump_cursor_direction(stmt);
1236 
1237  dump_indent += 2;
1238  if (stmt->target != NULL)
1239  {
1240  dump_ind();
1241  printf(" target = %d %s\n",
1242  stmt->target->dno, stmt->target->refname);
1243  }
1244  dump_indent -= 2;
1245  }
1246  else
1247  {
1248  printf("MOVE curvar=%d\n", stmt->curvar);
1249  dump_cursor_direction(stmt);
1250  }
1251 }
1252 
1253 static void
1255 {
1256  dump_indent += 2;
1257  dump_ind();
1258  switch (stmt->direction)
1259  {
1260  case FETCH_FORWARD:
1261  printf(" FORWARD ");
1262  break;
1263  case FETCH_BACKWARD:
1264  printf(" BACKWARD ");
1265  break;
1266  case FETCH_ABSOLUTE:
1267  printf(" ABSOLUTE ");
1268  break;
1269  case FETCH_RELATIVE:
1270  printf(" RELATIVE ");
1271  break;
1272  default:
1273  printf("??? unknown cursor direction %d", stmt->direction);
1274  }
1275 
1276  if (stmt->expr)
1277  {
1278  dump_expr(stmt->expr);
1279  printf("\n");
1280  }
1281  else
1282  printf("%ld\n", stmt->how_many);
1283 
1284  dump_indent -= 2;
1285 }
1286 
1287 static void
1289 {
1290  dump_ind();
1291  printf("CLOSE curvar=%d\n", stmt->curvar);
1292 }
1293 
1294 static void
1296 {
1297  dump_ind();
1298  printf("PERFORM expr = ");
1299  dump_expr(stmt->expr);
1300  printf("\n");
1301 }
1302 
1303 static void
1305 {
1306  dump_ind();
1307  printf("%s expr = ", stmt->is_call ? "CALL" : "DO");
1308  dump_expr(stmt->expr);
1309  printf("\n");
1310 }
1311 
1312 static void
1314 {
1315  dump_ind();
1316  if (stmt->chain)
1317  printf("COMMIT AND CHAIN\n");
1318  else
1319  printf("COMMIT\n");
1320 }
1321 
1322 static void
1324 {
1325  dump_ind();
1326  if (stmt->chain)
1327  printf("ROLLBACK AND CHAIN\n");
1328  else
1329  printf("ROLLBACK\n");
1330 }
1331 
1332 static void
1334 {
1335  dump_ind();
1336  printf("%s\n", stmt->expr->query);
1337 }
1338 
1339 static void
1341 {
1342  dump_ind();
1343  printf("%s", stmt->is_exit ? "EXIT" : "CONTINUE");
1344  if (stmt->label != NULL)
1345  printf(" label='%s'", stmt->label);
1346  if (stmt->cond != NULL)
1347  {
1348  printf(" WHEN ");
1349  dump_expr(stmt->cond);
1350  }
1351  printf("\n");
1352 }
1353 
1354 static void
1356 {
1357  dump_ind();
1358  printf("RETURN ");
1359  if (stmt->retvarno >= 0)
1360  printf("variable %d", stmt->retvarno);
1361  else if (stmt->expr != NULL)
1362  dump_expr(stmt->expr);
1363  else
1364  printf("NULL");
1365  printf("\n");
1366 }
1367 
1368 static void
1370 {
1371  dump_ind();
1372  printf("RETURN NEXT ");
1373  if (stmt->retvarno >= 0)
1374  printf("variable %d", stmt->retvarno);
1375  else if (stmt->expr != NULL)
1376  dump_expr(stmt->expr);
1377  else
1378  printf("NULL");
1379  printf("\n");
1380 }
1381 
1382 static void
1384 {
1385  dump_ind();
1386  if (stmt->query)
1387  {
1388  printf("RETURN QUERY ");
1389  dump_expr(stmt->query);
1390  printf("\n");
1391  }
1392  else
1393  {
1394  printf("RETURN QUERY EXECUTE ");
1395  dump_expr(stmt->dynquery);
1396  printf("\n");
1397  if (stmt->params != NIL)
1398  {
1399  ListCell *lc;
1400  int i;
1401 
1402  dump_indent += 2;
1403  dump_ind();
1404  printf(" USING\n");
1405  dump_indent += 2;
1406  i = 1;
1407  foreach(lc, stmt->params)
1408  {
1409  dump_ind();
1410  printf(" parameter $%d: ", i++);
1411  dump_expr((PLpgSQL_expr *) lfirst(lc));
1412  printf("\n");
1413  }
1414  dump_indent -= 4;
1415  }
1416  }
1417 }
1418 
1419 static void
1421 {
1422  ListCell *lc;
1423  int i = 0;
1424 
1425  dump_ind();
1426  printf("RAISE level=%d", stmt->elog_level);
1427  if (stmt->condname)
1428  printf(" condname='%s'", stmt->condname);
1429  if (stmt->message)
1430  printf(" message='%s'", stmt->message);
1431  printf("\n");
1432  dump_indent += 2;
1433  foreach(lc, stmt->params)
1434  {
1435  dump_ind();
1436  printf(" parameter %d: ", i++);
1437  dump_expr((PLpgSQL_expr *) lfirst(lc));
1438  printf("\n");
1439  }
1440  if (stmt->options)
1441  {
1442  dump_ind();
1443  printf(" USING\n");
1444  dump_indent += 2;
1445  foreach(lc, stmt->options)
1446  {
1448 
1449  dump_ind();
1450  switch (opt->opt_type)
1451  {
1453  printf(" ERRCODE = ");
1454  break;
1456  printf(" MESSAGE = ");
1457  break;
1459  printf(" DETAIL = ");
1460  break;
1462  printf(" HINT = ");
1463  break;
1465  printf(" COLUMN = ");
1466  break;
1468  printf(" CONSTRAINT = ");
1469  break;
1471  printf(" DATATYPE = ");
1472  break;
1474  printf(" TABLE = ");
1475  break;
1477  printf(" SCHEMA = ");
1478  break;
1479  }
1480  dump_expr(opt->expr);
1481  printf("\n");
1482  }
1483  dump_indent -= 2;
1484  }
1485  dump_indent -= 2;
1486 }
1487 
1488 static void
1490 {
1491  dump_ind();
1492  printf("ASSERT ");
1493  dump_expr(stmt->cond);
1494  printf("\n");
1495 
1496  dump_indent += 2;
1497  if (stmt->message != NULL)
1498  {
1499  dump_ind();
1500  printf(" MESSAGE = ");
1501  dump_expr(stmt->message);
1502  printf("\n");
1503  }
1504  dump_indent -= 2;
1505 }
1506 
1507 static void
1509 {
1510  dump_ind();
1511  printf("EXECSQL ");
1512  dump_expr(stmt->sqlstmt);
1513  printf("\n");
1514 
1515  dump_indent += 2;
1516  if (stmt->target != NULL)
1517  {
1518  dump_ind();
1519  printf(" INTO%s target = %d %s\n",
1520  stmt->strict ? " STRICT" : "",
1521  stmt->target->dno, stmt->target->refname);
1522  }
1523  dump_indent -= 2;
1524 }
1525 
1526 static void
1528 {
1529  dump_ind();
1530  printf("EXECUTE ");
1531  dump_expr(stmt->query);
1532  printf("\n");
1533 
1534  dump_indent += 2;
1535  if (stmt->target != NULL)
1536  {
1537  dump_ind();
1538  printf(" INTO%s target = %d %s\n",
1539  stmt->strict ? " STRICT" : "",
1540  stmt->target->dno, stmt->target->refname);
1541  }
1542  if (stmt->params != NIL)
1543  {
1544  ListCell *lc;
1545  int i;
1546 
1547  dump_ind();
1548  printf(" USING\n");
1549  dump_indent += 2;
1550  i = 1;
1551  foreach(lc, stmt->params)
1552  {
1553  dump_ind();
1554  printf(" parameter %d: ", i++);
1555  dump_expr((PLpgSQL_expr *) lfirst(lc));
1556  printf("\n");
1557  }
1558  dump_indent -= 2;
1559  }
1560  dump_indent -= 2;
1561 }
1562 
1563 static void
1565 {
1566  dump_ind();
1567  printf("FORS %s EXECUTE ", stmt->var->refname);
1568  dump_expr(stmt->query);
1569  printf("\n");
1570  if (stmt->params != NIL)
1571  {
1572  ListCell *lc;
1573  int i;
1574 
1575  dump_indent += 2;
1576  dump_ind();
1577  printf(" USING\n");
1578  dump_indent += 2;
1579  i = 1;
1580  foreach(lc, stmt->params)
1581  {
1582  dump_ind();
1583  printf(" parameter $%d: ", i++);
1584  dump_expr((PLpgSQL_expr *) lfirst(lc));
1585  printf("\n");
1586  }
1587  dump_indent -= 4;
1588  }
1589  dump_stmts(stmt->body);
1590  dump_ind();
1591  printf(" ENDFORS\n");
1592 }
1593 
1594 static void
1596 {
1597  ListCell *lc;
1598 
1599  dump_ind();
1600  printf("GET %s DIAGNOSTICS ", stmt->is_stacked ? "STACKED" : "CURRENT");
1601  foreach(lc, stmt->diag_items)
1602  {
1603  PLpgSQL_diag_item *diag_item = (PLpgSQL_diag_item *) lfirst(lc);
1604 
1605  if (lc != list_head(stmt->diag_items))
1606  printf(", ");
1607 
1608  printf("{var %d} = %s", diag_item->target,
1609  plpgsql_getdiag_kindname(diag_item->kind));
1610  }
1611  printf("\n");
1612 }
1613 
1614 static void
1616 {
1617  printf("'%s'", expr->query);
1618 }
1619 
1620 void
1622 {
1623  int i;
1624  PLpgSQL_datum *d;
1625 
1626  printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1627  func->fn_signature);
1628 
1629  printf("\nFunction's data area:\n");
1630  for (i = 0; i < func->ndatums; i++)
1631  {
1632  d = func->datums[i];
1633 
1634  printf(" entry %d: ", i);
1635  switch (d->dtype)
1636  {
1637  case PLPGSQL_DTYPE_VAR:
1638  case PLPGSQL_DTYPE_PROMISE:
1639  {
1640  PLpgSQL_var *var = (PLpgSQL_var *) d;
1641 
1642  printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1643  var->refname, var->datatype->typname,
1644  var->datatype->typoid,
1645  var->datatype->atttypmod);
1646  if (var->isconst)
1647  printf(" CONSTANT\n");
1648  if (var->notnull)
1649  printf(" NOT NULL\n");
1650  if (var->default_val != NULL)
1651  {
1652  printf(" DEFAULT ");
1653  dump_expr(var->default_val);
1654  printf("\n");
1655  }
1656  if (var->cursor_explicit_expr != NULL)
1657  {
1658  if (var->cursor_explicit_argrow >= 0)
1659  printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1660 
1661  printf(" CURSOR IS ");
1663  printf("\n");
1664  }
1665  if (var->promise != PLPGSQL_PROMISE_NONE)
1666  printf(" PROMISE %d\n",
1667  (int) var->promise);
1668  }
1669  break;
1670  case PLPGSQL_DTYPE_ROW:
1671  {
1672  PLpgSQL_row *row = (PLpgSQL_row *) d;
1673  int i;
1674 
1675  printf("ROW %-16s fields", row->refname);
1676  for (i = 0; i < row->nfields; i++)
1677  {
1678  printf(" %s=var %d", row->fieldnames[i],
1679  row->varnos[i]);
1680  }
1681  printf("\n");
1682  }
1683  break;
1684  case PLPGSQL_DTYPE_REC:
1685  printf("REC %-16s typoid %u\n",
1686  ((PLpgSQL_rec *) d)->refname,
1687  ((PLpgSQL_rec *) d)->rectypeid);
1688  if (((PLpgSQL_rec *) d)->isconst)
1689  printf(" CONSTANT\n");
1690  if (((PLpgSQL_rec *) d)->notnull)
1691  printf(" NOT NULL\n");
1692  if (((PLpgSQL_rec *) d)->default_val != NULL)
1693  {
1694  printf(" DEFAULT ");
1695  dump_expr(((PLpgSQL_rec *) d)->default_val);
1696  printf("\n");
1697  }
1698  break;
1700  printf("RECFIELD %-16s of REC %d\n",
1701  ((PLpgSQL_recfield *) d)->fieldname,
1702  ((PLpgSQL_recfield *) d)->recparentno);
1703  break;
1704  default:
1705  printf("??? unknown data type %d\n", d->dtype);
1706  }
1707  }
1708  printf("\nFunction's statements:\n");
1709 
1710  dump_indent = 0;
1711  printf("%3d:", func->action->lineno);
1712  dump_block(func->action);
1713  printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1714  fflush(stdout);
1715 }
PLpgSQL_promise_type promise
Definition: plpgsql.h:342
#define NIL
Definition: pg_list.h:65
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:737
PLpgSQL_expr * query
Definition: plpgsql.h:923
PLpgSQL_datum ** datums
Definition: plpgsql.h:1014
PLpgSQL_expr * cond
Definition: plpgsql.h:609
PLpgSQL_expr * cond
Definition: plpgsql.h:671
List * then_body
Definition: plpgsql.h:610
PLpgSQL_expr * expr
Definition: plpgsql.h:765
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:212
char * refname
Definition: plpgsql.h:367
char * query
Definition: plpgsql.h:220
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
static void free_assert(PLpgSQL_stmt_assert *stmt)
Definition: pl_funcs.c:684
FetchDirection direction
Definition: plpgsql.h:795
int lineno
Definition: plpgsql.h:456
static void free_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
Definition: pl_funcs.c:697
static void dump_cursor_direction(PLpgSQL_stmt_fetch *stmt)
Definition: pl_funcs.c:1254
char * refname
Definition: plpgsql.h:313
PLpgSQL_expr * expr
Definition: plpgsql.h:834
List * elsif_list
Definition: plpgsql.h:611
static void free_raise(PLpgSQL_stmt_raise *stmt)
Definition: pl_funcs.c:667
PLpgSQL_stmt_block * action
Definition: plpgsql.h:1018
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:327
List * stmts
Definition: plpgsql.h:622
PLpgSQL_variable * var
Definition: plpgsql.h:731
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:130
char * condname
Definition: plpgsql.h:472
PLpgSQL_type * datatype
Definition: plpgsql.h:320
static void dump_raise(PLpgSQL_stmt_raise *stmt)
Definition: pl_funcs.c:1420
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
static void dump_perform(PLpgSQL_stmt_perform *stmt)
Definition: pl_funcs.c:1295
bool isconst
Definition: plpgsql.h:315
static void dump_forc(PLpgSQL_stmt_forc *stmt)
Definition: pl_funcs.c:1137
PLpgSQL_expr * sqlstmt
Definition: plpgsql.h:907
struct PLpgSQL_condition * next
Definition: plpgsql.h:473
#define printf(...)
Definition: port.h:222
PLpgSQL_expr * dynquery
Definition: plpgsql.h:781
static void dump_rollback(PLpgSQL_stmt_rollback *stmt)
Definition: pl_funcs.c:1323
void plpgsql_dumptree(PLpgSQL_function *func)
Definition: pl_funcs.c:1621
PLpgSQL_expr * expr
Definition: plpgsql.h:531
PLpgSQL_expr * cond
Definition: plpgsql.h:621
List * else_stmts
Definition: plpgsql.h:637
static void free_open(PLpgSQL_stmt_open *stmt)
Definition: pl_funcs.c:583
PLpgSQL_datum_type dtype
Definition: plpgsql.h:277
static void dump_fors(PLpgSQL_stmt_fors *stmt)
Definition: pl_funcs.c:1123
PLpgSQL_expr * lower
Definition: plpgsql.h:685
static void free_return(PLpgSQL_stmt_return *stmt)
Definition: pl_funcs.c:642
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:35
PLpgSQL_getdiag_kind kind
Definition: plpgsql.h:585
SPIPlanPtr plan
Definition: plpgsql.h:222
static void free_loop(PLpgSQL_stmt_loop *stmt)
Definition: pl_funcs.c:540
PLpgSQL_raise_option_type opt_type
Definition: plpgsql.h:883
static void dump_fetch(PLpgSQL_stmt_fetch *stmt)
Definition: pl_funcs.c:1228
static void free_dynfors(PLpgSQL_stmt_dynfors *stmt)
Definition: pl_funcs.c:709
static void free_set(PLpgSQL_stmt_set *stmt)
Definition: pl_funcs.c:630
PLpgSQL_expr * query
Definition: plpgsql.h:858
static void free_rollback(PLpgSQL_stmt_rollback *stmt)
Definition: pl_funcs.c:625
bool notnull
Definition: plpgsql.h:316
static void free_assign(PLpgSQL_stmt_assign *stmt)
Definition: pl_funcs.c:501
int cursor_explicit_argrow
Definition: plpgsql.h:328
PLpgSQL_expr * expr
Definition: plpgsql.h:577
void plpgsql_ns_pop(void)
Definition: pl_funcs.c:67
static void free_getdiag(PLpgSQL_stmt_getdiag *stmt)
Definition: pl_funcs.c:722
PLpgSQL_expr * expr
Definition: plpgsql.h:846
#define ERROR
Definition: elog.h:45
PLpgSQL_var * var
Definition: plpgsql.h:684
char ** fieldnames
Definition: plpgsql.h:382
PLpgSQL_expr * message
Definition: plpgsql.h:896
PLpgSQL_variable * target
Definition: plpgsql.h:912
PLpgSQL_label_type
Definition: plpgsql.h:51
PLpgSQL_expr * default_val
Definition: plpgsql.h:317
unsigned long use_count
Definition: plpgsql.h:1026
static void free_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:727
static void free_fetch(PLpgSQL_stmt_fetch *stmt)
Definition: pl_funcs.c:597
static void dump_case(PLpgSQL_stmt_case *stmt)
Definition: pl_funcs.c:1029
static void free_close(PLpgSQL_stmt_close *stmt)
Definition: pl_funcs.c:603
static void free_case(PLpgSQL_stmt_case *stmt)
Definition: pl_funcs.c:524
PLpgSQL_variable * var
Definition: plpgsql.h:716
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
static void dump_getdiag(PLpgSQL_stmt_getdiag *stmt)
Definition: pl_funcs.c:1595
MemoryContext fn_cxt
Definition: plpgsql.h:986
void plpgsql_ns_init(void)
Definition: pl_funcs.c:43
PLpgSQL_expr * expr
Definition: plpgsql.h:646
List * case_when_list
Definition: plpgsql.h:635
static void dump_if(PLpgSQL_stmt_if *stmt)
Definition: pl_funcs.c:999
PLpgSQL_expr * query
Definition: plpgsql.h:750
int * varnos
Definition: plpgsql.h:383
static void free_fori(PLpgSQL_stmt_fori *stmt)
Definition: pl_funcs.c:553
static void dump_return_query(PLpgSQL_stmt_return_query *stmt)
Definition: pl_funcs.c:1383
static void free_perform(PLpgSQL_stmt_perform *stmt)
Definition: pl_funcs.c:608
static void dump_return(PLpgSQL_stmt_return *stmt)
Definition: pl_funcs.c:1355
static void free_return_next(PLpgSQL_stmt_return_next *stmt)
Definition: pl_funcs.c:648
PLpgSQL_expr * expr
Definition: plpgsql.h:542
static void dump_set(PLpgSQL_stmt_set *stmt)
Definition: pl_funcs.c:1333
static void dump_return_next(PLpgSQL_stmt_return_next *stmt)
Definition: pl_funcs.c:1369
static void dump_loop(PLpgSQL_stmt_loop *stmt)
Definition: pl_funcs.c:1067
static void free_call(PLpgSQL_stmt_call *stmt)
Definition: pl_funcs.c:614
static void free_fors(PLpgSQL_stmt_fors *stmt)
Definition: pl_funcs.c:562
PLpgSQL_getdiag_kind
Definition: plpgsql.h:148
static void dump_close(PLpgSQL_stmt_close *stmt)
Definition: pl_funcs.c:1288
static void free_exit(PLpgSQL_stmt_exit *stmt)
Definition: pl_funcs.c:636
static char * label
PLpgSQL_datum_type dtype
Definition: plpgsql.h:422
PLpgSQL_expr * cond
Definition: plpgsql.h:823
PLpgSQL_expr * query
Definition: plpgsql.h:780
static void dump_ind(void)
Definition: pl_funcs.c:833
PLpgSQL_variable * var
Definition: plpgsql.h:747
PLpgSQL_condition * conditions
Definition: plpgsql.h:492
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:446
static void dump_while(PLpgSQL_stmt_while *stmt)
Definition: pl_funcs.c:1079
static void free_stmts(List *stmts)
Definition: pl_funcs.c:473
static void free_if(PLpgSQL_stmt_if *stmt)
Definition: pl_funcs.c:507
PLpgSQL_nsitem * plpgsql_ns_find_nearest_loop(PLpgSQL_nsitem *ns_cur)
Definition: pl_funcs.c:214
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
int nfields
Definition: plpgsql.h:381
PLpgSQL_exception_block * exceptions
Definition: plpgsql.h:508
static void free_return_query(PLpgSQL_stmt_return_query *stmt)
Definition: pl_funcs.c:654
const char * plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind)
Definition: pl_funcs.c:302
static void dump_execsql(PLpgSQL_stmt_execsql *stmt)
Definition: pl_funcs.c:1508
PLpgSQL_stmt_type cmd_type
Definition: plpgsql.h:574
static void free_stmt(PLpgSQL_stmt *stmt)
Definition: pl_funcs.c:378
static int dump_indent
Definition: pl_funcs.c:796
char * fn_signature
Definition: plpgsql.h:979
static void dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
Definition: pl_funcs.c:1527
List * else_body
Definition: plpgsql.h:612
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
Definition: pl_funcs.c:54
PLpgSQL_nsitem * plpgsql_ns_lookup_label(PLpgSQL_nsitem *ns_cur, const char *name)
Definition: pl_funcs.c:195
char * typname
Definition: plpgsql.h:200
PLpgSQL_expr * step
Definition: plpgsql.h:687
PLpgSQL_expr * t_expr
Definition: plpgsql.h:633
char * refname
Definition: plpgsql.h:291
PLpgSQL_expr * dynquery
Definition: plpgsql.h:859
static void free_execsql(PLpgSQL_stmt_execsql *stmt)
Definition: pl_funcs.c:691
PLpgSQL_expr * expr
Definition: plpgsql.h:797
static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt)
Definition: pl_funcs.c:1564
const char * name
Definition: encode.c:515
PLpgSQL_expr * expr
Definition: plpgsql.h:520
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:949
PLpgSQL_expr * expr
Definition: plpgsql.h:884
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:921
e
Definition: preproc-init.c:82
static void dump_foreach_a(PLpgSQL_stmt_foreach_a *stmt)
Definition: pl_funcs.c:1160
void * palloc(Size size)
Definition: mcxt.c:950
int32 atttypmod
Definition: plpgsql.h:208
static void free_forc(PLpgSQL_stmt_forc *stmt)
Definition: pl_funcs.c:569
static void dump_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:1615
PLpgSQL_expr * argquery
Definition: plpgsql.h:779
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:439
#define elog(elevel,...)
Definition: elog.h:227
static void dump_commit(PLpgSQL_stmt_commit *stmt)
Definition: pl_funcs.c:1313
int i
const char * plpgsql_stmt_typename(PLpgSQL_stmt *stmt)
Definition: pl_funcs.c:232
static void dump_assert(PLpgSQL_stmt_assert *stmt)
Definition: pl_funcs.c:1489
static void dump_open(PLpgSQL_stmt_open *stmt)
Definition: pl_funcs.c:1177
PLpgSQL_expr * argquery
Definition: plpgsql.h:735
static void free_commit(PLpgSQL_stmt_commit *stmt)
Definition: pl_funcs.c:620
PLpgSQL_expr * upper
Definition: plpgsql.h:686
PLpgSQL_stmt_type cmd_type
Definition: plpgsql.h:455
static void dump_fori(PLpgSQL_stmt_fori *stmt)
Definition: pl_funcs.c:1093
static void free_while(PLpgSQL_stmt_while *stmt)
Definition: pl_funcs.c:546
PLpgSQL_expr * query
Definition: plpgsql.h:719
PLpgSQL_variable * target
Definition: plpgsql.h:793
PLpgSQL_expr * cond
Definition: plpgsql.h:895
PLpgSQL_variable * target
Definition: plpgsql.h:926
static void dump_stmts(List *stmts)
Definition: pl_funcs.c:938
static void dump_stmt(PLpgSQL_stmt *stmt)
Definition: pl_funcs.c:842
PLpgSQL_expr * default_val
Definition: plpgsql.h:397
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:447
static void free_foreach_a(PLpgSQL_stmt_foreach_a *stmt)
Definition: pl_funcs.c:576
Definition: pg_list.h:50
#define _(x)
Definition: elog.c:89
static void dump_call(PLpgSQL_stmt_call *stmt)
Definition: pl_funcs.c:1304
static void dump_assign(PLpgSQL_stmt_assign *stmt)
Definition: pl_funcs.c:990
#define offsetof(type, field)
Definition: c.h:727
static void free_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:484
PLpgSQL_nsitem_type
Definition: plpgsql.h:41
static void dump_exit(PLpgSQL_stmt_exit *stmt)
Definition: pl_funcs.c:1340
Oid typoid
Definition: plpgsql.h:201