PostgreSQL Source Code  git master
plpgsql.h File Reference
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
 
#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_RESULT_OID, PLPGSQL_GETDIAG_CONTEXT, PLPGSQL_GETDIAG_ERROR_CONTEXT,
  PLPGSQL_GETDIAG_ERROR_DETAIL, PLPGSQL_GETDIAG_ERROR_HINT, PLPGSQL_GETDIAG_RETURNED_SQLSTATE, PLPGSQL_GETDIAG_COLUMN_NAME,
  PLPGSQL_GETDIAG_CONSTRAINT_NAME, PLPGSQL_GETDIAG_DATATYPE_NAME, PLPGSQL_GETDIAG_MESSAGE_TEXT, PLPGSQL_GETDIAG_TABLE_NAME,
  PLPGSQL_GETDIAG_SCHEMA_NAME
}
 
enum  PLpgSQL_raise_option_type {
  PLPGSQL_RAISEOPTION_ERRCODE, PLPGSQL_RAISEOPTION_MESSAGE, PLPGSQL_RAISEOPTION_DETAIL, PLPGSQL_RAISEOPTION_HINT,
  PLPGSQL_RAISEOPTION_COLUMN, PLPGSQL_RAISEOPTION_CONSTRAINT, PLPGSQL_RAISEOPTION_DATATYPE, PLPGSQL_RAISEOPTION_TABLE,
  PLPGSQL_RAISEOPTION_SCHEMA
}
 
enum  PLpgSQL_resolve_option { PLPGSQL_RESOLVE_ERROR, PLPGSQL_RESOLVE_VARIABLE, PLPGSQL_RESOLVE_COLUMN }
 
enum  PLpgSQL_trigtype { PLPGSQL_DML_TRIGGER, PLPGSQL_EVENT_TRIGGER, PLPGSQL_NOT_TRIGGER }
 
enum  IdentifierLookup { IDENTIFIER_LOOKUP_NORMAL, IDENTIFIER_LOOKUP_DECLARE, IDENTIFIER_LOOKUP_EXPR }
 

Functions

PLpgSQL_functionplpgsql_compile (FunctionCallInfo fcinfo, bool forValidator)
 
PLpgSQL_functionplpgsql_compile_inline (char *proc_source)
 
void plpgsql_parser_setup (struct ParseState *pstate, PLpgSQL_expr *expr)
 
bool plpgsql_parse_word (char *word1, const char *yytxt, PLwdatum *wdatum, PLword *word)
 
bool plpgsql_parse_dblword (char *word1, char *word2, PLwdatum *wdatum, PLcword *cword)
 
bool plpgsql_parse_tripword (char *word1, char *word2, char *word3, PLwdatum *wdatum, PLcword *cword)
 
PLpgSQL_typeplpgsql_parse_wordtype (char *ident)
 
PLpgSQL_typeplpgsql_parse_cwordtype (List *idents)
 
PLpgSQL_typeplpgsql_parse_wordrowtype (char *ident)
 
PLpgSQL_typeplpgsql_parse_cwordrowtype (List *idents)
 
PLpgSQL_typeplpgsql_build_datatype (Oid typeOid, int32 typmod, Oid collation)
 
