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