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/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_arrayelem
 
struct  PLpgSQL_nsitem
 
struct  PLpgSQL_stmt
 
struct  PLpgSQL_condition
 
struct  PLpgSQL_exception_block
 
struct  PLpgSQL_exception
 
struct  PLpgSQL_stmt_block
 
struct  PLpgSQL_stmt_assign
 
struct  PLpgSQL_stmt_perform
 
struct  PLpgSQL_stmt_call
 
struct  PLpgSQL_stmt_commit
 
struct  PLpgSQL_stmt_rollback
 
struct  PLpgSQL_stmt_set
 
struct  PLpgSQL_diag_item
 
struct  PLpgSQL_stmt_getdiag
 
struct  PLpgSQL_stmt_if
 
struct  PLpgSQL_if_elsif
 
struct  PLpgSQL_stmt_case
 
struct  PLpgSQL_case_when
 
struct  PLpgSQL_stmt_loop
 
struct  PLpgSQL_stmt_while
 
struct  PLpgSQL_stmt_fori
 
struct  PLpgSQL_stmt_forq
 
struct  PLpgSQL_stmt_fors
 
struct  PLpgSQL_stmt_forc
 
struct  PLpgSQL_stmt_dynfors
 
struct  PLpgSQL_stmt_foreach_a
 
struct  PLpgSQL_stmt_open
 
struct  PLpgSQL_stmt_fetch
 
struct  PLpgSQL_stmt_close
 
struct  PLpgSQL_stmt_exit
 
struct  PLpgSQL_stmt_return
 
struct  PLpgSQL_stmt_return_next
 
struct  PLpgSQL_stmt_return_query
 
struct  PLpgSQL_stmt_raise
 
struct  PLpgSQL_raise_option
 
struct  PLpgSQL_stmt_assert
 
struct  PLpgSQL_stmt_execsql
 
struct  PLpgSQL_stmt_dynexecute
 
struct  PLpgSQL_func_hashkey
 
struct  PLpgSQL_function
 
struct  PLpgSQL_execstate
 
struct  PLpgSQL_plugin
 
struct  PLword
 
struct  PLcword
 
struct  PLwdatum
 

Macros

#define TEXTDOMAIN   PG_TEXTDOMAIN("plpgsql")
 
#define _(x)   dgettext(TEXTDOMAIN, x)
 
#define PLPGSQL_XCHECK_NONE   0
 
#define PLPGSQL_XCHECK_SHADOWVAR   (1 << 1)
 
#define PLPGSQL_XCHECK_TOOMANYROWS   (1 << 2)
 
#define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT   (1 << 3)
 
#define PLPGSQL_XCHECK_ALL   ((int) ~0)
 

Typedefs

typedef enum PLpgSQL_nsitem_type PLpgSQL_nsitem_type
 
typedef enum PLpgSQL_label_type PLpgSQL_label_type
 
typedef enum PLpgSQL_datum_type PLpgSQL_datum_type
 
typedef enum PLpgSQL_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 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_arrayelem PLpgSQL_arrayelem
 
typedef struct PLpgSQL_nsitem PLpgSQL_nsitem
 
typedef struct PLpgSQL_stmt PLpgSQL_stmt
 
typedef struct PLpgSQL_condition PLpgSQL_condition
 
typedef struct PLpgSQL_exception_block PLpgSQL_exception_block
 
typedef struct PLpgSQL_exception PLpgSQL_exception
 
typedef struct PLpgSQL_stmt_block PLpgSQL_stmt_block
 
typedef struct PLpgSQL_stmt_assign PLpgSQL_stmt_assign
 
typedef struct PLpgSQL_stmt_perform PLpgSQL_stmt_perform
 
typedef struct PLpgSQL_stmt_call PLpgSQL_stmt_call
 
typedef struct PLpgSQL_stmt_commit PLpgSQL_stmt_commit
 
typedef struct PLpgSQL_stmt_rollback PLpgSQL_stmt_rollback
 
typedef struct PLpgSQL_stmt_set PLpgSQL_stmt_set
 
typedef struct PLpgSQL_diag_item PLpgSQL_diag_item
 
typedef struct PLpgSQL_stmt_getdiag PLpgSQL_stmt_getdiag
 
typedef struct PLpgSQL_stmt_if PLpgSQL_stmt_if
 
typedef struct PLpgSQL_if_elsif PLpgSQL_if_elsif
 
typedef struct PLpgSQL_stmt_case PLpgSQL_stmt_case
 
typedef struct PLpgSQL_case_when PLpgSQL_case_when
 
typedef struct PLpgSQL_stmt_loop PLpgSQL_stmt_loop
 
typedef struct PLpgSQL_stmt_while PLpgSQL_stmt_while
 
typedef struct PLpgSQL_stmt_fori PLpgSQL_stmt_fori
 
typedef struct PLpgSQL_stmt_forq PLpgSQL_stmt_forq
 
typedef struct PLpgSQL_stmt_fors PLpgSQL_stmt_fors
 
typedef struct PLpgSQL_stmt_forc PLpgSQL_stmt_forc
 
typedef struct PLpgSQL_stmt_dynfors PLpgSQL_stmt_dynfors
 
typedef struct PLpgSQL_stmt_foreach_a PLpgSQL_stmt_foreach_a
 
typedef struct PLpgSQL_stmt_open PLpgSQL_stmt_open
 
typedef struct PLpgSQL_stmt_fetch PLpgSQL_stmt_fetch
 
typedef struct PLpgSQL_stmt_close PLpgSQL_stmt_close
 
typedef struct PLpgSQL_stmt_exit PLpgSQL_stmt_exit
 
typedef struct PLpgSQL_stmt_return PLpgSQL_stmt_return
 
typedef struct PLpgSQL_stmt_return_next PLpgSQL_stmt_return_next
 
typedef struct PLpgSQL_stmt_return_query PLpgSQL_stmt_return_query
 
typedef struct PLpgSQL_stmt_raise PLpgSQL_stmt_raise
 
typedef struct PLpgSQL_raise_option PLpgSQL_raise_option
 
typedef struct PLpgSQL_stmt_assert PLpgSQL_stmt_assert
 
typedef struct PLpgSQL_stmt_execsql PLpgSQL_stmt_execsql
 
typedef struct PLpgSQL_stmt_dynexecute PLpgSQL_stmt_dynexecute
 
typedef struct PLpgSQL_func_hashkey PLpgSQL_func_hashkey
 
typedef enum PLpgSQL_trigtype PLpgSQL_trigtype
 
typedef struct PLpgSQL_function PLpgSQL_function
 
typedef struct PLpgSQL_execstate PLpgSQL_execstate
 
typedef struct PLpgSQL_plugin PLpgSQL_plugin
 
typedef struct PLword PLword
 
typedef struct PLcword PLcword
 
typedef struct PLwdatum PLwdatum
 

Enumerations

enum  PLpgSQL_nsitem_type { PLPGSQL_NSTYPE_LABEL, PLPGSQL_NSTYPE_VAR, PLPGSQL_NSTYPE_REC }
 
enum  PLpgSQL_label_type { PLPGSQL_LABEL_BLOCK, PLPGSQL_LABEL_LOOP, PLPGSQL_LABEL_OTHER }
 
enum  PLpgSQL_datum_type {
  PLPGSQL_DTYPE_VAR, PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_RECFIELD,
  PLPGSQL_DTYPE_ARRAYELEM, PLPGSQL_DTYPE_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, PLPGSQL_STMT_SET
}
 
enum  { PLPGSQL_RC_OK, PLPGSQL_RC_EXIT, PLPGSQL_RC_RETURN, PLPGSQL_RC_CONTINUE }
 
enum  PLpgSQL_getdiag_kind {
  PLPGSQL_GETDIAG_ROW_COUNT, PLPGSQL_GETDIAG_CONTEXT, PLPGSQL_GETDIAG_ERROR_CONTEXT, PLPGSQL_GETDIAG_ERROR_DETAIL,
  PLPGSQL_GETDIAG_ERROR_HINT, PLPGSQL_GETDIAG_RETURNED_SQLSTATE, PLPGSQL_GETDIAG_COLUMN_NAME, PLPGSQL_GETDIAG_CONSTRAINT_NAME,
  PLPGSQL_GETDIAG_DATATYPE_NAME, PLPGSQL_GETDIAG_MESSAGE_TEXT, PLPGSQL_GETDIAG_TABLE_NAME, PLPGSQL_GETDIAG_SCHEMA_NAME
}
 
enum  PLpgSQL_raise_option_type {
  PLPGSQL_RAISEOPTION_ERRCODE, PLPGSQL_RAISEOPTION_MESSAGE, PLPGSQL_RAISEOPTION_DETAIL, PLPGSQL_RAISEOPTION_HINT,
  PLPGSQL_RAISEOPTION_COLUMN, PLPGSQL_RAISEOPTION_CONSTRAINT, PLPGSQL_RAISEOPTION_DATATYPE, PLPGSQL_RAISEOPTION_TABLE,
  PLPGSQL_RAISEOPTION_SCHEMA
}
 
enum  PLpgSQL_resolve_option { PLPGSQL_RESOLVE_ERROR, PLPGSQL_RESOLVE_VARIABLE, PLPGSQL_RESOLVE_COLUMN }
 
enum  PLpgSQL_trigtype { PLPGSQL_DML_TRIGGER, PLPGSQL_EVENT_TRIGGER, PLPGSQL_NOT_TRIGGER }
 
enum  IdentifierLookup { IDENTIFIER_LOOKUP_NORMAL, IDENTIFIER_LOOKUP_DECLARE, IDENTIFIER_LOOKUP_EXPR }
 

Functions

PLpgSQL_functionplpgsql_compile (FunctionCallInfo fcinfo, bool forValidator)
 
PLpgSQL_functionplpgsql_compile_inline (char *proc_source)
 
void plpgsql_parser_setup (struct ParseState *pstate, PLpgSQL_expr *expr)
 
bool plpgsql_parse_word (char *word1, const char *yytxt, 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)
 
PLpgSQL_typeplpgsql_build_datatype (Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
 
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)
 
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)
 
void plpgsql_HashTableInit (void)
 
void _PG_init (void)
 
Datum plpgsql_exec_function (PLpgSQL_function *func, FunctionCallInfo fcinfo, EState *simple_eval_estate, 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)
 
Oid plpgsql_exec_get_datum_type (PLpgSQL_execstate *estate, PLpgSQL_datum *datum)
 
void plpgsql_exec_get_datum_type_info (PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeId, int32 *typMod, Oid *collation)
 
void plpgsql_ns_init (void)
 
void plpgsql_ns_push (const char *label, PLpgSQL_label_type label_type)
 
void plpgsql_ns_pop (void)
 
PLpgSQL_nsitemplpgsql_ns_top (void)
 
