PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plpgsql.h File Reference
#include "postgres.h"
#include "access/xact.h"
#include "commands/event_trigger.h"
#include "commands/trigger.h"
#include "executor/spi.h"
Include dependency graph for plpgsql.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PLpgSQL_type
 
struct  PLpgSQL_datum
 
struct  PLpgSQL_variable
 
struct  PLpgSQL_expr
 
struct  PLpgSQL_var
 
struct  PLpgSQL_row
 
struct  PLpgSQL_rec
 
struct  PLpgSQL_recfield
 
struct  PLpgSQL_arrayelem
 
struct  PLpgSQL_nsitem
 
struct  PLpgSQL_stmt
 
struct  PLpgSQL_condition
 
struct  PLpgSQL_exception_block
 
struct  PLpgSQL_exception
 
struct  PLpgSQL_stmt_block
 
struct  PLpgSQL_stmt_assign
 
struct  PLpgSQL_stmt_perform
 
struct  PLpgSQL_diag_item
 
struct  PLpgSQL_stmt_getdiag
 
struct  PLpgSQL_stmt_if
 
struct  PLpgSQL_if_elsif
 
struct  PLpgSQL_stmt_case
 
struct  PLpgSQL_case_when
 
struct  PLpgSQL_stmt_loop
 
struct  PLpgSQL_stmt_while
 
struct  PLpgSQL_stmt_fori
 
struct  PLpgSQL_stmt_forq
 
struct  PLpgSQL_stmt_fors
 
struct  PLpgSQL_stmt_forc
 
struct  PLpgSQL_stmt_dynfors
 
struct  PLpgSQL_stmt_foreach_a
 
struct  PLpgSQL_stmt_open
 
struct  PLpgSQL_stmt_fetch
 
struct  PLpgSQL_stmt_close
 
struct  PLpgSQL_stmt_exit
 
struct  PLpgSQL_stmt_return
 
struct  PLpgSQL_stmt_return_next
 
struct  PLpgSQL_stmt_return_query
 
struct  PLpgSQL_stmt_raise
 
struct  PLpgSQL_raise_option
 
struct  PLpgSQL_stmt_assert
 
struct  PLpgSQL_stmt_execsql
 
struct  PLpgSQL_stmt_dynexecute
 
struct  PLpgSQL_func_hashkey
 
struct  PLpgSQL_function
 
struct  PLpgSQL_execstate
 
struct  PLpgSQL_plugin
 
struct  PLword
 
struct  PLcword
 
struct  PLwdatum
 

Macros

#define TEXTDOMAIN   PG_TEXTDOMAIN("plpgsql")
 
#define _(x)   dgettext(TEXTDOMAIN, x)
 
#define PLPGSQL_XCHECK_NONE   0
 
#define PLPGSQL_XCHECK_SHADOWVAR   1
 
#define PLPGSQL_XCHECK_ALL   ((int) ~0)
 

Typedefs

typedef enum PLpgSQL_nsitem_type PLpgSQL_nsitem_type
 
typedef enum PLpgSQL_label_type PLpgSQL_label_type
 
typedef enum PLpgSQL_datum_type PLpgSQL_datum_type
 
typedef enum PLpgSQL_type_type PLpgSQL_type_type
 
typedef enum PLpgSQL_stmt_type PLpgSQL_stmt_type
 
typedef enum PLpgSQL_getdiag_kind PLpgSQL_getdiag_kind
 
typedef enum
PLpgSQL_raise_option_type 
PLpgSQL_raise_option_type
 
typedef enum PLpgSQL_resolve_option PLpgSQL_resolve_option
 
typedef struct PLpgSQL_type PLpgSQL_type
 
typedef struct PLpgSQL_datum PLpgSQL_datum
 
typedef struct PLpgSQL_variable PLpgSQL_variable
 
typedef struct PLpgSQL_expr PLpgSQL_expr
 
typedef struct PLpgSQL_var PLpgSQL_var
 
typedef struct PLpgSQL_row PLpgSQL_row
 
typedef struct PLpgSQL_rec PLpgSQL_rec
 
typedef struct PLpgSQL_recfield PLpgSQL_recfield
 
typedef struct PLpgSQL_arrayelem PLpgSQL_arrayelem
 
typedef struct PLpgSQL_nsitem PLpgSQL_nsitem
 
typedef struct PLpgSQL_stmt PLpgSQL_stmt
 
typedef struct PLpgSQL_condition PLpgSQL_condition
 
typedef struct
PLpgSQL_exception_block 
PLpgSQL_exception_block
 
typedef struct PLpgSQL_exception PLpgSQL_exception
 
typedef struct PLpgSQL_stmt_block PLpgSQL_stmt_block
 
typedef struct PLpgSQL_stmt_assign PLpgSQL_stmt_assign
 
typedef struct PLpgSQL_stmt_perform PLpgSQL_stmt_perform
 
typedef struct PLpgSQL_diag_item PLpgSQL_diag_item
 
typedef struct PLpgSQL_stmt_getdiag PLpgSQL_stmt_getdiag
 
typedef struct PLpgSQL_stmt_if PLpgSQL_stmt_if
 
typedef struct PLpgSQL_if_elsif PLpgSQL_if_elsif
 
typedef struct PLpgSQL_stmt_case PLpgSQL_stmt_case
 
typedef struct PLpgSQL_case_when PLpgSQL_case_when
 
typedef struct PLpgSQL_stmt_loop PLpgSQL_stmt_loop
 
typedef struct PLpgSQL_stmt_while PLpgSQL_stmt_while
 
typedef struct PLpgSQL_stmt_fori PLpgSQL_stmt_fori
 
typedef struct PLpgSQL_stmt_forq PLpgSQL_stmt_forq
 
typedef struct PLpgSQL_stmt_fors PLpgSQL_stmt_fors
 
typedef struct PLpgSQL_stmt_forc PLpgSQL_stmt_forc
 
typedef struct PLpgSQL_stmt_dynfors PLpgSQL_stmt_dynfors
 
typedef struct
PLpgSQL_stmt_foreach_a 
PLpgSQL_stmt_foreach_a
 
typedef struct PLpgSQL_stmt_open PLpgSQL_stmt_open
 
typedef struct PLpgSQL_stmt_fetch PLpgSQL_stmt_fetch
 
typedef struct PLpgSQL_stmt_close PLpgSQL_stmt_close
 
typedef struct PLpgSQL_stmt_exit PLpgSQL_stmt_exit
 
typedef struct PLpgSQL_stmt_return PLpgSQL_stmt_return
 
typedef struct
PLpgSQL_stmt_return_next 
PLpgSQL_stmt_return_next
 
typedef struct
PLpgSQL_stmt_return_query 
PLpgSQL_stmt_return_query
 
typedef struct PLpgSQL_stmt_raise PLpgSQL_stmt_raise
 
typedef struct PLpgSQL_raise_option PLpgSQL_raise_option
 
typedef struct PLpgSQL_stmt_assert PLpgSQL_stmt_assert
 
typedef struct PLpgSQL_stmt_execsql PLpgSQL_stmt_execsql
 
typedef struct
PLpgSQL_stmt_dynexecute 
PLpgSQL_stmt_dynexecute
 
typedef struct PLpgSQL_func_hashkey PLpgSQL_func_hashkey
 
typedef enum PLpgSQL_trigtype PLpgSQL_trigtype
 
typedef struct PLpgSQL_function PLpgSQL_function
 
typedef struct PLpgSQL_execstate PLpgSQL_execstate
 
typedef struct PLpgSQL_plugin PLpgSQL_plugin
 
typedef struct PLword PLword
 
typedef struct PLcword PLcword
 
typedef struct PLwdatum PLwdatum
 

Enumerations

enum  PLpgSQL_nsitem_type { PLPGSQL_NSTYPE_LABEL, PLPGSQL_NSTYPE_VAR, PLPGSQL_NSTYPE_ROW, PLPGSQL_NSTYPE_REC }
 
enum  PLpgSQL_label_type { PLPGSQL_LABEL_BLOCK, PLPGSQL_LABEL_LOOP, PLPGSQL_LABEL_OTHER }
 
enum  PLpgSQL_datum_type {
  PLPGSQL_DTYPE_VAR, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD,
  PLPGSQL_DTYPE_ARRAYELEM, PLPGSQL_DTYPE_EXPR
}
 
enum  PLpgSQL_type_type { PLPGSQL_TTYPE_SCALAR, PLPGSQL_TTYPE_ROW, PLPGSQL_TTYPE_REC, PLPGSQL_TTYPE_PSEUDO }
 
enum  PLpgSQL_stmt_type {
  PLPGSQL_STMT_BLOCK, PLPGSQL_STMT_ASSIGN, PLPGSQL_STMT_IF, PLPGSQL_STMT_CASE,
  PLPGSQL_STMT_LOOP, PLPGSQL_STMT_WHILE, PLPGSQL_STMT_FORI, PLPGSQL_STMT_FORS,
  PLPGSQL_STMT_FORC, PLPGSQL_STMT_FOREACH_A, PLPGSQL_STMT_EXIT, PLPGSQL_STMT_RETURN,
  PLPGSQL_STMT_RETURN_NEXT, PLPGSQL_STMT_RETURN_QUERY, PLPGSQL_STMT_RAISE, PLPGSQL_STMT_ASSERT,
  PLPGSQL_STMT_EXECSQL, PLPGSQL_STMT_DYNEXECUTE, PLPGSQL_STMT_DYNFORS, PLPGSQL_STMT_GETDIAG,
  PLPGSQL_STMT_OPEN, PLPGSQL_STMT_FETCH, PLPGSQL_STMT_CLOSE, PLPGSQL_STMT_PERFORM
}
 
enum  { PLPGSQL_RC_OK, PLPGSQL_RC_EXIT, PLPGSQL_RC_RETURN, PLPGSQL_RC_CONTINUE }
 
enum  PLpgSQL_getdiag_kind {
  PLPGSQL_GETDIAG_ROW_COUNT, PLPGSQL_GETDIAG_RESULT_OID, PLPGSQL_GETDIAG_CONTEXT, PLPGSQL_GETDIAG_ERROR_CONTEXT,
  PLPGSQL_GETDIAG_ERROR_DETAIL, PLPGSQL_GETDIAG_ERROR_HINT, PLPGSQL_GETDIAG_RETURNED_SQLSTATE, PLPGSQL_GETDIAG_COLUMN_NAME,
  PLPGSQL_GETDIAG_CONSTRAINT_NAME, PLPGSQL_GETDIAG_DATATYPE_NAME, PLPGSQL_GETDIAG_MESSAGE_TEXT, PLPGSQL_GETDIAG_TABLE_NAME,
  PLPGSQL_GETDIAG_SCHEMA_NAME
}
 
enum  PLpgSQL_raise_option_type {
  PLPGSQL_RAISEOPTION_ERRCODE, PLPGSQL_RAISEOPTION_MESSAGE, PLPGSQL_RAISEOPTION_DETAIL, PLPGSQL_RAISEOPTION_HINT,
  PLPGSQL_RAISEOPTION_COLUMN, PLPGSQL_RAISEOPTION_CONSTRAINT, PLPGSQL_RAISEOPTION_DATATYPE, PLPGSQL_RAISEOPTION_TABLE,
  PLPGSQL_RAISEOPTION_SCHEMA
}
 
enum  PLpgSQL_resolve_option { PLPGSQL_RESOLVE_ERROR, PLPGSQL_RESOLVE_VARIABLE, PLPGSQL_RESOLVE_COLUMN }
 
enum  PLpgSQL_trigtype { PLPGSQL_DML_TRIGGER, PLPGSQL_EVENT_TRIGGER, PLPGSQL_NOT_TRIGGER }
 
enum  IdentifierLookup { IDENTIFIER_LOOKUP_NORMAL, IDENTIFIER_LOOKUP_DECLARE, IDENTIFIER_LOOKUP_EXPR }
 

Functions

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_typeplpgsql_build_datatype (Oid typeOid, int32 typmod, Oid collation)
 
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)
 
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)
 
void _PG_init (void)
 
Datum plpgsql_exec_function (PLpgSQL_function *func, FunctionCallInfo fcinfo, EState *simple_eval_estate)
 
