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