PLpgSQL_variableplpgsql_build_variable (const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
 
PLpgSQL_recplpgsql_build_record (const char *refname, int lineno, 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 *new)
 
int plpgsql_add_initdatums (int **varnos)
 
void plpgsql_HashTableInit (void)
 
void _PG_init (void)
 
Datum plpgsql_exec_function (PLpgSQL_function *func, FunctionCallInfo fcinfo, EState *simple_eval_estate, 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 35 of file plpgsql.h.

◆ PLPGSQL_XCHECK_ALL

#define PLPGSQL_XCHECK_ALL   ((int) ~0)

Definition at line 1141 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_NONE

#define PLPGSQL_XCHECK_NONE   0

Definition at line 1139 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ PLPGSQL_XCHECK_SHADOWVAR

#define PLPGSQL_XCHECK_SHADOWVAR   1

Definition at line 1140 of file plpgsql.h.

Referenced by plpgsql_extra_checks_check_hook().

◆ TEXTDOMAIN

#define TEXTDOMAIN   PG_TEXTDOMAIN("plpgsql")

Definition at line 32 of file plpgsql.h.

Typedef Documentation

◆ PLcword

◆ PLpgSQL_arrayelem

◆ PLpgSQL_case_when

◆ PLpgSQL_condition

◆ PLpgSQL_datum

◆ PLpgSQL_datum_type

◆ PLpgSQL_diag_item

◆ PLpgSQL_exception

◆ PLpgSQL_exception_block

◆ PLpgSQL_execstate

◆ PLpgSQL_expr

◆ PLpgSQL_func_hashkey

◆ PLpgSQL_function

◆ PLpgSQL_getdiag_kind

◆ PLpgSQL_if_elsif

◆ PLpgSQL_label_type

◆ PLpgSQL_nsitem

◆ PLpgSQL_nsitem_type

◆ PLpgSQL_plugin

◆ PLpgSQL_promise_type

◆ PLpgSQL_raise_option

◆ PLpgSQL_raise_option_type

◆ PLpgSQL_rec

◆ PLpgSQL_recfield

◆ PLpgSQL_resolve_option

◆ PLpgSQL_row

◆ PLpgSQL_stmt

◆ PLpgSQL_stmt_assert

◆ PLpgSQL_stmt_assign

◆ PLpgSQL_stmt_block

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

◆ PLpgSQL_type_type

◆ PLpgSQL_var

◆ PLpgSQL_variable

◆ PLwdatum

◆ PLword

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
PLPGSQL_RC_OK 
PLPGSQL_RC_EXIT 
PLPGSQL_RC_RETURN 
PLPGSQL_RC_CONTINUE 

Definition at line 137 of file plpgsql.h.

◆ IdentifierLookup

Enumerator
IDENTIFIER_LOOKUP_NORMAL 
IDENTIFIER_LOOKUP_DECLARE 
IDENTIFIER_LOOKUP_EXPR 

Definition at line 1123 of file plpgsql.h.

1124 {
1125  IDENTIFIER_LOOKUP_NORMAL, /* normal processing of var names */
1126  IDENTIFIER_LOOKUP_DECLARE, /* In DECLARE --- don't look up names */
1127  IDENTIFIER_LOOKUP_EXPR /* In SQL expression --- special case */
IdentifierLookup
Definition: plpgsql.h:1123

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

◆ PLpgSQL_getdiag_kind

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

Definition at line 148 of file plpgsql.h.

◆ PLpgSQL_label_type

Enumerator
PLPGSQL_LABEL_BLOCK 
PLPGSQL_LABEL_LOOP 
PLPGSQL_LABEL_OTHER 

Definition at line 50 of file plpgsql.h.

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

◆ PLpgSQL_nsitem_type

Enumerator
PLPGSQL_NSTYPE_LABEL 
PLPGSQL_NSTYPE_VAR 
PLPGSQL_NSTYPE_REC 

Definition at line 40 of file plpgsql.h.

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

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

103 {
PLpgSQL_stmt_type
Definition: plpgsql.h:102

◆ PLpgSQL_trigtype

Enumerator
PLPGSQL_DML_TRIGGER 
PLPGSQL_EVENT_TRIGGER 
PLPGSQL_NOT_TRIGGER 

Definition at line 917 of file plpgsql.h.

◆ PLpgSQL_type_type

Enumerator
PLPGSQL_TTYPE_SCALAR 
PLPGSQL_TTYPE_REC 
PLPGSQL_TTYPE_PSEUDO 

Definition at line 92 of file plpgsql.h.

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

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:8032
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:243
static ClientAuthentication_hook_type original_client_auth_hook
Definition: auth_delay.c:29
Definition: guc.h:72
static void auth_delay_checks(Port *port, int status)
Definition: auth_delay.c:35
static int auth_delay_milliseconds
Definition: auth_delay.c:26
#define GUC_UNIT_MS
Definition: guc.h:225

◆ plpgsql_add_initdatums()

int plpgsql_add_initdatums ( int **  varnos)

Definition at line 2265 of file pl_comp.c.

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

2266 {
2267  int i;
2268  int n = 0;
2269 
2270  /*
2271  * The set of dtypes recognized here must match what exec_stmt_block()
2272  * cares about (re)initializing at block entry.
2273  */
2274  for (i = datums_last; i < plpgsql_nDatums; i++)
2275  {
2276  switch (plpgsql_Datums[i]->dtype)
2277  {
2278  case PLPGSQL_DTYPE_VAR:
2279  case PLPGSQL_DTYPE_REC:
2280  n++;
2281  break;
2282 
2283  default:
2284  break;
2285  }
2286  }
2287 
2288  if (varnos != NULL)
2289  {
2290  if (n > 0)
2291  {
2292  *varnos = (int *) palloc(sizeof(int) * n);
2293 
2294  n = 0;
2295  for (i = datums_last; i < plpgsql_nDatums; i++)
2296  {
2297  switch (plpgsql_Datums[i]->dtype)
2298  {
2299  case PLPGSQL_DTYPE_VAR:
2300  case PLPGSQL_DTYPE_REC:
2301  (*varnos)[n++] = plpgsql_Datums[i]->dno;
2302 
2303  default:
2304  break;
2305  }
2306  }
2307  }
2308  else
2309  *varnos = NULL;
2310  }
2311 
2313  return n;
2314 }
int plpgsql_nDatums
Definition: pl_comp.c:46
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
void * palloc(Size size)
Definition: mcxt.c:924
int i
static int datums_last
Definition: pl_comp.c:48

◆ plpgsql_adddatum()

void plpgsql_adddatum ( PLpgSQL_datum new)

Definition at line 2204 of file pl_comp.c.

References datums_alloc, plpgsql_nDatums, and repalloc().

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

2205 {
2207  {
2208  datums_alloc *= 2;
2210  }
2211 
2212  new->dno = plpgsql_nDatums;
2214 }
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:1044

◆ plpgsql_append_source_text()

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

Definition at line 526 of file pl_scanner.c.

References appendBinaryStringInfo(), Assert, and scanorig.

528 {
529  Assert(startlocation <= endlocation);
530  appendBinaryStringInfo(buf, scanorig + startlocation,
531  endlocation - startlocation);
532 }
static const char * scanorig
Definition: pl_scanner.c:220
#define Assert(condition)
Definition: c.h:699
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:208

◆ plpgsql_base_yylex()

int plpgsql_base_yylex ( void  )

◆ plpgsql_build_datatype()

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

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

1999 {
2000  HeapTuple typeTup;
2001  PLpgSQL_type *typ;
2002 
2003  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid));
2004  if (!HeapTupleIsValid(typeTup))
2005  elog(ERROR, "cache lookup failed for type %u", typeOid);
2006 
2007  typ = build_datatype(typeTup, typmod, collation);
2008 
2009  ReleaseSysCache(typeTup);
2010 
2011  return typ;
2012 }
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2018
#define elog
Definition: elog.h:219

◆ plpgsql_build_recfield()

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

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

1957 {
1958  PLpgSQL_recfield *recfield;
1959  int i;
1960 
1961  /* search for an existing datum referencing this field */
1962  i = rec->firstfield;
1963  while (i >= 0)
1964  {
1966 
1968  fld->recparentno == rec->dno);
1969  if (strcmp(fld->fieldname, fldname) == 0)
1970  return fld;
1971  i = fld->nextfield;
1972  }
1973 
1974  /* nope, so make a new one */
1975  recfield = palloc0(sizeof(PLpgSQL_recfield));
1976  recfield->dtype = PLPGSQL_DTYPE_RECFIELD;
1977  recfield->fieldname = pstrdup(fldname);
1978  recfield->recparentno = rec->dno;
1980 
1981  plpgsql_adddatum((PLpgSQL_datum *) recfield);
1982 
1983  /* now we can link it into the parent's chain */
1984  recfield->nextfield = rec->firstfield;
1985  rec->firstfield = recfield->dno;
1986 
1987  return recfield;
1988 }
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
char * pstrdup(const char *in)
Definition: mcxt.c:1161
#define INVALID_TUPLEDESC_IDENTIFIER
Definition: typcache.h:145
uint64 rectupledescid
Definition: plpgsql.h:394
void * palloc0(Size size)
Definition: mcxt.c:955
PLpgSQL_datum_type dtype
Definition: plpgsql.h:387
#define Assert(condition)
Definition: c.h:699
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2204
int i
char * fieldname
Definition: plpgsql.h:391
int firstfield
Definition: plpgsql.h:374

◆ plpgsql_build_record()

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

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

1868 {
1869  PLpgSQL_rec *rec;
1870 
1871  rec = palloc0(sizeof(PLpgSQL_rec));
1872  rec->dtype = PLPGSQL_DTYPE_REC;
1873  rec->refname = pstrdup(refname);
1874  rec->lineno = lineno;
1875  /* other fields are left as 0, might be changed by caller */
1876  rec->datatype = dtype;
1877  rec->rectypeid = rectypeid;
1878  rec->firstfield = -1;
1879  rec->erh = NULL;
1881  if (add2namespace)
1883 
1884  return rec;
1885 }
PLpgSQL_datum_type dtype
Definition: plpgsql.h:362
PLpgSQL_type * datatype
Definition: plpgsql.h:371
char * pstrdup(const char *in)
Definition: mcxt.c:1161
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
Definition: pl_funcs.c:94
ExpandedRecordHeader * erh
Definition: plpgsql.h:379
char * refname
Definition: plpgsql.h:364
void * palloc0(Size size)
Definition: mcxt.c:955
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2204
Oid rectypeid
Definition: plpgsql.h:372
int lineno
Definition: plpgsql.h:365
int firstfield
Definition: plpgsql.h:374

◆ plpgsql_build_variable()

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

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

1804 {
1805  PLpgSQL_variable *result;
1806 
1807  switch (dtype->ttype)
1808  {
1809  case PLPGSQL_TTYPE_SCALAR:
1810  {
1811  /* Ordinary scalar datatype */
1812  PLpgSQL_var *var;
1813 
1814  var = palloc0(sizeof(PLpgSQL_var));
1815  var->dtype = PLPGSQL_DTYPE_VAR;
1816  var->refname = pstrdup(refname);
1817  var->lineno = lineno;
1818  var->datatype = dtype;
1819  /* other fields are left as 0, might be changed by caller */
1820 
1821  /* preset to NULL */
1822  var->value = 0;
1823  var->isnull = true;
1824  var->freeval = false;
1825 
1827  if (add2namespace)
1829  var->dno,
1830  refname);
1831  result = (PLpgSQL_variable *) var;
1832  break;
1833  }
1834  case PLPGSQL_TTYPE_REC:
1835  {
1836  /* Composite type -- build a record variable */
1837  PLpgSQL_rec *rec;
1838 
1839  rec = plpgsql_build_record(refname, lineno,
1840  dtype, dtype->typoid,
1841  add2namespace);
1842  result = (PLpgSQL_variable *) rec;
1843  break;
1844  }
1845  case PLPGSQL_TTYPE_PSEUDO:
1846  ereport(ERROR,
1847  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1848  errmsg("variable \"%s\" has pseudo-type %s",
1849  refname, format_type_be(dtype->typoid))));
1850  result = NULL; /* keep compiler quiet */
1851  break;
1852  default:
1853  elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
1854  result = NULL; /* keep compiler quiet */
1855  break;
1856  }
1857 
1858  return result;
1859 }
char * refname
Definition: plpgsql.h:289
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
Definition: pl_comp.c:1865
PLpgSQL_datum_type dtype
Definition: plpgsql.h:287
char * pstrdup(const char *in)
Definition: mcxt.c:1161
PLpgSQL_type * datatype
Definition: plpgsql.h:296
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:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:328
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool freeval
Definition: plpgsql.h:311
void * palloc0(Size size)
Definition: mcxt.c:955
Datum value
Definition: plpgsql.h:309
int lineno
Definition: plpgsql.h:290
int errmsg(const char *fmt,...)
Definition: elog.c:797
void plpgsql_adddatum(PLpgSQL_datum *new)
Definition: pl_comp.c:2204
#define elog
Definition: elog.h:219
bool isnull
Definition: plpgsql.h:310
Oid typoid
Definition: plpgsql.h:202

◆ plpgsql_compile()

PLpgSQL_function* plpgsql_compile ( FunctionCallInfo  fcinfo,
bool  forValidator 
)

Definition at line 136 of file pl_comp.c.

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

Referenced by plpgsql_call_handler(), and plpgsql_validator().

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

◆ plpgsql_compile_inline()

PLpgSQL_function* plpgsql_compile_inline ( char *  proc_source)

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