HeapTuple plpgsql_exec_trigger (PLpgSQL_function *func, TriggerData *trigdata)
 
void plpgsql_exec_event_trigger (PLpgSQL_function *func, EventTriggerData *trigdata)
 
void plpgsql_xact_cb (XactEvent event, void *arg)
 
void plpgsql_subxact_cb (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
 
Oid plpgsql_exec_get_datum_type (PLpgSQL_execstate *estate, PLpgSQL_datum *datum)
 
void plpgsql_exec_get_datum_type_info (PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeid, int32 *typmod, Oid *collation)
 
void plpgsql_ns_init (void)
 
void plpgsql_ns_push (const char *label, PLpgSQL_label_type label_type)
 
void plpgsql_ns_pop (void)
 
PLpgSQL_nsitemplpgsql_ns_top (void)
 
void plpgsql_ns_additem (PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
 
PLpgSQL_nsitemplpgsql_ns_lookup (PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
 
PLpgSQL_nsitemplpgsql_ns_lookup_label (PLpgSQL_nsitem *ns_cur, const char *name)
 
PLpgSQL_nsitemplpgsql_ns_find_nearest_loop (PLpgSQL_nsitem *ns_cur)
 
const char * plpgsql_stmt_typename (PLpgSQL_stmt *stmt)
 
const char * plpgsql_getdiag_kindname (PLpgSQL_getdiag_kind kind)
 
void plpgsql_free_function_memory (PLpgSQL_function *func)
 
void plpgsql_dumptree (PLpgSQL_function *func)
 
int plpgsql_base_yylex (void)
 
int plpgsql_yylex (void)
 
void plpgsql_push_back_token (int token)
 
bool plpgsql_token_is_unreserved_keyword (int token)
 
void plpgsql_append_source_text (StringInfo buf, int startlocation, int endlocation)
 
int plpgsql_peek (void)
 
void plpgsql_peek2 (int *tok1_p, int *tok2_p, int *tok1_loc, int *tok2_loc)
 
int plpgsql_scanner_errposition (int location)
 
void plpgsql_yyerror (const char *message) pg_attribute_noreturn()
 
int plpgsql_location_to_lineno (int location)
 
int plpgsql_latest_lineno (void)
 
void plpgsql_scanner_init (const char *str)
 
void plpgsql_scanner_finish (void)
 
int plpgsql_yyparse (void)
 

Variables

IdentifierLookup plpgsql_IdentifierLookup
 
int plpgsql_variable_conflict
 
bool plpgsql_print_strict_params
 
bool plpgsql_check_asserts
 
int plpgsql_extra_warnings
 
int plpgsql_extra_errors
 
bool plpgsql_check_syntax
 
bool plpgsql_DumpExecTree
 
PLpgSQL_stmt_blockplpgsql_parse_result
 
int plpgsql_nDatums
 
PLpgSQL_datum ** plpgsql_Datums
 
char * plpgsql_error_funcname
 
PLpgSQL_functionplpgsql_curr_compile
 
MemoryContext plpgsql_compile_tmp_cxt
 
PLpgSQL_plugin ** plpgsql_plugin_ptr
 

Macro Definition Documentation

#define _ (   x)    dgettext(TEXTDOMAIN, x)

Definition at line 35 of file plpgsql.h.

#define PLPGSQL_XCHECK_ALL   ((int) ~0)

Definition at line 1029 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

#define PLPGSQL_XCHECK_NONE   0

Definition at line 1027 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

#define PLPGSQL_XCHECK_SHADOWVAR   1

Definition at line 1028 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

#define TEXTDOMAIN   PG_TEXTDOMAIN("plpgsql")

Definition at line 32 of file plpgsql.h.

Typedef Documentation

Enumeration Type Documentation

anonymous enum
Enumerator
PLPGSQL_RC_OK 
PLPGSQL_RC_EXIT 
PLPGSQL_RC_RETURN 
PLPGSQL_RC_CONTINUE 

Definition at line 116 of file plpgsql.h.

Enumerator
IDENTIFIER_LOOKUP_NORMAL 
IDENTIFIER_LOOKUP_DECLARE 
IDENTIFIER_LOOKUP_EXPR 

Definition at line 1011 of file plpgsql.h.

1012 {
1013  IDENTIFIER_LOOKUP_NORMAL, /* normal processing of var names */
1014  IDENTIFIER_LOOKUP_DECLARE, /* In DECLARE --- don't look up names */
1015  IDENTIFIER_LOOKUP_EXPR /* In SQL expression --- special case */
IdentifierLookup
Definition: plpgsql.h:1011
Enumerator
PLPGSQL_DTYPE_VAR 
PLPGSQL_DTYPE_ROW 
PLPGSQL_DTYPE_REC 
PLPGSQL_DTYPE_RECFIELD 
PLPGSQL_DTYPE_ARRAYELEM 
PLPGSQL_DTYPE_EXPR 

Definition at line 61 of file plpgsql.h.

Enumerator
PLPGSQL_GETDIAG_ROW_COUNT 
PLPGSQL_GETDIAG_RESULT_OID 
PLPGSQL_GETDIAG_CONTEXT 
PLPGSQL_GETDIAG_ERROR_CONTEXT 
PLPGSQL_GETDIAG_ERROR_DETAIL 
PLPGSQL_GETDIAG_ERROR_HINT 
PLPGSQL_GETDIAG_RETURNED_SQLSTATE 
PLPGSQL_GETDIAG_COLUMN_NAME 
PLPGSQL_GETDIAG_CONSTRAINT_NAME 
PLPGSQL_GETDIAG_DATATYPE_NAME 
PLPGSQL_GETDIAG_MESSAGE_TEXT 
PLPGSQL_GETDIAG_TABLE_NAME 
PLPGSQL_GETDIAG_SCHEMA_NAME 

Definition at line 127 of file plpgsql.h.

Enumerator
PLPGSQL_LABEL_BLOCK 
PLPGSQL_LABEL_LOOP 
PLPGSQL_LABEL_OTHER 

Definition at line 51 of file plpgsql.h.

52 {
53  PLPGSQL_LABEL_BLOCK, /* DECLARE/BEGIN block */
54  PLPGSQL_LABEL_LOOP, /* looping construct */
55  PLPGSQL_LABEL_OTHER /* anything else */
PLpgSQL_label_type
Definition: plpgsql.h:51
Enumerator
PLPGSQL_NSTYPE_LABEL 
PLPGSQL_NSTYPE_VAR 
PLPGSQL_NSTYPE_ROW 
PLPGSQL_NSTYPE_REC 

Definition at line 40 of file plpgsql.h.

Enumerator
PLPGSQL_RAISEOPTION_ERRCODE 
PLPGSQL_RAISEOPTION_MESSAGE 
PLPGSQL_RAISEOPTION_DETAIL 
PLPGSQL_RAISEOPTION_HINT 
PLPGSQL_RAISEOPTION_COLUMN 
PLPGSQL_RAISEOPTION_CONSTRAINT 
PLPGSQL_RAISEOPTION_DATATYPE 
PLPGSQL_RAISEOPTION_TABLE 
PLPGSQL_RAISEOPTION_SCHEMA 

Definition at line 147 of file plpgsql.h.

Enumerator
PLPGSQL_RESOLVE_ERROR 
PLPGSQL_RESOLVE_VARIABLE 
PLPGSQL_RESOLVE_COLUMN 

Definition at line 163 of file plpgsql.h.

164 {
165  PLPGSQL_RESOLVE_ERROR, /* throw error if ambiguous */
166  PLPGSQL_RESOLVE_VARIABLE, /* prefer plpgsql var to table column */
167  PLPGSQL_RESOLVE_COLUMN /* prefer table column to plpgsql var */
PLpgSQL_resolve_option
Definition: plpgsql.h:163
Enumerator
PLPGSQL_STMT_BLOCK 
PLPGSQL_STMT_ASSIGN 
PLPGSQL_STMT_IF 
PLPGSQL_STMT_CASE 
PLPGSQL_STMT_LOOP 
PLPGSQL_STMT_WHILE 
PLPGSQL_STMT_FORI 
PLPGSQL_STMT_FORS 
PLPGSQL_STMT_FORC 
PLPGSQL_STMT_FOREACH_A 
PLPGSQL_STMT_EXIT 
PLPGSQL_STMT_RETURN 
PLPGSQL_STMT_RETURN_NEXT 
PLPGSQL_STMT_RETURN_QUERY 
PLPGSQL_STMT_RAISE 
PLPGSQL_STMT_ASSERT 
PLPGSQL_STMT_EXECSQL 
PLPGSQL_STMT_DYNEXECUTE 
PLPGSQL_STMT_DYNFORS 
PLPGSQL_STMT_GETDIAG 
PLPGSQL_STMT_OPEN 
PLPGSQL_STMT_FETCH 
PLPGSQL_STMT_CLOSE 
PLPGSQL_STMT_PERFORM 

Definition at line 85 of file plpgsql.h.

86 {
PLpgSQL_stmt_type
Definition: plpgsql.h:85
Enumerator
PLPGSQL_DML_TRIGGER 
PLPGSQL_EVENT_TRIGGER 
PLPGSQL_NOT_TRIGGER 

Definition at line 809 of file plpgsql.h.

Enumerator
PLPGSQL_TTYPE_SCALAR 
PLPGSQL_TTYPE_ROW 
PLPGSQL_TTYPE_REC 
PLPGSQL_TTYPE_PSEUDO 

Definition at line 74 of file plpgsql.h.

75 {
76  PLPGSQL_TTYPE_SCALAR, /* scalar types and domains */
77  PLPGSQL_TTYPE_ROW, /* composite types */
78  PLPGSQL_TTYPE_REC, /* RECORD pseudotype */
79  PLPGSQL_TTYPE_PSEUDO /* other pseudotypes */
PLpgSQL_type_type
Definition: plpgsql.h:74

Function Documentation

void _PG_init ( void  )

Definition at line 56 of file auth_delay.c.

57 {
58  /* Define custom GUC variables */
59  DefineCustomIntVariable("auth_delay.milliseconds",
60  "Milliseconds to delay before reporting authentication failure",
61  NULL,
63  0,
64  0, INT_MAX / 1000,
65  PGC_SIGHUP,
67  NULL,
68  NULL,
69  NULL);
70  /* Install Hooks */
73 }
void DefineCustomIntVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, int minValue, int maxValue, GucContext context, int flags, GucIntCheckHook check_hook, GucIntAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:7709
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:226
static ClientAuthentication_hook_type original_client_auth_hook
Definition: auth_delay.c:29
Definition: guc.h:72
static void auth_delay_checks(Port *port, int status)
Definition: auth_delay.c:35
#define NULL
Definition: c.h:226
static int auth_delay_milliseconds
Definition: auth_delay.c:26
#define GUC_UNIT_MS
Definition: guc.h:224
int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2387 of file pl_comp.c.

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

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

Definition at line 2326 of file pl_comp.c.

References datums_alloc, plpgsql_nDatums, and repalloc().

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

2327 {
2329  {
2330  datums_alloc *= 2;
2332  }
2333 
2334  new->dno = plpgsql_nDatums;
2336 }
int plpgsql_nDatums
Definition: pl_comp.c:44
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:45
static int datums_alloc
Definition: pl_comp.c:43
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021
void plpgsql_append_source_text ( StringInfo  buf,
int  startlocation,
int  endlocation 
)

Definition at line 518 of file pl_scanner.c.

References appendBinaryStringInfo(), Assert, and scanorig.

520 {
521  Assert(startlocation <= endlocation);
522  appendBinaryStringInfo(buf, scanorig + startlocation,
523  endlocation - startlocation);
524 }
static const char * scanorig
Definition: pl_scanner.c:212
#define Assert(condition)
Definition: c.h:671
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
int plpgsql_base_yylex ( void  )
PLpgSQL_type* plpgsql_build_datatype ( Oid  typeOid,
int32  typmod,
Oid  collation 
)

Definition at line 2123 of file pl_comp.c.

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

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

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

Definition at line 1941 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_build_variable().

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

Definition at line 1861 of file pl_comp.c.

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

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

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

Definition at line 135 of file pl_comp.c.

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

Referenced by plpgsql_call_handler(), and plpgsql_validator().

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

Definition at line 792 of file pl_comp.c.

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

Referenced by plpgsql_inline_handler().

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

Definition at line 1541 of file pl_funcs.c.

References PLpgSQL_function::action, PLpgSQL_type::atttypmod, PLpgSQL_var::cursor_explicit_argrow, PLpgSQL_var::cursor_explicit_expr, PLpgSQL_var::datatype, PLpgSQL_function::datums, PLpgSQL_var::default_val, PLpgSQL_datum::dtype, dump_block(), dump_expr(), dump_indent, PLpgSQL_row::fieldnames, PLpgSQL_function::fn_signature, i, PLpgSQL_var::isconst, PLpgSQL_stmt_block::lineno, PLpgSQL_function::ndatums, PLpgSQL_row::nfields, PLpgSQL_var::notnull, NULL, PLPGSQL_DTYPE_ARRAYELEM, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, PLpgSQL_var::refname, PLpgSQL_row::refname, PLpgSQL_type::typname, PLpgSQL_type::typoid, and PLpgSQL_row::varnos.

Referenced by do_compile().

1542 {
1543  int i;
1544  PLpgSQL_datum *d;
1545 
1546  printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1547  func->fn_signature);
1548 
1549  printf("\nFunction's data area:\n");
1550  for (i = 0; i < func->ndatums; i++)
1551  {
1552  d = func->datums[i];
1553 
1554  printf(" entry %d: ", i);
1555  switch (d->dtype)
1556  {
1557  case PLPGSQL_DTYPE_VAR:
1558  {
1559  PLpgSQL_var *var = (PLpgSQL_var *) d;
1560 
1561  printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1562  var->refname, var->datatype->typname,
1563  var->datatype->typoid,
1564  var->datatype->atttypmod);
1565  if (var->isconst)
1566  printf(" CONSTANT\n");
1567  if (var->notnull)
1568  printf(" NOT NULL\n");
1569  if (var->default_val != NULL)
1570  {
1571  printf(" DEFAULT ");
1572  dump_expr(var->default_val);
1573  printf("\n");
1574  }
1575  if (var->cursor_explicit_expr != NULL)
1576  {
1577  if (var->cursor_explicit_argrow >= 0)
1578  printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1579 
1580  printf(" CURSOR IS ");
1582  printf("\n");
1583  }
1584  }
1585  break;
1586  case PLPGSQL_DTYPE_ROW:
1587  {
1588  PLpgSQL_row *row = (PLpgSQL_row *) d;
1589  int i;
1590 
1591  printf("ROW %-16s fields", row->refname);
1592  for (i = 0; i < row->nfields; i++)
1593  {
1594  if (row->fieldnames[i])
1595  printf(" %s=var %d", row->fieldnames[i],
1596  row->varnos[i]);
1597  }
1598  printf("\n");
1599  }
1600  break;
1601  case PLPGSQL_DTYPE_REC:
1602  printf("REC %s\n", ((PLpgSQL_rec *) d)->refname);
1603  break;
1605  printf("RECFIELD %-16s of REC %d\n",
1606  ((PLpgSQL_recfield *) d)->fieldname,
1607  ((PLpgSQL_recfield *) d)->recparentno);
1608  break;
1610  printf("ARRAYELEM of VAR %d subscript ",
1611  ((PLpgSQL_arrayelem *) d)->arrayparentno);
1612  dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
1613  printf("\n");
1614  break;
1615  default:
1616  printf("??? unknown data type %d\n", d->dtype);
1617  }
1618  }
1619  printf("\nFunction's statements:\n");
1620 
1621  dump_indent = 0;
1622  printf("%3d:", func->action->lineno);
1623  dump_block(func->action);
1624  printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1625  fflush(stdout);
1626 }
PLpgSQL_datum ** datums
Definition: plpgsql.h:868
char * refname
Definition: plpgsql.h:283
int notnull
Definition: plpgsql.h:265
int isconst
Definition: plpgsql.h:264
char * refname
Definition: plpgsql.h:260
PLpgSQL_stmt_block * action
Definition: plpgsql.h:872
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:267
PLpgSQL_type * datatype
Definition: plpgsql.h:263
PLpgSQL_datum_type dtype
Definition: plpgsql.h:200
int cursor_explicit_argrow
Definition: plpgsql.h:268
char ** fieldnames
Definition: plpgsql.h:295
PLpgSQL_expr * default_val
Definition: plpgsql.h:266
int * varnos
Definition: plpgsql.h:296
#define NULL
Definition: c.h:226
int nfields
Definition: plpgsql.h:294
static int dump_indent
Definition: pl_funcs.c:749
char * fn_signature
Definition: plpgsql.h:821
char * typname
Definition: plpgsql.h:180
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:886
int32 atttypmod
Definition: plpgsql.h:189
static void dump_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:1535
int i
Oid typoid
Definition: plpgsql.h:181
void plpgsql_exec_event_trigger ( PLpgSQL_function func,
EventTriggerData trigdata 
)

Definition at line 885 of file pl_exec.c.

References PLpgSQL_function::action, ErrorContextCallback::arg, assign_text_var(), ErrorContextCallback::callback, copy_plpgsql_datum(), PLpgSQL_function::datums, PLpgSQL_execstate::datums, ereport, PLpgSQL_execstate::err_stmt, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, EventTriggerData::event, exec_eval_cleanup(), exec_stmt_block(), PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, gettext_noop, i, PLpgSQL_execstate::ndatums, NULL, plpgsql_destroy_econtext(), plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, ErrorContextCallback::previous, EventTriggerData::tag, PLpgSQL_function::tg_event_varno, and PLpgSQL_function::tg_tag_varno.

Referenced by plpgsql_call_handler().

886 {
887  PLpgSQL_execstate estate;
888  ErrorContextCallback plerrcontext;
889  int i;
890  int rc;
891  PLpgSQL_var *var;
892 
893  /*
894  * Setup the execution state
895  */
896  plpgsql_estate_setup(&estate, func, NULL, NULL);
897 
898  /*
899  * Setup error traceback support for ereport()
900  */
901  plerrcontext.callback = plpgsql_exec_error_callback;
902  plerrcontext.arg = &estate;
903  plerrcontext.previous = error_context_stack;
904  error_context_stack = &plerrcontext;
905 
906  /*
907  * Make local execution copies of all the datums
908  */
909  estate.err_text = gettext_noop("during initialization of execution state");
910  for (i = 0; i < estate.ndatums; i++)
911  estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
912 
913  /*
914  * Assign the special tg_ variables
915  */
916  var = (PLpgSQL_var *) (estate.datums[func->tg_event_varno]);
917  assign_text_var(&estate, var, trigdata->event);
918 
919  var = (PLpgSQL_var *) (estate.datums[func->tg_tag_varno]);
920  assign_text_var(&estate, var, trigdata->tag);
921 
922  /*
923  * Let the instrumentation plugin peek at this function
924  */
925  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
926  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
927 
928  /*
929  * Now call the toplevel block of statements
930  */
931  estate.err_text = NULL;
932  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
933  rc = exec_stmt_block(&estate, func->action);
934  if (rc != PLPGSQL_RC_RETURN)
935  {
936  estate.err_stmt = NULL;
937  estate.err_text = NULL;
938  ereport(ERROR,
939  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
940  errmsg("control reached end of trigger procedure without RETURN")));
941  }
942 
943  estate.err_stmt = NULL;
944  estate.err_text = gettext_noop("during function exit");
945 
946  /*
947  * Let the instrumentation plugin peek at this function
948  */
949  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
950  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
951 
952  /* Clean up any leftover temporary memory */
953  plpgsql_destroy_econtext(&estate);
954  exec_eval_cleanup(&estate);
955  /* stmt_mcontext will be destroyed when function's main context is */
956 
957  /*
958  * Pop the error context stack
959  */
960  error_context_stack = plerrcontext.previous;
961 
962  return;
963 }
int tg_event_varno
Definition: plpgsql.h:855
PLpgSQL_datum ** datums
Definition: plpgsql.h:868
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:933
PLpgSQL_stmt_block * action
Definition: plpgsql.h:872
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:969
#define gettext_noop(x)
Definition: c.h:139
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3388
int errcode(int sqlerrcode)
Definition: elog.c:575
const char * tag
Definition: event_trigger.h:28
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:3531
struct ErrorContextCallback * previous
Definition: elog.h:238
PLpgSQL_datum ** datums
Definition: plpgsql.h:909
ErrorContextCallback * error_context_stack
Definition: elog.c:88
#define ERROR
Definition: elog.h:43
const char * event
Definition: event_trigger.h:26
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:7053
#define ereport(elevel, rest)
Definition: elog.h:122
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:56
const char * err_text
Definition: plpgsql.h:934
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:973
#define NULL
Definition: c.h:226
static void assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, const char *str)
Definition: pl_exec.c:7168
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1173
void(* callback)(void *arg)
Definition: elog.h:239
int errmsg(const char *fmt,...)
Definition: elog.c:797
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:974
int i
static PLpgSQL_datum * copy_plpgsql_datum(PLpgSQL_datum *datum)
Definition: pl_exec.c:1027
Datum plpgsql_exec_function ( PLpgSQL_function func,
FunctionCallInfo  fcinfo,
EState simple_eval_estate 
)

Definition at line 329 of file pl_exec.c.

References PLpgSQL_function::action, ReturnSetInfo::allowedModes, FunctionCallInfoData::arg, ErrorContextCallback::arg, FunctionCallInfoData::argnull, assign_simple_var(), ErrorContextCallback::callback, convert_tuples_by_position(), copy_plpgsql_datum(), CreateTupleDescCopy(), CurrentMemoryContext, PLpgSQL_var::datatype, DatumGetPointer, PLpgSQL_function::datums, PLpgSQL_execstate::datums, do_convert_tuple(), PLpgSQL_datum::dtype, elog, ereport, PLpgSQL_execstate::err_stmt, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, exec_cast_value(), exec_eval_cleanup(), exec_move_row(), exec_move_row_from_datum(), exec_set_found(), exec_stmt_block(), expand_array(), PLpgSQL_function::fn_argvarnos, PLpgSQL_function::fn_nargs, PLpgSQL_function::fn_retbyval, PLpgSQL_function::fn_rettype, PLpgSQL_function::fn_rettyplen, PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, get_call_result_type(), gettext_noop, i, IsA, FunctionCallInfoData::isnull, PLpgSQL_var::isnull, MemoryContextSwitchTo(), PLpgSQL_execstate::ndatums, NULL, plpgsql_destroy_econtext(), PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, PointerGetDatum, ErrorContextCallback::previous, FunctionCallInfoData::resultinfo, PLpgSQL_execstate::retisnull, PLpgSQL_execstate::retisset, PLpgSQL_execstate::retistuple, PLpgSQL_execstate::rettupdesc, PLpgSQL_execstate::rettype, ReturnSetInfo::returnMode, PLpgSQL_execstate::retval, PLpgSQL_execstate::rsi, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, SPI_datumTransfer(), SPI_returntuple(), TransferExpandedObject(), PLpgSQL_execstate::tuple_store, PLpgSQL_execstate::tuple_store_cxt, TYPEFUNC_COMPOSITE, TYPEFUNC_RECORD, PLpgSQL_type::typisarray, PLpgSQL_var::value, VARATT_IS_EXTERNAL_EXPANDED_RO, and VARATT_IS_EXTERNAL_EXPANDED_RW.

Referenced by plpgsql_call_handler(), and plpgsql_inline_handler().

331 {
332  PLpgSQL_execstate estate;
333  ErrorContextCallback plerrcontext;
334  int i;
335  int rc;
336 
337  /*
338  * Setup the execution state
339  */
340  plpgsql_estate_setup(&estate, func, (ReturnSetInfo *) fcinfo->resultinfo,
341  simple_eval_estate);
342 
343  /*
344  * Setup error traceback support for ereport()
345  */
346  plerrcontext.callback = plpgsql_exec_error_callback;
347  plerrcontext.arg = &estate;
348  plerrcontext.previous = error_context_stack;
349  error_context_stack = &plerrcontext;
350 
351  /*
352  * Make local execution copies of all the datums
353  */
354  estate.err_text = gettext_noop("during initialization of execution state");
355  for (i = 0; i < estate.ndatums; i++)
356  estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
357 
358  /*
359  * Store the actual call argument values into the appropriate variables
360  */
361  estate.err_text = gettext_noop("while storing call arguments into local variables");
362  for (i = 0; i < func->fn_nargs; i++)
363  {
364  int n = func->fn_argvarnos[i];
365 
366  switch (estate.datums[n]->dtype)
367  {
368  case PLPGSQL_DTYPE_VAR:
369  {
370  PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
371 
372  assign_simple_var(&estate, var,
373  fcinfo->arg[i],
374  fcinfo->argnull[i],
375  false);
376 
377  /*
378  * Force any array-valued parameter to be stored in
379  * expanded form in our local variable, in hopes of
380  * improving efficiency of uses of the variable. (This is
381  * a hack, really: why only arrays? Need more thought
382  * about which cases are likely to win. See also
383  * typisarray-specific heuristic in exec_assign_value.)
384  *
385  * Special cases: If passed a R/W expanded pointer, assume
386  * we can commandeer the object rather than having to copy
387  * it. If passed a R/O expanded pointer, just keep it as
388  * the value of the variable for the moment. (We'll force
389  * it to R/W if the variable gets modified, but that may
390  * very well never happen.)
391  */
392  if (!var->isnull && var->datatype->typisarray)
393  {
395  {
396  /* take ownership of R/W object */
397  assign_simple_var(&estate, var,
400  false,
401  true);
402  }
404  {
405  /* R/O pointer, keep it as-is until assigned to */
406  }
407  else
408  {
409  /* flat array, so force to expanded form */
410  assign_simple_var(&estate, var,
411  expand_array(var->value,
413  NULL),
414  false,
415  true);
416  }
417  }
418  }
419  break;
420 
421  case PLPGSQL_DTYPE_ROW:
422  {
423  PLpgSQL_row *row = (PLpgSQL_row *) estate.datums[n];
424 
425  if (!fcinfo->argnull[i])
426  {
427  /* Assign row value from composite datum */
428  exec_move_row_from_datum(&estate, NULL, row,
429  fcinfo->arg[i]);
430  }
431  else
432  {
433  /* If arg is null, treat it as an empty row */
434  exec_move_row(&estate, NULL, row, NULL, NULL);
435  }
436  /* clean up after exec_move_row() */
437  exec_eval_cleanup(&estate);
438  }
439  break;
440 
441  default:
442  elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
443  }
444  }
445 
446  estate.err_text = gettext_noop("during function entry");
447 
448  /*
449  * Set the magic variable FOUND to false
450  */
451  exec_set_found(&estate, false);
452 
453  /*
454  * Let the instrumentation plugin peek at this function
455  */
456  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
457  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
458 
459  /*
460  * Now call the toplevel block of statements
461  */
462  estate.err_text = NULL;
463  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
464  rc = exec_stmt_block(&estate, func->action);
465  if (rc != PLPGSQL_RC_RETURN)
466  {
467  estate.err_stmt = NULL;
468  estate.err_text = NULL;
469  ereport(ERROR,
470  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
471  errmsg("control reached end of function without RETURN")));
472  }
473 
474  /*
475  * We got a return value - process it
476  */
477  estate.err_stmt = NULL;
478  estate.err_text = gettext_noop("while casting return value to function's return type");
479 
480  fcinfo->isnull = estate.retisnull;
481 
482  if (estate.retisset)
483  {
484  ReturnSetInfo *rsi = estate.rsi;
485 
486  /* Check caller can handle a set result */
487  if (!rsi || !IsA(rsi, ReturnSetInfo) ||
488  (rsi->allowedModes & SFRM_Materialize) == 0)
489  ereport(ERROR,
490  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
491  errmsg("set-valued function called in context that cannot accept a set")));
493 
494  /* If we produced any tuples, send back the result */
495  if (estate.tuple_store)
496  {
497  rsi->setResult = estate.tuple_store;
498  if (estate.rettupdesc)
499  {
500  MemoryContext oldcxt;
501 
502  oldcxt = MemoryContextSwitchTo(estate.tuple_store_cxt);
503  rsi->setDesc = CreateTupleDescCopy(estate.rettupdesc);
504  MemoryContextSwitchTo(oldcxt);
505  }
506  }
507  estate.retval = (Datum) 0;
508  fcinfo->isnull = true;
509  }
510  else if (!estate.retisnull)
511  {
512  if (estate.retistuple)
513  {
514  /*
515  * We have to check that the returned tuple actually matches the
516  * expected result type. XXX would be better to cache the tupdesc
517  * instead of repeating get_call_result_type()
518  */
519  HeapTuple rettup = (HeapTuple) DatumGetPointer(estate.retval);
520  TupleDesc tupdesc;
521  TupleConversionMap *tupmap;
522 
523  switch (get_call_result_type(fcinfo, NULL, &tupdesc))
524  {
525  case TYPEFUNC_COMPOSITE:
526  /* got the expected result rowtype, now check it */
527  tupmap = convert_tuples_by_position(estate.rettupdesc,
528  tupdesc,
529  gettext_noop("returned record type does not match expected record type"));
530  /* it might need conversion */
531  if (tupmap)
532  rettup = do_convert_tuple(rettup, tupmap);
533  /* no need to free map, we're about to return anyway */
534  break;
535  case TYPEFUNC_RECORD:
536 
537  /*
538  * Failed to determine actual type of RECORD. We could
539  * raise an error here, but what this means in practice is
540  * that the caller is expecting any old generic rowtype,
541  * so we don't really need to be restrictive. Pass back
542  * the generated result type, instead.
543  */
544  tupdesc = estate.rettupdesc;
545  if (tupdesc == NULL) /* shouldn't happen */
546  elog(ERROR, "return type must be a row type");
547  break;
548  default:
549  /* shouldn't get here if retistuple is true ... */
550  elog(ERROR, "return type must be a row type");
551  break;
552  }
553 
554  /*
555  * Copy tuple to upper executor memory, as a tuple Datum. Make
556  * sure it is labeled with the caller-supplied tuple type.
557  */
558  estate.retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
559  }
560  else
561  {
562  /* Cast value to proper type */
563  estate.retval = exec_cast_value(&estate,
564  estate.retval,
565  &fcinfo->isnull,
566  estate.rettype,
567  -1,
568  func->fn_rettype,
569  -1);
570 
571  /*
572  * If the function's return type isn't by value, copy the value
573  * into upper executor memory context. However, if we have a R/W
574  * expanded datum, we can just transfer its ownership out to the
575  * upper executor context.
576  */
577  if (!fcinfo->isnull && !func->fn_retbyval)
578  estate.retval = SPI_datumTransfer(estate.retval,
579  false,
580  func->fn_rettyplen);
581  }
582  }
583 
584  estate.err_text = gettext_noop("during function exit");
585 
586  /*
587  * Let the instrumentation plugin peek at this function
588  */
589  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
590  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
591 
592  /* Clean up any leftover temporary memory */
593  plpgsql_destroy_econtext(&estate);
594  exec_eval_cleanup(&estate);
595  /* stmt_mcontext will be destroyed when function's main context is */
596 
597  /*
598  * Pop the error context stack
599  */
600  error_context_stack = plerrcontext.previous;
601 
602  /*
603  * Return the function's result
604  */
605  return estate.retval;
606 }
bool fn_retbyval
Definition: plpgsql.h:832
PLpgSQL_datum ** datums
Definition: plpgsql.h:868
int fn_argvarnos[FUNC_MAX_ARGS]
Definition: plpgsql.h:838
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:141
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
HeapTupleData * HeapTuple
Definition: htup.h:70
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc)
Definition: spi.c:657
static void exec_move_row_from_datum(PLpgSQL_execstate *estate, PLpgSQL_rec *rec, PLpgSQL_row *row, Datum value)
Definition: pl_exec.c:6170
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:933
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:66
PLpgSQL_stmt_block * action
Definition: plpgsql.h:872
#define PointerGetDatum(X)
Definition: postgres.h:564
PLpgSQL_type * datatype
Definition: plpgsql.h:263
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:969
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define gettext_noop(x)
Definition: c.h:139
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3388
int errcode(int sqlerrcode)
Definition: elog.c:575
static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, Datum newvalue, bool isnull, bool freeable)
Definition: pl_exec.c:7133
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:3531
PLpgSQL_datum_type dtype
Definition: plpgsql.h:200
struct ErrorContextCallback * previous
Definition: elog.h:238
PLpgSQL_datum ** datums
Definition: plpgsql.h:909
ErrorContextCallback * error_context_stack
Definition: elog.c:88
Datum TransferExpandedObject(Datum d, MemoryContext new_parent)
static Datum exec_cast_value(PLpgSQL_execstate *estate, Datum value, bool *isnull, Oid valtype, int32 valtypmod, Oid reqtype, int32 reqtypmod)
Definition: pl_exec.c:6244
TupleDesc rettupdesc
Definition: plpgsql.h:896
#define ERROR
Definition: elog.h:43
MemoryContext tuple_store_cxt
Definition: plpgsql.h:902
Datum SPI_datumTransfer(Datum value, bool typByVal, int typLen)
Definition: spi.c:944
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:7053
fmNodePtr resultinfo
Definition: fmgr.h:73
ReturnSetInfo * rsi
Definition: plpgsql.h:904
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:78
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
static void exec_move_row(PLpgSQL_execstate *estate, PLpgSQL_rec *rec, PLpgSQL_row *row, HeapTuple tup, TupleDesc tupdesc)
Definition: pl_exec.c:5925
#define ereport(elevel, rest)
Definition: elog.h:122
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:56
Tuplestorestate * tuple_store
Definition: plpgsql.h:901
bool typisarray
Definition: plpgsql.h:188
uintptr_t Datum
Definition: postgres.h:374
const char * err_text
Definition: plpgsql.h:934
Datum value
Definition: plpgsql.h:271
int allowedModes
Definition: execnodes.h:199
Datum arg[FUNC_MAX_ARGS]
Definition: fmgr.h:77
SetFunctionReturnMode returnMode
Definition: execnodes.h:201
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:973
#define NULL
Definition: c.h:226
#define VARATT_IS_EXTERNAL_EXPANDED_RO(PTR)
Definition: postgres.h:321
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:6987
HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:341
Tuplestorestate * setResult
Definition: execnodes.h:204
#define DatumGetPointer(X)
Definition: postgres.h:557
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1173
TupleDesc setDesc
Definition: execnodes.h:205
void(* callback)(void *arg)
Definition: elog.h:239
int errmsg(const char *fmt,...)
Definition: elog.c:797
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:974
int i
#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR)
Definition: postgres.h:323
static PLpgSQL_datum * copy_plpgsql_datum(PLpgSQL_datum *datum)
Definition: pl_exec.c:1027
#define elog
Definition: elog.h:219
bool isnull
Definition: plpgsql.h:272
Oid plpgsql_exec_get_datum_type ( PLpgSQL_execstate estate,
PLpgSQL_datum datum 
)

