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