826 {
827  char *func_name = "inline_code_block";
828  PLpgSQL_function *function;
829  ErrorContextCallback plerrcontext;
830  PLpgSQL_variable *var;
831  int parse_rc;
832  MemoryContext func_cxt;
833 
834  /*
835  * Setup the scanner input and error info. We assume that this function
836  * cannot be invoked recursively, so there's no need to save and restore
837  * the static variables used here.
838  */
839  plpgsql_scanner_init(proc_source);
840 
841  plpgsql_error_funcname = func_name;
842 
843  /*
844  * Setup error traceback support for ereport()
845  */
847  plerrcontext.arg = proc_source;
848  plerrcontext.previous = error_context_stack;
849  error_context_stack = &plerrcontext;
850 
851  /* Do extra syntax checking if check_function_bodies is on */
853 
854  /* Function struct does not live past current statement */
855  function = (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
856 
857  plpgsql_curr_compile = function;
858 
859  /*
860  * All the rest of the compile-time storage (e.g. parse tree) is kept in
861  * its own memory context, so it can be reclaimed easily.
862  */
864  "PL/pgSQL inline code context",
867 
868  function->fn_signature = pstrdup(func_name);
869  function->fn_is_trigger = PLPGSQL_NOT_TRIGGER;
870  function->fn_input_collation = InvalidOid;
871  function->fn_cxt = func_cxt;
872  function->out_param_varno = -1; /* set up for no OUT param */
873  function->resolve_option = plpgsql_variable_conflict;
874  function->print_strict_params = plpgsql_print_strict_params;
875 
876  /*
877  * don't do extra validation for inline code as we don't want to add spam
878  * at runtime
879  */
880  function->extra_warnings = 0;
881  function->extra_errors = 0;
882 
883  plpgsql_ns_init();
885  plpgsql_DumpExecTree = false;
887 
888  /* Set up as though in a function returning VOID */
889  function->fn_rettype = VOIDOID;
890  function->fn_retset = false;
891  function->fn_retistuple = false;
892  function->fn_retisdomain = false;
893  function->fn_prokind = PROKIND_FUNCTION;
894  /* a bit of hardwired knowledge about type VOID here */
895  function->fn_retbyval = true;
896  function->fn_rettyplen = sizeof(int32);
897 
898  /*
899  * Remember if function is STABLE/IMMUTABLE. XXX would it be better to
900  * set this true inside a read-only transaction? Not clear.
901  */
902  function->fn_readonly = false;
903 
904  /*
905  * Create the magic FOUND variable.
906  */
907  var = plpgsql_build_variable("found", 0,
908  plpgsql_build_datatype(BOOLOID,
909  -1,
910  InvalidOid),
911  true);
912  function->found_varno = var->dno;
913 
914  /*
915  * Now parse the function's text
916  */
917  parse_rc = plpgsql_yyparse();
918  if (parse_rc != 0)
919  elog(ERROR, "plpgsql parser returned %d", parse_rc);
920  function->action = plpgsql_parse_result;
921 
923 
924  /*
925  * If it returns VOID (always true at the moment), we allow control to
926  * fall off the end without an explicit RETURN statement.
927  */
928  if (function->fn_rettype == VOIDOID)
929  add_dummy_return(function);
930 
931  /*
932  * Complete the function's info
933  */
934  function->fn_nargs = 0;
935 
936  plpgsql_finish_datums(function);
937 
938  /*
939  * Pop the error context stack
940  */
941  error_context_stack = plerrcontext.previous;
942  plpgsql_error_funcname = NULL;
943 
944  plpgsql_check_syntax = false;
945 
948  return function;
949 }
int plpgsql_yyparse(void)
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:1998
char * pstrdup(const char *in)
Definition: mcxt.c:1161
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool check_function_bodies
Definition: guc.c:449
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
static void plpgsql_start_datums(void)
Definition: pl_comp.c:2187
signed int int32
Definition: c.h:313
ErrorContextCallback * error_context_stack
Definition: elog.c:88
void plpgsql_scanner_finish(void)
Definition: pl_scanner.c:735
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:1010
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void plpgsql_ns_init(void)
Definition: pl_funcs.c:45
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:170
void * palloc0(Size size)
Definition: mcxt.c:955
#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:958
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:1802
on_exit_nicely_callback function
void plpgsql_scanner_init(const char *str)
Definition: pl_scanner.c:708
static void plpgsql_finish_datums(PLpgSQL_function *function)
Definition: pl_comp.c:2221
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
#define elog
Definition: elog.h:219
PLpgSQL_function * plpgsql_curr_compile
Definition: pl_comp.c:54

◆ plpgsql_dumptree()

void plpgsql_dumptree ( PLpgSQL_function func)

Definition at line 1622 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, PLpgSQL_var::promise, PLpgSQL_var::refname, PLpgSQL_row::refname, PLpgSQL_type::typname, PLpgSQL_type::typoid, and PLpgSQL_row::varnos.

Referenced by do_compile().

1623 {
1624  int i;
1625  PLpgSQL_datum *d;
1626 
1627  printf("\nExecution tree of successfully compiled PL/pgSQL function %s:\n",
1628  func->fn_signature);
1629 
1630  printf("\nFunction's data area:\n");
1631  for (i = 0; i < func->ndatums; i++)
1632  {
1633  d = func->datums[i];
1634 
1635  printf(" entry %d: ", i);
1636  switch (d->dtype)
1637  {
1638  case PLPGSQL_DTYPE_VAR:
1639  case PLPGSQL_DTYPE_PROMISE:
1640  {
1641  PLpgSQL_var *var = (PLpgSQL_var *) d;
1642 
1643  printf("VAR %-16s type %s (typoid %u) atttypmod %d\n",
1644  var->refname, var->datatype->typname,
1645  var->datatype->typoid,
1646  var->datatype->atttypmod);
1647  if (var->isconst)
1648  printf(" CONSTANT\n");
1649  if (var->notnull)
1650  printf(" NOT NULL\n");
1651  if (var->default_val != NULL)
1652  {
1653  printf(" DEFAULT ");
1654  dump_expr(var->default_val);
1655  printf("\n");
1656  }
1657  if (var->cursor_explicit_expr != NULL)
1658  {
1659  if (var->cursor_explicit_argrow >= 0)
1660  printf(" CURSOR argument row %d\n", var->cursor_explicit_argrow);
1661 
1662  printf(" CURSOR IS ");
1664  printf("\n");
1665  }
1666  if (var->promise != PLPGSQL_PROMISE_NONE)
1667  printf(" PROMISE %d\n",
1668  (int) var->promise);
1669  }
1670  break;
1671  case PLPGSQL_DTYPE_ROW:
1672  {
1673  PLpgSQL_row *row = (PLpgSQL_row *) d;
1674  int i;
1675 
1676  printf("ROW %-16s fields", row->refname);
1677  for (i = 0; i < row->nfields; i++)
1678  {
1679  printf(" %s=var %d", row->fieldnames[i],
1680  row->varnos[i]);
1681  }
1682  printf("\n");
1683  }
1684  break;
1685  case PLPGSQL_DTYPE_REC:
1686  printf("REC %-16s typoid %u\n",
1687  ((PLpgSQL_rec *) d)->refname,
1688  ((PLpgSQL_rec *) d)->rectypeid);
1689  if (((PLpgSQL_rec *) d)->isconst)
1690  printf(" CONSTANT\n");
1691  if (((PLpgSQL_rec *) d)->notnull)
1692  printf(" NOT NULL\n");
1693  if (((PLpgSQL_rec *) d)->default_val != NULL)
1694  {
1695  printf(" DEFAULT ");
1696  dump_expr(((PLpgSQL_rec *) d)->default_val);
1697  printf("\n");
1698  }
1699  break;
1701  printf("RECFIELD %-16s of REC %d\n",
1702  ((PLpgSQL_recfield *) d)->fieldname,
1703  ((PLpgSQL_recfield *) d)->recparentno);
1704  break;
1706  printf("ARRAYELEM of VAR %d subscript ",
1707  ((PLpgSQL_arrayelem *) d)->arrayparentno);
1708  dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
1709  printf("\n");
1710  break;
1711  default:
1712  printf("??? unknown data type %d\n", d->dtype);
1713  }
1714  }
1715  printf("\nFunction's statements:\n");
1716 
1717  dump_indent = 0;
1718  printf("%3d:", func->action->lineno);
1719  dump_block(func->action);
1720  printf("\nEnd of execution tree of function %s\n\n", func->fn_signature);
1721  fflush(stdout);
1722 }
PLpgSQL_promise_type promise
Definition: plpgsql.h:318
PLpgSQL_datum ** datums
Definition: plpgsql.h:964
char * refname
Definition: plpgsql.h:338
char * refname
Definition: plpgsql.h:289
PLpgSQL_stmt_block * action
Definition: plpgsql.h:968
PLpgSQL_expr * cursor_explicit_expr
Definition: plpgsql.h:303
PLpgSQL_type * datatype
Definition: plpgsql.h:296
bool isconst
Definition: plpgsql.h:291
PLpgSQL_datum_type dtype
Definition: plpgsql.h:253
bool notnull
Definition: plpgsql.h:292
int cursor_explicit_argrow
Definition: plpgsql.h:304
char ** fieldnames
Definition: plpgsql.h:353
PLpgSQL_expr * default_val
Definition: plpgsql.h:293
int * varnos
Definition: plpgsql.h:354
PLpgSQL_datum_type dtype
Definition: plpgsql.h:387
int nfields
Definition: plpgsql.h:352
static int dump_indent
Definition: pl_funcs.c:803
char * fn_signature
Definition: plpgsql.h:929
char * typname
Definition: plpgsql.h:201
static void dump_block(PLpgSQL_stmt_block *block)
Definition: pl_funcs.c:956
int32 atttypmod
Definition: plpgsql.h:209
static void dump_expr(PLpgSQL_expr *expr)
Definition: pl_funcs.c:1616
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 1080 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_block(), PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, gettext_noop, plpgsql_destroy_econtext(), plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, and ErrorContextCallback::previous.

Referenced by plpgsql_call_handler().

1081 {
1082  PLpgSQL_execstate estate;
1083  ErrorContextCallback plerrcontext;
1084  int rc;
1085 
1086  /*
1087  * Setup the execution state
1088  */
1089  plpgsql_estate_setup(&estate, func, NULL, NULL);
1090  estate.evtrigdata = trigdata;
1091 
1092  /*
1093  * Setup error traceback support for ereport()
1094  */
1095  plerrcontext.callback = plpgsql_exec_error_callback;
1096  plerrcontext.arg = &estate;
1097  plerrcontext.previous = error_context_stack;
1098  error_context_stack = &plerrcontext;
1099 
1100  /*
1101  * Make local execution copies of all the datums
1102  */
1103  estate.err_text = gettext_noop("during initialization of execution state");
1104  copy_plpgsql_datums(&estate, func);
1105 
1106  /*
1107  * Let the instrumentation plugin peek at this function
1108  */
1109  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
1110  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
1111 
1112  /*
1113  * Now call the toplevel block of statements
1114  */
1115  estate.err_text = NULL;
1116  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
1117  rc = exec_stmt_block(&estate, func->action);
1118  if (rc != PLPGSQL_RC_RETURN)
1119  {
1120  estate.err_stmt = NULL;
1121  estate.err_text = NULL;
1122  ereport(ERROR,
1123  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1124  errmsg("control reached end of trigger procedure without RETURN")));
1125  }
1126 
1127  estate.err_stmt = NULL;
1128  estate.err_text = gettext_noop("during function exit");
1129 
1130  /*
1131  * Let the instrumentation plugin peek at this function
1132  */
1133  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1134  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1135 
1136  /* Clean up any leftover temporary memory */
1137  plpgsql_destroy_econtext(&estate);
1138  exec_eval_cleanup(&estate);
1139  /* stmt_mcontext will be destroyed when function's main context is */
1140 
1141  /*
1142  * Pop the error context stack
1143  */
1144  error_context_stack = plerrcontext.previous;
1145 
1146  return;
1147 }
PLpgSQL_stmt * err_stmt
Definition: plpgsql.h:1045
PLpgSQL_stmt_block * action
Definition: plpgsql.h:968
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1153
#define gettext_noop(x)
Definition: c.h:1036
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3781
int errcode(int sqlerrcode)
Definition: elog.c:575
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:3927
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
static void copy_plpgsql_datums(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: pl_exec.c:1211
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:7988
#define ereport(elevel, rest)
Definition: elog.h:122
PLpgSQL_plugin ** plpgsql_plugin_ptr
Definition: pl_handler.c:58
void(* func_beg)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1085
EventTriggerData * evtrigdata
Definition: plpgsql.h:983
const char * err_text
Definition: plpgsql.h:1046
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1086
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1531
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ plpgsql_exec_function()

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

Definition at line 448 of file pl_exec.c.

References PLpgSQL_function::action, ReturnSetInfo::allowedModes, FunctionCallInfoData::arg, ErrorContextCallback::arg, FunctionCallInfoData::argnull, 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_block(), expand_array(), PLpgSQL_function::fn_argvarnos, PLpgSQL_function::fn_nargs, PLpgSQL_function::fn_retbyval, PLpgSQL_function::fn_retisdomain, PLpgSQL_function::fn_rettype, PLpgSQL_function::fn_rettyplen, PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, get_call_result_type(), gettext_noop, i, IsA, FunctionCallInfoData::isnull, PLpgSQL_var::isnull, MemoryContextSwitchTo(), plpgsql_destroy_econtext(), PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_VAR, plpgsql_estate_setup(), plpgsql_exec_error_callback(), plpgsql_plugin_ptr, PLPGSQL_RC_RETURN, ErrorContextCallback::previous, FunctionCallInfoData::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, VARATT_IS_EXTERNAL_EXPANDED_RO, and VARATT_IS_EXTERNAL_EXPANDED_RW.

Referenced by plpgsql_call_handler(), and plpgsql_inline_handler().

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

◆ plpgsql_exec_get_datum_type()

Oid plpgsql_exec_get_datum_type ( PLpgSQL_execstate estate,
PLpgSQL_datum datum 
)

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

5441 {
5442  Oid typeid;
5443 
5444  switch (datum->dtype)
5445  {
5446  case PLPGSQL_DTYPE_VAR:
5447  case PLPGSQL_DTYPE_PROMISE:
5448  {
5449  PLpgSQL_var *var = (PLpgSQL_var *) datum;
5450 
5451  typeid = var->datatype->typoid;
5452  break;
5453  }
5454 
5455  case PLPGSQL_DTYPE_REC:
5456  {
5457  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5458 
5459  if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5460  {
5461  /* Report variable's declared type */
5462  typeid = rec->rectypeid;
5463  }
5464  else
5465  {
5466  /* Report record's actual type if declared RECORD */
5467  typeid = rec->erh->er_typeid;
5468  }
5469  break;
5470  }
5471 
5473  {
5474  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5475  PLpgSQL_rec *rec;
5476 
5477  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5478 
5479  /*
5480  * If record variable is NULL, instantiate it if it has a
5481  * named composite type, else complain. (This won't change
5482  * the logical state of the record: it's still NULL.)
5483  */
5484  if (rec->erh == NULL)
5485  instantiate_empty_record_variable(estate, rec);
5486 
5487  /*
5488  * Look up the field's properties if we have not already, or
5489  * if the tuple descriptor ID changed since last time.
5490  */
5491  if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5492  {
5494  recfield->fieldname,
5495  &recfield->finfo))
5496  ereport(ERROR,
5497  (errcode(ERRCODE_UNDEFINED_COLUMN),
5498  errmsg("record \"%s\" has no field \"%s\"",
5499  rec->refname, recfield->fieldname)));
5500  recfield->rectupledescid = rec->erh->er_tupdesc_id;
5501  }
5502 
5503  typeid = recfield->finfo.ftypeid;
5504  break;
5505  }
5506 
5507  default:
5508  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5509  typeid = InvalidOid; /* keep compiler quiet */
5510  break;
5511  }
5512 
5513  return typeid;
5514 }
bool expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname, ExpandedRecordFieldInfo *finfo)
PLpgSQL_type * datatype
Definition: plpgsql.h:296
static void instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec)
Definition: pl_exec.c:7368
ExpandedRecordHeader * erh
Definition: plpgsql.h:379
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
PLpgSQL_datum_type dtype
Definition: plpgsql.h:253
char * refname
Definition: plpgsql.h:364
PLpgSQL_datum ** datums
Definition: plpgsql.h:1015
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
uint64 rectupledescid
Definition: plpgsql.h:394
ExpandedRecordFieldInfo finfo
Definition: plpgsql.h:395
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define unlikely(x)
Definition: c.h:208
#define elog
Definition: elog.h:219
Oid rectypeid
Definition: plpgsql.h:372
char * fieldname
Definition: plpgsql.h:391
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 5524 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().

