OSDN Git Service

Fix some localizability issues with existing errcontext() calls.
[pg-rex/syncrep.git] / 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  *        $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.62 2003/07/27 18:38:26 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 #include <setjmp.h>
42
43 #include "pl.tab.h"
44
45 #include "access/heapam.h"
46 #include "catalog/catname.h"
47 #include "catalog/namespace.h"
48 #include "catalog/pg_attribute.h"
49 #include "catalog/pg_attrdef.h"
50 #include "catalog/pg_class.h"
51 #include "catalog/pg_proc.h"
52 #include "catalog/pg_type.h"
53 #include "nodes/makefuncs.h"
54 #include "parser/gramparse.h"
55 #include "parser/parse_type.h"
56 #include "tcop/tcopprot.h"
57 #include "utils/builtins.h"
58 #include "utils/syscache.h"
59
60
61 /* ----------
62  * Variables in the parser that shouldn't go into plpgsql.h
63  * ----------
64  */
65 extern PLPGSQL_YYSTYPE plpgsql_yylval;
66
67 /* ----------
68  * Our own local and global variables
69  * ----------
70  */
71 static int      datums_alloc;
72 int                     plpgsql_nDatums;
73 PLpgSQL_datum **plpgsql_Datums;
74 static int      datums_last = 0;
75
76 int                     plpgsql_error_lineno;
77 char       *plpgsql_error_funcname;
78 int                     plpgsql_DumpExecTree = 0;
79
80 PLpgSQL_function *plpgsql_curr_compile;
81
82 /* ----------
83  * Hash table for compiled functions
84  * ----------
85  */
86 static HTAB *plpgsql_HashTable = (HTAB *) NULL;
87
88 typedef struct plpgsql_hashent
89 {
90         PLpgSQL_func_hashkey key;
91         PLpgSQL_function   *function;
92 } plpgsql_HashEnt;
93
94 #define FUNCS_PER_USER          128             /* initial table size */
95
96
97 /* ----------
98  * static prototypes
99  * ----------
100  */
101 static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
102                                                                         HeapTuple procTup,
103                                                                         PLpgSQL_func_hashkey *hashkey);
104 static void plpgsql_compile_error_callback(void *arg);
105 static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
106 static void compute_function_hashkey(FmgrInfo *flinfo,
107                                                                          Form_pg_proc procStruct,
108                                                                          PLpgSQL_func_hashkey *hashkey);
109 static void plpgsql_HashTableInit(void);
110 static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
111 static void plpgsql_HashTableInsert(PLpgSQL_function *function,
112                                                                         PLpgSQL_func_hashkey *func_key);
113 static void plpgsql_HashTableDelete(PLpgSQL_function *function);
114
115 /*
116  * This routine is a crock, and so is everyplace that calls it.  The problem
117  * is that the compiled form of a plpgsql function is allocated permanently
118  * (mostly via malloc()) and never released until backend exit.  Subsidiary
119  * data structures such as fmgr info records therefore must live forever
120  * as well.  A better implementation would store all this stuff in a per-
121  * function memory context that could be reclaimed at need.  In the meantime,
122  * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
123  * it might allocate, and whatever the eventual function might allocate using
124  * fn_mcxt, will live forever too.
125  */
126 static void
127 perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
128 {
129         fmgr_info_cxt(functionId, finfo, TopMemoryContext);
130 }
131
132
133 /* ----------
134  * plpgsql_compile              Make an execution tree for a PL/pgSQL function.
135  *
136  * Note: it's important for this to fall through quickly if the function
137  * has already been compiled.
138  * ----------
139  */
140 PLpgSQL_function *
141 plpgsql_compile(FunctionCallInfo fcinfo)
142 {
143         Oid                     funcOid = fcinfo->flinfo->fn_oid;
144         HeapTuple       procTup;
145         Form_pg_proc procStruct;
146         PLpgSQL_function *function;
147         PLpgSQL_func_hashkey hashkey;
148         bool            hashkey_valid = false;
149
150         /*
151          * Lookup the pg_proc tuple by Oid; we'll need it in any case
152          */
153         procTup = SearchSysCache(PROCOID,
154                                                          ObjectIdGetDatum(funcOid),
155                                                          0, 0, 0);
156         if (!HeapTupleIsValid(procTup))
157                 elog(ERROR, "cache lookup failed for function %u", funcOid);
158         procStruct = (Form_pg_proc) GETSTRUCT(procTup);
159
160         /*
161          * See if there's already a cache entry for the current FmgrInfo.
162          * If not, try to find one in the hash table.
163          */
164         function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
165
166         if (!function)
167         {
168                 /* First time through in this backend?  If so, init hashtable */
169                 if (!plpgsql_HashTable)
170                         plpgsql_HashTableInit();
171
172                 /* Compute hashkey using function signature and actual arg types */
173                 compute_function_hashkey(fcinfo->flinfo, procStruct, &hashkey);
174                 hashkey_valid = true;
175
176                 /* And do the lookup */
177                 function = plpgsql_HashTableLookup(&hashkey);
178         }
179
180         if (function)
181         {
182                 /* We have a compiled function, but is it still valid? */
183                 if (!(function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
184                           function->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data)))
185                 {
186                         /*
187                          * Nope, drop the hashtable entry.  XXX someday, free all the
188                          * subsidiary storage as well.
189                          */
190                         plpgsql_HashTableDelete(function);
191
192                         function = NULL;
193                 }
194         }
195
196         /*
197          * If the function wasn't found or was out-of-date, we have to compile it
198          */
199         if (!function)
200         {
201                 /*
202                  * Calculate hashkey if we didn't already; we'll need it to store
203                  * the completed function.
204                  */
205                 if (!hashkey_valid)
206                         compute_function_hashkey(fcinfo->flinfo, procStruct, &hashkey);
207
208                 /*
209                  * Do the hard part.
210                  */
211                 function = do_compile(fcinfo, procTup, &hashkey);
212         }
213
214         ReleaseSysCache(procTup);
215
216         /*
217          * Save pointer in FmgrInfo to avoid search on subsequent calls
218          */
219         fcinfo->flinfo->fn_extra = (void *) function;
220
221         /*
222          * Finally return the compiled function
223          */
224         return function;
225 }
226
227 /*
228  * This is the slow part of plpgsql_compile().
229  */
230 static PLpgSQL_function *
231 do_compile(FunctionCallInfo fcinfo,
232                    HeapTuple procTup,
233                    PLpgSQL_func_hashkey *hashkey)
234 {
235         Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
236         int                     functype = CALLED_AS_TRIGGER(fcinfo) ? T_TRIGGER : T_FUNCTION;
237         PLpgSQL_function *function;
238         char       *proc_source;
239         HeapTuple       typeTup;
240         Form_pg_type typeStruct;
241         PLpgSQL_var *var;
242         PLpgSQL_row *row;
243         PLpgSQL_rec *rec;
244         int                     i;
245         int                     arg_varnos[FUNC_MAX_ARGS];
246         ErrorContextCallback plerrcontext;
247         int                     parse_rc;
248         Oid                     rettypeid;
249
250         /*
251          * Setup the scanner input and error info.  We assume that this
252          * function cannot be invoked recursively, so there's no need to save
253          * and restore the static variables used here.
254          */
255         proc_source = DatumGetCString(DirectFunctionCall1(textout,
256                                                                         PointerGetDatum(&procStruct->prosrc)));
257         plpgsql_scanner_init(proc_source, functype);
258         pfree(proc_source);
259
260         plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
261         plpgsql_error_lineno = 0;
262
263         /*
264          * Setup error traceback support for ereport()
265          */
266         plerrcontext.callback = plpgsql_compile_error_callback;
267         plerrcontext.arg = NULL;
268         plerrcontext.previous = error_context_stack;
269         error_context_stack = &plerrcontext;
270
271         /*
272          * Initialize the compiler
273          */
274         plpgsql_ns_init();
275         plpgsql_ns_push(NULL);
276         plpgsql_DumpExecTree = 0;
277
278         datums_alloc = 128;
279         plpgsql_nDatums = 0;
280         plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
281         datums_last = 0;
282
283         /*
284          * Create the new function node
285          */
286         function = malloc(sizeof(PLpgSQL_function));
287         MemSet(function, 0, sizeof(PLpgSQL_function));
288         plpgsql_curr_compile = function;
289
290         function->fn_name = strdup(NameStr(procStruct->proname));
291         function->fn_oid = fcinfo->flinfo->fn_oid;
292         function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
293         function->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
294         function->fn_functype = functype;
295
296         switch (functype)
297         {
298                 case T_FUNCTION:
299
300                         /*
301                          * Check for a polymorphic returntype. If found, use the actual
302                          * returntype type from the caller's FuncExpr node, if we
303                          * have one.
304                          *
305                          * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
306                          * work; if it doesn't we're in some context that fails to make
307                          * the info available.
308                          */
309                         rettypeid = procStruct->prorettype;
310                         if (rettypeid == ANYARRAYOID || rettypeid == ANYELEMENTOID)
311                         {
312                                 rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
313                                 if (!OidIsValid(rettypeid))
314                                         ereport(ERROR,
315                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
316                                                          errmsg("could not determine actual return type "
317                                                                         "for polymorphic function \"%s\"",
318                                                                         plpgsql_error_funcname)));
319                         }
320
321                         /*
322                          * Normal function has a defined returntype
323                          */
324                         function->fn_rettype = rettypeid;
325                         function->fn_retset = procStruct->proretset;
326
327                         /*
328                          * Lookup the functions return type
329                          */
330                         typeTup = SearchSysCache(TYPEOID,
331                                                                          ObjectIdGetDatum(rettypeid),
332                                                                          0, 0, 0);
333                         if (!HeapTupleIsValid(typeTup))
334                                 elog(ERROR, "cache lookup failed for type %u", rettypeid);
335                         typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
336
337                         /* Disallow pseudotype result, except VOID or RECORD */
338                         /* (note we already replaced ANYARRAY/ANYELEMENT) */
339                         if (typeStruct->typtype == 'p')
340                         {
341                                 if (rettypeid == VOIDOID ||
342                                         rettypeid == RECORDOID)
343                                         /* okay */ ;
344                                 else if (rettypeid == TRIGGEROID)
345                                         ereport(ERROR,
346                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
347                                                          errmsg("trigger functions may only be called as triggers")));
348                                 else
349                                         ereport(ERROR,
350                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
351                                                          errmsg("plpgsql functions cannot return type %s",
352                                                                         format_type_be(rettypeid))));
353                         }
354
355                         if (typeStruct->typrelid != InvalidOid ||
356                                 rettypeid == RECORDOID)
357                                 function->fn_retistuple = true;
358                         else
359                         {
360                                 function->fn_retbyval = typeStruct->typbyval;
361                                 function->fn_rettyplen = typeStruct->typlen;
362                                 function->fn_rettypelem = typeStruct->typelem;
363                                 perm_fmgr_info(typeStruct->typinput, &(function->fn_retinput));
364
365                                 /*
366                                  * install $0 reference, but only for polymorphic
367                                  * return types
368                                  */
369                                 if (procStruct->prorettype == ANYARRAYOID ||
370                                         procStruct->prorettype == ANYELEMENTOID)
371                                 {
372                                         char            buf[32];
373
374                                         /* name for variable */
375                                         snprintf(buf, sizeof(buf), "$%d", 0);
376
377                                         /*
378                                          * Normal return values get a var node
379                                          */
380                                         var = malloc(sizeof(PLpgSQL_var));
381                                         memset(var, 0, sizeof(PLpgSQL_var));
382
383                                         var->dtype = PLPGSQL_DTYPE_VAR;
384                                         var->refname = strdup(buf);
385                                         var->lineno = 0;
386                                         var->datatype = build_datatype(typeTup, -1);
387                                         var->isconst = false;
388                                         var->notnull = false;
389                                         var->default_val = NULL;
390
391                                         /* preset to NULL */
392                                         var->value = 0;
393                                         var->isnull = true;
394                                         var->freeval = false;
395
396                                         plpgsql_adddatum((PLpgSQL_datum *) var);
397                                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno,
398                                                                            var->refname);
399                                 }
400                         }
401                         ReleaseSysCache(typeTup);
402
403                         /*
404                          * Create the variables for the procedure's parameters
405                          */
406                         for (i = 0; i < procStruct->pronargs; i++)
407                         {
408                                 char            buf[32];
409                                 Oid                     argtypeid;
410
411                                 /* name for variable */
412                                 snprintf(buf, sizeof(buf), "$%d", i + 1);
413
414                                 /*
415                                  * Since we already did the replacement of polymorphic
416                                  * argument types by actual argument types while computing
417                                  * the hashkey, we can just use those results.
418                                  */
419                                 argtypeid = hashkey->argtypes[i];
420
421                                 /*
422                                  * Get the parameters type
423                                  */
424                                 typeTup = SearchSysCache(TYPEOID,
425                                                                                  ObjectIdGetDatum(argtypeid),
426                                                                                  0, 0, 0);
427                                 if (!HeapTupleIsValid(typeTup))
428                                         elog(ERROR, "cache lookup failed for type %u", argtypeid);
429                                 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
430
431                                 /* Disallow pseudotype argument */
432                                 /* (note we already replaced ANYARRAY/ANYELEMENT) */
433                                 if (typeStruct->typtype == 'p')
434                                         ereport(ERROR,
435                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
436                                                          errmsg("plpgsql functions cannot take type %s",
437                                                                         format_type_be(argtypeid))));
438
439                                 if (typeStruct->typrelid != InvalidOid)
440                                 {
441                                         /*
442                                          * For tuple type parameters, we set up a record of
443                                          * that type
444                                          */
445                                         row = plpgsql_build_rowtype(typeStruct->typrelid);
446
447                                         row->refname = strdup(buf);
448
449                                         plpgsql_adddatum((PLpgSQL_datum *) row);
450                                         plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, row->rowno,
451                                                                            row->refname);
452
453                                         arg_varnos[i] = row->rowno;
454                                 }
455                                 else
456                                 {
457                                         /*
458                                          * Normal parameters get a var node
459                                          */
460                                         var = malloc(sizeof(PLpgSQL_var));
461                                         memset(var, 0, sizeof(PLpgSQL_var));
462
463                                         var->dtype = PLPGSQL_DTYPE_VAR;
464                                         var->refname = strdup(buf);
465                                         var->lineno = 0;
466                                         var->datatype = build_datatype(typeTup, -1);
467                                         var->isconst = true;
468                                         var->notnull = false;
469                                         var->default_val = NULL;
470
471                                         plpgsql_adddatum((PLpgSQL_datum *) var);
472                                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno,
473                                                                            var->refname);
474
475                                         arg_varnos[i] = var->varno;
476                                 }
477                                 ReleaseSysCache(typeTup);
478                         }
479                         break;
480
481                 case T_TRIGGER:
482
483                         /*
484                          * Trigger procedures return type is unknown yet
485                          */
486                         function->fn_rettype = InvalidOid;
487                         function->fn_retbyval = false;
488                         function->fn_retistuple = true;
489                         function->fn_retset = false;
490
491                         /*
492                          * Add the record for referencing NEW
493                          */
494                         rec = malloc(sizeof(PLpgSQL_rec));
495                         memset(rec, 0, sizeof(PLpgSQL_rec));
496                         rec->dtype = PLPGSQL_DTYPE_REC;
497                         rec->refname = strdup("new");
498                         rec->tup = NULL;
499                         rec->tupdesc = NULL;
500                         rec->freetup = false;
501                         plpgsql_adddatum((PLpgSQL_datum *) rec);
502                         plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
503                         function->new_varno = rec->recno;
504
505                         /*
506                          * Add the record for referencing OLD
507                          */
508                         rec = malloc(sizeof(PLpgSQL_rec));
509                         memset(rec, 0, sizeof(PLpgSQL_rec));
510                         rec->dtype = PLPGSQL_DTYPE_REC;
511                         rec->refname = strdup("old");
512                         rec->tup = NULL;
513                         rec->tupdesc = NULL;
514                         rec->freetup = false;
515                         plpgsql_adddatum((PLpgSQL_datum *) rec);
516                         plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
517                         function->old_varno = rec->recno;
518
519                         /*
520                          * Add the variable tg_name
521                          */
522                         var = malloc(sizeof(PLpgSQL_var));
523                         memset(var, 0, sizeof(PLpgSQL_var));
524
525                         var->dtype = PLPGSQL_DTYPE_VAR;
526                         var->refname = strdup("tg_name");
527                         var->lineno = 0;
528                         var->datatype = plpgsql_parse_datatype("name");
529                         var->isconst = false;
530                         var->notnull = false;
531                         var->default_val = NULL;
532
533                         plpgsql_adddatum((PLpgSQL_datum *) var);
534                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
535                         function->tg_name_varno = var->varno;
536
537                         /*
538                          * Add the variable tg_when
539                          */
540                         var = malloc(sizeof(PLpgSQL_var));
541                         memset(var, 0, sizeof(PLpgSQL_var));
542
543                         var->dtype = PLPGSQL_DTYPE_VAR;
544                         var->refname = strdup("tg_when");
545                         var->lineno = 0;
546                         var->datatype = plpgsql_parse_datatype("text");
547                         var->isconst = false;
548                         var->notnull = false;
549                         var->default_val = NULL;
550
551                         plpgsql_adddatum((PLpgSQL_datum *) var);
552                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
553                         function->tg_when_varno = var->varno;
554
555                         /*
556                          * Add the variable tg_level
557                          */
558                         var = malloc(sizeof(PLpgSQL_var));
559                         memset(var, 0, sizeof(PLpgSQL_var));
560
561                         var->dtype = PLPGSQL_DTYPE_VAR;
562                         var->refname = strdup("tg_level");
563                         var->lineno = 0;
564                         var->datatype = plpgsql_parse_datatype("text");
565                         var->isconst = false;
566                         var->notnull = false;
567                         var->default_val = NULL;
568
569                         plpgsql_adddatum((PLpgSQL_datum *) var);
570                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
571                         function->tg_level_varno = var->varno;
572
573                         /*
574                          * Add the variable tg_op
575                          */
576                         var = malloc(sizeof(PLpgSQL_var));
577                         memset(var, 0, sizeof(PLpgSQL_var));
578
579                         var->dtype = PLPGSQL_DTYPE_VAR;
580                         var->refname = strdup("tg_op");
581                         var->lineno = 0;
582                         var->datatype = plpgsql_parse_datatype("text");
583                         var->isconst = false;
584                         var->notnull = false;
585                         var->default_val = NULL;
586
587                         plpgsql_adddatum((PLpgSQL_datum *) var);
588                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
589                         function->tg_op_varno = var->varno;
590
591                         /*
592                          * Add the variable tg_relid
593                          */
594                         var = malloc(sizeof(PLpgSQL_var));
595                         memset(var, 0, sizeof(PLpgSQL_var));
596
597                         var->dtype = PLPGSQL_DTYPE_VAR;
598                         var->refname = strdup("tg_relid");
599                         var->lineno = 0;
600                         var->datatype = plpgsql_parse_datatype("oid");
601                         var->isconst = false;
602                         var->notnull = false;
603                         var->default_val = NULL;
604
605                         plpgsql_adddatum((PLpgSQL_datum *) var);
606                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
607                         function->tg_relid_varno = var->varno;
608
609                         /*
610                          * Add the variable tg_relname
611                          */
612                         var = malloc(sizeof(PLpgSQL_var));
613                         memset(var, 0, sizeof(PLpgSQL_var));
614
615                         var->dtype = PLPGSQL_DTYPE_VAR;
616                         var->refname = strdup("tg_relname");
617                         var->lineno = 0;
618                         var->datatype = plpgsql_parse_datatype("name");
619                         var->isconst = false;
620                         var->notnull = false;
621                         var->default_val = NULL;
622
623                         plpgsql_adddatum((PLpgSQL_datum *) var);
624                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
625                         function->tg_relname_varno = var->varno;
626
627                         /*
628                          * Add the variable tg_nargs
629                          */
630                         var = malloc(sizeof(PLpgSQL_var));
631                         memset(var, 0, sizeof(PLpgSQL_var));
632
633                         var->dtype = PLPGSQL_DTYPE_VAR;
634                         var->refname = strdup("tg_nargs");
635                         var->lineno = 0;
636                         var->datatype = plpgsql_parse_datatype("int4");
637                         var->isconst = false;
638                         var->notnull = false;
639                         var->default_val = NULL;
640
641                         plpgsql_adddatum((PLpgSQL_datum *) var);
642                         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
643                         function->tg_nargs_varno = var->varno;
644
645                         break;
646
647                 default:
648                         elog(ERROR, "unrecognized function typecode: %u", functype);
649                         break;
650         }
651
652         /*
653          * Create the magic FOUND variable.
654          */
655         var = malloc(sizeof(PLpgSQL_var));
656         memset(var, 0, sizeof(PLpgSQL_var));
657
658         var->dtype = PLPGSQL_DTYPE_VAR;
659         var->refname = strdup("found");
660         var->lineno = 0;
661         var->datatype = plpgsql_parse_datatype("bool");
662         var->isconst = false;
663         var->notnull = false;
664         var->default_val = NULL;
665
666         plpgsql_adddatum((PLpgSQL_datum *) var);
667         plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
668         function->found_varno = var->varno;
669
670         /*
671          * Forget about the above created variables
672          */
673         plpgsql_add_initdatums(NULL);
674
675         /*
676          * Now parse the functions text
677          */
678         parse_rc = plpgsql_yyparse();
679         if (parse_rc != 0)
680                 elog(ERROR, "plpgsql parser returned %d", parse_rc);
681
682         plpgsql_scanner_finish();
683
684         /*
685          * If that was successful, complete the functions info.
686          */
687         function->fn_nargs = procStruct->pronargs;
688         for (i = 0; i < function->fn_nargs; i++)
689                 function->fn_argvarnos[i] = arg_varnos[i];
690         function->ndatums = plpgsql_nDatums;
691         function->datums = malloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
692         for (i = 0; i < plpgsql_nDatums; i++)
693                 function->datums[i] = plpgsql_Datums[i];
694         function->action = plpgsql_yylval.program;
695
696         /* Debug dump for completed functions */
697         if (plpgsql_DumpExecTree)
698                 plpgsql_dumptree(function);
699
700         /*
701          * add it to the hash table
702          */
703         plpgsql_HashTableInsert(function, hashkey);
704
705         /*
706          * Pop the error context stack
707          */
708         error_context_stack = plerrcontext.previous;
709         plpgsql_error_funcname = NULL;
710         plpgsql_error_lineno = 0;
711
712         return function;
713 }
714
715
716 /*
717  * error context callback to let us supply a call-stack traceback
718  */
719 static void
720 plpgsql_compile_error_callback(void *arg)
721 {
722         if (plpgsql_error_funcname)
723                 errcontext("compile of PL/pgSQL function \"%s\" near line %d",
724                                    plpgsql_error_funcname, plpgsql_error_lineno);
725 }
726
727
728 /* ----------
729  * plpgsql_parse_word           The scanner calls this to postparse
730  *                              any single word not found by a
731  *                              keyword rule.
732  * ----------
733  */
734 int
735 plpgsql_parse_word(char *word)
736 {
737         PLpgSQL_nsitem *nse;
738         char       *cp[1];
739
740         /* Do case conversion and word separation */
741         plpgsql_convert_ident(word, cp, 1);
742
743         /*
744          * Recognize tg_argv when compiling triggers
745          */
746         if (plpgsql_curr_compile->fn_functype == T_TRIGGER)
747         {
748                 if (strcmp(cp[0], "tg_argv") == 0)
749                 {
750                         int                     save_spacescanned = plpgsql_SpaceScanned;
751                         PLpgSQL_trigarg *trigarg;
752
753                         trigarg = malloc(sizeof(PLpgSQL_trigarg));
754                         memset(trigarg, 0, sizeof(PLpgSQL_trigarg));
755                         trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
756
757                         if (plpgsql_yylex() != '[')
758                                 plpgsql_yyerror("expected [");
759
760                         trigarg->argnum = plpgsql_read_expression(']', "]");
761
762                         plpgsql_adddatum((PLpgSQL_datum *) trigarg);
763                         plpgsql_yylval.variable = (PLpgSQL_datum *) trigarg;
764
765                         plpgsql_SpaceScanned = save_spacescanned;
766                         pfree(cp[0]);
767                         return T_VARIABLE;
768                 }
769         }
770
771         /*
772          * Do a lookup on the compilers namestack
773          */
774         nse = plpgsql_ns_lookup(cp[0], NULL);
775         if (nse != NULL)
776         {
777                 pfree(cp[0]);
778                 switch (nse->itemtype)
779                 {
780                         case PLPGSQL_NSTYPE_LABEL:
781                                 return T_LABEL;
782
783                         case PLPGSQL_NSTYPE_VAR:
784                                 plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[nse->itemno]);
785                                 return T_VARIABLE;
786
787                         case PLPGSQL_NSTYPE_REC:
788                                 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]);
789                                 return T_RECORD;
790
791                         case PLPGSQL_NSTYPE_ROW:
792                                 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[nse->itemno]);
793                                 return T_ROW;
794
795                         default:
796                                 return T_ERROR;
797                 }
798         }
799
800         /*
801          * Nothing found - up to now it's a word without any special meaning
802          * for us.
803          */
804         pfree(cp[0]);
805         return T_WORD;
806 }
807
808
809 /* ----------
810  * plpgsql_parse_dblword                Same lookup for two words
811  *                                      separated by a dot.
812  * ----------
813  */
814 int
815 plpgsql_parse_dblword(char *word)
816 {
817         PLpgSQL_nsitem *ns;
818         char       *cp[2];
819
820         /* Do case conversion and word separation */
821         plpgsql_convert_ident(word, cp, 2);
822
823         /*
824          * Lookup the first word
825          */
826         ns = plpgsql_ns_lookup(cp[0], NULL);
827         if (ns == NULL)
828         {
829                 pfree(cp[0]);
830                 pfree(cp[1]);
831                 return T_ERROR;
832         }
833
834         switch (ns->itemtype)
835         {
836                 case PLPGSQL_NSTYPE_LABEL:
837
838                         /*
839                          * First word is a label, so second word could be a variable,
840                          * record or row in that bodies namestack. Anything else could
841                          * only be something in a query given to the SPI manager and
842                          * T_ERROR will get eaten up by the collector routines.
843                          */
844                         ns = plpgsql_ns_lookup(cp[1], cp[0]);
845                         pfree(cp[0]);
846                         pfree(cp[1]);
847                         if (ns == NULL)
848                                 return T_ERROR;
849                         switch (ns->itemtype)
850                         {
851                                 case PLPGSQL_NSTYPE_VAR:
852                                         plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[ns->itemno]);
853                                         return T_VARIABLE;
854
855                                 case PLPGSQL_NSTYPE_REC:
856                                         plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
857                                         return T_RECORD;
858
859                                 case PLPGSQL_NSTYPE_ROW:
860                                         plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
861                                         return T_ROW;
862
863                                 default:
864                                         return T_ERROR;
865                         }
866                         break;
867
868                 case PLPGSQL_NSTYPE_REC:
869                         {
870                                 /*
871                                  * First word is a record name, so second word must be a
872                                  * field in this record.
873                                  */
874                                 PLpgSQL_recfield *new;
875
876                                 new = malloc(sizeof(PLpgSQL_recfield));
877                                 new->dtype = PLPGSQL_DTYPE_RECFIELD;
878                                 new->fieldname = strdup(cp[1]);
879                                 new->recparentno = ns->itemno;
880
881                                 plpgsql_adddatum((PLpgSQL_datum *) new);
882
883                                 plpgsql_yylval.variable = (PLpgSQL_datum *) new;
884
885                                 pfree(cp[0]);
886                                 pfree(cp[1]);
887                                 return T_VARIABLE;
888                         }
889
890                 case PLPGSQL_NSTYPE_ROW:
891                         {
892                                 /*
893                                  * First word is a row name, so second word must be a
894                                  * field in this row.
895                                  */
896                                 PLpgSQL_row *row;
897                                 int                     i;
898
899                                 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
900                                 for (i = 0; i < row->nfields; i++)
901                                 {
902                                         if (strcmp(row->fieldnames[i], cp[1]) == 0)
903                                         {
904                                                 plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[row->varnos[i]]);
905                                                 pfree(cp[0]);
906                                                 pfree(cp[1]);
907                                                 return T_VARIABLE;
908                                         }
909                                 }
910                                 ereport(ERROR,
911                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
912                                                  errmsg("row \"%s\" has no field \"%s\"",
913                                                                 cp[0], cp[1])));
914                         }
915
916                 default:
917                         break;
918         }
919
920         pfree(cp[0]);
921         pfree(cp[1]);
922         return T_ERROR;
923 }
924
925
926 /* ----------
927  * plpgsql_parse_tripword               Same lookup for three words
928  *                                      separated by dots.
929  * ----------
930  */
931 int
932 plpgsql_parse_tripword(char *word)
933 {
934         PLpgSQL_nsitem *ns;
935         char       *cp[3];
936
937         /* Do case conversion and word separation */
938         plpgsql_convert_ident(word, cp, 3);
939
940         /*
941          * Lookup the first word - it must be a label
942          */
943         ns = plpgsql_ns_lookup(cp[0], NULL);
944         if (ns == NULL)
945         {
946                 pfree(cp[0]);
947                 pfree(cp[1]);
948                 pfree(cp[2]);
949                 return T_ERROR;
950         }
951         if (ns->itemtype != PLPGSQL_NSTYPE_LABEL)
952         {
953                 pfree(cp[0]);
954                 pfree(cp[1]);
955                 pfree(cp[2]);
956                 return T_ERROR;
957         }
958
959         /*
960          * First word is a label, so second word could be a record or row
961          */
962         ns = plpgsql_ns_lookup(cp[1], cp[0]);
963         if (ns == NULL)
964         {
965                 pfree(cp[0]);
966                 pfree(cp[1]);
967                 pfree(cp[2]);
968                 return T_ERROR;
969         }
970
971         switch (ns->itemtype)
972         {
973                 case PLPGSQL_NSTYPE_REC:
974                         {
975                                 /*
976                                  * This word is a record name, so third word must be a
977                                  * field in this record.
978                                  */
979                                 PLpgSQL_recfield *new;
980
981                                 new = malloc(sizeof(PLpgSQL_recfield));
982                                 new->dtype = PLPGSQL_DTYPE_RECFIELD;
983                                 new->fieldname = strdup(cp[2]);
984                                 new->recparentno = ns->itemno;
985
986                                 plpgsql_adddatum((PLpgSQL_datum *) new);
987
988                                 plpgsql_yylval.variable = (PLpgSQL_datum *) new;
989
990                                 pfree(cp[0]);
991                                 pfree(cp[1]);
992                                 pfree(cp[2]);
993                                 return T_VARIABLE;
994                         }
995
996                 case PLPGSQL_NSTYPE_ROW:
997                         {
998                                 /*
999                                  * This word is a row name, so third word must be a field
1000                                  * in this row.
1001                                  */
1002                                 PLpgSQL_row *row;
1003                                 int                     i;
1004
1005                                 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1006                                 for (i = 0; i < row->nfields; i++)
1007                                 {
1008                                         if (strcmp(row->fieldnames[i], cp[2]) == 0)
1009                                         {
1010                                                 plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[row->varnos[i]]);
1011                                                 pfree(cp[0]);
1012                                                 pfree(cp[1]);
1013                                                 pfree(cp[2]);
1014                                                 return T_VARIABLE;
1015                                         }
1016                                 }
1017                                 ereport(ERROR,
1018                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
1019                                                  errmsg("row \"%s.%s\" has no field \"%s\"",
1020                                                                 cp[0], cp[1], cp[2])));
1021                         }
1022
1023                 default:
1024                         break;
1025         }
1026
1027         pfree(cp[0]);
1028         pfree(cp[1]);
1029         pfree(cp[2]);
1030         return T_ERROR;
1031 }
1032
1033
1034 /* ----------
1035  * plpgsql_parse_wordtype       The scanner found word%TYPE. word can be
1036  *                              a variable name or a basetype.
1037  * ----------
1038  */
1039 int
1040 plpgsql_parse_wordtype(char *word)
1041 {
1042         PLpgSQL_nsitem *nse;
1043         bool            old_nsstate;
1044         Oid                     typeOid;
1045         char       *cp[2];
1046         int                     i;
1047
1048         /* Do case conversion and word separation */
1049         /* We convert %type to .type momentarily to keep converter happy */
1050         i = strlen(word) - 5;
1051         Assert(word[i] == '%');
1052         word[i] = '.';
1053         plpgsql_convert_ident(word, cp, 2);
1054         word[i] = '%';
1055         pfree(cp[1]);
1056
1057         /*
1058          * Do a lookup on the compilers namestack. But ensure it moves up to
1059          * the toplevel.
1060          */
1061         old_nsstate = plpgsql_ns_setlocal(false);
1062         nse = plpgsql_ns_lookup(cp[0], NULL);
1063         plpgsql_ns_setlocal(old_nsstate);
1064
1065         if (nse != NULL)
1066         {
1067                 pfree(cp[0]);
1068                 switch (nse->itemtype)
1069                 {
1070                         case PLPGSQL_NSTYPE_VAR:
1071                                 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1072                                 return T_DTYPE;
1073
1074                         default:
1075                                 return T_ERROR;
1076                 }
1077         }
1078
1079         /*
1080          * Word wasn't found on the namestack. Try to find a data type with
1081          * that name, but ignore pg_type entries that are in fact class types.
1082          */
1083         typeOid = LookupTypeName(makeTypeName(cp[0]));
1084         if (OidIsValid(typeOid))
1085         {
1086                 HeapTuple       typeTup;
1087
1088                 typeTup = SearchSysCache(TYPEOID,
1089                                                                  ObjectIdGetDatum(typeOid),
1090                                                                  0, 0, 0);
1091                 if (HeapTupleIsValid(typeTup))
1092                 {
1093                         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1094
1095                         if (!typeStruct->typisdefined ||
1096                                 typeStruct->typrelid != InvalidOid)
1097                         {
1098                                 ReleaseSysCache(typeTup);
1099                                 pfree(cp[0]);
1100                                 return T_ERROR;
1101                         }
1102
1103                         plpgsql_yylval.dtype = build_datatype(typeTup, -1);
1104
1105                         ReleaseSysCache(typeTup);
1106                         pfree(cp[0]);
1107                         return T_DTYPE;
1108                 }
1109         }
1110
1111         /*
1112          * Nothing found - up to now it's a word without any special meaning
1113          * for us.
1114          */
1115         pfree(cp[0]);
1116         return T_ERROR;
1117 }
1118
1119
1120 /* ----------
1121  * plpgsql_parse_dblwordtype            Same lookup for word.word%TYPE
1122  * ----------
1123  */
1124 int
1125 plpgsql_parse_dblwordtype(char *word)
1126 {
1127         PLpgSQL_nsitem *nse;
1128         bool            old_nsstate;
1129         Oid                     classOid;
1130         HeapTuple       classtup;
1131         Form_pg_class classStruct;
1132         HeapTuple       attrtup;
1133         Form_pg_attribute attrStruct;
1134         HeapTuple       typetup;
1135         char       *cp[3];
1136         int                     i;
1137
1138         /* Do case conversion and word separation */
1139         /* We convert %type to .type momentarily to keep converter happy */
1140         i = strlen(word) - 5;
1141         Assert(word[i] == '%');
1142         word[i] = '.';
1143         plpgsql_convert_ident(word, cp, 3);
1144         word[i] = '%';
1145         pfree(cp[2]);
1146
1147         /*
1148          * Lookup the first word
1149          */
1150         nse = plpgsql_ns_lookup(cp[0], NULL);
1151
1152         /*
1153          * If this is a label lookup the second word in that labels namestack
1154          * level
1155          */
1156         if (nse != NULL)
1157         {
1158                 if (nse->itemtype == PLPGSQL_NSTYPE_LABEL)
1159                 {
1160                         old_nsstate = plpgsql_ns_setlocal(false);
1161                         nse = plpgsql_ns_lookup(cp[1], cp[0]);
1162                         plpgsql_ns_setlocal(old_nsstate);
1163
1164                         pfree(cp[0]);
1165                         pfree(cp[1]);
1166
1167                         if (nse != NULL)
1168                         {
1169                                 switch (nse->itemtype)
1170                                 {
1171                                         case PLPGSQL_NSTYPE_VAR:
1172                                                 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1173                                                 return T_DTYPE;
1174
1175                                         default:
1176                                                 return T_ERROR;
1177                                 }
1178                         }
1179                         return T_ERROR;
1180                 }
1181                 pfree(cp[0]);
1182                 pfree(cp[1]);
1183                 return T_ERROR;
1184         }
1185
1186         /*
1187          * First word could also be a table name
1188          */
1189         classOid = RelnameGetRelid(cp[0]);
1190         if (!OidIsValid(classOid))
1191         {
1192                 pfree(cp[0]);
1193                 pfree(cp[1]);
1194                 return T_ERROR;
1195         }
1196         classtup = SearchSysCache(RELOID,
1197                                                           ObjectIdGetDatum(classOid),
1198                                                           0, 0, 0);
1199         if (!HeapTupleIsValid(classtup))
1200         {
1201                 pfree(cp[0]);
1202                 pfree(cp[1]);
1203                 return T_ERROR;
1204         }
1205
1206         /*
1207          * It must be a relation, sequence, view, or type
1208          */
1209         classStruct = (Form_pg_class) GETSTRUCT(classtup);
1210         if (classStruct->relkind != RELKIND_RELATION &&
1211                 classStruct->relkind != RELKIND_SEQUENCE &&
1212                 classStruct->relkind != RELKIND_VIEW &&
1213                 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1214         {
1215                 ReleaseSysCache(classtup);
1216                 pfree(cp[0]);
1217                 pfree(cp[1]);
1218                 return T_ERROR;
1219         }
1220
1221         /*
1222          * Fetch the named table field and it's type
1223          */
1224         attrtup = SearchSysCacheAttName(classOid, cp[1]);
1225         if (!HeapTupleIsValid(attrtup))
1226         {
1227                 ReleaseSysCache(classtup);
1228                 pfree(cp[0]);
1229                 pfree(cp[1]);
1230                 return T_ERROR;
1231         }
1232         attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1233
1234         typetup = SearchSysCache(TYPEOID,
1235                                                          ObjectIdGetDatum(attrStruct->atttypid),
1236                                                          0, 0, 0);
1237         if (!HeapTupleIsValid(typetup))
1238                 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1239
1240         /*
1241          * Found that - build a compiler type struct and return it
1242          */
1243         plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1244
1245         ReleaseSysCache(classtup);
1246         ReleaseSysCache(attrtup);
1247         ReleaseSysCache(typetup);
1248         pfree(cp[0]);
1249         pfree(cp[1]);
1250         return T_DTYPE;
1251 }
1252
1253 /* ----------
1254  * plpgsql_parse_tripwordtype           Same lookup for word.word.word%TYPE
1255  * ----------
1256  */
1257 #define TYPE_JUNK_LEN   5
1258
1259 int
1260 plpgsql_parse_tripwordtype(char *word)
1261 {
1262         Oid                     classOid;
1263         HeapTuple       classtup;
1264         Form_pg_class classStruct;
1265         HeapTuple       attrtup;
1266         Form_pg_attribute attrStruct;
1267         HeapTuple       typetup;
1268         char       *cp[2];
1269         char       *colname[1];
1270         int                     qualified_att_len;
1271         int                     numdots = 0;
1272         int                     i;
1273         RangeVar   *relvar;
1274
1275         /* Do case conversion and word separation */
1276         qualified_att_len = strlen(word) - TYPE_JUNK_LEN;
1277         Assert(word[qualified_att_len] == '%');
1278
1279         for (i = 0; i < qualified_att_len; i++)
1280         {
1281                 if (word[i] == '.' && ++numdots == 2)
1282                 {
1283                         cp[0] = (char *) palloc((i + 1) * sizeof(char));
1284                         memset(cp[0], 0, (i + 1) * sizeof(char));
1285                         memcpy(cp[0], word, i * sizeof(char));
1286
1287                         /* qualified_att_len - one based position + 1 (null terminator) */
1288                         cp[1] = (char *) palloc((qualified_att_len - i) * sizeof(char));
1289                         memset(cp[1], 0, (qualified_att_len - i) * sizeof(char));
1290                         memcpy(cp[1], &word[i + 1], (qualified_att_len - i - 1) * sizeof(char));
1291
1292                         break;
1293                 }
1294         }
1295
1296         relvar = makeRangeVarFromNameList(stringToQualifiedNameList(cp[0], "plpgsql_parse_tripwordtype"));
1297         classOid = RangeVarGetRelid(relvar, true);
1298         if (!OidIsValid(classOid))
1299         {
1300                 pfree(cp[0]);
1301                 pfree(cp[1]);
1302                 return T_ERROR;
1303         }
1304         classtup = SearchSysCache(RELOID,
1305                                                           ObjectIdGetDatum(classOid),
1306                                                           0, 0, 0);
1307         if (!HeapTupleIsValid(classtup))
1308         {
1309                 pfree(cp[0]);
1310                 pfree(cp[1]);
1311                 return T_ERROR;
1312         }
1313
1314         /*
1315          * It must be a relation, sequence, view, or type
1316          */
1317         classStruct = (Form_pg_class) GETSTRUCT(classtup);
1318         if (classStruct->relkind != RELKIND_RELATION &&
1319                 classStruct->relkind != RELKIND_SEQUENCE &&
1320                 classStruct->relkind != RELKIND_VIEW &&
1321                 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1322         {
1323                 ReleaseSysCache(classtup);
1324                 pfree(cp[0]);
1325                 pfree(cp[1]);
1326                 return T_ERROR;
1327         }
1328
1329         /*
1330          * Fetch the named table field and it's type
1331          */
1332         plpgsql_convert_ident(cp[1], colname, 1);
1333         attrtup = SearchSysCacheAttName(classOid, colname[0]);
1334         pfree(colname[0]);
1335
1336         if (!HeapTupleIsValid(attrtup))
1337         {
1338                 ReleaseSysCache(classtup);
1339                 pfree(cp[0]);
1340                 pfree(cp[1]);
1341                 return T_ERROR;
1342         }
1343         attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1344
1345         typetup = SearchSysCache(TYPEOID,
1346                                                          ObjectIdGetDatum(attrStruct->atttypid),
1347                                                          0, 0, 0);
1348         if (!HeapTupleIsValid(typetup))
1349                 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1350
1351         /*
1352          * Found that - build a compiler type struct and return it
1353          */
1354         plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1355
1356         ReleaseSysCache(classtup);
1357         ReleaseSysCache(attrtup);
1358         ReleaseSysCache(typetup);
1359         pfree(cp[0]);
1360         pfree(cp[1]);
1361         return T_DTYPE;
1362 }
1363
1364 /* ----------
1365  * plpgsql_parse_wordrowtype            Scanner found word%ROWTYPE.
1366  *                                      So word must be a table name.
1367  * ----------
1368  */
1369 int
1370 plpgsql_parse_wordrowtype(char *word)
1371 {
1372         Oid                     classOid;
1373         char       *cp[2];
1374         int                     i;
1375
1376         /* Do case conversion and word separation */
1377         /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1378         i = strlen(word) - 8;
1379         Assert(word[i] == '%');
1380         word[i] = '.';
1381         plpgsql_convert_ident(word, cp, 2);
1382         word[i] = '%';
1383
1384         /* Lookup the relation */
1385         classOid = RelnameGetRelid(cp[0]);
1386         if (!OidIsValid(classOid))
1387                 ereport(ERROR,
1388                                 (errcode(ERRCODE_UNDEFINED_TABLE),
1389                                  errmsg("relation \"%s\" does not exist", cp[0])));
1390
1391         /*
1392          * Build and return the complete row definition
1393          */
1394         plpgsql_yylval.row = plpgsql_build_rowtype(classOid);
1395
1396         pfree(cp[0]);
1397         pfree(cp[1]);
1398
1399         return T_ROW;
1400 }
1401
1402 /* ----------
1403  * plpgsql_parse_dblwordrowtype         Scanner found word.word%ROWTYPE.
1404  *                      So word must be namespace qualified a table name.
1405  * ----------
1406  */
1407 #define ROWTYPE_JUNK_LEN        8
1408
1409 int
1410 plpgsql_parse_dblwordrowtype(char *word)
1411 {
1412         Oid                     classOid;
1413         char       *cp;
1414         int                     i;
1415         RangeVar   *relvar;
1416
1417         /* Do case conversion and word separation */
1418         /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1419         i = strlen(word) - ROWTYPE_JUNK_LEN;
1420         Assert(word[i] == '%');
1421
1422         cp = (char *) palloc((i + 1) * sizeof(char));
1423         memset(cp, 0, (i + 1) * sizeof(char));
1424         memcpy(cp, word, i * sizeof(char));
1425
1426         /* Lookup the relation */
1427         relvar = makeRangeVarFromNameList(stringToQualifiedNameList(cp, "plpgsql_parse_dblwordrowtype"));
1428         classOid = RangeVarGetRelid(relvar, true);
1429         if (!OidIsValid(classOid))
1430                 ereport(ERROR,
1431                                 (errcode(ERRCODE_UNDEFINED_TABLE),
1432                                  errmsg("relation \"%s\" does not exist", cp)));
1433
1434         /*
1435          * Build and return the complete row definition
1436          */
1437         plpgsql_yylval.row = plpgsql_build_rowtype(classOid);
1438
1439         pfree(cp);
1440
1441         return T_ROW;
1442 }
1443
1444 /*
1445  * Build a rowtype data structure given the pg_class OID.
1446  */
1447 PLpgSQL_row *
1448 plpgsql_build_rowtype(Oid classOid)
1449 {
1450         PLpgSQL_row *row;
1451         HeapTuple       classtup;
1452         Form_pg_class classStruct;
1453         const char *relname;
1454         int                     i;
1455
1456         /*
1457          * Fetch the pg_class tuple.
1458          */
1459         classtup = SearchSysCache(RELOID,
1460                                                           ObjectIdGetDatum(classOid),
1461                                                           0, 0, 0);
1462         if (!HeapTupleIsValid(classtup))
1463                 elog(ERROR, "cache lookup failed for relation %u", classOid);
1464         classStruct = (Form_pg_class) GETSTRUCT(classtup);
1465         relname = NameStr(classStruct->relname);
1466
1467         /* accept relation, sequence, view, or type pg_class entries */
1468         if (classStruct->relkind != RELKIND_RELATION &&
1469                 classStruct->relkind != RELKIND_SEQUENCE &&
1470                 classStruct->relkind != RELKIND_VIEW &&
1471                 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1472                 ereport(ERROR,
1473                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1474                                  errmsg("relation \"%s\" is not a table", relname)));
1475
1476         /*
1477          * Create a row datum entry and all the required variables that it
1478          * will point to.
1479          */
1480         row = malloc(sizeof(PLpgSQL_row));
1481         memset(row, 0, sizeof(PLpgSQL_row));
1482
1483         row->dtype = PLPGSQL_DTYPE_ROW;
1484         row->nfields = classStruct->relnatts;
1485         row->rowtypeclass = classStruct->reltype;
1486         row->fieldnames = malloc(sizeof(char *) * row->nfields);
1487         row->varnos = malloc(sizeof(int) * row->nfields);
1488
1489         for (i = 0; i < row->nfields; i++)
1490         {
1491                 HeapTuple       attrtup;
1492                 Form_pg_attribute attrStruct;
1493                 HeapTuple       typetup;
1494                 const char *attname;
1495                 PLpgSQL_var *var;
1496
1497                 /*
1498                  * Get the attribute and it's type
1499                  */
1500                 attrtup = SearchSysCache(ATTNUM,
1501                                                                  ObjectIdGetDatum(classOid),
1502                                                                  Int16GetDatum(i + 1),
1503                                                                  0, 0);
1504                 if (!HeapTupleIsValid(attrtup))
1505                         elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1506                                  i + 1, classOid);
1507                 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1508
1509                 attname = NameStr(attrStruct->attname);
1510
1511                 typetup = SearchSysCache(TYPEOID,
1512                                                                  ObjectIdGetDatum(attrStruct->atttypid),
1513                                                                  0, 0, 0);
1514                 if (!HeapTupleIsValid(typetup))
1515                         elog(ERROR, "cache lookup failed for type %u",
1516                                  attrStruct->atttypid);
1517
1518                 /*
1519                  * Create the internal variable
1520                  *
1521                  * We know if the table definitions contain a default value or if the
1522                  * field is declared in the table as NOT NULL. But it's possible
1523                  * to create a table field as NOT NULL without a default value and
1524                  * that would lead to problems later when initializing the
1525                  * variables due to entering a block at execution time. Thus we
1526                  * ignore this information for now.
1527                  */
1528                 var = malloc(sizeof(PLpgSQL_var));
1529                 memset(var, 0, sizeof(PLpgSQL_var));
1530                 var->dtype = PLPGSQL_DTYPE_VAR;
1531                 var->refname = malloc(strlen(relname) + strlen(attname) + 2);
1532                 strcpy(var->refname, relname);
1533                 strcat(var->refname, ".");
1534                 strcat(var->refname, attname);
1535                 var->datatype = build_datatype(typetup, attrStruct->atttypmod);
1536                 var->isconst = false;
1537                 var->notnull = false;
1538                 var->default_val = NULL;
1539                 var->value = (Datum) 0;
1540                 var->isnull = true;
1541                 var->freeval = false;
1542
1543                 plpgsql_adddatum((PLpgSQL_datum *) var);
1544
1545                 /*
1546                  * Add the variable to the row.
1547                  */
1548                 row->fieldnames[i] = strdup(attname);
1549                 row->varnos[i] = var->varno;
1550
1551                 ReleaseSysCache(typetup);
1552                 ReleaseSysCache(attrtup);
1553         }
1554
1555         ReleaseSysCache(classtup);
1556
1557         return row;
1558 }
1559
1560
1561 /* ----------
1562  * plpgsql_parse_datatype                       Scanner found something that should
1563  *                                      be a datatype name.
1564  * ----------
1565  */
1566 PLpgSQL_type *
1567 plpgsql_parse_datatype(char *string)
1568 {
1569         Oid                     type_id;
1570         int32           typmod;
1571         HeapTuple       typeTup;
1572         PLpgSQL_type *typ;
1573
1574         /* Let the main parser try to parse it under standard SQL rules */
1575         parseTypeString(string, &type_id, &typmod);
1576
1577         /* Okay, build a PLpgSQL_type data structure for it */
1578         typeTup = SearchSysCache(TYPEOID,
1579                                                          ObjectIdGetDatum(type_id),
1580                                                          0, 0, 0);
1581         if (!HeapTupleIsValid(typeTup))
1582                 elog(ERROR, "cache lookup failed for type %u", type_id);
1583
1584         typ = build_datatype(typeTup, typmod);
1585
1586         ReleaseSysCache(typeTup);
1587
1588         return typ;
1589 }
1590
1591 /*
1592  * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1593  */
1594 static PLpgSQL_type *
1595 build_datatype(HeapTuple typeTup, int32 typmod)
1596 {
1597         Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1598         PLpgSQL_type *typ;
1599
1600         typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
1601
1602         typ->typname = strdup(NameStr(typeStruct->typname));
1603         typ->typoid = HeapTupleGetOid(typeTup);
1604         typ->typlen = typeStruct->typlen;
1605         typ->typbyval = typeStruct->typbyval;
1606         typ->typrelid = typeStruct->typrelid;
1607         typ->typelem = typeStruct->typelem;
1608         perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
1609         typ->atttypmod = typmod;
1610
1611         return typ;
1612 }
1613
1614
1615 /* ----------
1616  * plpgsql_adddatum                     Add a variable, record or row
1617  *                                      to the compilers datum list.
1618  * ----------
1619  */
1620 void
1621 plpgsql_adddatum(PLpgSQL_datum * new)
1622 {
1623         if (plpgsql_nDatums == datums_alloc)
1624         {
1625                 datums_alloc *= 2;
1626                 plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
1627         }
1628
1629         new->dno = plpgsql_nDatums;
1630         plpgsql_Datums[plpgsql_nDatums++] = new;
1631 }
1632
1633
1634 /* ----------
1635  * plpgsql_add_initdatums               Put all datum entries created
1636  *                                      since the last call into the
1637  *                                      finishing code block so the
1638  *                                      block knows which variables to
1639  *                                      reinitialize when entered.
1640  * ----------
1641  */
1642 int
1643 plpgsql_add_initdatums(int **varnos)
1644 {
1645         int                     i;
1646         int                     n = 0;
1647
1648         for (i = datums_last; i < plpgsql_nDatums; i++)
1649         {
1650                 switch (plpgsql_Datums[i]->dtype)
1651                 {
1652                         case PLPGSQL_DTYPE_VAR:
1653                                 n++;
1654                                 break;
1655
1656                         default:
1657                                 break;
1658                 }
1659         }
1660
1661         if (varnos != NULL)
1662         {
1663                 *varnos = (int *) malloc(sizeof(int) * n);
1664
1665                 n = 0;
1666                 for (i = datums_last; i < plpgsql_nDatums; i++)
1667                 {
1668                         switch (plpgsql_Datums[i]->dtype)
1669                         {
1670                                 case PLPGSQL_DTYPE_VAR:
1671                                         (*varnos)[n++] = plpgsql_Datums[i]->dno;
1672
1673                                 default:
1674                                         break;
1675                         }
1676                 }
1677         }
1678
1679         datums_last = plpgsql_nDatums;
1680         return n;
1681 }
1682
1683
1684 /* ---------
1685  * plpgsql_yyerror                      Handle parser error
1686  * ---------
1687  */
1688
1689 void
1690 plpgsql_yyerror(const char *s)
1691 {
1692         plpgsql_error_lineno = plpgsql_scanner_lineno();
1693         ereport(ERROR,
1694                         (errcode(ERRCODE_SYNTAX_ERROR),
1695                          /* translator: first %s is a phrase like "syntax error" */
1696                          errmsg("%s at or near \"%s\"", s, plpgsql_yytext)));
1697 }
1698
1699
1700 /*
1701  * Compute the hashkey for a given function invocation
1702  *
1703  * The hashkey is returned into the caller-provided storage at *hashkey.
1704  */
1705 static void
1706 compute_function_hashkey(FmgrInfo *flinfo,
1707                                                  Form_pg_proc procStruct,
1708                                                  PLpgSQL_func_hashkey *hashkey)
1709 {
1710         int             i;
1711
1712         /* Make sure any unused bytes of the struct are zero */
1713         MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
1714
1715         hashkey->funcOid = flinfo->fn_oid;
1716
1717         /* get the argument types */
1718         for (i = 0; i < procStruct->pronargs; i++)
1719         {
1720                 Oid                     argtypeid = procStruct->proargtypes[i];
1721
1722                 /*
1723                  * Check for polymorphic arguments. If found, use the actual
1724                  * parameter type from the caller's FuncExpr node, if we
1725                  * have one.
1726                  *
1727                  * We can support arguments of type ANY the same way as normal
1728                  * polymorphic arguments.
1729                  */
1730                 if (argtypeid == ANYARRAYOID || argtypeid == ANYELEMENTOID ||
1731                         argtypeid == ANYOID)
1732                 {
1733                         argtypeid = get_fn_expr_argtype(flinfo, i);
1734                         if (!OidIsValid(argtypeid))
1735                                 ereport(ERROR,
1736                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1737                                                  errmsg("could not determine actual argument "
1738                                                                 "type for polymorphic function \"%s\"",
1739                                                                 NameStr(procStruct->proname))));
1740                 }
1741
1742                 hashkey->argtypes[i] = argtypeid;
1743         }
1744 }
1745
1746 static void
1747 plpgsql_HashTableInit(void)
1748 {
1749         HASHCTL         ctl;
1750
1751         memset(&ctl, 0, sizeof(ctl));
1752         ctl.keysize = sizeof(PLpgSQL_func_hashkey);
1753         ctl.entrysize = sizeof(plpgsql_HashEnt);
1754         ctl.hash = tag_hash;
1755         plpgsql_HashTable = hash_create("PLpgSQL function cache",
1756                                                                         FUNCS_PER_USER,
1757                                                                         &ctl,
1758                                                                         HASH_ELEM | HASH_FUNCTION);
1759 }
1760
1761 static PLpgSQL_function *
1762 plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
1763 {
1764         plpgsql_HashEnt    *hentry;
1765
1766         hentry = (plpgsql_HashEnt*) hash_search(plpgsql_HashTable,
1767                                                                                         (void *) func_key,
1768                                                                                         HASH_FIND,
1769                                                                                         NULL);
1770         if (hentry)
1771                 return hentry->function;
1772         else
1773                 return (PLpgSQL_function *) NULL;
1774 }
1775
1776 static void
1777 plpgsql_HashTableInsert(PLpgSQL_function *function,
1778                                                 PLpgSQL_func_hashkey *func_key)
1779 {
1780         plpgsql_HashEnt    *hentry;
1781         bool                            found;
1782
1783         hentry = (plpgsql_HashEnt*) hash_search(plpgsql_HashTable,
1784                                                                                         (void *) func_key,
1785                                                                                         HASH_ENTER,
1786                                                                                         &found);
1787         if (hentry == NULL)
1788                 ereport(ERROR,
1789                                 (errcode(ERRCODE_OUT_OF_MEMORY),
1790                                  errmsg("out of memory")));
1791         if (found)
1792                 elog(WARNING, "trying to insert a function that already exists");
1793
1794         hentry->function = function;
1795         /* prepare back link from function to hashtable key */
1796         function->fn_hashkey = &hentry->key;
1797 }
1798
1799 static void
1800 plpgsql_HashTableDelete(PLpgSQL_function *function)
1801 {
1802         plpgsql_HashEnt    *hentry;
1803
1804         hentry = (plpgsql_HashEnt*) hash_search(plpgsql_HashTable,
1805                                                                                         (void *) function->fn_hashkey,
1806                                                                                         HASH_REMOVE,
1807                                                                                         NULL);
1808         if (hentry == NULL)
1809                 elog(WARNING, "trying to delete function that does not exist");
1810 }