Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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 "utils/expandedrecord.h"
#include "utils/funccache.h"
#include "utils/typcache.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_expr
 
struct  PLpgSQL_datum
 
struct  PLpgSQL_variable
 
struct  PLpgSQL_var
 
struct  PLpgSQL_row
 
struct  PLpgSQL_rec
 
struct  PLpgSQL_recfield
 
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_stmt_call
 
struct  PLpgSQL_stmt_commit
 
struct  PLpgSQL_stmt_rollback
 
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_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_OTHERS   (-1)
 
#define PLPGSQL_XCHECK_NONE   0
 
#define PLPGSQL_XCHECK_SHADOWVAR   (1 << 1)
 
#define PLPGSQL_XCHECK_TOOMANYROWS   (1 << 2)
 
#define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT   (1 << 3)
 
#define PLPGSQL_XCHECK_ALL   ((int) ~0)
 
#define YYLTYPE   int
 

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_promise_type PLpgSQL_promise_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 enum PLpgSQL_rwopt PLpgSQL_rwopt
 
typedef struct PLpgSQL_type PLpgSQL_type
 
typedef struct PLpgSQL_expr PLpgSQL_expr
 
typedef struct PLpgSQL_datum PLpgSQL_datum
 
typedef struct PLpgSQL_variable PLpgSQL_variable
 
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_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_stmt_call PLpgSQL_stmt_call
 
typedef struct PLpgSQL_stmt_commit PLpgSQL_stmt_commit
 
typedef struct PLpgSQL_stmt_rollback PLpgSQL_stmt_rollback
 
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 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
 
typedef void * yyscan_t
 

Enumerations

enum  PLpgSQL_nsitem_type { PLPGSQL_NSTYPE_LABEL , PLPGSQL_NSTYPE_VAR , 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_PROMISE
}
 
enum  PLpgSQL_promise_type {
  PLPGSQL_PROMISE_NONE = 0 , PLPGSQL_PROMISE_TG_NAME , PLPGSQL_PROMISE_TG_WHEN , PLPGSQL_PROMISE_TG_LEVEL ,
  PLPGSQL_PROMISE_TG_OP , PLPGSQL_PROMISE_TG_RELID , PLPGSQL_PROMISE_TG_TABLE_NAME , PLPGSQL_PROMISE_TG_TABLE_SCHEMA ,
  PLPGSQL_PROMISE_TG_NARGS , PLPGSQL_PROMISE_TG_ARGV , PLPGSQL_PROMISE_TG_EVENT , PLPGSQL_PROMISE_TG_TAG
}
 
enum  PLpgSQL_type_type { PLPGSQL_TTYPE_SCALAR , 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 ,
  PLPGSQL_STMT_CALL , PLPGSQL_STMT_COMMIT , PLPGSQL_STMT_ROLLBACK
}
 
enum  { PLPGSQL_RC_OK , PLPGSQL_RC_EXIT , PLPGSQL_RC_RETURN , PLPGSQL_RC_CONTINUE }
 
