~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/pl/plpgsql/src/pl_comp.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * pl_comp.c            - Compiler part of the PL/pgSQL
 
4
 *                        procedural language
 
5
 *
 
6
 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
 
7
 * Portions Copyright (c) 1994, Regents of the University of California
 
8
 *
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        src/pl/plpgsql/src/pl_comp.c
 
12
 *
 
13
 *-------------------------------------------------------------------------
 
14
 */
 
15
 
 
16
#include "plpgsql.h"
 
17
 
 
18
#include <ctype.h>
 
19
 
 
20
#include "catalog/namespace.h"
 
21
#include "catalog/pg_attrdef.h"
 
22
#include "catalog/pg_attribute.h"
 
23
#include "catalog/pg_class.h"
 
24
#include "catalog/pg_proc.h"
 
25
#include "catalog/pg_proc_fn.h"
 
26
#include "catalog/pg_type.h"
 
27
#include "funcapi.h"
 
28
#include "nodes/makefuncs.h"
 
29
#include "parser/parse_type.h"
 
30
#include "tcop/tcopprot.h"
 
31
#include "utils/array.h"
 
32
#include "utils/builtins.h"
 
33
#include "utils/lsyscache.h"
 
34
#include "utils/memutils.h"
 
35
#include "utils/syscache.h"
 
36
 
 
37
 
 
38
/* ----------
 
39
 * Our own local and global variables
 
40
 * ----------
 
41
 */
 
42
PLpgSQL_stmt_block *plpgsql_parse_result;
 
43
 
 
44
static int      datums_alloc;
 
45
int                     plpgsql_nDatums;
 
46
PLpgSQL_datum **plpgsql_Datums;
 
47
static int      datums_last = 0;
 
48
 
 
49
char       *plpgsql_error_funcname;
 
50
bool            plpgsql_DumpExecTree = false;
 
51
bool            plpgsql_check_syntax = false;
 
52
 
 
53
PLpgSQL_function *plpgsql_curr_compile;
 
54
 
 
55
/* A context appropriate for short-term allocs during compilation */
 
56
MemoryContext compile_tmp_cxt;
 
57
 
 
58
/* ----------
 
59
 * Hash table for compiled functions
 
60
 * ----------
 
61
 */
 
62
static HTAB *plpgsql_HashTable = NULL;
 
63
 
 
64
typedef struct plpgsql_hashent
 
65
{
 
66
        PLpgSQL_func_hashkey key;
 
67
        PLpgSQL_function *function;
 
68
} plpgsql_HashEnt;
 
69
 
 
70
#define FUNCS_PER_USER          128 /* initial table size */
 
71
 
 
72
/* ----------
 
73
 * Lookup table for EXCEPTION condition names
 
74
 * ----------
 
75
 */
 
76
typedef struct
 
77
{
 
78
        const char *label;
 
79
        int                     sqlerrstate;
 
80
} ExceptionLabelMap;
 
81
 
 
82
static const ExceptionLabelMap exception_label_map[] = {
 
83
#include "plerrcodes.h"
 
84
        {NULL, 0}
 
85
};
 
86
 
 
87
 
 
88
/* ----------
 
89
 * static prototypes
 
90
 * ----------
 
91
 */
 
92
static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
 
93
                   HeapTuple procTup,
 
94
                   PLpgSQL_function *function,
 
95
                   PLpgSQL_func_hashkey *hashkey,
 
96
                   bool forValidator);
 
97
static void plpgsql_compile_error_callback(void *arg);
 
98
static void add_dummy_return(PLpgSQL_function *function);
 
99
static Node *plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref);
 
100
static Node *plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var);
 
101
static Node *plpgsql_param_ref(ParseState *pstate, ParamRef *pref);
 
102
static Node *resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr,
 
103
                                   ColumnRef *cref, bool error_if_no_field);
 
104
static Node *make_datum_param(PLpgSQL_expr *expr, int dno, int location);
 
105
static PLpgSQL_row *build_row_from_class(Oid classOid);
 
106
static PLpgSQL_row *build_row_from_vars(PLpgSQL_variable **vars, int numvars);
 
107
static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod, Oid collation);
 
108
static void compute_function_hashkey(FunctionCallInfo fcinfo,
 
109
                                                 Form_pg_proc procStruct,
 
110
                                                 PLpgSQL_func_hashkey *hashkey,
 
111
                                                 bool forValidator);
 
112
static void plpgsql_resolve_polymorphic_argtypes(int numargs,
 
113
                                                                         Oid *argtypes, char *argmodes,
 
114
                                                                         Node *call_expr, bool forValidator,
 
115
                                                                         const char *proname);
 
116
static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
 
117
static void plpgsql_HashTableInsert(PLpgSQL_function *function,
 
118
                                                PLpgSQL_func_hashkey *func_key);
 
119
static void plpgsql_HashTableDelete(PLpgSQL_function *function);
 
120
static void delete_function(PLpgSQL_function *func);
 
121
 
 
122
/* ----------
 
123
 * plpgsql_compile              Make an execution tree for a PL/pgSQL function.
 
124
 *
 
125
 * If forValidator is true, we're only compiling for validation purposes,
 
126
 * and so some checks are skipped.
 
127
 *
 
128
 * Note: it's important for this to fall through quickly if the function
 
129
 * has already been compiled.
 
130
 * ----------
 
131
 */
 
132
PLpgSQL_function *
 
133
plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
 
134
{
 
135
        Oid                     funcOid = fcinfo->flinfo->fn_oid;
 
136
        HeapTuple       procTup;
 
137
        Form_pg_proc procStruct;
 
138
        PLpgSQL_function *function;
 
139
        PLpgSQL_func_hashkey hashkey;
 
140
        bool            function_valid = false;
 
141
        bool            hashkey_valid = false;
 
142
 
 
143
        /*
 
144
         * Lookup the pg_proc tuple by Oid; we'll need it in any case
 
145
         */
 
146
        procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
 
147
        if (!HeapTupleIsValid(procTup))
 
148
                elog(ERROR, "cache lookup failed for function %u", funcOid);
 
149
        procStruct = (Form_pg_proc) GETSTRUCT(procTup);
 
150
 
 
151
        /*
 
152
         * See if there's already a cache entry for the current FmgrInfo. If not,
 
153
         * try to find one in the hash table.
 
154
         */
 
155
        function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
 
156
 
 
157
recheck:
 
158
        if (!function)
 
159
        {
 
160
                /* Compute hashkey using function signature and actual arg types */
 
161
                compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
 
162
                hashkey_valid = true;
 
163
 
 
164
                /* And do the lookup */
 
165
                function = plpgsql_HashTableLookup(&hashkey);
 
166
        }
 
167
 
 
168
        if (function)
 
169
        {
 
170
                /* We have a compiled function, but is it still valid? */
 
171
                if (function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
 
172
                        ItemPointerEquals(&function->fn_tid, &procTup->t_self))
 
173
                        function_valid = true;
 
174
                else
 
175
                {
 
176
                        /*
 
177
                         * Nope, so remove it from hashtable and try to drop associated
 
178
                         * storage (if not done already).
 
179
                         */
 
180
                        delete_function(function);
 
181
 
 
182
                        /*
 
183
                         * If the function isn't in active use then we can overwrite the
 
184
                         * func struct with new data, allowing any other existing fn_extra
 
185
                         * pointers to make use of the new definition on their next use.
 
186
                         * If it is in use then just leave it alone and make a new one.
 
187
                         * (The active invocations will run to completion using the
 
188
                         * previous definition, and then the cache entry will just be
 
189
                         * leaked; doesn't seem worth adding code to clean it up, given
 
190
                         * what a corner case this is.)
 
191
                         *
 
192
                         * If we found the function struct via fn_extra then it's possible
 
193
                         * a replacement has already been made, so go back and recheck the
 
194
                         * hashtable.
 
195
                         */
 
196
                        if (function->use_count != 0)
 
197
                        {
 
198
                                function = NULL;
 
199
                                if (!hashkey_valid)
 
200
                                        goto recheck;
 
201
                        }
 
202
                }
 
203
        }
 
204
 
 
205
        /*
 
206
         * If the function wasn't found or was out-of-date, we have to compile it
 
207
         */
 
208
        if (!function_valid)
 
209
        {
 
210
                /*
 
211
                 * Calculate hashkey if we didn't already; we'll need it to store the
 
212
                 * 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, function,
 
222
                                                          &hashkey, forValidator);
 
223
        }
 
224
 
 
225
        ReleaseSysCache(procTup);
 
226
 
 
227
        /*
 
228
         * Save pointer in FmgrInfo to avoid search on subsequent calls
 
229
         */
 
230
        fcinfo->flinfo->fn_extra = (void *) function;
 
231
 
 
232
        /*
 
233
         * Finally return the compiled function
 
234
         */
 
235
        return function;
 
236
}
 
237
 
 
238
/*
 
239
 * This is the slow part of plpgsql_compile().
 
240
 *
 
241
 * The passed-in "function" pointer is either NULL or an already-allocated
 
242
 * function struct to overwrite.
 
243
 *
 
244
 * While compiling a function, the CurrentMemoryContext is the
 
245
 * per-function memory context of the function we are compiling. That
 
246
 * means a palloc() will allocate storage with the same lifetime as
 
247
 * the function itself.
 
248
 *
 
249
 * Because palloc()'d storage will not be immediately freed, temporary
 
250
 * allocations should either be performed in a short-lived memory
 
251
 * context or explicitly pfree'd. Since not all backend functions are
 
252
 * careful about pfree'ing their allocations, it is also wise to
 
253
 * switch into a short-term context before calling into the
 
254
 * backend. An appropriate context for performing short-term
 
255
 * allocations is the compile_tmp_cxt.
 
256
 *
 
257
 * NB: this code is not re-entrant.  We assume that nothing we do here could
 
258
 * result in the invocation of another plpgsql function.
 
259
 */
 
260
static PLpgSQL_function *
 
261
do_compile(FunctionCallInfo fcinfo,
 
262
                   HeapTuple procTup,
 
263
                   PLpgSQL_function *function,
 
264
                   PLpgSQL_func_hashkey *hashkey,
 
265
                   bool forValidator)
 
266
{
 
267
        Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
 
268
        bool            is_trigger = CALLED_AS_TRIGGER(fcinfo);
 
269
        Datum           prosrcdatum;
 
270
        bool            isnull;
 
271
        char       *proc_source;
 
272
        HeapTuple       typeTup;
 
273
        Form_pg_type typeStruct;
 
274
        PLpgSQL_variable *var;
 
275
        PLpgSQL_rec *rec;
 
276
        int                     i;
 
277
        ErrorContextCallback plerrcontext;
 
278
        int                     parse_rc;
 
279
        Oid                     rettypeid;
 
280
        int                     numargs;
 
281
        int                     num_in_args = 0;
 
282
        int                     num_out_args = 0;
 
283
        Oid                *argtypes;
 
284
        char      **argnames;
 
285
        char       *argmodes;
 
286
        int                *in_arg_varnos = NULL;
 
287
        PLpgSQL_variable **out_arg_variables;
 
288
        MemoryContext func_cxt;
 
289
 
 
290
        /*
 
291
         * Setup the scanner input and error info.      We assume that this function
 
292
         * cannot be invoked recursively, so there's no need to save and restore
 
293
         * the static variables used here.
 
294
         */
 
295
        prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
 
296
                                                                  Anum_pg_proc_prosrc, &isnull);
 
297
        if (isnull)
 
298
                elog(ERROR, "null prosrc");
 
299
        proc_source = TextDatumGetCString(prosrcdatum);
 
300
        plpgsql_scanner_init(proc_source);
 
301
 
 
302
        plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
 
303
 
 
304
        /*
 
305
         * Setup error traceback support for ereport()
 
306
         */
 
307
        plerrcontext.callback = plpgsql_compile_error_callback;
 
308
        plerrcontext.arg = forValidator ? proc_source : NULL;
 
309
        plerrcontext.previous = error_context_stack;
 
310
        error_context_stack = &plerrcontext;
 
311
 
 
312
        /*
 
313
         * Do extra syntax checks when validating the function definition. We skip
 
314
         * this when actually compiling functions for execution, for performance
 
315
         * reasons.
 
316
         */
 
317
        plpgsql_check_syntax = forValidator;
 
318
 
 
319
        /*
 
320
         * Create the new function struct, if not done already.  The function
 
321
         * structs are never thrown away, so keep them in TopMemoryContext.
 
322
         */
 
323
        if (function == NULL)
 
324
        {
 
325
                function = (PLpgSQL_function *)
 
326
                        MemoryContextAllocZero(TopMemoryContext, sizeof(PLpgSQL_function));
 
327
        }
 
328
        else
 
329
        {
 
330
                /* re-using a previously existing struct, so clear it out */
 
331
                memset(function, 0, sizeof(PLpgSQL_function));
 
332
        }
 
333
        plpgsql_curr_compile = function;
 
334
 
 
335
        /*
 
336
         * All the permanent output of compilation (e.g. parse tree) is kept in a
 
337
         * per-function memory context, so it can be reclaimed easily.
 
338
         */
 
339
        func_cxt = AllocSetContextCreate(TopMemoryContext,
 
340
                                                                         "PL/pgSQL function context",
 
341
                                                                         ALLOCSET_DEFAULT_MINSIZE,
 
342
                                                                         ALLOCSET_DEFAULT_INITSIZE,
 
343
                                                                         ALLOCSET_DEFAULT_MAXSIZE);
 
344
        compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
 
345
 
 
346
        function->fn_name = pstrdup(NameStr(procStruct->proname));
 
347
        function->fn_oid = fcinfo->flinfo->fn_oid;
 
348
        function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
 
349
        function->fn_tid = procTup->t_self;
 
350
        function->fn_is_trigger = is_trigger;
 
351
        function->fn_input_collation = fcinfo->fncollation;
 
352
        function->fn_cxt = func_cxt;
 
353
        function->out_param_varno = -1;         /* set up for no OUT param */
 
354
        function->resolve_option = plpgsql_variable_conflict;
 
355
 
 
356
        /*
 
357
         * Initialize the compiler, particularly the namespace stack.  The
 
358
         * outermost namespace contains function parameters and other special
 
359
         * variables (such as FOUND), and is named after the function itself.
 
360
         */
 
361
        plpgsql_ns_init();
 
362
        plpgsql_ns_push(NameStr(procStruct->proname));
 
363
        plpgsql_DumpExecTree = false;
 
364
 
 
365
        datums_alloc = 128;
 
366
        plpgsql_nDatums = 0;
 
367
        /* This is short-lived, so needn't allocate in function's cxt */
 
368
        plpgsql_Datums = MemoryContextAlloc(compile_tmp_cxt,
 
369
                                                                         sizeof(PLpgSQL_datum *) * datums_alloc);
 
370
        datums_last = 0;
 
371
 
 
372
        switch (is_trigger)
 
373
        {
 
374
                case false:
 
375
 
 
376
                        /*
 
377
                         * Fetch info about the procedure's parameters. Allocations aren't
 
378
                         * needed permanently, so make them in tmp cxt.
 
379
                         *
 
380
                         * We also need to resolve any polymorphic input or output
 
381
                         * argument types.      In validation mode we won't be able to, so we
 
382
                         * arbitrarily assume we are dealing with integers.
 
383
                         */
 
384
                        MemoryContextSwitchTo(compile_tmp_cxt);
 
385
 
 
386
                        numargs = get_func_arg_info(procTup,
 
387
                                                                                &argtypes, &argnames, &argmodes);
 
388
 
 
389
                        plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
 
390
                                                                                                 fcinfo->flinfo->fn_expr,
 
391
                                                                                                 forValidator,
 
392
                                                                                                 plpgsql_error_funcname);
 
393
 
 
394
                        in_arg_varnos = (int *) palloc(numargs * sizeof(int));
 
395
                        out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
 
396
 
 
397
                        MemoryContextSwitchTo(func_cxt);
 
398
 
 
399
                        /*
 
400
                         * Create the variables for the procedure's parameters.
 
401
                         */
 
402
                        for (i = 0; i < numargs; i++)
 
403
                        {
 
404
                                char            buf[32];
 
405
                                Oid                     argtypeid = argtypes[i];
 
406
                                char            argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
 
407
                                PLpgSQL_type *argdtype;
 
408
                                PLpgSQL_variable *argvariable;
 
409
                                int                     argitemtype;
 
410
 
 
411
                                /* Create $n name for variable */
 
412
                                snprintf(buf, sizeof(buf), "$%d", i + 1);
 
413
 
 
414
                                /* Create datatype info */
 
415
                                argdtype = plpgsql_build_datatype(argtypeid,
 
416
                                                                                                  -1,
 
417
                                                                                           function->fn_input_collation);
 
418
 
 
419
                                /* Disallow pseudotype argument */
 
420
                                /* (note we already replaced polymorphic types) */
 
421
                                /* (build_variable would do this, but wrong message) */
 
422
                                if (argdtype->ttype != PLPGSQL_TTYPE_SCALAR &&
 
423
                                        argdtype->ttype != PLPGSQL_TTYPE_ROW)
 
424
                                        ereport(ERROR,
 
425
                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
426
                                                   errmsg("PL/pgSQL functions cannot accept type %s",
 
427
                                                                  format_type_be(argtypeid))));
 
428
 
 
429
                                /* Build variable and add to datum list */
 
430
                                argvariable = plpgsql_build_variable(buf, 0,
 
431
                                                                                                         argdtype, false);
 
432
 
 
433
                                if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
 
434
                                {
 
435
                                        argitemtype = PLPGSQL_NSTYPE_VAR;
 
436
                                }
 
437
                                else
 
438
                                {
 
439
                                        Assert(argvariable->dtype == PLPGSQL_DTYPE_ROW);
 
440
                                        argitemtype = PLPGSQL_NSTYPE_ROW;
 
441
                                }
 
442
 
 
443
                                /* Remember arguments in appropriate arrays */
 
444
                                if (argmode == PROARGMODE_IN ||
 
445
                                        argmode == PROARGMODE_INOUT ||
 
446
                                        argmode == PROARGMODE_VARIADIC)
 
447
                                        in_arg_varnos[num_in_args++] = argvariable->dno;
 
448
                                if (argmode == PROARGMODE_OUT ||
 
449
                                        argmode == PROARGMODE_INOUT ||
 
450
                                        argmode == PROARGMODE_TABLE)
 
451
                                        out_arg_variables[num_out_args++] = argvariable;
 
452
 
 
453
                                /* Add to namespace under the $n name */
 
454
                                plpgsql_ns_additem(argitemtype, argvariable->dno, buf);
 
455
 
 
456
                                /* If there's a name for the argument, make an alias */
 
457
                                if (argnames && argnames[i][0] != '\0')
 
458
                                        plpgsql_ns_additem(argitemtype, argvariable->dno,
 
459
                                                                           argnames[i]);
 
460
                        }
 
