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-2020, 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/guc.h"
30 #include "utils/lsyscache.h"
31 #include "utils/memutils.h"
32 #include "utils/regproc.h"
33 #include "utils/rel.h"
34 #include "utils/syscache.h"
35 #include "utils/typcache.h"
36 
37 /* ----------
38  * Our own local and global variables
39  * ----------
40  */
42 
43 static int datums_alloc;
46 static int datums_last;
47 
49 bool plpgsql_DumpExecTree = false;
50 bool plpgsql_check_syntax = false;
51 
53 
54 /* A context appropriate for short-term allocs during compilation */
56 
57 /* ----------
58  * Hash table for compiled functions
59  * ----------
60  */
61 static HTAB *plpgsql_HashTable = NULL;
62 
63 typedef struct plpgsql_hashent
64 {
66  PLpgSQL_function *function;
68 
69 #define FUNCS_PER_USER 128 /* initial table size */
70 
71 /* ----------
72  * Lookup table for EXCEPTION condition names
73  * ----------
74  */
75 typedef struct
76 {
77  const char *label;
80 
82 #include "plerrcodes.h" /* pgrminclude ignore */
83  {NULL, 0}
84 };
85 
86 
87 /* ----------
88  * static prototypes
89  * ----------
90  */
92  HeapTuple procTup,
93  PLpgSQL_function *function,
94  PLpgSQL_func_hashkey *hashkey,
95  bool forValidator);
96 static void plpgsql_compile_error_callback(void *arg);
97 static void add_parameter_name(PLpgSQL_nsitem_type itemtype, int itemno, const char *name);
98 static void add_dummy_return(PLpgSQL_function *function);
99 static Node *plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref);
100 static Node *plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var);
101 static Node *plpgsql_param_ref(ParseState *pstate, ParamRef *pref);
102 static Node *resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr,
103  ColumnRef *cref, bool error_if_no_field);
104 static Node *make_datum_param(PLpgSQL_expr *expr, int dno, int location);
105 static PLpgSQL_row *build_row_from_vars(PLpgSQL_variable **vars, int numvars);
106 static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod,
107  Oid collation, TypeName *origtypname);
108 static void plpgsql_start_datums(void);
109 static void plpgsql_finish_datums(PLpgSQL_function *function);
110 static void compute_function_hashkey(FunctionCallInfo fcinfo,
111  Form_pg_proc procStruct,
112  PLpgSQL_func_hashkey *hashkey,
113  bool forValidator);
114 static void plpgsql_resolve_polymorphic_argtypes(int numargs,
115  Oid *argtypes, char *argmodes,
116  Node *call_expr, bool forValidator,
117  const char *proname);
119 static void plpgsql_HashTableInsert(PLpgSQL_function *function,
120  PLpgSQL_func_hashkey *func_key);
121 static void plpgsql_HashTableDelete(PLpgSQL_function *function);
122 static void delete_function(PLpgSQL_function *func);
123 
124 /* ----------
125  * plpgsql_compile Make an execution tree for a PL/pgSQL function.
126  *
127  * If forValidator is true, we're only compiling for validation purposes,
128  * and so some checks are skipped.
129  *
130  * Note: it's important for this to fall through quickly if the function
131  * has already been compiled.
132  * ----------
133  */
135 plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
136 {
137  Oid funcOid = fcinfo->flinfo->fn_oid;
138  HeapTuple procTup;
139  Form_pg_proc procStruct;
140  PLpgSQL_function *function;
141  PLpgSQL_func_hashkey hashkey;
142  bool function_valid = false;
143  bool hashkey_valid = false;
144 
145  /*
146  * Lookup the pg_proc tuple by Oid; we'll need it in any case
147  */
148  procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
149  if (!HeapTupleIsValid(procTup))
150  elog(ERROR, "cache lookup failed for function %u", funcOid);
151  procStruct = (Form_pg_proc) GETSTRUCT(procTup);
152 
153  /*
154  * See if there's already a cache entry for the current FmgrInfo. If not,
155  * try to find one in the hash table.
156  */
157  function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
158 
159 recheck:
160  if (!function)
161  {
162  /* Compute hashkey using function signature and actual arg types */
163  compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
164  hashkey_valid = true;
165 
166  /* And do the lookup */
167  function = plpgsql_HashTableLookup(&hashkey);
168  }
169 
170  if (function)
171  {
172  /* We have a compiled function, but is it still valid? */
173  if (function->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
174  ItemPointerEquals(&function->fn_tid, &procTup->t_self))
175  function_valid = true;
176  else
177  {
178  /*
179  * Nope, so remove it from hashtable and try to drop associated
180  * storage (if not done already).
181  */
182  delete_function(function);
183 
184  /*
185  * If the function isn't in active use then we can overwrite the
186  * func struct with new data, allowing any other existing fn_extra
187  * pointers to make use of the new definition on their next use.
188  * If it is in use then just leave it alone and make a new one.
189  * (The active invocations will run to completion using the
190  * previous definition, and then the cache entry will just be
191  * leaked; doesn't seem worth adding code to clean it up, given
192  * what a corner case this is.)
193  *
194  * If we found the function struct via fn_extra then it's possible
195  * a replacement has already been made, so go back and recheck the
196  * hashtable.
197  */
198  if (function->use_count != 0)
199  {
200  function = NULL;
201  if (!hashkey_valid)
202  goto recheck;
203  }
204  }
205  }
206 
207  /*
208  * If the function wasn't found or was out-of-date, we have to compile it
209  */
210  if (!function_valid)
211  {
212  /*
213  * Calculate hashkey if we didn't already; we'll need it to store the
214  * completed function.
215  */
216  if (!hashkey_valid)
217  compute_function_hashkey(fcinfo, procStruct, &hashkey,
218  forValidator);
219 
220  /*
221  * Do the hard part.
222  */
223  function = do_compile(fcinfo, procTup, function,
224  &hashkey, forValidator);
225  }
226 
227  ReleaseSysCache(procTup);
228 
229  /*
230  * Save pointer in FmgrInfo to avoid search on subsequent calls
231  */
232  fcinfo->flinfo->fn_extra = (void *) function;
233 
234  /*
235  * Finally return the compiled function
236  */
237  return function;
238 }
239 
240 /*
241  * This is the slow part of plpgsql_compile().
242  *
243  * The passed-in "function" pointer is either NULL or an already-allocated
244  * function struct to overwrite.
245  *
246  * While compiling a function, the CurrentMemoryContext is the
247  * per-function memory context of the function we are compiling. That
248  * means a palloc() will allocate storage with the same lifetime as
249  * the function itself.
250  *
251  * Because palloc()'d storage will not be immediately freed, temporary
252  * allocations should either be performed in a short-lived memory
253  * context or explicitly pfree'd. Since not all backend functions are
254  * careful about pfree'ing their allocations, it is also wise to
255  * switch into a short-term context before calling into the
256  * backend. An appropriate context for performing short-term
257  * allocations is the plpgsql_compile_tmp_cxt.
258  *
259  * NB: this code is not re-entrant. We assume that nothing we do here could
260  * result in the invocation of another plpgsql function.
261  */
262 static PLpgSQL_function *
264  HeapTuple procTup,
265  PLpgSQL_function *function,
266  PLpgSQL_func_hashkey *hashkey,
267  bool forValidator)
268 {
269  Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
270  bool is_dml_trigger = CALLED_AS_TRIGGER(fcinfo);
271  bool is_event_trigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
272  Datum prosrcdatum;
273  bool isnull;
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 = SysCacheGetAttr(PROCOID, procTup,
299  Anum_pg_proc_prosrc, &isnull);
300  if (isnull)
301  elog(ERROR, "null prosrc");
302  proc_source = TextDatumGetCString(prosrcdatum);
303  plpgsql_scanner_init(proc_source);
304 
305  plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
306 
307  /*
308  * Setup error traceback support for ereport()
309  */
311  plerrcontext.arg = forValidator ? proc_source : NULL;
312  plerrcontext.previous = error_context_stack;
313  error_context_stack = &plerrcontext;
314 
315  /*
316  * Do extra syntax checks when validating the function definition. We skip
317  * this when actually compiling functions for execution, for performance
318  * reasons.
319  */
320  plpgsql_check_syntax = forValidator;
321 
322  /*
323  * Create the new function struct, if not done already. The function
324  * structs are never thrown away, so keep them in TopMemoryContext.
325  */
326  if (function == NULL)
327  {
328  function = (PLpgSQL_function *)
330  }
331  else
332  {
333  /* re-using a previously existing struct, so clear it out */
334  memset(function, 0, sizeof(PLpgSQL_function));
335  }
336  plpgsql_curr_compile = function;
337 
338  /*
339  * All the permanent output of compilation (e.g. parse tree) is kept in a
340  * per-function memory context, so it can be reclaimed easily.
341  */
343  "PL/pgSQL function",
345  plpgsql_compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
346 
347  function->fn_signature = format_procedure(fcinfo->flinfo->fn_oid);
349  function->fn_oid = fcinfo->flinfo->fn_oid;
350  function->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
351  function->fn_tid = procTup->t_self;
352  function->fn_input_collation = fcinfo->fncollation;
353  function->fn_cxt = func_cxt;
354  function->out_param_varno = -1; /* set up for no OUT param */
355  function->resolve_option = plpgsql_variable_conflict;
356  function->print_strict_params = plpgsql_print_strict_params;
357  /* only promote extra warnings and errors at CREATE FUNCTION time */
358  function->extra_warnings = forValidator ? plpgsql_extra_warnings : 0;
359  function->extra_errors = forValidator ? plpgsql_extra_errors : 0;
360 
361  if (is_dml_trigger)
362  function->fn_is_trigger = PLPGSQL_DML_TRIGGER;
363  else if (is_event_trigger)
364  function->fn_is_trigger = PLPGSQL_EVENT_TRIGGER;
365  else
366  function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
367 
368  function->fn_prokind = procStruct->prokind;
369 
370  function->nstatements = 0;
371 
372  /*
373  * Initialize the compiler, particularly the namespace stack. The
374  * outermost namespace contains function parameters and other special
375  * variables (such as FOUND), and is named after the function itself.
376  */
377  plpgsql_ns_init();
378  plpgsql_ns_push(NameStr(procStruct->proname), PLPGSQL_LABEL_BLOCK);
379  plpgsql_DumpExecTree = false;
381 
382  switch (function->fn_is_trigger)
383  {
384  case PLPGSQL_NOT_TRIGGER:
385 
386  /*
387  * Fetch info about the procedure's parameters. Allocations aren't
388  * needed permanently, so make them in tmp cxt.
389  *
390  * We also need to resolve any polymorphic input or output
391  * argument types. In validation mode we won't be able to, so we
392  * arbitrarily assume we are dealing with integers.
393  */
394  MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
395 
396  numargs = get_func_arg_info(procTup,
397  &argtypes, &argnames, &argmodes);
398 
399  plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
400  fcinfo->flinfo->fn_expr,
401  forValidator,
403 
404  in_arg_varnos = (int *) palloc(numargs * sizeof(int));
405  out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
406 
407  MemoryContextSwitchTo(func_cxt);
408 
409  /*
410  * Create the variables for the procedure's parameters.
411  */
412  for (i = 0; i < numargs; i++)
413  {
414  char buf[32];
415  Oid argtypeid = argtypes[i];
416  char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
417  PLpgSQL_type *argdtype;
418  PLpgSQL_variable *argvariable;
419  PLpgSQL_nsitem_type argitemtype;
420 
421  /* Create $n name for variable */
422  snprintf(buf, sizeof(buf), "$%d", i + 1);
423 
424  /* Create datatype info */
425  argdtype = plpgsql_build_datatype(argtypeid,
426  -1,
428  NULL);
429 
430  /* Disallow pseudotype argument */
431  /* (note we already replaced polymorphic types) */
432  /* (build_variable would do this, but wrong message) */
433  if (argdtype->ttype == PLPGSQL_TTYPE_PSEUDO)
434  ereport(ERROR,
435  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
436  errmsg("PL/pgSQL functions cannot accept type %s",
437  format_type_be(argtypeid))));
438 
439  /*
440  * Build variable and add to datum list. If there's a name
441  * for the argument, use that as refname, else use $n name.
442  */
443  argvariable = plpgsql_build_variable((argnames &&
444  argnames[i][0] != '\0') ?
445  argnames[i] : buf,
446  0, argdtype, false);
447 
448  if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
449  {
450  argitemtype = PLPGSQL_NSTYPE_VAR;
451  }
452  else
453  {
454  Assert(argvariable->dtype == PLPGSQL_DTYPE_REC);
455  argitemtype = PLPGSQL_NSTYPE_REC;
456  }
457 
458  /* Remember arguments in appropriate arrays */
459  if (argmode == PROARGMODE_IN ||
460  argmode == PROARGMODE_INOUT ||
461  (argmode == PROARGMODE_OUT && function->fn_prokind == PROKIND_PROCEDURE) ||
462  argmode == PROARGMODE_VARIADIC)
463  in_arg_varnos[num_in_args++] = argvariable->dno;
464  if (argmode == PROARGMODE_OUT ||
465  argmode == PROARGMODE_INOUT ||
466  argmode == PROARGMODE_TABLE)
467  out_arg_variables[num_out_args++] = argvariable;
468 
469  /* Add to namespace under the $n name */
470  add_parameter_name(argitemtype, argvariable->dno, buf);
471 
472  /* If there's a name for the argument, make an alias */
473  if (argnames && argnames[i][0] != '\0')
474  add_parameter_name(argitemtype, argvariable->dno,
475  argnames[i]);
476  }
477 
478  /*
479  * If there's just one OUT parameter, out_param_varno points
480  * directly to it. If there's more than one, build a row that
481  * holds all of them. Procedures return a row even for one OUT
482  * parameter.
483  */
484  if (num_out_args > 1 ||
485  (num_out_args == 1 && function->fn_prokind == PROKIND_PROCEDURE))
486  {
487  PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
488  num_out_args);
489 
491  function->out_param_varno = row->dno;
492  }
493  else if (num_out_args == 1)
494  function->out_param_varno = out_arg_variables[0]->dno;
495 
496  /*
497  * Check for a polymorphic returntype. If found, use the actual
498  * returntype type from the caller's FuncExpr node, if we have
499  * one. (In validation mode we arbitrarily assume we are dealing
500  * with integers.)
501  *
502  * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
503  * work; if it doesn't we're in some context that fails to make
504  * the info available.
505  */
506  rettypeid = procStruct->prorettype;
507  if (IsPolymorphicType(rettypeid))
508  {
509  if (forValidator)
510  {
511  if (rettypeid == ANYARRAYOID ||
512  rettypeid == ANYCOMPATIBLEARRAYOID)
513  rettypeid = INT4ARRAYOID;
514  else if (rettypeid == ANYRANGEOID ||
515  rettypeid == ANYCOMPATIBLERANGEOID)
516  rettypeid = INT4RANGEOID;
517  else /* ANYELEMENT or ANYNONARRAY or ANYCOMPATIBLE */
518  rettypeid = INT4OID;
519  /* XXX what could we use for ANYENUM? */
520  }
521  else
522  {
523  rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
524  if (!OidIsValid(rettypeid))
525  ereport(ERROR,
526  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
527  errmsg("could not determine actual return type "
528  "for polymorphic function \"%s\"",
530  }
531  }
532 
533  /*
534  * Normal function has a defined returntype
535  */
536  function->fn_rettype = rettypeid;
537  function->fn_retset = procStruct->proretset;
538 
539  /*
540  * Lookup the function's return type
541  */
542  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettypeid));
543  if (!HeapTupleIsValid(typeTup))
544  elog(ERROR, "cache lookup failed for type %u", rettypeid);
545  typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
546 
547  /* Disallow pseudotype result, except VOID or RECORD */
548  /* (note we already replaced polymorphic types) */
549  if (typeStruct->typtype == TYPTYPE_PSEUDO)
550  {
551  if (rettypeid == VOIDOID ||
552  rettypeid == RECORDOID)
553  /* okay */ ;
554  else if (rettypeid == TRIGGEROID || rettypeid == EVENT_TRIGGEROID)
555  ereport(ERROR,
556  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
557  errmsg("trigger functions can only be called as triggers")));
558  else
559  ereport(ERROR,
560  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
561  errmsg("PL/pgSQL functions cannot return type %s",
562  format_type_be(rettypeid))));
563  }
564 
565  function->fn_retistuple = type_is_rowtype(rettypeid);
566  function->fn_retisdomain = (typeStruct->typtype == TYPTYPE_DOMAIN);
567  function->fn_retbyval = typeStruct->typbyval;
568  function->fn_rettyplen = typeStruct->typlen;
569 
570  /*
571  * install $0 reference, but only for polymorphic return types,
572  * and not when the return is specified through an output
573  * parameter.
574  */
575  if (IsPolymorphicType(procStruct->prorettype) &&
576  num_out_args == 0)
577  {
578  (void) plpgsql_build_variable("$0", 0,
579  build_datatype(typeTup,
580  -1,
582  NULL),
583  true);
584  }
585 
586  ReleaseSysCache(typeTup);
587  break;
588 
589  case PLPGSQL_DML_TRIGGER:
590  /* Trigger procedure's return type is unknown yet */
591  function->fn_rettype = InvalidOid;
592  function->fn_retbyval = false;
593  function->fn_retistuple = true;
594  function->fn_retisdomain = false;
595  function->fn_retset = false;
596 
597  /* shouldn't be any declared arguments */
598  if (procStruct->pronargs != 0)
599  ereport(ERROR,
600  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
601  errmsg("trigger functions cannot have declared arguments"),
602  errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
603 
604  /* Add the record for referencing NEW ROW */
605  rec = plpgsql_build_record("new", 0, NULL, RECORDOID, true);
606  function->new_varno = rec->dno;
607 
608  /* Add the record for referencing OLD ROW */
609  rec = plpgsql_build_record("old", 0, NULL, RECORDOID, true);
610  function->old_varno = rec->dno;
611 
612  /* Add the variable tg_name */
613  var = plpgsql_build_variable("tg_name", 0,
614  plpgsql_build_datatype(NAMEOID,
615  -1,
617  NULL),
618  true);
619  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
621  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_NAME;
622 
623  /* Add the variable tg_when */
624  var = plpgsql_build_variable("tg_when", 0,
625  plpgsql_build_datatype(TEXTOID,
626  -1,
628  NULL),
629  true);
630  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
632  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_WHEN;
633 
634  /* Add the variable tg_level */
635  var = plpgsql_build_variable("tg_level", 0,
636  plpgsql_build_datatype(TEXTOID,
637  -1,
639  NULL),
640  true);
641  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
643  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_LEVEL;
644 
645  /* Add the variable tg_op */
646  var = plpgsql_build_variable("tg_op", 0,
647  plpgsql_build_datatype(TEXTOID,
648  -1,
650  NULL),
651  true);
652  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
654  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_OP;
655 
656  /* Add the variable tg_relid */
657  var = plpgsql_build_variable("tg_relid", 0,
658  plpgsql_build_datatype(OIDOID,
659  -1,
660  InvalidOid,
661  NULL),
662  true);
663  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
665  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_RELID;
666 
667  /* Add the variable tg_relname */
668  var = plpgsql_build_variable("tg_relname", 0,
669  plpgsql_build_datatype(NAMEOID,
670  -1,
672  NULL),
673  true);
674  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
676  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_NAME;
677 
678  /* tg_table_name is now preferred to tg_relname */
679  var = plpgsql_build_variable("tg_table_name", 0,
680  plpgsql_build_datatype(NAMEOID,
681  -1,
683  NULL),
684  true);
685  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
687  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_NAME;
688 
689  /* add the variable tg_table_schema */
690  var = plpgsql_build_variable("tg_table_schema", 0,
691  plpgsql_build_datatype(NAMEOID,
692  -1,
694  NULL),
695  true);
696  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
698  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_SCHEMA;
699 
700  /* Add the variable tg_nargs */
701  var = plpgsql_build_variable("tg_nargs", 0,
702  plpgsql_build_datatype(INT4OID,
703  -1,
704  InvalidOid,
705  NULL),
706  true);
707  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
709  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_NARGS;
710 
711  /* Add the variable tg_argv */
712  var = plpgsql_build_variable("tg_argv", 0,
713  plpgsql_build_datatype(TEXTARRAYOID,
714  -1,
716  NULL),
717  true);
718  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
720  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_ARGV;
721 
722  break;
723 
725  function->fn_rettype = VOIDOID;
726  function->fn_retbyval = false;
727  function->fn_retistuple = true;
728  function->fn_retisdomain = false;
729  function->fn_retset = false;
730 
731  /* shouldn't be any declared arguments */
732  if (procStruct->pronargs != 0)
733  ereport(ERROR,
734  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
735  errmsg("event trigger functions cannot have declared arguments")));
736 
737  /* Add the variable tg_event */
738  var = plpgsql_build_variable("tg_event", 0,
739  plpgsql_build_datatype(TEXTOID,
740  -1,
742  NULL),
743  true);
744  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
746  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_EVENT;
747 
748  /* Add the variable tg_tag */
749  var = plpgsql_build_variable("tg_tag", 0,
750  plpgsql_build_datatype(TEXTOID,
751  -1,
753  NULL),
754  true);
755  Assert(var->dtype == PLPGSQL_DTYPE_VAR);
757  ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TAG;
758 
759  break;
760 
761  default:
762  elog(ERROR, "unrecognized function typecode: %d",
763  (int) function->fn_is_trigger);
764  break;
765  }
766 
767  /* Remember if function is STABLE/IMMUTABLE */
768  function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
769 
770  /*
771  * Create the magic FOUND variable.
772  */
773  var = plpgsql_build_variable("found", 0,
774  plpgsql_build_datatype(BOOLOID,
775  -1,
776  InvalidOid,
777  NULL),
778  true);
779  function->found_varno = var->dno;
780 
781  /*
782  * Now parse the function's text
783  */
784  parse_rc = plpgsql_yyparse();
785  if (parse_rc != 0)
786  elog(ERROR, "plpgsql parser returned %d", parse_rc);
787  function->action = plpgsql_parse_result;
788 
790  pfree(proc_source);
791 
792  /*
793  * If it has OUT parameters or returns VOID or returns a set, we allow
794  * control to fall off the end without an explicit RETURN statement. The
795  * easiest way to implement this is to add a RETURN statement to the end
796  * of the statement list during parsing.
797  */
798  if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
800  add_dummy_return(function);
801 
802  /*
803  * Complete the function's info
804  */
805  function->fn_nargs = procStruct->pronargs;
806  for (i = 0; i < function->fn_nargs; i++)
807  function->fn_argvarnos[i] = in_arg_varnos[i];
808 
809  plpgsql_finish_datums(function);
810 
811  /* Debug dump for completed functions */
813  plpgsql_dumptree(function);
814 
815  /*
816  * add it to the hash table
817  */
818  plpgsql_HashTableInsert(function, hashkey);
819 
820  /*
821  * Pop the error context stack
822  */
823  error_context_stack = plerrcontext.previous;
824  plpgsql_error_funcname = NULL;
825 
826  plpgsql_check_syntax = false;
827 
828  MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
829  plpgsql_compile_tmp_cxt = NULL;
830  return function;
831 }
832 
833 /* ----------
834  * plpgsql_compile_inline Make an execution tree for an anonymous code block.
835  *
836  * Note: this is generally parallel to do_compile(); is it worth trying to
837  * merge the two?
838  *
839  * Note: we assume the block will be thrown away so there is no need to build
840  * persistent data structures.
841  * ----------
842  */
844 plpgsql_compile_inline(char *proc_source)
845 {
846  char *func_name = "inline_code_block";
847  PLpgSQL_function *function;
848  ErrorContextCallback plerrcontext;
849  PLpgSQL_variable *var;
850  int parse_rc;
851  MemoryContext func_cxt;
852 
853  /*
854  * Setup the scanner input and error info. We assume that this function
855  * cannot be invoked recursively, so there's no need to save and restore
856  * the static variables used here.
857  */
858  plpgsql_scanner_init(proc_source);
859 
860  plpgsql_error_funcname = func_name;
861 
862  /*
863  * Setup error traceback support for ereport()
864  */
866  plerrcontext.arg = proc_source;
867  plerrcontext.previous = error_context_stack;
868  error_context_stack = &plerrcontext;
869 
870  /* Do extra syntax checking if check_function_bodies is on */
872 
873  /* Function struct does not live past current statement */
874  function = (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
875 
876  plpgsql_curr_compile = function;
877 
878  /*
879  * All the rest of the compile-time storage (e.g. parse tree) is kept in
880  * its own memory context, so it can be reclaimed easily.
881  */
883  "PL/pgSQL inline code context",
885  plpgsql_compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
886 
887  function->fn_signature = pstrdup(func_name);
888  function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
889  function->fn_input_collation = InvalidOid;
890  function->fn_cxt = func_cxt;
891  function->out_param_varno = -1; /* set up for no OUT param */
892  function->resolve_option = plpgsql_variable_conflict;
893  function->print_strict_params = plpgsql_print_strict_params;
894 
895  /*
896  * don't do extra validation for inline code as we don't want to add spam
897  * at runtime
898  */
899  function->extra_warnings = 0;
900  function->extra_errors = 0;
901 
902  function->nstatements = 0;
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 
968  MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
969  plpgsql_compile_tmp_cxt = NULL;
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.
1038  */
1039  if (function->action->exceptions != NULL)
1040  {
1041  PLpgSQL_stmt_block *new;
1042 
1043  new = palloc0(sizeof(PLpgSQL_stmt_block));
1044  new->cmd_type = PLPGSQL_STMT_BLOCK;
1045  new->stmtid = ++function->nstatements;
1046  new->body = list_make1(function->action);
1047 
1048  function->action = new;
1049  }
1050  if (function->action->body == NIL ||
1051  ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
1052  {
1053  PLpgSQL_stmt_return *new;
1054 
1055  new = palloc0(sizeof(PLpgSQL_stmt_return));
1056  new->cmd_type = PLPGSQL_STMT_RETURN;
1057  new->stmtid = ++function->nstatements;
1058  new->expr = NULL;
1059  new->retvarno = function->out_param_varno;
1060 
1061  function->action->body = lappend(function->action->body, new);
1062  }
1063 }
1064 
1065 
1066 /*
1067  * plpgsql_parser_setup set up parser hooks for dynamic parameters
1068  *
1069  * Note: this routine, and the hook functions it prepares for, are logically
1070  * part of plpgsql parsing. But they actually run during function execution,
1071  * when we are ready to evaluate a SQL query or expression that has not
1072  * previously been parsed and planned.
1073  */
1074 void
1076 {
1080  /* no need to use p_coerce_param_hook */
1081  pstate->p_ref_hook_state = (void *) expr;
1082 }
1083 
1084 /*
1085  * plpgsql_pre_column_ref parser callback before parsing a ColumnRef
1086  */
1087 static Node *
1089 {
1090  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1091 
1093  return resolve_column_ref(pstate, expr, cref, false);
1094  else
1095  return NULL;
1096 }
1097 
1098 /*
1099  * plpgsql_post_column_ref parser callback after parsing a ColumnRef
1100  */
1101 static Node *
1103 {
1104  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1105  Node *myvar;
1106 
1108  return NULL; /* we already found there's no match */
1109 
1110  if (expr->func->resolve_option == PLPGSQL_RESOLVE_COLUMN && var != NULL)
1111  return NULL; /* there's a table column, prefer that */
1112 
1113  /*
1114  * If we find a record/row variable but can't match a field name, throw
1115  * error if there was no core resolution for the ColumnRef either. In
1116  * that situation, the reference is inevitably going to fail, and
1117  * complaining about the record/row variable is likely to be more on-point
1118  * than the core parser's error message. (It's too bad we don't have
1119  * access to transformColumnRef's internal crerr state here, as in case of
1120  * a conflict with a table name this could still be less than the most
1121  * helpful error message possible.)
1122  */
1123  myvar = resolve_column_ref(pstate, expr, cref, (var == NULL));
1124 
1125  if (myvar != NULL && var != NULL)
1126  {
1127  /*
1128  * We could leave it to the core parser to throw this error, but we
1129  * can add a more useful detail message than the core could.
1130  */
1131  ereport(ERROR,
1132  (errcode(ERRCODE_AMBIGUOUS_COLUMN),
1133  errmsg("column reference \"%s\" is ambiguous",
1134  NameListToString(cref->fields)),
1135  errdetail("It could refer to either a PL/pgSQL variable or a table column."),
1136  parser_errposition(pstate, cref->location)));
1137  }
1138 
1139  return myvar;
1140 }
1141 
1142 /*
1143  * plpgsql_param_ref parser callback for ParamRefs ($n symbols)
1144  */
1145 static Node *
1147 {
1148  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1149  char pname[32];
1150  PLpgSQL_nsitem *nse;
1151 
1152  snprintf(pname, sizeof(pname), "$%d", pref->number);
1153 
1154  nse = plpgsql_ns_lookup(expr->ns, false,
1155  pname, NULL, NULL,
1156  NULL);
1157 
1158  if (nse == NULL)
1159  return NULL; /* name not known to plpgsql */
1160 
1161  return make_datum_param(expr, nse->itemno, pref->location);
1162 }
1163 
1164 /*
1165  * resolve_column_ref attempt to resolve a ColumnRef as a plpgsql var
1166  *
1167  * Returns the translated node structure, or NULL if name not found
1168  *
1169  * error_if_no_field tells whether to throw error or quietly return NULL if
1170  * we are able to match a record/row name but don't find a field name match.
1171  */
1172 static Node *
1174  ColumnRef *cref, bool error_if_no_field)
1175 {
1176  PLpgSQL_execstate *estate;
1177  PLpgSQL_nsitem *nse;
1178  const char *name1;
1179  const char *name2 = NULL;
1180  const char *name3 = NULL;
1181  const char *colname = NULL;
1182  int nnames;
1183  int nnames_scalar = 0;
1184  int nnames_wholerow = 0;
1185  int nnames_field = 0;
1186 
1187  /*
1188  * We use the function's current estate to resolve parameter data types.
1189  * This is really pretty bogus because there is no provision for updating
1190  * plans when those types change ...
1191  */
1192  estate = expr->func->cur_estate;
1193 
1194  /*----------
1195  * The allowed syntaxes are:
1196  *
1197  * A Scalar variable reference, or whole-row record reference.
1198  * A.B Qualified scalar or whole-row reference, or field reference.
1199  * A.B.C Qualified record field reference.
1200  * A.* Whole-row record reference.
1201  * A.B.* Qualified whole-row record reference.
1202  *----------
1203  */
1204  switch (list_length(cref->fields))
1205  {
1206  case 1:
1207  {
1208  Node *field1 = (Node *) linitial(cref->fields);
1209 
1210  Assert(IsA(field1, String));
1211  name1 = strVal(field1);
1212  nnames_scalar = 1;
1213  nnames_wholerow = 1;
1214  break;
1215  }
1216  case 2:
1217  {
1218  Node *field1 = (Node *) linitial(cref->fields);
1219  Node *field2 = (Node *) lsecond(cref->fields);
1220 
1221  Assert(IsA(field1, String));
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  Assert(IsA(field2, String));
1234  name2 = strVal(field2);
1235  colname = name2;
1236  nnames_scalar = 2;
1237  nnames_wholerow = 2;
1238  nnames_field = 1;
1239  break;
1240  }
1241  case 3:
1242  {
1243  Node *field1 = (Node *) linitial(cref->fields);
1244  Node *field2 = (Node *) lsecond(cref->fields);
1245  Node *field3 = (Node *) lthird(cref->fields);
1246 
1247  Assert(IsA(field1, String));
1248  name1 = strVal(field1);
1249  Assert(IsA(field2, String));
1250  name2 = strVal(field2);
1251 
1252  /* Whole-row reference? */
1253  if (IsA(field3, A_Star))
1254  {
1255  /* Set name3 to prevent matches to scalar variables */
1256  name3 = "*";
1257  nnames_wholerow = 2;
1258  break;
1259  }
1260 
1261  Assert(IsA(field3, String));
1262  name3 = strVal(field3);
1263  colname = name3;
1264  nnames_field = 2;
1265  break;
1266  }
1267  default:
1268  /* too many names, ignore */
1269  return NULL;
1270  }
1271 
1272  nse = plpgsql_ns_lookup(expr->ns, false,
1273  name1, name2, name3,
1274  &nnames);
1275 
1276  if (nse == NULL)
1277  return NULL; /* name not known to plpgsql */
1278 
1279  switch (nse->itemtype)
1280  {
1281  case PLPGSQL_NSTYPE_VAR:
1282  if (nnames == nnames_scalar)
1283  return make_datum_param(expr, nse->itemno, cref->location);
1284  break;
1285  case PLPGSQL_NSTYPE_REC:
1286  if (nnames == nnames_wholerow)
1287  return make_datum_param(expr, nse->itemno, cref->location);
1288  if (nnames == nnames_field)
1289  {
1290  /* colname could be a field in this record */
1291  PLpgSQL_rec *rec = (PLpgSQL_rec *) estate->datums[nse->itemno];
1292  int i;
1293 
1294  /* search for a datum referencing this field */
1295  i = rec->firstfield;
1296  while (i >= 0)
1297  {
1298  PLpgSQL_recfield *fld = (PLpgSQL_recfield *) estate->datums[i];
1299 
1301  fld->recparentno == nse->itemno);
1302  if (strcmp(fld->fieldname, colname) == 0)
1303  {
1304  return make_datum_param(expr, i, cref->location);
1305  }
1306  i = fld->nextfield;
1307  }
1308 
1309  /*
1310  * We should not get here, because a RECFIELD datum should
1311  * have been built at parse time for every possible qualified
1312  * reference to fields of this record. But if we do, handle
1313  * it like field-not-found: throw error or return NULL.
1314  */
1315  if (error_if_no_field)
1316  ereport(ERROR,
1317  (errcode(ERRCODE_UNDEFINED_COLUMN),
1318  errmsg("record \"%s\" has no field \"%s\"",
1319  (nnames_field == 1) ? name1 : name2,
1320  colname),
1321  parser_errposition(pstate, cref->location)));
1322  }
1323  break;
1324  default:
1325  elog(ERROR, "unrecognized plpgsql itemtype: %d", nse->itemtype);
1326  }
1327 
1328  /* Name format doesn't match the plpgsql variable type */
1329  return NULL;
1330 }
1331 
1332 /*
1333  * Helper for columnref parsing: build a Param referencing a plpgsql datum,
1334  * and make sure that that datum is listed in the expression's paramnos.
1335  */
1336 static Node *
1337 make_datum_param(PLpgSQL_expr *expr, int dno, int location)
1338 {
1339  PLpgSQL_execstate *estate;
1340  PLpgSQL_datum *datum;
1341  Param *param;
1342  MemoryContext oldcontext;
1343 
1344  /* see comment in resolve_column_ref */
1345  estate = expr->func->cur_estate;
1346  Assert(dno >= 0 && dno < estate->ndatums);
1347  datum = estate->datums[dno];
1348 
1349  /*
1350  * Bitmapset must be allocated in function's permanent memory context
1351  */
1352  oldcontext = MemoryContextSwitchTo(expr->func->fn_cxt);
1353  expr->paramnos = bms_add_member(expr->paramnos, dno);
1354  MemoryContextSwitchTo(oldcontext);
1355 
1356  param = makeNode(Param);
1357  param->paramkind = PARAM_EXTERN;
1358  param->paramid = dno + 1;
1360  datum,
1361  &param->paramtype,
1362  &param->paramtypmod,
1363  &param->paramcollid);
1364  param->location = location;
1365 
1366  return (Node *) param;
1367 }
1368 
1369 
1370 /* ----------
1371  * plpgsql_parse_word The scanner calls this to postparse
1372  * any single word that is not a reserved keyword.
1373  *
1374  * word1 is the downcased/dequoted identifier; it must be palloc'd in the
1375  * function's long-term memory context.
1376  *
1377  * yytxt is the original token text; we need this to check for quoting,
1378  * so that later checks for unreserved keywords work properly.
1379  *
1380  * We attempt to recognize the token as a variable only if lookup is true
1381  * and the plpgsql_IdentifierLookup context permits it.
1382  *
1383  * If recognized as a variable, fill in *wdatum and return true;
1384  * if not recognized, fill in *word and return false.
1385  * (Note: those two pointers actually point to members of the same union,
1386  * but for notational reasons we pass them separately.)
1387  * ----------
1388  */
1389 bool
1390 plpgsql_parse_word(char *word1, const char *yytxt, bool lookup,
1391  PLwdatum *wdatum, PLword *word)
1392 {
1393  PLpgSQL_nsitem *ns;
1394 
1395  /*
1396  * We should not lookup variables in DECLARE sections. In SQL
1397  * expressions, there's no need to do so either --- lookup will happen
1398  * when the expression is compiled.
1399  */
1401  {
1402  /*
1403  * Do a lookup in the current namespace stack
1404  */
1405  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1406  word1, NULL, NULL,
1407  NULL);
1408 
1409  if (ns != NULL)
1410  {
1411  switch (ns->itemtype)
1412  {
1413  case PLPGSQL_NSTYPE_VAR:
1414  case PLPGSQL_NSTYPE_REC:
1415  wdatum->datum = plpgsql_Datums[ns->itemno];
1416  wdatum->ident = word1;
1417  wdatum->quoted = (yytxt[0] == '"');
1418  wdatum->idents = NIL;
1419  return true;
1420 
1421  default:
1422  /* plpgsql_ns_lookup should never return anything else */
1423  elog(ERROR, "unrecognized plpgsql itemtype: %d",
1424  ns->itemtype);
1425  }
1426  }
1427  }
1428 
1429  /*
1430  * Nothing found - up to now it's a word without any special meaning for
1431  * us.
1432  */
1433  word->ident = word1;
1434  word->quoted = (yytxt[0] == '"');
1435  return false;
1436 }
1437 
1438 
1439 /* ----------
1440  * plpgsql_parse_dblword Same lookup for two words
1441  * separated by a dot.
1442  * ----------
1443  */
1444 bool
1445 plpgsql_parse_dblword(char *word1, char *word2,
1446  PLwdatum *wdatum, PLcword *cword)
1447 {
1448  PLpgSQL_nsitem *ns;
1449  List *idents;
1450  int nnames;
1451 
1452  idents = list_make2(makeString(word1),
1453  makeString(word2));
1454 
1455  /*
1456  * We should do nothing in DECLARE sections. In SQL expressions, we
1457  * really only need to make sure that RECFIELD datums are created when
1458  * needed.
1459  */
1461  {
1462  /*
1463  * Do a lookup in the current namespace stack
1464  */
1465  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1466  word1, word2, NULL,
1467  &nnames);
1468  if (ns != NULL)
1469  {
1470  switch (ns->itemtype)
1471  {
1472  case PLPGSQL_NSTYPE_VAR:
1473  /* Block-qualified reference to scalar variable. */
1474  wdatum->datum = plpgsql_Datums[ns->itemno];
1475  wdatum->ident = NULL;
1476  wdatum->quoted = false; /* not used */
1477  wdatum->idents = idents;
1478  return true;
1479 
1480  case PLPGSQL_NSTYPE_REC:
1481  if (nnames == 1)
1482  {
1483  /*
1484  * First word is a record name, so second word could
1485  * be a field in this record. We build a RECFIELD
1486  * datum whether it is or not --- any error will be
1487  * detected later.
1488  */
1489  PLpgSQL_rec *rec;
1490  PLpgSQL_recfield *new;
1491 
1492  rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1493  new = plpgsql_build_recfield(rec, word2);
1494 
1495  wdatum->datum = (PLpgSQL_datum *) new;
1496  }
1497  else
1498  {
1499  /* Block-qualified reference to record variable. */
1500  wdatum->datum = plpgsql_Datums[ns->itemno];
1501  }
1502  wdatum->ident = NULL;
1503  wdatum->quoted = false; /* not used */
1504  wdatum->idents = idents;
1505  return true;
1506 
1507  default:
1508  break;
1509  }
1510  }
1511  }
1512 
1513  /* Nothing found */
1514  cword->idents = idents;
1515  return false;
1516 }
1517 
1518 
1519 /* ----------
1520  * plpgsql_parse_tripword Same lookup for three words
1521  * separated by dots.
1522  * ----------
1523  */
1524 bool
1525 plpgsql_parse_tripword(char *word1, char *word2, char *word3,
1526  PLwdatum *wdatum, PLcword *cword)
1527 {
1528  PLpgSQL_nsitem *ns;
1529  List *idents;
1530  int nnames;
1531 
1532  idents = list_make3(makeString(word1),
1533  makeString(word2),
1534  makeString(word3));
1535 
1536  /*
1537  * We should do nothing in DECLARE sections. In SQL expressions, we
1538  * really only need to make sure that RECFIELD datums are created when
1539  * needed.
1540  */
1542  {
1543  /*
1544  * Do a lookup in the current namespace stack. Must find a qualified
1545  * reference, else ignore.
1546  */
1547  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1548  word1, word2, word3,
1549  &nnames);
1550  if (ns != NULL && nnames == 2)
1551  {
1552  switch (ns->itemtype)
1553  {
1554  case PLPGSQL_NSTYPE_REC:
1555  {
1556  /*
1557  * words 1/2 are a record name, so third word could be
1558  * a field in this record.
1559  */
1560  PLpgSQL_rec *rec;
1561  PLpgSQL_recfield *new;
1562 
1563  rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1564  new = plpgsql_build_recfield(rec, word3);
1565 
1566  wdatum->datum = (PLpgSQL_datum *) new;
1567  wdatum->ident = NULL;
1568  wdatum->quoted = false; /* not used */
1569  wdatum->idents = idents;
1570  return true;
1571  }
1572 
1573  default:
1574  break;
1575  }
1576  }
1577  }
1578 
1579  /* Nothing found */
1580  cword->idents = idents;
1581  return false;
1582 }
1583 
1584 
1585 /* ----------
1586  * plpgsql_parse_wordtype The scanner found word%TYPE. word can be
1587  * a variable name or a basetype.
1588  *
1589  * Returns datatype struct, or NULL if no match found for word.
1590  * ----------
1591  */
1592 PLpgSQL_type *
1594 {
1595  PLpgSQL_type *dtype;
1596  PLpgSQL_nsitem *nse;
1597  TypeName *typeName;
1598  HeapTuple typeTup;
1599 
1600  /*
1601  * Do a lookup in the current namespace stack
1602  */
1603  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1604  ident, NULL, NULL,
1605  NULL);
1606 
1607  if (nse != NULL)
1608  {
1609  switch (nse->itemtype)
1610  {
1611  case PLPGSQL_NSTYPE_VAR:
1612  return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1613 
1614  /* XXX perhaps allow REC/ROW here? */
1615 
1616  default:
1617  return NULL;
1618  }
1619  }
1620 
1621  /*
1622  * Word wasn't found in the namespace stack. Try to find a data type with
1623  * that name, but ignore shell types and complex types.
1624  */
1625  typeName = makeTypeName(ident);
1626  typeTup = LookupTypeName(NULL, typeName, NULL, false);
1627  if (typeTup)
1628  {
1629  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1630 
1631  if (!typeStruct->typisdefined ||
1632  typeStruct->typrelid != InvalidOid)
1633  {
1634  ReleaseSysCache(typeTup);
1635  return NULL;
1636  }
1637 
1638  dtype = build_datatype(typeTup, -1,
1639  plpgsql_curr_compile->fn_input_collation,
1640  typeName);
1641 
1642  ReleaseSysCache(typeTup);
1643  return dtype;
1644  }
1645 
1646  /*
1647  * Nothing found - up to now it's a word without any special meaning for
1648  * us.
1649  */
1650  return NULL;
1651 }
1652 
1653 
1654 /* ----------
1655  * plpgsql_parse_cwordtype Same lookup for compositeword%TYPE
1656  * ----------
1657  */
1658 PLpgSQL_type *
1660 {
1661  PLpgSQL_type *dtype = NULL;
1662  PLpgSQL_nsitem *nse;
1663  const char *fldname;
1664  Oid classOid;
1665  HeapTuple classtup = NULL;
1666  HeapTuple attrtup = NULL;
1667  HeapTuple typetup = NULL;
1668  Form_pg_class classStruct;
1669  Form_pg_attribute attrStruct;
1670  MemoryContext oldCxt;
1671 
1672  /* Avoid memory leaks in the long-term function context */
1673  oldCxt = MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
1674 
1675  if (list_length(idents) == 2)
1676  {
1677  /*
1678  * Do a lookup in the current namespace stack. We don't need to check
1679  * number of names matched, because we will only consider scalar
1680  * variables.
1681  */
1682  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1683  strVal(linitial(idents)),
1684  strVal(lsecond(idents)),
1685  NULL,
1686  NULL);
1687 
1688  if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1689  {
1690  dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1691  goto done;
1692  }
1693 
1694  /*
1695  * First word could also be a table name
1696  */
1697  classOid = RelnameGetRelid(strVal(linitial(idents)));
1698  if (!OidIsValid(classOid))
1699  goto done;
1700  fldname = strVal(lsecond(idents));
1701  }
1702  else if (list_length(idents) == 3)
1703  {
1704  RangeVar *relvar;
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);
1759  MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
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 */
1831  oldCxt = MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
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)
1944  plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->dno, rec->refname);
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  {
2030  PLpgSQL_recfield *fld = (PLpgSQL_recfield *) plpgsql_Datums[i];
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  typ->ttype = PLPGSQL_TTYPE_SCALAR;
2112  break;
2113  case TYPTYPE_COMPOSITE:
2114  typ->ttype = PLPGSQL_TTYPE_REC;
2115  break;
2116  case TYPTYPE_DOMAIN:
2117  if (type_is_rowtype(typeStruct->typbasetype))
2118  typ->ttype = PLPGSQL_TTYPE_REC;
2119  else
2120  typ->ttype = PLPGSQL_TTYPE_SCALAR;
2121  break;
2122  case TYPTYPE_PSEUDO:
2123  if (typ->typoid == RECORDOID)
2124  typ->ttype = PLPGSQL_TTYPE_REC;
2125  else
2126  typ->ttype = PLPGSQL_TTYPE_PSEUDO;
2127  break;
2128  default:
2129  elog(ERROR, "unrecognized typtype: %d",
2130  (int) typeStruct->typtype);
2131  break;
2132  }
2133  typ->typlen = typeStruct->typlen;
2134  typ->typbyval = typeStruct->typbyval;
2135  typ->typtype = typeStruct->typtype;
2136  typ->collation = typeStruct->typcollation;
2137  if (OidIsValid(collation) && OidIsValid(typ->collation))
2138  typ->collation = collation;
2139  /* Detect if type is true array, or domain thereof */
2140  /* NB: this is only used to decide whether to apply expand_array */
2141  if (typeStruct->typtype == TYPTYPE_BASE)
2142  {
2143  /*
2144  * This test should include what get_element_type() checks. We also
2145  * disallow non-toastable array types (i.e. oidvector and int2vector).
2146  */
2147  typ->typisarray = (typeStruct->typlen == -1 &&
2148  OidIsValid(typeStruct->typelem) &&
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  * plpgsql_recognize_err_condition
2200  * Check condition name and translate it to SQLSTATE.
2201  *
2202  * Note: there are some cases where the same condition name has multiple
2203  * entries in the table. We arbitrarily return the first match.
2204  */
2205 int
2206 plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
2207 {
2208  int i;
2209 
2210  if (allow_sqlstate)
2211  {
2212  if (strlen(condname) == 5 &&
2213  strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2214  return MAKE_SQLSTATE(condname[0],
2215  condname[1],
2216  condname[2],
2217  condname[3],
2218  condname[4]);
2219  }
2220 
2221  for (i = 0; exception_label_map[i].label != NULL; i++)
2222  {
2223  if (strcmp(condname, exception_label_map[i].label) == 0)
2224  return exception_label_map[i].sqlerrstate;
2225  }
2226 
2227  ereport(ERROR,
2228  (errcode(ERRCODE_UNDEFINED_OBJECT),
2229  errmsg("unrecognized exception condition \"%s\"",
2230  condname)));
2231  return 0; /* keep compiler quiet */
2232 }
2233 
2234 /*
2235  * plpgsql_parse_err_condition
2236  * Generate PLpgSQL_condition entry(s) for an exception condition name
2237  *
2238  * This has to be able to return a list because there are some duplicate
2239  * names in the table of error code names.
2240  */
2243 {
2244  int i;
2245  PLpgSQL_condition *new;
2246  PLpgSQL_condition *prev;
2247 
2248  /*
2249  * XXX Eventually we will want to look for user-defined exception names
2250  * here.
2251  */
2252 
2253  /*
2254  * OTHERS is represented as code 0 (which would map to '00000', but we
2255  * have no need to represent that as an exception condition).
2256  */
2257  if (strcmp(condname, "others") == 0)
2258  {
2259  new = palloc(sizeof(PLpgSQL_condition));
2260  new->sqlerrstate = 0;
2261  new->condname = condname;
2262  new->next = NULL;
2263  return new;
2264  }
2265 
2266  prev = NULL;
2267  for (i = 0; exception_label_map[i].label != NULL; i++)
2268  {
2269  if (strcmp(condname, exception_label_map[i].label) == 0)
2270  {
2271  new = palloc(sizeof(PLpgSQL_condition));
2272  new->sqlerrstate = exception_label_map[i].sqlerrstate;
2273  new->condname = condname;
2274  new->next = prev;
2275  prev = new;
2276  }
2277  }
2278 
2279  if (!prev)
2280  ereport(ERROR,
2281  (errcode(ERRCODE_UNDEFINED_OBJECT),
2282  errmsg("unrecognized exception condition \"%s\"",
2283  condname)));
2284 
2285  return prev;
2286 }
2287 
2288 /* ----------
2289  * plpgsql_start_datums Initialize datum list at compile startup.
2290  * ----------
2291  */
2292 static void
2294 {
2295  datums_alloc = 128;
2296  plpgsql_nDatums = 0;
2297  /* This is short-lived, so needn't allocate in function's cxt */
2298  plpgsql_Datums = MemoryContextAlloc(plpgsql_compile_tmp_cxt,
2299  sizeof(PLpgSQL_datum *) * datums_alloc);
2300  /* datums_last tracks what's been seen by plpgsql_add_initdatums() */
2301  datums_last = 0;
2302 }
2303 
2304 /* ----------
2305  * plpgsql_adddatum Add a variable, record or row
2306  * to the compiler's datum list.
2307  * ----------
2308  */
2309 void
2311 {
2313  {
2314  datums_alloc *= 2;
2315  plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
2316  }
2317 
2318  newdatum->dno = plpgsql_nDatums;
2319  plpgsql_Datums[plpgsql_nDatums++] = newdatum;
2320 }
2321 
2322 /* ----------
2323  * plpgsql_finish_datums Copy completed datum info into function struct.
2324  * ----------
2325  */
2326 static void
2328 {
2329  Size copiable_size = 0;
2330  int i;
2331 
2332  function->ndatums = plpgsql_nDatums;
2333  function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
2334  for (i = 0; i < plpgsql_nDatums; i++)
2335  {
2336  function->datums[i] = plpgsql_Datums[i];
2337 
2338  /* This must agree with copy_plpgsql_datums on what is copiable */
2339  switch (function->datums[i]->dtype)
2340  {
2341  case PLPGSQL_DTYPE_VAR:
2342  case PLPGSQL_DTYPE_PROMISE:
2343  copiable_size += MAXALIGN(sizeof(PLpgSQL_var));
2344  break;
2345  case PLPGSQL_DTYPE_REC:
2346  copiable_size += MAXALIGN(sizeof(PLpgSQL_rec));
2347  break;
2348  default:
2349  break;
2350  }
2351  }
2352  function->copiable_size = copiable_size;
2353 }
2354 
2355 
2356 /* ----------
2357  * plpgsql_add_initdatums Make an array of the datum numbers of
2358  * all the initializable datums created since the last call
2359  * to this function.
2360  *
2361  * If varnos is NULL, we just forget any datum entries created since the
2362  * last call.
2363  *
2364  * This is used around a DECLARE section to create a list of the datums
2365  * that have to be initialized at block entry. Note that datums can also
2366  * be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
2367  * the responsibility of special-purpose code to initialize them.
2368  * ----------
2369  */
2370 int
2372 {
2373  int i;
2374  int n = 0;
2375 
2376  /*
2377  * The set of dtypes recognized here must match what exec_stmt_block()
2378  * cares about (re)initializing at block entry.
2379  */
2380  for (i = datums_last; i < plpgsql_nDatums; i++)
2381  {
2382  switch (plpgsql_Datums[i]->dtype)
2383  {
2384  case PLPGSQL_DTYPE_VAR:
2385  case PLPGSQL_DTYPE_REC:
2386  n++;
2387  break;
2388 
2389  default:
2390  break;
2391  }
2392  }
2393 
2394  if (varnos != NULL)
2395  {
2396  if (n > 0)
2397  {
2398  *varnos = (int *) palloc(sizeof(int) * n);
2399 
2400  n = 0;
2401  for (i = datums_last; i < plpgsql_nDatums; i++)
2402  {
2403  switch (plpgsql_Datums[i]->dtype)
2404  {
2405  case PLPGSQL_DTYPE_VAR:
2406  case PLPGSQL_DTYPE_REC:
2407  (*varnos)[n++] = plpgsql_Datums[i]->dno;
2408 
2409  default:
2410  break;
2411  }
2412  }
2413  }
2414  else
2415  *varnos = NULL;
2416  }
2417 
2419  return n;
2420 }
2421 
2422 
2423 /*
2424  * Compute the hashkey for a given function invocation
2425  *
2426  * The hashkey is returned into the caller-provided storage at *hashkey.
2427  */
2428 static void
2430  Form_pg_proc procStruct,
2431  PLpgSQL_func_hashkey *hashkey,
2432  bool forValidator)
2433 {
2434  /* Make sure any unused bytes of the struct are zero */
2435  MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
2436 
2437  /* get function OID */
2438  hashkey->funcOid = fcinfo->flinfo->fn_oid;
2439 
2440  /* get call context */
2441  hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
2442  hashkey->isEventTrigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
2443 
2444  /*
2445  * If DML trigger, include trigger's OID in the hash, so that each trigger
2446  * usage gets a different hash entry, allowing for e.g. different relation
2447  * rowtypes or transition table names. In validation mode we do not know
2448  * what relation or transition table names are intended to be used, so we
2449  * leave trigOid zero; the hash entry built in this case will never be
2450  * used for any actual calls.
2451  *
2452  * We don't currently need to distinguish different event trigger usages
2453  * in the same way, since the special parameter variables don't vary in
2454  * type in that case.
2455  */
2456  if (hashkey->isTrigger && !forValidator)
2457  {
2458  TriggerData *trigdata = (TriggerData *) fcinfo->context;
2459 
2460  hashkey->trigOid = trigdata->tg_trigger->tgoid;
2461  }
2462 
2463  /* get input collation, if known */
2464  hashkey->inputCollation = fcinfo->fncollation;
2465 
2466  if (procStruct->pronargs > 0)
2467  {
2468  /* get the argument types */
2469  memcpy(hashkey->argtypes, procStruct->proargtypes.values,
2470  procStruct->pronargs * sizeof(Oid));
2471 
2472  /* resolve any polymorphic argument types */
2473  plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
2474  hashkey->argtypes,
2475  NULL,
2476  fcinfo->flinfo->fn_expr,
2477  forValidator,
2478  NameStr(procStruct->proname));
2479  }
2480 }
2481 
2482 /*
2483  * This is the same as the standard resolve_polymorphic_argtypes() function,
2484  * but with a special case for validation: assume that polymorphic arguments
2485  * are integer, integer-array or integer-range. Also, we go ahead and report
2486  * the error if we can't resolve the types.
2487  */
2488 static void
2490  Oid *argtypes, char *argmodes,
2491  Node *call_expr, bool forValidator,
2492  const char *proname)
2493 {
2494  int i;
2495 
2496  if (!forValidator)
2497  {
2498  /* normal case, pass to standard routine */
2499  if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
2500  call_expr))
2501  ereport(ERROR,
2502  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2503  errmsg("could not determine actual argument "
2504  "type for polymorphic function \"%s\"",
2505  proname)));
2506  }
2507  else
2508  {
2509  /* special validation case */
2510  for (i = 0; i < numargs; i++)
2511  {
2512  switch (argtypes[i])
2513  {
2514  case ANYELEMENTOID:
2515  case ANYNONARRAYOID:
2516  case ANYENUMOID: /* XXX dubious */
2517  case ANYCOMPATIBLEOID:
2518  case ANYCOMPATIBLENONARRAYOID:
2519  argtypes[i] = INT4OID;
2520  break;
2521  case ANYARRAYOID:
2522  case ANYCOMPATIBLEARRAYOID:
2523  argtypes[i] = INT4ARRAYOID;
2524  break;
2525  case ANYRANGEOID:
2526  case ANYCOMPATIBLERANGEOID:
2527  argtypes[i] = INT4RANGEOID;
2528  break;
2529  default:
2530  break;
2531  }
2532  }
2533  }
2534 }
2535 
2536 /*
2537  * delete_function - clean up as much as possible of a stale function cache
2538  *
2539  * We can't release the PLpgSQL_function struct itself, because of the
2540  * possibility that there are fn_extra pointers to it. We can release
2541  * the subsidiary storage, but only if there are no active evaluations
2542  * in progress. Otherwise we'll just leak that storage. Since the
2543  * case would only occur if a pg_proc update is detected during a nested
2544  * recursive call on the function, a leak seems acceptable.
2545  *
2546  * Note that this can be called more than once if there are multiple fn_extra
2547  * pointers to the same function cache. Hence be careful not to do things
2548  * twice.
2549  */
2550 static void
2552 {
2553  /* remove function from hash table (might be done already) */
2555 
2556  /* release the function's storage if safe and not done already */
2557  if (func->use_count == 0)
2559 }
2560 
2561 /* exported so we can call it from _PG_init() */
2562 void
2564 {
2565  HASHCTL ctl;
2566 
2567  /* don't allow double-initialization */
2568  Assert(plpgsql_HashTable == NULL);
2569 
2570  memset(&ctl, 0, sizeof(ctl));
2571  ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2572  ctl.entrysize = sizeof(plpgsql_HashEnt);
2573  plpgsql_HashTable = hash_create("PLpgSQL function hash",
2575  &ctl,
2576  HASH_ELEM | HASH_BLOBS);
2577 }
2578 
2579 static PLpgSQL_function *
2581 {
2582  plpgsql_HashEnt *hentry;
2583 
2584  hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2585  (void *) func_key,
2586  HASH_FIND,
2587  NULL);
2588  if (hentry)
2589  return hentry->function;
2590  else
2591  return NULL;
2592 }
2593 
2594 static void
2596  PLpgSQL_func_hashkey *func_key)
2597 {
2598  plpgsql_HashEnt *hentry;
2599  bool found;
2600 
2601  hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2602  (void *) func_key,
2603  HASH_ENTER,
2604  &found);
2605  if (found)
2606  elog(WARNING, "trying to insert a function that already exists");
2607 
2608  hentry->function = function;
2609  /* prepare back link from function to hashtable key */
2610  function->fn_hashkey = &hentry->key;
2611 }
2612 
2613 static void
2615 {
2616  plpgsql_HashEnt *hentry;
2617 
2618  /* do nothing if not in table */
2619  if (function->fn_hashkey == NULL)
2620  return;
2621 
2622  hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2623  (void *) function->fn_hashkey,
2624  HASH_REMOVE,
2625  NULL);
2626  if (hentry == NULL)
2627  elog(WARNING, "trying to delete function that does not exist");
2628 
2629  /* remove back link, which no longer points to allocated storage */
2630  function->fn_hashkey = NULL;
2631 }
#define list_make2(x1, x2)
Definition: pg_list.h:208
Value * makeString(char *str)
Definition: value.c:53
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
Definition: funcapi.c:830
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:38
PLpgSQL_function * plpgsql_compile_inline(char *proc_source)
Definition: pl_comp.c:844
#define list_make3(x1, x2, x3)
Definition: pg_list.h:210
int plpgsql_nDatums
Definition: pl_comp.c:44
int plpgsql_yyparse(void)
PLpgSQL_datum_type dtype
Definition: plpgsql.h:381
#define NIL
Definition: pg_list.h:65
#define FUNCS_PER_USER
Definition: pl_comp.c:69
int plpgsql_latest_lineno(void)
Definition: pl_scanner.c:572
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:737
PLpgSQL_datum ** datums
Definition: plpgsql.h:1031
int fn_argvarnos[FUNC_MAX_ARGS]
Definition: plpgsql.h:1012
Oid argtypes[FUNC_MAX_ARGS]
Definition: plpgsql.h:975
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
Definition: event_trigger.h:40
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
#define AllocSetContextCreate
Definition: memutils.h:170
PLpgSQL_func_hashkey * fn_hashkey
Definition: plpgsql.h:999
PLpgSQL_type * plpgsql_parse_wordrowtype(char *ident)
Definition: pl_comp.c:1779
char * refname
Definition: plpgsql.h:357
ItemPointerData fn_tid
Definition: plpgsql.h:996
int errhint(const char *fmt,...)
Definition: elog.c:1149
TypeCacheEntry * tcache
Definition: plpgsql.h:212
static PLpgSQL_function * do_compile(FunctionCallInfo fcinfo, HeapTuple procTup, PLpgSQL_function *function, PLpgSQL_func_hashkey *hashkey, bool forValidator)
Definition: pl_comp.c:263
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
const char * label
Definition: pl_comp.c:77
NameData proname
Definition: pg_proc.h:35
bool plpgsql_parse_dblword(char *word1, char *word2, PLwdatum *wdatum, PLcword *cword)
Definition: pl_comp.c:1445
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:74
static void compute_function_hashkey(FunctionCallInfo fcinfo, Form_pg_proc procStruct, PLpgSQL_func_hashkey *hashkey, bool forValidator)
Definition: pl_comp.c:2429
PLpgSQL_func_hashkey key
Definition: pl_comp.c:65
char * refname
Definition: plpgsql.h:303
#define HASH_ELEM
Definition: hsearch.h:85
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
Definition: pl_comp.c:1927
PLpgSQL_type * datatype
Definition: plpgsql.h:396
PLpgSQL_datum_type dtype
Definition: plpgsql.h:301
TypeName * origtypname
Definition: plpgsql.h:211
PLpgSQL_stmt_block * action
Definition: plpgsql.h:1035
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:680
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2090
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:62
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1088
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:78
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:130
char * pstrdup(const char *in)
Definition: mcxt.c:1187
PLpgSQL_type * datatype
Definition: plpgsql.h:310
Oid tgoid
Definition: reltrigger.h:25
#define llast(l)
Definition: pg_list.h:194
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:1094
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void plpgsql_HashTableInit(void)
Definition: pl_comp.c:2563
PLpgSQL_type_type ttype
Definition: plpgsql.h:203
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
Definition: pl_comp.c:2021
Size entrysize
Definition: hsearch.h:72
ParamKind paramkind
Definition: primnodes.h:262
TransactionId fn_xmin
Definition: plpgsql.h:995
Definition: nodes.h:527
int plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
Definition: pl_comp.c:2206
int plpgsql_extra_errors
Definition: pl_handler.c:53
ExpandedRecordHeader * erh
Definition: plpgsql.h:404
PLpgSQL_type * plpgsql_parse_wordtype(char *ident)
Definition: pl_comp.c:1593
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:691
#define MemSet(start, val, len)
Definition: c.h:1004
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
fmNodePtr context
Definition: fmgr.h:88
uint64 tupdesc_id
Definition: plpgsql.h:213
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:919
bool check_function_bodies
Definition: guc.c:528
void plpgsql_dumptree(PLpgSQL_function *func)
Definition: pl_funcs.c:1624
char * ident
Definition: plpgsql.h:1169
unsigned int Oid
Definition: postgres_ext.h:31
PLpgSQL_datum_type dtype
Definition: plpgsql.h:267
void(* callback)(void *arg)
Definition: elog.h:243
struct ErrorContextCallback * previous
Definition: elog.h:242
#define OidIsValid(objectId)
Definition: c.h:706
char * refname
Definition: plpgsql.h:383
#define INVALID_TUPLEDESC_IDENTIFIER
Definition: typcache.h:148
static void plpgsql_resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
Definition: pl_comp.c:2489
static void plpgsql_HashTableInsert(PLpgSQL_function *function, PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2595
#define lsecond(l)
Definition: pg_list.h:179
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2293
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:219
signed int int32
Definition: c.h:417
void plpgsql_adddatum(PLpgSQL_datum *newdatum)
Definition: pl_comp.c:2310
PLpgSQL_datum ** datums
Definition: plpgsql.h:1082
PLpgSQL_resolve_option resolve_option
Definition: plpgsql.h:1018
int location
Definition: parsenodes.h:237
HeapTupleHeader t_data
Definition: htup.h:68
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:61
Oid domainBaseType
Definition: typcache.h:107
ErrorContextCallback * error_context_stack
Definition: elog.c:92
static void delete_function(PLpgSQL_function *func)
Definition: pl_comp.c:2551
#define list_make1(x1)
Definition: pg_list.h:206
struct plpgsql_hashent plpgsql_HashEnt
void plpgsql_scanner_finish(void)
Definition: pl_scanner.c:613
Definition: dynahash.c:218
Bitmapset * paramnos
Definition: plpgsql.h:223
static PLpgSQL_function * plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2580
void pfree(void *pointer)
Definition: mcxt.c:1057
#define linitial(l)
Definition: pg_list.h:174
PLpgSQL_function * plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
Definition: pl_comp.c:135
bool plpgsql_check_syntax
Definition: pl_comp.c:50
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * plpgsql_error_funcname
Definition: pl_comp.c:48
char ** fieldnames
Definition: plpgsql.h:372
struct PLpgSQL_execstate * cur_estate
Definition: plpgsql.h:1038
Oid paramcollid
Definition: primnodes.h:266
struct PLpgSQL_func_hashkey PLpgSQL_func_hashkey
bool plpgsql_DumpExecTree
Definition: pl_comp.c:49
int location
Definition: primnodes.h:267
PLpgSQL_type * plpgsql_parse_cwordtype(List *idents)
Definition: pl_comp.c:1659
unsigned long use_count
Definition: plpgsql.h:1039
static void add_parameter_name(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_comp.c:1007
ItemPointerData t_self
Definition: htup.h:65
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:769
int plpgsql_extra_warnings
Definition: pl_handler.c:52
List * idents
Definition: plpgsql.h:1175
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
struct PLpgSQL_nsitem * ns
Definition: plpgsql.h:230
void plpgsql_parser_setup(struct ParseState *pstate, PLpgSQL_expr *expr)
Definition: pl_comp.c:1075
#define NoLock
Definition: lockdefs.h:34
static void add_dummy_return(PLpgSQL_function *function)
Definition: pl_comp.c:1032
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:220
static char * buf
Definition: pg_test_fsync.c:68
int errdetail(const char *fmt,...)
Definition: elog.c:1035
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1146
static int datums_alloc
Definition: pl_comp.c:43
Definition: zic.c:301
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
MemoryContext fn_cxt
Definition: plpgsql.h:1000
void plpgsql_ns_init(void)
Definition: pl_funcs.c:43
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2548
List * idents
Definition: plpgsql.h:1183
PLpgSQL_function * function
Definition: pl_comp.c:66
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
bool freeval
Definition: plpgsql.h:325
void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeId, int32 *typMod, Oid *collation)
Definition: pl_exec.c:5741
MemoryContext TopMemoryContext
Definition: mcxt.c:44
int * varnos
Definition: plpgsql.h:373
uint64 rectupledescid
Definition: plpgsql.h:419
Oid fn_input_collation
Definition: plpgsql.h:998
List * lappend(List *list, void *datum)
Definition: list.c:321
bool typbyval
Definition: plpgsql.h:205
#define TYPECACHE_DOMAIN_BASE_INFO
Definition: typcache.h:142
#define WARNING
Definition: elog.h:40
Oid collation
Definition: plpgsql.h:207
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1115
char * NameListToString(List *names)
Definition: namespace.c:3101
#define HASH_BLOBS
Definition: hsearch.h:86
#define TextDatumGetCString(d)
Definition: builtins.h:87
bool typisarray
Definition: plpgsql.h:208
void * palloc0(Size size)
Definition: mcxt.c:981
static void plpgsql_HashTableDelete(PLpgSQL_function *function)
Definition: pl_comp.c:2614
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:326
uintptr_t Datum
Definition: postgres.h:367
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:26
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1782
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1163
bool quoted
Definition: plpgsql.h:1170
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2068
FmgrInfo * flinfo
Definition: fmgr.h:87
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1376
static char * label
PLpgSQL_datum_type dtype
Definition: plpgsql.h:412
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1896
int number
Definition: parsenodes.h:246
Size keysize
Definition: hsearch.h:71
Trigger * tg_trigger
Definition: trigger.h:37
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:133
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:840
Datum value
Definition: plpgsql.h:323
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:334
#define InvalidOid
Definition: postgres_ext.h:36
struct PLpgSQL_function * func
Definition: plpgsql.h:227
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:444
Oid fn_oid
Definition: fmgr.h:59
#define ereport(elevel,...)
Definition: elog.h:155
PLpgSQL_trigtype fn_is_trigger
Definition: plpgsql.h:997
bool plpgsql_print_strict_params
Definition: pl_handler.c:46
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:322
int32 paramtypmod
Definition: primnodes.h:265
static void plpgsql_compile_error_callback(void *arg)
Definition: pl_comp.c:980
int location
Definition: parsenodes.h:247
int plpgsql_variable_conflict
Definition: pl_handler.c:44
char typtype
Definition: typcache.h:43
#define makeNode(_type_)
Definition: nodes.h:575
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:25
PLpgSQL_type * plpgsql_parse_cwordrowtype(List *idents)
Definition: pl_comp.c:1816
#define Assert(condition)
Definition: c.h:800
int nfields
Definition: plpgsql.h:371
int lineno
Definition: plpgsql.h:304
bool plpgsql_parse_word(char *word1, const char *yytxt, bool lookup, PLwdatum *wdatum, PLword *word)
Definition: pl_comp.c:1390
PLpgSQL_exception_block * exceptions
Definition: plpgsql.h:522
void * p_ref_hook_state
Definition: parse_node.h:222
fmNodePtr fn_expr
Definition: fmgr.h:66
int paramid
Definition: primnodes.h:263
size_t Size
Definition: c.h:528
static Node * resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
Definition: pl_comp.c:1173
char * fn_signature
Definition: plpgsql.h:993
bool function_parse_error_transpose(const char *prosrc)
Definition: pg_proc.c:965
PLpgSQL_datum * datum
Definition: plpgsql.h:1180
FormData_pg_type * Form_pg_type
Definition: pg_type.h:255
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
Definition: pl_funcs.c:54
static int list_length(const List *l)
Definition: pg_list.h:149
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
char * typname
Definition: plpgsql.h:201
PLpgSQL_stmt_block * plpgsql_parse_result
Definition: pl_comp.c:41
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
Definition: pl_comp.c:1864
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:81
#define MAXALIGN(LEN)
Definition: c.h:753
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition: mcxt.c:330
char * refname
Definition: plpgsql.h:281
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:308
uint64 tupDesc_identifier
Definition: typcache.h:89
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1256
PLpgSQL_datum_type dtype
Definition: plpgsql.h:279
void * fn_extra
Definition: fmgr.h:64
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1070
const char * name
Definition: encode.c:561
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1246
char typtype
Definition: plpgsql.h:206
int plpgsql_add_initdatums(int **varnos)
Definition: pl_comp.c:2371
void plpgsql_scanner_init(const char *str)
Definition: pl_scanner.c:586
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2714
bool quoted
Definition: plpgsql.h:1182
char * ident
Definition: plpgsql.h:1181
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:902
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2327
int32 atttypmod
Definition: plpgsql.h:209
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:797
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:453
#define elog(elevel,...)
Definition: elog.h:228
bool plpgsql_parse_tripword(char *word1, char *word2, char *word3, PLwdatum *wdatum, PLcword *cword)
Definition: pl_comp.c:1525
int i
TypeName * makeTypeNameFromNameList(List *names)
Definition: makefuncs.c:456
TupleDesc rowtupdesc
Definition: plpgsql.h:369
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:55
#define errcontext
Definition: elog.h:199
#define NameStr(name)
Definition: c.h:677
void * arg
static int datums_last
Definition: pl_comp.c:46
#define lthird(l)
Definition: pg_list.h:184
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:218
int16 typlen
Definition: plpgsql.h:204
Oid rectypeid
Definition: plpgsql.h:397
PLpgSQL_condition * plpgsql_parse_err_condition(char *condname)
Definition: pl_comp.c:2242
static PLpgSQL_row * build_row_from_vars(PLpgSQL_variable **vars, int numvars)
Definition: pl_comp.c:1954
Definition: regcomp.c:224
Definition: pg_list.h:50
#define snprintf
Definition: port.h:215
TupleDesc tupDesc
Definition: typcache.h:88
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1102
char * fieldname
Definition: plpgsql.h:416
int lineno
Definition: plpgsql.h:384
Oid paramtype
Definition: primnodes.h:264
#define TYPECACHE_TUPDESC
Definition: typcache.h:138
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:422
PLpgSQL_datum_type dtype
Definition: plpgsql.h:355
List * fields
Definition: parsenodes.h:236
int firstfield
Definition: plpgsql.h:399
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:52
PLpgSQL_nsitem_type
Definition: plpgsql.h:41
static Node * make_datum_param(PLpgSQL_expr *expr, int dno, int location)
Definition: pl_comp.c:1337
int lineno
Definition: plpgsql.h:358
bool isnull
Definition: plpgsql.h:324
Oid typoid
Definition: plpgsql.h:202