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