PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pl_comp.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_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 "plpgsql.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 71 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 977 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().

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

Definition at line 952 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().

953 {
954  /*
955  * Before adding the name, check for duplicates. We need this even though
956  * functioncmds.c has a similar check, because that code explicitly
957  * doesn't complain about conflicting IN and OUT parameter names. In
958  * plpgsql, such names are in the same namespace, so there is no way to
959  * disambiguate.
960  */
961  if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
962  name, NULL, NULL,
963  NULL) != NULL)
964  ereport(ERROR,
965  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
966  errmsg("parameter name \"%s\" used more than once",
967  name)));
968 
969  /* OK, add the name */
970  plpgsql_ns_additem(itemtype, itemno, name);
971 }
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
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:132
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
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:229
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 2145 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().

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

Definition at line 1966 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().

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

Definition at line 2061 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().

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

Definition at line 2441 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(), TriggerData::tg_trigger, Trigger::tgoid, and PLpgSQL_func_hashkey::trigOid.

Referenced by plpgsql_compile().

2445 {
2446  /* Make sure any unused bytes of the struct are zero */
2447  MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
2448 
2449  /* get function OID */
2450  hashkey->funcOid = fcinfo->flinfo->fn_oid;
2451 
2452  /* get call context */
2453  hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
2454 
2455  /*
2456  * if trigger, get its OID. In validation mode we do not know what
2457  * relation or transition table names are intended to be used, so we leave
2458  * trigOid zero; the hash entry built in this case will never really be
2459  * used.
2460  */
2461  if (hashkey->isTrigger && !forValidator)
2462  {
2463  TriggerData *trigdata = (TriggerData *) fcinfo->context;
2464 
2465  hashkey->trigOid = trigdata->tg_trigger->tgoid;
2466  }
2467 
2468  /* get input collation, if known */
2469  hashkey->inputCollation = fcinfo->fncollation;
2470 
2471  if (procStruct->pronargs > 0)
2472  {
2473  /* get the argument types */
2474  memcpy(hashkey->argtypes, procStruct->proargtypes.values,
2475  procStruct->pronargs * sizeof(Oid));
2476 
2477  /* resolve any polymorphic argument types */
2478  plpgsql_resolve_polymorphic_argtypes(procStruct->pronargs,
2479  hashkey->argtypes,
2480  NULL,
2481  fcinfo->flinfo->fn_expr,
2482  forValidator,
2483  NameStr(procStruct->proname));
2484  }
2485 }
Oid argtypes[FUNC_MAX_ARGS]
Definition: plpgsql.h:801
fmNodePtr context
Definition: fmgr.h:80
Oid tgoid
Definition: reltrigger.h:25
#define MemSet(start, val, len)
Definition: c.h:857
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:2494
FmgrInfo * flinfo
Definition: fmgr.h:79
Trigger * tg_trigger
Definition: trigger.h:37
Oid fn_oid
Definition: fmgr.h:59
#define NULL
Definition: c.h:229
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:25
fmNodePtr fn_expr
Definition: fmgr.h:66
#define NameStr(name)
Definition: c.h:499
static void delete_function ( PLpgSQL_function func)
static

Definition at line 2552 of file pl_comp.c.

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

Referenced by plpgsql_compile().

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

Definition at line 265 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().

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

Definition at line 1305 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().

1306 {
1307  PLpgSQL_execstate *estate;
1308  PLpgSQL_datum *datum;
1309  Param *param;
1310  MemoryContext oldcontext;
1311 
1312  /* see comment in resolve_column_ref */
1313  estate = expr->func->cur_estate;
1314  Assert(dno >= 0 && dno < estate->ndatums);
1315  datum = estate->datums[dno];
1316 
1317  /*
1318  * Bitmapset must be allocated in function's permanent memory context
1319  */
1320  oldcontext = MemoryContextSwitchTo(expr->func->fn_cxt);
1321  expr->paramnos = bms_add_member(expr->paramnos, dno);
1322  MemoryContextSwitchTo(oldcontext);
1323 
1324  param = makeNode(Param);
1325  param->paramkind = PARAM_EXTERN;
1326  param->paramid = dno + 1;
1328  datum,
1329  &param->paramtype,
1330  &param->paramtypmod,
1331  &param->paramcollid);
1332  param->location = location;
1333 
1334  return (Node *) param;
1335 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ParamKind paramkind
Definition: primnodes.h:244
Definition: nodes.h:509
PLpgSQL_datum ** datums
Definition: plpgsql.h:907
Bitmapset * paramnos
Definition: plpgsql.h:225
struct PLpgSQL_execstate * cur_estate
Definition: plpgsql.h:873
Oid paramcollid
Definition: primnodes.h:248
int location
Definition: primnodes.h:249
MemoryContext fn_cxt
Definition: plpgsql.h:826
void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeid, int32 *typmod, Oid *collation)
Definition: pl_exec.c:5020
struct PLpgSQL_function * func
Definition: plpgsql.h:229
int32 paramtypmod
Definition: primnodes.h:247
#define makeNode(_type_)
Definition: nodes.h:557
#define Assert(condition)
Definition: c.h:675
int paramid
Definition: primnodes.h:245
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
Oid paramtype
Definition: primnodes.h:246
int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2389 of file pl_comp.c.

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

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

