PostgreSQL Source Code  git master
plpgsql.h File Reference
#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 33 of file plpgsql.h.

◆ PLPGSQL_XCHECK_ALL

#define PLPGSQL_XCHECK_ALL   ((int) ~0)

Definition at line 1023 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_NONE

#define PLPGSQL_XCHECK_NONE   0

Definition at line 1021 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_SHADOWVAR

#define PLPGSQL_XCHECK_SHADOWVAR   1

Definition at line 1022 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ TEXTDOMAIN

#define TEXTDOMAIN   PG_TEXTDOMAIN("plpgsql")

Definition at line 30 of file plpgsql.h.

Typedef Documentation

◆ PLcword

◆ PLpgSQL_arrayelem

◆ PLpgSQL_case_when

◆ PLpgSQL_condition

◆ PLpgSQL_datum

◆ PLpgSQL_datum_type

◆ PLpgSQL_diag_item

◆ PLpgSQL_exception

◆ PLpgSQL_exception_block

◆ PLpgSQL_execstate

◆ PLpgSQL_expr

◆ PLpgSQL_func_hashkey

◆ PLpgSQL_function

◆ PLpgSQL_getdiag_kind

◆ PLpgSQL_if_elsif

◆ PLpgSQL_label_type

◆ PLpgSQL_nsitem

◆ PLpgSQL_nsitem_type

◆ PLpgSQL_plugin

◆ PLpgSQL_raise_option

◆ PLpgSQL_raise_option_type

◆ PLpgSQL_rec

◆ PLpgSQL_recfield

◆ PLpgSQL_resolve_option

◆ PLpgSQL_row

◆ PLpgSQL_stmt

◆ 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_forq

◆ 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

◆ PLpgSQL_stmt_type

◆ PLpgSQL_stmt_while

◆ PLpgSQL_trigtype

◆ PLpgSQL_type

◆ PLpgSQL_type_type

◆ PLpgSQL_var

◆ PLpgSQL_variable

◆ PLwdatum

◆ PLword

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
PLPGSQL_RC_OK 
PLPGSQL_RC_EXIT 
PLPGSQL_RC_RETURN 
PLPGSQL_RC_CONTINUE 

Definition at line 114 of file plpgsql.h.

◆ IdentifierLookup

Enumerator
IDENTIFIER_LOOKUP_NORMAL 
IDENTIFIER_LOOKUP_DECLARE 
IDENTIFIER_LOOKUP_EXPR 

Definition at line 1005 of file plpgsql.h.

