PostgreSQL Source Code  git master
spi.h File Reference
#include "commands/trigger.h"
#include "lib/ilist.h"
#include "parser/parser.h"
#include "utils/portal.h"
Include dependency graph for spi.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SPITupleTable
 
struct  SPIPrepareOptions
 
struct  SPIExecuteOptions
 
struct  SPIParseOpenOptions
 

Macros

#define SPI_ERROR_CONNECT   (-1)
 
#define SPI_ERROR_COPY   (-2)
 
#define SPI_ERROR_OPUNKNOWN   (-3)
 
#define SPI_ERROR_UNCONNECTED   (-4)
 
#define SPI_ERROR_CURSOR   (-5) /* not used anymore */
 
#define SPI_ERROR_ARGUMENT   (-6)
 
#define SPI_ERROR_PARAM   (-7)
 
#define SPI_ERROR_TRANSACTION   (-8)
 
#define SPI_ERROR_NOATTRIBUTE   (-9)
 
#define SPI_ERROR_NOOUTFUNC   (-10)
 
#define SPI_ERROR_TYPUNKNOWN   (-11)
 
#define SPI_ERROR_REL_DUPLICATE   (-12)
 
#define SPI_ERROR_REL_NOT_FOUND   (-13)
 
#define SPI_OK_CONNECT   1
 
#define SPI_OK_FINISH   2
 
#define SPI_OK_FETCH   3
 
#define SPI_OK_UTILITY   4
 
#define SPI_OK_SELECT   5
 
#define SPI_OK_SELINTO   6
 
#define SPI_OK_INSERT   7
 
#define SPI_OK_DELETE   8
 
#define SPI_OK_UPDATE   9
 
#define SPI_OK_CURSOR   10
 
#define SPI_OK_INSERT_RETURNING   11
 
#define SPI_OK_DELETE_RETURNING   12
 
#define SPI_OK_UPDATE_RETURNING   13
 
#define SPI_OK_REWRITTEN   14
 
#define SPI_OK_REL_REGISTER   15
 
#define SPI_OK_REL_UNREGISTER   16
 
#define SPI_OK_TD_REGISTER   17
 
#define SPI_OPT_NONATOMIC   (1 << 0)
 
#define SPI_push()   ((void) 0)
 
#define SPI_pop()   ((void) 0)
 
#define SPI_push_conditional()   false
 
#define SPI_pop_conditional(pushed)   ((void) 0)
 
#define SPI_restore_connection()   ((void) 0)
 

Typedefs

typedef struct SPITupleTable SPITupleTable
 
typedef struct SPIPrepareOptions SPIPrepareOptions
 
typedef struct SPIExecuteOptions SPIExecuteOptions
 
typedef struct SPIParseOpenOptions SPIParseOpenOptions
 
typedef struct _SPI_planSPIPlanPtr
 

Functions

int SPI_connect (void)
 
int SPI_connect_ext (int options)
 
int SPI_finish (void)
 
int SPI_execute (const char *src, bool read_only, long tcount)
 
int SPI_execute_extended (const char *src, const SPIExecuteOptions *options)
 