Definition at line 4932 of file pl_exec.c.

References BlessTupleDesc(), PLpgSQL_var::datatype, PLpgSQL_execstate::datums, PLpgSQL_datum::dtype, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, PLpgSQL_recfield::fieldname, InvalidOid, NULL, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, PLpgSQL_recfield::recparentno, PLpgSQL_rec::refname, PLpgSQL_row::rowtupdesc, SPI_ERROR_NOATTRIBUTE, SPI_fnumber(), SPI_gettypeid(), tupleDesc::tdtypeid, PLpgSQL_rec::tupdesc, and PLpgSQL_type::typoid.

Referenced by exec_stmt_foreach_a().

4934 {
4935  Oid typeid;
4936 
4937  switch (datum->dtype)
4938  {
4939  case PLPGSQL_DTYPE_VAR:
4940  {
4941  PLpgSQL_var *var = (PLpgSQL_var *) datum;
4942 
4943  typeid = var->datatype->typoid;
4944  break;
4945  }
4946 
4947  case PLPGSQL_DTYPE_ROW:
4948  {
4949  PLpgSQL_row *row = (PLpgSQL_row *) datum;
4950 
4951  if (!row->rowtupdesc) /* should not happen */
4952  elog(ERROR, "row variable has no tupdesc");
4953  /* Make sure we have a valid type/typmod setting */
4954  BlessTupleDesc(row->rowtupdesc);
4955  typeid = row->rowtupdesc->tdtypeid;
4956  break;
4957  }
4958 
4959  case PLPGSQL_DTYPE_REC:
4960  {
4961  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
4962 
4963  if (rec->tupdesc == NULL)
4964  ereport(ERROR,
4965  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4966  errmsg("record \"%s\" is not assigned yet",
4967  rec->refname),
4968  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
4969  /* Make sure we have a valid type/typmod setting */
4970  BlessTupleDesc(rec->tupdesc);
4971  typeid = rec->tupdesc->tdtypeid;
4972  break;
4973  }
4974 
4976  {
4977  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
4978  PLpgSQL_rec *rec;
4979  int fno;
4980 
4981  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
4982  if (rec->tupdesc == NULL)
4983  ereport(ERROR,
4984  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4985  errmsg("record \"%s\" is not assigned yet",
4986  rec->refname),
4987  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
4988  fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
4989  if (fno == SPI_ERROR_NOATTRIBUTE)
4990  ereport(ERROR,
4991  (errcode(ERRCODE_UNDEFINED_COLUMN),
4992  errmsg("record \"%s\" has no field \"%s\"",
4993  rec->refname, recfield->fieldname)));
4994  typeid = SPI_gettypeid(rec->tupdesc, fno);
4995  break;
4996  }
4997 
4998  default:
4999  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5000  typeid = InvalidOid; /* keep compiler quiet */
5001  break;
5002  }
5003 
5004  return typeid;
5005 }
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
Definition: spi.c:760
TupleDesc tupdesc
Definition: plpgsql.h:310
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:891
Oid tdtypeid
Definition: tupdesc.h:77
PLpgSQL_type * datatype
Definition: plpgsql.h:263
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
PLpgSQL_datum_type dtype
Definition: plpgsql.h:200
char * refname
Definition: plpgsql.h:306
PLpgSQL_datum ** datums
Definition: plpgsql.h:909
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1031
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
TupleDesc rowtupdesc
Definition: plpgsql.h:287
#define elog
Definition: elog.h:219
char * fieldname
Definition: plpgsql.h:322
Oid typoid
Definition: plpgsql.h:181
void plpgsql_exec_get_datum_type_info ( PLpgSQL_execstate estate,
PLpgSQL_datum datum,
Oid typeid,
int32 typmod,
Oid collation 
)

Definition at line 5014 of file pl_exec.c.

References tupleDesc::attrs, PLpgSQL_type::atttypmod, BlessTupleDesc(), PLpgSQL_type::collation, PLpgSQL_var::datatype, PLpgSQL_execstate::datums, PLpgSQL_datum::dtype, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, PLpgSQL_recfield::fieldname, InvalidOid, NULL, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, PLpgSQL_recfield::recparentno, PLpgSQL_rec::refname, PLpgSQL_row::rowtupdesc, SPI_ERROR_NOATTRIBUTE, SPI_fnumber(), SPI_gettypeid(), tupleDesc::tdtypeid, PLpgSQL_rec::tupdesc, and PLpgSQL_type::typoid.

Referenced by make_datum_param().

5017 {
5018  switch (datum->dtype)
5019  {
5020  case PLPGSQL_DTYPE_VAR:
5021  {
5022  PLpgSQL_var *var = (PLpgSQL_var *) datum;
5023 
5024  *typeid = var->datatype->typoid;
5025  *typmod = var->datatype->atttypmod;
5026  *collation = var->datatype->collation;
5027  break;
5028  }
5029 
5030  case PLPGSQL_DTYPE_ROW:
5031  {
5032  PLpgSQL_row *row = (PLpgSQL_row *) datum;
5033 
5034  if (!row->rowtupdesc) /* should not happen */
5035  elog(ERROR, "row variable has no tupdesc");
5036  /* Make sure we have a valid type/typmod setting */
5037  BlessTupleDesc(row->rowtupdesc);
5038  *typeid = row->rowtupdesc->tdtypeid;
5039  /* do NOT return the mutable typmod of a RECORD variable */
5040  *typmod = -1;
5041  /* composite types are never collatable */
5042  *collation = InvalidOid;
5043  break;
5044  }
5045 
5046  case PLPGSQL_DTYPE_REC:
5047  {
5048  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5049 
5050  if (rec->tupdesc == NULL)
5051  ereport(ERROR,
5052  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5053  errmsg("record \"%s\" is not assigned yet",
5054  rec->refname),
5055  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
5056  /* Make sure we have a valid type/typmod setting */
5057  BlessTupleDesc(rec->tupdesc);
5058  *typeid = rec->tupdesc->tdtypeid;
5059  /* do NOT return the mutable typmod of a RECORD variable */
5060  *typmod = -1;
5061  /* composite types are never collatable */
5062  *collation = InvalidOid;
5063  break;
5064  }
5065 
5067  {
5068  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5069  PLpgSQL_rec *rec;
5070  int fno;
5071 
5072  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5073  if (rec->tupdesc == NULL)
5074  ereport(ERROR,
5075  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5076  errmsg("record \"%s\" is not assigned yet",
5077  rec->refname),
5078  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
5079  fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
5080  if (fno == SPI_ERROR_NOATTRIBUTE)
5081  ereport(ERROR,
5082  (errcode(ERRCODE_UNDEFINED_COLUMN),
5083  errmsg("record \"%s\" has no field \"%s\"",
5084  rec->refname, recfield->fieldname)));
5085  *typeid = SPI_gettypeid(rec->tupdesc, fno);
5086  if (fno > 0)
5087  *typmod = rec->tupdesc->attrs[fno - 1]->atttypmod;
5088  else
5089  *typmod = -1;
5090  if (fno > 0)
5091  *collation = rec->tupdesc->attrs[fno - 1]->attcollation;
5092  else /* no system column types have collation */
5093  *collation = InvalidOid;
5094  break;
5095  }
5096 
5097  default:
5098  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5099  *typeid = InvalidOid; /* keep compiler quiet */
5100  *typmod = -1;
5101  *collation = InvalidOid;
5102  break;
5103  }
5104 }
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
Definition: spi.c:760
TupleDesc tupdesc
Definition: plpgsql.h:310
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:891
Oid tdtypeid
Definition: tupdesc.h:77
PLpgSQL_type * datatype
Definition: plpgsql.h:263
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int errcode(int sqlerrcode)
Definition: elog.c:575
PLpgSQL_datum_type dtype
Definition: plpgsql.h:200
char * refname
Definition: plpgsql.h:306
PLpgSQL_datum ** datums
Definition: plpgsql.h:909
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1031
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
Oid collation
Definition: plpgsql.h:187
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 atttypmod
Definition: plpgsql.h:189
TupleDesc rowtupdesc
Definition: plpgsql.h:287
#define elog
Definition: elog.h:219
char * fieldname
Definition: plpgsql.h:322
Oid typoid
Definition: plpgsql.h:181
HeapTuple plpgsql_exec_trigger ( PLpgSQL_function func,
TriggerData trigdata 
)

Definition at line 615 of file pl_exec.c.

References PLpgSQL_function::action, ErrorContextCallback::arg, assign_simple_var(), assign_text_var(), ErrorContextCallback::callback, construct_md_array(), convert_tuples_by_position(), copy_plpgsql_datum(), CStringGetDatum, CStringGetTextDatum, DatumGetPointer, PLpgSQL_function::datums, PLpgSQL_execstate::datums, DirectFunctionCall1, do_convert_tuple(), elog, ereport, PLpgSQL_execstate::err_stmt, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, exec_eval_cleanup(), exec_set_found(), exec_stmt_block(), PLpgSQL_rec::freetup, PLpgSQL_rec::freetupdesc, PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, get_namespace_name(), gettext_noop, i, Int16GetDatum, namein(), PLpgSQL_execstate::ndatums, PLpgSQL_function::new_varno, NULL, ObjectIdGetDatum, PLpgSQL_function::old_varno, palloc(), plpgsql_destroy_econtext(), plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, PointerGetDatum, ErrorContextCallback::previous, RelationData::rd_att, RelationData::rd_id, RelationGetNamespace, RelationGetRelationName, PLpgSQL_execstate::retisnull, PLpgSQL_execstate::retisset, PLpgSQL_execstate::rettupdesc, PLpgSQL_execstate::retval, SPI_copytuple(), TEXTOID, PLpgSQL_function::tg_argv_varno, TriggerData::tg_event, PLpgSQL_function::tg_level_varno, PLpgSQL_function::tg_name_varno, PLpgSQL_function::tg_nargs_varno, TriggerData::tg_newtuple, PLpgSQL_function::tg_op_varno, TriggerData::tg_relation, PLpgSQL_function::tg_relid_varno, PLpgSQL_function::tg_relname_varno, PLpgSQL_function::tg_table_name_varno, PLpgSQL_function::tg_table_schema_varno, TriggerData::tg_trigger, TriggerData::tg_trigtuple, PLpgSQL_function::tg_when_varno, Trigger::tgargs, Trigger::tgname, Trigger::tgnargs, TRIGGER_FIRED_AFTER, TRIGGER_FIRED_BEFORE, TRIGGER_FIRED_BY_DELETE, TRIGGER_FIRED_BY_INSERT, TRIGGER_FIRED_BY_TRUNCATE, TRIGGER_FIRED_BY_UPDATE, TRIGGER_FIRED_FOR_ROW, TRIGGER_FIRED_FOR_STATEMENT, TRIGGER_FIRED_INSTEAD, PLpgSQL_rec::tup, and PLpgSQL_rec::tupdesc.

Referenced by plpgsql_call_handler().

617 {
618  PLpgSQL_execstate estate;
619  ErrorContextCallback plerrcontext;
620  int i;
621  int rc;
622  PLpgSQL_var *var;
623  PLpgSQL_rec *rec_new,
624  *rec_old;
625  HeapTuple rettup;
626 
627  /*
628  * Setup the execution state
629  */
630  plpgsql_estate_setup(&estate, func, NULL, NULL);
631 
632  /*
633  * Setup error traceback support for ereport()
634  */
635  plerrcontext.callback = plpgsql_exec_error_callback;
636  plerrcontext.arg = &estate;
637  plerrcontext.previous = error_context_stack;
638  error_context_stack = &plerrcontext;
639 
640  /*
641  * Make local execution copies of all the datums
642  */
643  estate.err_text = gettext_noop("during initialization of execution state");
644  for (i = 0; i < estate.ndatums; i++)
645  estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
646 
647  /*
648  * Put the OLD and NEW tuples into record variables
649  *
650  * We make the tupdescs available in both records even though only one may
651  * have a value. This allows parsing of record references to succeed in
652  * functions that are used for multiple trigger types. For example, we
653  * might have a test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')",
654  * which should parse regardless of the current trigger type.
655  */
656  rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
657  rec_new->freetup = false;
658  rec_new->tupdesc = trigdata->tg_relation->rd_att;
659  rec_new->freetupdesc = false;
660  rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
661  rec_old->freetup = false;
662  rec_old->tupdesc = trigdata->tg_relation->rd_att;
663  rec_old->freetupdesc = false;
664 
665  if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
666  {
667  /*
668  * Per-statement triggers don't use OLD/NEW variables
669  */
670  rec_new->tup = NULL;
671  rec_old->tup = NULL;
672  }
673  else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
674  {
675  rec_new->tup = trigdata->tg_trigtuple;
676  rec_old->tup = NULL;
677  }
678  else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
679  {
680  rec_new->tup = trigdata->tg_newtuple;
681  rec_old->tup = trigdata->tg_trigtuple;
682  }
683  else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
684  {
685  rec_new->tup = NULL;
686  rec_old->tup = trigdata->tg_trigtuple;
687  }
688  else
689  elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
690 
691  /*
692  * Assign the special tg_ variables
693  */
694 
695  var = (PLpgSQL_var *) (estate.datums[func->tg_op_varno]);
696  if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
697  assign_text_var(&estate, var, "INSERT");
698  else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
699  assign_text_var(&estate, var, "UPDATE");
700  else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
701  assign_text_var(&estate, var, "DELETE");
702  else if (TRIGGER_FIRED_BY_TRUNCATE(trigdata->tg_event))
703  assign_text_var(&estate, var, "TRUNCATE");
704  else
705  elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, UPDATE, or TRUNCATE");
706 
707  var = (PLpgSQL_var *) (estate.datums[func->tg_name_varno]);
708  assign_simple_var(&estate, var,
710  CStringGetDatum(trigdata->tg_trigger->tgname)),
711  false, true);
712 
713  var = (PLpgSQL_var *) (estate.datums[func->tg_when_varno]);
714  if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
715  assign_text_var(&estate, var, "BEFORE");
716  else if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
717  assign_text_var(&estate, var, "AFTER");
718  else if (TRIGGER_FIRED_INSTEAD(trigdata->tg_event))
719  assign_text_var(&estate, var, "INSTEAD OF");
720  else
721  elog(ERROR, "unrecognized trigger execution time: not BEFORE, AFTER, or INSTEAD OF");
722 
723  var = (PLpgSQL_var *) (estate.datums[func->tg_level_varno]);
724  if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
725  assign_text_var(&estate, var, "ROW");
726  else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
727  assign_text_var(&estate, var, "STATEMENT");
728  else
729  elog(ERROR, "unrecognized trigger event type: not ROW or STATEMENT");
730 
731  var = (PLpgSQL_var *) (estate.datums[func->tg_relid_varno]);
732  assign_simple_var(&estate, var,
733  ObjectIdGetDatum(trigdata->tg_relation->rd_id),
734  false, false);
735 
736  var = (PLpgSQL_var *) (estate.datums[func->tg_relname_varno]);
737  assign_simple_var(&estate, var,
740  false, true);
741 
742  var = (PLpgSQL_var *) (estate.datums[func->tg_table_name_varno]);
743  assign_simple_var(&estate, var,
746  false, true);
747 
748  var = (PLpgSQL_var *) (estate.datums[func->tg_table_schema_varno]);
749  assign_simple_var(&estate, var,
753  trigdata->tg_relation)))),
754  false, true);
755 
756  var = (PLpgSQL_var *) (estate.datums[func->tg_nargs_varno]);
757  assign_simple_var(&estate, var,
758  Int16GetDatum(trigdata->tg_trigger->tgnargs),
759  false, false);
760 
761  var = (PLpgSQL_var *) (estate.datums[func->tg_argv_varno]);
762  if (trigdata->tg_trigger->tgnargs > 0)
763  {
764  /*
765  * For historical reasons, tg_argv[] subscripts start at zero not one.
766  * So we can't use construct_array().
767  */
768  int nelems = trigdata->tg_trigger->tgnargs;
769  Datum *elems;
770  int dims[1];
771  int lbs[1];
772 
773  elems = palloc(sizeof(Datum) * nelems);
774  for (i = 0; i < nelems; i++)
775  elems[i] = CStringGetTextDatum(trigdata->tg_trigger->tgargs[i]);
776  dims[0] = nelems;
777  lbs[0] = 0;
778 
779  assign_simple_var(&estate, var,
781  1, dims, lbs,
782  TEXTOID,
783  -1, false, 'i')),
784  false, true);
785  }
786  else
787  {
788  assign_simple_var(&estate, var, (Datum) 0, true, false);
789  }
790 
791  estate.err_text = gettext_noop("during function entry");
792 
793  /*
794  * Set the magic variable FOUND to false
795  */
796  exec_set_found(&estate, false);
797 
798  /*
799  * Let the instrumentation plugin peek at this function
800  */
801  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
802  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
803 
804  /*
805  * Now call the toplevel block of statements
806  */
807  estate.err_text = NULL;
808  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
809  rc = exec_stmt_block(&estate, func->action);
810  if (rc != PLPGSQL_RC_RETURN)
811  {
812  estate.err_stmt = NULL;
813  estate.err_text = NULL;
814  ereport(ERROR,
815  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
816  errmsg("control reached end of trigger procedure without RETURN")));
817  }
818 
819  estate.err_stmt = NULL;
820  estate.err_text = gettext_noop("during function exit");
821 
822  if (estate.retisset)
823  ereport(ERROR,
824  (errcode(ERRCODE_DATATYPE_MISMATCH),
825  errmsg("trigger procedure cannot return a set")));
826 
827  /*
828  * Check that the returned tuple structure has the same attributes, the
829  * relation that fired the trigger has. A per-statement trigger always
830  * needs to return NULL, so we ignore any return value the function itself
831  * produces (XXX: is this a good idea?)
832  *
833  * XXX This way it is possible, that the trigger returns a tuple where
834  * attributes don't have the correct atttypmod's length. It's up to the
835  * trigger's programmer to ensure that this doesn't happen. Jan
836  */
837  if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
838  rettup = NULL;
839  else
840  {
841  TupleConversionMap *tupmap;
842 
843  rettup = (HeapTuple) DatumGetPointer(estate.retval);
844  /* check rowtype compatibility */
845  tupmap = convert_tuples_by_position(estate.rettupdesc,
846  trigdata->tg_relation->rd_att,
847  gettext_noop("returned row structure does not match the structure of the triggering table"));
848  /* it might need conversion */
849  if (tupmap)
850  rettup = do_convert_tuple(rettup, tupmap);
851  /* no need to free map, we're about to return anyway */
852 
853  /* Copy tuple to upper executor memory */
854  rettup = SPI_copytuple(rettup);
855  }
856 
857  /*
858  * Let the instrumentation plugin peek at this function
859  */
860  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
861  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
862 
863  /* Clean up any leftover temporary memory */
864  plpgsql_destroy_econtext(&estate);
865  exec_eval_cleanup(&estate);
866  /* stmt_mcontext will be destroyed when function's main context is */
867 
868  /*
869  * Pop the error context stack
870  */
871  error_context_stack = plerrcontext.previous;
872 
873  /*
874  * Return the trigger's result
875  */
876  return rettup;
877 }
TupleDesc tupdesc
Definition: plpgsql.h:310
PLpgSQL_datum ** datums
Definition: plpgsql.h:868
HeapTupleData * HeapTuple
Definition: htup.h:70
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
int tg_table_name_varno
Definition: plpgsql.h:849
int tg_relid_varno
Definition: plpgsql.h:847
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:933
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:66
PLpgSQL_stmt_block * action
Definition: plpgsql.h:872
#define TEXTOID
Definition: pg_type.h:324
#define PointerGetDatum(X)
Definition: postgres.h:564
bool freetup
Definition: plpgsql.h:311
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:969
int tg_table_schema_varno
Definition: plpgsql.h:850
#define Int16GetDatum(X)
Definition: postgres.h:459
#define gettext_noop(x)
Definition: c.h:139
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3388
int errcode(int sqlerrcode)
Definition: elog.c:575
static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, Datum newvalue, bool isnull, bool freeable)
Definition: pl_exec.c:7133
HeapTuple SPI_copytuple(HeapTuple tuple)
Definition: spi.c:630
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:3531
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:555
#define TRIGGER_FIRED_AFTER(event)
Definition: trigger.h:91
struct ErrorContextCallback * previous
Definition: elog.h:238
#define TRIGGER_FIRED_FOR_STATEMENT(event)
Definition: trigger.h:85
HeapTuple tg_trigtuple
Definition: trigger.h:35
PLpgSQL_datum ** datums
Definition: plpgsql.h:909
ErrorContextCallback * error_context_stack
Definition: elog.c:88
int tg_relname_varno
Definition: plpgsql.h:848
#define TRIGGER_FIRED_BY_TRUNCATE(event)
Definition: trigger.h:79
TupleDesc rettupdesc
Definition: plpgsql.h:896
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
char * tgname
Definition: reltrigger.h:27
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:7053
#define CStringGetDatum(X)
Definition: postgres.h:586
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define ereport(elevel, rest)
Definition: elog.h:122
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:56
Oid rd_id
Definition: rel.h:115
char ** tgargs
Definition: reltrigger.h:40
#define TRIGGER_FIRED_BY_DELETE(event)
Definition: trigger.h:73
uintptr_t Datum
Definition: postgres.h:374
int tg_level_varno
Definition: plpgsql.h:845
const char * err_text
Definition: plpgsql.h:934
Trigger * tg_trigger
Definition: trigger.h:37
TupleDesc rd_att
Definition: rel.h:114
HeapTuple tg_newtuple
Definition: trigger.h:36
int tg_nargs_varno
Definition: plpgsql.h:851
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:973
#define NULL
Definition: c.h:226
static void assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, const char *str)
Definition: pl_exec.c:7168
TriggerEvent tg_event
Definition: trigger.h:33
bool freetupdesc
Definition: plpgsql.h:312
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:6987
HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:341
#define DatumGetPointer(X)
Definition: postgres.h:557
#define TRIGGER_FIRED_BEFORE(event)
Definition: trigger.h:88
#define TRIGGER_FIRED_INSTEAD(event)
Definition: trigger.h:94
#define TRIGGER_FIRED_BY_INSERT(event)
Definition: trigger.h:70
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1173
void(* callback)(void *arg)
Definition: elog.h:239
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
HeapTuple tup
Definition: plpgsql.h:309
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:974
int i
int16 tgnargs
Definition: reltrigger.h:37
#define CStringGetTextDatum(s)
Definition: builtins.h:90
static PLpgSQL_datum * copy_plpgsql_datum(PLpgSQL_datum *datum)
Definition: pl_exec.c:1027
#define elog
Definition: elog.h:219
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3340
#define TRIGGER_FIRED_FOR_ROW(event)
Definition: trigger.h:82
#define TRIGGER_FIRED_BY_UPDATE(event)
Definition: trigger.h:76
Relation tg_relation
Definition: trigger.h:34
#define RelationGetNamespace(relation)
Definition: rel.h:440
void plpgsql_free_function_memory ( PLpgSQL_function func)