5527 {
5528  switch (datum->dtype)
5529  {
5530  case PLPGSQL_DTYPE_VAR:
5531  case PLPGSQL_DTYPE_PROMISE:
5532  {
5533  PLpgSQL_var *var = (PLpgSQL_var *) datum;
5534 
5535  *typeid = var->datatype->typoid;
5536  *typmod = var->datatype->atttypmod;
5537  *collation = var->datatype->collation;
5538  break;
5539  }
5540 
5541  case PLPGSQL_DTYPE_REC:
5542  {
5543  PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5544 
5545  if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5546  {
5547  /* Report variable's declared type */
5548  *typeid = rec->rectypeid;
5549  *typmod = -1;
5550  }
5551  else
5552  {
5553  /* Report record's actual type if declared RECORD */
5554  *typeid = rec->erh->er_typeid;
5555  /* do NOT return the mutable typmod of a RECORD variable */
5556  *typmod = -1;
5557  }
5558  /* composite types are never collatable */
5559  *collation = InvalidOid;
5560  break;
5561  }
5562 
5564  {
5565  PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5566  PLpgSQL_rec *rec;
5567 
5568  rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5569 
5570  /*
5571  * If record variable is NULL, instantiate it if it has a
5572  * named composite type, else complain. (This won't change
5573  * the logical state of the record: it's still NULL.)
5574  */
5575  if (rec->erh == NULL)
5576  instantiate_empty_record_variable(estate, rec);
5577 
5578  /*
5579  * Look up the field's properties if we have not already, or
5580  * if the tuple descriptor ID changed since last time.
5581  */
5582  if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5583  {
5585  recfield->fieldname,
5586  &recfield->finfo))
5587  ereport(ERROR,
5588  (errcode(ERRCODE_UNDEFINED_COLUMN),
5589  errmsg("record \"%s\" has no field \"%s\"",
5590  rec->refname, recfield->fieldname)));
5591  recfield->rectupledescid = rec->erh->er_tupdesc_id;
5592  }
5593 
5594  *typeid = recfield->finfo.ftypeid;
5595  *typmod = recfield->finfo.ftypmod;
5596  *collation = recfield->finfo.fcollation;
5597  break;
5598  }
5599 
5600  default:
5601  elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5602  *typeid = InvalidOid; /* keep compiler quiet */
5603  *typmod = -1;
5604  *collation = InvalidOid;
5605  break;
5606  }
5607 }
bool expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname, ExpandedRecordFieldInfo *finfo)
PLpgSQL_type * datatype
Definition: plpgsql.h:296
static void instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec)
Definition: pl_exec.c:7368
ExpandedRecordHeader * erh
Definition: plpgsql.h:379
int errcode(int sqlerrcode)
Definition: elog.c:575
PLpgSQL_datum_type dtype
Definition: plpgsql.h:253
char * refname
Definition: plpgsql.h:364
PLpgSQL_datum ** datums
Definition: plpgsql.h:1015
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
uint64 rectupledescid
Definition: plpgsql.h:394
Oid collation
Definition: plpgsql.h:207
ExpandedRecordFieldInfo finfo
Definition: plpgsql.h:395
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 atttypmod
Definition: plpgsql.h:209
#define unlikely(x)
Definition: c.h:208
#define elog
Definition: elog.h:219
Oid rectypeid
Definition: plpgsql.h:372
char * fieldname
Definition: plpgsql.h:391
Oid typoid
Definition: plpgsql.h:202

◆ plpgsql_exec_trigger()

HeapTuple plpgsql_exec_trigger ( PLpgSQL_function func,
TriggerData trigdata 
)

Definition at line 858 of file pl_exec.c.

References PLpgSQL_function::action, ErrorContextCallback::arg, Assert, ErrorContextCallback::callback, convert_tuples_by_position(), copy_plpgsql_datums(), PLpgSQL_execstate::datum_context, DatumGetEOHP(), DatumGetPointer, PLpgSQL_execstate::datums, deconstruct_composite_datum(), do_convert_tuple(), 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_block(), expanded_record_get_tupdesc(), expanded_record_get_tuple(), expanded_record_set_tuple(), PLpgSQL_plugin::func_beg, PLpgSQL_plugin::func_end, gettext_noop, make_expanded_record_from_exprecord(), make_expanded_record_from_tupdesc(), 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_BY_DELETE, TRIGGER_FIRED_BY_INSERT, TRIGGER_FIRED_BY_UPDATE, TRIGGER_FIRED_FOR_ROW, type_is_rowtype(), and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by plpgsql_call_handler().