int SPI_execute_plan (SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
 
int SPI_execute_plan_extended (SPIPlanPtr plan, const SPIExecuteOptions *options)
 
int SPI_execute_plan_with_paramlist (SPIPlanPtr plan, ParamListInfo params, bool read_only, long tcount)
 
int SPI_exec (const char *src, long tcount)
 
int SPI_execp (SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount)
 
int SPI_execute_snapshot (SPIPlanPtr plan, Datum *Values, const char *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount)
 
int SPI_execute_with_args (const char *src, int nargs, Oid *argtypes, Datum *Values, const char *Nulls, bool read_only, long tcount)
 
SPIPlanPtr SPI_prepare (const char *src, int nargs, Oid *argtypes)
 
SPIPlanPtr SPI_prepare_cursor (const char *src, int nargs, Oid *argtypes, int cursorOptions)
 
SPIPlanPtr SPI_prepare_extended (const char *src, const SPIPrepareOptions *options)
 
SPIPlanPtr SPI_prepare_params (const char *src, ParserSetupHook parserSetup, void *parserSetupArg, int cursorOptions)
 
int SPI_keepplan (SPIPlanPtr plan)
 
SPIPlanPtr SPI_saveplan (SPIPlanPtr plan)
 
int SPI_freeplan (SPIPlanPtr plan)
 
Oid SPI_getargtypeid (SPIPlanPtr plan, int argIndex)
 
int SPI_getargcount (SPIPlanPtr plan)
 
bool SPI_is_cursor_plan (SPIPlanPtr plan)
 
bool SPI_plan_is_valid (SPIPlanPtr plan)
 
const char * SPI_result_code_string (int code)
 
ListSPI_plan_get_plan_sources (SPIPlanPtr plan)
 
CachedPlanSPI_plan_get_cached_plan (SPIPlanPtr plan)
 
HeapTuple SPI_copytuple (HeapTuple tuple)
 
HeapTupleHeader SPI_returntuple (HeapTuple tuple, TupleDesc tupdesc)
 
HeapTuple SPI_modifytuple (Relation rel, HeapTuple tuple, int natts, int *attnum, Datum *Values, const char *Nulls)
 
int SPI_fnumber (TupleDesc tupdesc, const char *fname)
 
char * SPI_fname (TupleDesc tupdesc, int fnumber)
 
char * SPI_getvalue (HeapTuple tuple, TupleDesc tupdesc, int fnumber)
 
Datum SPI_getbinval (HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
 
char * SPI_gettype (TupleDesc tupdesc, int fnumber)
 
Oid SPI_gettypeid (TupleDesc tupdesc, int fnumber)
 
char * SPI_getrelname (Relation rel)
 
char * SPI_getnspname (Relation rel)
 
void * SPI_palloc (Size size)
 
void * SPI_repalloc (void *pointer, Size size)
 
void SPI_pfree (void *pointer)
 
Datum SPI_datumTransfer (Datum value, bool typByVal, int typLen)
 
void SPI_freetuple (HeapTuple pointer)
 
void SPI_freetuptable (SPITupleTable *tuptable)
 
Portal SPI_cursor_open (const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
 
Portal SPI_cursor_open_with_args (const char *name, const char *src, int nargs, Oid *argtypes, Datum *Values, const char *Nulls, bool read_only, int cursorOptions)
 
Portal SPI_cursor_open_with_paramlist (const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only)
 
Portal SPI_cursor_parse_open (const char *name, const char *src, const SPIParseOpenOptions *options)
 
Portal SPI_cursor_find (const char *name)
 
void SPI_cursor_fetch (Portal portal, bool forward, long count)
 
void SPI_cursor_move (Portal portal, bool forward, long count)
 
void SPI_scroll_cursor_fetch (Portal, FetchDirection direction, long count)
 
void SPI_scroll_cursor_move (Portal, FetchDirection direction, long count)
 
void SPI_cursor_close (Portal portal)
 
int SPI_register_relation (EphemeralNamedRelation enr)
 
int SPI_unregister_relation (const char *name)
 
int SPI_register_trigger_data (TriggerData *tdata)
 
void SPI_start_transaction (void)
 
void SPI_commit (void)
 
void SPI_commit_and_chain (void)
 
void SPI_rollback (void)
 
void SPI_rollback_and_chain (void)
 
void SPICleanup (void)
 
void AtEOXact_SPI (bool isCommit)
 
void AtEOSubXact_SPI (bool isCommit, SubTransactionId mySubid)
 
bool SPI_inside_nonatomic_context (void)
 

Variables

PGDLLIMPORT uint64 SPI_processed
 
PGDLLIMPORT SPITupleTableSPI_tuptable
 
PGDLLIMPORT int SPI_result
 

Macro Definition Documentation

◆ SPI_ERROR_ARGUMENT

#define SPI_ERROR_ARGUMENT   (-6)

Definition at line 73 of file spi.h.

◆ SPI_ERROR_CONNECT

#define SPI_ERROR_CONNECT   (-1)

Definition at line 68 of file spi.h.

◆ SPI_ERROR_COPY

#define SPI_ERROR_COPY   (-2)

Definition at line 69 of file spi.h.

◆ SPI_ERROR_CURSOR

#define SPI_ERROR_CURSOR   (-5) /* not used anymore */

Definition at line 72 of file spi.h.

◆ SPI_ERROR_NOATTRIBUTE

#define SPI_ERROR_NOATTRIBUTE   (-9)

Definition at line 76 of file spi.h.

◆ SPI_ERROR_NOOUTFUNC

#define SPI_ERROR_NOOUTFUNC   (-10)

Definition at line 77 of file spi.h.

◆ SPI_ERROR_OPUNKNOWN

#define SPI_ERROR_OPUNKNOWN   (-3)

Definition at line 70 of file spi.h.

◆ SPI_ERROR_PARAM

#define SPI_ERROR_PARAM   (-7)

Definition at line 74 of file spi.h.

◆ SPI_ERROR_REL_DUPLICATE

#define SPI_ERROR_REL_DUPLICATE   (-12)

Definition at line 79 of file spi.h.

◆ SPI_ERROR_REL_NOT_FOUND

#define SPI_ERROR_REL_NOT_FOUND   (-13)

Definition at line 80 of file spi.h.

◆ SPI_ERROR_TRANSACTION

#define SPI_ERROR_TRANSACTION   (-8)

Definition at line 75 of file spi.h.

◆ SPI_ERROR_TYPUNKNOWN

#define SPI_ERROR_TYPUNKNOWN   (-11)

Definition at line 78 of file spi.h.

◆ SPI_ERROR_UNCONNECTED

#define SPI_ERROR_UNCONNECTED   (-4)

Definition at line 71 of file spi.h.

◆ SPI_OK_CONNECT

#define SPI_OK_CONNECT   1

Definition at line 82 of file spi.h.

◆ SPI_OK_CURSOR

#define SPI_OK_CURSOR   10

Definition at line 91 of file spi.h.

◆ SPI_OK_DELETE

#define SPI_OK_DELETE   8

Definition at line 89 of file spi.h.

◆ SPI_OK_DELETE_RETURNING

#define SPI_OK_DELETE_RETURNING   12

Definition at line 93 of file spi.h.

◆ SPI_OK_FETCH

#define SPI_OK_FETCH   3

Definition at line 84 of file spi.h.

◆ SPI_OK_FINISH

#define SPI_OK_FINISH   2

Definition at line 83 of file spi.h.

◆ SPI_OK_INSERT

#define SPI_OK_INSERT   7

Definition at line 88 of file spi.h.

◆ SPI_OK_INSERT_RETURNING

#define SPI_OK_INSERT_RETURNING   11

Definition at line 92 of file spi.h.

◆ SPI_OK_REL_REGISTER

#define SPI_OK_REL_REGISTER   15

Definition at line 96 of file spi.h.

◆ SPI_OK_REL_UNREGISTER

#define SPI_OK_REL_UNREGISTER   16

Definition at line 97 of file spi.h.

◆ SPI_OK_REWRITTEN

#define SPI_OK_REWRITTEN   14

Definition at line 95 of file spi.h.

◆ SPI_OK_SELECT

#define SPI_OK_SELECT   5

Definition at line 86 of file spi.h.

◆ SPI_OK_SELINTO

#define SPI_OK_SELINTO   6

Definition at line 87 of file spi.h.

◆ SPI_OK_TD_REGISTER

#define SPI_OK_TD_REGISTER   17

Definition at line 98 of file spi.h.

◆ SPI_OK_UPDATE

#define SPI_OK_UPDATE   9

Definition at line 90 of file spi.h.

◆ SPI_OK_UPDATE_RETURNING

#define SPI_OK_UPDATE_RETURNING   13

Definition at line 94 of file spi.h.

◆ SPI_OK_UTILITY

#define SPI_OK_UTILITY   4

Definition at line 85 of file spi.h.

◆ SPI_OPT_NONATOMIC

#define SPI_OPT_NONATOMIC   (1 << 0)

Definition at line 100 of file spi.h.

◆ SPI_pop

#define SPI_pop ( )    ((void) 0)

Definition at line 104 of file spi.h.

◆ SPI_pop_conditional

#define SPI_pop_conditional (   pushed)    ((void) 0)

Definition at line 106 of file spi.h.

◆ SPI_push

#define SPI_push ( )    ((void) 0)

Definition at line 103 of file spi.h.

◆ SPI_push_conditional

#define SPI_push_conditional ( )    false

Definition at line 105 of file spi.h.

◆ SPI_restore_connection

#define SPI_restore_connection ( )    ((void) 0)

Definition at line 107 of file spi.h.

Typedef Documentation

◆ SPIExecuteOptions

◆ SPIParseOpenOptions

◆ SPIPlanPtr

typedef struct _SPI_plan* SPIPlanPtr

Definition at line 66 of file spi.h.

◆ SPIPrepareOptions

◆ SPITupleTable

typedef struct SPITupleTable SPITupleTable

Function Documentation

◆ AtEOSubXact_SPI()

void AtEOSubXact_SPI ( bool  isCommit,
SubTransactionId  mySubid 
)

Definition at line 390 of file spi.c.

391 {
392  bool found = false;
393 
394  while (_SPI_connected >= 0)
395  {
397 
398  if (connection->connectSubid != mySubid)
399  break; /* couldn't be any underneath it either */
400 
401  if (connection->internal_xact)
402  break;
403 
404  found = true;
405 
406  /*
407  * Release procedure memory explicitly (see note in SPI_connect)
408  */
409  if (connection->execCxt)
410  {
412  connection->execCxt = NULL;
413  }
414  if (connection->procCxt)
415  {
417  connection->procCxt = NULL;
418  }
419 
420  /*
421  * Restore outer global variables and pop the stack entry. Unlike
422  * SPI_finish(), we don't risk switching to memory contexts that might
423  * be already gone.
424  */
425  SPI_processed = connection->outer_processed;
426  SPI_tuptable = connection->outer_tuptable;
427  SPI_result = connection->outer_result;
428 
429  _SPI_connected--;
430  if (_SPI_connected < 0)
431  _SPI_current = NULL;
432  else
434  }
435 
436  if (found && isCommit)
438  (errcode(ERRCODE_WARNING),
439  errmsg("subtransaction left non-empty SPI stack"),
440  errhint("Check for missing \"SPI_finish\" calls.")));
441 
442  /*
443  * If we are aborting a subtransaction and there is an open SPI context
444  * surrounding the subxact, clean up to prevent memory leakage.
445  */
446  if (_SPI_current && !isCommit)
447  {
448  slist_mutable_iter siter;
449 
450  /*
451  * Throw away executor state if current executor operation was started
452  * within current subxact (essentially, force a _SPI_end_call(true)).
453  */
454  if (_SPI_current->execSubid >= mySubid)
455  {
458  }
459 
460  /* throw away any tuple tables created within current subxact */
462  {
463  SPITupleTable *tuptable;
464 
465  tuptable = slist_container(SPITupleTable, next, siter.cur);
466  if (tuptable->subid >= mySubid)
467  {
468  /*
469  * If we used SPI_freetuptable() here, its internal search of
470  * the tuptables list would make this operation O(N^2).
471  * Instead, just free the tuptable manually. This should
472  * match what SPI_freetuptable() does.
473  */
474  slist_delete_current(&siter);
475  if (tuptable == _SPI_current->tuptable)
476  _SPI_current->tuptable = NULL;
477  if (tuptable == SPI_tuptable)
478  SPI_tuptable = NULL;
479  MemoryContextDelete(tuptable->tuptabcxt);
480  }
481  }
482  }
483 }
static int32 next
Definition: blutils.c:219
#define InvalidSubTransactionId
Definition: c.h:593
int errhint(const char *fmt,...)
Definition: elog.c:1151
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define WARNING
Definition: elog.h:30
#define ereport(elevel,...)
Definition: elog.h:143
static void slist_delete_current(slist_mutable_iter *iter)
Definition: ilist.h:671
#define slist_foreach_modify(iter, lhead)
Definition: ilist.h:735
#define slist_container(type, membername, ptr)
Definition: ilist.h:693
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:67
static int _SPI_connected
Definition: spi.c:52
uint64 SPI_processed
Definition: spi.c:45
static _SPI_connection * _SPI_stack
Definition: spi.c:49
SPITupleTable * SPI_tuptable
Definition: spi.c:46
int SPI_result
Definition: spi.c:47
static _SPI_connection * _SPI_current
Definition: spi.c:50
MemoryContext tuptabcxt
Definition: spi.h:31
SubTransactionId subid
Definition: spi.h:33
slist_head tuptables
Definition: spi_priv.h:32
MemoryContext execCxt
Definition: spi_priv.h:34
SubTransactionId execSubid
Definition: spi_priv.h:29
SPITupleTable * tuptable
Definition: spi_priv.h:26
slist_node * cur
Definition: ilist.h:241

References _SPI_connected, _SPI_current, _SPI_stack, slist_mutable_iter::cur, ereport, errcode(), errhint(), errmsg(), _SPI_connection::execCxt, _SPI_connection::execSubid, InvalidSubTransactionId, MemoryContextDelete(), MemoryContextResetAndDeleteChildren, next, slist_container, slist_delete_current(), slist_foreach_modify, SPI_processed, SPI_result, SPI_tuptable, SPITupleTable::subid, SPITupleTable::tuptabcxt, _SPI_connection::tuptable, _SPI_connection::tuptables, and WARNING.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_SPI()

void AtEOXact_SPI ( bool  isCommit)

Definition at line 368 of file spi.c.

369 {
370  /* Do nothing if the transaction end was initiated by SPI. */
372  return;
373 
374  if (isCommit && _SPI_connected != -1)
376  (errcode(ERRCODE_WARNING),
377  errmsg("transaction left non-empty SPI stack"),
378  errhint("Check for missing \"SPI_finish\" calls.")));
379 
380  SPICleanup();
381 }
void SPICleanup(void)
Definition: spi.c:354
bool internal_xact
Definition: spi_priv.h:42

References _SPI_connected, _SPI_current, ereport, errcode(), errhint(), errmsg(), _SPI_connection::internal_xact, SPICleanup(), and WARNING.

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

◆ SPI_commit()

void SPI_commit ( void  )

Definition at line 280 of file spi.c.

281 {
282  _SPI_commit(false);
283 }
static void _SPI_commit(bool chain)
Definition: spi.c:227

References _SPI_commit().

Referenced by exec_stmt_commit(), plperl_spi_commit(), pltcl_commit(), and PLy_commit().

◆ SPI_commit_and_chain()

void SPI_commit_and_chain ( void  )

Definition at line 286 of file spi.c.

287 {
288  _SPI_commit(true);
289 }

References _SPI_commit().

Referenced by exec_stmt_commit().

◆ SPI_connect()

◆ SPI_connect_ext()

int SPI_connect_ext ( int  options)

Definition at line 101 of file spi.c.

102 {
103  int newdepth;
104 
105  /* Enlarge stack if necessary */
106  if (_SPI_stack == NULL)
107  {
108  if (_SPI_connected != -1 || _SPI_stack_depth != 0)
109  elog(ERROR, "SPI stack corrupted");
110  newdepth = 16;
113  newdepth * sizeof(_SPI_connection));
114  _SPI_stack_depth = newdepth;
115  }
116  else
117  {
119  elog(ERROR, "SPI stack corrupted");
120  if (_SPI_stack_depth == _SPI_connected + 1)
121  {
122  newdepth = _SPI_stack_depth * 2;
125  newdepth * sizeof(_SPI_connection));
126  _SPI_stack_depth = newdepth;
127  }
128  }
129 
130  /* Enter new stack level */
131  _SPI_connected++;
133 
135  _SPI_current->processed = 0;
136  _SPI_current->tuptable = NULL;
139  _SPI_current->procCxt = NULL; /* in case we fail to create 'em */
140  _SPI_current->execCxt = NULL;
142  _SPI_current->queryEnv = NULL;
144  _SPI_current->internal_xact = false;
148 
149  /*
150  * Create memory contexts for this procedure
151  *
152  * In atomic contexts (the normal case), we use TopTransactionContext,
153  * otherwise PortalContext, so that it lives across transaction
154  * boundaries.
155  *
156  * XXX It could be better to use PortalContext as the parent context in
157  * all cases, but we may not be inside a portal (consider deferred-trigger
158  * execution). Perhaps CurTransactionContext could be an option? For now
159  * it doesn't matter because we clean up explicitly in AtEOSubXact_SPI().
160  */
162  "SPI Proc",
165  "SPI Exec",
167  /* ... and switch to procedure's context */
169 
170  /*
171  * Reset API global variables so that current caller cannot accidentally
172  * depend on state of an outer caller.
173  */
174  SPI_processed = 0;
175  SPI_tuptable = NULL;
176  SPI_result = 0;
177 
178  return SPI_OK_CONNECT;
179 }
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
static void slist_init(slist_head *head)
Definition: ilist.h:573
return false
Definition: isn.c:131
Assert(fmt[strlen(fmt) - 1] !='\n')
MemoryContext TopTransactionContext
Definition: mcxt.c:53
MemoryContext TopMemoryContext
Definition: mcxt.c:48
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
MemoryContext PortalContext
Definition: mcxt.c:57
#define AllocSetContextCreate
Definition: memutils.h:173
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static int _SPI_stack_depth
Definition: spi.c:51
#define SPI_OPT_NONATOMIC
Definition: spi.h:100
#define SPI_OK_CONNECT
Definition: spi.h:82
SubTransactionId connectSubid
Definition: spi_priv.h:36
uint64 processed
Definition: spi_priv.h:25
SPITupleTable * outer_tuptable
Definition: spi_priv.h:47
QueryEnvironment * queryEnv
Definition: spi_priv.h:37
int outer_result
Definition: spi_priv.h:48
uint64 outer_processed
Definition: spi_priv.h:46
MemoryContext procCxt
Definition: spi_priv.h:33
MemoryContext savedcxt
Definition: spi_priv.h:35
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:775

