PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pl_comp.c File Reference
#include "plpgsql.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_proc_fn.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "nodes/makefuncs.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/regproc.h"
#include "utils/rel.h"
#include "utils/syscache.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
 

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_class (Oid classOid)
 
static PLpgSQL_rowbuild_row_from_vars (PLpgSQL_variable **vars, int numvars)
 
static PLpgSQL_typebuild_datatype (HeapTuple typeTup, int32 typmod, Oid collation)
 
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, 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, bool add2namespace)
 
PLpgSQL_typeplpgsql_build_datatype (Oid typeOid, int32 typmod, Oid collation)
 
int plpgsql_recognize_err_condition (const char *condname, bool allow_sqlstate)
 
PLpgSQL_conditionplpgsql_parse_err_condition (char *condname)
 
void plpgsql_adddatum (PLpgSQL_datum *new)
 
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

#define FUNCS_PER_USER   128 /* initial table size */

Definition at line 69 of file pl_comp.c.

Referenced by plpgsql_HashTableInit().

Typedef Documentation

Function Documentation

static void add_dummy_return ( PLpgSQL_function function)
static

Definition at line 975 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

976 {
977  /*
978  * If the outer block has an EXCEPTION clause, we need to make a new outer
979  * block, since the added RETURN shouldn't act like it is inside the
980  * EXCEPTION clause.
981  */
982  if (function->action->exceptions != NULL)
983  {
984  PLpgSQL_stmt_block *new;
985 
986  new = palloc0(sizeof(PLpgSQL_stmt_block));
987  new->cmd_type = PLPGSQL_STMT_BLOCK;
988  new->body = list_make1(function->action);
989 
990  function->action = new;
991  }
992  if (function->action->body == NIL ||
993  ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
994  {
995  PLpgSQL_stmt_return *new;
996 
997  new = palloc0(sizeof(PLpgSQL_stmt_return));
998  new->cmd_type = PLPGSQL_STMT_RETURN;
999  new->expr = NULL;
1000  new->retvarno = function->out_param_varno;
1001 
1002  function->action->body = lappend(function->action->body, new);
1003  }
1004 }
#define NIL
Definition: pg_list.h:69
PLpgSQL_stmt_block * action
Definition: plpgsql.h:872
#define llast(l)
Definition: pg_list.h:126
#define list_make1(x1)
Definition: pg_list.h:133
List * lappend(List *list, void *datum)
Definition: list.c:128
void * palloc0(Size size)
Definition: mcxt.c:920
#define NULL
Definition: c.h:226
PLpgSQL_exception_block * exceptions
Definition: plpgsql.h:413
static void add_parameter_name ( PLpgSQL_nsitem_type  itemtype,
int  itemno,
const char *  name 
)
static

Definition at line 950 of file pl_comp.c.

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

Referenced by do_compile().

951 {
952  /*
953  * Before adding the name, check for duplicates. We need this even though
954  * functioncmds.c has a similar check, because that code explicitly
955  * doesn't complain about conflicting IN and OUT parameter names. In
956  * plpgsql, such names are in the same namespace, so there is no way to
957  * disambiguate.
958  */
959  if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
960  name, NULL, NULL,
961  NULL) != NULL)
962  ereport(ERROR,
963  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
964  errmsg("parameter name \"%s\" used more than once",
965  name)));
966 
967  /* OK, add the name */
968  plpgsql_ns_additem(itemtype, itemno, name);
969 }
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
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
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:226
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
static PLpgSQL_type * build_datatype ( HeapTuple  typeTup,
int32  typmod,
Oid  collation 
)
static

Definition at line 2143 of file pl_comp.c.

References Assert, PLpgSQL_type::atttypmod, PLpgSQL_type::collation, elog, ereport, errcode(), errmsg(), ERROR, get_base_element_type(), GETSTRUCT, HeapTupleGetOid, NameStr, OidIsValid, palloc(), PLPGSQL_TTYPE_PSEUDO, PLPGSQL_TTYPE_REC, PLPGSQL_TTYPE_ROW, PLPGSQL_TTYPE_SCALAR, pstrdup(), RECORDOID, PLpgSQL_type::ttype, PLpgSQL_type::typbyval, PLpgSQL_type::typisarray, PLpgSQL_type::typlen, PLpgSQL_type::typname, PLpgSQL_type::typoid, PLpgSQL_type::typrelid, PLpgSQL_type::typtype, TYPTYPE_BASE, TYPTYPE_COMPOSITE, TYPTYPE_DOMAIN, TYPTYPE_ENUM, TYPTYPE_PSEUDO, and TYPTYPE_RANGE.

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

2144 {
2145  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2146  PLpgSQL_type *typ;
2147 
2148  if (!typeStruct->typisdefined)
2149  ereport(ERROR,
2150  (errcode(ERRCODE_UNDEFINED_OBJECT),
2151  errmsg("type \"%s\" is only a shell",
2152  NameStr(typeStruct->typname))));
2153 
2154  typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
2155 
2156  typ->typname = pstrdup(NameStr(typeStruct->typname));
2157  typ->typoid = HeapTupleGetOid(typeTup);
2158  switch (typeStruct->typtype)
2159  {
2160  case TYPTYPE_BASE:
2161  case TYPTYPE_DOMAIN:
2162  case TYPTYPE_ENUM:
2163  case TYPTYPE_RANGE:
2164  typ->ttype = PLPGSQL_TTYPE_SCALAR;
2165  break;
2166  case TYPTYPE_COMPOSITE:
2167  Assert(OidIsValid(typeStruct->typrelid));
2168  typ->ttype = PLPGSQL_TTYPE_ROW;
2169  break;
2170  case TYPTYPE_PSEUDO:
2171  if (typ->typoid == RECORDOID)
2172  typ->ttype = PLPGSQL_TTYPE_REC;
2173  else
2174  typ->ttype = PLPGSQL_TTYPE_PSEUDO;
2175  break;
2176  default:
2177  elog(ERROR, "unrecognized typtype: %d",
2178  (int) typeStruct->typtype);
2179  break;
2180  }
2181  typ->typlen = typeStruct->typlen;
2182  typ->typbyval = typeStruct->typbyval;
2183  typ->typtype = typeStruct->typtype;
2184  typ->typrelid = typeStruct->typrelid;
2185  typ->collation = typeStruct->typcollation;
2186  if (OidIsValid(collation) && OidIsValid(typ->collation))
2187  typ->collation = collation;
2188  /* Detect if type is true array, or domain thereof */
2189  /* NB: this is only used to decide whether to apply expand_array */
2190  if (typeStruct->typtype == TYPTYPE_BASE)
2191  {
2192  /*
2193  * This test should include what get_element_type() checks. We also
2194  * disallow non-toastable array types (i.e. oidvector and int2vector).
2195  */
2196  typ->typisarray = (typeStruct->typlen == -1 &&
2197  OidIsValid(typeStruct->typelem) &&
2198  typeStruct->typstorage != 'p');
2199  }
2200  else if (typeStruct->typtype == TYPTYPE_DOMAIN)
2201  {
2202  /* we can short-circuit looking up base types if it's not varlena */
2203  typ->typisarray = (typeStruct->typlen == -1 &&
2204  typeStruct->typstorage != 'p' &&
2205  OidIsValid(get_base_element_type(typeStruct->typbasetype)));
2206  }
2207  else
2208  typ->typisarray = false;
2209  typ->atttypmod = typmod;
2210 
2211  return typ;
2212 }
#define TYPTYPE_DOMAIN
Definition: pg_type.h:710
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define TYPTYPE_BASE
Definition: pg_type.h:708
#define TYPTYPE_COMPOSITE
Definition: pg_type.h:709
char * pstrdup(const char *in)
Definition: mcxt.c:1165
PLpgSQL_type_type ttype
Definition: plpgsql.h:182
int errcode(int sqlerrcode)
Definition: elog.c:575
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
#define OidIsValid(objectId)
Definition: c.h:533
#define ERROR
Definition: elog.h:43
#define RECORDOID
Definition: pg_type.h:668
#define ereport(elevel, rest)
Definition: elog.h:122
Oid typrelid
Definition: plpgsql.h:186
bool typbyval
Definition: plpgsql.h:184
#define TYPTYPE_RANGE
Definition: pg_type.h:713
Oid collation
Definition: plpgsql.h:187
bool typisarray
Definition: plpgsql.h:188
#define Assert(condition)
Definition: c.h:670
char * typname
Definition: plpgsql.h:180
#define TYPTYPE_PSEUDO
Definition: pg_type.h:712
char typtype
Definition: plpgsql.h:185
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2525
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 atttypmod
Definition: plpgsql.h:189
#define NameStr(name)
Definition: c.h:494
#define TYPTYPE_ENUM
Definition: pg_type.h:711
#define elog
Definition: elog.h:219
int16 typlen
Definition: plpgsql.h:183
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
Oid typoid
Definition: plpgsql.h:181
static PLpgSQL_row * build_row_from_class ( Oid  classOid)
static

Definition at line 1964 of file pl_comp.c.

References AccessShareLock, tupleDesc::attrs, CreateTupleDescCopy(), PLpgSQL_row::dtype, ereport, errcode(), errmsg(), ERROR, PLpgSQL_row::fieldnames, i, NAMEDATALEN, NameStr, PLpgSQL_row::nfields, NULL, palloc(), palloc0(), plpgsql_build_datatype(), plpgsql_build_variable(), PLPGSQL_DTYPE_ROW, relation_close(), relation_open(), RelationGetDescr, RelationGetForm, RelationGetRelationName, RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, PLpgSQL_row::rowtupdesc, snprintf(), and PLpgSQL_row::varnos.

Referenced by plpgsql_build_variable().

1965 {
1966  PLpgSQL_row *row;
1967  Relation rel;
1968  Form_pg_class classStruct;
1969  const char *relname;
1970  int i;
1971 
1972  /*
1973  * Open the relation to get info.
1974  */
1975  rel = relation_open(classOid, AccessShareLock);
1976  classStruct = RelationGetForm(rel);
1977  relname = RelationGetRelationName(rel);
1978 
1979  /*
1980  * Accept relation, sequence, view, materialized view, composite type, or
1981  * foreign table.
1982  */
1983  if (classStruct->relkind != RELKIND_RELATION &&
1984  classStruct->relkind != RELKIND_SEQUENCE &&
1985  classStruct->relkind != RELKIND_VIEW &&
1986  classStruct->relkind != RELKIND_MATVIEW &&
1987  classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
1988  classStruct->relkind != RELKIND_FOREIGN_TABLE)
1989  ereport(ERROR,
1990  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1991  errmsg("relation \"%s\" is not a table", relname)));
1992 
1993  /*
1994  * Create a row datum entry and all the required variables that it will
1995  * point to.
1996  */
1997  row = palloc0(sizeof(PLpgSQL_row));
1998  row->dtype = PLPGSQL_DTYPE_ROW;
2000  row->nfields = classStruct->relnatts;
2001  row->fieldnames = palloc(sizeof(char *) * row->nfields);
2002  row->varnos = palloc(sizeof(int) * row->nfields);
2003 
2004  for (i = 0; i < row->nfields; i++)
2005  {
2006  Form_pg_attribute attrStruct;
2007 
2008  /*
2009  * Get the attribute and check for dropped column
2010  */
2011  attrStruct = row->rowtupdesc->attrs[i];
2012 
2013  if (!attrStruct->attisdropped)
2014  {
2015  char *attname;
2016  char refname[(NAMEDATALEN * 2) + 100];
2017  PLpgSQL_variable *var;
2018 
2019  attname = NameStr(attrStruct->attname);
2020  snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
2021 
2022  /*
2023  * Create the internal variable for the field
2024  *
2025  * We know if the table definitions contain a default value or if
2026  * the field is declared in the table as NOT NULL. But it's
2027  * possible to create a table field as NOT NULL without a default
2028  * value and that would lead to problems later when initializing
2029  * the variables due to entering a block at execution time. Thus
2030  * we ignore this information for now.
2031  */
2032  var = plpgsql_build_variable(refname, 0,
2033  plpgsql_build_datatype(attrStruct->atttypid,
2034  attrStruct->atttypmod,
2035  attrStruct->attcollation),
2036  false);
2037 
2038  /* Add the variable to the row */
2039  row->fieldnames[i] = attname;
2040  row->varnos[i] = var->dno;
2041  }
2042  else
2043  {
2044  /* Leave a hole in the row structure for the dropped col */
2045  row->fieldnames[i] = NULL;
2046  row->varnos[i] = -1;
2047  }
2048  }
2049 
2051 
2052  return row;
2053 }
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:141
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2123
#define RelationGetDescr(relation)
Definition: rel.h:425
#define RelationGetForm(relation)
Definition: rel.h:407
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define RELKIND_MATVIEW
Definition: pg_class.h:167
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:165
#define NAMEDATALEN
#define ERROR
Definition: elog.h:43
char ** fieldnames
Definition: plpgsql.h:295
#define RelationGetRelationName(relation)
Definition: rel.h:433
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:166
#define ereport(elevel, rest)
Definition: elog.h:122
int * varnos
Definition: plpgsql.h:296
void * palloc0(Size size)
Definition: mcxt.c:920
#define NULL
Definition: c.h:226
int nfields
Definition: plpgsql.h:294
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
Definition: pl_comp.c:1861
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
int i
TupleDesc rowtupdesc
Definition: plpgsql.h:287
#define NameStr(name)
Definition: c.h:494
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
PLpgSQL_datum_type dtype
Definition: plpgsql.h:281
static PLpgSQL_row * build_row_from_vars ( PLpgSQL_variable **  vars,
int  numvars 
)
static