1006 {
1007  IDENTIFIER_LOOKUP_NORMAL, /* normal processing of var names */
1008  IDENTIFIER_LOOKUP_DECLARE, /* In DECLARE --- don't look up names */
1009  IDENTIFIER_LOOKUP_EXPR /* In SQL expression --- special case */
IdentifierLookup
Definition: plpgsql.h:1005

◆ PLpgSQL_datum_type

Enumerator
PLPGSQL_DTYPE_VAR 
PLPGSQL_DTYPE_ROW 
PLPGSQL_DTYPE_REC 
PLPGSQL_DTYPE_RECFIELD 
PLPGSQL_DTYPE_ARRAYELEM 
PLPGSQL_DTYPE_EXPR 

Definition at line 59 of file plpgsql.h.

◆ PLpgSQL_getdiag_kind

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 125 of file plpgsql.h.

◆ PLpgSQL_label_type

Enumerator
PLPGSQL_LABEL_BLOCK 
PLPGSQL_LABEL_LOOP 
PLPGSQL_LABEL_OTHER 

Definition at line 49 of file plpgsql.h.

50 {
51  PLPGSQL_LABEL_BLOCK, /* DECLARE/BEGIN block */
52  PLPGSQL_LABEL_LOOP, /* looping construct */
53  PLPGSQL_LABEL_OTHER /* anything else */
PLpgSQL_label_type
Definition: plpgsql.h:49

◆ PLpgSQL_nsitem_type

Enumerator
PLPGSQL_NSTYPE_LABEL 
PLPGSQL_NSTYPE_VAR 
PLPGSQL_NSTYPE_ROW 
PLPGSQL_NSTYPE_REC 

Definition at line 38 of file plpgsql.h.

◆ PLpgSQL_raise_option_type

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 145 of file plpgsql.h.

◆ PLpgSQL_resolve_option

Enumerator
PLPGSQL_RESOLVE_ERROR 
PLPGSQL_RESOLVE_VARIABLE 
PLPGSQL_RESOLVE_COLUMN 

Definition at line 161 of file plpgsql.h.

162 {
163  PLPGSQL_RESOLVE_ERROR, /* throw error if ambiguous */
164  PLPGSQL_RESOLVE_VARIABLE, /* prefer plpgsql var to table column */
165  PLPGSQL_RESOLVE_COLUMN /* prefer table column to plpgsql var */
PLpgSQL_resolve_option
Definition: plpgsql.h:161

◆ PLpgSQL_stmt_type

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 83 of file plpgsql.h.

84 {
PLpgSQL_stmt_type
Definition: plpgsql.h:83

◆ PLpgSQL_trigtype

Enumerator
PLPGSQL_DML_TRIGGER 
PLPGSQL_EVENT_TRIGGER 
PLPGSQL_NOT_TRIGGER 

Definition at line 800 of file plpgsql.h.

◆ PLpgSQL_type_type

Enumerator
PLPGSQL_TTYPE_SCALAR 
PLPGSQL_TTYPE_ROW 
PLPGSQL_TTYPE_REC 
PLPGSQL_TTYPE_PSEUDO 

Definition at line 72 of file plpgsql.h.

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

Function Documentation

◆ _PG_init()

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:7790
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:243
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
static int auth_delay_milliseconds
Definition: auth_delay.c:26
#define GUC_UNIT_MS
Definition: guc.h:225

◆ plpgsql_add_initdatums()

int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2382 of file pl_comp.c.

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

2383 {
2384  int i;
2385  int n = 0;
2386 
2387  /*
2388  * The set of dtypes recognized here must match what exec_stmt_block()
2389  * cares about (re)initializing at block entry.
2390  */
2391  for (i = datums_last; i < plpgsql_nDatums; i++)
2392  {
2393  switch (plpgsql_Datums[i]->dtype)
2394  {
2395  case PLPGSQL_DTYPE_VAR:
2396  case PLPGSQL_DTYPE_REC:
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  case PLPGSQL_DTYPE_REC:
2418  (*varnos)[n++] = plpgsql_Datums[i]->dno;
2419 
2420  default:
2421  break;
2422  }
2423  }
2424  }
2425  else
2426  *varnos = NULL;
2427  }
2428 
2430  return n;
2431 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
void * palloc(Size size)
Definition: mcxt.c:835
int i
static int datums_last
Definition: pl_comp.c:48

◆ plpgsql_adddatum()

void plpgsql_adddatum ( PLpgSQL_datum new)

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

2340 {
2342  {
2343  datums_alloc *= 2;
2345  }
2346 
2347  new->dno = plpgsql_nDatums;
2349 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
static int datums_alloc
Definition: pl_comp.c:45
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:949

◆ plpgsql_append_source_text()

void plpgsql_append_source_text ( StringInfo  buf,
int  startlocation,
int  endlocation 
)

Definition at line 520 of file pl_scanner.c.

References appendBinaryStringInfo(), Assert, and scanorig.

522 {
523  Assert(startlocation <= endlocation);
524  appendBinaryStringInfo(buf, scanorig + startlocation,
525  endlocation - startlocation);
526 }
static const char * scanorig
Definition: pl_scanner.c:214
#define Assert(condition)
Definition: c.h:680
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:208

◆ plpgsql_base_yylex()

int plpgsql_base_yylex ( void  )

◆ plpgsql_build_datatype()

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

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

2137 {
2138  HeapTuple typeTup;
2139  PLpgSQL_type *typ;
2140 
2141  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
2142  if (!HeapTupleIsValid(typeTup))
2143  elog(ERROR, "cache lookup failed for type %u", typeOid);
2144 
2145  typ = build_datatype(typeTup, typmod, collation);
2146 
2147  ReleaseSysCache(typeTup);
2148 
2149  return typ;
2150 }
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2156
#define elog
Definition: elog.h:219

◆ plpgsql_build_record()

PLpgSQL_rec* plpgsql_build_record ( const char *  refname,
int  lineno,
bool  add2namespace 
)

Definition at line 1953 of file pl_comp.c.

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

Referenced by do_compile(), and plpgsql_build_variable().

1954 {
1955  PLpgSQL_rec *rec;
1956 
1957  rec = palloc0(sizeof(PLpgSQL_rec));
1958  rec->dtype = PLPGSQL_DTYPE_REC;
1959  rec->refname = pstrdup(refname);
1960  rec->lineno = lineno;
1961  rec->tup = NULL;
1962  rec->tupdesc = NULL;
1963  rec->freetup = false;
1964  rec->freetupdesc = false;
1966  if (add2namespace)
1968 
1969  return rec;
1970 }
PLpgSQL_datum_type dtype
Definition: plpgsql.h:302
TupleDesc tupdesc
Definition: plpgsql.h:308
char * pstrdup(const char *in)
Definition: mcxt.c:1063
bool freetup
Definition: plpgsql.h:309
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
char * refname
Definition: plpgsql.h:304
void * palloc0(Size size)
Definition: mcxt.c:864
bool freetupdesc
Definition: plpgsql.h:310
HeapTuple tup
Definition: plpgsql.h:307
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2339
int lineno
Definition: plpgsql.h:305

◆ plpgsql_build_variable()

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

Definition at line 1873 of file pl_comp.c.

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

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

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

◆ plpgsql_compile()

PLpgSQL_function* plpgsql_compile ( FunctionCallInfo  fcinfo,
bool  forValidator 
)

Definition at line 137 of file pl_comp.c.

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

Referenced by plpgsql_call_handler(), and plpgsql_validator().

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

◆ plpgsql_compile_inline()

PLpgSQL_function* plpgsql_compile_inline ( char *  proc_source)

Definition at line 803 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, PLpgSQL_function::fn_rettype, plpgsql_hashent::function, InvalidOid, MemoryContextSwitchTo(), palloc0(), plpgsql_build_datatype(), plpgsql_build_variable(), plpgsql_check_syntax, plpgsql_compile_error_callback(), plpgsql_DumpExecTree, plpgsql_error_funcname, plpgsql_finish_datums(), PLPGSQL_LABEL_BLOCK, PLPGSQL_NOT_TRIGGER, plpgsql_ns_init(), plpgsql_ns_push(), plpgsql_parse_result, plpgsql_print_strict_params, plpgsql_scanner_finish(), plpgsql_scanner_init(), plpgsql_start_datums(), plpgsql_variable_conflict, plpgsql_yyparse(), ErrorContextCallback::previous, pstrdup(), and VOIDOID.

Referenced by plpgsql_inline_handler().

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

◆ plpgsql_dumptree()

void plpgsql_dumptree ( PLpgSQL_function func)

Definition at line 1524 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, PLpgSQL_arrayelem::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, 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().

1525 {
1526  int i;
1527  PLpgSQL_datum *d;
1528 
1529  printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1530  func->fn_signature);
1531 
1532  printf("\nFunction's data area:\n");
1533  for (i = 0; i < func->ndatums; i++)
1534  {
1535  d = func->datums[i];
1536 
1537  printf(" entry %d: ", i);
1538  switch (d->dtype)
1539  {
1540  case PLPGSQL_DTYPE_VAR:
1541  {
1542  PLpgSQL_var *var = (PLpgSQL_var *) d;
1543 
1544  printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1545  var->refname, var->datatype->typname,
1546  var->datatype->typoid,
1547  var->datatype->atttypmod);
1548  if (var->isconst)
1549  printf(" CONSTANT\n");
1550  if (var->notnull)
1551  printf(" NOT NULL\n");
1552  if (var->default_val != NULL)
1553  {
1554  printf(" DEFAULT ");
1555  dump_expr(var->default_val);
1556  printf("\n");
1557  }
1558  if (var->cursor_explicit_expr != NULL)
1559  {
1560  if (var->cursor_explicit_argrow >= 0)
1561  printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1562 
1563  printf(" CURSOR IS ");
1565  printf("\n");
1566  }
1567  }
1568  break;
1569  case PLPGSQL_DTYPE_ROW:
1570  {
1571  PLpgSQL_row *row = (PLpgSQL_row *) d;
1572  int i;
1573 
1574  printf("ROW %-16s fields", row->refname);
1575  for (i = 0; i < row->nfields; i++)
1576  {
1577  if (row->fieldnames[i])
1578  printf(" %s=var %d", row->fieldnames[i],
1579  row->varnos[i]);
1580  }
1581  printf("\n");
1582  }
1583  break;
1584  case PLPGSQL_DTYPE_REC:
1585  printf("REC %s\n", ((PLpgSQL_rec *) d)->refname);
1586  break;
1588  printf("RECFIELD %-16s of REC %d\n",
1589  ((PLpgSQL_recfield *) d)->fieldname,
1590  ((PLpgSQL_recfield *) d)->recparentno);
1591  break;
1593  printf("ARRAYELEM of VAR %d subscript ",
1594  ((PLpgSQL_arrayelem *) d)->arrayparentno);
1595  dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
1596  printf("\n");
1597  break;
1598  default:
1599  printf("??? unknown data type %d\n", d->dtype);
1600  }
1601  }
1602  printf("\nFunction's statements:\n");
1603 
1604  dump_indent = 0;
1605  printf("%3d:", func->action->lineno);
1606  dump_block(func->action);
1607  printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1608  fflush(stdout);
1609 }
PLpgSQL_datum ** datums
Definition: plpgsql.h:859
char * refname
Definition: plpgsql.h:281
int notnull
Definition: plpgsql.h:263
int isconst
Definition: plpgsql.h:262
char * refname
Definition: plpgsql.h:258
PLpgSQL_stmt_block * action
Definition: plpgsql.h:862
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:265
PLpgSQL_type * datatype
Definition: plpgsql.h:261
PLpgSQL_datum_type dtype
Definition: plpgsql.h:198
int cursor_explicit_argrow
Definition: plpgsql.h:266
char ** fieldnames
Definition: plpgsql.h:293
PLpgSQL_expr * default_val
Definition: plpgsql.h:264
int * varnos
Definition: plpgsql.h:294
PLpgSQL_datum_type dtype
Definition: plpgsql.h:318
int nfields
Definition: plpgsql.h:292
static int dump_indent
Definition: pl_funcs.c:751
char * fn_signature
Definition: plpgsql.h:812
char * typname
Definition: plpgsql.h:178
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:888
int32 atttypmod
Definition: plpgsql.h:187
static void dump_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:1518
int i
Oid typoid
Definition: plpgsql.h:179

◆ plpgsql_exec_event_trigger()

void plpgsql_exec_event_trigger ( PLpgSQL_function func,
EventTriggerData trigdata 
)

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

980 {
981  PLpgSQL_execstate estate;
982  ErrorContextCallback plerrcontext;
983  int i;
984  int rc;
985  PLpgSQL_var *var;
986 
987  /*
988  * Setup the execution state
989  */
990  plpgsql_estate_setup(&estate, func, NULL, NULL);
991 
992  /*
993  * Setup error traceback support for ereport()
994  */
995  plerrcontext.callback = plpgsql_exec_error_callback;
996  plerrcontext.arg = &estate;
997  plerrcontext.previous = error_context_stack;
998  error_context_stack = &plerrcontext;
999 
1000  /*
1001  * Make local execution copies of all the datums
1002  */
1003  estate.err_text = gettext_noop("during initialization of execution state");
1004  for (i = 0; i < estate.ndatums; i++)
1005  estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
1006 
1007  /*
1008  * Assign the special tg_ variables
1009  */
1010  var = (PLpgSQL_var *) (estate.datums[func->tg_event_varno]);
1011  assign_text_var(&estate, var, trigdata->event);
1012 
1013  var = (PLpgSQL_var *) (estate.datums[func->tg_tag_varno]);
1014  assign_text_var(&estate, var, trigdata->tag);
1015 
1016  /*
1017  * Let the instrumentation plugin peek at this function
1018  */
1019  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
1020  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
1021 
1022  /*
1023  * Now call the toplevel block of statements
1024  */
1025  estate.err_text = NULL;
1026  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
1027  rc = exec_stmt_block(&estate, func->action);
1028  if (rc != PLPGSQL_RC_RETURN)
1029  {
1030  estate.err_stmt = NULL;
1031  estate.err_text = NULL;
1032  ereport(ERROR,
1033  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1034  errmsg("control reached end of trigger procedure without RETURN")));
1035  }
1036 
1037  estate.err_stmt = NULL;
1038  estate.err_text = gettext_noop("during function exit");
1039 
1040  /*
1041  * Let the instrumentation plugin peek at this function
1042  */
1043  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1044  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1045 
1046  /* Clean up any leftover temporary memory */
1047  plpgsql_destroy_econtext(&estate);
1048  exec_eval_cleanup(&estate);
1049  /* stmt_mcontext will be destroyed when function's main context is */
1050 
1051  /*
1052  * Pop the error context stack
1053  */
1054  error_context_stack = plerrcontext.previous;
1055 
1056  return;
1057 }
int tg_event_varno
Definition: plpgsql.h:846
PLpgSQL_datum ** datums
Definition: plpgsql.h:859
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:927
PLpgSQL_stmt_block * action
Definition: plpgsql.h:862
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1063
#define gettext_noop(x)
Definition: c.h:1005
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3332
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:3474
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
PLpgSQL_datum ** datums
Definition: plpgsql.h:899
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:6738
#define ereport(elevel, rest)
Definition: elog.h:122
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:58
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:967
const char * err_text
Definition: plpgsql.h:928
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:968
static void assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, const char *str)
Definition: pl_exec.c:6842
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1267
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
static PLpgSQL_datum * copy_plpgsql_datum(PLpgSQL_datum *datum)
Definition: pl_exec.c:1121

