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.136 2009/06/11 14:49:14 momjian 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/gramparse.h"
32 #include "parser/parse_type.h"
33 #include "tcop/tcopprot.h"
34 #include "utils/array.h"
35 #include "utils/builtins.h"
36 #include "utils/lsyscache.h"
37 #include "utils/memutils.h"
38 #include "utils/syscache.h"
42 * Our own local and global variables
45 static int datums_alloc;
47 PLpgSQL_datum **plpgsql_Datums;
48 static int datums_last = 0;
50 int plpgsql_error_lineno;
51 char *plpgsql_error_funcname;
52 bool plpgsql_DumpExecTree = false;
53 bool plpgsql_check_syntax = false;
55 PLpgSQL_function *plpgsql_curr_compile;
57 /* A context appropriate for short-term allocs during compilation */
58 MemoryContext compile_tmp_cxt;
61 * Hash table for compiled functions
64 static HTAB *plpgsql_HashTable = NULL;
66 typedef struct plpgsql_hashent
68 PLpgSQL_func_hashkey key;
69 PLpgSQL_function *function;
72 #define FUNCS_PER_USER 128 /* initial table size */
75 * Lookup table for EXCEPTION condition names
84 static const ExceptionLabelMap exception_label_map[] = {
85 #include "plerrcodes.h"
94 static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
96 PLpgSQL_function *function,
97 PLpgSQL_func_hashkey *hashkey,
99 static PLpgSQL_row *build_row_from_class(Oid classOid);
100 static PLpgSQL_row *build_row_from_vars(PLpgSQL_variable **vars, int numvars);
101 static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
102 static void compute_function_hashkey(FunctionCallInfo fcinfo,
103 Form_pg_proc procStruct,
104 PLpgSQL_func_hashkey *hashkey,
106 static void plpgsql_resolve_polymorphic_argtypes(int numargs,
107 Oid *argtypes, char *argmodes,
108 Node *call_expr, bool forValidator,
109 const char *proname);
110 static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
111 static void plpgsql_HashTableInsert(PLpgSQL_function *function,
112 PLpgSQL_func_hashkey *func_key);
113 static void plpgsql_HashTableDelete(PLpgSQL_function *function);
114 static void delete_function(PLpgSQL_function *func);
117 * plpgsql_compile Make an execution tree for a PL/pgSQL function.
119 * If forValidator is true, we're only compiling for validation purposes,
120 * and so some checks are skipped.
122 * Note: it's important for this to fall through quickly if the function
123 * has already been compiled.
127 plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
129 Oid funcOid = fcinfo->flinfo->fn_oid;
131 Form_pg_proc procStruct;
132 PLpgSQL_function *function;
133 PLpgSQL_func_hashkey hashkey;
134 bool function_valid = false;
135 bool hashkey_valid = false;
138 * Lookup the pg_proc tuple by Oid; we'll need it in any case
140 procTup = SearchSysCache(PROCOID,
141 ObjectIdGetDatum(funcOid),
143 if (!HeapTupleIsValid(procTup))
144 elog(ERROR, "cache lookup failed for function %u", funcOid);
145 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
148 * See if there's already a cache entry for the current FmgrInfo. If not,
149 * try to find one in the hash table.
151 function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
156 /* Compute hashkey using function signature and actual arg types */
157 compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
158 hashkey_valid = true;
160 /* And do the lookup */
161 function = plpgsql_HashTableLookup(&hashkey);
166 /* We have a compiled function, but is it still valid? */
167 if (function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
168 ItemPointerEquals(&function->fn_tid, &procTup->t_self))
169 function_valid = true;
173 * Nope, so remove it from hashtable and try to drop associated
174 * storage (if not done already).
176 delete_function(function);
179 * If the function isn't in active use then we can overwrite the
180 * func struct with new data, allowing any other existing fn_extra
181 * pointers to make use of the new definition on their next use.
182 * If it is in use then just leave it alone and make a new one.
183 * (The active invocations will run to completion using the
184 * previous definition, and then the cache entry will just be
185 * leaked; doesn't seem worth adding code to clean it up, given
186 * what a corner case this is.)
188 * If we found the function struct via fn_extra then it's possible
189 * a replacement has already been made, so go back and recheck the
192 if (function->use_count != 0)
202 * If the function wasn't found or was out-of-date, we have to compile it
207 * Calculate hashkey if we didn't already; we'll need it to store the
208 * completed function.
211 compute_function_hashkey(fcinfo, procStruct, &hashkey,
217 function = do_compile(fcinfo, procTup, function,
218 &hashkey, forValidator);
221 ReleaseSysCache(procTup);
224 * Save pointer in FmgrInfo to avoid search on subsequent calls
226 fcinfo->flinfo->fn_extra = (void *) function;
229 * Finally return the compiled function
235 * This is the slow part of plpgsql_compile().
237 * The passed-in "function" pointer is either NULL or an already-allocated
238 * function struct to overwrite.
240 * While compiling a function, the CurrentMemoryContext is the
241 * per-function memory context of the function we are compiling. That
242 * means a palloc() will allocate storage with the same lifetime as
243 * the function itself.
245 * Because palloc()'d storage will not be immediately freed, temporary
246 * allocations should either be performed in a short-lived memory
247 * context or explicitly pfree'd. Since not all backend functions are
248 * careful about pfree'ing their allocations, it is also wise to
249 * switch into a short-term context before calling into the
250 * backend. An appropriate context for performing short-term
251 * allocations is the compile_tmp_cxt.
253 * NB: this code is not re-entrant. We assume that nothing we do here could
254 * result in the invocation of another plpgsql function.
256 static PLpgSQL_function *
257 do_compile(FunctionCallInfo fcinfo,
259 PLpgSQL_function *function,
260 PLpgSQL_func_hashkey *hashkey,
263 Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
264 bool is_trigger = CALLED_AS_TRIGGER(fcinfo);
269 Form_pg_type typeStruct;
270 PLpgSQL_variable *var;
273 ErrorContextCallback plerrcontext;
278 int num_out_args = 0;
282 int *in_arg_varnos = NULL;
283 PLpgSQL_variable **out_arg_variables;
284 MemoryContext func_cxt;
287 * Setup the scanner input and error info. We assume that this function
288 * cannot be invoked recursively, so there's no need to save and restore
289 * the static variables used here.
291 prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
292 Anum_pg_proc_prosrc, &isnull);
294 elog(ERROR, "null prosrc");
295 proc_source = TextDatumGetCString(prosrcdatum);
296 plpgsql_scanner_init(proc_source);
298 plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
299 plpgsql_error_lineno = 0;
302 * Setup error traceback support for ereport()
304 plerrcontext.callback = plpgsql_compile_error_callback;
305 plerrcontext.arg = forValidator ? proc_source : NULL;
306 plerrcontext.previous = error_context_stack;
307 error_context_stack = &plerrcontext;
310 * Initialize the compiler, particularly the namespace stack. The
311 * outermost namespace contains function parameters and other special
312 * variables (such as FOUND), and is named after the function itself.
315 plpgsql_ns_push(NameStr(procStruct->proname));
316 plpgsql_DumpExecTree = false;
320 /* This is short-lived, so needn't allocate in function's cxt */
321 plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
325 * Do extra syntax checks when validating the function definition. We skip
326 * this when actually compiling functions for execution, for performance
329 plpgsql_check_syntax = forValidator;
332 * Create the new function struct, if not done already. The function
333 * structs are never thrown away, so keep them in TopMemoryContext.
335 if (function == NULL)
337 function = (PLpgSQL_function *)
338 MemoryContextAllocZero(TopMemoryContext, sizeof(PLpgSQL_function));
342 /* re-using a previously existing struct, so clear it out */
343 memset(function, 0, sizeof(PLpgSQL_function));
345 plpgsql_curr_compile = function;
348 * All the rest of the compile-time storage (e.g. parse tree) is kept in
349 * its own memory context, so it can be reclaimed easily.
351 func_cxt = AllocSetContextCreate(TopMemoryContext,
352 "PL/PgSQL function context",
353 ALLOCSET_DEFAULT_MINSIZE,
354 ALLOCSET_DEFAULT_INITSIZE,
355 ALLOCSET_DEFAULT_MAXSIZE);
356 compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
358 function->fn_name = pstrdup(NameStr(procStruct->proname));
359 function->fn_oid = fcinfo->flinfo->fn_oid;
360 function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
361 function->fn_tid = procTup->t_self;
362 function->fn_is_trigger = is_trigger;
363 function->fn_cxt = func_cxt;
364 function->out_param_varno = -1; /* set up for no OUT param */
371 * Fetch info about the procedure's parameters. Allocations aren't
372 * needed permanently, so make them in tmp cxt.
374 * We also need to resolve any polymorphic input or output
375 * argument types. In validation mode we won't be able to, so we
376 * arbitrarily assume we are dealing with integers.
378 MemoryContextSwitchTo(compile_tmp_cxt);
380 numargs = get_func_arg_info(procTup,
381 &argtypes, &argnames, &argmodes);
383 plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
384 fcinfo->flinfo->fn_expr,
386 plpgsql_error_funcname);
388 in_arg_varnos = (int *) palloc(numargs * sizeof(int));
389 out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
391 MemoryContextSwitchTo(func_cxt);
394 * Create the variables for the procedure's parameters.
396 for (i = 0; i < numargs; i++)
399 Oid argtypeid = argtypes[i];
400 char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
401 PLpgSQL_type *argdtype;
402 PLpgSQL_variable *argvariable;
405 /* Create $n name for variable */
406 snprintf(buf, sizeof(buf), "$%d", i + 1);
408 /* Create datatype info */
409 argdtype = plpgsql_build_datatype(argtypeid, -1);
411 /* Disallow pseudotype argument */
412 /* (note we already replaced polymorphic types) */
413 /* (build_variable would do this, but wrong message) */
414 if (argdtype->ttype != PLPGSQL_TTYPE_SCALAR &&
415 argdtype->ttype != PLPGSQL_TTYPE_ROW)
417 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
418 errmsg("PL/pgSQL functions cannot accept type %s",
419 format_type_be(argtypeid))));
421 /* Build variable and add to datum list */
422 argvariable = plpgsql_build_variable(buf, 0,
425 if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
427 argitemtype = PLPGSQL_NSTYPE_VAR;
428 /* input argument vars are forced to be CONSTANT */
429 if (argmode == PROARGMODE_IN ||
430 argmode == PROARGMODE_VARIADIC)
431 ((PLpgSQL_var *) argvariable)->isconst = true;
435 Assert(argvariable->dtype == PLPGSQL_DTYPE_ROW);
436 argitemtype = PLPGSQL_NSTYPE_ROW;
439 /* Remember arguments in appropriate arrays */
440 if (argmode == PROARGMODE_IN ||
441 argmode == PROARGMODE_INOUT ||
442 argmode == PROARGMODE_VARIADIC)
443 in_arg_varnos[num_in_args++] = argvariable->dno;
444 if (argmode == PROARGMODE_OUT ||
445 argmode == PROARGMODE_INOUT ||
446 argmode == PROARGMODE_TABLE)
447 out_arg_variables[num_out_args++] = argvariable;
449 /* Add to namespace under the $n name */
450 plpgsql_ns_additem(argitemtype, argvariable->dno, buf);
452 /* If there's a name for the argument, make an alias */
453 if (argnames && argnames[i][0] != '\0')
454 plpgsql_ns_additem(argitemtype, argvariable->dno,
459 * If there's just one OUT parameter, out_param_varno points
460 * directly to it. If there's more than one, build a row that
463 if (num_out_args == 1)
464 function->out_param_varno = out_arg_variables[0]->dno;
465 else if (num_out_args > 1)
467 PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
470 plpgsql_adddatum((PLpgSQL_datum *) row);
471 function->out_param_varno = row->dno;
475 * Check for a polymorphic returntype. If found, use the actual
476 * returntype type from the caller's FuncExpr node, if we have
477 * one. (In validation mode we arbitrarily assume we are dealing
480 * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
481 * work; if it doesn't we're in some context that fails to make
482 * the info available.
484 rettypeid = procStruct->prorettype;
485 if (IsPolymorphicType(rettypeid))
489 if (rettypeid == ANYARRAYOID)
490 rettypeid = INT4ARRAYOID;
491 else /* ANYELEMENT or ANYNONARRAY */
493 /* XXX what could we use for ANYENUM? */
497 rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
498 if (!OidIsValid(rettypeid))
500 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
501 errmsg("could not determine actual return type "
502 "for polymorphic function \"%s\"",
503 plpgsql_error_funcname)));
508 * Normal function has a defined returntype
510 function->fn_rettype = rettypeid;
511 function->fn_retset = procStruct->proretset;
514 * Lookup the function's return type
516 typeTup = SearchSysCache(TYPEOID,
517 ObjectIdGetDatum(rettypeid),
519 if (!HeapTupleIsValid(typeTup))
520 elog(ERROR, "cache lookup failed for type %u", rettypeid);
521 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
523 /* Disallow pseudotype result, except VOID or RECORD */
524 /* (note we already replaced polymorphic types) */
525 if (typeStruct->typtype == TYPTYPE_PSEUDO)
527 if (rettypeid == VOIDOID ||
528 rettypeid == RECORDOID)
530 else if (rettypeid == TRIGGEROID)
532 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
533 errmsg("trigger functions can only be called as triggers")));
536 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
537 errmsg("PL/pgSQL functions cannot return type %s",
538 format_type_be(rettypeid))));
541 if (typeStruct->typrelid != InvalidOid ||
542 rettypeid == RECORDOID)
543 function->fn_retistuple = true;
546 function->fn_retbyval = typeStruct->typbyval;
547 function->fn_rettyplen = typeStruct->typlen;
548 function->fn_rettypioparam = getTypeIOParam(typeTup);
549 fmgr_info(typeStruct->typinput, &(function->fn_retinput));
552 * install $0 reference, but only for polymorphic return
553 * types, and not when the return is specified through an
556 if (IsPolymorphicType(procStruct->prorettype) &&
559 (void) plpgsql_build_variable("$0", 0,
560 build_datatype(typeTup, -1),
564 ReleaseSysCache(typeTup);
568 /* Trigger procedure's return type is unknown yet */
569 function->fn_rettype = InvalidOid;
570 function->fn_retbyval = false;
571 function->fn_retistuple = true;
572 function->fn_retset = false;
574 /* shouldn't be any declared arguments */
575 if (procStruct->pronargs != 0)
577 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
578 errmsg("trigger functions cannot have declared arguments"),
579 errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
581 /* Add the record for referencing NEW */
582 rec = plpgsql_build_record("new", 0, true);
583 function->new_varno = rec->dno;
585 /* Add the record for referencing OLD */
586 rec = plpgsql_build_record("old", 0, true);
587 function->old_varno = rec->dno;
589 /* Add the variable tg_name */
590 var = plpgsql_build_variable("tg_name", 0,
591 plpgsql_build_datatype(NAMEOID, -1),
593 function->tg_name_varno = var->dno;
595 /* Add the variable tg_when */
596 var = plpgsql_build_variable("tg_when", 0,
597 plpgsql_build_datatype(TEXTOID, -1),
599 function->tg_when_varno = var->dno;
601 /* Add the variable tg_level */
602 var = plpgsql_build_variable("tg_level", 0,
603 plpgsql_build_datatype(TEXTOID, -1),
605 function->tg_level_varno = var->dno;
607 /* Add the variable tg_op */
608 var = plpgsql_build_variable("tg_op", 0,
609 plpgsql_build_datatype(TEXTOID, -1),
611 function->tg_op_varno = var->dno;
613 /* Add the variable tg_relid */
614 var = plpgsql_build_variable("tg_relid", 0,
615 plpgsql_build_datatype(OIDOID, -1),
617 function->tg_relid_varno = var->dno;
619 /* Add the variable tg_relname */
620 var = plpgsql_build_variable("tg_relname", 0,
621 plpgsql_build_datatype(NAMEOID, -1),
623 function->tg_relname_varno = var->dno;
625 /* tg_table_name is now preferred to tg_relname */
626 var = plpgsql_build_variable("tg_table_name", 0,
627 plpgsql_build_datatype(NAMEOID, -1),
629 function->tg_table_name_varno = var->dno;
632 /* add variable tg_table_schema */
633 var = plpgsql_build_variable("tg_table_schema", 0,
634 plpgsql_build_datatype(NAMEOID, -1),
636 function->tg_table_schema_varno = var->dno;
639 /* Add the variable tg_nargs */
640 var = plpgsql_build_variable("tg_nargs", 0,
641 plpgsql_build_datatype(INT4OID, -1),
643 function->tg_nargs_varno = var->dno;
648 elog(ERROR, "unrecognized function typecode: %d", (int) is_trigger);
652 /* Remember if function is STABLE/IMMUTABLE */
653 function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
656 * Create the magic FOUND variable.
658 var = plpgsql_build_variable("found", 0,
659 plpgsql_build_datatype(BOOLOID, -1),
661 function->found_varno = var->dno;
664 * Now parse the function's text
666 parse_rc = plpgsql_yyparse();
668 elog(ERROR, "plpgsql parser returned %d", parse_rc);
669 function->action = plpgsql_yylval.program;
671 plpgsql_scanner_finish();
675 * If it has OUT parameters or returns VOID or returns a set, we allow
676 * control to fall off the end without an explicit RETURN statement. The
677 * easiest way to implement this is to add a RETURN statement to the end
678 * of the statement list during parsing. However, if the outer block has
679 * an EXCEPTION clause, we need to make a new outer block, since the added
680 * RETURN shouldn't act like it is inside the EXCEPTION clause.
682 if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
685 if (function->action->exceptions != NULL)
687 PLpgSQL_stmt_block *new;
689 new = palloc0(sizeof(PLpgSQL_stmt_block));
690 new->cmd_type = PLPGSQL_STMT_BLOCK;
691 new->body = list_make1(function->action);
693 function->action = new;
695 if (function->action->body == NIL ||
696 ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
698 PLpgSQL_stmt_return *new;
700 new = palloc0(sizeof(PLpgSQL_stmt_return));
701 new->cmd_type = PLPGSQL_STMT_RETURN;
703 new->retvarno = function->out_param_varno;
705 function->action->body = lappend(function->action->body, new);
710 * Complete the function's info
712 function->fn_nargs = procStruct->pronargs;
713 for (i = 0; i < function->fn_nargs; i++)
714 function->fn_argvarnos[i] = in_arg_varnos[i];
715 function->ndatums = plpgsql_nDatums;
716 function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
717 for (i = 0; i < plpgsql_nDatums; i++)
718 function->datums[i] = plpgsql_Datums[i];
720 /* Debug dump for completed functions */
721 if (plpgsql_DumpExecTree)
722 plpgsql_dumptree(function);
725 * add it to the hash table
727 plpgsql_HashTableInsert(function, hashkey);
730 * Pop the error context stack
732 error_context_stack = plerrcontext.previous;
733 plpgsql_error_funcname = NULL;
734 plpgsql_error_lineno = 0;
736 plpgsql_check_syntax = false;
738 MemoryContextSwitchTo(compile_tmp_cxt);
739 compile_tmp_cxt = NULL;
745 * error context callback to let us supply a call-stack traceback. If
746 * we are validating, the function source is passed as an
747 * argument. This function is public only for the sake of an assertion
751 plpgsql_compile_error_callback(void *arg)
756 * Try to convert syntax error position to reference text of original
757 * CREATE FUNCTION command.
759 if (function_parse_error_transpose((const char *) arg))
763 * Done if a syntax error position was reported; otherwise we have to
764 * fall back to a "near line N" report.
768 if (plpgsql_error_funcname)
769 errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
770 plpgsql_error_funcname, plpgsql_error_lineno);
775 * plpgsql_parse_word The scanner calls this to postparse
776 * any single word not found by a
781 plpgsql_parse_word(const char *word)
786 /* Do case conversion and word separation */
787 plpgsql_convert_ident(word, cp, 1);
790 * Recognize tg_argv when compiling triggers (XXX this sucks, it should be
791 * a regular variable in the namestack)
793 if (plpgsql_curr_compile->fn_is_trigger)
795 if (strcmp(cp[0], "tg_argv") == 0)
797 bool save_spacescanned = plpgsql_SpaceScanned;
798 PLpgSQL_trigarg *trigarg;
800 trigarg = palloc0(sizeof(PLpgSQL_trigarg));
801 trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
803 if (plpgsql_yylex() != '[')
804 plpgsql_yyerror("expected \"[\"");
806 trigarg->argnum = plpgsql_read_expression(']', "]");
808 plpgsql_adddatum((PLpgSQL_datum *) trigarg);
809 plpgsql_yylval.scalar = (PLpgSQL_datum *) trigarg;
811 plpgsql_SpaceScanned = save_spacescanned;
818 * Do a lookup on the compiler's namestack
820 nse = plpgsql_ns_lookup(cp[0], NULL, NULL, NULL);
825 switch (nse->itemtype)
827 case PLPGSQL_NSTYPE_VAR:
828 plpgsql_yylval.scalar = plpgsql_Datums[nse->itemno];
831 case PLPGSQL_NSTYPE_REC:
832 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]);
835 case PLPGSQL_NSTYPE_ROW:
836 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[nse->itemno]);
845 * Nothing found - up to now it's a word without any special meaning for
853 * plpgsql_parse_dblword Same lookup for two words
854 * separated by a dot.
858 plpgsql_parse_dblword(const char *word)
864 /* Do case conversion and word separation */
865 plpgsql_convert_ident(word, cp, 2);
868 * Do a lookup on the compiler's namestack
870 ns = plpgsql_ns_lookup(cp[0], cp[1], NULL, &nnames);
878 switch (ns->itemtype)
880 case PLPGSQL_NSTYPE_VAR:
881 /* Block-qualified reference to scalar variable. */
882 plpgsql_yylval.scalar = plpgsql_Datums[ns->itemno];
887 case PLPGSQL_NSTYPE_REC:
891 * First word is a record name, so second word must be a field
894 PLpgSQL_recfield *new;
896 new = palloc(sizeof(PLpgSQL_recfield));
897 new->dtype = PLPGSQL_DTYPE_RECFIELD;
898 new->fieldname = pstrdup(cp[1]);
899 new->recparentno = ns->itemno;
901 plpgsql_adddatum((PLpgSQL_datum *) new);
903 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
911 /* Block-qualified reference to record variable. */
912 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
918 case PLPGSQL_NSTYPE_ROW:
922 * First word is a row name, so second word must be a field in
928 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
929 for (i = 0; i < row->nfields; i++)
931 if (row->fieldnames[i] &&
932 strcmp(row->fieldnames[i], cp[1]) == 0)
934 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
941 (errcode(ERRCODE_UNDEFINED_COLUMN),
942 errmsg("row \"%s\" has no field \"%s\"",
947 /* Block-qualified reference to row variable. */
948 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
965 * plpgsql_parse_tripword Same lookup for three words
970 plpgsql_parse_tripword(const char *word)
976 /* Do case conversion and word separation */
977 plpgsql_convert_ident(word, cp, 3);
980 * Do a lookup on the compiler's namestack. Must find a qualified
983 ns = plpgsql_ns_lookup(cp[0], cp[1], cp[2], &nnames);
984 if (ns == NULL || nnames != 2)
992 switch (ns->itemtype)
994 case PLPGSQL_NSTYPE_REC:
997 * words 1/2 are a record name, so third word must be a field
1000 PLpgSQL_recfield *new;
1002 new = palloc(sizeof(PLpgSQL_recfield));
1003 new->dtype = PLPGSQL_DTYPE_RECFIELD;
1004 new->fieldname = pstrdup(cp[2]);
1005 new->recparentno = ns->itemno;
1007 plpgsql_adddatum((PLpgSQL_datum *) new);
1009 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
1018 case PLPGSQL_NSTYPE_ROW:
1021 * words 1/2 are a row name, so third word must be a field in
1027 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1028 for (i = 0; i < row->nfields; i++)
1030 if (row->fieldnames[i] &&
1031 strcmp(row->fieldnames[i], cp[2]) == 0)
1033 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
1043 (errcode(ERRCODE_UNDEFINED_COLUMN),
1044 errmsg("row \"%s.%s\" has no field \"%s\"",
1045 cp[0], cp[1], cp[2])));
1060 * plpgsql_parse_wordtype The scanner found word%TYPE. word can be
1061 * a variable name or a basetype.
1065 plpgsql_parse_wordtype(char *word)
1067 PLpgSQL_nsitem *nse;
1073 /* Do case conversion and word separation */
1074 /* We convert %type to .type momentarily to keep converter happy */
1075 i = strlen(word) - 5;
1076 Assert(word[i] == '%');
1078 plpgsql_convert_ident(word, cp, 2);
1083 * Do a lookup on the compiler's namestack. Ensure we scan all levels.
1085 old_nsstate = plpgsql_ns_setlocal(false);
1086 nse = plpgsql_ns_lookup(cp[0], NULL, NULL, NULL);
1087 plpgsql_ns_setlocal(old_nsstate);
1092 switch (nse->itemtype)
1094 case PLPGSQL_NSTYPE_VAR:
1095 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1098 /* XXX perhaps allow REC here? */
1106 * Word wasn't found on the namestack. Try to find a data type with that
1107 * name, but ignore shell types and complex types.
1109 typeTup = LookupTypeName(NULL, makeTypeName(cp[0]), NULL);
1112 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1114 if (!typeStruct->typisdefined ||
1115 typeStruct->typrelid != InvalidOid)
1117 ReleaseSysCache(typeTup);
1122 plpgsql_yylval.dtype = build_datatype(typeTup, -1);
1124 ReleaseSysCache(typeTup);
1130 * Nothing found - up to now it's a word without any special meaning for
1139 * plpgsql_parse_dblwordtype Same lookup for word.word%TYPE
1143 plpgsql_parse_dblwordtype(char *word)
1145 PLpgSQL_nsitem *nse;
1148 HeapTuple classtup = NULL;
1149 HeapTuple attrtup = NULL;
1150 HeapTuple typetup = NULL;
1151 Form_pg_class classStruct;
1152 Form_pg_attribute attrStruct;
1155 MemoryContext oldCxt;
1156 int result = T_ERROR;
1158 /* Avoid memory leaks in the long-term function context */
1159 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1161 /* Do case conversion and word separation */
1162 /* We convert %type to .type momentarily to keep converter happy */
1163 i = strlen(word) - 5;
1164 Assert(word[i] == '%');
1166 plpgsql_convert_ident(word, cp, 3);
1171 * Do a lookup on the compiler's namestack. Ensure we scan all levels. We
1172 * don't need to check number of names matched, because we will only
1173 * consider scalar variables.
1175 old_nsstate = plpgsql_ns_setlocal(false);
1176 nse = plpgsql_ns_lookup(cp[0], cp[1], NULL, NULL);
1177 plpgsql_ns_setlocal(old_nsstate);
1179 if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1181 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1187 * First word could also be a table name
1189 classOid = RelnameGetRelid(cp[0]);
1190 if (!OidIsValid(classOid))
1193 classtup = SearchSysCache(RELOID,
1194 ObjectIdGetDatum(classOid),
1196 if (!HeapTupleIsValid(classtup))
1198 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1201 * It must be a relation, sequence, view, or type
1203 if (classStruct->relkind != RELKIND_RELATION &&
1204 classStruct->relkind != RELKIND_SEQUENCE &&
1205 classStruct->relkind != RELKIND_VIEW &&
1206 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1210 * Fetch the named table field and its type
1212 attrtup = SearchSysCacheAttName(classOid, cp[1]);
1213 if (!HeapTupleIsValid(attrtup))
1215 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1217 typetup = SearchSysCache(TYPEOID,
1218 ObjectIdGetDatum(attrStruct->atttypid),
1220 if (!HeapTupleIsValid(typetup))
1221 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1224 * Found that - build a compiler type struct in the caller's cxt and
1227 MemoryContextSwitchTo(oldCxt);
1228 plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1229 MemoryContextSwitchTo(compile_tmp_cxt);
1233 if (HeapTupleIsValid(classtup))
1234 ReleaseSysCache(classtup);
1235 if (HeapTupleIsValid(attrtup))
1236 ReleaseSysCache(attrtup);
1237 if (HeapTupleIsValid(typetup))
1238 ReleaseSysCache(typetup);
1240 MemoryContextSwitchTo(oldCxt);
1245 * plpgsql_parse_tripwordtype Same lookup for word.word.word%TYPE
1249 plpgsql_parse_tripwordtype(char *word)
1252 HeapTuple classtup = NULL;
1253 HeapTuple attrtup = NULL;
1254 HeapTuple typetup = NULL;
1255 Form_pg_class classStruct;
1256 Form_pg_attribute attrStruct;
1260 MemoryContext oldCxt;
1261 int result = T_ERROR;
1263 /* Avoid memory leaks in the long-term function context */
1264 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1266 /* Do case conversion and word separation */
1267 /* We convert %type to .type momentarily to keep converter happy */
1268 i = strlen(word) - 5;
1269 Assert(word[i] == '%');
1271 plpgsql_convert_ident(word, cp, 4);
1275 relvar = makeRangeVar(cp[0], cp[1], -1);
1276 classOid = RangeVarGetRelid(relvar, true);
1277 if (!OidIsValid(classOid))
1280 classtup = SearchSysCache(RELOID,
1281 ObjectIdGetDatum(classOid),
1283 if (!HeapTupleIsValid(classtup))
1285 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1288 * It must be a relation, sequence, view, or type
1290 if (classStruct->relkind != RELKIND_RELATION &&
1291 classStruct->relkind != RELKIND_SEQUENCE &&
1292 classStruct->relkind != RELKIND_VIEW &&
1293 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1297 * Fetch the named table field and its type
1299 attrtup = SearchSysCacheAttName(classOid, cp[2]);
1300 if (!HeapTupleIsValid(attrtup))
1302 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1304 typetup = SearchSysCache(TYPEOID,
1305 ObjectIdGetDatum(attrStruct->atttypid),
1307 if (!HeapTupleIsValid(typetup))
1308 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1311 * Found that - build a compiler type struct in the caller's cxt and
1314 MemoryContextSwitchTo(oldCxt);
1315 plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1316 MemoryContextSwitchTo(compile_tmp_cxt);
1320 if (HeapTupleIsValid(classtup))
1321 ReleaseSysCache(classtup);
1322 if (HeapTupleIsValid(attrtup))
1323 ReleaseSysCache(attrtup);
1324 if (HeapTupleIsValid(typetup))
1325 ReleaseSysCache(typetup);
1327 MemoryContextSwitchTo(oldCxt);
1332 * plpgsql_parse_wordrowtype Scanner found word%ROWTYPE.
1333 * So word must be a table name.
1337 plpgsql_parse_wordrowtype(char *word)
1343 /* Do case conversion and word separation */
1344 /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1345 i = strlen(word) - 8;
1346 Assert(word[i] == '%');
1348 plpgsql_convert_ident(word, cp, 2);
1351 /* Lookup the relation */
1352 classOid = RelnameGetRelid(cp[0]);
1353 if (!OidIsValid(classOid))
1355 (errcode(ERRCODE_UNDEFINED_TABLE),
1356 errmsg("relation \"%s\" does not exist", cp[0])));
1359 * Build and return the row type struct
1361 plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1371 * plpgsql_parse_dblwordrowtype Scanner found word.word%ROWTYPE.
1372 * So word must be a namespace qualified table name.
1376 plpgsql_parse_dblwordrowtype(char *word)
1382 MemoryContext oldCxt;
1384 /* Avoid memory leaks in long-term function context */
1385 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1387 /* Do case conversion and word separation */
1388 /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1389 i = strlen(word) - 8;
1390 Assert(word[i] == '%');
1392 plpgsql_convert_ident(word, cp, 3);
1395 /* Lookup the relation */
1396 relvar = makeRangeVar(cp[0], cp[1], -1);
1397 classOid = RangeVarGetRelid(relvar, true);
1398 if (!OidIsValid(classOid))
1400 (errcode(ERRCODE_UNDEFINED_TABLE),
1401 errmsg("relation \"%s.%s\" does not exist", cp[0], cp[1])));
1403 /* Build and return the row type struct */
1404 plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1407 MemoryContextSwitchTo(oldCxt);
1412 * plpgsql_build_variable - build a datum-array entry of a given
1415 * The returned struct may be a PLpgSQL_var, PLpgSQL_row, or
1416 * PLpgSQL_rec depending on the given datatype, and is allocated via
1417 * palloc. The struct is automatically added to the current datum
1418 * array, and optionally to the current namespace.
1421 plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype,
1424 PLpgSQL_variable *result;
1426 switch (dtype->ttype)
1428 case PLPGSQL_TTYPE_SCALAR:
1430 /* Ordinary scalar datatype */
1433 var = palloc0(sizeof(PLpgSQL_var));
1434 var->dtype = PLPGSQL_DTYPE_VAR;
1435 var->refname = pstrdup(refname);
1436 var->lineno = lineno;
1437 var->datatype = dtype;
1438 /* other fields might be filled by caller */
1440 /* preset to NULL */
1443 var->freeval = false;
1445 plpgsql_adddatum((PLpgSQL_datum *) var);
1447 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
1450 result = (PLpgSQL_variable *) var;
1453 case PLPGSQL_TTYPE_ROW:
1455 /* Composite type -- build a row variable */
1458 row = build_row_from_class(dtype->typrelid);
1460 row->dtype = PLPGSQL_DTYPE_ROW;
1461 row->refname = pstrdup(refname);
1462 row->lineno = lineno;
1464 plpgsql_adddatum((PLpgSQL_datum *) row);
1466 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
1469 result = (PLpgSQL_variable *) row;
1472 case PLPGSQL_TTYPE_REC:
1474 /* "record" type -- build a record variable */
1477 rec = plpgsql_build_record(refname, lineno, add2namespace);
1478 result = (PLpgSQL_variable *) rec;
1481 case PLPGSQL_TTYPE_PSEUDO:
1483 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1484 errmsg("variable \"%s\" has pseudo-type %s",
1485 refname, format_type_be(dtype->typoid))));
1486 result = NULL; /* keep compiler quiet */
1489 elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1490 result = NULL; /* keep compiler quiet */
1498 * Build empty named record variable, and optionally add it to namespace
1501 plpgsql_build_record(const char *refname, int lineno, bool add2namespace)
1505 rec = palloc0(sizeof(PLpgSQL_rec));
1506 rec->dtype = PLPGSQL_DTYPE_REC;
1507 rec->refname = pstrdup(refname);
1508 rec->lineno = lineno;
1510 rec->tupdesc = NULL;
1511 rec->freetup = false;
1512 plpgsql_adddatum((PLpgSQL_datum *) rec);
1514 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->dno, rec->refname);
1520 * Build a row-variable data structure given the pg_class OID.
1522 static PLpgSQL_row *
1523 build_row_from_class(Oid classOid)
1527 Form_pg_class classStruct;
1528 const char *relname;
1532 * Open the relation to get info.
1534 rel = relation_open(classOid, AccessShareLock);
1535 classStruct = RelationGetForm(rel);
1536 relname = RelationGetRelationName(rel);
1538 /* accept relation, sequence, view, or composite type entries */
1539 if (classStruct->relkind != RELKIND_RELATION &&
1540 classStruct->relkind != RELKIND_SEQUENCE &&
1541 classStruct->relkind != RELKIND_VIEW &&
1542 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1544 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1545 errmsg("relation \"%s\" is not a table", relname)));
1548 * Create a row datum entry and all the required variables that it will
1551 row = palloc0(sizeof(PLpgSQL_row));
1552 row->dtype = PLPGSQL_DTYPE_ROW;
1553 row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
1554 row->nfields = classStruct->relnatts;
1555 row->fieldnames = palloc(sizeof(char *) * row->nfields);
1556 row->varnos = palloc(sizeof(int) * row->nfields);
1558 for (i = 0; i < row->nfields; i++)
1560 Form_pg_attribute attrStruct;
1563 * Get the attribute and check for dropped column
1565 attrStruct = row->rowtupdesc->attrs[i];
1567 if (!attrStruct->attisdropped)
1570 char refname[(NAMEDATALEN * 2) + 100];
1571 PLpgSQL_variable *var;
1573 attname = NameStr(attrStruct->attname);
1574 snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
1577 * Create the internal variable for the field
1579 * We know if the table definitions contain a default value or if
1580 * the field is declared in the table as NOT NULL. But it's
1581 * possible to create a table field as NOT NULL without a default
1582 * value and that would lead to problems later when initializing
1583 * the variables due to entering a block at execution time. Thus
1584 * we ignore this information for now.
1586 var = plpgsql_build_variable(refname, 0,
1587 plpgsql_build_datatype(attrStruct->atttypid,
1588 attrStruct->atttypmod),
1591 /* Add the variable to the row */
1592 row->fieldnames[i] = attname;
1593 row->varnos[i] = var->dno;
1597 /* Leave a hole in the row structure for the dropped col */
1598 row->fieldnames[i] = NULL;
1599 row->varnos[i] = -1;
1603 relation_close(rel, AccessShareLock);
1609 * Build a row-variable data structure given the component variables.
1611 static PLpgSQL_row *
1612 build_row_from_vars(PLpgSQL_variable **vars, int numvars)
1617 row = palloc0(sizeof(PLpgSQL_row));
1618 row->dtype = PLPGSQL_DTYPE_ROW;
1619 row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
1620 row->nfields = numvars;
1621 row->fieldnames = palloc(numvars * sizeof(char *));
1622 row->varnos = palloc(numvars * sizeof(int));
1624 for (i = 0; i < numvars; i++)
1626 PLpgSQL_variable *var = vars[i];
1627 Oid typoid = RECORDOID;
1632 case PLPGSQL_DTYPE_VAR:
1633 typoid = ((PLpgSQL_var *) var)->datatype->typoid;
1634 typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
1637 case PLPGSQL_DTYPE_REC:
1640 case PLPGSQL_DTYPE_ROW:
1641 if (((PLpgSQL_row *) var)->rowtupdesc)
1643 typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
1644 typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
1649 elog(ERROR, "unrecognized dtype: %d", var->dtype);
1652 row->fieldnames[i] = var->refname;
1653 row->varnos[i] = var->dno;
1655 TupleDescInitEntry(row->rowtupdesc, i + 1,
1666 * plpgsql_parse_datatype Scanner found something that should
1667 * be a datatype name.
1671 plpgsql_parse_datatype(const char *string)
1676 /* Let the main parser try to parse it under standard SQL rules */
1677 parseTypeString(string, &type_id, &typmod);
1679 /* Okay, build a PLpgSQL_type data structure for it */
1680 return plpgsql_build_datatype(type_id, typmod);
1684 * plpgsql_build_datatype
1685 * Build PLpgSQL_type struct given type OID and typmod.
1688 plpgsql_build_datatype(Oid typeOid, int32 typmod)
1693 typeTup = SearchSysCache(TYPEOID,
1694 ObjectIdGetDatum(typeOid),
1696 if (!HeapTupleIsValid(typeTup))
1697 elog(ERROR, "cache lookup failed for type %u", typeOid);
1699 typ = build_datatype(typeTup, typmod);
1701 ReleaseSysCache(typeTup);
1707 * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1709 static PLpgSQL_type *
1710 build_datatype(HeapTuple typeTup, int32 typmod)
1712 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1715 if (!typeStruct->typisdefined)
1717 (errcode(ERRCODE_UNDEFINED_OBJECT),
1718 errmsg("type \"%s\" is only a shell",
1719 NameStr(typeStruct->typname))));
1721 typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
1723 typ->typname = pstrdup(NameStr(typeStruct->typname));
1724 typ->typoid = HeapTupleGetOid(typeTup);
1725 switch (typeStruct->typtype)
1728 case TYPTYPE_DOMAIN:
1730 typ->ttype = PLPGSQL_TTYPE_SCALAR;
1732 case TYPTYPE_COMPOSITE:
1733 Assert(OidIsValid(typeStruct->typrelid));
1734 typ->ttype = PLPGSQL_TTYPE_ROW;
1736 case TYPTYPE_PSEUDO:
1737 if (typ->typoid == RECORDOID)
1738 typ->ttype = PLPGSQL_TTYPE_REC;
1740 typ->ttype = PLPGSQL_TTYPE_PSEUDO;
1743 elog(ERROR, "unrecognized typtype: %d",
1744 (int) typeStruct->typtype);
1747 typ->typlen = typeStruct->typlen;
1748 typ->typbyval = typeStruct->typbyval;
1749 typ->typrelid = typeStruct->typrelid;
1750 typ->typioparam = getTypeIOParam(typeTup);
1751 fmgr_info(typeStruct->typinput, &(typ->typinput));
1752 typ->atttypmod = typmod;
1758 * plpgsql_recognize_err_condition
1759 * Check condition name and translate it to SQLSTATE.
1761 * Note: there are some cases where the same condition name has multiple
1762 * entries in the table. We arbitrarily return the first match.
1765 plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
1771 if (strlen(condname) == 5 &&
1772 strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
1773 return MAKE_SQLSTATE(condname[0],
1780 for (i = 0; exception_label_map[i].label != NULL; i++)
1782 if (strcmp(condname, exception_label_map[i].label) == 0)
1783 return exception_label_map[i].sqlerrstate;
1787 (errcode(ERRCODE_UNDEFINED_OBJECT),
1788 errmsg("unrecognized exception condition \"%s\"",
1790 return 0; /* keep compiler quiet */
1794 * plpgsql_parse_err_condition
1795 * Generate PLpgSQL_condition entry(s) for an exception condition name
1797 * This has to be able to return a list because there are some duplicate
1798 * names in the table of error code names.
1801 plpgsql_parse_err_condition(char *condname)
1804 PLpgSQL_condition *new;
1805 PLpgSQL_condition *prev;
1808 * XXX Eventually we will want to look for user-defined exception names
1813 * OTHERS is represented as code 0 (which would map to '00000', but we
1814 * have no need to represent that as an exception condition).
1816 if (strcmp(condname, "others") == 0)
1818 new = palloc(sizeof(PLpgSQL_condition));
1819 new->sqlerrstate = 0;
1820 new->condname = condname;
1826 for (i = 0; exception_label_map[i].label != NULL; i++)
1828 if (strcmp(condname, exception_label_map[i].label) == 0)
1830 new = palloc(sizeof(PLpgSQL_condition));
1831 new->sqlerrstate = exception_label_map[i].sqlerrstate;
1832 new->condname = condname;
1840 (errcode(ERRCODE_UNDEFINED_OBJECT),
1841 errmsg("unrecognized exception condition \"%s\"",
1848 * plpgsql_adddatum Add a variable, record or row
1849 * to the compiler's datum list.
1853 plpgsql_adddatum(PLpgSQL_datum *new)
1855 if (plpgsql_nDatums == datums_alloc)
1858 plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
1861 new->dno = plpgsql_nDatums;
1862 plpgsql_Datums[plpgsql_nDatums++] = new;
1867 * plpgsql_add_initdatums Make an array of the datum numbers of
1868 * all the simple VAR datums created since the last call
1871 * If varnos is NULL, we just forget any datum entries created since the
1874 * This is used around a DECLARE section to create a list of the VARs
1875 * that have to be initialized at block entry. Note that VARs can also
1876 * be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
1877 * the responsibility of special-purpose code to initialize them.
1881 plpgsql_add_initdatums(int **varnos)
1886 for (i = datums_last; i < plpgsql_nDatums; i++)
1888 switch (plpgsql_Datums[i]->dtype)
1890 case PLPGSQL_DTYPE_VAR:
1903 *varnos = (int *) palloc(sizeof(int) * n);
1906 for (i = datums_last; i < plpgsql_nDatums; i++)
1908 switch (plpgsql_Datums[i]->dtype)
1910 case PLPGSQL_DTYPE_VAR:
1911 (*varnos)[n++] = plpgsql_Datums[i]->dno;
1922 datums_last = plpgsql_nDatums;
1928 * Compute the hashkey for a given function invocation
1930 * The hashkey is returned into the caller-provided storage at *hashkey.
1933 compute_function_hashkey(FunctionCallInfo fcinfo,
1934 Form_pg_proc procStruct,
1935 PLpgSQL_func_hashkey *hashkey,
1938 /* Make sure any unused bytes of the struct are zero */
1939 MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
1941 /* get function OID */
1942 hashkey->funcOid = fcinfo->flinfo->fn_oid;
1944 /* get call context */
1945 hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
1948 * if trigger, get relation OID. In validation mode we do not know what
1949 * relation is intended to be used, so we leave trigrelOid zero; the hash
1950 * entry built in this case will never really be used.
1952 if (hashkey->isTrigger && !forValidator)
1954 TriggerData *trigdata = (TriggerData *) fcinfo->context;
1956 hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
1959 if (procStruct->pronargs > 0)
1961 /* get the argument types */
1962 memcpy(hashkey->argtypes, procStruct->proargtypes.values,
1963 procStruct->pronargs * sizeof(Oid));
1965 /* resolve any polymorphic argument types */
1966 plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
1969 fcinfo->flinfo->fn_expr,
1971 NameStr(procStruct->proname));
1976 * This is the same as the standard resolve_polymorphic_argtypes() function,
1977 * but with a special case for validation: assume that polymorphic arguments
1978 * are integer or integer-array. Also, we go ahead and report the error
1979 * if we can't resolve the types.
1982 plpgsql_resolve_polymorphic_argtypes(int numargs,
1983 Oid *argtypes, char *argmodes,
1984 Node *call_expr, bool forValidator,
1985 const char *proname)
1991 /* normal case, pass to standard routine */
1992 if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
1995 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1996 errmsg("could not determine actual argument "
1997 "type for polymorphic function \"%s\"",
2002 /* special validation case */
2003 for (i = 0; i < numargs; i++)
2005 switch (argtypes[i])
2008 case ANYNONARRAYOID:
2009 case ANYENUMOID: /* XXX dubious */
2010 argtypes[i] = INT4OID;
2013 argtypes[i] = INT4ARRAYOID;
2023 * delete_function - clean up as much as possible of a stale function cache
2025 * We can't release the PLpgSQL_function struct itself, because of the
2026 * possibility that there are fn_extra pointers to it. We can release
2027 * the subsidiary storage, but only if there are no active evaluations
2028 * in progress. Otherwise we'll just leak that storage. Since the
2029 * case would only occur if a pg_proc update is detected during a nested
2030 * recursive call on the function, a leak seems acceptable.
2032 * Note that this can be called more than once if there are multiple fn_extra
2033 * pointers to the same function cache. Hence be careful not to do things
2037 delete_function(PLpgSQL_function *func)
2039 /* remove function from hash table (might be done already) */
2040 plpgsql_HashTableDelete(func);
2042 /* release the function's storage if safe and not done already */
2043 if (func->use_count == 0 && func->fn_cxt)
2045 MemoryContextDelete(func->fn_cxt);
2046 func->fn_cxt = NULL;
2050 /* exported so we can call it from plpgsql_init() */
2052 plpgsql_HashTableInit(void)
2056 /* don't allow double-initialization */
2057 Assert(plpgsql_HashTable == NULL);
2059 memset(&ctl, 0, sizeof(ctl));
2060 ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2061 ctl.entrysize = sizeof(plpgsql_HashEnt);
2062 ctl.hash = tag_hash;
2063 plpgsql_HashTable = hash_create("PLpgSQL function cache",
2066 HASH_ELEM | HASH_FUNCTION);
2069 static PLpgSQL_function *
2070 plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
2072 plpgsql_HashEnt *hentry;
2074 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2079 return hentry->function;
2085 plpgsql_HashTableInsert(PLpgSQL_function *function,
2086 PLpgSQL_func_hashkey *func_key)
2088 plpgsql_HashEnt *hentry;
2091 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2096 elog(WARNING, "trying to insert a function that already exists");
2098 hentry->function = function;
2099 /* prepare back link from function to hashtable key */
2100 function->fn_hashkey = &hentry->key;
2104 plpgsql_HashTableDelete(PLpgSQL_function *function)
2106 plpgsql_HashEnt *hentry;
2108 /* do nothing if not in table */
2109 if (function->fn_hashkey == NULL)
2112 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2113 (void *) function->fn_hashkey,
2117 elog(WARNING, "trying to delete function that does not exist");
2119 /* remove back link, which no longer points to allocated storage */
2120 function->fn_hashkey = NULL;