Definition at line 2059 of file pl_comp.c.

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

Referenced by do_compile().

2060 {
2061  PLpgSQL_row *row;
2062  int i;
2063 
2064  row = palloc0(sizeof(PLpgSQL_row));
2065  row->dtype = PLPGSQL_DTYPE_ROW;
2066  row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
2067  row->nfields = numvars;
2068  row->fieldnames = palloc(numvars * sizeof(char *));
2069  row->varnos = palloc(numvars * sizeof(int));
2070 
2071  for (i = 0; i < numvars; i++)
2072  {
2073  PLpgSQL_variable *var = vars[i];
2074  Oid typoid = RECORDOID;
2075  int32 typmod = -1;
2076  Oid typcoll = InvalidOid;
2077 
2078  switch (var->dtype)
2079  {
2080  case PLPGSQL_DTYPE_VAR:
2081  typoid = ((PLpgSQL_var *) var)->datatype->typoid;
2082  typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
2083  typcoll = ((PLpgSQL_var *) var)->datatype->collation;
2084  break;
2085 
2086  case PLPGSQL_DTYPE_REC:
2087  break;
2088 
2089  case PLPGSQL_DTYPE_ROW:
2090  if (((PLpgSQL_row *) var)->rowtupdesc)
2091  {
2092  typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
2093  typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
2094  /* composite types have no collation */
2095  }
2096  break;
2097 
2098  default:
2099  elog(ERROR, "unrecognized dtype: %d", var->dtype);
2100  }
2101 
2102  row->fieldnames[i] = var->refname;
2103  row->varnos[i] = var->dno;
2104 
2105  TupleDescInitEntry(row->rowtupdesc, i + 1,
2106  var->refname,
2107  typoid, typmod,
2108  0);
2109  TupleDescInitEntryCollation(row->rowtupdesc, i + 1, typcoll);
2110  }
2111 
2112  return row;
2113 }
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:253
#define ERROR
Definition: elog.h:43
char ** fieldnames
Definition: plpgsql.h:295
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:650
#define RECORDOID
Definition: pg_type.h:668
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:493
int * varnos
Definition: plpgsql.h:296
void * palloc0(Size size)
Definition: mcxt.c:920
#define InvalidOid
Definition: postgres_ext.h:36
int nfields
Definition: plpgsql.h:294
char * refname
Definition: plpgsql.h:214
PLpgSQL_datum_type dtype
Definition: plpgsql.h:212
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
void * palloc(Size size)
Definition: mcxt.c:891
int i
TupleDesc rowtupdesc
Definition: plpgsql.h:287
#define elog
Definition: elog.h:219
PLpgSQL_datum_type dtype
Definition: plpgsql.h:281
static void compute_function_hashkey ( FunctionCallInfo  fcinfo,
Form_pg_proc  procStruct,
PLpgSQL_func_hashkey hashkey,
bool  forValidator 
)
static

Definition at line 2439 of file pl_comp.c.

References PLpgSQL_func_hashkey::argtypes, CALLED_AS_TRIGGER, FunctionCallInfoData::context, FunctionCallInfoData::flinfo, FmgrInfo::fn_expr, FmgrInfo::fn_oid, FunctionCallInfoData::fncollation, PLpgSQL_func_hashkey::funcOid, PLpgSQL_func_hashkey::inputCollation, PLpgSQL_func_hashkey::isTrigger, MemSet, NameStr, NULL, plpgsql_resolve_polymorphic_argtypes(), RelationGetRelid, TriggerData::tg_relation, and PLpgSQL_func_hashkey::trigrelOid.

Referenced by plpgsql_compile().

2443 {
2444  /* Make sure any unused bytes of the struct are zero */
2445  MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
2446 
2447  /* get function OID */
2448  hashkey->funcOid = fcinfo->flinfo->fn_oid;
2449 
2450  /* get call context */
2451  hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
2452 
2453  /*
2454  * if trigger, get relation OID. In validation mode we do not know what
2455  * relation is intended to be used, so we leave trigrelOid zero; the hash
2456  * entry built in this case will never really be used.
2457  */
2458  if (hashkey->isTrigger && !forValidator)
2459  {
2460  TriggerData *trigdata = (TriggerData *) fcinfo->context;
2461 
2462  hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
2463  }
2464 
2465  /* get input collation, if known */
2466  hashkey->inputCollation = fcinfo->fncollation;
2467 
2468  if (procStruct->pronargs > 0)
2469  {
2470  /* get the argument types */
2471  memcpy(hashkey->argtypes, procStruct->proargtypes.values,
2472  procStruct->pronargs * sizeof(Oid));
2473 
2474  /* resolve any polymorphic argument types */
2475  plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
2476  hashkey->argtypes,
2477  NULL,
2478  fcinfo->flinfo->fn_expr,
2479  forValidator,
2480  NameStr(procStruct->proname));
2481  }
2482 }
Oid argtypes[FUNC_MAX_ARGS]
Definition: plpgsql.h:803
fmNodePtr context
Definition: fmgr.h:72
#define MemSet(start, val, len)
Definition: c.h:852
unsigned int Oid
Definition: postgres_ext.h:31
static void plpgsql_resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
Definition: pl_comp.c:2491
FmgrInfo * flinfo
Definition: fmgr.h:71
Oid fn_oid
Definition: fmgr.h:56
#define NULL
Definition: c.h:226
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:25
fmNodePtr fn_expr
Definition: fmgr.h:63
#define NameStr(name)
Definition: c.h:494
#define RelationGetRelid(relation)
Definition: rel.h:413
Relation tg_relation
Definition: trigger.h:34
static void delete_function ( PLpgSQL_function func)
static

Definition at line 2549 of file pl_comp.c.

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

Referenced by plpgsql_compile().

2550 {
2551  /* remove function from hash table (might be done already) */
2553 
2554  /* release the function's storage if safe and not done already */
2555  if (func->use_count == 0)
2557 }
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:693
unsigned long use_count
Definition: plpgsql.h:876
static void plpgsql_HashTableDelete(PLpgSQL_function *function)
Definition: pl_comp.c:2612
static PLpgSQL_function * do_compile ( FunctionCallInfo  fcinfo,
HeapTuple  procTup,
PLpgSQL_function function,
PLpgSQL_func_hashkey hashkey,
bool  forValidator 
)
static

Definition at line 263 of file pl_comp.c.

References add_dummy_return(), add_parameter_name(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), Anum_pg_proc_prosrc, ANYARRAYOID, ANYRANGEOID, ErrorContextCallback::arg, Assert, BOOLOID, buf, build_datatype(), build_row_from_vars(), ErrorContextCallback::callback, 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, EVTTRIGGEROID, FunctionCallInfoData::flinfo, FmgrInfo::fn_expr, FmgrInfo::fn_oid, FunctionCallInfoData::fncollation, format_procedure(), format_type_be(), function, get_fn_expr_rettype(), get_func_arg_info(), GETSTRUCT, HeapTupleHeaderGetRawXmin, HeapTupleIsValid, i, INT4ARRAYOID, INT4OID, INT4RANGEOID, InvalidOid, IsPolymorphicType, MemoryContextAllocZero(), MemoryContextSwitchTo(), NAMEOID, NameStr, NULL, ObjectIdGetDatum, OidIsValid, OIDOID, palloc(), pfree(), plpgsql_adddatum(), plpgsql_build_datatype(), plpgsql_build_record(), plpgsql_build_variable(), plpgsql_check_syntax, plpgsql_compile_error_callback(), PLPGSQL_DML_TRIGGER, PLPGSQL_DTYPE_ROW, 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_ROW, PLPGSQL_NSTYPE_VAR, plpgsql_parse_result, plpgsql_print_strict_params, plpgsql_resolve_polymorphic_argtypes(), plpgsql_scanner_finish(), plpgsql_scanner_init(), plpgsql_start_datums(), PLPGSQL_TTYPE_ROW, PLPGSQL_TTYPE_SCALAR, plpgsql_variable_conflict, plpgsql_yyparse(), ErrorContextCallback::previous, PROARGMODE_IN, PROARGMODE_INOUT, PROARGMODE_OUT, PROARGMODE_TABLE, PROARGMODE_VARIADIC, PROCOID, PROVOLATILE_VOLATILE, pstrdup(), RECORDOID, ReleaseSysCache(), SearchSysCache1, snprintf(), SysCacheGetAttr(), HeapTupleData::t_data, HeapTupleData::t_self, TEXTARRAYOID, TextDatumGetCString, TEXTOID, TopMemoryContext, TRIGGEROID, PLpgSQL_type::ttype, TYPEOID, TYPTYPE_PSEUDO, and VOIDOID.

Referenced by plpgsql_compile().

