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 982 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

983 {
984  /*
985  * If the outer block has an EXCEPTION clause, we need to make a new outer
986  * block, since the added RETURN shouldn't act like it is inside the
987  * EXCEPTION clause.
988  */
989  if (function->action->exceptions != NULL)
990  {
991  PLpgSQL_stmt_block *new;
992 
993  new = palloc0(sizeof(PLpgSQL_stmt_block));
994  new->cmd_type = PLPGSQL_STMT_BLOCK;
995  new->body = list_make1(function->action);
996 
997  function->action = new;
998  }
999  if (function->action->body == NIL ||
1000  ((PLpgSQL_stmt *) llast(function->action->body))->cmd_type != PLPGSQL_STMT_RETURN)
1001  {
1002  PLpgSQL_stmt_return *new;
1003 
1004  new = palloc0(sizeof(PLpgSQL_stmt_return));
1005  new->cmd_type = PLPGSQL_STMT_RETURN;
1006  new->expr = NULL;
1007  new->retvarno = function->out_param_varno;
1008 
1009  function->action->body = lappend(function->action->body, new);
1010  }
1011 }
#define NIL
Definition: pg_list.h:69
PLpgSQL_stmt_block * action
Definition: plpgsql.h:871
#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:877
PLpgSQL_exception_block * exceptions
Definition: plpgsql.h:412
static void add_parameter_name ( PLpgSQL_nsitem_type  itemtype,
int  itemno,
const char *  name 
)
static

Definition at line 957 of file pl_comp.c.

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

Referenced by do_compile().

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

2153 {
2154  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2155  PLpgSQL_type *typ;
2156 
2157  if (!typeStruct->typisdefined)
2158  ereport(ERROR,
2159  (errcode(ERRCODE_UNDEFINED_OBJECT),
2160  errmsg("type \"%s\" is only a shell",
2161  NameStr(typeStruct->typname))));
2162 
2163  typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
2164 
2165  typ->typname = pstrdup(NameStr(typeStruct->typname));
2166  typ->typoid = HeapTupleGetOid(typeTup);
2167  switch (typeStruct->typtype)
2168  {
2169  case TYPTYPE_BASE:
2170  case TYPTYPE_DOMAIN:
2171  case TYPTYPE_ENUM:
2172  case TYPTYPE_RANGE:
2173  typ->ttype = PLPGSQL_TTYPE_SCALAR;
2174  break;
2175  case TYPTYPE_COMPOSITE:
2176  Assert(OidIsValid(typeStruct->typrelid));
2177  typ->ttype = PLPGSQL_TTYPE_ROW;
2178  break;
2179  case TYPTYPE_PSEUDO:
2180  if (typ->typoid == RECORDOID)
2181  typ->ttype = PLPGSQL_TTYPE_REC;
2182  else
2183  typ->ttype = PLPGSQL_TTYPE_PSEUDO;
2184  break;
2185  default:
2186  elog(ERROR, "unrecognized typtype: %d",
2187  (int) typeStruct->typtype);
2188  break;
2189  }
2190  typ->typlen = typeStruct->typlen;
2191  typ->typbyval = typeStruct->typbyval;
2192  typ->typtype = typeStruct->typtype;
2193  typ->typrelid = typeStruct->typrelid;
2194  typ->collation = typeStruct->typcollation;
2195  if (OidIsValid(collation) && OidIsValid(typ->collation))
2196  typ->collation = collation;
2197  /* Detect if type is true array, or domain thereof */
2198  /* NB: this is only used to decide whether to apply expand_array */
2199  if (typeStruct->typtype == TYPTYPE_BASE)
2200  {
2201  /*
2202  * This test should include what get_element_type() checks. We also
2203  * disallow non-toastable array types (i.e. oidvector and int2vector).
2204  */
2205  typ->typisarray = (typeStruct->typlen == -1 &&
2206  OidIsValid(typeStruct->typelem) &&
2207  typeStruct->typstorage != 'p');
2208  }
2209  else if (typeStruct->typtype == TYPTYPE_DOMAIN)
2210  {
2211  /* we can short-circuit looking up base types if it's not varlena */
2212  typ->typisarray = (typeStruct->typlen == -1 &&
2213  typeStruct->typstorage != 'p' &&
2214  OidIsValid(get_base_element_type(typeStruct->typbasetype)));
2215  }
2216  else
2217  typ->typisarray = false;
2218  typ->atttypmod = typmod;
2219 
2220  return typ;
2221 }
#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:1076
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:532
#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:681
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:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 atttypmod
Definition: plpgsql.h:187
#define NameStr(name)
Definition: c.h:493
#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 1972 of file pl_comp.c.

References AccessShareLock, CreateTupleDescCopy(), PLpgSQL_row::dtype, ereport, errcode(), errmsg(), ERROR, PLpgSQL_row::fieldnames, i, NAMEDATALEN, NameStr, PLpgSQL_row::nfields, 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_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, PLpgSQL_row::rowtupdesc, snprintf(), TupleDescAttr, and PLpgSQL_row::varnos.

Referenced by plpgsql_build_variable().

