PostgreSQL Source Code git master
pl_comp.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "nodes/makefuncs.h"
#include "parser/parse_node.h"
#include "plpgsql.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/regproc.h"
#include "utils/syscache.h"
#include "utils/typcache.h"
#include "plerrcodes.h"
Include dependency graph for pl_comp.c:

Go to the source code of this file.

Data Structures

struct  plpgsql_hashent
 
struct  ExceptionLabelMap
 
struct  compile_error_callback_arg
 

Macros

#define FUNCS_PER_USER   128 /* initial table size */
 

Typedefs

typedef struct plpgsql_hashent plpgsql_HashEnt
 

Functions

static PLpgSQL_functiondo_compile (FunctionCallInfo fcinfo, HeapTuple procTup, PLpgSQL_function *function, PLpgSQL_func_hashkey *hashkey, bool forValidator)
 
static void plpgsql_compile_error_callback (void *arg)
 
static void add_parameter_name (PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
 
static void add_dummy_return (PLpgSQL_function *function)
 
static Nodeplpgsql_pre_column_ref (ParseState *pstate, ColumnRef *cref)
 
static Nodeplpgsql_post_column_ref (ParseState *pstate, ColumnRef *cref, Node *var)
 
static Nodeplpgsql_param_ref (ParseState *pstate, ParamRef *pref)
 
static Noderesolve_column_ref (ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
 
static Nodemake_datum_param (PLpgSQL_expr *expr, int dno, int location)
 
static PLpgSQL_rowbuild_row_from_vars (PLpgSQL_variable **vars, int numvars)
 
static PLpgSQL_typebuild_datatype (HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
 
static void plpgsql_start_datums (void)
 
static void plpgsql_finish_datums (PLpgSQL_function *function)
 
static void compute_function_hashkey (FunctionCallInfo fcinfo, Form_pg_proc procStruct, PLpgSQL_func_hashkey *hashkey, bool forValidator)
 
static void plpgsql_resolve_polymorphic_argtypes (int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
 
static PLpgSQL_functionplpgsql_HashTableLookup (PLpgSQL_func_hashkey *func_key)
 
static void plpgsql_HashTableInsert (PLpgSQL_function *function, PLpgSQL_func_hashkey *func_key)
 
static void plpgsql_HashTableDelete (PLpgSQL_function *function)
 
static void delete_function (PLpgSQL_function *func)
 
PLpgSQL_functionplpgsql_compile (FunctionCallInfo fcinfo, bool forValidator)
 
PLpgSQL_functionplpgsql_compile_inline (char *proc_source)
 
void plpgsql_parser_setup (struct ParseState *pstate, PLpgSQL_expr *expr)
 
bool plpgsql_parse_word (char *word1, const char *yytxt, bool lookup, PLwdatum *wdatum, PLword *word)
 
bool plpgsql_parse_dblword (char *word1, char *word2, PLwdatum *wdatum, PLcword *cword)
 
bool plpgsql_parse_tripword (char *word1, char *word2, char *word3, PLwdatum *wdatum, PLcword *cword)
 
PLpgSQL_typeplpgsql_parse_wordtype (char *ident)
 
PLpgSQL_typeplpgsql_parse_cwordtype (List *idents)
 
PLpgSQL_typeplpgsql_parse_wordrowtype (char *ident)
 
PLpgSQL_typeplpgsql_parse_cwordrowtype (List *idents)
 
PLpgSQL_variableplpgsql_build_variable (const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
 
PLpgSQL_recplpgsql_build_record (const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
 
PLpgSQL_recfieldplpgsql_build_recfield (PLpgSQL_rec *rec, const char *fldname)
 
PLpgSQL_typeplpgsql_build_datatype (Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
 
PLpgSQL_typeplpgsql_build_datatype_arrayof (PLpgSQL_type *dtype)
 
int plpgsql_recognize_err_condition (const char *condname, bool allow_sqlstate)
 
PLpgSQL_conditionplpgsql_parse_err_condition (char *condname)
 
void plpgsql_adddatum (PLpgSQL_datum *newdatum)
 
int plpgsql_add_initdatums (int **varnos)
 
void plpgsql_HashTableInit (void)
 

Variables

PLpgSQL_stmt_blockplpgsql_parse_result
 
static int datums_alloc
 
int plpgsql_nDatums
 
PLpgSQL_datum ** plpgsql_Datums
 
static int datums_last
 
char * plpgsql_error_funcname
 
bool plpgsql_DumpExecTree = false
 
bool plpgsql_check_syntax = false
 
PLpgSQL_functionplpgsql_curr_compile
 
MemoryContext plpgsql_compile_tmp_cxt
 
static HTABplpgsql_HashTable = NULL
 
static const ExceptionLabelMap exception_label_map []
 

Macro Definition Documentation

◆ FUNCS_PER_USER

#define FUNCS_PER_USER   128 /* initial table size */

Definition at line 69 of file pl_comp.c.

Typedef Documentation

◆ plpgsql_HashEnt

Function Documentation

◆ add_dummy_return()

static void add_dummy_return ( PLpgSQL_function function)
static

Definition at line 1044 of file pl_comp.c.

1045{
1046 /*
1047 * If the outer block has an EXCEPTION clause, we need to make a new outer
1048 * block, since the added RETURN shouldn't act like it is inside the
1049 * EXCEPTION clause. Likewise, if it has a label, wrap it in a new outer
1050 * block so that EXIT doesn't skip the RETURN.
1051 */
1052 if (function->action->exceptions != NULL ||
1053 function->action->label != NULL)
1054 {
1055 PLpgSQL_stmt_block *new;
1056
1057 new = palloc0(sizeof(PLpgSQL_stmt_block));
1058 new->cmd_type = PLPGSQL_STMT_BLOCK;
1059 new->stmtid = ++function->nstatements;
1060 new->body = list_make1(function->action);
1061
1062 function->action = new;
1063 }
1064 if (function->action->body == NIL ||
1065 ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
1066 {
1068
1069 new = palloc0(sizeof(PLpgSQL_stmt_return));
1070 new->cmd_type = PLPGSQL_STMT_RETURN;
1071 new->stmtid = ++function->nstatements;
1072 new->expr = NULL;
1073 new->retvarno = function->out_param_varno;
1074
1075 function->action->body = lappend(function->action->body, new);
1076 }
1077}
List * lappend(List *list, void *datum)
Definition: list.c:339
void * palloc0(Size size)
Definition: mcxt.c:1347
on_exit_nicely_callback function
#define llast(l)
Definition: pg_list.h:198
#define NIL
Definition: pg_list.h:68
#define list_make1(x1)
Definition: pg_list.h:212
@ PLPGSQL_STMT_RETURN
Definition: plpgsql.h:115
@ PLPGSQL_STMT_BLOCK
Definition: plpgsql.h:104

References function, lappend(), list_make1, llast, NIL, palloc0(), PLPGSQL_STMT_BLOCK, and PLPGSQL_STMT_RETURN.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ add_parameter_name()

static void add_parameter_name ( PLpgSQL_nsitem_type  itemtype,
int  itemno,
const char *  name 
)
static

Definition at line 1019 of file pl_comp.c.

1020{
1021 /*
1022 * Before adding the name, check for duplicates. We need this even though
1023 * functioncmds.c has a similar check, because that code explicitly
1024 * doesn't complain about conflicting IN and OUT parameter names. In
1025 * plpgsql, such names are in the same namespace, so there is no way to
1026 * disambiguate.
1027 */
1029 name, NULL, NULL,
1030 NULL) != NULL)
1031 ereport(ERROR,
1032 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1033 errmsg("parameter name \"%s\" used more than once",
1034 name)));
1035
1036 /* OK, add the name */
1037 plpgsql_ns_additem(itemtype, itemno, name);
1038}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:130
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
const char * name

References ereport, errcode(), errmsg(), ERROR, name, plpgsql_ns_additem(), plpgsql_ns_lookup(), and plpgsql_ns_top().

Referenced by do_compile().

◆ build_datatype()

static PLpgSQL_type * build_datatype ( HeapTuple  typeTup,
int32  typmod,
Oid  collation,
TypeName origtypname 
)
static

Definition at line 2078 of file pl_comp.c.

2080{
2081 Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2082 PLpgSQL_type *typ;
2083
2084 if (!typeStruct->typisdefined)
2085 ereport(ERROR,
2086 (errcode(ERRCODE_UNDEFINED_OBJECT),
2087 errmsg("type \"%s\" is only a shell",
2088 NameStr(typeStruct->typname))));
2089
2090 typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
2091
2092 typ->typname = pstrdup(NameStr(typeStruct->typname));
2093 typ->typoid = typeStruct->oid;
2094 switch (typeStruct->typtype)
2095 {
2096 case TYPTYPE_BASE:
2097 case TYPTYPE_ENUM:
2098 case TYPTYPE_RANGE:
2099 case TYPTYPE_MULTIRANGE:
2101 break;
2102 case TYPTYPE_COMPOSITE:
2103 typ->ttype = PLPGSQL_TTYPE_REC;
2104 break;
2105 case TYPTYPE_DOMAIN:
2106 if (type_is_rowtype(typeStruct->typbasetype))
2107 typ->ttype = PLPGSQL_TTYPE_REC;
2108 else
2110 break;
2111 case TYPTYPE_PSEUDO:
2112 if (typ->typoid == RECORDOID)
2113 typ->ttype = PLPGSQL_TTYPE_REC;
2114 else
2116 break;
2117 default:
2118 elog(ERROR, "unrecognized typtype: %d",
2119 (int) typeStruct->typtype);
2120 break;
2121 }
2122 typ->typlen = typeStruct->typlen;
2123 typ->typbyval = typeStruct->typbyval;
2124 typ->typtype = typeStruct->typtype;
2125 typ->collation = typeStruct->typcollation;
2126 if (OidIsValid(collation) && OidIsValid(typ->collation))
2127 typ->collation = collation;
2128 /* Detect if type is true array, or domain thereof */
2129 /* NB: this is only used to decide whether to apply expand_array */
2130 if (typeStruct->typtype == TYPTYPE_BASE)
2131 {
2132 /*
2133 * This test should include what get_element_type() checks. We also
2134 * disallow non-toastable array types (i.e. oidvector and int2vector).
2135 */
2136 typ->typisarray = (IsTrueArrayType(typeStruct) &&
2137 typeStruct->typstorage != TYPSTORAGE_PLAIN);
2138 }
2139 else if (typeStruct->typtype == TYPTYPE_DOMAIN)
2140 {
2141 /* we can short-circuit looking up base types if it's not varlena */
2142 typ->typisarray = (typeStruct->typlen == -1 &&
2143 typeStruct->typstorage != TYPSTORAGE_PLAIN &&
2144 OidIsValid(get_base_element_type(typeStruct->typbasetype)));
2145 }
2146 else
2147 typ->typisarray = false;
2148 typ->atttypmod = typmod;
2149
2150 /*
2151 * If it's a named composite type (or domain over one), find the typcache
2152 * entry and record the current tupdesc ID, so we can detect changes
2153 * (including drops). We don't currently support on-the-fly replacement
2154 * of non-composite types, else we might want to do this for them too.
2155 */
2156 if (typ->ttype == PLPGSQL_TTYPE_REC && typ->typoid != RECORDOID)
2157 {
2158 TypeCacheEntry *typentry;
2159
2160 typentry = lookup_type_cache(typ->typoid,
2163 if (typentry->typtype == TYPTYPE_DOMAIN)
2164 typentry = lookup_type_cache(typentry->domainBaseType,
2166 if (typentry->tupDesc == NULL)
2167 ereport(ERROR,
2168 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2169 errmsg("type %s is not composite",
2170 format_type_be(typ->typoid))));
2171
2172 typ->origtypname = origtypname;
2173 typ->tcache = typentry;
2174 typ->tupdesc_id = typentry->tupDesc_identifier;
2175 }
2176 else
2177 {
2178 typ->origtypname = NULL;
2179 typ->tcache = NULL;
2180 typ->tupdesc_id = 0;
2181 }
2182
2183 return typ;
2184}
#define NameStr(name)
Definition: c.h:703
#define OidIsValid(objectId)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:225
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2655
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2832
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void * palloc(Size size)
Definition: mcxt.c:1317
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
@ PLPGSQL_TTYPE_PSEUDO
Definition: plpgsql.h:96
@ PLPGSQL_TTYPE_REC
Definition: plpgsql.h:95
@ PLPGSQL_TTYPE_SCALAR
Definition: plpgsql.h:94
char typtype
Definition: plpgsql.h:205
TypeName * origtypname
Definition: plpgsql.h:210
bool typisarray
Definition: plpgsql.h:207
TypeCacheEntry * tcache
Definition: plpgsql.h:211
uint64 tupdesc_id
Definition: plpgsql.h:212
Oid collation
Definition: plpgsql.h:206
PLpgSQL_type_type ttype
Definition: plpgsql.h:202
Oid typoid
Definition: plpgsql.h:201
char * typname
Definition: plpgsql.h:200
int16 typlen
Definition: plpgsql.h:203
int32 atttypmod
Definition: plpgsql.h:208
bool typbyval
Definition: plpgsql.h:204
uint64 tupDesc_identifier
Definition: typcache.h:90
char typtype
Definition: typcache.h:43
TupleDesc tupDesc
Definition: typcache.h:89
Oid domainBaseType
Definition: typcache.h:114
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:386
#define TYPECACHE_TUPDESC
Definition: typcache.h:145
#define TYPECACHE_DOMAIN_BASE_INFO
Definition: typcache.h:149

References PLpgSQL_type::atttypmod, PLpgSQL_type::collation, TypeCacheEntry::domainBaseType, elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_base_element_type(), GETSTRUCT, lookup_type_cache(), NameStr, OidIsValid, PLpgSQL_type::origtypname, palloc(), PLPGSQL_TTYPE_PSEUDO, PLPGSQL_TTYPE_REC, PLPGSQL_TTYPE_SCALAR, pstrdup(), PLpgSQL_type::tcache, PLpgSQL_type::ttype, TypeCacheEntry::tupDesc, PLpgSQL_type::tupdesc_id, TypeCacheEntry::tupDesc_identifier, PLpgSQL_type::typbyval, type_is_rowtype(), TYPECACHE_DOMAIN_BASE_INFO, TYPECACHE_TUPDESC, PLpgSQL_type::typisarray, PLpgSQL_type::typlen, PLpgSQL_type::typname, PLpgSQL_type::typoid, TypeCacheEntry::typtype, and PLpgSQL_type::typtype.

Referenced by do_compile(), plpgsql_build_datatype(), and plpgsql_parse_cwordtype().

◆ build_row_from_vars()

static PLpgSQL_row * build_row_from_vars ( PLpgSQL_variable **  vars,
int  numvars 
)
static

Definition at line 1942 of file pl_comp.c.

1943{
1944 PLpgSQL_row *row;
1945 int i;
1946
1947 row = palloc0(sizeof(PLpgSQL_row));
1948 row->dtype = PLPGSQL_DTYPE_ROW;
1949 row->refname = "(unnamed row)";
1950 row->lineno = -1;
1951 row->rowtupdesc = CreateTemplateTupleDesc(numvars);
1952 row->nfields = numvars;
1953 row->fieldnames = palloc(numvars * sizeof(char *));
1954 row->varnos = palloc(numvars * sizeof(int));
1955
1956 for (i = 0; i < numvars; i++)
1957 {
1958 PLpgSQL_variable *var = vars[i];
1959 Oid typoid;
1960 int32 typmod;
1961 Oid typcoll;
1962
1963 /* Member vars of a row should never be const */
1964 Assert(!var->isconst);
1965
1966 switch (var->dtype)
1967 {
1968 case PLPGSQL_DTYPE_VAR:
1970 typoid = ((PLpgSQL_var *) var)->datatype->typoid;
1971 typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
1972 typcoll = ((PLpgSQL_var *) var)->datatype->collation;
1973 break;
1974
1975 case PLPGSQL_DTYPE_REC:
1976 /* shouldn't need to revalidate rectypeid already... */
1977 typoid = ((PLpgSQL_rec *) var)->rectypeid;
1978 typmod = -1; /* don't know typmod, if it's used at all */
1979 typcoll = InvalidOid; /* composite types have no collation */
1980 break;
1981
1982 default:
1983 elog(ERROR, "unrecognized dtype: %d", var->dtype);
1984 typoid = InvalidOid; /* keep compiler quiet */
1985 typmod = 0;
1986 typcoll = InvalidOid;
1987 break;
1988 }
1989
1990 row->fieldnames[i] = var->refname;
1991 row->varnos[i] = var->dno;
1992
1994 var->refname,
1995 typoid, typmod,
1996 0);
1997 TupleDescInitEntryCollation(row->rowtupdesc, i + 1, typcoll);
1998 }
1999
2000 return row;
2001}
#define Assert(condition)
Definition: c.h:815
int32_t int32
Definition: c.h:484
int i
Definition: isn.c:72
@ PLPGSQL_DTYPE_ROW
Definition: plpgsql.h:64
@ PLPGSQL_DTYPE_PROMISE
Definition: plpgsql.h:67
@ PLPGSQL_DTYPE_REC
Definition: plpgsql.h:65
@ PLPGSQL_DTYPE_VAR
Definition: plpgsql.h:63
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
TupleDesc rowtupdesc
Definition: plpgsql.h:379
int lineno
Definition: plpgsql.h:368
PLpgSQL_datum_type dtype
Definition: plpgsql.h:365
int * varnos
Definition: plpgsql.h:383
char * refname
Definition: plpgsql.h:367
char ** fieldnames
Definition: plpgsql.h:382
int nfields
Definition: plpgsql.h:381
PLpgSQL_datum_type dtype
Definition: plpgsql.h:289
char * refname
Definition: plpgsql.h:291
Definition: regcomp.c:282
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:164
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:982
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:798

References Assert, CreateTemplateTupleDesc(), PLpgSQL_variable::dno, PLpgSQL_variable::dtype, PLpgSQL_row::dtype, elog, ERROR, PLpgSQL_row::fieldnames, i, InvalidOid, PLpgSQL_variable::isconst, PLpgSQL_row::lineno, PLpgSQL_row::nfields, palloc(), palloc0(), PLPGSQL_DTYPE_PROMISE, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, PLpgSQL_variable::refname, PLpgSQL_row::refname, PLpgSQL_row::rowtupdesc, TupleDescInitEntry(), TupleDescInitEntryCollation(), and PLpgSQL_row::varnos.

Referenced by do_compile().

◆ compute_function_hashkey()

static void compute_function_hashkey ( FunctionCallInfo  fcinfo,
Form_pg_proc  procStruct,
PLpgSQL_func_hashkey hashkey,
bool  forValidator 
)
static

Definition at line 2444 of file pl_comp.c.

2448{
2449 /* Make sure any unused bytes of the struct are zero */
2450 MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
2451
2452 /* get function OID */
2453 hashkey->funcOid = fcinfo->flinfo->fn_oid;
2454
2455 /* get call context */
2456 hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
2457 hashkey->isEventTrigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
2458
2459 /*
2460 * If DML trigger, include trigger's OID in the hash, so that each trigger
2461 * usage gets a different hash entry, allowing for e.g. different relation
2462 * rowtypes or transition table names. In validation mode we do not know
2463 * what relation or transition table names are intended to be used, so we
2464 * leave trigOid zero; the hash entry built in this case will never be
2465 * used for any actual calls.
2466 *
2467 * We don't currently need to distinguish different event trigger usages
2468 * in the same way, since the special parameter variables don't vary in
2469 * type in that case.
2470 */
2471 if (hashkey->isTrigger && !forValidator)
2472 {
2473 TriggerData *trigdata = (TriggerData *) fcinfo->context;
2474
2475 hashkey->trigOid = trigdata->tg_trigger->tgoid;
2476 }
2477
2478 /* get input collation, if known */
2479 hashkey->inputCollation = fcinfo->fncollation;
2480
2481 if (procStruct->pronargs > 0)
2482 {
2483 /* get the argument types */
2484 memcpy(hashkey->argtypes, procStruct->proargtypes.values,
2485 procStruct->pronargs * sizeof(Oid));
2486
2487 /* resolve any polymorphic argument types */
2488 plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
2489 hashkey->argtypes,
2490 NULL,
2491 fcinfo->flinfo->fn_expr,
2492 forValidator,
2493 NameStr(procStruct->proname));
2494 }
2495}
#define MemSet(start, val, len)
Definition: c.h:977
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
Definition: event_trigger.h:49
static void plpgsql_resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
Definition: pl_comp.c:2510
fmNodePtr fn_expr
Definition: fmgr.h:66
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo * flinfo
Definition: fmgr.h:87
fmNodePtr context
Definition: fmgr.h:88
Oid argtypes[FUNC_MAX_ARGS]
Definition: plpgsql.h:950
Trigger * tg_trigger
Definition: trigger.h:38
Oid tgoid
Definition: reltrigger.h:25
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:26

References PLpgSQL_func_hashkey::argtypes, CALLED_AS_EVENT_TRIGGER, CALLED_AS_TRIGGER, FunctionCallInfoBaseData::context, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_expr, FmgrInfo::fn_oid, FunctionCallInfoBaseData::fncollation, PLpgSQL_func_hashkey::funcOid, PLpgSQL_func_hashkey::inputCollation, PLpgSQL_func_hashkey::isEventTrigger, PLpgSQL_func_hashkey::isTrigger, MemSet, NameStr, plpgsql_resolve_polymorphic_argtypes(), TriggerData::tg_trigger, Trigger::tgoid, and PLpgSQL_func_hashkey::trigOid.

Referenced by plpgsql_compile().

◆ delete_function()

static void delete_function ( PLpgSQL_function func)
static

Definition at line 2595 of file pl_comp.c.

2596{
2597 /* remove function from hash table (might be done already) */
2599
2600 /* release the function's storage if safe and not done already */
2601 if (func->use_count == 0)
2603}
static void plpgsql_HashTableDelete(PLpgSQL_function *function)
Definition: pl_comp.c:2657
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:727
unsigned long use_count
Definition: plpgsql.h:1015

References plpgsql_free_function_memory(), plpgsql_HashTableDelete(), and PLpgSQL_function::use_count.

Referenced by plpgsql_compile().

◆ do_compile()

static PLpgSQL_function * do_compile ( FunctionCallInfo  fcinfo,
HeapTuple  procTup,
PLpgSQL_function function,
PLpgSQL_func_hashkey hashkey,
bool  forValidator 
)
static

Definition at line 269 of file pl_comp.c.

274{
275 Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
276 bool is_dml_trigger = CALLED_AS_TRIGGER(fcinfo);
277 bool is_event_trigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
278 yyscan_t scanner;
279 Datum prosrcdatum;
280 char *proc_source;
281 HeapTuple typeTup;
282 Form_pg_type typeStruct;
283 PLpgSQL_variable *var;
284 PLpgSQL_rec *rec;
285 int i;
286 struct compile_error_callback_arg cbarg;
287 ErrorContextCallback plerrcontext;
288 int parse_rc;
289 Oid rettypeid;
290 int numargs;
291 int num_in_args = 0;
292 int num_out_args = 0;
293 Oid *argtypes;
294 char **argnames;
295 char *argmodes;
296 int *in_arg_varnos = NULL;
297 PLpgSQL_variable **out_arg_variables;
298 MemoryContext func_cxt;
299
300 /*
301 * Setup the scanner input and error info.
302 */
303 prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup, Anum_pg_proc_prosrc);
304 proc_source = TextDatumGetCString(prosrcdatum);
306
307 plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
308
309 /*
310 * Setup error traceback support for ereport()
311 */
312 cbarg.proc_source = forValidator ? proc_source : NULL;
313 cbarg.yyscanner = scanner;
314 plerrcontext.callback = plpgsql_compile_error_callback;
315 plerrcontext.arg = &cbarg;
316 plerrcontext.previous = error_context_stack;
317 error_context_stack = &plerrcontext;
318
319 /*
320 * Do extra syntax checks when validating the function definition. We skip
321 * this when actually compiling functions for execution, for performance
322 * reasons.
323 */
324 plpgsql_check_syntax = forValidator;
325
326 /*
327 * Create the new function struct, if not done already. The function
328 * structs are never thrown away, so keep them in TopMemoryContext.
329 */
330 if (function == NULL)
331 {
334 }
335 else
336 {
337 /* re-using a previously existing struct, so clear it out */
338 memset(function, 0, sizeof(PLpgSQL_function));
339 }
341
342 /*
343 * All the permanent output of compilation (e.g. parse tree) is kept in a
344 * per-function memory context, so it can be reclaimed easily.
345 */
347 "PL/pgSQL function",
350
351 function->fn_signature = format_procedure(fcinfo->flinfo->fn_oid);
352 MemoryContextSetIdentifier(func_cxt, function->fn_signature);
353 function->fn_oid = fcinfo->flinfo->fn_oid;
354 function->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
355 function->fn_tid = procTup->t_self;
356 function->fn_input_collation = fcinfo->fncollation;
357 function->fn_cxt = func_cxt;
358 function->out_param_varno = -1; /* set up for no OUT param */
359 function->resolve_option = plpgsql_variable_conflict;
360 function->print_strict_params = plpgsql_print_strict_params;
361 /* only promote extra warnings and errors at CREATE FUNCTION time */
362 function->extra_warnings = forValidator ? plpgsql_extra_warnings : 0;
363 function->extra_errors = forValidator ? plpgsql_extra_errors : 0;
364
365 if (is_dml_trigger)
366 function->fn_is_trigger = PLPGSQL_DML_TRIGGER;
367 else if (is_event_trigger)
368 function->fn_is_trigger = PLPGSQL_EVENT_TRIGGER;
369 else
370 function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
371
372 function->fn_prokind = procStruct->prokind;
373
374 function->nstatements = 0;
375 function->requires_procedure_resowner = false;
376
377 /*
378 * Initialize the compiler, particularly the namespace stack. The
379 * outermost namespace contains function parameters and other special
380 * variables (such as FOUND), and is named after the function itself.
381 */
383 plpgsql_ns_push(NameStr(procStruct->proname), PLPGSQL_LABEL_BLOCK);
384 plpgsql_DumpExecTree = false;
386
387 switch (function->fn_is_trigger)
388 {
390
391 /*
392 * Fetch info about the procedure's parameters. Allocations aren't
393 * needed permanently, so make them in tmp cxt.
394 *
395 * We also need to resolve any polymorphic input or output
396 * argument types. In validation mode we won't be able to, so we
397 * arbitrarily assume we are dealing with integers.
398 */
400
401 numargs = get_func_arg_info(procTup,
402 &argtypes, &argnames, &argmodes);
403
404 plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
405 fcinfo->flinfo->fn_expr,
406 forValidator,
408
409 in_arg_varnos = (int *) palloc(numargs * sizeof(int));
410 out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
411
412 MemoryContextSwitchTo(func_cxt);
413
414 /*
415 * Create the variables for the procedure's parameters.
416 */
417 for (i = 0; i < numargs; i++)
418 {
419 char buf[32];
420 Oid argtypeid = argtypes[i];
421 char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
422 PLpgSQL_type *argdtype;
423 PLpgSQL_variable *argvariable;
424 PLpgSQL_nsitem_type argitemtype;
425
426 /* Create $n name for variable */
427 snprintf(buf, sizeof(buf), "$%d", i + 1);
428
429 /* Create datatype info */
430 argdtype = plpgsql_build_datatype(argtypeid,
431 -1,
432 function->fn_input_collation,
433 NULL);
434
435 /* Disallow pseudotype argument */
436 /* (note we already replaced polymorphic types) */
437 /* (build_variable would do this, but wrong message) */
438 if (argdtype->ttype == PLPGSQL_TTYPE_PSEUDO)
440 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
441 errmsg("PL/pgSQL functions cannot accept type %s",
442 format_type_be(argtypeid))));
443
444 /*
445 * Build variable and add to datum list. If there's a name
446 * for the argument, use that as refname, else use $n name.
447 */
448 argvariable = plpgsql_build_variable((argnames &&
449 argnames[i][0] != '\0') ?
450 argnames[i] : buf,
451 0, argdtype, false);
452
453 if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
454 {
455 argitemtype = PLPGSQL_NSTYPE_VAR;
456 }
457 else
458 {
459 Assert(argvariable->dtype == PLPGSQL_DTYPE_REC);
460 argitemtype = PLPGSQL_NSTYPE_REC;
461 }
462
463 /* Remember arguments in appropriate arrays */
464 if (argmode == PROARGMODE_IN ||
465 argmode == PROARGMODE_INOUT ||
466 argmode == PROARGMODE_VARIADIC)
467 in_arg_varnos[num_in_args++] = argvariable->dno;
468 if (argmode == PROARGMODE_OUT ||
469 argmode == PROARGMODE_INOUT ||
470 argmode == PROARGMODE_TABLE)
471 out_arg_variables[num_out_args++] = argvariable;
472
473 /* Add to namespace under the $n name */
474 add_parameter_name(argitemtype, argvariable->dno, buf);
475
476 /* If there's a name for the argument, make an alias */
477 if (argnames && argnames[i][0] != '\0')
478 add_parameter_name(argitemtype, argvariable->dno,
479 argnames[i]);
480 }
481
482 /*
483 * If there's just one OUT parameter, out_param_varno points
484 * directly to it. If there's more than one, build a row that
485 * holds all of them. Procedures return a row even for one OUT
486 * parameter.
487 */
488 if (num_out_args > 1 ||
489 (num_out_args == 1 && function->fn_prokind == PROKIND_PROCEDURE))
490 {
491 PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
492 num_out_args);
493
495 function->out_param_varno = row->dno;
496 }
497 else if (num_out_args == 1)
498 function->out_param_varno = out_arg_variables[0]->dno;
499
500 /*
501 * Check for a polymorphic returntype. If found, use the actual
502 * returntype type from the caller's FuncExpr node, if we have
503 * one. (In validation mode we arbitrarily assume we are dealing
504 * with integers.)
505 *
506 * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
507 * work; if it doesn't we're in some context that fails to make
508 * the info available.
509 */
510 rettypeid = procStruct->prorettype;
511 if (IsPolymorphicType(rettypeid))
512 {
513 if (forValidator)
514 {
515 if (rettypeid == ANYARRAYOID ||
516 rettypeid == ANYCOMPATIBLEARRAYOID)
517 rettypeid = INT4ARRAYOID;
518 else if (rettypeid == ANYRANGEOID ||
519 rettypeid == ANYCOMPATIBLERANGEOID)
520 rettypeid = INT4RANGEOID;
521 else if (rettypeid == ANYMULTIRANGEOID)
522 rettypeid = INT4MULTIRANGEOID;
523 else /* ANYELEMENT or ANYNONARRAY or ANYCOMPATIBLE */
524 rettypeid = INT4OID;
525 /* XXX what could we use for ANYENUM? */
526 }
527 else
528 {
529 rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
530 if (!OidIsValid(rettypeid))
532 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
533 errmsg("could not determine actual return type "
534 "for polymorphic function \"%s\"",
536 }
537 }
538
539 /*
540 * Normal function has a defined returntype
541 */
542 function->fn_rettype = rettypeid;
543 function->fn_retset = procStruct->proretset;
544
545 /*
546 * Lookup the function's return type
547 */
548 typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettypeid));
549 if (!HeapTupleIsValid(typeTup))
550 elog(ERROR, "cache lookup failed for type %u", rettypeid);
551 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
552
553 /* Disallow pseudotype result, except VOID or RECORD */
554 /* (note we already replaced polymorphic types) */
555 if (typeStruct->typtype == TYPTYPE_PSEUDO)
556 {
557 if (rettypeid == VOIDOID ||
558 rettypeid == RECORDOID)
559 /* okay */ ;
560 else if (rettypeid == TRIGGEROID || rettypeid == EVENT_TRIGGEROID)
562 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
563 errmsg("trigger functions can only be called as triggers")));
564 else
566 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
567 errmsg("PL/pgSQL functions cannot return type %s",
568 format_type_be(rettypeid))));
569 }
570
571 function->fn_retistuple = type_is_rowtype(rettypeid);
572 function->fn_retisdomain = (typeStruct->typtype == TYPTYPE_DOMAIN);
573 function->fn_retbyval = typeStruct->typbyval;
574 function->fn_rettyplen = typeStruct->typlen;
575
576 /*
577 * install $0 reference, but only for polymorphic return types,
578 * and not when the return is specified through an output
579 * parameter.
580 */
581 if (IsPolymorphicType(procStruct->prorettype) &&
582 num_out_args == 0)
583 {
584 (void) plpgsql_build_variable("$0", 0,
585 build_datatype(typeTup,
586 -1,
587 function->fn_input_collation,
588 NULL),
589 true);
590 }
591
592 ReleaseSysCache(typeTup);
593 break;
594
596 /* Trigger procedure's return type is unknown yet */
597 function->fn_rettype = InvalidOid;
598 function->fn_retbyval = false;
599 function->fn_retistuple = true;
600 function->fn_retisdomain = false;
601 function->fn_retset = false;
602
603 /* shouldn't be any declared arguments */
604 if (procStruct->pronargs != 0)
606 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
607 errmsg("trigger functions cannot have declared arguments"),
608 errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
609
610 /* Add the record for referencing NEW ROW */
611 rec = plpgsql_build_record("new", 0, NULL, RECORDOID, true);
612 function->new_varno = rec->dno;
613
614 /* Add the record for referencing OLD ROW */
615 rec = plpgsql_build_record("old", 0, NULL, RECORDOID, true);
616 function->old_varno = rec->dno;
617
618 /* Add the variable tg_name */
619 var = plpgsql_build_variable("tg_name", 0,
621 -1,
622 function->fn_input_collation,
623 NULL),
624 true);
627 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_NAME;
628
629 /* Add the variable tg_when */
630 var = plpgsql_build_variable("tg_when", 0,
632 -1,
633 function->fn_input_collation,
634 NULL),
635 true);
638 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_WHEN;
639
640 /* Add the variable tg_level */
641 var = plpgsql_build_variable("tg_level", 0,
643 -1,
644 function->fn_input_collation,
645 NULL),
646 true);
649 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_LEVEL;
650
651 /* Add the variable tg_op */
652 var = plpgsql_build_variable("tg_op", 0,
654 -1,
655 function->fn_input_collation,
656 NULL),
657 true);
660 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_OP;
661
662 /* Add the variable tg_relid */
663 var = plpgsql_build_variable("tg_relid", 0,
665 -1,
667 NULL),
668 true);
671 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_RELID;
672
673 /* Add the variable tg_relname */
674 var = plpgsql_build_variable("tg_relname", 0,
676 -1,
677 function->fn_input_collation,
678 NULL),
679 true);
682 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_NAME;
683
684 /* tg_table_name is now preferred to tg_relname */
685 var = plpgsql_build_variable("tg_table_name", 0,
687 -1,
688 function->fn_input_collation,
689 NULL),
690 true);
693 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_NAME;
694
695 /* add the variable tg_table_schema */
696 var = plpgsql_build_variable("tg_table_schema", 0,
698 -1,
699 function->fn_input_collation,
700 NULL),
701 true);
704 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_SCHEMA;
705
706 /* Add the variable tg_nargs */
707 var = plpgsql_build_variable("tg_nargs", 0,
709 -1,
711 NULL),
712 true);
715 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_NARGS;
716
717 /* Add the variable tg_argv */
718 var = plpgsql_build_variable("tg_argv", 0,
719 plpgsql_build_datatype(TEXTARRAYOID,
720 -1,
721 function->fn_input_collation,
722 NULL),
723 true);
726 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_ARGV;
727
728 break;
729
731 function->fn_rettype = VOIDOID;
732 function->fn_retbyval = false;
733 function->fn_retistuple = true;
734 function->fn_retisdomain = false;
735 function->fn_retset = false;
736
737 /* shouldn't be any declared arguments */
738 if (procStruct->pronargs != 0)
740 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
741 errmsg("event trigger functions cannot have declared arguments")));
742
743 /* Add the variable tg_event */
744 var = plpgsql_build_variable("tg_event", 0,
746 -1,
747 function->fn_input_collation,
748 NULL),
749 true);
752 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_EVENT;
753
754 /* Add the variable tg_tag */
755 var = plpgsql_build_variable("tg_tag", 0,
757 -1,
758 function->fn_input_collation,
759 NULL),
760 true);
763 ((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TAG;
764
765 break;
766
767 default:
768 elog(ERROR, "unrecognized function typecode: %d",
769 (int) function->fn_is_trigger);
770 break;
771 }
772
773 /* Remember if function is STABLE/IMMUTABLE */
774 function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
775
776 /*
777 * Create the magic FOUND variable.
778 */
779 var = plpgsql_build_variable("found", 0,
781 -1,
783 NULL),
784 true);
785 function->found_varno = var->dno;
786
787 /*
788 * Now parse the function's text
789 */
790 parse_rc = plpgsql_yyparse(scanner);
791 if (parse_rc != 0)
792 elog(ERROR, "plpgsql parser returned %d", parse_rc);
794
795 plpgsql_scanner_finish(scanner);
797
798 /*
799 * If it has OUT parameters or returns VOID or returns a set, we allow
800 * control to fall off the end without an explicit RETURN statement. The
801 * easiest way to implement this is to add a RETURN statement to the end
802 * of the statement list during parsing.
803 */
804 if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
805 function->fn_retset)
807
808 /*
809 * Complete the function's info
810 */
811 function->fn_nargs = procStruct->pronargs;
812 for (i = 0; i < function->fn_nargs; i++)
813 function->fn_argvarnos[i] = in_arg_varnos[i];
814
816
817 /* Debug dump for completed functions */
820
821 /*
822 * add it to the hash table
823 */
825
826 /*
827 * Pop the error context stack
828 */
829 error_context_stack = plerrcontext.previous;
831
832 plpgsql_check_syntax = false;
833
836 return function;
837}
#define TextDatumGetCString(d)
Definition: builtins.h:98
void * yyscan_t
Definition: cubedata.h:67
ErrorContextCallback * error_context_stack
Definition: elog.c:94
int errhint(const char *fmt,...)
Definition: elog.c:1317
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1888
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:1379
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:304
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1215
void pfree(void *pointer)
Definition: mcxt.c:1521
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition: mcxt.c:612
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static char * buf
Definition: pg_test_fsync.c:72
static void add_dummy_return(PLpgSQL_function *function)
Definition: pl_comp.c:1044
static PLpgSQL_row * build_row_from_vars(PLpgSQL_variable **vars, int numvars)
Definition: pl_comp.c:1942
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:55
static void plpgsql_HashTableInsert(PLpgSQL_function *function, PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2638
static void plpgsql_compile_error_callback(void *arg)
Definition: pl_comp.c:989
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2308
char * plpgsql_error_funcname
Definition: pl_comp.c:48
PLpgSQL_stmt_block * plpgsql_parse_result
Definition: pl_comp.c:41
bool plpgsql_check_syntax
Definition: pl_comp.c:50
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2056
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2342
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:52
void plpgsql_adddatum(PLpgSQL_datum *newdatum)
Definition: pl_comp.c:2325
bool plpgsql_DumpExecTree
Definition: pl_comp.c:49
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
Definition: pl_comp.c:1915
static void add_parameter_name(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_comp.c:1019
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2078
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
Definition: pl_comp.c:1852
void plpgsql_ns_init(void)
Definition: pl_funcs.c:43
void plpgsql_dumptree(PLpgSQL_function *func)
Definition: pl_funcs.c:1600
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
Definition: pl_funcs.c:54
int plpgsql_variable_conflict
Definition: pl_handler.c:44
int plpgsql_extra_warnings
Definition: pl_handler.c:52
bool plpgsql_print_strict_params
Definition: pl_handler.c:46
int plpgsql_extra_errors
Definition: pl_handler.c:53
void plpgsql_scanner_finish(yyscan_t yyscanner)
Definition: pl_scanner.c:650
yyscan_t plpgsql_scanner_init(const char *str)
Definition: pl_scanner.c:618
@ PLPGSQL_DML_TRIGGER
Definition: plpgsql.h:958
@ PLPGSQL_NOT_TRIGGER
Definition: plpgsql.h:960
@ PLPGSQL_EVENT_TRIGGER
Definition: plpgsql.h:959
int plpgsql_yyparse(yyscan_t yyscanner)
@ PLPGSQL_PROMISE_TG_RELID
Definition: plpgsql.h:80
@ PLPGSQL_PROMISE_TG_WHEN
Definition: plpgsql.h:77
@ PLPGSQL_PROMISE_TG_ARGV
Definition: plpgsql.h:84
@ PLPGSQL_PROMISE_TG_TABLE_SCHEMA
Definition: plpgsql.h:82
@ PLPGSQL_PROMISE_TG_EVENT
Definition: plpgsql.h:85
@ PLPGSQL_PROMISE_TG_TABLE_NAME
Definition: plpgsql.h:81
@ PLPGSQL_PROMISE_TG_TAG
Definition: plpgsql.h:86
@ PLPGSQL_PROMISE_TG_OP
Definition: plpgsql.h:79
@ PLPGSQL_PROMISE_TG_LEVEL
Definition: plpgsql.h:78
@ PLPGSQL_PROMISE_TG_NARGS
Definition: plpgsql.h:83
@ PLPGSQL_PROMISE_TG_NAME
Definition: plpgsql.h:76
@ PLPGSQL_LABEL_BLOCK
Definition: plpgsql.h:53
PLpgSQL_nsitem_type
Definition: plpgsql.h:42
@ PLPGSQL_NSTYPE_VAR
Definition: plpgsql.h:44
@ PLPGSQL_NSTYPE_REC
Definition: plpgsql.h:45
#define snprintf
Definition: port.h:238
uintptr_t Datum
Definition: postgres.h:69
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:299
struct ErrorContextCallback * previous
Definition: elog.h:296
ItemPointerData t_self
Definition: htup.h:65
HeapTupleHeader t_data
Definition: htup.h:68
const char * proc_source
Definition: pl_comp.c:242
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:631

References add_dummy_return(), add_parameter_name(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, buf, build_datatype(), build_row_from_vars(), CALLED_AS_EVENT_TRIGGER, CALLED_AS_TRIGGER, PLpgSQL_variable::dno, PLpgSQL_row::dno, PLpgSQL_rec::dno, PLpgSQL_variable::dtype, elog, ereport, errcode(), errhint(), errmsg(), ERROR, error_context_stack, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_expr, FmgrInfo::fn_oid, FunctionCallInfoBaseData::fncollation, format_procedure(), format_type_be(), function, get_fn_expr_rettype(), get_func_arg_info(), GETSTRUCT, HeapTupleHeaderGetRawXmin, HeapTupleIsValid, i, InvalidOid, MemoryContextAllocZero(), MemoryContextSetIdentifier(), MemoryContextSwitchTo(), NameStr, ObjectIdGetDatum(), OidIsValid, palloc(), pfree(), plpgsql_adddatum(), plpgsql_build_datatype(), plpgsql_build_record(), plpgsql_build_variable(), plpgsql_check_syntax, plpgsql_compile_error_callback(), plpgsql_compile_tmp_cxt, plpgsql_curr_compile, PLPGSQL_DML_TRIGGER, PLPGSQL_DTYPE_PROMISE, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_VAR, plpgsql_DumpExecTree, plpgsql_dumptree(), plpgsql_error_funcname, PLPGSQL_EVENT_TRIGGER, plpgsql_extra_errors, plpgsql_extra_warnings, plpgsql_finish_datums(), plpgsql_HashTableInsert(), PLPGSQL_LABEL_BLOCK, PLPGSQL_NOT_TRIGGER, plpgsql_ns_init(), plpgsql_ns_push(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, plpgsql_parse_result, plpgsql_print_strict_params, PLPGSQL_PROMISE_TG_ARGV, PLPGSQL_PROMISE_TG_EVENT, PLPGSQL_PROMISE_TG_LEVEL, PLPGSQL_PROMISE_TG_NAME, PLPGSQL_PROMISE_TG_NARGS, PLPGSQL_PROMISE_TG_OP, PLPGSQL_PROMISE_TG_RELID, PLPGSQL_PROMISE_TG_TABLE_NAME, PLPGSQL_PROMISE_TG_TABLE_SCHEMA, PLPGSQL_PROMISE_TG_TAG, PLPGSQL_PROMISE_TG_WHEN, plpgsql_resolve_polymorphic_argtypes(), plpgsql_scanner_finish(), plpgsql_scanner_init(), plpgsql_start_datums(), PLPGSQL_TTYPE_PSEUDO, plpgsql_variable_conflict, plpgsql_yyparse(), ErrorContextCallback::previous, compile_error_callback_arg::proc_source, pstrdup(), ReleaseSysCache(), SearchSysCache1(), snprintf, SysCacheGetAttrNotNull(), HeapTupleData::t_data, HeapTupleData::t_self, TextDatumGetCString, TopMemoryContext, PLpgSQL_type::ttype, type_is_rowtype(), and compile_error_callback_arg::yyscanner.

Referenced by plpgsql_compile().

◆ make_datum_param()

static Node * make_datum_param ( PLpgSQL_expr expr,
int  dno,
int  location 
)
static

Definition at line 1345 of file pl_comp.c.

1346{
1347 PLpgSQL_execstate *estate;
1348 PLpgSQL_datum *datum;
1349 Param *param;
1350 MemoryContext oldcontext;
1351
1352 /* see comment in resolve_column_ref */
1353 estate = expr->func->cur_estate;
1354 Assert(dno >= 0 && dno < estate->ndatums);
1355 datum = estate->datums[dno];
1356
1357 /*
1358 * Bitmapset must be allocated in function's permanent memory context
1359 */
1360 oldcontext = MemoryContextSwitchTo(expr->func->fn_cxt);
1361 expr->paramnos = bms_add_member(expr->paramnos, dno);
1362 MemoryContextSwitchTo(oldcontext);
1363
1364 param = makeNode(Param);
1365 param->paramkind = PARAM_EXTERN;
1366 param->paramid = dno + 1;
1368 datum,
1369 &param->paramtype,
1370 &param->paramtypmod,
1371 &param->paramcollid);
1372 param->location = location;
1373
1374 return (Node *) param;
1375}
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
#define makeNode(_type_)
Definition: nodes.h:155
void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeId, int32 *typMod, Oid *collation)
Definition: pl_exec.c:5542
@ PARAM_EXTERN
Definition: primnodes.h:383
Definition: nodes.h:129
PLpgSQL_datum ** datums
Definition: plpgsql.h:1058
struct PLpgSQL_function * func
Definition: plpgsql.h:226
Bitmapset * paramnos
Definition: plpgsql.h:223
MemoryContext fn_cxt
Definition: plpgsql.h:975
struct PLpgSQL_execstate * cur_estate
Definition: plpgsql.h:1014
ParseLoc location
Definition: primnodes.h:400
int paramid
Definition: primnodes.h:393
Oid paramtype
Definition: primnodes.h:394
ParamKind paramkind
Definition: primnodes.h:392

References Assert, bms_add_member(), PLpgSQL_function::cur_estate, PLpgSQL_execstate::datums, PLpgSQL_function::fn_cxt, PLpgSQL_expr::func, Param::location, makeNode, MemoryContextSwitchTo(), PARAM_EXTERN, Param::paramid, Param::paramkind, PLpgSQL_expr::paramnos, Param::paramtype, and plpgsql_exec_get_datum_type_info().

Referenced by plpgsql_param_ref(), and resolve_column_ref().

◆ plpgsql_add_initdatums()

int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2386 of file pl_comp.c.

2387{
2388 int i;
2389 int n = 0;
2390
2391 /*
2392 * The set of dtypes recognized here must match what exec_stmt_block()
2393 * cares about (re)initializing at block entry.
2394 */
2395 for (i = datums_last; i < plpgsql_nDatums; i++)
2396 {
2397 switch (plpgsql_Datums[i]->dtype)
2398 {
2399 case PLPGSQL_DTYPE_VAR:
2400 case PLPGSQL_DTYPE_REC:
2401 n++;
2402 break;
2403
2404 default:
2405 break;
2406 }
2407 }
2408
2409 if (varnos != NULL)
2410 {
2411 if (n > 0)
2412 {
2413 *varnos = (int *) palloc(sizeof(int) * n);
2414
2415 n = 0;
2416 for (i = datums_last; i < plpgsql_nDatums; i++)
2417 {
2418 switch (plpgsql_Datums[i]->dtype)
2419 {
2420 case PLPGSQL_DTYPE_VAR:
2421 case PLPGSQL_DTYPE_REC:
2422 (*varnos)[n++] = plpgsql_Datums[i]->dno;
2423
2424 default:
2425 break;
2426 }
2427 }
2428 }
2429 else
2430 *varnos = NULL;
2431 }
2432
2434 return n;
2435}
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
static int datums_last
Definition: pl_comp.c:46
int plpgsql_nDatums
Definition: pl_comp.c:44

References datums_last, PLpgSQL_datum::dno, i, palloc(), plpgsql_Datums, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_VAR, and plpgsql_nDatums.

◆ plpgsql_adddatum()

void plpgsql_adddatum ( PLpgSQL_datum newdatum)

Definition at line 2325 of file pl_comp.c.

2326{
2328 {
2329 datums_alloc *= 2;
2331 }
2332
2333 newdatum->dno = plpgsql_nDatums;
2334 plpgsql_Datums[plpgsql_nDatums++] = newdatum;
2335}
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
static int datums_alloc
Definition: pl_comp.c:43

References datums_alloc, PLpgSQL_datum::dno, plpgsql_Datums, plpgsql_nDatums, and repalloc().

Referenced by do_compile(), plpgsql_build_recfield(), plpgsql_build_record(), and plpgsql_build_variable().

◆ plpgsql_build_datatype()

PLpgSQL_type * plpgsql_build_datatype ( Oid  typeOid,
int32  typmod,
Oid  collation,
TypeName origtypname 
)

Definition at line 2056 of file pl_comp.c.

2058{
2059 HeapTuple typeTup;
2060 PLpgSQL_type *typ;
2061
2062 typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
2063 if (!HeapTupleIsValid(typeTup))
2064 elog(ERROR, "cache lookup failed for type %u", typeOid);
2065
2066 typ = build_datatype(typeTup, typmod, collation, origtypname);
2067
2068 ReleaseSysCache(typeTup);
2069
2070 return typ;
2071}

References build_datatype(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), and SearchSysCache1().

Referenced by do_compile(), exec_stmt_case(), plpgsql_build_datatype_arrayof(), plpgsql_compile_inline(), plpgsql_parse_cwordrowtype(), and plpgsql_parse_wordrowtype().

◆ plpgsql_build_datatype_arrayof()

PLpgSQL_type * plpgsql_build_datatype_arrayof ( PLpgSQL_type dtype)

Definition at line 2190 of file pl_comp.c.

2191{
2192 Oid array_typeid;
2193
2194 /*
2195 * If it's already an array type, use it as-is: Postgres doesn't do nested
2196 * arrays.
2197 */
2198 if (dtype->typisarray)
2199 return dtype;
2200
2201 array_typeid = get_array_type(dtype->typoid);
2202 if (!OidIsValid(array_typeid))
2203 ereport(ERROR,
2204 (errcode(ERRCODE_UNDEFINED_OBJECT),
2205 errmsg("could not find array type for data type %s",
2206 format_type_be(dtype->typoid))));
2207
2208 /* Note we inherit typmod and collation, if any, from the element type */
2209 return plpgsql_build_datatype(array_typeid, dtype->atttypmod,
2210 dtype->collation, NULL);
2211}
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2787

References PLpgSQL_type::atttypmod, PLpgSQL_type::collation, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_array_type(), OidIsValid, plpgsql_build_datatype(), PLpgSQL_type::typisarray, and PLpgSQL_type::typoid.

◆ plpgsql_build_recfield()

PLpgSQL_recfield * plpgsql_build_recfield ( PLpgSQL_rec rec,
const char *  fldname 
)

Definition at line 2009 of file pl_comp.c.

2010{
2011 PLpgSQL_recfield *recfield;
2012 int i;
2013
2014 /* search for an existing datum referencing this field */
2015 i = rec->firstfield;
2016 while (i >= 0)
2017 {
2019
2021 fld->recparentno == rec->dno);
2022 if (strcmp(fld->fieldname, fldname) == 0)
2023 return fld;
2024 i = fld->nextfield;
2025 }
2026
2027 /* nope, so make a new one */
2028 recfield = palloc0(sizeof(PLpgSQL_recfield));
2029 recfield->dtype = PLPGSQL_DTYPE_RECFIELD;
2030 recfield->fieldname = pstrdup(fldname);
2031 recfield->recparentno = rec->dno;
2033
2034 plpgsql_adddatum((PLpgSQL_datum *) recfield);
2035
2036 /* now we can link it into the parent's chain */
2037 recfield->nextfield = rec->firstfield;
2038 rec->firstfield = recfield->dno;
2039
2040 return recfield;
2041}
@ PLPGSQL_DTYPE_RECFIELD
Definition: plpgsql.h:66
int firstfield
Definition: plpgsql.h:409
uint64 rectupledescid
Definition: plpgsql.h:429
PLpgSQL_datum_type dtype
Definition: plpgsql.h:422
char * fieldname
Definition: plpgsql.h:426
#define INVALID_TUPLEDESC_IDENTIFIER
Definition: typcache.h:156

References Assert, PLpgSQL_rec::dno, PLpgSQL_recfield::dno, PLpgSQL_recfield::dtype, PLpgSQL_recfield::fieldname, PLpgSQL_rec::firstfield, i, INVALID_TUPLEDESC_IDENTIFIER, PLpgSQL_recfield::nextfield, palloc0(), plpgsql_adddatum(), plpgsql_Datums, PLPGSQL_DTYPE_RECFIELD, pstrdup(), PLpgSQL_recfield::recparentno, and PLpgSQL_recfield::rectupledescid.

Referenced by plpgsql_parse_dblword(), and plpgsql_parse_tripword().

◆ plpgsql_build_record()

PLpgSQL_rec * plpgsql_build_record ( const char *  refname,
int  lineno,
PLpgSQL_type dtype,
Oid  rectypeid,
bool  add2namespace 
)

Definition at line 1915 of file pl_comp.c.

1918{
1919 PLpgSQL_rec *rec;
1920
1921 rec = palloc0(sizeof(PLpgSQL_rec));
1922 rec->dtype = PLPGSQL_DTYPE_REC;
1923 rec->refname = pstrdup(refname);
1924 rec->lineno = lineno;
1925 /* other fields are left as 0, might be changed by caller */
1926 rec->datatype = dtype;
1927 rec->rectypeid = rectypeid;
1928 rec->firstfield = -1;
1929 rec->erh = NULL;
1931 if (add2namespace)
1933
1934 return rec;
1935}
ExpandedRecordHeader * erh
Definition: plpgsql.h:414
PLpgSQL_type * datatype
Definition: plpgsql.h:406
PLpgSQL_datum_type dtype
Definition: plpgsql.h:391
Oid rectypeid
Definition: plpgsql.h:407
int lineno
Definition: plpgsql.h:394
char * refname
Definition: plpgsql.h:393

References PLpgSQL_rec::datatype, PLpgSQL_rec::dno, PLpgSQL_rec::dtype, PLpgSQL_rec::erh, PLpgSQL_rec::firstfield, PLpgSQL_rec::lineno, palloc0(), plpgsql_adddatum(), PLPGSQL_DTYPE_REC, plpgsql_ns_additem(), PLPGSQL_NSTYPE_REC, pstrdup(), PLpgSQL_rec::rectypeid, and PLpgSQL_rec::refname.

Referenced by do_compile(), and plpgsql_build_variable().

◆ plpgsql_build_variable()

PLpgSQL_variable * plpgsql_build_variable ( const char *  refname,
int  lineno,
PLpgSQL_type dtype,
bool  add2namespace 
)

Definition at line 1852 of file pl_comp.c.

1854{
1855 PLpgSQL_variable *result;
1856
1857 switch (dtype->ttype)
1858 {
1860 {
1861 /* Ordinary scalar datatype */
1862 PLpgSQL_var *var;
1863
1864 var = palloc0(sizeof(PLpgSQL_var));
1865 var->dtype = PLPGSQL_DTYPE_VAR;
1866 var->refname = pstrdup(refname);
1867 var->lineno = lineno;
1868 var->datatype = dtype;
1869 /* other fields are left as 0, might be changed by caller */
1870
1871 /* preset to NULL */
1872 var->value = 0;
1873 var->isnull = true;
1874 var->freeval = false;
1875
1877 if (add2namespace)
1879 var->dno,
1880 refname);
1881 result = (PLpgSQL_variable *) var;
1882 break;
1883 }
1884 case PLPGSQL_TTYPE_REC:
1885 {
1886 /* Composite type -- build a record variable */
1887 PLpgSQL_rec *rec;
1888
1889 rec = plpgsql_build_record(refname, lineno,
1890 dtype, dtype->typoid,
1891 add2namespace);
1892 result = (PLpgSQL_variable *) rec;
1893 break;
1894 }
1896 ereport(ERROR,
1897 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1898 errmsg("variable \"%s\" has pseudo-type %s",
1899 refname, format_type_be(dtype->typoid))));
1900 result = NULL; /* keep compiler quiet */
1901 break;
1902 default:
1903 elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1904 result = NULL; /* keep compiler quiet */
1905 break;
1906 }
1907
1908 return result;
1909}
int lineno
Definition: plpgsql.h:314
PLpgSQL_datum_type dtype
Definition: plpgsql.h:311
bool freeval
Definition: plpgsql.h:335
bool isnull
Definition: plpgsql.h:334
PLpgSQL_type * datatype
Definition: plpgsql.h:320
char * refname
Definition: plpgsql.h:313
Datum value
Definition: plpgsql.h:333

