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

◆ SPI_ERROR_CONNECT

#define SPI_ERROR_CONNECT   (-1)

Definition at line 67 of file spi.h.

Referenced by SPI_result_code_string().

◆ SPI_ERROR_COPY

#define SPI_ERROR_COPY   (-2)

◆ SPI_ERROR_CURSOR

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

Definition at line 71 of file spi.h.

◆ SPI_ERROR_NOATTRIBUTE

◆ SPI_ERROR_NOOUTFUNC

#define SPI_ERROR_NOOUTFUNC   (-10)

Definition at line 76 of file spi.h.

Referenced by SPI_result_code_string().

◆ SPI_ERROR_OPUNKNOWN

#define SPI_ERROR_OPUNKNOWN   (-3)

Definition at line 69 of file spi.h.

Referenced by _SPI_pquery(), and SPI_result_code_string().

◆ SPI_ERROR_PARAM

#define SPI_ERROR_PARAM   (-7)

◆ SPI_ERROR_REL_DUPLICATE

#define SPI_ERROR_REL_DUPLICATE   (-12)

Definition at line 78 of file spi.h.

Referenced by SPI_register_relation(), and SPI_result_code_string().

◆ SPI_ERROR_REL_NOT_FOUND

#define SPI_ERROR_REL_NOT_FOUND   (-13)

Definition at line 79 of file spi.h.

Referenced by SPI_result_code_string(), and SPI_unregister_relation().

◆ SPI_ERROR_TRANSACTION

#define SPI_ERROR_TRANSACTION   (-8)

◆ SPI_ERROR_TYPUNKNOWN

#define SPI_ERROR_TYPUNKNOWN   (-11)

Definition at line 77 of file spi.h.

Referenced by SPI_gettype(), and SPI_result_code_string().

◆ SPI_ERROR_UNCONNECTED

#define SPI_ERROR_UNCONNECTED   (-4)

◆ SPI_OK_CONNECT

◆ SPI_OK_CURSOR

#define SPI_OK_CURSOR   10

Definition at line 90 of file spi.h.

Referenced by exec_run_select(), and SPI_result_code_string().

◆ SPI_OK_DELETE

◆ SPI_OK_DELETE_RETURNING

#define SPI_OK_DELETE_RETURNING   12

◆ SPI_OK_FETCH

#define SPI_OK_FETCH   3

Definition at line 83 of file spi.h.

Referenced by PLy_cursor_fetch(), and SPI_result_code_string().

◆ SPI_OK_FINISH

◆ SPI_OK_INSERT

#define SPI_OK_INSERT   7

◆ SPI_OK_INSERT_RETURNING

#define SPI_OK_INSERT_RETURNING   11

◆ SPI_OK_REL_REGISTER

#define SPI_OK_REL_REGISTER   15

Definition at line 95 of file spi.h.

Referenced by SPI_register_relation(), SPI_register_trigger_data(), and SPI_result_code_string().

◆ SPI_OK_REL_UNREGISTER

#define SPI_OK_REL_UNREGISTER   16

Definition at line 96 of file spi.h.

Referenced by SPI_result_code_string(), and SPI_unregister_relation().

◆ SPI_OK_REWRITTEN

#define SPI_OK_REWRITTEN   14

◆ SPI_OK_SELECT

◆ SPI_OK_SELINTO

#define SPI_OK_SELINTO   6

◆ SPI_OK_TD_REGISTER

#define SPI_OK_TD_REGISTER   17

Definition at line 97 of file spi.h.

Referenced by SPI_register_trigger_data().

◆ SPI_OK_UPDATE

◆ SPI_OK_UPDATE_RETURNING

#define SPI_OK_UPDATE_RETURNING   13

◆ SPI_OK_UTILITY

◆ SPI_OPT_NONATOMIC

◆ SPI_pop

#define SPI_pop ( )    ((void) 0)

Definition at line 103 of file spi.h.

◆ SPI_pop_conditional

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

Definition at line 105 of file spi.h.

◆ SPI_push

#define SPI_push ( )    ((void) 0)

Definition at line 102 of file spi.h.

◆ SPI_push_conditional

#define SPI_push_conditional ( )    false

Definition at line 104 of file spi.h.

◆ SPI_restore_connection

#define SPI_restore_connection ( )    ((void) 0)

Definition at line 106 of file spi.h.

Typedef Documentation

◆ SPIExecuteOptions

◆ SPIParseOpenOptions

◆ SPIPlanPtr

typedef struct _SPI_plan* SPIPlanPtr

Definition at line 65 of file spi.h.

◆ SPIPrepareOptions

◆ SPITupleTable

typedef struct SPITupleTable SPITupleTable

Function Documentation

◆ AtEOSubXact_SPI()

void AtEOSubXact_SPI ( bool  isCommit,
SubTransactionId  mySubid 
)

Definition at line 394 of file spi.c.

References _SPI_connected, _SPI_connection::connectSubid, slist_mutable_iter::cur, ereport, errcode(), errhint(), errmsg(), _SPI_connection::execCxt, _SPI_connection::execSubid, _SPI_connection::internal_xact, InvalidSubTransactionId, MemoryContextDelete(), MemoryContextResetAndDeleteChildren, next, _SPI_connection::outer_processed, _SPI_connection::outer_result, _SPI_connection::outer_tuptable, _SPI_connection::procCxt, slist_container, slist_delete_current(), slist_foreach_modify, SPI_processed, SPI_result, SPITupleTable::subid, SPITupleTable::tuptabcxt, _SPI_connection::tuptable, _SPI_connection::tuptables, and WARNING.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

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

◆ AtEOXact_SPI()

void AtEOXact_SPI ( bool  isCommit)

Definition at line 372 of file spi.c.

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

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

373 {
374  /* Do nothing if the transaction end was initiated by SPI. */
376  return;
377 
378  if (isCommit && _SPI_connected != -1)
380  (errcode(ERRCODE_WARNING),
381  errmsg("transaction left non-empty SPI stack"),
382  errhint("Check for missing \"SPI_finish\" calls.")));
383 
384  SPICleanup();
385 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
bool internal_xact
Definition: spi_priv.h:42
void SPICleanup(void)
Definition: spi.c:358
int errcode(int sqlerrcode)
Definition: elog.c:698
static int _SPI_connected
Definition: spi.c:52
static _SPI_connection * _SPI_current
Definition: spi.c:50
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ SPI_commit()

void SPI_commit ( void  )

Definition at line 287 of file spi.c.

References _SPI_commit().

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

288 {
289  _SPI_commit(false);
290 }
static void _SPI_commit(bool chain)
Definition: spi.c:230

◆ SPI_commit_and_chain()

void SPI_commit_and_chain ( void  )

Definition at line 293 of file spi.c.

References _SPI_commit().

Referenced by exec_stmt_commit().

294 {
295  _SPI_commit(true);
296 }
static void _SPI_commit(bool chain)
Definition: spi.c:230

◆ SPI_connect()

◆ SPI_connect_ext()

int SPI_connect_ext ( int  options)

Definition at line 104 of file spi.c.

References _SPI_connected, _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().

