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