Definition at line 693 of file pl_funcs.c.

References PLpgSQL_function::action, Assert, PLpgSQL_var::cursor_explicit_expr, PLpgSQL_function::datums, PLpgSQL_var::default_val, PLpgSQL_datum::dtype, elog, ERROR, PLpgSQL_function::fn_cxt, free_block(), free_expr(), i, MemoryContextDelete(), PLpgSQL_function::ndatums, NULL, PLPGSQL_DTYPE_ARRAYELEM, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, and PLpgSQL_function::use_count.

Referenced by delete_function(), and plpgsql_inline_handler().

694 {
695  int i;
696 
697  /* Better not call this on an in-use function */
698  Assert(func->use_count == 0);
699 
700  /* Release plans associated with variable declarations */
701  for (i = 0; i < func->ndatums; i++)
702  {
703  PLpgSQL_datum *d = func->datums[i];
704 
705  switch (d->dtype)
706  {
707  case PLPGSQL_DTYPE_VAR:
708  {
709  PLpgSQL_var *var = (PLpgSQL_var *) d;
710 
711  free_expr(var->default_val);
713  }
714  break;
715  case PLPGSQL_DTYPE_ROW:
716  break;
717  case PLPGSQL_DTYPE_REC:
718  break;
720  break;
722  free_expr(((PLpgSQL_arrayelem *) d)->subscript);
723  break;
724  default:
725  elog(ERROR, "unrecognized data type: %d", d->dtype);
726  }
727  }
728  func->ndatums = 0;
729 
730  /* Release plans in statement tree */
731  if (func->action)
732  free_block(func->action);
733  func->action = NULL;
734 
735  /*
736  * And finally, release all memory except the PLpgSQL_function struct
737  * itself (which has to be kept around because there may be multiple
738  * fn_extra pointers to it).
739  */
740  if (func->fn_cxt)
742  func->fn_cxt = NULL;
743 }
PLpgSQL_datum ** datums
Definition: plpgsql.h:868
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
PLpgSQL_stmt_block * action
Definition: plpgsql.h:872
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:267
PLpgSQL_datum_type dtype
Definition: plpgsql.h:200
#define ERROR
Definition: elog.h:43
PLpgSQL_expr * default_val
Definition: plpgsql.h:266
unsigned long use_count
Definition: plpgsql.h:876
static void free_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:683
MemoryContext fn_cxt
Definition: plpgsql.h:828
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
int i
#define elog
Definition: elog.h:219
static void free_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:462
const char* plpgsql_getdiag_kindname ( PLpgSQL_getdiag_kind  kind)

