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