void plpgsql_ns_additem (PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
 
PLpgSQL_nsitemplpgsql_ns_lookup (PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
 
PLpgSQL_nsitemplpgsql_ns_lookup_label (PLpgSQL_nsitem *ns_cur, const char *name)
 
PLpgSQL_nsitemplpgsql_ns_find_nearest_loop (PLpgSQL_nsitem *ns_cur)
 
const char * plpgsql_stmt_typename (PLpgSQL_stmt *stmt)
 
const char * plpgsql_getdiag_kindname (PLpgSQL_getdiag_kind kind)
 
void plpgsql_free_function_memory (PLpgSQL_function *func)
 
void plpgsql_dumptree (PLpgSQL_function *func)
 
int plpgsql_base_yylex (void)
 
int plpgsql_yylex (void)
 
void plpgsql_push_back_token (int token)
 
bool plpgsql_token_is_unreserved_keyword (int token)
 
void plpgsql_append_source_text (StringInfo buf, int startlocation, int endlocation)
 
int plpgsql_peek (void)
 
void plpgsql_peek2 (int *tok1_p, int *tok2_p, int *tok1_loc, int *tok2_loc)
 
int plpgsql_scanner_errposition (int location)
 
void plpgsql_yyerror (const char *message) pg_attribute_noreturn()
 
int plpgsql_location_to_lineno (int location)
 
int plpgsql_latest_lineno (void)
 
void plpgsql_scanner_init (const char *str)
 
void plpgsql_scanner_finish (void)
 
int plpgsql_yyparse (void)
 

Variables

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

Macro Definition Documentation

◆ _

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

Definition at line 36 of file plpgsql.h.

◆ PLPGSQL_XCHECK_ALL

#define PLPGSQL_XCHECK_ALL   ((int) ~0)

Definition at line 1198 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_NONE

#define PLPGSQL_XCHECK_NONE   0

Definition at line 1194 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_SHADOWVAR

#define PLPGSQL_XCHECK_SHADOWVAR   (1 << 1)

Definition at line 1195 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT

#define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT   (1 << 3)

Definition at line 1197 of file plpgsql.h.

Referenced by exec_move_row_from_fields(), and plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_TOOMANYROWS

#define PLPGSQL_XCHECK_TOOMANYROWS   (1 << 2)

Definition at line 1196 of file plpgsql.h.

Referenced by exec_stmt_execsql(), and plpgsql_extra_checks_check_hook().

◆ TEXTDOMAIN

#define TEXTDOMAIN   PG_TEXTDOMAIN("plpgsql")

Definition at line 33 of file plpgsql.h.

Typedef Documentation

◆ PLcword

typedef struct PLcword PLcword

◆ PLpgSQL_arrayelem

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

◆ 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_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_set

◆ 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

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
PLPGSQL_RC_OK 
PLPGSQL_RC_EXIT 
PLPGSQL_RC_RETURN 
PLPGSQL_RC_CONTINUE 

Definition at line 138 of file plpgsql.h.

◆ 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:1178

◆ PLpgSQL_datum_type

Enumerator
PLPGSQL_DTYPE_VAR 
PLPGSQL_DTYPE_ROW 
PLPGSQL_DTYPE_REC 
PLPGSQL_DTYPE_RECFIELD 
PLPGSQL_DTYPE_ARRAYELEM 
PLPGSQL_DTYPE_PROMISE 

Definition at line 61 of file plpgsql.h.

◆ PLpgSQL_getdiag_kind

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

◆ PLpgSQL_label_type

Enumerator
PLPGSQL_LABEL_BLOCK 
PLPGSQL_LABEL_LOOP 
PLPGSQL_LABEL_OTHER 

Definition at line 51 of file plpgsql.h.

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

◆ PLpgSQL_nsitem_type

Enumerator
PLPGSQL_NSTYPE_LABEL 
PLPGSQL_NSTYPE_VAR 
PLPGSQL_NSTYPE_REC 

Definition at line 41 of file plpgsql.h.

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

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

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

◆ 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:184

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

Definition at line 103 of file plpgsql.h.

104 {
PLpgSQL_stmt_type
Definition: plpgsql.h:103

◆ PLpgSQL_trigtype

Enumerator
PLPGSQL_DML_TRIGGER 
PLPGSQL_EVENT_TRIGGER 
PLPGSQL_NOT_TRIGGER 

Definition at line 970 of file plpgsql.h.

◆ 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:93

Function Documentation

◆ _PG_init()

void _PG_init ( void  )

Definition at line 56 of file auth_delay.c.

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

◆ plpgsql_add_initdatums()

int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2352 of file pl_comp.c.

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

2353 {
2354  int i;
2355  int n = 0;
2356 
2357  /*
2358  * The set of dtypes recognized here must match what exec_stmt_block()
2359  * cares about (re)initializing at block entry.
2360  */
2361  for (i = datums_last; i < plpgsql_nDatums; i++)
2362  {
2363  switch (plpgsql_Datums[i]->dtype)
2364  {
2365  case PLPGSQL_DTYPE_VAR:
2366  case PLPGSQL_DTYPE_REC:
2367  n++;
2368  break;
2369 
2370  default:
2371  break;
2372  }
2373  }
2374 
2375  if (varnos != NULL)
2376  {
2377  if (n > 0)
2378  {
2379  *varnos = (int *) palloc(sizeof(int) * n);
2380 
2381  n = 0;
2382  for (i = datums_last; i < plpgsql_nDatums; i++)
2383  {
2384  switch (plpgsql_Datums[i]->dtype)
2385  {
2386  case PLPGSQL_DTYPE_VAR:
2387  case PLPGSQL_DTYPE_REC:
2388  (*varnos)[n++] = plpgsql_Datums[i]->dno;
2389 
2390  default:
2391  break;
2392  }
2393  }
2394  }
2395  else
2396  *varnos = NULL;
2397  }
2398 
2400  return n;
2401 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
void * palloc(Size size)
Definition: mcxt.c:949
int i
static int datums_last
Definition: pl_comp.c:48

◆ plpgsql_adddatum()

void plpgsql_adddatum ( PLpgSQL_datum newdatum)

Definition at line 2291 of file pl_comp.c.

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

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

2292 {
2294  {
2295  datums_alloc *= 2;
2297  }
2298 
2299  newdatum->dno = plpgsql_nDatums;
2300  plpgsql_Datums[plpgsql_nDatums++] = newdatum;
2301 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
static int datums_alloc
Definition: pl_comp.c:45
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069

◆ plpgsql_append_source_text()

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

Definition at line 404 of file pl_scanner.c.

References appendBinaryStringInfo(), Assert, and scanorig.

406 {
407  Assert(startlocation <= endlocation);
408  appendBinaryStringInfo(buf, scanorig + startlocation,
409  endlocation - startlocation);
410 }
static const char * scanorig
Definition: pl_scanner.c:110
#define Assert(condition)
Definition: c.h:732
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

◆ plpgsql_base_yylex()

int plpgsql_base_yylex ( void  )

◆ plpgsql_build_datatype()

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

Definition at line 2049 of file pl_comp.c.

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

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

2051 {
2052  HeapTuple typeTup;
2053  PLpgSQL_type *typ;
2054 
2055  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
2056  if (!HeapTupleIsValid(typeTup))
2057  elog(ERROR, "cache lookup failed for type %u", typeOid);
2058 
2059  typ = build_datatype(typeTup, typmod, collation, origtypname);
2060 
2061  ReleaseSysCache(typeTup);
2062 
2063  return typ;
2064 }
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2071
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:226

◆ plpgsql_build_recfield()

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

Definition at line 2002 of file pl_comp.c.

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

Referenced by plpgsql_parse_dblword(), and plpgsql_parse_tripword().

2003 {
2004  PLpgSQL_recfield *recfield;
2005  int i;
2006 
2007  /* search for an existing datum referencing this field */
2008  i = rec->firstfield;
2009  while (i >= 0)
2010  {
2012 
2014  fld->recparentno == rec->dno);
2015  if (strcmp(fld->fieldname, fldname) == 0)
2016  return fld;
2017  i = fld->nextfield;
2018  }
2019 
2020  /* nope, so make a new one */
2021  recfield = palloc0(sizeof(PLpgSQL_recfield));
2022  recfield->dtype = PLPGSQL_DTYPE_RECFIELD;
2023  recfield->fieldname = pstrdup(fldname);
2024  recfield->recparentno = rec->dno;
2026 
2027  plpgsql_adddatum((PLpgSQL_datum *) recfield);
2028 
2029  /* now we can link it into the parent's chain */
2030  recfield->nextfield = rec->firstfield;
2031  rec->firstfield = recfield->dno;
2032 
2033  return recfield;
2034 }
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define INVALID_TUPLEDESC_IDENTIFIER
Definition: typcache.h:146
void plpgsql_adddatum(PLpgSQL_datum *newdatum)
Definition: pl_comp.c:2291
uint64 rectupledescid
Definition: plpgsql.h:409
void * palloc0(Size size)
Definition: mcxt.c:980
PLpgSQL_datum_type dtype
Definition: plpgsql.h:402
#define Assert(condition)
Definition: c.h:732
int i
char * fieldname
Definition: plpgsql.h:406
int firstfield
Definition: plpgsql.h:389

◆ plpgsql_build_record()

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

Definition at line 1908 of file pl_comp.c.

References PLpgSQL_rec::datatype, PLpgSQL_datum::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 do_compile(), and plpgsql_build_variable().

1911 {
1912  PLpgSQL_rec *rec;
1913 
1914  rec = palloc0(sizeof(PLpgSQL_rec));
1915  rec->dtype = PLPGSQL_DTYPE_REC;
1916  rec->refname = pstrdup(refname);
1917  rec->lineno = lineno;
1918  /* other fields are left as 0, might be changed by caller */
1919  rec->datatype = dtype;
1920  rec->rectypeid = rectypeid;
1921  rec->firstfield = -1;
1922  rec->erh = NULL;
1924  if (add2namespace)
1926 
1927  return rec;
1928 }
PLpgSQL_datum_type dtype
Definition: plpgsql.h:371
PLpgSQL_type * datatype
Definition: plpgsql.h:386
char * pstrdup(const char *in)
Definition: mcxt.c:1186
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
ExpandedRecordHeader * erh
Definition: plpgsql.h:394
char * refname
Definition: plpgsql.h:373
void plpgsql_adddatum(PLpgSQL_datum *newdatum)
Definition: pl_comp.c:2291
void * palloc0(Size size)
Definition: mcxt.c:980
Oid rectypeid
Definition: plpgsql.h:387
int lineno
Definition: plpgsql.h:374
int firstfield
Definition: plpgsql.h:389

◆ plpgsql_build_variable()

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

Definition at line 1845 of file pl_comp.c.

References PLpgSQL_var::datatype, PLpgSQL_datum::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 do_compile(), and plpgsql_compile_inline().

1847 {
1848  PLpgSQL_variable *result;
1849 
1850  switch (dtype->ttype)
1851  {
1852  case PLPGSQL_TTYPE_SCALAR:
1853  {
1854  /* Ordinary scalar datatype */
1855  PLpgSQL_var *var;
1856 
1857  var = palloc0(sizeof(PLpgSQL_var));
1858  var->dtype = PLPGSQL_DTYPE_VAR;
1859  var->refname = pstrdup(refname);
1860  var->lineno = lineno;
1861  var->datatype = dtype;
1862  /* other fields are left as 0, might be changed by caller */
1863 
1864  /* preset to NULL */
1865  var->value = 0;
1866  var->isnull = true;
1867  var->freeval = false;
1868 
1870  if (add2namespace)
1872  var->dno,
1873  refname);
1874  result = (PLpgSQL_variable *) var;
1875  break;
1876  }
1877  case PLPGSQL_TTYPE_REC:
1878  {
1879  /* Composite type -- build a record variable */
1880  PLpgSQL_rec *rec;
1881 
1882  rec = plpgsql_build_record(refname, lineno,
1883  dtype, dtype->typoid,
1884  add2namespace);
1885  result = (PLpgSQL_variable *) rec;
1886  break;
1887  }
1888  case PLPGSQL_TTYPE_PSEUDO:
1889  ereport(ERROR,
1890  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1891  errmsg("variable \"%s\" has pseudo-type %s",
1892  refname, format_type_be(dtype->typoid))));
1893  result = NULL; /* keep compiler quiet */
1894  break;
1895  default:
1896  elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1897  result = NULL; /* keep compiler quiet */
1898  break;
1899  }
1900 
1901  return result;
1902 }
char * refname
Definition: plpgsql.h:293
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
Definition: pl_comp.c:1908
PLpgSQL_datum_type dtype
Definition: plpgsql.h:291
char * pstrdup(const char *in)
Definition: mcxt.c:1186
PLpgSQL_type * datatype
Definition: plpgsql.h:300
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
PLpgSQL_type_type ttype
Definition: plpgsql.h:203
int errcode(int sqlerrcode)
Definition: elog.c:570
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
void plpgsql_adddatum(PLpgSQL_datum *newdatum)
Definition: pl_comp.c:2291
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool freeval
Definition: plpgsql.h:315
void * palloc0(Size size)
Definition: mcxt.c:980
Datum value
Definition: plpgsql.h:313
int lineno
Definition: plpgsql.h:294
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
bool isnull
Definition: plpgsql.h:314
Oid typoid
Definition: plpgsql.h:202

◆ plpgsql_compile()

PLpgSQL_function* plpgsql_compile ( FunctionCallInfo  fcinfo,
bool  forValidator 
)

Definition at line 137 of file pl_comp.c.

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

Referenced by plpgsql_call_handler(), and plpgsql_validator().

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

◆ plpgsql_compile_inline()

PLpgSQL_function* plpgsql_compile_inline ( char *  proc_source)

Definition at line 843 of file pl_comp.c.

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

Referenced by plpgsql_inline_handler().

844 {
845  char *func_name = "inline_code_block";
846  PLpgSQL_function *function;
847  ErrorContextCallback plerrcontext;
848  PLpgSQL_variable *var;
849  int parse_rc;
850  MemoryContext func_cxt;
851 
852  /*
853  * Setup the scanner input and error info. We assume that this function
854  * cannot be invoked recursively, so there's no need to save and restore
855  * the static variables used here.
856  */
857  plpgsql_scanner_init(proc_source);
858 
859  plpgsql_error_funcname = func_name;
860 
861  /*
862  * Setup error traceback support for ereport()
863  */
865  plerrcontext.arg = proc_source;
866  plerrcontext.previous = error_context_stack;
867  error_context_stack = &plerrcontext;
868 
869  /* Do extra syntax checking if check_function_bodies is on */
871 
872  /* Function struct does not live past current statement */
873  function = (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
874 
875  plpgsql_curr_compile = function;
876 
877  /*
878  * All the rest of the compile-time storage (e.g. parse tree) is kept in
879  * its own memory context, so it can be reclaimed easily.
880  */
882  "PL/pgSQL inline code context",
885 
886  function->fn_signature = pstrdup(func_name);
887  function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
888  function->fn_input_collation = InvalidOid;
889  function->fn_cxt = func_cxt;
890  function->out_param_varno = -1; /* set up for no OUT param */
891  function->resolve_option = plpgsql_variable_conflict;
892  function->print_strict_params = plpgsql_print_strict_params;
893 
894  /*
895  * don't do extra validation for inline code as we don't want to add spam
896  * at runtime
897  */
898  function->extra_warnings = 0;
899  function->extra_errors = 0;
900 
901  function->nstatements = 0;
902 
903  plpgsql_ns_init();
905  plpgsql_DumpExecTree = false;
907 
908  /* Set up as though in a function returning VOID */
909  function->fn_rettype = VOIDOID;
910  function->fn_retset = false;
911  function->fn_retistuple = false;
912  function->fn_retisdomain = false;
913  function->fn_prokind = PROKIND_FUNCTION;
914  /* a bit of hardwired knowledge about type VOID here */
915  function->fn_retbyval = true;
916  function->fn_rettyplen = sizeof(int32);
917 
918  /*
919  * Remember if function is STABLE/IMMUTABLE. XXX would it be better to
920  * set this true inside a read-only transaction? Not clear.
921  */
922  function->fn_readonly = false;
923 
924  /*
925  * Create the magic FOUND variable.
926  */
927  var = plpgsql_build_variable("found", 0,
928  plpgsql_build_datatype(BOOLOID,
929  -1,
930  InvalidOid,
931  NULL),
932  true);
933  function->found_varno = var->dno;
934 
935  /*
936  * Now parse the function's text
937  */
938  parse_rc = plpgsql_yyparse();
939  if (parse_rc != 0)
940  elog(ERROR, "plpgsql parser returned %d", parse_rc);
941  function->action = plpgsql_parse_result;
942 
944 
945  /*
946  * If it returns VOID (always true at the moment), we allow control to
947  * fall off the end without an explicit RETURN statement.
948  */
949  if (function->fn_rettype == VOIDOID)
950  add_dummy_return(function);
951 
952  /*
953  * Complete the function's info
954  */
955  function->fn_nargs = 0;
956 
957  plpgsql_finish_datums(function);
958 
959  /*
960  * Pop the error context stack
961  */
962  error_context_stack = plerrcontext.previous;
963  plpgsql_error_funcname = NULL;
964 
965  plpgsql_check_syntax = false;
966 
969  return function;
970 }
int plpgsql_yyparse(void)
#define AllocSetContextCreate
Definition: memutils.h:170
char * pstrdup(const char *in)
Definition: mcxt.c:1186
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool check_function_bodies
Definition: guc.c:500
void(* callback)(void *arg)
Definition: elog.h:254
struct ErrorContextCallback * previous
Definition: elog.h:253
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2274
signed int int32
Definition: c.h:346
ErrorContextCallback * error_context_stack
Definition: elog.c:88
void plpgsql_scanner_finish(void)
Definition: pl_scanner.c:613
bool plpgsql_check_syntax
Definition: pl_comp.c:52
#define ERROR
Definition: elog.h:43
char * plpgsql_error_funcname
Definition: pl_comp.c:50
bool plpgsql_DumpExecTree
Definition: pl_comp.c:51
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
static void add_dummy_return(PLpgSQL_function *function)
Definition: pl_comp.c:1031
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void plpgsql_ns_init(void)
Definition: pl_funcs.c:45
void * palloc0(Size size)
Definition: mcxt.c:980
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2049
#define InvalidOid
Definition: postgres_ext.h:36
bool plpgsql_print_strict_params
Definition: pl_handler.c:48
static void plpgsql_compile_error_callback(void *arg)
Definition: pl_comp.c:979
int plpgsql_variable_conflict
Definition: pl_handler.c:46
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
Definition: pl_funcs.c:56
PLpgSQL_stmt_block * plpgsql_parse_result
Definition: pl_comp.c:43
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
Definition: pl_comp.c:1845
on_exit_nicely_callback function
void plpgsql_scanner_init(const char *str)
Definition: pl_scanner.c:586
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2308
#define elog(elevel,...)
Definition: elog.h:226
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:54

◆ plpgsql_dumptree()

void plpgsql_dumptree ( PLpgSQL_function func)

Definition at line 1626 of file pl_funcs.c.

References PLpgSQL_function::action, PLpgSQL_type::atttypmod, PLpgSQL_var::cursor_explicit_argrow, PLpgSQL_var::cursor_explicit_expr, PLpgSQL_var::datatype, PLpgSQL_function::datums, PLpgSQL_var::default_val, PLpgSQL_datum::dtype, PLpgSQL_arrayelem::dtype, dump_block(), dump_expr(), dump_indent, PLpgSQL_row::fieldnames, PLpgSQL_function::fn_signature, i, PLpgSQL_var::isconst, PLpgSQL_stmt_block::lineno, PLpgSQL_function::ndatums, PLpgSQL_row::nfields, PLpgSQL_var::notnull, PLPGSQL_DTYPE_ARRAYELEM, PLPGSQL_DTYPE_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 do_compile().

1627 {
1628  int i;
1629  PLpgSQL_datum *d;
1630 
1631  printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1632  func->fn_signature);
1633 
1634  printf("\nFunction's data area:\n");
1635  for (i = 0; i < func->ndatums; i++)
1636  {
1637  d = func->datums[i];
1638 
1639  printf(" entry %d: ", i);
1640  switch (d->dtype)
1641  {
1642  case PLPGSQL_DTYPE_VAR:
1643  case PLPGSQL_DTYPE_PROMISE:
1644  {
1645  PLpgSQL_var *var = (PLpgSQL_var *) d;
1646 
1647  printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1648  var->refname, var->datatype->typname,
1649  var->datatype->typoid,
1650  var->datatype->atttypmod);
1651  if (var->isconst)
1652  printf(" CONSTANT\n");
1653  if (var->notnull)
1654  printf(" NOT NULL\n");
1655  if (var->default_val != NULL)
1656  {
1657  printf(" DEFAULT ");
1658  dump_expr(var->default_val);
1659  printf("\n");
1660  }
1661  if (var->cursor_explicit_expr != NULL)
1662  {
1663  if (var->cursor_explicit_argrow >= 0)
1664  printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1665 
1666  printf(" CURSOR IS ");
1668  printf("\n");
1669  }
1670  if (var->promise != PLPGSQL_PROMISE_NONE)
1671  printf(" PROMISE %d\n",
1672  (int) var->promise);
1673  }
1674  break;
1675  case PLPGSQL_DTYPE_ROW:
1676  {
1677  PLpgSQL_row *row = (PLpgSQL_row *) d;
1678  int i;
1679 
1680  printf("ROW %-16s fields", row->refname);
1681  for (i = 0; i < row->nfields; i++)
1682  {
1683  printf(" %s=var %d", row->fieldnames[i],
1684  row->varnos[i]);
1685  }
1686  printf("\n");
1687  }
1688  break;
1689  case PLPGSQL_DTYPE_REC:
1690  printf("REC %-16s typoid %u\n",
1691  ((PLpgSQL_rec *) d)->refname,
1692  ((PLpgSQL_rec *) d)->rectypeid);
1693  if (((PLpgSQL_rec *) d)->isconst)
1694  printf(" CONSTANT\n");
1695  if (((PLpgSQL_rec *) d)->notnull)
1696  printf(" NOT NULL\n");
1697  if (((PLpgSQL_rec *) d)->default_val != NULL)
1698  {
1699  printf(" DEFAULT ");
1700  dump_expr(((PLpgSQL_rec *) d)->default_val);
1701  printf("\n");
1702  }
1703  break;
1705  printf("RECFIELD %-16s of REC %d\n",
1706  ((PLpgSQL_recfield *) d)->fieldname,
1707  ((PLpgSQL_recfield *) d)->recparentno);
1708  break;
1710  printf("ARRAYELEM of VAR %d subscript ",
1711  ((PLpgSQL_arrayelem *) d)->arrayparentno);
1712  dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
1713  printf("\n");
1714  break;
1715  default:
1716  printf("??? unknown data type %d\n", d->dtype);
1717  }
1718  }
1719  printf("\nFunction's statements:\n");
1720 
1721  dump_indent = 0;
1722  printf("%3d:", func->action->lineno);
1723  dump_block(func->action);
1724  printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1725  fflush(stdout);
1726 }
PLpgSQL_promise_type promise
Definition: plpgsql.h:322
PLpgSQL_datum ** datums
Definition: plpgsql.h:1020
char * refname
Definition: plpgsql.h:347
char * refname
Definition: plpgsql.h:293
PLpgSQL_stmt_block * action
Definition: plpgsql.h:1024
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:307
PLpgSQL_type * datatype
Definition: plpgsql.h:300
bool isconst
Definition: plpgsql.h:295
#define printf(...)
Definition: port.h:198
PLpgSQL_datum_type dtype
Definition: plpgsql.h:257
bool notnull
Definition: plpgsql.h:296
int cursor_explicit_argrow
Definition: plpgsql.h:308
char ** fieldnames
Definition: plpgsql.h:362
PLpgSQL_expr * default_val
Definition: plpgsql.h:297
int * varnos
Definition: plpgsql.h:363
PLpgSQL_datum_type dtype
Definition: plpgsql.h:402
int nfields
Definition: plpgsql.h:361
static int dump_indent
Definition: pl_funcs.c:801
char * fn_signature
Definition: plpgsql.h:982
char * typname
Definition: plpgsql.h:201
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:954
int32 atttypmod
Definition: plpgsql.h:209
static void dump_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:1620
int i
Oid typoid
Definition: plpgsql.h:202

◆ plpgsql_exec_event_trigger()

void plpgsql_exec_event_trigger ( PLpgSQL_function func,
EventTriggerData trigdata 
)

Definition at line 1129 of file pl_exec.c.

References PLpgSQL_function::action, ErrorContextCallback::arg, ErrorContextCallback::callback, copy_plpgsql_datums(), ereport, PLpgSQL_execstate::err_stmt, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, PLpgSQL_execstate::evtrigdata, exec_eval_cleanup(), exec_stmt(), 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().

1130 {
1131  PLpgSQL_execstate estate;
1132  ErrorContextCallback plerrcontext;
1133  int rc;
1134 
1135  /*
1136  * Setup the execution state
1137  */
1138  plpgsql_estate_setup(&estate, func, NULL, NULL);
1139  estate.evtrigdata = trigdata;
1140 
1141  /*
1142  * Setup error traceback support for ereport()
1143  */
1144  plerrcontext.callback = plpgsql_exec_error_callback;
1145  plerrcontext.arg = &estate;
1146  plerrcontext.previous = error_context_stack;
1147  error_context_stack = &plerrcontext;
1148 
1149  /*
1150  * Make local execution copies of all the datums
1151  */
1152  estate.err_text = gettext_noop("during initialization of execution state");
1153  copy_plpgsql_datums(&estate, func);
1154 
1155  /*
1156  * Let the instrumentation plugin peek at this function
1157  */
1158  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
1159  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
1160 
1161  /*
1162  * Now call the toplevel block of statements
1163  */
1164  estate.err_text = NULL;
1165  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
1166  rc = exec_stmt(&estate, (PLpgSQL_stmt *) func->action);
1167  if (rc != PLPGSQL_RC_RETURN)
1168  {
1169  estate.err_stmt = NULL;
1170  estate.err_text = NULL;
1171  ereport(ERROR,
1172  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1173  errmsg("control reached end of trigger procedure without RETURN")));
1174  }
1175 
1176  estate.err_stmt = NULL;
1177  estate.err_text = gettext_noop("during function exit");
1178 
1179  /*
1180  * Let the instrumentation plugin peek at this function
1181  */
1182  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1183  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1184 
1185  /* Clean up any leftover temporary memory */
1186  plpgsql_destroy_econtext(&estate);
1187  exec_eval_cleanup(&estate);
1188  /* stmt_mcontext will be destroyed when function's main context is */
1189 
1190  /*
1191  * Pop the error context stack
1192  */
1193  error_context_stack = plerrcontext.previous;
1194 
1195  return;
1196 }
static int exec_stmt(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
Definition: pl_exec.c:1940
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:1100
PLpgSQL_stmt_block * action
Definition: plpgsql.h:1024
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1202
#define gettext_noop(x)
Definition: c.h:1117
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3876
int errcode(int sqlerrcode)
Definition: elog.c:570
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:4020
void(* callback)(void *arg)
Definition: elog.h:254
struct ErrorContextCallback * previous
Definition: elog.h:253
static void copy_plpgsql_datums(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: pl_exec.c:1260
ErrorContextCallback * error_context_stack
Definition: elog.c:88
#define ERROR
Definition: elog.h:43
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:8238
#define ereport(elevel, rest)
Definition: elog.h:141
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:58
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1140
EventTriggerData * evtrigdata
Definition: plpgsql.h:1039
const char * err_text
Definition: plpgsql.h:1101
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ plpgsql_exec_function()

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

Definition at line 451 of file pl_exec.c.

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_stmt, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, exec_cast_value(), exec_eval_cleanup(), exec_move_row(), exec_move_row_from_datum(), exec_set_found(), exec_stmt(), 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, IsA, FunctionCallInfoBaseData::isnull, PLpgSQL_var::isnull, NullableDatum::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, 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_var::value, NullableDatum::value, VARATT_IS_EXTERNAL_EXPANDED_RO, and VARATT_IS_EXTERNAL_EXPANDED_RW.

Referenced by plpgsql_call_handler(), and plpgsql_inline_handler().

453 {
454  PLpgSQL_execstate estate;
455  ErrorContextCallback plerrcontext;
456  int i;
457  int rc;
458 
459  /*
460  * Setup the execution state
461  */
462  plpgsql_estate_setup(&estate, func, (ReturnSetInfo *) fcinfo->resultinfo,
463  simple_eval_estate);
464  estate.atomic = atomic;
465 
466  /*
467  * Setup error traceback support for ereport()
468  */
469  plerrcontext.callback = plpgsql_exec_error_callback;
470  plerrcontext.arg = &estate;
471  plerrcontext.previous = error_context_stack;
472  error_context_stack = &plerrcontext;
473 
474  /*
475  * Make local execution copies of all the datums
476  */
477  estate.err_text = gettext_noop("during initialization of execution state");
478  copy_plpgsql_datums(&estate, func);
479 
480  /*
481  * Store the actual call argument values into the appropriate variables
482  */
483  estate.err_text = gettext_noop("while storing call arguments into local variables");
484  for (i = 0; i < func->fn_nargs; i++)
485  {
486  int n = func->fn_argvarnos[i];
487 
488  switch (estate.datums[n]->dtype)
489  {
490  case PLPGSQL_DTYPE_VAR:
491  {
492  PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
493 
494  assign_simple_var(&estate, var,
495  fcinfo->args[i].value,
496  fcinfo->args[i].isnull,
497  false);
498 
499  /*
500  * Force any array-valued parameter to be stored in
501  * expanded form in our local variable, in hopes of
502  * improving efficiency of uses of the variable. (This is
503  * a hack, really: why only arrays? Need more thought
504  * about which cases are likely to win. See also
505  * typisarray-specific heuristic in exec_assign_value.)
506  *
507  * Special cases: If passed a R/W expanded pointer, assume
508  * we can commandeer the object rather than having to copy
509  * it. If passed a R/O expanded pointer, just keep it as
510  * the value of the variable for the moment. (We'll force
511  * it to R/W if the variable gets modified, but that may
512  * very well never happen.)
513  */
514  if (!var->isnull && var->datatype->typisarray)
515  {
517  {
518  /* take ownership of R/W object */
519  assign_simple_var(&estate, var,
521  estate.datum_context),
522  false,
523  true);
524  }
526  {
527  /* R/O pointer, keep it as-is until assigned to */
528  }
529  else
530  {
531  /* flat array, so force to expanded form */
532  assign_simple_var(&estate, var,
533  expand_array(var->value,
534  estate.datum_context,
535  NULL),
536  false,
537  true);
538  }
539  }
540  }
541  break;
542 
543  case PLPGSQL_DTYPE_REC:
544  {
545  PLpgSQL_rec *rec = (PLpgSQL_rec *) estate.datums[n];
546 
547  if (!fcinfo->args[i].isnull)
548  {
549  /* Assign row value from composite datum */
550  exec_move_row_from_datum(&estate,
551  (PLpgSQL_variable *) rec,
552  fcinfo->args[i].value);
553  }
554  else
555  {
556  /* If arg is null, set variable to null */
557  exec_move_row(&estate, (PLpgSQL_variable *) rec,
558  NULL, NULL);
559  }
560  /* clean up after exec_move_row() */
561  exec_eval_cleanup(&estate);
562  }
563  break;
564 
565  default:
566  /* Anything else should not be an argument variable */
567  elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
568  }
569  }
570 
571  estate.err_text = gettext_noop("during function entry");
572 
573  /*
574  * Set the magic variable FOUND to false
575  */
576  exec_set_found(&estate, false);
577 
578  /*
579  * Let the instrumentation plugin peek at this function
580  */
581  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
582  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
583 
584  /*
585  * Now call the toplevel block of statements
586  */
587  estate.err_text = NULL;
588  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
589  rc = exec_stmt(&estate, (PLpgSQL_stmt *) func->action);
590  if (rc != PLPGSQL_RC_RETURN)
591  {
592  estate.err_stmt = NULL;
593  estate.err_text = NULL;
594  ereport(ERROR,
595  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
596  errmsg("control reached end of function without RETURN")));
597  }
598 
599  /*
600  * We got a return value - process it
601  */
602  estate.err_stmt = NULL;
603  estate.err_text = gettext_noop("while casting return value to function's return type");
604 
605  fcinfo->isnull = estate.retisnull;
606 
607  if (estate.retisset)
608  {
609  ReturnSetInfo *rsi = estate.rsi;
610 
611  /* Check caller can handle a set result */
612  if (!rsi || !IsA(rsi, ReturnSetInfo) ||
613  (rsi->allowedModes & SFRM_Materialize) == 0)
614  ereport(ERROR,
615  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
616  errmsg("set-valued function called in context that cannot accept a set")));
618 
619  /* If we produced any tuples, send back the result */
620  if (estate.tuple_store)
621  {
622  MemoryContext oldcxt;
623 
624  rsi->setResult = estate.tuple_store;
625  oldcxt = MemoryContextSwitchTo(estate.tuple_store_cxt);
627  MemoryContextSwitchTo(oldcxt);
628  }
629  estate.retval = (Datum) 0;
630  fcinfo->isnull = true;
631  }
632  else if (!estate.retisnull)
633  {
634  /*
635  * Cast result value to function's declared result type, and copy it
636  * out to the upper executor memory context. We must treat tuple
637  * results specially in order to deal with cases like rowtypes
638  * involving dropped columns.
639  */
640  if (estate.retistuple)
641  {
642  /* Don't need coercion if rowtype is known to match */
643  if (func->fn_rettype == estate.rettype &&
644  func->fn_rettype != RECORDOID)
645  {
646  /*
647  * Copy the tuple result into upper executor memory context.
648  * However, if we have a R/W expanded datum, we can just
649  * transfer its ownership out to the upper context.
650  */
651  estate.retval = SPI_datumTransfer(estate.retval,
652  false,
653  -1);
654  }
655  else
656  {
657  /*
658  * Need to look up the expected result type. XXX would be
659  * better to cache the tupdesc instead of repeating
660  * get_call_result_type(), but the only easy place to save it
661  * is in the PLpgSQL_function struct, and that's too
662  * long-lived: composite types could change during the
663  * existence of a PLpgSQL_function.
664  */
665  Oid resultTypeId;
666  TupleDesc tupdesc;
667 
668  switch (get_call_result_type(fcinfo, &resultTypeId, &tupdesc))
669  {
670  case TYPEFUNC_COMPOSITE:
671  /* got the expected result rowtype, now coerce it */
672  coerce_function_result_tuple(&estate, tupdesc);
673  break;
675  /* got the expected result rowtype, now coerce it */
676  coerce_function_result_tuple(&estate, tupdesc);
677  /* and check domain constraints */
678  /* XXX allowing caching here would be good, too */
679  domain_check(estate.retval, false, resultTypeId,
680  NULL, NULL);
681  break;
682  case TYPEFUNC_RECORD:
683 
684  /*
685  * Failed to determine actual type of RECORD. We
686  * could raise an error here, but what this means in
687  * practice is that the caller is expecting any old
688  * generic rowtype, so we don't really need to be
689  * restrictive. Pass back the generated result as-is.
690  */
691  estate.retval = SPI_datumTransfer(estate.retval,
692  false,
693  -1);
694  break;
695  default:
696  /* shouldn't get here if retistuple is true ... */
697  elog(ERROR, "return type must be a row type");
698  break;
699  }
700  }
701  }
702  else
703  {
704  /* Scalar case: use exec_cast_value */
705  estate.retval = exec_cast_value(&estate,
706  estate.retval,
707  &fcinfo->isnull,
708  estate.rettype,
709  -1,
710  func->fn_rettype,
711  -1);
712 
713  /*
714  * If the function's return type isn't by value, copy the value
715  * into upper executor memory context. However, if we have a R/W
716  * expanded datum, we can just transfer its ownership out to the
717  * upper executor context.
718  */
719  if (!fcinfo->isnull && !func->fn_retbyval)
720  estate.retval = SPI_datumTransfer(estate.retval,
721  false,
722  func->fn_rettyplen);
723  }
724  }
725  else
726  {
727  /*
728  * We're returning a NULL, which normally requires no conversion work
729  * regardless of datatypes. But, if we are casting it to a domain
730  * return type, we'd better check that the domain's constraints pass.
731  */
732  if (func->fn_retisdomain)
733  estate.retval = exec_cast_value(&estate,
734  estate.retval,
735  &fcinfo->isnull,
736  estate.rettype,
737  -1,
738  func->fn_rettype,
739  -1);
740  }
741 
742  estate.err_text = gettext_noop("during function exit");
743 
744  /*
745  * Let the instrumentation plugin peek at this function
746  */
747  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
748  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
749 
750  /* Clean up any leftover temporary memory */
751  plpgsql_destroy_econtext(&estate);
752  exec_eval_cleanup(&estate);
753  /* stmt_mcontext will be destroyed when function's main context is */
754 
755  /*
756  * Pop the error context stack
757  */
758  error_context_stack = plerrcontext.previous;
759 
760  /*
761  * Return the function's result
762  */
763  return estate.retval;
764 }
bool fn_retbyval
Definition: plpgsql.h:993
static int exec_stmt(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
Definition: pl_exec.c:1940
PLpgSQL_datum ** datums
Definition: plpgsql.h:1020
int fn_argvarnos[FUNC_MAX_ARGS]
Definition: plpgsql.h:1001
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:110
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:1100
PLpgSQL_stmt_block * action
Definition: plpgsql.h:1024
PLpgSQL_type * datatype
Definition: plpgsql.h:300
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1202
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define gettext_noop(x)
Definition: c.h:1117
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3876
int errcode(int sqlerrcode)
Definition: elog.c:570
static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, Datum newvalue, bool isnull, bool freeable)
Definition: pl_exec.c:8318
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:4020
unsigned int Oid
Definition: postgres_ext.h:31
static void exec_move_row_from_datum(PLpgSQL_execstate *estate, PLpgSQL_variable *target, Datum value)
Definition: pl_exec.c:7376
PLpgSQL_datum_type dtype
Definition: plpgsql.h:257
void(* callback)(void *arg)
Definition: elog.h:254
struct ErrorContextCallback * previous
Definition: elog.h:253
static void copy_plpgsql_datums(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: pl_exec.c:1260
PLpgSQL_datum ** datums
Definition: plpgsql.h:1071
ErrorContextCallback * error_context_stack
Definition: elog.c:88
Datum TransferExpandedObject(Datum d, MemoryContext new_parent)
TupleDesc tuple_store_desc
Definition: plpgsql.h:1057
static Datum exec_cast_value(PLpgSQL_execstate *estate, Datum value, bool *isnull, Oid valtype, int32 valtypmod, Oid reqtype, int32 reqtypmod)
Definition: pl_exec.c:7673
#define ERROR
Definition: elog.h:43
MemoryContext tuple_store_cxt
Definition: plpgsql.h:1058
fmNodePtr resultinfo
Definition: fmgr.h:89
Datum SPI_datumTransfer(Datum value, bool typByVal, int typLen)
Definition: spi.c:1137
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:8238
ReturnSetInfo * rsi
Definition: plpgsql.h:1060
#define ereport(elevel, rest)
Definition: elog.h:141
Datum value
Definition: postgres.h:378
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:58
Tuplestorestate * tuple_store
Definition: plpgsql.h:1056
bool fn_retisdomain
Definition: plpgsql.h:995
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1140
bool typisarray
Definition: plpgsql.h:208
uintptr_t Datum
Definition: postgres.h:367
const char * err_text
Definition: plpgsql.h:1101
void domain_check(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt)
Definition: domains.c:327
Datum value
Definition: plpgsql.h:313
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1141
int allowedModes
Definition: execnodes.h:303
SetFunctionReturnMode returnMode
Definition: execnodes.h:305
#define VARATT_IS_EXTERNAL_EXPANDED_RO(PTR)
Definition: postgres.h:318
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:8170
Tuplestorestate * setResult
Definition: execnodes.h:308
#define DatumGetPointer(X)
Definition: postgres.h:549
MemoryContext datum_context
Definition: plpgsql.h:1073
TupleDesc setDesc
Definition: execnodes.h:309
int errmsg(const char *fmt,...)
Definition: elog.c:784
static void exec_move_row(PLpgSQL_execstate *estate, PLpgSQL_variable *target, HeapTuple tup, TupleDesc tupdesc)
Definition: pl_exec.c:6711
#define elog(elevel,...)
Definition: elog.h:226
int i
#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR)
Definition: postgres.h:320
static void coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc)
Definition: pl_exec.c:775
bool isnull
Definition: plpgsql.h:314