461
 
 
462
                        /*
 
463
                         * If there's just one OUT parameter, out_param_varno points
 
464
                         * directly to it.      If there's more than one, build a row that
 
465
                         * holds all of them.
 
466
                         */
 
467
                        if (num_out_args == 1)
 
468
                                function->out_param_varno = out_arg_variables[0]->dno;
 
469
                        else if (num_out_args > 1)
 
470
                        {
 
471
                                PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
 
472
                                                                                                           num_out_args);
 
473
 
 
474
                                plpgsql_adddatum((PLpgSQL_datum *) row);
 
475
                                function->out_param_varno = row->dno;
 
476
                        }
 
477
 
 
478
                        /*
 
479
                         * Check for a polymorphic returntype. If found, use the actual
 
480
                         * returntype type from the caller's FuncExpr node, if we have
 
481
                         * one.  (In validation mode we arbitrarily assume we are dealing
 
482
                         * with integers.)
 
483
                         *
 
484
                         * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
 
485
                         * work; if it doesn't we're in some context that fails to make
 
486
                         * the info available.
 
487
                         */
 
488
                        rettypeid = procStruct->prorettype;
 
489
                        if (IsPolymorphicType(rettypeid))
 
490
                        {
 
491
                                if (forValidator)
 
492
                                {
 
493
                                        if (rettypeid == ANYARRAYOID)
 
494
                                                rettypeid = INT4ARRAYOID;
 
495
                                        else    /* ANYELEMENT or ANYNONARRAY */
 
496
                                                rettypeid = INT4OID;
 
497
                                        /* XXX what could we use for ANYENUM? */
 
498
                                }
 
499
                                else
 
500
                                {
 
501
                                        rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
 
502
                                        if (!OidIsValid(rettypeid))
 
503
                                                ereport(ERROR,
 
504
                                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
505
                                                         errmsg("could not determine actual return type "
 
506
                                                                        "for polymorphic function \"%s\"",
 
507
                                                                        plpgsql_error_funcname)));
 
508
                                }
 
509
                        }
 
510
 
 
511
                        /*
 
512
                         * Normal function has a defined returntype
 
513
                         */
 
514
                        function->fn_rettype = rettypeid;
 
515
                        function->fn_retset = procStruct->proretset;
 
516
 
 
517
                        /*
 
518
                         * Lookup the function's return type
 
519
                         */
 
520
                        typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettypeid));
 
521
                        if (!HeapTupleIsValid(typeTup))
 
522
                                elog(ERROR, "cache lookup failed for type %u", rettypeid);
 
523
                        typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
 
524
 
 
525
                        /* Disallow pseudotype result, except VOID or RECORD */
 
526
                        /* (note we already replaced polymorphic types) */
 
527
                        if (typeStruct->typtype == TYPTYPE_PSEUDO)
 
528
                        {
 
529
                                if (rettypeid == VOIDOID ||
 
530
                                        rettypeid == RECORDOID)
 
531
                                         /* okay */ ;
 
532
                                else if (rettypeid == TRIGGEROID)
 
533
                                        ereport(ERROR,
 
534
                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
535
                                                         errmsg("trigger functions can only be called as triggers")));
 
536
                                else
 
537
                                        ereport(ERROR,
 
538
                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
539
                                                   errmsg("PL/pgSQL functions cannot return type %s",
 
540
                                                                  format_type_be(rettypeid))));
 
541
                        }
 
542
 
 
543
                        if (typeStruct->typrelid != InvalidOid ||
 
544
                                rettypeid == RECORDOID)
 
545
                                function->fn_retistuple = true;
 
546
                        else
 
547
                        {
 
548
                                function->fn_retbyval = typeStruct->typbyval;
 
549
                                function->fn_rettyplen = typeStruct->typlen;
 
550
                                function->fn_rettypioparam = getTypeIOParam(typeTup);
 
551
                                fmgr_info(typeStruct->typinput, &(function->fn_retinput));
 
552
 
 
553
                                /*
 
554
                                 * install $0 reference, but only for polymorphic return
 
555
                                 * types, and not when the return is specified through an
 
556
                                 * output parameter.
 
557
                                 */
 
558
                                if (IsPolymorphicType(procStruct->prorettype) &&
 
559
                                        num_out_args == 0)
 
560
                                {
 
561
                                        (void) plpgsql_build_variable("$0", 0,
 
562
                                                                                                  build_datatype(typeTup,
 
563
                                                                                                                                 -1,
 
564
                                                                                           function->fn_input_collation),
 
565
                                                                                                  true);
 
566
                                }
 
567
                        }
 
568
                        ReleaseSysCache(typeTup);
 
569
                        break;
 
570
 
 
571
                case true:
 
572
                        /* Trigger procedure's return type is unknown yet */
 
573
                        function->fn_rettype = InvalidOid;
 
574
                        function->fn_retbyval = false;
 
575
                        function->fn_retistuple = true;
 
576
                        function->fn_retset = false;
 
577
 
 
578
                        /* shouldn't be any declared arguments */
 
579
                        if (procStruct->pronargs != 0)
 