1973 {
1974  PLpgSQL_row *row;
1975  Relation rel;
1976  Form_pg_class classStruct;
1977  const char *relname;
1978  int i;
1979 
1980  /*
1981  * Open the relation to get info.
1982  */
1983  rel = relation_open(classOid, AccessShareLock);
1984  classStruct = RelationGetForm(rel);
1985  relname = RelationGetRelationName(rel);
1986 
1987  /*
1988  * Accept relation, sequence, view, materialized view, composite type, or
1989  * foreign table.
1990  */
1991  if (classStruct->relkind != RELKIND_RELATION &&
1992  classStruct->relkind != RELKIND_SEQUENCE &&
1993  classStruct->relkind != RELKIND_VIEW &&
1994  classStruct->relkind != RELKIND_MATVIEW &&
1995  classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
1996  classStruct->relkind != RELKIND_FOREIGN_TABLE &&
1997  classStruct->relkind != RELKIND_PARTITIONED_TABLE)
1998  ereport(ERROR,
1999  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2000  errmsg("relation \"%s\" is not a table", relname)));
2001 
2002  /*
2003  * Create a row datum entry and all the required variables that it will
2004  * point to.
2005  */
2006  row = palloc0(sizeof(PLpgSQL_row));
2007  row->dtype = PLPGSQL_DTYPE_ROW;
2009  row->nfields = classStruct->relnatts;
2010  row->fieldnames = palloc(sizeof(char *) * row->nfields);
2011  row->varnos = palloc(sizeof(int) * row->nfields);
2012 
2013  for (i = 0; i < row->nfields; i++)
2014  {
2015  Form_pg_attribute attrStruct;
2016 
2017  /*
2018  * Get the attribute and check for dropped column
2019  */
2020  attrStruct = TupleDescAttr(row->rowtupdesc, i);
2021 
2022  if (!attrStruct->attisdropped)
2023  {
2024  char *attname;
2025  char refname[(NAMEDATALEN * 2) + 100];
2026  PLpgSQL_variable *var;
2027 
2028  attname = NameStr(attrStruct->attname);
2029  snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
2030 
2031  /*
2032  * Create the internal variable for the field
2033  *
2034  * We know if the table definitions contain a default value or if
2035  * the field is declared in the table as NOT NULL. But it's
2036  * possible to create a table field as NOT NULL without a default
2037  * value and that would lead to problems later when initializing
2038  * the variables due to entering a block at execution time. Thus
2039  * we ignore this information for now.
2040  */
2041  var = plpgsql_build_variable(refname, 0,
2042  plpgsql_build_datatype(attrStruct->atttypid,
2043  attrStruct->atttypmod,
2044  attrStruct->attcollation),
2045  false);
2046 
2047  /* Add the variable to the row */
2048  row->fieldnames[i] = attname;
2049  row->varnos[i] = var->dno;
2050  }
2051  else
2052  {
2053  /* Leave a hole in the row structure for the dropped col */
2054  row->fieldnames[i] = NULL;
2055  row->varnos[i] = -1;
2056  }
2057  }
2058 
2060 
2061  return row;
2062 }
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:102
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2132
#define RelationGetDescr(relation)
Definition: rel.h:428
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
#define RelationGetForm(relation)
Definition: rel.h:410
#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:1266
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:436
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
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
void * palloc0(Size size)
Definition: mcxt.c:877
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:1869
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
void * palloc(Size size)
Definition: mcxt.c:848
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:493
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1120
#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 2068 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().

2069 {
2070  PLpgSQL_row *row;
2071  int i;
2072 
2073  row = palloc0(sizeof(PLpgSQL_row));
2074  row->dtype = PLPGSQL_DTYPE_ROW;
2075  row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
2076  row->nfields = numvars;
2077  row->fieldnames = palloc(numvars * sizeof(char *));
2078  row->varnos = palloc(numvars * sizeof(int));
2079 
2080  for (i = 0; i < numvars; i++)
2081  {
2082  PLpgSQL_variable *var = vars[i];
2083  Oid typoid = RECORDOID;
2084  int32 typmod = -1;
2085  Oid typcoll = InvalidOid;
2086 
2087  switch (var->dtype)
2088  {
2089  case PLPGSQL_DTYPE_VAR:
2090  typoid = ((PLpgSQL_var *) var)->datatype->typoid;
2091  typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
2092  typcoll = ((PLpgSQL_var *) var)->datatype->collation;
2093  break;
2094 
2095  case PLPGSQL_DTYPE_REC:
2096  break;
2097 
2098  case PLPGSQL_DTYPE_ROW:
2099  if (((PLpgSQL_row *) var)->rowtupdesc)
2100  {
2101  typoid = ((PLpgSQL_row *) var)->rowtupdesc->tdtypeid;
2102  typmod = ((PLpgSQL_row *) var)->rowtupdesc->tdtypmod;
2103  /* composite types have no collation */
2104  }
2105  break;
2106 
2107  default:
2108  elog(ERROR, "unrecognized dtype: %d", var->dtype);
2109  }
2110 
2111  row->fieldnames[i] = var->refname;
2112  row->varnos[i] = var->dno;
2113 
2114  TupleDescInitEntry(row->rowtupdesc, i + 1,
2115  var->refname,
2116  typoid, typmod,
2117  0);
2118  TupleDescInitEntryCollation(row->rowtupdesc, i + 1, typcoll);
2119  }
2120 
2121  return row;
2122 }
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:246
#define ERROR
Definition: elog.h:43
char ** fieldnames
Definition: plpgsql.h:293
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:664
#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:505
int * varnos
Definition: plpgsql.h:294
void * palloc0(Size size)
Definition: mcxt.c:877
#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:43
void * palloc(Size size)
Definition: mcxt.c:848
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 2448 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, plpgsql_resolve_polymorphic_argtypes(), TriggerData::tg_trigger, Trigger::tgoid, and PLpgSQL_func_hashkey::trigOid.

Referenced by plpgsql_compile().

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

Definition at line 2559 of file pl_comp.c.

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

Referenced by plpgsql_compile().