105 {
106  int newdepth;
107 
108  /* Enlarge stack if necessary */
109  if (_SPI_stack == NULL)
110  {
111  if (_SPI_connected != -1 || _SPI_stack_depth != 0)
112  elog(ERROR, "SPI stack corrupted");
113  newdepth = 16;
116  newdepth * sizeof(_SPI_connection));
117  _SPI_stack_depth = newdepth;
118  }
119  else
120  {
122  elog(ERROR, "SPI stack corrupted");
123  if (_SPI_stack_depth == _SPI_connected + 1)
124  {
125  newdepth = _SPI_stack_depth * 2;
128  newdepth * sizeof(_SPI_connection));
129  _SPI_stack_depth = newdepth;
130  }
131  }
132 
133  /* Enter new stack level */
134  _SPI_connected++;
136 
138  _SPI_current->processed = 0;
139  _SPI_current->tuptable = NULL;
142  _SPI_current->procCxt = NULL; /* in case we fail to create 'em */
143  _SPI_current->execCxt = NULL;
145  _SPI_current->queryEnv = NULL;
147  _SPI_current->internal_xact = false;
151 
152  /*
153  * Create memory contexts for this procedure
154  *
155  * In atomic contexts (the normal case), we use TopTransactionContext,
156  * otherwise PortalContext, so that it lives across transaction
157  * boundaries.
158  *
159  * XXX It could be better to use PortalContext as the parent context in
160  * all cases, but we may not be inside a portal (consider deferred-trigger
161  * execution). Perhaps CurTransactionContext could be an option? For now
162  * it doesn't matter because we clean up explicitly in AtEOSubXact_SPI().
163  */
165  "SPI Proc",
168  "SPI Exec",
170  /* ... and switch to procedure's context */
172 
173  /*
174  * Reset API global variables so that current caller cannot accidentally
175  * depend on state of an outer caller.
176  */
177  SPI_processed = 0;
178  SPI_tuptable = NULL;
179  SPI_result = 0;
180 
181  return SPI_OK_CONNECT;
182 }
#define SPI_OK_CONNECT
Definition: spi.h:81
#define AllocSetContextCreate
Definition: memutils.h:173
MemoryContext TopTransactionContext
Definition: mcxt.c:53
static int _SPI_stack_depth
Definition: spi.c:51
bool internal_xact
Definition: spi_priv.h:42
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
static int _SPI_connected
Definition: spi.c:52
SubTransactionId execSubid
Definition: spi_priv.h:29
static _SPI_connection * _SPI_current
Definition: spi.c:50
#define false
Definition: c.h:399
uint64 SPI_processed
Definition: spi.c:45
SPITupleTable * outer_tuptable
Definition: spi_priv.h:47
MemoryContext PortalContext
Definition: mcxt.c:57
int SPI_result
Definition: spi.c:47
SubTransactionId connectSubid
Definition: spi_priv.h:36
static void slist_init(slist_head *head)
Definition: ilist.h:573
#define ERROR
Definition: elog.h:46
QueryEnvironment * queryEnv
Definition: spi_priv.h:37
#define SPI_OPT_NONATOMIC
Definition: spi.h:99
SPITupleTable * tuptable
Definition: spi_priv.h:26
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
static _SPI_connection * _SPI_stack
Definition: spi.c:49
MemoryContext TopMemoryContext
Definition: mcxt.c:48
MemoryContext savedcxt
Definition: spi_priv.h:35
uint64 outer_processed
Definition: spi_priv.h:46
MemoryContext procCxt
Definition: spi_priv.h:33
MemoryContext execCxt
Definition: spi_priv.h:34
uint64 processed
Definition: spi_priv.h:25
#define Assert(condition)
Definition: c.h:804
int outer_result
Definition: spi_priv.h:48
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
#define InvalidSubTransactionId
Definition: c.h:593
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
#define elog(elevel,...)
Definition: elog.h:232
slist_head tuptables
Definition: spi_priv.h:32

◆ SPI_copytuple()

HeapTuple SPI_copytuple ( HeapTuple  tuple)

Definition at line 943 of file spi.c.

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

