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