2560 {
2561  /* remove function from hash table (might be done already) */
2563 
2564  /* release the function's storage if safe and not done already */
2565  if (func->use_count == 0)
2567 }
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:695
unsigned long use_count
Definition: plpgsql.h:875
static void plpgsql_HashTableDelete(PLpgSQL_function *function)
Definition: pl_comp.c:2622
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, 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  /*
437  * Build variable and add to datum list. If there's a name
438  * for the argument, use that as refname, else use $n name.
439  */
440  argvariable = plpgsql_build_variable((argnames &&
441  argnames[i][0] != '\0') ?
442  argnames[i] : buf,
443  0, argdtype, false);
444 
445  if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
446  {
447  argitemtype = PLPGSQL_NSTYPE_VAR;
448  }
449  else
450  {
451  Assert(argvariable->dtype == PLPGSQL_DTYPE_ROW);
452  argitemtype = PLPGSQL_NSTYPE_ROW;
453  }
454 
455  /* Remember arguments in appropriate arrays */
456  if (argmode == PROARGMODE_IN ||
457  argmode == PROARGMODE_INOUT ||
458  argmode == PROARGMODE_VARIADIC)
459  in_arg_varnos[num_in_args++] = argvariable->dno;
460  if (argmode == PROARGMODE_OUT ||
461  argmode == PROARGMODE_INOUT ||
462  argmode == PROARGMODE_TABLE)
463  out_arg_variables[num_out_args++] = argvariable;
464 
465  /* Add to namespace under the $n name */
466  add_parameter_name(argitemtype, argvariable->dno, buf);
467 
468  /* If there's a name for the argument, make an alias */
469  if (argnames && argnames[i][0] != '\0')
470  add_parameter_name(argitemtype, argvariable->dno,
471  argnames[i]);
472  }
473 
474  /*
475  * If there's just one OUT parameter, out_param_varno points
476  * directly to it. If there's more than one, build a row that
477  * holds all of them.
478  */
479  if (num_out_args == 1)
480  function->out_param_varno = out_arg_variables[0]->dno;
481  else if (num_out_args > 1)
482  {
483  PLpgSQL_row *row = build_row_from_vars(out_arg_variables,
484  num_out_args);
485 
487  function->out_param_varno = row->dno;
488  }
489 
490  /*
491  * Check for a polymorphic returntype. If found, use the actual
492  * returntype type from the caller's FuncExpr node, if we have
493  * one. (In validation mode we arbitrarily assume we are dealing
494  * with integers.)
495  *
496  * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
497  * work; if it doesn't we're in some context that fails to make
498  * the info available.
499  */
500  rettypeid = procStruct->prorettype;
501  if (IsPolymorphicType(rettypeid))
502  {
503  if (forValidator)
504  {
505  if (rettypeid == ANYARRAYOID)
506  rettypeid = INT4ARRAYOID;
507  else if (rettypeid == ANYRANGEOID)
508  rettypeid = INT4RANGEOID;
509  else /* ANYELEMENT or ANYNONARRAY */
510  rettypeid = INT4OID;
511  /* XXX what could we use for ANYENUM? */
512  }
513  else
514  {
515  rettypeid = get_fn_expr_rettype(fcinfo->flinfo);
516  if (!OidIsValid(rettypeid))
517  ereport(ERROR,
518  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
519  errmsg("could not determine actual return type "
520  "for polymorphic function \"%s\"",
522  }
523  }
524 
525  /*
526  * Normal function has a defined returntype
527  */
528  function->fn_rettype = rettypeid;
529  function->fn_retset = procStruct->proretset;
530 
531  /*
532  * Lookup the function's return type
533  */
534  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettypeid));
535  if (!HeapTupleIsValid(typeTup))
536  elog(ERROR, "cache lookup failed for type %u", rettypeid);
537  typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
538 
539  /* Disallow pseudotype result, except VOID or RECORD */
540  /* (note we already replaced polymorphic types) */
541  if (typeStruct->typtype == TYPTYPE_PSEUDO)
542  {
543  if (rettypeid == VOIDOID ||
544  rettypeid == RECORDOID)
545  /* okay */ ;
546  else if (rettypeid == TRIGGEROID || rettypeid == EVTTRIGGEROID)
547  ereport(ERROR,
548  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
549  errmsg("trigger functions can only be called as triggers")));
550  else
551  ereport(ERROR,
552  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
553  errmsg("PL/pgSQL functions cannot return type %s",
554  format_type_be(rettypeid))));
555  }
556 
557  if (typeStruct->typrelid != InvalidOid ||
558  rettypeid == RECORDOID)
559  function->fn_retistuple = true;
560  else
561  {
562  function->fn_retbyval = typeStruct->typbyval;
563  function->fn_rettyplen = typeStruct->typlen;
564 
565  /*
566  * install $0 reference, but only for polymorphic return
567  * types, and not when the return is specified through an
568  * output parameter.
569  */
570  if (IsPolymorphicType(procStruct->prorettype) &&
571  num_out_args == 0)
572  {
573  (void) plpgsql_build_variable("$0", 0,
574  build_datatype(typeTup,
575  -1,
576  function->fn_input_collation),
577  true);
578  }
579  }
580  ReleaseSysCache(typeTup);
581  break;
582 
583  case PLPGSQL_DML_TRIGGER:
584  /* Trigger procedure's return type is unknown yet */
585  function->fn_rettype = InvalidOid;
586  function->fn_retbyval = false;
587  function->fn_retistuple = true;
588  function->fn_retset = false;
589 
590  /* shouldn't be any declared arguments */
591  if (procStruct->pronargs != 0)
592  ereport(ERROR,
593  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
594  errmsg("trigger functions cannot have declared arguments"),
595  errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
596 
597  /* Add the record for referencing NEW ROW */
598  rec = plpgsql_build_record("new", 0, true);
599  function->new_varno = rec->dno;
600 
601  /* Add the record for referencing OLD ROW */
602  rec = plpgsql_build_record("old", 0, true);
603  function->old_varno = rec->dno;
604 
605  /* Add the variable tg_name */
606  var = plpgsql_build_variable("tg_name", 0,
608  -1,
609  InvalidOid),
610  true);
611  function->tg_name_varno = var->dno;
612 
613  /* Add the variable tg_when */
614  var = plpgsql_build_variable("tg_when", 0,
616  -1,
617  function->fn_input_collation),
618  true);
619  function->tg_when_varno = var->dno;
620 
621  /* Add the variable tg_level */
622  var = plpgsql_build_variable("tg_level", 0,
624  -1,
625  function->fn_input_collation),
626  true);
627  function->tg_level_varno = var->dno;
628 
629  /* Add the variable tg_op */
630  var = plpgsql_build_variable("tg_op", 0,
632  -1,
633  function->fn_input_collation),
634  true);
635  function->tg_op_varno = var->dno;
636 
637  /* Add the variable tg_relid */
638  var = plpgsql_build_variable("tg_relid", 0,
640  -1,
641  InvalidOid),
642  true);
643  function->tg_relid_varno = var->dno;
644 
645  /* Add the variable tg_relname */
646  var = plpgsql_build_variable("tg_relname", 0,
648  -1,
649  InvalidOid),
650  true);
651  function->tg_relname_varno = var->dno;
652 
653  /* tg_table_name is now preferred to tg_relname */
654  var = plpgsql_build_variable("tg_table_name", 0,
656  -1,
657  InvalidOid),
658  true);
659  function->tg_table_name_varno = var->dno;
660 
661  /* add the variable tg_table_schema */
662  var = plpgsql_build_variable("tg_table_schema", 0,
664  -1,
665  InvalidOid),
666  true);
667  function->tg_table_schema_varno = var->dno;
668 
669  /* Add the variable tg_nargs */
670  var = plpgsql_build_variable("tg_nargs", 0,
672  -1,
673  InvalidOid),
674  true);
675  function->tg_nargs_varno = var->dno;
676 
677  /* Add the variable tg_argv */
678  var = plpgsql_build_variable("tg_argv", 0,
680  -1,
681  function->fn_input_collation),
682  true);
683  function->tg_argv_varno = var->dno;
684 
685  break;
686 
688  function->fn_rettype = VOIDOID;
689  function->fn_retbyval = false;
690  function->fn_retistuple = true;
691  function->fn_retset = false;
692 
693  /* shouldn't be any declared arguments */
694  if (procStruct->pronargs != 0)
695  ereport(ERROR,
696  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
697  errmsg("event trigger functions cannot have declared arguments")));
698 
699  /* Add the variable tg_event */
700  var = plpgsql_build_variable("tg_event", 0,
702  -1,
703  function->fn_input_collation),
704  true);
705  function->tg_event_varno = var->dno;
706 
707  /* Add the variable tg_tag */
708  var = plpgsql_build_variable("tg_tag", 0,
710  -1,
711  function->fn_input_collation),
712  true);
713  function->tg_tag_varno = var->dno;
714 
715  break;
716 
717  default:
718  elog(ERROR, "unrecognized function typecode: %d",
719  (int) function->fn_is_trigger);
720  break;
721  }
722 
723  /* Remember if function is STABLE/IMMUTABLE */
724  function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
725 
726  /*
727  * Create the magic FOUND variable.
728  */
729  var = plpgsql_build_variable("found", 0,
731  -1,
732  InvalidOid),
733  true);
734  function->found_varno = var->dno;
735 
736  /*
737  * Now parse the function's text
738  */
739  parse_rc = plpgsql_yyparse();
740  if (parse_rc != 0)
741  elog(ERROR, "plpgsql parser returned %d", parse_rc);
742  function->action = plpgsql_parse_result;
743 
745  pfree(proc_source);
746 
747  /*
748  * If it has OUT parameters or returns VOID or returns a set, we allow
749  * control to fall off the end without an explicit RETURN statement. The
750  * easiest way to implement this is to add a RETURN statement to the end
751  * of the statement list during parsing.
752  */
753  if (num_out_args > 0 || function->fn_rettype == VOIDOID ||
754  function->fn_retset)
755  add_dummy_return(function);
756 
757  /*
758  * Complete the function's info
759  */
760  function->fn_nargs = procStruct->pronargs;
761  for (i = 0; i < function->fn_nargs; i++)
762  function->fn_argvarnos[i] = in_arg_varnos[i];
763 
764  plpgsql_finish_datums(function);
765 
766  /* Debug dump for completed functions */
768  plpgsql_dumptree(function);
769 
770  /*
771  * add it to the hash table
772  */
773  plpgsql_HashTableInsert(function, hashkey);
774 
775  /*
776  * Pop the error context stack
777  */
778  error_context_stack = plerrcontext.previous;
779  plpgsql_error_funcname = NULL;
780 
781  plpgsql_check_syntax = false;
782 
785  return function;
786 }
int plpgsql_yyparse(void)
int fn_argvarnos[FUNC_MAX_ARGS]
Definition: plpgsql.h:837
#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:2132
#define OIDOID
Definition: pg_type.h:328
#define TEXTOID
Definition: pg_type.h:324
char * pstrdup(const char *in)
Definition: mcxt.c:1076
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:793
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:1949
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:5554
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:532
static void plpgsql_resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
Definition: pl_comp.c:2501
static void plpgsql_HashTableInsert(PLpgSQL_function *function, PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2603
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2318
#define PROARGMODE_INOUT
Definition: pg_proc.h:5553
#define PROARGMODE_OUT
Definition: pg_proc.h:5552
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:949
#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:957
#define TRIGGEROID
Definition: pg_type.h:692
#define PROARGMODE_TABLE
Definition: pg_proc.h:5555
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:982
static char * buf
Definition: pg_test_fsync.c:67
#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:5551
MemoryContext TopMemoryContext
Definition: mcxt.c:43
#define PROVOLATILE_VOLATILE
Definition: pg_proc.h:5535
Oid fn_input_collation
Definition: plpgsql.h:825
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#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:1882
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:741
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:59
PLpgSQL_trigtype fn_is_trigger
Definition: plpgsql.h:824
bool plpgsql_print_strict_params
Definition: pl_handler.c:48
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:323
static void plpgsql_compile_error_callback(void *arg)
Definition: pl_comp.c:930
int plpgsql_variable_conflict
Definition: pl_handler.c:46
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define EVTTRIGGEROID
Definition: pg_type.h:694
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:25
#define Assert(condition)
Definition: c.h:681
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:1869
#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:2152
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2355
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2335
int i
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
#define NameStr(name)
Definition: c.h:493
#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:2068
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 1310 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().

1311 {
1312  PLpgSQL_execstate *estate;
1313  PLpgSQL_datum *datum;
1314  Param *param;
1315  MemoryContext oldcontext;
1316 
1317  /* see comment in resolve_column_ref */
1318  estate = expr->func->cur_estate;
1319  Assert(dno >= 0 && dno < estate->ndatums);
1320  datum = estate->datums[dno];
1321 
1322  /*
1323  * Bitmapset must be allocated in function's permanent memory context
1324  */
1325  oldcontext = MemoryContextSwitchTo(expr->func->fn_cxt);
1326  expr->paramnos = bms_add_member(expr->paramnos, dno);
1327  MemoryContextSwitchTo(oldcontext);
1328 
1329  param = makeNode(Param);
1330  param->paramkind = PARAM_EXTERN;
1331  param->paramid = dno + 1;
1333  datum,
1334  &param->paramtype,
1335  &param->paramtypmod,
1336  &param->paramcollid);
1337  param->location = location;
1338 
1339  return (Node *) param;
1340 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ParamKind paramkind
Definition: primnodes.h:244
Definition: nodes.h:510
PLpgSQL_datum ** datums
Definition: plpgsql.h:908
Bitmapset * paramnos
Definition: plpgsql.h:225
struct PLpgSQL_execstate * cur_estate
Definition: plpgsql.h:874
Oid paramcollid
Definition: primnodes.h:248
int location
Definition: primnodes.h:249
MemoryContext fn_cxt
Definition: plpgsql.h:827
void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeid, int32 *typmod, Oid *collation)
Definition: pl_exec.c:5026
struct PLpgSQL_function * func
Definition: plpgsql.h:229
int32 paramtypmod
Definition: primnodes.h:247
#define makeNode(_type_)
Definition: nodes.h:558
#define Assert(condition)
Definition: c.h:681
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 2396 of file pl_comp.c.

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

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

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