References PLpgSQL_var::datatype, PLpgSQL_var::dno, PLpgSQL_var::dtype, elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), PLpgSQL_var::freeval, PLpgSQL_var::isnull, PLpgSQL_var::lineno, palloc0(), plpgsql_adddatum(), plpgsql_build_record(), PLPGSQL_DTYPE_VAR, plpgsql_ns_additem(), PLPGSQL_NSTYPE_VAR, PLPGSQL_TTYPE_PSEUDO, PLPGSQL_TTYPE_REC, PLPGSQL_TTYPE_SCALAR, pstrdup(), PLpgSQL_var::refname, PLpgSQL_type::ttype, PLpgSQL_type::typoid, and PLpgSQL_var::value.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ plpgsql_compile()

PLpgSQL_function * plpgsql_compile ( FunctionCallInfo  fcinfo,
bool  forValidator 
)

Definition at line 135 of file pl_comp.c.

136{
137 Oid funcOid = fcinfo->flinfo->fn_oid;
138 HeapTuple procTup;
139 Form_pg_proc procStruct;
141 PLpgSQL_func_hashkey hashkey;
142 bool function_valid = false;
143 bool hashkey_valid = false;
144
145 /*
146 * Lookup the pg_proc tuple by Oid; we'll need it in any case
147 */
148 procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
149 if (!HeapTupleIsValid(procTup))
150 elog(ERROR, "cache lookup failed for function %u", funcOid);
151 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
152
153 /*
154 * See if there's already a cache entry for the current FmgrInfo. If not,
155 * try to find one in the hash table.
156 */
158
159recheck:
160 if (!function)
161 {
162 /* Compute hashkey using function signature and actual arg types */
163 compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
164 hashkey_valid = true;
165
166 /* And do the lookup */
168 }
169
170 if (function)
171 {
172 /* We have a compiled function, but is it still valid? */
173 if (function->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
174 ItemPointerEquals(&function->fn_tid, &procTup->t_self))
175 function_valid = true;
176 else
177 {
178 /*
179 * Nope, so remove it from hashtable and try to drop associated
180 * storage (if not done already).
181 */
183
184 /*
185 * If the function isn't in active use then we can overwrite the
186 * func struct with new data, allowing any other existing fn_extra
187 * pointers to make use of the new definition on their next use.
188 * If it is in use then just leave it alone and make a new one.
189 * (The active invocations will run to completion using the
190 * previous definition, and then the cache entry will just be
191 * leaked; doesn't seem worth adding code to clean it up, given
192 * what a corner case this is.)
193 *
194 * If we found the function struct via fn_extra then it's possible
195 * a replacement has already been made, so go back and recheck the
196 * hashtable.
197 */
198 if (function->use_count != 0)
199 {
200 function = NULL;
201 if (!hashkey_valid)
202 goto recheck;
203 }
204 }
205 }
206
207 /*
208 * If the function wasn't found or was out-of-date, we have to compile it
209 */
210 if (!function_valid)
211 {
212 /*
213 * Calculate hashkey if we didn't already; we'll need it to store the
214 * completed function.
215 */
216 if (!hashkey_valid)
217 compute_function_hashkey(fcinfo, procStruct, &hashkey,
218 forValidator);
219
220 /*
221 * Do the hard part.
222 */
223 function = do_compile(fcinfo, procTup, function,
224 &hashkey, forValidator);
225 }
226
227 ReleaseSysCache(procTup);
228
229 /*
230 * Save pointer in FmgrInfo to avoid search on subsequent calls
231 */
232 fcinfo->flinfo->fn_extra = function;
233
234 /*
235 * Finally return the compiled function
236 */
237 return function;
238}
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:35
static void compute_function_hashkey(FunctionCallInfo fcinfo, Form_pg_proc procStruct, PLpgSQL_func_hashkey *hashkey, bool forValidator)
Definition: pl_comp.c:2444
static PLpgSQL_function * plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2623
static PLpgSQL_function * do_compile(FunctionCallInfo fcinfo, HeapTuple procTup, PLpgSQL_function *function, PLpgSQL_func_hashkey *hashkey, bool forValidator)
Definition: pl_comp.c:269
static void delete_function(PLpgSQL_function *func)
Definition: pl_comp.c:2595
void * fn_extra
Definition: fmgr.h:64