References _SPI_connected, _SPI_current, _SPI_stack, _SPI_stack_depth, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), _SPI_connection::atomic, _SPI_connection::connectSubid, elog, ERROR, _SPI_connection::execCxt, _SPI_connection::execSubid, false, GetCurrentSubTransactionId(), _SPI_connection::internal_xact, InvalidSubTransactionId, MemoryContextAlloc(), MemoryContextSwitchTo(), _SPI_connection::outer_processed, _SPI_connection::outer_result, _SPI_connection::outer_tuptable, PortalContext, _SPI_connection::procCxt, _SPI_connection::processed, _SPI_connection::queryEnv, repalloc(), _SPI_connection::savedcxt, slist_init(), SPI_OK_CONNECT, SPI_OPT_NONATOMIC, SPI_processed, SPI_result, SPI_tuptable, TopMemoryContext, TopTransactionContext, _SPI_connection::tuptable, and _SPI_connection::tuptables.

Referenced by plperl_func_handler(), plperl_inline_handler(), plpgsql_call_handler(), plpgsql_inline_handler(), plpython_call_handler(), plpython_inline_handler(), pltcl_func_handler(), and SPI_connect().

◆ SPI_copytuple()

HeapTuple SPI_copytuple ( HeapTuple  tuple)

Definition at line 952 of file spi.c.

953 {
954  MemoryContext oldcxt;
955  HeapTuple ctuple;
956 
957  if (tuple == NULL)
958  {
960  return NULL;
961  }
962 
963  if (_SPI_current == NULL)
964  {
966  return NULL;
967  }
968 
970 
971  ctuple = heap_copytuple(tuple);
972 
973  MemoryContextSwitchTo(oldcxt);
974 
975  return ctuple;
976 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:71
#define SPI_ERROR_ARGUMENT
Definition: spi.h:73

References _SPI_current, heap_copytuple(), MemoryContextSwitchTo(), _SPI_connection::savedcxt, SPI_ERROR_ARGUMENT, SPI_ERROR_UNCONNECTED, and SPI_result.

Referenced by get_tuple_of_interest(), and plpgsql_exec_trigger().

◆ SPI_cursor_close()

void SPI_cursor_close ( Portal  portal)

Definition at line 1767 of file spi.c.

1768 {
1769  if (!PortalIsValid(portal))
1770  elog(ERROR, "invalid portal in SPI cursor operation");
1771 
1772  PortalDrop(portal, false);
1773 }
#define PortalIsValid(p)
Definition: portal.h:212
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:468

References elog, ERROR, PortalDrop(), and PortalIsValid.

Referenced by exec_stmt_close(), exec_stmt_dynfors(), exec_stmt_forc(), exec_stmt_fors(), plperl_spi_cursor_close(), plperl_spi_fetchrow(), PLy_cursor_close(), PLy_cursor_dealloc(), query_to_xml_and_xmlschema(), query_to_xmlschema(), ts_stat_sql(), and tsquery_rewrite_query().

◆ SPI_cursor_fetch()

void SPI_cursor_fetch ( Portal  portal,
bool  forward,
long  count 
)

Definition at line 1711 of file spi.c.

1712 {
1713  _SPI_cursor_operation(portal,
1714  forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1716  /* we know that the DestSPI receiver doesn't need a destroy call */
1717 }
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:113
@ DestSPI
Definition: dest.h:94
@ FETCH_FORWARD
Definition: parsenodes.h:2858
@ FETCH_BACKWARD
Definition: parsenodes.h:2859
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2883

References _SPI_cursor_operation(), CreateDestReceiver(), DestSPI, FETCH_BACKWARD, and FETCH_FORWARD.

Referenced by cursor_to_xml(), exec_for_query(), plperl_spi_fetchrow(), PLy_cursor_fetch(), PLy_cursor_iternext(), ts_stat_sql(), and tsquery_rewrite_query().

◆ SPI_cursor_find()

Portal SPI_cursor_find ( const char *  name)

Definition at line 1699 of file spi.c.

1700 {
1701  return GetPortalByName(name);
1702 }
const char * name
Definition: encode.c:561
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130

References GetPortalByName(), and name.

Referenced by cursor_to_xml(), cursor_to_xmlschema(), exec_stmt_close(), exec_stmt_fetch(), exec_stmt_forc(), exec_stmt_open(), plperl_spi_cursor_close(), and plperl_spi_fetchrow().

◆ SPI_cursor_move()

void SPI_cursor_move ( Portal  portal,
bool  forward,
long  count 
)

Definition at line 1726 of file spi.c.

1727 {
1728  _SPI_cursor_operation(portal,
1729  forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1730  None_Receiver);
1731 }
DestReceiver * None_Receiver
Definition: dest.c:96

References _SPI_cursor_operation(), FETCH_BACKWARD, FETCH_FORWARD, and None_Receiver.

◆ SPI_cursor_open()

Portal SPI_cursor_open ( const char *  name,
SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
bool  read_only 
)

Definition at line 1350 of file spi.c.

1353 {
1354  Portal portal;
1355  ParamListInfo paramLI;
1356 
1357  /* build transient ParamListInfo in caller's context */
1358  paramLI = _SPI_convert_params(plan->nargs, plan->argtypes,
1359  Values, Nulls);
1360 
1361  portal = SPI_cursor_open_internal(name, plan, paramLI, read_only);
1362 
1363  /* done with the transient ParamListInfo */
1364  if (paramLI)
1365  pfree(paramLI);
1366 
1367  return portal;
1368 }
static bool Nulls[MAXATTR]
Definition: bootstrap.c:157
void pfree(void *pointer)
Definition: mcxt.c:1169
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2731
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1482
Oid * argtypes
Definition: spi_priv.h:100
int nargs
Definition: spi_priv.h:99

References _SPI_convert_params(), _SPI_plan::argtypes, name, _SPI_plan::nargs, Nulls, pfree(), and SPI_cursor_open_internal().

Referenced by plperl_spi_query(), plperl_spi_query_prepared(), PLy_cursor_plan(), PLy_cursor_query(), query_to_xml_and_xmlschema(), query_to_xmlschema(), ts_stat_sql(), and tsquery_rewrite_query().

◆ SPI_cursor_open_with_args()

Portal SPI_cursor_open_with_args ( const char *  name,
const char *  src,
int  nargs,
Oid argtypes,
Datum Values,
const char *  Nulls,
bool  read_only,
int  cursorOptions 
)

Definition at line 1377 of file spi.c.

1382 {
1383  Portal result;
1384  _SPI_plan plan;
1385  ParamListInfo paramLI;
1386 
1387  if (src == NULL || nargs < 0)
1388  elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
1389 
1390  if (nargs > 0 && (argtypes == NULL || Values == NULL))
1391  elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
1392 
1393  SPI_result = _SPI_begin_call(true);
1394  if (SPI_result < 0)
1395  elog(ERROR, "SPI_cursor_open_with_args called while not connected");
1396 
1397  memset(&plan, 0, sizeof(_SPI_plan));
1398  plan.magic = _SPI_PLAN_MAGIC;
1400  plan.cursor_options = cursorOptions;
1401  plan.nargs = nargs;
1402  plan.argtypes = argtypes;
1403  plan.parserSetup = NULL;
1404  plan.parserSetupArg = NULL;
1405 
1406  /* build transient ParamListInfo in executor context */
1407  paramLI = _SPI_convert_params(nargs, argtypes,
1408  Values, Nulls);
1409 
1410  _SPI_prepare_plan(src, &plan);
1411 
1412  /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1413 
1414  result = SPI_cursor_open_internal(name, &plan, paramLI, read_only);
1415 
1416  /* And clean up */
1417  _SPI_end_call(true);
1418 
1419  return result;
1420 }
@ RAW_PARSE_DEFAULT
Definition: parser.h:39
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2977
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2118
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2953
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
ParserSetupHook parserSetup
Definition: spi_priv.h:101
int magic
Definition: spi_priv.h:92
int cursor_options
Definition: spi_priv.h:98
RawParseMode parse_mode
Definition: spi_priv.h:97
void * parserSetupArg
Definition: spi_priv.h:102

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), _SPI_plan::argtypes, _SPI_plan::cursor_options, elog, ERROR, _SPI_plan::magic, name, _SPI_plan::nargs, Nulls, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, SPI_cursor_open_internal(), and SPI_result.

◆ SPI_cursor_open_with_paramlist()

Portal SPI_cursor_open_with_paramlist ( const char *  name,
SPIPlanPtr  plan,
ParamListInfo  params,
bool  read_only 
)

Definition at line 1430 of file spi.c.

1432 {
1433  return SPI_cursor_open_internal(name, plan, params, read_only);
1434 }

References name, and SPI_cursor_open_internal().

Referenced by exec_run_select(), exec_stmt_forc(), and exec_stmt_open().

◆ SPI_cursor_parse_open()

Portal SPI_cursor_parse_open ( const char *  name,
const char *  src,
const SPIParseOpenOptions options 
)

Definition at line 1438 of file spi.c.

1441 {
1442  Portal result;
1443  _SPI_plan plan;
1444 
1445  if (src == NULL || options == NULL)
1446  elog(ERROR, "SPI_cursor_parse_open called with invalid arguments");
1447 
1448  SPI_result = _SPI_begin_call(true);
1449  if (SPI_result < 0)
1450  elog(ERROR, "SPI_cursor_parse_open called while not connected");
1451 
1452  memset(&plan, 0, sizeof(_SPI_plan));
1453  plan.magic = _SPI_PLAN_MAGIC;
1455  plan.cursor_options = options->cursorOptions;
1456  if (options->params)
1457  {
1458  plan.parserSetup = options->params->parserSetup;
1459  plan.parserSetupArg = options->params->parserSetupArg;
1460  }
1461 
1462  _SPI_prepare_plan(src, &plan);
1463 
1464  /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1465 
1466  result = SPI_cursor_open_internal(name, &plan,
1467  options->params, options->read_only);
1468 
1469  /* And clean up */
1470  _SPI_end_call(true);
1471 
1472  return result;
1473 }

References _SPI_begin_call(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), _SPI_plan::cursor_options, elog, ERROR, _SPI_plan::magic, name, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, SPI_cursor_open_internal(), and SPI_result.

Referenced by exec_dynquery_with_params().

◆ SPI_datumTransfer()

Datum SPI_datumTransfer ( Datum  value,
bool  typByVal,
int  typLen 
)

Definition at line 1266 of file spi.c.

1267 {
1268  MemoryContext oldcxt;
1269  Datum result;
1270 
1271  if (_SPI_current == NULL)
1272  elog(ERROR, "SPI_datumTransfer called while not connected to SPI");
1273 
1275 
1276  result = datumTransfer(value, typByVal, typLen);
1277 
1278  MemoryContextSwitchTo(oldcxt);
1279 
1280  return result;
1281 }
Datum datumTransfer(Datum value, bool typByVal, int typLen)
Definition: datum.c:194
static struct @142 value
uintptr_t Datum
Definition: postgres.h:411

References _SPI_current, datumTransfer(), elog, ERROR, MemoryContextSwitchTo(), _SPI_connection::savedcxt, and value.

Referenced by coerce_function_result_tuple(), and plpgsql_exec_function().

◆ SPI_exec()

int SPI_exec ( const char *  src,
long  tcount 
)

Definition at line 535 of file spi.c.

536 {
537  return SPI_execute(src, false, tcount);
538 }
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:501

References SPI_execute().

Referenced by get_tuple_of_interest(), refresh_by_match_merge(), and xpath_table().

◆ SPI_execp()

int SPI_execp ( SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
long  tcount 
)

Definition at line 609 of file spi.c.

610 {
611  return SPI_execute_plan(plan, Values, Nulls, false, tcount);
612 }
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
Definition: spi.c:577

References Nulls, and SPI_execute_plan().

Referenced by check_foreign_key(), check_primary_key(), and ttdummy().

◆ SPI_execute()

int SPI_execute ( const char *  src,
bool  read_only,
long  tcount 
)

Definition at line 501 of file spi.c.

502 {
503  _SPI_plan plan;
505  int res;
506 
507  if (src == NULL || tcount < 0)
508  return SPI_ERROR_ARGUMENT;
509 
510  res = _SPI_begin_call(true);
511  if (res < 0)
512  return res;
513 
514  memset(&plan, 0, sizeof(_SPI_plan));
515  plan.magic = _SPI_PLAN_MAGIC;
518 
519  _SPI_prepare_oneshot_plan(src, &plan);
520 
521  memset(&options, 0, sizeof(options));
522  options.read_only = read_only;
523  options.tcount = tcount;
524 
525  res = _SPI_execute_plan(&plan, &options,
527  true);
528 
529  _SPI_end_call(true);
530  return res;
531 }
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2830
static char ** options
#define InvalidSnapshot
Definition: snapshot.h:123
static int _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options, Snapshot snapshot, Snapshot crosscheck_snapshot, bool fire_triggers)
Definition: spi.c:2296
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2226

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_prepare_oneshot_plan(), CURSOR_OPT_PARALLEL_OK, _SPI_plan::cursor_options, InvalidSnapshot, _SPI_plan::magic, options, _SPI_plan::parse_mode, RAW_PARSE_DEFAULT, res, and SPI_ERROR_ARGUMENT.