2336 {
2338  {
2339  datums_alloc *= 2;
2341  }
2342 
2343  new->dno = plpgsql_nDatums;
2345 }
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:962
PLpgSQL_type* plpgsql_build_datatype ( Oid  typeOid,
int32  typmod,
Oid  collation 
)

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

2133 {
2134  HeapTuple typeTup;
2135  PLpgSQL_type *typ;
2136 
2137  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
2138  if (!HeapTupleIsValid(typeTup))
2139  elog(ERROR, "cache lookup failed for type %u", typeOid);
2140 
2141  typ = build_datatype(typeTup, typmod, collation);
2142 
2143  ReleaseSysCache(typeTup);
2144 
2145  return typ;
2146 }
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2152
#define elog
Definition: elog.h:219
PLpgSQL_rec* plpgsql_build_record ( const char *  refname,
int  lineno,
bool  add2namespace 
)

Definition at line 1949 of file pl_comp.c.

References PLpgSQL_rec::dno, PLpgSQL_rec::dtype, PLpgSQL_rec::freetup, PLpgSQL_rec::freetupdesc, PLpgSQL_rec::lineno, 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().

1950 {
1951  PLpgSQL_rec *rec;
1952 
1953  rec = palloc0(sizeof(PLpgSQL_rec));
1954  rec->dtype = PLPGSQL_DTYPE_REC;
1955  rec->refname = pstrdup(refname);
1956  rec->lineno = lineno;
1957  rec->tup = NULL;
1958  rec->tupdesc = NULL;
1959  rec->freetup = false;
1960  rec->freetupdesc = false;
1962  if (add2namespace)
1964 
1965  return rec;
1966 }
PLpgSQL_datum_type dtype
Definition: plpgsql.h:302
TupleDesc tupdesc
Definition: plpgsql.h:308
char * pstrdup(const char *in)
Definition: mcxt.c:1076
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:877
bool freetupdesc
Definition: plpgsql.h:310
HeapTuple tup
Definition: plpgsql.h:307
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2335
int lineno
Definition: plpgsql.h:305
PLpgSQL_variable* plpgsql_build_variable ( const char *  refname,
int  lineno,
PLpgSQL_type dtype,
bool  add2namespace 
)