Definition at line 294 of file pl_funcs.c.

References PLPGSQL_GETDIAG_COLUMN_NAME, PLPGSQL_GETDIAG_CONSTRAINT_NAME, PLPGSQL_GETDIAG_CONTEXT, PLPGSQL_GETDIAG_DATATYPE_NAME, PLPGSQL_GETDIAG_ERROR_CONTEXT, PLPGSQL_GETDIAG_ERROR_DETAIL, PLPGSQL_GETDIAG_ERROR_HINT, PLPGSQL_GETDIAG_MESSAGE_TEXT, PLPGSQL_GETDIAG_RESULT_OID, PLPGSQL_GETDIAG_RETURNED_SQLSTATE, PLPGSQL_GETDIAG_ROW_COUNT, PLPGSQL_GETDIAG_SCHEMA_NAME, and PLPGSQL_GETDIAG_TABLE_NAME.

Referenced by dump_getdiag().

295 {
296  switch (kind)
297  {
299  return "ROW_COUNT";
301  return "RESULT_OID";
303  return "PG_CONTEXT";
305  return "PG_EXCEPTION_CONTEXT";
307  return "PG_EXCEPTION_DETAIL";
309  return "PG_EXCEPTION_HINT";
311  return "RETURNED_SQLSTATE";
313  return "COLUMN_NAME";
315  return "CONSTRAINT_NAME";
317  return "PG_DATATYPE_NAME";
319  return "MESSAGE_TEXT";
321  return "TABLE_NAME";
323  return "SCHEMA_NAME";
324  }
325 
326  return "unknown";
327 }
void plpgsql_HashTableInit ( void  )