◆ plpgsql_exec_function()

Datum plpgsql_exec_function ( PLpgSQL_function func,
FunctionCallInfo  fcinfo,
EState simple_eval_estate 
)

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

413 {
414  PLpgSQL_execstate estate;
415  ErrorContextCallback plerrcontext;
416  int i;
417  int rc;
418 
419  /*
420  * Setup the execution state
421  */
422  plpgsql_estate_setup(&estate, func, (ReturnSetInfo *) fcinfo->resultinfo,
423  simple_eval_estate);
424 
425  /*
426  * Setup error traceback support for ereport()
427  */
428  plerrcontext.callback = plpgsql_exec_error_callback;
429  plerrcontext.arg = &estate;
430  plerrcontext.previous = error_context_stack;
431  error_context_stack = &plerrcontext;
432 
433  /*
434  * Make local execution copies of all the datums
435  */
436  estate.err_text = gettext_noop("during initialization of execution state");
437  for (i = 0; i < estate.ndatums; i++)
438  estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
439 
440  /*
441  * Store the actual call argument values into the appropriate variables
442  */
443  estate.err_text = gettext_noop("while storing call arguments into local variables");
444  for (i = 0; i < func->fn_nargs; i++)
445  {
446  int n = func->fn_argvarnos[i];
447 
448  switch (estate.datums[n]->dtype)
449  {
450  case PLPGSQL_DTYPE_VAR:
451  {
452  PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
453 
454  assign_simple_var(&estate, var,
455  fcinfo->arg[i],
456  fcinfo->argnull[i],
457  false);
458 
459  /*
460  * Force any array-valued parameter to be stored in
461  * expanded form in our local variable, in hopes of
462  * improving efficiency of uses of the variable. (This is
463  * a hack, really: why only arrays? Need more thought
464  * about which cases are likely to win. See also
465  * typisarray-specific heuristic in exec_assign_value.)
466  *
467  * Special cases: If passed a R/W expanded pointer, assume
468  * we can commandeer the object rather than having to copy
469  * it. If passed a R/O expanded pointer, just keep it as
470  * the value of the variable for the moment. (We'll force
471  * it to R/W if the variable gets modified, but that may
472  * very well never happen.)
473  */
474  if (!var->isnull && var->datatype->typisarray)
475  {
477  {
478  /* take ownership of R/W object */
479  assign_simple_var(&estate, var,
482  false,
483  true);
484  }
486  {
487  /* R/O pointer, keep it as-is until assigned to */
488  }
489  else
490  {
491  /* flat array, so force to expanded form */
492  assign_simple_var(&estate, var,
493  expand_array(var->value,
495  NULL),
496  false,
497  true);
498  }
499  }
500  }
501  break;
502 
503  case PLPGSQL_DTYPE_ROW:
504  {
505  PLpgSQL_row *row = (PLpgSQL_row *) estate.datums[n];
506 
507  if (!fcinfo->argnull[i])
508  {
509  /* Assign row value from composite datum */
510  exec_move_row_from_datum(&estate,
511  (PLpgSQL_variable *) row,
512  fcinfo->arg[i]);
513  }
514  else
515  {
516  /* If arg is null, treat it as an empty row */
517  exec_move_row(&estate, (PLpgSQL_variable *) row,
518  NULL, NULL);
519  }
520  /* clean up after exec_move_row() */
521  exec_eval_cleanup(&estate);
522  }
523  break;
524 
525  default:
526  elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
527  }
528  }
529 
530  estate.err_text = gettext_noop("during function entry");
531 
532  /*
533  * Set the magic variable FOUND to false
534  */
535  exec_set_found(&estate, false);
536 
537  /*
538  * Let the instrumentation plugin peek at this function
539  */
540  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
541  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
542 
543  /*
544  * Now call the toplevel block of statements
545  */
546  estate.err_text = NULL;
547  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
548  rc = exec_stmt_block(&estate, func->action);
549  if (rc != PLPGSQL_RC_RETURN && func->fn_rettype)
550  {
551  estate.err_stmt = NULL;
552  estate.err_text = NULL;
553  ereport(ERROR,
554  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
555  errmsg("control reached end of function without RETURN")));
556  }
557 
558  /*
559  * We got a return value - process it
560  */
561  estate.err_stmt = NULL;
562  estate.err_text = gettext_noop("while casting return value to function's return type");
563 
564  fcinfo->isnull = estate.retisnull;
565 
566  if (estate.retisset)
567  {
568  ReturnSetInfo *rsi = estate.rsi;
569 
570  /* Check caller can handle a set result */
571  if (!rsi || !IsA(rsi, ReturnSetInfo) ||
572  (rsi->allowedModes & SFRM_Materialize) == 0)
573  ereport(ERROR,
574  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
575  errmsg("set-valued function called in context that cannot accept a set")));
577 
578  /* If we produced any tuples, send back the result */
579  if (estate.tuple_store)
580  {
581  rsi->setResult = estate.tuple_store;
582  if (estate.rettupdesc)
583  {
584  MemoryContext oldcxt;
585 
586  oldcxt = MemoryContextSwitchTo(estate.tuple_store_cxt);
587  rsi->setDesc = CreateTupleDescCopy(estate.rettupdesc);
588  MemoryContextSwitchTo(oldcxt);
589  }
590  }
591  estate.retval = (Datum) 0;
592  fcinfo->isnull = true;
593  }
594  else if (!estate.retisnull)
595  {
596  if (!func->fn_rettype)
597  {
598  ereport(ERROR,
599  (errmsg("cannot return a value from a procedure")));
600  }
601 
602  if (estate.retistuple)
603  {
604  /*
605  * We have to check that the returned tuple actually matches the
606  * expected result type. XXX would be better to cache the tupdesc
607  * instead of repeating get_call_result_type()
608  */
609  HeapTuple rettup = (HeapTuple) DatumGetPointer(estate.retval);
610  TupleDesc tupdesc;
611  TupleConversionMap *tupmap;
612 
613  switch (get_call_result_type(fcinfo, NULL, &tupdesc))
614  {
615  case TYPEFUNC_COMPOSITE:
616  /* got the expected result rowtype, now check it */
617  tupmap = convert_tuples_by_position(estate.rettupdesc,
618  tupdesc,
619  gettext_noop("returned record type does not match expected record type"));
620  /* it might need conversion */
621  if (tupmap)
622  rettup = do_convert_tuple(rettup, tupmap);
623  /* no need to free map, we're about to return anyway */
624  break;
625  case TYPEFUNC_RECORD:
626 
627  /*
628  * Failed to determine actual type of RECORD. We could
629  * raise an error here, but what this means in practice is
630  * that the caller is expecting any old generic rowtype,
631  * so we don't really need to be restrictive. Pass back
632  * the generated result type, instead.
633  */
634  tupdesc = estate.rettupdesc;
635  if (tupdesc == NULL) /* shouldn't happen */
636  elog(ERROR, "return type must be a row type");
637  break;
638  default:
639  /* shouldn't get here if retistuple is true ... */
640  elog(ERROR, "return type must be a row type");
641  break;
642  }
643 
644  /*
645  * Copy tuple to upper executor memory, as a tuple Datum. Make
646  * sure it is labeled with the caller-supplied tuple type.
647  */
648  estate.retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
649  }
650  else
651  {
652  /* Cast value to proper type */
653  estate.retval = exec_cast_value(&estate,
654  estate.retval,
655  &fcinfo->isnull,
656  estate.rettype,
657  -1,
658  func->fn_rettype,
659  -1);
660 
661  /*
662  * If the function's return type isn't by value, copy the value
663  * into upper executor memory context. However, if we have a R/W
664  * expanded datum, we can just transfer its ownership out to the
665  * upper executor context.
666  */
667  if (!fcinfo->isnull && !func->fn_retbyval)
668  estate.retval = SPI_datumTransfer(estate.retval,
669  false,
670  func->fn_rettyplen);
671  }
672  }
673 
674  estate.err_text = gettext_noop("during function exit");
675 
676  /*
677  * Let the instrumentation plugin peek at this function
678  */
679  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
680  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
681 
682  /* Clean up any leftover temporary memory */
683  plpgsql_destroy_econtext(&estate);
684  exec_eval_cleanup(&estate);
685  /* stmt_mcontext will be destroyed when function's main context is */
686 
687  /*
688  * Pop the error context stack
689  */
690  error_context_stack = plerrcontext.previous;
691 
692  /*
693  * Return the function's result
694  */
695  return estate.retval;
696 }
bool fn_retbyval
Definition: plpgsql.h:823
PLpgSQL_datum ** datums
Definition: plpgsql.h:859
int fn_argvarnos[FUNC_MAX_ARGS]
Definition: plpgsql.h:829
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:110
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
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:664
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:927
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:66
PLpgSQL_stmt_block * action
Definition: plpgsql.h:862
#define PointerGetDatum(X)
Definition: postgres.h:562
PLpgSQL_type * datatype
Definition: plpgsql.h:261
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1063
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define gettext_noop(x)
Definition: c.h:1005
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3332
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:6818
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:3474
static void exec_move_row_from_datum(PLpgSQL_execstate *estate, PLpgSQL_variable *target, Datum value)
Definition: pl_exec.c:6108
PLpgSQL_datum_type dtype
Definition: plpgsql.h:198
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
PLpgSQL_datum ** datums
Definition: plpgsql.h:899
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:6181
TupleDesc rettupdesc
Definition: plpgsql.h:886
#define ERROR
Definition: elog.h:43
MemoryContext tuple_store_cxt
Definition: plpgsql.h:892
Datum SPI_datumTransfer(Datum value, bool typByVal, int typLen)
Definition: spi.c:953
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:6738
fmNodePtr resultinfo
Definition: fmgr.h:81
ReturnSetInfo * rsi
Definition: plpgsql.h:894
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:86
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define ereport(elevel, rest)
Definition: elog.h:122
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:58
Tuplestorestate * tuple_store
Definition: plpgsql.h:891
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:967
bool typisarray
Definition: plpgsql.h:186
uintptr_t Datum
Definition: postgres.h:372
const char * err_text
Definition: plpgsql.h:928
Datum value
Definition: plpgsql.h:269
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:968
int allowedModes
Definition: execnodes.h:279
Datum arg[FUNC_MAX_ARGS]
Definition: fmgr.h:85
SetFunctionReturnMode returnMode
Definition: execnodes.h:281
#define VARATT_IS_EXTERNAL_EXPANDED_RO(PTR)
Definition: postgres.h:319
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:6672
HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:354
Tuplestorestate * setResult
Definition: execnodes.h:284
#define DatumGetPointer(X)
Definition: postgres.h:555
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1267
TupleDesc setDesc
Definition: execnodes.h:285
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void exec_move_row(PLpgSQL_execstate *estate, PLpgSQL_variable *target, HeapTuple tup, TupleDesc tupdesc)
Definition: pl_exec.c:5860
int i
#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR)
Definition: postgres.h:321
static PLpgSQL_datum * copy_plpgsql_datum(PLpgSQL_datum *datum)
Definition: pl_exec.c:1121
#define elog
Definition: elog.h:219
bool isnull
Definition: plpgsql.h:270