Definition at line 1869 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, palloc0(), plpgsql_adddatum(), plpgsql_build_record(), PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, plpgsql_ns_additem(), PLPGSQL_NSTYPE_ROW, PLPGSQL_NSTYPE_VAR, PLPGSQL_TTYPE_PSEUDO, PLPGSQL_TTYPE_REC, PLPGSQL_TTYPE_ROW, PLPGSQL_TTYPE_SCALAR, pstrdup(), PLpgSQL_var::refname, PLpgSQL_row::refname, PLpgSQL_type::ttype, PLpgSQL_type::typoid, PLpgSQL_type::typrelid, and PLpgSQL_var::value.

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

1871 {
1872  PLpgSQL_variable *result;
1873 
1874  switch (dtype->ttype)
1875  {
1876  case PLPGSQL_TTYPE_SCALAR:
1877  {
1878  /* Ordinary scalar datatype */
1879  PLpgSQL_var *var;
1880 
1881  var = palloc0(sizeof(PLpgSQL_var));
1882  var->dtype = PLPGSQL_DTYPE_VAR;
1883  var->refname = pstrdup(refname);
1884  var->lineno = lineno;
1885  var->datatype = dtype;
1886  /* other fields might be filled by caller */
1887 
1888  /* preset to NULL */
1889  var->value = 0;
1890  var->isnull = true;
1891  var->freeval = false;
1892 
1894  if (add2namespace)
1896  var->dno,
1897  refname);
1898  result = (PLpgSQL_variable *) var;
1899  break;
1900  }
1901  case PLPGSQL_TTYPE_ROW:
1902  {
1903  /* Composite type -- build a row variable */
1904  PLpgSQL_row *row;
1905 
1906  row = build_row_from_class(dtype->typrelid);
1907 
1908  row->dtype = PLPGSQL_DTYPE_ROW;
1909  row->refname = pstrdup(refname);
1910  row->lineno = lineno;
1911 
1913  if (add2namespace)
1915  row->dno,
1916  refname);
1917  result = (PLpgSQL_variable *) row;
1918  break;
1919  }
1920  case PLPGSQL_TTYPE_REC:
1921  {
1922  /* "record" type -- build a record variable */
1923  PLpgSQL_rec *rec;
1924 
1925  rec = plpgsql_build_record(refname, lineno, add2namespace);
1926  result = (PLpgSQL_variable *) rec;
1927  break;
1928  }
1929  case PLPGSQL_TTYPE_PSEUDO:
1930  ereport(ERROR,
1931  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1932  errmsg("variable \"%s\" has pseudo-type %s",
1933  refname, format_type_be(dtype->typoid))));
1934  result = NULL; /* keep compiler quiet */
1935  break;
1936  default:
1937  elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1938  result = NULL; /* keep compiler quiet */
1939  break;
1940  }
1941 
1942  return result;
1943 }
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:1972
PLpgSQL_datum_type dtype
Definition: plpgsql.h:256
char * pstrdup(const char *in)
Definition: mcxt.c:1076
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:1949
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool freeval
Definition: plpgsql.h:271
Oid typrelid
Definition: plpgsql.h:184
void * palloc0(Size size)
Definition: mcxt.c:877
Datum value
Definition: plpgsql.h:269
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:2335
#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(), 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:2448
unsigned int Oid
Definition: postgres_ext.h:31
HeapTupleHeader t_data
Definition: htup.h:67
static void delete_function(PLpgSQL_function *func)
Definition: pl_comp.c:2559
FmgrInfo * flinfo
Definition: fmgr.h:79
static PLpgSQL_function * plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
Definition: pl_comp.c:2588
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
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 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 930 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().

