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