]> granicus.if.org Git - postgresql/blob - src/pl/plpgsql/src/pl_comp.c
Simplify ParamListInfo data structure to support only numbered parameters,
[postgresql] / src / pl / plpgsql / src / pl_comp.c
1 /*-------------------------------------------------------------------------
2  *
3  * pl_comp.c            - Compiler part of the PL/pgSQL
4  *                        procedural language
5  *
6  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.101 2006/03/14 22:48:23 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "plpgsql.h"
17
18 #include <ctype.h>
19
20 #include "pl.tab.h"
21
22 #include "access/heapam.h"
23 #include "catalog/namespace.h"
24 #include "catalog/pg_attribute.h"
25 #include "catalog/pg_attrdef.h"
26 #include "catalog/pg_class.h"
27 #include "catalog/pg_proc.h"
28 #include "catalog/pg_type.h"
29 #include "funcapi.h"
30 #include "nodes/makefuncs.h"
31 #include "parser/gramparse.h"
32 #include "parser/parse_type.h"
33 #include "tcop/tcopprot.h"
34 #include "utils/array.h"
35 #include "utils/builtins.h"
36 #include "utils/lsyscache.h"
37 #include "utils/memutils.h"
38 #include "utils/syscache.h"
39
40
41 /* ----------
42  * Our own local and global variables
43  * ----------
44  */
45 static int      datums_alloc;
46 int                     plpgsql_nDatums;
47 PLpgSQL_datum **plpgsql_Datums;
48 static int      datums_last = 0;
49
50 int                     plpgsql_error_lineno;
51 char       *plpgsql_error_funcname;
52 bool            plpgsql_DumpExecTree = false;
53 bool            plpgsql_check_syntax = false;
54
55 PLpgSQL_function *plpgsql_curr_compile;
56
57 /* A context appropriate for short-term allocs during compilation */
58 MemoryContext compile_tmp_cxt;
59
60 /* ----------
61  * Hash table for compiled functions
62  * ----------
63  */
64 static HTAB *plpgsql_HashTable = NULL;
65
66 typedef struct plpgsql_hashent
67 {
68         PLpgSQL_func_hashkey key;
69         PLpgSQL_function *function;
70 } plpgsql_HashEnt;
71
72 #define FUNCS_PER_USER          128 /* initial table size */
73
74 /* ----------
75  * Lookup table for EXCEPTION condition names
76  * ----------
77  */
78 typedef struct
79 {
80         const char *label;
81         int                     sqlerrstate;
82 } ExceptionLabelMap;
83
84 static const ExceptionLabelMap exception_label_map[] = {
85 #include "plerrcodes.h"
86         {NULL, 0}
87 };
88
89
90 /* ----------
91  * static prototypes
92  * ----------
93  */
94 static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
95                    HeapTuple procTup,
96                    PLpgSQL_func_hashkey *hashkey,
97                    bool forValidator);
98 static PLpgSQL_row *build_row_from_class(Oid classOid);
99 static PLpgSQL_row *build_row_from_vars(PLpgSQL_variable **vars, int numvars);
100 static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
101 static void compute_function_hashkey(FunctionCallInfo fcinfo,
102                                                  Form_pg_proc procStruct,
103                                                  PLpgSQL_func_hashkey *hashkey,
104                                                  bool forValidator);
105 static void plpgsql_resolve_polymorphic_argtypes(int numargs,
106                                                                          Oid *argtypes, char *argmodes,
107                                                                          Node *call_expr, bool forValidator,
108                                                                          const char *proname);
109 static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
110 static void plpgsql_HashTableInsert(PLpgSQL_function *function,
111                                                 PLpgSQL_func_hashkey *func_key);
112 static void plpgsql_HashTableDelete(PLpgSQL_function *function);
113 static void delete_function(PLpgSQL_function *func);
114
115 /* ----------
116  * plpgsql_compile              Make an execution tree for a PL/pgSQL function.
117  *
118  * If forValidator is true, we're only compiling for validation purposes,
119  * and so some checks are skipped.
120  *
121  * Note: it's important for this to fall through quickly if the function
122  * has already been compiled.
123  * ----------
124  */
125 PLpgSQL_function *
126 plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
127 {
128         Oid                     funcOid = fcinfo->flinfo->fn_oid;
129         HeapTuple       procTup;
130         Form_pg_proc procStruct;
131         PLpgSQL_function *function;
132         PLpgSQL_func_hashkey hashkey;
133         bool            hashkey_valid = false;
134
135         /*
136          * Lookup the pg_proc tuple by Oid; we'll need it in any case
137          */
138         procTup = SearchSysCache(PROCOID,
139                                                          ObjectIdGetDatum(funcOid),
140                                                          0, 0, 0);
141         if (!HeapTupleIsValid(procTup))
142                 elog(ERROR, "cache lookup failed for function %u", funcOid);
143         procStruct = (Form_pg_proc) GETSTRUCT(procTup);
144
145         /*
146          * See if there's already a cache entry for the current FmgrInfo. If not,
147          * try to find one in the hash table.
148          */
149         function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
150
151         if (!function)
152         {
153                 /* Compute hashkey using function signature and actual arg types */
154                 compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
155                 hashkey_valid = true;
156
157                 /* And do the lookup */
158                 function = plpgsql_HashTableLookup(&hashkey);
159         }
160
161         if (function)
162         {
163                 /* We have a compiled function, but is it still valid? */
164                 if (!(function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
165                           function->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data)))
166                 {
167                         /* Nope, drop the function and associated storage */
168                         delete_function(function);
169                         function = NULL;
170                 }
171         }
172
173         /*
174          * If the function wasn't found or was out-of-date, we have to compile it
175          */
176         if (!function)
177         {
178                 /*
179                  * Calculate hashkey if we didn't already; we'll need it to store the
180                  * completed function.
181                  */
182                 if (!hashkey_valid)
183                         compute_function_hashkey(fcinfo, procStruct, &hashkey,
184                                                                          forValidator);
185
186                 /*
187                  * Do the hard part.
188                  */
189                 function = do_compile(fcinfo, procTup, &hashkey, forValidator);
190         }
191
192         ReleaseSysCache(procTup);
193
194         /*
195          * Save pointer in FmgrInfo to avoid search on subsequent calls
196          */
197         fcinfo->flinfo->fn_extra = (void *) function;
198
199         /*
200          * Finally return the compiled function
201          */
202         return function;
203 }
204
205 /*
206  * This is the slow part of plpgsql_compile().
207  *
208  * While compiling a function, the CurrentMemoryContext is the
209  * per-function memory context of the function we are compiling. That
210  * means a palloc() will allocate storage with the same lifetime as
211  * the function itself.
212  *
213  * Because palloc()'d storage will not be immediately freed, temporary
214  * allocations should either be performed in a short-lived memory
215  * context or explicitly pfree'd. Since not all backend functions are
216  * careful about pfree'ing their allocations, it is also wise to
217  * switch into a short-term context before calling into the
218  * backend. An appropriate context for performing short-term
219  * allocations is the compile_tmp_cxt.
220  */
221 static PLpgSQL_function *
222 do_compile(FunctionCallInfo fcinfo,
223                    HeapTuple procTup,
224                    PLpgSQL_func_hashkey *hashkey,
225                    bool forValidator)
226 {
227         Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
228         int                     functype = CALLED_AS_TRIGGER(fcinfo) ? T_TRIGGER : T_FUNCTION;
229         PLpgSQL_function *function;
230         Datum           prosrcdatum;
231         bool            isnull;
232         char       *proc_source;
233         HeapTuple       typeTup;
234         Form_pg_type typeStruct;
235         PLpgSQL_variable *var;
236         PLpgSQL_rec *rec;
237         int                     i;
238         ErrorContextCallback plerrcontext;
239         int                     parse_rc;
240         Oid                     rettypeid;
241         int                     numargs;
242         int                     num_in_args = 0;
243         int                     num_out_args = 0;
244         Oid                *argtypes;
245         char      **argnames;
246         char       *argmodes;
247         int                *in_arg_varnos = NULL;
248         PLpgSQL_variable **out_arg_variables;
249         MemoryContext func_cxt;
250
251         /*
252          * Setup the scanner input and error info.      We assume that this function
253          * cannot be invoked recursively, so there's no need to save and restore
254          * the static variables used here.
255          */
256         prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
257                                                                   Anum_pg_proc_prosrc, &isnull);
258         if (isnull)
259                 elog(ERROR, "null prosrc");
260         proc_source = DatumGetCString(DirectFunctionCall1(textout, prosrcdatum));
261         plpgsql_scanner_init(proc_source, functype);
262
263         plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
264         plpgsql_error_lineno = 0;
265
266         /*
267          * Setup error traceback support for ereport()
268          */
269         plerrcontext.callback = plpgsql_compile_error_callback;
270         plerrcontext.arg = forValidator ? proc_source : NULL;
271         plerrcontext.previous = error_context_stack;
272         error_context_stack = &plerrcontext;
273
274         /*
275          * Initialize the compiler
276          */
277         plpgsql_ns_init();
278         plpgsql_ns_push(NULL);
279         plpgsql_DumpExecTree = false;
280
281         datums_alloc = 128;
282         plpgsql_nDatums = 0;
283         /* This is short-lived, so needn't allocate in function's cxt */
284         plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
285         datums_last = 0;
286
287         /*
288          * Do extra syntax checks when validating the function definition. We skip
289          * this when actually compiling functions for execution, for performance
290          * reasons.
291          */
292         plpgsql_check_syntax = forValidator;
293
294         /*
295          * Create the new function node. We allocate the function and all of its
296          * compile-time storage (e.g. parse tree) in its own memory context. This
297          * allows us to reclaim the function's storage cleanly.
298          */
299         func_cxt = AllocSetContextCreate(TopMemoryContext,
300                                                                          "PL/PgSQL function context",
301                                                                          ALLOCSET_DEFAULT_MINSIZE,
302                                                                          ALLOCSET_DEFAULT_INITSIZE,
303                                                                          ALLOCSET_DEFAULT_MAXSIZE);
304         compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
305         function = palloc0(sizeof(*function));
306         plpgsql_curr_compile = function;
307
308         function->fn_name = pstrdup(NameStr(procStruct->proname));
309         function->fn_oid = fcinfo->flinfo->fn_oid;
310         function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
311         function->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
312         function->fn_functype = functype;
313         function->fn_cxt = func_cxt;
314         function->out_param_varno = -1;         /* set up for no OUT param */
315
316         switch (functype)
317         {
318                 case T_FUNCTION:
319
320                         /*
321                          * Fetch info about the procedure's parameters. Allocations aren't
322                          * needed permanently, so make them in tmp cxt.
323                          *
324                          * We also need to resolve any polymorphic input or output
325                          * argument types.      In validation mode we won't be able to, so we
326                          * arbitrarily assume we are dealing with integers.
327                          */
328                         MemoryContextSwitchTo(compile_tmp_cxt);
329
330                         numargs = get_func_arg_info(procTup,
331                                                                                 &argtypes, &argnames, &argmodes);
332
333                         plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
334                                                                                                  fcinfo->flinfo->fn_expr,
335                                                                                                  forValidator,
336                                                                                                  plpgsql_error_funcname);
337
338                         in_arg_varnos = (int *) palloc(numargs * sizeof(int));
339                         out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
340
341                         MemoryContextSwitchTo(func_cxt);
342
343                         /*
344                          * Create the variables for the procedure's parameters.
345                          */
346                         for (i = 0; i < numargs; i++)
347                         {
348                                 char            buf[32];
349                                 Oid                     argtypeid = argtypes[i];
350                                 char            argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
351                                 PLpgSQL_type *argdtype;
352                                 PLpgSQL_variable *argvariable;
353                                 int                     argitemtype;
354
355                                 /* Create $n name for variable */
356                                 snprintf(buf, sizeof(buf), "$%d", i + 1);
357
358                                 /* Create datatype info */
359                                 argdtype = plpgsql_build_datatype(argtypeid, -1);
360
361                                 /* Disallow pseudotype argument */
362                                 /* (note we already replaced ANYARRAY/ANYELEMENT) */
363                                 /* (build_variable would do this, but wrong message) */
364                                 if (argdtype->ttype != PLPGSQL_TTYPE_SCALAR &&
365                                         argdtype->ttype != PLPGSQL_TTYPE_ROW)
366                                         ereport(ERROR,
367                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
368                                                          errmsg("plpgsql functions cannot take type %s",
369                                                                         format_type_be(argtypeid))));
370
371                                 /* Build variable and add to datum list */
372                                 argvariable = plpgsql_build_variable(buf, 0,
373                                                                                                          argdtype, false);
374
375                                 if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
376                                 {
377                                         argitemtype = PLPGSQL_NSTYPE_VAR;
378                                         /* input argument vars are forced to be CONSTANT */
379                                         if (argmode == PROARGMODE_IN)
380                                                 ((PLpgSQL_var *) argvariable)->isconst = true;
381                                 }
382                                 else
383                                 {
384                                         Assert(argvariable->dtype == PLPGSQL_DTYPE_ROW);
385                                         argitemtype = PLPGSQL_NSTYPE_ROW;
386                                 }
387
388                                 /* Remember arguments in appropriate arrays */
389                                 if (argmode == PROARGMODE_IN || argmode == PROARGMODE_INOUT)
390                                         in_arg_varnos[num_in_args++] = argvariable->dno;
391                                 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_INOUT)
392                                         out_arg_variables[num_out_args++] = argvariable;
393
394                                 /* Add to namespace under the $n name */
395                                 plpgsql_ns_additem(argitemtype, argvariable->dno, buf);
396
397                                 /* If there's a name for the argument, make an alias */
398                                 if (argnames && argnames[i][0] != '\0')
399                                         plpgsql_ns_additem(argitemtype, argvariable->dno,
400                                                                            argnames[i]);
401                         }
402
403                         /*
404                          * If there's just one OUT parameter, out_param_varno points
405                          * directly to it.      If there's more than one, build a row that
406                          * holds all of them.
407                          */
408                         if (num_out_args == 1)
409                                 function->out_param_varno = out_arg_variables[0]->dno;
410                         else if (num_out_args > 1)
411                         {
412                                 PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
413                                                                                                            num_out_args);
414
415                                 plpgsql_adddatum((PLpgSQL_datum *) row);
416                                 function->out_param_varno = row->rowno;
417                         }
418
419                         /*
420                          * Check for a polymorphic returntype. If found, use the actual
421                          * returntype type from the caller's FuncExpr node, if we have
422                          * one.  (In validation mode we arbitrarily assume we are dealing
423                          * with integers.)
424                          *
425                          * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
426                          * work; if it doesn't we're in some context that fails to make
427                          * the info available.
428                          */
429                         rettypeid = procStruct->prorettype;
430                         if (rettypeid == ANYARRAYOID || rettypeid == ANYELEMENTOID)
431                         {
432                                 if (forValidator)
433                                 {
434                                         if (rettypeid == ANYARRAYOID)
435                                                 rettypeid = INT4ARRAYOID;
436                                         else
437                                                 rettypeid = INT4OID;
438                                 }
439                                 else
440                                 {
441                                         rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
442                                         if (!OidIsValid(rettypeid))
443                                                 ereport(ERROR,
444                                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
445                                                          errmsg("could not determine actual return type "
446                                                                         "for polymorphic function \"%s\"",
447                                                                         plpgsql_error_funcname)));
448                                 }
449                         }
450
451                         /*
452                          * Normal function has a defined returntype
453                          */
454                         function->fn_rettype = rettypeid;
455                         function->fn_retset = procStruct->proretset;
456
457                         /*
458                          * Lookup the function's return type
459                          */
460                         typeTup = SearchSysCache(TYPEOID,
461                                                                          ObjectIdGetDatum(rettypeid),
462                                                                          0, 0, 0);
463                         if (!HeapTupleIsValid(typeTup))
464                                 elog(ERROR, "cache lookup failed for type %u", rettypeid);
465                         typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
466
467                         /* Disallow pseudotype result, except VOID or RECORD */
468                         /* (note we already replaced ANYARRAY/ANYELEMENT) */
469                         if (typeStruct->typtype == 'p')
470                         {
471                                 if (rettypeid == VOIDOID ||
472                                         rettypeid == RECORDOID)
473                                          /* okay */ ;
474                                 else if (rettypeid == TRIGGEROID)
475                                         ereport(ERROR,
476                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
477                                                          errmsg("trigger functions may only be called as triggers")));
478                                 else
479                                         ereport(ERROR,
480                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
481                                                          errmsg("plpgsql functions cannot return type %s",
482                                                                         format_type_be(rettypeid))));
483                         }
484
485                         if (typeStruct->typrelid != InvalidOid ||
486                                 rettypeid == RECORDOID)
487                                 function->fn_retistuple = true;
488                         else
489                         {
490                                 function->fn_retbyval = typeStruct->typbyval;
491                                 function->fn_rettyplen = typeStruct->typlen;
492                                 function->fn_rettypioparam = getTypeIOParam(typeTup);
493                                 fmgr_info(typeStruct->typinput, &(function->fn_retinput));
494
495                                 /*
496                                  * install $0 reference, but only for polymorphic return
497                                  * types, and not when the return is specified through an
498                                  * output parameter.
499                                  */
500                                 if ((procStruct->prorettype == ANYARRAYOID ||
501                                          procStruct->prorettype == ANYELEMENTOID) &&
502                                         num_out_args == 0)
503                                 {
504                                         (void) plpgsql_build_variable("$0", 0,
505                                                                                                   build_datatype(typeTup, -1),
506                                                                                                   true);
507                                 }
508                         }
509                         ReleaseSysCache(typeTup);
510                         break;
511
512                 case T_TRIGGER:
513                         /* Trigger procedure's return type is unknown yet */
514                         function->fn_rettype = InvalidOid;
515                         function->fn_retbyval = false;
516                         function->fn_retistuple = true;
517                         function->fn_retset = false;
518
519                         /* shouldn't be any declared arguments */
520                         if (procStruct->pronargs != 0)
521                                 ereport(ERROR,
522                                                 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
523                                   errmsg("trigger functions cannot have declared arguments"),
524                                                  errhint("You probably want to use TG_NARGS and TG_ARGV instead.")));
525
526                         /* Add the record for referencing NEW */
527                         rec = palloc0(sizeof(PLpgSQL_rec));
528                         rec->dtype = PLPGSQL_DTYPE_REC;
529                         rec->refname = pstrdup("new");
530                         rec->tup = NULL;
531                         rec->tupdesc = NULL;
532                         rec->freetup = false;
533                         plpgsql_adddatum((PLpgSQL_datum *) rec);
534                         plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
535                         function->new_varno = rec->recno;
536
537                         /* Add the record for referencing OLD */
538                         rec = palloc0(sizeof(PLpgSQL_rec));
539                         rec->dtype = PLPGSQL_DTYPE_REC;
540                         rec->refname = pstrdup("old");
541                         rec->tup = NULL;
542                         rec->tupdesc = NULL;
543                         rec->freetup = false;
544                         plpgsql_adddatum((PLpgSQL_datum *) rec);
545                         plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
546                         function->old_varno = rec->recno;
547
548                         /* Add the variable tg_name */
549                         var = plpgsql_build_variable("tg_name", 0,
550                                                                                  plpgsql_build_datatype(NAMEOID, -1),
551                                                                                  true);
552                         function->tg_name_varno = var->dno;
553
554                         /* Add the variable tg_when */
555                         var = plpgsql_build_variable("tg_when", 0,
556                                                                                  plpgsql_build_datatype(TEXTOID, -1),
557                                                                                  true);
558                         function->tg_when_varno = var->dno;
559
560                         /* Add the variable tg_level */
561                         var = plpgsql_build_variable("tg_level", 0,
562                                                                                  plpgsql_build_datatype(TEXTOID, -1),
563                                                                                  true);
564                         function->tg_level_varno = var->dno;
565
566                         /* Add the variable tg_op */
567                         var = plpgsql_build_variable("tg_op", 0,
568                                                                                  plpgsql_build_datatype(TEXTOID, -1),
569                                                                                  true);
570                         function->tg_op_varno = var->dno;
571
572                         /* Add the variable tg_relid */
573                         var = plpgsql_build_variable("tg_relid", 0,
574                                                                                  plpgsql_build_datatype(OIDOID, -1),
575                                                                                  true);
576                         function->tg_relid_varno = var->dno;
577
578                         /* Add the variable tg_relname */
579                         var = plpgsql_build_variable("tg_relname", 0,
580                                                                                  plpgsql_build_datatype(NAMEOID, -1),
581                                                                                  true);
582                         function->tg_relname_varno = var->dno;
583
584                         /* Add the variable tg_nargs */
585                         var = plpgsql_build_variable("tg_nargs", 0,
586                                                                                  plpgsql_build_datatype(INT4OID, -1),
587                                                                                  true);
588                         function->tg_nargs_varno = var->dno;
589
590                         break;
591
592                 default:
593                         elog(ERROR, "unrecognized function typecode: %u", functype);
594                         break;
595         }
596
597         /* Remember if function is STABLE/IMMUTABLE */
598         function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
599
600         /*
601          * Create the magic FOUND variable.
602          */
603         var = plpgsql_build_variable("found", 0,
604                                                                  plpgsql_build_datatype(BOOLOID, -1),
605                                                                  true);
606         function->found_varno = var->dno;
607
608         /*
609          * Forget about the above created variables
610          */
611         plpgsql_add_initdatums(NULL);
612
613         /*
614          * Now parse the function's text
615          */
616         parse_rc = plpgsql_yyparse();
617         if (parse_rc != 0)
618                 elog(ERROR, "plpgsql parser returned %d", parse_rc);
619         function->action = plpgsql_yylval.program;
620
621         plpgsql_scanner_finish();
622         pfree(proc_source);
623
624         /*
625          * If it has OUT parameters or returns VOID or returns a set, we allow
626          * control to fall off the end without an explicit RETURN statement. The
627          * easiest way to implement this is to add a RETURN statement to the end
628          * of the statement list during parsing.  However, if the outer block has
629          * an EXCEPTION clause, we need to make a new outer block, since the added
630          * RETURN shouldn't act like it is inside the EXCEPTION clause.
631          */
632         if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
633                 function->fn_retset)
634         {
635                 if (function->action->exceptions != NULL)
636                 {
637                         PLpgSQL_stmt_block *new;
638
639                         new = palloc0(sizeof(PLpgSQL_stmt_block));
640                         new->cmd_type = PLPGSQL_STMT_BLOCK;
641                         new->body = list_make1(function->action);
642
643                         function->action = new;
644                 }
645                 if (function->action->body == NIL ||
646                         ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
647                 {
648                         PLpgSQL_stmt_return *new;
649
650                         new = palloc0(sizeof(PLpgSQL_stmt_return));
651                         new->cmd_type = PLPGSQL_STMT_RETURN;
652                         new->expr = NULL;
653                         new->retvarno = function->out_param_varno;
654
655                         function->action->body = lappend(function->action->body, new);
656                 }
657         }
658
659         /*
660          * Complete the function's info
661          */
662         function->fn_nargs = procStruct->pronargs;
663         for (i = 0; i < function->fn_nargs; i++)
664                 function->fn_argvarnos[i] = in_arg_varnos[i];
665         function->ndatums = plpgsql_nDatums;
666         function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
667         for (i = 0; i < plpgsql_nDatums; i++)
668                 function->datums[i] = plpgsql_Datums[i];
669
670         /* Debug dump for completed functions */
671         if (plpgsql_DumpExecTree)
672                 plpgsql_dumptree(function);
673
674         /*
675          * add it to the hash table
676          */
677         plpgsql_HashTableInsert(function, hashkey);
678
679         /*
680          * Pop the error context stack
681          */
682         error_context_stack = plerrcontext.previous;
683         plpgsql_error_funcname = NULL;
684         plpgsql_error_lineno = 0;
685
686         plpgsql_check_syntax = false;
687
688         MemoryContextSwitchTo(compile_tmp_cxt);
689         compile_tmp_cxt = NULL;
690         return function;
691 }
692
693
694 /*
695  * error context callback to let us supply a call-stack traceback. If
696  * we are validating, the function source is passed as an
697  * argument. This function is public only for the sake of an assertion
698  * in gram.y
699  */
700 void
701 plpgsql_compile_error_callback(void *arg)
702 {
703         if (arg)
704         {
705                 /*
706                  * Try to convert syntax error position to reference text of original
707                  * CREATE FUNCTION command.
708                  */
709                 if (function_parse_error_transpose((const char *) arg))
710                         return;
711
712                 /*
713                  * Done if a syntax error position was reported; otherwise we have to
714                  * fall back to a "near line N" report.
715                  */
716         }
717
718         if (plpgsql_error_funcname)
719                 errcontext("compile of PL/pgSQL function \"%s\" near line %d",
720                                    plpgsql_error_funcname, plpgsql_error_lineno);
721 }
722
723
724 /* ----------
725  * plpgsql_parse_word           The scanner calls this to postparse
726  *                              any single word not found by a
727  *                              keyword rule.
728  * ----------
729  */
730 int
731 plpgsql_parse_word(char *word)
732 {
733         PLpgSQL_nsitem *nse;
734         char       *cp[1];
735
736         /* Do case conversion and word separation */
737         plpgsql_convert_ident(word, cp, 1);
738
739         /*
740          * Recognize tg_argv when compiling triggers
741          */
742         if (plpgsql_curr_compile->fn_functype == T_TRIGGER)
743         {
744                 if (strcmp(cp[0], "tg_argv") == 0)
745                 {
746                         bool            save_spacescanned = plpgsql_SpaceScanned;
747                         PLpgSQL_trigarg *trigarg;
748
749                         trigarg = palloc0(sizeof(PLpgSQL_trigarg));
750                         trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
751
752                         if (plpgsql_yylex() != '[')
753                                 plpgsql_yyerror("expected \"[\"");
754
755                         trigarg->argnum = plpgsql_read_expression(']', "]");
756
757                         plpgsql_adddatum((PLpgSQL_datum *) trigarg);
758                         plpgsql_yylval.scalar = (PLpgSQL_datum *) trigarg;
759
760                         plpgsql_SpaceScanned = save_spacescanned;
761                         pfree(cp[0]);
762                         return T_SCALAR;
763                 }
764         }
765
766         /*
767          * Do a lookup on the compiler's namestack
768          */
769         nse = plpgsql_ns_lookup(cp[0], NULL);
770         if (nse != NULL)
771         {
772                 pfree(cp[0]);
773                 switch (nse->itemtype)
774                 {
775                         case PLPGSQL_NSTYPE_LABEL:
776                                 return T_LABEL;
777
778                         case PLPGSQL_NSTYPE_VAR:
779                                 plpgsql_yylval.scalar = plpgsql_Datums[nse->itemno];
780                                 return T_SCALAR;
781
782                         case PLPGSQL_NSTYPE_REC:
783                                 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]);
784                                 return T_RECORD;
785
786                         case PLPGSQL_NSTYPE_ROW:
787                                 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[nse->itemno]);
788                                 return T_ROW;
789
790                         default:
791                                 return T_ERROR;
792                 }
793         }
794
795         /*
796          * Nothing found - up to now it's a word without any special meaning for
797          * us.
798          */
799         pfree(cp[0]);
800         return T_WORD;
801 }
802
803
804 /* ----------
805  * plpgsql_parse_dblword                Same lookup for two words
806  *                                      separated by a dot.
807  * ----------
808  */
809 int
810 plpgsql_parse_dblword(char *word)
811 {
812         PLpgSQL_nsitem *ns;
813         char       *cp[2];
814
815         /* Do case conversion and word separation */
816         plpgsql_convert_ident(word, cp, 2);
817
818         /*
819          * Lookup the first word
820          */
821         ns = plpgsql_ns_lookup(cp[0], NULL);
822         if (ns == NULL)
823         {
824                 pfree(cp[0]);
825                 pfree(cp[1]);
826                 return T_ERROR;
827         }
828
829         switch (ns->itemtype)
830         {
831                 case PLPGSQL_NSTYPE_LABEL:
832
833                         /*
834                          * First word is a label, so second word could be a variable,
835                          * record or row in that bodies namestack. Anything else could
836                          * only be something in a query given to the SPI manager and
837                          * T_ERROR will get eaten up by the collector routines.
838                          */
839                         ns = plpgsql_ns_lookup(cp[1], cp[0]);
840                         pfree(cp[0]);
841                         pfree(cp[1]);
842                         if (ns == NULL)
843                                 return T_ERROR;
844                         switch (ns->itemtype)
845                         {
846                                 case PLPGSQL_NSTYPE_VAR:
847                                         plpgsql_yylval.scalar = plpgsql_Datums[ns->itemno];
848                                         return T_SCALAR;
849
850                                 case PLPGSQL_NSTYPE_REC:
851                                         plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
852                                         return T_RECORD;
853
854                                 case PLPGSQL_NSTYPE_ROW:
855                                         plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
856                                         return T_ROW;
857
858                                 default:
859                                         return T_ERROR;
860                         }
861                         break;
862
863                 case PLPGSQL_NSTYPE_REC:
864                         {
865                                 /*
866                                  * First word is a record name, so second word must be a field
867                                  * in this record.
868                                  */
869                                 PLpgSQL_recfield *new;
870
871                                 new = palloc(sizeof(PLpgSQL_recfield));
872                                 new->dtype = PLPGSQL_DTYPE_RECFIELD;
873                                 new->fieldname = pstrdup(cp[1]);
874                                 new->recparentno = ns->itemno;
875
876                                 plpgsql_adddatum((PLpgSQL_datum *) new);
877
878                                 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
879
880                                 pfree(cp[0]);
881                                 pfree(cp[1]);
882                                 return T_SCALAR;
883                         }
884
885                 case PLPGSQL_NSTYPE_ROW:
886                         {
887                                 /*
888                                  * First word is a row name, so second word must be a field in
889                                  * this row.
890                                  */
891                                 PLpgSQL_row *row;
892                                 int                     i;
893
894                                 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
895                                 for (i = 0; i < row->nfields; i++)
896                                 {
897                                         if (row->fieldnames[i] &&
898                                                 strcmp(row->fieldnames[i], cp[1]) == 0)
899                                         {
900                                                 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
901                                                 pfree(cp[0]);
902                                                 pfree(cp[1]);
903                                                 return T_SCALAR;
904                                         }
905                                 }
906                                 ereport(ERROR,
907                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
908                                                  errmsg("row \"%s\" has no field \"%s\"",
909                                                                 cp[0], cp[1])));
910                         }
911
912                 default:
913                         break;
914         }
915
916         pfree(cp[0]);
917         pfree(cp[1]);
918         return T_ERROR;
919 }
920
921
922 /* ----------
923  * plpgsql_parse_tripword               Same lookup for three words
924  *                                      separated by dots.
925  * ----------
926  */
927 int
928 plpgsql_parse_tripword(char *word)
929 {
930         PLpgSQL_nsitem *ns;
931         char       *cp[3];
932
933         /* Do case conversion and word separation */
934         plpgsql_convert_ident(word, cp, 3);
935
936         /*
937          * Lookup the first word - it must be a label
938          */
939         ns = plpgsql_ns_lookup(cp[0], NULL);
940         if (ns == NULL)
941         {
942                 pfree(cp[0]);
943                 pfree(cp[1]);
944                 pfree(cp[2]);
945                 return T_ERROR;
946         }
947         if (ns->itemtype != PLPGSQL_NSTYPE_LABEL)
948         {
949                 pfree(cp[0]);
950                 pfree(cp[1]);
951                 pfree(cp[2]);
952                 return T_ERROR;
953         }
954
955         /*
956          * First word is a label, so second word could be a record or row
957          */
958         ns = plpgsql_ns_lookup(cp[1], cp[0]);
959         if (ns == NULL)
960         {
961                 pfree(cp[0]);
962                 pfree(cp[1]);
963                 pfree(cp[2]);
964                 return T_ERROR;
965         }
966
967         switch (ns->itemtype)
968         {
969                 case PLPGSQL_NSTYPE_REC:
970                         {
971                                 /*
972                                  * This word is a record name, so third word must be a field
973                                  * in this record.
974                                  */
975                                 PLpgSQL_recfield *new;
976
977                                 new = palloc(sizeof(PLpgSQL_recfield));
978                                 new->dtype = PLPGSQL_DTYPE_RECFIELD;
979                                 new->fieldname = pstrdup(cp[2]);
980                                 new->recparentno = ns->itemno;
981
982                                 plpgsql_adddatum((PLpgSQL_datum *) new);
983
984                                 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
985
986                                 pfree(cp[0]);
987                                 pfree(cp[1]);
988                                 pfree(cp[2]);
989
990                                 return T_SCALAR;
991                         }
992
993                 case PLPGSQL_NSTYPE_ROW:
994                         {
995                                 /*
996                                  * This word is a row name, so third word must be a field in
997                                  * this row.
998                                  */
999                                 PLpgSQL_row *row;
1000                                 int                     i;
1001
1002                                 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1003                                 for (i = 0; i < row->nfields; i++)
1004                                 {
1005                                         if (row->fieldnames[i] &&
1006                                                 strcmp(row->fieldnames[i], cp[2]) == 0)
1007                                         {
1008                                                 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
1009
1010                                                 pfree(cp[0]);
1011                                                 pfree(cp[1]);
1012                                                 pfree(cp[2]);
1013
1014                                                 return T_SCALAR;
1015                                         }
1016                                 }
1017                                 ereport(ERROR,
1018                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
1019                                                  errmsg("row \"%s.%s\" has no field \"%s\"",
1020                                                                 cp[0], cp[1], cp[2])));
1021                         }
1022
1023                 default:
1024                         break;
1025         }
1026
1027         pfree(cp[0]);
1028         pfree(cp[1]);
1029         pfree(cp[2]);
1030         return T_ERROR;
1031 }
1032
1033
1034 /* ----------
1035  * plpgsql_parse_wordtype       The scanner found word%TYPE. word can be
1036  *                              a variable name or a basetype.
1037  * ----------
1038  */
1039 int
1040 plpgsql_parse_wordtype(char *word)
1041 {
1042         PLpgSQL_nsitem *nse;
1043         bool            old_nsstate;
1044         Oid                     typeOid;
1045         char       *cp[2];
1046         int                     i;
1047
1048         /* Do case conversion and word separation */
1049         /* We convert %type to .type momentarily to keep converter happy */
1050         i = strlen(word) - 5;
1051         Assert(word[i] == '%');
1052         word[i] = '.';
1053         plpgsql_convert_ident(word, cp, 2);
1054         word[i] = '%';
1055         pfree(cp[1]);
1056
1057         /*
1058          * Do a lookup on the compiler's namestack. But ensure it moves up to the
1059          * toplevel.
1060          */
1061         old_nsstate = plpgsql_ns_setlocal(false);
1062         nse = plpgsql_ns_lookup(cp[0], NULL);
1063         plpgsql_ns_setlocal(old_nsstate);
1064
1065         if (nse != NULL)
1066         {
1067                 pfree(cp[0]);
1068                 switch (nse->itemtype)
1069                 {
1070                         case PLPGSQL_NSTYPE_VAR:
1071                                 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1072                                 return T_DTYPE;
1073
1074                                 /* XXX perhaps allow REC here? */
1075
1076                         default:
1077                                 return T_ERROR;
1078                 }
1079         }
1080
1081         /*
1082          * Word wasn't found on the namestack. Try to find a data type with that
1083          * name, but ignore pg_type entries that are in fact class types.
1084          */
1085         typeOid = LookupTypeName(NULL, makeTypeName(cp[0]));
1086         if (OidIsValid(typeOid))
1087         {
1088                 HeapTuple       typeTup;
1089
1090                 typeTup = SearchSysCache(TYPEOID,
1091                                                                  ObjectIdGetDatum(typeOid),
1092                                                                  0, 0, 0);
1093                 if (HeapTupleIsValid(typeTup))
1094                 {
1095                         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1096
1097                         if (!typeStruct->typisdefined ||
1098                                 typeStruct->typrelid != InvalidOid)
1099                         {
1100                                 ReleaseSysCache(typeTup);
1101                                 pfree(cp[0]);
1102                                 return T_ERROR;
1103                         }
1104
1105                         plpgsql_yylval.dtype = build_datatype(typeTup, -1);
1106
1107                         ReleaseSysCache(typeTup);
1108                         pfree(cp[0]);
1109                         return T_DTYPE;
1110                 }
1111         }
1112
1113         /*
1114          * Nothing found - up to now it's a word without any special meaning for
1115          * us.
1116          */
1117         pfree(cp[0]);
1118         return T_ERROR;
1119 }
1120
1121
1122 /* ----------
1123  * plpgsql_parse_dblwordtype            Same lookup for word.word%TYPE
1124  * ----------
1125  */
1126 int
1127 plpgsql_parse_dblwordtype(char *word)
1128 {
1129         PLpgSQL_nsitem *nse;
1130         bool            old_nsstate;
1131         Oid                     classOid;
1132         HeapTuple       classtup = NULL;
1133         HeapTuple       attrtup = NULL;
1134         HeapTuple       typetup = NULL;
1135         Form_pg_class classStruct;
1136         Form_pg_attribute attrStruct;
1137         char       *cp[3];
1138         int                     i;
1139         MemoryContext oldCxt;
1140         int                     result = T_ERROR;
1141
1142         /* Avoid memory leaks in the long-term function context */
1143         oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1144
1145         /* Do case conversion and word separation */
1146         /* We convert %type to .type momentarily to keep converter happy */
1147         i = strlen(word) - 5;
1148         Assert(word[i] == '%');
1149         word[i] = '.';
1150         plpgsql_convert_ident(word, cp, 3);
1151         word[i] = '%';
1152
1153         /*
1154          * Lookup the first word
1155          */
1156         nse = plpgsql_ns_lookup(cp[0], NULL);
1157
1158         /*
1159          * If this is a label lookup the second word in that label's namestack
1160          * level
1161          */
1162         if (nse != NULL)
1163         {
1164                 if (nse->itemtype == PLPGSQL_NSTYPE_LABEL)
1165                 {
1166                         old_nsstate = plpgsql_ns_setlocal(false);
1167                         nse = plpgsql_ns_lookup(cp[1], cp[0]);
1168                         plpgsql_ns_setlocal(old_nsstate);
1169
1170                         if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1171                         {
1172                                 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1173                                 result = T_DTYPE;
1174                         }
1175                 }
1176
1177                 /* Return T_ERROR if not found, otherwise T_DTYPE */
1178                 goto done;
1179         }
1180
1181         /*
1182          * First word could also be a table name
1183          */
1184         classOid = RelnameGetRelid(cp[0]);
1185         if (!OidIsValid(classOid))
1186                 goto done;
1187
1188         classtup = SearchSysCache(RELOID,
1189                                                           ObjectIdGetDatum(classOid),
1190                                                           0, 0, 0);
1191         if (!HeapTupleIsValid(classtup))
1192                 goto done;
1193         classStruct = (Form_pg_class) GETSTRUCT(classtup);
1194
1195         /*
1196          * It must be a relation, sequence, view, or type
1197          */
1198         if (classStruct->relkind != RELKIND_RELATION &&
1199                 classStruct->relkind != RELKIND_SEQUENCE &&
1200                 classStruct->relkind != RELKIND_VIEW &&
1201                 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1202                 goto done;
1203
1204         /*
1205          * Fetch the named table field and its type
1206          */
1207         attrtup = SearchSysCacheAttName(classOid, cp[1]);
1208         if (!HeapTupleIsValid(attrtup))
1209                 goto done;
1210         attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1211
1212         typetup = SearchSysCache(TYPEOID,
1213                                                          ObjectIdGetDatum(attrStruct->atttypid),
1214                                                          0, 0, 0);
1215         if (!HeapTupleIsValid(typetup))
1216                 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1217
1218         /*
1219          * Found that - build a compiler type struct in the caller's cxt and
1220          * return it
1221          */
1222         MemoryContextSwitchTo(oldCxt);
1223         plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1224         MemoryContextSwitchTo(compile_tmp_cxt);
1225         result = T_DTYPE;
1226
1227 done:
1228         if (HeapTupleIsValid(classtup))
1229                 ReleaseSysCache(classtup);
1230         if (HeapTupleIsValid(attrtup))
1231                 ReleaseSysCache(attrtup);
1232         if (HeapTupleIsValid(typetup))
1233                 ReleaseSysCache(typetup);
1234
1235         MemoryContextSwitchTo(oldCxt);
1236         return result;
1237 }
1238
1239 /* ----------
1240  * plpgsql_parse_tripwordtype           Same lookup for word.word.word%TYPE
1241  * ----------
1242  */
1243 #define TYPE_JUNK_LEN   5
1244
1245 int
1246 plpgsql_parse_tripwordtype(char *word)
1247 {
1248         Oid                     classOid;
1249         HeapTuple       classtup = NULL;
1250         HeapTuple       attrtup = NULL;
1251         HeapTuple       typetup = NULL;
1252         Form_pg_class classStruct;
1253         Form_pg_attribute attrStruct;
1254         char       *cp[2];
1255         char       *colname[1];
1256         int                     qualified_att_len;
1257         int                     numdots = 0;
1258         int                     i;
1259         RangeVar   *relvar;
1260         MemoryContext oldCxt;
1261         int                     result = T_ERROR;
1262
1263         /* Avoid memory leaks in the long-term function context */
1264         oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1265
1266         /* Do case conversion and word separation */
1267         qualified_att_len = strlen(word) - TYPE_JUNK_LEN;
1268         Assert(word[qualified_att_len] == '%');
1269
1270         for (i = 0; i < qualified_att_len; i++)
1271         {
1272                 if (word[i] == '.' && ++numdots == 2)
1273                         break;
1274         }
1275
1276         cp[0] = (char *) palloc((i + 1) * sizeof(char));
1277         memcpy(cp[0], word, i * sizeof(char));
1278         cp[0][i] = '\0';
1279
1280         /*
1281          * qualified_att_len - one based position + 1 (null terminator)
1282          */
1283         cp[1] = (char *) palloc((qualified_att_len - i) * sizeof(char));
1284         memcpy(cp[1], &word[i + 1], (qualified_att_len - i - 1) * sizeof(char));
1285         cp[1][qualified_att_len - i - 1] = '\0';
1286
1287         relvar = makeRangeVarFromNameList(stringToQualifiedNameList(cp[0],
1288                                                                                           "plpgsql_parse_tripwordtype"));
1289         classOid = RangeVarGetRelid(relvar, true);
1290         if (!OidIsValid(classOid))
1291                 goto done;
1292
1293         classtup = SearchSysCache(RELOID,
1294                                                           ObjectIdGetDatum(classOid),
1295                                                           0, 0, 0);
1296         if (!HeapTupleIsValid(classtup))
1297                 goto done;
1298         classStruct = (Form_pg_class) GETSTRUCT(classtup);
1299
1300         /*
1301          * It must be a relation, sequence, view, or type
1302          */
1303         if (classStruct->relkind != RELKIND_RELATION &&
1304                 classStruct->relkind != RELKIND_SEQUENCE &&
1305                 classStruct->relkind != RELKIND_VIEW &&
1306                 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1307                 goto done;
1308
1309         /*
1310          * Fetch the named table field and its type
1311          */
1312         plpgsql_convert_ident(cp[1], colname, 1);
1313         attrtup = SearchSysCacheAttName(classOid, colname[0]);
1314         if (!HeapTupleIsValid(attrtup))
1315                 goto done;
1316         attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1317
1318         typetup = SearchSysCache(TYPEOID,
1319                                                          ObjectIdGetDatum(attrStruct->atttypid),
1320                                                          0, 0, 0);
1321         if (!HeapTupleIsValid(typetup))
1322                 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1323
1324         /*
1325          * Found that - build a compiler type struct in the caller's cxt and
1326          * return it
1327          */
1328         MemoryContextSwitchTo(oldCxt);
1329         plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1330         MemoryContextSwitchTo(compile_tmp_cxt);
1331         result = T_DTYPE;
1332
1333 done:
1334         if (HeapTupleIsValid(classtup))
1335                 ReleaseSysCache(classtup);
1336         if (HeapTupleIsValid(attrtup))
1337                 ReleaseSysCache(attrtup);
1338         if (HeapTupleIsValid(typetup))
1339                 ReleaseSysCache(typetup);
1340
1341         MemoryContextSwitchTo(oldCxt);
1342         return result;
1343 }
1344
1345 /* ----------
1346  * plpgsql_parse_wordrowtype            Scanner found word%ROWTYPE.
1347  *                                      So word must be a table name.
1348  * ----------
1349  */
1350 int
1351 plpgsql_parse_wordrowtype(char *word)
1352 {
1353         Oid                     classOid;
1354         char       *cp[2];
1355         int                     i;
1356
1357         /* Do case conversion and word separation */
1358         /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1359         i = strlen(word) - 8;
1360         Assert(word[i] == '%');
1361         word[i] = '.';
1362         plpgsql_convert_ident(word, cp, 2);
1363         word[i] = '%';
1364
1365         /* Lookup the relation */
1366         classOid = RelnameGetRelid(cp[0]);
1367         if (!OidIsValid(classOid))
1368                 ereport(ERROR,
1369                                 (errcode(ERRCODE_UNDEFINED_TABLE),
1370                                  errmsg("relation \"%s\" does not exist", cp[0])));
1371
1372         /*
1373          * Build and return the row type struct
1374          */
1375         plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1376                                                                                                   -1);
1377
1378         pfree(cp[0]);
1379         pfree(cp[1]);
1380
1381         return T_DTYPE;
1382 }
1383
1384 /* ----------
1385  * plpgsql_parse_dblwordrowtype         Scanner found word.word%ROWTYPE.
1386  *                      So word must be a namespace qualified table name.
1387  * ----------
1388  */
1389 #define ROWTYPE_JUNK_LEN        8
1390
1391 int
1392 plpgsql_parse_dblwordrowtype(char *word)
1393 {
1394         Oid                     classOid;
1395         char       *cp;
1396         int                     i;
1397         RangeVar   *relvar;
1398         MemoryContext oldCxt;
1399
1400         /* Avoid memory leaks in long-term function context */
1401         oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1402
1403         /* Do case conversion and word separation */
1404         /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1405         i = strlen(word) - ROWTYPE_JUNK_LEN;
1406         Assert(word[i] == '%');
1407         word[i] = '\0';
1408         cp = pstrdup(word);
1409         word[i] = '%';
1410
1411         /* Lookup the relation */
1412         relvar = makeRangeVarFromNameList(stringToQualifiedNameList(cp, "plpgsql_parse_dblwordrowtype"));
1413         classOid = RangeVarGetRelid(relvar, true);
1414         if (!OidIsValid(classOid))
1415                 ereport(ERROR,
1416                                 (errcode(ERRCODE_UNDEFINED_TABLE),
1417                                  errmsg("relation \"%s\" does not exist", cp)));
1418
1419         /* Build and return the row type struct */
1420         plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1421                                                                                                   -1);
1422
1423         MemoryContextSwitchTo(oldCxt);
1424         return T_DTYPE;
1425 }
1426
1427 /*
1428  * plpgsql_build_variable - build a datum-array entry of a given
1429  * datatype
1430  *
1431  * The returned struct may be a PLpgSQL_var, PLpgSQL_row, or
1432  * PLpgSQL_rec depending on the given datatype, and is allocated via
1433  * palloc.      The struct is automatically added to the current datum
1434  * array, and optionally to the current namespace.
1435  */
1436 PLpgSQL_variable *
1437 plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype,
1438                                            bool add2namespace)
1439 {
1440         PLpgSQL_variable *result;
1441
1442         switch (dtype->ttype)
1443         {
1444                 case PLPGSQL_TTYPE_SCALAR:
1445                         {
1446                                 /* Ordinary scalar datatype */
1447                                 PLpgSQL_var *var;
1448
1449                                 var = palloc0(sizeof(PLpgSQL_var));
1450                                 var->dtype = PLPGSQL_DTYPE_VAR;
1451                                 var->refname = pstrdup(refname);
1452                                 var->lineno = lineno;
1453                                 var->datatype = dtype;
1454                                 /* other fields might be filled by caller */
1455
1456                                 /* preset to NULL */
1457                                 var->value = 0;
1458                                 var->isnull = true;
1459                                 var->freeval = false;
1460
1461                                 plpgsql_adddatum((PLpgSQL_datum *) var);
1462                                 if (add2namespace)
1463                                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
1464                                                                            var->varno,
1465                                                                            refname);
1466                                 result = (PLpgSQL_variable *) var;
1467                                 break;
1468                         }
1469                 case PLPGSQL_TTYPE_ROW:
1470                         {
1471                                 /* Composite type -- build a row variable */
1472                                 PLpgSQL_row *row;
1473
1474                                 row = build_row_from_class(dtype->typrelid);
1475
1476                                 row->dtype = PLPGSQL_DTYPE_ROW;
1477                                 row->refname = pstrdup(refname);
1478                                 row->lineno = lineno;
1479
1480                                 plpgsql_adddatum((PLpgSQL_datum *) row);
1481                                 if (add2namespace)
1482                                         plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
1483                                                                            row->rowno,
1484                                                                            refname);
1485                                 result = (PLpgSQL_variable *) row;
1486                                 break;
1487                         }
1488                 case PLPGSQL_TTYPE_REC:
1489                         {
1490                                 /*
1491                                  * "record" type -- build a variable-contents record variable
1492                                  */
1493                                 PLpgSQL_rec *rec;
1494
1495                                 rec = palloc0(sizeof(PLpgSQL_rec));
1496                                 rec->dtype = PLPGSQL_DTYPE_REC;
1497                                 rec->refname = pstrdup(refname);
1498                                 rec->lineno = lineno;
1499
1500                                 plpgsql_adddatum((PLpgSQL_datum *) rec);
1501                                 if (add2namespace)
1502                                         plpgsql_ns_additem(PLPGSQL_NSTYPE_REC,
1503                                                                            rec->recno,
1504                                                                            refname);
1505                                 result = (PLpgSQL_variable *) rec;
1506                                 break;
1507                         }
1508                 case PLPGSQL_TTYPE_PSEUDO:
1509                         ereport(ERROR,
1510                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1511                                          errmsg("variable \"%s\" has pseudo-type %s",
1512                                                         refname, format_type_be(dtype->typoid))));
1513                         result = NULL;          /* keep compiler quiet */
1514                         break;
1515                 default:
1516                         elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1517                         result = NULL;          /* keep compiler quiet */
1518                         break;
1519         }
1520
1521         return result;
1522 }
1523
1524 /*
1525  * Build a row-variable data structure given the pg_class OID.
1526  */
1527 static PLpgSQL_row *
1528 build_row_from_class(Oid classOid)
1529 {
1530         PLpgSQL_row *row;
1531         Relation        rel;
1532         Form_pg_class classStruct;
1533         const char *relname;
1534         int                     i;
1535
1536         /*
1537          * Open the relation to get info.
1538          */
1539         rel = relation_open(classOid, AccessShareLock);
1540         classStruct = RelationGetForm(rel);
1541         relname = RelationGetRelationName(rel);
1542
1543         /* accept relation, sequence, view, or composite type entries */
1544         if (classStruct->relkind != RELKIND_RELATION &&
1545                 classStruct->relkind != RELKIND_SEQUENCE &&
1546                 classStruct->relkind != RELKIND_VIEW &&
1547                 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1548                 ereport(ERROR,
1549                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1550                                  errmsg("relation \"%s\" is not a table", relname)));
1551
1552         /*
1553          * Create a row datum entry and all the required variables that it will
1554          * point to.
1555          */
1556         row = palloc0(sizeof(PLpgSQL_row));
1557         row->dtype = PLPGSQL_DTYPE_ROW;
1558         row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
1559         row->nfields = classStruct->relnatts;
1560         row->fieldnames = palloc(sizeof(char *) * row->nfields);
1561         row->varnos = palloc(sizeof(int) * row->nfields);
1562
1563         for (i = 0; i < row->nfields; i++)
1564         {
1565                 Form_pg_attribute attrStruct;
1566
1567                 /*
1568                  * Get the attribute and check for dropped column
1569                  */
1570                 attrStruct = row->rowtupdesc->attrs[i];
1571
1572                 if (!attrStruct->attisdropped)
1573                 {
1574                         char       *attname;
1575                         char            refname[(NAMEDATALEN * 2) + 100];
1576                         PLpgSQL_variable *var;
1577
1578                         attname = NameStr(attrStruct->attname);
1579                         snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
1580
1581                         /*
1582                          * Create the internal variable for the field
1583                          *
1584                          * We know if the table definitions contain a default value or if
1585                          * the field is declared in the table as NOT NULL. But it's
1586                          * possible to create a table field as NOT NULL without a default
1587                          * value and that would lead to problems later when initializing
1588                          * the variables due to entering a block at execution time. Thus
1589                          * we ignore this information for now.
1590                          */
1591                         var = plpgsql_build_variable(refname, 0,
1592                                                                  plpgsql_build_datatype(attrStruct->atttypid,
1593                                                                                                           attrStruct->atttypmod),
1594                                                                                  false);
1595
1596                         /* Add the variable to the row */
1597                         row->fieldnames[i] = attname;
1598                         row->varnos[i] = var->dno;
1599                 }
1600                 else
1601                 {
1602                         /* Leave a hole in the row structure for the dropped col */
1603                         row->fieldnames[i] = NULL;
1604                         row->varnos[i] = -1;
1605                 }
1606         }
1607
1608         relation_close(rel, AccessShareLock);
1609
1610         return row;
1611 }
1612
1613 /*
1614  * Build a row-variable data structure given the component variables.
1615  */
1616 static PLpgSQL_row *
1617 build_row_from_vars(PLpgSQL_variable **vars, int numvars)
1618 {
1619         PLpgSQL_row *row;
1620         int                     i;
1621
1622         row = palloc0(sizeof(PLpgSQL_row));
1623         row->dtype = PLPGSQL_DTYPE_ROW;
1624         row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
1625         row->nfields = numvars;
1626         row->fieldnames = palloc(numvars * sizeof(char *));
1627         row->varnos = palloc(numvars * sizeof(int));
1628
1629         for (i = 0; i < numvars; i++)
1630         {
1631                 PLpgSQL_variable *var = vars[i];
1632                 Oid                     typoid = RECORDOID;
1633                 int32           typmod = -1;
1634
1635                 switch (var->dtype)
1636                 {
1637                         case PLPGSQL_DTYPE_VAR:
1638                                 typoid = ((PLpgSQL_var *) var)->datatype->typoid;
1639                                 typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
1640                                 break;
1641
1642                         case PLPGSQL_DTYPE_REC:
1643                                 break;
1644
1645                         case PLPGSQL_DTYPE_ROW:
1646                                 if (((PLpgSQL_row *) var)->rowtupdesc)
1647                                 {
1648                                         typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
1649                                         typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
1650                                 }
1651                                 break;
1652
1653                         default:
1654                                 elog(ERROR, "unrecognized dtype: %d", var->dtype);
1655                 }
1656
1657                 row->fieldnames[i] = var->refname;
1658                 row->varnos[i] = var->dno;
1659
1660                 TupleDescInitEntry(row->rowtupdesc, i + 1,
1661                                                    var->refname,
1662                                                    typoid, typmod,
1663                                                    0);
1664         }
1665
1666         return row;
1667 }
1668
1669
1670 /* ----------
1671  * plpgsql_parse_datatype                       Scanner found something that should
1672  *                                      be a datatype name.
1673  * ----------
1674  */
1675 PLpgSQL_type *
1676 plpgsql_parse_datatype(const char *string)
1677 {
1678         Oid                     type_id;
1679         int32           typmod;
1680
1681         /* Let the main parser try to parse it under standard SQL rules */
1682         parseTypeString(string, &type_id, &typmod);
1683
1684         /* Okay, build a PLpgSQL_type data structure for it */
1685         return plpgsql_build_datatype(type_id, typmod);
1686 }
1687
1688 /*
1689  * plpgsql_build_datatype
1690  *              Build PLpgSQL_type struct given type OID and typmod.
1691  */
1692 PLpgSQL_type *
1693 plpgsql_build_datatype(Oid typeOid, int32 typmod)
1694 {
1695         HeapTuple       typeTup;
1696         PLpgSQL_type *typ;
1697
1698         typeTup = SearchSysCache(TYPEOID,
1699                                                          ObjectIdGetDatum(typeOid),
1700                                                          0, 0, 0);
1701         if (!HeapTupleIsValid(typeTup))
1702                 elog(ERROR, "cache lookup failed for type %u", typeOid);
1703
1704         typ = build_datatype(typeTup, typmod);
1705
1706         ReleaseSysCache(typeTup);
1707
1708         return typ;
1709 }
1710
1711 /*
1712  * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1713  */
1714 static PLpgSQL_type *
1715 build_datatype(HeapTuple typeTup, int32 typmod)
1716 {
1717         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1718         PLpgSQL_type *typ;
1719
1720         if (!typeStruct->typisdefined)
1721                 ereport(ERROR,
1722                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
1723                                  errmsg("type \"%s\" is only a shell",
1724                                                 NameStr(typeStruct->typname))));
1725
1726         typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
1727
1728         typ->typname = pstrdup(NameStr(typeStruct->typname));
1729         typ->typoid = HeapTupleGetOid(typeTup);
1730         switch (typeStruct->typtype)
1731         {
1732                 case 'b':                               /* base type */
1733                 case 'd':                               /* domain */
1734                         typ->ttype = PLPGSQL_TTYPE_SCALAR;
1735                         break;
1736                 case 'c':                               /* composite, ie, rowtype */
1737                         Assert(OidIsValid(typeStruct->typrelid));
1738                         typ->ttype = PLPGSQL_TTYPE_ROW;
1739                         break;
1740                 case 'p':                               /* pseudo */
1741                         if (typ->typoid == RECORDOID)
1742                                 typ->ttype = PLPGSQL_TTYPE_REC;
1743                         else
1744                                 typ->ttype = PLPGSQL_TTYPE_PSEUDO;
1745                         break;
1746                 default:
1747                         elog(ERROR, "unrecognized typtype: %d",
1748                                  (int) typeStruct->typtype);
1749                         break;
1750         }
1751         typ->typlen = typeStruct->typlen;
1752         typ->typbyval = typeStruct->typbyval;
1753         typ->typrelid = typeStruct->typrelid;
1754         typ->typioparam = getTypeIOParam(typeTup);
1755         fmgr_info(typeStruct->typinput, &(typ->typinput));
1756         typ->atttypmod = typmod;
1757
1758         return typ;
1759 }
1760
1761 /*
1762  * plpgsql_parse_err_condition
1763  *              Generate PLpgSQL_condition entry(s) for an exception condition name
1764  *
1765  * This has to be able to return a list because there are some duplicate
1766  * names in the table of error code names.
1767  */
1768 PLpgSQL_condition *
1769 plpgsql_parse_err_condition(char *condname)
1770 {
1771         int                     i;
1772         PLpgSQL_condition *new;
1773         PLpgSQL_condition *prev;
1774
1775         /*
1776          * XXX Eventually we will want to look for user-defined exception names
1777          * here.
1778          */
1779
1780         /*
1781          * OTHERS is represented as code 0 (which would map to '00000', but we
1782          * have no need to represent that as an exception condition).
1783          */
1784         if (strcmp(condname, "others") == 0)
1785         {
1786                 new = palloc(sizeof(PLpgSQL_condition));
1787                 new->sqlerrstate = 0;
1788                 new->condname = condname;
1789                 new->next = NULL;
1790                 return new;
1791         }
1792
1793         prev = NULL;
1794         for (i = 0; exception_label_map[i].label != NULL; i++)
1795         {
1796                 if (strcmp(condname, exception_label_map[i].label) == 0)
1797                 {
1798                         new = palloc(sizeof(PLpgSQL_condition));
1799                         new->sqlerrstate = exception_label_map[i].sqlerrstate;
1800                         new->condname = condname;
1801                         new->next = prev;
1802                         prev = new;
1803                 }
1804         }
1805
1806         if (!prev)
1807                 ereport(ERROR,
1808                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
1809                                  errmsg("unrecognized exception condition \"%s\"",
1810                                                 condname)));
1811
1812         return prev;
1813 }
1814
1815 /* ----------
1816  * plpgsql_adddatum                     Add a variable, record or row
1817  *                                      to the compiler's datum list.
1818  * ----------
1819  */
1820 void
1821 plpgsql_adddatum(PLpgSQL_datum *new)
1822 {
1823         if (plpgsql_nDatums == datums_alloc)
1824         {
1825                 datums_alloc *= 2;
1826                 plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
1827         }
1828
1829         new->dno = plpgsql_nDatums;
1830         plpgsql_Datums[plpgsql_nDatums++] = new;
1831 }
1832
1833
1834 /* ----------
1835  * plpgsql_add_initdatums               Put all datum entries created
1836  *                                      since the last call into the
1837  *                                      finishing code block so the
1838  *                                      block knows which variables to
1839  *                                      reinitialize when entered.
1840  * ----------
1841  */
1842 int
1843 plpgsql_add_initdatums(int **varnos)
1844 {
1845         int                     i;
1846         int                     n = 0;
1847
1848         for (i = datums_last; i < plpgsql_nDatums; i++)
1849         {
1850                 switch (plpgsql_Datums[i]->dtype)
1851                 {
1852                         case PLPGSQL_DTYPE_VAR:
1853                                 n++;
1854                                 break;
1855
1856                         default:
1857                                 break;
1858                 }
1859         }
1860
1861         if (varnos != NULL)
1862         {
1863                 if (n > 0)
1864                 {
1865                         *varnos = (int *) palloc(sizeof(int) * n);
1866
1867                         n = 0;
1868                         for (i = datums_last; i < plpgsql_nDatums; i++)
1869                         {
1870                                 switch (plpgsql_Datums[i]->dtype)
1871                                 {
1872                                         case PLPGSQL_DTYPE_VAR:
1873                                                 (*varnos)[n++] = plpgsql_Datums[i]->dno;
1874
1875                                         default:
1876                                                 break;
1877                                 }
1878                         }
1879                 }
1880                 else
1881                         *varnos = NULL;
1882         }
1883
1884         datums_last = plpgsql_nDatums;
1885         return n;
1886 }
1887
1888
1889 /*
1890  * Compute the hashkey for a given function invocation
1891  *
1892  * The hashkey is returned into the caller-provided storage at *hashkey.
1893  */
1894 static void
1895 compute_function_hashkey(FunctionCallInfo fcinfo,
1896                                                  Form_pg_proc procStruct,
1897                                                  PLpgSQL_func_hashkey *hashkey,
1898                                                  bool forValidator)
1899 {
1900         /* Make sure any unused bytes of the struct are zero */
1901         MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
1902
1903         /* get function OID */
1904         hashkey->funcOid = fcinfo->flinfo->fn_oid;
1905
1906         /*
1907          * if trigger, get relation OID.  In validation mode we do not know what
1908          * relation is intended to be used, so we leave trigrelOid zero; the hash
1909          * entry built in this case will never really be used.
1910          */
1911         if (CALLED_AS_TRIGGER(fcinfo) && !forValidator)
1912         {
1913                 TriggerData *trigdata = (TriggerData *) fcinfo->context;
1914
1915                 hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
1916         }
1917
1918         if (procStruct->pronargs > 0)
1919         {
1920                 /* get the argument types */
1921                 memcpy(hashkey->argtypes, procStruct->proargtypes.values,
1922                            procStruct->pronargs * sizeof(Oid));
1923
1924                 /* resolve any polymorphic argument types */
1925                 plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
1926                                                                                          hashkey->argtypes,
1927                                                                                          NULL,
1928                                                                                          fcinfo->flinfo->fn_expr,
1929                                                                                          forValidator,
1930                                                                                          NameStr(procStruct->proname));
1931         }
1932 }
1933
1934 /*
1935  * This is the same as the standard resolve_polymorphic_argtypes() function,
1936  * but with a special case for validation: assume that polymorphic arguments
1937  * are integer or integer-array.  Also, we go ahead and report the error
1938  * if we can't resolve the types.
1939  */
1940 static void
1941 plpgsql_resolve_polymorphic_argtypes(int numargs,
1942                                                                          Oid *argtypes, char *argmodes,
1943                                                                          Node *call_expr, bool forValidator,
1944                                                                          const char *proname)
1945 {
1946         int                     i;
1947
1948         if (!forValidator)
1949         {
1950                 /* normal case, pass to standard routine */
1951                 if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
1952                                                                                   call_expr))
1953                         ereport(ERROR,
1954                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1955                                          errmsg("could not determine actual argument "
1956                                                         "type for polymorphic function \"%s\"",
1957                                                         proname)));
1958         }
1959         else
1960         {
1961                 /* special validation case */
1962                 for (i = 0; i < numargs; i++)
1963                 {
1964                         switch (argtypes[i])
1965                         {
1966                                 case ANYELEMENTOID:
1967                                         argtypes[i] = INT4OID;
1968                                         break;
1969                                 case ANYARRAYOID:
1970                                         argtypes[i] = INT4ARRAYOID;
1971                                         break;
1972                                 default:
1973                                         break;
1974                         }
1975                 }
1976         }
1977 }
1978
1979 static void
1980 delete_function(PLpgSQL_function *func)
1981 {
1982         /* remove function from hash table */
1983         plpgsql_HashTableDelete(func);
1984
1985         /* release the function's storage */
1986         MemoryContextDelete(func->fn_cxt);
1987
1988         /*
1989          * Caller should be sure not to use passed-in pointer, as it now points to
1990          * pfree'd storage
1991          */
1992 }
1993
1994 /* exported so we can call it from plpgsql_init() */
1995 void
1996 plpgsql_HashTableInit(void)
1997 {
1998         HASHCTL         ctl;
1999
2000         /* don't allow double-initialization */
2001         Assert(plpgsql_HashTable == NULL);
2002
2003         memset(&ctl, 0, sizeof(ctl));
2004         ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2005         ctl.entrysize = sizeof(plpgsql_HashEnt);
2006         ctl.hash = tag_hash;
2007         plpgsql_HashTable = hash_create("PLpgSQL function cache",
2008                                                                         FUNCS_PER_USER,
2009                                                                         &ctl,
2010                                                                         HASH_ELEM | HASH_FUNCTION);
2011 }
2012
2013 static PLpgSQL_function *
2014 plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
2015 {
2016         plpgsql_HashEnt *hentry;
2017
2018         hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2019                                                                                          (void *) func_key,
2020                                                                                          HASH_FIND,
2021                                                                                          NULL);
2022         if (hentry)
2023                 return hentry->function;
2024         else
2025                 return NULL;
2026 }
2027
2028 static void
2029 plpgsql_HashTableInsert(PLpgSQL_function *function,
2030                                                 PLpgSQL_func_hashkey *func_key)
2031 {
2032         plpgsql_HashEnt *hentry;
2033         bool            found;
2034
2035         hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2036                                                                                          (void *) func_key,
2037                                                                                          HASH_ENTER,
2038                                                                                          &found);
2039         if (found)
2040                 elog(WARNING, "trying to insert a function that already exists");
2041
2042         hentry->function = function;
2043         /* prepare back link from function to hashtable key */
2044         function->fn_hashkey = &hentry->key;
2045 }
2046
2047 static void
2048 plpgsql_HashTableDelete(PLpgSQL_function *function)
2049 {
2050         plpgsql_HashEnt *hentry;
2051
2052         hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2053                                                                                          (void *) function->fn_hashkey,
2054                                                                                          HASH_REMOVE,
2055                                                                                          NULL);
2056         if (hentry == NULL)
2057                 elog(WARNING, "trying to delete function that does not exist");
2058 }