580
                                ereport(ERROR,
 
581
                                                (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
 
582
                                  errmsg("trigger functions cannot have declared arguments"),
 
583
                                                 errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
 
584
 
 
585
                        /* Add the record for referencing NEW */
 
586
                        rec = plpgsql_build_record("new", 0, true);
 
587
                        function->new_varno = rec->dno;
 
588
 
 
589
                        /* Add the record for referencing OLD */
 
590
                        rec = plpgsql_build_record("old", 0, true);
 
591
                        function->old_varno = rec->dno;
 
592
 
 
593
                        /* Add the variable tg_name */
 
594
                        var = plpgsql_build_variable("tg_name", 0,
 
595
                                                                                 plpgsql_build_datatype(NAMEOID,
 
596
                                                                                                                                -1,
 
597
                                                                                                                                InvalidOid),
 
598
                                                                                 true);
 
599
                        function->tg_name_varno = var->dno;
 
600
 
 
601
                        /* Add the variable tg_when */
 
602
                        var = plpgsql_build_variable("tg_when", 0,
 
603
                                                                                 plpgsql_build_datatype(TEXTOID,
 
604
                                                                                                                                -1,
 
605
                                                                                           function->fn_input_collation),
 
606
                                                                                 true);
 
607
                        function->tg_when_varno = var->dno;
 
608
 
 
609
                        /* Add the variable tg_level */
 
610
                        var = plpgsql_build_variable("tg_level", 0,
 
611
                                                                                 plpgsql_build_datatype(TEXTOID,
 
612
                                                                                                                                -1,
 
613
                                                                                           function->fn_input_collation),
 
614
                                                                                 true);
 
615
                        function->tg_level_varno = var->dno;
 
616
 
 
617
                        /* Add the variable tg_op */
 
618
                        var = plpgsql_build_variable("tg_op", 0,
 
619
                                                                                 plpgsql_build_datatype(TEXTOID,
 
620
                                                                                                                                -1,
 
621
                                                                                           function->fn_input_collation),
 
622
                                                                                 true);
 
623
                        function->tg_op_varno = var->dno;
 
624
 
 
625
                        /* Add the variable tg_relid */
 
626
                        var = plpgsql_build_variable("tg_relid", 0,
 
627
                                                                                 plpgsql_build_datatype(OIDOID,
 
628
                                                                                                                                -1,
 
629
                                                                                                                                InvalidOid),
 
630
                                                                                 true);
 
631
                        function->tg_relid_varno = var->dno;
 
632
 
 
633
                        /* Add the variable tg_relname */
 
634
                        var = plpgsql_build_variable("tg_relname", 0,
 
635
                                                                                 plpgsql_build_datatype(NAMEOID,
 
636
                                                                                                                                -1,
 
637
                                                                                                                                InvalidOid),
 
638
                                                                                 true);
 
639
                        function->tg_relname_varno = var->dno;
 
640
 
 
641
                        /* tg_table_name is now preferred to tg_relname */
 
642
                        var = plpgsql_build_variable("tg_table_name", 0,
 
643
                                                                                 plpgsql_build_datatype(NAMEOID,
 
644
                                                                                                                                -1,
 
645
                                                                                                                                InvalidOid),
 
646
                                                                                 true);
 
647
                        function->tg_table_name_varno = var->dno;
 
648
 
 
649
                        /* add the variable tg_table_schema */
 
650
                        var = plpgsql_build_variable("tg_table_schema", 0,
 
651
                                                                                 plpgsql_build_datatype(NAMEOID,
 
652
                                                                                                                                -1,
 
653
                                                                                                                                InvalidOid),
 
654
                                                                                 true);
 
655
                        function->tg_table_schema_varno = var->dno;
 
656
 
 
657
                        /* Add the variable tg_nargs */
 
658
                        var = plpgsql_build_variable("tg_nargs", 0,
 
659
                                                                                 plpgsql_build_datatype(INT4OID,
 
660
                                                                                                                                -1,
 
661
                                                                                                                                InvalidOid),
 
662
                                                                                 true);
 
663
                        function->tg_nargs_varno = var->dno;
 
664
 
 
665
                        /* Add the variable tg_argv */
 
666
                        var = plpgsql_build_variable("tg_argv", 0,
 
667
                                                                                 plpgsql_build_datatype(TEXTARRAYOID,
 
668
                                                                                                                                -1,
 
669
                                                                                           function->fn_input_collation),
 
670
                                                                                 true);
 
671
                        function->tg_argv_varno = var->dno;
 
672
 
 
673
                        break;
 
674
 
 
675
                default:
 
676
                        elog(ERROR, "unrecognized function typecode: %d", (int) is_trigger);
 
677
                        break;
 
678
        }
 
679
 
 
680
        /* Remember if function is STABLE/IMMUTABLE */
 
681
        function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
 
682
 
 
683
        /*
 
684
         * Create the magic FOUND variable.
 
685
         */
 
686
        var = plpgsql_build_variable("found", 0,
 
687
                                                                 plpgsql_build_datatype(BOOLOID,
 
688
                                                                                                                -1,
 
689
                                                                                                                InvalidOid),
 
690
                                                                 true);
 
691
        function->found_varno = var->dno;
 
692
 
 
693
        /*
 
694
         * Now parse the function's text
 
695
         */
 
696
        parse_rc = plpgsql_yyparse();
 
697
        if (parse_rc != 0)
 
698
                elog(ERROR, "plpgsql parser returned %d", parse_rc);
 
699
        function->action = plpgsql_parse_result;
 
700
 
 
701
        plpgsql_scanner_finish();
 
702
        pfree(proc_source);
 
703
 
 
704
        /*
 
705
         * If it has OUT parameters or returns VOID or returns a set, we allow
 
706
         * control to fall off the end without an explicit RETURN statement. The
 
707
         * easiest way to implement this is to add a RETURN statement to the end
 
708
         * of the statement list during parsing.
 
709
         */
 
710
        if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
 
711
                function->fn_retset)
 
712
                add_dummy_return(function);
 
713
 
 
714
        /*
 
715
         * Complete the function's info
 
716
         */
 
717
        function->fn_nargs = procStruct->pronargs;
 
718
        for (i = 0; i < function->fn_nargs; i++)
 
719
                function->fn_argvarnos[i] = in_arg_varnos[i];
 
720
        function->ndatums = plpgsql_nDatums;
 
721
        function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
 
722
        for (i = 0; i < plpgsql_nDatums; i++)
 
723
                function->datums[i] = plpgsql_Datums[i];
 
724
 
 
725
        /* Debug dump for completed functions */
 
726
        if (plpgsql_DumpExecTree)
 
727
                plpgsql_dumptree(function);
 
728
 
 
729
        /*
 
730
         * add it to the hash table
 
731
         */
 
732
        plpgsql_HashTableInsert(function, hashkey);
 
733
 
 
734
        /*
 
735
         * Pop the error context stack
 
736
         */
 
737
        error_context_stack = plerrcontext.previous;
 
738
        plpgsql_error_funcname = NULL;
 
739
 
 
740
        plpgsql_check_syntax = false;
 
741
 
 
742
        MemoryContextSwitchTo(compile_tmp_cxt);
 
743
        compile_tmp_cxt = NULL;
 
744
        return function;
 
745
}
 
746
 
 
747
/* ----------
 
748
 * plpgsql_compile_inline       Make an execution tree for an anonymous code block.
 
749
 *
 
750
 * Note: this is generally parallel to do_compile(); is it worth trying to
 
751
 * merge the two?
 
752
 *
 
753
 * Note: we assume the block will be thrown away so there is no need to build
 
754
 * persistent data structures.
 
755
 * ----------
 
756
 */
 
757
PLpgSQL_function *
 
758
plpgsql_compile_inline(char *proc_source)
 
759
{
 
760
        char       *func_name = "inline_code_block";
 
761
        PLpgSQL_function *function;
 
762
        ErrorContextCallback plerrcontext;
 
763
        Oid                     typinput;
 
764
        PLpgSQL_variable *var;
 
765
        int                     parse_rc;
 
766
        MemoryContext func_cxt;
 
767
        int                     i;
 
768
 
 
769
        /*
 
770
         * Setup the scanner input and error info.      We assume that this function
 
771
         * cannot be invoked recursively, so there's no need to save and restore
 
772
         * the static variables used here.
 
773
         */
 
774
        plpgsql_scanner_init(proc_source);
 
775
 
 
776
        plpgsql_error_funcname = func_name;
 
777
 
 
778
        /*
 
779
         * Setup error traceback support for ereport()
 
780
         */
 
781
        plerrcontext.callback = plpgsql_compile_error_callback;
 
782
        plerrcontext.arg = proc_source;
 
783
        plerrcontext.previous = error_context_stack;
 
784
        error_context_stack = &plerrcontext;
 
785
 
 
786
        /* Do extra syntax checking if check_function_bodies is on */
 
787
        plpgsql_check_syntax = check_function_bodies;
 
788
 
 
789
        /* Function struct does not live past current statement */
 
790
        function = (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
 
791
 
 
792
        plpgsql_curr_compile = function;
 
793
 
 
794
        /*
 
795
         * All the rest of the compile-time storage (e.g. parse tree) is kept in
 
796
         * its own memory context, so it can be reclaimed easily.
 
797
         */
 
798
        func_cxt = AllocSetContextCreate(CurrentMemoryContext,
 
799
                                                                         "PL/pgSQL function context",
 
800
                                                                         ALLOCSET_DEFAULT_MINSIZE,
 
801
                                                                         ALLOCSET_DEFAULT_INITSIZE,
 
802
                                                                         ALLOCSET_DEFAULT_MAXSIZE);
 
803
        compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
 
804
 
 
805
        function->fn_name = pstrdup(func_name);
 
806
        function->fn_is_trigger = false;
 
807
        function->fn_input_collation = InvalidOid;
 
808
        function->fn_cxt = func_cxt;
 
809
        function->out_param_varno = -1;         /* set up for no OUT param */
 
810
        function->resolve_option = plpgsql_variable_conflict;
 
811
 
 
812
        plpgsql_ns_init();
 
813
        plpgsql_ns_push(func_name);
 
814
        plpgsql_DumpExecTree = false;
 
815
 
 
816
        datums_alloc = 128;
 
817
        plpgsql_nDatums = 0;
 
818
        plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
 
819
        datums_last = 0;
 
820
 
 
821
        /* Set up as though in a function returning VOID */
 
822
        function->fn_rettype = VOIDOID;
 
823
        function->fn_retset = false;
 
824
        function->fn_retistuple = false;
 
825
        /* a bit of hardwired knowledge about type VOID here */
 
826
        function->fn_retbyval = true;
 
827
        function->fn_rettyplen = sizeof(int32);
 
828
        getTypeInputInfo(VOIDOID, &typinput, &function->fn_rettypioparam);
 
829
        fmgr_info(typinput, &(function->fn_retinput));
 
830
 
 
831
        /*
 
832
         * Remember if function is STABLE/IMMUTABLE.  XXX would it be better to
 
833
         * set this TRUE inside a read-only transaction?  Not clear.
 
834
         */
 
835
        function->fn_readonly = false;
 
836
 
 
837
        /*
 
838
         * Create the magic FOUND variable.
 
839
         */
 
840
        var = plpgsql_build_variable("found", 0,
 
841
                                                                 plpgsql_build_datatype(BOOLOID,
 
842
                                                                                                                -1,
 
843
                                                                                                                InvalidOid),
 
844
                                                                 true);
 
845
        function->found_varno = var->dno;
 
846
 
 
847
        /*
 
848
         * Now parse the function's text
 
849
         */
 
850
        parse_rc = plpgsql_yyparse();
 
851
        if (parse_rc != 0)
 
852
                elog(ERROR, "plpgsql parser returned %d", parse_rc);
 
853
        function->action = plpgsql_parse_result;
 
854
 
 
855
        plpgsql_scanner_finish();
 
856
 
 
857
        /*
 
858
         * If it returns VOID (always true at the moment), we allow control to
 
859
         * fall off the end without an explicit RETURN statement.
 
860
         */
 
861
        if (function->fn_rettype == VOIDOID)
 
862
                add_dummy_return(function);
 
863
 
 
864
        /*
 
865
         * Complete the function's info
 
866
         */
 
867
        function->fn_nargs = 0;
 
868
        function->ndatums = plpgsql_nDatums;
 
869
        function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
 
870
        for (i = 0; i < plpgsql_nDatums; i++)
 
871
                function->datums[i] = plpgsql_Datums[i];
 
872
 
 
873
        /*
 
874
         * Pop the error context stack
 
875
         */
 
876
        error_context_stack = plerrcontext.previous;
 
877
        plpgsql_error_funcname = NULL;
 
878
 
 
879
        plpgsql_check_syntax = false;
 
880
 
 
881
        MemoryContextSwitchTo(compile_tmp_cxt);
 
882
        compile_tmp_cxt = NULL;
 
883
        return function;
 
884
}
 
885
 
 
886
 
 
887
/*
 
888
 * error context callback to let us supply a call-stack traceback.
 
889
 * If we are validating or executing an anonymous code block, the function
 
890
 * source text is passed as an argument.
 
891
 */
 
892
static void
 
893
plpgsql_compile_error_callback(void *arg)
 
894
{
 
895
        if (arg)
 
896
        {
 
897
                /*
 
898
                 * Try to convert syntax error position to reference text of original
 
899
                 * CREATE FUNCTION or DO command.
 
900
                 */
 
901
                if (function_parse_error_transpose((const char *) arg))
 
902
                        return;
 
903
 
 
904
                /*
 
905
                 * Done if a syntax error position was reported; otherwise we have to
 
906
                 * fall back to a "near line N" report.
 
907
                 */
 
908
        }
 
909
 
 
910
        if (plpgsql_error_funcname)
 
911
                errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
 
912
                                   plpgsql_error_funcname, plpgsql_latest_lineno());
 
913
}
 
914
 
 
915
 
 
916
/*
 
917
 * Add a dummy RETURN statement to the given function's body
 
918
 */
 
919
static void
 
920
add_dummy_return(PLpgSQL_function *function)
 