enum  PLpgSQL_getdiag_kind {
  PLPGSQL_GETDIAG_ROW_COUNT , PLPGSQL_GETDIAG_ROUTINE_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_rwopt { PLPGSQL_RWOPT_UNKNOWN = 0 , PLPGSQL_RWOPT_NOPE , PLPGSQL_RWOPT_TRANSFER , PLPGSQL_RWOPT_INPLACE }
 
enum  PLpgSQL_trigtype { PLPGSQL_DML_TRIGGER , PLPGSQL_EVENT_TRIGGER , PLPGSQL_NOT_TRIGGER }
 
enum  IdentifierLookup { IDENTIFIER_LOOKUP_NORMAL , IDENTIFIER_LOOKUP_DECLARE , IDENTIFIER_LOOKUP_EXPR }
 

Functions

PGDLLEXPORT PLpgSQL_functionplpgsql_compile (FunctionCallInfo fcinfo, bool forValidator)
 
PLpgSQL_functionplpgsql_compile_inline (char *proc_source)
 
PGDLLEXPORT void plpgsql_parser_setup (struct ParseState *pstate, PLpgSQL_expr *expr)
 
bool plpgsql_parse_word (char *word1, const char *yytxt, bool lookup, 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)
 
PGDLLEXPORT PLpgSQL_typeplpgsql_build_datatype (Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
 
PLpgSQL_typeplpgsql_build_datatype_arrayof (PLpgSQL_type *dtype)
 
PLpgSQL_variableplpgsql_build_variable (const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
 
PLpgSQL_recplpgsql_build_record (const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
 
PLpgSQL_recfieldplpgsql_build_recfield (PLpgSQL_rec *rec, const char *fldname)
 
PGDLLEXPORT int plpgsql_recognize_err_condition (const char *condname, bool allow_sqlstate)
 
PLpgSQL_conditionplpgsql_parse_err_condition (char *condname)
 
void plpgsql_adddatum (PLpgSQL_datum *newdatum)
 
int plpgsql_add_initdatums (int **varnos)
 
Datum plpgsql_exec_function (PLpgSQL_function *func, FunctionCallInfo fcinfo, EState *simple_eval_estate, ResourceOwner simple_eval_resowner, ResourceOwner procedure_resowner, bool atomic)
 
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)
 
PGDLLEXPORT 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)
 
PGDLLEXPORT 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)
 
PGDLLEXPORT const char * plpgsql_stmt_typename (PLpgSQL_stmt *stmt)
 
const char * plpgsql_getdiag_kindname (PLpgSQL_getdiag_kind kind)
 
void plpgsql_mark_local_assignment_targets (PLpgSQL_function *func)
 
void plpgsql_free_function_memory (PLpgSQL_function *func)
 
void plpgsql_delete_callback (CachedFunction *cfunc)
 
void plpgsql_dumptree (PLpgSQL_function *func)
 
int plpgsql_yylex (union YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
 
int plpgsql_token_length (yyscan_t yyscanner)
 
void plpgsql_push_back_token (int token, union YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
 
bool plpgsql_token_is_unreserved_keyword (int token)
 
void plpgsql_append_source_text (StringInfo buf, int startlocation, int endlocation, yyscan_t yyscanner)
 
int plpgsql_peek (yyscan_t yyscanner)
 
void plpgsql_peek2 (int *tok1_p, int *tok2_p, int *tok1_loc, int *tok2_loc, yyscan_t yyscanner)
 
int plpgsql_scanner_errposition (int location, yyscan_t yyscanner)
 
pg_noreturn void plpgsql_yyerror (YYLTYPE *yyllocp, PLpgSQL_stmt_block **plpgsql_parse_result_p, yyscan_t yyscanner, const char *message)
 
int plpgsql_location_to_lineno (int location, yyscan_t yyscanner)
 
int plpgsql_latest_lineno (yyscan_t yyscanner)
 
yyscan_t plpgsql_scanner_init (const char *str)
 
void plpgsql_scanner_finish (yyscan_t yyscanner)
 
int plpgsql_yyparse (PLpgSQL_stmt_block **plpgsql_parse_result_p, yyscan_t yyscanner)
 

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

◆ PLPGSQL_OTHERS

#define PLPGSQL_OTHERS   (-1)

Definition at line 500 of file plpgsql.h.

◆ PLPGSQL_XCHECK_ALL

#define PLPGSQL_XCHECK_ALL   ((int) ~0)

Definition at line 1198 of file plpgsql.h.

◆ PLPGSQL_XCHECK_NONE

#define PLPGSQL_XCHECK_NONE   0

Definition at line 1194 of file plpgsql.h.

◆ PLPGSQL_XCHECK_SHADOWVAR

#define PLPGSQL_XCHECK_SHADOWVAR   (1 << 1)

Definition at line 1195 of file plpgsql.h.

◆ PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT

#define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT   (1 << 3)

Definition at line 1197 of file plpgsql.h.

◆ PLPGSQL_XCHECK_TOOMANYROWS

#define PLPGSQL_XCHECK_TOOMANYROWS   (1 << 2)

Definition at line 1196 of file plpgsql.h.

◆ TEXTDOMAIN

#define TEXTDOMAIN   PG_TEXTDOMAIN("plpgsql")

Definition at line 34 of file plpgsql.h.

◆ YYLTYPE

#define YYLTYPE   int

Definition at line 1309 of file plpgsql.h.

Typedef Documentation

◆ PLcword

typedef struct PLcword PLcword

◆ PLpgSQL_case_when

◆ PLpgSQL_condition

◆ PLpgSQL_datum

typedef struct PLpgSQL_datum PLpgSQL_datum

◆ PLpgSQL_datum_type

◆ PLpgSQL_diag_item

◆ PLpgSQL_exception

◆ PLpgSQL_exception_block

◆ PLpgSQL_execstate

◆ PLpgSQL_expr

typedef struct PLpgSQL_expr PLpgSQL_expr

◆ PLpgSQL_function

◆ PLpgSQL_getdiag_kind

◆ PLpgSQL_if_elsif

◆ PLpgSQL_label_type

◆ PLpgSQL_nsitem

◆ PLpgSQL_nsitem_type

◆ PLpgSQL_plugin

◆ PLpgSQL_promise_type

◆ PLpgSQL_raise_option

◆ PLpgSQL_raise_option_type

◆ PLpgSQL_rec

typedef struct PLpgSQL_rec PLpgSQL_rec

◆ PLpgSQL_recfield

◆ PLpgSQL_resolve_option

◆ PLpgSQL_row

typedef struct PLpgSQL_row PLpgSQL_row

◆ PLpgSQL_rwopt

◆ PLpgSQL_stmt

typedef struct PLpgSQL_stmt PLpgSQL_stmt

◆ PLpgSQL_stmt_assert

◆ PLpgSQL_stmt_assign

◆ PLpgSQL_stmt_block

◆ PLpgSQL_stmt_call

◆ PLpgSQL_stmt_case

◆ PLpgSQL_stmt_close

◆ PLpgSQL_stmt_commit

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

◆ PLpgSQL_stmt_type

◆ PLpgSQL_stmt_while

◆ PLpgSQL_trigtype

◆ PLpgSQL_type

typedef struct PLpgSQL_type PLpgSQL_type

◆ PLpgSQL_type_type

◆ PLpgSQL_var

typedef struct PLpgSQL_var PLpgSQL_var

◆ PLpgSQL_variable

◆ PLwdatum

typedef struct PLwdatum PLwdatum

◆ PLword

typedef struct PLword PLword

◆ yyscan_t

typedef void* yyscan_t

Definition at line 1310 of file plpgsql.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
PLPGSQL_RC_OK 
PLPGSQL_RC_EXIT 
PLPGSQL_RC_RETURN 
PLPGSQL_RC_CONTINUE 

Definition at line 137 of file plpgsql.h.

138{
143};
@ PLPGSQL_RC_RETURN
Definition: plpgsql.h:141
@ PLPGSQL_RC_EXIT
Definition: plpgsql.h:140
@ PLPGSQL_RC_OK
Definition: plpgsql.h:139
@ PLPGSQL_RC_CONTINUE
Definition: plpgsql.h:142

◆ IdentifierLookup

Enumerator
IDENTIFIER_LOOKUP_NORMAL 
IDENTIFIER_LOOKUP_DECLARE 
IDENTIFIER_LOOKUP_EXPR 

Definition at line 1178 of file plpgsql.h.

1179{
1180 IDENTIFIER_LOOKUP_NORMAL, /* normal processing of var names */
1181 IDENTIFIER_LOOKUP_DECLARE, /* In DECLARE --- don't look up names */
1182 IDENTIFIER_LOOKUP_EXPR, /* In SQL expression --- special case */
IdentifierLookup
Definition: plpgsql.h:1179
@ IDENTIFIER_LOOKUP_DECLARE
Definition: plpgsql.h:1181
@ IDENTIFIER_LOOKUP_NORMAL
Definition: plpgsql.h:1180
@ IDENTIFIER_LOOKUP_EXPR
Definition: plpgsql.h:1182

◆ PLpgSQL_datum_type

Enumerator
PLPGSQL_DTYPE_VAR 
PLPGSQL_DTYPE_ROW 
PLPGSQL_DTYPE_REC 
PLPGSQL_DTYPE_RECFIELD 
PLPGSQL_DTYPE_PROMISE 

Definition at line 62 of file plpgsql.h.

63{
PLpgSQL_datum_type
Definition: plpgsql.h:63
@ PLPGSQL_DTYPE_ROW
Definition: plpgsql.h:65
@ PLPGSQL_DTYPE_PROMISE
Definition: plpgsql.h:68
@ PLPGSQL_DTYPE_RECFIELD
Definition: plpgsql.h:67
@ PLPGSQL_DTYPE_REC
Definition: plpgsql.h:66
@ PLPGSQL_DTYPE_VAR
Definition: plpgsql.h:64

◆ PLpgSQL_getdiag_kind

Enumerator
PLPGSQL_GETDIAG_ROW_COUNT 
PLPGSQL_GETDIAG_ROUTINE_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 148 of file plpgsql.h.

149{
PLpgSQL_getdiag_kind
Definition: plpgsql.h:149
@ PLPGSQL_GETDIAG_ERROR_DETAIL
Definition: plpgsql.h:154
@ PLPGSQL_GETDIAG_SCHEMA_NAME
Definition: plpgsql.h:162
@ PLPGSQL_GETDIAG_MESSAGE_TEXT
Definition: plpgsql.h:160
@ PLPGSQL_GETDIAG_DATATYPE_NAME
Definition: plpgsql.h:159
@ PLPGSQL_GETDIAG_TABLE_NAME
Definition: plpgsql.h:161
@ PLPGSQL_GETDIAG_CONSTRAINT_NAME
Definition: plpgsql.h:158
@ PLPGSQL_GETDIAG_COLUMN_NAME
Definition: plpgsql.h:157
@ PLPGSQL_GETDIAG_ROW_COUNT
Definition: plpgsql.h:150
@ PLPGSQL_GETDIAG_RETURNED_SQLSTATE
Definition: plpgsql.h:156
@ PLPGSQL_GETDIAG_CONTEXT
Definition: plpgsql.h:152
@ PLPGSQL_GETDIAG_ERROR_HINT
Definition: plpgsql.h:155
@ PLPGSQL_GETDIAG_ERROR_CONTEXT
Definition: plpgsql.h:153
@ PLPGSQL_GETDIAG_ROUTINE_OID
Definition: plpgsql.h:151

◆ PLpgSQL_label_type

Enumerator
PLPGSQL_LABEL_BLOCK 
PLPGSQL_LABEL_LOOP 
PLPGSQL_LABEL_OTHER 

Definition at line 52 of file plpgsql.h.

53{
54 PLPGSQL_LABEL_BLOCK, /* DECLARE/BEGIN block */
55 PLPGSQL_LABEL_LOOP, /* looping construct */
56 PLPGSQL_LABEL_OTHER, /* anything else */
PLpgSQL_label_type
Definition: plpgsql.h:53
@ PLPGSQL_LABEL_LOOP
Definition: plpgsql.h:55
@ PLPGSQL_LABEL_OTHER
Definition: plpgsql.h:56
@ PLPGSQL_LABEL_BLOCK
Definition: plpgsql.h:54

◆ PLpgSQL_nsitem_type

Enumerator
PLPGSQL_NSTYPE_LABEL 
PLPGSQL_NSTYPE_VAR 
PLPGSQL_NSTYPE_REC 

Definition at line 42 of file plpgsql.h.

43{
44 PLPGSQL_NSTYPE_LABEL, /* block label */
45 PLPGSQL_NSTYPE_VAR, /* scalar variable */
46 PLPGSQL_NSTYPE_REC, /* composite variable */
PLpgSQL_nsitem_type
Definition: plpgsql.h:43
@ PLPGSQL_NSTYPE_VAR
Definition: plpgsql.h:45
@ PLPGSQL_NSTYPE_REC
Definition: plpgsql.h:46
@ PLPGSQL_NSTYPE_LABEL
Definition: plpgsql.h:44

◆ PLpgSQL_promise_type

Enumerator
PLPGSQL_PROMISE_NONE 
PLPGSQL_PROMISE_TG_NAME 
PLPGSQL_PROMISE_TG_WHEN 
PLPGSQL_PROMISE_TG_LEVEL 
PLPGSQL_PROMISE_TG_OP 
PLPGSQL_PROMISE_TG_RELID 
PLPGSQL_PROMISE_TG_TABLE_NAME 
PLPGSQL_PROMISE_TG_TABLE_SCHEMA 
PLPGSQL_PROMISE_TG_NARGS 
PLPGSQL_PROMISE_TG_ARGV 
PLPGSQL_PROMISE_TG_EVENT 
PLPGSQL_PROMISE_TG_TAG 

Definition at line 74 of file plpgsql.h.

75{
76 PLPGSQL_PROMISE_NONE = 0, /* not a promise, or promise satisfied */
PLpgSQL_promise_type
Definition: plpgsql.h:75
@ PLPGSQL_PROMISE_TG_RELID
Definition: plpgsql.h:81
@ PLPGSQL_PROMISE_NONE
Definition: plpgsql.h:76
@ PLPGSQL_PROMISE_TG_WHEN
Definition: plpgsql.h:78
@ PLPGSQL_PROMISE_TG_ARGV
Definition: plpgsql.h:85
@ PLPGSQL_PROMISE_TG_TABLE_SCHEMA
Definition: plpgsql.h:83
@ PLPGSQL_PROMISE_TG_EVENT
Definition: plpgsql.h:86
@ PLPGSQL_PROMISE_TG_TABLE_NAME
Definition: plpgsql.h:82
@ PLPGSQL_PROMISE_TG_TAG
Definition: plpgsql.h:87
@ PLPGSQL_PROMISE_TG_OP
Definition: plpgsql.h:80
@ PLPGSQL_PROMISE_TG_LEVEL
Definition: plpgsql.h:79
@ PLPGSQL_PROMISE_TG_NARGS
Definition: plpgsql.h:84
@ PLPGSQL_PROMISE_TG_NAME
Definition: plpgsql.h:77

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

169{
PLpgSQL_raise_option_type
Definition: plpgsql.h:169
@ PLPGSQL_RAISEOPTION_COLUMN
Definition: plpgsql.h:174
@ PLPGSQL_RAISEOPTION_TABLE
Definition: plpgsql.h:177
@ PLPGSQL_RAISEOPTION_SCHEMA
Definition: plpgsql.h:178
@ PLPGSQL_RAISEOPTION_CONSTRAINT
Definition: plpgsql.h:175
@ PLPGSQL_RAISEOPTION_DETAIL
Definition: plpgsql.h:172
@ PLPGSQL_RAISEOPTION_MESSAGE
Definition: plpgsql.h:171
@ PLPGSQL_RAISEOPTION_HINT
Definition: plpgsql.h:173
@ PLPGSQL_RAISEOPTION_ERRCODE
Definition: plpgsql.h:170
@ PLPGSQL_RAISEOPTION_DATATYPE
Definition: plpgsql.h:176

◆ PLpgSQL_resolve_option

Enumerator
PLPGSQL_RESOLVE_ERROR 
PLPGSQL_RESOLVE_VARIABLE 
PLPGSQL_RESOLVE_COLUMN 

Definition at line 184 of file plpgsql.h.

185{
186 PLPGSQL_RESOLVE_ERROR, /* throw error if ambiguous */
187 PLPGSQL_RESOLVE_VARIABLE, /* prefer plpgsql var to table column */
188 PLPGSQL_RESOLVE_COLUMN, /* prefer table column to plpgsql var */
PLpgSQL_resolve_option
Definition: plpgsql.h:185
@ PLPGSQL_RESOLVE_COLUMN
Definition: plpgsql.h:188
@ PLPGSQL_RESOLVE_ERROR
Definition: plpgsql.h:186
@ PLPGSQL_RESOLVE_VARIABLE
Definition: plpgsql.h:187

◆ PLpgSQL_rwopt

Enumerator
PLPGSQL_RWOPT_UNKNOWN 
PLPGSQL_RWOPT_NOPE 
PLPGSQL_RWOPT_TRANSFER 
PLPGSQL_RWOPT_INPLACE 

Definition at line 194 of file plpgsql.h.

195{
196 PLPGSQL_RWOPT_UNKNOWN = 0, /* applicability not determined yet */
197 PLPGSQL_RWOPT_NOPE, /* cannot do any optimization */
198 PLPGSQL_RWOPT_TRANSFER, /* transfer the old value into expr state */
199 PLPGSQL_RWOPT_INPLACE, /* pass value as R/W to top-level function */
PLpgSQL_rwopt
Definition: plpgsql.h:195
@ PLPGSQL_RWOPT_INPLACE
Definition: plpgsql.h:199
@ PLPGSQL_RWOPT_UNKNOWN
Definition: plpgsql.h:196
@ PLPGSQL_RWOPT_TRANSFER
Definition: plpgsql.h:198
@ PLPGSQL_RWOPT_NOPE
Definition: plpgsql.h:197

◆ 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 
PLPGSQL_STMT_CALL 
PLPGSQL_STMT_COMMIT 
PLPGSQL_STMT_ROLLBACK 

Definition at line 103 of file plpgsql.h.

104{
PLpgSQL_stmt_type
Definition: plpgsql.h:104
@ PLPGSQL_STMT_DYNFORS
Definition: plpgsql.h:123
@ PLPGSQL_STMT_FORI
Definition: plpgsql.h:111
@ PLPGSQL_STMT_FETCH
Definition: plpgsql.h:126
@ PLPGSQL_STMT_CASE
Definition: plpgsql.h:108
@ PLPGSQL_STMT_OPEN
Definition: plpgsql.h:125
@ PLPGSQL_STMT_ROLLBACK
Definition: plpgsql.h:131
@ PLPGSQL_STMT_COMMIT
Definition: plpgsql.h:130
@ PLPGSQL_STMT_RETURN_QUERY
Definition: plpgsql.h:118
@ PLPGSQL_STMT_RETURN
Definition: plpgsql.h:116
@ PLPGSQL_STMT_CLOSE
Definition: plpgsql.h:127
@ PLPGSQL_STMT_WHILE
Definition: plpgsql.h:110
@ PLPGSQL_STMT_BLOCK
Definition: plpgsql.h:105
@ PLPGSQL_STMT_FORS
Definition: plpgsql.h:112
@ PLPGSQL_STMT_FORC
Definition: plpgsql.h:113
@ PLPGSQL_STMT_IF
Definition: plpgsql.h:107
@ PLPGSQL_STMT_PERFORM
Definition: plpgsql.h:128
@ PLPGSQL_STMT_LOOP
Definition: plpgsql.h:109
@ PLPGSQL_STMT_ASSERT
Definition: plpgsql.h:120
@ PLPGSQL_STMT_FOREACH_A
Definition: plpgsql.h:114
@ PLPGSQL_STMT_GETDIAG
Definition: plpgsql.h:124
@ PLPGSQL_STMT_RETURN_NEXT
Definition: plpgsql.h:117
@ PLPGSQL_STMT_ASSIGN
Definition: plpgsql.h:106
@ PLPGSQL_STMT_EXIT
Definition: plpgsql.h:115
@ PLPGSQL_STMT_EXECSQL
Definition: plpgsql.h:121
@ PLPGSQL_STMT_RAISE
Definition: plpgsql.h:119
@ PLPGSQL_STMT_CALL
Definition: plpgsql.h:129
@ PLPGSQL_STMT_DYNEXECUTE
Definition: plpgsql.h:122

◆ PLpgSQL_trigtype

Enumerator
PLPGSQL_DML_TRIGGER 
PLPGSQL_EVENT_TRIGGER 
PLPGSQL_NOT_TRIGGER 

Definition at line 948 of file plpgsql.h.

949{
PLpgSQL_trigtype
Definition: plpgsql.h:949
@ PLPGSQL_DML_TRIGGER
Definition: plpgsql.h:950
@ PLPGSQL_NOT_TRIGGER
Definition: plpgsql.h:952
@ PLPGSQL_EVENT_TRIGGER
Definition: plpgsql.h:951

◆ PLpgSQL_type_type

Enumerator
PLPGSQL_TTYPE_SCALAR 
PLPGSQL_TTYPE_REC 
PLPGSQL_TTYPE_PSEUDO 

Definition at line 93 of file plpgsql.h.

94{
95 PLPGSQL_TTYPE_SCALAR, /* scalar types and domains */
96 PLPGSQL_TTYPE_REC, /* composite types, including RECORD */
97 PLPGSQL_TTYPE_PSEUDO, /* pseudotypes */
PLpgSQL_type_type
Definition: plpgsql.h:94
@ PLPGSQL_TTYPE_PSEUDO
Definition: plpgsql.h:97
@ PLPGSQL_TTYPE_REC
Definition: plpgsql.h:96
@ PLPGSQL_TTYPE_SCALAR
Definition: plpgsql.h:95

Function Documentation

◆ plpgsql_add_initdatums()

int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2299 of file pl_comp.c.

2300{
2301 int i;
2302 int n = 0;
2303
2304 /*
2305 * The set of dtypes recognized here must match what exec_stmt_block()
2306 * cares about (re)initializing at block entry.
2307 */
2308 for (i = datums_last; i < plpgsql_nDatums; i++)
2309 {
2310 switch (plpgsql_Datums[i]->dtype)
2311 {
2312 case PLPGSQL_DTYPE_VAR:
2313 case PLPGSQL_DTYPE_REC:
2314 n++;
2315 break;
2316
2317 default:
2318 break;
2319 }
2320 }
2321
2322 if (varnos != NULL)
2323 {
2324 if (n > 0)
2325 {
2326 *varnos = (int *) palloc(sizeof(int) * n);
2327
2328 n = 0;
2329 for (i = datums_last; i < plpgsql_nDatums; i++)
2330 {
2331 switch (plpgsql_Datums[i]->dtype)
2332 {
2333 case PLPGSQL_DTYPE_VAR:
2334 case PLPGSQL_DTYPE_REC:
2335 (*varnos)[n++] = plpgsql_Datums[i]->dno;
2336
2337 default:
2338 break;
2339 }
2340 }
2341 }
2342 else
2343 *varnos = NULL;
2344 }
2345
2347 return n;
2348}
int i
Definition: isn.c:77
void * palloc(Size size)
Definition: mcxt.c:1365
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:43
static int datums_last
Definition: pl_comp.c:44
int plpgsql_nDatums
Definition: pl_comp.c:42

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

◆ plpgsql_adddatum()

void plpgsql_adddatum ( PLpgSQL_datum newdatum)

Definition at line 2238 of file pl_comp.c.

2239{
2241 {
2242 datums_alloc *= 2;
2244 }
2245
2246 newdatum->dno = plpgsql_nDatums;
2247 plpgsql_Datums[plpgsql_nDatums++] = newdatum;
2248}
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1610
static int datums_alloc
Definition: pl_comp.c:41

References datums_alloc, PLpgSQL_datum::dno, plpgsql_Datums, plpgsql_nDatums, and repalloc().

Referenced by plpgsql_build_recfield(), plpgsql_build_record(), plpgsql_build_variable(), and plpgsql_compile_callback().

◆ plpgsql_append_source_text()

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

Definition at line 435 of file pl_scanner.c.

438{
439 Assert(startlocation <= endlocation);
440 appendBinaryStringInfo(buf, yyextra->scanorig + startlocation,
441 endlocation - startlocation);
442}
Assert(PointerIsAligned(start, uint64))
static char * buf
Definition: pg_test_fsync.c:72
#define yyextra
Definition: pl_scanner.c:147
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281

References appendBinaryStringInfo(), Assert(), buf, and yyextra.

◆ plpgsql_build_datatype()

PGDLLEXPORT PLpgSQL_type * plpgsql_build_datatype ( Oid  typeOid,
int32  typmod,
Oid  collation,
TypeName origtypname 
)

Definition at line 1973 of file pl_comp.c.

1975{
1976 HeapTuple typeTup;
1977 PLpgSQL_type *typ;
1978
1979 typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
1980 if (!HeapTupleIsValid(typeTup))
1981 elog(ERROR, "cache lookup failed for type %u", typeOid);
1982
1983 typ = build_datatype(typeTup, typmod, collation, origtypname);
1984
1985 ReleaseSysCache(typeTup);
1986
1987 return typ;
1988}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:1995
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220

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

Referenced by exec_stmt_case(), plpgsql_build_datatype_arrayof(), plpgsql_compile_callback(), plpgsql_compile_inline(), plpgsql_parse_cwordrowtype(), and plpgsql_parse_wordrowtype().

◆ plpgsql_build_datatype_arrayof()

PLpgSQL_type * plpgsql_build_datatype_arrayof ( PLpgSQL_type dtype)

Definition at line 2107 of file pl_comp.c.

2108{
2109 Oid array_typeid;
2110
2111 /*
2112 * If it's already an array type, use it as-is: Postgres doesn't do nested
2113 * arrays.
2114 */
2115 if (dtype->typisarray)
2116 return dtype;
2117
2118 array_typeid = get_array_type(dtype->typoid);
2119 if (!OidIsValid(array_typeid))
2120 ereport(ERROR,
2121 (errcode(ERRCODE_UNDEFINED_OBJECT),
2122 errmsg("could not find array type for data type %s",
2123 format_type_be(dtype->typoid))));
2124
2125 /* Note we inherit typmod and collation, if any, from the element type */
2126 return plpgsql_build_datatype(array_typeid, dtype->atttypmod,
2127 dtype->collation, NULL);
2128}
#define OidIsValid(objectId)
Definition: c.h:775
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ereport(elevel,...)
Definition: elog.h:150
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2954
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:1973
unsigned int Oid
Definition: postgres_ext.h:32
bool typisarray
Definition: plpgsql.h:219
Oid collation
Definition: plpgsql.h:218
Oid typoid
Definition: plpgsql.h:213
int32 atttypmod
Definition: plpgsql.h:220

References PLpgSQL_type::atttypmod, PLpgSQL_type::collation, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_array_type(), OidIsValid, plpgsql_build_datatype(), PLpgSQL_type::typisarray, and PLpgSQL_type::typoid.

◆ plpgsql_build_recfield()

PLpgSQL_recfield * plpgsql_build_recfield ( PLpgSQL_rec rec,
const char *  fldname 
)

Definition at line 1924 of file pl_comp.c.

1925{
1926 PLpgSQL_recfield *recfield;
1927 int i;
1928
1929 /* search for an existing datum referencing this field */
1930 i = rec->firstfield;
1931 while (i >= 0)
1932 {
1934
1936 fld->recparentno == rec->dno);
1937 if (strcmp(fld->fieldname, fldname) == 0)
1938 return fld;
1939 i = fld->nextfield;
1940 }
1941
1942 /* nope, so make a new one */
1943 recfield = palloc0(sizeof(PLpgSQL_recfield));
1944 recfield->dtype = PLPGSQL_DTYPE_RECFIELD;
1945 recfield->fieldname = pstrdup(fldname);
1946 recfield->recparentno = rec->dno;
1948
1949 plpgsql_adddatum((PLpgSQL_datum *) recfield);
1950
1951 /* now we can link it into the parent's chain */
1952 recfield->nextfield = rec->firstfield;
1953 rec->firstfield = recfield->dno;
1954
1955 return recfield;
1956}
char * pstrdup(const char *in)
Definition: mcxt.c:1759
void * palloc0(Size size)
Definition: mcxt.c:1395
void plpgsql_adddatum(PLpgSQL_datum *newdatum)
Definition: pl_comp.c:2238
int firstfield
Definition: plpgsql.h:432
uint64 rectupledescid
Definition: plpgsql.h:452
PLpgSQL_datum_type dtype
Definition: plpgsql.h:445
char * fieldname
Definition: plpgsql.h:449
#define INVALID_TUPLEDESC_IDENTIFIER
Definition: typcache.h:157

References Assert(), PLpgSQL_rec::dno, PLpgSQL_recfield::dno, PLpgSQL_recfield::dtype, PLpgSQL_recfield::fieldname, PLpgSQL_rec::firstfield, i, INVALID_TUPLEDESC_IDENTIFIER, PLpgSQL_recfield::nextfield, palloc0(), plpgsql_adddatum(), plpgsql_Datums, PLPGSQL_DTYPE_RECFIELD, pstrdup(), PLpgSQL_recfield::recparentno, and PLpgSQL_recfield::rectupledescid.

Referenced by plpgsql_parse_dblword(), and plpgsql_parse_tripword().

◆ plpgsql_build_record()

PLpgSQL_rec * plpgsql_build_record ( const char *  refname,
int  lineno,
PLpgSQL_type dtype,
Oid  rectypeid,
bool  add2namespace 
)

Definition at line 1830 of file pl_comp.c.

1833{
1834 PLpgSQL_rec *rec;
1835
1836 rec = palloc0(sizeof(PLpgSQL_rec));
1837 rec->dtype = PLPGSQL_DTYPE_REC;
1838 rec->refname = pstrdup(refname);
1839 rec->lineno = lineno;
1840 /* other fields are left as 0, might be changed by caller */
1841 rec->datatype = dtype;
1842 rec->rectypeid = rectypeid;
1843 rec->firstfield = -1;
1844 rec->erh = NULL;
1846 if (add2namespace)
1848
1849 return rec;
1850}
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:92
ExpandedRecordHeader * erh
Definition: plpgsql.h:437
PLpgSQL_type * datatype
Definition: plpgsql.h:429
PLpgSQL_datum_type dtype
Definition: plpgsql.h:414
Oid rectypeid
Definition: plpgsql.h:430
int lineno
Definition: plpgsql.h:417
char * refname
Definition: plpgsql.h:416

References PLpgSQL_rec::datatype, PLpgSQL_rec::dno, PLpgSQL_rec::dtype, PLpgSQL_rec::erh, PLpgSQL_rec::firstfield, PLpgSQL_rec::lineno, palloc0(), plpgsql_adddatum(), PLPGSQL_DTYPE_REC, plpgsql_ns_additem(), PLPGSQL_NSTYPE_REC, pstrdup(), PLpgSQL_rec::rectypeid, and PLpgSQL_rec::refname.

Referenced by plpgsql_build_variable(), and plpgsql_compile_callback().

◆ plpgsql_build_variable()

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

Definition at line 1767 of file pl_comp.c.

1769{
1770 PLpgSQL_variable *result;
1771
1772 switch (dtype->ttype)
1773 {
1775 {
1776 /* Ordinary scalar datatype */
1777 PLpgSQL_var *var;
1778
1779 var = palloc0(sizeof(PLpgSQL_var));
1780 var->dtype = PLPGSQL_DTYPE_VAR;
1781 var->refname = pstrdup(refname);
1782 var->lineno = lineno;
1783 var->datatype = dtype;
1784 /* other fields are left as 0, might be changed by caller */
1785
1786 /* preset to NULL */
1787 var->value = 0;
1788 var->isnull = true;
1789 var->freeval = false;
1790
1792 if (add2namespace)
1794 var->dno,
1795 refname);
1796 result = (PLpgSQL_variable *) var;
1797 break;
1798 }
1799 case PLPGSQL_TTYPE_REC:
1800 {
1801 /* Composite type -- build a record variable */
1802 PLpgSQL_rec *rec;
1803
1804 rec = plpgsql_build_record(refname, lineno,
1805 dtype, dtype->typoid,
1806 add2namespace);
1807 result = (PLpgSQL_variable *) rec;
1808 break;
1809 }
1811 ereport(ERROR,
1812 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1813 errmsg("variable \"%s\" has pseudo-type %s",
1814 refname, format_type_be(dtype->typoid))));
1815 result = NULL; /* keep compiler quiet */
1816 break;
1817 default:
1818 elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1819 result = NULL; /* keep compiler quiet */
1820 break;
1821 }
1822
1823 return result;
1824}
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
Definition: pl_comp.c:1830
PLpgSQL_type_type ttype
Definition: plpgsql.h:214
int lineno
Definition: plpgsql.h:337
PLpgSQL_datum_type dtype
Definition: plpgsql.h:334
bool freeval
Definition: plpgsql.h:358
bool isnull
Definition: plpgsql.h:357
PLpgSQL_type * datatype
Definition: plpgsql.h:343
char * refname
Definition: plpgsql.h:336
Datum value
Definition: plpgsql.h:356

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

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_compile()

PGDLLEXPORT PLpgSQL_function * plpgsql_compile ( FunctionCallInfo  fcinfo,
bool  forValidator 
)

Definition at line 106 of file pl_comp.c.

107{
109
110 /*
111 * funccache.c manages re-use of existing PLpgSQL_function caches.
112 *
113 * In PL/pgSQL we use fn_extra directly as the pointer to the long-lived
114 * function cache entry; we have no need for any query-lifespan cache.
115 * Also, we don't need to make the cache key depend on composite result
116 * type (at least for now).
117 */
120 fcinfo->flinfo->fn_extra,
123 sizeof(PLpgSQL_function),
124 false,
125 forValidator);
126
127 /*
128 * Save pointer in FmgrInfo to avoid search on subsequent calls
129 */
130 fcinfo->flinfo->fn_extra = function;
131
132 /*
133 * Finally return the compiled function
134 */
135 return function;
136}
CachedFunction * cached_function_compile(FunctionCallInfo fcinfo, CachedFunction *function, CachedFunctionCompileCallback ccallback, CachedFunctionDeleteCallback dcallback, Size cacheEntrySize, bool includeResultType, bool forValidator)
Definition: funccache.c:480
on_exit_nicely_callback function
static void plpgsql_compile_callback(FunctionCallInfo fcinfo, HeapTuple procTup, const CachedFunctionHashKey *hashkey, CachedFunction *cfunc, bool forValidator)
Definition: pl_comp.c:167
void plpgsql_delete_callback(CachedFunction *cfunc)
Definition: pl_funcs.c:772
void * fn_extra
Definition: fmgr.h:64
FmgrInfo * flinfo
Definition: fmgr.h:87

References cached_function_compile(), FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, function, plpgsql_compile_callback(), and plpgsql_delete_callback().

Referenced by plpgsql_call_handler(), and plpgsql_validator().

◆ plpgsql_compile_inline()

PLpgSQL_function * plpgsql_compile_inline ( char *  proc_source)

Definition at line 743 of file pl_comp.c.

744{
745 yyscan_t scanner;
746 char *func_name = "inline_code_block";
748 struct compile_error_callback_arg cbarg;
749 ErrorContextCallback plerrcontext;
750 PLpgSQL_variable *var;
751 int parse_rc;
752 MemoryContext func_cxt;
753
754 /*
755 * Setup the scanner input and error info.
756 */
758
759 plpgsql_error_funcname = func_name;
760
761 /*
762 * Setup error traceback support for ereport()
763 */
764 cbarg.proc_source = proc_source;
765 cbarg.yyscanner = scanner;
766 plerrcontext.callback = plpgsql_compile_error_callback;
767 plerrcontext.arg = &cbarg;
768 plerrcontext.previous = error_context_stack;
769 error_context_stack = &plerrcontext;
770
771 /* Do extra syntax checking if check_function_bodies is on */
773
774 /* Function struct does not live past current statement */
776
778
779 /*
780 * All the rest of the compile-time storage (e.g. parse tree) is kept in
781 * its own memory context, so it can be reclaimed easily.
782 */
784 "PL/pgSQL inline code context",
787
788 function->fn_signature = pstrdup(func_name);
789 function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
790 function->fn_input_collation = InvalidOid;
791 function->fn_cxt = func_cxt;
792 function->out_param_varno = -1; /* set up for no OUT param */
793 function->resolve_option = plpgsql_variable_conflict;
794 function->print_strict_params = plpgsql_print_strict_params;
795
796 /*
797 * don't do extra validation for inline code as we don't want to add spam
798 * at runtime
799 */
800 function->extra_warnings = 0;
801 function->extra_errors = 0;
802
803 function->nstatements = 0;
804 function->requires_procedure_resowner = false;
805 function->has_exception_block = false;
806
809 plpgsql_DumpExecTree = false;
811
812 /* Set up as though in a function returning VOID */
813 function->fn_rettype = VOIDOID;
814 function->fn_retset = false;
815 function->fn_retistuple = false;
816 function->fn_retisdomain = false;
817 function->fn_prokind = PROKIND_FUNCTION;
818 /* a bit of hardwired knowledge about type VOID here */
819 function->fn_retbyval = true;
820 function->fn_rettyplen = sizeof(int32);
821
822 /*
823 * Remember if function is STABLE/IMMUTABLE. XXX would it be better to
824 * set this true inside a read-only transaction? Not clear.
825 */
826 function->fn_readonly = false;
827
828 /*
829 * Create the magic FOUND variable.
830 */
831 var = plpgsql_build_variable("found", 0,
833 -1,
835 NULL),
836 true);
837 function->found_varno = var->dno;
838
839 /*
840 * Now parse the function's text
841 */
842 parse_rc = plpgsql_yyparse(&function->action, scanner);
843 if (parse_rc != 0)
844 elog(ERROR, "plpgsql parser returned %d", parse_rc);
845
846 plpgsql_scanner_finish(scanner);
847
848 /*
849 * If it returns VOID (always true at the moment), we allow control to
850 * fall off the end without an explicit RETURN statement.
851 */
852 if (function->fn_rettype == VOIDOID)
854
855 /*
856 * Complete the function's info
857 */
858 function->fn_nargs = 0;
859
861
862 if (function->has_exception_block)
864
865 /* Debug dump for completed functions */
868
869 /*
870 * Pop the error context stack
871 */
872 error_context_stack = plerrcontext.previous;
874
875 plpgsql_check_syntax = false;
876
879 return function;
880}
int32_t int32
Definition: c.h:535
void * yyscan_t
Definition: cubedata.h:65
ErrorContextCallback * error_context_stack
Definition: elog.c:95
bool check_function_bodies
Definition: guc_tables.c:529
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static void add_dummy_return(PLpgSQL_function *function)
Definition: pl_comp.c:944
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:53
static void plpgsql_compile_error_callback(void *arg)
Definition: pl_comp.c:889
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2221
char * plpgsql_error_funcname
Definition: pl_comp.c:46
bool plpgsql_check_syntax
Definition: pl_comp.c:48
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2255
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:50
bool plpgsql_DumpExecTree
Definition: pl_comp.c:47
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
Definition: pl_comp.c:1767
void plpgsql_ns_init(void)
Definition: pl_funcs.c:43
void plpgsql_dumptree(PLpgSQL_function *func)
Definition: pl_funcs.c:1601
void plpgsql_mark_local_assignment_targets(PLpgSQL_function *func)
Definition: pl_funcs.c:673
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
Definition: pl_funcs.c:54
int plpgsql_variable_conflict
Definition: pl_handler.c:47
bool plpgsql_print_strict_params
Definition: pl_handler.c:49
void plpgsql_scanner_finish(yyscan_t yyscanner)
Definition: pl_scanner.c:653
yyscan_t plpgsql_scanner_init(const char *str)
Definition: pl_scanner.c:621
int plpgsql_yyparse(PLpgSQL_stmt_block **plpgsql_parse_result_p, yyscan_t yyscanner)
#define InvalidOid
Definition: postgres_ext.h:37
struct ErrorContextCallback * previous
Definition: elog.h:297
const char * proc_source
Definition: pl_comp.c:140

References add_dummy_return(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, check_function_bodies, CurrentMemoryContext, PLpgSQL_variable::dno, elog, ERROR, error_context_stack, function, InvalidOid, MemoryContextSwitchTo(), palloc0(), plpgsql_build_datatype(), plpgsql_build_variable(), plpgsql_check_syntax, plpgsql_compile_error_callback(), plpgsql_compile_tmp_cxt, plpgsql_curr_compile, plpgsql_DumpExecTree, plpgsql_dumptree(), plpgsql_error_funcname, plpgsql_finish_datums(), PLPGSQL_LABEL_BLOCK, plpgsql_mark_local_assignment_targets(), PLPGSQL_NOT_TRIGGER, plpgsql_ns_init(), plpgsql_ns_push(), plpgsql_print_strict_params, plpgsql_scanner_finish(), plpgsql_scanner_init(), plpgsql_start_datums(), plpgsql_variable_conflict, plpgsql_yyparse(), ErrorContextCallback::previous, compile_error_callback_arg::proc_source, pstrdup(), and compile_error_callback_arg::yyscanner.

Referenced by plpgsql_inline_handler().

◆ plpgsql_delete_callback()

void plpgsql_delete_callback ( CachedFunction cfunc)

Definition at line 772 of file pl_funcs.c.

773{
775}
void plpgsql_free_function_memory(PLpgSQL_function *func)
Definition: pl_funcs.c:716

References plpgsql_free_function_memory().

Referenced by plpgsql_compile().

◆ plpgsql_dumptree()

void plpgsql_dumptree ( PLpgSQL_function func)

Definition at line 1601 of file pl_funcs.c.

1602{
1603 int i;
1604 PLpgSQL_datum *d;
1605
1606 printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1607 func->fn_signature);
1608
1609 printf("\nFunction's data area:\n");
1610 for (i = 0; i < func->ndatums; i++)
1611 {
1612 d = func->datums[i];
1613
1614 printf(" entry %d: ", i);
1615 switch (d->dtype)
1616 {
1617 case PLPGSQL_DTYPE_VAR:
1619 {
1620 PLpgSQL_var *var = (PLpgSQL_var *) d;
1621
1622 printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1623 var->refname, var->datatype->typname,
1624 var->datatype->typoid,
1625 var->datatype->atttypmod);
1626 if (var->isconst)
1627 printf(" CONSTANT\n");
1628 if (var->notnull)
1629 printf(" NOT NULL\n");
1630 if (var->default_val != NULL)
1631 {
1632 printf(" DEFAULT ");
1633 dump_expr(var->default_val);
1634 printf("\n");
1635 }
1636 if (var->cursor_explicit_expr != NULL)
1637 {
1638 if (var->cursor_explicit_argrow >= 0)
1639 printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1640
1641 printf(" CURSOR IS ");
1643 printf("\n");
1644 }
1645 if (var->promise != PLPGSQL_PROMISE_NONE)
1646 printf(" PROMISE %d\n",
1647 (int) var->promise);
1648 }
1649 break;
1650 case PLPGSQL_DTYPE_ROW:
1651 {
1652 PLpgSQL_row *row = (PLpgSQL_row *) d;
1653
1654 printf("ROW %-16s fields", row->refname);
1655 for (int j = 0; j < row->nfields; j++)
1656 {
1657 printf(" %s=var %d", row->fieldnames[j],
1658 row->varnos[j]);
1659 }
1660 printf("\n");
1661 }
1662 break;
1663 case PLPGSQL_DTYPE_REC:
1664 printf("REC %-16s typoid %u\n",
1665 ((PLpgSQL_rec *) d)->refname,
1666 ((PLpgSQL_rec *) d)->rectypeid);
1667 if (((PLpgSQL_rec *) d)->isconst)
1668 printf(" CONSTANT\n");
1669 if (((PLpgSQL_rec *) d)->notnull)
1670 printf(" NOT NULL\n");
1671 if (((PLpgSQL_rec *) d)->default_val != NULL)
1672 {
1673 printf(" DEFAULT ");
1674 dump_expr(((PLpgSQL_rec *) d)->default_val);
1675 printf("\n");
1676 }
1677 break;
1679 printf("RECFIELD %-16s of REC %d\n",
1680 ((PLpgSQL_recfield *) d)->fieldname,
1681 ((PLpgSQL_recfield *) d)->recparentno);
1682 break;
1683 default:
1684 printf("??? unknown data type %d\n", d->dtype);
1685 }
1686 }
1687 printf("\nFunction's statements:\n");
1688
1689 dump_indent = 0;
1690 printf("%3d:", func->action->lineno);
1691 dump_block(func->action);
1692 printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1693 fflush(stdout);
1694}
int j
Definition: isn.c:78
static int dump_indent
Definition: pl_funcs.c:784
static void dump_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:1592
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:933
#define printf(...)
Definition: port.h:245
PLpgSQL_datum_type dtype
Definition: plpgsql.h:300
PLpgSQL_stmt_block * action
Definition: plpgsql.h:998
PLpgSQL_datum ** datums
Definition: plpgsql.h:994
char * fn_signature
Definition: plpgsql.h:962
int * varnos
Definition: plpgsql.h:406
char * refname
Definition: plpgsql.h:390
char ** fieldnames
Definition: plpgsql.h:405
int nfields
Definition: plpgsql.h:404
char * typname
Definition: plpgsql.h:212
PLpgSQL_promise_type promise
Definition: plpgsql.h:365
int cursor_explicit_argrow
Definition: plpgsql.h:351
bool notnull
Definition: plpgsql.h:339
bool isconst
Definition: plpgsql.h:338
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:350
PLpgSQL_expr * default_val
Definition: plpgsql.h:340

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_rec::dtype, dump_block(), dump_expr(), dump_indent, PLpgSQL_row::fieldnames, PLpgSQL_function::fn_signature, i, PLpgSQL_var::isconst, j, PLpgSQL_stmt_block::lineno, PLpgSQL_function::ndatums, PLpgSQL_row::nfields, PLpgSQL_var::notnull, PLPGSQL_DTYPE_PROMISE, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, PLPGSQL_PROMISE_NONE, printf, PLpgSQL_var::promise, PLpgSQL_var::refname, PLpgSQL_row::refname, generate_unaccent_rules::stdout, PLpgSQL_type::typname, PLpgSQL_type::typoid, and PLpgSQL_row::varnos.

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_exec_event_trigger()

void plpgsql_exec_event_trigger ( PLpgSQL_function func,
EventTriggerData trigdata 
)

Definition at line 1175 of file pl_exec.c.

1176{
1177 PLpgSQL_execstate estate;
1178 ErrorContextCallback plerrcontext;
1179 int rc;
1180
1181 /*
1182 * Setup the execution state
1183 */
1184 plpgsql_estate_setup(&estate, func, NULL, NULL, NULL);
1185 estate.evtrigdata = trigdata;
1186
1187 /*
1188 * Setup error traceback support for ereport()
1189 */
1191 plerrcontext.arg = &estate;
1192 plerrcontext.previous = error_context_stack;
1193 error_context_stack = &plerrcontext;
1194
1195 /*
1196 * Make local execution copies of all the datums
1197 */
1198 estate.err_text = gettext_noop("during initialization of execution state");
1199 copy_plpgsql_datums(&estate, func);
1200
1201 /*
1202 * Let the instrumentation plugin peek at this function
1203 */
1204 if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
1205 ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
1206
1207 /*
1208 * Now call the toplevel block of statements
1209 */
1210 estate.err_text = NULL;
1211 rc = exec_toplevel_block(&estate, func->action);
1212 if (rc != PLPGSQL_RC_RETURN)
1213 {
1214 estate.err_text = NULL;
1215 ereport(ERROR,
1216 (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1217 errmsg("control reached end of trigger procedure without RETURN")));
1218 }
1219
1220 estate.err_text = gettext_noop("during function exit");
1221
1222 /*
1223 * Let the instrumentation plugin peek at this function
1224 */
1225 if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1226 ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1227
1228 /* Clean up any leftover temporary memory */
1229 plpgsql_destroy_econtext(&estate);
1230 exec_eval_cleanup(&estate);
1231 /* stmt_mcontext will be destroyed when function's main context is */
1232
1233 /*
1234 * Pop the error context stack
1235 */
1236 error_context_stack = plerrcontext.previous;
1237}
#define gettext_noop(x)
Definition: c.h:1196
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:4150
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1243
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate, ResourceOwner simple_eval_resowner)
Definition: pl_exec.c:3993
static int exec_toplevel_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1634
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:8702
static void copy_plpgsql_datums(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: pl_exec.c:1310
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:59
void(* callback)(void *arg)
Definition: elog.h:298
const char * err_text
Definition: plpgsql.h:1083
EventTriggerData * evtrigdata
Definition: plpgsql.h:1017
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1128
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1129

References PLpgSQL_function::action, ErrorContextCallback::arg, ErrorContextCallback::callback, copy_plpgsql_datums(), ereport, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, PLpgSQL_execstate::evtrigdata, exec_eval_cleanup(), exec_toplevel_block(), PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, gettext_noop, plpgsql_destroy_econtext(), plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, and ErrorContextCallback::previous.

Referenced by plpgsql_call_handler().

◆ plpgsql_exec_function()

Datum plpgsql_exec_function ( PLpgSQL_function func,
FunctionCallInfo  fcinfo,
EState simple_eval_estate,
ResourceOwner  simple_eval_resowner,
ResourceOwner  procedure_resowner,
bool  atomic 
)

Definition at line 493 of file pl_exec.c.

498{
499 PLpgSQL_execstate estate;
500 ErrorContextCallback plerrcontext;
501 int i;
502 int rc;
503
504 /*
505 * Setup the execution state
506 */
507 plpgsql_estate_setup(&estate, func, (ReturnSetInfo *) fcinfo->resultinfo,
508 simple_eval_estate, simple_eval_resowner);
509 estate.procedure_resowner = procedure_resowner;
510 estate.atomic = atomic;
511
512 /*
513 * Setup error traceback support for ereport()
514 */
516 plerrcontext.arg = &estate;
517 plerrcontext.previous = error_context_stack;
518 error_context_stack = &plerrcontext;
519
520 /*
521 * Make local execution copies of all the datums
522 */
523 estate.err_text = gettext_noop("during initialization of execution state");
524 copy_plpgsql_datums(&estate, func);
525
526 /*
527 * Store the actual call argument values into the appropriate variables
528 */
529 estate.err_text = gettext_noop("while storing call arguments into local variables");
530 for (i = 0; i < func->fn_nargs; i++)
531 {
532 int n = func->fn_argvarnos[i];
533
534 switch (estate.datums[n]->dtype)
535 {
537 {
538 PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
539
540 assign_simple_var(&estate, var,
541 fcinfo->args[i].value,
542 fcinfo->args[i].isnull,
543 false);
544
545 /*
546 * If it's a varlena type, check to see if we received a
547 * R/W expanded-object pointer. If so, we can commandeer
548 * the object rather than having to copy it. If passed a
549 * R/O expanded pointer, just keep it as the value of the
550 * variable for the moment. (We can change it to R/W if
551 * the variable gets modified, but that may very well
552 * never happen.)
553 *
554 * Also, force any flat array value to be stored in
555 * expanded form in our local variable, in hopes of
556 * improving efficiency of uses of the variable. (This is
557 * a hack, really: why only arrays? Need more thought
558 * about which cases are likely to win. See also
559 * typisarray-specific heuristic in exec_assign_value.)
560 */
561 if (!var->isnull && var->datatype->typlen == -1)
562 {
564 {
565 /* take ownership of R/W object */
566 assign_simple_var(&estate, var,
568 estate.datum_context),
569 false,
570 true);
571 }
573 {
574 /* R/O pointer, keep it as-is until assigned to */
575 }
576 else if (var->datatype->typisarray)
577 {
578 /* flat array, so force to expanded form */
579 assign_simple_var(&estate, var,
580 expand_array(var->value,
581 estate.datum_context,
582 NULL),
583 false,
584 true);
585 }
586 }
587 }
588 break;
589
591 {
592 PLpgSQL_rec *rec = (PLpgSQL_rec *) estate.datums[n];
593
594 if (!fcinfo->args[i].isnull)
595 {
596 /* Assign row value from composite datum */
598 (PLpgSQL_variable *) rec,
599 fcinfo->args[i].value);
600 }
601 else
602 {
603 /* If arg is null, set variable to null */
604 exec_move_row(&estate, (PLpgSQL_variable *) rec,
605 NULL, NULL);
606 }
607 /* clean up after exec_move_row() */
608 exec_eval_cleanup(&estate);
609 }
610 break;
611
612 default:
613 /* Anything else should not be an argument variable */
614 elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
615 }
616 }
617
618 estate.err_text = gettext_noop("during function entry");
619
620 /*
621 * Set the magic variable FOUND to false
622 */
623 exec_set_found(&estate, false);
624
625 /*
626 * Let the instrumentation plugin peek at this function
627 */
628 if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
629 ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
630
631 /*
632 * Now call the toplevel block of statements
633 */
634 estate.err_text = NULL;
635 rc = exec_toplevel_block(&estate, func->action);
636 if (rc != PLPGSQL_RC_RETURN)
637 {
638 estate.err_text = NULL;
640 (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
641 errmsg("control reached end of function without RETURN")));
642 }
643
644 /*
645 * We got a return value - process it
646 */
647 estate.err_text = gettext_noop("while casting return value to function's return type");
648
649 fcinfo->isnull = estate.retisnull;
650
651 if (estate.retisset)
652 {
653 ReturnSetInfo *rsi = estate.rsi;
654
655 /* Check caller can handle a set result */
656 if (!rsi || !IsA(rsi, ReturnSetInfo))
658 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
659 errmsg("set-valued function called in context that cannot accept a set")));
660
661 if (!(rsi->allowedModes & SFRM_Materialize))
663 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
664 errmsg("materialize mode required, but it is not allowed in this context")));
665
667
668 /* If we produced any tuples, send back the result */
669 if (estate.tuple_store)
670 {
671 MemoryContext oldcxt;
672
673 rsi->setResult = estate.tuple_store;
674 oldcxt = MemoryContextSwitchTo(estate.tuple_store_cxt);
676 MemoryContextSwitchTo(oldcxt);
677 }
678 estate.retval = (Datum) 0;
679 fcinfo->isnull = true;
680 }
681 else if (!estate.retisnull)
682 {
683 /*
684 * Cast result value to function's declared result type, and copy it
685 * out to the upper executor memory context. We must treat tuple
686 * results specially in order to deal with cases like rowtypes
687 * involving dropped columns.
688 */
689 if (estate.retistuple)
690 {
691 /* Don't need coercion if rowtype is known to match */
692 if (func->fn_rettype == estate.rettype &&
693 func->fn_rettype != RECORDOID)
694 {
695 /*
696 * Copy the tuple result into upper executor memory context.
697 * However, if we have a R/W expanded datum, we can just
698 * transfer its ownership out to the upper context.
699 */
700 estate.retval = SPI_datumTransfer(estate.retval,
701 false,
702 -1);
703 }
704 else
705 {
706 /*
707 * Need to look up the expected result type. XXX would be
708 * better to cache the tupdesc instead of repeating
709 * get_call_result_type(), but the only easy place to save it
710 * is in the PLpgSQL_function struct, and that's too
711 * long-lived: composite types could change during the
712 * existence of a PLpgSQL_function.
713 */
714 Oid resultTypeId;
715 TupleDesc tupdesc;
716
717 switch (get_call_result_type(fcinfo, &resultTypeId, &tupdesc))
718 {
720 /* got the expected result rowtype, now coerce it */
721 coerce_function_result_tuple(&estate, tupdesc);
722 break;
724 /* got the expected result rowtype, now coerce it */
725 coerce_function_result_tuple(&estate, tupdesc);
726 /* and check domain constraints */
727 /* XXX allowing caching here would be good, too */
728 domain_check(estate.retval, false, resultTypeId,
729 NULL, NULL);
730 break;
731 case TYPEFUNC_RECORD:
732
733 /*
734 * Failed to determine actual type of RECORD. We
735 * could raise an error here, but what this means in
736 * practice is that the caller is expecting any old
737 * generic rowtype, so we don't really need to be
738 * restrictive. Pass back the generated result as-is.
739 */
740 estate.retval = SPI_datumTransfer(estate.retval,
741 false,
742 -1);
743 break;
744 default:
745 /* shouldn't get here if retistuple is true ... */
746 elog(ERROR, "return type must be a row type");
747 break;
748 }
749 }
750 }
751 else
752 {
753 /* Scalar case: use exec_cast_value */
754 estate.retval = exec_cast_value(&estate,
755 estate.retval,
756 &fcinfo->isnull,
757 estate.rettype,
758 -1,
759 func->fn_rettype,
760 -1);
761
762 /*
763 * If the function's return type isn't by value, copy the value
764 * into upper executor memory context. However, if we have a R/W
765 * expanded datum, we can just transfer its ownership out to the
766 * upper executor context.
767 */
768 if (!fcinfo->isnull && !func->fn_retbyval)
769 estate.retval = SPI_datumTransfer(estate.retval,
770 false,
771 func->fn_rettyplen);
772 }
773 }
774 else
775 {
776 /*
777 * We're returning a NULL, which normally requires no conversion work
778 * regardless of datatypes. But, if we are casting it to a domain
779 * return type, we'd better check that the domain's constraints pass.
780 */
781 if (func->fn_retisdomain)
782 estate.retval = exec_cast_value(&estate,
783 estate.retval,
784 &fcinfo->isnull,
785 estate.rettype,
786 -1,
787 func->fn_rettype,
788 -1);
789 }
790
791 estate.err_text = gettext_noop("during function exit");
792
793 /*
794 * Let the instrumentation plugin peek at this function
795 */
796 if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
797 ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
798
799 /* Clean up any leftover temporary memory */
801 exec_eval_cleanup(&estate);
802 /* stmt_mcontext will be destroyed when function's main context is */
803
804 /*
805 * Pop the error context stack
806 */
807 error_context_stack = plerrcontext.previous;
808
809 /*
810 * Return the function's result
811 */
812 return estate.retval;
813}
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
void domain_check(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt)
Definition: domains.c:346
@ SFRM_Materialize
Definition: execnodes.h:341
Datum TransferExpandedObject(Datum d, MemoryContext new_parent)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition: funcapi.h:149
@ TYPEFUNC_RECORD
Definition: funcapi.h:151
@ TYPEFUNC_COMPOSITE_DOMAIN
Definition: funcapi.h:150
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
static void coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc)
Definition: pl_exec.c:824
static void exec_move_row_from_datum(PLpgSQL_execstate *estate, PLpgSQL_variable *target, Datum value)
Definition: pl_exec.c:7591
static Datum exec_cast_value(PLpgSQL_execstate *estate, Datum value, bool *isnull, Oid valtype, int32 valtypmod, Oid reqtype, int32 reqtypmod)
Definition: pl_exec.c:7888
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:8608
static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, Datum newvalue, bool isnull, bool freeable)
Definition: pl_exec.c:8793
static void exec_move_row(PLpgSQL_execstate *estate, PLpgSQL_variable *target, HeapTuple tup, TupleDesc tupdesc)
Definition: pl_exec.c:6917
uint64_t Datum
Definition: postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
Datum SPI_datumTransfer(Datum value, bool typByVal, int typLen)
Definition: spi.c:1361
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
Datum value
Definition: postgres.h:87
bool isnull
Definition: postgres.h:89
PLpgSQL_datum ** datums
Definition: plpgsql.h:1049
ResourceOwner procedure_resowner
Definition: plpgsql.h:1066
Tuplestorestate * tuple_store
Definition: plpgsql.h:1034
MemoryContext tuple_store_cxt
Definition: plpgsql.h:1036
TupleDesc tuple_store_desc
Definition: plpgsql.h:1035
MemoryContext datum_context
Definition: plpgsql.h:1051
ReturnSetInfo * rsi
Definition: plpgsql.h:1038
bool fn_retbyval
Definition: plpgsql.h:970
bool fn_retisdomain
Definition: plpgsql.h:972
int fn_argvarnos[FUNC_MAX_ARGS]
Definition: plpgsql.h:978
int16 typlen
Definition: plpgsql.h:215
SetFunctionReturnMode returnMode
Definition: execnodes.h:360
TupleDesc setDesc
Definition: execnodes.h:364
Tuplestorestate * setResult
Definition: execnodes.h:363
int allowedModes
Definition: execnodes.h:358
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:252
static bool VARATT_IS_EXTERNAL_EXPANDED_RW(const void *PTR)
Definition: varatt.h:382
static bool VARATT_IS_EXTERNAL_EXPANDED_RO(const void *PTR)
Definition: varatt.h:375