◆ plpgsql_exec_get_datum_type()

Oid plpgsql_exec_get_datum_type ( PLpgSQL_execstate estate,
PLpgSQL_datum datum 
)

Definition at line 5527 of file pl_exec.c.

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

5529 {
5530  Oid typeid;
5531 
5532  switch (datum->dtype)
5533  {
5534  case PLPGSQL_DTYPE_VAR:
5535  case PLPGSQL_DTYPE_PROMISE:
5536  {
5537  PLpgSQL_var *var = (PLpgSQL_var *) datum;
5538 
5539  typeid = var->datatype->typoid;
5540  break;
5541  }
5542 
5543  case PLPGSQL_DTYPE_REC:
5544  {
5545  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5546 
5547  if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5548  {
5549  /* Report variable's declared type */
5550  typeid = rec->rectypeid;
5551  }
5552  else
5553  {
5554  /* Report record's actual type if declared RECORD */
5555  typeid = rec->erh->er_typeid;
5556  }
5557  break;
5558  }
5559 
5561  {
5562  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5563  PLpgSQL_rec *rec;
5564 
5565  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5566 
5567  /*
5568  * If record variable is NULL, instantiate it if it has a
5569  * named composite type, else complain. (This won't change
5570  * the logical state of the record: it's still NULL.)
5571  */
5572  if (rec->erh == NULL)
5573  instantiate_empty_record_variable(estate, rec);
5574 
5575  /*
5576  * Look up the field's properties if we have not already, or
5577  * if the tuple descriptor ID changed since last time.
5578  */
5579  if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5580  {
5582  recfield->fieldname,
5583  &recfield->finfo))
5584  ereport(ERROR,
5585  (errcode(ERRCODE_UNDEFINED_COLUMN),
5586  errmsg("record \"%s\" has no field \"%s\"",
5587  rec->refname, recfield->fieldname)));
5588  recfield->rectupledescid = rec->erh->er_tupdesc_id;
5589  }
5590 
5591  typeid = recfield->finfo.ftypeid;
5592  break;
5593  }
5594 
5595  default:
5596  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5597  typeid = InvalidOid; /* keep compiler quiet */
5598  break;
5599  }
5600 
5601  return typeid;
5602 }
bool expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname, ExpandedRecordFieldInfo *finfo)
PLpgSQL_type * datatype
Definition: plpgsql.h:300
static void instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec)
Definition: pl_exec.c:7609
ExpandedRecordHeader * erh
Definition: plpgsql.h:394
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
PLpgSQL_datum_type dtype
Definition: plpgsql.h:257
char * refname
Definition: plpgsql.h:373
PLpgSQL_datum ** datums
Definition: plpgsql.h:1071
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
uint64 rectupledescid
Definition: plpgsql.h:409
ExpandedRecordFieldInfo finfo
Definition: plpgsql.h:410
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define unlikely(x)
Definition: c.h:208
Oid rectypeid
Definition: plpgsql.h:387
char * fieldname
Definition: plpgsql.h:406
Oid typoid
Definition: plpgsql.h:202

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

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