944 {
945  MemoryContext oldcxt;
946  HeapTuple ctuple;
947 
948  if (tuple == NULL)
949  {
951  return NULL;
952  }
953 
954  if (_SPI_current == NULL)
955  {
957  return NULL;
958  }
959 
961 
962  ctuple = heap_copytuple(tuple);
963 
964  MemoryContextSwitchTo(oldcxt);
965 
966  return ctuple;
967 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:70
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static _SPI_connection * _SPI_current
Definition: spi.c:50
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
MemoryContext savedcxt
Definition: spi_priv.h:35

◆ SPI_cursor_close()

void SPI_cursor_close ( Portal  portal)

Definition at line 1752 of file spi.c.

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

1753 {
1754  if (!PortalIsValid(portal))
1755  elog(ERROR, "invalid portal in SPI cursor operation");
1756 
1757  PortalDrop(portal, false);
1758 }
#define ERROR
Definition: elog.h:46
#define PortalIsValid(p)
Definition: portal.h:203
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:467
#define elog(elevel,...)
Definition: elog.h:232

◆ SPI_cursor_fetch()

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

Definition at line 1696 of file spi.c.

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

1697 {
1698  _SPI_cursor_operation(portal,
1699  forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1701  /* we know that the DestSPI receiver doesn't need a destroy call */
1702 }
Definition: dest.h:94
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:113
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2804

◆ SPI_cursor_find()

Portal SPI_cursor_find ( const char *  name)

Definition at line 1684 of file spi.c.

References GetPortalByName().

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

1685 {
1686  return GetPortalByName(name);
1687 }
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
const char * name
Definition: encode.c:515

◆ SPI_cursor_move()

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

Definition at line 1711 of file spi.c.

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

1712 {
1713  _SPI_cursor_operation(portal,
1714  forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1715  None_Receiver);
1716 }
DestReceiver * None_Receiver
Definition: dest.c:96
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2804

◆ SPI_cursor_open()

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

Definition at line 1341 of file spi.c.

References _SPI_convert_params(), _SPI_plan::argtypes, _SPI_plan::nargs, 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().

1344 {
1345  Portal portal;
1346  ParamListInfo paramLI;
1347 
1348  /* build transient ParamListInfo in caller's context */
1349  paramLI = _SPI_convert_params(plan->nargs, plan->argtypes,
1350  Values, Nulls);
1351 
1352  portal = SPI_cursor_open_internal(name, plan, paramLI, read_only);
1353 
1354  /* done with the transient ParamListInfo */
1355  if (paramLI)
1356  pfree(paramLI);
1357 
1358  return portal;
1359 }
Oid * argtypes
Definition: spi_priv.h:100
void pfree(void *pointer)
Definition: mcxt.c:1169
int nargs
Definition: spi_priv.h:99
const char * name
Definition: encode.c:515
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1473
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2652
static bool Nulls[MAXATTR]
Definition: bootstrap.c:167

◆ 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 1368 of file spi.c.

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, _SPI_plan::nargs, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, SPI_cursor_open_internal(), and SPI_result.

1373 {
1374  Portal result;
1375  _SPI_plan plan;
1376  ParamListInfo paramLI;
1377 
1378  if (src == NULL || nargs < 0)
1379  elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
1380 
1381  if (nargs > 0 && (argtypes == NULL || Values == NULL))
1382  elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
1383 
1384  SPI_result = _SPI_begin_call(true);
1385  if (SPI_result < 0)
1386  elog(ERROR, "SPI_cursor_open_with_args called while not connected");
1387 
1388  memset(&plan, 0, sizeof(_SPI_plan));
1389  plan.magic = _SPI_PLAN_MAGIC;
1391  plan.cursor_options = cursorOptions;
1392  plan.nargs = nargs;
1393  plan.argtypes = argtypes;
1394  plan.parserSetup = NULL;
1395  plan.parserSetupArg = NULL;
1396 
1397  /* build transient ParamListInfo in executor context */
1398  paramLI = _SPI_convert_params(nargs, argtypes,
1399  Values, Nulls);
1400 
1401  _SPI_prepare_plan(src, &plan);
1402 
1403  /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1404 
1405  result = SPI_cursor_open_internal(name, &plan, paramLI, read_only);
1406 
1407  /* And clean up */
1408  _SPI_end_call(true);
1409 
1410  return result;
1411 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2103
Oid * argtypes
Definition: spi_priv.h:100
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
int SPI_result
Definition: spi.c:47
#define ERROR
Definition: elog.h:46
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
int nargs
Definition: spi_priv.h:99
ParserSetupHook parserSetup
Definition: spi_priv.h:101
void * parserSetupArg
Definition: spi_priv.h:102
const char * name
Definition: encode.c:515
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1473
#define elog(elevel,...)
Definition: elog.h:232
int cursor_options
Definition: spi_priv.h:98
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2652
static bool Nulls[MAXATTR]
Definition: bootstrap.c:167

◆ SPI_cursor_open_with_paramlist()

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

Definition at line 1421 of file spi.c.

References SPI_cursor_open_internal().

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

1423 {
1424  return SPI_cursor_open_internal(name, plan, params, read_only);
1425 }
const char * name
Definition: encode.c:515
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1473

◆ SPI_cursor_parse_open()

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

Definition at line 1429 of file spi.c.

References _SPI_begin_call(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), _SPI_plan::cursor_options, SPIParseOpenOptions::cursorOptions, elog, ERROR, _SPI_plan::magic, SPIParseOpenOptions::params, _SPI_plan::parse_mode, _SPI_plan::parserSetup, ParamListInfoData::parserSetup, _SPI_plan::parserSetupArg, ParamListInfoData::parserSetupArg, RAW_PARSE_DEFAULT, SPIParseOpenOptions::read_only, SPI_cursor_open_internal(), and SPI_result.

Referenced by exec_dynquery_with_params().

1432 {
1433  Portal result;
1434  _SPI_plan plan;
1435 
1436  if (src == NULL || options == NULL)
1437  elog(ERROR, "SPI_cursor_parse_open called with invalid arguments");
1438 
1439  SPI_result = _SPI_begin_call(true);
1440  if (SPI_result < 0)
1441  elog(ERROR, "SPI_cursor_parse_open called while not connected");
1442 
1443  memset(&plan, 0, sizeof(_SPI_plan));
1444  plan.magic = _SPI_PLAN_MAGIC;
1446  plan.cursor_options = options->cursorOptions;
1447  if (options->params)
1448  {
1449  plan.parserSetup = options->params->parserSetup;
1450  plan.parserSetupArg = options->params->parserSetupArg;
1451  }
1452 
1453  _SPI_prepare_plan(src, &plan);
1454 
1455  /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1456 
1457  result = SPI_cursor_open_internal(name, &plan,
1458  options->params, options->read_only);
1459 
1460  /* And clean up */
1461  _SPI_end_call(true);
1462 
1463  return result;
1464 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2103
void * parserSetupArg
Definition: params.h:117
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
ParamListInfo params
Definition: spi.h:59
int magic
Definition: spi_priv.h:92
ParserSetupHook parserSetup
Definition: params.h:116
bool read_only
Definition: spi.h:61
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
int SPI_result
Definition: spi.c:47
#define ERROR
Definition: elog.h:46
int cursorOptions
Definition: spi.h:60
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
ParserSetupHook parserSetup
Definition: spi_priv.h:101
void * parserSetupArg
Definition: spi_priv.h:102
const char * name
Definition: encode.c:515
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1473
#define elog(elevel,...)
Definition: elog.h:232
int cursor_options
Definition: spi_priv.h:98

◆ SPI_datumTransfer()

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

Definition at line 1257 of file spi.c.

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

Referenced by coerce_function_result_tuple(), and plpgsql_exec_function().

1258 {
1259  MemoryContext oldcxt;
1260  Datum result;
1261 
1262  if (_SPI_current == NULL)
1263  elog(ERROR, "SPI_datumTransfer called while not connected to SPI");
1264 
1266 
1267  result = datumTransfer(value, typByVal, typLen);
1268 
1269  MemoryContextSwitchTo(oldcxt);
1270 
1271  return result;
1272 }
static struct @142 value
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static _SPI_connection * _SPI_current
Definition: spi.c:50
#define ERROR
Definition: elog.h:46
MemoryContext savedcxt
Definition: spi_priv.h:35
uintptr_t Datum
Definition: postgres.h:411
Datum datumTransfer(Datum value, bool typByVal, int typLen)
Definition: datum.c:193
#define elog(elevel,...)
Definition: elog.h:232

◆ SPI_exec()

int SPI_exec ( const char *  src,
long  tcount 
)

Definition at line 536 of file spi.c.

References SPI_execute().

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

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

◆ SPI_execp()

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

Definition at line 609 of file spi.c.

References SPI_execute_plan().

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

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:580
static bool Nulls[MAXATTR]
Definition: bootstrap.c:167

◆ SPI_execute()

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

Definition at line 505 of file spi.c.

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

506 {
507  _SPI_plan plan;
508  int res;
509 
510  if (src == NULL || tcount < 0)
511  return SPI_ERROR_ARGUMENT;
512 
513  res = _SPI_begin_call(true);
514  if (res < 0)
515  return res;
516 
517  memset(&plan, 0, sizeof(_SPI_plan));
518  plan.magic = _SPI_PLAN_MAGIC;
521 
522  _SPI_prepare_oneshot_plan(src, &plan);
523 
524  res = _SPI_execute_plan(&plan, NULL,
526  read_only, false,
527  true, tcount,
528  NULL, NULL);
529 
530  _SPI_end_call(true);
531  return res;
532 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2211
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool no_snapshots, bool fire_triggers, uint64 tcount, DestReceiver *caller_dest, ResourceOwner plan_owner)
Definition: spi.c:2276
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
#define InvalidSnapshot
Definition: snapshot.h:123
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2804
int cursor_options
Definition: spi_priv.h:98

◆ SPI_execute_extended()

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

Definition at line 543 of file spi.c.

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, SPIExecuteOptions::dest, InvalidSnapshot, _SPI_plan::magic, SPIExecuteOptions::no_snapshots, SPIExecuteOptions::owner, SPIExecuteOptions::params, _SPI_plan::parse_mode, _SPI_plan::parserSetup, ParamListInfoData::parserSetup, _SPI_plan::parserSetupArg, ParamListInfoData::parserSetupArg, RAW_PARSE_DEFAULT, SPIExecuteOptions::read_only, SPI_ERROR_ARGUMENT, and SPIExecuteOptions::tcount.

Referenced by exec_stmt_dynexecute(), and exec_stmt_return_query().

545 {
546  int res;
547  _SPI_plan plan;
548 
549  if (src == NULL || options == NULL)
550  return SPI_ERROR_ARGUMENT;
551 
552  res = _SPI_begin_call(true);
553  if (res < 0)
554  return res;
555 
556  memset(&plan, 0, sizeof(_SPI_plan));
557  plan.magic = _SPI_PLAN_MAGIC;
560  if (options->params)
561  {
562  plan.parserSetup = options->params->parserSetup;
563  plan.parserSetupArg = options->params->parserSetupArg;
564  }
565 
566  _SPI_prepare_oneshot_plan(src, &plan);
567 
568  res = _SPI_execute_plan(&plan, options->params,
570  options->read_only, options->no_snapshots,
571  true, options->tcount,
572  options->dest, options->owner);
573 
574  _SPI_end_call(true);
575  return res;
576 }
void * parserSetupArg
Definition: params.h:117
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
DestReceiver * dest
Definition: spi.h:52
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2211
uint64 tcount
Definition: spi.h:51
ParserSetupHook parserSetup
Definition: params.h:116
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
ResourceOwner owner
Definition: spi.h:53
bool no_snapshots
Definition: spi.h:50
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool no_snapshots, bool fire_triggers, uint64 tcount, DestReceiver *caller_dest, ResourceOwner plan_owner)
Definition: spi.c:2276
ParamListInfo params
Definition: spi.h:48
bool read_only
Definition: spi.h:49
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
#define InvalidSnapshot
Definition: snapshot.h:123
ParserSetupHook parserSetup
Definition: spi_priv.h:101
void * parserSetupArg
Definition: spi_priv.h:102
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2804
int cursor_options
Definition: spi_priv.h:98

◆ SPI_execute_plan()

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

Definition at line 580 of file spi.c.

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

582 {
583  int res;
584 
585  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
586  return SPI_ERROR_ARGUMENT;
587 
588  if (plan->nargs > 0 && Values == NULL)
589  return SPI_ERROR_PARAM;
590 
591  res = _SPI_begin_call(true);
592  if (res < 0)
593  return res;
594 
595  res = _SPI_execute_plan(plan,
596  _SPI_convert_params(plan->nargs, plan->argtypes,
597  Values, Nulls),
599  read_only, false,
600  true, tcount,
601  NULL, NULL);
602 
603  _SPI_end_call(true);
604  return res;
605 }
Oid * argtypes
Definition: spi_priv.h:100
#define SPI_ERROR_PARAM
Definition: spi.h:73
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool no_snapshots, bool fire_triggers, uint64 tcount, DestReceiver *caller_dest, ResourceOwner plan_owner)
Definition: spi.c:2276
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
#define InvalidSnapshot
Definition: snapshot.h:123
int nargs
Definition: spi_priv.h:99
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2652
static bool Nulls[MAXATTR]
Definition: bootstrap.c:167

◆ SPI_execute_plan_extended()

int SPI_execute_plan_extended ( SPIPlanPtr  plan,
const SPIExecuteOptions options 
)

Definition at line 616 of file spi.c.

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, SPIExecuteOptions::dest, InvalidSnapshot, _SPI_plan::magic, SPIExecuteOptions::no_snapshots, SPIExecuteOptions::owner, SPIExecuteOptions::params, SPIExecuteOptions::read_only, SPI_ERROR_ARGUMENT, and SPIExecuteOptions::tcount.

Referenced by exec_stmt_call(), exec_stmt_return_query(), and exec_stmt_set().

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->params,
630  options->read_only, options->no_snapshots,
631  true, options->tcount,
632  options->dest, options->owner);
633 
634  _SPI_end_call(true);
635  return res;
636 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
DestReceiver * dest
Definition: spi.h:52
uint64 tcount
Definition: spi.h:51
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
ResourceOwner owner
Definition: spi.h:53
bool no_snapshots
Definition: spi.h:50
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool no_snapshots, bool fire_triggers, uint64 tcount, DestReceiver *caller_dest, ResourceOwner plan_owner)
Definition: spi.c:2276
ParamListInfo params
Definition: spi.h:48
bool read_only
Definition: spi.h:49
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
#define InvalidSnapshot
Definition: snapshot.h:123

◆ SPI_execute_plan_with_paramlist()

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

Definition at line 640 of file spi.c.

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

Referenced by exec_run_select(), and exec_stmt_execsql().

642 {
643  int res;
644 
645  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
646  return SPI_ERROR_ARGUMENT;
647 
648  res = _SPI_begin_call(true);
649  if (res < 0)
650  return res;
651 
652  res = _SPI_execute_plan(plan, params,
654  read_only, false,
655  true, tcount,
656  NULL, NULL);
657 
658  _SPI_end_call(true);
659  return res;
660 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool no_snapshots, bool fire_triggers, uint64 tcount, DestReceiver *caller_dest, ResourceOwner plan_owner)
Definition: spi.c:2276
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
#define InvalidSnapshot
Definition: snapshot.h:123