References PLpgSQL_function::action, ReturnSetInfo::allowedModes, ErrorContextCallback::arg, FunctionCallInfoBaseData::args, assign_simple_var(), PLpgSQL_execstate::atomic, ErrorContextCallback::callback, coerce_function_result_tuple(), copy_plpgsql_datums(), CreateTupleDescCopy(), PLpgSQL_var::datatype, PLpgSQL_execstate::datum_context, DatumGetPointer(), PLpgSQL_function::datums, PLpgSQL_execstate::datums, domain_check(), PLpgSQL_datum::dtype, elog, ereport, 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_toplevel_block(), expand_array(), PLpgSQL_function::fn_argvarnos, PLpgSQL_function::fn_nargs, PLpgSQL_function::fn_retbyval, PLpgSQL_function::fn_retisdomain, PLpgSQL_function::fn_rettype, PLpgSQL_function::fn_rettyplen, PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, get_call_result_type(), gettext_noop, i, if(), IsA, FunctionCallInfoBaseData::isnull, NullableDatum::isnull, PLpgSQL_var::isnull, MemoryContextSwitchTo(), plpgsql_destroy_econtext(), PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_VAR, plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, ErrorContextCallback::previous, PLpgSQL_execstate::procedure_resowner, FunctionCallInfoBaseData::resultinfo, PLpgSQL_execstate::retisnull, PLpgSQL_execstate::retisset, PLpgSQL_execstate::retistuple, PLpgSQL_execstate::rettype, ReturnSetInfo::returnMode, PLpgSQL_execstate::retval, PLpgSQL_execstate::rsi, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, SPI_datumTransfer(), TransferExpandedObject(), PLpgSQL_execstate::tuple_store, PLpgSQL_execstate::tuple_store_cxt, PLpgSQL_execstate::tuple_store_desc, TYPEFUNC_COMPOSITE, TYPEFUNC_COMPOSITE_DOMAIN, TYPEFUNC_RECORD, PLpgSQL_type::typisarray, PLpgSQL_type::typlen, NullableDatum::value, PLpgSQL_var::value, VARATT_IS_EXTERNAL_EXPANDED_RO(), and VARATT_IS_EXTERNAL_EXPANDED_RW().

