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