Referenced by build_tuplestore_recursively(), crosstab(), get_crosstab_tuplestore(), initialize_worker_spi(), load_categories_hash(), plperl_spi_exec(), pltcl_SPI_execute(), PLy_spi_execute_query(), query_to_oid_list(), query_to_xml_internal(), refresh_by_match_merge(), and SPI_exec().

◆ SPI_execute_extended()

int SPI_execute_extended ( const char *  src,
const SPIExecuteOptions options 
)

Definition at line 542 of file spi.c.

544 {
545  int res;
546  _SPI_plan plan;
547 
548  if (src == NULL || options == NULL)
549  return SPI_ERROR_ARGUMENT;
550 
551  res = _SPI_begin_call(true);
552  if (res < 0)
553  return res;
554 
555  memset(&plan, 0, sizeof(_SPI_plan));
556  plan.magic = _SPI_PLAN_MAGIC;
559  if (options->params)
560  {
561  plan.parserSetup = options->params->parserSetup;
562  plan.parserSetupArg = options->params->parserSetupArg;
563  }
564 
565  _SPI_prepare_oneshot_plan(src, &plan);
566 
567  res = _SPI_execute_plan(&plan, options,
569  true);
570 
571  _SPI_end_call(true);
572  return res;
573 }

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_prepare_oneshot_plan(), CURSOR_OPT_PARALLEL_OK, _SPI_plan::cursor_options, InvalidSnapshot, _SPI_plan::magic, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, res, and SPI_ERROR_ARGUMENT.

Referenced by exec_stmt_dynexecute(), and exec_stmt_return_query().

◆ SPI_execute_plan()

int SPI_execute_plan ( SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
bool  read_only,
long  tcount 
)

Definition at line 577 of file spi.c.

579 {
581  int res;
582 
583  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
584  return SPI_ERROR_ARGUMENT;
585 
586  if (plan->nargs > 0 && Values == NULL)
587  return SPI_ERROR_PARAM;
588 
589  res = _SPI_begin_call(true);
590  if (res < 0)
591  return res;
592 
593  memset(&options, 0, sizeof(options));
594  options.params = _SPI_convert_params(plan->nargs, plan->argtypes,
595  Values, Nulls);
596  options.read_only = read_only;
597  options.tcount = tcount;
598 
599  res = _SPI_execute_plan(plan, &options,
601  true);
602 
603  _SPI_end_call(true);
604  return res;
605 }
#define SPI_ERROR_PARAM
Definition: spi.h:74

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_plan::argtypes, InvalidSnapshot, _SPI_plan::magic, _SPI_plan::nargs, Nulls, options, res, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

Referenced by pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_spi_exec_prepared(), pltcl_SPI_execute_plan(), PLy_spi_execute_plan(), SPI_execp(), and test_predtest().

◆ SPI_execute_plan_extended()

int SPI_execute_plan_extended ( SPIPlanPtr  plan,
const SPIExecuteOptions options 
)

Definition at line 616 of file spi.c.

618 {
619  int res;
620 
621  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || options == NULL)
622  return SPI_ERROR_ARGUMENT;
623 
624  res = _SPI_begin_call(true);
625  if (res < 0)
626  return res;
627 
628  res = _SPI_execute_plan(plan, options,
630  true);
631 
632  _SPI_end_call(true);
633  return res;
634 }

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, InvalidSnapshot, _SPI_plan::magic, res, and SPI_ERROR_ARGUMENT.

Referenced by exec_stmt_call(), and exec_stmt_return_query().

◆ SPI_execute_plan_with_paramlist()

int SPI_execute_plan_with_paramlist ( SPIPlanPtr  plan,
ParamListInfo  params,
bool  read_only,
long  tcount 
)

Definition at line 638 of file spi.c.

640 {
642  int res;
643 
644  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
645  return SPI_ERROR_ARGUMENT;
646 
647  res = _SPI_begin_call(true);
648  if (res < 0)
649  return res;
650 
651  memset(&options, 0, sizeof(options));
652  options.params = params;
653  options.read_only = read_only;
654  options.tcount = tcount;
655 
656  res = _SPI_execute_plan(plan, &options,
658  true);
659 
660  _SPI_end_call(true);
661  return res;
662 }

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, InvalidSnapshot, _SPI_plan::magic, options, res, and SPI_ERROR_ARGUMENT.

Referenced by exec_run_select(), and exec_stmt_execsql().

◆ SPI_execute_snapshot()

int SPI_execute_snapshot ( SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
Snapshot  snapshot,
Snapshot  crosscheck_snapshot,
bool  read_only,
bool  fire_triggers,
long  tcount 
)

Definition at line 678 of file spi.c.

682 {
684  int res;
685 
686  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
687  return SPI_ERROR_ARGUMENT;
688 
689  if (plan->nargs > 0 && Values == NULL)
690  return SPI_ERROR_PARAM;
691 
692  res = _SPI_begin_call(true);
693  if (res < 0)
694  return res;
695 
696  memset(&options, 0, sizeof(options));
697  options.params = _SPI_convert_params(plan->nargs, plan->argtypes,
698  Values, Nulls);
699  options.read_only = read_only;
700  options.tcount = tcount;
701 
702  res = _SPI_execute_plan(plan, &options,
703  snapshot, crosscheck_snapshot,
704  fire_triggers);
705 
706  _SPI_end_call(true);
707  return res;
708 }

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_plan::argtypes, _SPI_plan::magic, _SPI_plan::nargs, Nulls, options, res, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

Referenced by RI_Initial_Check(), RI_PartitionRemove_Check(), and ri_PerformCheck().

◆ SPI_execute_with_args()

int SPI_execute_with_args ( const char *  src,
int  nargs,
Oid argtypes,
Datum Values,
const char *  Nulls,
bool  read_only,
long  tcount 
)

Definition at line 717 of file spi.c.

721 {
722  int res;
723  _SPI_plan plan;
724  ParamListInfo paramLI;
726 
727  if (src == NULL || nargs < 0 || tcount < 0)
728  return SPI_ERROR_ARGUMENT;
729 
730  if (nargs > 0 && (argtypes == NULL || Values == NULL))
731  return SPI_ERROR_PARAM;
732 
733  res = _SPI_begin_call(true);
734  if (res < 0)
735  return res;
736 
737  memset(&plan, 0, sizeof(_SPI_plan));
738  plan.magic = _SPI_PLAN_MAGIC;
741  plan.nargs = nargs;
742  plan.argtypes = argtypes;
743  plan.parserSetup = NULL;
744  plan.parserSetupArg = NULL;
745 
746  paramLI = _SPI_convert_params(nargs, argtypes,
747  Values, Nulls);
748 
749  _SPI_prepare_oneshot_plan(src, &plan);
750 
751  memset(&options, 0, sizeof(options));
752  options.params = paramLI;
753  options.read_only = read_only;
754  options.tcount = tcount;
755 
756  res = _SPI_execute_plan(&plan, &options,
758  true);
759 
760  _SPI_end_call(true);
761  return res;
762 }

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_prepare_oneshot_plan(), _SPI_plan::argtypes, CURSOR_OPT_PARALLEL_OK, _SPI_plan::cursor_options, InvalidSnapshot, _SPI_plan::magic, _SPI_plan::nargs, Nulls, options, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, res, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

◆ SPI_finish()

int SPI_finish ( void  )

Definition at line 182 of file spi.c.

183 {
184  int res;
185 
186  res = _SPI_begin_call(false); /* just check we're connected */
187  if (res < 0)
188  return res;
189 
190  /* Restore memory context as it was before procedure call */
192 
193  /* Release memory used in procedure call (including tuptables) */
195  _SPI_current->execCxt = NULL;
197  _SPI_current->procCxt = NULL;
198 
199  /*
200  * Restore outer API variables, especially SPI_tuptable which is probably
201  * pointing at a just-deleted tuptable
202  */
206 
207  /* Exit stack level */
208  _SPI_connected--;
209  if (_SPI_connected < 0)
210  _SPI_current = NULL;
211  else
213 
214  return SPI_OK_FINISH;
215 }
#define SPI_OK_FINISH
Definition: spi.h:83

References _SPI_begin_call(), _SPI_connected, _SPI_current, _SPI_stack, _SPI_connection::execCxt, MemoryContextDelete(), MemoryContextSwitchTo(), _SPI_connection::outer_processed, _SPI_connection::outer_result, _SPI_connection::outer_tuptable, _SPI_connection::procCxt, res, _SPI_connection::savedcxt, SPI_OK_FINISH, SPI_processed, SPI_result, and SPI_tuptable.