Definition at line 2328 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().

2329 {
2331  {
2332  datums_alloc *= 2;
2334  }
2335 
2336  new->dno = plpgsql_nDatums;
2338 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
static int datums_alloc
Definition: pl_comp.c:45
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
PLpgSQL_type* plpgsql_build_datatype ( Oid  typeOid,
int32  typmod,
Oid  collation 
)

Definition at line 2125 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().

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

Definition at line 1943 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().

1944 {
1945  PLpgSQL_rec *rec;
1946 
1947  rec = palloc0(sizeof(PLpgSQL_rec));
1948  rec->dtype = PLPGSQL_DTYPE_REC;
1949  rec->refname = pstrdup(refname);
1950  rec->lineno = lineno;
1951  rec->tup = NULL;
1952  rec->tupdesc = NULL;
1953  rec->freetup = false;
1954  rec->freetupdesc = false;
1956  if (add2namespace)
1958 
1959  return rec;
1960 }
PLpgSQL_datum_type dtype
Definition: plpgsql.h:302
TupleDesc tupdesc
Definition: plpgsql.h:308
char * pstrdup(const char *in)
Definition: mcxt.c:1077
bool freetup
Definition: plpgsql.h:309
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
char * refname
Definition: plpgsql.h:304
void * palloc0(Size size)
Definition: mcxt.c:878
#define NULL
Definition: c.h:229
bool freetupdesc
Definition: plpgsql.h:310
HeapTuple tup
Definition: plpgsql.h:307
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2328
int lineno
Definition: plpgsql.h:305
PLpgSQL_variable* plpgsql_build_variable ( const char *  refname,
int  lineno,
PLpgSQL_type dtype,
bool  add2namespace 
)

Definition at line 1863 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, result, 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().

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

Definition at line 137 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().

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

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

Definition at line 794 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().

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

Definition at line 2348 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().

2349 {
2350  Bitmapset *resettable_datums = NULL;
2351  int i;
2352 
2353  function->ndatums = plpgsql_nDatums;
2354  function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
2355  for (i = 0; i < plpgsql_nDatums; i++)
2356  {
2357  function->datums[i] = plpgsql_Datums[i];
2358  switch (function->datums[i]->dtype)
2359  {
2360  case PLPGSQL_DTYPE_ROW:
2361  case PLPGSQL_DTYPE_REC:
2363  resettable_datums = bms_add_member(resettable_datums, i);
2364  break;
2365 
2366  default:
2367  break;
2368  }
2369  }
2370  function->resettable_datums = resettable_datums;
2371 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** datums
Definition: plpgsql.h:866
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_datum_type dtype
Definition: plpgsql.h:198
#define NULL
Definition: c.h:229
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
void * palloc(Size size)
Definition: mcxt.c:849
int i
static void plpgsql_HashTableDelete ( PLpgSQL_function function)
static

Definition at line 2615 of file pl_comp.c.

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

Referenced by delete_function().

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

Definition at line 2564 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().

2565 {
2566  HASHCTL ctl;
2567 
2568  /* don't allow double-initialization */
2570 
2571  memset(&ctl, 0, sizeof(ctl));
2572  ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2573  ctl.entrysize = sizeof(plpgsql_HashEnt);
2574  plpgsql_HashTable = hash_create("PLpgSQL function cache",
2576  &ctl,
2577  HASH_ELEM | HASH_BLOBS);
2578 }
#define FUNCS_PER_USER
Definition: pl_comp.c:71
#define HASH_ELEM
Definition: hsearch.h:87
Size entrysize
Definition: hsearch.h:73
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:63
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:229
#define Assert(condition)
Definition: c.h:675
static void plpgsql_HashTableInsert ( PLpgSQL_function function,
PLpgSQL_func_hashkey func_key 
)
static

Definition at line 2596 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().

2598 {
2599  plpgsql_HashEnt *hentry;
2600  bool found;
2601 
2603  (void *) func_key,
2604  HASH_ENTER,
2605  &found);
2606  if (found)
2607  elog(WARNING, "trying to insert a function that already exists");
2608 
2609  hentry->function = function;
2610  /* prepare back link from function to hashtable key */
2611  function->fn_hashkey = &hentry->key;
2612 }
PLpgSQL_func_hashkey * fn_hashkey
Definition: plpgsql.h:825
PLpgSQL_func_hashkey key
Definition: pl_comp.c:67
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:63
PLpgSQL_function * function
Definition: pl_comp.c:68
#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 2581 of file pl_comp.c.

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

Referenced by plpgsql_compile().

2582 {
2583  plpgsql_HashEnt *hentry;
2584 
2586  (void *) func_key,
2587  HASH_FIND,
2588  NULL);
2589  if (hentry)
2590  return hentry->function;
2591  else
2592  return NULL;
2593 }
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:63
PLpgSQL_function * function
Definition: pl_comp.c:68
#define NULL
Definition: c.h:229
static Node * plpgsql_param_ref ( ParseState pstate,
ParamRef pref 
)
static