860 {
861  PLpgSQL_execstate estate;
862  ErrorContextCallback plerrcontext;
863  int rc;
864  TupleDesc tupdesc;
865  PLpgSQL_rec *rec_new,
866  *rec_old;
867  HeapTuple rettup;
868 
869  /*
870  * Setup the execution state
871  */
872  plpgsql_estate_setup(&estate, func, NULL, NULL);
873  estate.trigdata = trigdata;
874 
875  /*
876  * Setup error traceback support for ereport()
877  */
878  plerrcontext.callback = plpgsql_exec_error_callback;
879  plerrcontext.arg = &estate;
880  plerrcontext.previous = error_context_stack;
881  error_context_stack = &plerrcontext;
882 
883  /*
884  * Make local execution copies of all the datums
885  */
886  estate.err_text = gettext_noop("during initialization of execution state");
887  copy_plpgsql_datums(&estate, func);
888 
889  /*
890  * Put the OLD and NEW tuples into record variables
891  *
892  * We make the tupdescs available in both records even though only one may
893  * have a value. This allows parsing of record references to succeed in
894  * functions that are used for multiple trigger types. For example, we
895  * might have a test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')",
896  * which should parse regardless of the current trigger type.
897  */
898  tupdesc = RelationGetDescr(trigdata->tg_relation);
899 
900  rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
901  rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
902 
903  rec_new->erh = make_expanded_record_from_tupdesc(tupdesc,
904  estate.datum_context);
905  rec_old->erh = make_expanded_record_from_exprecord(rec_new->erh,
906  estate.datum_context);
907 
908  if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
909  {
910  /*
911  * Per-statement triggers don't use OLD/NEW variables
912  */
913  }
914  else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
915  {
916  expanded_record_set_tuple(rec_new->erh, trigdata->tg_trigtuple,
917  false, false);
918  }
919  else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
920  {
921  expanded_record_set_tuple(rec_new->erh, trigdata->tg_newtuple,
922  false, false);
923  expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
924  false, false);
925  }
926  else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
927  {
928  expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
929  false, false);
930  }
931  else
932  elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
933 
934  /* Make transition tables visible to this SPI connection */
935  rc = SPI_register_trigger_data(trigdata);
936  Assert(rc >= 0);
937 
938  estate.err_text = gettext_noop("during function entry");
939 
940  /*
941  * Set the magic variable FOUND to false
942  */
943  exec_set_found(&estate, false);
944 
945  /*
946  * Let the instrumentation plugin peek at this function
947  */
948  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
949  ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
950 
951  /*
952  * Now call the toplevel block of statements
953  */
954  estate.err_text = NULL;
955  estate.err_stmt = (PLpgSQL_stmt *) (func->action);
956  rc = exec_stmt_block(&estate, func->action);
957  if (rc != PLPGSQL_RC_RETURN)
958  {
959  estate.err_stmt = NULL;
960  estate.err_text = NULL;
961  ereport(ERROR,
962  (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
963  errmsg("control reached end of trigger procedure without RETURN")));
964  }
965 
966  estate.err_stmt = NULL;
967  estate.err_text = gettext_noop("during function exit");
968 
969  if (estate.retisset)
970  ereport(ERROR,
971  (errcode(ERRCODE_DATATYPE_MISMATCH),
972  errmsg("trigger procedure cannot return a set")));
973 
974  /*
975  * Check that the returned tuple structure has the same attributes, the
976  * relation that fired the trigger has. A per-statement trigger always
977  * needs to return NULL, so we ignore any return value the function itself
978  * produces (XXX: is this a good idea?)
979  *
980  * XXX This way it is possible, that the trigger returns a tuple where
981  * attributes don't have the correct atttypmod's length. It's up to the
982  * trigger's programmer to ensure that this doesn't happen. Jan
983  */
984  if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
985  rettup = NULL;
986  else
987  {
988  TupleDesc retdesc;
989  TupleConversionMap *tupmap;
990 
991  /* We assume exec_stmt_return verified that result is composite */
992  Assert(type_is_rowtype(estate.rettype));
993 
994  /* We can special-case expanded records for speed */
996  {
998 
999  Assert(erh->er_magic == ER_MAGIC);
1000 
1001  /* Extract HeapTuple and TupleDesc */
1002  rettup = expanded_record_get_tuple(erh);
1003  Assert(rettup);
1004  retdesc = expanded_record_get_tupdesc(erh);
1005 
1006  if (retdesc != RelationGetDescr(trigdata->tg_relation))
1007  {
1008  /* check rowtype compatibility */
1009  tupmap = convert_tuples_by_position(retdesc,
1010  RelationGetDescr(trigdata->tg_relation),
1011  gettext_noop("returned row structure does not match the structure of the triggering table"));
1012  /* it might need conversion */
1013  if (tupmap)
1014  rettup = do_convert_tuple(rettup, tupmap);
1015  /* no need to free map, we're about to return anyway */
1016  }
1017 
1018  /*
1019  * Copy tuple to upper executor memory. But if user just did
1020  * "return new" or "return old" without changing anything, there's
1021  * no need to copy; we can return the original tuple (which will
1022  * save a few cycles in trigger.c as well as here).
1023  */
1024  if (rettup != trigdata->tg_newtuple &&
1025  rettup != trigdata->tg_trigtuple)
1026  rettup = SPI_copytuple(rettup);
1027  }
1028  else
1029  {
1030  /* Convert composite datum to a HeapTuple and TupleDesc */
1031  HeapTupleData tmptup;
1032 
1033  retdesc = deconstruct_composite_datum(estate.retval, &tmptup);
1034  rettup = &tmptup;
1035 
1036  /* check rowtype compatibility */
1037  tupmap = convert_tuples_by_position(retdesc,
1038  RelationGetDescr(trigdata->tg_relation),
1039  gettext_noop("returned row structure does not match the structure of the triggering table"));
1040  /* it might need conversion */
1041  if (tupmap)
1042  rettup = do_convert_tuple(rettup, tupmap);
1043 
1044  ReleaseTupleDesc(retdesc);
1045  /* no need to free map, we're about to return anyway */
1046 
1047  /* Copy tuple to upper executor memory */
1048  rettup = SPI_copytuple(rettup);
1049  }
1050  }
1051 
1052  /*
1053  * Let the instrumentation plugin peek at this function
1054  */
1055  if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1056  ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1057 
1058  /* Clean up any leftover temporary memory */
1059  plpgsql_destroy_econtext(&estate);
1060  exec_eval_cleanup(&estate);
1061  /* stmt_mcontext will be destroyed when function's main context is */
1062 
1063  /*
1064  * Pop the error context stack
1065  */
1066  error_context_stack = plerrcontext.previous;
1067 
1068  /*
1069  * Return the trigger's result
1070  */
1071  return rettup;
1072 }
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:1045
#define RelationGetDescr(relation)
Definition: rel.h:433
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:66
PLpgSQL_stmt_block * action
Definition: plpgsql.h:968
TriggerData * trigdata
Definition: plpgsql.h:982
static void plpgsql_exec_error_callback(void *arg)
Definition: pl_exec.c:1153
#define gettext_noop(x)
Definition: c.h:1036
static void plpgsql_estate_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func, ReturnSetInfo *rsi, EState *simple_eval_estate)
Definition: pl_exec.c:3781
ExpandedRecordHeader * erh
Definition: plpgsql.h:379
static TupleDesc deconstruct_composite_datum(Datum value, HeapTupleData *tmptup)
Definition: pl_exec.c:7109
int errcode(int sqlerrcode)
Definition: elog.c:575
HeapTuple SPI_copytuple(HeapTuple tuple)
Definition: spi.c:727
static void exec_eval_cleanup(PLpgSQL_execstate *estate)
Definition: pl_exec.c:3927
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
static void copy_plpgsql_datums(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: pl_exec.c:1211
HeapTuple tg_trigtuple
Definition: trigger.h:35
PLpgSQL_datum ** datums
Definition: plpgsql.h:1015
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:7988
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2409
#define ereport(elevel, rest)
Definition: elog.h:122
int SPI_register_trigger_data(TriggerData *tdata)
Definition: spi.c:2856
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:1085
#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:1046
HeapTuple tg_newtuple
Definition: trigger.h:36
void(* func_end)(PLpgSQL_execstate *estate, PLpgSQL_function *func)
Definition: plpgsql.h:1086
#define Assert(condition)
Definition: c.h:699
TriggerEvent tg_event
Definition: trigger.h:33
static void exec_set_found(PLpgSQL_execstate *estate, bool state)
Definition: pl_exec.c:7920
HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:354
#define DatumGetPointer(X)
Definition: postgres.h:534
MemoryContext datum_context
Definition: plpgsql.h:1017
#define TRIGGER_FIRED_BY_INSERT(event)
Definition: trigger.h:116
static int exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
Definition: pl_exec.c:1531
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:124
#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 741 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().

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

◆ 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_RESULT_OID, 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 "RESULT_OID";
313  return "PG_CONTEXT";
315  return "PG_EXCEPTION_CONTEXT";
317  return "PG_EXCEPTION_DETAIL";
319  return "PG_EXCEPTION_HINT";
321  return "RETURNED_SQLSTATE";
323  return "COLUMN_NAME";
325  return "CONSTRAINT_NAME";
327  return "PG_DATATYPE_NAME";
329  return "MESSAGE_TEXT";
331  return "TABLE_NAME";
333  return "SCHEMA_NAME";
334  }
335 
336  return "unknown";
337 }