Definition at line 2561 of file pl_comp.c.

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

Referenced by _PG_init().

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

Definition at line 686 of file pl_scanner.c.

References cur_line_num.

Referenced by plpgsql_compile_error_callback().

687 {
688  return cur_line_num;
689 }
static int cur_line_num
Definition: pl_scanner.c:230
int plpgsql_location_to_lineno ( int  location)

Definition at line 652 of file pl_scanner.c.

References cur_line_end, cur_line_num, cur_line_start, location_lineno_init(), NULL, and scanorig.

653 {
654  const char *loc;
655 
656  if (location < 0 || scanorig == NULL)
657  return 0; /* garbage in, garbage out */
658  loc = scanorig + location;
659 
660  /* be correct, but not fast, if input location goes backwards */
661  if (loc < cur_line_start)
663 
664  while (cur_line_end != NULL && loc > cur_line_end)
665  {
667  cur_line_num++;
668  cur_line_end = strchr(cur_line_start, '\n');
669  }
670 
671  return cur_line_num;
672 }
static int cur_line_num
Definition: pl_scanner.c:230
static void location_lineno_init(void)
Definition: pl_scanner.c:676
static const char * cur_line_start
Definition: pl_scanner.c:228
static const char * scanorig
Definition: pl_scanner.c:212
#define NULL
Definition: c.h:226
static const char * cur_line_end
Definition: pl_scanner.c:229
void plpgsql_ns_additem ( PLpgSQL_nsitem_type  itemtype,
int  itemno,
const char *  name 
)

