PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "plpgsql.h"
17 
18 #include "utils/memutils.h"
19 
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  */
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  }
286 
287  return "unknown";
288 }
289 
290 /*
291  * GET DIAGNOSTICS item name as a string, for use in error messages etc.
292  */
293 const char *
295 {
296  switch (kind)
297  {
299  return "ROW_COUNT";
301  return "RESULT_OID";
303  return "PG_CONTEXT";
305  return "PG_EXCEPTION_CONTEXT";
307  return "PG_EXCEPTION_DETAIL";
309  return "PG_EXCEPTION_HINT";
311  return "RETURNED_SQLSTATE";
313  return "COLUMN_NAME";
315  return "CONSTRAINT_NAME";
317  return "PG_DATATYPE_NAME";
319  return "MESSAGE_TEXT";
321  return "TABLE_NAME";
323  return "SCHEMA_NAME";
324  }
325 
326  return "unknown";
327 }
328 
329 
330 /**********************************************************************
331  * Release memory when a PL/pgSQL function is no longer needed
332  *
333  * The code for recursing through the function tree is really only
334  * needed to locate PLpgSQL_expr nodes, which may contain references
335  * to saved SPI Plans that must be freed. The function tree itself,
336  * along with subsidiary data, is freed in one swoop by freeing the
337  * function's permanent memory context.
338  **********************************************************************/
339 static void free_stmt(PLpgSQL_stmt *stmt);
340 static void free_block(PLpgSQL_stmt_block *block);
341 static void free_assign(PLpgSQL_stmt_assign *stmt);
342 static void free_if(PLpgSQL_stmt_if *stmt);
343 static void free_case(PLpgSQL_stmt_case *stmt);
344 static void free_loop(PLpgSQL_stmt_loop *stmt);
345 static void free_while(PLpgSQL_stmt_while *stmt);
346 static void free_fori(PLpgSQL_stmt_fori *stmt);
347 static void free_fors(PLpgSQL_stmt_fors *stmt);
348 static void free_forc(PLpgSQL_stmt_forc *stmt);
349 static void free_foreach_a(PLpgSQL_stmt_foreach_a *stmt);
350 static void free_exit(PLpgSQL_stmt_exit *stmt);
351 static void free_return(PLpgSQL_stmt_return *stmt);
352 static void free_return_next(PLpgSQL_stmt_return_next *stmt);
354 static void free_raise(PLpgSQL_stmt_raise *stmt);
355 static void free_assert(PLpgSQL_stmt_assert *stmt);
356 static void free_execsql(PLpgSQL_stmt_execsql *stmt);
357 static void free_dynexecute(PLpgSQL_stmt_dynexecute *stmt);
358 static void free_dynfors(PLpgSQL_stmt_dynfors *stmt);
359 static void free_getdiag(PLpgSQL_stmt_getdiag *stmt);
360 static void free_open(PLpgSQL_stmt_open *stmt);
361 static void free_fetch(PLpgSQL_stmt_fetch *stmt);
362 static void free_close(PLpgSQL_stmt_close *stmt);
363 static void free_perform(PLpgSQL_stmt_perform *stmt);
364 static void free_expr(PLpgSQL_expr *expr);
365 
366 
367 static void
369 {
370  switch (stmt->cmd_type)
371  {
372  case PLPGSQL_STMT_BLOCK:
373  free_block((PLpgSQL_stmt_block *) stmt);
374  break;
375  case PLPGSQL_STMT_ASSIGN:
377  break;
378  case PLPGSQL_STMT_IF:
379  free_if((PLpgSQL_stmt_if *) stmt);
380  break;
381  case PLPGSQL_STMT_CASE:
382  free_case((PLpgSQL_stmt_case *) stmt);
383  break;
384  case PLPGSQL_STMT_LOOP:
385  free_loop((PLpgSQL_stmt_loop *) stmt);
386  break;
387  case PLPGSQL_STMT_WHILE:
388  free_while((PLpgSQL_stmt_while *) stmt);
389  break;
390  case PLPGSQL_STMT_FORI:
391  free_fori((PLpgSQL_stmt_fori *) stmt);
392  break;
393  case PLPGSQL_STMT_FORS:
394  free_fors((PLpgSQL_stmt_fors *) stmt);
395  break;
396  case PLPGSQL_STMT_FORC:
397  free_forc((PLpgSQL_stmt_forc *) stmt);
398  break;
401  break;
402  case PLPGSQL_STMT_EXIT:
403  free_exit((PLpgSQL_stmt_exit *) stmt);
404  break;
405  case PLPGSQL_STMT_RETURN:
407  break;
410  break;
413  break;
414  case PLPGSQL_STMT_RAISE:
415  free_raise((PLpgSQL_stmt_raise *) stmt);
416  break;
417  case PLPGSQL_STMT_ASSERT:
419  break;
422  break;
425  break;
428  break;
431  break;
432  case PLPGSQL_STMT_OPEN:
433  free_open((PLpgSQL_stmt_open *) stmt);
434  break;
435  case PLPGSQL_STMT_FETCH:
436  free_fetch((PLpgSQL_stmt_fetch *) stmt);
437  break;
438  case PLPGSQL_STMT_CLOSE:
439  free_close((PLpgSQL_stmt_close *) stmt);
440  break;
443  break;
444  default:
445  elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
446  break;
447  }
448 }
449 
450 static void
452 {
453  ListCell *s;
454 
455  foreach(s, stmts)
456  {
457  free_stmt((PLpgSQL_stmt *) lfirst(s));
458  }
459 }
460 
461 static void
463 {
464  free_stmts(block->body);
465  if (block->exceptions)
466  {
467  ListCell *e;
468 
469  foreach(e, block->exceptions->exc_list)
470  {
472 
473  free_stmts(exc->action);
474  }
475  }
476 }
477 
478 static void
480 {
481  free_expr(stmt->expr);
482 }
483 
484 static void
486 {
487  ListCell *l;
488 
489  free_expr(stmt->cond);
490  free_stmts(stmt->then_body);
491  foreach(l, stmt->elsif_list)
492  {
494 
495  free_expr(elif->cond);
496  free_stmts(elif->stmts);
497  }
498  free_stmts(stmt->else_body);
499 }
500 
501 static void
503 {
504  ListCell *l;
505 
506  free_expr(stmt->t_expr);
507  foreach(l, stmt->case_when_list)
508  {
510 
511  free_expr(cwt->expr);
512  free_stmts(cwt->stmts);
513  }
514  free_stmts(stmt->else_stmts);
515 }
516 
517 static void
519 {
520  free_stmts(stmt->body);
521 }
522 
523 static void
525 {
526  free_expr(stmt->cond);
527  free_stmts(stmt->body);
528 }
529 
530 static void
532 {
533  free_expr(stmt->lower);
534  free_expr(stmt->upper);
535  free_expr(stmt->step);
536  free_stmts(stmt->body);
537 }
538 
539 static void
541 {
542  free_stmts(stmt->body);
543  free_expr(stmt->query);
544 }
545 
546 static void
548 {
549  free_stmts(stmt->body);
550  free_expr(stmt->argquery);
551 }
552 
553 static void
555 {
556  free_expr(stmt->expr);
557  free_stmts(stmt->body);
558 }
559 
560 static void
562 {
563  ListCell *lc;
564 
565  free_expr(stmt->argquery);
566  free_expr(stmt->query);
567  free_expr(stmt->dynquery);
568  foreach(lc, stmt->params)
569  {
570  free_expr((PLpgSQL_expr *) lfirst(lc));
571  }
572 }
573 
574 static void
576 {
577  free_expr(stmt->expr);
578 }
579 
580 static void
582 {
583 }
584 
585 static void
587 {
588  free_expr(stmt->expr);
589 }
590 
591 static void
593 {
594  free_expr(stmt->cond);
595 }
596 
597 static void
599 {
600  free_expr(stmt->expr);
601 }
602 
603 static void
605 {
606  free_expr(stmt->expr);
607 }
608 
609 static void
611 {
612  ListCell *lc;
613 
614  free_expr(stmt->query);
615  free_expr(stmt->dynquery);
616  foreach(lc, stmt->params)
617  {
618  free_expr((PLpgSQL_expr *) lfirst(lc));
619  }
620 }
621 
622 static void
624 {
625  ListCell *lc;
626 
627  foreach(lc, stmt->params)
628  {
629  free_expr((PLpgSQL_expr *) lfirst(lc));
630  }
631  foreach(lc, stmt->options)
632  {
634 
635  free_expr(opt->expr);
636  }
637 }
638 
639 static void
641 {
642  free_expr(stmt->cond);
643  free_expr(stmt->message);
644 }
645 
646 static void
648 {
649  free_expr(stmt->sqlstmt);
650 }
651 
652 static void
654 {
655  ListCell *lc;
656 
657  free_expr(stmt->query);
658  foreach(lc, stmt->params)
659  {
660  free_expr((PLpgSQL_expr *) lfirst(lc));
661  }
662 }
663 
664 static void
666 {
667  ListCell *lc;
668 
669  free_stmts(stmt->body);
670  free_expr(stmt->query);
671  foreach(lc, stmt->params)
672  {
673  free_expr((PLpgSQL_expr *) lfirst(lc));
674  }
675 }
676 
677 static void
679 {
680 }
681 
682 static void
684 {
685  if (expr && expr->plan)
686  {
687  SPI_freeplan(expr->plan);
688  expr->plan = NULL;
689  }
690 }
691 
692 void
694 {
695  int i;
696 
697  /* Better not call this on an in-use function */
698  Assert(func->use_count == 0);
699 
700  /* Release plans associated with variable declarations */
701  for (i = 0; i < func->ndatums; i++)
702  {
703  PLpgSQL_datum *d = func->datums[i];
704 
705  switch (d->dtype)
706  {
707  case PLPGSQL_DTYPE_VAR:
708  {
709  PLpgSQL_var *var = (PLpgSQL_var *) d;
710 
711  free_expr(var->default_val);
713  }
714  break;
715  case PLPGSQL_DTYPE_ROW:
716  break;
717  case PLPGSQL_DTYPE_REC:
718  break;
720  break;
722  free_expr(((PLpgSQL_arrayelem *) d)->subscript);
723  break;
724  default:
725  elog(ERROR, "unrecognized data type: %d", d->dtype);
726  }
727  }
728  func->ndatums = 0;
729 
730  /* Release plans in statement tree */
731  if (func->action)
732  free_block(func->action);
733  func->action = NULL;
734 
735  /*
736  * And finally, release all memory except the PLpgSQL_function struct
737  * itself (which has to be kept around because there may be multiple
738  * fn_extra pointers to it).
739  */
740  if (func->fn_cxt)
742  func->fn_cxt = NULL;
743 }
744 
745 
746 /**********************************************************************
747  * Debug functions for analyzing the compiled code
748  **********************************************************************/
749 static int dump_indent;
750 
751 static void dump_ind(void);
752 static void dump_stmt(PLpgSQL_stmt *stmt);
753 static void dump_block(PLpgSQL_stmt_block *block);
754 static void dump_assign(PLpgSQL_stmt_assign *stmt);
755 static void dump_if(PLpgSQL_stmt_if *stmt);
756 static void dump_case(PLpgSQL_stmt_case *stmt);
757 static void dump_loop(PLpgSQL_stmt_loop *stmt);
758 static void dump_while(PLpgSQL_stmt_while *stmt);
759 static void dump_fori(PLpgSQL_stmt_fori *stmt);
760 static void dump_fors(PLpgSQL_stmt_fors *stmt);
761 static void dump_forc(PLpgSQL_stmt_forc *stmt);
762 static void dump_foreach_a(PLpgSQL_stmt_foreach_a *stmt);
763 static void dump_exit(PLpgSQL_stmt_exit *stmt);
764 static void dump_return(PLpgSQL_stmt_return *stmt);
765 static void dump_return_next(PLpgSQL_stmt_return_next *stmt);
767 static void dump_raise(PLpgSQL_stmt_raise *stmt);
768 static void dump_assert(PLpgSQL_stmt_assert *stmt);
769 static void dump_execsql(PLpgSQL_stmt_execsql *stmt);
770 static void dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt);
771 static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt);
772 static void dump_getdiag(PLpgSQL_stmt_getdiag *stmt);
773 static void dump_open(PLpgSQL_stmt_open *stmt);
774 static void dump_fetch(PLpgSQL_stmt_fetch *stmt);
775 static void dump_cursor_direction(PLpgSQL_stmt_fetch *stmt);
776 static void dump_close(PLpgSQL_stmt_close *stmt);
777 static void dump_perform(PLpgSQL_stmt_perform *stmt);
778 static void dump_expr(PLpgSQL_expr *expr);
779 
780 
781 static void
782 dump_ind(void)
783 {
784  int i;
785 
786  for (i = 0; i < dump_indent; i++)
787  printf(" ");
788 }
789 
790 static void
792 {
793  printf("%3d:", stmt->lineno);
794  switch (stmt->cmd_type)
795  {
796  case PLPGSQL_STMT_BLOCK:
797  dump_block((PLpgSQL_stmt_block *) stmt);
798  break;
799  case PLPGSQL_STMT_ASSIGN:
801  break;
802  case PLPGSQL_STMT_IF:
803  dump_if((PLpgSQL_stmt_if *) stmt);
804  break;
805  case PLPGSQL_STMT_CASE:
806  dump_case((PLpgSQL_stmt_case *) stmt);
807  break;
808  case PLPGSQL_STMT_LOOP:
809  dump_loop((PLpgSQL_stmt_loop *) stmt);
810  break;
811  case PLPGSQL_STMT_WHILE:
812  dump_while((PLpgSQL_stmt_while *) stmt);
813  break;
814  case PLPGSQL_STMT_FORI:
815  dump_fori((PLpgSQL_stmt_fori *) stmt);
816  break;
817  case PLPGSQL_STMT_FORS:
818  dump_fors((PLpgSQL_stmt_fors *) stmt);
819  break;
820  case PLPGSQL_STMT_FORC:
821  dump_forc((PLpgSQL_stmt_forc *) stmt);
822  break;
825  break;
826  case PLPGSQL_STMT_EXIT:
827  dump_exit((PLpgSQL_stmt_exit *) stmt);
828  break;
829  case PLPGSQL_STMT_RETURN:
831  break;
834  break;
837  break;
838  case PLPGSQL_STMT_RAISE:
839  dump_raise((PLpgSQL_stmt_raise *) stmt);
840  break;
841  case PLPGSQL_STMT_ASSERT:
843  break;
846  break;
849  break;
852  break;
855  break;
856  case PLPGSQL_STMT_OPEN:
857  dump_open((PLpgSQL_stmt_open *) stmt);
858  break;
859  case PLPGSQL_STMT_FETCH:
860  dump_fetch((PLpgSQL_stmt_fetch *) stmt);
861  break;
862  case PLPGSQL_STMT_CLOSE:
863  dump_close((PLpgSQL_stmt_close *) stmt);
864  break;
867  break;
868  default:
869  elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
870  break;
871  }
872 }
873 
874 static void
876 {
877  ListCell *s;
878 
879  dump_indent += 2;
880  foreach(s, stmts)
881  dump_stmt((PLpgSQL_stmt *) lfirst(s));
882  dump_indent -= 2;
883 }
884 
885 static void
887 {
888  char *name;
889 
890  if (block->label == NULL)
891  name = "*unnamed*";
892  else
893  name = block->label;
894 
895  dump_ind();
896  printf("BLOCK <<%s>>\n", name);
897 
898  dump_stmts(block->body);
899 
900  if (block->exceptions)
901  {
902  ListCell *e;
903 
904  foreach(e, block->exceptions->exc_list)
905  {
907  PLpgSQL_condition *cond;
908 
909  dump_ind();
910  printf(" EXCEPTION WHEN ");
911  for (cond = exc->conditions; cond; cond = cond->next)
912  {
913  if (cond != exc->conditions)
914  printf(" OR ");
915  printf("%s", cond->condname);
916  }
917  printf(" THEN\n");
918  dump_stmts(exc->action);
919  }
920  }
921 
922  dump_ind();
923  printf(" END -- %s\n", name);
924 }
925 
926 static void
928 {
929  dump_ind();
930  printf("ASSIGN var %d := ", stmt->varno);
931  dump_expr(stmt->expr);
932  printf("\n");
933 }
934 
935 static void
937 {
938  ListCell *l;
939 
940  dump_ind();
941  printf("IF ");
942  dump_expr(stmt->cond);
943  printf(" THEN\n");
944  dump_stmts(stmt->then_body);
945  foreach(l, stmt->elsif_list)
946  {
948 
949  dump_ind();
950  printf(" ELSIF ");
951  dump_expr(elif->cond);
952  printf(" THEN\n");
953  dump_stmts(elif->stmts);
954  }
955  if (stmt->else_body != NIL)
956  {
957  dump_ind();
958  printf(" ELSE\n");
959  dump_stmts(stmt->else_body);
960  }
961  dump_ind();
962  printf(" ENDIF\n");
963 }
964 
965 static void
967 {
968  ListCell *l;
969 
970  dump_ind();
971  printf("CASE %d ", stmt->t_varno);
972  if (stmt->t_expr)
973  dump_expr(stmt->t_expr);
974  printf("\n");
975  dump_indent += 6;
976  foreach(l, stmt->case_when_list)
977  {
979 
980  dump_ind();
981  printf("WHEN ");
982  dump_expr(cwt->expr);
983  printf("\n");
984  dump_ind();
985  printf("THEN\n");
986  dump_indent += 2;
987  dump_stmts(cwt->stmts);
988  dump_indent -= 2;
989  }
990  if (stmt->have_else)
991  {
992  dump_ind();
993  printf("ELSE\n");
994  dump_indent += 2;
995  dump_stmts(stmt->else_stmts);
996  dump_indent -= 2;
997  }
998  dump_indent -= 6;
999  dump_ind();
1000  printf(" ENDCASE\n");
1001 }
1002 
1003 static void
1005 {
1006  dump_ind();
1007  printf("LOOP\n");
1008 
1009  dump_stmts(stmt->body);
1010 
1011  dump_ind();
1012  printf(" ENDLOOP\n");
1013 }
1014 
1015 static void
1017 {
1018  dump_ind();
1019  printf("WHILE ");
1020  dump_expr(stmt->cond);
1021  printf("\n");
1022 
1023  dump_stmts(stmt->body);
1024 
1025  dump_ind();
1026  printf(" ENDWHILE\n");
1027 }
1028 
1029 static void
1031 {
1032  dump_ind();
1033  printf("FORI %s %s\n", stmt->var->refname, (stmt->reverse) ? "REVERSE" : "NORMAL");
1034 
1035  dump_indent += 2;
1036  dump_ind();
1037  printf(" lower = ");
1038  dump_expr(stmt->lower);
1039  printf("\n");
1040  dump_ind();
1041  printf(" upper = ");
1042  dump_expr(stmt->upper);
1043  printf("\n");
1044  if (stmt->step)
1045  {
1046  dump_ind();
1047  printf(" step = ");
1048  dump_expr(stmt->step);
1049  printf("\n");
1050  }
1051  dump_indent -= 2;
1052 
1053  dump_stmts(stmt->body);
1054 
1055  dump_ind();
1056  printf(" ENDFORI\n");
1057 }
1058 
1059 static void
1061 {
1062  dump_ind();
1063  printf("FORS %s ", (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
1064  dump_expr(stmt->query);
1065  printf("\n");
1066 
1067  dump_stmts(stmt->body);
1068 
1069  dump_ind();
1070  printf(" ENDFORS\n");
1071 }
1072 
1073 static void
1075 {
1076  dump_ind();
1077  printf("FORC %s ", stmt->rec->refname);
1078  printf("curvar=%d\n", stmt->curvar);
1079 
1080  dump_indent += 2;
1081  if (stmt->argquery != NULL)
1082  {
1083  dump_ind();
1084  printf(" arguments = ");
1085  dump_expr(stmt->argquery);
1086  printf("\n");
1087  }
1088  dump_indent -= 2;
1089 
1090  dump_stmts(stmt->body);
1091 
1092  dump_ind();
1093  printf(" ENDFORC\n");
1094 }
1095 
1096 static void
1098 {
1099  dump_ind();
1100  printf("FOREACHA var %d ", stmt->varno);
1101  if (stmt->slice != 0)
1102  printf("SLICE %d ", stmt->slice);
1103  printf("IN ");
1104  dump_expr(stmt->expr);
1105  printf("\n");
1106 
1107  dump_stmts(stmt->body);
1108 
1109  dump_ind();
1110  printf(" ENDFOREACHA");
1111 }
1112 
1113 static void
1115 {
1116  dump_ind();
1117  printf("OPEN curvar=%d\n", stmt->curvar);
1118 
1119  dump_indent += 2;
1120  if (stmt->argquery != NULL)
1121  {
1122  dump_ind();
1123  printf(" arguments = '");
1124  dump_expr(stmt->argquery);
1125  printf("'\n");
1126  }
1127  if (stmt->query != NULL)
1128  {
1129  dump_ind();
1130  printf(" query = '");
1131  dump_expr(stmt->query);
1132  printf("'\n");
1133  }
1134  if (stmt->dynquery != NULL)
1135  {
1136  dump_ind();
1137  printf(" execute = '");
1138  dump_expr(stmt->dynquery);
1139  printf("'\n");
1140 
1141  if (stmt->params != NIL)
1142  {
1143  ListCell *lc;
1144  int i;
1145 
1146  dump_indent += 2;
1147  dump_ind();
1148  printf(" USING\n");
1149  dump_indent += 2;
1150  i = 1;
1151  foreach(lc, stmt->params)
1152  {
1153  dump_ind();
1154  printf(" parameter $%d: ", i++);
1155  dump_expr((PLpgSQL_expr *) lfirst(lc));
1156  printf("\n");
1157  }
1158  dump_indent -= 4;
1159  }
1160  }
1161  dump_indent -= 2;
1162 }
1163 
1164 static void
1166 {
1167  dump_ind();
1168 
1169  if (!stmt->is_move)
1170  {
1171  printf("FETCH curvar=%d\n", stmt->curvar);
1172  dump_cursor_direction(stmt);
1173 
1174  dump_indent += 2;
1175  if (stmt->rec != NULL)
1176  {
1177  dump_ind();
1178  printf(" target = %d %s\n", stmt->rec->dno, stmt->rec->refname);
1179  }
1180  if (stmt->row != NULL)
1181  {
1182  dump_ind();
1183  printf(" target = %d %s\n", stmt->row->dno, stmt->row->refname);
1184  }
1185  dump_indent -= 2;
1186  }
1187  else
1188  {
1189  printf("MOVE curvar=%d\n", stmt->curvar);
1190  dump_cursor_direction(stmt);
1191  }
1192 }
1193 
1194 static void
1196 {
1197  dump_indent += 2;
1198  dump_ind();
1199  switch (stmt->direction)
1200  {
1201  case FETCH_FORWARD:
1202  printf(" FORWARD ");
1203  break;
1204  case FETCH_BACKWARD:
1205  printf(" BACKWARD ");
1206  break;
1207  case FETCH_ABSOLUTE:
1208  printf(" ABSOLUTE ");
1209  break;
1210  case FETCH_RELATIVE:
1211  printf(" RELATIVE ");
1212  break;
1213  default:
1214  printf("??? unknown cursor direction %d", stmt->direction);
1215  }
1216 
1217  if (stmt->expr)
1218  {
1219  dump_expr(stmt->expr);
1220  printf("\n");
1221  }
1222  else
1223  printf("%ld\n", stmt->how_many);
1224 
1225  dump_indent -= 2;
1226 }
1227 
1228 static void
1230 {
1231  dump_ind();
1232  printf("CLOSE curvar=%d\n", stmt->curvar);
1233 }
1234 
1235 static void
1237 {
1238  dump_ind();
1239  printf("PERFORM expr = ");
1240  dump_expr(stmt->expr);
1241  printf("\n");
1242 }
1243 
1244 static void
1246 {
1247  dump_ind();
1248  printf("%s", stmt->is_exit ? "EXIT" : "CONTINUE");
1249  if (stmt->label != NULL)
1250  printf(" label='%s'", stmt->label);
1251  if (stmt->cond != NULL)
1252  {
1253  printf(" WHEN ");
1254  dump_expr(stmt->cond);
1255  }
1256  printf("\n");
1257 }
1258 
1259 static void
1261 {
1262  dump_ind();
1263  printf("RETURN ");
1264  if (stmt->retvarno >= 0)
1265  printf("variable %d", stmt->retvarno);
1266  else if (stmt->expr != NULL)
1267  dump_expr(stmt->expr);
1268  else
1269  printf("NULL");
1270  printf("\n");
1271 }
1272 
1273 static void
1275 {
1276  dump_ind();
1277  printf("RETURN NEXT ");
1278  if (stmt->retvarno >= 0)
1279  printf("variable %d", stmt->retvarno);
1280  else if (stmt->expr != NULL)
1281  dump_expr(stmt->expr);
1282  else
1283  printf("NULL");
1284  printf("\n");
1285 }
1286 
1287 static void
1289 {
1290  dump_ind();
1291  if (stmt->query)
1292  {
1293  printf("RETURN QUERY ");
1294  dump_expr(stmt->query);
1295  printf("\n");
1296  }
1297  else
1298  {
1299  printf("RETURN QUERY EXECUTE ");
1300  dump_expr(stmt->dynquery);
1301  printf("\n");
1302  if (stmt->params != NIL)
1303  {
1304  ListCell *lc;
1305  int i;
1306 
1307  dump_indent += 2;
1308  dump_ind();
1309  printf(" USING\n");
1310  dump_indent += 2;
1311  i = 1;
1312  foreach(lc, stmt->params)
1313  {
1314  dump_ind();
1315  printf(" parameter $%d: ", i++);
1316  dump_expr((PLpgSQL_expr *) lfirst(lc));
1317  printf("\n");
1318  }
1319  dump_indent -= 4;
1320  }
1321  }
1322 }
1323 
1324 static void
1326 {
1327  ListCell *lc;
1328  int i = 0;
1329 
1330  dump_ind();
1331  printf("RAISE level=%d", stmt->elog_level);
1332  if (stmt->condname)
1333  printf(" condname='%s'", stmt->condname);
1334  if (stmt->message)
1335  printf(" message='%s'", stmt->message);
1336  printf("\n");
1337  dump_indent += 2;
1338  foreach(lc, stmt->params)
1339  {
1340  dump_ind();
1341  printf(" parameter %d: ", i++);
1342  dump_expr((PLpgSQL_expr *) lfirst(lc));
1343  printf("\n");
1344  }
1345  if (stmt->options)
1346  {
1347  dump_ind();
1348  printf(" USING\n");
1349  dump_indent += 2;
1350  foreach(lc, stmt->options)
1351  {
1353 
1354  dump_ind();
1355  switch (opt->opt_type)
1356  {
1358  printf(" ERRCODE = ");
1359  break;
1361  printf(" MESSAGE = ");
1362  break;
1364  printf(" DETAIL = ");
1365  break;
1367  printf(" HINT = ");
1368  break;
1370  printf(" COLUMN = ");
1371  break;
1373  printf(" CONSTRAINT = ");
1374  break;
1376  printf(" DATATYPE = ");
1377  break;
1379  printf(" TABLE = ");
1380  break;
1382  printf(" SCHEMA = ");
1383  break;
1384  }
1385  dump_expr(opt->expr);
1386  printf("\n");
1387  }
1388  dump_indent -= 2;
1389  }
1390  dump_indent -= 2;
1391 }
1392 
1393 static void
1395 {
1396  dump_ind();
1397  printf("ASSERT ");
1398  dump_expr(stmt->cond);
1399  printf("\n");
1400 
1401  dump_indent += 2;
1402  if (stmt->message != NULL)
1403  {
1404  dump_ind();
1405  printf(" MESSAGE = ");
1406  dump_expr(stmt->message);
1407  printf("\n");
1408  }
1409  dump_indent -= 2;
1410 }
1411 
1412 static void
1414 {
1415  dump_ind();
1416  printf("EXECSQL ");
1417  dump_expr(stmt->sqlstmt);
1418  printf("\n");
1419 
1420  dump_indent += 2;
1421  if (stmt->rec != NULL)
1422  {
1423  dump_ind();
1424  printf(" INTO%s target = %d %s\n",
1425  stmt->strict ? " STRICT" : "",
1426  stmt->rec->dno, stmt->rec->refname);
1427  }
1428  if (stmt->row != NULL)
1429  {
1430  dump_ind();
1431  printf(" INTO%s target = %d %s\n",
1432  stmt->strict ? " STRICT" : "",
1433  stmt->row->dno, stmt->row->refname);
1434  }
1435  dump_indent -= 2;
1436 }
1437 
1438 static void
1440 {
1441  dump_ind();
1442  printf("EXECUTE ");
1443  dump_expr(stmt->query);
1444  printf("\n");
1445 
1446  dump_indent += 2;
1447  if (stmt->rec != NULL)
1448  {
1449  dump_ind();
1450  printf(" INTO%s target = %d %s\n",
1451  stmt->strict ? " STRICT" : "",
1452  stmt->rec->dno, stmt->rec->refname);
1453  }
1454  if (stmt->row != NULL)
1455  {
1456  dump_ind();
1457  printf(" INTO%s target = %d %s\n",
1458  stmt->strict ? " STRICT" : "",
1459  stmt->row->dno, stmt->row->refname);
1460  }
1461  if (stmt->params != NIL)
1462  {
1463  ListCell *lc;
1464  int i;
1465 
1466  dump_ind();
1467  printf(" USING\n");
1468  dump_indent += 2;
1469  i = 1;
1470  foreach(lc, stmt->params)
1471  {
1472  dump_ind();
1473  printf(" parameter %d: ", i++);
1474  dump_expr((PLpgSQL_expr *) lfirst(lc));
1475  printf("\n");
1476  }
1477  dump_indent -= 2;
1478  }
1479  dump_indent -= 2;
1480 }
1481 
1482 static void
1484 {
1485  dump_ind();
1486  printf("FORS %s EXECUTE ",
1487  (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
1488  dump_expr(stmt->query);
1489  printf("\n");
1490  if (stmt->params != NIL)
1491  {
1492  ListCell *lc;
1493  int i;
1494 
1495  dump_indent += 2;
1496  dump_ind();
1497  printf(" USING\n");
1498  dump_indent += 2;
1499  i = 1;
1500  foreach(lc, stmt->params)
1501  {
1502  dump_ind();
1503  printf(" parameter $%d: ", i++);
1504  dump_expr((PLpgSQL_expr *) lfirst(lc));
1505  printf("\n");
1506  }
1507  dump_indent -= 4;
1508  }
1509  dump_stmts(stmt->body);
1510  dump_ind();
1511  printf(" ENDFORS\n");
1512 }
1513 
1514 static void
1516 {
1517  ListCell *lc;
1518 
1519  dump_ind();
1520  printf("GET %s DIAGNOSTICS ", stmt->is_stacked ? "STACKED" : "CURRENT");
1521  foreach(lc, stmt->diag_items)
1522  {
1523  PLpgSQL_diag_item *diag_item = (PLpgSQL_diag_item *) lfirst(lc);
1524 
1525  if (lc != list_head(stmt->diag_items))
1526  printf(", ");
1527 
1528  printf("{var %d} = %s", diag_item->target,
1529  plpgsql_getdiag_kindname(diag_item->kind));
1530  }
1531  printf("\n");
1532 }
1533 
1534 static void
1536 {
1537  printf("'%s'", expr->query);
1538 }
1539 
1540 void
1542 {
1543  int i;
1544  PLpgSQL_datum *d;
1545 
1546  printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1547  func->fn_signature);
1548 
1549  printf("\nFunction's data area:\n");
1550  for (i = 0; i < func->ndatums; i++)
1551  {
1552  d = func->datums[i];
1553 
1554  printf(" entry %d: ", i);
1555  switch (d->dtype)
1556  {
1557  case PLPGSQL_DTYPE_VAR:
1558  {
1559  PLpgSQL_var *var = (PLpgSQL_var *) d;
1560 
1561  printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1562  var->refname, var->datatype->typname,
1563  var->datatype->typoid,
1564  var->datatype->atttypmod);
1565  if (var->isconst)
1566  printf(" CONSTANT\n");
1567  if (var->notnull)
1568  printf(" NOT NULL\n");
1569  if (var->default_val != NULL)
1570  {
1571  printf(" DEFAULT ");
1572  dump_expr(var->default_val);
1573  printf("\n");
1574  }
1575  if (var->cursor_explicit_expr != NULL)
1576  {
1577  if (var->cursor_explicit_argrow >= 0)
1578  printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1579 
1580  printf(" CURSOR IS ");
1582  printf("\n");
1583  }
1584  }
1585  break;
1586  case PLPGSQL_DTYPE_ROW:
1587  {
1588  PLpgSQL_row *row = (PLpgSQL_row *) d;
1589  int i;
1590 
1591  printf("ROW %-16s fields", row->refname);
1592  for (i = 0; i < row->nfields; i++)
1593  {
1594  if (row->fieldnames[i])
1595  printf(" %s=var %d", row->fieldnames[i],
1596  row->varnos[i]);
1597  }
1598  printf("\n");
1599  }
1600  break;
1601  case PLPGSQL_DTYPE_REC:
1602  printf("REC %s\n", ((PLpgSQL_rec *) d)->refname);
1603  break;
1605  printf("RECFIELD %-16s of REC %d\n",
1606  ((PLpgSQL_recfield *) d)->fieldname,
1607  ((PLpgSQL_recfield *) d)->recparentno);
1608  break;
1610  printf("ARRAYELEM of VAR %d subscript ",
1611  ((PLpgSQL_arrayelem *) d)->arrayparentno);
1612  dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
1613  printf("\n");
1614  break;
1615  default:
1616  printf("??? unknown data type %d\n", d->dtype);
1617  }
1618  }
1619  printf("\nFunction's statements:\n");
1620 
1621  dump_indent = 0;
1622  printf("%3d:", func->action->lineno);
1623  dump_block(func->action);
1624  printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1625  fflush(stdout);
1626 }
#define NIL
Definition: pg_list.h:69
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:693
PLpgSQL_expr * query
Definition: plpgsql.h:765
PLpgSQL_datum ** datums
Definition: plpgsql.h:868
PLpgSQL_expr * cond
Definition: plpgsql.h:464
PLpgSQL_expr * cond
Definition: plpgsql.h:523
List * then_body
Definition: plpgsql.h:465
PLpgSQL_expr * expr
Definition: plpgsql.h:615
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
char * refname
Definition: plpgsql.h:283
char * query
Definition: plpgsql.h:225
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
static void free_assert(PLpgSQL_stmt_assert *stmt)
Definition: pl_funcs.c:640
int notnull
Definition: plpgsql.h:265
FetchDirection direction
Definition: plpgsql.h:645
int isconst
Definition: plpgsql.h:264
int lineno
Definition: plpgsql.h:369
static void free_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
Definition: pl_funcs.c:653
static void dump_cursor_direction(PLpgSQL_stmt_fetch *stmt)
Definition: pl_funcs.c:1195
PLpgSQL_row * row
Definition: plpgsql.h:598
char * refname
Definition: plpgsql.h:260
PLpgSQL_expr * expr
Definition: plpgsql.h:681
List * elsif_list
Definition: plpgsql.h:466
static void free_raise(PLpgSQL_stmt_raise *stmt)
Definition: pl_funcs.c:623
PLpgSQL_rec * rec
Definition: plpgsql.h:597
PLpgSQL_stmt_block * action
Definition: plpgsql.h:872
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:267
List * stmts
Definition: plpgsql.h:477
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:378
PLpgSQL_type * datatype
Definition: plpgsql.h:263
static void dump_raise(PLpgSQL_stmt_raise *stmt)
Definition: pl_funcs.c:1325
PLpgSQL_row * row
Definition: plpgsql.h:567
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
PLpgSQL_row * row
Definition: plpgsql.h:769
static void dump_perform(PLpgSQL_stmt_perform *stmt)
Definition: pl_funcs.c:1236
static void dump_forc(PLpgSQL_stmt_forc *stmt)
Definition: pl_funcs.c:1074
PLpgSQL_expr * sqlstmt
Definition: plpgsql.h:749
struct PLpgSQL_condition * next
Definition: plpgsql.h:379
PLpgSQL_expr * dynquery
Definition: plpgsql.h:631
PLpgSQL_rec * rec
Definition: plpgsql.h:642
void plpgsql_dumptree(PLpgSQL_function *func)
Definition: pl_funcs.c:1541
PLpgSQL_expr * expr
Definition: plpgsql.h:434
PLpgSQL_expr * cond
Definition: plpgsql.h:476
List * else_stmts
Definition: plpgsql.h:491
static void free_open(PLpgSQL_stmt_open *stmt)
Definition: pl_funcs.c:561
PLpgSQL_datum_type dtype
Definition: plpgsql.h:200
char * refname
Definition: plpgsql.h:306
static void dump_fors(PLpgSQL_stmt_fors *stmt)
Definition: pl_funcs.c:1060
PLpgSQL_expr * lower
Definition: plpgsql.h:536
static void free_return(PLpgSQL_stmt_return *stmt)
Definition: pl_funcs.c:598
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:35
PLpgSQL_getdiag_kind kind
Definition: plpgsql.h:442
SPIPlanPtr plan
Definition: plpgsql.h:226
static void free_loop(PLpgSQL_stmt_loop *stmt)
Definition: pl_funcs.c:518
PLpgSQL_raise_option_type opt_type
Definition: plpgsql.h:727
static void dump_fetch(PLpgSQL_stmt_fetch *stmt)
Definition: pl_funcs.c:1165
static void free_dynfors(PLpgSQL_stmt_dynfors *stmt)
Definition: pl_funcs.c:665
PLpgSQL_expr * query
Definition: plpgsql.h:703
static void free_assign(PLpgSQL_stmt_assign *stmt)
Definition: pl_funcs.c:479
int cursor_explicit_argrow
Definition: plpgsql.h:268
PLpgSQL_rec * rec
Definition: plpgsql.h:754
void plpgsql_ns_pop(void)
Definition: pl_funcs.c:67
static void free_getdiag(PLpgSQL_stmt_getdiag *stmt)
Definition: pl_funcs.c:678
PLpgSQL_expr * expr
Definition: plpgsql.h:692
#define ERROR
Definition: elog.h:43
PLpgSQL_var * var
Definition: plpgsql.h:535
char ** fieldnames
Definition: plpgsql.h:295
PLpgSQL_expr * message
Definition: plpgsql.h:739
PLpgSQL_label_type
Definition: plpgsql.h:51
PLpgSQL_expr * default_val
Definition: plpgsql.h:266
unsigned long use_count
Definition: plpgsql.h:876
static void free_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:683
static void free_fetch(PLpgSQL_stmt_fetch *stmt)
Definition: pl_funcs.c:575
static void dump_case(PLpgSQL_stmt_case *stmt)
Definition: pl_funcs.c:966
static void free_close(PLpgSQL_stmt_close *stmt)
Definition: pl_funcs.c:581
static void free_case(PLpgSQL_stmt_case *stmt)
Definition: pl_funcs.c:502
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
static void dump_getdiag(PLpgSQL_stmt_getdiag *stmt)
Definition: pl_funcs.c:1515
MemoryContext fn_cxt
Definition: plpgsql.h:828
void plpgsql_ns_init(void)
Definition: pl_funcs.c:43
PLpgSQL_expr * expr
Definition: plpgsql.h:500
List * case_when_list
Definition: plpgsql.h:489
static void dump_if(PLpgSQL_stmt_if *stmt)
Definition: pl_funcs.c:936
PLpgSQL_expr * query
Definition: plpgsql.h:601
int * varnos
Definition: plpgsql.h:296
static void free_fori(PLpgSQL_stmt_fori *stmt)
Definition: pl_funcs.c:531
static void dump_return_query(PLpgSQL_stmt_return_query *stmt)
Definition: pl_funcs.c:1288
static void free_perform(PLpgSQL_stmt_perform *stmt)
Definition: pl_funcs.c:586
static void dump_return(PLpgSQL_stmt_return *stmt)
Definition: pl_funcs.c:1260
static void free_return_next(PLpgSQL_stmt_return_next *stmt)
Definition: pl_funcs.c:604
static void dump_return_next(PLpgSQL_stmt_return_next *stmt)
Definition: pl_funcs.c:1274
static void dump_loop(PLpgSQL_stmt_loop *stmt)
Definition: pl_funcs.c:1004
static void free_fors(PLpgSQL_stmt_fors *stmt)
Definition: pl_funcs.c:540
PLpgSQL_getdiag_kind
Definition: plpgsql.h:127
static void dump_close(PLpgSQL_stmt_close *stmt)
Definition: pl_funcs.c:1229
PLpgSQL_rec * rec
Definition: plpgsql.h:566
static void free_exit(PLpgSQL_stmt_exit *stmt)
Definition: pl_funcs.c:592
static char * label
Definition: pg_basebackup.c:83
PLpgSQL_expr * cond
Definition: plpgsql.h:671
PLpgSQL_expr * query
Definition: plpgsql.h:630
static void dump_ind(void)
Definition: pl_funcs.c:782
PLpgSQL_row * row
Definition: plpgsql.h:643
PLpgSQL_condition * conditions
Definition: plpgsql.h:398
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:359
static void dump_while(PLpgSQL_stmt_while *stmt)
Definition: pl_funcs.c:1016
static void free_stmts(List *stmts)
Definition: pl_funcs.c:451
static void free_if(PLpgSQL_stmt_if *stmt)
Definition: pl_funcs.c:485
PLpgSQL_nsitem * plpgsql_ns_find_nearest_loop(PLpgSQL_nsitem *ns_cur)
Definition: pl_funcs.c:214
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
int nfields
Definition: plpgsql.h:294
PLpgSQL_exception_block * exceptions
Definition: plpgsql.h:413
static void free_return_query(PLpgSQL_stmt_return_query *stmt)
Definition: pl_funcs.c:610
PLpgSQL_rec * rec
Definition: plpgsql.h:581
const char * plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind)
Definition: pl_funcs.c:294
static void dump_execsql(PLpgSQL_stmt_execsql *stmt)
Definition: pl_funcs.c:1413
static void free_stmt(PLpgSQL_stmt *stmt)
Definition: pl_funcs.c:368
static int dump_indent
Definition: pl_funcs.c:749
char * fn_signature
Definition: plpgsql.h:821
static void dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
Definition: pl_funcs.c:1439
List * else_body
Definition: plpgsql.h:467
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:180
PLpgSQL_expr * step
Definition: plpgsql.h:538
PLpgSQL_expr * t_expr
Definition: plpgsql.h:487
PLpgSQL_expr * dynquery
Definition: plpgsql.h:704
static void free_execsql(PLpgSQL_stmt_execsql *stmt)
Definition: pl_funcs.c:647
PLpgSQL_expr * expr
Definition: plpgsql.h:647
static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt)
Definition: pl_funcs.c:1483
const char * name
Definition: encode.c:521
PLpgSQL_expr * expr
Definition: plpgsql.h:424
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:886
PLpgSQL_expr * expr
Definition: plpgsql.h:728
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:608
e
Definition: preproc-init.c:82
static void dump_foreach_a(PLpgSQL_stmt_foreach_a *stmt)
Definition: pl_funcs.c:1097
void * palloc(Size size)
Definition: mcxt.c:891
PLpgSQL_rec * rec
Definition: plpgsql.h:768
int32 atttypmod
Definition: plpgsql.h:189
static void free_forc(PLpgSQL_stmt_forc *stmt)
Definition: pl_funcs.c:547
static void dump_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:1535
PLpgSQL_expr * argquery
Definition: plpgsql.h:629
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
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:1394
static void dump_open(PLpgSQL_stmt_open *stmt)
Definition: pl_funcs.c:1114
PLpgSQL_expr * argquery
Definition: plpgsql.h:586
PLpgSQL_expr * upper
Definition: plpgsql.h:537
PLpgSQL_stmt_type cmd_type
Definition: plpgsql.h:368
static void dump_fori(PLpgSQL_stmt_fori *stmt)
Definition: pl_funcs.c:1030
static void free_while(PLpgSQL_stmt_while *stmt)
Definition: pl_funcs.c:524
#define elog
Definition: elog.h:219
PLpgSQL_expr * query
Definition: plpgsql.h:570
PLpgSQL_expr * cond
Definition: plpgsql.h:738
static void dump_stmts(List *stmts)
Definition: pl_funcs.c:875
PLpgSQL_row * row
Definition: plpgsql.h:755
static void dump_stmt(PLpgSQL_stmt *stmt)
Definition: pl_funcs.c:791
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:360
static void free_foreach_a(PLpgSQL_stmt_foreach_a *stmt)
Definition: pl_funcs.c:554
Definition: pg_list.h:45
#define _(x)
Definition: elog.c:84
static void dump_assign(PLpgSQL_stmt_assign *stmt)
Definition: pl_funcs.c:927
#define offsetof(type, field)
Definition: c.h:551
static void free_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:462
PLpgSQL_nsitem_type
Definition: plpgsql.h:40
static void dump_exit(PLpgSQL_stmt_exit *stmt)
Definition: pl_funcs.c:1245
Oid typoid
Definition: plpgsql.h:181