Referenced by plpgsql_call_handler(), and plpgsql_inline_handler().

◆ plpgsql_exec_get_datum_type()

PGDLLEXPORT Oid plpgsql_exec_get_datum_type ( PLpgSQL_execstate estate,
PLpgSQL_datum datum 
)

Definition at line 5453 of file pl_exec.c.

5455{
5456 Oid typeid;
5457
5458 switch (datum->dtype)
5459 {
5460 case PLPGSQL_DTYPE_VAR:
5462 {
5463 PLpgSQL_var *var = (PLpgSQL_var *) datum;
5464
5465 typeid = var->datatype->typoid;
5466 break;
5467 }
5468
5469 case PLPGSQL_DTYPE_REC:
5470 {
5471 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5472
5473 if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5474 {
5475 /* Report variable's declared type */
5476 typeid = rec->rectypeid;
5477 }
5478 else
5479 {
5480 /* Report record's actual type if declared RECORD */
5481 typeid = rec->erh->er_typeid;
5482 }
5483 break;
5484 }
5485
5487 {
5488 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5489 PLpgSQL_rec *rec;
5490
5491 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5492
5493 /*
5494 * If record variable is NULL, instantiate it if it has a
5495 * named composite type, else complain. (This won't change
5496 * the logical state of the record: it's still NULL.)
5497 */
5498 if (rec->erh == NULL)
5500
5501 /*
5502 * Look up the field's properties if we have not already, or
5503 * if the tuple descriptor ID changed since last time.
5504 */
5505 if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5506 {
5508 recfield->fieldname,
5509 &recfield->finfo))
5510 ereport(ERROR,
5511 (errcode(ERRCODE_UNDEFINED_COLUMN),
5512 errmsg("record \"%s\" has no field \"%s\"",
5513 rec->refname, recfield->fieldname)));
5514 recfield->rectupledescid = rec->erh->er_tupdesc_id;
5515 }
5516
5517 typeid = recfield->finfo.ftypeid;
5518 break;
5519 }
5520
5521 default:
5522 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5523 typeid = InvalidOid; /* keep compiler quiet */
5524 break;
5525 }
5526
5527 return typeid;
5528}
#define unlikely(x)
Definition: c.h:403
bool expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname, ExpandedRecordFieldInfo *finfo)
static void instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec)
Definition: pl_exec.c:7824
ExpandedRecordFieldInfo finfo
Definition: plpgsql.h:453

