1 /*--------------------------------------------------------------------
2 * Symbols referenced in this file:
3 * - plpgsql_ns_init
4 * - ns_top
5 * - plpgsql_ns_push
6 * - plpgsql_ns_additem
7 * - plpgsql_ns_pop
8 * - plpgsql_ns_lookup
9 * - plpgsql_ns_top
10 * - plpgsql_getdiag_kindname
11 * - plpgsql_ns_lookup_label
12 * - plpgsql_ns_find_nearest_loop
13 * - plpgsql_free_function_memory
14 * - free_expr
15 * - free_block
16 * - free_stmts
17 * - free_stmt
18 * - free_assign
19 * - free_if
20 * - free_case
21 * - free_loop
22 * - free_while
23 * - free_fori
24 * - free_fors
25 * - free_forc
26 * - free_foreach_a
27 * - free_exit
28 * - free_return
29 * - free_return_next
30 * - free_return_query
31 * - free_raise
32 * - free_assert
33 * - free_execsql
34 * - free_dynexecute
35 * - free_dynfors
36 * - free_getdiag
37 * - free_open
38 * - free_fetch
39 * - free_close
40 * - free_perform
41 *--------------------------------------------------------------------
42 */
43
44 /*-------------------------------------------------------------------------
45 *
46 * pl_funcs.c - Misc functions for the PL/pgSQL
47 * procedural language
48 *
49 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
50 * Portions Copyright (c) 1994, Regents of the University of California
51 *
52 *
53 * IDENTIFICATION
54 * src/pl/plpgsql/src/pl_funcs.c
55 *
56 *-------------------------------------------------------------------------
57 */
58
59 #include "postgres.h"
60
61 #include "utils/memutils.h"
62
63 #include "plpgsql.h"
64
65
66 /* ----------
67 * Local variables for namespace handling
68 *
69 * The namespace structure actually forms a tree, of which only one linear
70 * list or "chain" (from the youngest item to the root) is accessible from
71 * any one plpgsql statement. During initial parsing of a function, ns_top
72 * points to the youngest item accessible from the block currently being
73 * parsed. We store the entire tree, however, since at runtime we will need
74 * to access the chain that's relevant to any one statement.
75 *
76 * Block boundaries in the namespace chain are marked by PLPGSQL_NSTYPE_LABEL
77 * items.
78 * ----------
79 */
80 static __thread PLpgSQL_nsitem *ns_top = NULL;
81
82
83
84 /* ----------
85 * plpgsql_ns_init Initialize namespace processing for a new function
86 * ----------
87 */
88 void
plpgsql_ns_init(void)89 plpgsql_ns_init(void)
90 {
91 ns_top = NULL;
92 }
93
94
95 /* ----------
96 * plpgsql_ns_push Create a new namespace level
97 * ----------
98 */
99 void
plpgsql_ns_push(const char * label,PLpgSQL_label_type label_type)100 plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
101 {
102 if (label == NULL)
103 label = "";
104 plpgsql_ns_additem(PLPGSQL_NSTYPE_LABEL, (int) label_type, label);
105 }
106
107
108 /* ----------
109 * plpgsql_ns_pop Pop entries back to (and including) the last label
110 * ----------
111 */
112 void
plpgsql_ns_pop(void)113 plpgsql_ns_pop(void)
114 {
115 Assert(ns_top != NULL);
116 while (ns_top->itemtype != PLPGSQL_NSTYPE_LABEL)
117 ns_top = ns_top->prev;
118 ns_top = ns_top->prev;
119 }
120
121
122 /* ----------
123 * plpgsql_ns_top Fetch the current namespace chain end
124 * ----------
125 */
126 PLpgSQL_nsitem *
plpgsql_ns_top(void)127 plpgsql_ns_top(void)
128 {
129 return ns_top;
130 }
131
132
133 /* ----------
134 * plpgsql_ns_additem Add an item to the current namespace chain
135 * ----------
136 */
137 void
plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype,int itemno,const char * name)138 plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
139 {
140 PLpgSQL_nsitem *nse;
141
142 Assert(name != NULL);
143 /* first item added must be a label */
144 Assert(ns_top != NULL || itemtype == PLPGSQL_NSTYPE_LABEL);
145
146 nse = palloc(offsetof(PLpgSQL_nsitem, name) + strlen(name) + 1);
147 nse->itemtype = itemtype;
148 nse->itemno = itemno;
149 nse->prev = ns_top;
150 strcpy(nse->name, name);
151 ns_top = nse;
152 }
153
154
155 /* ----------
156 * plpgsql_ns_lookup Lookup an identifier in the given namespace chain
157 *
158 * Note that this only searches for variables, not labels.
159 *
160 * If localmode is TRUE, only the topmost block level is searched.
161 *
162 * name1 must be non-NULL. Pass NULL for name2 and/or name3 if parsing a name
163 * with fewer than three components.
164 *
165 * If names_used isn't NULL, *names_used receives the number of names
166 * matched: 0 if no match, 1 if name1 matched an unqualified variable name,
167 * 2 if name1 and name2 matched a block label + variable name.
168 *
169 * Note that name3 is never directly matched to anything. However, if it
170 * isn't NULL, we will disregard qualified matches to scalar variables.
171 * Similarly, if name2 isn't NULL, we disregard unqualified matches to
172 * scalar variables.
173 * ----------
174 */
175 PLpgSQL_nsitem *
plpgsql_ns_lookup(PLpgSQL_nsitem * ns_cur,bool localmode,const char * name1,const char * name2,const char * name3,int * names_used)176 plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode,
177 const char *name1, const char *name2, const char *name3,
178 int *names_used)
179 {
180 /* Outer loop iterates once per block level in the namespace chain */
181 while (ns_cur != NULL)
182 {
183 PLpgSQL_nsitem *nsitem;
184
185 /* Check this level for unqualified match to variable name */
186 for (nsitem = ns_cur;
187 nsitem->itemtype != PLPGSQL_NSTYPE_LABEL;
188 nsitem = nsitem->prev)
189 {
190 if (strcmp(nsitem->name, name1) == 0)
191 {
192 if (name2 == NULL ||
193 nsitem->itemtype != PLPGSQL_NSTYPE_VAR)
194 {
195 if (names_used)
196 *names_used = 1;
197 return nsitem;
198 }
199 }
200 }
201
202 /* Check this level for qualified match to variable name */
203 if (name2 != NULL &&
204 strcmp(nsitem->name, name1) == 0)
205 {
206 for (nsitem = ns_cur;
207 nsitem->itemtype != PLPGSQL_NSTYPE_LABEL;
208 nsitem = nsitem->prev)
209 {
210 if (strcmp(nsitem->name, name2) == 0)
211 {
212 if (name3 == NULL ||
213 nsitem->itemtype != PLPGSQL_NSTYPE_VAR)
214 {
215 if (names_used)
216 *names_used = 2;
217 return nsitem;
218 }
219 }
220 }
221 }
222
223 if (localmode)
224 break; /* do not look into upper levels */
225
226 ns_cur = nsitem->prev;
227 }
228
229 /* This is just to suppress possibly-uninitialized-variable warnings */
230 if (names_used)
231 *names_used = 0;
232 return NULL; /* No match found */
233 }
234
235
236 /* ----------
237 * plpgsql_ns_lookup_label Lookup a label in the given namespace chain
238 * ----------
239 */
240 PLpgSQL_nsitem *
plpgsql_ns_lookup_label(PLpgSQL_nsitem * ns_cur,const char * name)241 plpgsql_ns_lookup_label(PLpgSQL_nsitem *ns_cur, const char *name)
242 {
243 while (ns_cur != NULL)
244 {
245 if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
246 strcmp(ns_cur->name, name) == 0)
247 return ns_cur;
248 ns_cur = ns_cur->prev;
249 }
250
251 return NULL; /* label not found */
252 }
253
254
255 /* ----------
256 * plpgsql_ns_find_nearest_loop Find innermost loop label in namespace chain
257 * ----------
258 */
259 PLpgSQL_nsitem *
plpgsql_ns_find_nearest_loop(PLpgSQL_nsitem * ns_cur)260 plpgsql_ns_find_nearest_loop(PLpgSQL_nsitem *ns_cur)
261 {
262 while (ns_cur != NULL)
263 {
264 if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
265 ns_cur->itemno == PLPGSQL_LABEL_LOOP)
266 return ns_cur;
267 ns_cur = ns_cur->prev;
268 }
269
270 return NULL; /* no loop found */
271 }
272
273
274 /*
275 * Statement type as a string, for use in error messages etc.
276 */
277
278
279 /*
280 * GET DIAGNOSTICS item name as a string, for use in error messages etc.
281 */
282 const char *
plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind)283 plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind)
284 {
285 switch (kind)
286 {
287 case PLPGSQL_GETDIAG_ROW_COUNT:
288 return "ROW_COUNT";
289 case PLPGSQL_GETDIAG_RESULT_OID:
290 return "RESULT_OID";
291 case PLPGSQL_GETDIAG_CONTEXT:
292 return "PG_CONTEXT";
293 case PLPGSQL_GETDIAG_ERROR_CONTEXT:
294 return "PG_EXCEPTION_CONTEXT";
295 case PLPGSQL_GETDIAG_ERROR_DETAIL:
296 return "PG_EXCEPTION_DETAIL";
297 case PLPGSQL_GETDIAG_ERROR_HINT:
298 return "PG_EXCEPTION_HINT";
299 case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
300 return "RETURNED_SQLSTATE";
301 case PLPGSQL_GETDIAG_COLUMN_NAME:
302 return "COLUMN_NAME";
303 case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
304 return "CONSTRAINT_NAME";
305 case PLPGSQL_GETDIAG_DATATYPE_NAME:
306 return "PG_DATATYPE_NAME";
307 case PLPGSQL_GETDIAG_MESSAGE_TEXT:
308 return "MESSAGE_TEXT";
309 case PLPGSQL_GETDIAG_TABLE_NAME:
310 return "TABLE_NAME";
311 case PLPGSQL_GETDIAG_SCHEMA_NAME:
312 return "SCHEMA_NAME";
313 }
314
315 return "unknown";
316 }
317
318
319 /**********************************************************************
320 * Release memory when a PL/pgSQL function is no longer needed
321 *
322 * The code for recursing through the function tree is really only
323 * needed to locate PLpgSQL_expr nodes, which may contain references
324 * to saved SPI Plans that must be freed. The function tree itself,
325 * along with subsidiary data, is freed in one swoop by freeing the
326 * function's permanent memory context.
327 **********************************************************************/
328 static void free_stmt(PLpgSQL_stmt *stmt);
329 static void free_block(PLpgSQL_stmt_block *block);
330 static void free_assign(PLpgSQL_stmt_assign *stmt);
331 static void free_if(PLpgSQL_stmt_if *stmt);
332 static void free_case(PLpgSQL_stmt_case *stmt);
333 static void free_loop(PLpgSQL_stmt_loop *stmt);
334 static void free_while(PLpgSQL_stmt_while *stmt);
335 static void free_fori(PLpgSQL_stmt_fori *stmt);
336 static void free_fors(PLpgSQL_stmt_fors *stmt);
337 static void free_forc(PLpgSQL_stmt_forc *stmt);
338 static void free_foreach_a(PLpgSQL_stmt_foreach_a *stmt);
339 static void free_exit(PLpgSQL_stmt_exit *stmt);
340 static void free_return(PLpgSQL_stmt_return *stmt);
341 static void free_return_next(PLpgSQL_stmt_return_next *stmt);
342 static void free_return_query(PLpgSQL_stmt_return_query *stmt);
343 static void free_raise(PLpgSQL_stmt_raise *stmt);
344 static void free_assert(PLpgSQL_stmt_assert *stmt);
345 static void free_execsql(PLpgSQL_stmt_execsql *stmt);
346 static void free_dynexecute(PLpgSQL_stmt_dynexecute *stmt);
347 static void free_dynfors(PLpgSQL_stmt_dynfors *stmt);
348 static void free_getdiag(PLpgSQL_stmt_getdiag *stmt);
349 static void free_open(PLpgSQL_stmt_open *stmt);
350 static void free_fetch(PLpgSQL_stmt_fetch *stmt);
351 static void free_close(PLpgSQL_stmt_close *stmt);
352 static void free_perform(PLpgSQL_stmt_perform *stmt);
353 static void free_expr(PLpgSQL_expr *expr);
354
355
356 static void
free_stmt(PLpgSQL_stmt * stmt)357 free_stmt(PLpgSQL_stmt *stmt)
358 {
359 switch (stmt->cmd_type)
360 {
361 case PLPGSQL_STMT_BLOCK:
362 free_block((PLpgSQL_stmt_block *) stmt);
363 break;
364 case PLPGSQL_STMT_ASSIGN:
365 free_assign((PLpgSQL_stmt_assign *) stmt);
366 break;
367 case PLPGSQL_STMT_IF:
368 free_if((PLpgSQL_stmt_if *) stmt);
369 break;
370 case PLPGSQL_STMT_CASE:
371 free_case((PLpgSQL_stmt_case *) stmt);
372 break;
373 case PLPGSQL_STMT_LOOP:
374 free_loop((PLpgSQL_stmt_loop *) stmt);
375 break;
376 case PLPGSQL_STMT_WHILE:
377 free_while((PLpgSQL_stmt_while *) stmt);
378 break;
379 case PLPGSQL_STMT_FORI:
380 free_fori((PLpgSQL_stmt_fori *) stmt);
381 break;
382 case PLPGSQL_STMT_FORS:
383 free_fors((PLpgSQL_stmt_fors *) stmt);
384 break;
385 case PLPGSQL_STMT_FORC:
386 free_forc((PLpgSQL_stmt_forc *) stmt);
387 break;
388 case PLPGSQL_STMT_FOREACH_A:
389 free_foreach_a((PLpgSQL_stmt_foreach_a *) stmt);
390 break;
391 case PLPGSQL_STMT_EXIT:
392 free_exit((PLpgSQL_stmt_exit *) stmt);
393 break;
394 case PLPGSQL_STMT_RETURN:
395 free_return((PLpgSQL_stmt_return *) stmt);
396 break;
397 case PLPGSQL_STMT_RETURN_NEXT:
398 free_return_next((PLpgSQL_stmt_return_next *) stmt);
399 break;
400 case PLPGSQL_STMT_RETURN_QUERY:
401 free_return_query((PLpgSQL_stmt_return_query *) stmt);
402 break;
403 case PLPGSQL_STMT_RAISE:
404 free_raise((PLpgSQL_stmt_raise *) stmt);
405 break;
406 case PLPGSQL_STMT_ASSERT:
407 free_assert((PLpgSQL_stmt_assert *) stmt);
408 break;
409 case PLPGSQL_STMT_EXECSQL:
410 free_execsql((PLpgSQL_stmt_execsql *) stmt);
411 break;
412 case PLPGSQL_STMT_DYNEXECUTE:
413 free_dynexecute((PLpgSQL_stmt_dynexecute *) stmt);
414 break;
415 case PLPGSQL_STMT_DYNFORS:
416 free_dynfors((PLpgSQL_stmt_dynfors *) stmt);
417 break;
418 case PLPGSQL_STMT_GETDIAG:
419 free_getdiag((PLpgSQL_stmt_getdiag *) stmt);
420 break;
421 case PLPGSQL_STMT_OPEN:
422 free_open((PLpgSQL_stmt_open *) stmt);
423 break;
424 case PLPGSQL_STMT_FETCH:
425 free_fetch((PLpgSQL_stmt_fetch *) stmt);
426 break;
427 case PLPGSQL_STMT_CLOSE:
428 free_close((PLpgSQL_stmt_close *) stmt);
429 break;
430 case PLPGSQL_STMT_PERFORM:
431 free_perform((PLpgSQL_stmt_perform *) stmt);
432 break;
433 default:
434 elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
435 break;
436 }
437 }
438
439 static void
free_stmts(List * stmts)440 free_stmts(List *stmts)
441 {
442 ListCell *s;
443
444 foreach(s, stmts)
445 {
446 free_stmt((PLpgSQL_stmt *) lfirst(s));
447 }
448 }
449
450 static void
free_block(PLpgSQL_stmt_block * block)451 free_block(PLpgSQL_stmt_block *block)
452 {
453 free_stmts(block->body);
454 if (block->exceptions)
455 {
456 ListCell *e;
457
458 foreach(e, block->exceptions->exc_list)
459 {
460 PLpgSQL_exception *exc = (PLpgSQL_exception *) lfirst(e);
461
462 free_stmts(exc->action);
463 }
464 }
465 }
466
467 static void
free_assign(PLpgSQL_stmt_assign * stmt)468 free_assign(PLpgSQL_stmt_assign *stmt)
469 {
470 free_expr(stmt->expr);
471 }
472
473 static void
free_if(PLpgSQL_stmt_if * stmt)474 free_if(PLpgSQL_stmt_if *stmt)
475 {
476 ListCell *l;
477
478 free_expr(stmt->cond);
479 free_stmts(stmt->then_body);
480 foreach(l, stmt->elsif_list)
481 {
482 PLpgSQL_if_elsif *elif = (PLpgSQL_if_elsif *) lfirst(l);
483
484 free_expr(elif->cond);
485 free_stmts(elif->stmts);
486 }
487 free_stmts(stmt->else_body);
488 }
489
490 static void
free_case(PLpgSQL_stmt_case * stmt)491 free_case(PLpgSQL_stmt_case *stmt)
492 {
493 ListCell *l;
494
495 free_expr(stmt->t_expr);
496 foreach(l, stmt->case_when_list)
497 {
498 PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l);
499
500 free_expr(cwt->expr);
501 free_stmts(cwt->stmts);
502 }
503 free_stmts(stmt->else_stmts);
504 }
505
506 static void
free_loop(PLpgSQL_stmt_loop * stmt)507 free_loop(PLpgSQL_stmt_loop *stmt)
508 {
509 free_stmts(stmt->body);
510 }
511
512 static void
free_while(PLpgSQL_stmt_while * stmt)513 free_while(PLpgSQL_stmt_while *stmt)
514 {
515 free_expr(stmt->cond);
516 free_stmts(stmt->body);
517 }
518
519 static void
free_fori(PLpgSQL_stmt_fori * stmt)520 free_fori(PLpgSQL_stmt_fori *stmt)
521 {
522 free_expr(stmt->lower);
523 free_expr(stmt->upper);
524 free_expr(stmt->step);
525 free_stmts(stmt->body);
526 }
527
528 static void
free_fors(PLpgSQL_stmt_fors * stmt)529 free_fors(PLpgSQL_stmt_fors *stmt)
530 {
531 free_stmts(stmt->body);
532 free_expr(stmt->query);
533 }
534
535 static void
free_forc(PLpgSQL_stmt_forc * stmt)536 free_forc(PLpgSQL_stmt_forc *stmt)
537 {
538 free_stmts(stmt->body);
539 free_expr(stmt->argquery);
540 }
541
542 static void
free_foreach_a(PLpgSQL_stmt_foreach_a * stmt)543 free_foreach_a(PLpgSQL_stmt_foreach_a *stmt)
544 {
545 free_expr(stmt->expr);
546 free_stmts(stmt->body);
547 }
548
549 static void
free_open(PLpgSQL_stmt_open * stmt)550 free_open(PLpgSQL_stmt_open *stmt)
551 {
552 ListCell *lc;
553
554 free_expr(stmt->argquery);
555 free_expr(stmt->query);
556 free_expr(stmt->dynquery);
557 foreach(lc, stmt->params)
558 {
559 free_expr((PLpgSQL_expr *) lfirst(lc));
560 }
561 }
562
563 static void
free_fetch(PLpgSQL_stmt_fetch * stmt)564 free_fetch(PLpgSQL_stmt_fetch *stmt)
565 {
566 free_expr(stmt->expr);
567 }
568
569 static void
free_close(PLpgSQL_stmt_close * stmt)570 free_close(PLpgSQL_stmt_close *stmt)
571 {
572 }
573
574 static void
free_perform(PLpgSQL_stmt_perform * stmt)575 free_perform(PLpgSQL_stmt_perform *stmt)
576 {
577 free_expr(stmt->expr);
578 }
579
580 static void
free_exit(PLpgSQL_stmt_exit * stmt)581 free_exit(PLpgSQL_stmt_exit *stmt)
582 {
583 free_expr(stmt->cond);
584 }
585
586 static void
free_return(PLpgSQL_stmt_return * stmt)587 free_return(PLpgSQL_stmt_return *stmt)
588 {
589 free_expr(stmt->expr);
590 }
591
592 static void
free_return_next(PLpgSQL_stmt_return_next * stmt)593 free_return_next(PLpgSQL_stmt_return_next *stmt)
594 {
595 free_expr(stmt->expr);
596 }
597
598 static void
free_return_query(PLpgSQL_stmt_return_query * stmt)599 free_return_query(PLpgSQL_stmt_return_query *stmt)
600 {
601 ListCell *lc;
602
603 free_expr(stmt->query);
604 free_expr(stmt->dynquery);
605 foreach(lc, stmt->params)
606 {
607 free_expr((PLpgSQL_expr *) lfirst(lc));
608 }
609 }
610
611 static void
free_raise(PLpgSQL_stmt_raise * stmt)612 free_raise(PLpgSQL_stmt_raise *stmt)
613 {
614 ListCell *lc;
615
616 foreach(lc, stmt->params)
617 {
618 free_expr((PLpgSQL_expr *) lfirst(lc));
619 }
620 foreach(lc, stmt->options)
621 {
622 PLpgSQL_raise_option *opt = (PLpgSQL_raise_option *) lfirst(lc);
623
624 free_expr(opt->expr);
625 }
626 }
627
628 static void
free_assert(PLpgSQL_stmt_assert * stmt)629 free_assert(PLpgSQL_stmt_assert *stmt)
630 {
631 free_expr(stmt->cond);
632 free_expr(stmt->message);
633 }
634
635 static void
free_execsql(PLpgSQL_stmt_execsql * stmt)636 free_execsql(PLpgSQL_stmt_execsql *stmt)
637 {
638 free_expr(stmt->sqlstmt);
639 }
640
641 static void
free_dynexecute(PLpgSQL_stmt_dynexecute * stmt)642 free_dynexecute(PLpgSQL_stmt_dynexecute *stmt)
643 {
644 ListCell *lc;
645
646 free_expr(stmt->query);
647 foreach(lc, stmt->params)
648 {
649 free_expr((PLpgSQL_expr *) lfirst(lc));
650 }
651 }
652
653 static void
free_dynfors(PLpgSQL_stmt_dynfors * stmt)654 free_dynfors(PLpgSQL_stmt_dynfors *stmt)
655 {
656 ListCell *lc;
657
658 free_stmts(stmt->body);
659 free_expr(stmt->query);
660 foreach(lc, stmt->params)
661 {
662 free_expr((PLpgSQL_expr *) lfirst(lc));
663 }
664 }
665
666 static void
free_getdiag(PLpgSQL_stmt_getdiag * stmt)667 free_getdiag(PLpgSQL_stmt_getdiag *stmt)
668 {
669 }
670
free_expr(PLpgSQL_expr * expr)671 static void free_expr(PLpgSQL_expr *expr) {}
672
673
674 void
plpgsql_free_function_memory(PLpgSQL_function * func)675 plpgsql_free_function_memory(PLpgSQL_function *func)
676 {
677 int i;
678
679 /* Better not call this on an in-use function */
680 Assert(func->use_count == 0);
681
682 /* Release plans associated with variable declarations */
683 for (i = 0; i < func->ndatums; i++)
684 {
685 PLpgSQL_datum *d = func->datums[i];
686
687 switch (d->dtype)
688 {
689 case PLPGSQL_DTYPE_VAR:
690 {
691 PLpgSQL_var *var = (PLpgSQL_var *) d;
692
693 free_expr(var->default_val);
694 free_expr(var->cursor_explicit_expr);
695 }
696 break;
697 case PLPGSQL_DTYPE_ROW:
698 break;
699 case PLPGSQL_DTYPE_REC:
700 break;
701 case PLPGSQL_DTYPE_RECFIELD:
702 break;
703 case PLPGSQL_DTYPE_ARRAYELEM:
704 free_expr(((PLpgSQL_arrayelem *) d)->subscript);
705 break;
706 default:
707 elog(ERROR, "unrecognized data type: %d", d->dtype);
708 }
709 }
710 func->ndatums = 0;
711
712 /* Release plans in statement tree */
713 if (func->action)
714 free_block(func->action);
715 func->action = NULL;
716
717 /*
718 * And finally, release all memory except the PLpgSQL_function struct
719 * itself (which has to be kept around because there may be multiple
720 * fn_extra pointers to it).
721 */
722 if (func->fn_cxt)
723 MemoryContextDelete(func->fn_cxt);
724 func->fn_cxt = NULL;
725 }
726
727
728 /**********************************************************************
729 * Debug functions for analyzing the compiled code
730 **********************************************************************/
731
732
733 static void dump_ind(void);
734 static void dump_stmt(PLpgSQL_stmt *stmt);
735 static void dump_block(PLpgSQL_stmt_block *block);
736 static void dump_assign(PLpgSQL_stmt_assign *stmt);
737 static void dump_if(PLpgSQL_stmt_if *stmt);
738 static void dump_case(PLpgSQL_stmt_case *stmt);
739 static void dump_loop(PLpgSQL_stmt_loop *stmt);
740 static void dump_while(PLpgSQL_stmt_while *stmt);
741 static void dump_fori(PLpgSQL_stmt_fori *stmt);
742 static void dump_fors(PLpgSQL_stmt_fors *stmt);
743 static void dump_forc(PLpgSQL_stmt_forc *stmt);
744 static void dump_foreach_a(PLpgSQL_stmt_foreach_a *stmt);
745 static void dump_exit(PLpgSQL_stmt_exit *stmt);
746 static void dump_return(PLpgSQL_stmt_return *stmt);
747 static void dump_return_next(PLpgSQL_stmt_return_next *stmt);
748 static void dump_return_query(PLpgSQL_stmt_return_query *stmt);
749 static void dump_raise(PLpgSQL_stmt_raise *stmt);
750 static void dump_assert(PLpgSQL_stmt_assert *stmt);
751 static void dump_execsql(PLpgSQL_stmt_execsql *stmt);
752 static void dump_dynexecute(PLpgSQL_stmt_dynexecute *stmt);
753 static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt);
754 static void dump_getdiag(PLpgSQL_stmt_getdiag *stmt);
755 static void dump_open(PLpgSQL_stmt_open *stmt);
756 static void dump_fetch(PLpgSQL_stmt_fetch *stmt);
757 static void dump_cursor_direction(PLpgSQL_stmt_fetch *stmt);
758 static void dump_close(PLpgSQL_stmt_close *stmt);
759 static void dump_perform(PLpgSQL_stmt_perform *stmt);
760 static void dump_expr(PLpgSQL_expr *expr);
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822