Definition at line 92 of file pl_funcs.c.

References Assert, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, PLpgSQL_nsitem::name, ns_top, NULL, offsetof, palloc(), PLPGSQL_NSTYPE_LABEL, and PLpgSQL_nsitem::prev.

Referenced by add_parameter_name(), plpgsql_build_record(), plpgsql_build_variable(), and plpgsql_ns_push().

93 {
94  PLpgSQL_nsitem *nse;
95 
96  Assert(name != NULL);
97  /* first item added must be a label */
98  Assert(ns_top != NULL || itemtype == PLPGSQL_NSTYPE_LABEL);
99 
100  nse = palloc(offsetof(PLpgSQL_nsitem, name) +strlen(name) + 1);
101  nse->itemtype = itemtype;
102  nse->itemno = itemno;
103  nse->prev = ns_top;
104  strcpy(nse->name, name);
105  ns_top = nse;
106 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:35
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:359
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
const char * name
Definition: encode.c:521
void * palloc(Size size)
Definition: mcxt.c:891
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:360
#define offsetof(type, field)
Definition: c.h:551
PLpgSQL_nsitem* plpgsql_ns_find_nearest_loop ( PLpgSQL_nsitem ns_cur)

Definition at line 214 of file pl_funcs.c.

References PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, NULL, PLPGSQL_LABEL_LOOP, PLPGSQL_NSTYPE_LABEL, and PLpgSQL_nsitem::prev.

215 {
216  while (ns_cur != NULL)
217  {
218  if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
219  ns_cur->itemno == PLPGSQL_LABEL_LOOP)
220  return ns_cur;
221  ns_cur = ns_cur->prev;
222  }
223 
224  return NULL; /* no loop found */
225 }
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:359
#define NULL
Definition: c.h:226
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
void plpgsql_ns_init ( void  )

Definition at line 43 of file pl_funcs.c.

References NULL.

Referenced by do_compile(), and plpgsql_compile_inline().

44 {
45  ns_top = NULL;
46 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:35
#define NULL
Definition: c.h:226
PLpgSQL_nsitem* plpgsql_ns_lookup ( PLpgSQL_nsitem ns_cur,
bool  localmode,
const char *  name1,
const char *  name2,
const char *  name3,
int *  names_used 
)

Definition at line 130 of file pl_funcs.c.

References PLpgSQL_nsitem::itemtype, PLpgSQL_nsitem::name, NULL, PLPGSQL_NSTYPE_LABEL, PLPGSQL_NSTYPE_VAR, and PLpgSQL_nsitem::prev.

Referenced by add_parameter_name(), plpgsql_param_ref(), plpgsql_parse_cwordtype(), plpgsql_parse_dblword(), plpgsql_parse_tripword(), plpgsql_parse_word(), plpgsql_parse_wordtype(), and resolve_column_ref().

133 {
134  /* Outer loop iterates once per block level in the namespace chain */
135  while (ns_cur != NULL)
136  {
137  PLpgSQL_nsitem *nsitem;
138 
139  /* Check this level for unqualified match to variable name */
140  for (nsitem = ns_cur;
141  nsitem->itemtype != PLPGSQL_NSTYPE_LABEL;
142  nsitem = nsitem->prev)
143  {
144  if (strcmp(nsitem->name, name1) == 0)
145  {
146  if (name2 == NULL ||
147  nsitem->itemtype != PLPGSQL_NSTYPE_VAR)
148  {
149  if (names_used)
150  *names_used = 1;
151  return nsitem;
152  }
153  }
154  }
155 
156  /* Check this level for qualified match to variable name */
157  if (name2 != NULL &&
158  strcmp(nsitem->name, name1) == 0)
159  {
160  for (nsitem = ns_cur;
161  nsitem->itemtype != PLPGSQL_NSTYPE_LABEL;
162  nsitem = nsitem->prev)
163  {
164  if (strcmp(nsitem->name, name2) == 0)
165  {
166  if (name3 == NULL ||
167  nsitem->itemtype != PLPGSQL_NSTYPE_VAR)
168  {
169  if (names_used)
170  *names_used = 2;
171  return nsitem;
172  }
173  }
174  }
175  }
176 
177  if (localmode)
178  break; /* do not look into upper levels */
179 
180  ns_cur = nsitem->prev;
181  }
182 
183  /* This is just to suppress possibly-uninitialized-variable warnings */
184  if (names_used)
185  *names_used = 0;
186  return NULL; /* No match found */
187 }
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:359
#define NULL
Definition: c.h:226
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:360
PLpgSQL_nsitem* plpgsql_ns_lookup_label ( PLpgSQL_nsitem ns_cur,
const char *  name 
)

Definition at line 195 of file pl_funcs.c.

References PLpgSQL_nsitem::itemtype, PLpgSQL_nsitem::name, NULL, PLPGSQL_NSTYPE_LABEL, and PLpgSQL_nsitem::prev.

196 {
197  while (ns_cur != NULL)
198  {
199  if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
200  strcmp(ns_cur->name, name) == 0)
201  return ns_cur;
202  ns_cur = ns_cur->prev;
203  }
204 
205  return NULL; /* label not found */
206 }
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:359
#define NULL
Definition: c.h:226
const char * name
Definition: encode.c:521
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:360
void plpgsql_ns_pop ( void  )

Definition at line 67 of file pl_funcs.c.

References Assert, PLpgSQL_nsitem::itemtype, NULL, PLPGSQL_NSTYPE_LABEL, and PLpgSQL_nsitem::prev.

