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