268 {
269  Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
270  bool is_dml_trigger = CALLED_AS_TRIGGER(fcinfo);
271  bool is_event_trigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
272  Datum prosrcdatum;
273  bool isnull;
274  char *proc_source;
275  HeapTuple typeTup;
276  Form_pg_type typeStruct;
277  PLpgSQL_variable *var;
278  PLpgSQL_rec *rec;
279  int i;
280  ErrorContextCallback plerrcontext;
281  int parse_rc;
282  Oid rettypeid;
283  int numargs;
284  int num_in_args = 0;
285  int num_out_args = 0;
286  Oid *argtypes;
287  char **argnames;
288  char *argmodes;
289  int *in_arg_varnos = NULL;
290  PLpgSQL_variable **out_arg_variables;
291  MemoryContext func_cxt;
292 
293  /*
294  * Setup the scanner input and error info. We assume that this function
295  * cannot be invoked recursively, so there's no need to save and restore
296  * the static variables used here.
297  */
298  prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
299  Anum_pg_proc_prosrc, &isnull);
300  if (isnull)
301  elog(ERROR, "null prosrc");
302  proc_source = TextDatumGetCString(prosrcdatum);
303  plpgsql_scanner_init(proc_source);
304 
305  plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
306 
307  /*
308  * Setup error traceback support for ereport()
309  */
311  plerrcontext.arg = forValidator ? proc_source : NULL;
312  plerrcontext.previous = error_context_stack;
313  error_context_stack = &plerrcontext;
314 
315  /*
316  * Do extra syntax checks when validating the function definition. We skip
317  * this when actually compiling functions for execution, for performance
318  * reasons.
319  */
320  plpgsql_check_syntax = forValidator;
321 
322  /*
323  * Create the new function struct, if not done already. The function
324  * structs are never thrown away, so keep them in TopMemoryContext.
325  */
326  if (function == NULL)
327  {
328  function = (PLpgSQL_function *)
330  }
331  else
332  {
333  /* re-using a previously existing struct, so clear it out */
334  memset(function, 0, sizeof(PLpgSQL_function));
335  }
336  plpgsql_curr_compile = function;
337 
338  /*
339  * All the permanent output of compilation (e.g. parse tree) is kept in a
340  * per-function memory context, so it can be reclaimed easily.
341  */
343  "PL/pgSQL function context",
346 
347  function->fn_signature = format_procedure(fcinfo->flinfo->fn_oid);
348  function->fn_oid = fcinfo->flinfo->fn_oid;
349  function->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
350  function->fn_tid = procTup->t_self;
351  function->fn_input_collation = fcinfo->fncollation;
352  function->fn_cxt = func_cxt;
353  function->out_param_varno = -1; /* set up for no OUT param */
354  function->resolve_option = plpgsql_variable_conflict;
355  function->print_strict_params = plpgsql_print_strict_params;
356  /* only promote extra warnings and errors at CREATE FUNCTION time */
357  function->extra_warnings = forValidator ? plpgsql_extra_warnings : 0;
358  function->extra_errors = forValidator ? plpgsql_extra_errors : 0;
359 
360  if (is_dml_trigger)
361  function->fn_is_trigger = PLPGSQL_DML_TRIGGER;
362  else if (is_event_trigger)
363  function->fn_is_trigger = PLPGSQL_EVENT_TRIGGER;
364  else
365  function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
366 
367  /*
368  * Initialize the compiler, particularly the namespace stack. The
369  * outermost namespace contains function parameters and other special
370  * variables (such as FOUND), and is named after the function itself.
371  */
372  plpgsql_ns_init();
373  plpgsql_ns_push(NameStr(procStruct->proname), PLPGSQL_LABEL_BLOCK);
374  plpgsql_DumpExecTree = false;
376 
377  switch (function->fn_is_trigger)
378  {
379  case PLPGSQL_NOT_TRIGGER:
380 
381  /*
382  * Fetch info about the procedure's parameters. Allocations aren't
383  * needed permanently, so make them in tmp cxt.
384  *
385  * We also need to resolve any polymorphic input or output
386  * argument types. In validation mode we won't be able to, so we
387  * arbitrarily assume we are dealing with integers.
388  */
390 
391  numargs = get_func_arg_info(procTup,
392  &argtypes, &argnames, &argmodes);
393 
394  plpgsql_resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
395  fcinfo->flinfo->fn_expr,
396  forValidator,
398 
399  in_arg_varnos = (int *) palloc(numargs * sizeof(int));
400  out_arg_variables = (PLpgSQL_variable **) palloc(numargs * sizeof(PLpgSQL_variable *));
401 
402  MemoryContextSwitchTo(func_cxt);
403 
404  /*
405  * Create the variables for the procedure's parameters.
406  */
407  for (i = 0; i < numargs; i++)
408  {
409  char buf[32];
410  Oid argtypeid = argtypes[i];
411  char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
412  PLpgSQL_type *argdtype;
413  PLpgSQL_variable *argvariable;
414  PLpgSQL_nsitem_type argitemtype;
415 
416  /* Create $n name for variable */
417  snprintf(buf, sizeof(buf), "$%d", i + 1);
418 
419  /* Create datatype info */
420  argdtype = plpgsql_build_datatype(argtypeid,
421  -1,
422  function->fn_input_collation);
423 
424  /* Disallow pseudotype argument */
425  /* (note we already replaced polymorphic types) */
426  /* (build_variable would do this, but wrong message) */
427  if (argdtype->ttype != PLPGSQL_TTYPE_SCALAR &&
428  argdtype->ttype != PLPGSQL_TTYPE_ROW)
429  ereport(ERROR,
430  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
431  errmsg("PL/pgSQL functions cannot accept type %s",
432  format_type_be(argtypeid))));
433 
434  /* Build variable and add to datum list */
435  argvariable = plpgsql_build_variable(buf, 0,
436  argdtype, false);
437 
438  if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
439  {
440  argitemtype = PLPGSQL_NSTYPE_VAR;
441  }
442  else
443  {
444  Assert(argvariable->dtype == PLPGSQL_DTYPE_ROW);
445  argitemtype = PLPGSQL_NSTYPE_ROW;
446  }
447 
448  /* Remember arguments in appropriate arrays */
449  if (argmode == PROARGMODE_IN ||
450  argmode == PROARGMODE_INOUT ||
451  argmode == PROARGMODE_VARIADIC)
452  in_arg_varnos[num_in_args++] = argvariable->dno;
453  if (argmode == PROARGMODE_OUT ||
454  argmode == PROARGMODE_INOUT ||
455  argmode == PROARGMODE_TABLE)
456  out_arg_variables[num_out_args++] = argvariable;
457 
458  /* Add to namespace under the $n name */
459  add_parameter_name(argitemtype, argvariable->dno, buf);
460 
461  /* If there's a name for the argument, make an alias */
462  if (argnames && argnames[i][0] != '\0')
463  add_parameter_name(argitemtype, argvariable->dno,
464  argnames[i]);
465  }
466 
467  /*
468  * If there's just one OUT parameter, out_param_varno points
469  * directly to it. If there's more than one, build a row that
470  * holds all of them.
471  */
472  if (num_out_args == 1)
473  function->out_param_varno = out_arg_variables[0]->dno;
474  else if (num_out_args > 1)
475  {
476  PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
477  num_out_args);
478 
480  function->out_param_varno = row->dno;
481  }
482 
483  /*
484  * Check for a polymorphic returntype. If found, use the actual
485  * returntype type from the caller's FuncExpr node, if we have
486  * one. (In validation mode we arbitrarily assume we are dealing
487  * with integers.)
488  *
489  * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
490  * work; if it doesn't we're in some context that fails to make
491  * the info available.
492  */
493  rettypeid = procStruct->prorettype;
494  if (IsPolymorphicType(rettypeid))
495  {
496  if (forValidator)
497  {
498  if (rettypeid == ANYARRAYOID)
499  rettypeid = INT4ARRAYOID;
500  else if (rettypeid == ANYRANGEOID)
501  rettypeid = INT4RANGEOID;
502  else /* ANYELEMENT or ANYNONARRAY */
503  rettypeid = INT4OID;
504  /* XXX what could we use for ANYENUM? */
505  }
506  else
507  {
508  rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
509  if (!OidIsValid(rettypeid))
510  ereport(ERROR,
511  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
512  errmsg("could not determine actual return type "
513  "for polymorphic function \"%s\"",
515  }
516  }
517 
518  /*
519  * Normal function has a defined returntype
520  */
521  function->fn_rettype = rettypeid;
522  function->fn_retset = procStruct->proretset;
523 
524  /*
525  * Lookup the function's return type
526  */
527  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettypeid));
528  if (!HeapTupleIsValid(typeTup))
529  elog(ERROR, "cache lookup failed for type %u", rettypeid);
530  typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
531 
532  /* Disallow pseudotype result, except VOID or RECORD */
533  /* (note we already replaced polymorphic types) */
534  if (typeStruct->typtype == TYPTYPE_PSEUDO)
535  {
536  if (rettypeid == VOIDOID ||
537  rettypeid == RECORDOID)
538  /* okay */ ;
539  else if (rettypeid == TRIGGEROID || rettypeid == EVTTRIGGEROID)
540  ereport(ERROR,
541  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
542  errmsg("trigger functions can only be called as triggers")));
543  else
544  ereport(ERROR,
545  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
546  errmsg("PL/pgSQL functions cannot return type %s",
547  format_type_be(rettypeid))));
548  }
549 
550  if (typeStruct->typrelid != InvalidOid ||
551  rettypeid == RECORDOID)
552  function->fn_retistuple = true;
553  else
554  {
555  function->fn_retbyval = typeStruct->typbyval;
556  function->fn_rettyplen = typeStruct->typlen;
557 
558  /*
559  * install $0 reference, but only for polymorphic return
560  * types, and not when the return is specified through an
561  * output parameter.
562  */
563  if (IsPolymorphicType(procStruct->prorettype) &&
564  num_out_args == 0)
565  {
566  (void) plpgsql_build_variable("$0", 0,
567  build_datatype(typeTup,
568  -1,
569  function->fn_input_collation),
570  true);
571  }
572  }
573  ReleaseSysCache(typeTup);
574  break;
575 
576  case PLPGSQL_DML_TRIGGER:
577  /* Trigger procedure's return type is unknown yet */
578  function->fn_rettype = InvalidOid;
579  function->fn_retbyval = false;
580  function->fn_retistuple = true;
581  function->fn_retset = false;
582 
583  /* shouldn't be any declared arguments */
584  if (procStruct->pronargs != 0)
585  ereport(ERROR,
586  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
587  errmsg("trigger functions cannot have declared arguments"),
588  errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
589 
590  /* Add the record for referencing NEW */
591  rec = plpgsql_build_record("new", 0, true);
592  function->new_varno = rec->dno;
593 
594  /* Add the record for referencing OLD */
595  rec = plpgsql_build_record("old", 0, true);
596  function->old_varno = rec->dno;
597 
598  /* Add the variable tg_name */
599  var = plpgsql_build_variable("tg_name", 0,
601  -1,
602  InvalidOid),
603  true);
604  function->tg_name_varno = var->dno;
605 
606  /* Add the variable tg_when */
607  var = plpgsql_build_variable("tg_when", 0,
609  -1,
610  function->fn_input_collation),
611  true);
612  function->tg_when_varno = var->dno;
613 
614  /* Add the variable tg_level */
615  var = plpgsql_build_variable("tg_level", 0,
617  -1,
618  function->fn_input_collation),
619  true);
620  function->tg_level_varno = var->dno;
621 
622  /* Add the variable tg_op */
623  var = plpgsql_build_variable("tg_op", 0,
625  -1,
626  function->fn_input_collation),
627  true);
628  function->tg_op_varno = var->dno;
629 
630  /* Add the variable tg_relid */
631  var = plpgsql_build_variable("tg_relid", 0,
633  -1,
634  InvalidOid),
635  true);
636  function->tg_relid_varno = var->dno;
637 
638  /* Add the variable tg_relname */
639  var = plpgsql_build_variable("tg_relname", 0,
641  -1,
642  InvalidOid),
643  true);
644  function->tg_relname_varno = var->dno;
645 
646  /* tg_table_name is now preferred to tg_relname */
647  var = plpgsql_build_variable("tg_table_name", 0,
649  -1,
650  InvalidOid),
651  true);
652  function->tg_table_name_varno = var->dno;
653 
654  /* add the variable tg_table_schema */
655  var = plpgsql_build_variable("tg_table_schema", 0,
657  -1,
658  InvalidOid),
659  true);
660  function->tg_table_schema_varno = var->dno;
661 
662  /* Add the variable tg_nargs */
663  var = plpgsql_build_variable("tg_nargs", 0,
665  -1,
666  InvalidOid),
667  true);
668  function->tg_nargs_varno = var->dno;
669 
670  /* Add the variable tg_argv */
671  var = plpgsql_build_variable("tg_argv", 0,
673  -1,
674  function->fn_input_collation),
675  true);
676  function->tg_argv_varno = var->dno;
677 
678  break;
679 
681  function->fn_rettype = VOIDOID;
682  function->fn_retbyval = false;
683  function->fn_retistuple = true;
684  function->fn_retset = false;
685 
686  /* shouldn't be any declared arguments */
687  if (procStruct->pronargs != 0)
688  ereport(ERROR,
689  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
690  errmsg("event trigger functions cannot have declared arguments")));
691 
692  /* Add the variable tg_event */
693  var = plpgsql_build_variable("tg_event", 0,
695  -1,
696  function->fn_input_collation),
697  true);
698  function->tg_event_varno = var->dno;
699 
700  /* Add the variable tg_tag */
701  var = plpgsql_build_variable("tg_tag", 0,
703  -1,
704  function->fn_input_collation),
705  true);
706  function->tg_tag_varno = var->dno;
707 
708  break;
709 
710  default:
711  elog(ERROR, "unrecognized function typecode: %d",
712  (int) function->fn_is_trigger);
713  break;
714  }
715 
716  /* Remember if function is STABLE/IMMUTABLE */
717  function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
718 
719  /*
720  * Create the magic FOUND variable.
721  */
722  var = plpgsql_build_variable("found", 0,
724  -1,
725  InvalidOid),
726  true);
727  function->found_varno = var->dno;
728 
729  /*
730  * Now parse the function's text
731  */
732  parse_rc = plpgsql_yyparse();
733  if (parse_rc != 0)
734  elog(ERROR, "plpgsql parser returned %d", parse_rc);
735  function->action = plpgsql_parse_result;
736 
738  pfree(proc_source);
739 
740  /*
741  * If it has OUT parameters or returns VOID or returns a set, we allow
742  * control to fall off the end without an explicit RETURN statement. The
743  * easiest way to implement this is to add a RETURN statement to the end
744  * of the statement list during parsing.
745  */
746  if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
747  function->fn_retset)
748  add_dummy_return(function);
749 
750  /*
751  * Complete the function's info
752  */
753  function->fn_nargs = procStruct->pronargs;
754  for (i = 0; i < function->fn_nargs; i++)
755  function->fn_argvarnos[i] = in_arg_varnos[i];
756 
757  plpgsql_finish_datums(function);
758 
759  /* Debug dump for completed functions */
761  plpgsql_dumptree(function);
762 
763  /*
764  * add it to the hash table
765  */
766  plpgsql_HashTableInsert(function, hashkey);
767 
768  /*
769  * Pop the error context stack
770  */
771  error_context_stack = plerrcontext.previous;
773 
774  plpgsql_check_syntax = false;
775 
778  return function;
779 }
int plpgsql_yyparse(void)
int fn_argvarnos[FUNC_MAX_ARGS]
Definition: plpgsql.h:838
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
Definition: event_trigger.h:40
#define NAMEOID
Definition: pg_type.h:300
int errhint(const char *fmt,...)
Definition: elog.c:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2123
#define OIDOID
Definition: pg_type.h:328
#define TEXTOID
Definition: pg_type.h:324
char * pstrdup(const char *in)
Definition: mcxt.c:1165
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:791
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define Anum_pg_proc_prosrc
Definition: pg_proc.h:115
PLpgSQL_type_type ttype
Definition: plpgsql.h:182
#define INT4OID
Definition: pg_type.h:316
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, bool add2namespace)
Definition: pl_comp.c:1941
int plpgsql_extra_errors
Definition: pl_handler.c:53
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
#define PROARGMODE_VARIADIC
Definition: pg_proc.h:5393
void plpgsql_dumptree(PLpgSQL_function *func)
Definition: pl_funcs.c:1541
unsigned int Oid
Definition: postgres_ext.h:31
struct ErrorContextCallback * previous
Definition: elog.h:238
#define OidIsValid(objectId)
Definition: c.h:533
static void plpgsql_resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
Definition: pl_comp.c:2491
static void plpgsql_HashTableInsert(PLpgSQL_function *function, PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2593
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2309
#define PROARGMODE_INOUT
Definition: pg_proc.h:5392
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define PROARGMODE_OUT
Definition: pg_proc.h:5391
HeapTupleHeader t_data
Definition: htup.h:67
ErrorContextCallback * error_context_stack
Definition: elog.c:88
void plpgsql_scanner_finish(void)
Definition: pl_scanner.c:727
FmgrInfo * flinfo
Definition: fmgr.h:71
void pfree(void *pointer)
Definition: mcxt.c:992
#define VOIDOID
Definition: pg_type.h:678
#define TEXTARRAYOID
Definition: pg_type.h:459
bool plpgsql_check_syntax
Definition: pl_comp.c:50
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
char * plpgsql_error_funcname
Definition: pl_comp.c:48
#define IsPolymorphicType(typid)
Definition: pg_type.h:733
bool plpgsql_DumpExecTree
Definition: pl_comp.c:49
#define ANYRANGEOID
Definition: pg_type.h:702
static void add_parameter_name(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_comp.c:950
#define TRIGGEROID
Definition: pg_type.h:680
#define PROARGMODE_TABLE
Definition: pg_proc.h:5394
ItemPointerData t_self
Definition: htup.h:65
int plpgsql_extra_warnings
Definition: pl_handler.c:52
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
#define INT4RANGEOID
Definition: pg_type.h:636
static void add_dummy_return(PLpgSQL_function *function)
Definition: pl_comp.c:975
static char * buf
Definition: pg_test_fsync.c:65
#define RECORDOID
Definition: pg_type.h:668
void plpgsql_ns_init(void)
Definition: pl_funcs.c:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define PROARGMODE_IN
Definition: pg_proc.h:5390
MemoryContext TopMemoryContext
Definition: mcxt.c:43
#define PROVOLATILE_VOLATILE
Definition: pg_proc.h:5374
Oid fn_input_collation
Definition: plpgsql.h:826
#define TextDatumGetCString(d)
Definition: builtins.h:91
#define ANYARRAYOID
Definition: pg_type.h:676
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
uintptr_t Datum
Definition: postgres.h:374
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:2198
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:784
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:56
PLpgSQL_trigtype fn_is_trigger
Definition: plpgsql.h:825
bool plpgsql_print_strict_params
Definition: pl_handler.c:46
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:367
static void plpgsql_compile_error_callback(void *arg)
Definition: pl_comp.c:923
int plpgsql_variable_conflict
Definition: pl_handler.c:44
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define EVTTRIGGEROID
Definition: pg_type.h:682
#define NULL
Definition: c.h:226
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:25
#define Assert(condition)
Definition: c.h:670
fmNodePtr fn_expr
Definition: fmgr.h:63
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
Definition: pl_funcs.c:54
PLpgSQL_stmt_block * plpgsql_parse_result
Definition: pl_comp.c:41
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
Definition: pl_comp.c:1861
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
PLpgSQL_datum_type dtype
Definition: plpgsql.h:212
#define BOOLOID
Definition: pg_type.h:288
#define TYPTYPE_PSEUDO
Definition: pg_type.h:712
void plpgsql_scanner_init(const char *str)
Definition: pl_scanner.c:700
void(* callback)(void *arg)
Definition: elog.h:239
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2143
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2346
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2326
int i
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:55
#define NameStr(name)
Definition: c.h:494
#define elog
Definition: elog.h:219
#define INT4ARRAYOID
Definition: pg_type.h:456
static PLpgSQL_row * build_row_from_vars(PLpgSQL_variable **vars, int numvars)
Definition: pl_comp.c:2059
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:52
PLpgSQL_nsitem_type
Definition: plpgsql.h:40
static Node * make_datum_param ( PLpgSQL_expr expr,
int  dno,
int  location 
)
static

Definition at line 1303 of file pl_comp.c.

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::paramcollid, Param::paramid, Param::paramkind, PLpgSQL_expr::paramnos, Param::paramtype, Param::paramtypmod, and plpgsql_exec_get_datum_type_info().

Referenced by plpgsql_param_ref(), and resolve_column_ref().

1304 {
1305  PLpgSQL_execstate *estate;
1306  PLpgSQL_datum *datum;
1307  Param *param;
1308  MemoryContext oldcontext;
1309 
1310  /* see comment in resolve_column_ref */
1311  estate = expr->func->cur_estate;
1312  Assert(dno >= 0 && dno < estate->ndatums);
1313  datum = estate->datums[dno];
1314 
1315  /*
1316  * Bitmapset must be allocated in function's permanent memory context
1317  */
1318  oldcontext = MemoryContextSwitchTo(expr->func->fn_cxt);
1319  expr->paramnos = bms_add_member(expr->paramnos, dno);
1320  MemoryContextSwitchTo(oldcontext);
1321 
1322  param = makeNode(Param);
1323  param->paramkind = PARAM_EXTERN;
1324  param->paramid = dno + 1;
1326  datum,
1327  &param->paramtype,
1328  &param->paramtypmod,
1329  &param->paramcollid);
1330  param->location = location;
1331 
1332  return (Node *) param;
1333 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ParamKind paramkind
Definition: primnodes.h:222
Definition: nodes.h:508
PLpgSQL_datum ** datums
Definition: plpgsql.h:909
Bitmapset * paramnos
Definition: plpgsql.h:227
struct PLpgSQL_execstate * cur_estate
Definition: plpgsql.h:875
Oid paramcollid
Definition: primnodes.h:226
int location
Definition: primnodes.h:227
MemoryContext fn_cxt
Definition: plpgsql.h:828
void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeid, int32 *typmod, Oid *collation)
Definition: pl_exec.c:5014
struct PLpgSQL_function * func
Definition: plpgsql.h:231
int32 paramtypmod
Definition: primnodes.h:225
#define makeNode(_type_)
Definition: nodes.h:556
#define Assert(condition)
Definition: c.h:670
int paramid
Definition: primnodes.h:223
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:668
Oid paramtype
Definition: primnodes.h:224
int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2387 of file pl_comp.c.

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

2388 {
2389  int i;
2390  int n = 0;
2391 
2392  for (i = datums_last; i < plpgsql_nDatums; i++)
2393  {
2394  switch (plpgsql_Datums[i]->dtype)
2395  {
2396  case PLPGSQL_DTYPE_VAR:
2397  n++;
2398  break;
2399 
2400  default:
2401  break;
2402  }
2403  }
2404 
2405  if (varnos != NULL)
2406  {
2407  if (n > 0)
2408  {
2409  *varnos = (int *) palloc(sizeof(int) * n);
2410 
2411  n = 0;
2412  for (i = datums_last; i < plpgsql_nDatums; i++)
2413  {
2414  switch (plpgsql_Datums[i]->dtype)
2415  {
2416  case PLPGSQL_DTYPE_VAR:
2417  (*varnos)[n++] = plpgsql_Datums[i]->dno;
2418 
2419  default:
2420  break;
2421  }
2422  }
2423  }
2424  else
2425  *varnos = NULL;
2426  }
2427 
2429  return n;
2430 }
int plpgsql_nDatums
Definition: pl_comp.c:44
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
#define NULL
Definition: c.h:226
void * palloc(Size size)
Definition: mcxt.c:891
int i
static int datums_last
Definition: pl_comp.c:46
void plpgsql_adddatum ( PLpgSQL_datum new)

Definition at line 2326 of file pl_comp.c.

References datums_alloc, plpgsql_nDatums, and repalloc().

Referenced by do_compile(), plpgsql_build_record(), plpgsql_build_variable(), plpgsql_parse_dblword(), and plpgsql_parse_tripword().

2327 {
2329  {
2330  datums_alloc *= 2;
2332  }
2333 
2334  new->dno = plpgsql_nDatums;
2336 }
int plpgsql_nDatums
Definition: pl_comp.c:44
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
static int datums_alloc
Definition: pl_comp.c:43
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021
PLpgSQL_type* plpgsql_build_datatype ( Oid  typeOid,
int32  typmod,
Oid  collation 
)

Definition at line 2123 of file pl_comp.c.

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

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

2124 {
2125  HeapTuple typeTup;
2126  PLpgSQL_type *typ;
2127 
2128  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
2129  if (!HeapTupleIsValid(typeTup))
2130  elog(ERROR, "cache lookup failed for type %u", typeOid);
2131 
2132  typ = build_datatype(typeTup, typmod, collation);
2133 
2134  ReleaseSysCache(typeTup);
2135 
2136  return typ;
2137 }
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2143
#define elog
Definition: elog.h:219
PLpgSQL_rec* plpgsql_build_record ( const char *  refname,
int  lineno,
bool  add2namespace 
)

Definition at line 1941 of file pl_comp.c.

References PLpgSQL_rec::dno, PLpgSQL_rec::dtype, PLpgSQL_rec::freetup, PLpgSQL_rec::freetupdesc, PLpgSQL_rec::lineno, NULL, palloc0(), plpgsql_adddatum(), PLPGSQL_DTYPE_REC, plpgsql_ns_additem(), PLPGSQL_NSTYPE_REC, pstrdup(), PLpgSQL_rec::refname, PLpgSQL_rec::tup, and PLpgSQL_rec::tupdesc.

Referenced by do_compile(), and plpgsql_build_variable().

1942 {
1943  PLpgSQL_rec *rec;
1944 
1945  rec = palloc0(sizeof(PLpgSQL_rec));
1946  rec->dtype = PLPGSQL_DTYPE_REC;
1947  rec->refname = pstrdup(refname);
1948  rec->lineno = lineno;
1949  rec->tup = NULL;
1950  rec->tupdesc = NULL;
1951  rec->freetup = false;
1952  rec->freetupdesc = false;
1954  if (add2namespace)
1956 
1957  return rec;
1958 }
PLpgSQL_datum_type dtype
Definition: plpgsql.h:304
TupleDesc tupdesc
Definition: plpgsql.h:310
char * pstrdup(const char *in)
Definition: mcxt.c:1165
bool freetup
Definition: plpgsql.h:311
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
char * refname
Definition: plpgsql.h:306
void * palloc0(Size size)
Definition: mcxt.c:920
#define NULL
Definition: c.h:226
bool freetupdesc
Definition: plpgsql.h:312
HeapTuple tup
Definition: plpgsql.h:309
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2326
int lineno
Definition: plpgsql.h:307
PLpgSQL_variable* plpgsql_build_variable ( const char *  refname,
int  lineno,
PLpgSQL_type dtype,
bool  add2namespace 
)

Definition at line 1861 of file pl_comp.c.

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

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

1863 {
1864  PLpgSQL_variable *result;
1865 
1866  switch (dtype->ttype)
1867  {
1868  case PLPGSQL_TTYPE_SCALAR:
1869  {
1870  /* Ordinary scalar datatype */
1871  PLpgSQL_var *var;
1872 
1873  var = palloc0(sizeof(PLpgSQL_var));
1874  var->dtype = PLPGSQL_DTYPE_VAR;
1875  var->refname = pstrdup(refname);
1876  var->lineno = lineno;
1877  var->datatype = dtype;
1878  /* other fields might be filled by caller */
1879 
1880  /* preset to NULL */
1881  var->value = 0;
1882  var->isnull = true;
1883  var->freeval = false;
1884 
1886  if (add2namespace)
1888  var->dno,
1889  refname);
1890  result = (PLpgSQL_variable *) var;
1891  break;
1892  }
1893  case PLPGSQL_TTYPE_ROW:
1894  {
1895  /* Composite type -- build a row variable */
1896  PLpgSQL_row *row;
1897 
1898  row = build_row_from_class(dtype->typrelid);
1899 
1900  row->dtype = PLPGSQL_DTYPE_ROW;
1901  row->refname = pstrdup(refname);
1902  row->lineno = lineno;
1903 
1905  if (add2namespace)
1907  row->dno,
1908  refname);
1909  result = (PLpgSQL_variable *) row;
1910  break;
1911  }
1912  case PLPGSQL_TTYPE_REC:
1913  {
1914  /* "record" type -- build a record variable */
1915  PLpgSQL_rec *rec;
1916 
1917  rec = plpgsql_build_record(refname, lineno, add2namespace);
1918  result = (PLpgSQL_variable *) rec;
1919  break;
1920  }
1921  case PLPGSQL_TTYPE_PSEUDO:
1922  ereport(ERROR,
1923  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1924  errmsg("variable \"%s\" has pseudo-type %s",
1925  refname, format_type_be(dtype->typoid))));
1926  result = NULL; /* keep compiler quiet */
1927  break;
1928  default:
1929  elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1930  result = NULL; /* keep compiler quiet */
1931  break;
1932  }
1933 
1934  return result;
1935 }
char * refname
Definition: plpgsql.h:283
char * refname
Definition: plpgsql.h:260
static PLpgSQL_row * build_row_from_class(Oid classOid)
Definition: pl_comp.c:1964
PLpgSQL_datum_type dtype
Definition: plpgsql.h:258
char * pstrdup(const char *in)
Definition: mcxt.c:1165
PLpgSQL_type * datatype
Definition: plpgsql.h:263
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
PLpgSQL_type_type ttype
Definition: plpgsql.h:182
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, bool add2namespace)
Definition: pl_comp.c:1941
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool freeval
Definition: plpgsql.h:273
Oid typrelid
Definition: plpgsql.h:186
void * palloc0(Size size)
Definition: mcxt.c:920
Datum value
Definition: plpgsql.h:271
#define NULL
Definition: c.h:226
int lineno
Definition: plpgsql.h:261
int errmsg(const char *fmt,...)
Definition: elog.c:797
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2326
#define elog
Definition: elog.h:219
PLpgSQL_datum_type dtype
Definition: plpgsql.h:281
int lineno
Definition: plpgsql.h:284
bool isnull
Definition: plpgsql.h:272
Oid typoid
Definition: plpgsql.h:181
PLpgSQL_function* plpgsql_compile ( FunctionCallInfo  fcinfo,
bool  forValidator 
)