◆ 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 676 of file spi.c.

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, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

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

680 {
681  int res;
682 
683  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
684  return SPI_ERROR_ARGUMENT;
685 
686  if (plan->nargs > 0 && Values == NULL)
687  return SPI_ERROR_PARAM;
688 
689  res = _SPI_begin_call(true);
690  if (res < 0)
691  return res;
692 
693  res = _SPI_execute_plan(plan,
694  _SPI_convert_params(plan->nargs, plan->argtypes,
695  Values, Nulls),
696  snapshot, crosscheck_snapshot,
697  read_only, false,
698  fire_triggers, tcount,
699  NULL, NULL);
700 
701  _SPI_end_call(true);
702  return res;
703 }
Oid * argtypes
Definition: spi_priv.h:100
#define SPI_ERROR_PARAM
Definition: spi.h:73
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool no_snapshots, bool fire_triggers, uint64 tcount, DestReceiver *caller_dest, ResourceOwner plan_owner)
Definition: spi.c:2276
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
int nargs
Definition: spi_priv.h:99
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2652
static bool Nulls[MAXATTR]
Definition: bootstrap.c:167

◆ 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 712 of file spi.c.

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, _SPI_plan::parse_mode, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, RAW_PARSE_DEFAULT, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

716 {
717  int res;
718  _SPI_plan plan;
719  ParamListInfo paramLI;
720 
721  if (src == NULL || nargs < 0 || tcount < 0)
722  return SPI_ERROR_ARGUMENT;
723 
724  if (nargs > 0 && (argtypes == NULL || Values == NULL))
725  return SPI_ERROR_PARAM;
726 
727  res = _SPI_begin_call(true);
728  if (res < 0)
729  return res;
730 
731  memset(&plan, 0, sizeof(_SPI_plan));
732  plan.magic = _SPI_PLAN_MAGIC;
735  plan.nargs = nargs;
736  plan.argtypes = argtypes;
737  plan.parserSetup = NULL;
738  plan.parserSetupArg = NULL;
739 
740  paramLI = _SPI_convert_params(nargs, argtypes,
741  Values, Nulls);
742 
743  _SPI_prepare_oneshot_plan(src, &plan);
744 
745  res = _SPI_execute_plan(&plan, paramLI,
747  read_only, false,
748  true, tcount,
749  NULL, NULL);
750 
751  _SPI_end_call(true);
752  return res;
753 }
Oid * argtypes
Definition: spi_priv.h:100
#define SPI_ERROR_PARAM
Definition: spi.h:73
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2211
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool no_snapshots, bool fire_triggers, uint64 tcount, DestReceiver *caller_dest, ResourceOwner plan_owner)
Definition: spi.c:2276
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
#define InvalidSnapshot
Definition: snapshot.h:123
int nargs
Definition: spi_priv.h:99
ParserSetupHook parserSetup
Definition: spi_priv.h:101
void * parserSetupArg
Definition: spi_priv.h:102
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2804
int cursor_options
Definition: spi_priv.h:98
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2652
static bool Nulls[MAXATTR]
Definition: bootstrap.c:167

◆ SPI_finish()

int SPI_finish ( void  )

Definition at line 185 of file spi.c.

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

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