5615 {
5616  switch (datum->dtype)
5617  {
5618  case PLPGSQL_DTYPE_VAR:
5619  case PLPGSQL_DTYPE_PROMISE:
5620  {
5621  PLpgSQL_var *var = (PLpgSQL_var *) datum;
5622 
5623  *typeId = var->datatype->typoid;
5624  *typMod = var->datatype->atttypmod;
5625  *collation = var->datatype->collation;
5626  break;
5627  }
5628 
5629  case PLPGSQL_DTYPE_REC:
5630  {
5631  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5632 
5633  if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5634  {
5635  /* Report variable's declared type */
5636  *typeId = rec->rectypeid;
5637  *typMod = -1;
5638  }
5639  else
5640  {
5641  /* Report record's actual type if declared RECORD */
5642  *typeId = rec->erh->er_typeid;
5643  /* do NOT return the mutable typmod of a RECORD variable */
5644  *typMod = -1;
5645  }
5646  /* composite types are never collatable */
5647  *collation = InvalidOid;
5648  break;
5649  }
5650 
5652  {
5653  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5654  PLpgSQL_rec *rec;
5655 
5656  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5657 
5658  /*
5659  * If record variable is NULL, instantiate it if it has a
5660  * named composite type, else complain. (This won't change
5661  * the logical state of the record: it's still NULL.)
5662  */
5663  if (rec->erh == NULL)
5664  instantiate_empty_record_variable(estate, rec);
5665 
5666  /*
5667  * Look up the field's properties if we have not already, or
5668  * if the tuple descriptor ID changed since last time.
5669  */
5670  if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5671  {
5673  recfield->fieldname,
5674  &recfield->finfo))
5675  ereport(ERROR,
5676  (errcode(ERRCODE_UNDEFINED_COLUMN),
5677  errmsg("record \"%s\" has no field \"%s\"",
5678  rec->refname, recfield->fieldname)));
5679  recfield->rectupledescid = rec->erh->er_tupdesc_id;
5680  }
5681 
5682  *typeId = recfield->finfo.ftypeid;
5683  *typMod = recfield->finfo.ftypmod;
5684  *collation = recfield->finfo.fcollation;
5685  break;
5686  }
5687 
5688  default:
5689  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5690  *typeId = InvalidOid; /* keep compiler quiet */
5691  *typMod = -1;
5692  *collation = InvalidOid;
5693  break;
5694  }
5695 }
bool expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname, ExpandedRecordFieldInfo *finfo)
PLpgSQL_type * datatype
Definition: plpgsql.h:300
static void instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec)
Definition: pl_exec.c:7609
ExpandedRecordHeader * erh
Definition: plpgsql.h:394
int errcode(int sqlerrcode)
Definition: elog.c:570
PLpgSQL_datum_type dtype
Definition: plpgsql.h:257
char * refname
Definition: plpgsql.h:373
PLpgSQL_datum ** datums
Definition: plpgsql.h:1071
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
uint64 rectupledescid
Definition: plpgsql.h:409
Oid collation
Definition: plpgsql.h:207
ExpandedRecordFieldInfo finfo
Definition: plpgsql.h:410
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:784
int32 atttypmod
Definition: plpgsql.h:209
#define elog(elevel,...)
Definition: elog.h:226
#define unlikely(x)
Definition: c.h:208
Oid rectypeid
Definition: plpgsql.h:387
char * fieldname
Definition: plpgsql.h:406
Oid typoid
Definition: plpgsql.h:202

