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