◆ plpgsql_exec_get_datum_type()

Oid plpgsql_exec_get_datum_type ( PLpgSQL_execstate estate,
PLpgSQL_datum datum 
)

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

4864 {
4865  Oid typeid;
4866 
4867  switch (datum->dtype)
4868  {
4869  case PLPGSQL_DTYPE_VAR:
4870  {
4871  PLpgSQL_var *var = (PLpgSQL_var *) datum;
4872 
4873  typeid = var->datatype->typoid;
4874  break;
4875  }
4876 
4877  case PLPGSQL_DTYPE_ROW:
4878  {
4879  PLpgSQL_row *row = (PLpgSQL_row *) datum;
4880 
4881  if (!row->rowtupdesc) /* should not happen */
4882  elog(ERROR, "row variable has no tupdesc");
4883  /* Make sure we have a valid type/typmod setting */
4884  BlessTupleDesc(row->rowtupdesc);
4885  typeid = row->rowtupdesc->tdtypeid;
4886  break;
4887  }
4888 
4889  case PLPGSQL_DTYPE_REC:
4890  {
4891  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
4892 
4893  if (rec->tupdesc == NULL)
4894  ereport(ERROR,
4895  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4896  errmsg("record \"%s\" is not assigned yet",
4897  rec->refname),
4898  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
4899  /* Make sure we have a valid type/typmod setting */
4900  BlessTupleDesc(rec->tupdesc);
4901  typeid = rec->tupdesc->tdtypeid;
4902  break;
4903  }
4904 
4906  {
4907  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
4908  PLpgSQL_rec *rec;
4909  int fno;
4910 
4911  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
4912  if (rec->tupdesc == NULL)
4913  ereport(ERROR,
4914  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4915  errmsg("record \"%s\" is not assigned yet",
4916  rec->refname),
4917  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
4918  fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
4919  if (fno == SPI_ERROR_NOATTRIBUTE)
4920  ereport(ERROR,
4921  (errcode(ERRCODE_UNDEFINED_COLUMN),
4922  errmsg("record \"%s\" has no field \"%s\"",
4923  rec->refname, recfield->fieldname)));
4924  typeid = SPI_gettypeid(rec->tupdesc, fno);
4925  break;
4926  }
4927 
4928  default:
4929  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
4930  typeid = InvalidOid; /* keep compiler quiet */
4931  break;
4932  }
4933 
4934  return typeid;
4935 }
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
Definition: spi.c:767
TupleDesc tupdesc
Definition: plpgsql.h:308
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:900
Oid tdtypeid
Definition: tupdesc.h:80
PLpgSQL_type * datatype
Definition: plpgsql.h:261
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
PLpgSQL_datum_type dtype
Definition: plpgsql.h:198
char * refname
Definition: plpgsql.h:304
PLpgSQL_datum ** datums
Definition: plpgsql.h:899
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1032
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:44
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
TupleDesc rowtupdesc
Definition: plpgsql.h:285
#define elog
Definition: elog.h:219
char * fieldname
Definition: plpgsql.h:320
Oid typoid
Definition: plpgsql.h:179

◆ plpgsql_exec_get_datum_type_info()

void plpgsql_exec_get_datum_type_info ( PLpgSQL_execstate estate,
PLpgSQL_datum datum,
Oid typeid,
int32 typmod,
Oid collation 
)

Definition at line 4944 of file pl_exec.c.

References 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, 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, TupleDescAttr, and PLpgSQL_type::typoid.

Referenced by make_datum_param().

4947 {
4948  switch (datum->dtype)
4949  {
4950  case PLPGSQL_DTYPE_VAR:
4951  {
4952  PLpgSQL_var *var = (PLpgSQL_var *) datum;
4953 
4954  *typeid = var->datatype->typoid;
4955  *typmod = var->datatype->atttypmod;
4956  *collation = var->datatype->collation;
4957  break;
4958  }
4959 
4960  case PLPGSQL_DTYPE_ROW:
4961  {
4962  PLpgSQL_row *row = (PLpgSQL_row *) datum;
4963 
4964  if (!row->rowtupdesc) /* should not happen */
4965  elog(ERROR, "row variable has no tupdesc");
4966  /* Make sure we have a valid type/typmod setting */
4967  BlessTupleDesc(row->rowtupdesc);
4968  *typeid = row->rowtupdesc->tdtypeid;
4969  /* do NOT return the mutable typmod of a RECORD variable */
4970  *typmod = -1;
4971  /* composite types are never collatable */
4972  *collation = InvalidOid;
4973  break;
4974  }
4975 
4976  case PLPGSQL_DTYPE_REC:
4977  {
4978  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
4979 
4980  if (rec->tupdesc == NULL)
4981  ereport(ERROR,
4982  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4983  errmsg("record \"%s\" is not assigned yet",
4984  rec->refname),
4985  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
4986  /* Make sure we have a valid type/typmod setting */
4987  BlessTupleDesc(rec->tupdesc);
4988  *typeid = rec->tupdesc->tdtypeid;
4989  /* do NOT return the mutable typmod of a RECORD variable */
4990  *typmod = -1;
4991  /* composite types are never collatable */
4992  *collation = InvalidOid;
4993  break;
4994  }
4995 
4997  {
4998  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
4999  PLpgSQL_rec *rec;
5000  int fno;
5001 
5002  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5003  if (rec->tupdesc == NULL)
5004  ereport(ERROR,
5005  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5006  errmsg("record \"%s\" is not assigned yet",
5007  rec->refname),
5008  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
5009  fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
5010  if (fno == SPI_ERROR_NOATTRIBUTE)
5011  ereport(ERROR,
5012  (errcode(ERRCODE_UNDEFINED_COLUMN),
5013  errmsg("record \"%s\" has no field \"%s\"",
5014  rec->refname, recfield->fieldname)));
5015  *typeid = SPI_gettypeid(rec->tupdesc, fno);
5016  if (fno > 0)
5017  {
5018  Form_pg_attribute attr = TupleDescAttr(rec->tupdesc, fno - 1);
5019 
5020  *typmod = attr->atttypmod;
5021  }
5022  else
5023  *typmod = -1;
5024  if (fno > 0)
5025  {
5026  Form_pg_attribute attr = TupleDescAttr(rec->tupdesc, fno - 1);
5027 
5028  *collation = attr->attcollation;
5029  }
5030  else /* no system column types have collation */
5031  *collation = InvalidOid;
5032  break;
5033  }
5034 
5035  default:
5036  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5037  *typeid = InvalidOid; /* keep compiler quiet */
5038  *typmod = -1;
5039  *collation = InvalidOid;
5040  break;
5041  }
5042 }
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
Definition: spi.c:767
TupleDesc tupdesc
Definition: plpgsql.h:308
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
Definition: spi.c:900
Oid tdtypeid
Definition: tupdesc.h:80
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
PLpgSQL_type * datatype
Definition: plpgsql.h:261
int errcode(int sqlerrcode)
Definition: elog.c:575
PLpgSQL_datum_type dtype
Definition: plpgsql.h:198
char * refname
Definition: plpgsql.h:304
PLpgSQL_datum ** datums
Definition: plpgsql.h:899
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1032
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:44
int errdetail(const char *fmt,...)
Definition: elog.c:873
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define ereport(elevel, rest)
Definition: elog.h:122
Oid collation
Definition: plpgsql.h:185
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 atttypmod
Definition: plpgsql.h:187
TupleDesc rowtupdesc
Definition: plpgsql.h:285
#define elog
Definition: elog.h:219
char * fieldname
Definition: plpgsql.h:320
Oid typoid
Definition: plpgsql.h:179

◆ plpgsql_exec_trigger()

HeapTuple plpgsql_exec_trigger ( PLpgSQL_function func,
TriggerData trigdata 
)

Definition at line 705 of file pl_exec.c.

References PLpgSQL_function::action, ErrorContextCallback::arg, Assert, 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, 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(), SPI_register_trigger_data(), 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().

707 {
708  PLpgSQL_execstate estate;
709  ErrorContextCallback plerrcontext;
710  int i;
711  int rc;
712  PLpgSQL_var *var;
713  PLpgSQL_rec *rec_new,
714  *rec_old;
715  HeapTuple rettup;
716 
717  /*
718  * Setup the execution state
719  */
720  plpgsql_estate_setup(&estate, func, NULL, NULL);
721 
722  /*
723  * Setup error traceback support for ereport()
724  */
725  plerrcontext.callback = plpgsql_exec_error_callback;
726  plerrcontext.arg = &estate;
727  plerrcontext.previous = error_context_stack;
728  error_context_stack = &plerrcontext;
729 
730  /*
731  * Make local execution copies of all the datums
732  */
733  estate.err_text = gettext_noop("during initialization of execution state");
734  for (i = 0; i < estate.ndatums; i++)
735  estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
736 
737  /*
738  * Put the OLD and NEW tuples into record variables
739  *
740  * We make the tupdescs available in both records even though only one may
741  * have a value. This allows parsing of record references to succeed in
742  * functions that are used for multiple trigger types. For example, we
743  * might have a test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')",
744  * which should parse regardless of the current trigger type.
745  */
746  rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
747  rec_new->freetup = false;
748  rec_new->tupdesc = trigdata->tg_relation->rd_att;
749  rec_new->freetupdesc = false;
750  rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
751  rec_old->freetup = false;
752  rec_old->tupdesc = trigdata->tg_relation->rd_att;
753  rec_old->freetupdesc = false;
754 
755  if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
756  {
757  /*
758  * Per-statement triggers don't use OLD/NEW variables
759  */
760  rec_new->tup = NULL;
761  rec_old->tup = NULL;
762  }
763  else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
764  {
765  rec_new->tup = trigdata->tg_trigtuple;
766  rec_old->tup = NULL;
767  }
768  else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
769  {
770  rec_new->tup = trigdata->tg_newtuple;
771  rec_old->tup = trigdata->tg_trigtuple;
772  }
773  else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
774  {
775  rec_new->tup = NULL;
776  rec_old->tup = trigdata->tg_trigtuple;
777  }
778  else
779  elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
780 
781  /* Make transition tables visible to this SPI connection */
782  rc = SPI_register_trigger_data(trigdata);
783  Assert(rc >= 0);
784 
785  /*
786  * Assign the special tg_ variables
787  */
788 
789  var = (PLpgSQL_var *) (estate.datums[func->tg_op_varno]);
790  if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
791  assign_text_var(&estate, var, "INSERT");
792  else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
793  assign_text_var(&estate, var, "UPDATE");
794  else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
795  assign_text_var(&estate, var, "DELETE");
796  else if (TRIGGER_FIRED_BY_TRUNCATE(trigdata->tg_event))
797  assign_text_var(&estate, var, "TRUNCATE");
798  else
799  elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, UPDATE, or TRUNCATE");
800 
801  var = (PLpgSQL_var *) (estate.datums[func->tg_name_varno]);
802  assign_simple_var(&estate, var,
804  CStringGetDatum(trigdata->tg_trigger->tgname)),
805  false, true);
806 
807  var = (PLpgSQL_var *) (estate.datums[func->tg_when_varno]);
808  if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
809  assign_text_var(&estate, var, "BEFORE");
810  else if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
811  assign_text_var(&estate, var, "AFTER");
812  else if (TRIGGER_FIRED_INSTEAD(trigdata->tg_event))
813  assign_text_var(&estate, var, "INSTEAD OF");
814  else
815  elog(ERROR, "unrecognized trigger execution time: not BEFORE, AFTER, or INSTEAD OF");
816 
817  var = (PLpgSQL_var *) (estate.datums[func->tg_level_varno]);
818  if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
819  assign_text_var(&estate, var, "ROW");
820  else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
821  assign_text_var(&estate, var, "STATEMENT");
822  else
823  elog(ERROR, "unrecognized trigger event type: not ROW or STATEMENT");
824 
825  var = (PLpgSQL_var *) (estate.datums[func->tg_relid_varno]);
826  assign_simple_var(&estate, var,
827  ObjectIdGetDatum(trigdata->tg_relation->rd_id),
828  false, false);
829 
830  var = (PLpgSQL_var *) (estate.datums[func->tg_relname_varno]);
831  assign_simple_var(&estate, var,
834  false, true);
835 
836  var = (PLpgSQL_var *) (estate.datums[func->tg_table_name_varno]);
837  assign_simple_var(&estate, var,
840  false, true);
841 
842  var = (PLpgSQL_var *) (estate.datums[func->tg_table_schema_varno]);
843  assign_simple_var(&estate, var,
847  trigdata->tg_relation)))),
848  false, true);
849 
850  var = (PLpgSQL_var *) (estate.datums[func->tg_nargs_varno]);
851  assign_simple_var(&estate, var,
852  Int16GetDatum(trigdata->tg_trigger->tgnargs),
853  false, false);
854 
855  var = (PLpgSQL_var *) (estate.datums[func->tg_argv_varno]);
856  if (trigdata->tg_trigger->tgnargs > 0)
857  {
858  /*
859  * For historical reasons, tg_argv[] subscripts start at zero not one.
860  * So we can't use construct_array().
861  */
862  int nelems = trigdata->tg_trigger->tgnargs;
863  Datum *elems;
864  int dims[1];
865  int lbs[1];
866 
867  elems = palloc(sizeof(Datum) * nelems);
868  for (i = 0; i < nelems; i++)
869  elems[i] = CStringGetTextDatum(trigdata->tg_trigger->tgargs[i]);
870  dims[0] = nelems;
871  lbs[0] = 0;
872 
873  assign_simple_var(&estate, var,
875  1, dims, lbs,
876  TEXTOID,
877  -1, false, 'i')),
878  false, true);
879  }
880  else
881  {
882  assign_simple_var(&estate, var, (Datum) 0, true, false);
883  }
884 
885  estate.err_text = gettext_noop("during function entry");
886 
887  /*
888  * Set the magic variable FOUND to false
889  */
890  exec_set_found(&estate, false);
891 
892  /*
893  * Let the instrumentation plugin peek at this function
894  */
895  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
896  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
897 
898  /*
899  * Now call the toplevel block of statements
900  */
901  estate.err_text = NULL;
902  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
903  rc = exec_stmt_block(&estate, func->action);
904  if (rc != PLPGSQL_RC_RETURN)
905  {
906  estate.err_stmt = NULL;
907  estate.err_text = NULL;
908  ereport(ERROR,
909  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
910  errmsg("control reached end of trigger procedure without RETURN")));
911  }
912 
913  estate.err_stmt = NULL;
914  estate.err_text = gettext_noop("during function exit");
915 
916  if (estate.retisset)
917  ereport(ERROR,
918  (errcode(ERRCODE_DATATYPE_MISMATCH),
919  errmsg("trigger procedure cannot return a set")));
920 
921  /*
922  * Check that the returned tuple structure has the same attributes, the
923  * relation that fired the trigger has. A per-statement trigger always
924  * needs to return NULL, so we ignore any return value the function itself
925  * produces (XXX: is this a good idea?)
926  *
927  * XXX This way it is possible, that the trigger returns a tuple where
928  * attributes don't have the correct atttypmod's length. It's up to the
929  * trigger's programmer to ensure that this doesn't happen. Jan
930  */
931  if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
932  rettup = NULL;
933  else
934  {
935  TupleConversionMap *tupmap;
936 
937  rettup = (HeapTuple) DatumGetPointer(estate.retval);
938  /* check rowtype compatibility */
939  tupmap = convert_tuples_by_position(estate.rettupdesc,
940  trigdata->tg_relation->rd_att,
941  gettext_noop("returned row structure does not match the structure of the triggering table"));
942  /* it might need conversion */
943  if (tupmap)
944  rettup = do_convert_tuple(rettup, tupmap);
945  /* no need to free map, we're about to return anyway */
946 
947  /* Copy tuple to upper executor memory */
948  rettup = SPI_copytuple(rettup);
949  }
950 
951  /*
952  * Let the instrumentation plugin peek at this function
953  */
954  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
955  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
956 
957  /* Clean up any leftover temporary memory */
958  plpgsql_destroy_econtext(&estate);
959  exec_eval_cleanup(&estate);
960  /* stmt_mcontext will be destroyed when function's main context is */
961 
962  /*
963  * Pop the error context stack
964  */
965  error_context_stack = plerrcontext.previous;
966 
967  /*
968  * Return the trigger's result
969  */
970  return rettup;
971 }
TupleDesc tupdesc
Definition: plpgsql.h:308
PLpgSQL_datum ** datums
Definition: plpgsql.h:859
HeapTupleData * HeapTuple
Definition: htup.h:70
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
int tg_table_name_varno
Definition: plpgsql.h:840
int tg_relid_varno
Definition: plpgsql.h:838
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:927
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:66
PLpgSQL_stmt_block * action
Definition: plpgsql.h:862
#define TEXTOID
Definition: pg_type.h:324
#define PointerGetDatum(X)
Definition: postgres.h:562
bool freetup
Definition: plpgsql.h:309
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1063
int tg_table_schema_varno
Definition: plpgsql.h:841
#define Int16GetDatum(X)
Definition: postgres.h:457
#define gettext_noop(x)
Definition: c.h:1005
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3332
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:6818
HeapTuple SPI_copytuple(HeapTuple tuple)
Definition: spi.c:637
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:3474
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
#define TRIGGER_FIRED_AFTER(event)
Definition: trigger.h:137
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
#define TRIGGER_FIRED_FOR_STATEMENT(event)
Definition: trigger.h:131
HeapTuple tg_trigtuple
Definition: trigger.h:35
PLpgSQL_datum ** datums
Definition: plpgsql.h:899
ErrorContextCallback * error_context_stack
Definition: elog.c:88
int tg_relname_varno
Definition: plpgsql.h:839
#define TRIGGER_FIRED_BY_TRUNCATE(event)
Definition: trigger.h:125
TupleDesc rettupdesc
Definition: plpgsql.h:886
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * tgname
Definition: reltrigger.h:27
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3066
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:6738
#define CStringGetDatum(X)
Definition: postgres.h:584
#define RelationGetRelationName(relation)
Definition: rel.h:445
#define ereport(elevel, rest)
Definition: elog.h:122
int SPI_register_trigger_data(TriggerData *tdata)
Definition: spi.c:2756
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:58
Oid rd_id
Definition: rel.h:116
char ** tgargs
Definition: reltrigger.h:40
#define TRIGGER_FIRED_BY_DELETE(event)
Definition: trigger.h:119
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:967
uintptr_t Datum
Definition: postgres.h:372
int tg_level_varno
Definition: plpgsql.h:836
const char * err_text
Definition: plpgsql.h:928
Trigger * tg_trigger
Definition: trigger.h:37
TupleDesc rd_att
Definition: rel.h:115
HeapTuple tg_newtuple
Definition: trigger.h:36
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:968
int tg_nargs_varno
Definition: plpgsql.h:842
static void assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, const char *str)
Definition: pl_exec.c:6842
#define Assert(condition)
Definition: c.h:680
TriggerEvent tg_event
Definition: trigger.h:33
bool freetupdesc
Definition: plpgsql.h:310
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:6672
HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:354
#define DatumGetPointer(X)
Definition: postgres.h:555
#define TRIGGER_FIRED_BEFORE(event)
Definition: trigger.h:134
#define TRIGGER_FIRED_INSTEAD(event)
Definition: trigger.h:140
#define TRIGGER_FIRED_BY_INSERT(event)
Definition: trigger.h:116
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1267
void * palloc(Size size)
Definition: mcxt.c:835
int errmsg(const char *fmt,...)
Definition: elog.c:797
HeapTuple tup
Definition: plpgsql.h:307
int i
int16 tgnargs
Definition: reltrigger.h:37
#define CStringGetTextDatum(s)
Definition: builtins.h:91
static PLpgSQL_datum * copy_plpgsql_datum(PLpgSQL_datum *datum)
Definition: pl_exec.c:1121
#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:3314
#define TRIGGER_FIRED_FOR_ROW(event)
Definition: trigger.h:128
#define TRIGGER_FIRED_BY_UPDATE(event)
Definition: trigger.h:122
Relation tg_relation
Definition: trigger.h:34
#define RelationGetNamespace(relation)
Definition: rel.h:452

