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