931 {
932  if (arg)
933  {
934  /*
935  * Try to convert syntax error position to reference text of original
936  * CREATE FUNCTION or DO command.
937  */
938  if (function_parse_error_transpose((const char *) arg))
939  return;
940 
941  /*
942  * Done if a syntax error position was reported; otherwise we have to
943  * fall back to a "near line N" report.
944  */
945  }
946 
948  errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
950 }
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 799 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(), 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().

800 {
801  char *func_name = "inline_code_block";
802  PLpgSQL_function *function;
803  ErrorContextCallback plerrcontext;
804  PLpgSQL_variable *var;
805  int parse_rc;
806  MemoryContext func_cxt;
807 
808  /*
809  * Setup the scanner input and error info. We assume that this function
810  * cannot be invoked recursively, so there's no need to save and restore
811  * the static variables used here.
812  */
813  plpgsql_scanner_init(proc_source);
814 
815  plpgsql_error_funcname = func_name;
816 
817  /*
818  * Setup error traceback support for ereport()
819  */
821  plerrcontext.arg = proc_source;
822  plerrcontext.previous = error_context_stack;
823  error_context_stack = &plerrcontext;
824 
825  /* Do extra syntax checking if check_function_bodies is on */
827 
828  /* Function struct does not live past current statement */
829  function = (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
830 
831  plpgsql_curr_compile = function;
832 
833  /*
834  * All the rest of the compile-time storage (e.g. parse tree) is kept in
835  * its own memory context, so it can be reclaimed easily.
836  */
838  "PL/pgSQL inline code context",
841 
842  function->fn_signature = pstrdup(func_name);
843  function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
844  function->fn_input_collation = InvalidOid;
845  function->fn_cxt = func_cxt;
846  function->out_param_varno = -1; /* set up for no OUT param */
847  function->resolve_option = plpgsql_variable_conflict;
848  function->print_strict_params = plpgsql_print_strict_params;
849 
850  /*
851  * don't do extra validation for inline code as we don't want to add spam
852  * at runtime
853  */
854  function->extra_warnings = 0;
855  function->extra_errors = 0;
856 
857  plpgsql_ns_init();
859  plpgsql_DumpExecTree = false;
861 
862  /* Set up as though in a function returning VOID */
863  function->fn_rettype = VOIDOID;
864  function->fn_retset = false;
865  function->fn_retistuple = false;
866  /* a bit of hardwired knowledge about type VOID here */
867  function->fn_retbyval = true;
868  function->fn_rettyplen = sizeof(int32);
869 
870  /*
871  * Remember if function is STABLE/IMMUTABLE. XXX would it be better to
872  * set this TRUE inside a read-only transaction? Not clear.
873  */
874  function->fn_readonly = false;
875 
876  /*
877  * Create the magic FOUND variable.
878  */
879  var = plpgsql_build_variable("found", 0,
881  -1,
882  InvalidOid),
883  true);
884  function->found_varno = var->dno;
885 
886  /*
887  * Now parse the function's text
888  */
889  parse_rc = plpgsql_yyparse();
890  if (parse_rc != 0)
891  elog(ERROR, "plpgsql parser returned %d", parse_rc);
892  function->action = plpgsql_parse_result;
893 
895 
896  /*
897  * If it returns VOID (always true at the moment), we allow control to
898  * fall off the end without an explicit RETURN statement.
899  */
900  if (function->fn_rettype == VOIDOID)
901  add_dummy_return(function);
902 
903  /*
904  * Complete the function's info
905  */
906  function->fn_nargs = 0;
907 
908  plpgsql_finish_datums(function);
909 
910  /*
911  * Pop the error context stack
912  */
913  error_context_stack = plerrcontext.previous;
914  plpgsql_error_funcname = NULL;
915 
916  plpgsql_check_syntax = false;
917 
920  return function;
921 }
int plpgsql_yyparse(void)
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2132
char * pstrdup(const char *in)
Definition: mcxt.c:1076
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool check_function_bodies
Definition: guc.c:447
struct ErrorContextCallback * previous
Definition: elog.h:238
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2318
signed int int32
Definition: c.h:246
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:982
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:877
#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:930
int plpgsql_variable_conflict
Definition: pl_handler.c:46
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:1869
#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:2355
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 2355 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

