1
/*-------------------------------------------------------------------------
3
* pl_comp.c - Compiler part of the PL/pgSQL
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* src/pl/plpgsql/src/pl_comp.c
13
*-------------------------------------------------------------------------
20
#include "catalog/namespace.h"
21
#include "catalog/pg_attrdef.h"
22
#include "catalog/pg_attribute.h"
23
#include "catalog/pg_class.h"
24
#include "catalog/pg_proc.h"
25
#include "catalog/pg_proc_fn.h"
26
#include "catalog/pg_type.h"
28
#include "nodes/makefuncs.h"
29
#include "parser/parse_type.h"
30
#include "tcop/tcopprot.h"
31
#include "utils/array.h"
32
#include "utils/builtins.h"
33
#include "utils/lsyscache.h"
34
#include "utils/memutils.h"
35
#include "utils/syscache.h"
39
* Our own local and global variables
42
PLpgSQL_stmt_block *plpgsql_parse_result;
44
static int datums_alloc;
46
PLpgSQL_datum **plpgsql_Datums;
47
static int datums_last = 0;
49
char *plpgsql_error_funcname;
50
bool plpgsql_DumpExecTree = false;
51
bool plpgsql_check_syntax = false;
53
PLpgSQL_function *plpgsql_curr_compile;
55
/* A context appropriate for short-term allocs during compilation */
56
MemoryContext compile_tmp_cxt;
59
* Hash table for compiled functions
62
static HTAB *plpgsql_HashTable = NULL;
64
typedef struct plpgsql_hashent
66
PLpgSQL_func_hashkey key;
67
PLpgSQL_function *function;
70
#define FUNCS_PER_USER 128 /* initial table size */
73
* Lookup table for EXCEPTION condition names
82
static const ExceptionLabelMap exception_label_map[] = {
83
#include "plerrcodes.h"
92
static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
94
PLpgSQL_function *function,
95
PLpgSQL_func_hashkey *hashkey,
97
static void plpgsql_compile_error_callback(void *arg);
98
static void add_dummy_return(PLpgSQL_function *function);
99
static Node *plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref);
100
static Node *plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var);
101
static Node *plpgsql_param_ref(ParseState *pstate, ParamRef *pref);
102
static Node *resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr,
103
ColumnRef *cref, bool error_if_no_field);
104
static Node *make_datum_param(PLpgSQL_expr *expr, int dno, int location);
105
static PLpgSQL_row *build_row_from_class(Oid classOid);
106
static PLpgSQL_row *build_row_from_vars(PLpgSQL_variable **vars, int numvars);
107
static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod, Oid collation);
108
static void compute_function_hashkey(FunctionCallInfo fcinfo,
109
Form_pg_proc procStruct,
110
PLpgSQL_func_hashkey *hashkey,
112
static void plpgsql_resolve_polymorphic_argtypes(int numargs,
113
Oid *argtypes, char *argmodes,
114
Node *call_expr, bool forValidator,
115
const char *proname);
116
static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
117
static void plpgsql_HashTableInsert(PLpgSQL_function *function,
118
PLpgSQL_func_hashkey *func_key);
119
static void plpgsql_HashTableDelete(PLpgSQL_function *function);
120
static void delete_function(PLpgSQL_function *func);
123
* plpgsql_compile Make an execution tree for a PL/pgSQL function.
125
* If forValidator is true, we're only compiling for validation purposes,
126
* and so some checks are skipped.
128
* Note: it's important for this to fall through quickly if the function
129
* has already been compiled.
133
plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
135
Oid funcOid = fcinfo->flinfo->fn_oid;
137
Form_pg_proc procStruct;
138
PLpgSQL_function *function;
139
PLpgSQL_func_hashkey hashkey;
140
bool function_valid = false;
141
bool hashkey_valid = false;
144
* Lookup the pg_proc tuple by Oid; we'll need it in any case
146
procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
147
if (!HeapTupleIsValid(procTup))
148
elog(ERROR, "cache lookup failed for function %u", funcOid);
149
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
152
* See if there's already a cache entry for the current FmgrInfo. If not,
153
* try to find one in the hash table.
155
function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
160
/* Compute hashkey using function signature and actual arg types */
161
compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
162
hashkey_valid = true;
164
/* And do the lookup */
165
function = plpgsql_HashTableLookup(&hashkey);
170
/* We have a compiled function, but is it still valid? */
171
if (function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
172
ItemPointerEquals(&function->fn_tid, &procTup->t_self))
173
function_valid = true;
177
* Nope, so remove it from hashtable and try to drop associated
178
* storage (if not done already).
180
delete_function(function);
183
* If the function isn't in active use then we can overwrite the
184
* func struct with new data, allowing any other existing fn_extra
185
* pointers to make use of the new definition on their next use.
186
* If it is in use then just leave it alone and make a new one.
187
* (The active invocations will run to completion using the
188
* previous definition, and then the cache entry will just be
189
* leaked; doesn't seem worth adding code to clean it up, given
190
* what a corner case this is.)
192
* If we found the function struct via fn_extra then it's possible
193
* a replacement has already been made, so go back and recheck the
196
if (function->use_count != 0)
206
* If the function wasn't found or was out-of-date, we have to compile it
211
* Calculate hashkey if we didn't already; we'll need it to store the
212
* completed function.
215
compute_function_hashkey(fcinfo, procStruct, &hashkey,
221
function = do_compile(fcinfo, procTup, function,
222
&hashkey, forValidator);
225
ReleaseSysCache(procTup);
228
* Save pointer in FmgrInfo to avoid search on subsequent calls
230
fcinfo->flinfo->fn_extra = (void *) function;
233
* Finally return the compiled function
239
* This is the slow part of plpgsql_compile().
241
* The passed-in "function" pointer is either NULL or an already-allocated
242
* function struct to overwrite.
244
* While compiling a function, the CurrentMemoryContext is the
245
* per-function memory context of the function we are compiling. That
246
* means a palloc() will allocate storage with the same lifetime as
247
* the function itself.
249
* Because palloc()'d storage will not be immediately freed, temporary
250
* allocations should either be performed in a short-lived memory
251
* context or explicitly pfree'd. Since not all backend functions are
252
* careful about pfree'ing their allocations, it is also wise to
253
* switch into a short-term context before calling into the
254
* backend. An appropriate context for performing short-term
255
* allocations is the compile_tmp_cxt.
257
* NB: this code is not re-entrant. We assume that nothing we do here could
258
* result in the invocation of another plpgsql function.
260
static PLpgSQL_function *
261
do_compile(FunctionCallInfo fcinfo,
263
PLpgSQL_function *function,
264
PLpgSQL_func_hashkey *hashkey,
267
Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
268
bool is_trigger = CALLED_AS_TRIGGER(fcinfo);
273
Form_pg_type typeStruct;
274
PLpgSQL_variable *var;
277
ErrorContextCallback plerrcontext;
282
int num_out_args = 0;
286
int *in_arg_varnos = NULL;
287
PLpgSQL_variable **out_arg_variables;
288
MemoryContext func_cxt;
291
* Setup the scanner input and error info. We assume that this function
292
* cannot be invoked recursively, so there's no need to save and restore
293
* the static variables used here.
295
prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
296
Anum_pg_proc_prosrc, &isnull);
298
elog(ERROR, "null prosrc");
299
proc_source = TextDatumGetCString(prosrcdatum);
300
plpgsql_scanner_init(proc_source);
302
plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
305
* Setup error traceback support for ereport()
307
plerrcontext.callback = plpgsql_compile_error_callback;
308
plerrcontext.arg = forValidator ? proc_source : NULL;
309
plerrcontext.previous = error_context_stack;
310
error_context_stack = &plerrcontext;
313
* Do extra syntax checks when validating the function definition. We skip
314
* this when actually compiling functions for execution, for performance
317
plpgsql_check_syntax = forValidator;
320
* Create the new function struct, if not done already. The function
321
* structs are never thrown away, so keep them in TopMemoryContext.
323
if (function == NULL)
325
function = (PLpgSQL_function *)
326
MemoryContextAllocZero(TopMemoryContext, sizeof(PLpgSQL_function));
330
/* re-using a previously existing struct, so clear it out */
331
memset(function, 0, sizeof(PLpgSQL_function));
333
plpgsql_curr_compile = function;
336
* All the permanent output of compilation (e.g. parse tree) is kept in a
337
* per-function memory context, so it can be reclaimed easily.
339
func_cxt = AllocSetContextCreate(TopMemoryContext,
340
"PL/pgSQL function context",
341
ALLOCSET_DEFAULT_MINSIZE,
342
ALLOCSET_DEFAULT_INITSIZE,
343
ALLOCSET_DEFAULT_MAXSIZE);
344
compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
346
function->fn_name = pstrdup(NameStr(procStruct->proname));
347
function->fn_oid = fcinfo->flinfo->fn_oid;
348
function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
349
function->fn_tid = procTup->t_self;
350
function->fn_is_trigger = is_trigger;
351
function->fn_input_collation = fcinfo->fncollation;
352
function->fn_cxt = func_cxt;
353
function->out_param_varno = -1; /* set up for no OUT param */
354
function->resolve_option = plpgsql_variable_conflict;
357
* Initialize the compiler, particularly the namespace stack. The
358
* outermost namespace contains function parameters and other special
359
* variables (such as FOUND), and is named after the function itself.
362
plpgsql_ns_push(NameStr(procStruct->proname));
363
plpgsql_DumpExecTree = false;
367
/* This is short-lived, so needn't allocate in function's cxt */
368
plpgsql_Datums = MemoryContextAlloc(compile_tmp_cxt,
369
sizeof(PLpgSQL_datum *) * datums_alloc);
377
* Fetch info about the procedure's parameters. Allocations aren't
378
* needed permanently, so make them in tmp cxt.
380
* We also need to resolve any polymorphic input or output
381
* argument types. In validation mode we won't be able to, so we
382
* arbitrarily assume we are dealing with integers.
384
MemoryContextSwitchTo(compile_tmp_cxt);
386
numargs = get_func_arg_info(procTup,
387
&argtypes, &argnames, &argmodes);
389
plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
390
fcinfo->flinfo->fn_expr,
392
plpgsql_error_funcname);
394
in_arg_varnos = (int *) palloc(numargs * sizeof(int));
395
out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
397
MemoryContextSwitchTo(func_cxt);
400
* Create the variables for the procedure's parameters.
402
for (i = 0; i < numargs; i++)
405
Oid argtypeid = argtypes[i];
406
char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
407
PLpgSQL_type *argdtype;
408
PLpgSQL_variable *argvariable;
411
/* Create $n name for variable */
412
snprintf(buf, sizeof(buf), "$%d", i + 1);
414
/* Create datatype info */
415
argdtype = plpgsql_build_datatype(argtypeid,
417
function->fn_input_collation);
419
/* Disallow pseudotype argument */
420
/* (note we already replaced polymorphic types) */
421
/* (build_variable would do this, but wrong message) */
422
if (argdtype->ttype != PLPGSQL_TTYPE_SCALAR &&
423
argdtype->ttype != PLPGSQL_TTYPE_ROW)
425
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
426
errmsg("PL/pgSQL functions cannot accept type %s",
427
format_type_be(argtypeid))));
429
/* Build variable and add to datum list */
430
argvariable = plpgsql_build_variable(buf, 0,
433
if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
435
argitemtype = PLPGSQL_NSTYPE_VAR;
439
Assert(argvariable->dtype == PLPGSQL_DTYPE_ROW);
440
argitemtype = PLPGSQL_NSTYPE_ROW;
443
/* Remember arguments in appropriate arrays */
444
if (argmode == PROARGMODE_IN ||
445
argmode == PROARGMODE_INOUT ||
446
argmode == PROARGMODE_VARIADIC)
447
in_arg_varnos[num_in_args++] = argvariable->dno;
448
if (argmode == PROARGMODE_OUT ||
449
argmode == PROARGMODE_INOUT ||
450
argmode == PROARGMODE_TABLE)
451
out_arg_variables[num_out_args++] = argvariable;
453
/* Add to namespace under the $n name */
454
plpgsql_ns_additem(argitemtype, argvariable->dno, buf);
456
/* If there's a name for the argument, make an alias */
457
if (argnames && argnames[i][0] != '\0')
458
plpgsql_ns_additem(argitemtype, argvariable->dno,
463
* If there's just one OUT parameter, out_param_varno points
464
* directly to it. If there's more than one, build a row that
467
if (num_out_args == 1)
468
function->out_param_varno = out_arg_variables[0]->dno;
469
else if (num_out_args > 1)
471
PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
474
plpgsql_adddatum((PLpgSQL_datum *) row);
475
function->out_param_varno = row->dno;
479
* Check for a polymorphic returntype. If found, use the actual
480
* returntype type from the caller's FuncExpr node, if we have
481
* one. (In validation mode we arbitrarily assume we are dealing
484
* Note: errcode is FEATURE_NOT_SUPPORTED because it should always
485
* work; if it doesn't we're in some context that fails to make
486
* the info available.
488
rettypeid = procStruct->prorettype;
489
if (IsPolymorphicType(rettypeid))
493
if (rettypeid == ANYARRAYOID)
494
rettypeid = INT4ARRAYOID;
495
else /* ANYELEMENT or ANYNONARRAY */
497
/* XXX what could we use for ANYENUM? */
501
rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
502
if (!OidIsValid(rettypeid))
504
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
505
errmsg("could not determine actual return type "
506
"for polymorphic function \"%s\"",
507
plpgsql_error_funcname)));
512
* Normal function has a defined returntype
514
function->fn_rettype = rettypeid;
515
function->fn_retset = procStruct->proretset;
518
* Lookup the function's return type
520
typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettypeid));
521
if (!HeapTupleIsValid(typeTup))
522
elog(ERROR, "cache lookup failed for type %u", rettypeid);
523
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
525
/* Disallow pseudotype result, except VOID or RECORD */
526
/* (note we already replaced polymorphic types) */
527
if (typeStruct->typtype == TYPTYPE_PSEUDO)
529
if (rettypeid == VOIDOID ||
530
rettypeid == RECORDOID)
532
else if (rettypeid == TRIGGEROID)
534
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
535
errmsg("trigger functions can only be called as triggers")));
538
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
539
errmsg("PL/pgSQL functions cannot return type %s",
540
format_type_be(rettypeid))));
543
if (typeStruct->typrelid != InvalidOid ||
544
rettypeid == RECORDOID)
545
function->fn_retistuple = true;
548
function->fn_retbyval = typeStruct->typbyval;
549
function->fn_rettyplen = typeStruct->typlen;
550
function->fn_rettypioparam = getTypeIOParam(typeTup);
551
fmgr_info(typeStruct->typinput, &(function->fn_retinput));
554
* install $0 reference, but only for polymorphic return
555
* types, and not when the return is specified through an
558
if (IsPolymorphicType(procStruct->prorettype) &&
561
(void) plpgsql_build_variable("$0", 0,
562
build_datatype(typeTup,
564
function->fn_input_collation),
568
ReleaseSysCache(typeTup);
572
/* Trigger procedure's return type is unknown yet */
573
function->fn_rettype = InvalidOid;
574
function->fn_retbyval = false;
575
function->fn_retistuple = true;
576
function->fn_retset = false;
578
/* shouldn't be any declared arguments */
579
if (procStruct->pronargs != 0)
581
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
582
errmsg("trigger functions cannot have declared arguments"),
583
errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
585
/* Add the record for referencing NEW */
586
rec = plpgsql_build_record("new", 0, true);
587
function->new_varno = rec->dno;
589
/* Add the record for referencing OLD */
590
rec = plpgsql_build_record("old", 0, true);
591
function->old_varno = rec->dno;
593
/* Add the variable tg_name */
594
var = plpgsql_build_variable("tg_name", 0,
595
plpgsql_build_datatype(NAMEOID,
599
function->tg_name_varno = var->dno;
601
/* Add the variable tg_when */
602
var = plpgsql_build_variable("tg_when", 0,
603
plpgsql_build_datatype(TEXTOID,
605
function->fn_input_collation),
607
function->tg_when_varno = var->dno;
609
/* Add the variable tg_level */
610
var = plpgsql_build_variable("tg_level", 0,
611
plpgsql_build_datatype(TEXTOID,
613
function->fn_input_collation),
615
function->tg_level_varno = var->dno;
617
/* Add the variable tg_op */
618
var = plpgsql_build_variable("tg_op", 0,
619
plpgsql_build_datatype(TEXTOID,
621
function->fn_input_collation),
623
function->tg_op_varno = var->dno;
625
/* Add the variable tg_relid */
626
var = plpgsql_build_variable("tg_relid", 0,
627
plpgsql_build_datatype(OIDOID,
631
function->tg_relid_varno = var->dno;
633
/* Add the variable tg_relname */
634
var = plpgsql_build_variable("tg_relname", 0,
635
plpgsql_build_datatype(NAMEOID,
639
function->tg_relname_varno = var->dno;
641
/* tg_table_name is now preferred to tg_relname */
642
var = plpgsql_build_variable("tg_table_name", 0,
643
plpgsql_build_datatype(NAMEOID,
647
function->tg_table_name_varno = var->dno;
649
/* add the variable tg_table_schema */
650
var = plpgsql_build_variable("tg_table_schema", 0,
651
plpgsql_build_datatype(NAMEOID,
655
function->tg_table_schema_varno = var->dno;
657
/* Add the variable tg_nargs */
658
var = plpgsql_build_variable("tg_nargs", 0,
659
plpgsql_build_datatype(INT4OID,
663
function->tg_nargs_varno = var->dno;
665
/* Add the variable tg_argv */
666
var = plpgsql_build_variable("tg_argv", 0,
667
plpgsql_build_datatype(TEXTARRAYOID,
669
function->fn_input_collation),
671
function->tg_argv_varno = var->dno;
676
elog(ERROR, "unrecognized function typecode: %d", (int) is_trigger);
680
/* Remember if function is STABLE/IMMUTABLE */
681
function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
684
* Create the magic FOUND variable.
686
var = plpgsql_build_variable("found", 0,
687
plpgsql_build_datatype(BOOLOID,
691
function->found_varno = var->dno;
694
* Now parse the function's text
696
parse_rc = plpgsql_yyparse();
698
elog(ERROR, "plpgsql parser returned %d", parse_rc);
699
function->action = plpgsql_parse_result;
701
plpgsql_scanner_finish();
705
* If it has OUT parameters or returns VOID or returns a set, we allow
706
* control to fall off the end without an explicit RETURN statement. The
707
* easiest way to implement this is to add a RETURN statement to the end
708
* of the statement list during parsing.
710
if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
712
add_dummy_return(function);
715
* Complete the function's info
717
function->fn_nargs = procStruct->pronargs;
718
for (i = 0; i < function->fn_nargs; i++)
719
function->fn_argvarnos[i] = in_arg_varnos[i];
720
function->ndatums = plpgsql_nDatums;
721
function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
722
for (i = 0; i < plpgsql_nDatums; i++)
723
function->datums[i] = plpgsql_Datums[i];
725
/* Debug dump for completed functions */
726
if (plpgsql_DumpExecTree)
727
plpgsql_dumptree(function);
730
* add it to the hash table
732
plpgsql_HashTableInsert(function, hashkey);
735
* Pop the error context stack
737
error_context_stack = plerrcontext.previous;
738
plpgsql_error_funcname = NULL;
740
plpgsql_check_syntax = false;
742
MemoryContextSwitchTo(compile_tmp_cxt);
743
compile_tmp_cxt = NULL;
748
* plpgsql_compile_inline Make an execution tree for an anonymous code block.
750
* Note: this is generally parallel to do_compile(); is it worth trying to
753
* Note: we assume the block will be thrown away so there is no need to build
754
* persistent data structures.
758
plpgsql_compile_inline(char *proc_source)
760
char *func_name = "inline_code_block";
761
PLpgSQL_function *function;
762
ErrorContextCallback plerrcontext;
764
PLpgSQL_variable *var;
766
MemoryContext func_cxt;
770
* Setup the scanner input and error info. We assume that this function
771
* cannot be invoked recursively, so there's no need to save and restore
772
* the static variables used here.
774
plpgsql_scanner_init(proc_source);
776
plpgsql_error_funcname = func_name;
779
* Setup error traceback support for ereport()
781
plerrcontext.callback = plpgsql_compile_error_callback;
782
plerrcontext.arg = proc_source;
783
plerrcontext.previous = error_context_stack;
784
error_context_stack = &plerrcontext;
786
/* Do extra syntax checking if check_function_bodies is on */
787
plpgsql_check_syntax = check_function_bodies;
789
/* Function struct does not live past current statement */
790
function = (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
792
plpgsql_curr_compile = function;
795
* All the rest of the compile-time storage (e.g. parse tree) is kept in
796
* its own memory context, so it can be reclaimed easily.
798
func_cxt = AllocSetContextCreate(CurrentMemoryContext,
799
"PL/pgSQL function context",
800
ALLOCSET_DEFAULT_MINSIZE,
801
ALLOCSET_DEFAULT_INITSIZE,
802
ALLOCSET_DEFAULT_MAXSIZE);
803
compile_tmp_cxt = MemoryContextSwitchTo(func_cxt);
805
function->fn_name = pstrdup(func_name);
806
function->fn_is_trigger = false;
807
function->fn_input_collation = InvalidOid;
808
function->fn_cxt = func_cxt;
809
function->out_param_varno = -1; /* set up for no OUT param */
810
function->resolve_option = plpgsql_variable_conflict;
813
plpgsql_ns_push(func_name);
814
plpgsql_DumpExecTree = false;
818
plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
821
/* Set up as though in a function returning VOID */
822
function->fn_rettype = VOIDOID;
823
function->fn_retset = false;
824
function->fn_retistuple = false;
825
/* a bit of hardwired knowledge about type VOID here */
826
function->fn_retbyval = true;
827
function->fn_rettyplen = sizeof(int32);
828
getTypeInputInfo(VOIDOID, &typinput, &function->fn_rettypioparam);
829
fmgr_info(typinput, &(function->fn_retinput));
832
* Remember if function is STABLE/IMMUTABLE. XXX would it be better to
833
* set this TRUE inside a read-only transaction? Not clear.
835
function->fn_readonly = false;
838
* Create the magic FOUND variable.
840
var = plpgsql_build_variable("found", 0,
841
plpgsql_build_datatype(BOOLOID,
845
function->found_varno = var->dno;
848
* Now parse the function's text
850
parse_rc = plpgsql_yyparse();
852
elog(ERROR, "plpgsql parser returned %d", parse_rc);
853
function->action = plpgsql_parse_result;
855
plpgsql_scanner_finish();
858
* If it returns VOID (always true at the moment), we allow control to
859
* fall off the end without an explicit RETURN statement.
861
if (function->fn_rettype == VOIDOID)
862
add_dummy_return(function);
865
* Complete the function's info
867
function->fn_nargs = 0;
868
function->ndatums = plpgsql_nDatums;
869
function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
870
for (i = 0; i < plpgsql_nDatums; i++)
871
function->datums[i] = plpgsql_Datums[i];
874
* Pop the error context stack
876
error_context_stack = plerrcontext.previous;
877
plpgsql_error_funcname = NULL;
879
plpgsql_check_syntax = false;
881
MemoryContextSwitchTo(compile_tmp_cxt);
882
compile_tmp_cxt = NULL;
888
* error context callback to let us supply a call-stack traceback.
889
* If we are validating or executing an anonymous code block, the function
890
* source text is passed as an argument.
893
plpgsql_compile_error_callback(void *arg)
898
* Try to convert syntax error position to reference text of original
899
* CREATE FUNCTION or DO command.
901
if (function_parse_error_transpose((const char *) arg))
905
* Done if a syntax error position was reported; otherwise we have to
906
* fall back to a "near line N" report.
910
if (plpgsql_error_funcname)
911
errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
912
plpgsql_error_funcname, plpgsql_latest_lineno());
917
* Add a dummy RETURN statement to the given function's body
920
add_dummy_return(PLpgSQL_function *function)
923
* If the outer block has an EXCEPTION clause, we need to make a new outer
924
* block, since the added RETURN shouldn't act like it is inside the
927
if (function->action->exceptions != NULL)
929
PLpgSQL_stmt_block *new;
931
new = palloc0(sizeof(PLpgSQL_stmt_block));
932
new->cmd_type = PLPGSQL_STMT_BLOCK;
933
new->body = list_make1(function->action);
935
function->action = new;
937
if (function->action->body == NIL ||
938
((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
940
PLpgSQL_stmt_return *new;
942
new = palloc0(sizeof(PLpgSQL_stmt_return));
943
new->cmd_type = PLPGSQL_STMT_RETURN;
945
new->retvarno = function->out_param_varno;
947
function->action->body = lappend(function->action->body, new);
953
* plpgsql_parser_setup set up parser hooks for dynamic parameters
955
* Note: this routine, and the hook functions it prepares for, are logically
956
* part of plpgsql parsing. But they actually run during function execution,
957
* when we are ready to evaluate a SQL query or expression that has not
958
* previously been parsed and planned.
961
plpgsql_parser_setup(struct ParseState *pstate, PLpgSQL_expr *expr)
963
pstate->p_pre_columnref_hook = plpgsql_pre_column_ref;
964
pstate->p_post_columnref_hook = plpgsql_post_column_ref;
965
pstate->p_paramref_hook = plpgsql_param_ref;
966
/* no need to use p_coerce_param_hook */
967
pstate->p_ref_hook_state = (void *) expr;
971
* plpgsql_pre_column_ref parser callback before parsing a ColumnRef
974
plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
976
PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
978
if (expr->func->resolve_option == PLPGSQL_RESOLVE_VARIABLE)
979
return resolve_column_ref(pstate, expr, cref, false);
985
* plpgsql_post_column_ref parser callback after parsing a ColumnRef
988
plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
990
PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
993
if (expr->func->resolve_option == PLPGSQL_RESOLVE_VARIABLE)
994
return NULL; /* we already found there's no match */
996
if (expr->func->resolve_option == PLPGSQL_RESOLVE_COLUMN && var != NULL)
997
return NULL; /* there's a table column, prefer that */
1000
* If we find a record/row variable but can't match a field name, throw
1001
* error if there was no core resolution for the ColumnRef either. In
1002
* that situation, the reference is inevitably going to fail, and
1003
* complaining about the record/row variable is likely to be more on-point
1004
* than the core parser's error message. (It's too bad we don't have
1005
* access to transformColumnRef's internal crerr state here, as in case of
1006
* a conflict with a table name this could still be less than the most
1007
* helpful error message possible.)
1009
myvar = resolve_column_ref(pstate, expr, cref, (var == NULL));
1011
if (myvar != NULL && var != NULL)
1014
* We could leave it to the core parser to throw this error, but we
1015
* can add a more useful detail message than the core could.
1018
(errcode(ERRCODE_AMBIGUOUS_COLUMN),
1019
errmsg("column reference \"%s\" is ambiguous",
1020
NameListToString(cref->fields)),
1021
errdetail("It could refer to either a PL/pgSQL variable or a table column."),
1022
parser_errposition(pstate, cref->location)));
1029
* plpgsql_param_ref parser callback for ParamRefs ($n symbols)
1032
plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
1034
PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1036
PLpgSQL_nsitem *nse;
1038
snprintf(pname, sizeof(pname), "$%d", pref->number);
1040
nse = plpgsql_ns_lookup(expr->ns, false,
1045
return NULL; /* name not known to plpgsql */
1047
return make_datum_param(expr, nse->itemno, pref->location);
1051
* resolve_column_ref attempt to resolve a ColumnRef as a plpgsql var
1053
* Returns the translated node structure, or NULL if name not found
1055
* error_if_no_field tells whether to throw error or quietly return NULL if
1056
* we are able to match a record/row name but don't find a field name match.
1059
resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr,
1060
ColumnRef *cref, bool error_if_no_field)
1062
PLpgSQL_execstate *estate;
1063
PLpgSQL_nsitem *nse;
1065
const char *name2 = NULL;
1066
const char *name3 = NULL;
1067
const char *colname = NULL;
1069
int nnames_scalar = 0;
1070
int nnames_wholerow = 0;
1071
int nnames_field = 0;
1074
* We use the function's current estate to resolve parameter data types.
1075
* This is really pretty bogus because there is no provision for updating
1076
* plans when those types change ...
1078
estate = expr->func->cur_estate;
1081
* The allowed syntaxes are:
1083
* A Scalar variable reference, or whole-row record reference.
1084
* A.B Qualified scalar or whole-row reference, or field reference.
1085
* A.B.C Qualified record field reference.
1086
* A.* Whole-row record reference.
1087
* A.B.* Qualified whole-row record reference.
1090
switch (list_length(cref->fields))
1094
Node *field1 = (Node *) linitial(cref->fields);
1096
Assert(IsA(field1, String));
1097
name1 = strVal(field1);
1099
nnames_wholerow = 1;
1104
Node *field1 = (Node *) linitial(cref->fields);
1105
Node *field2 = (Node *) lsecond(cref->fields);
1107
Assert(IsA(field1, String));
1108
name1 = strVal(field1);
1110
/* Whole-row reference? */
1111
if (IsA(field2, A_Star))
1113
/* Set name2 to prevent matches to scalar variables */
1115
nnames_wholerow = 1;
1119
Assert(IsA(field2, String));
1120
name2 = strVal(field2);
1123
nnames_wholerow = 2;
1129
Node *field1 = (Node *) linitial(cref->fields);
1130
Node *field2 = (Node *) lsecond(cref->fields);
1131
Node *field3 = (Node *) lthird(cref->fields);
1133
Assert(IsA(field1, String));
1134
name1 = strVal(field1);
1135
Assert(IsA(field2, String));
1136
name2 = strVal(field2);
1138
/* Whole-row reference? */
1139
if (IsA(field3, A_Star))
1141
/* Set name3 to prevent matches to scalar variables */
1143
nnames_wholerow = 2;
1147
Assert(IsA(field3, String));
1148
name3 = strVal(field3);
1154
/* too many names, ignore */
1158
nse = plpgsql_ns_lookup(expr->ns, false,
1159
name1, name2, name3,
1163
return NULL; /* name not known to plpgsql */
1165
switch (nse->itemtype)
1167
case PLPGSQL_NSTYPE_VAR:
1168
if (nnames == nnames_scalar)
1169
return make_datum_param(expr, nse->itemno, cref->location);
1171
case PLPGSQL_NSTYPE_REC:
1172
if (nnames == nnames_wholerow)
1173
return make_datum_param(expr, nse->itemno, cref->location);
1174
if (nnames == nnames_field)
1176
/* colname could be a field in this record */
1179
/* search for a datum referencing this field */
1180
for (i = 0; i < estate->ndatums; i++)
1182
PLpgSQL_recfield *fld = (PLpgSQL_recfield *) estate->datums[i];
1184
if (fld->dtype == PLPGSQL_DTYPE_RECFIELD &&
1185
fld->recparentno == nse->itemno &&
1186
strcmp(fld->fieldname, colname) == 0)
1188
return make_datum_param(expr, i, cref->location);
1193
* We should not get here, because a RECFIELD datum should
1194
* have been built at parse time for every possible qualified
1195
* reference to fields of this record. But if we do, handle
1196
* it like field-not-found: throw error or return NULL.
1198
if (error_if_no_field)
1200
(errcode(ERRCODE_UNDEFINED_COLUMN),
1201
errmsg("record \"%s\" has no field \"%s\"",
1202
(nnames_field == 1) ? name1 : name2,
1204
parser_errposition(pstate, cref->location)));
1207
case PLPGSQL_NSTYPE_ROW:
1208
if (nnames == nnames_wholerow)
1209
return make_datum_param(expr, nse->itemno, cref->location);
1210
if (nnames == nnames_field)
1212
/* colname could be a field in this row */
1213
PLpgSQL_row *row = (PLpgSQL_row *) estate->datums[nse->itemno];
1216
for (i = 0; i < row->nfields; i++)
1218
if (row->fieldnames[i] &&
1219
strcmp(row->fieldnames[i], colname) == 0)
1221
return make_datum_param(expr, row->varnos[i],
1225
/* Not found, so throw error or return NULL */
1226
if (error_if_no_field)
1228
(errcode(ERRCODE_UNDEFINED_COLUMN),
1229
errmsg("record \"%s\" has no field \"%s\"",
1230
(nnames_field == 1) ? name1 : name2,
1232
parser_errposition(pstate, cref->location)));
1236
elog(ERROR, "unrecognized plpgsql itemtype: %d", nse->itemtype);
1239
/* Name format doesn't match the plpgsql variable type */
1244
* Helper for columnref parsing: build a Param referencing a plpgsql datum,
1245
* and make sure that that datum is listed in the expression's paramnos.
1248
make_datum_param(PLpgSQL_expr *expr, int dno, int location)
1250
PLpgSQL_execstate *estate;
1251
PLpgSQL_datum *datum;
1253
MemoryContext oldcontext;
1255
/* see comment in resolve_column_ref */
1256
estate = expr->func->cur_estate;
1257
Assert(dno >= 0 && dno < estate->ndatums);
1258
datum = estate->datums[dno];
1261
* Bitmapset must be allocated in function's permanent memory context
1263
oldcontext = MemoryContextSwitchTo(expr->func->fn_cxt);
1264
expr->paramnos = bms_add_member(expr->paramnos, dno);
1265
MemoryContextSwitchTo(oldcontext);
1267
param = makeNode(Param);
1268
param->paramkind = PARAM_EXTERN;
1269
param->paramid = dno + 1;
1270
param->paramtype = exec_get_datum_type(estate, datum);
1271
param->paramtypmod = -1;
1272
param->paramcollid = exec_get_datum_collation(estate, datum);
1273
param->location = location;
1275
return (Node *) param;
1280
* plpgsql_parse_word The scanner calls this to postparse
1281
* any single word that is not a reserved keyword.
1283
* word1 is the downcased/dequoted identifier; it must be palloc'd in the
1284
* function's long-term memory context.
1286
* yytxt is the original token text; we need this to check for quoting,
1287
* so that later checks for unreserved keywords work properly.
1289
* If recognized as a variable, fill in *wdatum and return TRUE;
1290
* if not recognized, fill in *word and return FALSE.
1291
* (Note: those two pointers actually point to members of the same union,
1292
* but for notational reasons we pass them separately.)
1296
plpgsql_parse_word(char *word1, const char *yytxt,
1297
PLwdatum *wdatum, PLword *word)
1302
* We should do nothing in DECLARE sections. In SQL expressions, there's
1303
* no need to do anything either --- lookup will happen when the
1304
* expression is compiled.
1306
if (plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_NORMAL)
1309
* Do a lookup in the current namespace stack
1311
ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1317
switch (ns->itemtype)
1319
case PLPGSQL_NSTYPE_VAR:
1320
case PLPGSQL_NSTYPE_ROW:
1321
case PLPGSQL_NSTYPE_REC:
1322
wdatum->datum = plpgsql_Datums[ns->itemno];
1323
wdatum->ident = word1;
1324
wdatum->quoted = (yytxt[0] == '"');
1325
wdatum->idents = NIL;
1329
/* plpgsql_ns_lookup should never return anything else */
1330
elog(ERROR, "unrecognized plpgsql itemtype: %d",
1337
* Nothing found - up to now it's a word without any special meaning for
1340
word->ident = word1;
1341
word->quoted = (yytxt[0] == '"');
1347
* plpgsql_parse_dblword Same lookup for two words
1348
* separated by a dot.
1352
plpgsql_parse_dblword(char *word1, char *word2,
1353
PLwdatum *wdatum, PLcword *cword)
1359
idents = list_make2(makeString(word1),
1363
* We should do nothing in DECLARE sections. In SQL expressions, we
1364
* really only need to make sure that RECFIELD datums are created when
1367
if (plpgsql_IdentifierLookup != IDENTIFIER_LOOKUP_DECLARE)
1370
* Do a lookup in the current namespace stack
1372
ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1377
switch (ns->itemtype)
1379
case PLPGSQL_NSTYPE_VAR:
1380
/* Block-qualified reference to scalar variable. */
1381
wdatum->datum = plpgsql_Datums[ns->itemno];
1382
wdatum->ident = NULL;
1383
wdatum->quoted = false; /* not used */
1384
wdatum->idents = idents;
1387
case PLPGSQL_NSTYPE_REC:
1391
* First word is a record name, so second word could
1392
* be a field in this record. We build a RECFIELD
1393
* datum whether it is or not --- any error will be
1396
PLpgSQL_recfield *new;
1398
new = palloc(sizeof(PLpgSQL_recfield));
1399
new->dtype = PLPGSQL_DTYPE_RECFIELD;
1400
new->fieldname = pstrdup(word2);
1401
new->recparentno = ns->itemno;
1403
plpgsql_adddatum((PLpgSQL_datum *) new);
1405
wdatum->datum = (PLpgSQL_datum *) new;
1409
/* Block-qualified reference to record variable. */
1410
wdatum->datum = plpgsql_Datums[ns->itemno];
1412
wdatum->ident = NULL;
1413
wdatum->quoted = false; /* not used */
1414
wdatum->idents = idents;
1417
case PLPGSQL_NSTYPE_ROW:
1421
* First word is a row name, so second word could be a
1422
* field in this row. Again, no error now if it
1428
row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1429
for (i = 0; i < row->nfields; i++)
1431
if (row->fieldnames[i] &&
1432
strcmp(row->fieldnames[i], word2) == 0)
1434
wdatum->datum = plpgsql_Datums[row->varnos[i]];
1435
wdatum->ident = NULL;
1436
wdatum->quoted = false; /* not used */
1437
wdatum->idents = idents;
1441
/* fall through to return CWORD */
1445
/* Block-qualified reference to row variable. */
1446
wdatum->datum = plpgsql_Datums[ns->itemno];
1447
wdatum->ident = NULL;
1448
wdatum->quoted = false; /* not used */
1449
wdatum->idents = idents;
1461
cword->idents = idents;
1467
* plpgsql_parse_tripword Same lookup for three words
1468
* separated by dots.
1472
plpgsql_parse_tripword(char *word1, char *word2, char *word3,
1473
PLwdatum *wdatum, PLcword *cword)
1479
idents = list_make3(makeString(word1),
1484
* We should do nothing in DECLARE sections. In SQL expressions, we
1485
* really only need to make sure that RECFIELD datums are created when
1488
if (plpgsql_IdentifierLookup != IDENTIFIER_LOOKUP_DECLARE)
1491
* Do a lookup in the current namespace stack. Must find a qualified
1492
* reference, else ignore.
1494
ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1495
word1, word2, word3,
1497
if (ns != NULL && nnames == 2)
1499
switch (ns->itemtype)
1501
case PLPGSQL_NSTYPE_REC:
1504
* words 1/2 are a record name, so third word could be
1505
* a field in this record.
1507
PLpgSQL_recfield *new;
1509
new = palloc(sizeof(PLpgSQL_recfield));
1510
new->dtype = PLPGSQL_DTYPE_RECFIELD;
1511
new->fieldname = pstrdup(word3);
1512
new->recparentno = ns->itemno;
1514
plpgsql_adddatum((PLpgSQL_datum *) new);
1516
wdatum->datum = (PLpgSQL_datum *) new;
1517
wdatum->ident = NULL;
1518
wdatum->quoted = false; /* not used */
1519
wdatum->idents = idents;
1523
case PLPGSQL_NSTYPE_ROW:
1526
* words 1/2 are a row name, so third word could be a
1527
* field in this row.
1532
row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1533
for (i = 0; i < row->nfields; i++)
1535
if (row->fieldnames[i] &&
1536
strcmp(row->fieldnames[i], word3) == 0)
1538
wdatum->datum = plpgsql_Datums[row->varnos[i]];
1539
wdatum->ident = NULL;
1540
wdatum->quoted = false; /* not used */
1541
wdatum->idents = idents;
1545
/* fall through to return CWORD */
1556
cword->idents = idents;
1562
* plpgsql_parse_wordtype The scanner found word%TYPE. word can be
1563
* a variable name or a basetype.
1565
* Returns datatype struct, or NULL if no match found for word.
1569
plpgsql_parse_wordtype(char *ident)
1571
PLpgSQL_type *dtype;
1572
PLpgSQL_nsitem *nse;
1576
* Do a lookup in the current namespace stack
1578
nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1584
switch (nse->itemtype)
1586
case PLPGSQL_NSTYPE_VAR:
1587
return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1589
/* XXX perhaps allow REC/ROW here? */
1597
* Word wasn't found in the namespace stack. Try to find a data type with
1598
* that name, but ignore shell types and complex types.
1600
typeTup = LookupTypeName(NULL, makeTypeName(ident), NULL);
1603
Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1605
if (!typeStruct->typisdefined ||
1606
typeStruct->typrelid != InvalidOid)
1608
ReleaseSysCache(typeTup);
1612
dtype = build_datatype(typeTup, -1,
1613
plpgsql_curr_compile->fn_input_collation);
1615
ReleaseSysCache(typeTup);
1620
* Nothing found - up to now it's a word without any special meaning for
1628
* plpgsql_parse_cwordtype Same lookup for compositeword%TYPE
1632
plpgsql_parse_cwordtype(List *idents)
1634
PLpgSQL_type *dtype = NULL;
1635
PLpgSQL_nsitem *nse;
1636
const char *fldname;
1638
HeapTuple classtup = NULL;
1639
HeapTuple attrtup = NULL;
1640
HeapTuple typetup = NULL;
1641
Form_pg_class classStruct;
1642
Form_pg_attribute attrStruct;
1643
MemoryContext oldCxt;
1645
/* Avoid memory leaks in the long-term function context */
1646
oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1648
if (list_length(idents) == 2)
1651
* Do a lookup in the current namespace stack. We don't need to check
1652
* number of names matched, because we will only consider scalar
1655
nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1656
strVal(linitial(idents)),
1657
strVal(lsecond(idents)),
1661
if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1663
dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1668
* First word could also be a table name
1670
classOid = RelnameGetRelid(strVal(linitial(idents)));
1671
if (!OidIsValid(classOid))
1673
fldname = strVal(lsecond(idents));
1675
else if (list_length(idents) == 3)
1679
relvar = makeRangeVar(strVal(linitial(idents)),
1680
strVal(lsecond(idents)),
1682
classOid = RangeVarGetRelid(relvar, true);
1683
if (!OidIsValid(classOid))
1685
fldname = strVal(lthird(idents));
1690
classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(classOid));
1691
if (!HeapTupleIsValid(classtup))
1693
classStruct = (Form_pg_class) GETSTRUCT(classtup);
1696
* It must be a relation, sequence, view, or type
1698
if (classStruct->relkind != RELKIND_RELATION &&
1699
classStruct->relkind != RELKIND_SEQUENCE &&
1700
classStruct->relkind != RELKIND_VIEW &&
1701
classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1705
* Fetch the named table field and its type
1707
attrtup = SearchSysCacheAttName(classOid, fldname);
1708
if (!HeapTupleIsValid(attrtup))
1710
attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1712
typetup = SearchSysCache1(TYPEOID,
1713
ObjectIdGetDatum(attrStruct->atttypid));
1714
if (!HeapTupleIsValid(typetup))
1715
elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1718
* Found that - build a compiler type struct in the caller's cxt and
1721
MemoryContextSwitchTo(oldCxt);
1722
dtype = build_datatype(typetup,
1723
attrStruct->atttypmod,
1724
attrStruct->attcollation);
1725
MemoryContextSwitchTo(compile_tmp_cxt);
1728
if (HeapTupleIsValid(classtup))
1729
ReleaseSysCache(classtup);
1730
if (HeapTupleIsValid(attrtup))
1731
ReleaseSysCache(attrtup);
1732
if (HeapTupleIsValid(typetup))
1733
ReleaseSysCache(typetup);
1735
MemoryContextSwitchTo(oldCxt);
1740
* plpgsql_parse_wordrowtype Scanner found word%ROWTYPE.
1741
* So word must be a table name.
1745
plpgsql_parse_wordrowtype(char *ident)
1749
/* Lookup the relation */
1750
classOid = RelnameGetRelid(ident);
1751
if (!OidIsValid(classOid))
1753
(errcode(ERRCODE_UNDEFINED_TABLE),
1754
errmsg("relation \"%s\" does not exist", ident)));
1756
/* Build and return the row type struct */
1757
return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1761
* plpgsql_parse_cwordrowtype Scanner found compositeword%ROWTYPE.
1762
* So word must be a namespace qualified table name.
1766
plpgsql_parse_cwordrowtype(List *idents)
1770
MemoryContext oldCxt;
1772
if (list_length(idents) != 2)
1775
/* Avoid memory leaks in long-term function context */
1776
oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
1778
/* Lookup the relation */
1779
relvar = makeRangeVar(strVal(linitial(idents)),
1780
strVal(lsecond(idents)),
1782
classOid = RangeVarGetRelid(relvar, true);
1783
if (!OidIsValid(classOid))
1785
(errcode(ERRCODE_UNDEFINED_TABLE),
1786
errmsg("relation \"%s.%s\" does not exist",
1787
strVal(linitial(idents)), strVal(lsecond(idents)))));
1789
MemoryContextSwitchTo(oldCxt);
1791
/* Build and return the row type struct */
1792
return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1796
* plpgsql_build_variable - build a datum-array entry of a given
1799
* The returned struct may be a PLpgSQL_var, PLpgSQL_row, or
1800
* PLpgSQL_rec depending on the given datatype, and is allocated via
1801
* palloc. The struct is automatically added to the current datum
1802
* array, and optionally to the current namespace.
1805
plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype,
1808
PLpgSQL_variable *result;
1810
switch (dtype->ttype)
1812
case PLPGSQL_TTYPE_SCALAR:
1814
/* Ordinary scalar datatype */
1817
var = palloc0(sizeof(PLpgSQL_var));
1818
var->dtype = PLPGSQL_DTYPE_VAR;
1819
var->refname = pstrdup(refname);
1820
var->lineno = lineno;
1821
var->datatype = dtype;
1822
/* other fields might be filled by caller */
1824
/* preset to NULL */
1827
var->freeval = false;
1829
plpgsql_adddatum((PLpgSQL_datum *) var);
1831
plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
1834
result = (PLpgSQL_variable *) var;
1837
case PLPGSQL_TTYPE_ROW:
1839
/* Composite type -- build a row variable */
1842
row = build_row_from_class(dtype->typrelid);
1844
row->dtype = PLPGSQL_DTYPE_ROW;
1845
row->refname = pstrdup(refname);
1846
row->lineno = lineno;
1848
plpgsql_adddatum((PLpgSQL_datum *) row);
1850
plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
1853
result = (PLpgSQL_variable *) row;
1856
case PLPGSQL_TTYPE_REC:
1858
/* "record" type -- build a record variable */
1861
rec = plpgsql_build_record(refname, lineno, add2namespace);
1862
result = (PLpgSQL_variable *) rec;
1865
case PLPGSQL_TTYPE_PSEUDO:
1867
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1868
errmsg("variable \"%s\" has pseudo-type %s",
1869
refname, format_type_be(dtype->typoid))));
1870
result = NULL; /* keep compiler quiet */
1873
elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1874
result = NULL; /* keep compiler quiet */
1882
* Build empty named record variable, and optionally add it to namespace
1885
plpgsql_build_record(const char *refname, int lineno, bool add2namespace)
1889
rec = palloc0(sizeof(PLpgSQL_rec));
1890
rec->dtype = PLPGSQL_DTYPE_REC;
1891
rec->refname = pstrdup(refname);
1892
rec->lineno = lineno;
1894
rec->tupdesc = NULL;
1895
rec->freetup = false;
1896
plpgsql_adddatum((PLpgSQL_datum *) rec);
1898
plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->dno, rec->refname);
1904
* Build a row-variable data structure given the pg_class OID.
1906
static PLpgSQL_row *
1907
build_row_from_class(Oid classOid)
1911
Form_pg_class classStruct;
1912
const char *relname;
1916
* Open the relation to get info.
1918
rel = relation_open(classOid, AccessShareLock);
1919
classStruct = RelationGetForm(rel);
1920
relname = RelationGetRelationName(rel);
1922
/* accept relation, sequence, view, or composite type entries */
1923
if (classStruct->relkind != RELKIND_RELATION &&
1924
classStruct->relkind != RELKIND_SEQUENCE &&
1925
classStruct->relkind != RELKIND_VIEW &&
1926
classStruct->relkind != RELKIND_COMPOSITE_TYPE)
1928
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1929
errmsg("relation \"%s\" is not a table", relname)));
1932
* Create a row datum entry and all the required variables that it will
1935
row = palloc0(sizeof(PLpgSQL_row));
1936
row->dtype = PLPGSQL_DTYPE_ROW;
1937
row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
1938
row->nfields = classStruct->relnatts;
1939
row->fieldnames = palloc(sizeof(char *) * row->nfields);
1940
row->varnos = palloc(sizeof(int) * row->nfields);
1942
for (i = 0; i < row->nfields; i++)
1944
Form_pg_attribute attrStruct;
1947
* Get the attribute and check for dropped column
1949
attrStruct = row->rowtupdesc->attrs[i];
1951
if (!attrStruct->attisdropped)
1954
char refname[(NAMEDATALEN * 2) + 100];
1955
PLpgSQL_variable *var;
1957
attname = NameStr(attrStruct->attname);
1958
snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
1961
* Create the internal variable for the field
1963
* We know if the table definitions contain a default value or if
1964
* the field is declared in the table as NOT NULL. But it's
1965
* possible to create a table field as NOT NULL without a default
1966
* value and that would lead to problems later when initializing
1967
* the variables due to entering a block at execution time. Thus
1968
* we ignore this information for now.
1970
var = plpgsql_build_variable(refname, 0,
1971
plpgsql_build_datatype(attrStruct->atttypid,
1972
attrStruct->atttypmod,
1973
attrStruct->attcollation),
1976
/* Add the variable to the row */
1977
row->fieldnames[i] = attname;
1978
row->varnos[i] = var->dno;
1982
/* Leave a hole in the row structure for the dropped col */
1983
row->fieldnames[i] = NULL;
1984
row->varnos[i] = -1;
1988
relation_close(rel, AccessShareLock);
1994
* Build a row-variable data structure given the component variables.
1996
static PLpgSQL_row *
1997
build_row_from_vars(PLpgSQL_variable **vars, int numvars)
2002
row = palloc0(sizeof(PLpgSQL_row));
2003
row->dtype = PLPGSQL_DTYPE_ROW;
2004
row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
2005
row->nfields = numvars;
2006
row->fieldnames = palloc(numvars * sizeof(char *));
2007
row->varnos = palloc(numvars * sizeof(int));
2009
for (i = 0; i < numvars; i++)
2011
PLpgSQL_variable *var = vars[i];
2012
Oid typoid = RECORDOID;
2014
Oid typcoll = InvalidOid;
2018
case PLPGSQL_DTYPE_VAR:
2019
typoid = ((PLpgSQL_var *) var)->datatype->typoid;
2020
typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
2021
typcoll = ((PLpgSQL_var *) var)->datatype->collation;
2024
case PLPGSQL_DTYPE_REC:
2027
case PLPGSQL_DTYPE_ROW:
2028
if (((PLpgSQL_row *) var)->rowtupdesc)
2030
typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
2031
typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
2032
/* composite types have no collation */
2037
elog(ERROR, "unrecognized dtype: %d", var->dtype);
2040
row->fieldnames[i] = var->refname;
2041
row->varnos[i] = var->dno;
2043
TupleDescInitEntry(row->rowtupdesc, i + 1,
2047
TupleDescInitEntryCollation(row->rowtupdesc, i + 1, typcoll);
2054
* plpgsql_build_datatype
2055
* Build PLpgSQL_type struct given type OID, typmod, and collation.
2057
* If collation is not InvalidOid then it overrides the type's default
2058
* collation. But collation is ignored if the datatype is non-collatable.
2061
plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
2066
typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
2067
if (!HeapTupleIsValid(typeTup))
2068
elog(ERROR, "cache lookup failed for type %u", typeOid);
2070
typ = build_datatype(typeTup, typmod, collation);
2072
ReleaseSysCache(typeTup);
2078
* Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
2080
static PLpgSQL_type *
2081
build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
2083
Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2086
if (!typeStruct->typisdefined)
2088
(errcode(ERRCODE_UNDEFINED_OBJECT),
2089
errmsg("type \"%s\" is only a shell",
2090
NameStr(typeStruct->typname))));
2092
typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
2094
typ->typname = pstrdup(NameStr(typeStruct->typname));
2095
typ->typoid = HeapTupleGetOid(typeTup);
2096
switch (typeStruct->typtype)
2099
case TYPTYPE_DOMAIN:
2101
typ->ttype = PLPGSQL_TTYPE_SCALAR;
2103
case TYPTYPE_COMPOSITE:
2104
Assert(OidIsValid(typeStruct->typrelid));
2105
typ->ttype = PLPGSQL_TTYPE_ROW;
2107
case TYPTYPE_PSEUDO:
2108
if (typ->typoid == RECORDOID)
2109
typ->ttype = PLPGSQL_TTYPE_REC;
2111
typ->ttype = PLPGSQL_TTYPE_PSEUDO;
2114
elog(ERROR, "unrecognized typtype: %d",
2115
(int) typeStruct->typtype);
2118
typ->typlen = typeStruct->typlen;
2119
typ->typbyval = typeStruct->typbyval;
2120
typ->typrelid = typeStruct->typrelid;
2121
typ->typioparam = getTypeIOParam(typeTup);
2122
typ->collation = typeStruct->typcollation;
2123
if (OidIsValid(collation) && OidIsValid(typ->collation))
2124
typ->collation = collation;
2125
fmgr_info(typeStruct->typinput, &(typ->typinput));
2126
typ->atttypmod = typmod;
2132
* plpgsql_recognize_err_condition
2133
* Check condition name and translate it to SQLSTATE.
2135
* Note: there are some cases where the same condition name has multiple
2136
* entries in the table. We arbitrarily return the first match.
2139
plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
2145
if (strlen(condname) == 5 &&
2146
strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2147
return MAKE_SQLSTATE(condname[0],
2154
for (i = 0; exception_label_map[i].label != NULL; i++)
2156
if (strcmp(condname, exception_label_map[i].label) == 0)
2157
return exception_label_map[i].sqlerrstate;
2161
(errcode(ERRCODE_UNDEFINED_OBJECT),
2162
errmsg("unrecognized exception condition \"%s\"",
2164
return 0; /* keep compiler quiet */
2168
* plpgsql_parse_err_condition
2169
* Generate PLpgSQL_condition entry(s) for an exception condition name
2171
* This has to be able to return a list because there are some duplicate
2172
* names in the table of error code names.
2175
plpgsql_parse_err_condition(char *condname)
2178
PLpgSQL_condition *new;
2179
PLpgSQL_condition *prev;
2182
* XXX Eventually we will want to look for user-defined exception names
2187
* OTHERS is represented as code 0 (which would map to '00000', but we
2188
* have no need to represent that as an exception condition).
2190
if (strcmp(condname, "others") == 0)
2192
new = palloc(sizeof(PLpgSQL_condition));
2193
new->sqlerrstate = 0;
2194
new->condname = condname;
2200
for (i = 0; exception_label_map[i].label != NULL; i++)
2202
if (strcmp(condname, exception_label_map[i].label) == 0)
2204
new = palloc(sizeof(PLpgSQL_condition));
2205
new->sqlerrstate = exception_label_map[i].sqlerrstate;
2206
new->condname = condname;
2214
(errcode(ERRCODE_UNDEFINED_OBJECT),
2215
errmsg("unrecognized exception condition \"%s\"",
2222
* plpgsql_adddatum Add a variable, record or row
2223
* to the compiler's datum list.
2227
plpgsql_adddatum(PLpgSQL_datum *new)
2229
if (plpgsql_nDatums == datums_alloc)
2232
plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
2235
new->dno = plpgsql_nDatums;
2236
plpgsql_Datums[plpgsql_nDatums++] = new;
2241
* plpgsql_add_initdatums Make an array of the datum numbers of
2242
* all the simple VAR datums created since the last call
2245
* If varnos is NULL, we just forget any datum entries created since the
2248
* This is used around a DECLARE section to create a list of the VARs
2249
* that have to be initialized at block entry. Note that VARs can also
2250
* be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
2251
* the responsibility of special-purpose code to initialize them.
2255
plpgsql_add_initdatums(int **varnos)
2260
for (i = datums_last; i < plpgsql_nDatums; i++)
2262
switch (plpgsql_Datums[i]->dtype)
2264
case PLPGSQL_DTYPE_VAR:
2277
*varnos = (int *) palloc(sizeof(int) * n);
2280
for (i = datums_last; i < plpgsql_nDatums; i++)
2282
switch (plpgsql_Datums[i]->dtype)
2284
case PLPGSQL_DTYPE_VAR:
2285
(*varnos)[n++] = plpgsql_Datums[i]->dno;
2296
datums_last = plpgsql_nDatums;
2302
* Compute the hashkey for a given function invocation
2304
* The hashkey is returned into the caller-provided storage at *hashkey.
2307
compute_function_hashkey(FunctionCallInfo fcinfo,
2308
Form_pg_proc procStruct,
2309
PLpgSQL_func_hashkey *hashkey,
2312
/* Make sure any unused bytes of the struct are zero */
2313
MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
2315
/* get function OID */
2316
hashkey->funcOid = fcinfo->flinfo->fn_oid;
2318
/* get call context */
2319
hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
2322
* if trigger, get relation OID. In validation mode we do not know what
2323
* relation is intended to be used, so we leave trigrelOid zero; the hash
2324
* entry built in this case will never really be used.
2326
if (hashkey->isTrigger && !forValidator)
2328
TriggerData *trigdata = (TriggerData *) fcinfo->context;
2330
hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
2333
/* get input collation, if known */
2334
hashkey->inputCollation = fcinfo->fncollation;
2336
if (procStruct->pronargs > 0)
2338
/* get the argument types */
2339
memcpy(hashkey->argtypes, procStruct->proargtypes.values,
2340
procStruct->pronargs * sizeof(Oid));
2342
/* resolve any polymorphic argument types */
2343
plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
2346
fcinfo->flinfo->fn_expr,
2348
NameStr(procStruct->proname));
2353
* This is the same as the standard resolve_polymorphic_argtypes() function,
2354
* but with a special case for validation: assume that polymorphic arguments
2355
* are integer or integer-array. Also, we go ahead and report the error
2356
* if we can't resolve the types.
2359
plpgsql_resolve_polymorphic_argtypes(int numargs,
2360
Oid *argtypes, char *argmodes,
2361
Node *call_expr, bool forValidator,
2362
const char *proname)
2368
/* normal case, pass to standard routine */
2369
if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
2372
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2373
errmsg("could not determine actual argument "
2374
"type for polymorphic function \"%s\"",
2379
/* special validation case */
2380
for (i = 0; i < numargs; i++)
2382
switch (argtypes[i])
2385
case ANYNONARRAYOID:
2386
case ANYENUMOID: /* XXX dubious */
2387
argtypes[i] = INT4OID;
2390
argtypes[i] = INT4ARRAYOID;
2400
* delete_function - clean up as much as possible of a stale function cache
2402
* We can't release the PLpgSQL_function struct itself, because of the
2403
* possibility that there are fn_extra pointers to it. We can release
2404
* the subsidiary storage, but only if there are no active evaluations
2405
* in progress. Otherwise we'll just leak that storage. Since the
2406
* case would only occur if a pg_proc update is detected during a nested
2407
* recursive call on the function, a leak seems acceptable.
2409
* Note that this can be called more than once if there are multiple fn_extra
2410
* pointers to the same function cache. Hence be careful not to do things
2414
delete_function(PLpgSQL_function *func)
2416
/* remove function from hash table (might be done already) */
2417
plpgsql_HashTableDelete(func);
2419
/* release the function's storage if safe and not done already */
2420
if (func->use_count == 0)
2421
plpgsql_free_function_memory(func);
2424
/* exported so we can call it from plpgsql_init() */
2426
plpgsql_HashTableInit(void)
2430
/* don't allow double-initialization */
2431
Assert(plpgsql_HashTable == NULL);
2433
memset(&ctl, 0, sizeof(ctl));
2434
ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2435
ctl.entrysize = sizeof(plpgsql_HashEnt);
2436
ctl.hash = tag_hash;
2437
plpgsql_HashTable = hash_create("PLpgSQL function cache",
2440
HASH_ELEM | HASH_FUNCTION);
2443
static PLpgSQL_function *
2444
plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
2446
plpgsql_HashEnt *hentry;
2448
hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2453
return hentry->function;
2459
plpgsql_HashTableInsert(PLpgSQL_function *function,
2460
PLpgSQL_func_hashkey *func_key)
2462
plpgsql_HashEnt *hentry;
2465
hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2470
elog(WARNING, "trying to insert a function that already exists");
2472
hentry->function = function;
2473
/* prepare back link from function to hashtable key */
2474
function->fn_hashkey = &hentry->key;
2478
plpgsql_HashTableDelete(PLpgSQL_function *function)
2480
plpgsql_HashEnt *hentry;
2482
/* do nothing if not in table */
2483
if (function->fn_hashkey == NULL)
2486
hentry = (plpgsql_HashEnt *) hash_search(plpgsql_HashTable,
2487
(void *) function->fn_hashkey,
2491
elog(WARNING, "trying to delete function that does not exist");
2493
/* remove back link, which no longer points to allocated storage */
2494
function->fn_hashkey = NULL;