References compute_function_hashkey(), delete_function(), do_compile(), elog, ERROR, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, FmgrInfo::fn_oid, function, GETSTRUCT, HeapTupleHeaderGetRawXmin, HeapTupleIsValid, if(), ItemPointerEquals(), ObjectIdGetDatum(), plpgsql_HashTableLookup(), ReleaseSysCache(), SearchSysCache1(), HeapTupleData::t_data, and HeapTupleData::t_self.

Referenced by plpgsql_call_handler(), and plpgsql_validator().

◆ plpgsql_compile_error_callback()

static void plpgsql_compile_error_callback ( void *  arg)
static

Definition at line 989 of file pl_comp.c.

990{
993
994 if (cbarg->proc_source)
995 {
996 /*
997 * Try to convert syntax error position to reference text of original
998 * CREATE FUNCTION or DO command.
999 */
1001 return;
1002
1003 /*
1004 * Done if a syntax error position was reported; otherwise we have to
1005 * fall back to a "near line N" report.
1006 */
1007 }
1008
1010 errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
1012}
#define errcontext
Definition: elog.h:196
void * arg
bool function_parse_error_transpose(const char *prosrc)
Definition: pg_proc.c:1002
int plpgsql_latest_lineno(yyscan_t yyscanner)
Definition: pl_scanner.c:604