921
{
 
922
        /*
 
923
         * If the outer block has an EXCEPTION clause, we need to make a new outer
 
924
         * block, since the added RETURN shouldn't act like it is inside the
 
925
         * EXCEPTION clause.
 
926
         */
 
927
        if (function->action->exceptions != NULL)
 
928
        {
 
929
                PLpgSQL_stmt_block *new;
 
930
 
 
931
                new = palloc0(sizeof(PLpgSQL_stmt_block));
 
932
                new->cmd_type = PLPGSQL_STMT_BLOCK;
 
933
                new->body = list_make1(function->action);
 
934
 
 
935
                function->action = new;
 
936
        }
 
937
        if (function->action->body == NIL ||
 
938
                ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
 
939
        {
 
940
                PLpgSQL_stmt_return *new;
 
941
 
 
942
                new = palloc0(sizeof(PLpgSQL_stmt_return));
 
943
                new->cmd_type = PLPGSQL_STMT_RETURN;
 
944
                new->expr = NULL;
 
945
                new->retvarno = function->out_param_varno;
 
946
 
 
947
                function->action->body = lappend(function->action->body, new);
 
948
        }
 
949
}
 
950
 
 
951
 
 
952
/*
 
953
 * plpgsql_parser_setup         set up parser hooks for dynamic parameters
 
954
 *
 
955
 * Note: this routine, and the hook functions it prepares for, are logically
 
956
 * part of plpgsql parsing.  But they actually run during function execution,
 
957
 * when we are ready to evaluate a SQL query or expression that has not
 
958
 * previously been parsed and planned.
 
959
 */
 
960
void
 
961
plpgsql_parser_setup(struct ParseState *pstate, PLpgSQL_expr *expr)
 
962
{
 
963
        pstate->p_pre_columnref_hook = plpgsql_pre_column_ref;
 
964
        pstate->p_post_columnref_hook = plpgsql_post_column_ref;
 
965
        pstate->p_paramref_hook = plpgsql_param_ref;
 
966
        /* no need to use p_coerce_param_hook */
 
967
        pstate->p_ref_hook_state = (void *) expr;
 
968
}
 
969
 
 
970
/*
 
971
 * plpgsql_pre_column_ref               parser callback before parsing a ColumnRef
 
972
 */
 
973
static Node *
 
974
plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
 
975
{
 
976
        PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
 
977
 
 
978
        if (expr->func->resolve_option == PLPGSQL_RESOLVE_VARIABLE)
 
979
                return resolve_column_ref(pstate, expr, cref, false);
 
980
        else
 
981
                return NULL;
 
982
}
 
983
 
 
984
/*
 
985
 * plpgsql_post_column_ref              parser callback after parsing a ColumnRef
 
986
 */
 
987
static Node *
 
988
plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
 
989
{
 
990
        PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
 
991
        Node       *myvar;
 
992
 
 
993
        if (expr->func->resolve_option == PLPGSQL_RESOLVE_VARIABLE)
 
994
                return NULL;                    /* we already found there's no match */
 
995
 
 
996
        if (expr->func->resolve_option == PLPGSQL_RESOLVE_COLUMN && var != NULL)
 
997
                return NULL;                    /* there's a table column, prefer that */
 
998
 
 
999
        /*
 
1000
         * If we find a record/row variable but can't match a field name, throw
 
1001
         * error if there was no core resolution for the ColumnRef either.      In
 
1002
         * that situation, the reference is inevitably going to fail, and
 
1003
         * complaining about the record/row variable is likely to be more on-point
 
1004
         * than the core parser's error message.  (It's too bad we don't have
 
1005
         * access to transformColumnRef's internal crerr state here, as in case of
 
1006
         * a conflict with a table name this could still be less than the most
 
1007
         * helpful error message possible.)
 
1008
         */
 
1009
        myvar = resolve_column_ref(pstate, expr, cref, (var == NULL));
 
1010
 
 
1011
        if (myvar != NULL && var != NULL)
 
1012
        {
 
1013
                /*
 
1014
                 * We could leave it to the core parser to throw this error, but we
 
1015
                 * can add a more useful detail message than the core could.
 
1016
                 */
 
1017
                ereport(ERROR,
 
1018
                                (errcode(ERRCODE_AMBIGUOUS_COLUMN),
 
1019
                                 errmsg("column reference \"%s\" is ambiguous",
 
1020
                                                NameListToString(cref->fields)),
 
1021
                                 errdetail("It could refer to either a PL/pgSQL variable or a table column."),
 
1022
                                 parser_errposition(pstate, cref->location)));
 
1023
        }
 
1024
 
 
1025
        return myvar;
 
1026
}
 
1027
 
 
1028
/*
 
1029
 * plpgsql_param_ref            parser callback for ParamRefs ($n symbols)
 
1030
 */
 
1031
static Node *
 
1032
plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
 
1033
{
 
1034
        PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
 
1035
        char            pname[32];
 
1036
        PLpgSQL_nsitem *nse;
 
1037
 
 
1038
        snprintf(pname, sizeof(pname), "$%d", pref->number);
 
1039
 
 
1040
        nse = plpgsql_ns_lookup(expr->ns, false,
 
1041
                                                        pname, NULL, NULL,
 
1042
                                                        NULL);
 
1043
 
 
1044
        if (nse == NULL)
 
1045
                return NULL;                    /* name not known to plpgsql */
 
1046
 
 
1047
        return make_datum_param(expr, nse->itemno, pref->location);
 
1048
}
 
1049
 
 
1050
/*
 
1051
 * resolve_column_ref           attempt to resolve a ColumnRef as a plpgsql var
 
1052
 *
 
1053
 * Returns the translated node structure, or NULL if name not found
 
1054
 *
 
1055
 * error_if_no_field tells whether to throw error or quietly return NULL if
 
1056
 * we are able to match a record/row name but don't find a field name match.
 
1057
 */
 
1058
static Node *
 
1059
resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr,
 
1060
                                   ColumnRef *cref, bool error_if_no_field)
 
1061
{
 
1062
        PLpgSQL_execstate *estate;
 
1063
        PLpgSQL_nsitem *nse;
 
1064
        const char *name1;
 
1065
        const char *name2 = NULL;
 
1066
        const char *name3 = NULL;
 
1067
        const char *colname = NULL;
 
1068
        int                     nnames;
 
1069
        int                     nnames_scalar = 0;
 
1070
        int                     nnames_wholerow = 0;
 
1071
        int                     nnames_field = 0;
 
1072
 
 
1073
        /*
 
1074
         * We use the function's current estate to resolve parameter data types.
 
1075
         * This is really pretty bogus because there is no provision for updating
 
1076
         * plans when those types change ...
 
1077
         */
 
1078
        estate = expr->func->cur_estate;
 
1079
 
 
1080
        /*----------
 
1081
         * The allowed syntaxes are:
 
1082
         *
 
1083
         * A            Scalar variable reference, or whole-row record reference.
 
1084
         * A.B          Qualified scalar or whole-row reference, or field reference.
 
1085
         * A.B.C        Qualified record field reference.
 
1086
         * A.*          Whole-row record reference.
 
1087
         * A.B.*        Qualified whole-row record reference.
 
1088
         *----------
 
1089
         */
 
1090
        switch (list_length(cref->fields))
 
1091
        {
 
1092
                case 1:
 
1093
                        {
 
1094
                                Node       *field1 = (Node *) linitial(cref->fields);
 
1095
 
 
1096
                                Assert(IsA(field1, String));
 
1097
                                name1 = strVal(field1);
 
1098
                                nnames_scalar = 1;
 
1099
                                nnames_wholerow = 1;
 
1100
                                break;
 
1101
                        }
 
1102
                case 2:
 
1103
                        {
 
1104
                                Node       *field1 = (Node *) linitial(cref->fields);
 
1105
                                Node       *field2 = (Node *) lsecond(cref->fields);
 
1106
 
 
1107
                                Assert(IsA(field1, String));
 
1108
                                name1 = strVal(field1);
 
1109
 
 
1110
                                /* Whole-row reference? */
 
1111
                                if (IsA(field2, A_Star))
 
1112
                                {
 
1113
                                        /* Set name2 to prevent matches to scalar variables */
 
1114
                                        name2 = "*";
 
1115
                                        nnames_wholerow = 1;
 
1116
                                        break;
 
1117
                                }
 
1118
 
 
1119
                                Assert(IsA(field2, String));
 
1120
                                name2 = strVal(field2);
 
1121
                                colname = name2;
 
1122
                                nnames_scalar = 2;
 
1123
                                nnames_wholerow = 2;
 
1124
                                nnames_field = 1;
 
1125
                                break;
 
1126
                        }
 
1127
                case 3:
 
1128
                        {
 
1129
                                Node       *field1 = (Node *) linitial(cref->fields);
 
1130
                                Node       *field2 = (Node *) lsecond(cref->fields);
 
1131
                                Node       *field3 = (Node *) lthird(cref->fields);
 
1132
 
 
1133
                                Assert(IsA(field1, String));
 
1134
                                name1 = strVal(field1);
 
1135
                                Assert(IsA(field2, String));
 
1136
                                name2 = strVal(field2);
 
1137
 
 
1138
                                /* Whole-row reference? */
 
1139
                                if (IsA(field3, A_Star))
 
1140
                                {
 
1141
                                        /* Set name3 to prevent matches to scalar variables */
 
1142
                                        name3 = "*";
 
1143
                                        nnames_wholerow = 2;
 
1144
                                        break;
 
1145
                                }
 
1146
 
 
1147
                                Assert(IsA(field3, String));
 
1148
                                name3 = strVal(field3);
 
1149
                                colname = name3;
 
1150
                                nnames_field = 2;
 
1151
                                break;
 
1152
                        }
 
1153
                default:
 
1154
                        /* too many names, ignore */
 
1155
                        return NULL;
 
1156
        }
 
1157
 
 
1158
        nse = plpgsql_ns_lookup(expr->ns, false,
 
1159
                                                        name1, name2, name3,
 
1160
                                                        &nnames);
 
1161
 
 
1162
        if (nse == NULL)
 
1163
                return NULL;                    /* name not known to plpgsql */
 
1164
 
 
1165
        switch (nse->itemtype)
 
1166
        {
 
1167
                case PLPGSQL_NSTYPE_VAR:
 
1168
                        if (nnames == nnames_scalar)
 
1169
                                return make_datum_param(expr, nse->itemno, cref->location);
 
1170
                        break;
 
1171
                case PLPGSQL_NSTYPE_REC:
 
1172
                        if (nnames == nnames_wholerow)
 
1173
                                return make_datum_param(expr, nse->itemno, cref->location);
 
1174
                        if (nnames == nnames_field)
 
1175
                        {
 
1176
                                /* colname could be a field in this record */
 
1177
                                int                     i;
 
1178
 
 
1179
                                /* search for a datum referencing this field */
 
1180
                                for (i = 0; i < estate->ndatums; i++)
 
1181
                                {
 
1182
                                        PLpgSQL_recfield *fld = (PLpgSQL_recfield *) estate->datums[i];
 
1183
 
 
1184
                                        if (fld->dtype == PLPGSQL_DTYPE_RECFIELD &&
 
1185
                                                fld->recparentno == nse->itemno &&
 
1186
                                                strcmp(fld->fieldname, colname) == 0)
 
1187
                                        {
 
1188
                                                return make_datum_param(expr, i, cref->location);
 
1189
                                        }
 
1190
                                }
 
1191
 
 
1192
                                /*
 
1193
                                 * We should not get here, because a RECFIELD datum should
 
1194
                                 * have been built at parse time for every possible qualified
 
1195
                                 * reference to fields of this record.  But if we do, handle
 
1196
                                 * it like field-not-found: throw error or return NULL.
 
1197
                                 */
 
1198
                                if (error_if_no_field)
 
1199
                                        ereport(ERROR,
 
1200
                                                        (errcode(ERRCODE_UNDEFINED_COLUMN),
 
1201
                                                         errmsg("record \"%s\" has no field \"%s\"",
 
1202
                                                                        (nnames_field == 1) ? name1 : name2,
 
1203
                                                                        colname),
 
1204
                                                         parser_errposition(pstate, cref->location)));
 
1205
                        }
 
1206
                        break;
 
1207
                case PLPGSQL_NSTYPE_ROW:
 
1208
                        if (nnames == nnames_wholerow)
 
1209
                                return make_datum_param(expr, nse->itemno, cref->location);
 
1210
                        if (nnames == nnames_field)
 
1211
                        {
 
1212
                                /* colname could be a field in this row */
 
1213
                                PLpgSQL_row *row = (PLpgSQL_row *) estate->datums[nse->itemno];
 
1214
                                int                     i;
 
1215
 
 
1216
                                for (i = 0; i < row->nfields; i++)
 
1217
                                {
 
1218
                                        if (row->fieldnames[i] &&
 
1219
                                                strcmp(row->fieldnames[i], colname) == 0)
 
1220
                                        {
 
1221
                                                return make_datum_param(expr, row->varnos[i],
 
1222
                                                                                                cref->location);
 
1223
                                        }
 
1224
                                }
 
1225
                                /* Not found, so throw error or return NULL */
 
1226
                                if (error_if_no_field)
 
1227
                                        ereport(ERROR,
 
1228
                                                        (errcode(ERRCODE_UNDEFINED_COLUMN),
 
1229
                                                         errmsg("record \"%s\" has no field \"%s\"",
 
1230
                                                                        (nnames_field == 1) ? name1 : name2,
 
1231
                                                                        colname),
 
1232
                                                         parser_errposition(pstate, cref->location)));
 
1233
                        }
 
1234
                        break;
 
1235
                default:
 
1236
                        elog(ERROR, "unrecognized plpgsql itemtype: %d", nse->itemtype);
 
1237
        }
 
1238
 
 
1239
        /* Name format doesn't match the plpgsql variable type */
 
1240
        return NULL;
 
1241
}
 
