1 /*-------------------------------------------------------------------------
3 * pl_comp.c - Compiler part of the PL/pgSQL
6 * Portions Copyright (c) 1996-2008, 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.127 2008/07/16 01:30:23 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/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 int functype = CALLED_AS_TRIGGER(fcinfo) ? T_TRIGGER : T_FUNCTION;
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, functype);
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_functype = functype;
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("plpgsql functions cannot take 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 || argmode == PROARGMODE_INOUT)
445 out_arg_variables[num_out_args++] = argvariable;
447 /* Add to namespace under the $n name */
448 plpgsql_ns_additem(argitemtype, argvariable->dno, buf);
450 /* If there's a name for the argument, make an alias */
451 if (argnames && argnames[i][0] != '\0')
452 plpgsql_ns_additem(argitemtype, argvariable->dno,
457 * If there's just one OUT parameter, out_param_varno points
458 * directly to it. If there's more than one, build a row that
461 if (num_out_args == 1)
462 function->out_param_varno = out_arg_variables[0]->dno;
463 else if (num_out_args > 1)
465 PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
468 plpgsql_adddatum((PLpgSQL_datum *) row);
469 function->out_param_varno = row->rowno;
473 * Check for a polymorphic returntype. If found, use the actual
474 * returntype type from the caller's FuncExpr node, if we have
475 * one. (In validation mode we arbitrarily assume we are dealing
478 * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
479 * work; if it doesn't we're in some context that fails to make
480 * the info available.
482 rettypeid = procStruct->prorettype;
483 if (IsPolymorphicType(rettypeid))
487 if (rettypeid == ANYARRAYOID)
488 rettypeid = INT4ARRAYOID;
489 else /* ANYELEMENT or ANYNONARRAY */
491 /* XXX what could we use for ANYENUM? */
495 rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
496 if (!OidIsValid(rettypeid))
498 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
499 errmsg("could not determine actual return type "
500 "for polymorphic function \"%s\"",
501 plpgsql_error_funcname)));
506 * Normal function has a defined returntype
508 function->fn_rettype = rettypeid;
509 function->fn_retset = procStruct->proretset;
512 * Lookup the function's return type
514 typeTup = SearchSysCache(TYPEOID,
515 ObjectIdGetDatum(rettypeid),
517 if (!HeapTupleIsValid(typeTup))
518 elog(ERROR, "cache lookup failed for type %u", rettypeid);
519 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
521 /* Disallow pseudotype result, except VOID or RECORD */
522 /* (note we already replaced polymorphic types) */
523 if (typeStruct->typtype == TYPTYPE_PSEUDO)
525 if (rettypeid == VOIDOID ||
526 rettypeid == RECORDOID)
528 else if (rettypeid == TRIGGEROID)
530 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
531 errmsg("trigger functions can only be called as triggers")));
534 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
535 errmsg("plpgsql functions cannot return type %s",
536 format_type_be(rettypeid))));
539 if (typeStruct->typrelid != InvalidOid ||
540 rettypeid == RECORDOID)
541 function->fn_retistuple = true;
544 function->fn_retbyval = typeStruct->typbyval;
545 function->fn_rettyplen = typeStruct->typlen;
546 function->fn_rettypioparam = getTypeIOParam(typeTup);
547 fmgr_info(typeStruct->typinput, &(function->fn_retinput));
550 * install $0 reference, but only for polymorphic return
551 * types, and not when the return is specified through an
554 if (IsPolymorphicType(procStruct->prorettype) &&
557 (void) plpgsql_build_variable("$0", 0,
558 build_datatype(typeTup, -1),
562 ReleaseSysCache(typeTup);
566 /* Trigger procedure's return type is unknown yet */
567 function->fn_rettype = InvalidOid;
568 function->fn_retbyval = false;
569 function->fn_retistuple = true;
570 function->fn_retset = false;
572 /* shouldn't be any declared arguments */
573 if (procStruct->pronargs != 0)
575 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
576 errmsg("trigger functions cannot have declared arguments"),
577 errhint("You probably want to use TG_NARGS and TG_ARGV instead.")));
579 /* Add the record for referencing NEW */
580 rec = plpgsql_build_record("new", 0, true);
581 function->new_varno = rec->recno;
583 /* Add the record for referencing OLD */
584 rec = plpgsql_build_record("old", 0, true);
585 function->old_varno = rec->recno;
587 /* Add the variable tg_name */
588 var = plpgsql_build_variable("tg_name", 0,
589 plpgsql_build_datatype(NAMEOID, -1),
591 function->tg_name_varno = var->dno;
593 /* Add the variable tg_when */
594 var = plpgsql_build_variable("tg_when", 0,
595 plpgsql_build_datatype(TEXTOID, -1),
597 function->tg_when_varno = var->dno;
599 /* Add the variable tg_level */
600 var = plpgsql_build_variable("tg_level", 0,
601 plpgsql_build_datatype(TEXTOID, -1),
603 function->tg_level_varno = var->dno;
605 /* Add the variable tg_op */
606 var = plpgsql_build_variable("tg_op", 0,
607 plpgsql_build_datatype(TEXTOID, -1),
609 function->tg_op_varno = var->dno;
611 /* Add the variable tg_relid */
612 var = plpgsql_build_variable("tg_relid", 0,
613 plpgsql_build_datatype(OIDOID, -1),
615 function->tg_relid_varno = var->dno;
617 /* Add the variable tg_relname */
618 var = plpgsql_build_variable("tg_relname", 0,
619 plpgsql_build_datatype(NAMEOID, -1),
621 function->tg_relname_varno = var->dno;
623 /* tg_table_name is now preferred to tg_relname */
624 var = plpgsql_build_variable("tg_table_name", 0,
625 plpgsql_build_datatype(NAMEOID, -1),
627 function->tg_table_name_varno = var->dno;
630 /* add variable tg_table_schema */
631 var = plpgsql_build_variable("tg_table_schema", 0,
632 plpgsql_build_datatype(NAMEOID, -1),
634 function->tg_table_schema_varno = var->dno;
637 /* Add the variable tg_nargs */
638 var = plpgsql_build_variable("tg_nargs", 0,
639 plpgsql_build_datatype(INT4OID, -1),
641 function->tg_nargs_varno = var->dno;
646 elog(ERROR, "unrecognized function typecode: %u", functype);
650 /* Remember if function is STABLE/IMMUTABLE */
651 function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
654 * Create the magic FOUND variable.
656 var = plpgsql_build_variable("found", 0,
657 plpgsql_build_datatype(BOOLOID, -1),
659 function->found_varno = var->dno;
662 * Now parse the function's text
664 parse_rc = plpgsql_yyparse();
666 elog(ERROR, "plpgsql parser returned %d", parse_rc);
667 function->action = plpgsql_yylval.program;
669 plpgsql_scanner_finish();
673 * If it has OUT parameters or returns VOID or returns a set, we allow
674 * control to fall off the end without an explicit RETURN statement. The
675 * easiest way to implement this is to add a RETURN statement to the end
676 * of the statement list during parsing. However, if the outer block has
677 * an EXCEPTION clause, we need to make a new outer block, since the added
678 * RETURN shouldn't act like it is inside the EXCEPTION clause.
680 if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
683 if (function->action->exceptions != NULL)
685 PLpgSQL_stmt_block *new;
687 new = palloc0(sizeof(PLpgSQL_stmt_block));
688 new->cmd_type = PLPGSQL_STMT_BLOCK;
689 new->body = list_make1(function->action);
691 function->action = new;
693 if (function->action->body == NIL ||
694 ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
696 PLpgSQL_stmt_return *new;
698 new = palloc0(sizeof(PLpgSQL_stmt_return));
699 new->cmd_type = PLPGSQL_STMT_RETURN;
701 new->retvarno = function->out_param_varno;
703 function->action->body = lappend(function->action->body, new);
708 * Complete the function's info
710 function->fn_nargs = procStruct->pronargs;
711 for (i = 0; i < function->fn_nargs; i++)
712 function->fn_argvarnos[i] = in_arg_varnos[i];
713 function->ndatums = plpgsql_nDatums;
714 function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
715 for (i = 0; i < plpgsql_nDatums; i++)
716 function->datums[i] = plpgsql_Datums[i];
718 /* Debug dump for completed functions */
719 if (plpgsql_DumpExecTree)
720 plpgsql_dumptree(function);
723 * add it to the hash table
725 plpgsql_HashTableInsert(function, hashkey);
728 * Pop the error context stack
730 error_context_stack = plerrcontext.previous;
731 plpgsql_error_funcname = NULL;
732 plpgsql_error_lineno = 0;
734 plpgsql_check_syntax = false;
736 MemoryContextSwitchTo(compile_tmp_cxt);
737 compile_tmp_cxt = NULL;
743 * error context callback to let us supply a call-stack traceback. If
744 * we are validating, the function source is passed as an
745 * argument. This function is public only for the sake of an assertion
749 plpgsql_compile_error_callback(void *arg)
754 * Try to convert syntax error position to reference text of original
755 * CREATE FUNCTION command.
757 if (function_parse_error_transpose((const char *) arg))
761 * Done if a syntax error position was reported; otherwise we have to
762 * fall back to a "near line N" report.
766 if (plpgsql_error_funcname)
767 errcontext("compile of PL/pgSQL function \"%s\" near line %d",
768 plpgsql_error_funcname, plpgsql_error_lineno);
773 * plpgsql_parse_word The scanner calls this to postparse
774 * any single word not found by a
779 plpgsql_parse_word(const char *word)
784 /* Do case conversion and word separation */
785 plpgsql_convert_ident(word, cp, 1);
788 * Recognize tg_argv when compiling triggers
789 * (XXX this sucks, it should be a regular variable in the namestack)
791 if (plpgsql_curr_compile->fn_functype == T_TRIGGER)
793 if (strcmp(cp[0], "tg_argv") == 0)
795 bool save_spacescanned = plpgsql_SpaceScanned;
796 PLpgSQL_trigarg *trigarg;
798 trigarg = palloc0(sizeof(PLpgSQL_trigarg));
799 trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
801 if (plpgsql_yylex() != '[')
802 plpgsql_yyerror("expected \"[\"");
804 trigarg->argnum = plpgsql_read_expression(']', "]");
806 plpgsql_adddatum((PLpgSQL_datum *) trigarg);
807 plpgsql_yylval.scalar = (PLpgSQL_datum *) trigarg;
809 plpgsql_SpaceScanned = save_spacescanned;
816 * Do a lookup on the compiler's namestack
818 nse = plpgsql_ns_lookup(cp[0], NULL, NULL, NULL);
823 switch (nse->itemtype)
825 case PLPGSQL_NSTYPE_VAR:
826 plpgsql_yylval.scalar = plpgsql_Datums[nse->itemno];
829 case PLPGSQL_NSTYPE_REC:
830 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]);
833 case PLPGSQL_NSTYPE_ROW:
834 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[nse->itemno]);
843 * Nothing found - up to now it's a word without any special meaning for
851 * plpgsql_parse_dblword Same lookup for two words
852 * separated by a dot.
856 plpgsql_parse_dblword(const char *word)
862 /* Do case conversion and word separation */
863 plpgsql_convert_ident(word, cp, 2);
866 * Do a lookup on the compiler's namestack
868 ns = plpgsql_ns_lookup(cp[0], cp[1], NULL, &nnames);
876 switch (ns->itemtype)
878 case PLPGSQL_NSTYPE_VAR:
879 /* Block-qualified reference to scalar variable. */
880 plpgsql_yylval.scalar = plpgsql_Datums[ns->itemno];
885 case PLPGSQL_NSTYPE_REC:
889 * First word is a record name, so second word must be a field
892 PLpgSQL_recfield *new;
894 new = palloc(sizeof(PLpgSQL_recfield));
895 new->dtype = PLPGSQL_DTYPE_RECFIELD;
896 new->fieldname = pstrdup(cp[1]);
897 new->recparentno = ns->itemno;
899 plpgsql_adddatum((PLpgSQL_datum *) new);
901 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
909 /* Block-qualified reference to record variable. */
910 plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
916 case PLPGSQL_NSTYPE_ROW:
920 * First word is a row name, so second word must be a field in
926 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
927 for (i = 0; i < row->nfields; i++)
929 if (row->fieldnames[i] &&
930 strcmp(row->fieldnames[i], cp[1]) == 0)
932 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
939 (errcode(ERRCODE_UNDEFINED_COLUMN),
940 errmsg("row \"%s\" has no field \"%s\"",
945 /* Block-qualified reference to row variable. */
946 plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
963 * plpgsql_parse_tripword Same lookup for three words
968 plpgsql_parse_tripword(const char *word)
974 /* Do case conversion and word separation */
975 plpgsql_convert_ident(word, cp, 3);
978 * Do a lookup on the compiler's namestack.
979 * Must find a qualified reference.
981 ns = plpgsql_ns_lookup(cp[0], cp[1], cp[2], &nnames);
982 if (ns == NULL || nnames != 2)
990 switch (ns->itemtype)
992 case PLPGSQL_NSTYPE_REC:
995 * words 1/2 are a record name, so third word must be a field
998 PLpgSQL_recfield *new;
1000 new = palloc(sizeof(PLpgSQL_recfield));
1001 new->dtype = PLPGSQL_DTYPE_RECFIELD;
1002 new->fieldname = pstrdup(cp[2]);
1003 new->recparentno = ns->itemno;
1005 plpgsql_adddatum((PLpgSQL_datum *) new);
1007 plpgsql_yylval.scalar = (PLpgSQL_datum *) new;
1016 case PLPGSQL_NSTYPE_ROW:
1019 * words 1/2 are a row name, so third word must be a field in
1025 row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1026 for (i = 0; i < row->nfields; i++)
1028 if (row->fieldnames[i] &&
1029 strcmp(row->fieldnames[i], cp[2]) == 0)
1031 plpgsql_yylval.scalar = plpgsql_Datums[row->varnos[i]];
1041 (errcode(ERRCODE_UNDEFINED_COLUMN),
1042 errmsg("row \"%s.%s\" has no field \"%s\"",
1043 cp[0], cp[1], cp[2])));
1058 * plpgsql_parse_wordtype The scanner found word%TYPE. word can be
1059 * a variable name or a basetype.
1063 plpgsql_parse_wordtype(char *word)
1065 PLpgSQL_nsitem *nse;
1071 /* Do case conversion and word separation */
1072 /* We convert %type to .type momentarily to keep converter happy */
1073 i = strlen(word) - 5;
1074 Assert(word[i] == '%');
1076 plpgsql_convert_ident(word, cp, 2);
1081 * Do a lookup on the compiler's namestack. Ensure we scan all levels.
1083 old_nsstate = plpgsql_ns_setlocal(false);
1084 nse = plpgsql_ns_lookup(cp[0], NULL, NULL, NULL);
1085 plpgsql_ns_setlocal(old_nsstate);
1090 switch (nse->itemtype)
1092 case PLPGSQL_NSTYPE_VAR:
1093 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1096 /* XXX perhaps allow REC here? */
1104 * Word wasn't found on the namestack. Try to find a data type with that
1105 * name, but ignore shell types and complex types.
1107 typeTup = LookupTypeName(NULL, makeTypeName(cp[0]), NULL);
1110 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1112 if (!typeStruct->typisdefined ||
1113 typeStruct->typrelid != InvalidOid)
1115 ReleaseSysCache(typeTup);
1120 plpgsql_yylval.dtype = build_datatype(typeTup, -1);
1122 ReleaseSysCache(typeTup);
1128 * Nothing found - up to now it's a word without any special meaning for
1137 * plpgsql_parse_dblwordtype Same lookup for word.word%TYPE
1141 plpgsql_parse_dblwordtype(char *word)
1143 PLpgSQL_nsitem *nse;
1146 HeapTuple classtup = NULL;
1147 HeapTuple attrtup = NULL;
1148 HeapTuple typetup = NULL;
1149 Form_pg_class classStruct;
1150 Form_pg_attribute attrStruct;
1153 MemoryContext oldCxt;
1154 int result = T_ERROR;
1156 /* Avoid memory leaks in the long-term function context */
1157 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1159 /* Do case conversion and word separation */
1160 /* We convert %type to .type momentarily to keep converter happy */
1161 i = strlen(word) - 5;
1162 Assert(word[i] == '%');
1164 plpgsql_convert_ident(word, cp, 3);
1169 * Do a lookup on the compiler's namestack. Ensure we scan all levels.
1170 * We don't need to check number of names matched, because we will only
1171 * consider scalar variables.
1173 old_nsstate = plpgsql_ns_setlocal(false);
1174 nse = plpgsql_ns_lookup(cp[0], cp[1], NULL, NULL);
1175 plpgsql_ns_setlocal(old_nsstate);
1177 if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1179 plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1185 * First word could also be a table name
1187 classOid = RelnameGetRelid(cp[0]);
1188 if (!OidIsValid(classOid))
1191 classtup = SearchSysCache(RELOID,
1192 ObjectIdGetDatum(classOid),
1194 if (!HeapTupleIsValid(classtup))
1196 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1199 * It must be a relation, sequence, view, or type
1201 if (classStruct->relkind != RELKIND_RELATION &&
1202 classStruct->relkind != RELKIND_SEQUENCE &&
1203 classStruct->relkind != RELKIND_VIEW &&
1204 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1208 * Fetch the named table field and its type
1210 attrtup = SearchSysCacheAttName(classOid, cp[1]);
1211 if (!HeapTupleIsValid(attrtup))
1213 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1215 typetup = SearchSysCache(TYPEOID,
1216 ObjectIdGetDatum(attrStruct->atttypid),
1218 if (!HeapTupleIsValid(typetup))
1219 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1222 * Found that - build a compiler type struct in the caller's cxt and
1225 MemoryContextSwitchTo(oldCxt);
1226 plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1227 MemoryContextSwitchTo(compile_tmp_cxt);
1231 if (HeapTupleIsValid(classtup))
1232 ReleaseSysCache(classtup);
1233 if (HeapTupleIsValid(attrtup))
1234 ReleaseSysCache(attrtup);
1235 if (HeapTupleIsValid(typetup))
1236 ReleaseSysCache(typetup);
1238 MemoryContextSwitchTo(oldCxt);
1243 * plpgsql_parse_tripwordtype Same lookup for word.word.word%TYPE
1247 plpgsql_parse_tripwordtype(char *word)
1250 HeapTuple classtup = NULL;
1251 HeapTuple attrtup = NULL;
1252 HeapTuple typetup = NULL;
1253 Form_pg_class classStruct;
1254 Form_pg_attribute attrStruct;
1258 MemoryContext oldCxt;
1259 int result = T_ERROR;
1261 /* Avoid memory leaks in the long-term function context */
1262 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1264 /* Do case conversion and word separation */
1265 /* We convert %type to .type momentarily to keep converter happy */
1266 i = strlen(word) - 5;
1267 Assert(word[i] == '%');
1269 plpgsql_convert_ident(word, cp, 4);
1273 relvar = makeRangeVar(cp[0], cp[1]);
1274 classOid = RangeVarGetRelid(relvar, true);
1275 if (!OidIsValid(classOid))
1278 classtup = SearchSysCache(RELOID,
1279 ObjectIdGetDatum(classOid),
1281 if (!HeapTupleIsValid(classtup))
1283 classStruct = (Form_pg_class) GETSTRUCT(classtup);
1286 * It must be a relation, sequence, view, or type
1288 if (classStruct->relkind != RELKIND_RELATION &&
1289 classStruct->relkind != RELKIND_SEQUENCE &&
1290 classStruct->relkind != RELKIND_VIEW &&
1291 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1295 * Fetch the named table field and its type
1297 attrtup = SearchSysCacheAttName(classOid, cp[2]);
1298 if (!HeapTupleIsValid(attrtup))
1300 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1302 typetup = SearchSysCache(TYPEOID,
1303 ObjectIdGetDatum(attrStruct->atttypid),
1305 if (!HeapTupleIsValid(typetup))
1306 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1309 * Found that - build a compiler type struct in the caller's cxt and
1312 MemoryContextSwitchTo(oldCxt);
1313 plpgsql_yylval.dtype = build_datatype(typetup, attrStruct->atttypmod);
1314 MemoryContextSwitchTo(compile_tmp_cxt);
1318 if (HeapTupleIsValid(classtup))
1319 ReleaseSysCache(classtup);
1320 if (HeapTupleIsValid(attrtup))
1321 ReleaseSysCache(attrtup);
1322 if (HeapTupleIsValid(typetup))
1323 ReleaseSysCache(typetup);
1325 MemoryContextSwitchTo(oldCxt);
1330 * plpgsql_parse_wordrowtype Scanner found word%ROWTYPE.
1331 * So word must be a table name.
1335 plpgsql_parse_wordrowtype(char *word)
1341 /* Do case conversion and word separation */
1342 /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1343 i = strlen(word) - 8;
1344 Assert(word[i] == '%');
1346 plpgsql_convert_ident(word, cp, 2);
1349 /* Lookup the relation */
1350 classOid = RelnameGetRelid(cp[0]);
1351 if (!OidIsValid(classOid))
1353 (errcode(ERRCODE_UNDEFINED_TABLE),
1354 errmsg("relation \"%s\" does not exist", cp[0])));
1357 * Build and return the row type struct
1359 plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1369 * plpgsql_parse_dblwordrowtype Scanner found word.word%ROWTYPE.
1370 * So word must be a namespace qualified table name.
1374 plpgsql_parse_dblwordrowtype(char *word)
1380 MemoryContext oldCxt;
1382 /* Avoid memory leaks in long-term function context */
1383 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1385 /* Do case conversion and word separation */
1386 /* We convert %rowtype to .rowtype momentarily to keep converter happy */
1387 i = strlen(word) - 8;
1388 Assert(word[i] == '%');
1390 plpgsql_convert_ident(word, cp, 3);
1393 /* Lookup the relation */
1394 relvar = makeRangeVar(cp[0], cp[1]);
1395 classOid = RangeVarGetRelid(relvar, true);
1396 if (!OidIsValid(classOid))
1398 (errcode(ERRCODE_UNDEFINED_TABLE),
1399 errmsg("relation \"%s.%s\" does not exist", cp[0], cp[1])));
1401 /* Build and return the row type struct */
1402 plpgsql_yylval.dtype = plpgsql_build_datatype(get_rel_type_id(classOid),
1405 MemoryContextSwitchTo(oldCxt);
1410 * plpgsql_build_variable - build a datum-array entry of a given
1413 * The returned struct may be a PLpgSQL_var, PLpgSQL_row, or
1414 * PLpgSQL_rec depending on the given datatype, and is allocated via
1415 * palloc. The struct is automatically added to the current datum
1416 * array, and optionally to the current namespace.
1419 plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype,
1422 PLpgSQL_variable *result;
1424 switch (dtype->ttype)
1426 case PLPGSQL_TTYPE_SCALAR:
1428 /* Ordinary scalar datatype */
1431 var = palloc0(sizeof(PLpgSQL_var));
1432 var->dtype = PLPGSQL_DTYPE_VAR;
1433 var->refname = pstrdup(refname);
1434 var->lineno = lineno;
1435 var->datatype = dtype;
1436 /* other fields might be filled by caller */
1438 /* preset to NULL */
1441 var->freeval = false;
1443 plpgsql_adddatum((PLpgSQL_datum *) var);
1445 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
1448 result = (PLpgSQL_variable *) var;
1451 case PLPGSQL_TTYPE_ROW:
1453 /* Composite type -- build a row variable */
1456 row = build_row_from_class(dtype->typrelid);
1458 row->dtype = PLPGSQL_DTYPE_ROW;
1459 row->refname = pstrdup(refname);
1460 row->lineno = lineno;
1462 plpgsql_adddatum((PLpgSQL_datum *) row);
1464 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
1467 result = (PLpgSQL_variable *) row;
1470 case PLPGSQL_TTYPE_REC:
1472 /* "record" type -- build a record variable */
1475 rec = plpgsql_build_record(refname, lineno, add2namespace);
1476 result = (PLpgSQL_variable *) rec;
1479 case PLPGSQL_TTYPE_PSEUDO:
1481 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1482 errmsg("variable \"%s\" has pseudo-type %s",
1483 refname, format_type_be(dtype->typoid))));
1484 result = NULL; /* keep compiler quiet */
1487 elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1488 result = NULL; /* keep compiler quiet */
1496 * Build empty named record variable, and optionally add it to namespace
1499 plpgsql_build_record(const char *refname, int lineno, bool add2namespace)
1503 rec = palloc0(sizeof(PLpgSQL_rec));
1504 rec->dtype = PLPGSQL_DTYPE_REC;
1505 rec->refname = pstrdup(refname);
1506 rec->lineno = lineno;
1508 rec->tupdesc = NULL;
1509 rec->freetup = false;
1510 plpgsql_adddatum((PLpgSQL_datum *) rec);
1512 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
1518 * Build a row-variable data structure given the pg_class OID.
1520 static PLpgSQL_row *
1521 build_row_from_class(Oid classOid)
1525 Form_pg_class classStruct;
1526 const char *relname;
1530 * Open the relation to get info.
1532 rel = relation_open(classOid, AccessShareLock);
1533 classStruct = RelationGetForm(rel);
1534 relname = RelationGetRelationName(rel);
1536 /* accept relation, sequence, view, or composite type entries */
1537 if (classStruct->relkind != RELKIND_RELATION &&
1538 classStruct->relkind != RELKIND_SEQUENCE &&
1539 classStruct->relkind != RELKIND_VIEW &&
1540 classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1542 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1543 errmsg("relation \"%s\" is not a table", relname)));
1546 * Create a row datum entry and all the required variables that it will
1549 row = palloc0(sizeof(PLpgSQL_row));
1550 row->dtype = PLPGSQL_DTYPE_ROW;
1551 row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
1552 row->nfields = classStruct->relnatts;
1553 row->fieldnames = palloc(sizeof(char *) * row->nfields);
1554 row->varnos = palloc(sizeof(int) * row->nfields);
1556 for (i = 0; i < row->nfields; i++)
1558 Form_pg_attribute attrStruct;
1561 * Get the attribute and check for dropped column
1563 attrStruct = row->rowtupdesc->attrs[i];
1565 if (!attrStruct->attisdropped)
1568 char refname[(NAMEDATALEN * 2) + 100];
1569 PLpgSQL_variable *var;
1571 attname = NameStr(attrStruct->attname);
1572 snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
1575 * Create the internal variable for the field
1577 * We know if the table definitions contain a default value or if
1578 * the field is declared in the table as NOT NULL. But it's
1579 * possible to create a table field as NOT NULL without a default
1580 * value and that would lead to problems later when initializing
1581 * the variables due to entering a block at execution time. Thus
1582 * we ignore this information for now.
1584 var = plpgsql_build_variable(refname, 0,
1585 plpgsql_build_datatype(attrStruct->atttypid,
1586 attrStruct->atttypmod),
1589 /* Add the variable to the row */
1590 row->fieldnames[i] = attname;
1591 row->varnos[i] = var->dno;
1595 /* Leave a hole in the row structure for the dropped col */
1596 row->fieldnames[i] = NULL;
1597 row->varnos[i] = -1;
1601 relation_close(rel, AccessShareLock);
1607 * Build a row-variable data structure given the component variables.
1609 static PLpgSQL_row *
1610 build_row_from_vars(PLpgSQL_variable **vars, int numvars)
1615 row = palloc0(sizeof(PLpgSQL_row));
1616 row->dtype = PLPGSQL_DTYPE_ROW;
1617 row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
1618 row->nfields = numvars;
1619 row->fieldnames = palloc(numvars * sizeof(char *));
1620 row->varnos = palloc(numvars * sizeof(int));
1622 for (i = 0; i < numvars; i++)
1624 PLpgSQL_variable *var = vars[i];
1625 Oid typoid = RECORDOID;
1630 case PLPGSQL_DTYPE_VAR:
1631 typoid = ((PLpgSQL_var *) var)->datatype->typoid;
1632 typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
1635 case PLPGSQL_DTYPE_REC:
1638 case PLPGSQL_DTYPE_ROW:
1639 if (((PLpgSQL_row *) var)->rowtupdesc)
1641 typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
1642 typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
1647 elog(ERROR, "unrecognized dtype: %d", var->dtype);
1650 row->fieldnames[i] = var->refname;
1651 row->varnos[i] = var->dno;
1653 TupleDescInitEntry(row->rowtupdesc, i + 1,
1664 * plpgsql_parse_datatype Scanner found something that should
1665 * be a datatype name.
1669 plpgsql_parse_datatype(const char *string)
1674 /* Let the main parser try to parse it under standard SQL rules */
1675 parseTypeString(string, &type_id, &typmod);
1677 /* Okay, build a PLpgSQL_type data structure for it */
1678 return plpgsql_build_datatype(type_id, typmod);
1682 * plpgsql_build_datatype
1683 * Build PLpgSQL_type struct given type OID and typmod.
1686 plpgsql_build_datatype(Oid typeOid, int32 typmod)
1691 typeTup = SearchSysCache(TYPEOID,
1692 ObjectIdGetDatum(typeOid),
1694 if (!HeapTupleIsValid(typeTup))
1695 elog(ERROR, "cache lookup failed for type %u", typeOid);
1697 typ = build_datatype(typeTup, typmod);
1699 ReleaseSysCache(typeTup);
1705 * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1707 static PLpgSQL_type *
1708 build_datatype(HeapTuple typeTup, int32 typmod)
1710 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1713 if (!typeStruct->typisdefined)
1715 (errcode(ERRCODE_UNDEFINED_OBJECT),
1716 errmsg("type \"%s\" is only a shell",
1717 NameStr(typeStruct->typname))));
1719 typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
1721 typ->typname = pstrdup(NameStr(typeStruct->typname));
1722 typ->typoid = HeapTupleGetOid(typeTup);
1723 switch (typeStruct->typtype)
1726 case TYPTYPE_DOMAIN:
1728 typ->ttype = PLPGSQL_TTYPE_SCALAR;
1730 case TYPTYPE_COMPOSITE:
1731 Assert(OidIsValid(typeStruct->typrelid));
1732 typ->ttype = PLPGSQL_TTYPE_ROW;
1734 case TYPTYPE_PSEUDO:
1735 if (typ->typoid == RECORDOID)
1736 typ->ttype = PLPGSQL_TTYPE_REC;
1738 typ->ttype = PLPGSQL_TTYPE_PSEUDO;
1741 elog(ERROR, "unrecognized typtype: %d",
1742 (int) typeStruct->typtype);
1745 typ->typlen = typeStruct->typlen;
1746 typ->typbyval = typeStruct->typbyval;
1747 typ->typrelid = typeStruct->typrelid;
1748 typ->typioparam = getTypeIOParam(typeTup);
1749 fmgr_info(typeStruct->typinput, &(typ->typinput));
1750 typ->atttypmod = typmod;
1756 * plpgsql_recognize_err_condition
1757 * Check condition name and translate it to SQLSTATE.
1759 * Note: there are some cases where the same condition name has multiple
1760 * entries in the table. We arbitrarily return the first match.
1763 plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
1769 if (strlen(condname) == 5 &&
1770 strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
1771 return MAKE_SQLSTATE(condname[0],
1778 for (i = 0; exception_label_map[i].label != NULL; i++)
1780 if (strcmp(condname, exception_label_map[i].label) == 0)
1781 return exception_label_map[i].sqlerrstate;
1785 (errcode(ERRCODE_UNDEFINED_OBJECT),
1786 errmsg("unrecognized exception condition \"%s\"",
1788 return 0; /* keep compiler quiet */
1792 * plpgsql_parse_err_condition
1793 * Generate PLpgSQL_condition entry(s) for an exception condition name
1795 * This has to be able to return a list because there are some duplicate
1796 * names in the table of error code names.
1799 plpgsql_parse_err_condition(char *condname)
1802 PLpgSQL_condition *new;
1803 PLpgSQL_condition *prev;
1806 * XXX Eventually we will want to look for user-defined exception names
1811 * OTHERS is represented as code 0 (which would map to '00000', but we
1812 * have no need to represent that as an exception condition).
1814 if (strcmp(condname, "others") == 0)
1816 new = palloc(sizeof(PLpgSQL_condition));
1817 new->sqlerrstate = 0;
1818 new->condname = condname;
1824 for (i = 0; exception_label_map[i].label != NULL; i++)
1826 if (strcmp(condname, exception_label_map[i].label) == 0)
1828 new = palloc(sizeof(PLpgSQL_condition));
1829 new->sqlerrstate = exception_label_map[i].sqlerrstate;
1830 new->condname = condname;
1838 (errcode(ERRCODE_UNDEFINED_OBJECT),
1839 errmsg("unrecognized exception condition \"%s\"",
1846 * plpgsql_adddatum Add a variable, record or row
1847 * to the compiler's datum list.
1851 plpgsql_adddatum(PLpgSQL_datum *new)
1853 if (plpgsql_nDatums == datums_alloc)
1856 plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
1859 new->dno = plpgsql_nDatums;
1860 plpgsql_Datums[plpgsql_nDatums++] = new;
1865 * plpgsql_add_initdatums Make an array of the datum numbers of
1866 * all the simple VAR datums created since the last call
1869 * If varnos is NULL, we just forget any datum entries created since the
1872 * This is used around a DECLARE section to create a list of the VARs
1873 * that have to be initialized at block entry. Note that VARs can also
1874 * be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
1875 * the responsibility of special-purpose code to initialize them.
1879 plpgsql_add_initdatums(int **varnos)
1884 for (i = datums_last; i < plpgsql_nDatums; i++)
1886 switch (plpgsql_Datums[i]->dtype)
1888 case PLPGSQL_DTYPE_VAR:
1901 *varnos = (int *) palloc(sizeof(int) * n);
1904 for (i = datums_last; i < plpgsql_nDatums; i++)
1906 switch (plpgsql_Datums[i]->dtype)
1908 case PLPGSQL_DTYPE_VAR:
1909 (*varnos)[n++] = plpgsql_Datums[i]->dno;
1920 datums_last = plpgsql_nDatums;
1926 * Compute the hashkey for a given function invocation
1928 * The hashkey is returned into the caller-provided storage at *hashkey.
1931 compute_function_hashkey(FunctionCallInfo fcinfo,
1932 Form_pg_proc procStruct,
1933 PLpgSQL_func_hashkey *hashkey,
1936 /* Make sure any unused bytes of the struct are zero */
1937 MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
1939 /* get function OID */
1940 hashkey->funcOid = fcinfo->flinfo->fn_oid;
1943 * if trigger, get relation OID. In validation mode we do not know what
1944 * relation is intended to be used, so we leave trigrelOid zero; the hash
1945 * entry built in this case will never really be used.
1947 if (CALLED_AS_TRIGGER(fcinfo) && !forValidator)
1949 TriggerData *trigdata = (TriggerData *) fcinfo->context;
1951 hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
1954 if (procStruct->pronargs > 0)
1956 /* get the argument types */
1957 memcpy(hashkey->argtypes, procStruct->proargtypes.values,
1958 procStruct->pronargs * sizeof(Oid));
1960 /* resolve any polymorphic argument types */
1961 plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
1964 fcinfo->flinfo->fn_expr,
1966 NameStr(procStruct->proname));
1971 * This is the same as the standard resolve_polymorphic_argtypes() function,
1972 * but with a special case for validation: assume that polymorphic arguments
1973 * are integer or integer-array. Also, we go ahead and report the error
1974 * if we can't resolve the types.
1977 plpgsql_resolve_polymorphic_argtypes(int numargs,
1978 Oid *argtypes, char *argmodes,
1979 Node *call_expr, bool forValidator,
1980 const char *proname)
1986 /* normal case, pass to standard routine */
1987 if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
1990 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1991 errmsg("could not determine actual argument "
1992 "type for polymorphic function \"%s\"",
1997 /* special validation case */
1998 for (i = 0; i < numargs; i++)
2000 switch (argtypes[i])
2003 case ANYNONARRAYOID:
2004 case ANYENUMOID: /* XXX dubious */
2005 argtypes[i] = INT4OID;
2008 argtypes[i] = INT4ARRAYOID;
2018 * delete_function - clean up as much as possible of a stale function cache
2020 * We can't release the PLpgSQL_function struct itself, because of the
2021 * possibility that there are fn_extra pointers to it. We can release
2022 * the subsidiary storage, but only if there are no active evaluations
2023 * in progress. Otherwise we'll just leak that storage. Since the
2024 * case would only occur if a pg_proc update is detected during a nested
2025 * recursive call on the function, a leak seems acceptable.
2027 * Note that this can be called more than once if there are multiple fn_extra
2028 * pointers to the same function cache. Hence be careful not to do things
2032 delete_function(PLpgSQL_function *func)
2034 /* remove function from hash table (might be done already) */
2035 plpgsql_HashTableDelete(func);
2037 /* release the function's storage if safe and not done already */
2038 if (func->use_count == 0 && func->fn_cxt)
2040 MemoryContextDelete(func->fn_cxt);
2041 func->fn_cxt = NULL;
2045 /* exported so we can call it from plpgsql_init() */
2047 plpgsql_HashTableInit(void)
2051 /* don't allow double-initialization */
2052 Assert(plpgsql_HashTable == NULL);
2054 memset(&ctl, 0, sizeof(ctl));
2055 ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2056 ctl.entrysize = sizeof(plpgsql_HashEnt);
2057 ctl.hash = tag_hash;
2058 plpgsql_HashTable = hash_create("PLpgSQL function cache",
2061 HASH_ELEM | HASH_FUNCTION);
2064 static PLpgSQL_function *
2065 plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
2067 plpgsql_HashEnt *hentry;
2069 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2074 return hentry->function;
2080 plpgsql_HashTableInsert(PLpgSQL_function *function,
2081 PLpgSQL_func_hashkey *func_key)
2083 plpgsql_HashEnt *hentry;
2086 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2091 elog(WARNING, "trying to insert a function that already exists");
2093 hentry->function = function;
2094 /* prepare back link from function to hashtable key */
2095 function->fn_hashkey = &hentry->key;
2099 plpgsql_HashTableDelete(PLpgSQL_function *function)
2101 plpgsql_HashEnt *hentry;
2103 /* do nothing if not in table */
2104 if (function->fn_hashkey == NULL)
2107 hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2108 (void *) function->fn_hashkey,
2112 elog(WARNING, "trying to delete function that does not exist");
2114 /* remove back link, which no longer points to allocated storage */
2115 function->fn_hashkey = NULL;