2356 {
2357  Bitmapset *resettable_datums = NULL;
2358  int i;
2359 
2360  function->ndatums = plpgsql_nDatums;
2361  function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
2362  for (i = 0; i < plpgsql_nDatums; i++)
2363  {
2364  function->datums[i] = plpgsql_Datums[i];
2365  switch (function->datums[i]->dtype)
2366  {
2367  case PLPGSQL_DTYPE_ROW:
2368  case PLPGSQL_DTYPE_REC:
2370  resettable_datums = bms_add_member(resettable_datums, i);
2371  break;
2372 
2373  default:
2374  break;
2375  }
2376  }
2377  function->resettable_datums = resettable_datums;
2378 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** datums
Definition: plpgsql.h:867
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_datum_type dtype
Definition: plpgsql.h:198
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
void * palloc(Size size)
Definition: mcxt.c:848
int i
static void plpgsql_HashTableDelete ( PLpgSQL_function function)
static

Definition at line 2622 of file pl_comp.c.

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

Referenced by delete_function().

2623 {
2624  plpgsql_HashEnt *hentry;
2625 
2626  /* do nothing if not in table */
2627  if (function->fn_hashkey == NULL)
2628  return;
2629 
2631  (void *) function->fn_hashkey,
2632  HASH_REMOVE,
2633  NULL);
2634  if (hentry == NULL)
2635  elog(WARNING, "trying to delete function that does not exist");
2636 
2637  /* remove back link, which no longer points to allocated storage */
2638  function->fn_hashkey = NULL;
2639 }
PLpgSQL_func_hashkey * fn_hashkey
Definition: plpgsql.h:826
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:902
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:63
#define WARNING
Definition: elog.h:40
#define elog
Definition: elog.h:219
void plpgsql_HashTableInit ( void  )

Definition at line 2571 of file pl_comp.c.

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

Referenced by _PG_init().

2572 {
2573  HASHCTL ctl;
2574 
2575  /* don't allow double-initialization */
2576  Assert(plpgsql_HashTable == NULL);
2577 
2578  memset(&ctl, 0, sizeof(ctl));
2579  ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2580  ctl.entrysize = sizeof(plpgsql_HashEnt);
2581  plpgsql_HashTable = hash_create("PLpgSQL function cache",
2583  &ctl,
2584  HASH_ELEM | HASH_BLOBS);
2585 }
#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:316
Size keysize
Definition: hsearch.h:72
#define Assert(condition)
Definition: c.h:681
static void plpgsql_HashTableInsert ( PLpgSQL_function function,
PLpgSQL_func_hashkey func_key 
)
static

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

2605 {
2606  plpgsql_HashEnt *hentry;
2607  bool found;
2608 
2610  (void *) func_key,
2611  HASH_ENTER,
2612  &found);
2613  if (found)
2614  elog(WARNING, "trying to insert a function that already exists");
2615 
2616  hentry->function = function;
2617  /* prepare back link from function to hashtable key */
2618  function->fn_hashkey = &hentry->key;
2619 }
PLpgSQL_func_hashkey * fn_hashkey
Definition: plpgsql.h:826
PLpgSQL_func_hashkey key
Definition: pl_comp.c:67
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:902
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 2588 of file pl_comp.c.

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

Referenced by plpgsql_compile().

2589 {
2590  plpgsql_HashEnt *hentry;
2591 
2593  (void *) func_key,
2594  HASH_FIND,
2595  NULL);
2596  if (hentry)
2597  return hentry->function;
2598  else
2599  return NULL;
2600 }
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:902
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:63
PLpgSQL_function * function
Definition: pl_comp.c:68
static Node * plpgsql_param_ref ( ParseState pstate,
ParamRef pref 
)
static

Definition at line 1094 of file pl_comp.c.

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

Referenced by plpgsql_parser_setup().