References arg, errcontext, function_parse_error_transpose(), plpgsql_error_funcname, plpgsql_latest_lineno(), compile_error_callback_arg::proc_source, and compile_error_callback_arg::yyscanner.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ plpgsql_compile_inline()

PLpgSQL_function * plpgsql_compile_inline ( char *  proc_source)

Definition at line 850 of file pl_comp.c.

851{
852 yyscan_t scanner;
853 char *func_name = "inline_code_block";
855 struct compile_error_callback_arg cbarg;
856 ErrorContextCallback plerrcontext;
857 PLpgSQL_variable *var;
858 int parse_rc;
859 MemoryContext func_cxt;
860
861 /*
862 * Setup the scanner input and error info.
863 */
865
866 plpgsql_error_funcname = func_name;
867
868 /*
869 * Setup error traceback support for ereport()
870 */
871 cbarg.proc_source = proc_source;
872 cbarg.yyscanner = scanner;
873 plerrcontext.callback = plpgsql_compile_error_callback;
874 plerrcontext.arg = &cbarg;
875 plerrcontext.previous = error_context_stack;
876 error_context_stack = &plerrcontext;
877
878 /* Do extra syntax checking if check_function_bodies is on */
880
881 /* Function struct does not live past current statement */
883
885
886 /*
887 * All the rest of the compile-time storage (e.g. parse tree) is kept in
888 * its own memory context, so it can be reclaimed easily.
889 */
891 "PL/pgSQL inline code context",
894
895 function->fn_signature = pstrdup(func_name);
896 function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
897 function->fn_input_collation = InvalidOid;
898 function->fn_cxt = func_cxt;
899 function->out_param_varno = -1; /* set up for no OUT param */
900 function->resolve_option = plpgsql_variable_conflict;
901 function->print_strict_params = plpgsql_print_strict_params;
902
903 /*
904 * don't do extra validation for inline code as we don't want to add spam
905 * at runtime
906 */
907 function->extra_warnings = 0;
908 function->extra_errors = 0;
909
910 function->nstatements = 0;
911 function->requires_procedure_resowner = false;
912
915 plpgsql_DumpExecTree = false;
917
918 /* Set up as though in a function returning VOID */
919 function->fn_rettype = VOIDOID;
920 function->fn_retset = false;
921 function->fn_retistuple = false;
922 function->fn_retisdomain = false;
923 function->fn_prokind = PROKIND_FUNCTION;
924 /* a bit of hardwired knowledge about type VOID here */
925 function->fn_retbyval = true;
926 function->fn_rettyplen = sizeof(int32);
927
928 /*
929 * Remember if function is STABLE/IMMUTABLE. XXX would it be better to
930 * set this true inside a read-only transaction? Not clear.
931 */
932 function->fn_readonly = false;
933
934 /*
935 * Create the magic FOUND variable.
936 */
937 var = plpgsql_build_variable("found", 0,
939 -1,
941 NULL),
942 true);
943 function->found_varno = var->dno;
944
945 /*
946 * Now parse the function's text
947 */
948 parse_rc = plpgsql_yyparse(scanner);
949 if (parse_rc != 0)
950 elog(ERROR, "plpgsql parser returned %d", parse_rc);
952
953 plpgsql_scanner_finish(scanner);
954
955 /*
956 * If it returns VOID (always true at the moment), we allow control to
957 * fall off the end without an explicit RETURN statement.
958 */
959 if (function->fn_rettype == VOIDOID)
961
962 /*
963 * Complete the function's info
964 */
965 function->fn_nargs = 0;
966
968
969 /*
970 * Pop the error context stack
971 */
972 error_context_stack = plerrcontext.previous;
974
975 plpgsql_check_syntax = false;
976
979 return function;
980}
bool check_function_bodies
Definition: guc_tables.c:511
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143

