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 "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  */
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->rec != NULL) ? stmt->rec->refname : stmt->row->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->rec->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->rec != NULL)
1178  {
1179  dump_ind();
1180  printf(" target = %d %s\n", stmt->rec->dno, stmt->rec->refname);
1181  }
1182  if (stmt->row != NULL)
1183  {
1184  dump_ind();
1185  printf(" target = %d %s\n", stmt->row->dno, stmt->row->refname);
1186  }
1187  dump_indent -= 2;
1188  }
1189  else
1190  {
1191  printf("MOVE curvar=%d\n", stmt->curvar);
1192  dump_cursor_direction(stmt);
1193  }
1194 }
1195 
1196 static void
1198 {
1199  dump_indent += 2;
1200  dump_ind();
1201  switch (stmt->direction)
1202  {
1203  case FETCH_FORWARD:
1204  printf(" FORWARD ");
1205  break;
1206  case FETCH_BACKWARD:
1207  printf(" BACKWARD ");
1208  break;
1209  case FETCH_ABSOLUTE:
1210  printf(" ABSOLUTE ");
1211  break;
1212  case FETCH_RELATIVE:
1213  printf(" RELATIVE ");
1214  break;
1215  default:
1216  printf("??? unknown cursor direction %d", stmt->direction);
1217  }
1218 
1219  if (stmt->expr)
1220  {
1221  dump_expr(stmt->expr);
1222  printf("\n");
1223  }
1224  else
1225  printf("%ld\n", stmt->how_many);
1226 
1227  dump_indent -= 2;
1228 }
1229 
1230 static void
1232 {
1233  dump_ind();
1234  printf("CLOSE curvar=%d\n", stmt->curvar);
1235 }
1236 
1237 static void
1239 {
1240  dump_ind();
1241  printf("PERFORM expr = ");
1242  dump_expr(stmt->expr);
1243  printf("\n");
1244 }
1245 
1246 static void
1248 {
1249  dump_ind();
1250  printf("%s", stmt->is_exit ? "EXIT" : "CONTINUE");
1251  if (stmt->label != NULL)
1252  printf(" label='%s'", stmt->label);
1253  if (stmt->cond != NULL)
1254  {
1255  printf(" WHEN ");
1256  dump_expr(stmt->cond);
1257  }
1258  printf("\n");
1259 }
1260 
1261 static void
1263 {
1264  dump_ind();
1265  printf("RETURN ");
1266  if (stmt->retvarno >= 0)
1267  printf("variable %d", stmt->retvarno);
1268  else if (stmt->expr != NULL)
1269  dump_expr(stmt->expr);
1270  else
1271  printf("NULL");
1272  printf("\n");
1273 }
1274 
1275 static void
1277 {
1278  dump_ind();
1279  printf("RETURN NEXT ");
1280  if (stmt->retvarno >= 0)
1281  printf("variable %d", stmt->retvarno);
1282  else if (stmt->expr != NULL)
1283  dump_expr(stmt->expr);
1284  else
1285  printf("NULL");
1286  printf("\n");
1287 }
1288 
1289 static void
1291 {
1292  dump_ind();
1293  if (stmt->query)
1294  {
1295  printf("RETURN QUERY ");
1296  dump_expr(stmt->query);
1297  printf("\n");
1298  }
1299  else
1300  {
1301  printf("RETURN QUERY EXECUTE ");
1302  dump_expr(stmt->dynquery);
1303  printf("\n");
1304  if (stmt->params != NIL)
1305  {
1306  ListCell *lc;
1307  int i;
1308 
1309  dump_indent += 2;
1310  dump_ind();
1311  printf(" USING\n");
1312  dump_indent += 2;
1313  i = 1;
1314  foreach(lc, stmt->params)
1315  {
1316  dump_ind();
1317  printf(" parameter $%d: ", i++);
1318  dump_expr((PLpgSQL_expr *) lfirst(lc));
1319  printf("\n");
1320  }
1321  dump_indent -= 4;
1322  }
1323  }
1324 }
1325 
1326 static void
1328 {
1329  ListCell *lc;
1330  int i = 0;
1331 
1332  dump_ind();
1333  printf("RAISE level=%d", stmt->elog_level);
1334  if (stmt->condname)
1335  printf(" condname='%s'", stmt->condname);
1336  if (stmt->message)
1337  printf(" message='%s'", stmt->message);
1338  printf("\n");
1339  dump_indent += 2;
1340  foreach(lc, stmt->params)
1341  {
1342  dump_ind();
1343  printf(" parameter %d: ", i++);
1344  dump_expr((PLpgSQL_expr *) lfirst(lc));
1345  printf("\n");
1346  }
1347  if (stmt->options)
1348  {
1349  dump_ind();
1350  printf(" USING\n");
1351  dump_indent += 2;
1352  foreach(lc, stmt->options)
1353  {
1355 
1356  dump_ind();
1357  switch (opt->opt_type)
1358  {
1360  printf(" ERRCODE = ");
1361  break;
1363  printf(" MESSAGE = ");
1364  break;
1366  printf(" DETAIL = ");
1367  break;
1369  printf(" HINT = ");
1370  break;
1372  printf(" COLUMN = ");
1373  break;
1375  printf(" CONSTRAINT = ");
1376  break;
1378  printf(" DATATYPE = ");
1379  break;
1381  printf(" TABLE = ");
1382  break;
1384  printf(" SCHEMA = ");
1385  break;
1386  }
1387  dump_expr(opt->expr);
1388  printf("\n");
1389  }
1390  dump_indent -= 2;
1391  }
1392  dump_indent -= 2;
1393 }
1394 
1395 static void
1397 {
1398  dump_ind();
1399  printf("ASSERT ");
1400  dump_expr(stmt->cond);
1401  printf("\n");
1402 
1403  dump_indent += 2;
1404  if (stmt->message != NULL)
1405  {
1406  dump_ind();
1407  printf(" MESSAGE = ");
1408  dump_expr(stmt->message);
1409  printf("\n");
1410  }
1411  dump_indent -= 2;
1412 }
1413 
1414 static void
1416 {
1417  dump_ind();
1418  printf("EXECSQL ");
1419  dump_expr(stmt->sqlstmt);
1420  printf("\n");
1421 
1422  dump_indent += 2;
1423  if (stmt->rec != NULL)
1424  {
1425  dump_ind();
1426  printf(" INTO%s target = %d %s\n",
1427  stmt->strict ? " STRICT" : "",
1428  stmt->rec->dno, stmt->rec->refname);
1429  }
1430  if (stmt->row != NULL)
1431  {
1432  dump_ind();
1433  printf(" INTO%s target = %d %s\n",
1434  stmt->strict ? " STRICT" : "",
1435  stmt->row->dno, stmt->row->refname);
1436  }
1437  dump_indent -= 2;
1438 }
1439 
1440 static void
1442 {
1443  dump_ind();
1444  printf("EXECUTE ");
1445  dump_expr(stmt->query);
1446  printf("\n");
1447 
1448  dump_indent += 2;
1449  if (stmt->rec != NULL)
1450  {
1451  dump_ind();
1452  printf(" INTO%s target = %d %s\n",
1453  stmt->strict ? " STRICT" : "",
1454  stmt->rec->dno, stmt->rec->refname);
1455  }
1456  if (stmt->row != NULL)
1457  {
1458  dump_ind();
1459  printf(" INTO%s target = %d %s\n",
1460  stmt->strict ? " STRICT" : "",
1461  stmt->row->dno, stmt->row->refname);
1462  }
1463  if (stmt->params != NIL)
1464  {
1465  ListCell *lc;
1466  int i;
1467 
1468  dump_ind();
1469  printf(" USING\n");
1470  dump_indent += 2;
1471  i = 1;
1472  foreach(lc, stmt->params)
1473  {
1474  dump_ind();
1475  printf(" parameter %d: ", i++);
1476  dump_expr((PLpgSQL_expr *) lfirst(lc));
1477  printf("\n");
1478  }
1479  dump_indent -= 2;
1480  }
1481  dump_indent -= 2;
1482 }
1483 
1484 static void
1486 {
1487  dump_ind();
1488  printf("FORS %s EXECUTE ",
1489  (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
1490  dump_expr(stmt->query);
1491  printf("\n");
1492  if (stmt->params != NIL)
1493  {
1494  ListCell *lc;
1495  int i;
1496 
1497  dump_indent += 2;
1498  dump_ind();
1499  printf(" USING\n");
1500  dump_indent += 2;
1501  i = 1;
1502  foreach(lc, stmt->params)
1503  {
1504  dump_ind();
1505  printf(" parameter $%d: ", i++);
1506  dump_expr((PLpgSQL_expr *) lfirst(lc));
1507  printf("\n");
1508  }
1509  dump_indent -= 4;
1510  }
1511  dump_stmts(stmt->body);
1512  dump_ind();
1513  printf(" ENDFORS\n");
1514 }
1515 
1516 static void
1518 {
1519  ListCell *lc;
1520 
1521  dump_ind();
1522  printf("GET %s DIAGNOSTICS ", stmt->is_stacked ? "STACKED" : "CURRENT");
1523  foreach(lc, stmt->diag_items)
1524  {
1525  PLpgSQL_diag_item *diag_item = (PLpgSQL_diag_item *) lfirst(lc);
1526 
1527  if (lc != list_head(stmt->diag_items))
1528  printf(", ");
1529 
1530  printf("{var %d} = %s", diag_item->target,
1531  plpgsql_getdiag_kindname(diag_item->kind));
1532  }
1533  printf("\n");
1534 }
1535 
1536 static void
1538 {
1539  printf("'%s'", expr->query);
1540 }
1541 
1542 void
1544 {
1545  int i;
1546  PLpgSQL_datum *d;
1547 
1548  printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1549  func->fn_signature);
1550 
1551  printf("\nFunction's data area:\n");
1552  for (i = 0; i < func->ndatums; i++)
1553  {
1554  d = func->datums[i];
1555 
1556  printf(" entry %d: ", i);
1557  switch (d->dtype)
1558  {
1559  case PLPGSQL_DTYPE_VAR:
1560  {
1561  PLpgSQL_var *var = (PLpgSQL_var *) d;
1562 
1563  printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1564  var->refname, var->datatype->typname,
1565  var->datatype->typoid,
1566  var->datatype->atttypmod);
1567  if (var->isconst)
1568  printf(" CONSTANT\n");
1569  if (var->notnull)
1570  printf(" NOT NULL\n");
1571  if (var->default_val != NULL)
1572  {
1573  printf(" DEFAULT ");
1574  dump_expr(var->default_val);
1575  printf("\n");
1576  }
1577  if (var->cursor_explicit_expr != NULL)
1578  {
1579  if (var->cursor_explicit_argrow >= 0)
1580  printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1581 
1582  printf(" CURSOR IS ");
1584  printf("\n");
1585  }
1586  }
1587  break;
1588  case PLPGSQL_DTYPE_ROW:
1589  {
1590  PLpgSQL_row *row = (PLpgSQL_row *) d;
1591  int i;
1592 
1593  printf("ROW %-16s fields", row->refname);
1594  for (i = 0; i < row->nfields; i++)
1595  {
1596  if (row->fieldnames[i])
1597  printf(" %s=var %d", row->fieldnames[i],
1598  row->varnos[i]);
1599  }
1600  printf("\n");
1601  }
1602  break;
1603  case PLPGSQL_DTYPE_REC:
1604  printf("REC %s\n", ((PLpgSQL_rec *) d)->refname);
1605  break;
1607  printf("RECFIELD %-16s of REC %d\n",
1608  ((PLpgSQL_recfield *) d)->fieldname,
1609  ((PLpgSQL_recfield *) d)->recparentno);
1610  break;
1612  printf("ARRAYELEM of VAR %d subscript ",
1613  ((PLpgSQL_arrayelem *) d)->arrayparentno);
1614  dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
1615  printf("\n");
1616  break;
1617  default:
1618  printf("??? unknown data type %d\n", d->dtype);
1619  }
1620  }
1621  printf("\nFunction's statements:\n");
1622 
1623  dump_indent = 0;
1624  printf("%3d:", func->action->lineno);
1625  dump_block(func->action);
1626  printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1627  fflush(stdout);
1628 }
#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:763
PLpgSQL_datum ** datums
Definition: plpgsql.h:866
PLpgSQL_expr * cond
Definition: plpgsql.h:462
PLpgSQL_expr * cond
Definition: plpgsql.h:521
List * then_body
Definition: plpgsql.h:463
PLpgSQL_expr * expr
Definition: plpgsql.h:613
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
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:643
int isconst
Definition: plpgsql.h:262
int lineno
Definition: plpgsql.h:367
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:1197
PLpgSQL_row * row
Definition: plpgsql.h:596
char * refname
Definition: plpgsql.h:258
PLpgSQL_expr * expr
Definition: plpgsql.h:679
List * elsif_list
Definition: plpgsql.h:464
static void free_raise(PLpgSQL_stmt_raise *stmt)
Definition: pl_funcs.c:625
PLpgSQL_rec * rec
Definition: plpgsql.h:595
PLpgSQL_stmt_block * action
Definition: plpgsql.h:870
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:265
List * stmts
Definition: plpgsql.h:475
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:376
PLpgSQL_type * datatype
Definition: plpgsql.h:261
static void dump_raise(PLpgSQL_stmt_raise *stmt)
Definition: pl_funcs.c:1327
PLpgSQL_row * row
Definition: plpgsql.h:565
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
PLpgSQL_row * row
Definition: plpgsql.h:767
static void dump_perform(PLpgSQL_stmt_perform *stmt)
Definition: pl_funcs.c:1238
static void dump_forc(PLpgSQL_stmt_forc *stmt)
Definition: pl_funcs.c:1076
PLpgSQL_expr * sqlstmt
Definition: plpgsql.h:747
struct PLpgSQL_condition * next
Definition: plpgsql.h:377
PLpgSQL_expr * dynquery
Definition: plpgsql.h:629
PLpgSQL_rec * rec
Definition: plpgsql.h:640
void plpgsql_dumptree(PLpgSQL_function *func)
Definition: pl_funcs.c:1543
PLpgSQL_expr * expr
Definition: plpgsql.h:432
PLpgSQL_expr * cond
Definition: plpgsql.h:474
List * else_stmts
Definition: plpgsql.h:489
static void free_open(PLpgSQL_stmt_open *stmt)
Definition: pl_funcs.c:563
PLpgSQL_datum_type dtype
Definition: plpgsql.h:198
char * refname
Definition: plpgsql.h:304
static void dump_fors(PLpgSQL_stmt_fors *stmt)
Definition: pl_funcs.c:1062
PLpgSQL_expr * lower
Definition: plpgsql.h:534
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:440
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:725
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:701
static void free_assign(PLpgSQL_stmt_assign *stmt)
Definition: pl_funcs.c:481
int cursor_explicit_argrow
Definition: plpgsql.h:266
PLpgSQL_rec * rec
Definition: plpgsql.h:752
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:690
#define ERROR
Definition: elog.h:43
PLpgSQL_var * var
Definition: plpgsql.h:533
char ** fieldnames
Definition: plpgsql.h:293
PLpgSQL_expr * message
Definition: plpgsql.h:737
PLpgSQL_label_type
Definition: plpgsql.h:49
PLpgSQL_expr * default_val
Definition: plpgsql.h:264
unsigned long use_count
Definition: plpgsql.h:874
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
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
static void dump_getdiag(PLpgSQL_stmt_getdiag *stmt)
Definition: pl_funcs.c:1517
MemoryContext fn_cxt
Definition: plpgsql.h:826
void plpgsql_ns_init(void)
Definition: pl_funcs.c:45
PLpgSQL_expr * expr
Definition: plpgsql.h:498
List * case_when_list
Definition: plpgsql.h:487
static void dump_if(PLpgSQL_stmt_if *stmt)
Definition: pl_funcs.c:938
PLpgSQL_expr * query
Definition: plpgsql.h:599
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:1290
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:1262
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:1276
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:1231
PLpgSQL_rec * rec
Definition: plpgsql.h:564
static void free_exit(PLpgSQL_stmt_exit *stmt)
Definition: pl_funcs.c:594
static char * label
Definition: pg_basebackup.c:81
PLpgSQL_expr * cond
Definition: plpgsql.h:669
PLpgSQL_expr * query
Definition: plpgsql.h:628
static void dump_ind(void)
Definition: pl_funcs.c:784
PLpgSQL_row * row
Definition: plpgsql.h:641
PLpgSQL_condition * conditions
Definition: plpgsql.h:396
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:357
static void dump_while(PLpgSQL_stmt_while *stmt)
Definition: pl_funcs.c:1018
static void free_stmts(List *stmts)
Definition: pl_funcs.c:453
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 NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
int nfields
Definition: plpgsql.h:292
PLpgSQL_exception_block * exceptions
Definition: plpgsql.h:411
static void free_return_query(PLpgSQL_stmt_return_query *stmt)
Definition: pl_funcs.c:612
PLpgSQL_rec * rec
Definition: plpgsql.h:579
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:1415
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:819
static void dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
Definition: pl_funcs.c:1441
List * else_body
Definition: plpgsql.h:465
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:536
PLpgSQL_expr * t_expr
Definition: plpgsql.h:485
PLpgSQL_expr * dynquery
Definition: plpgsql.h:702
static void free_execsql(PLpgSQL_stmt_execsql *stmt)
Definition: pl_funcs.c:649
PLpgSQL_expr * expr
Definition: plpgsql.h:645
static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt)
Definition: pl_funcs.c:1485
const char * name
Definition: encode.c:521
PLpgSQL_expr * expr
Definition: plpgsql.h:422
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:888
PLpgSQL_expr * expr
Definition: plpgsql.h:726
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:609
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:849
PLpgSQL_rec * rec
Definition: plpgsql.h:766
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:1537
PLpgSQL_expr * argquery
Definition: plpgsql.h:627
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:1396
static void dump_open(PLpgSQL_stmt_open *stmt)
Definition: pl_funcs.c:1116
PLpgSQL_expr * argquery
Definition: plpgsql.h:584
PLpgSQL_expr * upper
Definition: plpgsql.h:535
PLpgSQL_stmt_type cmd_type
Definition: plpgsql.h:366
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:568
PLpgSQL_expr * cond
Definition: plpgsql.h:736
static void dump_stmts(List *stmts)
Definition: pl_funcs.c:877
PLpgSQL_row * row
Definition: plpgsql.h:753
static void dump_stmt(PLpgSQL_stmt *stmt)
Definition: pl_funcs.c:793
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:358
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:555
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:1247
Oid typoid
Definition: plpgsql.h:179