Definition at line 135 of file pl_comp.c.

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

Referenced by plpgsql_call_handler(), and plpgsql_validator().

136 {
137  Oid funcOid = fcinfo->flinfo->fn_oid;
138  HeapTuple procTup;
139  Form_pg_proc procStruct;
140  PLpgSQL_function *function;
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  */
157  function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
158 
159 recheck:
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 */
167  function = plpgsql_HashTableLookup(&hashkey);
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  */
182  delete_function(function);
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 = (void *) function;
233 
234  /*
235  * Finally return the compiled function
236  */
237  return function;
238 }
static PLpgSQL_function * do_compile(FunctionCallInfo fcinfo, HeapTuple procTup, PLpgSQL_function *function, PLpgSQL_func_hashkey *hashkey, bool forValidator)
Definition: pl_comp.c:263
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
static void compute_function_hashkey(FunctionCallInfo fcinfo, Form_pg_proc procStruct, PLpgSQL_func_hashkey *hashkey, bool forValidator)
Definition: pl_comp.c:2439
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
HeapTupleHeader t_data
Definition: htup.h:67
static void delete_function(PLpgSQL_function *func)
Definition: pl_comp.c:2549
FmgrInfo * flinfo
Definition: fmgr.h:71
static PLpgSQL_function * plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2578
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
Oid fn_oid
Definition: fmgr.h:56
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
void * fn_extra
Definition: fmgr.h:61
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
on_exit_nicely_callback function
#define elog
Definition: elog.h:219
static void plpgsql_compile_error_callback ( void *  arg)
static