References add_dummy_return(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, check_function_bodies, CurrentMemoryContext, PLpgSQL_variable::dno, elog, ERROR, error_context_stack, function, InvalidOid, MemoryContextSwitchTo(), palloc0(), plpgsql_build_datatype(), plpgsql_build_variable(), plpgsql_check_syntax, plpgsql_compile_error_callback(), plpgsql_compile_tmp_cxt, plpgsql_curr_compile, plpgsql_DumpExecTree, plpgsql_error_funcname, plpgsql_finish_datums(), PLPGSQL_LABEL_BLOCK, PLPGSQL_NOT_TRIGGER, plpgsql_ns_init(), plpgsql_ns_push(), plpgsql_parse_result, plpgsql_print_strict_params, plpgsql_scanner_finish(), plpgsql_scanner_init(), plpgsql_start_datums(), plpgsql_variable_conflict, plpgsql_yyparse(), ErrorContextCallback::previous, compile_error_callback_arg::proc_source, pstrdup(), and compile_error_callback_arg::yyscanner.

Referenced by plpgsql_inline_handler().

◆ plpgsql_finish_datums()

static void plpgsql_finish_datums ( PLpgSQL_function function)
static

Definition at line 2342 of file pl_comp.c.

2343{
2344 Size copiable_size = 0;
2345 int i;
2346
2347 function->ndatums = plpgsql_nDatums;
2348 function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
2349 for (i = 0; i < plpgsql_nDatums; i++)
2350 {
2351 function->datums[i] = plpgsql_Datums[i];
2352
2353 /* This must agree with copy_plpgsql_datums on what is copiable */
2354 switch (function->datums[i]->dtype)
2355 {
2356 case PLPGSQL_DTYPE_VAR:
2358 copiable_size += MAXALIGN(sizeof(PLpgSQL_var));
2359 break;
2360 case PLPGSQL_DTYPE_REC:
2361 copiable_size += MAXALIGN(sizeof(PLpgSQL_rec));
2362 break;
2363 default:
2364 break;
2365 }
2366 }
2367 function->copiable_size = copiable_size;
2368}
#define MAXALIGN(LEN)
Definition: c.h:768
size_t Size
Definition: c.h:562

References function, i, MAXALIGN, palloc(), plpgsql_Datums, PLPGSQL_DTYPE_PROMISE, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_VAR, and plpgsql_nDatums.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ plpgsql_HashTableDelete()

static void plpgsql_HashTableDelete ( PLpgSQL_function function)
static

Definition at line 2657 of file pl_comp.c.

2658{
2659 plpgsql_HashEnt *hentry;
2660
2661 /* do nothing if not in table */
2662 if (function->fn_hashkey == NULL)
2663 return;
2664
2666 function->fn_hashkey,
2668 NULL);
2669 if (hentry == NULL)
2670 elog(WARNING, "trying to delete function that does not exist");
2671
2672 /* remove back link, which no longer points to allocated storage */
2673 function->fn_hashkey = NULL;
2674}
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
#define WARNING
Definition: elog.h:36
@ HASH_REMOVE
Definition: hsearch.h:115
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:61