1242
 
 
1243
/*
 
1244
 * Helper for columnref parsing: build a Param referencing a plpgsql datum,
 
1245
 * and make sure that that datum is listed in the expression's paramnos.
 
1246
 */
 
1247
static Node *
 
1248
make_datum_param(PLpgSQL_expr *expr, int dno, int location)
 
1249
{
 
1250
        PLpgSQL_execstate *estate;
 
1251
        PLpgSQL_datum *datum;
 
1252
        Param      *param;
 
1253
        MemoryContext oldcontext;
 
1254
 
 
1255
        /* see comment in resolve_column_ref */
 
1256
        estate = expr->func->cur_estate;
 
1257
        Assert(dno >= 0 && dno < estate->ndatums);
 
1258
        datum = estate->datums[dno];
 
1259
 
 
1260
        /*
 
1261
         * Bitmapset must be allocated in function's permanent memory context
 
1262
         */
 
1263
        oldcontext = MemoryContextSwitchTo(expr->func->fn_cxt);
 
1264
        expr->paramnos = bms_add_member(expr->paramnos, dno);
 
1265
        MemoryContextSwitchTo(oldcontext);
 
1266
 
 
1267
        param = makeNode(Param);
 
1268
        param->paramkind = PARAM_EXTERN;
 
1269
        param->paramid = dno + 1;
 
1270
        param->paramtype = exec_get_datum_type(estate, datum);
 
1271
        param->paramtypmod = -1;
 
1272
        param->paramcollid = exec_get_datum_collation(estate, datum);
 
1273
        param->location = location;
 
1274
 
 
1275
        return (Node *) param;
 
1276
}
 
1277
 
 
1278
 
 
1279
/* ----------
 
1280
 * plpgsql_parse_word           The scanner calls this to postparse
 
1281
 *                              any single word that is not a reserved keyword.
 
1282
 *
 
1283
 * word1 is the downcased/dequoted identifier; it must be palloc'd in the
 
1284
 * function's long-term memory context.
 
1285
 *
 
1286
 * yytxt is the original token text; we need this to check for quoting,
 
1287
 * so that later checks for unreserved keywords work properly.
 
1288
 *
 
1289
 * If recognized as a variable, fill in *wdatum and return TRUE;
 
1290
 * if not recognized, fill in *word and return FALSE.
 
1291
 * (Note: those two pointers actually point to members of the same union,
 
1292
 * but for notational reasons we pass them separately.)
 
1293
 * ----------
 
1294
 */
 
1295
bool
 
1296
plpgsql_parse_word(char *word1, const char *yytxt,
 
1297
                                   PLwdatum *wdatum, PLword *word)
 
1298
{
 
1299
        PLpgSQL_nsitem *ns;
 
1300
 
 
1301
        /*
 
1302
         * We should do nothing in DECLARE sections.  In SQL expressions, there's
 
1303
         * no need to do anything either --- lookup will happen when the
 
1304
         * expression is compiled.
 
1305
         */
 
1306
        if (plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_NORMAL)
 
1307
        {
 
1308
                /*
 
1309
                 * Do a lookup in the current namespace stack
 
1310
                 */
 
1311
                ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
 
1312
                                                           word1, NULL, NULL,
 
1313
                                                           NULL);
 
1314
 
 
1315
                if (ns != NULL)
 
1316
                {
 
1317
                        switch (ns->itemtype)
 
1318
                        {
 
1319
                                case PLPGSQL_NSTYPE_VAR:
 
1320
                                case PLPGSQL_NSTYPE_ROW:
 
1321
                                case PLPGSQL_NSTYPE_REC:
 
1322
                                        wdatum->datum = plpgsql_Datums[ns->itemno];
 
1323
                                        wdatum->ident = word1;
 
1324
                                        wdatum->quoted = (yytxt[0] == '"');
 
1325
                                        wdatum->idents = NIL;
 
1326
                                        return true;
 
1327
 
 
1328
                                default:
 
1329
                                        /* plpgsql_ns_lookup should never return anything else */
 
1330
                                        elog(ERROR, "unrecognized plpgsql itemtype: %d",
 
1331
                                                 ns->itemtype);
 
1332
                        }
 
1333
                }
 
1334
        }
 
1335
 
 
1336
        /*
 
1337
         * Nothing found - up to now it's a word without any special meaning for
 
1338
         * us.
 
1339
         */
 
1340
        word->ident = word1;
 
1341
        word->quoted = (yytxt[0] == '"');
 
1342
        return false;
 
1343
}
 
1344
 
 
1345
 
 
1346
/* ----------
 
1347
 * plpgsql_parse_dblword                Same lookup for two words
 
1348
 *                                      separated by a dot.
 
1349
 * ----------
 
1350
 */
 
1351
bool
 
1352
plpgsql_parse_dblword(char *word1, char *word2,
 
1353
                                          PLwdatum *wdatum, PLcword *cword)
 
1354
{
 
1355
        PLpgSQL_nsitem *ns;
 
1356
        List       *idents;
 
1357
        int                     nnames;
 
1358
 
 
1359
        idents = list_make2(makeString(word1),
 
1360
                                                makeString(word2));
 
1361
 
 
1362
        /*
 
1363
         * We should do nothing in DECLARE sections.  In SQL expressions, we
 
1364
         * really only need to make sure that RECFIELD datums are created when
 
1365
         * needed.
 
1366
         */
 
1367
        if (plpgsql_IdentifierLookup != IDENTIFIER_LOOKUP_DECLARE)
 
1368
        {
 
1369
                /*
 
1370
                 * Do a lookup in the current namespace stack
 
1371
                 */
 
1372
                ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
 
1373
                                                           word1, word2, NULL,
 
1374
                                                           &nnames);
 
1375
                if (ns != NULL)
 
1376
                {
 
1377
                        switch (ns->itemtype)
 
1378
                        {
 
1379
                                case PLPGSQL_NSTYPE_VAR:
 
1380
                                        /* Block-qualified reference to scalar variable. */
 
1381
                                        wdatum->datum = plpgsql_Datums[ns->itemno];
 
1382
                                        wdatum->ident = NULL;
 
1383
                                        wdatum->quoted = false;         /* not used */
 
1384
                                        wdatum->idents = idents;
 
1385
                                        return true;
 
1386
 
 
1387
                                case PLPGSQL_NSTYPE_REC:
 
1388
                                        if (nnames == 1)
 
1389
                                        {
 
1390
                                                /*
 
1391
                                                 * First word is a record name, so second word could
 
1392
                                                 * be a field in this record.  We build a RECFIELD
 
1393
                                                 * datum whether it is or not --- any error will be
 
1394
                                                 * detected later.
 
1395
                                                 */
 
1396
                                                PLpgSQL_recfield *new;
 
1397
 
 
1398
                                                new = palloc(sizeof(PLpgSQL_recfield));
 
1399
                                                new->dtype = PLPGSQL_DTYPE_RECFIELD;
 
1400
                                                new->fieldname = pstrdup(word2);
 
1401
                                                new->recparentno = ns->itemno;
 
1402
 
 
1403
                                                plpgsql_adddatum((PLpgSQL_datum *) new);
 
1404
 
 
1405
                                                wdatum->datum = (PLpgSQL_datum *) new;
 
1406
                                        }
 
1407
                                        else
 
1408
                                        {
 
1409
                                                /* Block-qualified reference to record variable. */
 
1410
                                                wdatum->datum = plpgsql_Datums[ns->itemno];
 
1411
                                        }
 
1412
                                        wdatum->ident = NULL;
 
1413
                                        wdatum->quoted = false;         /* not used */
 
1414
                                        wdatum->idents = idents;
 
1415
                                        return true;
 
1416
 
 
1417
                                case PLPGSQL_NSTYPE_ROW:
 
1418
                                        if (nnames == 1)
 
1419
                                        {
 
1420
                                                /*
 
1421
                                                 * First word is a row name, so second word could be a
 
1422
                                                 * field in this row.  Again, no error now if it
 
1423
                                                 * isn't.
 
1424
                                                 */
 
1425
                                                PLpgSQL_row *row;
 
1426
                                                int                     i;
 
1427
 
 
1428
                                                row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
 
1429
                                                for (i = 0; i < row->nfields; i++)
 
1430
                                                {
 
1431
                                                        if (row->fieldnames[i] &&
 
1432
                                                                strcmp(row->fieldnames[i], word2) == 0)
 
1433
                                                        {
 
1434
                                                                wdatum->datum = plpgsql_Datums[row->varnos[i]];
 
1435
                                                                wdatum->ident = NULL;
 
1436
                                                                wdatum->quoted = false; /* not used */
 
1437
                                                                wdatum->idents = idents;
 
1438
                                                                return true;
 
1439
                                                        }
 
1440
                                                }
 
1441
                                                /* fall through to return CWORD */
 
1442
                                        }
 
1443
                                        else
 
1444
                                        {
 
1445
                                                /* Block-qualified reference to row variable. */
 
1446
                                                wdatum->datum = plpgsql_Datums[ns->itemno];
 
1447
                                                wdatum->ident = NULL;
 
1448
                                                wdatum->quoted = false; /* not used */
 
1449
                                                wdatum->idents = idents;
 
1450
                                                return true;
 
1451
                                        }
 
1452
                                        break;
 
1453
 
 
1454
                                default:
 
1455
                                        break;
 
1456
                        }
 
1457
                }
 
1458
        }
 
1459
 
 
1460
        /* Nothing found */
 
1461
        cword->idents = idents;
 
1462
        return false;
 
1463
}
 
1464
 
 
1465
 
 
1466
/* ----------
 
1467
 * plpgsql_parse_tripword               Same lookup for three words
 
1468
 *                                      separated by dots.
 
1469
 * ----------
 
1470
 */
 
1471
bool
 
1472
plpgsql_parse_tripword(char *word1, char *word2, char *word3,
 
1473
                                           PLwdatum *wdatum, PLcword *cword)
 
1474
{
 
1475
        PLpgSQL_nsitem *ns;
 
1476
        List       *idents;
 
1477
        int                     nnames;
 
1478
 
 
1479
        idents = list_make3(makeString(word1),
 
1480
                                                makeString(word2),
 
1481
                                                makeString(word3));
 
1482
 
 
1483
        /*
 
1484
         * We should do nothing in DECLARE sections.  In SQL expressions, we
 
1485
         * really only need to make sure that RECFIELD datums are created when
 
1486
         * needed.
 
1487
         */
 
1488
        if (plpgsql_IdentifierLookup != IDENTIFIER_LOOKUP_DECLARE)
 
1489
        {
 
1490
                /*
 
1491
                 * Do a lookup in the current namespace stack. Must find a qualified
 
1492
                 * reference, else ignore.
 
1493
                 */
 
1494
                ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
 
1495
                                                           word1, word2, word3,
 
1496
                                                           &nnames);
 
1497
                if (ns != NULL && nnames == 2)
 
1498
                {
 
1499
                        switch (ns->itemtype)
 
1500
                        {
 
1501
                                case PLPGSQL_NSTYPE_REC:
 
1502
                                        {
 
1503
                                                /*
 
1504
                                                 * words 1/2 are a record name, so third word could be
 
1505
                                                 * a field in this record.
 
1506
                                                 */
 
1507
                                                PLpgSQL_recfield *new;
 
1508
 
 
1509
                                                new = palloc(sizeof(PLpgSQL_recfield));
 
1510
                                                new->dtype = PLPGSQL_DTYPE_RECFIELD;
 
1511
                                                new->fieldname = pstrdup(word3);
 
1512
                                                new->recparentno = ns->itemno;
 
1513
 
 
1514
                                                plpgsql_adddatum((PLpgSQL_datum *) new);
 
1515
 
 
1516
                                                wdatum->datum = (PLpgSQL_datum *) new;
 
1517
                                                wdatum->ident = NULL;
 
1518
                                                wdatum->quoted = false; /* not used */
 
1519
                                                wdatum->idents = idents;
 
1520
                                                return true;
 
1521
                                        }
 
1522
 
 
1523
                                case PLPGSQL_NSTYPE_ROW:
 
1524
                                        {
 
1525
                                                /*
 
1526
                                                 * words 1/2 are a row name, so third word could be a
 
1527
                                                 * field in this row.
 
1528
                                                 */
 
1529
                                                PLpgSQL_row *row;
 
1530
                                                int                     i;
 
1531
 
 
1532
                                                row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
 
1533
                                                for (i = 0; i < row->nfields; i++)
 
1534
                                                {
 
1535
                                                        if (row->fieldnames[i] &&
 
1536
                                                                strcmp(row->fieldnames[i], word3) == 0)
 
1537
                                                        {
 
1538
                                                                wdatum->datum = plpgsql_Datums[row->varnos[i]];
 
1539
                                                                wdatum->ident = NULL;
 
1540
                                                                wdatum->quoted = false; /* not used */
 
1541
                                                                wdatum->idents = idents;
 
1542
                                                                return true;
 
1543
                                                        }
 
1544
                                                }
 
1545
                                                /* fall through to return CWORD */
 
1546
                                                break;
 
1547
                                        }
 
1548
 
 
1549
                                default:
 
1550
                                        break;
 
1551
                        }
 
1552
                }
 
1553
        }
 