Definition at line 923 of file pl_comp.c.

References errcontext, function_parse_error_transpose(), plpgsql_error_funcname, and plpgsql_latest_lineno().

Referenced by do_compile(), and plpgsql_compile_inline().

924 {
925  if (arg)
926  {
927  /*
928  * Try to convert syntax error position to reference text of original
929  * CREATE FUNCTION or DO command.
930  */
931  if (function_parse_error_transpose((const char *) arg))
932  return;
933 
934  /*
935  * Done if a syntax error position was reported; otherwise we have to
936  * fall back to a "near line N" report.
937  */
938  }
939 
941  errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
943 }
int plpgsql_latest_lineno(void)
Definition: pl_scanner.c:686
char * plpgsql_error_funcname
Definition: pl_comp.c:48
bool function_parse_error_transpose(const char *prosrc)
Definition: pg_proc.c:983
#define errcontext
Definition: elog.h:164
void * arg
PLpgSQL_function* plpgsql_compile_inline ( char *  proc_source)

Definition at line 792 of file pl_comp.c.

References add_dummy_return(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), ErrorContextCallback::arg, BOOLOID, ErrorContextCallback::callback, check_function_bodies, CurrentMemoryContext, PLpgSQL_variable::dno, elog, ERROR, error_context_stack, function, InvalidOid, MemoryContextSwitchTo(), NULL, palloc0(), plpgsql_build_datatype(), plpgsql_build_variable(), plpgsql_check_syntax, plpgsql_compile_error_callback(), 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, pstrdup(), and VOIDOID.

Referenced by plpgsql_inline_handler().

793 {
794  char *func_name = "inline_code_block";
795  PLpgSQL_function *function;
796  ErrorContextCallback plerrcontext;
797  PLpgSQL_variable *var;
798  int parse_rc;
799  MemoryContext func_cxt;
800 
801  /*
802  * Setup the scanner input and error info. We assume that this function
803  * cannot be invoked recursively, so there's no need to save and restore
804  * the static variables used here.
805  */
806  plpgsql_scanner_init(proc_source);
807 
808  plpgsql_error_funcname = func_name;
809 
810  /*
811  * Setup error traceback support for ereport()
812  */
814  plerrcontext.arg = proc_source;
815  plerrcontext.previous = error_context_stack;
816  error_context_stack = &plerrcontext;
817 
818  /* Do extra syntax checking if check_function_bodies is on */
820 
821  /* Function struct does not live past current statement */
822  function = (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
823 
824  plpgsql_curr_compile = function;
825 
826  /*
827  * All the rest of the compile-time storage (e.g. parse tree) is kept in
828  * its own memory context, so it can be reclaimed easily.
829  */
831  "PL/pgSQL inline code context",
834 
835  function->fn_signature = pstrdup(func_name);
836  function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
837  function->fn_input_collation = InvalidOid;
838  function->fn_cxt = func_cxt;
839  function->out_param_varno = -1; /* set up for no OUT param */
840  function->resolve_option = plpgsql_variable_conflict;
841  function->print_strict_params = plpgsql_print_strict_params;
842 
843  /*
844  * don't do extra validation for inline code as we don't want to add spam
845  * at runtime
846  */
847  function->extra_warnings = 0;
848  function->extra_errors = 0;
849 
850  plpgsql_ns_init();
852  plpgsql_DumpExecTree = false;
854 
855  /* Set up as though in a function returning VOID */
856  function->fn_rettype = VOIDOID;
857  function->fn_retset = false;
858  function->fn_retistuple = false;
859  /* a bit of hardwired knowledge about type VOID here */
860  function->fn_retbyval = true;
861  function->fn_rettyplen = sizeof(int32);
862 
863  /*
864  * Remember if function is STABLE/IMMUTABLE. XXX would it be better to
865  * set this TRUE inside a read-only transaction? Not clear.
866  */
867  function->fn_readonly = false;
868 
869  /*
870  * Create the magic FOUND variable.
871  */
872  var = plpgsql_build_variable("found", 0,
874  -1,
875  InvalidOid),
876  true);
877  function->found_varno = var->dno;
878 
879  /*
880  * Now parse the function's text
881  */
882  parse_rc = plpgsql_yyparse();
883  if (parse_rc != 0)
884  elog(ERROR, "plpgsql parser returned %d", parse_rc);
885  function->action = plpgsql_parse_result;
886 
888 
889  /*
890  * If it returns VOID (always true at the moment), we allow control to
891  * fall off the end without an explicit RETURN statement.
892  */
893  if (function->fn_rettype == VOIDOID)
894  add_dummy_return(function);
895 
896  /*
897  * Complete the function's info
898  */
899  function->fn_nargs = 0;
900 
901  plpgsql_finish_datums(function);
902 
903  /*
904  * Pop the error context stack
905  */
906  error_context_stack = plerrcontext.previous;
908 
909  plpgsql_check_syntax = false;
910 
913  return function;
914 }
int plpgsql_yyparse(void)
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2123
char * pstrdup(const char *in)
Definition: mcxt.c:1165
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool check_function_bodies
Definition: guc.c:449
struct ErrorContextCallback * previous
Definition: elog.h:238
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2309
signed int int32
Definition: c.h:253
ErrorContextCallback * error_context_stack
Definition: elog.c:88
void plpgsql_scanner_finish(void)
Definition: pl_scanner.c:727
#define VOIDOID
Definition: pg_type.h:678
bool plpgsql_check_syntax
Definition: pl_comp.c:50
#define ERROR
Definition: elog.h:43
char * plpgsql_error_funcname
Definition: pl_comp.c:48
bool plpgsql_DumpExecTree
Definition: pl_comp.c:49
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
static void add_dummy_return(PLpgSQL_function *function)
Definition: pl_comp.c:975
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
void plpgsql_ns_init(void)
Definition: pl_funcs.c:43
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
void * palloc0(Size size)
Definition: mcxt.c:920
#define InvalidOid
Definition: postgres_ext.h:36
bool plpgsql_print_strict_params
Definition: pl_handler.c:46
static void plpgsql_compile_error_callback(void *arg)
Definition: pl_comp.c:923
int plpgsql_variable_conflict
Definition: pl_handler.c:44
#define NULL
Definition: c.h:226
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
Definition: pl_funcs.c:54
PLpgSQL_stmt_block * plpgsql_parse_result
Definition: pl_comp.c:41
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
Definition: pl_comp.c:1861
#define BOOLOID
Definition: pg_type.h:288
on_exit_nicely_callback function
void plpgsql_scanner_init(const char *str)
Definition: pl_scanner.c:700
void(* callback)(void *arg)
Definition: elog.h:239
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2346
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:55
#define elog
Definition: elog.h:219
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:52
static void plpgsql_finish_datums ( PLpgSQL_function function)
static

Definition at line 2346 of file pl_comp.c.

References bms_add_member(), function, i, NULL, palloc(), PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_ROW, and plpgsql_nDatums.

Referenced by do_compile(), and plpgsql_compile_inline().

2347 {
2348  Bitmapset *resettable_datums = NULL;
2349  int i;
2350 
2351  function->ndatums = plpgsql_nDatums;
2352  function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
2353  for (i = 0; i < plpgsql_nDatums; i++)
2354  {
2355  function->datums[i] = plpgsql_Datums[i];
2356  switch (function->datums[i]->dtype)
2357  {
2358  case PLPGSQL_DTYPE_ROW:
2359  case PLPGSQL_DTYPE_REC:
2361  resettable_datums = bms_add_member(resettable_datums, i);
2362  break;
2363 
2364  default:
2365  break;
2366  }
2367  }
2368  function->resettable_datums = resettable_datums;
2369 }
int plpgsql_nDatums
Definition: pl_comp.c:44
PLpgSQL_datum ** datums
Definition: plpgsql.h:868
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
PLpgSQL_datum_type dtype
Definition: plpgsql.h:200
#define NULL
Definition: c.h:226
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:668
void * palloc(Size size)
Definition: mcxt.c:891
int i
static void plpgsql_HashTableDelete ( PLpgSQL_function function)
static

Definition at line 2612 of file pl_comp.c.

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

Referenced by delete_function().

2613 {
2614  plpgsql_HashEnt *hentry;
2615 
2616  /* do nothing if not in table */
2617  if (function->fn_hashkey == NULL)
2618  return;
2619 
2621  (void *) function->fn_hashkey,
2622  HASH_REMOVE,
2623  NULL);
2624  if (hentry == NULL)
2625  elog(WARNING, "trying to delete function that does not exist");
2626 
2627  /* remove back link, which no longer points to allocated storage */
2628  function->fn_hashkey = NULL;
2629 }
PLpgSQL_func_hashkey * fn_hashkey
Definition: plpgsql.h:827
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:61
#define WARNING
Definition: elog.h:40
#define NULL
Definition: c.h:226
#define elog
Definition: elog.h:219
void plpgsql_HashTableInit ( void  )

Definition at line 2561 of file pl_comp.c.

References Assert, HASHCTL::entrysize, FUNCS_PER_USER, HASH_BLOBS, hash_create(), HASH_ELEM, HASHCTL::keysize, and NULL.

Referenced by _PG_init().

2562 {
2563  HASHCTL ctl;
2564 
2565  /* don't allow double-initialization */
2567 
2568  memset(&ctl, 0, sizeof(ctl));
2569  ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2570  ctl.entrysize = sizeof(plpgsql_HashEnt);
2571  plpgsql_HashTable = hash_create("PLpgSQL function cache",
2573  &ctl,
2574  HASH_ELEM | HASH_BLOBS);
2575 }
#define FUNCS_PER_USER
Definition: pl_comp.c:69
#define HASH_ELEM
Definition: hsearch.h:87
Size entrysize
Definition: hsearch.h:73
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:61
struct plpgsql_hashent plpgsql_HashEnt
struct PLpgSQL_func_hashkey PLpgSQL_func_hashkey
#define HASH_BLOBS
Definition: hsearch.h:88
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:301
Size keysize
Definition: hsearch.h:72
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
static void plpgsql_HashTableInsert ( PLpgSQL_function function,
PLpgSQL_func_hashkey func_key 
)
static