◆ plpgsql_exec_trigger()

HeapTuple plpgsql_exec_trigger ( PLpgSQL_function func,
TriggerData trigdata 
)

Definition at line 886 of file pl_exec.c.

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_stmt, PLpgSQL_execstate::err_text, errcode(), errmsg(), ERROR, error_context_stack, exec_eval_cleanup(), exec_set_found(), exec_stmt(), 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().

888 {
889  PLpgSQL_execstate estate;
890  ErrorContextCallback plerrcontext;
891  int rc;
892  TupleDesc tupdesc;
893  PLpgSQL_rec *rec_new,
894  *rec_old;
895  HeapTuple rettup;
896 
897  /*
898  * Setup the execution state
899  */
900  plpgsql_estate_setup(&estate, func, NULL, NULL);
901  estate.trigdata = trigdata;
902 
903  /*
904  * Setup error traceback support for ereport()
905  */
906  plerrcontext.callback = plpgsql_exec_error_callback;
907  plerrcontext.arg = &estate;
908  plerrcontext.previous = error_context_stack;
909  error_context_stack = &plerrcontext;
910 
911  /*
912  * Make local execution copies of all the datums
913  */
914  estate.err_text = gettext_noop("during initialization of execution state");
915  copy_plpgsql_datums(&estate, func);
916 
917  /*
918  * Put the OLD and NEW tuples into record variables
919  *
920  * We set up expanded records for both variables even though only one may
921  * have a value. This allows record references to succeed in functions
922  * that are used for multiple trigger types. For example, we might have a
923  * test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')", which should
924  * work regardless of the current trigger type. If a value is actually
925  * fetched from an unsupplied tuple, it will read as NULL.
926  */
927  tupdesc = RelationGetDescr(trigdata->tg_relation);
928 
929  rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
930  rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
931 
932  rec_new->erh = make_expanded_record_from_tupdesc(tupdesc,
933  estate.datum_context);
934  rec_old->erh = make_expanded_record_from_exprecord(rec_new->erh,
935  estate.datum_context);
936 
937  if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
938  {
939  /*
940  * Per-statement triggers don't use OLD/NEW variables
941  */
942  }
943  else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
944  {
945  expanded_record_set_tuple(rec_new->erh, trigdata->tg_trigtuple,
946  false, false);
947  }
948  else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
949  {
950  expanded_record_set_tuple(rec_new->erh, trigdata->tg_newtuple,
951  false, false);
952  expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
953  false, false);
954 
955  /*
956  * In BEFORE trigger, stored generated columns are not computed yet,
957  * so make them null in the NEW row. (Only needed in UPDATE branch;
958  * in the INSERT case, they are already null, but in UPDATE, the field
959  * still contains the old value.) Alternatively, we could construct a
960  * whole new row structure without the generated columns, but this way
961  * seems more efficient and potentially less confusing.
962  */
963  if (tupdesc->constr && tupdesc->constr->has_generated_stored &&
964  TRIGGER_FIRED_BEFORE(trigdata->tg_event))
965  {
966  for (int i = 0; i < tupdesc->natts; i++)
967  if (TupleDescAttr(tupdesc, i)->attgenerated == ATTRIBUTE_GENERATED_STORED)
969  i + 1,
970  (Datum) 0,
971  true, /* isnull */
972  false, false);
973  }
974  }
975  else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
976  {
977  expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
978  false, false);
979  }
980  else
981  elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
982 
983  /* Make transition tables visible to this SPI connection */
984  rc = SPI_register_trigger_data(trigdata);
985  Assert(rc >= 0);
986 
987  estate.err_text = gettext_noop("during function entry");
988 
989  /*
990  * Set the magic variable FOUND to false
991  */
992  exec_set_found(&estate, false);
993 
994  /*
995  * Let the instrumentation plugin peek at this function
996  */
997  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
998  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
999 
1000  /*
1001  * Now call the toplevel block of statements
1002  */
1003  estate.err_text = NULL;
1004  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
1005  rc = exec_stmt(&estate, (PLpgSQL_stmt *) func->action);
1006  if (rc != PLPGSQL_RC_RETURN)
1007  {
1008  estate.err_stmt = NULL;
1009  estate.err_text = NULL;
1010  ereport(ERROR,
1011  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1012  errmsg("control reached end of trigger procedure without RETURN")));
1013  }
1014 
1015  estate.err_stmt = NULL;
1016  estate.err_text = gettext_noop("during function exit");
1017 
1018  if (estate.retisset)
1019  ereport(ERROR,
1020  (errcode(ERRCODE_DATATYPE_MISMATCH),
1021  errmsg("trigger procedure cannot return a set")));
1022 
1023  /*
1024  * Check that the returned tuple structure has the same attributes, the
1025  * relation that fired the trigger has. A per-statement trigger always
1026  * needs to return NULL, so we ignore any return value the function itself
1027  * produces (XXX: is this a good idea?)
1028  *
1029  * XXX This way it is possible, that the trigger returns a tuple where
1030  * attributes don't have the correct atttypmod's length. It's up to the
1031  * trigger's programmer to ensure that this doesn't happen. Jan
1032  */
1033  if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
1034  rettup = NULL;
1035  else
1036  {
1037  TupleDesc retdesc;
1038  TupleConversionMap *tupmap;
1039 
1040  /* We assume exec_stmt_return verified that result is composite */
1041  Assert(type_is_rowtype(estate.rettype));
1042 
1043  /* We can special-case expanded records for speed */
1045  {
1047 
1048  Assert(erh->er_magic == ER_MAGIC);
1049 
1050  /* Extract HeapTuple and TupleDesc */
1051  rettup = expanded_record_get_tuple(erh);
1052  Assert(rettup);
1053  retdesc = expanded_record_get_tupdesc(erh);
1054 
1055  if (retdesc != RelationGetDescr(trigdata->tg_relation))
1056  {
1057  /* check rowtype compatibility */
1058  tupmap = convert_tuples_by_position(retdesc,
1059  RelationGetDescr(trigdata->tg_relation),
1060  gettext_noop("returned row structure does not match the structure of the triggering table"));
1061  /* it might need conversion */
1062  if (tupmap)
1063  rettup = execute_attr_map_tuple(rettup, tupmap);
1064  /* no need to free map, we're about to return anyway */
1065  }
1066 
1067  /*
1068  * Copy tuple to upper executor memory. But if user just did
1069  * "return new" or "return old" without changing anything, there's
1070  * no need to copy; we can return the original tuple (which will
1071  * save a few cycles in trigger.c as well as here).
1072  */
1073  if (rettup != trigdata->tg_newtuple &&
1074  rettup != trigdata->tg_trigtuple)
1075  rettup = SPI_copytuple(rettup);
1076  }
1077  else
1078  {
1079  /* Convert composite datum to a HeapTuple and TupleDesc */
1080  HeapTupleData tmptup;
1081 
1082  retdesc = deconstruct_composite_datum(estate.retval, &tmptup);
1083  rettup = &tmptup;
1084 
1085  /* check rowtype compatibility */
1086  tupmap = convert_tuples_by_position(retdesc,
1087  RelationGetDescr(trigdata->tg_relation),
1088  gettext_noop("returned row structure does not match the structure of the triggering table"));
1089  /* it might need conversion */
1090  if (tupmap)
1091  rettup = execute_attr_map_tuple(rettup, tupmap);
1092 
1093  ReleaseTupleDesc(retdesc);
1094  /* no need to free map, we're about to return anyway */
1095 
1096  /* Copy tuple to upper executor memory */
1097  rettup = SPI_copytuple(rettup);
1098  }
1099  }
1100 
1101  /*
1102  * Let the instrumentation plugin peek at this function
1103  */
1104  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1105  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1106 
1107  /* Clean up any leftover temporary memory */
1108  plpgsql_destroy_econtext(&estate);
1109  exec_eval_cleanup(&estate);
1110  /* stmt_mcontext will be destroyed when function's main context is */
1111 
1112  /*
1113  * Pop the error context stack
1114  */
1115  error_context_stack = plerrcontext.previous;
1116 
1117  /*
1118  * Return the trigger's result
1119  */
1120  return rettup;
1121 }
void expanded_record_set_field_internal(ExpandedRecordHeader *erh, int fnumber, Datum newValue, bool isnull, bool expand_external, bool check_constraints)
static int exec_stmt(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
Definition: pl_exec.c:1940
HeapTuple expanded_record_get_tuple(ExpandedRecordHeader *erh)
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:322
void expanded_record_set_tuple(ExpandedRecordHeader *erh, HeapTuple tuple, bool copy, bool expand_external)
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:1100
#define RelationGetDescr(relation)
Definition: rel.h:445
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:65
PLpgSQL_stmt_block * action
Definition: plpgsql.h:1024
TriggerData * trigdata
Definition: plpgsql.h:1038
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1202
#define gettext_noop(x)
Definition: c.h:1117
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3876
ExpandedRecordHeader * erh
Definition: plpgsql.h:394
static TupleDesc deconstruct_composite_datum(Datum value, HeapTupleData *tmptup)
Definition: pl_exec.c:7345
int errcode(int sqlerrcode)
Definition: elog.c:570
HeapTuple SPI_copytuple(HeapTuple tuple)
Definition: spi.c:823
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:4020
void(* callback)(void *arg)
Definition: elog.h:254
struct ErrorContextCallback * previous
Definition: elog.h:253
static void copy_plpgsql_datums(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: pl_exec.c:1260
HeapTuple tg_trigtuple
Definition: trigger.h:35
PLpgSQL_datum ** datums
Definition: plpgsql.h:1071
ErrorContextCallback * error_context_stack
Definition: elog.c:88
bool has_generated_stored
Definition: tupdesc.h:45
#define ERROR
Definition: elog.h:43
TupleConstr * constr
Definition: tupdesc.h:85
static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
Definition: pl_exec.c:8238
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2433
HeapTuple execute_attr_map_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:387
#define ereport(elevel, rest)
Definition: elog.h:141
int SPI_register_trigger_data(TriggerData *tdata)
Definition: spi.c:2934
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:58
static TupleDesc expanded_record_get_tupdesc(ExpandedRecordHeader *erh)
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
#define TRIGGER_FIRED_BY_DELETE(event)
Definition: trigger.h:119
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1140
uintptr_t Datum
Definition: postgres.h:367
#define ER_MAGIC
ExpandedRecordHeader * make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh, MemoryContext parentcontext)
ExpandedRecordHeader * make_expanded_record_from_tupdesc(TupleDesc tupdesc, MemoryContext parentcontext)
const char * err_text
Definition: plpgsql.h:1101
HeapTuple tg_newtuple
Definition: trigger.h:36
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1141
#define Assert(condition)
Definition: c.h:732
TriggerEvent tg_event
Definition: trigger.h:33
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:8170
#define DatumGetPointer(X)
Definition: postgres.h:549
MemoryContext datum_context
Definition: plpgsql.h:1073
#define TRIGGER_FIRED_BEFORE(event)
Definition: trigger.h:134
#define TRIGGER_FIRED_BY_INSERT(event)
Definition: trigger.h:116
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define TRIGGER_FIRED_FOR_ROW(event)
Definition: trigger.h:128
#define TRIGGER_FIRED_BY_UPDATE(event)
Definition: trigger.h:122
Relation tg_relation
Definition: trigger.h:34

◆ plpgsql_free_function_memory()

void plpgsql_free_function_memory ( PLpgSQL_function func)

Definition at line 739 of file pl_funcs.c.

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

Referenced by delete_function(), and plpgsql_inline_handler().

740 {
741  int i;
742 
743  /* Better not call this on an in-use function */
744  Assert(func->use_count == 0);
745 
746  /* Release plans associated with variable declarations */
747  for (i = 0; i < func->ndatums; i++)
748  {
749  PLpgSQL_datum *d = func->datums[i];
750 
751  switch (d->dtype)
752  {
753  case PLPGSQL_DTYPE_VAR:
755  {
756  PLpgSQL_var *var = (PLpgSQL_var *) d;
757 
758  free_expr(var->default_val);
760  }
761  break;
762  case PLPGSQL_DTYPE_ROW:
763  break;
764  case PLPGSQL_DTYPE_REC:
765  {
766  PLpgSQL_rec *rec = (PLpgSQL_rec *) d;
767 
768  free_expr(rec->default_val);
769  }
770  break;
772  break;
774  free_expr(((PLpgSQL_arrayelem *) d)->subscript);
775  break;
776  default:
777  elog(ERROR, "unrecognized data type: %d", d->dtype);
778  }
779  }
780  func->ndatums = 0;
781 
782  /* Release plans in statement tree */
783  if (func->action)
784  free_block(func->action);
785  func->action = NULL;
786 
787  /*
788  * And finally, release all memory except the PLpgSQL_function struct
789  * itself (which has to be kept around because there may be multiple
790  * fn_extra pointers to it).
791  */
792  if (func->fn_cxt)
794  func->fn_cxt = NULL;
795 }
PLpgSQL_datum ** datums
Definition: plpgsql.h:1020
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
PLpgSQL_stmt_block * action
Definition: plpgsql.h:1024
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:307
PLpgSQL_datum_type dtype
Definition: plpgsql.h:257
#define ERROR
Definition: elog.h:43
PLpgSQL_expr * default_val
Definition: plpgsql.h:297
unsigned long use_count
Definition: plpgsql.h:1028
static void free_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:729
MemoryContext fn_cxt
Definition: plpgsql.h:989
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
int i
PLpgSQL_expr * default_val
Definition: plpgsql.h:377
static void free_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:486

◆ plpgsql_getdiag_kindname()

const char* plpgsql_getdiag_kindname ( PLpgSQL_getdiag_kind  kind)

Definition at line 304 of file pl_funcs.c.

References free_assert(), free_assign(), free_block(), free_call(), free_case(), free_close(), free_commit(), free_dynexecute(), free_dynfors(), free_execsql(), free_exit(), free_expr(), free_fetch(), free_forc(), free_foreach_a(), free_fori(), free_fors(), free_getdiag(), free_if(), free_loop(), free_open(), free_perform(), free_raise(), free_return(), free_return_next(), free_return_query(), free_rollback(), free_set(), free_stmt(), free_while(), PLPGSQL_GETDIAG_COLUMN_NAME, PLPGSQL_GETDIAG_CONSTRAINT_NAME, PLPGSQL_GETDIAG_CONTEXT, PLPGSQL_GETDIAG_DATATYPE_NAME, PLPGSQL_GETDIAG_ERROR_CONTEXT, PLPGSQL_GETDIAG_ERROR_DETAIL, PLPGSQL_GETDIAG_ERROR_HINT, PLPGSQL_GETDIAG_MESSAGE_TEXT, PLPGSQL_GETDIAG_RETURNED_SQLSTATE, PLPGSQL_GETDIAG_ROW_COUNT, PLPGSQL_GETDIAG_SCHEMA_NAME, and PLPGSQL_GETDIAG_TABLE_NAME.

Referenced by dump_getdiag().

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

◆ plpgsql_HashTableInit()

void plpgsql_HashTableInit ( void  )

Definition at line 2533 of file pl_comp.c.

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

Referenced by _PG_init().

2534 {
2535  HASHCTL ctl;
2536 
2537  /* don't allow double-initialization */
2538  Assert(plpgsql_HashTable == NULL);
2539 
2540  memset(&ctl, 0, sizeof(ctl));
2541  ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2542  ctl.entrysize = sizeof(plpgsql_HashEnt);
2543  plpgsql_HashTable = hash_create("PLpgSQL function hash",
2545  &ctl,
2546  HASH_ELEM | HASH_BLOBS);
2547 }
#define FUNCS_PER_USER
Definition: pl_comp.c:71
#define HASH_ELEM
Definition: hsearch.h:87
Size entrysize
Definition: hsearch.h:73
static HTAB * plpgsql_HashTable
Definition: pl_comp.c:63
struct plpgsql_hashent plpgsql_HashEnt
struct PLpgSQL_func_hashkey PLpgSQL_func_hashkey
#define HASH_BLOBS
Definition: hsearch.h:88
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:316
Size keysize
Definition: hsearch.h:72
#define Assert(condition)
Definition: c.h:732

◆ plpgsql_latest_lineno()

int plpgsql_latest_lineno ( void  )

Definition at line 572 of file pl_scanner.c.

References cur_line_num.

Referenced by plpgsql_compile_error_callback().

573 {
574  return cur_line_num;
575 }
static int cur_line_num
Definition: pl_scanner.c:128

◆ plpgsql_location_to_lineno()

int plpgsql_location_to_lineno ( int  location)

Definition at line 538 of file pl_scanner.c.

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

539 {
540  const char *loc;
541 
542  if (location < 0 || scanorig == NULL)
543  return 0; /* garbage in, garbage out */
544  loc = scanorig + location;
545 
546  /* be correct, but not fast, if input location goes backwards */
547  if (loc < cur_line_start)
549 
550  while (cur_line_end != NULL && loc > cur_line_end)
551  {
553  cur_line_num++;
554  cur_line_end = strchr(cur_line_start, '\n');
555  }
556 
557  return cur_line_num;
558 }
static int cur_line_num
Definition: pl_scanner.c:128
static void location_lineno_init(void)
Definition: pl_scanner.c:562
static const char * cur_line_start
Definition: pl_scanner.c:126
static const char * scanorig
Definition: pl_scanner.c:110
static const char * cur_line_end
Definition: pl_scanner.c:127

◆ plpgsql_ns_additem()

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

Definition at line 94 of file pl_funcs.c.

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

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

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

◆ plpgsql_ns_find_nearest_loop()

PLpgSQL_nsitem* plpgsql_ns_find_nearest_loop ( PLpgSQL_nsitem ns_cur)

Definition at line 216 of file pl_funcs.c.

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

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

◆ plpgsql_ns_init()

void plpgsql_ns_init ( void  )

Definition at line 45 of file pl_funcs.c.

Referenced by do_compile(), and plpgsql_compile_inline().

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

◆ plpgsql_ns_lookup()

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

Definition at line 132 of file pl_funcs.c.

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

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

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

◆ plpgsql_ns_lookup_label()

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

Definition at line 197 of file pl_funcs.c.

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

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

◆ plpgsql_ns_pop()

void plpgsql_ns_pop ( void  )

Definition at line 69 of file pl_funcs.c.

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

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

◆ plpgsql_ns_push()

void plpgsql_ns_push ( const char *  label,
PLpgSQL_label_type  label_type 
)

Definition at line 56 of file pl_funcs.c.

References plpgsql_ns_additem(), and PLPGSQL_NSTYPE_LABEL.

Referenced by do_compile(), and plpgsql_compile_inline().

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

◆ plpgsql_ns_top()

PLpgSQL_nsitem* plpgsql_ns_top ( void  )

Definition at line 83 of file pl_funcs.c.

References ns_top.

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

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

◆ plpgsql_parse_cwordrowtype()

PLpgSQL_type* plpgsql_parse_cwordrowtype ( List idents)

Definition at line 1806 of file pl_comp.c.

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

1807 {
1808  Oid classOid;
1809  RangeVar *relvar;
1810  MemoryContext oldCxt;
1811 
1812  /*
1813  * As above, this is a relation lookup but could be a type lookup if we
1814  * weren't being backwards-compatible about error wording.
1815  */
1816  if (list_length(idents) != 2)
1817  return NULL;
1818 
1819  /* Avoid memory leaks in long-term function context */
1821 
1822  /* Look up relation name. Can't lock it - we might not have privileges. */
1823  relvar = makeRangeVar(strVal(linitial(idents)),
1824  strVal(lsecond(idents)),
1825  -1);
1826  classOid = RangeVarGetRelid(relvar, NoLock, false);
1827 
1828  MemoryContextSwitchTo(oldCxt);
1829 
1830  /* Build and return the row type struct */
1831  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid,
1832  makeTypeNameFromNameList(idents));
1833 }
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:63
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
#define lsecond(l)
Definition: pg_list.h:200
#define linitial(l)
Definition: pg_list.h:195
#define NoLock
Definition: lockdefs.h:34
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2049
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1781
#define InvalidOid
Definition: postgres_ext.h:36
static int list_length(const List *l)
Definition: pg_list.h:169
TypeName * makeTypeNameFromNameList(List *names)
Definition: makefuncs.c:454
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:420