1554
 
 
1555
        /* Nothing found */
 
1556
        cword->idents = idents;
 
1557
        return false;
 
1558
}
 
1559
 
 
1560
 
 
1561
/* ----------
 
1562
 * plpgsql_parse_wordtype       The scanner found word%TYPE. word can be
 
1563
 *                              a variable name or a basetype.
 
1564
 *
 
1565
 * Returns datatype struct, or NULL if no match found for word.
 
1566
 * ----------
 
1567
 */
 
1568
PLpgSQL_type *
 
1569
plpgsql_parse_wordtype(char *ident)
 
1570
{
 
1571
        PLpgSQL_type *dtype;
 
1572
        PLpgSQL_nsitem *nse;
 
1573
        HeapTuple       typeTup;
 
1574
 
 
1575
        /*
 
1576
         * Do a lookup in the current namespace stack
 
1577
         */
 
1578
        nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
 
1579
                                                        ident, NULL, NULL,
 
1580
                                                        NULL);
 
1581
 
 
1582
        if (nse != NULL)
 
1583
        {
 
1584
                switch (nse->itemtype)
 
1585
                {
 
1586
                        case PLPGSQL_NSTYPE_VAR:
 
1587
                                return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
 
1588
 
 
1589
                                /* XXX perhaps allow REC/ROW here? */
 
1590
 
 
1591
                        default:
 
1592
                                return NULL;
 
1593
                }
 
1594
        }
 
1595
 
 
1596
        /*
 
1597
         * Word wasn't found in the namespace stack. Try to find a data type with
 
1598
         * that name, but ignore shell types and complex types.
 
1599
         */
 
1600
        typeTup = LookupTypeName(NULL, makeTypeName(ident), NULL);
 
1601
        if (typeTup)
 
1602
        {
 
1603
                Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
 
1604
 
 
1605
                if (!typeStruct->typisdefined ||
 
1606
                        typeStruct->typrelid != InvalidOid)
 
1607
                {
 
1608
                        ReleaseSysCache(typeTup);
 
1609
                        return NULL;
 
1610
                }
 
1611
 
 
1612
                dtype = build_datatype(typeTup, -1,
 
1613
                                                           plpgsql_curr_compile->fn_input_collation);
 
1614
 
 
1615
                ReleaseSysCache(typeTup);
 
1616
                return dtype;
 
1617
        }
 
1618
 
 
1619
        /*
 
1620
         * Nothing found - up to now it's a word without any special meaning for
 
1621
         * us.
 
1622
         */
 
1623
        return NULL;
 
1624
}
 
1625
 
 
1626
 
 
1627
/* ----------
 
1628
 * plpgsql_parse_cwordtype              Same lookup for compositeword%TYPE
 
1629
 * ----------
 
1630
 */
 
1631
PLpgSQL_type *
 
1632
plpgsql_parse_cwordtype(List *idents)
 
1633
{
 
1634
        PLpgSQL_type *dtype = NULL;
 
1635
        PLpgSQL_nsitem *nse;
 
1636
        const char *fldname;
 
1637
        Oid                     classOid;
 
1638
        HeapTuple       classtup = NULL;
 
1639
        HeapTuple       attrtup = NULL;
 
1640
        HeapTuple       typetup = NULL;
 
1641
        Form_pg_class classStruct;
 
1642
        Form_pg_attribute attrStruct;
 
1643
        MemoryContext oldCxt;
 
1644
 
 
1645
        /* Avoid memory leaks in the long-term function context */
 
1646
        oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
 
1647
 
 
1648
        if (list_length(idents) == 2)
 
1649
        {
 
1650
                /*
 
1651
                 * Do a lookup in the current namespace stack. We don't need to check
 
1652
                 * number of names matched, because we will only consider scalar
 
1653
                 * variables.
 
1654
                 */
 
1655
                nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
 
1656
                                                                strVal(linitial(idents)),
 
1657
                                                                strVal(lsecond(idents)),
 
1658
                                                                NULL,
 
1659
                                                                NULL);
 
1660
 
 
1661
                if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
 
1662
                {
 
1663
                        dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
 
1664
                        goto done;
 
1665
                }
 
1666
 
 
1667
                /*
 
1668
                 * First word could also be a table name
 
1669
                 */
 
1670
                classOid = RelnameGetRelid(strVal(linitial(idents)));
 
1671
                if (!OidIsValid(classOid))
 
1672
                        goto done;
 
1673
                fldname = strVal(lsecond(idents));
 
1674
        }
 
1675
        else if (list_length(idents) == 3)
 
1676
        {
 
1677
                RangeVar   *relvar;
 
1678
 
 
1679
                relvar = makeRangeVar(strVal(linitial(idents)),
 
1680
                                                          strVal(lsecond(idents)),
 
1681
                                                          -1);
 
1682
                classOid = RangeVarGetRelid(relvar, true);
 
1683
                if (!OidIsValid(classOid))
 
1684
                        goto done;
 
1685
                fldname = strVal(lthird(idents));
 
1686
        }
 
1687
        else
 
1688
                goto done;
 
1689
 
 
1690
        classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(classOid));
 
1691
        if (!HeapTupleIsValid(classtup))
 
1692
                goto done;
 
1693
        classStruct = (Form_pg_class) GETSTRUCT(classtup);
 
1694
 
 
1695
        /*
 
1696
         * It must be a relation, sequence, view, or type
 
1697
         */
 
1698
        if (classStruct->relkind != RELKIND_RELATION &&
 
1699
                classStruct->relkind != RELKIND_SEQUENCE &&
 
1700
                classStruct->relkind != RELKIND_VIEW &&
 
1701
                classStruct->relkind != RELKIND_COMPOSITE_TYPE)
 
1702
                goto done;
 
1703
 
 
1704
        /*
 
1705
         * Fetch the named table field and its type
 
1706
         */
 
1707
        attrtup = SearchSysCacheAttName(classOid, fldname);
 
1708
        if (!HeapTupleIsValid(attrtup))
 
1709
                goto done;
 
1710
        attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
 
1711
 
 
1712
        typetup = SearchSysCache1(TYPEOID,
 
1713
                                                          ObjectIdGetDatum(attrStruct->atttypid));
 
1714
        if (!HeapTupleIsValid(typetup))
 
1715
                elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
 
1716
 
 
1717
        /*
 
1718
         * Found that - build a compiler type struct in the caller's cxt and
 
1719
         * return it
 
1720
         */
 
1721
        MemoryContextSwitchTo(oldCxt);
 
1722
        dtype = build_datatype(typetup,
 
1723
                                                   attrStruct->atttypmod,
 
1724
                                                   attrStruct->attcollation);
 
1725
        MemoryContextSwitchTo(compile_tmp_cxt);
 
1726
 
 
1727
done:
 
1728
        if (HeapTupleIsValid(classtup))
 
1729
                ReleaseSysCache(classtup);
 
1730
        if (HeapTupleIsValid(attrtup))
 
1731
                ReleaseSysCache(attrtup);
 
1732
        if (HeapTupleIsValid(typetup))
 
1733
                ReleaseSysCache(typetup);
 
1734
 
 
1735
        MemoryContextSwitchTo(oldCxt);
 
1736
        return dtype;
 
1737
}
 
1738
 
 
1739
/* ----------
 
1740
 * plpgsql_parse_wordrowtype            Scanner found word%ROWTYPE.
 
1741
 *                                      So word must be a table name.
 
1742
 * ----------
 
1743
 */
 
1744
PLpgSQL_type *
 
1745
plpgsql_parse_wordrowtype(char *ident)
 
1746
{
 
1747
        Oid                     classOid;
 
1748
 
 
1749
        /* Lookup the relation */
 
1750
        classOid = RelnameGetRelid(ident);
 
1751
        if (!OidIsValid(classOid))
 
1752
                ereport(ERROR,
 
1753
                                (errcode(ERRCODE_UNDEFINED_TABLE),
 
1754
                                 errmsg("relation \"%s\" does not exist", ident)));
 
1755
 
 
1756
        /* Build and return the row type struct */
 
1757
        return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
 
1758
}
 
1759
 
 
1760
/* ----------
 
1761
 * plpgsql_parse_cwordrowtype           Scanner found compositeword%ROWTYPE.
 
1762
 *                      So word must be a namespace qualified table name.
 
1763
 * ----------
 
1764
 */
 
1765
PLpgSQL_type *
 
1766
plpgsql_parse_cwordrowtype(List *idents)
 
1767
{
 
1768
        Oid                     classOid;
 
1769
        RangeVar   *relvar;
 
1770
        MemoryContext oldCxt;
 
1771
 
 
1772
        if (list_length(idents) != 2)
 
1773
                return NULL;
 
1774
 
 
1775
        /* Avoid memory leaks in long-term function context */
 
1776
        oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
 
1777
 
 
1778
        /* Lookup the relation */
 
1779
        relvar = makeRangeVar(strVal(linitial(idents)),
 
1780
                                                  strVal(lsecond(idents)),
 
1781
                                                  -1);
 
1782
        classOid = RangeVarGetRelid(relvar, true);
 
1783
        if (!OidIsValid(classOid))
 
1784
                ereport(ERROR,
 
1785
                                (errcode(ERRCODE_UNDEFINED_TABLE),
 
1786
                                 errmsg("relation \"%s.%s\" does not exist",
 
1787
                                                strVal(linitial(idents)), strVal(lsecond(idents)))));
 
1788
 
 
1789
        MemoryContextSwitchTo(oldCxt);
 
1790
 
 
1791
        /* Build and return the row type struct */
 
1792
        return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
 
1793
}
 
1794
 
 
1795
/*
 
1796
 * plpgsql_build_variable - build a datum-array entry of a given
 
1797
 * datatype
 
1798
 *
 
1799
 * The returned struct may be a PLpgSQL_var, PLpgSQL_row, or
 
1800
 * PLpgSQL_rec depending on the given datatype, and is allocated via
 
1801
 * palloc.      The struct is automatically added to the current datum
 
1802
 * array, and optionally to the current namespace.
 
1803
 */
 
1804
PLpgSQL_variable *
 
1805
plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype,
 
1806
                                           bool add2namespace)
 
1807
{
 
1808
        PLpgSQL_variable *result;
 
1809
 
 
1810
        switch (dtype->ttype)
 
1811
        {
 
1812
                case PLPGSQL_TTYPE_SCALAR:
 
1813
                        {
 
1814
                                /* Ordinary scalar datatype */
 
1815
                                PLpgSQL_var *var;
 
1816
 
 
1817
                                var = palloc0(sizeof(PLpgSQL_var));
 
1818
                                var->dtype = PLPGSQL_DTYPE_VAR;
 
1819
                                var->refname = pstrdup(refname);
 
1820
                                var->lineno = lineno;
 
1821
                                var->datatype = dtype;
 
1822
                                /* other fields might be filled by caller */
 
1823
 
 
1824
                                /* preset to NULL */
 
1825
                                var->value = 0;
 
1826
                                var->isnull = true;
 
1827
                                var->freeval = false;
 
1828
 
 
1829
                                plpgsql_adddatum((PLpgSQL_datum *) var);
 
1830
                                if (add2namespace)
 
1831
                                        plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
 
1832
                                                                           var->dno,
 
1833
                                                                           refname);
 
1834
                                result = (PLpgSQL_variable *) var;
 
1835
                                break;
 
1836
                        }
 
1837
                case PLPGSQL_TTYPE_ROW:
 
1838
                        {
 
1839
                                /* Composite type -- build a row variable */
 
1840
                                PLpgSQL_row *row;
 
1841
 
 
1842
                                row = build_row_from_class(dtype->typrelid);
 
1843
 
 
1844
                                row->dtype = PLPGSQL_DTYPE_ROW;
 
1845
                                row->refname = pstrdup(refname);
 
1846
                                row->lineno = lineno;
 
1847
 
 
1848
                                plpgsql_adddatum((PLpgSQL_datum *) row);
 
1849
                                if (add2namespace)
 
1850
                                        plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
 
1851
                                                                           row->dno,
 
1852
                                                                           refname);
 
1853
                                result = (PLpgSQL_variable *) row;
 
1854
                                break;
 
1855
                        }
 
1856
                case PLPGSQL_TTYPE_REC:
 