References PLpgSQL_var::datatype, PLpgSQL_execstate::datums, PLpgSQL_datum::dtype, elog, ExpandedRecordHeader::er_tupdesc_id, ExpandedRecordHeader::er_typeid, ereport, PLpgSQL_rec::erh, errcode(), errmsg(), ERROR, expanded_record_lookup_field(), PLpgSQL_recfield::fieldname, PLpgSQL_recfield::finfo, ExpandedRecordFieldInfo::ftypeid, instantiate_empty_record_variable(), InvalidOid, PLPGSQL_DTYPE_PROMISE, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_VAR, PLpgSQL_recfield::recparentno, PLpgSQL_recfield::rectupledescid, PLpgSQL_rec::rectypeid, PLpgSQL_rec::refname, PLpgSQL_type::typoid, and unlikely.

Referenced by exec_stmt_foreach_a().

◆ 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 5538 of file pl_exec.c.

5541{
5542 switch (datum->dtype)
5543 {
5544 case PLPGSQL_DTYPE_VAR:
5546 {
5547 PLpgSQL_var *var = (PLpgSQL_var *) datum;
5548
5549 *typeId = var->datatype->typoid;
5550 *typMod = var->datatype->atttypmod;
5551 *collation = var->datatype->collation;
5552 break;
5553 }
5554
5555 case PLPGSQL_DTYPE_REC:
5556 {
5557 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5558
5559 if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5560 {
5561 /* Report variable's declared type */
5562 *typeId = rec->rectypeid;
5563 *typMod = -1;
5564 }
5565 else
5566 {
5567 /* Report record's actual type if declared RECORD */
5568 *typeId = rec->erh->er_typeid;
5569 /* do NOT return the mutable typmod of a RECORD variable */
5570 *typMod = -1;
5571 }
5572 /* composite types are never collatable */
5573 *collation = InvalidOid;
5574 break;
5575 }
5576
5578 {
5579 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5580 PLpgSQL_rec *rec;
5581
5582 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5583
5584 /*
5585 * If record variable is NULL, instantiate it if it has a
5586 * named composite type, else complain. (This won't change
5587 * the logical state of the record: it's still NULL.)
5588 */
5589 if (rec->erh == NULL)
5591
5592 /*
5593 * Look up the field's properties if we have not already, or
5594 * if the tuple descriptor ID changed since last time.
5595 */
5596 if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5597 {
5599 recfield->fieldname,
5600 &recfield->finfo))
5601 ereport(ERROR,
5602 (errcode(ERRCODE_UNDEFINED_COLUMN),
5603 errmsg("record \"%s\" has no field \"%s\"",
5604 rec->refname, recfield->fieldname)));
5605 recfield->rectupledescid = rec->erh->er_tupdesc_id;
5606 }
5607
5608 *typeId = recfield->finfo.ftypeid;
5609 *typMod = recfield->finfo.ftypmod;
5610 *collation = recfield->finfo.fcollation;
5611 break;
5612 }
5613
5614 default:
5615 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5616 *typeId = InvalidOid; /* keep compiler quiet */
5617 *typMod = -1;
5618 *collation = InvalidOid;
5619 break;
5620 }
5621}

References PLpgSQL_type::atttypmod, PLpgSQL_type::collation, PLpgSQL_var::datatype, PLpgSQL_execstate::datums, PLpgSQL_datum::dtype, elog, ExpandedRecordHeader::er_tupdesc_id, ExpandedRecordHeader::er_typeid, ereport, PLpgSQL_rec::erh, errcode(), errmsg(), ERROR, expanded_record_lookup_field(), ExpandedRecordFieldInfo::fcollation, PLpgSQL_recfield::fieldname, PLpgSQL_recfield::finfo, ExpandedRecordFieldInfo::ftypeid, ExpandedRecordFieldInfo::ftypmod, instantiate_empty_record_variable(), InvalidOid, PLPGSQL_DTYPE_PROMISE, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_VAR, PLpgSQL_recfield::recparentno, PLpgSQL_recfield::rectupledescid, PLpgSQL_rec::rectypeid, PLpgSQL_rec::refname, PLpgSQL_type::typoid, and unlikely.

Referenced by make_datum_param().

◆ plpgsql_exec_trigger()

HeapTuple plpgsql_exec_trigger ( PLpgSQL_function func,
TriggerData trigdata 
)

Definition at line 935 of file pl_exec.c.

937{
938 PLpgSQL_execstate estate;
939 ErrorContextCallback plerrcontext;
940 int rc;
941 TupleDesc tupdesc;
942 PLpgSQL_rec *rec_new,
943 *rec_old;
944 HeapTuple rettup;
945
946 /*
947 * Setup the execution state
948 */
949 plpgsql_estate_setup(&estate, func, NULL, NULL, NULL);
950 estate.trigdata = trigdata;
951
952 /*
953 * Setup error traceback support for ereport()
954 */
956 plerrcontext.arg = &estate;
957 plerrcontext.previous = error_context_stack;
958 error_context_stack = &plerrcontext;
959
960 /*
961 * Make local execution copies of all the datums
962 */
963 estate.err_text = gettext_noop("during initialization of execution state");
964 copy_plpgsql_datums(&estate, func);
965
966 /*
967 * Put the OLD and NEW tuples into record variables
968 *
969 * We set up expanded records for both variables even though only one may
970 * have a value. This allows record references to succeed in functions
971 * that are used for multiple trigger types. For example, we might have a
972 * test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')", which should
973 * work regardless of the current trigger type. If a value is actually
974 * fetched from an unsupplied tuple, it will read as NULL.
975 */
976 tupdesc = RelationGetDescr(trigdata->tg_relation);
977
978 rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
979 rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
980
981 rec_new->erh = make_expanded_record_from_tupdesc(tupdesc,
982 estate.datum_context);
983 rec_old->erh = make_expanded_record_from_exprecord(rec_new->erh,
984 estate.datum_context);
985
986 if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
987 {
988 /*
989 * Per-statement triggers don't use OLD/NEW variables
990 */
991 }
992 else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
993 {
994 expanded_record_set_tuple(rec_new->erh, trigdata->tg_trigtuple,
995 false, false);
996 }
997 else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
998 {
999 expanded_record_set_tuple(rec_new->erh, trigdata->tg_newtuple,
1000 false, false);
1001 expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
1002 false, false);
1003
1004 /*
1005 * In BEFORE trigger, stored generated columns are not computed yet,
1006 * so make them null in the NEW row. (Only needed in UPDATE branch;
1007 * in the INSERT case, they are already null, but in UPDATE, the field
1008 * still contains the old value.) Alternatively, we could construct a
1009 * whole new row structure without the generated columns, but this way
1010 * seems more efficient and potentially less confusing.
1011 */
1012 if (tupdesc->constr && tupdesc->constr->has_generated_stored &&
1013 TRIGGER_FIRED_BEFORE(trigdata->tg_event))
1014 {
1015 for (int i = 0; i < tupdesc->natts; i++)
1016 if (TupleDescAttr(tupdesc, i)->attgenerated == ATTRIBUTE_GENERATED_STORED)
1018 i + 1,
1019 (Datum) 0,
1020 true, /* isnull */
1021 false, false);
1022 }
1023 }
1024 else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
1025 {
1026 expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
1027 false, false);
1028 }
1029 else
1030 elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
1031
1032 /* Make transition tables visible to this SPI connection */
1033 rc = SPI_register_trigger_data(trigdata);
1034 Assert(rc >= 0);
1035
1036 estate.err_text = gettext_noop("during function entry");
1037
1038 /*
1039 * Set the magic variable FOUND to false
1040 */
1041 exec_set_found(&estate, false);
1042
1043 /*
1044 * Let the instrumentation plugin peek at this function
1045 */
1046 if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
1047 ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
1048
1049 /*
1050 * Now call the toplevel block of statements
1051 */
1052 estate.err_text = NULL;
1053 rc = exec_toplevel_block(&estate, func->action);
1054 if (rc != PLPGSQL_RC_RETURN)
1055 {
1056 estate.err_text = NULL;
1057 ereport(ERROR,
1058 (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1059 errmsg("control reached end of trigger procedure without RETURN")));
1060 }
1061
1062 estate.err_text = gettext_noop("during function exit");
1063
1064 if (estate.retisset)
1065 ereport(ERROR,
1066 (errcode(ERRCODE_DATATYPE_MISMATCH),
1067 errmsg("trigger procedure cannot return a set")));
1068
1069 /*
1070 * Check that the returned tuple structure has the same attributes, the
1071 * relation that fired the trigger has. A per-statement trigger always
1072 * needs to return NULL, so we ignore any return value the function itself
1073 * produces (XXX: is this a good idea?)
1074 *
1075 * XXX This way it is possible, that the trigger returns a tuple where
1076 * attributes don't have the correct atttypmod's length. It's up to the
1077 * trigger's programmer to ensure that this doesn't happen. Jan
1078 */
1079 if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
1080 rettup = NULL;
1081 else
1082 {
1083 TupleDesc retdesc;
1084 TupleConversionMap *tupmap;
1085
1086 /* We assume exec_stmt_return verified that result is composite */
1088
1089 /* We can special-case expanded records for speed */
1091 {
1093
1094 Assert(erh->er_magic == ER_MAGIC);
1095
1096 /* Extract HeapTuple and TupleDesc */
1097 rettup = expanded_record_get_tuple(erh);
1098 Assert(rettup);
1099 retdesc = expanded_record_get_tupdesc(erh);
1100
1101 if (retdesc != RelationGetDescr(trigdata->tg_relation))
1102 {
1103 /* check rowtype compatibility */
1104 tupmap = convert_tuples_by_position(retdesc,
1105 RelationGetDescr(trigdata->tg_relation),
1106 gettext_noop("returned row structure does not match the structure of the triggering table"));
1107 /* it might need conversion */
1108 if (tupmap)
1109 rettup = execute_attr_map_tuple(rettup, tupmap);
1110 /* no need to free map, we're about to return anyway */
1111 }
1112
1113 /*
1114 * Copy tuple to upper executor memory. But if user just did
1115 * "return new" or "return old" without changing anything, there's
1116 * no need to copy; we can return the original tuple (which will
1117 * save a few cycles in trigger.c as well as here).
1118 */
1119 if (rettup != trigdata->tg_newtuple &&
1120 rettup != trigdata->tg_trigtuple)
1121 rettup = SPI_copytuple(rettup);
1122 }
1123 else
1124 {
1125 /* Convert composite datum to a HeapTuple and TupleDesc */
1126 HeapTupleData tmptup;
1127
1128 retdesc = deconstruct_composite_datum(estate.retval, &tmptup);
1129 rettup = &tmptup;
1130
1131 /* check rowtype compatibility */
1132 tupmap = convert_tuples_by_position(retdesc,
1133 RelationGetDescr(trigdata->tg_relation),
1134 gettext_noop("returned row structure does not match the structure of the triggering table"));
1135 /* it might need conversion */
1136 if (tupmap)
1137 rettup = execute_attr_map_tuple(rettup, tupmap);
1138
1139 ReleaseTupleDesc(retdesc);
1140 /* no need to free map, we're about to return anyway */
1141
1142 /* Copy tuple to upper executor memory */
1143 rettup = SPI_copytuple(rettup);
1144 }
1145 }
1146
1147 /*
1148 * Let the instrumentation plugin peek at this function
1149 */
1150 if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1151 ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1152
1153 /* Clean up any leftover temporary memory */
1154 plpgsql_destroy_econtext(&estate);
1155 exec_eval_cleanup(&estate);
1156 /* stmt_mcontext will be destroyed when function's main context is */
1157
1158 /*
1159 * Pop the error context stack
1160 */
1161 error_context_stack = plerrcontext.previous;
1162
1163 /*
1164 * Return the trigger's result
1165 */
1166 return rettup;
1167}
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
ExpandedRecordHeader * make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh, MemoryContext parentcontext)
ExpandedRecordHeader * make_expanded_record_from_tupdesc(TupleDesc tupdesc, MemoryContext parentcontext)
void expanded_record_set_field_internal(ExpandedRecordHeader *erh, int fnumber, Datum newValue, bool isnull, bool expand_external, bool check_constraints)
void expanded_record_set_tuple(ExpandedRecordHeader *erh, HeapTuple tuple, bool copy, bool expand_external)
HeapTuple expanded_record_get_tuple(ExpandedRecordHeader *erh)
#define ER_MAGIC
static TupleDesc expanded_record_get_tupdesc(ExpandedRecordHeader *erh)
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2822
static TupleDesc deconstruct_composite_datum(Datum value, HeapTupleData *tmptup)
Definition: pl_exec.c:7560
#define RelationGetDescr(relation)
Definition: rel.h:540
int SPI_register_trigger_data(TriggerData *tdata)
Definition: spi.c:3364
HeapTuple SPI_copytuple(HeapTuple tuple)
Definition: spi.c:1047
TriggerData * trigdata
Definition: plpgsql.h:1016
Relation tg_relation
Definition: trigger.h:35
TriggerEvent tg_event
Definition: trigger.h:34
HeapTuple tg_newtuple
Definition: trigger.h:37
HeapTuple tg_trigtuple
Definition: trigger.h:36
bool has_generated_stored
Definition: tupdesc.h:46
TupleConstr * constr
Definition: tupdesc.h:141
#define TRIGGER_FIRED_BY_DELETE(event)
Definition: trigger.h:113
#define TRIGGER_FIRED_BEFORE(event)
Definition: trigger.h:128
#define TRIGGER_FIRED_FOR_ROW(event)
Definition: trigger.h:122
#define TRIGGER_FIRED_BY_INSERT(event)
Definition: trigger.h:110
#define TRIGGER_FIRED_BY_UPDATE(event)
Definition: trigger.h:116
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:59
HeapTuple execute_attr_map_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:154
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:219
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
static bool VARATT_IS_EXTERNAL_EXPANDED(const void *PTR)
Definition: varatt.h:389