◆ plpgsql_parse_cwordtype()

PLpgSQL_type* plpgsql_parse_cwordtype ( List idents)

Definition at line 1658 of file pl_comp.c.

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

1659 {
1660  PLpgSQL_type *dtype = NULL;
1661  PLpgSQL_nsitem *nse;
1662  const char *fldname;
1663  Oid classOid;
1664  HeapTuple classtup = NULL;
1665  HeapTuple attrtup = NULL;
1666  HeapTuple typetup = NULL;
1667  Form_pg_class classStruct;
1668  Form_pg_attribute attrStruct;
1669  MemoryContext oldCxt;
1670 
1671  /* Avoid memory leaks in the long-term function context */
1673 
1674  if (list_length(idents) == 2)
1675  {
1676  /*
1677  * Do a lookup in the current namespace stack. We don't need to check
1678  * number of names matched, because we will only consider scalar
1679  * variables.
1680  */
1681  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1682  strVal(linitial(idents)),
1683  strVal(lsecond(idents)),
1684  NULL,
1685  NULL);
1686 
1687  if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1688  {
1689  dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1690  goto done;
1691  }
1692 
1693  /*
1694  * First word could also be a table name
1695  */
1696  classOid = RelnameGetRelid(strVal(linitial(idents)));
1697  if (!OidIsValid(classOid))
1698  goto done;
1699  fldname = strVal(lsecond(idents));
1700  }
1701  else if (list_length(idents) == 3)
1702  {
1703  RangeVar *relvar;
1704 
1705  relvar = makeRangeVar(strVal(linitial(idents)),
1706  strVal(lsecond(idents)),
1707  -1);
1708  /* Can't lock relation - we might not have privileges. */
1709  classOid = RangeVarGetRelid(relvar, NoLock, true);
1710  if (!OidIsValid(classOid))
1711  goto done;
1712  fldname = strVal(lthird(idents));
1713  }
1714  else
1715  goto done;
1716 
1717  classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(classOid));
1718  if (!HeapTupleIsValid(classtup))
1719  goto done;
1720  classStruct = (Form_pg_class) GETSTRUCT(classtup);
1721 
1722  /*
1723  * It must be a relation, sequence, view, materialized view, composite
1724  * type, or foreign table
1725  */
1726  if (classStruct->relkind != RELKIND_RELATION &&
1727  classStruct->relkind != RELKIND_SEQUENCE &&
1728  classStruct->relkind != RELKIND_VIEW &&
1729  classStruct->relkind != RELKIND_MATVIEW &&
1730  classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
1731  classStruct->relkind != RELKIND_FOREIGN_TABLE &&
1732  classStruct->relkind != RELKIND_PARTITIONED_TABLE)
1733  goto done;
1734 
1735  /*
1736  * Fetch the named table field and its type
1737  */
1738  attrtup = SearchSysCacheAttName(classOid, fldname);
1739  if (!HeapTupleIsValid(attrtup))
1740  goto done;
1741  attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1742 
1743  typetup = SearchSysCache1(TYPEOID,
1744  ObjectIdGetDatum(attrStruct->atttypid));
1745  if (!HeapTupleIsValid(typetup))
1746  elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1747 
1748  /*
1749  * Found that - build a compiler type struct in the caller's cxt and
1750  * return it. Note that we treat the type as being found-by-OID; no
1751  * attempt to re-look-up the type name will happen during invalidations.
1752  */
1753  MemoryContextSwitchTo(oldCxt);
1754  dtype = build_datatype(typetup,
1755  attrStruct->atttypmod,
1756  attrStruct->attcollation,
1757  NULL);
1759 
1760 done:
1761  if (HeapTupleIsValid(classtup))
1762  ReleaseSysCache(classtup);
1763  if (HeapTupleIsValid(attrtup))
1764  ReleaseSysCache(attrtup);
1765  if (HeapTupleIsValid(typetup))
1766  ReleaseSysCache(typetup);
1767 
1768  MemoryContextSwitchTo(oldCxt);
1769  return dtype;
1770 }
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:672
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2071
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:63
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define lsecond(l)
Definition: pg_list.h:200
#define linitial(l)
Definition: pg_list.h:195
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static int list_length(const List *l)
Definition: pg_list.h:169
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1265
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:443
#define elog(elevel,...)
Definition: elog.h:226
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
#define lthird(l)
Definition: pg_list.h:205
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:420

