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