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