◆ plpgsql_free_function_memory()

void plpgsql_free_function_memory ( PLpgSQL_function func)

Definition at line 695 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, PLpgSQL_arrayelem::dtype, elog, ERROR, PLpgSQL_function::fn_cxt, free_block(), free_expr(), i, MemoryContextDelete(), PLpgSQL_function::ndatums, 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().

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

◆ plpgsql_getdiag_kindname()

const char* plpgsql_getdiag_kindname ( PLpgSQL_getdiag_kind  kind)

Definition at line 296 of file pl_funcs.c.

References free_assert(), free_assign(), free_block(), free_case(), free_close(), free_dynexecute(), free_dynfors(), free_execsql(), free_exit(), free_expr(), free_fetch(), free_forc(), free_foreach_a(), free_fori(), free_fors(), free_getdiag(), free_if(), free_loop(), free_open(), free_perform(), free_raise(), free_return(), free_return_next(), free_return_query(), free_stmt(), free_while(), 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().

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

◆ plpgsql_HashTableInit()

void plpgsql_HashTableInit ( void  )

Definition at line 2563 of file pl_comp.c.

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

Referenced by _PG_init().

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

◆ plpgsql_latest_lineno()

int plpgsql_latest_lineno ( void  )

Definition at line 688 of file pl_scanner.c.