References elog, function, HASH_REMOVE, hash_search(), plpgsql_HashTable, and WARNING.

Referenced by delete_function().

◆ plpgsql_HashTableInit()

void plpgsql_HashTableInit ( void  )

Definition at line 2607 of file pl_comp.c.

2608{
2609 HASHCTL ctl;
2610
2611 /* don't allow double-initialization */
2612 Assert(plpgsql_HashTable == NULL);
2613
2614 ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2615 ctl.entrysize = sizeof(plpgsql_HashEnt);
2616 plpgsql_HashTable = hash_create("PLpgSQL function hash",
2618 &ctl,
2620}
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
#define FUNCS_PER_USER
Definition: pl_comp.c:69
struct plpgsql_hashent plpgsql_HashEnt
struct PLpgSQL_func_hashkey PLpgSQL_func_hashkey
tree ctl
Definition: radixtree.h:1838

References Assert, ctl, FUNCS_PER_USER, HASH_BLOBS, hash_create(), HASH_ELEM, and plpgsql_HashTable.

Referenced by _PG_init().

◆ plpgsql_HashTableInsert()

static void plpgsql_HashTableInsert ( PLpgSQL_function function,
PLpgSQL_func_hashkey func_key 
)
static

Definition at line 2638 of file pl_comp.c.

2640{
2641 plpgsql_HashEnt *hentry;
2642 bool found;
2643
2645 func_key,
2646 HASH_ENTER,
2647 &found);
2648 if (found)
2649 elog(WARNING, "trying to insert a function that already exists");
2650
2651 hentry->function = function;
2652 /* prepare back link from function to hashtable key */
2653 function->fn_hashkey = &hentry->key;
2654}
@ HASH_ENTER
Definition: hsearch.h:114
PLpgSQL_function * function
Definition: pl_comp.c:66
PLpgSQL_func_hashkey key
Definition: pl_comp.c:65

References elog, function, plpgsql_hashent::function, HASH_ENTER, hash_search(), plpgsql_hashent::key, plpgsql_HashTable, and WARNING.

Referenced by do_compile().

◆ plpgsql_HashTableLookup()

static PLpgSQL_function * plpgsql_HashTableLookup ( PLpgSQL_func_hashkey func_key)
static

Definition at line 2623 of file pl_comp.c.

2624{
2625 plpgsql_HashEnt *hentry;
2626
2628 func_key,
2629 HASH_FIND,
2630 NULL);
2631 if (hentry)
2632 return hentry->function;
2633 else
2634 return NULL;
2635}
@ HASH_FIND
Definition: hsearch.h:113

References plpgsql_hashent::function, HASH_FIND, hash_search(), and plpgsql_HashTable.

Referenced by plpgsql_compile().

◆ plpgsql_param_ref()

static Node * plpgsql_param_ref ( ParseState pstate,
ParamRef pref 
)
static

Definition at line 1160 of file pl_comp.c.

1161{
1162 PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1163 char pname[32];
1164 PLpgSQL_nsitem *nse;
1165
1166 snprintf(pname, sizeof(pname), "$%d", pref->number);
1167
1168 nse = plpgsql_ns_lookup(expr->ns, false,
1169 pname, NULL, NULL,
1170 NULL);
1171
1172 if (nse == NULL)
1173 return NULL; /* name not known to plpgsql */
1174
1175 return make_datum_param(expr, nse->itemno, pref->location);
1176}
static Node * make_datum_param(PLpgSQL_expr *expr, int dno, int location)
Definition: pl_comp.c:1345
struct PLpgSQL_nsitem * ns
Definition: plpgsql.h:229
ParseLoc location
Definition: parsenodes.h:316
int number
Definition: parsenodes.h:315
void * p_ref_hook_state
Definition: parse_node.h:258

References ParamRef::location, make_datum_param(), PLpgSQL_expr::ns, ParamRef::number, ParseState::p_ref_hook_state, plpgsql_ns_lookup(), and snprintf.

Referenced by plpgsql_parser_setup().

◆ plpgsql_parse_cwordrowtype()

PLpgSQL_type * plpgsql_parse_cwordrowtype ( List idents)

Definition at line 1808 of file pl_comp.c.

1809{
1810 Oid classOid;
1811 Oid typOid;
1812 RangeVar *relvar;
1813 MemoryContext oldCxt;
1814
1815 /*
1816 * As above, this is a relation lookup but could be a type lookup if we
1817 * weren't being backwards-compatible about error wording.
1818 */
1819
1820 /* Avoid memory leaks in long-term function context */
1822
1823 /* Look up relation name. Can't lock it - we might not have privileges. */
1824 relvar = makeRangeVarFromNameList(idents);
1825 classOid = RangeVarGetRelid(relvar, NoLock, false);
1826
1827 /* Some relkinds lack type OIDs */
1828 typOid = get_rel_type_id(classOid);
1829 if (!OidIsValid(typOid))
1830 ereport(ERROR,
1831 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1832 errmsg("relation \"%s\" does not have a composite type",
1833 relvar->relname)));
1834
1835 MemoryContextSwitchTo(oldCxt);
1836
1837 /* Build and return the row type struct */
1838 return plpgsql_build_datatype(typOid, -1, InvalidOid,
1839 makeTypeNameFromNameList(idents));
1840}
#define NoLock
Definition: lockdefs.h:34
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1979
TypeName * makeTypeNameFromNameList(List *names)
Definition: makefuncs.c:484
RangeVar * makeRangeVarFromNameList(const List *names)
Definition: namespace.c:3554
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:80
char * relname
Definition: primnodes.h:82

References ereport, errcode(), errmsg(), ERROR, get_rel_type_id(), InvalidOid, makeRangeVarFromNameList(), makeTypeNameFromNameList(), MemoryContextSwitchTo(), NoLock, OidIsValid, plpgsql_build_datatype(), plpgsql_compile_tmp_cxt, RangeVarGetRelid, and RangeVar::relname.

◆ plpgsql_parse_cwordtype()

PLpgSQL_type * plpgsql_parse_cwordtype ( List idents)

Definition at line 1659 of file pl_comp.c.

1660{
1661 PLpgSQL_type *dtype = NULL;
1662 PLpgSQL_nsitem *nse;
1663 int nnames;
1664 RangeVar *relvar = NULL;
1665 const char *fldname = NULL;
1666 Oid classOid;
1667 HeapTuple attrtup = NULL;
1668 HeapTuple typetup = NULL;
1669 Form_pg_attribute attrStruct;
1670 MemoryContext oldCxt;
1671
1672 /* Avoid memory leaks in the long-term function context */
1674
1675 if (list_length(idents) == 2)
1676 {
1677 /*
1678 * Do a lookup in the current namespace stack
1679 */
1680 nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1681 strVal(linitial(idents)),
1682 strVal(lsecond(idents)),
1683 NULL,
1684 &nnames);
1685
1686 if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1687 {
1688 /* Block-qualified reference to scalar variable. */
1689 dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1690 goto done;
1691 }
1692 else if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_REC &&
1693 nnames == 2)
1694 {
1695 /* Block-qualified reference to record variable. */
1696 dtype = ((PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]))->datatype;
1697 goto done;
1698 }
1699
1700 /*
1701 * First word could also be a table name
1702 */
1703 relvar = makeRangeVar(NULL,
1704 strVal(linitial(idents)),
1705 -1);
1706 fldname = strVal(lsecond(idents));
1707 }
1708 else
1709 {
1710 /*
1711 * We could check for a block-qualified reference to a field of a
1712 * record variable, but %TYPE is documented as applying to variables,
1713 * not fields of variables. Things would get rather ambiguous if we
1714 * allowed either interpretation.
1715 */
1716 List *rvnames;
1717
1718 Assert(list_length(idents) > 2);
1719 rvnames = list_delete_last(list_copy(idents));
1720 relvar = makeRangeVarFromNameList(rvnames);
1721 fldname = strVal(llast(idents));
1722 }
1723
1724 /* Look up relation name. Can't lock it - we might not have privileges. */
1725 classOid = RangeVarGetRelid(relvar, NoLock, false);
1726
1727 /*
1728 * Fetch the named table field and its type
1729 */
1730 attrtup = SearchSysCacheAttName(classOid, fldname);
1731 if (!HeapTupleIsValid(attrtup))
1732 ereport(ERROR,
1733 (errcode(ERRCODE_UNDEFINED_COLUMN),
1734 errmsg("column \"%s\" of relation \"%s\" does not exist",
1735 fldname, relvar->relname)));
1736 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1737
1738 typetup = SearchSysCache1(TYPEOID,
1739 ObjectIdGetDatum(attrStruct->atttypid));
1740 if (!HeapTupleIsValid(typetup))
1741 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1742
1743 /*
1744 * Found that - build a compiler type struct in the caller's cxt and
1745 * return it. Note that we treat the type as being found-by-OID; no
1746 * attempt to re-look-up the type name will happen during invalidations.
1747 */
1748 MemoryContextSwitchTo(oldCxt);
1749 dtype = build_datatype(typetup,
1750 attrStruct->atttypmod,
1751 attrStruct->attcollation,
1752 NULL);
1754
1755done:
1756 if (HeapTupleIsValid(attrtup))
1757 ReleaseSysCache(attrtup);
1758 if (HeapTupleIsValid(typetup))
1759 ReleaseSysCache(typetup);
1760
1761 MemoryContextSwitchTo(oldCxt);
1762 return dtype;
1763}
List * list_copy(const List *oldlist)
Definition: list.c:1573
List * list_delete_last(List *list)
Definition: list.c:957
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:426
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
Definition: pg_list.h:54
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:439
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:480
#define strVal(v)
Definition: value.h:82

References Assert, build_datatype(), elog, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, linitial, list_copy(), list_delete_last(), list_length(), llast, lsecond, makeRangeVar(), makeRangeVarFromNameList(), MemoryContextSwitchTo(), NoLock, ObjectIdGetDatum(), plpgsql_compile_tmp_cxt, plpgsql_Datums, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, RangeVarGetRelid, ReleaseSysCache(), RangeVar::relname, SearchSysCache1(), SearchSysCacheAttName(), and strVal.

◆ plpgsql_parse_dblword()

bool plpgsql_parse_dblword ( char *  word1,
char *  word2,
PLwdatum wdatum,
PLcword cword 
)

Definition at line 1453 of file pl_comp.c.