References PLpgSQL_function::action, ErrorContextCallback::arg, Assert(), ErrorContextCallback::callback, TupleDescData::constr, convert_tuples_by_position(), copy_plpgsql_datums(), PLpgSQL_execstate::datum_context, DatumGetEOHP(), DatumGetPointer(), PLpgSQL_execstate::datums, deconstruct_composite_datum(), elog, ER_MAGIC, ExpandedRecordHeader::er_magic, ereport, PLpgSQL_rec::erh, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, exec_eval_cleanup(), exec_set_found(), exec_toplevel_block(), execute_attr_map_tuple(), expanded_record_get_tupdesc(), expanded_record_get_tuple(), expanded_record_set_field_internal(), expanded_record_set_tuple(), PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, gettext_noop, TupleConstr::has_generated_stored, i, make_expanded_record_from_exprecord(), make_expanded_record_from_tupdesc(), TupleDescData::natts, PLpgSQL_function::new_varno, PLpgSQL_function::old_varno, plpgsql_destroy_econtext(), plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, ErrorContextCallback::previous, RelationGetDescr, ReleaseTupleDesc, PLpgSQL_execstate::retisnull, PLpgSQL_execstate::retisset, PLpgSQL_execstate::rettype, PLpgSQL_execstate::retval, SPI_copytuple(), SPI_register_trigger_data(), TriggerData::tg_event, TriggerData::tg_newtuple, TriggerData::tg_relation, TriggerData::tg_trigtuple, PLpgSQL_execstate::trigdata, TRIGGER_FIRED_BEFORE, TRIGGER_FIRED_BY_DELETE, TRIGGER_FIRED_BY_INSERT, TRIGGER_FIRED_BY_UPDATE, TRIGGER_FIRED_FOR_ROW, TupleDescAttr(), type_is_rowtype(), and VARATT_IS_EXTERNAL_EXPANDED().

Referenced by plpgsql_call_handler().

◆ plpgsql_free_function_memory()

void plpgsql_free_function_memory ( PLpgSQL_function func)

Definition at line 716 of file pl_funcs.c.

717{
718 int i;
719
720 /* Better not call this on an in-use function */
721 Assert(func->cfunc.use_count == 0);
722
723 /* Release plans associated with variable declarations */
724 for (i = 0; i < func->ndatums; i++)
725 {
726 PLpgSQL_datum *d = func->datums[i];
727
728 switch (d->dtype)
729 {
732 {
733 PLpgSQL_var *var = (PLpgSQL_var *) d;
734
735 free_expr(var->default_val, NULL);
737 }
738 break;
740 break;
742 {
743 PLpgSQL_rec *rec = (PLpgSQL_rec *) d;
744
745 free_expr(rec->default_val, NULL);
746 }
747 break;
749 break;
750 default:
751 elog(ERROR, "unrecognized data type: %d", d->dtype);
752 }
753 }
754 func->ndatums = 0;
755
756 /* Release plans in statement tree */
757 free_stmt((PLpgSQL_stmt *) func->action, NULL);
758 func->action = NULL;
759
760 /*
761 * And finally, release all memory except the PLpgSQL_function struct
762 * itself (which has to be kept around because there may be multiple
763 * fn_extra pointers to it).
764 */
765 if (func->fn_cxt)
767 func->fn_cxt = NULL;
768}
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:469
static void free_stmt(PLpgSQL_stmt *stmt, void *context)
Definition: pl_funcs.c:698
static void free_expr(PLpgSQL_expr *expr, void *context)
Definition: pl_funcs.c:706
uint64 use_count
Definition: funccache.h:117
CachedFunction cfunc
Definition: plpgsql.h:960
MemoryContext fn_cxt
Definition: plpgsql.h:966
PLpgSQL_expr * default_val
Definition: plpgsql.h:420

References PLpgSQL_function::action, Assert(), PLpgSQL_function::cfunc, PLpgSQL_var::cursor_explicit_expr, PLpgSQL_function::datums, PLpgSQL_var::default_val, PLpgSQL_rec::default_val, PLpgSQL_datum::dtype, elog, ERROR, PLpgSQL_function::fn_cxt, free_expr(), free_stmt(), i, MemoryContextDelete(), PLpgSQL_function::ndatums, PLPGSQL_DTYPE_PROMISE, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_VAR, and CachedFunction::use_count.

Referenced by plpgsql_delete_callback(), and plpgsql_inline_handler().

◆ plpgsql_getdiag_kindname()

const char * plpgsql_getdiag_kindname ( PLpgSQL_getdiag_kind  kind)

Definition at line 300 of file pl_funcs.c.

301{
302 switch (kind)
303 {
305 return "ROW_COUNT";
307 return "PG_ROUTINE_OID";
309 return "PG_CONTEXT";
311 return "PG_EXCEPTION_CONTEXT";
313 return "PG_EXCEPTION_DETAIL";
315 return "PG_EXCEPTION_HINT";
317 return "RETURNED_SQLSTATE";
319 return "COLUMN_NAME";
321 return "CONSTRAINT_NAME";
323 return "PG_DATATYPE_NAME";
325 return "MESSAGE_TEXT";
327 return "TABLE_NAME";
329 return "SCHEMA_NAME";
330 }
331
332 return "unknown";
333}

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

Referenced by dump_getdiag().

◆ plpgsql_latest_lineno()

int plpgsql_latest_lineno ( yyscan_t  yyscanner)

Definition at line 607 of file pl_scanner.c.

608{
609 return yyextra->cur_line_num;
610}

References yyextra.

Referenced by plpgsql_compile_error_callback().

◆ plpgsql_location_to_lineno()

int plpgsql_location_to_lineno ( int  location,
yyscan_t  yyscanner 
)

Definition at line 573 of file pl_scanner.c.

574{
575 const char *loc;
576
577 if (location < 0 || yyextra->scanorig == NULL)
578 return 0; /* garbage in, garbage out */
579 loc = yyextra->scanorig + location;
580
581 /* be correct, but not fast, if input location goes backwards */
582 if (loc < yyextra->cur_line_start)
583 location_lineno_init(yyscanner);
584
585 while (yyextra->cur_line_end != NULL && loc > yyextra->cur_line_end)
586 {
587 yyextra->cur_line_start = yyextra->cur_line_end + 1;
588 yyextra->cur_line_num++;
589 yyextra->cur_line_end = strchr(yyextra->cur_line_start, '\n');
590 }
591
592 return yyextra->cur_line_num;
593}
static void location_lineno_init(yyscan_t yyscanner)
Definition: pl_scanner.c:597

References plpgsql_yy_extra_type::cur_line_start, location_lineno_init(), plpgsql_yy_extra_type::scanorig, and yyextra.

◆ plpgsql_mark_local_assignment_targets()

void plpgsql_mark_local_assignment_targets ( PLpgSQL_function func)

Definition at line 673 of file pl_funcs.c.

674{
675 Bitmapset *local_dnos;
676
677 /* Function parameters can be treated as local targets at outer level */
678 local_dnos = NULL;
679 for (int i = 0; i < func->fn_nargs; i++)
680 local_dnos = bms_add_member(local_dnos, func->fn_argvarnos[i]);
681 mark_stmt((PLpgSQL_stmt *) func->action, local_dnos);
682 bms_free(local_dnos);
683}
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
static void mark_stmt(PLpgSQL_stmt *stmt, Bitmapset *local_dnos)
Definition: pl_funcs.c:623

References PLpgSQL_function::action, bms_add_member(), bms_free(), PLpgSQL_function::fn_argvarnos, PLpgSQL_function::fn_nargs, i, and mark_stmt().

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_ns_additem()

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

Definition at line 92 of file pl_funcs.c.

93{
94 PLpgSQL_nsitem *nse;
95
96 Assert(name != NULL);
97 /* first item added must be a label */
98 Assert(ns_top != NULL || itemtype == PLPGSQL_NSTYPE_LABEL);
99
100 nse = palloc(offsetof(PLpgSQL_nsitem, name) + strlen(name) + 1);
101 nse->itemtype = itemtype;
102 nse->itemno = itemno;
103 nse->prev = ns_top;
104 strcpy(nse->name, name);
105 ns_top = nse;
106}
static PLpgSQL_nsitem * ns_top
Definition: pl_funcs.c:35
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:470
struct PLpgSQL_nsitem * prev
Definition: plpgsql.h:469
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:462
const char * name

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

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

◆ plpgsql_ns_find_nearest_loop()

PLpgSQL_nsitem * plpgsql_ns_find_nearest_loop ( PLpgSQL_nsitem ns_cur)

Definition at line 214 of file pl_funcs.c.

215{
216 while (ns_cur != NULL)
217 {
218 if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
219 ns_cur->itemno == PLPGSQL_LABEL_LOOP)
220 return ns_cur;
221 ns_cur = ns_cur->prev;
222 }
223
224 return NULL; /* no loop found */
225}

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

◆ plpgsql_ns_init()

void plpgsql_ns_init ( void  )

Definition at line 43 of file pl_funcs.c.

44{
45 ns_top = NULL;
46}

References ns_top.

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_ns_lookup()

PGDLLEXPORT PLpgSQL_nsitem * plpgsql_ns_lookup ( PLpgSQL_nsitem ns_cur,
bool  localmode,
const char *  name1,
const char *  name2,
const char *  name3,
int *  names_used 
)

Definition at line 130 of file pl_funcs.c.

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

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

◆ plpgsql_ns_lookup_label()

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

Definition at line 195 of file pl_funcs.c.

196{
197 while (ns_cur != NULL)
198 {
199 if (ns_cur->itemtype == PLPGSQL_NSTYPE_LABEL &&
200 strcmp(ns_cur->name, name) == 0)
201 return ns_cur;
202 ns_cur = ns_cur->prev;
203 }
204
205 return NULL; /* label not found */
206}

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

◆ plpgsql_ns_pop()

void plpgsql_ns_pop ( void  )

Definition at line 67 of file pl_funcs.c.

68{
69 Assert(ns_top != NULL);
73}

References Assert(), PLpgSQL_nsitem::itemtype, ns_top, PLPGSQL_NSTYPE_LABEL, and PLpgSQL_nsitem::prev.

◆ plpgsql_ns_push()

void plpgsql_ns_push ( const char *  label,
PLpgSQL_label_type  label_type 
)

Definition at line 54 of file pl_funcs.c.

55{
56 if (label == NULL)
57 label = "";
59}
static char * label

References label, plpgsql_ns_additem(), and PLPGSQL_NSTYPE_LABEL.

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_ns_top()

PLpgSQL_nsitem * plpgsql_ns_top ( void  )

◆ plpgsql_parse_cwordrowtype()

PLpgSQL_type * plpgsql_parse_cwordrowtype ( List idents)

Definition at line 1721 of file pl_comp.c.

1722{
1723 Oid classOid;
1724 Oid typOid;
1725 RangeVar *relvar;
1726 TypeName *typName;
1727 MemoryContext oldCxt;
1728
1729 /*
1730 * As above, this is a relation lookup but could be a type lookup if we
1731 * weren't being backwards-compatible about error wording.
1732 */
1733
1734 /* Avoid memory leaks in long-term function context */
1736
1737 /* Look up relation name. Can't lock it - we might not have privileges. */
1738 relvar = makeRangeVarFromNameList(idents);
1739 classOid = RangeVarGetRelid(relvar, NoLock, false);
1740
1741 /* Some relkinds lack type OIDs */
1742 typOid = get_rel_type_id(classOid);
1743 if (!OidIsValid(typOid))
1744 ereport(ERROR,
1745 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1746 errmsg("relation \"%s\" does not have a composite type",
1747 relvar->relname)));
1748
1749 typName = makeTypeNameFromNameList(idents);
1750
1751 MemoryContextSwitchTo(oldCxt);
1752
1753 /* Build and return the row type struct */
1754 return plpgsql_build_datatype(typOid, -1, InvalidOid, typName);
1755}
#define NoLock
Definition: lockdefs.h:34
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:2146
TypeName * makeTypeNameFromNameList(List *names)
Definition: makefuncs.c:531
RangeVar * makeRangeVarFromNameList(const List *names)
Definition: namespace.c:3624
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:98
char * relname
Definition: primnodes.h:83

References ereport, errcode(), errmsg(), ERROR, get_rel_type_id(), InvalidOid, makeRangeVarFromNameList(), makeTypeNameFromNameList(), MemoryContextSwitchTo(), NoLock, OidIsValid, plpgsql_build_datatype(), plpgsql_compile_tmp_cxt, RangeVarGetRelid, and RangeVar::relname.

◆ plpgsql_parse_cwordtype()

PLpgSQL_type * plpgsql_parse_cwordtype ( List idents)

Definition at line 1564 of file pl_comp.c.

1565{
1566 PLpgSQL_type *dtype = NULL;
1567 PLpgSQL_nsitem *nse;
1568 int nnames;
1569 RangeVar *relvar = NULL;
1570 const char *fldname = NULL;
1571 Oid classOid;
1572 HeapTuple attrtup = NULL;
1573 HeapTuple typetup = NULL;
1574 Form_pg_attribute attrStruct;
1575 MemoryContext oldCxt;
1576
1577 /* Avoid memory leaks in the long-term function context */
1579
1580 if (list_length(idents) == 2)
1581 {
1582 /*
1583 * Do a lookup in the current namespace stack
1584 */
1585 nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1586 strVal(linitial(idents)),
1587 strVal(lsecond(idents)),
1588 NULL,
1589 &nnames);
1590
1591 if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1592 {
1593 /* Block-qualified reference to scalar variable. */
1594 dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1595 goto done;
1596 }
1597 else if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_REC &&
1598 nnames == 2)
1599 {
1600 /* Block-qualified reference to record variable. */
1601 dtype = ((PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]))->datatype;
1602 goto done;
1603 }
1604
1605 /*
1606 * First word could also be a table name
1607 */
1608 relvar = makeRangeVar(NULL,
1609 strVal(linitial(idents)),
1610 -1);
1611 fldname = strVal(lsecond(idents));
1612 }
1613 else
1614 {
1615 /*
1616 * We could check for a block-qualified reference to a field of a
1617 * record variable, but %TYPE is documented as applying to variables,
1618 * not fields of variables. Things would get rather ambiguous if we
1619 * allowed either interpretation.
1620 */
1621 List *rvnames;
1622
1623 Assert(list_length(idents) > 2);
1624 rvnames = list_delete_last(list_copy(idents));
1625 relvar = makeRangeVarFromNameList(rvnames);
1626 fldname = strVal(llast(idents));
1627 }
1628
1629 /* Look up relation name. Can't lock it - we might not have privileges. */
1630 classOid = RangeVarGetRelid(relvar, NoLock, false);
1631
1632 /*
1633 * Fetch the named table field and its type
1634 */
1635 attrtup = SearchSysCacheAttName(classOid, fldname);
1636 if (!HeapTupleIsValid(attrtup))
1637 ereport(ERROR,
1638 (errcode(ERRCODE_UNDEFINED_COLUMN),
1639 errmsg("column \"%s\" of relation \"%s\" does not exist",
1640 fldname, relvar->relname)));
1641 attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1642
1643 typetup = SearchSysCache1(TYPEOID,
1644 ObjectIdGetDatum(attrStruct->atttypid));
1645 if (!HeapTupleIsValid(typetup))
1646 elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1647
1648 /*
1649 * Found that - build a compiler type struct in the caller's cxt and
1650 * return it. Note that we treat the type as being found-by-OID; no
1651 * attempt to re-look-up the type name will happen during invalidations.
1652 */
1653 MemoryContextSwitchTo(oldCxt);
1654 dtype = build_datatype(typetup,
1655 attrStruct->atttypmod,
1656 attrStruct->attcollation,
1657 NULL);
1659
1660done:
1661 if (HeapTupleIsValid(attrtup))
1662 ReleaseSysCache(attrtup);
1663 if (HeapTupleIsValid(typetup))
1664 ReleaseSysCache(typetup);
1665
1666 MemoryContextSwitchTo(oldCxt);
1667 return dtype;
1668}
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
List * list_copy(const List *oldlist)
Definition: list.c:1573
List * list_delete_last(List *list)
Definition: list.c:957
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:473
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
#define llast(l)
Definition: pg_list.h:198
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:130
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:81
Definition: pg_list.h:54
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:475
#define strVal(v)
Definition: value.h:82

References Assert(), build_datatype(), elog, ereport, errcode(), errmsg(), ERROR, GETSTRUCT(), HeapTupleIsValid, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, linitial, list_copy(), list_delete_last(), list_length(), llast, lsecond, makeRangeVar(), makeRangeVarFromNameList(), MemoryContextSwitchTo(), NoLock, ObjectIdGetDatum(), plpgsql_compile_tmp_cxt, plpgsql_Datums, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, RangeVarGetRelid, ReleaseSysCache(), RangeVar::relname, SearchSysCache1(), SearchSysCacheAttName(), and strVal.

◆ plpgsql_parse_dblword()

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

Definition at line 1358 of file pl_comp.c.