1857
                        {
 
1858
                                /* "record" type -- build a record variable */
 
1859
                                PLpgSQL_rec *rec;
 
1860
 
 
1861
                                rec = plpgsql_build_record(refname, lineno, add2namespace);
 
1862
                                result = (PLpgSQL_variable *) rec;
 
1863
                                break;
 
1864
                        }
 
1865
                case PLPGSQL_TTYPE_PSEUDO:
 
1866
                        ereport(ERROR,
 
1867
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
1868
                                         errmsg("variable \"%s\" has pseudo-type %s",
 
1869
                                                        refname, format_type_be(dtype->typoid))));
 
1870
                        result = NULL;          /* keep compiler quiet */
 
1871
                        break;
 
1872
                default:
 
1873
                        elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
 
1874
                        result = NULL;          /* keep compiler quiet */
 
1875
                        break;
 
1876
        }
 
1877
 
 
1878
        return result;
 
1879
}
 
1880
 
 
1881
/*
 
1882
 * Build empty named record variable, and optionally add it to namespace
 
1883
 */
 
1884
PLpgSQL_rec *
 
1885
plpgsql_build_record(const char *refname, int lineno, bool add2namespace)
 
1886
{
 
1887
        PLpgSQL_rec *rec;
 
1888
 
 
1889
        rec = palloc0(sizeof(PLpgSQL_rec));
 
1890
        rec->dtype = PLPGSQL_DTYPE_REC;
 
1891
        rec->refname = pstrdup(refname);
 
1892
        rec->lineno = lineno;
 
1893
        rec->tup = NULL;
 
1894
        rec->tupdesc = NULL;
 
1895
        rec->freetup = false;
 
1896
        plpgsql_adddatum((PLpgSQL_datum *) rec);
 
1897
        if (add2namespace)
 
1898
                plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->dno, rec->refname);
 
1899
 
 
1900
        return rec;
 
1901
}
 
1902
 
 
1903
/*
 
1904
 * Build a row-variable data structure given the pg_class OID.
 
1905
 */
 
1906
static PLpgSQL_row *
 
1907
build_row_from_class(Oid classOid)
 
1908
{
 
1909
        PLpgSQL_row *row;
 
1910
        Relation        rel;
 
1911
        Form_pg_class classStruct;
 
1912
        const char *relname;
 
1913
        int                     i;
 
1914
 
 
1915
        /*
 
1916
         * Open the relation to get info.
 
1917
         */
 
1918
        rel = relation_open(classOid, AccessShareLock);
 
1919
        classStruct = RelationGetForm(rel);
 
1920
        relname = RelationGetRelationName(rel);
 
1921
 
 
1922
        /* accept relation, sequence, view, or composite type entries */
 
1923
        if (classStruct->relkind != RELKIND_RELATION &&
 
1924
                classStruct->relkind != RELKIND_SEQUENCE &&
 
1925
                classStruct->relkind != RELKIND_VIEW &&
 
1926
                classStruct->relkind != RELKIND_COMPOSITE_TYPE)
 
1927
                ereport(ERROR,
 
1928
                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
 
1929
                                 errmsg("relation \"%s\" is not a table", relname)));
 
1930
 
 
1931
        /*
 
1932
         * Create a row datum entry and all the required variables that it will
 
1933
         * point to.
 
1934
         */
 
1935
        row = palloc0(sizeof(PLpgSQL_row));
 
1936
        row->dtype = PLPGSQL_DTYPE_ROW;
 
1937
        row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
 
1938
        row->nfields = classStruct->relnatts;
 
1939
        row->fieldnames = palloc(sizeof(char *) * row->nfields);
 
1940
        row->varnos = palloc(sizeof(int) * row->nfields);
 
1941
 
 
1942
        for (i = 0; i < row->nfields; i++)
 
1943
        {
 
1944
                Form_pg_attribute attrStruct;
 
1945
 
 
1946
                /*
 
1947
                 * Get the attribute and check for dropped column
 
1948
                 */
 
1949
                attrStruct = row->rowtupdesc->attrs[i];
 
1950
 
 
1951
                if (!attrStruct->attisdropped)
 
1952
                {
 
1953
                        char       *attname;
 
1954
                        char            refname[(NAMEDATALEN * 2) + 100];
 
1955
                        PLpgSQL_variable *var;
 
1956
 
 
1957
                        attname = NameStr(attrStruct->attname);
 
1958
                        snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
 
1959
 
 
1960
                        /*
 
1961
                         * Create the internal variable for the field
 
1962
                         *
 
1963
                         * We know if the table definitions contain a default value or if
 
1964
                         * the field is declared in the table as NOT NULL. But it's
 
1965
                         * possible to create a table field as NOT NULL without a default
 
1966
                         * value and that would lead to problems later when initializing
 
1967
                         * the variables due to entering a block at execution time. Thus
 
1968
                         * we ignore this information for now.
 
1969
                         */
 
1970
                        var = plpgsql_build_variable(refname, 0,
 
1971
                                                                 plpgsql_build_datatype(attrStruct->atttypid,
 
1972
                                                                                                                attrStruct->atttypmod,
 
1973
                                                                                                   attrStruct->attcollation),
 
1974
                                                                                 false);
 
1975
 
 
1976
                        /* Add the variable to the row */
 
1977
                        row->fieldnames[i] = attname;
 
1978
                        row->varnos[i] = var->dno;
 
1979
                }
 
1980
                else
 
1981
                {
 
1982
                        /* Leave a hole in the row structure for the dropped col */
 
1983
                        row->fieldnames[i] = NULL;
 
1984
                        row->varnos[i] = -1;
 
1985
                }
 
1986
        }
 
1987
 
 
1988
        relation_close(rel, AccessShareLock);
 
1989
 
 
1990
        return row;
 
1991
}
 
1992
 
 
1993
/*
 
1994
 * Build a row-variable data structure given the component variables.
 
1995
 */
 
1996
static PLpgSQL_row *
 
1997
build_row_from_vars(PLpgSQL_variable **vars, int numvars)
 
1998
{
 
1999
        PLpgSQL_row *row;
 
2000
        int                     i;
 
2001
 
 
2002
        row = palloc0(sizeof(PLpgSQL_row));
 
2003
        row->dtype = PLPGSQL_DTYPE_ROW;
 
2004
        row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
 
2005
        row->nfields = numvars;
 
2006
        row->fieldnames = palloc(numvars * sizeof(char *));
 
2007
        row->varnos = palloc(numvars * sizeof(int));
 
2008
 
 
2009
        for (i = 0; i < numvars; i++)
 
2010
        {
 
2011
                PLpgSQL_variable *var = vars[i];
 
2012
                Oid                     typoid = RECORDOID;
 
2013
                int32           typmod = -1;
 
2014
                Oid                     typcoll = InvalidOid;
 
2015
 
 
2016
                switch (var->dtype)
 
2017
                {
 
2018
                        case PLPGSQL_DTYPE_VAR:
 
2019
                                typoid = ((PLpgSQL_var *) var)->datatype->typoid;
 
2020
                                typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
 
2021
                                typcoll = ((PLpgSQL_var *) var)->datatype->collation;
 
2022
                                break;
 
2023
 
 
2024
                        case PLPGSQL_DTYPE_REC:
 
2025
                                break;
 
2026
 
 
2027
                        case PLPGSQL_DTYPE_ROW:
 
2028
                                if (((PLpgSQL_row *) var)->rowtupdesc)
 
2029
                                {
 
2030
                                        typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
 
2031
                                        typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
 
2032
                                        /* composite types have no collation */
 
2033
                                }
 
2034
                                break;
 
2035
 
 
2036
                        default:
 
2037
                                elog(ERROR, "unrecognized dtype: %d", var->dtype);
 
2038
                }
 
2039
 
 
2040
                row->fieldnames[i] = var->refname;
 
2041
                row->varnos[i] = var->dno;
 
2042
 
 
2043
                TupleDescInitEntry(row->rowtupdesc, i + 1,
 
2044
                                                   var->refname,
 
2045
                                                   typoid, typmod,
 
2046
                                                   0);
 
2047
                TupleDescInitEntryCollation(row->rowtupdesc, i + 1, typcoll);
 
2048
        }
 
2049
 
 
2050
        return row;
 
2051
}
 
2052
 
 
2053
/*
 
2054
 * plpgsql_build_datatype
 
2055
 *              Build PLpgSQL_type struct given type OID, typmod, and collation.
 
2056
 *
 
2057
 * If collation is not InvalidOid then it overrides the type's default
 
2058
 * collation.  But collation is ignored if the datatype is non-collatable.
 
2059
 */
 
2060
PLpgSQL_type *
 
2061
plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
 
2062
{
 
2063
        HeapTuple       typeTup;
 
2064
        PLpgSQL_type *typ;
 
2065
 
 
2066
        typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
 
2067
        if (!HeapTupleIsValid(typeTup))
 
2068
                elog(ERROR, "cache lookup failed for type %u", typeOid);
 
2069
 
 
2070
        typ = build_datatype(typeTup, typmod, collation);
 
2071
 
 
2072
        ReleaseSysCache(typeTup);
 
2073
 
 
2074
        return typ;
 
2075
}
 
2076
 
 
2077
/*
 
2078
 * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
 
2079
 */
 
2080
static PLpgSQL_type *
 
2081
build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
 
2082
{
 
2083
        Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
 
2084
        PLpgSQL_type *typ;
 
2085
 
 
2086
        if (!typeStruct->typisdefined)
 
2087
                ereport(ERROR,
 
2088
                                (errcode(ERRCODE_UNDEFINED_OBJECT),
 
2089
                                 errmsg("type \"%s\" is only a shell",
 
2090
                                                NameStr(typeStruct->typname))));
 
2091
 
 
2092
        typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
 
2093
 
 
2094
        typ->typname = pstrdup(NameStr(typeStruct->typname));
 
2095
        typ->typoid = HeapTupleGetOid(typeTup);
 
2096
        switch (typeStruct->typtype)
 
2097
        {
 
2098
                case TYPTYPE_BASE:
 
2099
                case TYPTYPE_DOMAIN:
 
2100
                case TYPTYPE_ENUM:
 
2101
                        typ->ttype = PLPGSQL_TTYPE_SCALAR;
 
2102
                        break;
 
2103
                case TYPTYPE_COMPOSITE:
 
2104
                        Assert(OidIsValid(typeStruct->typrelid));
 
2105
                        typ->ttype = PLPGSQL_TTYPE_ROW;
 
2106
                        break;
 
2107
                case TYPTYPE_PSEUDO:
 
2108
                        if (typ->typoid == RECORDOID)
 
2109
                                typ->ttype = PLPGSQL_TTYPE_REC;
 
2110
                        else
 
2111
                                typ->ttype = PLPGSQL_TTYPE_PSEUDO;
 
2112
                        break;
 
2113
                default:
 
2114
                        elog(ERROR, "unrecognized typtype: %d",
 
2115
                                 (int) typeStruct->typtype);
 
2116
                        break;
 
2117
        }
 
2118
        typ->typlen = typeStruct->typlen;
 
2119
        typ->typbyval = typeStruct->typbyval;
 
2120
        typ->typrelid = typeStruct->typrelid;
 
2121
        typ->typioparam = getTypeIOParam(typeTup);
 
2122
        typ->collation = typeStruct->typcollation;
 
2123
        if (OidIsValid(collation) && OidIsValid(typ->collation))
 
2124
                typ->collation = collation;
 
2125
        fmgr_info(typeStruct->typinput, &(typ->typinput));
 
2126
        typ->atttypmod = typmod;
 
2127
 
 
2128
        return typ;
 
2129
}
 
2130
 
 
2131
/*
 
2132
 *      plpgsql_recognize_err_condition
 
2133
 *              Check condition name and translate it to SQLSTATE.
 
2134
 *
 
2135
 * Note: there are some cases where the same condition name has multiple
 
2136
 * entries in the table.  We arbitrarily return the first match.
 
2137
 */
 
2138
int
 
2139
plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
 