Definition at line 2593 of file pl_comp.c.

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

Referenced by do_compile().

2595 {
2596  plpgsql_HashEnt *hentry;
2597  bool found;
2598 
2600  (void *) func_key,
2601  HASH_ENTER,
2602  &found);
2603  if (found)
2604  elog(WARNING, "trying to insert a function that already exists");
2605 
2606  hentry->function = function;
2607  /* prepare back link from function to hashtable key */
2608  function->fn_hashkey = &hentry->key;
2609 }
PLpgSQL_func_hashkey * fn_hashkey
Definition: plpgsql.h:827
PLpgSQL_func_hashkey key
Definition: pl_comp.c:65
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:61
PLpgSQL_function * function
Definition: pl_comp.c:66
#define WARNING
Definition: elog.h:40
#define elog
Definition: elog.h:219
static PLpgSQL_function * plpgsql_HashTableLookup ( PLpgSQL_func_hashkey func_key)
static

Definition at line 2578 of file pl_comp.c.

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

Referenced by plpgsql_compile().

2579 {
2580  plpgsql_HashEnt *hentry;
2581 
2583  (void *) func_key,
2584  HASH_FIND,
2585  NULL);
2586  if (hentry)
2587  return hentry->function;
2588  else
2589  return NULL;
2590 }
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:61
PLpgSQL_function * function
Definition: pl_comp.c:66
#define NULL
Definition: c.h:226
static Node * plpgsql_param_ref ( ParseState pstate,
ParamRef pref 
)
static

Definition at line 1087 of file pl_comp.c.

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

Referenced by plpgsql_parser_setup().

1088 {
1089  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1090  char pname[32];
1091  PLpgSQL_nsitem *nse;
1092 
1093  snprintf(pname, sizeof(pname), "$%d", pref->number);
1094 
1095  nse = plpgsql_ns_lookup(expr->ns, false,
1096  pname, NULL, NULL,
1097  NULL);
1098 
1099  if (nse == NULL)
1100  return NULL; /* name not known to plpgsql */
1101 
1102  return make_datum_param(expr, nse->itemno, pref->location);
1103 }
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
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
struct PLpgSQL_nsitem * ns
Definition: plpgsql.h:234
int number
Definition: parsenodes.h:236
int location
Definition: parsenodes.h:237
#define NULL
Definition: c.h:226
void * p_ref_hook_state
Definition: parse_node.h:206
static Node * make_datum_param(PLpgSQL_expr *expr, int dno, int location)
Definition: pl_comp.c:1303
PLpgSQL_type* plpgsql_parse_cwordrowtype ( List idents)

Definition at line 1827 of file pl_comp.c.

References get_rel_type_id(), InvalidOid, linitial, list_length(), lsecond, makeRangeVar(), MemoryContextSwitchTo(), NoLock, NULL, plpgsql_build_datatype(), RangeVarGetRelid, and strVal.

1828 {
1829  Oid classOid;
1830  RangeVar *relvar;
1831  MemoryContext oldCxt;
1832 
1833  if (list_length(idents) != 2)
1834  return NULL;
1835 
1836  /* Avoid memory leaks in long-term function context */
1838 
1839  /* Look up relation name. Can't lock it - we might not have privileges. */
1840  relvar = makeRangeVar(strVal(linitial(idents)),
1841  strVal(lsecond(idents)),
1842  -1);
1843  classOid = RangeVarGetRelid(relvar, NoLock, false);
1844 
1845  MemoryContextSwitchTo(oldCxt);
1846 
1847  /* Build and return the row type struct */
1848  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1849 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2123
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:53
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
#define lsecond(l)
Definition: pg_list.h:114
#define linitial(l)
Definition: pg_list.h:110
#define NoLock
Definition: lockdefs.h:34
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1745
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:226
static int list_length(const List *l)
Definition: pg_list.h:89
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:55
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:419
PLpgSQL_type* plpgsql_parse_cwordtype ( List idents)

Definition at line 1689 of file pl_comp.c.

References build_datatype(), elog, ERROR, GETSTRUCT, HeapTupleIsValid, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, linitial, list_length(), lsecond, lthird, makeRangeVar(), MemoryContextSwitchTo(), NoLock, NULL, ObjectIdGetDatum, OidIsValid, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_VAR, RangeVarGetRelid, ReleaseSysCache(), RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, RelnameGetRelid(), RELOID, SearchSysCache1, SearchSysCacheAttName(), strVal, and TYPEOID.

1690 {
1691  PLpgSQL_type *dtype = NULL;
1692  PLpgSQL_nsitem *nse;
1693  const char *fldname;
1694  Oid classOid;
1695  HeapTuple classtup = NULL;
1696  HeapTuple attrtup = NULL;
1697  HeapTuple typetup = NULL;
1698  Form_pg_class classStruct;
1699  Form_pg_attribute attrStruct;
1700  MemoryContext oldCxt;
1701 
1702  /* Avoid memory leaks in the long-term function context */
1704 
1705  if (list_length(idents) == 2)
1706  {
1707  /*
1708  * Do a lookup in the current namespace stack. We don't need to check
1709  * number of names matched, because we will only consider scalar
1710  * variables.
1711  */
1712  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1713  strVal(linitial(idents)),
1714  strVal(lsecond(idents)),
1715  NULL,
1716  NULL);
1717 
1718  if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1719  {
1720  dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1721  goto done;
1722  }
1723 
1724  /*
1725  * First word could also be a table name
1726  */
1727  classOid = RelnameGetRelid(strVal(linitial(idents)));
1728  if (!OidIsValid(classOid))
1729  goto done;
1730  fldname = strVal(lsecond(idents));
1731  }
1732  else if (list_length(idents) == 3)
1733  {
1734  RangeVar *relvar;
1735 
1736  relvar = makeRangeVar(strVal(linitial(idents)),
1737  strVal(lsecond(idents)),
1738  -1);
1739  /* Can't lock relation - we might not have privileges. */
1740  classOid = RangeVarGetRelid(relvar, NoLock, true);
1741  if (!OidIsValid(classOid))
1742  goto done;
1743  fldname = strVal(lthird(idents));
1744  }
1745  else
1746  goto done;
1747 
1748  classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(classOid));
1749  if (!HeapTupleIsValid(classtup))
1750  goto done;
1751  classStruct = (Form_pg_class) GETSTRUCT(classtup);
1752 
1753  /*
1754  * It must be a relation, sequence, view, materialized view, composite
1755  * type, or foreign table
1756  */
1757  if (classStruct->relkind != RELKIND_RELATION &&
1758  classStruct->relkind != RELKIND_SEQUENCE &&
1759  classStruct->relkind != RELKIND_VIEW &&
1760  classStruct->relkind != RELKIND_MATVIEW &&
1761  classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
1762  classStruct->relkind != RELKIND_FOREIGN_TABLE)
1763  goto done;
1764 
1765  /*
1766  * Fetch the named table field and its type
1767  */
1768  attrtup = SearchSysCacheAttName(classOid, fldname);
1769  if (!HeapTupleIsValid(attrtup))
1770  goto done;
1771  attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1772 
1773  typetup = SearchSysCache1(TYPEOID,
1774  ObjectIdGetDatum(attrStruct->atttypid));
1775  if (!HeapTupleIsValid(typetup))
1776  elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1777 
1778  /*
1779  * Found that - build a compiler type struct in the caller's cxt and
1780  * return it
1781  */
1782  MemoryContextSwitchTo(oldCxt);
1783  dtype = build_datatype(typetup,
1784  attrStruct->atttypmod,
1785  attrStruct->attcollation);
1787 
1788 done:
1789  if (HeapTupleIsValid(classtup))
1790  ReleaseSysCache(classtup);
1791  if (HeapTupleIsValid(attrtup))
1792  ReleaseSysCache(attrtup);
1793  if (HeapTupleIsValid(typetup))
1794  ReleaseSysCache(typetup);
1795 
1796  MemoryContextSwitchTo(oldCxt);
1797  return dtype;
1798 }
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:653
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:53
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
#define RELKIND_MATVIEW
Definition: pg_class.h:167
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:533
#define lsecond(l)
Definition: pg_list.h:114
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:165
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define linitial(l)
Definition: pg_list.h:110
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:166
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
static int list_length(const List *l)
Definition: pg_list.h:89
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1171
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2143
#define RELKIND_VIEW
Definition: pg_class.h:164
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:55
#define lthird(l)
Definition: pg_list.h:118
#define elog
Definition: elog.h:219
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:419
bool plpgsql_parse_dblword ( char *  word1,
char *  word2,
PLwdatum wdatum,
PLcword cword 
)

Definition at line 1409 of file pl_comp.c.

References PLwdatum::datum, PLpgSQL_row::fieldnames, i, PLwdatum::ident, IDENTIFIER_LOOKUP_DECLARE, PLcword::idents, PLwdatum::idents, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, list_make2, makeString(), PLpgSQL_row::nfields, NULL, palloc(), plpgsql_adddatum(), PLPGSQL_DTYPE_RECFIELD, plpgsql_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_ROW, PLPGSQL_NSTYPE_VAR, pstrdup(), PLwdatum::quoted, and PLpgSQL_row::varnos.

Referenced by plpgsql_yylex().

1411 {
1412  PLpgSQL_nsitem *ns;
1413  List *idents;
1414  int nnames;
1415 
1416  idents = list_make2(makeString(word1),
1417  makeString(word2));
1418 
1419  /*
1420  * We should do nothing in DECLARE sections. In SQL expressions, we
1421  * really only need to make sure that RECFIELD datums are created when
1422  * needed.
1423  */
1425  {
1426  /*
1427  * Do a lookup in the current namespace stack
1428  */
1429  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1430  word1, word2, NULL,
1431  &nnames);
1432  if (ns != NULL)
1433  {
1434  switch (ns->itemtype)
1435  {
1436  case PLPGSQL_NSTYPE_VAR:
1437  /* Block-qualified reference to scalar variable. */
1438  wdatum->datum = plpgsql_Datums[ns->itemno];
1439  wdatum->ident = NULL;
1440  wdatum->quoted = false; /* not used */
1441  wdatum->idents = idents;
1442  return true;
1443 
1444  case PLPGSQL_NSTYPE_REC:
1445  if (nnames == 1)
1446  {
1447  /*
1448  * First word is a record name, so second word could
1449  * be a field in this record. We build a RECFIELD
1450  * datum whether it is or not --- any error will be
1451  * detected later.
1452  */
1453  PLpgSQL_recfield *new;
1454 
1455  new = palloc(sizeof(PLpgSQL_recfield));
1456  new->dtype = PLPGSQL_DTYPE_RECFIELD;
1457  new->fieldname = pstrdup(word2);
1458  new->recparentno = ns->itemno;
1459 
1461 
1462  wdatum->datum = (PLpgSQL_datum *) new;
1463  }
1464  else
1465  {
1466  /* Block-qualified reference to record variable. */
1467  wdatum->datum = plpgsql_Datums[ns->itemno];
1468  }
1469  wdatum->ident = NULL;
1470  wdatum->quoted = false; /* not used */
1471  wdatum->idents = idents;
1472  return true;
1473 
1474  case PLPGSQL_NSTYPE_ROW:
1475  if (nnames == 1)
1476  {
1477  /*
1478  * First word is a row name, so second word could be a
1479  * field in this row. Again, no error now if it
1480  * isn't.
1481  */
1482  PLpgSQL_row *row;
1483  int i;
1484 
1485  row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1486  for (i = 0; i < row->nfields; i++)
1487  {
1488  if (row->fieldnames[i] &&
1489  strcmp(row->fieldnames[i], word2) == 0)
1490  {
1491  wdatum->datum = plpgsql_Datums[row->varnos[i]];
1492  wdatum->ident = NULL;
1493  wdatum->quoted = false; /* not used */
1494  wdatum->idents = idents;
1495  return true;
1496  }
1497  }
1498  /* fall through to return CWORD */
1499  }
1500  else
1501  {
1502  /* Block-qualified reference to row variable. */
1503  wdatum->datum = plpgsql_Datums[ns->itemno];
1504  wdatum->ident = NULL;
1505  wdatum->quoted = false; /* not used */
1506  wdatum->idents = idents;
1507  return true;
1508  }
1509  break;
1510 
1511  default:
1512  break;
1513  }
1514  }
1515  }
1516 
1517  /* Nothing found */
1518  cword->idents = idents;
1519  return false;
1520 }
#define list_make2(x1, x2)
Definition: pg_list.h:134
Value * makeString(char *str)
Definition: value.c:53
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
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
char * pstrdup(const char *in)
Definition: mcxt.c:1165
char ** fieldnames
Definition: plpgsql.h:295
List * idents
Definition: plpgsql.h:996
List * idents
Definition: plpgsql.h:1004
int * varnos
Definition: plpgsql.h:296
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:27
#define NULL
Definition: c.h:226
int nfields
Definition: plpgsql.h:294
PLpgSQL_datum * datum
Definition: plpgsql.h:1001
bool quoted
Definition: plpgsql.h:1003
char * ident
Definition: plpgsql.h:1002
void * palloc(Size size)
Definition: mcxt.c:891
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2326
int i
Definition: pg_list.h:45
PLpgSQL_condition* plpgsql_parse_err_condition ( char *  condname)