◆ plpgsql_parse_dblword()

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

Definition at line 1444 of file pl_comp.c.

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_IdentifierLookup, plpgsql_ns_lookup(), plpgsql_ns_top(), PLPGSQL_NSTYPE_REC, PLPGSQL_NSTYPE_VAR, and PLwdatum::quoted.

Referenced by plpgsql_yylex().

1446 {
1447  PLpgSQL_nsitem *ns;
1448  List *idents;
1449  int nnames;
1450 
1451  idents = list_make2(makeString(word1),
1452  makeString(word2));
1453 
1454  /*
1455  * We should do nothing in DECLARE sections. In SQL expressions, we
1456  * really only need to make sure that RECFIELD datums are created when
1457  * needed.
1458  */
1460  {
1461  /*
1462  * Do a lookup in the current namespace stack
1463  */
1464  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1465  word1, word2, NULL,
1466  &nnames);
1467  if (ns != NULL)
1468  {
1469  switch (ns->itemtype)
1470  {
1471  case PLPGSQL_NSTYPE_VAR:
1472  /* Block-qualified reference to scalar variable. */
1473  wdatum->datum = plpgsql_Datums[ns->itemno];
1474  wdatum->ident = NULL;
1475  wdatum->quoted = false; /* not used */
1476  wdatum->idents = idents;
1477  return true;
1478 
1479  case PLPGSQL_NSTYPE_REC:
1480  if (nnames == 1)
1481  {
1482  /*
1483  * First word is a record name, so second word could
1484  * be a field in this record. We build a RECFIELD
1485  * datum whether it is or not --- any error will be
1486  * detected later.
1487  */
1488  PLpgSQL_rec *rec;
1489  PLpgSQL_recfield *new;
1490 
1491  rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1492  new = plpgsql_build_recfield(rec, word2);
1493 
1494  wdatum->datum = (PLpgSQL_datum *) new;
1495  }
1496  else
1497  {
1498  /* Block-qualified reference to record variable. */
1499  wdatum->datum = plpgsql_Datums[ns->itemno];
1500  }
1501  wdatum->ident = NULL;
1502  wdatum->quoted = false; /* not used */
1503  wdatum->idents = idents;
1504  return true;
1505 
1506  default:
1507  break;
1508  }
1509  }
1510  }
1511 
1512  /* Nothing found */
1513  cword->idents = idents;
1514  return false;
1515 }
#define list_make2(x1, x2)
Definition: pg_list.h:229
Value * makeString(char *str)
Definition: value.c:53
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
Definition: pl_comp.c:2002
List * idents
Definition: plpgsql.h:1163
List * idents
Definition: plpgsql.h:1171
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:26
PLpgSQL_datum * datum
Definition: plpgsql.h:1168
bool quoted
Definition: plpgsql.h:1170
char * ident
Definition: plpgsql.h:1169
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:443
Definition: pg_list.h:50

◆ plpgsql_parse_err_condition()

PLpgSQL_condition* plpgsql_parse_err_condition ( char *  condname)

Definition at line 2223 of file pl_comp.c.

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

2224 {
2225  int i;
2226  PLpgSQL_condition *new;
2227  PLpgSQL_condition *prev;
2228 
2229  /*
2230  * XXX Eventually we will want to look for user-defined exception names
2231  * here.
2232  */
2233 
2234  /*
2235  * OTHERS is represented as code 0 (which would map to '00000', but we
2236  * have no need to represent that as an exception condition).
2237  */
2238  if (strcmp(condname, "others") == 0)
2239  {
2240  new = palloc(sizeof(PLpgSQL_condition));
2241  new->sqlerrstate = 0;
2242  new->condname = condname;
2243  new->next = NULL;
2244  return new;
2245  }
2246 
2247  prev = NULL;
2248  for (i = 0; exception_label_map[i].label != NULL; i++)
2249  {
2250  if (strcmp(condname, exception_label_map[i].label) == 0)
2251  {
2252  new = palloc(sizeof(PLpgSQL_condition));
2253  new->sqlerrstate = exception_label_map[i].sqlerrstate;
2254  new->condname = condname;
2255  new->next = prev;
2256  prev = new;
2257  }
2258  }
2259 
2260  if (!prev)
2261  ereport(ERROR,
2262  (errcode(ERRCODE_UNDEFINED_OBJECT),
2263  errmsg("unrecognized exception condition \"%s\"",
2264  condname)));
2265 
2266  return prev;
2267 }
const char * label
Definition: pl_comp.c:79
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static char * label
Definition: pg_basebackup.c:86
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:83
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i

◆ plpgsql_parse_tripword()

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

Definition at line 1524 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

1526 {
1527  PLpgSQL_nsitem *ns;
1528  List *idents;
1529  int nnames;
1530 
1531  idents = list_make3(makeString(word1),
1532  makeString(word2),
1533  makeString(word3));
1534 
1535  /*
1536  * We should do nothing in DECLARE sections. In SQL expressions, we
1537  * really only need to make sure that RECFIELD datums are created when
1538  * needed.
1539  */
1541  {
1542  /*
1543  * Do a lookup in the current namespace stack. Must find a qualified
1544  * reference, else ignore.
1545  */
1546  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1547  word1, word2, word3,
1548  &nnames);
1549  if (ns != NULL && nnames == 2)
1550  {
1551  switch (ns->itemtype)
1552  {
1553  case PLPGSQL_NSTYPE_REC:
1554  {
1555  /*
1556  * words 1/2 are a record name, so third word could be
1557  * a field in this record.
1558  */
1559  PLpgSQL_rec *rec;
1560  PLpgSQL_recfield *new;
1561 
1562  rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1563  new = plpgsql_build_recfield(rec, word3);
1564 
1565  wdatum->datum = (PLpgSQL_datum *) new;
1566  wdatum->ident = NULL;
1567  wdatum->quoted = false; /* not used */
1568  wdatum->idents = idents;
1569  return true;
1570  }
1571 
1572  default:
1573  break;
1574  }
1575  }
1576  }
1577 
1578  /* Nothing found */
1579  cword->idents = idents;
1580  return false;
1581 }
Value * makeString(char *str)
Definition: value.c:53
#define list_make3(x1, x2, x3)
Definition: pg_list.h:231
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
Definition: pl_comp.c:2002
List * idents
Definition: plpgsql.h:1163
List * idents
Definition: plpgsql.h:1171
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:26
PLpgSQL_datum * datum
Definition: plpgsql.h:1168
bool quoted
Definition: plpgsql.h:1170
char * ident
Definition: plpgsql.h:1169
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:443
Definition: pg_list.h:50

◆ plpgsql_parse_word()

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

Definition at line 1389 of file pl_comp.c.

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

Referenced by plpgsql_yylex().

1391 {
1392  PLpgSQL_nsitem *ns;
1393 
1394  /*
1395  * We should not lookup variables in DECLARE sections. In SQL
1396  * expressions, there's no need to do so either --- lookup will happen
1397  * when the expression is compiled.
1398  */
1400  {
1401  /*
1402  * Do a lookup in the current namespace stack
1403  */
1404  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1405  word1, NULL, NULL,
1406  NULL);
1407 
1408  if (ns != NULL)
1409  {
1410  switch (ns->itemtype)
1411  {
1412  case PLPGSQL_NSTYPE_VAR:
1413  case PLPGSQL_NSTYPE_REC:
1414  wdatum->datum = plpgsql_Datums[ns->itemno];
1415  wdatum->ident = word1;
1416  wdatum->quoted = (yytxt[0] == '"');
1417  wdatum->idents = NIL;
1418  return true;
1419 
1420  default:
1421  /* plpgsql_ns_lookup should never return anything else */
1422  elog(ERROR, "unrecognized plpgsql itemtype: %d",
1423  ns->itemtype);
1424  }
1425  }
1426  }
1427 
1428  /*
1429  * Nothing found - up to now it's a word without any special meaning for
1430  * us.
1431  */
1432  word->ident = word1;
1433  word->quoted = (yytxt[0] == '"');
1434  return false;
1435 }
#define NIL
Definition: pg_list.h:65
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
char * ident
Definition: plpgsql.h:1157
#define ERROR
Definition: elog.h:43
Definition: zic.c:298
List * idents
Definition: plpgsql.h:1171
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:26
bool quoted
Definition: plpgsql.h:1158
PLpgSQL_datum * datum
Definition: plpgsql.h:1168
bool quoted
Definition: plpgsql.h:1170
char * ident
Definition: plpgsql.h:1169
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:443
#define elog(elevel,...)
Definition: elog.h:226

◆ plpgsql_parse_wordrowtype()

PLpgSQL_type* plpgsql_parse_wordrowtype ( char *  ident)

Definition at line 1778 of file pl_comp.c.

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

1779 {
1780  Oid classOid;
1781 
1782  /*
1783  * Look up the relation. Note that because relation rowtypes have the
1784  * same names as their relations, this could be handled as a type lookup
1785  * equally well; we use the relation lookup code path only because the
1786  * errors thrown here have traditionally referred to relations not types.
1787  * But we'll make a TypeName in case we have to do re-look-up of the type.
1788  */
1789  classOid = RelnameGetRelid(ident);
1790  if (!OidIsValid(classOid))
1791  ereport(ERROR,
1793  errmsg("relation \"%s\" does not exist", ident)));
1794 
1795  /* Build and return the row type struct */
1796  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid,
1797  makeTypeName(ident));
1798 }
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:72
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:672
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2049
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1781
#define InvalidOid
Definition: postgres_ext.h:36
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:442
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ plpgsql_parse_wordtype()

PLpgSQL_type* plpgsql_parse_wordtype ( char *  ident)

Definition at line 1592 of file pl_comp.c.

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