2140
{
 
2141
        int                     i;
 
2142
 
 
2143
        if (allow_sqlstate)
 
2144
        {
 
2145
                if (strlen(condname) == 5 &&
 
2146
                        strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
 
2147
                        return MAKE_SQLSTATE(condname[0],
 
2148
                                                                 condname[1],
 
2149
                                                                 condname[2],
 
2150
                                                                 condname[3],
 
2151
                                                                 condname[4]);
 
2152
        }
 
2153
 
 
2154
        for (i = 0; exception_label_map[i].label != NULL; i++)
 
2155
        {
 
2156
                if (strcmp(condname, exception_label_map[i].label) == 0)
 
2157
                        return exception_label_map[i].sqlerrstate;
 
2158
        }
 
2159
 
 
2160
        ereport(ERROR,
 
2161
                        (errcode(ERRCODE_UNDEFINED_OBJECT),
 
2162
                         errmsg("unrecognized exception condition \"%s\"",
 
2163
                                        condname)));
 
2164
        return 0;                                       /* keep compiler quiet */
 
2165
}
 
2166
 
 
2167
/*
 
2168
 * plpgsql_parse_err_condition
 
2169
 *              Generate PLpgSQL_condition entry(s) for an exception condition name
 
2170
 *
 
2171
 * This has to be able to return a list because there are some duplicate
 
2172
 * names in the table of error code names.
 
2173
 */
 
2174
PLpgSQL_condition *
 
2175
plpgsql_parse_err_condition(char *condname)
 
2176
{
 
2177
        int                     i;
 
2178
        PLpgSQL_condition *new;
 
2179
        PLpgSQL_condition *prev;
 
2180
 
 
2181
        /*
 
2182
         * XXX Eventually we will want to look for user-defined exception names
 
2183
         * here.
 
2184
         */
 
2185
 
 
2186
        /*
 
2187
         * OTHERS is represented as code 0 (which would map to '00000', but we
 
2188
         * have no need to represent that as an exception condition).
 
2189
         */
 
2190
        if (strcmp(condname, "others") == 0)
 
2191
        {
 
2192
                new = palloc(sizeof(PLpgSQL_condition));
 
2193
                new->sqlerrstate = 0;
 
2194
                new->condname = condname;
 
2195
                new->next = NULL;
 
2196
                return new;
 
2197
        }
 
2198
 
 
2199
        prev = NULL;
 
2200
        for (i = 0; exception_label_map[i].label != NULL; i++)
 
2201
        {
 
2202
                if (strcmp(condname, exception_label_map[i].label) == 0)
 
2203
                {
 
2204
                        new = palloc(sizeof(PLpgSQL_condition));
 
2205
                        new->sqlerrstate = exception_label_map[i].sqlerrstate;
 
2206
                        new->condname = condname;
 
2207
                        new->next = prev;
 
2208
                        prev = new;
 
2209
                }
 
2210
        }
 
2211
 
 
2212
        if (!prev)
 
2213
                ereport(ERROR,
 
2214
                                (errcode(ERRCODE_UNDEFINED_OBJECT),
 
2215
                                 errmsg("unrecognized exception condition \"%s\"",
 
2216
                                                condname)));
 
2217
 
 
2218
        return prev;
 
2219
}
 
2220
 
 
2221
/* ----------
 
2222
 * plpgsql_adddatum                     Add a variable, record or row
 
2223
 *                                      to the compiler's datum list.
 
2224
 * ----------
 
2225
 */
 
2226
void
 
2227
plpgsql_adddatum(PLpgSQL_datum *new)
 
2228
{
 
2229
        if (plpgsql_nDatums == datums_alloc)
 
2230
        {
 
2231
                datums_alloc *= 2;
 
2232
                plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
 
2233
        }
 
2234
 
 
2235
        new->dno = plpgsql_nDatums;
 
2236
        plpgsql_Datums[plpgsql_nDatums++] = new;
 
2237
}
 
2238
 
 
2239
 
 
2240
/* ----------
 
2241
 * plpgsql_add_initdatums               Make an array of the datum numbers of
 
2242
 *                                      all the simple VAR datums created since the last call
 
2243
 *                                      to this function.
 
2244
 *
 
2245
 * If varnos is NULL, we just forget any datum entries created since the
 
2246
 * last call.
 
2247
 *
 
2248
 * This is used around a DECLARE section to create a list of the VARs
 
2249
 * that have to be initialized at block entry.  Note that VARs can also
 
2250
 * be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
 
2251
 * the responsibility of special-purpose code to initialize them.
 
2252
 * ----------
 
2253
 */
 
2254
int
 
2255
plpgsql_add_initdatums(int **varnos)
 
2256
{
 
2257
        int                     i;
 
2258
        int                     n = 0;
 
2259
 
 
2260
        for (i = datums_last; i < plpgsql_nDatums; i++)
 
2261
        {
 
2262
                switch (plpgsql_Datums[i]->dtype)
 
2263
                {
 
2264
                        case PLPGSQL_DTYPE_VAR:
 
2265
                                n++;
 
2266
                                break;
 
2267
 
 
2268
                        default:
 
2269
                                break;
 
2270
                }
 
2271
        }
 
2272
 
 
2273
        if (varnos != NULL)
 
2274
        {
 
2275
                if (n > 0)
 
2276
                {
 
2277
                        *varnos = (int *) palloc(sizeof(int) * n);
 
2278
 
 
2279
                        n = 0;
 
2280
                        for (i = datums_last; i < plpgsql_nDatums; i++)
 
2281
                        {
 
2282
                                switch (plpgsql_Datums[i]->dtype)
 
2283
                                {
 
2284
                                        case PLPGSQL_DTYPE_VAR:
 
2285
                                                (*varnos)[n++] = plpgsql_Datums[i]->dno;
 
2286
 
 
2287
                                        default:
 
2288
                                                break;
 
2289
                                }
 
2290
                        }
 
2291
                }
 
2292
                else
 
2293
                        *varnos = NULL;
 
2294
        }
 
2295
 
 
2296
        datums_last = plpgsql_nDatums;
 
2297
        return n;
 
2298
}
 
2299
 
 
2300
 
 
2301
/*
 
2302
 * Compute the hashkey for a given function invocation
 
2303
 *
 
2304
 * The hashkey is returned into the caller-provided storage at *hashkey.
 
2305
 */
 
2306
static void
 
2307
compute_function_hashkey(FunctionCallInfo fcinfo,
 
2308
                                                 Form_pg_proc procStruct,
 
2309
                                                 PLpgSQL_func_hashkey *hashkey,
 
2310
                                                 bool forValidator)
 
2311
{
 
2312
        /* Make sure any unused bytes of the struct are zero */
 
2313
        MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
 
2314
 
 
2315
        /* get function OID */
 
2316
        hashkey->funcOid = fcinfo->flinfo->fn_oid;
 
2317
 
 
2318
        /* get call context */
 
2319
        hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
 
2320
 
 
2321
        /*
 
2322
         * if trigger, get relation OID.  In validation mode we do not know what
 
2323
         * relation is intended to be used, so we leave trigrelOid zero; the hash
 
2324
         * entry built in this case will never really be used.
 
2325
         */
 
2326
        if (hashkey->isTrigger && !forValidator)
 
2327
        {
 
2328
                TriggerData *trigdata = (TriggerData *) fcinfo->context;
 
2329
 
 
2330
                hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
 
2331
        }
 
2332
 
 
2333
        /* get input collation, if known */
 
2334
        hashkey->inputCollation = fcinfo->fncollation;
 
2335
 
 
2336
        if (procStruct->pronargs > 0)
 
2337
        {
 
2338
                /* get the argument types */
 
2339
                memcpy(hashkey->argtypes, procStruct->proargtypes.values,
 
2340
                           procStruct->pronargs * sizeof(Oid));
 
2341
 
 
2342
                /* resolve any polymorphic argument types */
 
2343
                plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
 
2344
                                                                                         hashkey->argtypes,
 
2345
                                                                                         NULL,
 
2346
                                                                                         fcinfo->flinfo->fn_expr,
 
2347
                                                                                         forValidator,
 
2348
                                                                                         NameStr(procStruct->proname));
 
2349
        }
 
2350
}
 
2351
 
 
2352
/*
 
2353
 * This is the same as the standard resolve_polymorphic_argtypes() function,
 
2354
 * but with a special case for validation: assume that polymorphic arguments
 
2355
 * are integer or integer-array.  Also, we go ahead and report the error
 
2356
 * if we can't resolve the types.
 
2357
 */
 
2358
static void
 
2359
plpgsql_resolve_polymorphic_argtypes(int numargs,
 
2360
                                                                         Oid *argtypes, char *argmodes,
 
2361
                                                                         Node *call_expr, bool forValidator,
 
2362
                                                                         const char *proname)
 
2363
{
 
2364
        int                     i;
 
2365
 
 
2366
        if (!forValidator)
 
2367
        {
 
2368
                /* normal case, pass to standard routine */
 
2369
                if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
 
2370
                                                                                  call_expr))
 
2371
                        ereport(ERROR,
 
2372
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
2373
                                         errmsg("could not determine actual argument "
 
2374
                                                        "type for polymorphic function \"%s\"",
 
2375
                                                        proname)));
 
2376
        }
 
2377
        else
 
2378
        {
 
2379
                /* special validation case */
 
2380
                for (i = 0; i < numargs; i++)
 
2381
                {
 
2382
                        switch (argtypes[i])
 
2383
                        {
 
2384
                                case ANYELEMENTOID:
 
2385
                                case ANYNONARRAYOID:
 
2386
                                case ANYENUMOID:                /* XXX dubious */
 
2387
                                        argtypes[i] = INT4OID;
 
2388
                                        break;
 
2389
                                case ANYARRAYOID:
 
2390
                                        argtypes[i] = INT4ARRAYOID;
 
2391
                                        break;
 
2392
                                default:
 
2393
                                        break;
 
2394
                        }
 
2395
                }
 
2396
        }
 
2397
}
 
2398
 
 
2399
/*
 
2400
 * delete_function - clean up as much as possible of a stale function cache
 
2401
 *
 
2402
 * We can't release the PLpgSQL_function struct itself, because of the
 
2403
 * possibility that there are fn_extra pointers to it.  We can release
 
2404
 * the subsidiary storage, but only if there are no active evaluations
 
2405
 * in progress.  Otherwise we'll just leak that storage.  Since the
 
2406
 * case would only occur if a pg_proc update is detected during a nested
 
2407
 * recursive call on the function, a leak seems acceptable.
 
2408
 *
 
2409
 * Note that this can be called more than once if there are multiple fn_extra
 
2410
 * pointers to the same function cache.  Hence be careful not to do things
 
2411
 * twice.
 
2412
 */
 
2413
static void
 
2414
delete_function(PLpgSQL_function *func)
 
2415
{
 
2416
        /* remove function from hash table (might be done already) */
 
2417
        plpgsql_HashTableDelete(func);
 
2418
 
 
2419
        /* release the function's storage if safe and not done already */
 
2420
        if (func->use_count == 0)
 
2421
                plpgsql_free_function_memory(func);
 
2422
}
 
2423
 
 
2424
/* exported so we can call it from plpgsql_init() */
 
2425
void
 
2426
plpgsql_HashTableInit(void)
 
2427
{
 
2428
        HASHCTL         ctl;
 
2429
 
 
2430
        /* don't allow double-initialization */
 
2431
        Assert(plpgsql_HashTable == NULL);
 
2432
 
 
2433
        memset(&ctl, 0, sizeof(ctl));
 
2434
        ctl.keysize = sizeof(PLpgSQL_func_hashkey);
 
2435
        ctl.entrysize = sizeof(plpgsql_HashEnt);
 
2436
        ctl.hash = tag_hash;
 
2437
        plpgsql_HashTable = hash_create("PLpgSQL function cache",
 
2438
                                                                        FUNCS_PER_USER,
 
2439
                                                                        &ctl,
 
2440
                                                                        HASH_ELEM | HASH_FUNCTION);
 
2441
}
 
2442
 
 
2443
static PLpgSQL_function *
 
2444
plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
 
2445
{
 
2446
        plpgsql_HashEnt *hentry;
 
2447
 
 
2448
        hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
 
2449
                                                                                         (void *) func_key,
 
2450
                                                                                         HASH_FIND,
 
2451
                                                                                         NULL);
 
2452
        if (hentry)
 
2453
                return hentry->function;
 
2454
        else
 
2455
                return NULL;
 
2456
}
 
2457
 
 
2458
static void
 
2459
plpgsql_HashTableInsert(PLpgSQL_function *function,
 
2460
                                                PLpgSQL_func_hashkey *func_key)
 
2461
{
 
2462
        plpgsql_HashEnt *hentry;
 
2463
        bool            found;
 
2464
 
 
2465
        hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
 
2466
                                                                                         (void *) func_key,
 
2467
                                                                                         HASH_ENTER,
 
2468
                                                                                         &found);
 
2469
        if (found)
 
2470
                elog(WARNING, "trying to insert a function that already exists");
 
2471
 
 
2472
        hentry->function = function;
 
2473
        /* prepare back link from function to hashtable key */
 
2474
        function->fn_hashkey = &hentry->key;
 
2475
}
 
2476
 
 
2477
static void
 
2478
plpgsql_HashTableDelete(PLpgSQL_function *function)
 
2479
{
 
2480
        plpgsql_HashEnt *hentry;
 
2481
 
 
2482
        /* do nothing if not in table */
 
2483
        if (function->fn_hashkey == NULL)
 
2484
                return;
 
2485
 
 
2486
        hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
 
2487
                                                                                         (void *) function->fn_hashkey,
 
2488
                                                                                         HASH_REMOVE,
 
2489
                                                                                         NULL);
 
2490
        if (hentry == NULL)
 
2491
                elog(WARNING, "trying to delete function that does not exist");
 
2492
 
 
2493
        /* remove back link, which no longer points to allocated storage */
 
2494
        function->fn_hashkey = NULL;
 
2495
}