Definition at line 2258 of file pl_comp.c.

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

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

Definition at line 1529 of file pl_comp.c.

References PLwdatum::datum, PLpgSQL_row::fieldnames, i, PLwdatum::ident, IDENTIFIER_LOOKUP_DECLARE, PLcword::idents, PLwdatum::idents, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, list_make3, makeString(), PLpgSQL_row::nfields, NULL, palloc(), plpgsql_adddatum(), PLPGSQL_DTYPE_RECFIELD, plpgsql_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_ROW, pstrdup(), PLwdatum::quoted, and PLpgSQL_row::varnos.

Referenced by plpgsql_yylex().

1531 {
1532  PLpgSQL_nsitem *ns;
1533  List *idents;
1534  int nnames;
1535 
1536  idents = list_make3(makeString(word1),
1537  makeString(word2),
1538  makeString(word3));
1539 
1540  /*
1541  * We should do nothing in DECLARE sections. In SQL expressions, we
1542  * really only need to make sure that RECFIELD datums are created when
1543  * needed.
1544  */
1546  {
1547  /*
1548  * Do a lookup in the current namespace stack. Must find a qualified
1549  * reference, else ignore.
1550  */
1551  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1552  word1, word2, word3,
1553  &nnames);
1554  if (ns != NULL && nnames == 2)
1555  {
1556  switch (ns->itemtype)
1557  {
1558  case PLPGSQL_NSTYPE_REC:
1559  {
1560  /*
1561  * words 1/2 are a record name, so third word could be
1562  * a field in this record.
1563  */
1564  PLpgSQL_recfield *new;
1565 
1566  new = palloc(sizeof(PLpgSQL_recfield));
1567  new->dtype = PLPGSQL_DTYPE_RECFIELD;
1568  new->fieldname = pstrdup(word3);
1569  new->recparentno = ns->itemno;
1570 
1572 
1573  wdatum->datum = (PLpgSQL_datum *) new;
1574  wdatum->ident = NULL;
1575  wdatum->quoted = false; /* not used */
1576  wdatum->idents = idents;
1577  return true;
1578  }
1579 
1580  case PLPGSQL_NSTYPE_ROW:
1581  {
1582  /*
1583  * words 1/2 are a row name, so third word could be a
1584  * field in this row.
1585  */
1586  PLpgSQL_row *row;
1587  int i;
1588 
1589  row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
1590  for (i = 0; i < row->nfields; i++)
1591  {
1592  if (row->fieldnames[i] &&
1593  strcmp(row->fieldnames[i], word3) == 0)
1594  {
1595  wdatum->datum = plpgsql_Datums[row->varnos[i]];
1596  wdatum->ident = NULL;
1597  wdatum->quoted = false; /* not used */
1598  wdatum->idents = idents;
1599  return true;
1600  }
1601  }
1602  /* fall through to return CWORD */
1603  break;
1604  }
1605 
1606  default:
1607  break;
1608  }
1609  }
1610  }
1611 
1612  /* Nothing found */
1613  cword->idents = idents;
1614  return false;
1615 }
Value * makeString(char *str)
Definition: value.c:53
#define list_make3(x1, x2, x3)
Definition: pg_list.h:135
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
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
char * pstrdup(const char *in)
Definition: mcxt.c:1165
char ** fieldnames
Definition: plpgsql.h:295
List * idents
Definition: plpgsql.h:996
List * idents
Definition: plpgsql.h:1004
int * varnos
Definition: plpgsql.h:296
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:27
#define NULL
Definition: c.h:226
int nfields
Definition: plpgsql.h:294
PLpgSQL_datum * datum
Definition: plpgsql.h:1001
bool quoted
Definition: plpgsql.h:1003
char * ident
Definition: plpgsql.h:1002
void * palloc(Size size)
Definition: mcxt.c:891
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2326
int i
Definition: pg_list.h:45
bool plpgsql_parse_word ( char *  word1,
const char *  yytxt,
PLwdatum wdatum,
PLword word 
)

Definition at line 1353 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

1355 {
1356  PLpgSQL_nsitem *ns;
1357 
1358  /*
1359  * We should do nothing in DECLARE sections. In SQL expressions, there's
1360  * no need to do anything either --- lookup will happen when the
1361  * expression is compiled.
1362  */
1364  {
1365  /*
1366  * Do a lookup in the current namespace stack
1367  */
1368  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1369  word1, NULL, NULL,
1370  NULL);
1371 
1372  if (ns != NULL)
1373  {
1374  switch (ns->itemtype)
1375  {
1376  case PLPGSQL_NSTYPE_VAR:
1377  case PLPGSQL_NSTYPE_ROW:
1378  case PLPGSQL_NSTYPE_REC:
1379  wdatum->datum = plpgsql_Datums[ns->itemno];
1380  wdatum->ident = word1;
1381  wdatum->quoted = (yytxt[0] == '"');
1382  wdatum->idents = NIL;
1383  return true;
1384 
1385  default:
1386  /* plpgsql_ns_lookup should never return anything else */
1387  elog(ERROR, "unrecognized plpgsql itemtype: %d",
1388  ns->itemtype);
1389  }
1390  }
1391  }
1392 
1393  /*
1394  * Nothing found - up to now it's a word without any special meaning for
1395  * us.
1396  */
1397  word->ident = word1;
1398  word->quoted = (yytxt[0] == '"');
1399  return false;
1400 }
#define NIL
Definition: pg_list.h:69
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
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
char * ident
Definition: plpgsql.h:990
#define ERROR
Definition: elog.h:43
List * idents
Definition: plpgsql.h:1004
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:27
bool quoted
Definition: plpgsql.h:991
#define NULL
Definition: c.h:226
PLpgSQL_datum * datum
Definition: plpgsql.h:1001
bool quoted
Definition: plpgsql.h:1003
char * ident
Definition: plpgsql.h:1002
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
#define elog
Definition: elog.h:219
PLpgSQL_type* plpgsql_parse_wordrowtype ( char *  ident)

Definition at line 1806 of file pl_comp.c.

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

1807 {
1808  Oid classOid;
1809 
1810  /* Lookup the relation */
1811  classOid = RelnameGetRelid(ident);
1812  if (!OidIsValid(classOid))
1813  ereport(ERROR,
1815  errmsg("relation \"%s\" does not exist", ident)));
1816 
1817  /* Build and return the row type struct */
1818  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1819 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2123
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:61
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:653
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:533
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1745
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
PLpgSQL_type* plpgsql_parse_wordtype ( char *  ident)

Definition at line 1626 of file pl_comp.c.

References build_datatype(), PLpgSQL_function::fn_input_collation, GETSTRUCT, InvalidOid, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, LookupTypeName(), makeTypeName(), NULL, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_VAR, and ReleaseSysCache().

1627 {
1628  PLpgSQL_type *dtype;
1629  PLpgSQL_nsitem *nse;
1630  HeapTuple typeTup;
1631 
1632  /*
1633  * Do a lookup in the current namespace stack
1634  */
1635  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1636  ident, NULL, NULL,
1637  NULL);
1638 
1639  if (nse != NULL)
1640  {
1641  switch (nse->itemtype)
1642  {
1643  case PLPGSQL_NSTYPE_VAR:
1644  return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1645 
1646  /* XXX perhaps allow REC/ROW here? */
1647 
1648  default:
1649  return NULL;
1650  }
1651  }
1652 
1653  /*
1654  * Word wasn't found in the namespace stack. Try to find a data type with
1655  * that name, but ignore shell types and complex types.
1656  */
1657  typeTup = LookupTypeName(NULL, makeTypeName(ident), NULL, false);
1658  if (typeTup)
1659  {
1660  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1661 
1662  if (!typeStruct->typisdefined ||
1663  typeStruct->typrelid != InvalidOid)
1664  {
1665  ReleaseSysCache(typeTup);
1666  return NULL;
1667  }
1668 
1669  dtype = build_datatype(typeTup, -1,
1671 
1672  ReleaseSysCache(typeTup);
1673  return dtype;
1674  }
1675 
1676  /*
1677  * Nothing found - up to now it's a word without any special meaning for
1678  * us.
1679  */
1680  return NULL;
1681 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:57
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
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
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
Oid fn_input_collation
Definition: plpgsql.h:826
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define InvalidOid
Definition: postgres_ext.h:36
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:441
#define NULL
Definition: c.h:226
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2143
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:52
void plpgsql_parser_setup ( struct ParseState pstate,
PLpgSQL_expr expr 
)

Definition at line 1016 of file pl_comp.c.

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(), plpgsql_estate_setup(), and setup_unshared_param_list().

1017 {
1021  /* no need to use p_coerce_param_hook */
1022  pstate->p_ref_hook_state = (void *) expr;
1023 }
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1029
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:203
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:204
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1087
void * p_ref_hook_state
Definition: parse_node.h:206
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:202
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1043
static Node * plpgsql_post_column_ref ( ParseState pstate,
ColumnRef cref,
Node var 
)
static

Definition at line 1043 of file pl_comp.c.

References ereport, errcode(), errdetail(), errmsg(), ERROR, ColumnRef::fields, PLpgSQL_expr::func, ColumnRef::location, NameListToString(), NULL, 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().

1044 {
1045  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1046  Node *myvar;
1047 
1049  return NULL; /* we already found there's no match */
1050 
1051  if (expr->func->resolve_option == PLPGSQL_RESOLVE_COLUMN && var != NULL)
1052  return NULL; /* there's a table column, prefer that */
1053 
1054  /*
1055  * If we find a record/row variable but can't match a field name, throw
1056  * error if there was no core resolution for the ColumnRef either. In
1057  * that situation, the reference is inevitably going to fail, and
1058  * complaining about the record/row variable is likely to be more on-point
1059  * than the core parser's error message. (It's too bad we don't have
1060  * access to transformColumnRef's internal crerr state here, as in case of
1061  * a conflict with a table name this could still be less than the most
1062  * helpful error message possible.)
1063  */
1064  myvar = resolve_column_ref(pstate, expr, cref, (var == NULL));
1065 
1066  if (myvar != NULL && var != NULL)
1067  {
1068  /*
1069  * We could leave it to the core parser to throw this error, but we
1070  * can add a more useful detail message than the core could.
1071  */
1072  ereport(ERROR,
1073  (errcode(ERRCODE_AMBIGUOUS_COLUMN),
1074  errmsg("column reference \"%s\" is ambiguous",
1075  NameListToString(cref->fields)),
1076  errdetail("It could refer to either a PL/pgSQL variable or a table column."),
1077  parser_errposition(pstate, cref->location)));
1078  }
1079 
1080  return myvar;
1081 }
Definition: nodes.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
PLpgSQL_resolve_option resolve_option
Definition: plpgsql.h:858
int location
Definition: parsenodes.h:227
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
struct PLpgSQL_function * func
Definition: plpgsql.h:231
#define NULL
Definition: c.h:226
void * p_ref_hook_state
Definition: parse_node.h:206
static Node * resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
Definition: pl_comp.c:1114
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:109
int errmsg(const char *fmt,...)
Definition: elog.c:797
List * fields
Definition: parsenodes.h:226
static Node * plpgsql_pre_column_ref ( ParseState pstate,
ColumnRef cref 
)
static

Definition at line 1029 of file pl_comp.c.

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

Referenced by plpgsql_parser_setup().

1030 {
1031  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1032 
1034  return resolve_column_ref(pstate, expr, cref, false);
1035  else
1036  return NULL;
1037 }
PLpgSQL_resolve_option resolve_option
Definition: plpgsql.h:858
struct PLpgSQL_function * func
Definition: plpgsql.h:231
#define NULL
Definition: c.h:226
void * p_ref_hook_state
Definition: parse_node.h:206
static Node * resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
Definition: pl_comp.c:1114
int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2222 of file pl_comp.c.

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

Referenced by exec_stmt_raise().

2223 {
2224  int i;
2225 
2226  if (allow_sqlstate)
2227  {
2228  if (strlen(condname) == 5 &&
2229  strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2230  return MAKE_SQLSTATE(condname[0],
2231  condname[1],
2232  condname[2],
2233  condname[3],
2234  condname[4]);
2235  }
2236 
2237  for (i = 0; exception_label_map[i].label != NULL; i++)
2238  {
2239  if (strcmp(condname, exception_label_map[i].label) == 0)
2241  }
2242 
2243  ereport(ERROR,
2244  (errcode(ERRCODE_UNDEFINED_OBJECT),
2245  errmsg("unrecognized exception condition \"%s\"",
2246  condname)));
2247  return 0; /* keep compiler quiet */
2248 }
const char * label
Definition: pl_comp.c:77
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:62
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static char * label
Definition: pg_basebackup.c:84
#define NULL
Definition: c.h:226
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:81
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
static void plpgsql_resolve_polymorphic_argtypes ( int  numargs,
Oid argtypes,
char *  argmodes,
Node call_expr,
bool  forValidator,
const char *  proname 
)
static

Definition at line 2491 of file pl_comp.c.

References ANYARRAYOID, ANYELEMENTOID, ANYENUMOID, ANYNONARRAYOID, ANYRANGEOID, ereport, errcode(), errmsg(), ERROR, i, INT4ARRAYOID, INT4OID, INT4RANGEOID, and resolve_polymorphic_argtypes().

Referenced by compute_function_hashkey(), and do_compile().

2495 {
2496  int i;
2497 
2498  if (!forValidator)
2499  {
2500  /* normal case, pass to standard routine */
2501  if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
2502  call_expr))
2503  ereport(ERROR,
2504  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2505  errmsg("could not determine actual argument "
2506  "type for polymorphic function \"%s\"",
2507  proname)));
2508  }
2509  else
2510  {
2511  /* special validation case */
2512  for (i = 0; i < numargs; i++)
2513  {
2514  switch (argtypes[i])
2515  {
2516  case ANYELEMENTOID:
2517  case ANYNONARRAYOID:
2518  case ANYENUMOID: /* XXX dubious */
2519  argtypes[i] = INT4OID;
2520  break;
2521  case ANYARRAYOID:
2522  argtypes[i] = INT4ARRAYOID;
2523  break;
2524  case ANYRANGEOID:
2525  argtypes[i] = INT4RANGEOID;
2526  break;
2527  default:
2528  break;
2529  }
2530  }
2531  }
2532 }
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
Definition: funcapi.c:597
#define ANYNONARRAYOID
Definition: pg_type.h:692
#define ANYELEMENTOID
Definition: pg_type.h:690
#define INT4OID
Definition: pg_type.h:316
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ANYRANGEOID
Definition: pg_type.h:702
#define INT4RANGEOID
Definition: pg_type.h:636
#define ANYENUMOID
Definition: pg_type.h:694
#define ereport(elevel, rest)
Definition: elog.h:122
#define ANYARRAYOID
Definition: pg_type.h:676
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define INT4ARRAYOID
Definition: pg_type.h:456
static void plpgsql_start_datums ( void  )
static