Referenced by check_foreign_key(), check_primary_key(), connectby(), crosstab(), cursor_to_xml(), cursor_to_xmlschema(), database_to_xml_internal(), database_to_xmlschema_internal(), get_crosstab_tuplestore(), get_tuple_of_interest(), initialize_worker_spi(), load_categories_hash(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_event_trigger_handler(), plperl_func_handler(), plperl_inline_handler(), plperl_trigger_handler(), plpgsql_call_handler(), plpgsql_inline_handler(), plpgsql_validator(), pltcl_event_trigger_handler(), pltcl_func_handler(), pltcl_trigger_handler(), PLy_exec_function(), PLy_exec_trigger(), query_to_xml_and_xmlschema(), query_to_xml_internal(), query_to_xmlschema(), refresh_by_match_merge(), ri_Check_Pk_Match(), RI_FKey_cascade_del(), RI_FKey_cascade_upd(), RI_FKey_check(), RI_Initial_Check(), RI_PartitionRemove_Check(), ri_restrict(), ri_set(), schema_to_xml_internal(), schema_to_xmlschema_internal(), test_predtest(), ts_stat1(), ts_stat2(), tsquery_rewrite_query(), ttdummy(), and xpath_table().

◆ SPI_fname()

char* SPI_fname ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1103 of file spi.c.

1104 {
1105  const FormData_pg_attribute *att;
1106 
1107  SPI_result = 0;
1108 
1109  if (fnumber > tupdesc->natts || fnumber == 0 ||
1111  {
1113  return NULL;
1114  }
1115 
1116  if (fnumber > 0)
1117  att = TupleDescAttr(tupdesc, fnumber - 1);
1118  else
1119  att = SystemAttributeDefinition(fnumber);
1120 
1121  return pstrdup(NameStr(att->attname));
1122 }
#define NameStr(name)
Definition: c.h:681
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition: heap.c:253
char * pstrdup(const char *in)
Definition: mcxt.c:1299
FormData_pg_attribute
Definition: pg_attribute.h:191
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:76
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92

References FirstLowInvalidHeapAttributeNumber, FormData_pg_attribute, NameStr, TupleDescData::natts, pstrdup(), SPI_ERROR_NOATTRIBUTE, SPI_result, SystemAttributeDefinition(), and TupleDescAttr.

Referenced by get_pkey_attnames(), and SPI_sql_row_to_xmlelement().

◆ SPI_fnumber()

int SPI_fnumber ( TupleDesc  tupdesc,
const char *  fname 
)

Definition at line 1080 of file spi.c.

1081 {
1082  int res;
1083  const FormData_pg_attribute *sysatt;
1084 
1085  for (res = 0; res < tupdesc->natts; res++)
1086  {
1087  Form_pg_attribute attr = TupleDescAttr(tupdesc, res);
1088 
1089  if (namestrcmp(&attr->attname, fname) == 0 &&
1090  !attr->attisdropped)
1091  return res + 1;
1092  }
1093 
1094  sysatt = SystemAttributeByName(fname);
1095  if (sysatt != NULL)
1096  return sysatt->attnum;
1097 
1098  /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
1099  return SPI_ERROR_NOATTRIBUTE;
1100 }
const FormData_pg_attribute * SystemAttributeByName(const char *attname)
Definition: heap.c:265
int namestrcmp(Name name, const char *str)
Definition: name.c:247
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207

References FormData_pg_attribute, namestrcmp(), TupleDescData::natts, res, SPI_ERROR_NOATTRIBUTE, SystemAttributeByName(), and TupleDescAttr.

Referenced by autoinc(), check_foreign_key(), check_primary_key(), insert_username(), lo_manage(), make_ruledef(), make_viewdef(), moddatetime(), plperl_build_tuple_result(), plperl_modify_tuple(), pltcl_build_tuple_result(), PLy_modify_tuple(), tsvector_update_trigger(), and ttdummy().

◆ SPI_freeplan()

int SPI_freeplan ( SPIPlanPtr  plan)

Definition at line 930 of file spi.c.

931 {
932  ListCell *lc;
933 
934  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
935  return SPI_ERROR_ARGUMENT;
936 
937  /* Release the plancache entries */
938  foreach(lc, plan->plancache_list)
939  {
940  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
941 
942  DropCachedPlan(plansource);
943  }
944 
945  /* Now get rid of the _SPI_plan and subsidiary data in its plancxt */
947 
948  return 0;
949 }
#define lfirst(lc)
Definition: pg_list.h:169
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:498
List * plancache_list
Definition: spi_priv.h:95
MemoryContext plancxt
Definition: spi_priv.h:96

References _SPI_PLAN_MAGIC, DropCachedPlan(), lfirst, _SPI_plan::magic, MemoryContextDelete(), _SPI_plan::plancache_list, _SPI_plan::plancxt, and SPI_ERROR_ARGUMENT.

Referenced by free_expr(), plperl_spi_freeplan(), plperl_spi_prepare(), plperl_spi_query(), PLy_cursor_query(), PLy_plan_dealloc(), ri_FetchPreparedPlan(), ts_stat_sql(), and tsquery_rewrite_query().

◆ SPI_freetuple()

void SPI_freetuple ( HeapTuple  pointer)

Definition at line 1284 of file spi.c.

1285 {
1286  /* No longer need to worry which context tuple was in... */
1287  heap_freetuple(tuple);
1288 }
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338

References heap_freetuple().

◆ SPI_freetuptable()

void SPI_freetuptable ( SPITupleTable tuptable)

Definition at line 1291 of file spi.c.

1292 {
1293  bool found = false;
1294 
1295  /* ignore call if NULL pointer */
1296  if (tuptable == NULL)
1297  return;
1298 
1299  /*
1300  * Search only the topmost SPI context for a matching tuple table.
1301  */
1302  if (_SPI_current != NULL)
1303  {
1304  slist_mutable_iter siter;
1305 
1306  /* find tuptable in active list, then remove it */
1308  {
1309  SPITupleTable *tt;
1310 
1311  tt = slist_container(SPITupleTable, next, siter.cur);
1312  if (tt == tuptable)
1313  {
1314  slist_delete_current(&siter);
1315  found = true;
1316  break;
1317  }
1318  }
1319  }
1320 
1321  /*
1322  * Refuse the deletion if we didn't find it in the topmost SPI context.
1323  * This is primarily a guard against double deletion, but might prevent
1324  * other errors as well. Since the worst consequence of not deleting a
1325  * tuptable would be a transient memory leak, this is just a WARNING.
1326  */
1327  if (!found)
1328  {
1329  elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);
1330  return;
1331  }
1332 
1333  /* for safety, reset global variables that might point at tuptable */
1334  if (tuptable == _SPI_current->tuptable)
1335  _SPI_current->tuptable = NULL;
1336  if (tuptable == SPI_tuptable)
1337  SPI_tuptable = NULL;
1338 
1339  /* release all memory belonging to tuptable */
1340  MemoryContextDelete(tuptable->tuptabcxt);
1341 }

References _SPI_current, slist_mutable_iter::cur, elog, MemoryContextDelete(), next, slist_container, slist_delete_current(), slist_foreach_modify, SPI_tuptable, SPITupleTable::tuptabcxt, _SPI_connection::tuptable, _SPI_connection::tuptables, and WARNING.

Referenced by _SPI_execute_plan(), exec_eval_cleanup(), exec_for_query(), exec_stmt_call(), exec_stmt_dynexecute(), exec_stmt_execsql(), exec_stmt_fetch(), plperl_spi_execute_fetch_result(), plperl_spi_fetchrow(), pltcl_process_SPI_result(), PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_spi_execute_fetch_result(), ts_stat_sql(), and tsquery_rewrite_query().

◆ SPI_getargcount()

int SPI_getargcount ( SPIPlanPtr  plan)

Definition at line 1795 of file spi.c.

1796 {
1797  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1798  {
1800  return -1;
1801  }
1802  return plan->nargs;
1803 }

References _SPI_PLAN_MAGIC, _SPI_plan::magic, _SPI_plan::nargs, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_getargtypeid()

Oid SPI_getargtypeid ( SPIPlanPtr  plan,
int  argIndex 
)

Definition at line 1780 of file spi.c.

1781 {
1782  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
1783  argIndex < 0 || argIndex >= plan->nargs)
1784  {
1786  return InvalidOid;
1787  }
1788  return plan->argtypes[argIndex];
1789 }
#define InvalidOid
Definition: postgres_ext.h:36

References _SPI_PLAN_MAGIC, _SPI_plan::argtypes, InvalidOid, _SPI_plan::magic, _SPI_plan::nargs, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_getbinval()

Datum SPI_getbinval ( HeapTuple  tuple,
TupleDesc  tupdesc,
int  fnumber,
bool isnull 
)

Definition at line 1157 of file spi.c.