◆ plpgsql_HashTableInit()

void plpgsql_HashTableInit ( void  )

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

2447 {
2448  HASHCTL ctl;
2449 
2450  /* don't allow double-initialization */
2451  Assert(plpgsql_HashTable == NULL);
2452 
2453  memset(&ctl, 0, sizeof(ctl));
2454  ctl.keysize = sizeof(PLpgSQL_func_hashkey);
2455  ctl.entrysize = sizeof(plpgsql_HashEnt);
2456  plpgsql_HashTable = hash_create("PLpgSQL function hash",
2458  &ctl,
2459  HASH_ELEM | HASH_BLOBS);
2460 }
#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:699

◆ plpgsql_latest_lineno()

int plpgsql_latest_lineno ( void  )

Definition at line 694 of file pl_scanner.c.

References cur_line_num.

Referenced by plpgsql_compile_error_callback().

695 {
696  return cur_line_num;
697 }
static int cur_line_num
Definition: pl_scanner.c:238

◆ plpgsql_location_to_lineno()

int plpgsql_location_to_lineno ( int  location)

Definition at line 660 of file pl_scanner.c.

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

661 {
662  const char *loc;
663 
664  if (location < 0 || scanorig == NULL)
665  return 0; /* garbage in, garbage out */
666  loc = scanorig + location;
667 
668  /* be correct, but not fast, if input location goes backwards */
669  if (loc < cur_line_start)
671 
672  while (cur_line_end != NULL && loc > cur_line_end)
673  {
675  cur_line_num++;
676  cur_line_end = strchr(cur_line_start, '\n');
677  }
678 
679  return cur_line_num;
680 }
static int cur_line_num
Definition: pl_scanner.c:238
static void location_lineno_init(void)
Definition: pl_scanner.c:684
static const char * cur_line_start
Definition: pl_scanner.c:236
static const char * scanorig
Definition: pl_scanner.c:220
static const char * cur_line_end
Definition: pl_scanner.c:237

◆ 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:435
#define Assert(condition)
Definition: c.h:699
const char * name
Definition: encode.c:521
void * palloc(Size size)
Definition: mcxt.c:924
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:436
#define offsetof(type, field)
Definition: c.h:622

◆ 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:435
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428

◆ 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:435
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:436

◆ 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:435
const char * name
Definition: encode.c:521
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: plpgsql.h:436

◆ 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:435
#define Assert(condition)
Definition: c.h:699
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428

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

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

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

1769 {
1770  Oid classOid;
1771  RangeVar *relvar;
1772  MemoryContext oldCxt;
1773 
1774  if (list_length(idents) != 2)
1775  return NULL;
1776 
1777  /* Avoid memory leaks in long-term function context */
1779 
1780  /* Look up relation name. Can't lock it - we might not have privileges. */
1781  relvar = makeRangeVar(strVal(linitial(idents)),
1782  strVal(lsecond(idents)),
1783  -1);
1784  classOid = RangeVarGetRelid(relvar, NoLock, false);
1785 
1786  MemoryContextSwitchTo(oldCxt);
1787 
1788  /* Build and return the row type struct */
1789  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1790 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:1998
#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:116
#define linitial(l)
Definition: pg_list.h:111
#define NoLock
Definition: lockdefs.h:34
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1781
#define InvalidOid
Definition: postgres_ext.h:36
static int list_length(const List *l)
Definition: pg_list.h:89
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:421

◆ plpgsql_parse_cwordtype()

PLpgSQL_type* plpgsql_parse_cwordtype ( List idents)

Definition at line 1629 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.

1630 {
1631  PLpgSQL_type *dtype = NULL;
1632  PLpgSQL_nsitem *nse;
1633  const char *fldname;
1634  Oid classOid;
1635  HeapTuple classtup = NULL;
1636  HeapTuple attrtup = NULL;
1637  HeapTuple typetup = NULL;
1638  Form_pg_class classStruct;
1639  Form_pg_attribute attrStruct;
1640  MemoryContext oldCxt;
1641 
1642  /* Avoid memory leaks in the long-term function context */
1644 
1645  if (list_length(idents) == 2)
1646  {
1647  /*
1648  * Do a lookup in the current namespace stack. We don't need to check
1649  * number of names matched, because we will only consider scalar
1650  * variables.
1651  */
1652  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1653  strVal(linitial(idents)),
1654  strVal(lsecond(idents)),
1655  NULL,
1656  NULL);
1657 
1658  if (nse != NULL && nse->itemtype == PLPGSQL_NSTYPE_VAR)
1659  {
1660  dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1661  goto done;
1662  }
1663 
1664  /*
1665  * First word could also be a table name
1666  */
1667  classOid = RelnameGetRelid(strVal(linitial(idents)));
1668  if (!OidIsValid(classOid))
1669  goto done;
1670  fldname = strVal(lsecond(idents));
1671  }
1672  else if (list_length(idents) == 3)
1673  {
1674  RangeVar *relvar;
1675 
1676  relvar = makeRangeVar(strVal(linitial(idents)),
1677  strVal(lsecond(idents)),
1678  -1);
1679  /* Can't lock relation - we might not have privileges. */
1680  classOid = RangeVarGetRelid(relvar, NoLock, true);
1681  if (!OidIsValid(classOid))
1682  goto done;
1683  fldname = strVal(lthird(idents));
1684  }
1685  else
1686  goto done;
1687 
1688  classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(classOid));
1689  if (!HeapTupleIsValid(classtup))
1690  goto done;
1691  classStruct = (Form_pg_class) GETSTRUCT(classtup);
1692 
1693  /*
1694  * It must be a relation, sequence, view, materialized view, composite
1695  * type, or foreign table
1696  */
1697  if (classStruct->relkind != RELKIND_RELATION &&
1698  classStruct->relkind != RELKIND_SEQUENCE &&
1699  classStruct->relkind != RELKIND_VIEW &&
1700  classStruct->relkind != RELKIND_MATVIEW &&
1701  classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
1702  classStruct->relkind != RELKIND_FOREIGN_TABLE &&
1703  classStruct->relkind != RELKIND_PARTITIONED_TABLE)
1704  goto done;
1705 
1706  /*
1707  * Fetch the named table field and its type
1708  */
1709  attrtup = SearchSysCacheAttName(classOid, fldname);
1710  if (!HeapTupleIsValid(attrtup))
1711  goto done;
1712  attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
1713 
1714  typetup = SearchSysCache1(TYPEOID,
1715  ObjectIdGetDatum(attrStruct->atttypid));
1716  if (!HeapTupleIsValid(typetup))
1717  elog(ERROR, "cache lookup failed for type %u", attrStruct->atttypid);
1718 
1719  /*
1720  * Found that - build a compiler type struct in the caller's cxt and
1721  * return it
1722  */
1723  MemoryContextSwitchTo(oldCxt);
1724  dtype = build_datatype(typetup,
1725  attrStruct->atttypmod,
1726  attrStruct->attcollation);
1728 
1729 done:
1730  if (HeapTupleIsValid(classtup))
1731  ReleaseSysCache(classtup);
1732  if (HeapTupleIsValid(attrtup))
1733  ReleaseSysCache(attrtup);
1734  if (HeapTupleIsValid(typetup))
1735  ReleaseSysCache(typetup);
1736 
1737  MemoryContextSwitchTo(oldCxt);
1738  return dtype;
1739 }
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:668
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:673
#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:605
#define lsecond(l)
Definition: pg_list.h:116
#define linitial(l)
Definition: pg_list.h:111
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static int list_length(const List *l)
Definition: pg_list.h:89
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1248
FormData_pg_class * Form_pg_class
Definition: pg_class.h:93
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2018
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428
MemoryContext plpgsql_compile_tmp_cxt
Definition: pl_comp.c:57
#define lthird(l)
Definition: pg_list.h:121
#define elog
Definition: elog.h:219
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:421

◆ plpgsql_parse_dblword()

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

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

1420 {
1421  PLpgSQL_nsitem *ns;
1422  List *idents;
1423  int nnames;
1424 
1425  idents = list_make2(makeString(word1),
1426  makeString(word2));
1427 
1428  /*
1429  * We should do nothing in DECLARE sections. In SQL expressions, we
1430  * really only need to make sure that RECFIELD datums are created when
1431  * needed.
1432  */
1434  {
1435  /*
1436  * Do a lookup in the current namespace stack
1437  */
1438  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1439  word1, word2, NULL,
1440  &nnames);
1441  if (ns != NULL)
1442  {
1443  switch (ns->itemtype)
1444  {
1445  case PLPGSQL_NSTYPE_VAR:
1446  /* Block-qualified reference to scalar variable. */
1447  wdatum->datum = plpgsql_Datums[ns->itemno];
1448  wdatum->ident = NULL;
1449  wdatum->quoted = false; /* not used */
1450  wdatum->idents = idents;
1451  return true;
1452 
1453  case PLPGSQL_NSTYPE_REC:
1454  if (nnames == 1)
1455  {
1456  /*
1457  * First word is a record name, so second word could
1458  * be a field in this record. We build a RECFIELD
1459  * datum whether it is or not --- any error will be
1460  * detected later.
1461  */
1462  PLpgSQL_rec *rec;
1463  PLpgSQL_recfield *new;
1464 
1465  rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1466  new = plpgsql_build_recfield(rec, word2);
1467 
1468  wdatum->datum = (PLpgSQL_datum *) new;
1469  }
1470  else
1471  {
1472  /* Block-qualified reference to record variable. */
1473  wdatum->datum = plpgsql_Datums[ns->itemno];
1474  }
1475  wdatum->ident = NULL;
1476  wdatum->quoted = false; /* not used */
1477  wdatum->idents = idents;
1478  return true;
1479 
1480  default:
1481  break;
1482  }
1483  }
1484  }
1485 
1486  /* Nothing found */
1487  cword->idents = idents;
1488  return false;
1489 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
Value * makeString(char *str)
Definition: value.c:53
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
Definition: pl_comp.c:1956
List * idents
Definition: plpgsql.h:1108
List * idents
Definition: plpgsql.h:1116
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:29
PLpgSQL_datum * datum
Definition: plpgsql.h:1113
bool quoted
Definition: plpgsql.h:1115
char * ident
Definition: plpgsql.h:1114
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428
Definition: pg_list.h:45