1360{
1361 PLpgSQL_nsitem *ns;
1362 List *idents;
1363 int nnames;
1364
1365 idents = list_make2(makeString(word1),
1366 makeString(word2));
1367
1368 /*
1369 * We should do nothing in DECLARE sections. In SQL expressions, we
1370 * really only need to make sure that RECFIELD datums are created when
1371 * needed. In all the cases handled by this function, returning a T_DATUM
1372 * with a two-word idents string is the right thing.
1373 */
1375 {
1376 /*
1377 * Do a lookup in the current namespace stack
1378 */
1379 ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1380 word1, word2, NULL,
1381 &nnames);
1382 if (ns != NULL)
1383 {
1384 switch (ns->itemtype)
1385 {
1386 case PLPGSQL_NSTYPE_VAR:
1387 /* Block-qualified reference to scalar variable. */
1388 wdatum->datum = plpgsql_Datums[ns->itemno];
1389 wdatum->ident = NULL;
1390 wdatum->quoted = false; /* not used */
1391 wdatum->idents = idents;
1392 return true;
1393
1394 case PLPGSQL_NSTYPE_REC:
1395 if (nnames == 1)
1396 {
1397 /*
1398 * First word is a record name, so second word could
1399 * be a field in this record. We build a RECFIELD
1400 * datum whether it is or not --- any error will be
1401 * detected later.
1402 */
1403 PLpgSQL_rec *rec;
1404 PLpgSQL_recfield *new;
1405
1406 rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1407 new = plpgsql_build_recfield(rec, word2);
1408
1409 wdatum->datum = (PLpgSQL_datum *) new;
1410 }
1411 else
1412 {
1413 /* Block-qualified reference to record variable. */
1414 wdatum->datum = plpgsql_Datums[ns->itemno];
1415 }
1416 wdatum->ident = NULL;
1417 wdatum->quoted = false; /* not used */
1418 wdatum->idents = idents;
1419 return true;
1420
1421 default:
1422 break;
1423 }
1424 }
1425 }
1426
1427 /* Nothing found */
1428 cword->idents = idents;
1429 return false;
1430}
#define list_make2(x1, x2)
Definition: pg_list.h:214
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
Definition: pl_comp.c:1924
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:26
List * idents
Definition: plpgsql.h:1163
List * idents
Definition: plpgsql.h:1171
char * ident
Definition: plpgsql.h:1169
PLpgSQL_datum * datum
Definition: plpgsql.h:1168
bool quoted
Definition: plpgsql.h:1170
String * makeString(char *str)
Definition: value.c:63

References PLwdatum::datum, PLwdatum::ident, IDENTIFIER_LOOKUP_DECLARE, PLcword::idents, PLwdatum::idents, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, list_make2, makeString(), plpgsql_build_recfield(), plpgsql_Datums, plpgsql_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, and PLwdatum::quoted.

Referenced by plpgsql_yylex().

◆ plpgsql_parse_err_condition()

PLpgSQL_condition * plpgsql_parse_err_condition ( char *  condname)

Definition at line 2174 of file pl_comp.c.

2175{
2176 int i;
2177 PLpgSQL_condition *new;
2178 PLpgSQL_condition *prev;
2179
2180 /*
2181 * XXX Eventually we will want to look for user-defined exception names
2182 * here.
2183 */
2184
2185 if (strcmp(condname, "others") == 0)
2186 {
2187 new = palloc(sizeof(PLpgSQL_condition));
2188 new->sqlerrstate = PLPGSQL_OTHERS;
2189 new->condname = condname;
2190 new->next = NULL;
2191 return new;
2192 }
2193
2194 prev = NULL;
2195 for (i = 0; exception_label_map[i].label != NULL; i++)
2196 {
2197 if (strcmp(condname, exception_label_map[i].label) == 0)
2198 {
2199 new = palloc(sizeof(PLpgSQL_condition));
2200 new->sqlerrstate = exception_label_map[i].sqlerrstate;
2201 new->condname = condname;
2202 new->next = prev;
2203 prev = new;
2204 }
2205 }
2206
2207 if (!prev)
2208 ereport(ERROR,
2209 (errcode(ERRCODE_UNDEFINED_OBJECT),
2210 errmsg("unrecognized exception condition \"%s\"",
2211 condname)));
2212
2213 return prev;
2214}
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:65
#define PLPGSQL_OTHERS
Definition: plpgsql.h:500
const char * label
Definition: pl_comp.c:61

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

◆ plpgsql_parse_tripword()

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

Definition at line 1439 of file pl_comp.c.

1441{
1442 PLpgSQL_nsitem *ns;
1443 List *idents;
1444 int nnames;
1445
1446 /*
1447 * We should do nothing in DECLARE sections. In SQL expressions, we need
1448 * to make sure that RECFIELD datums are created when needed, and we need
1449 * to be careful about how many names are reported as belonging to the
1450 * T_DATUM: the third word could be a sub-field reference, which we don't
1451 * care about here.
1452 */
1454 {
1455 /*
1456 * Do a lookup in the current namespace stack. Must find a record
1457 * reference, else ignore.
1458 */
1459 ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1460 word1, word2, word3,
1461 &nnames);
1462 if (ns != NULL)
1463 {
1464 switch (ns->itemtype)
1465 {
1466 case PLPGSQL_NSTYPE_REC:
1467 {
1468 PLpgSQL_rec *rec;
1469 PLpgSQL_recfield *new;
1470
1471 rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1472 if (nnames == 1)
1473 {
1474 /*
1475 * First word is a record name, so second word
1476 * could be a field in this record (and the third,
1477 * a sub-field). We build a RECFIELD datum
1478 * whether it is or not --- any error will be
1479 * detected later.
1480 */
1481 new = plpgsql_build_recfield(rec, word2);
1482 idents = list_make2(makeString(word1),
1483 makeString(word2));
1484 }
1485 else
1486 {
1487 /* Block-qualified reference to record variable. */
1488 new = plpgsql_build_recfield(rec, word3);
1489 idents = list_make3(makeString(word1),
1490 makeString(word2),
1491 makeString(word3));
1492 }
1493 wdatum->datum = (PLpgSQL_datum *) new;
1494 wdatum->ident = NULL;
1495 wdatum->quoted = false; /* not used */
1496 wdatum->idents = idents;
1497 return true;
1498 }
1499
1500 default:
1501 break;
1502 }
1503 }
1504 }
1505
1506 /* Nothing found */
1507 idents = list_make3(makeString(word1),
1508 makeString(word2),
1509 makeString(word3));
1510 cword->idents = idents;
1511 return false;
1512}
#define list_make3(x1, x2, x3)
Definition: pg_list.h:216

References PLwdatum::datum, PLwdatum::ident, IDENTIFIER_LOOKUP_DECLARE, PLcword::idents, PLwdatum::idents, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, list_make2, list_make3, makeString(), plpgsql_build_recfield(), plpgsql_Datums, plpgsql_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, and PLwdatum::quoted.

Referenced by plpgsql_yylex().

◆ plpgsql_parse_word()

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

Definition at line 1303 of file pl_comp.c.

1305{
1306 PLpgSQL_nsitem *ns;
1307
1308 /*
1309 * We should not lookup variables in DECLARE sections. In SQL
1310 * expressions, there's no need to do so either --- lookup will happen
1311 * when the expression is compiled.
1312 */
1314 {
1315 /*
1316 * Do a lookup in the current namespace stack
1317 */
1318 ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1319 word1, NULL, NULL,
1320 NULL);
1321
1322 if (ns != NULL)
1323 {
1324 switch (ns->itemtype)
1325 {
1326 case PLPGSQL_NSTYPE_VAR:
1327 case PLPGSQL_NSTYPE_REC:
1328 wdatum->datum = plpgsql_Datums[ns->itemno];
1329 wdatum->ident = word1;
1330 wdatum->quoted = (yytxt[0] == '"');
1331 wdatum->idents = NIL;
1332 return true;
1333
1334 default:
1335 /* plpgsql_ns_lookup should never return anything else */
1336 elog(ERROR, "unrecognized plpgsql itemtype: %d",
1337 ns->itemtype);
1338 }
1339 }
1340 }
1341
1342 /*
1343 * Nothing found - up to now it's a word without any special meaning for
1344 * us.
1345 */
1346 word->ident = word1;
1347 word->quoted = (yytxt[0] == '"');
1348 return false;
1349}
#define NIL
Definition: pg_list.h:68
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
Definition: regcomp.c:1476
Definition: zic.c:304

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

Referenced by plpgsql_yylex().

◆ plpgsql_parse_wordrowtype()

PLpgSQL_type * plpgsql_parse_wordrowtype ( char *  ident)

Definition at line 1676 of file pl_comp.c.

1677{
1678 Oid classOid;
1679 Oid typOid;
1680 TypeName *typName;
1681 MemoryContext oldCxt;
1682
1683 /* Avoid memory leaks in long-term function context */
1685
1686 /*
1687 * Look up the relation. Note that because relation rowtypes have the
1688 * same names as their relations, this could be handled as a type lookup
1689 * equally well; we use the relation lookup code path only because the
1690 * errors thrown here have traditionally referred to relations not types.
1691 * But we'll make a TypeName in case we have to do re-look-up of the type.
1692 */
1693 classOid = RelnameGetRelid(ident);
1694 if (!OidIsValid(classOid))
1695 ereport(ERROR,
1697 errmsg("relation \"%s\" does not exist", ident)));
1698
1699 /* Some relkinds lack type OIDs */
1700 typOid = get_rel_type_id(classOid);
1701 if (!OidIsValid(typOid))
1702 ereport(ERROR,
1703 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1704 errmsg("relation \"%s\" does not have a composite type",
1705 ident)));
1706
1707 typName = makeTypeName(ident);
1708
1709 MemoryContextSwitchTo(oldCxt);
1710
1711 /* Build and return the row type struct */
1712 return plpgsql_build_datatype(typOid, -1, InvalidOid, typName);
1713}
#define ident
Definition: indent_codes.h:47
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:519
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:884
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:79

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

◆ plpgsql_parse_wordtype()

PLpgSQL_type * plpgsql_parse_wordtype ( char *  ident)

Definition at line 1523 of file pl_comp.c.

1524{
1525 PLpgSQL_nsitem *nse;
1526
1527 /*
1528 * Do a lookup in the current namespace stack
1529 */
1530 nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1531 ident, NULL, NULL,
1532 NULL);
1533
1534 if (nse != NULL)
1535 {
1536 switch (nse->itemtype)
1537 {
1538 case PLPGSQL_NSTYPE_VAR:
1539 return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1540 case PLPGSQL_NSTYPE_REC:
1541 return ((PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]))->datatype;
1542 default:
1543 break;
1544 }
1545 }
1546
1547 /* No match, complain */
1548 ereport(ERROR,
1549 (errcode(ERRCODE_UNDEFINED_OBJECT),
1550 errmsg("variable \"%s\" does not exist", ident)));
1551 return NULL; /* keep compiler quiet */
1552}

References ereport, errcode(), errmsg(), ERROR, ident, PLpgSQL_nsitem::itemno, PLpgSQL_nsitem::itemtype, plpgsql_Datums, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, and PLPGSQL_NSTYPE_VAR.

◆ plpgsql_parser_setup()

PGDLLEXPORT void plpgsql_parser_setup ( struct ParseState pstate,
PLpgSQL_expr expr 
)

Definition at line 989 of file pl_comp.c.

990{
994 /* no need to use p_coerce_param_hook */
995 pstate->p_ref_hook_state = expr;
996}
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1060
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1002
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1016
void * p_ref_hook_state
Definition: parse_node.h:242
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:240
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:238
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:239

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

◆ plpgsql_peek()

int plpgsql_peek ( yyscan_t  yyscanner)

Definition at line 452 of file pl_scanner.c.

453{
454 int tok1;
455 TokenAuxData aux1;
456
457 tok1 = internal_yylex(&aux1, yyscanner);
458 push_back_token(tok1, &aux1, yyscanner);
459 return tok1;
460}
static void push_back_token(int token, TokenAuxData *auxdata, yyscan_t yyscanner)
Definition: pl_scanner.c:385
static int internal_yylex(TokenAuxData *auxdata, yyscan_t yyscanner)
Definition: pl_scanner.c:339

References internal_yylex(), and push_back_token().

◆ plpgsql_peek2()

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

Definition at line 471 of file pl_scanner.c.

472{
473 int tok1,
474 tok2;
475 TokenAuxData aux1,
476 aux2;
477
478 tok1 = internal_yylex(&aux1, yyscanner);
479 tok2 = internal_yylex(&aux2, yyscanner);
480
481 *tok1_p = tok1;
482 if (tok1_loc)
483 *tok1_loc = aux1.lloc;
484 *tok2_p = tok2;
485 if (tok2_loc)
486 *tok2_loc = aux2.lloc;
487
488 push_back_token(tok2, &aux2, yyscanner);
489 push_back_token(tok1, &aux1, yyscanner);
490}
YYLTYPE lloc
Definition: pl_scanner.c:94

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

◆ plpgsql_push_back_token()

void plpgsql_push_back_token ( int  token,
union YYSTYPE yylvalp,
YYLTYPE yyllocp,
yyscan_t  yyscanner 
)

Definition at line 401 of file pl_scanner.c.

402{
403 TokenAuxData auxdata;
404
405 auxdata.lval = *yylvalp;
406 auxdata.lloc = *yyllocp;
407 auxdata.leng = yyextra->plpgsql_yyleng;
408 push_back_token(token, &auxdata, yyscanner);
409}
YYSTYPE lval
Definition: pl_scanner.c:93

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

◆ plpgsql_recognize_err_condition()

PGDLLEXPORT int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2138 of file pl_comp.c.

2139{
2140 int i;
2141
2142 if (allow_sqlstate)
2143 {
2144 if (strlen(condname) == 5 &&
2145 strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2146 return MAKE_SQLSTATE(condname[0],
2147 condname[1],
2148 condname[2],
2149 condname[3],
2150 condname[4]);
2151 }
2152
2153 for (i = 0; exception_label_map[i].label != NULL; i++)
2154 {
2155 if (strcmp(condname, exception_label_map[i].label) == 0)
2157 }
2158
2159 ereport(ERROR,
2160 (errcode(ERRCODE_UNDEFINED_OBJECT),
2161 errmsg("unrecognized exception condition \"%s\"",
2162 condname)));
2163 return 0; /* keep compiler quiet */
2164}
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:56

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

Referenced by exec_stmt_raise().

◆ plpgsql_scanner_errposition()

int plpgsql_scanner_errposition ( int  location,
yyscan_t  yyscanner 
)

Definition at line 504 of file pl_scanner.c.

505{
506 int pos;
507
508 if (location < 0 || yyextra->scanorig == NULL)
509 return 0; /* no-op if location is unknown */
510
511 /* Convert byte offset to character number */
512 pos = pg_mbstrlen_with_len(yyextra->scanorig, location) + 1;
513 /* And pass it to the ereport mechanism */
514 (void) internalerrposition(pos);
515 /* Also pass the function body string */
516 return internalerrquery(yyextra->scanorig);
517}
int internalerrquery(const char *query)
Definition: elog.c:1507
int internalerrposition(int cursorpos)
Definition: elog.c:1487
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:1058

References internalerrposition(), internalerrquery(), pg_mbstrlen_with_len(), plpgsql_yy_extra_type::scanorig, and yyextra.

Referenced by plpgsql_yyerror().

◆ plpgsql_scanner_finish()

void plpgsql_scanner_finish ( yyscan_t  yyscanner)

Definition at line 653 of file pl_scanner.c.

654{
655 /* release storage */
656 scanner_finish(yyscanner);
657}
void scanner_finish(core_yyscan_t yyscanner)
Definition: scan.l:1291

References scanner_finish().

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_scanner_init()

yyscan_t plpgsql_scanner_init ( const char *  str)

Definition at line 621 of file pl_scanner.c.

622{
623 yyscan_t yyscanner;
625
626 /* Start up the core scanner */
627 yyscanner = scanner_init(str, (core_yy_extra_type *) yyext,
628 &ReservedPLKeywords, ReservedPLKeywordTokens);
629
630 /*
631 * scanorig points to the original string, which unlike the scanner's
632 * scanbuf won't be modified on-the-fly by flex. Notice that although
633 * yytext points into scanbuf, we rely on being able to apply locations
634 * (offsets from string start) to scanorig as well.
635 */
636 yyext->scanorig = str;
637
638 /* Other setup */
640 yyext->plpgsql_yytoken = 0;
641
642 yyext->num_pushbacks = 0;
643
644 location_lineno_init(yyscanner);
645
646 return yyscanner;
647}
#define palloc0_object(type)
Definition: fe_memutils.h:75
const char * str
static const uint16 ReservedPLKeywordTokens[]
Definition: pl_scanner.c:66
core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, const ScanKeywordList *keywordlist, const uint16 *keyword_tokens)
Definition: scan.l:1249
const char * scanorig
Definition: pl_scanner.c:109