Definition at line 1089 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().

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

Definition at line 1829 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.

1830 {
1831  Oid classOid;
1832  RangeVar *relvar;
1833  MemoryContext oldCxt;
1834 
1835  if (list_length(idents) != 2)
1836  return NULL;
1837 
1838  /* Avoid memory leaks in long-term function context */
1840 
1841  /* Look up relation name. Can't lock it - we might not have privileges. */
1842  relvar = makeRangeVar(strVal(linitial(idents)),
1843  strVal(lsecond(idents)),
1844  -1);
1845  classOid = RangeVarGetRelid(relvar, NoLock, false);
1846 
1847  MemoryContextSwitchTo(oldCxt);
1848 
1849  /* Build and return the row type struct */
1850  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1851 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2125
#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:116
#define linitial(l)
Definition: pg_list.h:111
#define NoLock
Definition: lockdefs.h:34
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1777
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
static int list_length(const List *l)
Definition: pg_list.h:89
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:419
PLpgSQL_type* plpgsql_parse_cwordtype ( List idents)

Definition at line 1691 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.

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

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

Definition at line 2260 of file pl_comp.c.

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

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

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

Definition at line 1355 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().

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

Definition at line 1808 of file pl_comp.c.

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

1809 {
1810  Oid classOid;
1811 
1812  /* Lookup the relation */
1813  classOid = RelnameGetRelid(ident);
1814  if (!OidIsValid(classOid))
1815  ereport(ERROR,
1817  errmsg("relation \"%s\" does not exist", ident)));
1818 
1819  /* Build and return the row type struct */
1820  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1821 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2125
#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:538
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1777
#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 1628 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().

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

Definition at line 1018 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().

1019 {
1023  /* no need to use p_coerce_param_hook */
1024  pstate->p_ref_hook_state = (void *) expr;
1025 }
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1031
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:206
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:207
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1089
void * p_ref_hook_state
Definition: parse_node.h:209
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:205
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1045
static Node * plpgsql_post_column_ref ( ParseState pstate,
ColumnRef cref,
Node var 
)
static

Definition at line 1045 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().

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

Definition at line 1031 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().

1032 {
1033  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1034 
1036  return resolve_column_ref(pstate, expr, cref, false);
1037  else
1038  return NULL;
1039 }
PLpgSQL_resolve_option resolve_option
Definition: plpgsql.h:856
struct PLpgSQL_function * func
Definition: plpgsql.h:229
#define NULL
Definition: c.h:229
void * p_ref_hook_state
Definition: parse_node.h:209
static Node * resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
Definition: pl_comp.c:1116
int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2224 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().

2225 {
2226  int i;
2227 
2228  if (allow_sqlstate)
2229  {
2230  if (strlen(condname) == 5 &&
2231  strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2232  return MAKE_SQLSTATE(condname[0],
2233  condname[1],
2234  condname[2],
2235  condname[3],
2236  condname[4]);
2237  }
2238 
2239  for (i = 0; exception_label_map[i].label != NULL; i++)
2240  {
2241  if (strcmp(condname, exception_label_map[i].label) == 0)
2243  }
2244 
2245  ereport(ERROR,
2246  (errcode(ERRCODE_UNDEFINED_OBJECT),
2247  errmsg("unrecognized exception condition \"%s\"",
2248  condname)));
2249  return 0; /* keep compiler quiet */
2250 }
const char * label
Definition: pl_comp.c:79
#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:81
#define NULL
Definition: c.h:229
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:83
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 2494 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().

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

Definition at line 2311 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

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

Definition at line 1116 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().

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

Variable Documentation

int datums_alloc
static

Definition at line 45 of file pl_comp.c.

Referenced by plpgsql_adddatum(), and plpgsql_start_datums().

int datums_last
static

Definition at line 48 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:229

Definition at line 83 of file pl_comp.c.

bool plpgsql_check_syntax = false

Definition at line 52 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().

MemoryContext plpgsql_compile_tmp_cxt

Definition at line 57 of file pl_comp.c.

PLpgSQL_function* plpgsql_curr_compile

Definition at line 54 of file pl_comp.c.

PLpgSQL_datum** plpgsql_Datums

Definition at line 47 of file pl_comp.c.

bool plpgsql_DumpExecTree = false

Definition at line 51 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().

char* plpgsql_error_funcname

Definition at line 50 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 63 of file pl_comp.c.

int plpgsql_nDatums
PLpgSQL_stmt_block* plpgsql_parse_result

Definition at line 43 of file pl_comp.c.

Referenced by do_compile(), and plpgsql_compile_inline().