References cur_line_num.

Referenced by plpgsql_compile_error_callback().

689 {
690  return cur_line_num;
691 }
static int cur_line_num
Definition: pl_scanner.c:232

◆ plpgsql_location_to_lineno()

int plpgsql_location_to_lineno ( int  location)

Definition at line 654 of file pl_scanner.c.

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

655 {
656  const char *loc;
657 
658  if (location < 0 || scanorig == NULL)
659  return 0; /* garbage in, garbage out */
660  loc = scanorig + location;
661 
662  /* be correct, but not fast, if input location goes backwards */
663  if (loc < cur_line_start)
665 
666  while (cur_line_end != NULL && loc > cur_line_end)
667  {
669  cur_line_num++;
670  cur_line_end = strchr(cur_line_start, '\n');
671  }
672 
673  return cur_line_num;
674 }
static int cur_line_num
Definition: pl_scanner.c:232
static void location_lineno_init(void)
Definition: pl_scanner.c:678
static const char * cur_line_start
Definition: pl_scanner.c:230
static const char * scanorig
Definition: pl_scanner.c:214
static const char * cur_line_end
Definition: pl_scanner.c:231

◆ plpgsql_ns_additem()

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

Definition at line 94 of file pl_funcs.c.

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

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

95 {
96  PLpgSQL_nsitem *nse;
97 
98  Assert(name != NULL);
99  /* first item added must be a label */
100  Assert(ns_top != NULL || itemtype == PLPGSQL_NSTYPE_LABEL);
101 
102  nse = palloc(offsetof(PLpgSQL_nsitem, name) + strlen(name) + 1);
103  nse->itemtype = itemtype;
104  nse->itemno = itemno;
105  nse->prev = ns_top;
106  strcpy(nse->name, name);
107  ns_top = nse;
108 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:37
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:358
#define Assert(condition)
Definition: c.h:680
const char * name
Definition: encode.c:521
void * palloc(Size size)
Definition: mcxt.c:835
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:351
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:359
#define offsetof(type, field)
Definition: c.h:603

◆ plpgsql_ns_find_nearest_loop()

PLpgSQL_nsitem* plpgsql_ns_find_nearest_loop ( PLpgSQL_nsitem ns_cur)

Definition at line 216 of file pl_funcs.c.

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

217 {
218  while (ns_cur != NULL)
219  {
220  if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
221  ns_cur->itemno == PLPGSQL_LABEL_LOOP)
222  return ns_cur;
223  ns_cur = ns_cur->prev;
224  }
225 
226  return NULL; /* no loop found */
227 }
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:358
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:351