1593 {
1594  PLpgSQL_type *dtype;
1595  PLpgSQL_nsitem *nse;
1596  TypeName *typeName;
1597  HeapTuple typeTup;
1598 
1599  /*
1600  * Do a lookup in the current namespace stack
1601  */
1602  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1603  ident, NULL, NULL,
1604  NULL);
1605 
1606  if (nse != NULL)
1607  {
1608  switch (nse->itemtype)
1609  {
1610  case PLPGSQL_NSTYPE_VAR:
1611  return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1612 
1613  /* XXX perhaps allow REC/ROW here? */
1614 
1615  default:
1616  return NULL;
1617  }
1618  }
1619 
1620  /*
1621  * Word wasn't found in the namespace stack. Try to find a data type with
1622  * that name, but ignore shell types and complex types.
1623  */
1624  typeName = makeTypeName(ident);
1625  typeTup = LookupTypeName(NULL, typeName, NULL, false);
1626  if (typeTup)
1627  {
1628  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1629 
1630  if (!typeStruct->typisdefined ||
1631  typeStruct->typrelid != InvalidOid)
1632  {
1633  ReleaseSysCache(typeTup);
1634  return NULL;
1635  }
1636 
1637  dtype = build_datatype(typeTup, -1,
1639  typeName);
1640 
1641  ReleaseSysCache(typeTup);
1642  return dtype;
1643  }
1644 
1645  /*
1646  * Nothing found - up to now it's a word without any special meaning for
1647  * us.
1648  */
1649  return NULL;
1650 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:39
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
Definition: pl_comp.c:2071
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
Oid fn_input_collation
Definition: plpgsql.h:987
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define InvalidOid
Definition: postgres_ext.h:36
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:442
FormData_pg_type * Form_pg_type
Definition: pg_type.h:251
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:443
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:54

◆ plpgsql_parser_setup()

void plpgsql_parser_setup ( struct ParseState pstate,
PLpgSQL_expr expr 
)

Definition at line 1074 of file pl_comp.c.

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

Referenced by exec_prepare_plan(), and plpgsql_estate_setup().

1075 {
1079  /* no need to use p_coerce_param_hook */
1080  pstate->p_ref_hook_state = (void *) expr;
1081 }
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1087
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:216
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:217
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1145
void * p_ref_hook_state
Definition: parse_node.h:219
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:215
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1101

◆ plpgsql_peek()

int plpgsql_peek ( void  )

Definition at line 420 of file pl_scanner.c.

References internal_yylex(), and push_back_token().

421 {
422  int tok1;
423  TokenAuxData aux1;
424 
425  tok1 = internal_yylex(&aux1);
426  push_back_token(tok1, &aux1);
427  return tok1;
428 }
static int internal_yylex(TokenAuxData *auxdata)
Definition: pl_scanner.c:308
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:354

◆ plpgsql_peek2()

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

Definition at line 439 of file pl_scanner.c.

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

440 {
441  int tok1,
442  tok2;
443  TokenAuxData aux1,
444  aux2;
445 
446  tok1 = internal_yylex(&aux1);
447  tok2 = internal_yylex(&aux2);
448 
449  *tok1_p = tok1;
450  if (tok1_loc)
451  *tok1_loc = aux1.lloc;
452  *tok2_p = tok2;
453  if (tok2_loc)
454  *tok2_loc = aux2.lloc;
455 
456  push_back_token(tok2, &aux2);
457  push_back_token(tok1, &aux1);
458 }
YYLTYPE lloc
Definition: pl_scanner.c:94
static int internal_yylex(TokenAuxData *auxdata)
Definition: pl_scanner.c:308
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:354

◆ plpgsql_push_back_token()

void plpgsql_push_back_token ( int  token)

Definition at line 370 of file pl_scanner.c.

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

371 {
372  TokenAuxData auxdata;
373 
374  auxdata.lval = plpgsql_yylval;
375  auxdata.lloc = plpgsql_yylloc;
376  auxdata.leng = plpgsql_yyleng;
377  push_back_token(token, &auxdata);
378 }
YYLTYPE lloc
Definition: pl_scanner.c:94
YYSTYPE lval
Definition: pl_scanner.c:93
static int plpgsql_yyleng
Definition: pl_scanner.c:113
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:354

◆ plpgsql_recognize_err_condition()

int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2187 of file pl_comp.c.

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

Referenced by exec_stmt_raise().

2188 {
2189  int i;
2190 
2191  if (allow_sqlstate)
2192  {
2193  if (strlen(condname) == 5 &&
2194  strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2195  return MAKE_SQLSTATE(condname[0],
2196  condname[1],
2197  condname[2],
2198  condname[3],
2199  condname[4]);
2200  }
2201 
2202  for (i = 0; exception_label_map[i].label != NULL; i++)
2203  {
2204  if (strcmp(condname, exception_label_map[i].label) == 0)
2206  }
2207 
2208  ereport(ERROR,
2209  (errcode(ERRCODE_UNDEFINED_OBJECT),
2210  errmsg("unrecognized exception condition \"%s\"",
2211  condname)));
2212  return 0; /* keep compiler quiet */
2213 }
const char * label
Definition: pl_comp.c:79
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:62
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static char * label
Definition: pg_basebackup.c:86
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:83
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i

◆ plpgsql_scanner_errposition()

int plpgsql_scanner_errposition ( int  location)

Definition at line 472 of file pl_scanner.c.

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

Referenced by plpgsql_yyerror().

473 {
474  int pos;
475 
476  if (location < 0 || scanorig == NULL)
477  return 0; /* no-op if location is unknown */
478 
479  /* Convert byte offset to character number */
480  pos = pg_mbstrlen_with_len(scanorig, location) + 1;
481  /* And pass it to the ereport mechanism */
482  (void) internalerrposition(pos);
483  /* Also pass the function body string */
484  return internalerrquery(scanorig);
485 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:836
static const char * scanorig
Definition: pl_scanner.c:110
int internalerrquery(const char *query)
Definition: elog.c:1148
int internalerrposition(int cursorpos)
Definition: elog.c:1128

◆ plpgsql_scanner_finish()

void plpgsql_scanner_finish ( void  )

Definition at line 613 of file pl_scanner.c.

References scanner_finish(), scanorig, and yyscanner.

Referenced by do_compile(), and plpgsql_compile_inline().

614 {
615  /* release storage */
617  /* avoid leaving any dangling pointers */
618  yyscanner = NULL;
619  scanorig = NULL;
620 }
static const char * scanorig
Definition: pl_scanner.c:110
static core_yyscan_t yyscanner
Definition: pl_scanner.c:106
void scanner_finish(core_yyscan_t yyscanner)

◆ plpgsql_scanner_init()

void plpgsql_scanner_init ( const char *  str)

Definition at line 586 of file pl_scanner.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

587 {
588  /* Start up the core scanner */
590  &ReservedPLKeywords, ReservedPLKeywordTokens);
591 
592  /*
593  * scanorig points to the original string, which unlike the scanner's
594  * scanbuf won't be modified on-the-fly by flex. Notice that although
595  * yytext points into scanbuf, we rely on being able to apply locations
596  * (offsets from string start) to scanorig as well.
597  */
598  scanorig = str;
599 
600  /* Other setup */
602  plpgsql_yytoken = 0;
603 
604  num_pushbacks = 0;
605 
607 }
static void location_lineno_init(void)
Definition: pl_scanner.c:562
static int plpgsql_yytoken
Definition: pl_scanner.c:116
core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, const ScanKeywordList *keywordlist, const uint16 *keyword_tokens)
static const char * scanorig
Definition: pl_scanner.c:110
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:26
static int num_pushbacks
Definition: pl_scanner.c:121
static core_yy_extra_type core_yy
Definition: pl_scanner.c:107
static const uint16 ReservedPLKeywordTokens[]
Definition: pl_scanner.c:66
static core_yyscan_t yyscanner
Definition: pl_scanner.c:106

◆ plpgsql_stmt_typename()

const char* plpgsql_stmt_typename ( PLpgSQL_stmt stmt)

Definition at line 234 of file pl_funcs.c.

References _, PLpgSQL_stmt::cmd_type, PLPGSQL_STMT_ASSERT, PLPGSQL_STMT_ASSIGN, PLPGSQL_STMT_BLOCK, PLPGSQL_STMT_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_SET, and PLPGSQL_STMT_WHILE.

Referenced by plpgsql_exec_error_callback().

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

◆ plpgsql_subxact_cb()

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

Definition at line 8291 of file pl_exec.c.

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

Referenced by _PG_init(), and plpgsql_inline_handler().

8293 {
8294  if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
8295  {
8296  while (simple_econtext_stack != NULL &&
8297  simple_econtext_stack->xact_subxid == mySubid)
8298  {
8300 
8302  (event == SUBXACT_EVENT_COMMIT_SUB));
8303  next = simple_econtext_stack->next;
8306  }
8307  }
8308 }
static int32 next
Definition: blutils.c:215
struct SimpleEcontextStackEntry * next
Definition: pl_exec.c:92
void pfree(void *pointer)
Definition: mcxt.c:1056
ExprContext * stack_econtext
Definition: pl_exec.c:90
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:96
SubTransactionId xact_subxid
Definition: pl_exec.c:91
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:375

◆ plpgsql_token_is_unreserved_keyword()

bool plpgsql_token_is_unreserved_keyword ( int  token)

Definition at line 387 of file pl_scanner.c.

References i, lengthof, and UnreservedPLKeywordTokens.

388 {
389  int i;
390 
391  for (i = 0; i < lengthof(UnreservedPLKeywordTokens); i++)
392  {
393  if (UnreservedPLKeywordTokens[i] == token)
394  return true;
395  }
396  return false;
397 }
#define lengthof(array)
Definition: c.h:662
static const uint16 UnreservedPLKeywordTokens[]
Definition: pl_scanner.c:70
int i

◆ plpgsql_xact_cb()

void plpgsql_xact_cb ( XactEvent  event,
void *  arg 
)

Definition at line 8260 of file pl_exec.c.

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

Referenced by _PG_init().

8261 {
8262  /*
8263  * If we are doing a clean transaction shutdown, free the EState (so that
8264  * any remaining resources will be released correctly). In an abort, we
8265  * expect the regular abort recovery procedures to release everything of
8266  * interest.
8267  */
8268  if (event == XACT_EVENT_COMMIT || event == XACT_EVENT_PREPARE)
8269  {
8270  simple_econtext_stack = NULL;
8271 
8275  }
8276  else if (event == XACT_EVENT_ABORT)
8277  {
8278  simple_econtext_stack = NULL;
8280  }
8281 }
void FreeExecutorState(EState *estate)
Definition: execUtils.c:190
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:96
static EState * shared_simple_eval_estate
Definition: pl_exec.c:95

◆ plpgsql_yyerror()

void plpgsql_yyerror ( const char *  message)

Definition at line 499 of file pl_scanner.c.

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

500 {
501  char *yytext = core_yy.scanbuf + plpgsql_yylloc;
502 
503  if (*yytext == '\0')
504  {
505  ereport(ERROR,
506  (errcode(ERRCODE_SYNTAX_ERROR),
507  /* translator: %s is typically the translation of "syntax error" */
508  errmsg("%s at end of input", _(message)),
509  plpgsql_scanner_errposition(plpgsql_yylloc)));
510  }
511  else
512  {
513  /*
514  * If we have done any lookahead then flex will have restored the
515  * character after the end-of-token. Zap it again so that we report
516  * only the single token here. This modifies scanbuf but we no longer
517  * care about that.
518  */
519  yytext[plpgsql_yyleng] = '\0';
520 
521  ereport(ERROR,
522  (errcode(ERRCODE_SYNTAX_ERROR),
523  /* translator: first %s is typically the translation of "syntax error" */
524  errmsg("%s at or near \"%s\"", _(message), yytext),
525  plpgsql_scanner_errposition(plpgsql_yylloc)));
526  }
527 }
int errcode(int sqlerrcode)
Definition: elog.c:570
char * scanbuf
Definition: scanner.h:72
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static core_yy_extra_type core_yy
Definition: pl_scanner.c:107
static int plpgsql_yyleng
Definition: pl_scanner.c:113
int plpgsql_scanner_errposition(int location)
Definition: pl_scanner.c:472
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define _(x)
Definition: elog.c:84

◆ plpgsql_yylex()

int plpgsql_yylex ( void  )

Definition at line 146 of file pl_scanner.c.

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

147 {
148  int tok1;
149  TokenAuxData aux1;
150  int kwnum;
151 
152  tok1 = internal_yylex(&aux1);
153  if (tok1 == IDENT || tok1 == PARAM)
154  {
155  int tok2;
156  TokenAuxData aux2;
157 
158  tok2 = internal_yylex(&aux2);
159  if (tok2 == '.')
160  {
161  int tok3;
162  TokenAuxData aux3;
163 
164  tok3 = internal_yylex(&aux3);
165  if (tok3 == IDENT)
166  {
167  int tok4;
168  TokenAuxData aux4;
169 
170  tok4 = internal_yylex(&aux4);
171  if (tok4 == '.')
172  {
173  int tok5;
174  TokenAuxData aux5;
175 
176  tok5 = internal_yylex(&aux5);
177  if (tok5 == IDENT)
178  {
179  if (plpgsql_parse_tripword(aux1.lval.str,
180  aux3.lval.str,
181  aux5.lval.str,
182  &aux1.lval.wdatum,
183  &aux1.lval.cword))
184  tok1 = T_DATUM;
185  else
186  tok1 = T_CWORD;
187