1 /*-------------------------------------------------------------------------
3 * pl_comp.c - Compiler part of the PL/pgSQL
6 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.137 2009/07/12 17:12:34 tgl Exp $
13 *-------------------------------------------------------------------------
22 #include "catalog/namespace.h"
23 #include "catalog/pg_attrdef.h"
24 #include "catalog/pg_attribute.h"
25 #include "catalog/pg_class.h"
26 #include "catalog/pg_proc.h"
27 #include "catalog/pg_proc_fn.h"
28 #include "catalog/pg_type.h"
30 #include "nodes/makefuncs.h"
31 #include "parser/parse_type.h"
32 #include "tcop/tcopprot.h"
33 #include "utils/array.h"
34 #include "utils/builtins.h"
35 #include "utils/lsyscache.h"
36 #include "utils/memutils.h"
37 #include "utils/syscache.h"
41 * Our own local and global variables
44 static int datums_alloc;
46 PLpgSQL_datum **plpgsql_Datums;
47 static int datums_last = 0;
49 int plpgsql_error_lineno;
50 char *plpgsql_error_funcname;
51 bool plpgsql_DumpExecTree = false;
52 bool plpgsql_check_syntax = false;
54 PLpgSQL_function *plpgsql_curr_compile;
56 /* A context appropriate for short-term allocs during compilation */
57 MemoryContext compile_tmp_cxt;
60 * Hash table for compiled functions
63 static HTAB *plpgsql_HashTable = NULL;
65 typedef struct plpgsql_hashent
67 PLpgSQL_func_hashkey key;
68 PLpgSQL_function *function;
71 #define FUNCS_PER_USER 128 /* initial table size */
74 * Lookup table for EXCEPTION condition names
83 static const ExceptionLabelMap exception_label_map[] = {
84 #include "plerrcodes.h"
93 static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
95 PLpgSQL_function *function,
96 PLpgSQL_func_hashkey *hashkey,
98 static PLpgSQL_row *build_row_from_class(Oid classOid);
99 static PLpgSQL_row *build_row_from_vars(PLpgSQL_variable **vars, int numvars);
100 static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
101 static void compute_function_hashkey(FunctionCallInfo fcinfo,
102 Form_pg_proc procStruct,
103 PLpgSQL_func_hashkey *hashkey,
105 static void plpgsql_resolve_polymorphic_argtypes(int numargs,
106 Oid *argtypes, char *argmodes,
107 Node *call_expr, bool forValidator,
108 const char *proname);
109 static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
110 static void plpgsql_HashTableInsert(PLpgSQL_function *function,
111 PLpgSQL_func_hashkey *func_key);
112 static void plpgsql_HashTableDelete(PLpgSQL_function *function);
113 static void delete_function(PLpgSQL_function *func);
116 * plpgsql_compile Make an execution tree for a PL/pgSQL function.
118 * If forValidator is true, we're only compiling for validation purposes,
119 * and so some checks are skipped.
121 * Note: it's important for this to fall through quickly if the function
122 * has already been compiled.
126 plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
128 Oid funcOid = fcinfo->flinfo->fn_oid;
130 Form_pg_proc procStruct;
131 PLpgSQL_function *function;
132 PLpgSQL_func_hashkey hashkey;
133 bool function_valid = false;
134 bool hashkey_valid = false;
137 * Lookup the pg_proc tuple by Oid; we'll need it in any case
139 procTup = SearchSysCache(PROCOID,
140 ObjectIdGetDatum(funcOid),
142 if (!HeapTupleIsValid(procTup))
143 elog(ERROR, "cache lookup failed for function %u", funcOid);
144 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
147 * See if there's already a cache entry for the current FmgrInfo. If not,
148 * try to find one in the hash table.
150 function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
155 /* Compute hashkey using function signature and actual arg types */
156 compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
157 hashkey_valid = true;
159 /* And do the lookup */
160 function = plpgsql_HashTableLookup(&hashkey);
165 /* We have a compiled function, but is it still valid? */
166 if (function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
167 ItemPointerEquals(&function->fn_tid, &procTup->t_self))
168 function_valid = true;
172 * Nope, so remove it from hashtable and try to drop associated
173 * storage (if not done already).
175 delete_function(function);
178 * If the function isn't in active use then we can overwrite the
179 * func struct with new data, allowing any other existing fn_extra
180 * pointers to make use of the new definition on their next use.
181 * If it is in use then just leave it alone and make a new one.
182 * (The active invocations will run to completion using the
183 * previous definition, and then the cache entry will just be
184 * leaked; doesn't seem worth adding code to clean it up, given
185 * what a corner case this is.)
187 * If we found the function struct via fn_extra then it's possible
188 * a replacement has already been made, so go back and recheck the
191 if (function->use_count != 0)
201 * If the function wasn't found or was out-of-date, we have to compile it
206 * Calculate hashkey if we didn't already; we'll need it to store the
207 * completed function.
210 compute_function_hashkey(fcinfo, procStruct, &hashkey,
216 function = do_compile(fcinfo, procTup, function,
217 &hashkey, forValidator);
220 ReleaseSysCache(procTup);
223 * Save pointer in FmgrInfo to avoid search on subsequent calls
225 fcinfo->flinfo->fn_extra = (void *) function;
228 * Finally return the compiled function
234 * This is the slow part of plpgsql_compile().
236 * The passed-in "function" pointer is either NULL or an already-allocated
237 * function struct to overwrite.
239 * While compiling a function, the CurrentMemoryContext is the
240 * per-function memory context of the function we are compiling. That
241 * means a palloc() will allocate storage with the same lifetime as
242 * the function itself.
244 * Because palloc()'d storage will not be immediately freed, temporary
245 * allocations should either be performed in a short-lived memory
246 * context or explicitly pfree'd. Since not all backend functions are
247 * careful about pfree'ing their allocations, it is also wise to
248 * switch into a short-term context before calling into the
249 * backend. An appropriate context for performing short-term
250 * allocations is the compile_tmp_cxt.
252 * NB: this code is not re-entrant. We assume that nothing we do here could
253 * result in the invocation of another plpgsql function.
255 static PLpgSQL_function *
256 do_compile(FunctionCallInfo fcinfo,
258 PLpgSQL_function *function,
259 PLpgSQL_func_hashkey *hashkey,
262 Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
263 bool is_trigger = CALLED_AS_TRIGGER(fcinfo);
268 Form_pg_type typeStruct;
269 PLpgSQL_variable *var;
272 ErrorContextCallback plerrcontext;
277 int num_out_args = 0;
281 int *in_arg_varnos = NULL;
282 PLpgSQL_variable **out_arg_variables;
283 MemoryContext func_cxt;
286 * Setup the scanner input and error info. We assume that this function
287 * cannot be invoked recursively, so there's no need to save and restore
288 * the static variables used here.
290 prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
291 Anum_pg_proc_prosrc, &isnull);
293 elog(ERROR, "null prosrc");
294 proc_source = TextDatumGetCString(prosrcdatum);
295 plpgsql_scanner_init(proc_source);
297 plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
298 plpgsql_error_lineno = 0;
301 * Setup error traceback support for ereport()
303 plerrcontext.callback = plpgsql_compile_error_callback;
304 plerrcontext.arg = forValidator ? proc_source : NULL;
305 plerrcontext.previous = error_context_stack;
306 error_context_stack = &plerrcontext;
309 * Initialize the compiler, particularly the namespace stack. The
310 * outermost namespace contains function parameters and other special
311 * variables (such as FOUND), and is named after the function itself.
314 plpgsql_ns_push(NameStr(procStruct->proname));
315 plpgsql_DumpExecTree = false;
319 /* This is short-lived, so needn't allocate in function's cxt */
320 plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
324 * Do extra syntax checks when validating the function definition. We skip
325 * this when actually compiling functions for execution, for performance
328 plpgsql_check_syntax = forValidator;
331 * Create the new function struct, if not done already. The function
332 * structs are never thrown away, so keep them in TopMemoryContext.
334 if (function == NULL)
336 function = (PLpgSQL_function *)
337 MemoryContextAllocZero(TopMemoryContext, sizeof(PLpgSQL_function));
341 /* re-using a previously existing struct, so clear it out */
342 memset(function, 0, sizeof(PLpgSQL_function));
344 plpgsql_curr_compile = function;
347 * All the rest of the compile-time storage (e.g. parse tree) is kept in
348 * its own memory context, so it can be reclaimed easily.
350 func_cxt = AllocSetContextCreate(TopMemoryContext,
351 "PL/PgSQL function context",
352 ALLOCSET_DEFAULT_MINSIZE,
353 ALLOCSET_DEFAULT_INITSIZE,
354 ALLOCSET_DEFAULT_MAXSIZE);
355 compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
357 function->fn_name = pstrdup(NameStr(procStruct->proname));
358 function->fn_oid = fcinfo->flinfo->fn_oid;
359 function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
360 function->fn_tid = procTup->t_self;
361 function->fn_is_trigger = is_trigger;
362 function->fn_cxt = func_cxt;
363 function->out_param_varno = -1; /* set up for no OUT param */
370 * Fetch info about the procedure's parameters. Allocations aren't
371 * needed permanently, so make them in tmp cxt.
373 * We also need to resolve any polymorphic input or output
374 * argument types. In validation mode we won't be able to, so we
375 * arbitrarily assume we are dealing with integers.
377 MemoryContextSwitchTo(compile_tmp_cxt);
379 numargs = get_func_arg_info(procTup,
380 &argtypes, &argnames, &argmodes);
382 plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
383 fcinfo->flinfo->fn_expr,
385 plpgsql_error_funcname);
387 in_arg_varnos = (int *) palloc(numargs * sizeof(int));
388 out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
390 MemoryContextSwitchTo(func_cxt);
393 * Create the variables for the procedure's parameters.
395 for (i = 0; i < numargs; i++)
398 Oid argtypeid = argtypes[i];
399 char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
400 PLpgSQL_type *argdtype;
401 PLpgSQL_variable *argvariable;
404 /* Create $n name for variable */
405 snprintf(buf, sizeof(buf), "$%d", i + 1);
407 /* Create datatype info */
408 argdtype = plpgsql_build_datatype(argtypeid, -1);
410 /* Disallow pseudotype argument */
411 /* (note we already replaced polymorphic types) */
412 /* (build_variable would do this, but wrong message) */
413 if (argdtype->ttype != PLPGSQL_TTYPE_SCALAR &&
414 argdtype->ttype != PLPGSQL_TTYPE_ROW)
416 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
417 errmsg("PL/pgSQL functions cannot accept type %s",
418 format_type_be(argtypeid))));
420 /* Build variable and add to datum list */
421 argvariable = plpgsql_build_variable(buf, 0,
424 if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
426 argitemtype = PLPGSQL_NSTYPE_VAR;
427 /* input argument vars are forced to be CONSTANT */
428 if (argmode == PROARGMODE_IN ||
429 argmode == PROARGMODE_VARIADIC)
430 ((PLpgSQL_var *) argvariable)->isconst = true;
434 Assert(argvariable->dtype == PLPGSQL_DTYPE_ROW);
435 argitemtype = PLPGSQL_NSTYPE_ROW;
438 /* Remember arguments in appropriate arrays */
439 if (argmode == PROARGMODE_IN ||
440 argmode == PROARGMODE_INOUT ||
441 argmode == PROARGMODE_VARIADIC)
442 in_arg_varnos[num_in_args++] = argvariable->dno;
443 if (argmode == PROARGMODE_OUT ||
444 argmode == PROARGMODE_INOUT ||
445 argmode == PROARGMODE_TABLE)
446 out_arg_variables[num_out_args++] = argvariable;
448 /* Add to namespace under the $n name */
449 plpgsql_ns_additem(argitemtype, argvariable->dno, buf);
451 /* If there's a name for the argument, make an alias */
452 if (argnames && argnames[i][0] != '\0')
453 plpgsql_ns_additem(argitemtype, argvariable->dno,
458 * If there's just one OUT parameter, out_param_varno points
459 * directly to it. If there's more than one, build a row that
462 if (num_out_args == 1)
463 function->out_param_varno = out_arg_variables[0]->dno;
464 else if (num_out_args > 1)
466 PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
469 plpgsql_adddatum((PLpgSQL_datum *) row);
470 function->out_param_varno = row->dno;
474 * Check for a polymorphic returntype. If found, use the actual
475 * returntype type from the caller's FuncExpr node, if we have
476 * one. (In validation mode we arbitrarily assume we are dealing
479 * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
480 * work; if it doesn't we're in some context that fails to make
481 * the info available.
483 rettypeid = procStruct->prorettype;
484 if (IsPolymorphicType(rettypeid))
488 if (rettypeid == ANYARRAYOID)
489 rettypeid = INT4ARRAYOID;
490 else /* ANYELEMENT or ANYNONARRAY */
492 /* XXX what could we use for ANYENUM? */
496 rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
497 if (!OidIsValid(rettypeid))
499 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
500 errmsg("could not determine actual return type "
501 "for polymorphic function \"%s\"",
502 plpgsql_error_funcname)));
507 * Normal function has a defined returntype
509 function->fn_rettype = rettypeid;
510 function->fn_retset = procStruct->proretset;
513 * Lookup the function's return type
515 typeTup = SearchSysCache(TYPEOID,
516 ObjectIdGetDatum(rettypeid),
518 if (!HeapTupleIsValid(typeTup))
519 elog(ERROR, "cache lookup failed for type %u", rettypeid);
520 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
522 /* Disallow pseudotype result, except VOID or RECORD */
523 /* (note we already replaced polymorphic types) */
524 if (typeStruct->typtype == TYPTYPE_PSEUDO)
526 if (rettypeid == VOIDOID ||
527 rettypeid == RECORDOID)
529 else if (rettypeid == TRIGGEROID)
531 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
532 errmsg("trigger functions can only be called as triggers")));
535 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
536 errmsg("PL/pgSQL functions cannot return type %s",
537 format_type_be(rettypeid))));
540 if (typeStruct->typrelid != InvalidOid ||
541 rettypeid == RECORDOID)
542 function->fn_retistuple = true;
545 function->fn_retbyval = typeStruct->typbyval;
546 function->fn_rettyplen = typeStruct->typlen;
547 function->fn_rettypioparam = getTypeIOParam(typeTup);
548 fmgr_info(typeStruct->typinput, &(function->fn_retinput));
551 * install $0 reference, but only for polymorphic return
552 * types, and not when the return is specified through an
555 if (IsPolymorphicType(procStruct->prorettype) &&
558 (void) plpgsql_build_variable("$0", 0,
559 build_datatype(typeTup, -1),
563 ReleaseSysCache(typeTup);
567 /* Trigger procedure's return type is unknown yet */
568 function->fn_rettype = InvalidOid;
569 function->fn_retbyval = false;
570 function->fn_retistuple = true;
571 function->fn_retset = false;
573 /* shouldn't be any declared arguments */
574 if (procStruct->pronargs != 0)
576 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
577 errmsg("trigger functions cannot have declared arguments"),
578 errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
580 /* Add the record for referencing NEW */
581 rec = plpgsql_build_record("new", 0, true);
582 function->new_varno = rec->dno;
584 /* Add the record for referencing OLD */
585 rec = plpgsql_build_record("old", 0, true);
586 function->old_varno = rec->dno;
588 /* Add the variable tg_name */
589 var = plpgsql_build_variable("tg_name", 0,
590 plpgsql_build_datatype(NAMEOID, -1),
592 function->tg_name_varno = var->dno;
594 /* Add the variable tg_when */
595 var = plpgsql_build_variable("tg_when", 0,
596 plpgsql_build_datatype(TEXTOID, -1),
598 function->tg_when_varno = var->dno;
600 /* Add the variable tg_level */
601 var = plpgsql_build_variable("tg_level", 0,
602 plpgsql_build_datatype(TEXTOID, -1),
604 function->tg_level_varno = var->dno;
606 /* Add the variable tg_op */
607 var = plpgsql_build_variable("tg_op", 0,
608 plpgsql_build_datatype(TEXTOID, -1),
610 function->tg_op_varno = var->dno;
612 /* Add the variable tg_relid */
613 var = plpgsql_build_variable("tg_relid", 0,
614 plpgsql_build_datatype(OIDOID, -1),
616 function->tg_relid_varno = var->dno;
618 /* Add the variable tg_relname */
619 var = plpgsql_build_variable("tg_relname", 0,
620 plpgsql_build_datatype(NAMEOID, -1),
622 function->tg_relname_varno = var->dno;
624 /* tg_table_name is now preferred to tg_relname */
625 var = plpgsql_build_variable("tg_table_name", 0,
626 plpgsql_build_datatype(NAMEOID, -1),
628 function->tg_table_name_varno = var->dno;
631 /* add variable tg_table_schema */
632 var = plpgsql_build_variable("tg_table_schema", 0,
633 plpgsql_build_datatype(NAMEOID, -1),
635 function->tg_table_schema_varno = var->dno;
638 /* Add the variable tg_nargs */
639 var = plpgsql_build_variable("tg_nargs", 0,
640 plpgsql_build_datatype(INT4OID, -1),
642 function->tg_nargs_varno = var->dno;
647 elog(ERROR, "unrecognized function typecode: %d", (int) is_trigger);
651 /* Remember if function is STABLE/IMMUTABLE */
652 function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
655 * Create the magic FOUND variable.
657 var = plpgsql_build_variable("found", 0,
658 plpgsql_build_datatype(BOOLOID, -1),
660 function->found_varno = var->dno;
663 * Now parse the function's text
665 parse_rc = plpgsql_yyparse();
667 elog(ERROR, "plpgsql parser returned %d", parse_rc);
668 function->action = plpgsql_yylval.program;
670 plpgsql_scanner_finish();
674 * If it has OUT parameters or returns VOID or returns a set, we allow
675 * control to fall off the end without an explicit RETURN statement. The
676 * easiest way to implement this is to add a RETURN statement to the end
677 * of the statement list during parsing. However, if the outer block has
678 * an EXCEPTION clause, we need to make a new outer block, since the added
679 * RETURN shouldn't act like it is inside the EXCEPTION clause.
681 if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
684 if (function->action->exceptions != NULL)
686 PLpgSQL_stmt_block *new;
688 new = palloc0(sizeof(PLpgSQL_stmt_block));
689 new->cmd_type = PLPGSQL_STMT_BLOCK;
690 new->body = list_make1(function->action);
692 function->action = new;
694 if (function->action->body == NIL ||
695 ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
697 PLpgSQL_stmt_return *new;
699 new = palloc0(sizeof(PLpgSQL_stmt_return));
700 new->cmd_type = PLPGSQL_STMT_RETURN;
702 new->retvarno = function->out_param_varno;
704 function->action->body = lappend(function->action->body, new);
709 * Complete the function's info
711 function->fn_nargs = procStruct->pronargs;
712 for (i = 0; i < function->fn_nargs; i++)
713 function->fn_argvarnos[i] = in_arg_varnos[i];
714 function->ndatums = plpgsql_nDatums;
715 function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
716 for (i = 0; i < plpgsql_nDatums; i++)
717 function->datums[i] = plpgsql_Datums[i];
719 /* Debug dump for completed functions */
720 if (plpgsql_DumpExecTree)
721 plpgsql_dumptree(function);
724 * add it to the hash table
726 plpgsql_HashTableInsert(function, hashkey);
729 * Pop the error context stack
731 error_context_stack = plerrcontext.previous;
732 plpgsql_error_funcname = NULL;
733 plpgsql_error_lineno = 0;
735 plpgsql_check_syntax = false;
737 MemoryContextSwitchTo(compile_tmp_cxt);
738 compile_tmp_cxt = NULL;
744 * error context callback to let us supply a call-stack traceback. If
745 * we are validating, the function source is passed as an
746 * argument. This function is public only for the sake of an assertion
750 plpgsql_compile_error_callback(void *arg)
755 * Try to convert syntax error position to reference text of original
756 * CREATE FUNCTION command.
758 if (function_parse_error_transpose((const char *) arg))
762 * Done if a syntax error position was reported; otherwise we have to
763 * fall back to a "near line N" report.
767 if (plpgsql_error_funcname)
768 errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
769 plpgsql_error_funcname, plpgsql_error_lineno);
774 * plpgsql_parse_word The scanner calls this to postparse
775 * any single word not found by a
780 plpgsql_parse_word(const char *word)
785 /* Do case conversion and word separation */
786 plpgsql_convert_ident(word, cp, 1);
789 * Recognize tg_argv when compiling triggers (XXX this sucks, it should be
790 * a regular variable in the namestack)
792 if (plpgsql_curr_compile->fn_is_trigger)
794 if (strcmp(cp[0], "tg_argv") == 0)
796 bool save_spacescanned = plpgsql_SpaceScanned;
797 PLpgSQL_trigarg *trigarg;
799 trigarg = palloc0(sizeof(PLpgSQL_trigarg));
800 trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
802 if (plpgsql_yylex() != '[')
803 plpgsql_yyerror("expected \"[\"");
805 trigarg->argnum = plpgsql_read_expression(']', "]");
807 plpgsql_adddatum((PLpgSQL_datum *) trigarg);
808 plpgsql_yylval.scalar = (PLpgSQL_datum *) trigarg;
810 plpgsql_SpaceScanned = save_spacescanned;
817 * Do a lookup on the compiler's namestack
819 nse = plpgsql_ns_lookup(cp[0], NULL, NULL, NULL);
824 switch (nse->itemtype)
826 case PLPGSQL_NSTYPE_VAR:
827 plpgsql_yylval.scalar = plpgsql_Datums[nse->itemno];
830 case PLPGSQL_NSTYPE_REC:
831 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]);
834 case PLPGSQL_NSTYPE_ROW:
835 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[nse->itemno]);
844 * Nothing found - up to now it's a word without any special meaning for
852 * plpgsql_parse_dblword Same lookup for two words
853 * separated by a dot.
857 plpgsql_parse_dblword(const char *word)
863 /* Do case conversion and word separation */
864 plpgsql_convert_ident(word, cp, 2);
867 * Do a lookup on the compiler's namestack
869 ns = plpgsql_ns_lookup(cp[0], cp[1], NULL, &nnames);
877 switch (ns->itemtype)
879 case PLPGSQL_NSTYPE_VAR:
880 /* Block-qualified reference to scalar variable. */
881 plpgsql_yylval.scalar = plpgsql_Datums[ns->itemno];
886 case PLPGSQL_NSTYPE_REC:
890 * First word is a record name, so second word must be a field
893 PLpgSQL_recfield *new;
895 new = palloc(sizeof(PLpgSQL_recfield));
896 new->dtype = PLPGSQL_DTYPE_RECFIELD;
897 new->fieldname = pstrdup(cp[1]);
898 new->recparentno = ns->itemno;
900 plpgsql_adddatum((PLpgSQL_datum *) new);
902 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
910 /* Block-qualified reference to record variable. */
911 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
917 case PLPGSQL_NSTYPE_ROW:
921 * First word is a row name, so second word must be a field in
927 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
928 for (i = 0; i < row->nfields; i++)
930 if (row->fieldnames[i] &&
931 strcmp(row->fieldnames[i], cp[1]) == 0)
933 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
940 (errcode(ERRCODE_UNDEFINED_COLUMN),
941 errmsg("row \"%s\" has no field \"%s\"",
946 /* Block-qualified reference to row variable. */
947 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
964 * plpgsql_parse_tripword Same lookup for three words
969 plpgsql_parse_tripword(const char *word)
975 /* Do case conversion and word separation */
976 plpgsql_convert_ident(word, cp, 3);
979 * Do a lookup on the compiler's namestack. Must find a qualified
982 ns = plpgsql_ns_lookup(cp[0], cp[1], cp[2], &nnames);
983 if (ns == NULL || nnames != 2)
991 switch (ns->itemtype)
993 case PLPGSQL_NSTYPE_REC:
996 * words 1/2 are a record name, so third word must be a field
999 PLpgSQL_recfield *new;
1001 new = palloc(sizeof(PLpgSQL_recfield));
1002 new->dtype = PLPGSQL_DTYPE_RECFIELD;
1003 new->fieldname = pstrdup(cp[2]);
1004 new->recparentno = ns->itemno;
1006 plpgsql_adddatum((PLpgSQL_datum *) new);
1008 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
1017 case PLPGSQL_NSTYPE_ROW:
1020 * words 1/2 are a row name, so third word must be a field in
1026 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1027 for (i = 0; i < row->nfields; i++)
1029 if (row->fieldnames[i] &&
1030 strcmp(row->fieldnames[i], cp[2]) == 0)
1032 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
1042 (errcode(ERRCODE_UNDEFINED_COLUMN),
1043 errmsg("row \"%s.%s\" has no field \"%s\"",
1044 cp[0], cp[1], cp[2])));
1059 * plpgsql_parse_wordtype The scanner found word%TYPE. word can be
1060 * a variable name or a basetype.
1064 plpgsql_parse_wordtype(char *word)
1066 PLpgSQL_nsitem *nse;
1072 /* Do case conversion and word separation */
1073 /* We convert %type to .type momentarily to keep converter happy */
1074 i = strlen(word) - 5;
1075 Assert(word[i] == '%');
1077 plpgsql_convert_ident(word, cp, 2);
1082 * Do a lookup on the compiler's namestack. Ensure we scan all levels.
1084 old_nsstate = plpgsql_ns_setlocal(false);
1085 nse = plpgsql_ns_lookup(cp[0], NULL, NULL, NULL);
1086 plpgsql_ns_setlocal(old_nsstate);
1091 switch (nse->itemtype)
1093 case PLPGSQL_NSTYPE_VAR:
1094 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1097 /* XXX perhaps allow REC here? */
1105 * Word wasn't found on the namestack. Try to find a data type with that
1106 * name, but ignore shell types and complex types.
1108 typeTup = LookupTypeName(NULL, makeTypeName(cp[0]), NULL);
1111 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1113 if (!typeStruct->typisdefined ||
1114 typeStruct->typrelid != InvalidOid)
1116 ReleaseSysCache(typeTup);
1121 plpgsql_yylval.dtype = build_datatype(typeTup, -1);
1123 ReleaseSysCache(typeTup);
1129 * Nothing found - up to now it's a word without any special meaning for
1138 * plpgsql_parse_dblwordtype Same lookup for word.word%TYPE
1142 plpgsql_parse_dblwordtype(char *word)
1144 PLpgSQL_nsitem *nse;
1147 HeapTuple classtup = NULL;
1148 HeapTuple attrtup = NULL;
1149 HeapTuple typetup = NULL;
1150 Form_pg_class classStruct;
1151 Form_pg_attribute attrStruct;
1154 MemoryContext oldCxt;
1155 int result = T_ERROR;
1157 /* Avoid memory leaks in the long-term function context */
1158 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1160 /* Do case conversion and word separation */
1161 /* We convert %type to .type momentarily to keep converter happy */
1162 i = strlen(word) - 5;
1163 Assert(word[i] == '%');
1165 plpgsql_convert_ident(word, cp, 3);
1170 * Do a lookup on the compiler's namestack. Ensure we scan all levels. We
1171 * don't need to check number of names matched, because we will only
1172 * consider scalar variables.
1174 old_nsstate = plpgsql_ns_setlocal(false);
1175 nse = plpgsql_ns_lookup(cp[0], cp[1], NULL, NULL);
1176 plpgsql_ns_setlocal(old_nsstate);
1178 if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1180 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1186 * First word could also be a table name
1188 classOid = RelnameGetRelid(cp[0]);
1189 if (!OidIsValid(classOid))
1192 classtup = SearchSysCache(RELOID,
1193 ObjectIdGetDatum(classOid),
1195 if (!HeapTupleIsValid(classtup))
1197 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1200 * It must be a relation, sequence, view, or type
1202 if (classStruct->relkind != RELKIND_RELATION &&
1203 classStruct->relkind != RELKIND_SEQUENCE &&
1204 classStruct->relkind != RELKIND_VIEW &&
1205 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1209 * Fetch the named table field and its type
1211 attrtup = SearchSysCacheAttName(classOid, cp[1]);
1212 if (!HeapTupleIsValid(attrtup))
1214 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1216 typetup = SearchSysCache(TYPEOID,
1217 ObjectIdGetDatum(attrStruct->atttypid),
1219 if (!HeapTupleIsValid(typetup))
1220 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1223 * Found that - build a compiler type struct in the caller's cxt and
1226 MemoryContextSwitchTo(oldCxt);
1227 plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1228 MemoryContextSwitchTo(compile_tmp_cxt);
1232 if (HeapTupleIsValid(classtup))
1233 ReleaseSysCache(classtup);
1234 if (HeapTupleIsValid(attrtup))
1235 ReleaseSysCache(attrtup);
1236 if (HeapTupleIsValid(typetup))
1237 ReleaseSysCache(typetup);
1239 MemoryContextSwitchTo(oldCxt);
1244 * plpgsql_parse_tripwordtype Same lookup for word.word.word%TYPE
1248 plpgsql_parse_tripwordtype(char *word)
1251 HeapTuple classtup = NULL;
1252 HeapTuple attrtup = NULL;
1253 HeapTuple typetup = NULL;
1254 Form_pg_class classStruct;
1255 Form_pg_attribute attrStruct;
1259 MemoryContext oldCxt;
1260 int result = T_ERROR;
1262 /* Avoid memory leaks in the long-term function context */
1263 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1265 /* Do case conversion and word separation */
1266 /* We convert %type to .type momentarily to keep converter happy */
1267 i = strlen(word) - 5;
1268 Assert(word[i] == '%');
1270 plpgsql_convert_ident(word, cp, 4);
1274 relvar = makeRangeVar(cp[0], cp[1], -1);
1275 classOid = RangeVarGetRelid(relvar, true);
1276 if (!OidIsValid(classOid))
1279 classtup = SearchSysCache(RELOID,
1280 ObjectIdGetDatum(classOid),
1282 if (!HeapTupleIsValid(classtup))
1284 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1287 * It must be a relation, sequence, view, or type
1289 if (classStruct->relkind != RELKIND_RELATION &&
1290 classStruct->relkind != RELKIND_SEQUENCE &&
1291 classStruct->relkind != RELKIND_VIEW &&
1292 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1296 * Fetch the named table field and its type
1298 attrtup = SearchSysCacheAttName(classOid, cp[2]);
1299 if (!HeapTupleIsValid(attrtup))
1301 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1303 typetup = SearchSysCache(TYPEOID,
1304 ObjectIdGetDatum(attrStruct->atttypid),
1306 if (!HeapTupleIsValid(typetup))
1307 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1310 * Found that - build a compiler type struct in the caller's cxt and
1313 MemoryContextSwitchTo(oldCxt);
1314 plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1315 MemoryContextSwitchTo(compile_tmp_cxt);
1319 if (HeapTupleIsValid(classtup))
1320 ReleaseSysCache(classtup);
1321 if (HeapTupleIsValid(attrtup))
1322 ReleaseSysCache(attrtup);
1323 if (HeapTupleIsValid(typetup))
1324 ReleaseSysCache(typetup);
1326 MemoryContextSwitchTo(oldCxt);
1331 * plpgsql_parse_wordrowtype Scanner found word%ROWTYPE.
1332 * So word must be a table name.
1336 plpgsql_parse_wordrowtype(char *word)
1342 /* Do case conversion and word separation */
1343 /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1344 i = strlen(word) - 8;
1345 Assert(word[i] == '%');
1347 plpgsql_convert_ident(word, cp, 2);
1350 /* Lookup the relation */
1351 classOid = RelnameGetRelid(cp[0]);
1352 if (!OidIsValid(classOid))
1354 (errcode(ERRCODE_UNDEFINED_TABLE),
1355 errmsg("relation \"%s\" does not exist", cp[0])));
1358 * Build and return the row type struct
1360 plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1370 * plpgsql_parse_dblwordrowtype Scanner found word.word%ROWTYPE.
1371 * So word must be a namespace qualified table name.
1375 plpgsql_parse_dblwordrowtype(char *word)
1381 MemoryContext oldCxt;
1383 /* Avoid memory leaks in long-term function context */
1384 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1386 /* Do case conversion and word separation */
1387 /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1388 i = strlen(word) - 8;
1389 Assert(word[i] == '%');
1391 plpgsql_convert_ident(word, cp, 3);
1394 /* Lookup the relation */
1395 relvar = makeRangeVar(cp[0], cp[1], -1);
1396 classOid = RangeVarGetRelid(relvar, true);
1397 if (!OidIsValid(classOid))
1399 (errcode(ERRCODE_UNDEFINED_TABLE),
1400 errmsg("relation \"%s.%s\" does not exist", cp[0], cp[1])));
1402 /* Build and return the row type struct */
1403 plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1406 MemoryContextSwitchTo(oldCxt);
1411 * plpgsql_build_variable - build a datum-array entry of a given
1414 * The returned struct may be a PLpgSQL_var, PLpgSQL_row, or
1415 * PLpgSQL_rec depending on the given datatype, and is allocated via
1416 * palloc. The struct is automatically added to the current datum
1417 * array, and optionally to the current namespace.
1420 plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype,
1423 PLpgSQL_variable *result;
1425 switch (dtype->ttype)
1427 case PLPGSQL_TTYPE_SCALAR:
1429 /* Ordinary scalar datatype */
1432 var = palloc0(sizeof(PLpgSQL_var));
1433 var->dtype = PLPGSQL_DTYPE_VAR;
1434 var->refname = pstrdup(refname);
1435 var->lineno = lineno;
1436 var->datatype = dtype;
1437 /* other fields might be filled by caller */
1439 /* preset to NULL */
1442 var->freeval = false;
1444 plpgsql_adddatum((PLpgSQL_datum *) var);
1446 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
1449 result = (PLpgSQL_variable *) var;
1452 case PLPGSQL_TTYPE_ROW:
1454 /* Composite type -- build a row variable */
1457 row = build_row_from_class(dtype->typrelid);
1459 row->dtype = PLPGSQL_DTYPE_ROW;
1460 row->refname = pstrdup(refname);
1461 row->lineno = lineno;
1463 plpgsql_adddatum((PLpgSQL_datum *) row);
1465 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
1468 result = (PLpgSQL_variable *) row;
1471 case PLPGSQL_TTYPE_REC:
1473 /* "record" type -- build a record variable */
1476 rec = plpgsql_build_record(refname, lineno, add2namespace);
1477 result = (PLpgSQL_variable *) rec;
1480 case PLPGSQL_TTYPE_PSEUDO:
1482 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1483 errmsg("variable \"%s\" has pseudo-type %s",
1484 refname, format_type_be(dtype->typoid))));
1485 result = NULL; /* keep compiler quiet */
1488 elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1489 result = NULL; /* keep compiler quiet */
1497 * Build empty named record variable, and optionally add it to namespace
1500 plpgsql_build_record(const char *refname, int lineno, bool add2namespace)
1504 rec = palloc0(sizeof(PLpgSQL_rec));
1505 rec->dtype = PLPGSQL_DTYPE_REC;
1506 rec->refname = pstrdup(refname);
1507 rec->lineno = lineno;
1509 rec->tupdesc = NULL;
1510 rec->freetup = false;
1511 plpgsql_adddatum((PLpgSQL_datum *) rec);
1513 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->dno, rec->refname);
1519 * Build a row-variable data structure given the pg_class OID.
1521 static PLpgSQL_row *
1522 build_row_from_class(Oid classOid)
1526 Form_pg_class classStruct;
1527 const char *relname;
1531 * Open the relation to get info.
1533 rel = relation_open(classOid, AccessShareLock);
1534 classStruct = RelationGetForm(rel);
1535 relname = RelationGetRelationName(rel);
1537 /* accept relation, sequence, view, or composite type entries */
1538 if (classStruct->relkind != RELKIND_RELATION &&
1539 classStruct->relkind != RELKIND_SEQUENCE &&
1540 classStruct->relkind != RELKIND_VIEW &&
1541 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1543 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1544 errmsg("relation \"%s\" is not a table", relname)));
1547 * Create a row datum entry and all the required variables that it will
1550 row = palloc0(sizeof(PLpgSQL_row));
1551 row->dtype = PLPGSQL_DTYPE_ROW;
1552 row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
1553 row->nfields = classStruct->relnatts;
1554 row->fieldnames = palloc(sizeof(char *) * row->nfields);
1555 row->varnos = palloc(sizeof(int) * row->nfields);
1557 for (i = 0; i < row->nfields; i++)
1559 Form_pg_attribute attrStruct;
1562 * Get the attribute and check for dropped column
1564 attrStruct = row->rowtupdesc->attrs[i];
1566 if (!attrStruct->attisdropped)
1569 char refname[(NAMEDATALEN * 2) + 100];
1570 PLpgSQL_variable *var;
1572 attname = NameStr(attrStruct->attname);
1573 snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
1576 * Create the internal variable for the field
1578 * We know if the table definitions contain a default value or if
1579 * the field is declared in the table as NOT NULL. But it's
1580 * possible to create a table field as NOT NULL without a default
1581 * value and that would lead to problems later when initializing
1582 * the variables due to entering a block at execution time. Thus
1583 * we ignore this information for now.
1585 var = plpgsql_build_variable(refname, 0,
1586 plpgsql_build_datatype(attrStruct->atttypid,
1587 attrStruct->atttypmod),
1590 /* Add the variable to the row */
1591 row->fieldnames[i] = attname;
1592 row->varnos[i] = var->dno;
1596 /* Leave a hole in the row structure for the dropped col */
1597 row->fieldnames[i] = NULL;
1598 row->varnos[i] = -1;
1602 relation_close(rel, AccessShareLock);
1608 * Build a row-variable data structure given the component variables.
1610 static PLpgSQL_row *
1611 build_row_from_vars(PLpgSQL_variable **vars, int numvars)
1616 row = palloc0(sizeof(PLpgSQL_row));
1617 row->dtype = PLPGSQL_DTYPE_ROW;
1618 row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
1619 row->nfields = numvars;
1620 row->fieldnames = palloc(numvars * sizeof(char *));
1621 row->varnos = palloc(numvars * sizeof(int));
1623 for (i = 0; i < numvars; i++)
1625 PLpgSQL_variable *var = vars[i];
1626 Oid typoid = RECORDOID;
1631 case PLPGSQL_DTYPE_VAR:
1632 typoid = ((PLpgSQL_var *) var)->datatype->typoid;
1633 typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
1636 case PLPGSQL_DTYPE_REC:
1639 case PLPGSQL_DTYPE_ROW:
1640 if (((PLpgSQL_row *) var)->rowtupdesc)
1642 typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
1643 typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
1648 elog(ERROR, "unrecognized dtype: %d", var->dtype);
1651 row->fieldnames[i] = var->refname;
1652 row->varnos[i] = var->dno;
1654 TupleDescInitEntry(row->rowtupdesc, i + 1,
1665 * plpgsql_parse_datatype Scanner found something that should
1666 * be a datatype name.
1670 plpgsql_parse_datatype(const char *string)
1675 /* Let the main parser try to parse it under standard SQL rules */
1676 parseTypeString(string, &type_id, &typmod);
1678 /* Okay, build a PLpgSQL_type data structure for it */
1679 return plpgsql_build_datatype(type_id, typmod);
1683 * plpgsql_build_datatype
1684 * Build PLpgSQL_type struct given type OID and typmod.
1687 plpgsql_build_datatype(Oid typeOid, int32 typmod)
1692 typeTup = SearchSysCache(TYPEOID,
1693 ObjectIdGetDatum(typeOid),
1695 if (!HeapTupleIsValid(typeTup))
1696 elog(ERROR, "cache lookup failed for type %u", typeOid);
1698 typ = build_datatype(typeTup, typmod);
1700 ReleaseSysCache(typeTup);
1706 * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1708 static PLpgSQL_type *
1709 build_datatype(HeapTuple typeTup, int32 typmod)
1711 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1714 if (!typeStruct->typisdefined)
1716 (errcode(ERRCODE_UNDEFINED_OBJECT),
1717 errmsg("type \"%s\" is only a shell",
1718 NameStr(typeStruct->typname))));
1720 typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
1722 typ->typname = pstrdup(NameStr(typeStruct->typname));
1723 typ->typoid = HeapTupleGetOid(typeTup);
1724 switch (typeStruct->typtype)
1727 case TYPTYPE_DOMAIN:
1729 typ->ttype = PLPGSQL_TTYPE_SCALAR;
1731 case TYPTYPE_COMPOSITE:
1732 Assert(OidIsValid(typeStruct->typrelid));
1733 typ->ttype = PLPGSQL_TTYPE_ROW;
1735 case TYPTYPE_PSEUDO:
1736 if (typ->typoid == RECORDOID)
1737 typ->ttype = PLPGSQL_TTYPE_REC;
1739 typ->ttype = PLPGSQL_TTYPE_PSEUDO;
1742 elog(ERROR, "unrecognized typtype: %d",
1743 (int) typeStruct->typtype);
1746 typ->typlen = typeStruct->typlen;
1747 typ->typbyval = typeStruct->typbyval;
1748 typ->typrelid = typeStruct->typrelid;
1749 typ->typioparam = getTypeIOParam(typeTup);
1750 fmgr_info(typeStruct->typinput, &(typ->typinput));
1751 typ->atttypmod = typmod;
1757 * plpgsql_recognize_err_condition
1758 * Check condition name and translate it to SQLSTATE.
1760 * Note: there are some cases where the same condition name has multiple
1761 * entries in the table. We arbitrarily return the first match.
1764 plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
1770 if (strlen(condname) == 5 &&
1771 strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
1772 return MAKE_SQLSTATE(condname[0],
1779 for (i = 0; exception_label_map[i].label != NULL; i++)
1781 if (strcmp(condname, exception_label_map[i].label) == 0)
1782 return exception_label_map[i].sqlerrstate;
1786 (errcode(ERRCODE_UNDEFINED_OBJECT),
1787 errmsg("unrecognized exception condition \"%s\"",
1789 return 0; /* keep compiler quiet */
1793 * plpgsql_parse_err_condition
1794 * Generate PLpgSQL_condition entry(s) for an exception condition name
1796 * This has to be able to return a list because there are some duplicate
1797 * names in the table of error code names.
1800 plpgsql_parse_err_condition(char *condname)
1803 PLpgSQL_condition *new;
1804 PLpgSQL_condition *prev;
1807 * XXX Eventually we will want to look for user-defined exception names
1812 * OTHERS is represented as code 0 (which would map to '00000', but we
1813 * have no need to represent that as an exception condition).
1815 if (strcmp(condname, "others") == 0)
1817 new = palloc(sizeof(PLpgSQL_condition));
1818 new->sqlerrstate = 0;
1819 new->condname = condname;
1825 for (i = 0; exception_label_map[i].label != NULL; i++)
1827 if (strcmp(condname, exception_label_map[i].label) == 0)
1829 new = palloc(sizeof(PLpgSQL_condition));
1830 new->sqlerrstate = exception_label_map[i].sqlerrstate;
1831 new->condname = condname;
1839 (errcode(ERRCODE_UNDEFINED_OBJECT),
1840 errmsg("unrecognized exception condition \"%s\"",
1847 * plpgsql_adddatum Add a variable, record or row
1848 * to the compiler's datum list.
1852 plpgsql_adddatum(PLpgSQL_datum *new)
1854 if (plpgsql_nDatums == datums_alloc)
1857 plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
1860 new->dno = plpgsql_nDatums;
1861 plpgsql_Datums[plpgsql_nDatums++] = new;
1866 * plpgsql_add_initdatums Make an array of the datum numbers of
1867 * all the simple VAR datums created since the last call
1870 * If varnos is NULL, we just forget any datum entries created since the
1873 * This is used around a DECLARE section to create a list of the VARs
1874 * that have to be initialized at block entry. Note that VARs can also
1875 * be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
1876 * the responsibility of special-purpose code to initialize them.
1880 plpgsql_add_initdatums(int **varnos)
1885 for (i = datums_last; i < plpgsql_nDatums; i++)
1887 switch (plpgsql_Datums[i]->dtype)
1889 case PLPGSQL_DTYPE_VAR:
1902 *varnos = (int *) palloc(sizeof(int) * n);
1905 for (i = datums_last; i < plpgsql_nDatums; i++)
1907 switch (plpgsql_Datums[i]->dtype)
1909 case PLPGSQL_DTYPE_VAR:
1910 (*varnos)[n++] = plpgsql_Datums[i]->dno;
1921 datums_last = plpgsql_nDatums;
1927 * Compute the hashkey for a given function invocation
1929 * The hashkey is returned into the caller-provided storage at *hashkey.
1932 compute_function_hashkey(FunctionCallInfo fcinfo,
1933 Form_pg_proc procStruct,
1934 PLpgSQL_func_hashkey *hashkey,
1937 /* Make sure any unused bytes of the struct are zero */
1938 MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
1940 /* get function OID */
1941 hashkey->funcOid = fcinfo->flinfo->fn_oid;
1943 /* get call context */
1944 hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
1947 * if trigger, get relation OID. In validation mode we do not know what
1948 * relation is intended to be used, so we leave trigrelOid zero; the hash
1949 * entry built in this case will never really be used.
1951 if (hashkey->isTrigger && !forValidator)
1953 TriggerData *trigdata = (TriggerData *) fcinfo->context;
1955 hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
1958 if (procStruct->pronargs > 0)
1960 /* get the argument types */
1961 memcpy(hashkey->argtypes, procStruct->proargtypes.values,
1962 procStruct->pronargs * sizeof(Oid));
1964 /* resolve any polymorphic argument types */
1965 plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
1968 fcinfo->flinfo->fn_expr,
1970 NameStr(procStruct->proname));
1975 * This is the same as the standard resolve_polymorphic_argtypes() function,
1976 * but with a special case for validation: assume that polymorphic arguments
1977 * are integer or integer-array. Also, we go ahead and report the error
1978 * if we can't resolve the types.
1981 plpgsql_resolve_polymorphic_argtypes(int numargs,
1982 Oid *argtypes, char *argmodes,
1983 Node *call_expr, bool forValidator,
1984 const char *proname)
1990 /* normal case, pass to standard routine */
1991 if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
1994 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1995 errmsg("could not determine actual argument "
1996 "type for polymorphic function \"%s\"",
2001 /* special validation case */
2002 for (i = 0; i < numargs; i++)
2004 switch (argtypes[i])
2007 case ANYNONARRAYOID:
2008 case ANYENUMOID: /* XXX dubious */
2009 argtypes[i] = INT4OID;
2012 argtypes[i] = INT4ARRAYOID;
2022 * delete_function - clean up as much as possible of a stale function cache
2024 * We can't release the PLpgSQL_function struct itself, because of the
2025 * possibility that there are fn_extra pointers to it. We can release
2026 * the subsidiary storage, but only if there are no active evaluations
2027 * in progress. Otherwise we'll just leak that storage. Since the
2028 * case would only occur if a pg_proc update is detected during a nested
2029 * recursive call on the function, a leak seems acceptable.
2031 * Note that this can be called more than once if there are multiple fn_extra
2032 * pointers to the same function cache. Hence be careful not to do things
2036 delete_function(PLpgSQL_function *func)
2038 /* remove function from hash table (might be done already) */
2039 plpgsql_HashTableDelete(func);
2041 /* release the function's storage if safe and not done already */
2042 if (func->use_count == 0 && func->fn_cxt)
2044 MemoryContextDelete(func->fn_cxt);
2045 func->fn_cxt = NULL;
2049 /* exported so we can call it from plpgsql_init() */
2051 plpgsql_HashTableInit(void)
2055 /* don't allow double-initialization */
2056 Assert(plpgsql_HashTable == NULL);
2058 memset(&ctl, 0, sizeof(ctl));
2059 ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2060 ctl.entrysize = sizeof(plpgsql_HashEnt);
2061 ctl.hash = tag_hash;
2062 plpgsql_HashTable = hash_create("PLpgSQL function cache",
2065 HASH_ELEM | HASH_FUNCTION);
2068 static PLpgSQL_function *
2069 plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
2071 plpgsql_HashEnt *hentry;
2073 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2078 return hentry->function;
2084 plpgsql_HashTableInsert(PLpgSQL_function *function,
2085 PLpgSQL_func_hashkey *func_key)
2087 plpgsql_HashEnt *hentry;
2090 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2095 elog(WARNING, "trying to insert a function that already exists");
2097 hentry->function = function;
2098 /* prepare back link from function to hashtable key */
2099 function->fn_hashkey = &hentry->key;
2103 plpgsql_HashTableDelete(PLpgSQL_function *function)
2105 plpgsql_HashEnt *hentry;
2107 /* do nothing if not in table */
2108 if (function->fn_hashkey == NULL)
2111 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2112 (void *) function->fn_hashkey,
2116 elog(WARNING, "trying to delete function that does not exist");
2118 /* remove back link, which no longer points to allocated storage */
2119 function->fn_hashkey = NULL;