1095 {
1096  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1097  char pname[32];
1098  PLpgSQL_nsitem *nse;
1099 
1100  snprintf(pname, sizeof(pname), "$%d", pref->number);
1101 
1102  nse = plpgsql_ns_lookup(expr->ns, false,
1103  pname, NULL, NULL,
1104  NULL);
1105 
1106  if (nse == NULL)
1107  return NULL; /* name not known to plpgsql */
1108 
1109  return make_datum_param(expr, nse->itemno, pref->location);
1110 }
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:244
int location
Definition: parsenodes.h:245
void * p_ref_hook_state
Definition: parse_node.h:214
static Node * make_datum_param(PLpgSQL_expr *expr, int dno, int location)
Definition: pl_comp.c:1310
PLpgSQL_type* plpgsql_parse_cwordrowtype ( List idents)

Definition at line 1835 of file pl_comp.c.

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

1836 {
1837  Oid classOid;
1838  RangeVar *relvar;
1839  MemoryContext oldCxt;
1840 
1841  if (list_length(idents) != 2)
1842  return NULL;
1843 
1844  /* Avoid memory leaks in long-term function context */
1846 
1847  /* Look up relation name. Can't lock it - we might not have privileges. */
1848  relvar = makeRangeVar(strVal(linitial(idents)),
1849  strVal(lsecond(idents)),
1850  -1);
1851  classOid = RangeVarGetRelid(relvar, NoLock, false);
1852 
1853  MemoryContextSwitchTo(oldCxt);
1854 
1855  /* Build and return the row type struct */
1856  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1857 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2132
#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
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 1696 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, ObjectIdGetDatum, OidIsValid, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_VAR, RangeVarGetRelid, ReleaseSysCache(), RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, RelnameGetRelid(), RELOID, SearchSysCache1(), SearchSysCacheAttName(), strVal, and TYPEOID.

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

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

Definition at line 2267 of file pl_comp.c.

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

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

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

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

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

Definition at line 1814 of file pl_comp.c.

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

1815 {
1816  Oid classOid;
1817 
1818  /* Lookup the relation */
1819  classOid = RelnameGetRelid(ident);
1820  if (!OidIsValid(classOid))
1821  ereport(ERROR,
1823  errmsg("relation \"%s\" does not exist", ident)));
1824 
1825  /* Build and return the row type struct */
1826  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1827 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2132
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:61
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:654
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#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 1633 of file pl_comp.c.

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

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

1024 {
1028  /* no need to use p_coerce_param_hook */
1029  pstate->p_ref_hook_state = (void *) expr;
1030 }
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1036
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:211
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:212
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1094
void * p_ref_hook_state
Definition: parse_node.h:214
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:210
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1050
static Node * plpgsql_post_column_ref ( ParseState pstate,
ColumnRef cref,
Node var 
)
static

Definition at line 1050 of file pl_comp.c.

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

Referenced by plpgsql_parser_setup().

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

Definition at line 1036 of file pl_comp.c.

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

Referenced by plpgsql_parser_setup().

1037 {
1038  PLpgSQL_expr *expr = (PLpgSQL_expr *) pstate->p_ref_hook_state;
1039 
1041  return resolve_column_ref(pstate, expr, cref, false);
1042  else
1043  return NULL;
1044 }
PLpgSQL_resolve_option resolve_option
Definition: plpgsql.h:857
struct PLpgSQL_function * func
Definition: plpgsql.h:229
void * p_ref_hook_state
Definition: parse_node.h:214
static Node * resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
Definition: pl_comp.c:1121
int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2231 of file pl_comp.c.

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

Referenced by exec_stmt_raise().

2232 {
2233  int i;
2234 
2235  if (allow_sqlstate)
2236  {
2237  if (strlen(condname) == 5 &&
2238  strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2239  return MAKE_SQLSTATE(condname[0],
2240  condname[1],
2241  condname[2],
2242  condname[3],
2243  condname[4]);
2244  }
2245 
2246  for (i = 0; exception_label_map[i].label != NULL; i++)
2247  {
2248  if (strcmp(condname, exception_label_map[i].label) == 0)
2250  }
2251 
2252  ereport(ERROR,
2253  (errcode(ERRCODE_UNDEFINED_OBJECT),
2254  errmsg("unrecognized exception condition \"%s\"",
2255  condname)));
2256  return 0; /* keep compiler quiet */
2257 }
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:82
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 2501 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().

2505 {
2506  int i;
2507 
2508  if (!forValidator)
2509  {
2510  /* normal case, pass to standard routine */
2511  if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
2512  call_expr))
2513  ereport(ERROR,
2514  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2515  errmsg("could not determine actual argument "
2516  "type for polymorphic function \"%s\"",
2517  proname)));
2518  }
2519  else
2520  {
2521  /* special validation case */
2522  for (i = 0; i < numargs; i++)
2523  {
2524  switch (argtypes[i])
2525  {
2526  case ANYELEMENTOID:
2527  case ANYNONARRAYOID:
2528  case ANYENUMOID: /* XXX dubious */
2529  argtypes[i] = INT4OID;
2530  break;
2531  case ANYARRAYOID:
2532  argtypes[i] = INT4ARRAYOID;
2533  break;
2534  case ANYRANGEOID:
2535  argtypes[i] = INT4RANGEOID;
2536  break;
2537  default:
2538  break;
2539  }
2540  }
2541  }
2542 }
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
Definition: funcapi.c:599
#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 2318 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

2319 {
2320  datums_alloc = 128;
2321  plpgsql_nDatums = 0;
2322  /* This is short-lived, so needn't allocate in function's cxt */
2324  sizeof(PLpgSQL_datum *) * datums_alloc);
2325  /* datums_last tracks what's been seen by plpgsql_add_initdatums() */
2326  datums_last = 0;
2327 }
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:706
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 1121 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, 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().

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

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}
}

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