1455{
1456 PLpgSQL_nsitem *ns;
1457 List *idents;
1458 int nnames;
1459
1460 idents = list_make2(makeString(word1),
1461 makeString(word2));
1462
1463 /*
1464 * We should do nothing in DECLARE sections. In SQL expressions, we
1465 * really only need to make sure that RECFIELD datums are created when
1466 * needed. In all the cases handled by this function, returning a T_DATUM
1467 * with a two-word idents string is the right thing.
1468 */
1470 {
1471 /*
1472 * Do a lookup in the current namespace stack
1473 */
1474 ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1475 word1, word2, NULL,
1476 &nnames);
1477 if (ns != NULL)
1478 {
1479 switch (ns->itemtype)
1480 {
1481 case PLPGSQL_NSTYPE_VAR:
1482 /* Block-qualified reference to scalar variable. */
1483 wdatum->datum = plpgsql_Datums[ns->itemno];
1484 wdatum->ident = NULL;
1485 wdatum->quoted = false; /* not used */
1486 wdatum->idents = idents;
1487 return true;
1488
1489 case PLPGSQL_NSTYPE_REC:
1490 if (nnames == 1)
1491 {
1492 /*
1493 * First word is a record name, so second word could
1494 * be a field in this record. We build a RECFIELD
1495 * datum whether it is or not --- any error will be
1496 * detected later.
1497 */
1498 PLpgSQL_rec *rec;
1499 PLpgSQL_recfield *new;
1500
1501 rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1502 new = plpgsql_build_recfield(rec, word2);
1503
1504 wdatum->datum = (PLpgSQL_datum *) new;
1505 }
1506 else
1507 {
1508 /* Block-qualified reference to record variable. */
1509 wdatum->datum = plpgsql_Datums[ns->itemno];
1510 }
1511 wdatum->ident = NULL;
1512 wdatum->quoted = false; /* not used */
1513 wdatum->idents = idents;
1514 return true;
1515
1516 default:
1517 break;
1518 }
1519 }
1520 }
1521
1522 /* Nothing found */
1523 cword->idents = idents;
1524 return false;
1525}
#define list_make2(x1, x2)
Definition: pg_list.h:214
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
Definition: pl_comp.c:2009
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:26
@ IDENTIFIER_LOOKUP_DECLARE
Definition: plpgsql.h:1190
List * idents
Definition: plpgsql.h:1172
List * idents
Definition: plpgsql.h:1180
char * ident
Definition: plpgsql.h:1178
PLpgSQL_datum * datum
Definition: plpgsql.h:1177
bool quoted
Definition: plpgsql.h:1179
String * makeString(char *str)
Definition: value.c:63

References PLwdatum::datum, PLwdatum::ident, IDENTIFIER_LOOKUP_DECLARE, PLcword::idents, PLwdatum::idents, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, list_make2, makeString(), plpgsql_build_recfield(), plpgsql_Datums, plpgsql_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, and PLwdatum::quoted.

Referenced by plpgsql_yylex().

◆ plpgsql_parse_err_condition()

PLpgSQL_condition * plpgsql_parse_err_condition ( char *  condname)

Definition at line 2257 of file pl_comp.c.

2258{
2259 int i;
2260 PLpgSQL_condition *new;
2261 PLpgSQL_condition *prev;
2262
2263 /*
2264 * XXX Eventually we will want to look for user-defined exception names
2265 * here.
2266 */
2267
2268 /*
2269 * OTHERS is represented as code 0 (which would map to '00000', but we
2270 * have no need to represent that as an exception condition).
2271 */
2272 if (strcmp(condname, "others") == 0)
2273 {
2274 new = palloc(sizeof(PLpgSQL_condition));
2275 new->sqlerrstate = 0;
2276 new->condname = condname;
2277 new->next = NULL;
2278 return new;
2279 }
2280
2281 prev = NULL;
2282 for (i = 0; exception_label_map[i].label != NULL; i++)
2283 {
2284 if (strcmp(condname, exception_label_map[i].label) == 0)
2285 {
2286 new = palloc(sizeof(PLpgSQL_condition));
2287 new->sqlerrstate = exception_label_map[i].sqlerrstate;
2288 new->condname = condname;
2289 new->next = prev;
2290 prev = new;
2291 }
2292 }
2293
2294 if (!prev)
2295 ereport(ERROR,
2296 (errcode(ERRCODE_UNDEFINED_OBJECT),
2297 errmsg("unrecognized exception condition \"%s\"",
2298 condname)));
2299
2300 return prev;
2301}
static char * label
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:81
const char * label
Definition: pl_comp.c:77

References ereport, errcode(), errmsg(), ERROR, exception_label_map, i, label, ExceptionLabelMap::label, palloc(), and ExceptionLabelMap::sqlerrstate.

◆ plpgsql_parse_tripword()

bool plpgsql_parse_tripword ( char *  word1,
char *  word2,
char *  word3,
PLwdatum wdatum,
PLcword cword 
)

Definition at line 1534 of file pl_comp.c.

1536{
1537 PLpgSQL_nsitem *ns;
1538 List *idents;
1539 int nnames;
1540
1541 /*
1542 * We should do nothing in DECLARE sections. In SQL expressions, we need
1543 * to make sure that RECFIELD datums are created when needed, and we need
1544 * to be careful about how many names are reported as belonging to the
1545 * T_DATUM: the third word could be a sub-field reference, which we don't
1546 * care about here.
1547 */
1549 {
1550 /*
1551 * Do a lookup in the current namespace stack. Must find a record
1552 * reference, else ignore.
1553 */
1554 ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1555 word1, word2, word3,
1556 &nnames);
1557 if (ns != NULL)
1558 {
1559 switch (ns->itemtype)
1560 {
1561 case PLPGSQL_NSTYPE_REC:
1562 {
1563 PLpgSQL_rec *rec;
1564 PLpgSQL_recfield *new;
1565
1566 rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1567 if (nnames == 1)
1568 {
1569 /*
1570 * First word is a record name, so second word
1571 * could be a field in this record (and the third,
1572 * a sub-field). We build a RECFIELD datum
1573 * whether it is or not --- any error will be
1574 * detected later.
1575 */
1576 new = plpgsql_build_recfield(rec, word2);
1577 idents = list_make2(makeString(word1),
1578 makeString(word2));
1579 }
1580 else
1581 {
1582 /* Block-qualified reference to record variable. */
1583 new = plpgsql_build_recfield(rec, word3);
1584 idents = list_make3(makeString(word1),
1585 makeString(word2),
1586 makeString(word3));
1587 }
1588 wdatum->datum = (PLpgSQL_datum *) new;
1589 wdatum->ident = NULL;
1590 wdatum->quoted = false; /* not used */
1591 wdatum->idents = idents;
1592 return true;
1593 }
1594
1595 default:
1596 break;
1597 }
1598 }
1599 }
1600
1601 /* Nothing found */
1602 idents = list_make3(makeString(word1),
1603 makeString(word2),
1604 makeString(word3));
1605 cword->idents = idents;
1606 return false;
1607}
#define list_make3(x1, x2, x3)
Definition: pg_list.h:216

References PLwdatum::datum, PLwdatum::ident, IDENTIFIER_LOOKUP_DECLARE, PLcword::idents, PLwdatum::idents, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, list_make2, list_make3, makeString(), plpgsql_build_recfield(), plpgsql_Datums, plpgsql_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, and PLwdatum::quoted.

Referenced by plpgsql_yylex().

◆ plpgsql_parse_word()

bool plpgsql_parse_word ( char *  word1,
const char *  yytxt,
bool  lookup,
PLwdatum wdatum,
PLword word 
)

Definition at line 1398 of file pl_comp.c.

1400{
1401 PLpgSQL_nsitem *ns;
1402
1403 /*
1404 * We should not lookup variables in DECLARE sections. In SQL
1405 * expressions, there's no need to do so either --- lookup will happen
1406 * when the expression is compiled.
1407 */
1409 {
1410 /*
1411 * Do a lookup in the current namespace stack
1412 */
1413 ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1414 word1, NULL, NULL,
1415 NULL);
1416
1417 if (ns != NULL)
1418 {
1419 switch (ns->itemtype)
1420 {
1421 case PLPGSQL_NSTYPE_VAR:
1422 case PLPGSQL_NSTYPE_REC:
1423 wdatum->datum = plpgsql_Datums[ns->itemno];
1424 wdatum->ident = word1;
1425 wdatum->quoted = (yytxt[0] == '"');
1426 wdatum->idents = NIL;
1427 return true;
1428
1429 default:
1430 /* plpgsql_ns_lookup should never return anything else */
1431 elog(ERROR, "unrecognized plpgsql itemtype: %d",
1432 ns->itemtype);
1433 }
1434 }
1435 }
1436
1437 /*
1438 * Nothing found - up to now it's a word without any special meaning for
1439 * us.
1440 */
1441 word->ident = word1;
1442 word->quoted = (yytxt[0] == '"');
1443 return false;
1444}
@ IDENTIFIER_LOOKUP_NORMAL
Definition: plpgsql.h:1189
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
Definition: regcomp.c:1476
Definition: zic.c:304

References PLwdatum::datum, elog, ERROR, PLwdatum::ident, IDENTIFIER_LOOKUP_NORMAL, PLwdatum::idents, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, NIL, plpgsql_Datums, plpgsql_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, PLwdatum::quoted, and word().

Referenced by plpgsql_yylex().

◆ plpgsql_parse_wordrowtype()

PLpgSQL_type * plpgsql_parse_wordrowtype ( char *  ident)

Definition at line 1771 of file pl_comp.c.

1772{
1773 Oid classOid;
1774 Oid typOid;
1775
1776 /*
1777 * Look up the relation. Note that because relation rowtypes have the
1778 * same names as their relations, this could be handled as a type lookup
1779 * equally well; we use the relation lookup code path only because the
1780 * errors thrown here have traditionally referred to relations not types.
1781 * But we'll make a TypeName in case we have to do re-look-up of the type.
1782 */
1783 classOid = RelnameGetRelid(ident);
1784 if (!OidIsValid(classOid))
1785 ereport(ERROR,
1787 errmsg("relation \"%s\" does not exist", ident)));
1788
1789 /* Some relkinds lack type OIDs */
1790 typOid = get_rel_type_id(classOid);
1791 if (!OidIsValid(typOid))
1792 ereport(ERROR,
1793 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1794 errmsg("relation \"%s\" does not have a composite type",
1795 ident)));
1796
1797 /* Build and return the row type struct */
1798 return plpgsql_build_datatype(typOid, -1, InvalidOid,
1800}
#define ident
Definition: indent_codes.h:47
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:472
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:885
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:78

References ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, get_rel_type_id(), ident, InvalidOid, makeTypeName(), OidIsValid, plpgsql_build_datatype(), and RelnameGetRelid().

◆ plpgsql_parse_wordtype()

PLpgSQL_type * plpgsql_parse_wordtype ( char *  ident)

Definition at line 1618 of file pl_comp.c.

1619{
1620 PLpgSQL_nsitem *nse;
1621
1622 /*
1623 * Do a lookup in the current namespace stack
1624 */
1625 nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1626 ident, NULL, NULL,
1627 NULL);
1628
1629 if (nse != NULL)
1630 {
1631 switch (nse->itemtype)
1632 {
1633 case PLPGSQL_NSTYPE_VAR:
1634 return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1635 case PLPGSQL_NSTYPE_REC:
1636 return ((PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]))->datatype;
1637 default:
1638 break;
1639 }
1640 }
1641
1642 /* No match, complain */
1643 ereport(ERROR,
1644 (errcode(ERRCODE_UNDEFINED_OBJECT),
1645 errmsg("variable \"%s\" does not exist", ident)));
1646 return NULL; /* keep compiler quiet */
1647}

References ereport, errcode(), errmsg(), ERROR, ident, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, plpgsql_Datums, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, and PLPGSQL_NSTYPE_VAR.

◆ plpgsql_parser_setup()

void plpgsql_parser_setup ( struct ParseState pstate,
PLpgSQL_expr expr 
)

Definition at line 1089 of file pl_comp.c.

1090{
1094 /* no need to use p_coerce_param_hook */
1095 pstate->p_ref_hook_state = expr;
1096}
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1160
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1102
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1116
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:256
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:254
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:255

References ParseState::p_paramref_hook, ParseState::p_post_columnref_hook, ParseState::p_pre_columnref_hook, ParseState::p_ref_hook_state, plpgsql_param_ref(), plpgsql_post_column_ref(), and plpgsql_pre_column_ref().

Referenced by exec_prepare_plan(), and plpgsql_estate_setup().

◆ plpgsql_post_column_ref()

static Node * plpgsql_post_column_ref ( ParseState pstate,
ColumnRef cref,
Node var 
)
static

Definition at line 1116 of file pl_comp.c.

1117{
1118 PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1119 Node *myvar;
1120
1122 return NULL; /* we already found there's no match */
1123
1124 if (expr->func->resolve_option == PLPGSQL_RESOLVE_COLUMN && var != NULL)
1125 return NULL; /* there's a table column, prefer that */
1126
1127 /*
1128 * If we find a record/row variable but can't match a field name, throw
1129 * error if there was no core resolution for the ColumnRef either. In
1130 * that situation, the reference is inevitably going to fail, and
1131 * complaining about the record/row variable is likely to be more on-point
1132 * than the core parser's error message. (It's too bad we don't have
1133 * access to transformColumnRef's internal crerr state here, as in case of
1134 * a conflict with a table name this could still be less than the most
1135 * helpful error message possible.)
1136 */
1137 myvar = resolve_column_ref(pstate, expr, cref, (var == NULL));
1138
1139 if (myvar != NULL && var != NULL)
1140 {
1141 /*
1142 * We could leave it to the core parser to throw this error, but we
1143 * can add a more useful detail message than the core could.
1144 */
1145 ereport(ERROR,
1146 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
1147 errmsg("column reference \"%s\" is ambiguous",
1148 NameListToString(cref->fields)),
1149 errdetail("It could refer to either a PL/pgSQL variable or a table column."),
1150 parser_errposition(pstate, cref->location)));
1151 }
1152
1153 return myvar;
1154}
int errdetail(const char *fmt,...)
Definition: elog.c:1203
char * NameListToString(const List *names)
Definition: namespace.c:3594
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
static Node * resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
Definition: pl_comp.c:1187
@ PLPGSQL_RESOLVE_COLUMN
Definition: plpgsql.h:187
@ PLPGSQL_RESOLVE_VARIABLE
Definition: plpgsql.h:186
ParseLoc location
Definition: parsenodes.h:306
List * fields
Definition: parsenodes.h:305
PLpgSQL_resolve_option resolve_option
Definition: plpgsql.h:993