68 {
69  Assert(ns_top != NULL);
71  ns_top = ns_top->prev;
72  ns_top = ns_top->prev;
73 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:35
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:359
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:353
void plpgsql_ns_push ( const char *  label,
PLpgSQL_label_type  label_type 
)

Definition at line 54 of file pl_funcs.c.

References NULL, plpgsql_ns_additem(), and PLPGSQL_NSTYPE_LABEL.

Referenced by do_compile(), and plpgsql_compile_inline().

55 {
56  if (label == NULL)
57  label = "";
58  plpgsql_ns_additem(PLPGSQL_NSTYPE_LABEL, (int) label_type, label);
59 }
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
static char * label
Definition: pg_basebackup.c:84
#define NULL
Definition: c.h:226
PLpgSQL_nsitem* plpgsql_ns_top ( void  )

Definition at line 81 of file pl_funcs.c.

References ns_top.

Referenced by add_parameter_name(), plpgsql_parse_cwordtype(), plpgsql_parse_dblword(), plpgsql_parse_tripword(), plpgsql_parse_word(), and plpgsql_parse_wordtype().

82 {
83  return ns_top;
84 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:35
PLpgSQL_type* plpgsql_parse_cwordrowtype ( List idents)

Definition at line 1827 of file pl_comp.c.

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

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

Definition at line 1689 of file pl_comp.c.

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

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

Definition at line 1409 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

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

Definition at line 2258 of file pl_comp.c.

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

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

Definition at line 1529 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

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

Definition at line 1353 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

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

Definition at line 1806 of file pl_comp.c.

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

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

Definition at line 1626 of file pl_comp.c.

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

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

Definition at line 1016 of file pl_comp.c.

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

Referenced by exec_prepare_plan(), plpgsql_estate_setup(), and setup_unshared_param_list().

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

Definition at line 534 of file pl_scanner.c.

References internal_yylex(), and push_back_token().

535 {
536  int tok1;
537  TokenAuxData aux1;
538 
539  tok1 = internal_yylex(&aux1);
540  push_back_token(tok1, &aux1);
541  return tok1;
542 }
static int internal_yylex(TokenAuxData *auxdata)
Definition: pl_scanner.c:422
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:468
void plpgsql_peek2 ( int *  tok1_p,
int *  tok2_p,
int *  tok1_loc,
int *  tok2_loc 
)

Definition at line 553 of file pl_scanner.c.

References internal_yylex(), TokenAuxData::lloc, and push_back_token().

554 {
555  int tok1,
556  tok2;
557  TokenAuxData aux1,
558  aux2;
559 
560  tok1 = internal_yylex(&aux1);
561  tok2 = internal_yylex(&aux2);
562 
563  *tok1_p = tok1;
564  if (tok1_loc)
565  *tok1_loc = aux1.lloc;
566  *tok2_p = tok2;
567  if (tok2_loc)
568  *tok2_loc = aux2.lloc;
569 
570  push_back_token(tok2, &aux2);
571  push_back_token(tok1, &aux1);
572 }
YYLTYPE lloc
Definition: pl_scanner.c:196
static int internal_yylex(TokenAuxData *auxdata)
Definition: pl_scanner.c:422
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:468
void plpgsql_push_back_token ( int  token)

Definition at line 484 of file pl_scanner.c.

References TokenAuxData::leng, TokenAuxData::lloc, TokenAuxData::lval, plpgsql_yyleng, and push_back_token().

485 {
486  TokenAuxData auxdata;
487 
488  auxdata.lval = plpgsql_yylval;
489  auxdata.lloc = plpgsql_yylloc;
490  auxdata.leng = plpgsql_yyleng;
491  push_back_token(token, &auxdata);
492 }
YYLTYPE lloc
Definition: pl_scanner.c:196
YYSTYPE lval
Definition: pl_scanner.c:195
static int plpgsql_yyleng
Definition: pl_scanner.c:215
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:468
int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2222 of file pl_comp.c.

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

Referenced by exec_stmt_raise().

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

Definition at line 586 of file pl_scanner.c.

References internalerrposition(), internalerrquery(), NULL, pg_mbstrlen_with_len(), and scanorig.

Referenced by plpgsql_yyerror().

587 {
588  int pos;
589 
590  if (location < 0 || scanorig == NULL)
591  return 0; /* no-op if location is unknown */
592 
593  /* Convert byte offset to character number */
594  pos = pg_mbstrlen_with_len(scanorig, location) + 1;
595  /* And pass it to the ereport mechanism */
596  (void) internalerrposition(pos);
597  /* Also pass the function body string */
598  return internalerrquery(scanorig);
599 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:805
static const char * scanorig
Definition: pl_scanner.c:212
int internalerrquery(const char *query)
Definition: elog.c:1161
#define NULL
Definition: c.h:226
int internalerrposition(int cursorpos)
Definition: elog.c:1141
void plpgsql_scanner_finish ( void  )

Definition at line 727 of file pl_scanner.c.

References NULL, scanner_finish(), scanorig, and yyscanner.

Referenced by do_compile(), and plpgsql_compile_inline().

728 {
729  /* release storage */
731  /* avoid leaving any dangling pointers */
732  yyscanner = NULL;
733  scanorig = NULL;
734 }
static const char * scanorig
Definition: pl_scanner.c:212
#define NULL
Definition: c.h:226
static core_yyscan_t yyscanner
Definition: pl_scanner.c:208
void scanner_finish(core_yyscan_t yyscanner)
void plpgsql_scanner_init ( const char *  str)

Definition at line 700 of file pl_scanner.c.

References IDENTIFIER_LOOKUP_NORMAL, location_lineno_init(), num_pushbacks, num_reserved_keywords, plpgsql_IdentifierLookup, plpgsql_yytoken, scanner_init(), scanorig, and yyscanner.

Referenced by do_compile(), and plpgsql_compile_inline().

701 {
702  /* Start up the core scanner */
705 
706  /*
707  * scanorig points to the original string, which unlike the scanner's
708  * scanbuf won't be modified on-the-fly by flex. Notice that although
709  * yytext points into scanbuf, we rely on being able to apply locations
710  * (offsets from string start) to scanorig as well.
711  */
712  scanorig = str;
713 
714  /* Other setup */
716  plpgsql_yytoken = 0;
717 
718  num_pushbacks = 0;
719 
721 }
static const ScanKeyword reserved_keywords[]
Definition: pl_scanner.c:68
static void location_lineno_init(void)
Definition: pl_scanner.c:676
static int plpgsql_yytoken
Definition: pl_scanner.c:218
static const char * scanorig
Definition: pl_scanner.c:212
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:27
static int num_pushbacks
Definition: pl_scanner.c:223
static core_yy_extra_type core_yy
Definition: pl_scanner.c:209
core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, const ScanKeyword *keywords, int num_keywords)
static core_yyscan_t yyscanner
Definition: pl_scanner.c:208
static const int num_reserved_keywords
Definition: pl_scanner.c:95
const char* plpgsql_stmt_typename ( PLpgSQL_stmt stmt)

Definition at line 232 of file pl_funcs.c.

References _, PLpgSQL_stmt::cmd_type, PLPGSQL_STMT_ASSERT, PLPGSQL_STMT_ASSIGN, PLPGSQL_STMT_BLOCK, PLPGSQL_STMT_CASE, PLPGSQL_STMT_CLOSE, PLPGSQL_STMT_DYNEXECUTE, PLPGSQL_STMT_DYNFORS, PLPGSQL_STMT_EXECSQL, PLPGSQL_STMT_EXIT, PLPGSQL_STMT_FETCH, PLPGSQL_STMT_FORC, PLPGSQL_STMT_FOREACH_A, PLPGSQL_STMT_FORI, PLPGSQL_STMT_FORS, PLPGSQL_STMT_GETDIAG, PLPGSQL_STMT_IF, PLPGSQL_STMT_LOOP, PLPGSQL_STMT_OPEN, PLPGSQL_STMT_PERFORM, PLPGSQL_STMT_RAISE, PLPGSQL_STMT_RETURN, PLPGSQL_STMT_RETURN_NEXT, PLPGSQL_STMT_RETURN_QUERY, and PLPGSQL_STMT_WHILE.

Referenced by plpgsql_exec_error_callback().

233 {
234  switch (stmt->cmd_type)
235  {
236  case PLPGSQL_STMT_BLOCK:
237  return _("statement block");
238  case PLPGSQL_STMT_ASSIGN:
239  return _("assignment");
240  case PLPGSQL_STMT_IF:
241  return "IF";
242  case PLPGSQL_STMT_CASE:
243  return "CASE";
244  case PLPGSQL_STMT_LOOP:
245  return "LOOP";
246  case PLPGSQL_STMT_WHILE:
247  return "WHILE";
248  case PLPGSQL_STMT_FORI:
249  return _("FOR with integer loop variable");
250  case PLPGSQL_STMT_FORS:
251  return _("FOR over SELECT rows");
252  case PLPGSQL_STMT_FORC:
253  return _("FOR over cursor");
255  return _("FOREACH over array");
256  case PLPGSQL_STMT_EXIT:
257  return ((PLpgSQL_stmt_exit *) stmt)->is_exit ? "EXIT" : "CONTINUE";
258  case PLPGSQL_STMT_RETURN:
259  return "RETURN";
261  return "RETURN NEXT";
263  return "RETURN QUERY";
264  case PLPGSQL_STMT_RAISE:
265  return "RAISE";
266  case PLPGSQL_STMT_ASSERT:
267  return "ASSERT";
269  return _("SQL statement");
271  return "EXECUTE";
273  return _("FOR over EXECUTE statement");
275  return ((PLpgSQL_stmt_getdiag *) stmt)->is_stacked ?
276  "GET STACKED DIAGNOSTICS" : "GET DIAGNOSTICS";
277  case PLPGSQL_STMT_OPEN:
278  return "OPEN";
279  case PLPGSQL_STMT_FETCH:
280  return ((PLpgSQL_stmt_fetch *) stmt)->is_move ? "MOVE" : "FETCH";
281  case PLPGSQL_STMT_CLOSE:
282  return "CLOSE";
284  return "PERFORM";
285  }
286 
287  return "unknown";
288 }
PLpgSQL_stmt_type cmd_type
Definition: plpgsql.h:368
#define _(x)
Definition: elog.c:84
void plpgsql_subxact_cb ( SubXactEvent  event,
SubTransactionId  mySubid,
SubTransactionId  parentSubid,
void *  arg 
)

Definition at line 7107 of file pl_exec.c.

References FreeExprContext(), SimpleEcontextStackEntry::next, next, NULL, pfree(), SimpleEcontextStackEntry::stack_econtext, SUBXACT_EVENT_ABORT_SUB, SUBXACT_EVENT_COMMIT_SUB, and SimpleEcontextStackEntry::xact_subxid.

Referenced by _PG_init(), and plpgsql_inline_handler().

7109 {
7110  if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
7111  {
7112  while (simple_econtext_stack != NULL &&
7113  simple_econtext_stack->xact_subxid == mySubid)
7114  {
7116 
7118  (event == SUBXACT_EVENT_COMMIT_SUB));
7119  next = simple_econtext_stack->next;
7122  }
7123  }
7124 }
static int32 next
Definition: blutils.c:210
struct SimpleEcontextStackEntry * next
Definition: pl_exec.c:83
void pfree(void *pointer)
Definition: mcxt.c:992
ExprContext * stack_econtext
Definition: pl_exec.c:81
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:87
SubTransactionId xact_subxid
Definition: pl_exec.c:82
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:339
#define NULL
Definition: c.h:226
bool plpgsql_token_is_unreserved_keyword ( int  token)

Definition at line 501 of file pl_scanner.c.

References i, num_unreserved_keywords, and value.

502 {
503  int i;
504 
505  for (i = 0; i < num_unreserved_keywords; i++)
506  {
507  if (unreserved_keywords[i].value == token)
508  return true;
509  }
510  return false;
511 }
static struct @76 value
static const int num_unreserved_keywords
Definition: pl_scanner.c:176
static const ScanKeyword unreserved_keywords[]
Definition: pl_scanner.c:97
int i
void plpgsql_xact_cb ( XactEvent  event,
void *  arg 
)

Definition at line 7075 of file pl_exec.c.

References Assert, FreeExecutorState(), NULL, XACT_EVENT_ABORT, XACT_EVENT_COMMIT, and XACT_EVENT_PREPARE.

Referenced by _PG_init().

7076 {
7077  /*
7078  * If we are doing a clean transaction shutdown, free the EState (so that
7079  * any remaining resources will be released correctly). In an abort, we
7080  * expect the regular abort recovery procedures to release everything of
7081  * interest.
7082  */
7083  if (event == XACT_EVENT_COMMIT || event == XACT_EVENT_PREPARE)
7084  {
7085  /* Shouldn't be any econtext stack entries left at commit */
7087 
7091  }
7092  else if (event == XACT_EVENT_ABORT)
7093  {
7096  }
7097 }
void FreeExecutorState(EState *estate)
Definition: execUtils.c:168
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:87
static EState * shared_simple_eval_estate
Definition: pl_exec.c:86
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
void plpgsql_yyerror ( const char *  message)

Definition at line 613 of file pl_scanner.c.

References _, ereport, errcode(), errmsg(), ERROR, plpgsql_scanner_errposition(), plpgsql_yyleng, and core_yy_extra_type::scanbuf.

614 {
615  char *yytext = core_yy.scanbuf + plpgsql_yylloc;
616 
617  if (*yytext == '\0')
618  {
619  ereport(ERROR,
620  (errcode(ERRCODE_SYNTAX_ERROR),
621  /* translator: %s is typically the translation of "syntax error" */
622  errmsg("%s at end of input", _(message)),
623  plpgsql_scanner_errposition(plpgsql_yylloc)));
624  }
625  else
626  {
627  /*
628  * If we have done any lookahead then flex will have restored the
629  * character after the end-of-token. Zap it again so that we report
630  * only the single token here. This modifies scanbuf but we no longer
631  * care about that.
632  */
633  yytext[plpgsql_yyleng] = '\0';
634 
635  ereport(ERROR,
636  (errcode(ERRCODE_SYNTAX_ERROR),
637  /* translator: first %s is typically the translation of "syntax error" */
638  errmsg("%s at or near \"%s\"", _(message), yytext),
639  plpgsql_scanner_errposition(plpgsql_yylloc)));
640  }
641 }
int errcode(int sqlerrcode)
Definition: elog.c:575
char * scanbuf
Definition: scanner.h:72
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static core_yy_extra_type core_yy
Definition: pl_scanner.c:209
static int plpgsql_yyleng
Definition: pl_scanner.c:215
int plpgsql_scanner_errposition(int location)
Definition: pl_scanner.c:586
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define _(x)
Definition: elog.c:84
int plpgsql_yylex ( void  )

Definition at line 248 of file pl_scanner.c.

References AT_STMT_START, internal_yylex(), TokenAuxData::leng, TokenAuxData::lloc, TokenAuxData::lval, ScanKeyword::name, num_unreserved_keywords, plpgsql_parse_dblword(), plpgsql_parse_tripword(), plpgsql_parse_word(), plpgsql_yyleng, plpgsql_yytoken, push_back_token(), core_yy_extra_type::scanbuf, ScanKeywordLookup(), and ScanKeyword::value.

249 {
250  int tok1;
251  TokenAuxData aux1;
252  const ScanKeyword *kw;
253 
254  tok1 = internal_yylex(&aux1);
255  if (tok1 == IDENT || tok1 == PARAM)
256  {
257  int tok2;
258  TokenAuxData aux2;
259 
260  tok2 = internal_yylex(&aux2);
261  if (tok2 == '.')
262  {
263  int tok3;
264  TokenAuxData aux3;
265 
266  tok3 = internal_yylex(&aux3);
267  if (tok3 == IDENT)
268  {
269  int tok4;
270  TokenAuxData aux4;
271 
272  tok4 = internal_yylex(&aux4);
273  if (tok4 == '.')