Definition at line 2309 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

2310 {
2311  datums_alloc = 128;
2312  plpgsql_nDatums = 0;
2313  /* This is short-lived, so needn't allocate in function's cxt */
2315  sizeof(PLpgSQL_datum *) * datums_alloc);
2316  /* datums_last tracks what's been seen by plpgsql_add_initdatums() */
2317  datums_last = 0;
2318 }
int plpgsql_nDatums
Definition: pl_comp.c:44
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
static int datums_alloc
Definition: pl_comp.c:43
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:55
static int datums_last
Definition: pl_comp.c:46
static Node * resolve_column_ref ( ParseState pstate,
PLpgSQL_expr expr,
ColumnRef cref,
bool  error_if_no_field 
)
static

Definition at line 1114 of file pl_comp.c.

References Assert, PLpgSQL_function::cur_estate, PLpgSQL_execstate::datums, PLpgSQL_recfield::dtype, elog, ereport, errcode(), errmsg(), ERROR, PLpgSQL_recfield::fieldname, PLpgSQL_row::fieldnames, ColumnRef::fields, PLpgSQL_expr::func, i, IsA, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, linitial, list_length(), ColumnRef::location, lsecond, lthird, make_datum_param(), PLpgSQL_execstate::ndatums, PLpgSQL_row::nfields, PLpgSQL_expr::ns, NULL, parser_errposition(), PLPGSQL_DTYPE_RECFIELD, plpgsql_ns_lookup(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_ROW, PLPGSQL_NSTYPE_VAR, PLpgSQL_recfield::recparentno, strVal, and PLpgSQL_row::varnos.

Referenced by plpgsql_post_column_ref(), and plpgsql_pre_column_ref().

1116 {
1117  PLpgSQL_execstate *estate;
1118  PLpgSQL_nsitem *nse;
1119  const char *name1;
1120  const char *name2 = NULL;
1121  const char *name3 = NULL;
1122  const char *colname = NULL;
1123  int nnames;
1124  int nnames_scalar = 0;
1125  int nnames_wholerow = 0;
1126  int nnames_field = 0;
1127 
1128  /*
1129  * We use the function's current estate to resolve parameter data types.
1130  * This is really pretty bogus because there is no provision for updating
1131  * plans when those types change ...
1132  */
1133  estate = expr->func->cur_estate;
1134 
1135  /*----------
1136  * The allowed syntaxes are:
1137  *
1138  * A Scalar variable reference, or whole-row record reference.
1139  * A.B Qualified scalar or whole-row reference, or field reference.
1140  * A.B.C Qualified record field reference.
1141  * A.* Whole-row record reference.
1142  * A.B.* Qualified whole-row record reference.
1143  *----------
1144  */
1145  switch (list_length(cref->fields))
1146  {
1147  case 1:
1148  {
1149  Node *field1 = (Node *) linitial(cref->fields);
1150 
1151  Assert(IsA(field1, String));
1152  name1 = strVal(field1);
1153  nnames_scalar = 1;
1154  nnames_wholerow = 1;
1155  break;
1156  }
1157  case 2:
1158  {
1159  Node *field1 = (Node *) linitial(cref->fields);
1160  Node *field2 = (Node *) lsecond(cref->fields);
1161 
1162  Assert(IsA(field1, String));
1163  name1 = strVal(field1);
1164 
1165  /* Whole-row reference? */
1166  if (IsA(field2, A_Star))
1167  {
1168  /* Set name2 to prevent matches to scalar variables */
1169  name2 = "*";
1170  nnames_wholerow = 1;
1171  break;
1172  }
1173 
1174  Assert(IsA(field2, String));
1175  name2 = strVal(field2);
1176  colname = name2;
1177  nnames_scalar = 2;
1178  nnames_wholerow = 2;
1179  nnames_field = 1;
1180  break;
1181  }
1182  case 3:
1183  {
1184  Node *field1 = (Node *) linitial(cref->fields);
1185  Node *field2 = (Node *) lsecond(cref->fields);
1186  Node *field3 = (Node *) lthird(cref->fields);
1187 
1188  Assert(IsA(field1, String));
1189  name1 = strVal(field1);
1190  Assert(IsA(field2, String));
1191  name2 = strVal(field2);
1192 
1193  /* Whole-row reference? */
1194  if (IsA(field3, A_Star))
1195  {
1196  /* Set name3 to prevent matches to scalar variables */
1197  name3 = "*";
1198  nnames_wholerow = 2;
1199  break;
1200  }
1201 
1202  Assert(IsA(field3, String));
1203  name3 = strVal(field3);
1204  colname = name3;
1205  nnames_field = 2;
1206  break;
1207  }
1208  default:
1209  /* too many names, ignore */
1210  return NULL;
1211  }
1212 
1213  nse = plpgsql_ns_lookup(expr->ns, false,
1214  name1, name2, name3,
1215  &nnames);
1216 
1217  if (nse == NULL)
1218  return NULL; /* name not known to plpgsql */
1219 
1220  switch (nse->itemtype)
1221  {
1222  case PLPGSQL_NSTYPE_VAR:
1223  if (nnames == nnames_scalar)
1224  return make_datum_param(expr, nse->itemno, cref->location);
1225  break;
1226  case PLPGSQL_NSTYPE_REC:
1227  if (nnames == nnames_wholerow)
1228  return make_datum_param(expr, nse->itemno, cref->location);
1229  if (nnames == nnames_field)
1230  {
1231  /* colname could be a field in this record */
1232  int i;
1233 
1234  /* search for a datum referencing this field */
1235  for (i = 0; i < estate->ndatums; i++)
1236  {
1237  PLpgSQL_recfield *fld = (PLpgSQL_recfield *) estate->datums[i];
1238 
1239  if (fld->dtype == PLPGSQL_DTYPE_RECFIELD &&
1240  fld->recparentno == nse->itemno &&
1241  strcmp(fld->fieldname, colname) == 0)
1242  {
1243  return make_datum_param(expr, i, cref->location);
1244  }
1245  }
1246 
1247  /*
1248  * We should not get here, because a RECFIELD datum should
1249  * have been built at parse time for every possible qualified
1250  * reference to fields of this record. But if we do, handle
1251  * it like field-not-found: throw error or return NULL.
1252  */
1253  if (error_if_no_field)
1254  ereport(ERROR,
1255  (errcode(ERRCODE_UNDEFINED_COLUMN),
1256  errmsg("record \"%s\" has no field \"%s\"",
1257  (nnames_field == 1) ? name1 : name2,
1258  colname),
1259  parser_errposition(pstate, cref->location)));
1260  }
1261  break;
1262  case PLPGSQL_NSTYPE_ROW:
1263  if (nnames == nnames_wholerow)
1264  return make_datum_param(expr, nse->itemno, cref->location);
1265  if (nnames == nnames_field)
1266  {
1267  /* colname could be a field in this row */
1268  PLpgSQL_row *row = (PLpgSQL_row *) estate->datums[nse->itemno];
1269  int i;
1270 
1271  for (i = 0; i < row->nfields; i++)
1272  {
1273  if (row->fieldnames[i] &&
1274  strcmp(row->fieldnames[i], colname) == 0)
1275  {
1276  return make_datum_param(expr, row->varnos[i],
1277  cref->location);
1278  }
1279  }
1280  /* Not found, so throw error or return NULL */
1281  if (error_if_no_field)
1282  ereport(ERROR,
1283  (errcode(ERRCODE_UNDEFINED_COLUMN),
1284  errmsg("record \"%s\" has no field \"%s\"",
1285  (nnames_field == 1) ? name1 : name2,
1286  colname),
1287  parser_errposition(pstate, cref->location)));
1288  }
1289  break;
1290  default:
1291  elog(ERROR, "unrecognized plpgsql itemtype: %d", nse->itemtype);
1292  }
1293 
1294  /* Name format doesn't match the plpgsql variable type */
1295  return NULL;
1296 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
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
Definition: nodes.h:508
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lsecond(l)
Definition: pg_list.h:114
PLpgSQL_datum ** datums
Definition: plpgsql.h:909
int location
Definition: parsenodes.h:227
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
char ** fieldnames
Definition: plpgsql.h:295
struct PLpgSQL_execstate * cur_estate
Definition: plpgsql.h:875
struct PLpgSQL_nsitem * ns
Definition: plpgsql.h:234
#define ereport(elevel, rest)
Definition: elog.h:122
int * varnos
Definition: plpgsql.h:296
PLpgSQL_datum_type dtype
Definition: plpgsql.h:320
struct PLpgSQL_function * func
Definition: plpgsql.h:231
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
int nfields
Definition: plpgsql.h:294
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:109
int errmsg(const char *fmt,...)
Definition: elog.c:797
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
int i
#define lthird(l)
Definition: pg_list.h:118
#define elog
Definition: elog.h:219
char * fieldname
Definition: plpgsql.h:322
List * fields
Definition: parsenodes.h:226
static Node * make_datum_param(PLpgSQL_expr *expr, int dno, int location)
Definition: pl_comp.c:1303

Variable Documentation

int datums_alloc
static

Definition at line 43 of file pl_comp.c.

Referenced by plpgsql_adddatum(), and plpgsql_start_datums().

int datums_last
static

Definition at line 46 of file pl_comp.c.

Referenced by plpgsql_add_initdatums(), and plpgsql_start_datums().

const ExceptionLabelMap exception_label_map[]
static
Initial value:
= {
{NULL, 0}
}
#define NULL
Definition: c.h:226

Definition at line 81 of file pl_comp.c.

bool plpgsql_check_syntax = false

Definition at line 50 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().

MemoryContext plpgsql_compile_tmp_cxt

Definition at line 55 of file pl_comp.c.

PLpgSQL_function* plpgsql_curr_compile

Definition at line 52 of file pl_comp.c.

PLpgSQL_datum** plpgsql_Datums

Definition at line 45 of file pl_comp.c.

bool plpgsql_DumpExecTree = false

Definition at line 49 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().

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().

HTAB* plpgsql_HashTable = NULL
static

Definition at line 61 of file pl_comp.c.

int plpgsql_nDatums
PLpgSQL_stmt_block* plpgsql_parse_result

Definition at line 41 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().