References ereport, errcode(), errdetail(), errmsg(), ERROR, ColumnRef::fields, PLpgSQL_expr::func, if(), ColumnRef::location, NameListToString(), ParseState::p_ref_hook_state, parser_errposition(), PLPGSQL_RESOLVE_COLUMN, PLPGSQL_RESOLVE_VARIABLE, resolve_column_ref(), and PLpgSQL_function::resolve_option.

Referenced by plpgsql_parser_setup().

◆ plpgsql_pre_column_ref()

static Node * plpgsql_pre_column_ref ( ParseState pstate,
ColumnRef cref 
)
static

Definition at line 1102 of file pl_comp.c.

1103{
1104 PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1105
1107 return resolve_column_ref(pstate, expr, cref, false);
1108 else
1109 return NULL;
1110}

References PLpgSQL_expr::func, if(), ParseState::p_ref_hook_state, PLPGSQL_RESOLVE_VARIABLE, resolve_column_ref(), and PLpgSQL_function::resolve_option.

Referenced by plpgsql_parser_setup().

◆ plpgsql_recognize_err_condition()

int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2221 of file pl_comp.c.

2222{
2223 int i;
2224
2225 if (allow_sqlstate)
2226 {
2227 if (strlen(condname) == 5 &&
2228 strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2229 return MAKE_SQLSTATE(condname[0],
2230 condname[1],
2231 condname[2],
2232 condname[3],
2233 condname[4]);
2234 }
2235
2236 for (i = 0; exception_label_map[i].label != NULL; i++)
2237 {
2238 if (strcmp(condname, exception_label_map[i].label) == 0)
2240 }
2241
2242 ereport(ERROR,
2243 (errcode(ERRCODE_UNDEFINED_OBJECT),
2244 errmsg("unrecognized exception condition \"%s\"",
2245 condname)));
2246 return 0; /* keep compiler quiet */
2247}
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:56

References ereport, errcode(), errmsg(), ERROR, exception_label_map, i, label, ExceptionLabelMap::label, MAKE_SQLSTATE, and ExceptionLabelMap::sqlerrstate.

Referenced by exec_stmt_raise().

◆ plpgsql_resolve_polymorphic_argtypes()

static void plpgsql_resolve_polymorphic_argtypes ( int  numargs,
Oid argtypes,
char *  argmodes,
Node call_expr,
bool  forValidator,
const char *  proname 
)
static

Definition at line 2510 of file pl_comp.c.

2514{
2515 int i;
2516
2517 if (!forValidator)
2518 {
2519 int inargno;
2520
2521 /* normal case, pass to standard routine */
2522 if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
2523 call_expr))
2524 ereport(ERROR,
2525 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2526 errmsg("could not determine actual argument "
2527 "type for polymorphic function \"%s\"",
2528 proname)));
2529 /* also, treat RECORD inputs (but not outputs) as polymorphic */
2530 inargno = 0;
2531 for (i = 0; i < numargs; i++)
2532 {
2533 char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
2534
2535 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
2536 continue;
2537 if (argtypes[i] == RECORDOID || argtypes[i] == RECORDARRAYOID)
2538 {
2539 Oid resolvedtype = get_call_expr_argtype(call_expr,
2540 inargno);
2541
2542 if (OidIsValid(resolvedtype))
2543 argtypes[i] = resolvedtype;
2544 }
2545 inargno++;
2546 }
2547 }
2548 else
2549 {
2550 /* special validation case (no need to do anything for RECORD) */
2551 for (i = 0; i < numargs; i++)
2552 {
2553 switch (argtypes[i])
2554 {
2555 case ANYELEMENTOID:
2556 case ANYNONARRAYOID:
2557 case ANYENUMOID: /* XXX dubious */
2558 case ANYCOMPATIBLEOID:
2559 case ANYCOMPATIBLENONARRAYOID:
2560 argtypes[i] = INT4OID;
2561 break;
2562 case ANYARRAYOID:
2563 case ANYCOMPATIBLEARRAYOID:
2564 argtypes[i] = INT4ARRAYOID;
2565 break;
2566 case ANYRANGEOID:
2567 case ANYCOMPATIBLERANGEOID:
2568 argtypes[i] = INT4RANGEOID;
2569 break;
2570 case ANYMULTIRANGEOID:
2571 argtypes[i] = INT4MULTIRANGEOID;
2572 break;
2573 default:
2574 break;
2575 }
2576 }
2577 }
2578}
Oid get_call_expr_argtype(Node *expr, int argnum)
Definition: fmgr.c:1929
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
Definition: funcapi.c:1064
NameData proname
Definition: pg_proc.h:35

References ereport, errcode(), errmsg(), ERROR, get_call_expr_argtype(), i, OidIsValid, proname, and resolve_polymorphic_argtypes().

Referenced by compute_function_hashkey(), and do_compile().

◆ plpgsql_start_datums()

static void plpgsql_start_datums ( void  )
static

Definition at line 2308 of file pl_comp.c.

2309{
2310 datums_alloc = 128;
2311 plpgsql_nDatums = 0;
2312 /* This is short-lived, so needn't allocate in function's cxt */
2314 sizeof(PLpgSQL_datum *) * datums_alloc);
2315 /* datums_last tracks what's been seen by plpgsql_add_initdatums() */
2316 datums_last = 0;
2317}
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181

References datums_alloc, datums_last, MemoryContextAlloc(), plpgsql_compile_tmp_cxt, plpgsql_Datums, and plpgsql_nDatums.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ resolve_column_ref()

static Node * resolve_column_ref ( ParseState pstate,
PLpgSQL_expr expr,
ColumnRef cref,
bool  error_if_no_field 
)
static

Definition at line 1187 of file pl_comp.c.

1189{
1190 PLpgSQL_execstate *estate;
1191 PLpgSQL_nsitem *nse;
1192 const char *name1;
1193 const char *name2 = NULL;
1194 const char *name3 = NULL;
1195 const char *colname = NULL;
1196 int nnames;
1197 int nnames_scalar = 0;
1198 int nnames_wholerow = 0;
1199 int nnames_field = 0;
1200
1201 /*
1202 * We use the function's current estate to resolve parameter data types.
1203 * This is really pretty bogus because there is no provision for updating
1204 * plans when those types change ...
1205 */
1206 estate = expr->func->cur_estate;
1207
1208 /*----------
1209 * The allowed syntaxes are:
1210 *
1211 * A Scalar variable reference, or whole-row record reference.
1212 * A.B Qualified scalar or whole-row reference, or field reference.
1213 * A.B.C Qualified record field reference.
1214 * A.* Whole-row record reference.
1215 * A.B.* Qualified whole-row record reference.
1216 *----------
1217 */
1218 switch (list_length(cref->fields))
1219 {
1220 case 1:
1221 {
1222 Node *field1 = (Node *) linitial(cref->fields);
1223
1224 name1 = strVal(field1);
1225 nnames_scalar = 1;
1226 nnames_wholerow = 1;
1227 break;
1228 }
1229 case 2:
1230 {
1231 Node *field1 = (Node *) linitial(cref->fields);
1232 Node *field2 = (Node *) lsecond(cref->fields);
1233
1234 name1 = strVal(field1);
1235
1236 /* Whole-row reference? */
1237 if (IsA(field2, A_Star))
1238 {
1239 /* Set name2 to prevent matches to scalar variables */
1240 name2 = "*";
1241 nnames_wholerow = 1;
1242 break;
1243 }
1244
1245 name2 = strVal(field2);
1246 colname = name2;
1247 nnames_scalar = 2;
1248 nnames_wholerow = 2;
1249 nnames_field = 1;
1250 break;
1251 }
1252 case 3:
1253 {
1254 Node *field1 = (Node *) linitial(cref->fields);
1255 Node *field2 = (Node *) lsecond(cref->fields);
1256 Node *field3 = (Node *) lthird(cref->fields);
1257
1258 name1 = strVal(field1);
1259 name2 = strVal(field2);
1260
1261 /* Whole-row reference? */
1262 if (IsA(field3, A_Star))
1263 {
1264 /* Set name3 to prevent matches to scalar variables */
1265 name3 = "*";
1266 nnames_wholerow = 2;
1267 break;
1268 }
1269
1270 name3 = strVal(field3);
1271 colname = name3;
1272 nnames_field = 2;
1273 break;
1274 }
1275 default:
1276 /* too many names, ignore */
1277 return NULL;
1278 }
1279
1280 nse = plpgsql_ns_lookup(expr->ns, false,
1281 name1, name2, name3,
1282 &nnames);
1283
1284 if (nse == NULL)
1285 return NULL; /* name not known to plpgsql */
1286
1287 switch (nse->itemtype)
1288 {
1289 case PLPGSQL_NSTYPE_VAR:
1290 if (nnames == nnames_scalar)
1291 return make_datum_param(expr, nse->itemno, cref->location);
1292 break;
1293 case PLPGSQL_NSTYPE_REC:
1294 if (nnames == nnames_wholerow)
1295 return make_datum_param(expr, nse->itemno, cref->location);
1296 if (nnames == nnames_field)
1297 {
1298 /* colname could be a field in this record */
1299 PLpgSQL_rec *rec = (PLpgSQL_rec *) estate->datums[nse->itemno];
1300 int i;
1301
1302 /* search for a datum referencing this field */
1303 i = rec->firstfield;
1304 while (i >= 0)
1305 {
1306 PLpgSQL_recfield *fld = (PLpgSQL_recfield *) estate->datums[i];
1307
1309 fld->recparentno == nse->itemno);
1310 if (strcmp(fld->fieldname, colname) == 0)
1311 {
1312 return make_datum_param(expr, i, cref->location);
1313 }
1314 i = fld->nextfield;
1315 }
1316
1317 /*
1318 * We should not get here, because a RECFIELD datum should
1319 * have been built at parse time for every possible qualified
1320 * reference to fields of this record. But if we do, handle
1321 * it like field-not-found: throw error or return NULL.
1322 */
1323 if (error_if_no_field)
1324 ereport(ERROR,
1325 (errcode(ERRCODE_UNDEFINED_COLUMN),
1326 errmsg("record \"%s\" has no field \"%s\"",
1327 (nnames_field == 1) ? name1 : name2,
1328 colname),
1329 parser_errposition(pstate, cref->location)));
1330 }
1331 break;
1332 default:
1333 elog(ERROR, "unrecognized plpgsql itemtype: %d", nse->itemtype);
1334 }
1335
1336 /* Name format doesn't match the plpgsql variable type */
1337 return NULL;
1338}
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
while(p+4<=pend)
#define lthird(l)
Definition: pg_list.h:188

References Assert, PLpgSQL_function::cur_estate, PLpgSQL_execstate::datums, PLpgSQL_recfield::dtype, elog, ereport, errcode(), errmsg(), ERROR, PLpgSQL_recfield::fieldname, ColumnRef::fields, PLpgSQL_rec::firstfield, PLpgSQL_expr::func, i, IsA, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, linitial, list_length(), ColumnRef::location, lsecond, lthird, make_datum_param(), PLpgSQL_recfield::nextfield, PLpgSQL_expr::ns, parser_errposition(), PLPGSQL_DTYPE_RECFIELD, plpgsql_ns_lookup(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, PLpgSQL_recfield::recparentno, strVal, and while().

Referenced by plpgsql_post_column_ref(), and plpgsql_pre_column_ref().

Variable Documentation

◆ datums_alloc

int datums_alloc
static

Definition at line 43 of file pl_comp.c.

Referenced by plpgsql_adddatum(), and plpgsql_start_datums().

◆ datums_last

int datums_last
static

Definition at line 46 of file pl_comp.c.

Referenced by plpgsql_add_initdatums(), and plpgsql_start_datums().

◆ exception_label_map

const ExceptionLabelMap exception_label_map[]
static
Initial value:
= {
{NULL, 0}
}

Definition at line 81 of file pl_comp.c.

Referenced by plpgsql_parse_err_condition(), and plpgsql_recognize_err_condition().

◆ plpgsql_check_syntax

bool plpgsql_check_syntax = false

Definition at line 50 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ plpgsql_compile_tmp_cxt

◆ plpgsql_curr_compile

PLpgSQL_function* plpgsql_curr_compile

Definition at line 52 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ plpgsql_Datums

◆ plpgsql_DumpExecTree

bool plpgsql_DumpExecTree = false

Definition at line 49 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().

◆ plpgsql_error_funcname

char* plpgsql_error_funcname

Definition at line 48 of file pl_comp.c.

Referenced by do_compile(), plpgsql_compile_error_callback(), and plpgsql_compile_inline().

◆ plpgsql_HashTable

HTAB* plpgsql_HashTable = NULL
static

◆ plpgsql_nDatums

int plpgsql_nDatums

◆ plpgsql_parse_result

PLpgSQL_stmt_block* plpgsql_parse_result

Definition at line 41 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().