◆ plpgsql_parse_err_condition()

PLpgSQL_condition* plpgsql_parse_err_condition ( char *  condname)

Definition at line 2136 of file pl_comp.c.

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

2137 {
2138  int i;
2139  PLpgSQL_condition *new;
2140  PLpgSQL_condition *prev;
2141 
2142  /*
2143  * XXX Eventually we will want to look for user-defined exception names
2144  * here.
2145  */
2146 
2147  /*
2148  * OTHERS is represented as code 0 (which would map to '00000', but we
2149  * have no need to represent that as an exception condition).
2150  */
2151  if (strcmp(condname, "others") == 0)
2152  {
2153  new = palloc(sizeof(PLpgSQL_condition));
2154  new->sqlerrstate = 0;
2155  new->condname = condname;
2156  new->next = NULL;
2157  return new;
2158  }
2159 
2160  prev = NULL;
2161  for (i = 0; exception_label_map[i].label != NULL; i++)
2162  {
2163  if (strcmp(condname, exception_label_map[i].label) == 0)
2164  {
2165  new = palloc(sizeof(PLpgSQL_condition));
2166  new->sqlerrstate = exception_label_map[i].sqlerrstate;
2167  new->condname = condname;
2168  new->next = prev;
2169  prev = new;
2170  }
2171  }
2172 
2173  if (!prev)
2174  ereport(ERROR,
2175  (errcode(ERRCODE_UNDEFINED_OBJECT),
2176  errmsg("unrecognized exception condition \"%s\"",
2177  condname)));
2178 
2179  return prev;
2180 }
const char * label
Definition: pl_comp.c:79
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static char * label
Definition: pg_basebackup.c:84
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:83
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i

◆ plpgsql_parse_tripword()

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

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

1500 {
1501  PLpgSQL_nsitem *ns;
1502  List *idents;
1503  int nnames;
1504 
1505  idents = list_make3(makeString(word1),
1506  makeString(word2),
1507  makeString(word3));
1508 
1509  /*
1510  * We should do nothing in DECLARE sections. In SQL expressions, we
1511  * really only need to make sure that RECFIELD datums are created when
1512  * needed.
1513  */
1515  {
1516  /*
1517  * Do a lookup in the current namespace stack. Must find a qualified
1518  * reference, else ignore.
1519  */
1520  ns = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1521  word1, word2, word3,
1522  &nnames);
1523  if (ns != NULL && nnames == 2)
1524  {
1525  switch (ns->itemtype)
1526  {
1527  case PLPGSQL_NSTYPE_REC:
1528  {
1529  /*
1530  * words 1/2 are a record name, so third word could be
1531  * a field in this record.
1532  */
1533  PLpgSQL_rec *rec;
1534  PLpgSQL_recfield *new;
1535 
1536  rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
1537  new = plpgsql_build_recfield(rec, word3);
1538 
1539  wdatum->datum = (PLpgSQL_datum *) new;
1540  wdatum->ident = NULL;
1541  wdatum->quoted = false; /* not used */
1542  wdatum->idents = idents;
1543  return true;
1544  }
1545 
1546  default:
1547  break;
1548  }
1549  }
1550  }
1551 
1552  /* Nothing found */
1553  cword->idents = idents;
1554  return false;
1555 }
Value * makeString(char *str)
Definition: value.c:53
#define list_make3(x1, x2, x3)
Definition: pg_list.h:141
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
Definition: pl_funcs.c:132
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
Definition: pl_comp.c:1956
List * idents
Definition: plpgsql.h:1108
List * idents
Definition: plpgsql.h:1116
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:29
PLpgSQL_datum * datum
Definition: plpgsql.h:1113
bool quoted
Definition: plpgsql.h:1115
char * ident
Definition: plpgsql.h:1114
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428
Definition: pg_list.h:45

◆ plpgsql_parse_word()

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

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

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

◆ plpgsql_parse_wordrowtype()

PLpgSQL_type* plpgsql_parse_wordrowtype ( char *  ident)

Definition at line 1747 of file pl_comp.c.

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

1748 {
1749  Oid classOid;
1750 
1751  /* Lookup the relation */
1752  classOid = RelnameGetRelid(ident);
1753  if (!OidIsValid(classOid))
1754  ereport(ERROR,
1756  errmsg("relation \"%s\" does not exist", ident)));
1757 
1758  /* Build and return the row type struct */
1759  return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid);
1760 }
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation)
Definition: pl_comp.c:1998
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:62
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:673
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Oid get_rel_type_id(Oid relid)
Definition: lsyscache.c:1781
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ plpgsql_parse_wordtype()

PLpgSQL_type* plpgsql_parse_wordtype ( char *  ident)

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