186 {
187  int res;
188 
189  res = _SPI_begin_call(false); /* just check we're connected */
190  if (res < 0)
191  return res;
192 
193  /* Restore memory context as it was before procedure call */
195 
196  /* Release memory used in procedure call (including tuptables) */
198  _SPI_current->execCxt = NULL;
200  _SPI_current->procCxt = NULL;
201 
202  /*
203  * Restore outer API variables, especially SPI_tuptable which is probably
204  * pointing at a just-deleted tuptable
205  */
209 
210  /* Exit stack level */
211  _SPI_connected--;
212  if (_SPI_connected < 0)
213  _SPI_current = NULL;
214  else
216 
217  return SPI_OK_FINISH;
218 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
static int _SPI_connected
Definition: spi.c:52
static _SPI_connection * _SPI_current
Definition: spi.c:50
uint64 SPI_processed
Definition: spi.c:45
SPITupleTable * outer_tuptable
Definition: spi_priv.h:47
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
int SPI_result
Definition: spi.c:47
static _SPI_connection * _SPI_stack
Definition: spi.c:49
MemoryContext savedcxt
Definition: spi_priv.h:35
uint64 outer_processed
Definition: spi_priv.h:46
MemoryContext procCxt
Definition: spi_priv.h:33
MemoryContext execCxt
Definition: spi_priv.h:34
int outer_result
Definition: spi_priv.h:48
#define SPI_OK_FINISH
Definition: spi.h:82

◆ SPI_fname()

char* SPI_fname ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1094 of file spi.c.

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

1095 {
1096  const FormData_pg_attribute *att;
1097 
1098  SPI_result = 0;
1099 
1100  if (fnumber > tupdesc->natts || fnumber == 0 ||
1102  {
1104  return NULL;
1105  }
1106 
1107  if (fnumber > 0)
1108  att = TupleDescAttr(tupdesc, fnumber - 1);
1109  else
1110  att = SystemAttributeDefinition(fnumber);
1111 
1112  return pstrdup(NameStr(att->attname));
1113 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
char * pstrdup(const char *in)
Definition: mcxt.c:1299
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition: heap.c:250
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
FormData_pg_attribute
Definition: pg_attribute.h:187
#define NameStr(name)
Definition: c.h:681

◆ SPI_fnumber()

int SPI_fnumber ( TupleDesc  tupdesc,
const char *  fname 
)

Definition at line 1071 of file spi.c.

References FormData_pg_attribute, namestrcmp(), TupleDescData::natts, 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().

1072 {
1073  int res;
1074  const FormData_pg_attribute *sysatt;
1075 
1076  for (res = 0; res < tupdesc->natts; res++)
1077  {
1078  Form_pg_attribute attr = TupleDescAttr(tupdesc, res);
1079 
1080  if (namestrcmp(&attr->attname, fname) == 0 &&
1081  !attr->attisdropped)
1082  return res + 1;
1083  }
1084 
1085  sysatt = SystemAttributeByName(fname);
1086  if (sysatt != NULL)
1087  return sysatt->attnum;
1088 
1089  /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
1090  return SPI_ERROR_NOATTRIBUTE;
1091 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
int namestrcmp(Name name, const char *str)
Definition: name.c:247
const FormData_pg_attribute * SystemAttributeByName(const char *attname)
Definition: heap.c:262
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:203
FormData_pg_attribute
Definition: pg_attribute.h:187

◆ SPI_freeplan()

int SPI_freeplan ( SPIPlanPtr  plan)

Definition at line 921 of file spi.c.

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

922 {
923  ListCell *lc;
924 
925  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
926  return SPI_ERROR_ARGUMENT;
927 
928  /* Release the plancache entries */
929  foreach(lc, plan->plancache_list)
930  {
931  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
932 
933  DropCachedPlan(plansource);
934  }
935 
936  /* Now get rid of the _SPI_plan and subsidiary data in its plancxt */
938 
939  return 0;
940 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
List * plancache_list
Definition: spi_priv.h:95
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
MemoryContext plancxt
Definition: spi_priv.h:96
#define lfirst(lc)
Definition: pg_list.h:169
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:498

◆ SPI_freetuple()

void SPI_freetuple ( HeapTuple  pointer)

Definition at line 1275 of file spi.c.

References heap_freetuple().

1276 {
1277  /* No longer need to worry which context tuple was in... */
1278  heap_freetuple(tuple);
1279 }
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338

◆ SPI_freetuptable()

void SPI_freetuptable ( SPITupleTable tuptable)

Definition at line 1282 of file spi.c.

References slist_mutable_iter::cur, elog, MemoryContextDelete(), next, slist_container, slist_delete_current(), slist_foreach_modify, 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().

1283 {
1284  bool found = false;
1285 
1286  /* ignore call if NULL pointer */
1287  if (tuptable == NULL)
1288  return;
1289 
1290  /*
1291  * Search only the topmost SPI context for a matching tuple table.
1292  */
1293  if (_SPI_current != NULL)
1294  {
1295  slist_mutable_iter siter;
1296 
1297  /* find tuptable in active list, then remove it */
1299  {
1300  SPITupleTable *tt;
1301 
1302  tt = slist_container(SPITupleTable, next, siter.cur);
1303  if (tt == tuptable)
1304  {
1305  slist_delete_current(&siter);
1306  found = true;
1307  break;
1308  }
1309  }
1310  }
1311 
1312  /*
1313  * Refuse the deletion if we didn't find it in the topmost SPI context.
1314  * This is primarily a guard against double deletion, but might prevent
1315  * other errors as well. Since the worst consequence of not deleting a
1316  * tuptable would be a transient memory leak, this is just a WARNING.
1317  */
1318  if (!found)
1319  {
1320  elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);
1321  return;
1322  }
1323 
1324  /* for safety, reset global variables that might point at tuptable */
1325  if (tuptable == _SPI_current->tuptable)
1326  _SPI_current->tuptable = NULL;
1327  if (tuptable == SPI_tuptable)
1328  SPI_tuptable = NULL;
1329 
1330  /* release all memory belonging to tuptable */
1331  MemoryContextDelete(tuptable->tuptabcxt);
1332 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
static int32 next
Definition: blutils.c:219
slist_node * cur
Definition: ilist.h:241
SPITupleTable * SPI_tuptable
Definition: spi.c:46
static _SPI_connection * _SPI_current
Definition: spi.c:50
#define slist_foreach_modify(iter, lhead)
Definition: ilist.h:735
SPITupleTable * tuptable
Definition: spi_priv.h:26
#define WARNING
Definition: elog.h:40
#define slist_container(type, membername, ptr)
Definition: ilist.h:693
#define elog(elevel,...)
Definition: elog.h:232
static void slist_delete_current(slist_mutable_iter *iter)
Definition: ilist.h:671
slist_head tuptables
Definition: spi_priv.h:32
MemoryContext tuptabcxt
Definition: spi.h:31

◆ SPI_getargcount()

int SPI_getargcount ( SPIPlanPtr  plan)

Definition at line 1780 of file spi.c.

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

1781 {
1782  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1783  {
1785  return -1;
1786  }
1787  return plan->nargs;
1788 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
int nargs
Definition: spi_priv.h:99

◆ SPI_getargtypeid()

Oid SPI_getargtypeid ( SPIPlanPtr  plan,
int  argIndex 
)

Definition at line 1765 of file spi.c.

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

1766 {
1767  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
1768  argIndex < 0 || argIndex >= plan->nargs)
1769  {
1771  return InvalidOid;
1772  }
1773  return plan->argtypes[argIndex];
1774 }
Oid * argtypes
Definition: spi_priv.h:100
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
int nargs
Definition: spi_priv.h:99
#define InvalidOid
Definition: postgres_ext.h:36

◆ SPI_getbinval()

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

Definition at line 1148 of file spi.c.

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

1149 {
1150  SPI_result = 0;
1151 
1152  if (fnumber > tupdesc->natts || fnumber == 0 ||
1154  {
1156  *isnull = true;
1157  return (Datum) NULL;
1158  }
1159 
1160  return heap_getattr(tuple, fnumber, tupdesc, isnull);
1161 }
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:761
uintptr_t Datum
Definition: postgres.h:411

◆ SPI_getnspname()

char* SPI_getnspname ( Relation  rel)

Definition at line 1228 of file spi.c.

References get_namespace_name(), and RelationGetNamespace.

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

1229 {
1231 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3316
#define RelationGetNamespace(relation)
Definition: rel.h:510

◆ SPI_getrelname()

char* SPI_getrelname ( Relation  rel)

Definition at line 1222 of file spi.c.

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

1223 {
1224  return pstrdup(RelationGetRelationName(rel));
1225 }
char * pstrdup(const char *in)
Definition: mcxt.c:1299
#define RelationGetRelationName(relation)
Definition: rel.h:503

◆ SPI_gettype()

char* SPI_gettype ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1164 of file spi.c.

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

1165 {
1166  Oid typoid;
1167  HeapTuple typeTuple;
1168  char *result;
1169 
1170  SPI_result = 0;
1171 
1172  if (fnumber > tupdesc->natts || fnumber == 0 ||
1174  {
1176  return NULL;
1177  }
1178 
1179  if (fnumber > 0)
1180  typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1181  else
1182  typoid = (SystemAttributeDefinition(fnumber))->atttypid;
1183 
1184  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
1185 
1186  if (!HeapTupleIsValid(typeTuple))
1187  {
1189  return NULL;
1190  }
1191 
1192  result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
1193  ReleaseSysCache(typeTuple);
1194  return result;
1195 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
char * pstrdup(const char *in)
Definition: mcxt.c:1299
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
unsigned int Oid
Definition: postgres_ext.h:31
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition: heap.c:250
int SPI_result
Definition: spi.c:47
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
NameData typname
Definition: pg_type.h:41
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
#define SPI_ERROR_TYPUNKNOWN
Definition: spi.h:77
#define NameStr(name)
Definition: c.h:681

◆ SPI_gettypeid()

Oid SPI_gettypeid ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1204 of file spi.c.

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

1205 {
1206  SPI_result = 0;
1207 
1208  if (fnumber > tupdesc->natts || fnumber == 0 ||
1210  {
1212  return InvalidOid;
1213  }
1214 
1215  if (fnumber > 0)
1216  return TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1217  else
1218  return (SystemAttributeDefinition(fnumber))->atttypid;
1219 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition: heap.c:250
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
#define InvalidOid
Definition: postgres_ext.h:36

◆ SPI_getvalue()

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

Definition at line 1116 of file spi.c.

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

1117 {
1118  Datum val;
1119  bool isnull;
1120  Oid typoid,
1121  foutoid;
1122  bool typisvarlena;
1123 
1124  SPI_result = 0;
1125 
1126  if (fnumber > tupdesc->natts || fnumber == 0 ||
1128  {
1130  return NULL;
1131  }
1132 
1133  val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
1134  if (isnull)
1135  return NULL;
1136 
1137  if (fnumber > 0)
1138  typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1139  else
1140  typoid = (SystemAttributeDefinition(fnumber))->atttypid;
1141 
1142  getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
1143 
1144  return OidOutputFunctionCall(foutoid, val);
1145 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2854
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
unsigned int Oid
Definition: postgres_ext.h:31
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition: heap.c:250
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:761
uintptr_t Datum
Definition: postgres.h:411
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1653
long val
Definition: informix.c:664

◆ SPI_inside_nonatomic_context()

bool SPI_inside_nonatomic_context ( void  )

Definition at line 493 of file spi.c.

References _SPI_connection::atomic.

Referenced by StartTransaction().

494 {
495  if (_SPI_current == NULL)
496  return false; /* not in any SPI context at all */
497  if (_SPI_current->atomic)
498  return false; /* it's atomic (ie function not procedure) */
499  return true;
500 }
static _SPI_connection * _SPI_current
Definition: spi.c:50

◆ SPI_is_cursor_plan()

bool SPI_is_cursor_plan ( SPIPlanPtr  plan)

Definition at line 1800 of file spi.c.

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

1801 {
1802  CachedPlanSource *plansource;
1803 
1804  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1805  {
1807  return false;
1808  }
1809 
1810  if (list_length(plan->plancache_list) != 1)
1811  {
1812  SPI_result = 0;
1813  return false; /* not exactly 1 pre-rewrite command */
1814  }
1815  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1816 
1817  /*
1818  * We used to force revalidation of the cached plan here, but that seems
1819  * unnecessary: invalidation could mean a change in the rowtype of the
1820  * tuples returned by a plan, but not whether it returns tuples at all.
1821  */
1822  SPI_result = 0;
1823 
1824  /* Does it return tuples? */
1825  if (plansource->resultDesc)
1826  return true;
1827 
1828  return false;
1829 }
List * plancache_list
Definition: spi_priv.h:95
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
TupleDesc resultDesc
Definition: plancache.h:108
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
#define linitial(l)
Definition: pg_list.h:174
static int list_length(const List *l)
Definition: pg_list.h:149

◆ SPI_keepplan()

int SPI_keepplan ( SPIPlanPtr  plan)

Definition at line 872 of file spi.c.

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

873 {
874  ListCell *lc;
875 
876  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
877  plan->saved || plan->oneshot)
878  return SPI_ERROR_ARGUMENT;
879 
880  /*
881  * Mark it saved, reparent it under CacheMemoryContext, and mark all the
882  * component CachedPlanSources as saved. This sequence cannot fail
883  * partway through, so there's no risk of long-term memory leakage.
884  */
885  plan->saved = true;
887 
888  foreach(lc, plan->plancache_list)
889  {
890  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
891 
892  SaveCachedPlan(plansource);
893  }
894 
895  return 0;
896 }
List * plancache_list
Definition: spi_priv.h:95
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:361
int magic
Definition: spi_priv.h:92
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
MemoryContext plancxt
Definition: spi_priv.h:96
bool saved
Definition: spi_priv.h:93
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:454
#define lfirst(lc)
Definition: pg_list.h:169
bool oneshot
Definition: spi_priv.h:94
MemoryContext CacheMemoryContext
Definition: mcxt.c:51

◆ SPI_modifytuple()

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

Definition at line 1002 of file spi.c.

References heap_deform_tuple(), heap_form_tuple(), i, MemoryContextSwitchTo(), TupleDescData::natts, 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().

1004 {
1005  MemoryContext oldcxt;
1006  HeapTuple mtuple;
1007  int numberOfAttributes;
1008  Datum *v;
1009  bool *n;
1010  int i;
1011 
1012  if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
1013  {
1015  return NULL;
1016  }
1017 
1018  if (_SPI_current == NULL)
1019  {
1021  return NULL;
1022  }
1023 
1025 
1026  SPI_result = 0;
1027 
1028  numberOfAttributes = rel->rd_att->natts;
1029  v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1030  n = (bool *) palloc(numberOfAttributes * sizeof(bool));
1031 
1032  /* fetch old values and nulls */
1033  heap_deform_tuple(tuple, rel->rd_att, v, n);
1034 
1035  /* replace values and nulls */
1036  for (i = 0; i < natts; i++)
1037  {
1038  if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
1039  break;
1040  v[attnum[i] - 1] = Values[i];
1041  n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? true : false;
1042  }
1043 
1044  if (i == natts) /* no errors in *attnum */
1045  {
1046  mtuple = heap_form_tuple(rel->rd_att, v, n);
1047 
1048  /*
1049  * copy the identification info of the old tuple: t_ctid, t_self, and
1050  * OID (if any)
1051  */
1052  mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
1053  mtuple->t_self = tuple->t_self;
1054  mtuple->t_tableOid = tuple->t_tableOid;
1055  }
1056  else
1057  {
1058  mtuple = NULL;
1060  }
1061 
1062  pfree(v);
1063  pfree(n);
1064 
1065  MemoryContextSwitchTo(oldcxt);
1066 
1067  return mtuple;
1068 }
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:70
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static _SPI_connection * _SPI_current
Definition: spi.c:50
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
HeapTupleHeader t_data
Definition: htup.h:68
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
void pfree(void *pointer)
Definition: mcxt.c:1169
ItemPointerData t_ctid
Definition: htup_details.h:160
ItemPointerData t_self
Definition: htup.h:65
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
Oid t_tableOid
Definition: htup.h:66
MemoryContext savedcxt
Definition: spi_priv.h:35
uintptr_t Datum
Definition: postgres.h:411
TupleDesc rd_att
Definition: rel.h:110
int16 attnum
Definition: pg_attribute.h:83
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1249
void * palloc(Size size)
Definition: mcxt.c:1062
int i
static bool Nulls[MAXATTR]
Definition: bootstrap.c:167

◆ SPI_palloc()

void* SPI_palloc ( Size  size)

Definition at line 1234 of file spi.c.

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

Referenced by _SPI_strdup(), and coerce_function_result_tuple().

1235 {
1236  if (_SPI_current == NULL)
1237  elog(ERROR, "SPI_palloc called while not connected to SPI");
1238 
1239  return MemoryContextAlloc(_SPI_current->savedcxt, size);
1240 }
static _SPI_connection * _SPI_current
Definition: spi.c:50
#define ERROR
Definition: elog.h:46
MemoryContext savedcxt
Definition: spi_priv.h:35
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
#define elog(elevel,...)
Definition: elog.h:232

◆ SPI_pfree()

void SPI_pfree ( void *  pointer)

Definition at line 1250 of file spi.c.

References pfree().

1251 {
1252  /* No longer need to worry which context chunk was in... */
1253  pfree(pointer);
1254 }
void pfree(void *pointer)
Definition: mcxt.c:1169

◆ SPI_plan_get_cached_plan()

CachedPlan* SPI_plan_get_cached_plan ( SPIPlanPtr  plan)

Definition at line 1958 of file spi.c.

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

1959 {
1960  CachedPlanSource *plansource;
1961  CachedPlan *cplan;
1962  SPICallbackArg spicallbackarg;
1963  ErrorContextCallback spierrcontext;
1964 
1965  Assert(plan->magic == _SPI_PLAN_MAGIC);
1966 
1967  /* Can't support one-shot plans here */
1968  if (plan->oneshot)
1969  return NULL;
1970 
1971  /* Must have exactly one CachedPlanSource */
1972  if (list_length(plan->plancache_list) != 1)
1973  return NULL;
1974  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1975 
1976  /* Setup error traceback support for ereport() */
1977  spicallbackarg.query = plansource->query_string;
1978  spicallbackarg.mode = plan->parse_mode;
1979  spierrcontext.callback = _SPI_error_callback;
1980  spierrcontext.arg = &spicallbackarg;
1981  spierrcontext.previous = error_context_stack;
1982  error_context_stack = &spierrcontext;
1983 
1984  /* Get the generic plan for the query */
1985  cplan = GetCachedPlan(plansource, NULL,
1986  plan->saved ? CurrentResourceOwner : NULL,
1988  Assert(cplan == plansource->gplan);
1989 
1990  /* Pop the error context stack */
1991  error_context_stack = spierrcontext.previous;
1992 
1993  return cplan;
1994 }
RawParseMode mode
Definition: spi.c:57
List * plancache_list
Definition: spi_priv.h:95
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static _SPI_connection * _SPI_current
Definition: spi.c:50
void(* callback)(void *arg)
Definition: elog.h:247
struct ErrorContextCallback * previous
Definition: elog.h:246
struct CachedPlan * gplan
Definition: plancache.h:121
ErrorContextCallback * error_context_stack
Definition: elog.c:93
RawParseMode parse_mode
Definition: spi_priv.h:97
static void _SPI_error_callback(void *arg)
Definition: spi.c:2758
#define linitial(l)
Definition: pg_list.h:174
QueryEnvironment * queryEnv
Definition: spi_priv.h:37
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
Definition: plancache.c:1141
bool saved
Definition: spi_priv.h:93
#define Assert(condition)
Definition: c.h:804
bool oneshot
Definition: spi_priv.h:94
const char * query_string
Definition: plancache.h:100
static int list_length(const List *l)
Definition: pg_list.h:149
const char * query
Definition: spi.c:56

◆ SPI_plan_get_plan_sources()

List* SPI_plan_get_plan_sources ( SPIPlanPtr  plan)

Definition at line 1939 of file spi.c.

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

1940 {
1941  Assert(plan->magic == _SPI_PLAN_MAGIC);
1942  return plan->plancache_list;
1943 }
List * plancache_list
Definition: spi_priv.h:95
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
#define Assert(condition)
Definition: c.h:804

◆ SPI_plan_is_valid()

bool SPI_plan_is_valid ( SPIPlanPtr  plan)

Definition at line 1838 of file spi.c.

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

Referenced by ri_FetchPreparedPlan().

1839 {
1840  ListCell *lc;
1841 
1842  Assert(plan->magic == _SPI_PLAN_MAGIC);
1843 
1844  foreach(lc, plan->plancache_list)
1845  {
1846  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1847 
1848  if (!CachedPlanIsValid(plansource))
1849  return false;
1850  }
1851  return true;
1852 }
List * plancache_list
Definition: spi_priv.h:95
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
bool CachedPlanIsValid(CachedPlanSource *plansource)
Definition: plancache.c:1598

◆ 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 762 of file spi.c.

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

764 {
765  _SPI_plan plan;
766  SPIPlanPtr result;
767 
768  if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
769  {
771  return NULL;
772  }
773 
774  SPI_result = _SPI_begin_call(true);
775  if (SPI_result < 0)
776  return NULL;
777 
778  memset(&plan, 0, sizeof(_SPI_plan));
779  plan.magic = _SPI_PLAN_MAGIC;
781  plan.cursor_options = cursorOptions;
782  plan.nargs = nargs;
783  plan.argtypes = argtypes;
784  plan.parserSetup = NULL;
785  plan.parserSetupArg = NULL;
786 
787  _SPI_prepare_plan(src, &plan);
788 
789  /* copy plan to procedure context */
790  result = _SPI_make_plan_non_temp(&plan);
791 
792  _SPI_end_call(true);
793 
794  return result;
795 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2103
Oid * argtypes
Definition: spi_priv.h:100
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:2938
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
int nargs
Definition: spi_priv.h:99
ParserSetupHook parserSetup
Definition: spi_priv.h:101
void * parserSetupArg
Definition: spi_priv.h:102
int cursor_options
Definition: spi_priv.h:98

◆ SPI_prepare_extended()

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

Definition at line 798 of file spi.c.

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, SPIPrepareOptions::cursorOptions, _SPI_plan::magic, _SPI_plan::nargs, _SPI_plan::parse_mode, SPIPrepareOptions::parseMode, SPIPrepareOptions::parserSetup, _SPI_plan::parserSetup, SPIPrepareOptions::parserSetupArg, _SPI_plan::parserSetupArg, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by exec_prepare_plan().

800 {
801  _SPI_plan plan;
802  SPIPlanPtr result;
803 
804  if (src == NULL || options == NULL)
805  {
807  return NULL;
808  }
809 
810  SPI_result = _SPI_begin_call(true);
811  if (SPI_result < 0)
812  return NULL;
813 
814  memset(&plan, 0, sizeof(_SPI_plan));
815  plan.magic = _SPI_PLAN_MAGIC;
816  plan.parse_mode = options->parseMode;
817  plan.cursor_options = options->cursorOptions;
818  plan.nargs = 0;
819  plan.argtypes = NULL;
820  plan.parserSetup = options->parserSetup;
821  plan.parserSetupArg = options->parserSetupArg;
822 
823  _SPI_prepare_plan(src, &plan);
824 
825  /* copy plan to procedure context */
826  result = _SPI_make_plan_non_temp(&plan);
827 
828  _SPI_end_call(true);
829 
830  return result;
831 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2103
Oid * argtypes
Definition: spi_priv.h:100
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:2938
ParserSetupHook parserSetup
Definition: spi.h:39
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
int cursorOptions
Definition: spi.h:42
int nargs
Definition: spi_priv.h:99
ParserSetupHook parserSetup
Definition: spi_priv.h:101
void * parserSetupArg
Definition: spi_priv.h:102
int cursor_options
Definition: spi_priv.h:98
void * parserSetupArg
Definition: spi.h:40
RawParseMode parseMode
Definition: spi.h:41

◆ SPI_prepare_params()

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

Definition at line 834 of file spi.c.

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.

838 {
839  _SPI_plan plan;
840  SPIPlanPtr result;
841 
842  if (src == NULL)
843  {
845  return NULL;
846  }
847 
848  SPI_result = _SPI_begin_call(true);
849  if (SPI_result < 0)
850  return NULL;
851 
852  memset(&plan, 0, sizeof(_SPI_plan));
853  plan.magic = _SPI_PLAN_MAGIC;
855  plan.cursor_options = cursorOptions;
856  plan.nargs = 0;
857  plan.argtypes = NULL;
858  plan.parserSetup = parserSetup;
859  plan.parserSetupArg = parserSetupArg;
860 
861  _SPI_prepare_plan(src, &plan);
862 
863  /* copy plan to procedure context */
864  result = _SPI_make_plan_non_temp(&plan);
865 
866  _SPI_end_call(true);
867 
868  return result;
869 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2103
Oid * argtypes
Definition: spi_priv.h:100
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
RawParseMode parse_mode
Definition: spi_priv.h:97
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:2938
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
int nargs
Definition: spi_priv.h:99
ParserSetupHook parserSetup
Definition: spi_priv.h:101
void * parserSetupArg
Definition: spi_priv.h:102
int cursor_options
Definition: spi_priv.h:98

◆ SPI_register_relation()

int SPI_register_relation ( EphemeralNamedRelation  enr)

Definition at line 3094 of file spi.c.

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

Referenced by SPI_register_trigger_data().

3095 {
3096  EphemeralNamedRelation match;
3097  int res;
3098 
3099  if (enr == NULL || enr->md.name == NULL)
3100  return SPI_ERROR_ARGUMENT;
3101 
3102  res = _SPI_begin_call(false); /* keep current memory context */
3103  if (res < 0)
3104  return res;
3105 
3106  match = _SPI_find_ENR_by_name(enr->md.name);
3107  if (match)
3109  else
3110  {
3111  if (_SPI_current->queryEnv == NULL)
3113 
3115  res = SPI_OK_REL_REGISTER;
3116  }
3117 
3118  _SPI_end_call(false);
3119 
3120  return res;
3121 }
EphemeralNamedRelationMetadataData md
#define SPI_ERROR_REL_DUPLICATE
Definition: spi.h:78
static EphemeralNamedRelation _SPI_find_ENR_by_name(const char *name)
Definition: spi.c:3077
static _SPI_connection * _SPI_current
Definition: spi.c:50
#define SPI_OK_REL_REGISTER
Definition: spi.h:95
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
QueryEnvironment * queryEnv
Definition: spi_priv.h:37
QueryEnvironment * create_queryEnv(void)
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
void register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr)

◆ SPI_register_trigger_data()

int SPI_register_trigger_data ( TriggerData tdata)

Definition at line 3161 of file spi.c.

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

3162 {
3163  if (tdata == NULL)
3164  return SPI_ERROR_ARGUMENT;
3165 
3166  if (tdata->tg_newtable)
3167  {
3170  int rc;
3171 
3172  enr->md.name = tdata->tg_trigger->tgnewtable;
3173  enr->md.reliddesc = tdata->tg_relation->rd_id;
3174  enr->md.tupdesc = NULL;
3177  enr->reldata = tdata->tg_newtable;
3178  rc = SPI_register_relation(enr);
3179  if (rc != SPI_OK_REL_REGISTER)
3180  return rc;
3181  }
3182 
3183  if (tdata->tg_oldtable)
3184  {
3187  int rc;
3188 
3189  enr->md.name = tdata->tg_trigger->tgoldtable;
3190  enr->md.reliddesc = tdata->tg_relation->rd_id;
3191  enr->md.tupdesc = NULL;
3194  enr->reldata = tdata->tg_oldtable;
3195  rc = SPI_register_relation(enr);
3196  if (rc != SPI_OK_REL_REGISTER)
3197  return rc;
3198  }
3199 
3200  return SPI_OK_TD_REGISTER;
3201 }
EphemeralNamedRelationMetadataData md
#define SPI_OK_REL_REGISTER
Definition: spi.h:95
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
#define SPI_OK_TD_REGISTER
Definition: spi.h:97
Oid rd_id
Definition: rel.h:111
char * tgnewtable
Definition: reltrigger.h:44
Trigger * tg_trigger
Definition: trigger.h:37
int64 tuplestore_tuple_count(Tuplestorestate *state)
Definition: tuplestore.c:546
Tuplestorestate * tg_oldtable
Definition: trigger.h:40
int SPI_register_relation(EphemeralNamedRelation enr)
Definition: spi.c:3094
void * palloc(Size size)
Definition: mcxt.c:1062
Tuplestorestate * tg_newtable
Definition: trigger.h:41
EphemeralNameRelationType enrtype
char * tgoldtable
Definition: reltrigger.h:43
Relation tg_relation
Definition: trigger.h:34

◆ SPI_repalloc()

void* SPI_repalloc ( void *  pointer,
Size  size 
)

Definition at line 1243 of file spi.c.

References repalloc().

1244 {
1245  /* No longer need to worry which context chunk was in... */
1246  return repalloc(pointer, size);
1247 }
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182

◆ SPI_result_code_string()

const char* SPI_result_code_string ( int  code)

Definition at line 1862 of file spi.c.

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

1863 {
1864  static char buf[64];
1865 
1866  switch (code)
1867  {
1868  case SPI_ERROR_CONNECT:
1869  return "SPI_ERROR_CONNECT";
1870  case SPI_ERROR_COPY:
1871  return "SPI_ERROR_COPY";
1872  case SPI_ERROR_OPUNKNOWN:
1873  return "SPI_ERROR_OPUNKNOWN";
1874  case SPI_ERROR_UNCONNECTED:
1875  return "SPI_ERROR_UNCONNECTED";
1876  case SPI_ERROR_ARGUMENT:
1877  return "SPI_ERROR_ARGUMENT";
1878  case SPI_ERROR_PARAM:
1879  return "SPI_ERROR_PARAM";
1880  case SPI_ERROR_TRANSACTION:
1881  return "SPI_ERROR_TRANSACTION";
1882  case SPI_ERROR_NOATTRIBUTE:
1883  return "SPI_ERROR_NOATTRIBUTE";
1884  case SPI_ERROR_NOOUTFUNC:
1885  return "SPI_ERROR_NOOUTFUNC";
1886  case SPI_ERROR_TYPUNKNOWN:
1887  return "SPI_ERROR_TYPUNKNOWN";
1889  return "SPI_ERROR_REL_DUPLICATE";
1891  return "SPI_ERROR_REL_NOT_FOUND";
1892  case SPI_OK_CONNECT:
1893  return "SPI_OK_CONNECT";
1894  case SPI_OK_FINISH:
1895  return "SPI_OK_FINISH";
1896  case SPI_OK_FETCH:
1897  return "SPI_OK_FETCH";
1898  case SPI_OK_UTILITY:
1899  return "SPI_OK_UTILITY";
1900  case SPI_OK_SELECT:
1901  return "SPI_OK_SELECT";
1902  case SPI_OK_SELINTO:
1903  return "SPI_OK_SELINTO";
1904  case SPI_OK_INSERT:
1905  return "SPI_OK_INSERT";
1906  case SPI_OK_DELETE:
1907  return "SPI_OK_DELETE";
1908  case SPI_OK_UPDATE:
1909  return "SPI_OK_UPDATE";
1910  case SPI_OK_CURSOR:
1911  return "SPI_OK_CURSOR";
1913  return "SPI_OK_INSERT_RETURNING";
1915  return "SPI_OK_DELETE_RETURNING";
1917  return "SPI_OK_UPDATE_RETURNING";
1918  case SPI_OK_REWRITTEN:
1919  return "SPI_OK_REWRITTEN";
1920  case SPI_OK_REL_REGISTER:
1921  return "SPI_OK_REL_REGISTER";
1922  case SPI_OK_REL_UNREGISTER:
1923  return "SPI_OK_REL_UNREGISTER";
1924  }
1925  /* Unrecognized code ... return something useful ... */
1926  sprintf(buf, "Unrecognized SPI code %d", code);
1927  return buf;
1928 }
#define SPI_OK_CONNECT
Definition: spi.h:81
#define SPI_ERROR_PARAM
Definition: spi.h:73
#define SPI_ERROR_REL_NOT_FOUND
Definition: spi.h:79
#define SPI_ERROR_REL_DUPLICATE
Definition: spi.h:78
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:70
#define SPI_OK_DELETE_RETURNING
Definition: spi.h:92
#define SPI_OK_DELETE
Definition: spi.h:88
#define SPI_ERROR_COPY
Definition: spi.h:68
#define SPI_ERROR_OPUNKNOWN
Definition: spi.h:69
#define SPI_OK_REL_REGISTER
Definition: spi.h:95
#define SPI_ERROR_CONNECT
Definition: spi.h:67
#define SPI_OK_CURSOR
Definition: spi.h:90
#define sprintf
Definition: port.h:218
#define SPI_ERROR_NOOUTFUNC
Definition: spi.h:76
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
#define SPI_OK_INSERT_RETURNING
Definition: spi.h:91
static char * buf
Definition: pg_test_fsync.c:68
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:75
#define SPI_OK_UTILITY
Definition: spi.h:84
#define SPI_OK_UPDATE_RETURNING
Definition: spi.h:93
#define SPI_OK_REWRITTEN
Definition: spi.h:94
#define SPI_ERROR_TRANSACTION
Definition: spi.h:74
#define SPI_OK_SELINTO
Definition: spi.h:86
#define SPI_OK_FETCH
Definition: spi.h:83
#define SPI_OK_SELECT
Definition: spi.h:85
#define SPI_OK_FINISH
Definition: spi.h:82
#define SPI_ERROR_TYPUNKNOWN
Definition: spi.h:77
#define SPI_OK_UPDATE
Definition: spi.h:89
#define SPI_OK_INSERT
Definition: spi.h:87
#define SPI_OK_REL_UNREGISTER
Definition: spi.h:96

◆ SPI_returntuple()

HeapTupleHeader SPI_returntuple ( HeapTuple  tuple,
TupleDesc  tupdesc 
)

Definition at line 970 of file spi.c.

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

971 {
972  MemoryContext oldcxt;
973  HeapTupleHeader dtup;
974 
975  if (tuple == NULL || tupdesc == NULL)
976  {
978  return NULL;
979  }
980 
981  if (_SPI_current == NULL)
982  {
984  return NULL;
985  }
986 
987  /* For RECORD results, make sure a typmod has been assigned */
988  if (tupdesc->tdtypeid == RECORDOID &&
989  tupdesc->tdtypmod < 0)
990  assign_record_type_typmod(tupdesc);
991 
993 
994  dtup = DatumGetHeapTupleHeader(heap_copy_tuple_as_datum(tuple, tupdesc));
995 
996  MemoryContextSwitchTo(oldcxt);
997 
998  return dtup;
999 }
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:70
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static _SPI_connection * _SPI_current
Definition: spi.c:50
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:295
void assign_record_type_typmod(TupleDesc tupDesc)
Definition: typcache.c:1946
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
int32 tdtypmod
Definition: tupdesc.h:83
MemoryContext savedcxt
Definition: spi_priv.h:35
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:984
Oid tdtypeid
Definition: tupdesc.h:82

◆ SPI_rollback()

void SPI_rollback ( void  )

Definition at line 342 of file spi.c.

References _SPI_rollback().

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

343 {
344  _SPI_rollback(false);
345 }
static void _SPI_rollback(bool chain)
Definition: spi.c:299

◆ SPI_rollback_and_chain()

void SPI_rollback_and_chain ( void  )

Definition at line 348 of file spi.c.

References _SPI_rollback().

Referenced by exec_stmt_rollback().

349 {
350  _SPI_rollback(true);
351 }
static void _SPI_rollback(bool chain)
Definition: spi.c:299

◆ SPI_saveplan()

SPIPlanPtr SPI_saveplan ( SPIPlanPtr  plan)

Definition at line 899 of file spi.c.

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

900 {
901  SPIPlanPtr newplan;
902 
903  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
904  {
906  return NULL;
907  }
908 
909  SPI_result = _SPI_begin_call(false); /* don't change context */
910  if (SPI_result < 0)
911  return NULL;
912 
913  newplan = _SPI_save_plan(plan);
914 
915  SPI_result = _SPI_end_call(false);
916 
917  return newplan;
918 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:92
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
int SPI_result
Definition: spi.c:47
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan)
Definition: spi.c:3006
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898

◆ SPI_scroll_cursor_fetch()

void SPI_scroll_cursor_fetch ( Portal  ,
FetchDirection  direction,
long  count 
)

Definition at line 1725 of file spi.c.

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

Referenced by exec_stmt_fetch().

1726 {
1727  _SPI_cursor_operation(portal,
1728  direction, count,
1730  /* we know that the DestSPI receiver doesn't need a destroy call */
1731 }
Definition: dest.h:94
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:113
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2804

◆ SPI_scroll_cursor_move()

void SPI_scroll_cursor_move ( Portal  ,
FetchDirection  direction,
long  count 
)

Definition at line 1740 of file spi.c.

References _SPI_cursor_operation(), and None_Receiver.

Referenced by exec_stmt_fetch().

1741 {
1742  _SPI_cursor_operation(portal, direction, count, None_Receiver);
1743 }
DestReceiver * None_Receiver
Definition: dest.c:96
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2804

◆ SPI_start_transaction()

void SPI_start_transaction ( void  )

Definition at line 221 of file spi.c.

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

222 {
223  MemoryContext oldcontext = CurrentMemoryContext;
224 
226  MemoryContextSwitchTo(oldcontext);
227 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
void StartTransactionCommand(void)
Definition: xact.c:2838

◆ SPI_unregister_relation()

int SPI_unregister_relation ( const char *  name)

Definition at line 3128 of file spi.c.

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

3129 {
3130  EphemeralNamedRelation match;
3131  int res;
3132 
3133  if (name == NULL)
3134  return SPI_ERROR_ARGUMENT;
3135 
3136  res = _SPI_begin_call(false); /* keep current memory context */
3137  if (res < 0)
3138  return res;
3139 
3140  match = _SPI_find_ENR_by_name(name);
3141  if (match)
3142  {
3144  res = SPI_OK_REL_UNREGISTER;
3145  }
3146  else
3148 
3149  _SPI_end_call(false);
3150 
3151  return res;
3152 }
EphemeralNamedRelationMetadataData md
#define SPI_ERROR_REL_NOT_FOUND
Definition: spi.h:79
static EphemeralNamedRelation _SPI_find_ENR_by_name(const char *name)
Definition: spi.c:3077
static _SPI_connection * _SPI_current
Definition: spi.c:50
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:2874
#define SPI_ERROR_ARGUMENT
Definition: spi.h:72
QueryEnvironment * queryEnv
Definition: spi_priv.h:37
void unregister_ENR(QueryEnvironment *queryEnv, const char *name)
static int _SPI_end_call(bool use_exec)
Definition: spi.c:2898
const char * name
Definition: encode.c:515
#define SPI_OK_REL_UNREGISTER
Definition: spi.h:96

◆ SPICleanup()

void SPICleanup ( void  )

Definition at line 358 of file spi.c.

References _SPI_connected, SPI_processed, and SPI_result.

Referenced by AtEOXact_SPI(), and PostgresMain().

359 {
360  _SPI_current = NULL;
361  _SPI_connected = -1;
362  /* Reset API global variables, too */
363  SPI_processed = 0;
364  SPI_tuptable = NULL;
365  SPI_result = 0;
366 }
SPITupleTable * SPI_tuptable
Definition: spi.c:46
static int _SPI_connected
Definition: spi.c:52
static _SPI_connection * _SPI_current
Definition: spi.c:50
uint64 SPI_processed
Definition: spi.c:45
int SPI_result
Definition: spi.c:47

Variable Documentation

◆ SPI_processed

◆ SPI_result

◆ SPI_tuptable