◆ plpgsql_ns_init()

void plpgsql_ns_init ( void  )

Definition at line 45 of file pl_funcs.c.

Referenced by do_compile(), and plpgsql_compile_inline().

46 {
47  ns_top = NULL;
48 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:37

◆ plpgsql_ns_lookup()

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 132 of file pl_funcs.c.

References PLpgSQL_nsitem::itemtype, PLpgSQL_nsitem::name, 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().

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

◆ plpgsql_ns_lookup_label()

PLpgSQL_nsitem* plpgsql_ns_lookup_label ( PLpgSQL_nsitem ns_cur,
const char *  name 
)

Definition at line 197 of file pl_funcs.c.

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

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

◆ plpgsql_ns_pop()

void plpgsql_ns_pop ( void  )

Definition at line 69 of file pl_funcs.c.

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

70 {
71  Assert(ns_top != NULL);
73  ns_top = ns_top->prev;
74  ns_top = ns_top->prev;
75 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:37
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:358
#define Assert(condition)
Definition: c.h:680
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:351

◆ plpgsql_ns_push()

void plpgsql_ns_push ( const char *  label,
PLpgSQL_label_type  label_type 
)

Definition at line 56 of file pl_funcs.c.

References plpgsql_ns_additem(), and PLPGSQL_NSTYPE_LABEL.

Referenced by do_compile(), and plpgsql_compile_inline().

57 {
58  if (label == NULL)
59  label = "";
60  plpgsql_ns_additem(PLPGSQL_NSTYPE_LABEL, (int) label_type, label);
61 }
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
static char * label
Definition: pg_basebackup.c:82

◆ plpgsql_ns_top()

PLpgSQL_nsitem* plpgsql_ns_top ( void  )

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

84 {
85  return ns_top;
86 }
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:37

◆ plpgsql_parse_cwordrowtype()

PLpgSQL_type* plpgsql_parse_cwordrowtype ( List idents)

Definition at line 1839 of file pl_comp.c.

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

1840 {
1841  Oid classOid;
1842  RangeVar *relvar;
1843  MemoryContext oldCxt;
1844 
1845  if (list_length(idents) != 2)
1846  return NULL;
1847 
1848  /* Avoid memory leaks in long-term function context */
1850 
1851  /* Look up relation name. Can't lock it - we might not have privileges. */
1852  relvar = makeRangeVar(strVal(linitial(idents)),
1853  strVal(lsecond(idents)),
1854  -1);
1855  classOid = RangeVarGetRelid(relvar, NoLock, false);
1856 
1857  MemoryContextSwitchTo(oldCxt);
1858 
1859  /* Build and return the row type struct */
1860  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1861 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2136
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:53
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
#define lsecond(l)
Definition: pg_list.h:116
#define linitial(l)
Definition: pg_list.h:111
#define NoLock
Definition: lockdefs.h:34
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1796
#define InvalidOid
Definition: postgres_ext.h:36
static int list_length(const List *l)
Definition: pg_list.h:89
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:421

◆ plpgsql_parse_cwordtype()

PLpgSQL_type* plpgsql_parse_cwordtype ( List idents)

Definition at line 1700 of file pl_comp.c.

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

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

◆ plpgsql_parse_dblword()

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

Definition at line 1420 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

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

◆ plpgsql_parse_err_condition()

PLpgSQL_condition* plpgsql_parse_err_condition ( char *  condname)

Definition at line 2271 of file pl_comp.c.

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

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

◆ plpgsql_parse_tripword()

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

Definition at line 1540 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

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

◆ plpgsql_parse_word()

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

Definition at line 1364 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

1366 {
1367  PLpgSQL_nsitem *ns;
1368 
1369  /*
1370  * We should do nothing in DECLARE sections. In SQL expressions, there's
1371  * no need to do anything either --- lookup will happen when the
1372  * expression is compiled.
1373  */
1375  {
1376  /*
1377  * Do a lookup in the current namespace stack
1378  */
1379  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1380  word1, NULL, NULL,
1381  NULL);
1382 
1383  if (ns != NULL)
1384  {
1385  switch (ns->itemtype)
1386  {
1387  case PLPGSQL_NSTYPE_VAR:
1388  case PLPGSQL_NSTYPE_ROW:
1389  case PLPGSQL_NSTYPE_REC:
1390  wdatum->datum = plpgsql_Datums[ns->itemno];
1391  wdatum->ident = word1;
1392  wdatum->quoted = (yytxt[0] == '"');
1393  wdatum->idents = NIL;
1394  return true;
1395 
1396  default:
1397  /* plpgsql_ns_lookup should never return anything else */
1398  elog(ERROR, "unrecognized plpgsql itemtype: %d",
1399  ns->itemtype);
1400  }
1401  }
1402  }
1403 
1404  /*
1405  * Nothing found - up to now it's a word without any special meaning for
1406  * us.
1407  */
1408  word->ident = word1;
1409  word->quoted = (yytxt[0] == '"');
1410  return false;
1411 }
#define NIL
Definition: pg_list.h:69
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
char * ident
Definition: plpgsql.h:984
#define ERROR
Definition: elog.h:43
List * idents
Definition: plpgsql.h:998
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:29
bool quoted
Definition: plpgsql.h:985
PLpgSQL_datum * datum
Definition: plpgsql.h:995
bool quoted
Definition: plpgsql.h:997
char * ident
Definition: plpgsql.h:996
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:351
#define elog
Definition: elog.h:219

◆ plpgsql_parse_wordrowtype()

PLpgSQL_type* plpgsql_parse_wordrowtype ( char *  ident)

Definition at line 1818 of file pl_comp.c.

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

1819 {
1820  Oid classOid;
1821 
1822  /* Lookup the relation */
1823  classOid = RelnameGetRelid(ident);
1824  if (!OidIsValid(classOid))
1825  ereport(ERROR,
1827  errmsg("relation \"%s\" does not exist", ident)));
1828 
1829  /* Build and return the row type struct */
1830  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1831 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:2136
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:61
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:654
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:586
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1796
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ plpgsql_parse_wordtype()

PLpgSQL_type* plpgsql_parse_wordtype ( char *  ident)

Definition at line 1637 of file pl_comp.c.

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

1638 {
1639  PLpgSQL_type *dtype;
1640  PLpgSQL_nsitem *nse;
1641  HeapTuple typeTup;
1642 
1643  /*
1644  * Do a lookup in the current namespace stack
1645  */
1646  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1647  ident, NULL, NULL,
1648  NULL);
1649 
1650  if (nse != NULL)
1651  {
1652  switch (nse->itemtype)
1653  {
1654  case PLPGSQL_NSTYPE_VAR:
1655  return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1656 
1657  /* XXX perhaps allow REC/ROW here? */
1658 
1659  default:
1660  return NULL;
1661  }
1662  }
1663 
1664  /*
1665  * Word wasn't found in the namespace stack. Try to find a data type with
1666  * that name, but ignore shell types and complex types.
1667  */
1668  typeTup = LookupTypeName(NULL, makeTypeName(ident), NULL, false);
1669  if (typeTup)
1670  {
1671  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1672 
1673  if (!typeStruct->typisdefined ||
1674  typeStruct->typrelid != InvalidOid)
1675  {
1676  ReleaseSysCache(typeTup);
1677  return NULL;
1678  }
1679 
1680  dtype = build_datatype(typeTup, -1,
1682 
1683  ReleaseSysCache(typeTup);
1684  return dtype;
1685  }
1686 
1687  /*
1688  * Nothing found - up to now it's a word without any special meaning for
1689  * us.
1690  */
1691  return NULL;
1692 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:57
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
Oid fn_input_collation
Definition: plpgsql.h:817
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define InvalidOid
Definition: postgres_ext.h:36
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:443
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2156
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:351
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:54

◆ plpgsql_parser_setup()

void plpgsql_parser_setup ( struct ParseState pstate,
PLpgSQL_expr expr 
)

Definition at line 1027 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(), and plpgsql_estate_setup().

1028 {
1032  /* no need to use p_coerce_param_hook */
1033  pstate->p_ref_hook_state = (void *) expr;
1034 }
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1040
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:212
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:213
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1098
void * p_ref_hook_state
Definition: parse_node.h:215
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:211
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1054

◆ plpgsql_peek()

int plpgsql_peek ( void  )

Definition at line 536 of file pl_scanner.c.

References internal_yylex(), and push_back_token().

537 {
538  int tok1;
539  TokenAuxData aux1;
540 
541  tok1 = internal_yylex(&aux1);
542  push_back_token(tok1, &aux1);
543  return tok1;
544 }
static int internal_yylex(TokenAuxData *auxdata)
Definition: pl_scanner.c:424
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:470

◆ plpgsql_peek2()

void plpgsql_peek2 ( int *  tok1_p,
int *  tok2_p,
int *  tok1_loc,
int *  tok2_loc 
)

Definition at line 555 of file pl_scanner.c.

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

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

◆ plpgsql_push_back_token()

void plpgsql_push_back_token ( int  token)

Definition at line 486 of file pl_scanner.c.

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

487 {
488  TokenAuxData auxdata;
489 
490  auxdata.lval = plpgsql_yylval;
491  auxdata.lloc = plpgsql_yylloc;
492  auxdata.leng = plpgsql_yyleng;
493  push_back_token(token, &auxdata);
494 }
YYLTYPE lloc
Definition: pl_scanner.c:198
YYSTYPE lval
Definition: pl_scanner.c:197
static int plpgsql_yyleng
Definition: pl_scanner.c:217
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:470

◆ plpgsql_recognize_err_condition()

int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2235 of file pl_comp.c.

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

Referenced by exec_stmt_raise().

2236 {
2237  int i;
2238 
2239  if (allow_sqlstate)
2240  {
2241  if (strlen(condname) == 5 &&
2242  strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2243  return MAKE_SQLSTATE(condname[0],
2244  condname[1],
2245  condname[2],
2246  condname[3],
2247  condname[4]);
2248  }
2249 
2250  for (i = 0; exception_label_map[i].label != NULL; i++)
2251  {
2252  if (strcmp(condname, exception_label_map[i].label) == 0)
2254  }
2255 
2256  ereport(ERROR,
2257  (errcode(ERRCODE_UNDEFINED_OBJECT),
2258  errmsg("unrecognized exception condition \"%s\"",
2259  condname)));
2260  return 0; /* keep compiler quiet */
2261 }
const char * label
Definition: pl_comp.c:79
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:62
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static char * label
Definition: pg_basebackup.c:82
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:83
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i

◆ plpgsql_scanner_errposition()

int plpgsql_scanner_errposition ( int  location)

Definition at line 588 of file pl_scanner.c.

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

Referenced by plpgsql_yyerror().

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

◆ plpgsql_scanner_finish()

void plpgsql_scanner_finish ( void  )

Definition at line 729 of file pl_scanner.c.

References scanner_finish(), scanorig, and yyscanner.

Referenced by do_compile(), and plpgsql_compile_inline().

730 {
731  /* release storage */
733  /* avoid leaving any dangling pointers */
734  yyscanner = NULL;
735  scanorig = NULL;
736 }
static const char * scanorig
Definition: pl_scanner.c:214
static core_yyscan_t yyscanner
Definition: pl_scanner.c:210
void scanner_finish(core_yyscan_t yyscanner)

◆ plpgsql_scanner_init()

void plpgsql_scanner_init ( const char *  str)

Definition at line 702 of file pl_scanner.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

703 {
704  /* Start up the core scanner */
707 
708  /*
709  * scanorig points to the original string, which unlike the scanner's
710  * scanbuf won't be modified on-the-fly by flex. Notice that although
711  * yytext points into scanbuf, we rely on being able to apply locations
712  * (offsets from string start) to scanorig as well.
713  */
714  scanorig = str;
715 
716  /* Other setup */
718  plpgsql_yytoken = 0;
719 
720  num_pushbacks = 0;
721 
723 }
static const ScanKeyword reserved_keywords[]
Definition: pl_scanner.c:70
static void location_lineno_init(void)
Definition: pl_scanner.c:678
static int plpgsql_yytoken
Definition: pl_scanner.c:220
static const char * scanorig
Definition: pl_scanner.c:214
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:29
static int num_pushbacks
Definition: pl_scanner.c:225
static core_yy_extra_type core_yy
Definition: pl_scanner.c:211
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:210
static const int num_reserved_keywords
Definition: pl_scanner.c:97

◆ plpgsql_stmt_typename()

const char* plpgsql_stmt_typename ( PLpgSQL_stmt stmt)

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

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

◆ plpgsql_subxact_cb()

void plpgsql_subxact_cb ( SubXactEvent  event,
SubTransactionId  mySubid,
SubTransactionId  parentSubid,
void *  arg 
)

Definition at line 6792 of file pl_exec.c.

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

Referenced by _PG_init(), and plpgsql_inline_handler().

6794 {
6795  if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
6796  {
6797  while (simple_econtext_stack != NULL &&
6798  simple_econtext_stack->xact_subxid == mySubid)
6799  {
6801 
6803  (event == SUBXACT_EVENT_COMMIT_SUB));
6804  next = simple_econtext_stack->next;
6807  }
6808  }
6809 }
static int32 next
Definition: blutils.c:210
struct SimpleEcontextStackEntry * next
Definition: pl_exec.c:86
void pfree(void *pointer)
Definition: mcxt.c:936
ExprContext * stack_econtext
Definition: pl_exec.c:84
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:90
SubTransactionId xact_subxid
Definition: pl_exec.c:85
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:357

◆ plpgsql_token_is_unreserved_keyword()

bool plpgsql_token_is_unreserved_keyword ( int  token)

Definition at line 503 of file pl_scanner.c.

References i, num_unreserved_keywords, and value.

504 {
505  int i;
506 
507  for (i = 0; i < num_unreserved_keywords; i++)
508  {
509  if (unreserved_keywords[i].value == token)
510  return true;
511  }
512  return false;
513 }
static struct @130 value
static const int num_unreserved_keywords
Definition: pl_scanner.c:178
static const ScanKeyword unreserved_keywords[]
Definition: pl_scanner.c:99
int i

◆ plpgsql_xact_cb()

void plpgsql_xact_cb ( XactEvent  event,
void *  arg 
)

Definition at line 6760 of file pl_exec.c.

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

Referenced by _PG_init().

6761 {
6762  /*
6763  * If we are doing a clean transaction shutdown, free the EState (so that
6764  * any remaining resources will be released correctly). In an abort, we
6765  * expect the regular abort recovery procedures to release everything of
6766  * interest.
6767  */
6768  if (event == XACT_EVENT_COMMIT || event == XACT_EVENT_PREPARE)
6769  {
6770  /* Shouldn't be any econtext stack entries left at commit */
6771  Assert(simple_econtext_stack == NULL);
6772 
6776  }
6777  else if (event == XACT_EVENT_ABORT)
6778  {
6779  simple_econtext_stack = NULL;
6781  }
6782 }
void FreeExecutorState(EState *estate)
Definition: execUtils.c:186
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:90
static EState * shared_simple_eval_estate
Definition: pl_exec.c:89
#define Assert(condition)
Definition: c.h:680

◆ plpgsql_yyerror()

void plpgsql_yyerror ( const char *  message)

Definition at line 615 of file pl_scanner.c.

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

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

◆ plpgsql_yylex()