1158 {
1159  SPI_result = 0;
1160 
1161  if (fnumber > tupdesc->natts || fnumber == 0 ||
1163  {
1165  *isnull = true;
1166  return (Datum) NULL;
1167  }
1168 
1169  return heap_getattr(tuple, fnumber, tupdesc, isnull);
1170 }
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:756

References FirstLowInvalidHeapAttributeNumber, heap_getattr, TupleDescData::natts, SPI_ERROR_NOATTRIBUTE, and SPI_result.

Referenced by autoinc(), check_foreign_key(), check_primary_key(), exec_eval_expr(), initialize_worker_spi(), make_ruledef(), make_viewdef(), query_to_oid_list(), SPI_sql_row_to_xmlelement(), test_predtest(), ts_stat_sql(), tsquery_rewrite_query(), tsvector_update_trigger(), and ttdummy().

◆ SPI_getnspname()

char* SPI_getnspname ( Relation  rel)

Definition at line 1237 of file spi.c.

1238 {
1240 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3316
#define RelationGetNamespace(relation)
Definition: rel.h:519

References get_namespace_name(), and RelationGetNamespace.

Referenced by plperl_trigger_build_args(), pltcl_trigger_handler(), and PLy_trigger_build_args().

◆ SPI_getrelname()

char* SPI_getrelname ( Relation  rel)

Definition at line 1231 of file spi.c.

1232 {
1233  return pstrdup(RelationGetRelationName(rel));
1234 }
#define RelationGetRelationName(relation)
Definition: rel.h:512

References pstrdup(), and RelationGetRelationName.

Referenced by autoinc(), check_foreign_key(), check_primary_key(), insert_username(), moddatetime(), plperl_trigger_build_args(), pltcl_trigger_handler(), PLy_trigger_build_args(), and ttdummy().

◆ SPI_gettype()

char* SPI_gettype ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1173 of file spi.c.

1174 {
1175  Oid typoid;
1176  HeapTuple typeTuple;
1177  char *result;
1178 
1179  SPI_result = 0;
1180 
1181  if (fnumber > tupdesc->natts || fnumber == 0 ||
1183  {
1185  return NULL;
1186  }
1187 
1188  if (fnumber > 0)
1189  typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1190  else
1191  typoid = (SystemAttributeDefinition(fnumber))->atttypid;
1192 
1193  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
1194 
1195  if (!HeapTupleIsValid(typeTuple))
1196  {
1198  return NULL;
1199  }
1200 
1201  result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
1202  ReleaseSysCache(typeTuple);
1203  return result;
1204 }
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
NameData typname
Definition: pg_type.h:41
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
unsigned int Oid
Definition: postgres_ext.h:31
#define SPI_ERROR_TYPUNKNOWN
Definition: spi.h:78
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1198
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1150
@ TYPEOID
Definition: syscache.h:112

References FirstLowInvalidHeapAttributeNumber, GETSTRUCT, HeapTupleIsValid, NameStr, TupleDescData::natts, ObjectIdGetDatum, pstrdup(), ReleaseSysCache(), SearchSysCache1(), SPI_ERROR_NOATTRIBUTE, SPI_ERROR_TYPUNKNOWN, SPI_result, SystemAttributeDefinition(), TupleDescAttr, TYPEOID, and typname.

Referenced by check_foreign_key().

◆ SPI_gettypeid()

Oid SPI_gettypeid ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1213 of file spi.c.

1214 {
1215  SPI_result = 0;
1216 
1217  if (fnumber > tupdesc->natts || fnumber == 0 ||
1219  {
1221  return InvalidOid;
1222  }
1223 
1224  if (fnumber > 0)
1225  return TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1226  else
1227  return (SystemAttributeDefinition(fnumber))->atttypid;
1228 }

References FirstLowInvalidHeapAttributeNumber, InvalidOid, TupleDescData::natts, SPI_ERROR_NOATTRIBUTE, SPI_result, SystemAttributeDefinition(), and TupleDescAttr.

Referenced by autoinc(), check_foreign_key(), check_primary_key(), insert_username(), moddatetime(), SPI_sql_row_to_xmlelement(), ts_stat_sql(), tsquery_rewrite_query(), tsvector_update_trigger(), and ttdummy().

◆ SPI_getvalue()

char* SPI_getvalue ( HeapTuple  tuple,
TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1125 of file spi.c.

1126 {
1127  Datum val;
1128  bool isnull;
1129  Oid typoid,
1130  foutoid;
1131  bool typisvarlena;
1132 
1133  SPI_result = 0;
1134 
1135  if (fnumber > tupdesc->natts || fnumber == 0 ||
1137  {
1139  return NULL;
1140  }
1141 
1142  val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
1143  if (isnull)
1144  return NULL;
1145 
1146  if (fnumber > 0)
1147  typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1148  else
1149  typoid = (SystemAttributeDefinition(fnumber))->atttypid;
1150 
1151  getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
1152 
1153  return OidOutputFunctionCall(foutoid, val);
1154 }
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1653
long val
Definition: informix.c:664
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2854

References FirstLowInvalidHeapAttributeNumber, getTypeOutputInfo(), heap_getattr, TupleDescData::natts, OidOutputFunctionCall(), SPI_ERROR_NOATTRIBUTE, SPI_result, SystemAttributeDefinition(), TupleDescAttr, and val.

Referenced by build_tuplestore_recursively(), check_foreign_key(), crosstab(), get_crosstab_tuplestore(), get_sql_insert(), get_sql_update(), lo_manage(), load_categories_hash(), make_ruledef(), make_viewdef(), refresh_by_match_merge(), triggered_change_notification(), and xpath_table().

◆ SPI_inside_nonatomic_context()

bool SPI_inside_nonatomic_context ( void  )

Definition at line 489 of file spi.c.

490 {
491  if (_SPI_current == NULL)
492  return false; /* not in any SPI context at all */
493  if (_SPI_current->atomic)
494  return false; /* it's atomic (ie function not procedure) */
495  return true;
496 }

References _SPI_current, and _SPI_connection::atomic.

Referenced by StartTransaction().

◆ SPI_is_cursor_plan()

bool SPI_is_cursor_plan ( SPIPlanPtr  plan)

Definition at line 1815 of file spi.c.

1816 {
1817  CachedPlanSource *plansource;
1818 
1819  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1820  {
1822  return false;
1823  }
1824 
1825  if (list_length(plan->plancache_list) != 1)
1826  {
1827  SPI_result = 0;
1828  return false; /* not exactly 1 pre-rewrite command */
1829  }
1830  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1831 
1832  /*
1833  * We used to force revalidation of the cached plan here, but that seems
1834  * unnecessary: invalidation could mean a change in the rowtype of the
1835  * tuples returned by a plan, but not whether it returns tuples at all.
1836  */
1837  SPI_result = 0;
1838 
1839  /* Does it return tuples? */
1840  if (plansource->resultDesc)
1841  return true;
1842 
1843  return false;
1844 }
static int list_length(const List *l)
Definition: pg_list.h:149
#define linitial(l)
Definition: pg_list.h:174
TupleDesc resultDesc
Definition: plancache.h:108

References _SPI_PLAN_MAGIC, linitial, list_length(), _SPI_plan::magic, _SPI_plan::plancache_list, CachedPlanSource::resultDesc, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by SPI_cursor_open_internal().

◆ SPI_keepplan()

int SPI_keepplan ( SPIPlanPtr  plan)

Definition at line 881 of file spi.c.

882 {
883  ListCell *lc;
884 
885  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
886  plan->saved || plan->oneshot)
887  return SPI_ERROR_ARGUMENT;
888 
889  /*
890  * Mark it saved, reparent it under CacheMemoryContext, and mark all the
891  * component CachedPlanSources as saved. This sequence cannot fail
892  * partway through, so there's no risk of long-term memory leakage.
893  */
894  plan->saved = true;
896 
897  foreach(lc, plan->plancache_list)
898  {
899  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
900 
901  SaveCachedPlan(plansource);
902  }
903 
904  return 0;
905 }
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:361
MemoryContext CacheMemoryContext
Definition: mcxt.c:51
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:454
bool oneshot
Definition: spi_priv.h:94
bool saved
Definition: spi_priv.h:93

References _SPI_PLAN_MAGIC, CacheMemoryContext, lfirst, _SPI_plan::magic, MemoryContextSetParent(), _SPI_plan::oneshot, _SPI_plan::plancache_list, _SPI_plan::plancxt, SaveCachedPlan(), _SPI_plan::saved, and SPI_ERROR_ARGUMENT.

Referenced by check_foreign_key(), check_primary_key(), exec_prepare_plan(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_spi_prepare(), pltcl_SPI_prepare(), PLy_spi_prepare(), ri_PlanCheck(), and ttdummy().

◆ SPI_modifytuple()

HeapTuple SPI_modifytuple ( Relation  rel,
HeapTuple  tuple,
int  natts,
int *  attnum,
Datum Values,
const char *  Nulls 
)

Definition at line 1011 of file spi.c.

1013 {
1014  MemoryContext oldcxt;
1015  HeapTuple mtuple;
1016  int numberOfAttributes;
1017  Datum *v;
1018  bool *n;
1019  int i;
1020 
1021  if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
1022  {
1024  return NULL;
1025  }
1026 
1027  if (_SPI_current == NULL)
1028  {
1030  return NULL;
1031  }
1032 
1034 
1035  SPI_result = 0;
1036 
1037  numberOfAttributes = rel->rd_att->natts;
1038  v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1039  n = (bool *) palloc(numberOfAttributes * sizeof(bool));
1040 
1041  /* fetch old values and nulls */
1042  heap_deform_tuple(tuple, rel->rd_att, v, n);
1043 
1044  /* replace values and nulls */
1045  for (i = 0; i < natts; i++)
1046  {
1047  if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
1048  break;
1049  v[attnum[i] - 1] = Values[i];
1050  n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n');
1051  }
1052 
1053  if (i == natts) /* no errors in *attnum */
1054  {
1055  mtuple = heap_form_tuple(rel->rd_att, v, n);
1056 
1057  /*
1058  * copy the identification info of the old tuple: t_ctid, t_self, and
1059  * OID (if any)
1060  */
1061  mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
1062  mtuple->t_self = tuple->t_self;
1063  mtuple->t_tableOid = tuple->t_tableOid;
1064  }
1065  else
1066  {
1067  mtuple = NULL;
1069  }
1070 
1071  pfree(v);
1072  pfree(n);
1073 
1074  MemoryContextSwitchTo(oldcxt);
1075 
1076  return mtuple;
1077 }
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1249
int i
Definition: isn.c:73
void * palloc(Size size)
Definition: mcxt.c:1062
int16 attnum
Definition: pg_attribute.h:83
ItemPointerData t_self
Definition: htup.h:65
HeapTupleHeader t_data
Definition: htup.h:68
Oid t_tableOid
Definition: htup.h:66
ItemPointerData t_ctid
Definition: htup_details.h:160
TupleDesc rd_att
Definition: rel.h:110

References _SPI_current, attnum, heap_deform_tuple(), heap_form_tuple(), i, MemoryContextSwitchTo(), TupleDescData::natts, Nulls, palloc(), pfree(), RelationData::rd_att, _SPI_connection::savedcxt, SPI_ERROR_ARGUMENT, SPI_ERROR_NOATTRIBUTE, SPI_ERROR_UNCONNECTED, SPI_result, HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_self, and HeapTupleData::t_tableOid.

Referenced by ttdummy().

◆ SPI_palloc()

void* SPI_palloc ( Size  size)

Definition at line 1243 of file spi.c.

1244 {
1245  if (_SPI_current == NULL)
1246  elog(ERROR, "SPI_palloc called while not connected to SPI");
1247 
1248  return MemoryContextAlloc(_SPI_current->savedcxt, size);
1249 }

References _SPI_current, elog, ERROR, MemoryContextAlloc(), and _SPI_connection::savedcxt.

Referenced by _SPI_strdup(), and coerce_function_result_tuple().

◆ SPI_pfree()

void SPI_pfree ( void *  pointer)

Definition at line 1259 of file spi.c.

1260 {
1261  /* No longer need to worry which context chunk was in... */
1262  pfree(pointer);
1263 }

References pfree().

◆ SPI_plan_get_cached_plan()

CachedPlan* SPI_plan_get_cached_plan ( SPIPlanPtr  plan)

Definition at line 1973 of file spi.c.

1974 {
1975  CachedPlanSource *plansource;
1976  CachedPlan *cplan;
1977  SPICallbackArg spicallbackarg;
1978  ErrorContextCallback spierrcontext;
1979 
1980  Assert(plan->magic == _SPI_PLAN_MAGIC);
1981 
1982  /* Can't support one-shot plans here */
1983  if (plan->oneshot)
1984  return NULL;
1985 
1986  /* Must have exactly one CachedPlanSource */
1987  if (list_length(plan->plancache_list) != 1)
1988  return NULL;
1989  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1990 
1991  /* Setup error traceback support for ereport() */
1992  spicallbackarg.query = plansource->query_string;
1993  spicallbackarg.mode = plan->parse_mode;
1994  spierrcontext.callback = _SPI_error_callback;
1995  spierrcontext.arg = &spicallbackarg;
1996  spierrcontext.previous = error_context_stack;
1997  error_context_stack = &spierrcontext;
1998 
1999  /* Get the generic plan for the query */
2000  cplan = GetCachedPlan(plansource, NULL,
2001  plan->saved ? CurrentResourceOwner : NULL,
2003  Assert(cplan == plansource->gplan);
2004 
2005  /* Pop the error context stack */
2006  error_context_stack = spierrcontext.previous;
2007 
2008  return cplan;
2009 }
ErrorContextCallback * error_context_stack
Definition: elog.c:93
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
Definition: plancache.c:1141
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static void _SPI_error_callback(void *arg)
Definition: spi.c:2837
struct CachedPlan * gplan
Definition: plancache.h:121
const char * query_string
Definition: plancache.h:100
struct ErrorContextCallback * previous
Definition: elog.h:232
void(* callback)(void *arg)
Definition: elog.h:233
const char * query
Definition: spi.c:56
RawParseMode mode
Definition: spi.c:57

References _SPI_current, _SPI_error_callback(), _SPI_PLAN_MAGIC, ErrorContextCallback::arg, Assert(), ErrorContextCallback::callback, CurrentResourceOwner, error_context_stack, GetCachedPlan(), CachedPlanSource::gplan, linitial, list_length(), _SPI_plan::magic, SPICallbackArg::mode, _SPI_plan::oneshot, _SPI_plan::parse_mode, _SPI_plan::plancache_list, ErrorContextCallback::previous, SPICallbackArg::query, CachedPlanSource::query_string, _SPI_connection::queryEnv, and _SPI_plan::saved.

Referenced by exec_eval_simple_expr(), exec_simple_check_plan(), and test_predtest().

◆ SPI_plan_get_plan_sources()

List* SPI_plan_get_plan_sources ( SPIPlanPtr  plan)

Definition at line 1954 of file spi.c.

1955 {
1956  Assert(plan->magic == _SPI_PLAN_MAGIC);
1957  return plan->plancache_list;
1958 }

References _SPI_PLAN_MAGIC, Assert(), _SPI_plan::magic, and _SPI_plan::plancache_list.

Referenced by exec_simple_check_plan(), exec_stmt_execsql(), and make_callstmt_target().

◆ SPI_plan_is_valid()

bool SPI_plan_is_valid ( SPIPlanPtr  plan)

Definition at line 1853 of file spi.c.

1854 {
1855  ListCell *lc;
1856 
1857  Assert(plan->magic == _SPI_PLAN_MAGIC);
1858 
1859  foreach(lc, plan->plancache_list)
1860  {
1861  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1862 
1863  if (!CachedPlanIsValid(plansource))
1864  return false;
1865  }
1866  return true;
1867 }
bool CachedPlanIsValid(CachedPlanSource *plansource)
Definition: plancache.c:1598

References _SPI_PLAN_MAGIC, Assert(), CachedPlanIsValid(), lfirst, _SPI_plan::magic, and _SPI_plan::plancache_list.

Referenced by ri_FetchPreparedPlan().

◆ SPI_prepare()

SPIPlanPtr SPI_prepare ( const char *  src,
int  nargs,
Oid argtypes 
)

◆ SPI_prepare_cursor()

SPIPlanPtr SPI_prepare_cursor ( const char *  src,
int  nargs,
Oid argtypes,
int  cursorOptions 
)

Definition at line 771 of file spi.c.

773 {
774  _SPI_plan plan;
775  SPIPlanPtr result;
776 
777  if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
778  {
780  return NULL;
781  }
782 
783  SPI_result = _SPI_begin_call(true);
784  if (SPI_result < 0)
785  return NULL;
786 
787  memset(&plan, 0, sizeof(_SPI_plan));
788  plan.magic = _SPI_PLAN_MAGIC;
790  plan.cursor_options = cursorOptions;
791  plan.nargs = nargs;
792  plan.argtypes = argtypes;
793  plan.parserSetup = NULL;
794  plan.parserSetupArg = NULL;
795 
796  _SPI_prepare_plan(src, &plan);
797 
798  /* copy plan to procedure context */
799  result = _SPI_make_plan_non_temp(&plan);
800 
801  _SPI_end_call(true);
802 
803  return result;
804 }
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:3017

References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), _SPI_plan::argtypes, _SPI_plan::cursor_options, _SPI_plan::magic, _SPI_plan::nargs, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by SPI_prepare().

◆ SPI_prepare_extended()

SPIPlanPtr SPI_prepare_extended ( const char *  src,
const SPIPrepareOptions options 
)

Definition at line 807 of file spi.c.

809 {
810  _SPI_plan plan;
811  SPIPlanPtr result;
812 
813  if (src == NULL || options == NULL)
814  {
816  return NULL;
817  }
818 
819  SPI_result = _SPI_begin_call(true);
820  if (SPI_result < 0)
821  return NULL;
822 
823  memset(&plan, 0, sizeof(_SPI_plan));
824  plan.magic = _SPI_PLAN_MAGIC;
825  plan.parse_mode = options->parseMode;
826  plan.cursor_options = options->cursorOptions;
827  plan.nargs = 0;
828  plan.argtypes = NULL;
829  plan.parserSetup = options->parserSetup;
830  plan.parserSetupArg = options->parserSetupArg;
831 
832  _SPI_prepare_plan(src, &plan);
833 
834  /* copy plan to procedure context */
835  result = _SPI_make_plan_non_temp(&plan);
836 
837  _SPI_end_call(true);
838 
839  return result;
840 }

References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), _SPI_plan::argtypes, _SPI_plan::cursor_options, _SPI_plan::magic, _SPI_plan::nargs, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by exec_prepare_plan().

◆ SPI_prepare_params()

SPIPlanPtr SPI_prepare_params ( const char *  src,
ParserSetupHook  parserSetup,
void *  parserSetupArg,
int  cursorOptions 
)

Definition at line 843 of file spi.c.

847 {
848  _SPI_plan plan;
849  SPIPlanPtr result;
850 
851  if (src == NULL)
852  {
854  return NULL;
855  }
856 
857  SPI_result = _SPI_begin_call(true);
858  if (SPI_result < 0)
859  return NULL;
860 
861  memset(&plan, 0, sizeof(_SPI_plan));
862  plan.magic = _SPI_PLAN_MAGIC;
864  plan.cursor_options = cursorOptions;
865  plan.nargs = 0;
866  plan.argtypes = NULL;
867  plan.parserSetup = parserSetup;
868  plan.parserSetupArg = parserSetupArg;
869 
870  _SPI_prepare_plan(src, &plan);
871 
872  /* copy plan to procedure context */
873  result = _SPI_make_plan_non_temp(&plan);
874 
875  _SPI_end_call(true);
876 
877  return result;
878 }

References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), _SPI_plan::argtypes, _SPI_plan::cursor_options, _SPI_plan::magic, _SPI_plan::nargs, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_register_relation()

int SPI_register_relation ( EphemeralNamedRelation  enr)

Definition at line 3173 of file spi.c.

3174 {
3175  EphemeralNamedRelation match;
3176  int res;
3177 
3178  if (enr == NULL || enr->md.name == NULL)
3179  return SPI_ERROR_ARGUMENT;
3180 
3181  res = _SPI_begin_call(false); /* keep current memory context */
3182  if (res < 0)
3183  return res;
3184 
3185  match = _SPI_find_ENR_by_name(enr->md.name);
3186  if (match)
3188  else
3189  {
3190  if (_SPI_current->queryEnv == NULL)
3192 
3195  }
3196 
3197  _SPI_end_call(false);
3198 
3199  return res;
3200 }
QueryEnvironment * create_queryEnv(void)
void register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr)
static EphemeralNamedRelation _SPI_find_ENR_by_name(const char *name)
Definition: spi.c:3156
#define SPI_ERROR_REL_DUPLICATE
Definition: spi.h:79
#define SPI_OK_REL_REGISTER
Definition: spi.h:96
EphemeralNamedRelationMetadataData md

References _SPI_begin_call(), _SPI_current, _SPI_end_call(), _SPI_find_ENR_by_name(), create_queryEnv(), EphemeralNamedRelationData::md, EphemeralNamedRelationMetadataData::name, _SPI_connection::queryEnv, register_ENR(), res, SPI_ERROR_ARGUMENT, SPI_ERROR_REL_DUPLICATE, and SPI_OK_REL_REGISTER.

Referenced by SPI_register_trigger_data().

◆ SPI_register_trigger_data()

int SPI_register_trigger_data ( TriggerData tdata)

Definition at line 3240 of file spi.c.

3241 {
3242  if (tdata == NULL)
3243  return SPI_ERROR_ARGUMENT;
3244 
3245  if (tdata->tg_newtable)
3246  {
3249  int rc;
3250 
3251  enr->md.name = tdata->tg_trigger->tgnewtable;
3252  enr->md.reliddesc = tdata->tg_relation->rd_id;
3253  enr->md.tupdesc = NULL;
3256  enr->reldata = tdata->tg_newtable;
3257  rc = SPI_register_relation(enr);
3258  if (rc != SPI_OK_REL_REGISTER)
3259  return rc;
3260  }
3261 
3262  if (tdata->tg_oldtable)
3263  {
3266  int rc;
3267 
3268  enr->md.name = tdata->tg_trigger->tgoldtable;
3269  enr->md.reliddesc = tdata->tg_relation->rd_id;
3270  enr->md.tupdesc = NULL;
3273  enr->reldata = tdata->tg_oldtable;
3274  rc = SPI_register_relation(enr);
3275  if (rc != SPI_OK_REL_REGISTER)
3276  return rc;
3277  }
3278 
3279  return SPI_OK_TD_REGISTER;
3280 }
@ ENR_NAMED_TUPLESTORE
int SPI_register_relation(EphemeralNamedRelation enr)
Definition: spi.c:3173
#define SPI_OK_TD_REGISTER
Definition: spi.h:98
EphemeralNameRelationType enrtype
Oid rd_id
Definition: rel.h:111
Tuplestorestate * tg_oldtable
Definition: trigger.h:40
Relation tg_relation
Definition: trigger.h:34
Tuplestorestate * tg_newtable
Definition: trigger.h:41
Trigger * tg_trigger
Definition: trigger.h:37
char * tgoldtable
Definition: reltrigger.h:43
char * tgnewtable
Definition: reltrigger.h:44
int64 tuplestore_tuple_count(Tuplestorestate *state)
Definition: tuplestore.c:546

References ENR_NAMED_TUPLESTORE, EphemeralNamedRelationMetadataData::enrtuples, EphemeralNamedRelationMetadataData::enrtype, EphemeralNamedRelationData::md, EphemeralNamedRelationMetadataData::name, palloc(), RelationData::rd_id, EphemeralNamedRelationData::reldata, EphemeralNamedRelationMetadataData::reliddesc, SPI_ERROR_ARGUMENT, SPI_OK_REL_REGISTER, SPI_OK_TD_REGISTER, SPI_register_relation(), TriggerData::tg_newtable, TriggerData::tg_oldtable, TriggerData::tg_relation, TriggerData::tg_trigger, Trigger::tgnewtable, Trigger::tgoldtable, EphemeralNamedRelationMetadataData::tupdesc, and tuplestore_tuple_count().

Referenced by plperl_trigger_handler(), plpgsql_exec_trigger(), pltcl_trigger_handler(), and PLy_exec_trigger().

◆ SPI_repalloc()

void* SPI_repalloc ( void *  pointer,
Size  size 
)

Definition at line 1252 of file spi.c.

1253 {
1254  /* No longer need to worry which context chunk was in... */
1255  return repalloc(pointer, size);
1256 }

References repalloc().

◆ SPI_result_code_string()

const char* SPI_result_code_string ( int  code)

Definition at line 1877 of file spi.c.

1878 {
1879  static char buf[64];
1880 
1881  switch (code)
1882  {
1883  case SPI_ERROR_CONNECT:
1884  return "SPI_ERROR_CONNECT";
1885  case SPI_ERROR_COPY:
1886  return "SPI_ERROR_COPY";
1887  case SPI_ERROR_OPUNKNOWN:
1888  return "SPI_ERROR_OPUNKNOWN";
1889  case SPI_ERROR_UNCONNECTED:
1890  return "SPI_ERROR_UNCONNECTED";
1891  case SPI_ERROR_ARGUMENT:
1892  return "SPI_ERROR_ARGUMENT";
1893  case SPI_ERROR_PARAM:
1894  return "SPI_ERROR_PARAM";
1895  case SPI_ERROR_TRANSACTION:
1896  return "SPI_ERROR_TRANSACTION";
1897  case SPI_ERROR_NOATTRIBUTE:
1898  return "SPI_ERROR_NOATTRIBUTE";
1899  case SPI_ERROR_NOOUTFUNC:
1900  return "SPI_ERROR_NOOUTFUNC";
1901  case SPI_ERROR_TYPUNKNOWN:
1902  return "SPI_ERROR_TYPUNKNOWN";
1904  return "SPI_ERROR_REL_DUPLICATE";
1906  return "SPI_ERROR_REL_NOT_FOUND";
1907  case SPI_OK_CONNECT:
1908  return "SPI_OK_CONNECT";
1909  case SPI_OK_FINISH:
1910  return "SPI_OK_FINISH";
1911  case SPI_OK_FETCH:
1912  return "SPI_OK_FETCH";
1913  case SPI_OK_UTILITY:
1914  return "SPI_OK_UTILITY";
1915  case SPI_OK_SELECT:
1916  return "SPI_OK_SELECT";
1917  case SPI_OK_SELINTO:
1918  return "SPI_OK_SELINTO";
1919  case SPI_OK_INSERT:
1920  return "SPI_OK_INSERT";
1921  case SPI_OK_DELETE:
1922  return "SPI_OK_DELETE";
1923  case SPI_OK_UPDATE:
1924  return "SPI_OK_UPDATE";
1925  case SPI_OK_CURSOR:
1926  return "SPI_OK_CURSOR";
1928  return "SPI_OK_INSERT_RETURNING";
1930  return "SPI_OK_DELETE_RETURNING";
1932  return "SPI_OK_UPDATE_RETURNING";
1933  case SPI_OK_REWRITTEN:
1934  return "SPI_OK_REWRITTEN";
1935  case SPI_OK_REL_REGISTER:
1936  return "SPI_OK_REL_REGISTER";
1937  case SPI_OK_REL_UNREGISTER:
1938  return "SPI_OK_REL_UNREGISTER";
1939  }
1940  /* Unrecognized code ... return something useful ... */
1941  sprintf(buf, "Unrecognized SPI code %d", code);
1942  return buf;
1943 }
static char * buf
Definition: pg_test_fsync.c:70
#define sprintf
Definition: port.h:227
#define SPI_ERROR_TRANSACTION
Definition: spi.h:75
#define SPI_ERROR_REL_NOT_FOUND
Definition: spi.h:80
#define SPI_OK_UTILITY
Definition: spi.h:85
#define SPI_OK_REWRITTEN
Definition: spi.h:95
#define SPI_OK_INSERT
Definition: spi.h:88
#define SPI_OK_UPDATE
Definition: spi.h:90
#define SPI_OK_CURSOR
Definition: spi.h:91
#define SPI_OK_FETCH
Definition: spi.h:84
#define SPI_OK_SELINTO
Definition: spi.h:87
#define SPI_ERROR_OPUNKNOWN
Definition: spi.h:70
#define SPI_OK_UPDATE_RETURNING
Definition: spi.h:94
#define SPI_OK_DELETE
Definition: spi.h:89
#define SPI_OK_REL_UNREGISTER
Definition: spi.h:97
#define SPI_OK_INSERT_RETURNING
Definition: spi.h:92
#define SPI_ERROR_COPY
Definition: spi.h:69
#define SPI_ERROR_NOOUTFUNC
Definition: spi.h:77
#define SPI_OK_DELETE_RETURNING
Definition: spi.h:93
#define SPI_ERROR_CONNECT
Definition: spi.h:68
#define SPI_OK_SELECT
Definition: spi.h:86

References buf, SPI_ERROR_ARGUMENT, SPI_ERROR_CONNECT, SPI_ERROR_COPY, SPI_ERROR_NOATTRIBUTE, SPI_ERROR_NOOUTFUNC, SPI_ERROR_OPUNKNOWN, SPI_ERROR_PARAM, SPI_ERROR_REL_DUPLICATE, SPI_ERROR_REL_NOT_FOUND, SPI_ERROR_TRANSACTION, SPI_ERROR_TYPUNKNOWN, SPI_ERROR_UNCONNECTED, SPI_OK_CONNECT, SPI_OK_CURSOR, SPI_OK_DELETE, SPI_OK_DELETE_RETURNING, SPI_OK_FETCH, SPI_OK_FINISH, SPI_OK_INSERT, SPI_OK_INSERT_RETURNING, SPI_OK_REL_REGISTER, SPI_OK_REL_UNREGISTER, SPI_OK_REWRITTEN, SPI_OK_SELECT, SPI_OK_SELINTO, SPI_OK_UPDATE, SPI_OK_UPDATE_RETURNING, SPI_OK_UTILITY, and sprintf.

Referenced by check_foreign_key(), check_primary_key(), exec_dynquery_with_params(), exec_prepare_plan(), exec_run_select(), exec_stmt_call(), exec_stmt_dynexecute(), exec_stmt_execsql(), exec_stmt_forc(), exec_stmt_open(), exec_stmt_return_query(), plperl_spi_execute_fetch_result(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), plpgsql_call_handler(), plpgsql_inline_handler(), plpgsql_validator(), pltcl_process_SPI_result(), PLy_cursor_plan(), PLy_cursor_query(), PLy_spi_execute_plan(), PLy_spi_execute_query(), PLy_spi_prepare(), query_to_oid_list(), RI_Initial_Check(), RI_PartitionRemove_Check(), ri_PerformCheck(), ri_PlanCheck(), and ttdummy().

◆ SPI_returntuple()

HeapTupleHeader SPI_returntuple ( HeapTuple  tuple,
TupleDesc  tupdesc 
)

Definition at line 979 of file spi.c.

980 {
981  MemoryContext oldcxt;
982  HeapTupleHeader dtup;
983 
984  if (tuple == NULL || tupdesc == NULL)
985  {
987  return NULL;
988  }
989 
990  if (_SPI_current == NULL)
991  {
993  return NULL;
994  }
995 
996  /* For RECORD results, make sure a typmod has been assigned */
997  if (tupdesc->tdtypeid == RECORDOID &&
998  tupdesc->tdtypmod < 0)
999  assign_record_type_typmod(tupdesc);
1000 
1002 
1003  dtup = DatumGetHeapTupleHeader(heap_copy_tuple_as_datum(tuple, tupdesc));
1004 
1005  MemoryContextSwitchTo(oldcxt);
1006 
1007  return dtup;
1008 }
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:295
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:984
int32 tdtypmod
Definition: tupdesc.h:83
Oid tdtypeid
Definition: tupdesc.h:82
void assign_record_type_typmod(TupleDesc tupDesc)
Definition: typcache.c:1950

References _SPI_current, assign_record_type_typmod(), DatumGetHeapTupleHeader, heap_copy_tuple_as_datum(), MemoryContextSwitchTo(), _SPI_connection::savedcxt, SPI_ERROR_ARGUMENT, SPI_ERROR_UNCONNECTED, SPI_result, TupleDescData::tdtypeid, and TupleDescData::tdtypmod.

Referenced by coerce_function_result_tuple().

◆ SPI_rollback()

void SPI_rollback ( void  )

Definition at line 338 of file spi.c.

339 {
340  _SPI_rollback(false);
341 }
static void _SPI_rollback(bool chain)
Definition: spi.c:292

References _SPI_rollback().

Referenced by exec_stmt_rollback(), plperl_spi_rollback(), pltcl_rollback(), and PLy_rollback().

◆ SPI_rollback_and_chain()

void SPI_rollback_and_chain ( void  )

Definition at line 344 of file spi.c.

345 {
346  _SPI_rollback(true);
347 }

References _SPI_rollback().

Referenced by exec_stmt_rollback().

◆ SPI_saveplan()

SPIPlanPtr SPI_saveplan ( SPIPlanPtr  plan)

Definition at line 908 of file spi.c.

909 {
910  SPIPlanPtr newplan;
911 
912  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
913  {
915  return NULL;
916  }
917 
918  SPI_result = _SPI_begin_call(false); /* don't change context */
919  if (SPI_result < 0)
920  return NULL;
921 
922  newplan = _SPI_save_plan(plan);
923 
924  SPI_result = _SPI_end_call(false);
925 
926  return newplan;
927 }
static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan)
Definition: spi.c:3085

References _SPI_begin_call(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_save_plan(), _SPI_plan::magic, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_scroll_cursor_fetch()

void SPI_scroll_cursor_fetch ( Portal  portal,
FetchDirection  direction,
long  count 
)

Definition at line 1740 of file spi.c.

1741 {
1742  _SPI_cursor_operation(portal,
1743  direction, count,
1745  /* we know that the DestSPI receiver doesn't need a destroy call */
1746 }

References _SPI_cursor_operation(), CreateDestReceiver(), and DestSPI.

Referenced by exec_stmt_fetch().

◆ SPI_scroll_cursor_move()

void SPI_scroll_cursor_move ( Portal  portal,
FetchDirection  direction,
long  count 
)

Definition at line 1755 of file spi.c.

1756 {
1757  _SPI_cursor_operation(portal, direction, count, None_Receiver);
1758 }

References _SPI_cursor_operation(), and None_Receiver.

Referenced by exec_stmt_fetch().

◆ SPI_start_transaction()

void SPI_start_transaction ( void  )

Definition at line 218 of file spi.c.

219 {
220  MemoryContext oldcontext = CurrentMemoryContext;
221 
223  MemoryContextSwitchTo(oldcontext);
224 }
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
void StartTransactionCommand(void)
Definition: xact.c:2909

References CurrentMemoryContext, MemoryContextSwitchTo(), and StartTransactionCommand().

Referenced by exec_stmt_commit(), exec_stmt_rollback(), plperl_spi_commit(), plperl_spi_rollback(), pltcl_commit(), pltcl_rollback(), PLy_commit(), and PLy_rollback().

◆ SPI_unregister_relation()

int SPI_unregister_relation ( const char *  name)

Definition at line 3207 of file spi.c.

3208 {
3209  EphemeralNamedRelation match;
3210  int res;
3211 
3212  if (name == NULL)
3213  return SPI_ERROR_ARGUMENT;
3214 
3215  res = _SPI_begin_call(false); /* keep current memory context */
3216  if (res < 0)
3217  return res;
3218 
3219  match = _SPI_find_ENR_by_name(name);
3220  if (match)
3221  {
3224  }
3225  else
3227 
3228  _SPI_end_call(false);
3229 
3230  return res;
3231 }
void unregister_ENR(QueryEnvironment *queryEnv, const char *name)

References _SPI_begin_call(), _SPI_current, _SPI_end_call(), _SPI_find_ENR_by_name(), EphemeralNamedRelationData::md, name, EphemeralNamedRelationMetadataData::name, _SPI_connection::queryEnv, res, SPI_ERROR_ARGUMENT, SPI_ERROR_REL_NOT_FOUND, SPI_OK_REL_UNREGISTER, and unregister_ENR().

◆ SPICleanup()

void SPICleanup ( void  )

Definition at line 354 of file spi.c.

355 {
356  _SPI_current = NULL;
357  _SPI_connected = -1;
358  /* Reset API global variables, too */
359  SPI_processed = 0;
360  SPI_tuptable = NULL;
361  SPI_result = 0;
362 }

References _SPI_connected, _SPI_current, SPI_processed, SPI_result, and SPI_tuptable.

Referenced by AtEOXact_SPI(), and PostgresMain().

Variable Documentation

◆ SPI_processed

◆ SPI_result

◆ SPI_tuptable