1567 {
1568  PLpgSQL_type *dtype;
1569  PLpgSQL_nsitem *nse;
1570  HeapTuple typeTup;
1571 
1572  /*
1573  * Do a lookup in the current namespace stack
1574  */
1575  nse = plpgsql_ns_lookup(plpgsql_ns_top(), false,
1576  ident, NULL, NULL,
1577  NULL);
1578 
1579  if (nse != NULL)
1580  {
1581  switch (nse->itemtype)
1582  {
1583  case PLPGSQL_NSTYPE_VAR:
1584  return ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
1585 
1586  /* XXX perhaps allow REC/ROW here? */
1587 
1588  default:
1589  return NULL;
1590  }
1591  }
1592 
1593  /*
1594  * Word wasn't found in the namespace stack. Try to find a data type with
1595  * that name, but ignore shell types and complex types.
1596  */
1597  typeTup = LookupTypeName(NULL, makeTypeName(ident), NULL, false);
1598  if (typeTup)
1599  {
1600  Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1601 
1602  if (!typeStruct->typisdefined ||
1603  typeStruct->typrelid != InvalidOid)
1604  {
1605  ReleaseSysCache(typeTup);
1606  return NULL;
1607  }
1608 
1609  dtype = build_datatype(typeTup, -1,
1611 
1612  ReleaseSysCache(typeTup);
1613  return dtype;
1614  }
1615 
1616  /*
1617  * Nothing found - up to now it's a word without any special meaning for
1618  * us.
1619  */
1620  return NULL;
1621 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:57
PLpgSQL_datum ** plpgsql_Datums
Definition: pl_comp.c:47
PLpgSQL_nsitem * plpgsql_ns_top(void)
Definition: pl_funcs.c:83
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
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:934
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define InvalidOid
Definition: postgres_ext.h:36
TypeName * makeTypeName(char *typnam)
Definition: makefuncs.c:443
FormData_pg_type * Form_pg_type
Definition: pg_type.h:247
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
Definition: pl_comp.c:2018
PLpgSQL_nsitem_type itemtype
Definition: plpgsql.h:428
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 1051 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().

1052 {
1056  /* no need to use p_coerce_param_hook */
1057  pstate->p_ref_hook_state = (void *) expr;
1058 }
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
Definition: pl_comp.c:1064
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:213
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:214
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
Definition: pl_comp.c:1122
void * p_ref_hook_state
Definition: parse_node.h:216
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:212
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: pl_comp.c:1078

◆ plpgsql_peek()

int plpgsql_peek ( void  )

Definition at line 542 of file pl_scanner.c.

References internal_yylex(), and push_back_token().

543 {
544  int tok1;
545  TokenAuxData aux1;
546 
547  tok1 = internal_yylex(&aux1);
548  push_back_token(tok1, &aux1);
549  return tok1;
550 }
static int internal_yylex(TokenAuxData *auxdata)
Definition: pl_scanner.c:430
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:476

◆ plpgsql_peek2()

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

Definition at line 561 of file pl_scanner.c.

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

562 {
563  int tok1,
564  tok2;
565  TokenAuxData aux1,
566  aux2;
567 
568  tok1 = internal_yylex(&aux1);
569  tok2 = internal_yylex(&aux2);
570 
571  *tok1_p = tok1;
572  if (tok1_loc)
573  *tok1_loc = aux1.lloc;
574  *tok2_p = tok2;
575  if (tok2_loc)
576  *tok2_loc = aux2.lloc;
577 
578  push_back_token(tok2, &aux2);
579  push_back_token(tok1, &aux1);
580 }
YYLTYPE lloc
Definition: pl_scanner.c:204
static int internal_yylex(TokenAuxData *auxdata)
Definition: pl_scanner.c:430
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:476

◆ plpgsql_push_back_token()

void plpgsql_push_back_token ( int  token)

Definition at line 492 of file pl_scanner.c.

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

493 {
494  TokenAuxData auxdata;
495 
496  auxdata.lval = plpgsql_yylval;
497  auxdata.lloc = plpgsql_yylloc;
498  auxdata.leng = plpgsql_yyleng;
499  push_back_token(token, &auxdata);
500 }
YYLTYPE lloc
Definition: pl_scanner.c:204
YYSTYPE lval
Definition: pl_scanner.c:203
static int plpgsql_yyleng
Definition: pl_scanner.c:223
static void push_back_token(int token, TokenAuxData *auxdata)
Definition: pl_scanner.c:476

◆ plpgsql_recognize_err_condition()

int plpgsql_recognize_err_condition ( const char *  condname,
bool  allow_sqlstate 
)

Definition at line 2100 of file pl_comp.c.

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

Referenced by exec_stmt_raise().

2101 {
2102  int i;
2103 
2104  if (allow_sqlstate)
2105  {
2106  if (strlen(condname) == 5 &&
2107  strspn(condname, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2108  return MAKE_SQLSTATE(condname[0],
2109  condname[1],
2110  condname[2],
2111  condname[3],
2112  condname[4]);
2113  }
2114 
2115  for (i = 0; exception_label_map[i].label != NULL; i++)
2116  {
2117  if (strcmp(condname, exception_label_map[i].label) == 0)
2119  }
2120 
2121  ereport(ERROR,
2122  (errcode(ERRCODE_UNDEFINED_OBJECT),
2123  errmsg("unrecognized exception condition \"%s\"",
2124  condname)));
2125  return 0; /* keep compiler quiet */
2126 }
const char * label
Definition: pl_comp.c:79
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:62
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static char * label
Definition: pg_basebackup.c:84
static const ExceptionLabelMap exception_label_map[]
Definition: pl_comp.c:83
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i

◆ plpgsql_scanner_errposition()

int plpgsql_scanner_errposition ( int  location)

Definition at line 594 of file pl_scanner.c.

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

Referenced by plpgsql_yyerror().

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

◆ plpgsql_scanner_finish()

void plpgsql_scanner_finish ( void  )

Definition at line 735 of file pl_scanner.c.

References scanner_finish(), scanorig, and yyscanner.

Referenced by do_compile(), and plpgsql_compile_inline().

736 {
737  /* release storage */
739  /* avoid leaving any dangling pointers */
740  yyscanner = NULL;
741  scanorig = NULL;
742 }
static const char * scanorig
Definition: pl_scanner.c:220
static core_yyscan_t yyscanner
Definition: pl_scanner.c:216
void scanner_finish(core_yyscan_t yyscanner)

◆ plpgsql_scanner_init()

void plpgsql_scanner_init ( const char *  str)

Definition at line 708 of file pl_scanner.c.

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

Referenced by do_compile(), and plpgsql_compile_inline().

709 {
710  /* Start up the core scanner */
713 
714  /*
715  * scanorig points to the original string, which unlike the scanner's
716  * scanbuf won't be modified on-the-fly by flex. Notice that although
717  * yytext points into scanbuf, we rely on being able to apply locations
718  * (offsets from string start) to scanorig as well.
719  */
720  scanorig = str;
721 
722  /* Other setup */
724  plpgsql_yytoken = 0;
725 
726  num_pushbacks = 0;
727 
729 }
static const ScanKeyword reserved_keywords[]
Definition: pl_scanner.c:70
static void location_lineno_init(void)
Definition: pl_scanner.c:684
static int plpgsql_yytoken
Definition: pl_scanner.c:226
static const char * scanorig
Definition: pl_scanner.c:220
IdentifierLookup plpgsql_IdentifierLookup
Definition: pl_scanner.c:29
static int num_pushbacks
Definition: pl_scanner.c:231
static core_yy_extra_type core_yy
Definition: pl_scanner.c:217
core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, const ScanKeyword *keywords, int num_keywords)
static core_yyscan_t yyscanner
Definition: pl_scanner.c:216
static const int num_reserved_keywords
Definition: pl_scanner.c:97

◆ plpgsql_stmt_typename()

const char* plpgsql_stmt_typename ( PLpgSQL_stmt stmt)

Definition at line 234 of file pl_funcs.c.

References _, PLpgSQL_stmt::cmd_type, PLPGSQL_STMT_ASSERT, PLPGSQL_STMT_ASSIGN, PLPGSQL_STMT_BLOCK, PLPGSQL_STMT_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:444
#define _(x)
Definition: elog.c:84

◆ plpgsql_subxact_cb()

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

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

8043 {
8044  if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
8045  {
8046  while (simple_econtext_stack != NULL &&
8047  simple_econtext_stack->xact_subxid == mySubid)
8048  {
8050 
8052  (event == SUBXACT_EVENT_COMMIT_SUB));
8053  next = simple_econtext_stack->next;
8056  }
8057  }
8058 }
static int32 next
Definition: blutils.c:211
struct SimpleEcontextStackEntry * next
Definition: pl_exec.c:91
void pfree(void *pointer)
Definition: mcxt.c:1031
ExprContext * stack_econtext
Definition: pl_exec.c:89
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:95
SubTransactionId xact_subxid
Definition: pl_exec.c:90
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:359

◆ plpgsql_token_is_unreserved_keyword()

bool plpgsql_token_is_unreserved_keyword ( int  token)

Definition at line 509 of file pl_scanner.c.

References i, num_unreserved_keywords, and value.

510 {
511  int i;
512 
513  for (i = 0; i < num_unreserved_keywords; i++)
514  {
515  if (unreserved_keywords[i].value == token)
516  return true;
517  }
518  return false;
519 }
static const int num_unreserved_keywords
Definition: pl_scanner.c:184
static const ScanKeyword unreserved_keywords[]
Definition: pl_scanner.c:99
static struct @131 value
int i

◆ plpgsql_xact_cb()

void plpgsql_xact_cb ( XactEvent  event,
void *  arg 
)

Definition at line 8010 of file pl_exec.c.

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

Referenced by _PG_init().

8011 {
8012  /*
8013  * If we are doing a clean transaction shutdown, free the EState (so that
8014  * any remaining resources will be released correctly). In an abort, we
8015  * expect the regular abort recovery procedures to release everything of
8016  * interest.
8017  */
8018  if (event == XACT_EVENT_COMMIT || event == XACT_EVENT_PREPARE)
8019  {
8020  simple_econtext_stack = NULL;
8021 
8025  }
8026  else if (event == XACT_EVENT_ABORT)
8027  {
8028  simple_econtext_stack = NULL;
8030  }
8031 }
void FreeExecutorState(EState *estate)
Definition: execUtils.c:188
static SimpleEcontextStackEntry * simple_econtext_stack
Definition: pl_exec.c:95
static EState * shared_simple_eval_estate
Definition: pl_exec.c:94

◆ plpgsql_yyerror()

void plpgsql_yyerror ( const char *  message)

Definition at line 621 of file pl_scanner.c.

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

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

◆ plpgsql_yylex()

int plpgsql_yylex ( void  )

Definition at line 256 of file pl_scanner.c.

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

257 {
258  int tok1;
259  TokenAuxData aux1;
260  const ScanKeyword *kw;
261 
262  tok1 = internal_yylex(&aux1);
263  if (tok1 == IDENT || tok1 == PARAM)
264  {
265  int tok2;
266  TokenAuxData aux2;
267 
268  tok2 = internal_yylex(&aux2);
269  if (tok2 == '.')
270  {
271  int tok3;
272  TokenAuxData aux3;
273 
274  tok3 = internal_yylex(&aux3);
275  if (tok3 == IDENT)
276  {
277  int tok4;
278  TokenAuxData aux4;
279 
280  tok4 = internal_yylex(&aux4);
281  if (tok4 == '.')
282  {
283  int tok5;
284  TokenAuxData aux5;
285 
286  tok5 = internal_yylex(&aux5);
287  if (tok5 == IDENT)
288  {
289  if (plpgsql_parse_tripword(aux1.lval.str,
290  aux3.lval.str,
291  aux5.lval.str,
292  &aux1.lval.wdatum,
293  &aux1.lval.cword))
294  tok1 = T_DATUM;
295  else
296  tok1 = T_CWORD;
297  }
298  else
299  {
300  /* not A.B.C, so just process A.B */
301  push_back_token(tok5, &aux5);
302  push_back_token(tok4, &aux4);
303  if (plpgsql_parse_dblword(aux1.lval.str,
304  aux3.lval.str,
305  &aux1.lval.wdatum,
306  &aux1.lval.cword))
307  tok1 = T_DATUM;
308  else
309  tok1 = T_CWORD;
310  }
311  }
312  else
313  {
314  /* not A.B.C, so just process A.B */
315  push_back_token(tok4, &aux4);
316  if (plpgsql_parse_dblword(aux1.lval.str,
317  aux3.lval.str,
318  &aux1.lval.wdatum,
319  &aux1.lval.cword))
320  tok1 = T_DATUM;
321  else
322  tok1 = T_CWORD;
323  }
324  }
325  else
326  {
327  /* not A.B, so just process A */
328  push_back_token(tok3, &aux3);
329  push_back_token(tok2, &aux2);
330  if (plpgsql_parse_word(aux1.lval.str,
331  core_yy.scanbuf + aux1.lloc,
332  &aux1.lval.wdatum,
333  &aux1.lval.word))
334  tok1 = T_DATUM;
335  else if (!aux1.lval.word.quoted &&
336  (kw = ScanKeywordLookup(aux1.lval.word.ident,
339  {
340  aux1.lval.keyword = kw->name;
341  tok1 = kw->value;