References IDENTIFIER_LOOKUP_NORMAL, location_lineno_init(), plpgsql_yy_extra_type::num_pushbacks, palloc0_object, plpgsql_IdentifierLookup, plpgsql_yy_extra_type::plpgsql_yytoken, ReservedPLKeywordTokens, scanner_init(), plpgsql_yy_extra_type::scanorig, and str.

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_stmt_typename()

PGDLLEXPORT const char * plpgsql_stmt_typename ( PLpgSQL_stmt stmt)

Definition at line 232 of file pl_funcs.c.

233{
234 switch (stmt->cmd_type)
235 {
237 return _("statement block");
239 return _("assignment");
240 case PLPGSQL_STMT_IF:
241 return "IF";
243 return "CASE";
245 return "LOOP";
247 return "WHILE";
249 return _("FOR with integer loop variable");
251 return _("FOR over SELECT rows");
253 return _("FOR over cursor");
255 return _("FOREACH over array");
257 return ((PLpgSQL_stmt_exit *) stmt)->is_exit ? "EXIT" : "CONTINUE";
259 return "RETURN";
261 return "RETURN NEXT";
263 return "RETURN QUERY";
265 return "RAISE";
267 return "ASSERT";
269 return _("SQL statement");
271 return "EXECUTE";
273 return _("FOR over EXECUTE statement");
275 return ((PLpgSQL_stmt_getdiag *) stmt)->is_stacked ?
276 "GET STACKED DIAGNOSTICS" : "GET DIAGNOSTICS";
278 return "OPEN";
280 return ((PLpgSQL_stmt_fetch *) stmt)->is_move ? "MOVE" : "FETCH";
282 return "CLOSE";
284 return "PERFORM";
286 return ((PLpgSQL_stmt_call *) stmt)->is_call ? "CALL" : "DO";
288 return "COMMIT";
290 return "ROLLBACK";
291 }
292
293 return "unknown";
294}
#define _(x)
Definition: elog.c:91
#define stmt
Definition: indent_codes.h:59

References _, PLPGSQL_STMT_ASSERT, PLPGSQL_STMT_ASSIGN, PLPGSQL_STMT_BLOCK, PLPGSQL_STMT_CALL, PLPGSQL_STMT_CASE, PLPGSQL_STMT_CLOSE, PLPGSQL_STMT_COMMIT, 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, PLPGSQL_STMT_ROLLBACK, PLPGSQL_STMT_WHILE, and stmt.

Referenced by plpgsql_exec_error_callback().

◆ plpgsql_subxact_cb()

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

Definition at line 8766 of file pl_exec.c.

8768{
8769 if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
8770 {
8771 while (simple_econtext_stack != NULL &&
8773 {
8775
8777 (event == SUBXACT_EVENT_COMMIT_SUB));
8781 }
8782 }
8783}
static int32 next
Definition: blutils.c:224
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:416
void pfree(void *pointer)
Definition: mcxt.c:1594
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:92
struct SimpleEcontextStackEntry * next
Definition: pl_exec.c:88
ExprContext * stack_econtext
Definition: pl_exec.c:86
SubTransactionId xact_subxid
Definition: pl_exec.c:87
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:145
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:144

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

Referenced by _PG_init(), and plpgsql_inline_handler().

◆ plpgsql_token_is_unreserved_keyword()

bool plpgsql_token_is_unreserved_keyword ( int  token)

Definition at line 418 of file pl_scanner.c.

419{
420 int i;
421
422 for (i = 0; i < lengthof(UnreservedPLKeywordTokens); i++)
423 {
425 return true;
426 }
427 return false;
428}
#define lengthof(array)
Definition: c.h:788
static const uint16 UnreservedPLKeywordTokens[]
Definition: pl_scanner.c:70

References i, lengthof, and UnreservedPLKeywordTokens.

◆ plpgsql_token_length()

int plpgsql_token_length ( yyscan_t  yyscanner)

Definition at line 327 of file pl_scanner.c.

328{
329 return yyextra->plpgsql_yyleng;
330}

References yyextra.

◆ plpgsql_xact_cb()

void plpgsql_xact_cb ( XactEvent  event,
void *  arg 
)

Definition at line 8724 of file pl_exec.c.

8725{
8726 /*
8727 * If we are doing a clean transaction shutdown, free the EState and tell
8728 * the resowner to release whatever plancache references it has, so that
8729 * all remaining resources will be released correctly. (We don't need to
8730 * actually delete the resowner here; deletion of the
8731 * TopTransactionResourceOwner will take care of that.)
8732 *
8733 * In an abort, we expect the regular abort recovery procedures to release
8734 * everything of interest, so just clear our pointers.
8735 */
8736 if (event == XACT_EVENT_COMMIT ||
8737 event == XACT_EVENT_PARALLEL_COMMIT ||
8738 event == XACT_EVENT_PREPARE)
8739 {
8740 simple_econtext_stack = NULL;
8741
8748 }
8749 else if (event == XACT_EVENT_ABORT ||
8751 {
8752 simple_econtext_stack = NULL;
8755 }
8756}
void FreeExecutorState(EState *estate)
Definition: execUtils.c:192
static ResourceOwner shared_simple_eval_resowner
Definition: pl_exec.c:102
static EState * shared_simple_eval_estate
Definition: pl_exec.c:91
void ReleaseAllPlanCacheRefsInOwner(ResourceOwner owner)
Definition: plancache.c:2370
@ XACT_EVENT_COMMIT
Definition: xact.h:129
@ XACT_EVENT_PARALLEL_COMMIT
Definition: xact.h:130
@ XACT_EVENT_ABORT
Definition: xact.h:131
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:132
@ XACT_EVENT_PREPARE
Definition: xact.h:133

References FreeExecutorState(), ReleaseAllPlanCacheRefsInOwner(), shared_simple_eval_estate, shared_simple_eval_resowner, simple_econtext_stack, XACT_EVENT_ABORT, XACT_EVENT_COMMIT, XACT_EVENT_PARALLEL_ABORT, XACT_EVENT_PARALLEL_COMMIT, and XACT_EVENT_PREPARE.

Referenced by _PG_init().

◆ plpgsql_yyerror()

pg_noreturn void plpgsql_yyerror ( YYLTYPE yyllocp,
PLpgSQL_stmt_block **  plpgsql_parse_result_p,
yyscan_t  yyscanner,
const char *  message 
)

Definition at line 534 of file pl_scanner.c.

535{
536 char *yytext = yyextra->core_yy_extra.scanbuf + *yyllocp;
537
538 if (*yytext == '\0')
539 {
541 (errcode(ERRCODE_SYNTAX_ERROR),
542 /* translator: %s is typically the translation of "syntax error" */
543 errmsg("%s at end of input", _(message)),
544 plpgsql_scanner_errposition(*yyllocp, yyscanner)));
545 }
546 else
547 {
548 /*
549 * If we have done any lookahead then flex will have restored the
550 * character after the end-of-token. Zap it again so that we report
551 * only the single token here. This modifies scanbuf but we no longer
552 * care about that.
553 */
554 yytext[yyextra->plpgsql_yyleng] = '\0';
555
557 (errcode(ERRCODE_SYNTAX_ERROR),
558 /* translator: first %s is typically the translation of "syntax error" */
559 errmsg("%s at or near \"%s\"", _(message), yytext),
560 plpgsql_scanner_errposition(*yyllocp, yyscanner)));
561 }
562}
int plpgsql_scanner_errposition(int location, yyscan_t yyscanner)
Definition: pl_scanner.c:504

References _, ereport, errcode(), errmsg(), ERROR, plpgsql_scanner_errposition(), and yyextra.

◆ plpgsql_yylex()

int plpgsql_yylex ( union YYSTYPE yylvalp,
YYLTYPE yyllocp,
yyscan_t  yyscanner 
)

Definition at line 160 of file pl_scanner.c.

161{
162 int tok1;
163 TokenAuxData aux1;
164 int kwnum;
165
166 tok1 = internal_yylex(&aux1, yyscanner);
167 if (tok1 == IDENT || tok1 == PARAM)
168 {
169 int tok2;
170 TokenAuxData aux2;
171
172 tok2 = internal_yylex(&aux2, yyscanner);
173 if (tok2 == '.')
174 {
175 int tok3;
176 TokenAuxData aux3;
177
178 tok3 = internal_yylex(&aux3, yyscanner);
179 if (tok3 == IDENT)
180 {
181 int tok4;
182 TokenAuxData aux4;
183
184 tok4 = internal_yylex(&aux4, yyscanner);
185 if (tok4 == '.')
186 {
187 int tok5;
188 TokenAuxData aux5;
189
190 tok5 = internal_yylex(&aux5, yyscanner);
191 if (tok5 == IDENT)
192 {
193 if (plpgsql_parse_tripword(aux1.lval.str,
194 aux3.lval.str,
195 aux5.lval.str,
196 &aux1.lval.wdatum,
197 &aux1.lval.cword))
198 tok1 = T_DATUM;
199 else
200 tok1 = T_CWORD;
201 /* Adjust token length to include A.B.C */
202 aux1.leng = aux5.lloc - aux1.lloc + aux5.leng;
203 }
204 else
205 {
206 /* not A.B.C, so just process A.B */
207 push_back_token(tok5, &aux5, yyscanner);
208 push_back_token(tok4, &aux4, yyscanner);
209 if (plpgsql_parse_dblword(aux1.lval.str,
210 aux3.lval.str,
211 &aux1.lval.wdatum,
212 &aux1.lval.cword))
213 tok1 = T_DATUM;
214 else
215 tok1 = T_CWORD;
216 /* Adjust token length to include A.B */
217 aux1.leng = aux3.lloc - aux1.lloc + aux3.leng;
218 }
219 }
220 else
221 {
222 /* not A.B.C, so just process A.B */
223 push_back_token(tok4, &aux4, yyscanner);
224 if (plpgsql_parse_dblword(aux1.lval.str,
225 aux3.lval.str,
226 &aux1.lval.wdatum,
227 &aux1.lval.cword))
228 tok1 = T_DATUM;
229 else
230 tok1 = T_CWORD;
231 /* Adjust token length to include A.B */
232 aux1.leng = aux3.lloc - aux1.lloc + aux3.leng;
233 }
234 }
235 else
236 {
237 /* not A.B, so just process A */
238 push_back_token(tok3, &aux3, yyscanner);
239 push_back_token(tok2, &aux2, yyscanner);
240 if (plpgsql_parse_word(aux1.lval.str,
241 yyextra->core_yy_extra.scanbuf + aux1.lloc,
242 true,
243 &aux1.lval.wdatum,
244 &aux1.lval.word))
245 tok1 = T_DATUM;
246 else if (!aux1.lval.word.quoted &&
247 (kwnum = ScanKeywordLookup(aux1.lval.word.ident,
248 &UnreservedPLKeywords)) >= 0)
249 {
250 aux1.lval.keyword = GetScanKeyword(kwnum,
251 &UnreservedPLKeywords);
252 tok1 = UnreservedPLKeywordTokens[kwnum];
253 }
254 else
255 tok1 = T_WORD;
256 }
257 }
258 else
259 {
260 /* not A.B, so just process A */
261 push_back_token(tok2, &aux2, yyscanner);
262
263 /*
264 * See if it matches a variable name, except in the context where
265 * we are at start of statement and the next token isn't
266 * assignment or '['. In that case, it couldn't validly be a
267 * variable name, and skipping the lookup allows variable names to
268 * be used that would conflict with plpgsql or core keywords that
269 * introduce statements (e.g., "comment"). Without this special
270 * logic, every statement-introducing keyword would effectively be
271 * reserved in PL/pgSQL, which would be unpleasant.
272 *
273 * If it isn't a variable name, try to match against unreserved
274 * plpgsql keywords. If not one of those either, it's T_WORD.
275 *
276 * Note: we must call plpgsql_parse_word even if we don't want to
277 * do variable lookup, because it sets up aux1.lval.word for the
278 * non-variable cases.
279 */
280 if (plpgsql_parse_word(aux1.lval.str,
281 yyextra->core_yy_extra.scanbuf + aux1.lloc,
282 (!AT_STMT_START(yyextra->plpgsql_yytoken) ||
283 (tok2 == '=' || tok2 == COLON_EQUALS ||
284 tok2 == '[')),
285 &aux1.lval.wdatum,
286 &aux1.lval.word))
287 tok1 = T_DATUM;
288 else if (!aux1.lval.word.quoted &&
289 (kwnum = ScanKeywordLookup(aux1.lval.word.ident,
290 &UnreservedPLKeywords)) >= 0)
291 {
292 aux1.lval.keyword = GetScanKeyword(kwnum,
293 &UnreservedPLKeywords);
294 tok1 = UnreservedPLKeywordTokens[kwnum];
295 }
296 else
297 tok1 = T_WORD;
298 }
299 }
300 else
301 {
302 /*
303 * Not a potential plpgsql variable name, just return the data.
304 *
305 * Note that we also come through here if the grammar pushed back a
306 * T_DATUM, T_CWORD, T_WORD, or unreserved-keyword token returned by a
307 * previous lookup cycle; thus, pushbacks do not incur extra lookup
308 * work, since we'll never do the above code twice for the same token.
309 * This property also makes it safe to rely on the old value of
310 * plpgsql_yytoken in the is-this-start-of-statement test above.
311 */
312 }
313
314 *yylvalp = aux1.lval;
315 *yyllocp = aux1.lloc;
316 yyextra->plpgsql_yyleng = aux1.leng;
317 yyextra->plpgsql_yytoken = tok1;
318 return tok1;
319}
int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords)
Definition: kwlookup.c:38
static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)
Definition: kwlookup.h:39
bool plpgsql_parse_dblword(char *word1, char *word2, PLwdatum *wdatum, PLcword *cword)
Definition: pl_comp.c:1358
bool plpgsql_parse_word(char *word1, const char *yytxt, bool lookup, PLwdatum *wdatum, PLword *word)
Definition: pl_comp.c:1303
bool plpgsql_parse_tripword(char *word1, char *word2, char *word3, PLwdatum *wdatum, PLcword *cword)
Definition: pl_comp.c:1439
#define AT_STMT_START(prev_token)
Definition: pl_scanner.c:82

References AT_STMT_START, GetScanKeyword(), internal_yylex(), TokenAuxData::leng, TokenAuxData::lloc, TokenAuxData::lval, plpgsql_parse_dblword(), plpgsql_parse_tripword(), plpgsql_parse_word(), push_back_token(), ScanKeywordLookup(), UnreservedPLKeywordTokens, and yyextra.

◆ plpgsql_yyparse()

int plpgsql_yyparse ( PLpgSQL_stmt_block **  plpgsql_parse_result_p,
yyscan_t  yyscanner 
)

Variable Documentation

◆ plpgsql_check_asserts

bool plpgsql_check_asserts
extern

Definition at line 51 of file pl_handler.c.

Referenced by _PG_init(), and exec_stmt_assert().

◆ plpgsql_check_syntax

bool plpgsql_check_syntax
extern

Definition at line 48 of file pl_comp.c.

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_compile_tmp_cxt

◆ plpgsql_curr_compile

PLpgSQL_function* plpgsql_curr_compile
extern

Definition at line 50 of file pl_comp.c.

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_Datums

◆ plpgsql_DumpExecTree

bool plpgsql_DumpExecTree
extern

Definition at line 47 of file pl_comp.c.

Referenced by plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_error_funcname

char* plpgsql_error_funcname
extern

◆ plpgsql_extra_errors

int plpgsql_extra_errors
extern

◆ plpgsql_extra_warnings

int plpgsql_extra_warnings
extern

◆ plpgsql_IdentifierLookup

IdentifierLookup plpgsql_IdentifierLookup
extern

◆ plpgsql_nDatums

int plpgsql_nDatums
extern

◆ plpgsql_plugin_ptr

◆ plpgsql_print_strict_params

bool plpgsql_print_strict_params
extern

Definition at line 49 of file pl_handler.c.

Referenced by _PG_init(), plpgsql_compile_callback(), and plpgsql_compile_inline().

◆ plpgsql_variable_conflict

int plpgsql_variable_conflict
extern

Definition at line 47 of file pl_handler.c.

Referenced by _PG_init(), plpgsql_compile_callback(), and plpgsql_compile_inline().