PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
spi.h File Reference
#include "lib/ilist.h"
#include "nodes/parsenodes.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
 

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_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_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 _SPI_planSPIPlanPtr
 

Functions

int SPI_connect (void)
 
int SPI_finish (void)
 
int SPI_execute (const char *src, bool read_only, long tcount)
 
int SPI_execute_plan (SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
 
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_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_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)
 
void AtEOXact_SPI (bool isCommit)
 
void AtEOSubXact_SPI (bool isCommit, SubTransactionId mySubid)
 

Variables

PGDLLIMPORT uint64 SPI_processed
 
PGDLLIMPORT Oid SPI_lastoid
 
PGDLLIMPORT SPITupleTableSPI_tuptable
 
PGDLLIMPORT int SPI_result
 

Macro Definition Documentation

#define SPI_ERROR_CONNECT   (-1)

Definition at line 35 of file spi.h.

Referenced by SPI_result_code_string().

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

Definition at line 39 of file spi.h.

#define SPI_ERROR_NOOUTFUNC   (-10)

Definition at line 44 of file spi.h.

Referenced by SPI_result_code_string().

#define SPI_ERROR_OPUNKNOWN   (-3)

Definition at line 37 of file spi.h.

Referenced by _SPI_pquery(), and SPI_result_code_string().

#define SPI_ERROR_PARAM   (-7)
#define SPI_ERROR_TRANSACTION   (-8)
#define SPI_ERROR_TYPUNKNOWN   (-11)

Definition at line 45 of file spi.h.

Referenced by SPI_gettype(), and SPI_result_code_string().

#define SPI_ERROR_UNCONNECTED   (-4)
#define SPI_OK_CURSOR   10

Definition at line 56 of file spi.h.

Referenced by exec_run_select(), and SPI_result_code_string().

#define SPI_OK_DELETE_RETURNING   12
#define SPI_OK_FETCH   3

Definition at line 49 of file spi.h.

Referenced by PLy_cursor_fetch(), and SPI_result_code_string().

#define SPI_OK_INSERT   7
#define SPI_OK_INSERT_RETURNING   11
#define SPI_OK_REWRITTEN   14
#define SPI_OK_SELINTO   6
#define SPI_OK_UPDATE_RETURNING   13
#define SPI_pop ( )    ((void) 0)

Definition at line 64 of file spi.h.

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

Definition at line 66 of file spi.h.

#define SPI_push ( )    ((void) 0)

Definition at line 63 of file spi.h.

#define SPI_push_conditional ( )    false

Definition at line 65 of file spi.h.

#define SPI_restore_connection ( )    ((void) 0)

Definition at line 67 of file spi.h.

Typedef Documentation

Definition at line 33 of file spi.h.

Function Documentation

void AtEOSubXact_SPI ( bool  isCommit,
SubTransactionId  mySubid 
)

Definition at line 214 of file spi.c.

References _SPI_connected, Assert, _SPI_connection::connectSubid, slist_mutable_iter::cur, ereport, errcode(), errhint(), errmsg(), _SPI_connection::execCxt, InvalidOid, MemoryContextDelete(), MemoryContextResetAndDeleteChildren, next, NULL, _SPI_connection::procCxt, slist_container, slist_delete_current(), slist_foreach_modify, SPI_lastoid, SPI_processed, SPITupleTable::subid, SPITupleTable::tuptabcxt, _SPI_connection::tuptable, _SPI_connection::tuptables, and WARNING.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

215 {
216  bool found = false;
217 
218  while (_SPI_connected >= 0)
219  {
221 
222  if (connection->connectSubid != mySubid)
223  break; /* couldn't be any underneath it either */
224 
225  found = true;
226 
227  /*
228  * Release procedure memory explicitly (see note in SPI_connect)
229  */
230  if (connection->execCxt)
231  {
232  MemoryContextDelete(connection->execCxt);
233  connection->execCxt = NULL;
234  }
235  if (connection->procCxt)
236  {
237  MemoryContextDelete(connection->procCxt);
238  connection->procCxt = NULL;
239  }
240 
241  /*
242  * Pop the stack entry and reset global variables. Unlike
243  * SPI_finish(), we don't risk switching to memory contexts that might
244  * be already gone.
245  */
246  _SPI_connected--;
247  if (_SPI_connected < 0)
248  _SPI_current = NULL;
249  else
251  SPI_processed = 0;
253  SPI_tuptable = NULL;
254  }
255 
256  if (found && isCommit)
258  (errcode(ERRCODE_WARNING),
259  errmsg("subtransaction left non-empty SPI stack"),
260  errhint("Check for missing \"SPI_finish\" calls.")));
261 
262  /*
263  * If we are aborting a subtransaction and there is an open SPI context
264  * surrounding the subxact, clean up to prevent memory leakage.
265  */
266  if (_SPI_current && !isCommit)
267  {
268  slist_mutable_iter siter;
269 
270  /* free Executor memory the same as _SPI_end_call would do */
272 
273  /* throw away any tuple tables created within current subxact */
275  {
276  SPITupleTable *tuptable;
277 
278  tuptable = slist_container(SPITupleTable, next, siter.cur);
279  if (tuptable->subid >= mySubid)
280  {
281  /*
282  * If we used SPI_freetuptable() here, its internal search of
283  * the tuptables list would make this operation O(N^2).
284  * Instead, just free the tuptable manually. This should
285  * match what SPI_freetuptable() does.
286  */
287  slist_delete_current(&siter);
288  if (tuptable == _SPI_current->tuptable)
290  if (tuptable == SPI_tuptable)
291  SPI_tuptable = NULL;
292  MemoryContextDelete(tuptable->tuptabcxt);
293  }
294  }
295  /* in particular we should have gotten rid of any in-progress table */
297  }
298 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
int errhint(const char *fmt,...)
Definition: elog.c:987
static int32 next
Definition: blutils.c:210
slist_node * cur
Definition: ilist.h:241
SPITupleTable * SPI_tuptable
Definition: spi.c:41
int errcode(int sqlerrcode)
Definition: elog.c:575
static int _SPI_connected
Definition: spi.c:47
static _SPI_connection * _SPI_current
Definition: spi.c:45
uint64 SPI_processed
Definition: spi.c:39
#define slist_foreach_modify(iter, lhead)
Definition: ilist.h:716
SubTransactionId connectSubid
Definition: spi_priv.h:33
SPITupleTable * tuptable
Definition: spi_priv.h:26
static _SPI_connection * _SPI_stack
Definition: spi.c:44
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:67
#define slist_container(type, membername, ptr)
Definition: ilist.h:674
MemoryContext procCxt
Definition: spi_priv.h:30
Oid SPI_lastoid
Definition: spi.c:40
MemoryContext execCxt
Definition: spi_priv.h:31
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void slist_delete_current(slist_mutable_iter *iter)
Definition: ilist.h:652
SubTransactionId subid
Definition: spi.h:29
slist_head tuptables
Definition: spi_priv.h:29
MemoryContext tuptabcxt
Definition: spi.h:23
void AtEOXact_SPI ( bool  isCommit)

Definition at line 186 of file spi.c.

References _SPI_connected, _SPI_stack_depth, ereport, errcode(), errhint(), errmsg(), InvalidOid, NULL, SPI_lastoid, SPI_processed, and WARNING.

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

187 {
188  /*
189  * Note that memory contexts belonging to SPI stack entries will be freed
190  * automatically, so we can ignore them here. We just need to restore our
191  * static variables to initial state.
192  */
193  if (isCommit && _SPI_connected != -1)
195  (errcode(ERRCODE_WARNING),
196  errmsg("transaction left non-empty SPI stack"),
197  errhint("Check for missing \"SPI_finish\" calls.")));
198 
200  _SPI_stack_depth = 0;
201  _SPI_connected = -1;
202  SPI_processed = 0;
204  SPI_tuptable = NULL;
205 }
int errhint(const char *fmt,...)
Definition: elog.c:987
static int _SPI_stack_depth
Definition: spi.c:46
SPITupleTable * SPI_tuptable
Definition: spi.c:41
int errcode(int sqlerrcode)
Definition: elog.c:575
static int _SPI_connected
Definition: spi.c:47
static _SPI_connection * _SPI_current
Definition: spi.c:45
uint64 SPI_processed
Definition: spi.c:39
static _SPI_connection * _SPI_stack
Definition: spi.c:44
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
Oid SPI_lastoid
Definition: spi.c:40
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
int SPI_connect ( void  )

Definition at line 84 of file spi.c.

References _SPI_connected, _SPI_stack_depth, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), Assert, _SPI_connection::connectSubid, elog, ERROR, _SPI_connection::execCxt, GetCurrentSubTransactionId(), InvalidOid, _SPI_connection::lastoid, MemoryContextAlloc(), MemoryContextSwitchTo(), NULL, _SPI_connection::procCxt, _SPI_connection::processed, repalloc(), _SPI_connection::savedcxt, slist_init(), SPI_OK_CONNECT, TopTransactionContext, _SPI_connection::tuptable, and _SPI_connection::tuptables.

Referenced by check_foreign_key(), check_primary_key(), connectby(), crosstab(), cursor_to_xml(), cursor_to_xmlschema(), database_to_xml_internal(), database_to_xmlschema_internal(), funny_dup17(), 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(), plpython_call_handler(), plpython_inline_handler(), pltcl_event_trigger_handler(), pltcl_func_handler(), pltcl_trigger_handler(), 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_FKey_setdefault_del(), RI_FKey_setdefault_upd(), RI_FKey_setnull_del(), RI_FKey_setnull_upd(), RI_Initial_Check(), ri_restrict_del(), ri_restrict_upd(), schema_to_xml_internal(), schema_to_xmlschema_internal(), timetravel(), ts_stat1(), ts_stat2(), tsquery_rewrite_query(), ttdummy(), and xpath_table().

85 {
86  int newdepth;
87 
88  /* Enlarge stack if necessary */
89  if (_SPI_stack == NULL)
90  {
91  if (_SPI_connected != -1 || _SPI_stack_depth != 0)
92  elog(ERROR, "SPI stack corrupted");
93  newdepth = 16;
96  newdepth * sizeof(_SPI_connection));
97  _SPI_stack_depth = newdepth;
98  }
99  else
100  {
102  elog(ERROR, "SPI stack corrupted");
103  if (_SPI_stack_depth == _SPI_connected + 1)
104  {
105  newdepth = _SPI_stack_depth * 2;
108  newdepth * sizeof(_SPI_connection));
109  _SPI_stack_depth = newdepth;
110  }
111  }
112 
113  /* Enter new stack level */
114  _SPI_connected++;
116 
118  _SPI_current->processed = 0;
122  _SPI_current->procCxt = NULL; /* in case we fail to create 'em */
125 
126  /*
127  * Create memory contexts for this procedure
128  *
129  * XXX it would be better to use PortalContext as the parent context, but
130  * we may not be inside a portal (consider deferred-trigger execution).
131  * Perhaps CurTransactionContext would do? For now it doesn't matter
132  * because we clean up explicitly in AtEOSubXact_SPI().
133  */
135  "SPI Proc",
138  "SPI Exec",
140  /* ... and switch to procedure's context */
142 
143  return SPI_OK_CONNECT;
144 }
#define SPI_OK_CONNECT
Definition: spi.h:47
MemoryContext TopTransactionContext
Definition: mcxt.c:48
static int _SPI_stack_depth
Definition: spi.c:46
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static int _SPI_connected
Definition: spi.c:47
static _SPI_connection * _SPI_current
Definition: spi.c:45
SubTransactionId connectSubid
Definition: spi_priv.h:33
static void slist_init(slist_head *head)
Definition: ilist.h:554
#define ERROR
Definition: elog.h:43
SPITupleTable * tuptable
Definition: spi_priv.h:26
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
static _SPI_connection * _SPI_stack
Definition: spi.c:44
MemoryContext savedcxt
Definition: spi_priv.h:32
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
MemoryContext procCxt
Definition: spi_priv.h:30
MemoryContext execCxt
Definition: spi_priv.h:31
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
uint64 processed
Definition: spi_priv.h:24
#define Assert(condition)
Definition: c.h:675
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:649
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
#define elog
Definition: elog.h:219
slist_head tuptables
Definition: spi_priv.h:29
HeapTuple SPI_copytuple ( HeapTuple  tuple)

Definition at line 630 of file spi.c.

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

Referenced by get_tuple_of_interest(), and plpgsql_exec_trigger().

631 {
632  MemoryContext oldcxt;
633  HeapTuple ctuple;
634 
635  if (tuple == NULL)
636  {
638  return NULL;
639  }
640 
641  if (_SPI_current == NULL)
642  {
644  return NULL;
645  }
646 
648 
649  ctuple = heap_copytuple(tuple);
650 
651  MemoryContextSwitchTo(oldcxt);
652 
653  return ctuple;
654 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:38
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static _SPI_connection * _SPI_current
Definition: spi.c:45
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
MemoryContext savedcxt
Definition: spi_priv.h:32
#define NULL
Definition: c.h:229
void SPI_cursor_close ( Portal  portal)

Definition at line 1399 of file spi.c.

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

Referenced by exec_stmt_close(), exec_stmt_dynfors(), exec_stmt_forc(), exec_stmt_fors(), exec_stmt_return_query(), 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().

1400 {
1401  if (!PortalIsValid(portal))
1402  elog(ERROR, "invalid portal in SPI cursor operation");
1403 
1404  PortalDrop(portal, false);
1405 }
#define ERROR
Definition: elog.h:43
#define PortalIsValid(p)
Definition: portal.h:198
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:461
#define elog
Definition: elog.h:219
void SPI_cursor_fetch ( Portal  portal,
bool  forward,
long  count 
)

Definition at line 1343 of file spi.c.

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

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

1344 {
1345  _SPI_cursor_operation(portal,
1346  forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1348  /* we know that the DestSPI receiver doesn't need a destroy call */
1349 }
Definition: dest.h:93
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:109
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2364
Portal SPI_cursor_find ( const char *  name)

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

1332 {
1333  return GetPortalByName(name);
1334 }
Portal GetPortalByName(const char *name)
Definition: portalmem.c:129
const char * name
Definition: encode.c:521
void SPI_cursor_move ( Portal  portal,
bool  forward,
long  count 
)

Definition at line 1358 of file spi.c.

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

1359 {
1360  _SPI_cursor_operation(portal,
1361  forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1362  None_Receiver);
1363 }
DestReceiver * None_Receiver
Definition: dest.c:91
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2364
Portal SPI_cursor_open ( const char *  name,
SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
bool  read_only 
)

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

1031 {
1032  Portal portal;
1033  ParamListInfo paramLI;
1034 
1035  /* build transient ParamListInfo in caller's context */
1036  paramLI = _SPI_convert_params(plan->nargs, plan->argtypes,
1037  Values, Nulls);
1038 
1039  portal = SPI_cursor_open_internal(name, plan, paramLI, read_only);
1040 
1041  /* done with the transient ParamListInfo */
1042  if (paramLI)
1043  pfree(paramLI);
1044 
1045  return portal;
1046 }
Oid * argtypes
Definition: spi_priv.h:84
void pfree(void *pointer)
Definition: mcxt.c:950
int nargs
Definition: spi_priv.h:83
const char * name
Definition: encode.c:521
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1120
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2221
static bool Nulls[MAXATTR]
Definition: bootstrap.c:163
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 1055 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, NULL, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, result, SPI_cursor_open_internal(), and SPI_result.

Referenced by exec_dynquery_with_params().

1060 {
1061  Portal result;
1062  _SPI_plan plan;
1063  ParamListInfo paramLI;
1064 
1065  if (src == NULL || nargs < 0)
1066  elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
1067 
1068  if (nargs > 0 && (argtypes == NULL || Values == NULL))
1069  elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
1070 
1071  SPI_result = _SPI_begin_call(true);
1072  if (SPI_result < 0)
1073  elog(ERROR, "SPI_cursor_open_with_args called while not connected");
1074 
1075  memset(&plan, 0, sizeof(_SPI_plan));
1076  plan.magic = _SPI_PLAN_MAGIC;
1077  plan.cursor_options = cursorOptions;
1078  plan.nargs = nargs;
1079  plan.argtypes = argtypes;
1080  plan.parserSetup = NULL;
1081  plan.parserSetupArg = NULL;
1082 
1083  /* build transient ParamListInfo in executor context */
1084  paramLI = _SPI_convert_params(nargs, argtypes,
1085  Values, Nulls);
1086 
1087  _SPI_prepare_plan(src, &plan);
1088 
1089  /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1090 
1091  result = SPI_cursor_open_internal(name, &plan, paramLI, read_only);
1092 
1093  /* And clean up */
1094  _SPI_end_call(true);
1095 
1096  return result;
1097 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1732
Oid * argtypes
Definition: spi_priv.h:84
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
return result
Definition: formatting.c:1618
int SPI_result
Definition: spi.c:42
#define ERROR
Definition: elog.h:43
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
int nargs
Definition: spi_priv.h:83
#define NULL
Definition: c.h:229
ParserSetupHook parserSetup
Definition: spi_priv.h:85
void * parserSetupArg
Definition: spi_priv.h:86
const char * name
Definition: encode.c:521
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1120
int cursor_options
Definition: spi_priv.h:82
#define elog
Definition: elog.h:219
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2221
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
static bool Nulls[MAXATTR]
Definition: bootstrap.c:163
Portal SPI_cursor_open_with_paramlist ( const char *  name,
SPIPlanPtr  plan,
ParamListInfo  params,
bool  read_only 
)

Definition at line 1107 of file spi.c.

References SPI_cursor_open_internal().

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

1109 {
1110  return SPI_cursor_open_internal(name, plan, params, read_only);
1111 }
const char * name
Definition: encode.c:521
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1120
Datum SPI_datumTransfer ( Datum  value,
bool  typByVal,
int  typLen 
)

Definition at line 944 of file spi.c.

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

Referenced by plpgsql_exec_function().

945 {
946  MemoryContext oldcxt;
947  Datum result;
948 
949  if (_SPI_current == NULL)
950  elog(ERROR, "SPI_datumTransfer called while not connected to SPI");
951 
953 
954  result = datumTransfer(value, typByVal, typLen);
955 
956  MemoryContextSwitchTo(oldcxt);
957 
958  return result;
959 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
return result
Definition: formatting.c:1618
static _SPI_connection * _SPI_current
Definition: spi.c:45
static struct @114 value
#define ERROR
Definition: elog.h:43
MemoryContext savedcxt
Definition: spi_priv.h:32
uintptr_t Datum
Definition: postgres.h:372
Datum datumTransfer(Datum value, bool typByVal, int typLen)
Definition: datum.c:190
#define NULL
Definition: c.h:229
#define elog
Definition: elog.h:219
int SPI_exec ( const char *  src,
long  tcount 
)

Definition at line 331 of file spi.c.

References SPI_execute().

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

332 {
333  return SPI_execute(src, false, tcount);
334 }
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:303
int SPI_execp ( SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
long  tcount 
)

Definition at line 365 of file spi.c.

References SPI_execute_plan().

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

366 {
367  return SPI_execute_plan(plan, Values, Nulls, false, tcount);
368 }
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
Definition: spi.c:338
static bool Nulls[MAXATTR]
Definition: bootstrap.c:163
int SPI_execute ( const char *  src,
bool  read_only,
long  tcount 
)

Definition at line 303 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, NULL, and SPI_ERROR_ARGUMENT.

Referenced by build_tuplestore_recursively(), crosstab(), exec_stmt_dynexecute(), 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().

304 {
305  _SPI_plan plan;
306  int res;
307 
308  if (src == NULL || tcount < 0)
309  return SPI_ERROR_ARGUMENT;
310 
311  res = _SPI_begin_call(true);
312  if (res < 0)
313  return res;
314 
315  memset(&plan, 0, sizeof(_SPI_plan));
316  plan.magic = _SPI_PLAN_MAGIC;
318 
319  _SPI_prepare_oneshot_plan(src, &plan);
320 
321  res = _SPI_execute_plan(&plan, NULL,
323  read_only, true, tcount);
324 
325  _SPI_end_call(true);
326  return res;
327 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1835
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, uint64 tcount)
Definition: spi.c:1893
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
#define InvalidSnapshot
Definition: snapshot.h:25
#define NULL
Definition: c.h:229
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2579
int cursor_options
Definition: spi_priv.h:82
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
int SPI_execute_plan ( SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
bool  read_only,
long  tcount 
)

Definition at line 338 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, NULL, 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(), and SPI_execp().

340 {
341  int res;
342 
343  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
344  return SPI_ERROR_ARGUMENT;
345 
346  if (plan->nargs > 0 && Values == NULL)
347  return SPI_ERROR_PARAM;
348 
349  res = _SPI_begin_call(true);
350  if (res < 0)
351  return res;
352 
353  res = _SPI_execute_plan(plan,
354  _SPI_convert_params(plan->nargs, plan->argtypes,
355  Values, Nulls),
357  read_only, true, tcount);
358 
359  _SPI_end_call(true);
360  return res;
361 }
Oid * argtypes
Definition: spi_priv.h:84
#define SPI_ERROR_PARAM
Definition: spi.h:41
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, uint64 tcount)
Definition: spi.c:1893
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
#define InvalidSnapshot
Definition: snapshot.h:25
int nargs
Definition: spi_priv.h:83
#define NULL
Definition: c.h:229
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2221
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
static bool Nulls[MAXATTR]
Definition: bootstrap.c:163
int SPI_execute_plan_with_paramlist ( SPIPlanPtr  plan,
ParamListInfo  params,
bool  read_only,
long  tcount 
)

Definition at line 372 of file spi.c.

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

Referenced by exec_run_select(), and exec_stmt_execsql().

374 {
375  int res;
376 
377  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
378  return SPI_ERROR_ARGUMENT;
379 
380  res = _SPI_begin_call(true);
381  if (res < 0)
382  return res;
383 
384  res = _SPI_execute_plan(plan, params,
386  read_only, true, tcount);
387 
388  _SPI_end_call(true);
389  return res;
390 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, uint64 tcount)
Definition: spi.c:1893
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
#define InvalidSnapshot
Definition: snapshot.h:25
#define NULL
Definition: c.h:229
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
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 406 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, NULL, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

Referenced by RI_Initial_Check(), and ri_PerformCheck().

410 {
411  int res;
412 
413  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
414  return SPI_ERROR_ARGUMENT;
415 
416  if (plan->nargs > 0 && Values == NULL)
417  return SPI_ERROR_PARAM;
418 
419  res = _SPI_begin_call(true);
420  if (res < 0)
421  return res;
422 
423  res = _SPI_execute_plan(plan,
424  _SPI_convert_params(plan->nargs, plan->argtypes,
425  Values, Nulls),
426  snapshot, crosscheck_snapshot,
427  read_only, fire_triggers, tcount);
428 
429  _SPI_end_call(true);
430  return res;
431 }
Oid * argtypes
Definition: spi_priv.h:84
#define SPI_ERROR_PARAM
Definition: spi.h:41
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, uint64 tcount)
Definition: spi.c:1893
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
int nargs
Definition: spi_priv.h:83
#define NULL
Definition: c.h:229
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2221
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
static bool Nulls[MAXATTR]
Definition: bootstrap.c:163
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 440 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, NULL, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

Referenced by exec_stmt_dynexecute().

444 {
445  int res;
446  _SPI_plan plan;
447  ParamListInfo paramLI;
448 
449  if (src == NULL || nargs < 0 || tcount < 0)
450  return SPI_ERROR_ARGUMENT;
451 
452  if (nargs > 0 && (argtypes == NULL || Values == NULL))
453  return SPI_ERROR_PARAM;
454 
455  res = _SPI_begin_call(true);
456  if (res < 0)
457  return res;
458 
459  memset(&plan, 0, sizeof(_SPI_plan));
460  plan.magic = _SPI_PLAN_MAGIC;
462  plan.nargs = nargs;
463  plan.argtypes = argtypes;
464  plan.parserSetup = NULL;
465  plan.parserSetupArg = NULL;
466 
467  paramLI = _SPI_convert_params(nargs, argtypes,
468  Values, Nulls);
469 
470  _SPI_prepare_oneshot_plan(src, &plan);
471 
472  res = _SPI_execute_plan(&plan, paramLI,
474  read_only, true, tcount);
475 
476  _SPI_end_call(true);
477  return res;
478 }
Oid * argtypes
Definition: spi_priv.h:84
#define SPI_ERROR_PARAM
Definition: spi.h:41
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1835
static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, uint64 tcount)
Definition: spi.c:1893
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
#define InvalidSnapshot
Definition: snapshot.h:25
int nargs
Definition: spi_priv.h:83
#define NULL
Definition: c.h:229
ParserSetupHook parserSetup
Definition: spi_priv.h:85
void * parserSetupArg
Definition: spi_priv.h:86
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2579
int cursor_options
Definition: spi_priv.h:82
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2221
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
static bool Nulls[MAXATTR]
Definition: bootstrap.c:163
int SPI_finish ( void  )

Definition at line 147 of file spi.c.

References _SPI_begin_call(), _SPI_connected, _SPI_connection::execCxt, InvalidOid, MemoryContextDelete(), MemoryContextSwitchTo(), NULL, _SPI_connection::procCxt, _SPI_connection::savedcxt, SPI_lastoid, SPI_OK_FINISH, and SPI_processed.

Referenced by check_foreign_key(), check_primary_key(), connectby(), crosstab(), cursor_to_xml(), cursor_to_xmlschema(), database_to_xml_internal(), database_to_xmlschema_internal(), funny_dup17(), 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_FKey_setdefault_del(), RI_FKey_setdefault_upd(), RI_FKey_setnull_del(), RI_FKey_setnull_upd(), RI_Initial_Check(), ri_restrict_del(), ri_restrict_upd(), schema_to_xml_internal(), schema_to_xmlschema_internal(), timetravel(), ts_stat1(), ts_stat2(), tsquery_rewrite_query(), ttdummy(), and xpath_table().

148 {
149  int res;
150 
151  res = _SPI_begin_call(false); /* live in procedure memory */
152  if (res < 0)
153  return res;
154 
155  /* Restore memory context as it was before procedure call */
157 
158  /* Release memory used in procedure call (including tuptables) */
163 
164  /*
165  * Reset result variables, especially SPI_tuptable which is probably
166  * pointing at a just-deleted tuptable
167  */
168  SPI_processed = 0;
170  SPI_tuptable = NULL;
171 
172  /* Exit stack level */
173  _SPI_connected--;
174  if (_SPI_connected < 0)
175  _SPI_current = NULL;
176  else
178 
179  return SPI_OK_FINISH;
180 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:41
static int _SPI_connected
Definition: spi.c:47
static _SPI_connection * _SPI_current
Definition: spi.c:45
uint64 SPI_processed
Definition: spi.c:39
static _SPI_connection * _SPI_stack
Definition: spi.c:44
MemoryContext savedcxt
Definition: spi_priv.h:32
MemoryContext procCxt
Definition: spi_priv.h:30
Oid SPI_lastoid
Definition: spi.c:40
MemoryContext execCxt
Definition: spi_priv.h:31
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define SPI_OK_FINISH
Definition: spi.h:48
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
char* SPI_fname ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 781 of file spi.c.

References tupleDesc::attrs, FirstLowInvalidHeapAttributeNumber, NameStr, tupleDesc::natts, NULL, pstrdup(), SPI_ERROR_NOATTRIBUTE, SPI_result, and SystemAttributeDefinition().

Referenced by funny_dup17(), get_pkey_attnames(), ri_ReportViolation(), and SPI_sql_row_to_xmlelement().

782 {
783  Form_pg_attribute att;
784 
785  SPI_result = 0;
786 
787  if (fnumber > tupdesc->natts || fnumber == 0 ||
789  {
791  return NULL;
792  }
793 
794  if (fnumber > 0)
795  att = tupdesc->attrs[fnumber - 1];
796  else
797  att = SystemAttributeDefinition(fnumber, true);
798 
799  return pstrdup(NameStr(att->attname));
800 }
char * pstrdup(const char *in)
Definition: mcxt.c:1077
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
int natts
Definition: tupdesc.h:73
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
Definition: heap.c:200
#define NULL
Definition: c.h:229
#define NameStr(name)
Definition: c.h:499
int SPI_fnumber ( TupleDesc  tupdesc,
const char *  fname 
)

Definition at line 760 of file spi.c.

References tupleDesc::attrs, namestrcmp(), tupleDesc::natts, NULL, SPI_ERROR_NOATTRIBUTE, and SystemAttributeByName().

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

761 {
762  int res;
763  Form_pg_attribute sysatt;
764 
765  for (res = 0; res < tupdesc->natts; res++)
766  {
767  if (namestrcmp(&tupdesc->attrs[res]->attname, fname) == 0 &&
768  !tupdesc->attrs[res]->attisdropped)
769  return res + 1;
770  }
771 
772  sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ );
773  if (sysatt != NULL)
774  return sysatt->attnum;
775 
776  /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
777  return SPI_ERROR_NOATTRIBUTE;
778 }
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Form_pg_attribute SystemAttributeByName(const char *attname, bool relhasoids)
Definition: heap.c:214
int namestrcmp(Name name, const char *str)
Definition: name.c:248
int natts
Definition: tupdesc.h:73
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define NULL
Definition: c.h:229
int SPI_freeplan ( SPIPlanPtr  plan)

Definition at line 608 of file spi.c.

References _SPI_PLAN_MAGIC, DropCachedPlan(), lfirst, _SPI_plan::magic, MemoryContextDelete(), NULL, _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().

609 {
610  ListCell *lc;
611 
612  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
613  return SPI_ERROR_ARGUMENT;
614 
615  /* Release the plancache entries */
616  foreach(lc, plan->plancache_list)
617  {
618  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
619 
620  DropCachedPlan(plansource);
621  }
622 
623  /* Now get rid of the _SPI_plan and subsidiary data in its plancxt */
625 
626  return 0;
627 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
List * plancache_list
Definition: spi_priv.h:80
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
MemoryContext plancxt
Definition: spi_priv.h:81
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:485
void SPI_freetuple ( HeapTuple  pointer)

Definition at line 962 of file spi.c.

References heap_freetuple().

963 {
964  /* No longer need to worry which context tuple was in... */
965  heap_freetuple(tuple);
966 }
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
void SPI_freetuptable ( SPITupleTable tuptable)

Definition at line 969 of file spi.c.

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

Referenced by _SPI_execute_plan(), exec_assign_value(), exec_eval_cleanup(), exec_for_query(), exec_stmt_dynexecute(), exec_stmt_execsql(), exec_stmt_fetch(), exec_stmt_return_query(), 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().

970 {
971  bool found = false;
972 
973  /* ignore call if NULL pointer */
974  if (tuptable == NULL)
975  return;
976 
977  /*
978  * Search only the topmost SPI context for a matching tuple table.
979  */
980  if (_SPI_current != NULL)
981  {
982  slist_mutable_iter siter;
983 
984  /* find tuptable in active list, then remove it */
986  {
987  SPITupleTable *tt;
988 
989  tt = slist_container(SPITupleTable, next, siter.cur);
990  if (tt == tuptable)
991  {
992  slist_delete_current(&siter);
993  found = true;
994  break;
995  }
996  }
997  }
998 
999  /*
1000  * Refuse the deletion if we didn't find it in the topmost SPI context.
1001  * This is primarily a guard against double deletion, but might prevent
1002  * other errors as well. Since the worst consequence of not deleting a
1003  * tuptable would be a transient memory leak, this is just a WARNING.
1004  */
1005  if (!found)
1006  {
1007  elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);
1008  return;
1009  }
1010 
1011  /* for safety, reset global variables that might point at tuptable */
1012  if (tuptable == _SPI_current->tuptable)
1014  if (tuptable == SPI_tuptable)
1015  SPI_tuptable = NULL;
1016 
1017  /* release all memory belonging to tuptable */
1018  MemoryContextDelete(tuptable->tuptabcxt);
1019 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
static int32 next
Definition: blutils.c:210
slist_node * cur
Definition: ilist.h:241
SPITupleTable * SPI_tuptable
Definition: spi.c:41
static _SPI_connection * _SPI_current
Definition: spi.c:45
#define slist_foreach_modify(iter, lhead)
Definition: ilist.h:716
SPITupleTable * tuptable
Definition: spi_priv.h:26
#define WARNING
Definition: elog.h:40
#define slist_container(type, membername, ptr)
Definition: ilist.h:674
#define NULL
Definition: c.h:229
static void slist_delete_current(slist_mutable_iter *iter)
Definition: ilist.h:652
#define elog
Definition: elog.h:219
slist_head tuptables
Definition: spi_priv.h:29
MemoryContext tuptabcxt
Definition: spi.h:23
int SPI_getargcount ( SPIPlanPtr  plan)

Definition at line 1427 of file spi.c.

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

1428 {
1429  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1430  {
1432  return -1;
1433  }
1434  return plan->nargs;
1435 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
int nargs
Definition: spi_priv.h:83
#define NULL
Definition: c.h:229
Oid SPI_getargtypeid ( SPIPlanPtr  plan,
int  argIndex 
)

Definition at line 1412 of file spi.c.

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

1413 {
1414  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
1415  argIndex < 0 || argIndex >= plan->nargs)
1416  {
1418  return InvalidOid;
1419  }
1420  return plan->argtypes[argIndex];
1421 }
Oid * argtypes
Definition: spi_priv.h:84
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
int nargs
Definition: spi_priv.h:83
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
Datum SPI_getbinval ( HeapTuple  tuple,
TupleDesc  tupdesc,
int  fnumber,
bool isnull 
)

Definition at line 835 of file spi.c.

References FirstLowInvalidHeapAttributeNumber, heap_getattr, tupleDesc::natts, NULL, SPI_ERROR_NOATTRIBUTE, and SPI_result.

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

836 {
837  SPI_result = 0;
838 
839  if (fnumber > tupdesc->natts || fnumber == 0 ||
841  {
843  *isnull = true;
844  return (Datum) NULL;
845  }
846 
847  return heap_getattr(tuple, fnumber, tupdesc, isnull);
848 }
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
int natts
Definition: tupdesc.h:73
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
uintptr_t Datum
Definition: postgres.h:372
#define NULL
Definition: c.h:229
char* SPI_getnspname ( Relation  rel)

Definition at line 915 of file spi.c.

References get_namespace_name(), and RelationGetNamespace.

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

916 {
918 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
#define RelationGetNamespace(relation)
Definition: rel.h:444
char* SPI_getrelname ( Relation  rel)

Definition at line 909 of file spi.c.

References pstrdup(), and RelationGetRelationName.

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

910 {
911  return pstrdup(RelationGetRelationName(rel));
912 }
char * pstrdup(const char *in)
Definition: mcxt.c:1077
#define RelationGetRelationName(relation)
Definition: rel.h:437
char* SPI_gettype ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 851 of file spi.c.

References tupleDesc::attrs, FirstLowInvalidHeapAttributeNumber, GETSTRUCT, HeapTupleIsValid, NameStr, tupleDesc::natts, NULL, ObjectIdGetDatum, pstrdup(), ReleaseSysCache(), result, SearchSysCache1, SPI_ERROR_NOATTRIBUTE, SPI_ERROR_TYPUNKNOWN, SPI_result, SystemAttributeDefinition(), and TYPEOID.

Referenced by check_foreign_key(), and funny_dup17().

852 {
853  Oid typoid;
854  HeapTuple typeTuple;
855  char *result;
856 
857  SPI_result = 0;
858 
859  if (fnumber > tupdesc->natts || fnumber == 0 ||
861  {
863  return NULL;
864  }
865 
866  if (fnumber > 0)
867  typoid = tupdesc->attrs[fnumber - 1]->atttypid;
868  else
869  typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
870 
871  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
872 
873  if (!HeapTupleIsValid(typeTuple))
874  {
876  return NULL;
877  }
878 
879  result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
880  ReleaseSysCache(typeTuple);
881  return result;
882 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * pstrdup(const char *in)
Definition: mcxt.c:1077
Form_pg_attribute * attrs
Definition: tupdesc.h:74
return result
Definition: formatting.c:1618
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
int SPI_result
Definition: spi.c:42
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
Definition: heap.c:200
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define SPI_ERROR_TYPUNKNOWN
Definition: spi.h:45
#define NameStr(name)
Definition: c.h:499
Oid SPI_gettypeid ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 891 of file spi.c.

References tupleDesc::attrs, FirstLowInvalidHeapAttributeNumber, InvalidOid, tupleDesc::natts, SPI_ERROR_NOATTRIBUTE, SPI_result, and SystemAttributeDefinition().

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

892 {
893  SPI_result = 0;
894 
895  if (fnumber > tupdesc->natts || fnumber == 0 ||
897  {
899  return InvalidOid;
900  }
901 
902  if (fnumber > 0)
903  return tupdesc->attrs[fnumber - 1]->atttypid;
904  else
905  return (SystemAttributeDefinition(fnumber, true))->atttypid;
906 }
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
int natts
Definition: tupdesc.h:73
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
Definition: heap.c:200
#define InvalidOid
Definition: postgres_ext.h:36
char* SPI_getvalue ( HeapTuple  tuple,
TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 803 of file spi.c.

References tupleDesc::attrs, FirstLowInvalidHeapAttributeNumber, getTypeOutputInfo(), heap_getattr, tupleDesc::natts, NULL, OidOutputFunctionCall(), SPI_ERROR_NOATTRIBUTE, SPI_result, SystemAttributeDefinition(), and val.

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

804 {
805  Datum val;
806  bool isnull;
807  Oid typoid,
808  foutoid;
809  bool typisvarlena;
810 
811  SPI_result = 0;
812 
813  if (fnumber > tupdesc->natts || fnumber == 0 ||
815  {
817  return NULL;
818  }
819 
820  val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
821  if (isnull)
822  return NULL;
823 
824  if (fnumber > 0)
825  typoid = tupdesc->attrs[fnumber - 1]->atttypid;
826  else
827  typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
828 
829  getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
830 
831  return OidOutputFunctionCall(foutoid, val);
832 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2600
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
uintptr_t Datum
Definition: postgres.h:372
Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
Definition: heap.c:200
#define NULL
Definition: c.h:229
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:2056
long val
Definition: informix.c:689
bool SPI_is_cursor_plan ( SPIPlanPtr  plan)

Definition at line 1447 of file spi.c.

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

Referenced by SPI_cursor_open_internal().

1448 {
1449  CachedPlanSource *plansource;
1450 
1451  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1452  {
1454  return false;
1455  }
1456 
1457  if (list_length(plan->plancache_list) != 1)
1458  {
1459  SPI_result = 0;
1460  return false; /* not exactly 1 pre-rewrite command */
1461  }
1462  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1463 
1464  /*
1465  * We used to force revalidation of the cached plan here, but that seems
1466  * unnecessary: invalidation could mean a change in the rowtype of the
1467  * tuples returned by a plan, but not whether it returns tuples at all.
1468  */
1469  SPI_result = 0;
1470 
1471  /* Does it return tuples? */
1472  if (plansource->resultDesc)
1473  return true;
1474 
1475  return false;
1476 }
List * plancache_list
Definition: spi_priv.h:80
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
TupleDesc resultDesc
Definition: plancache.h:91
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
#define linitial(l)
Definition: pg_list.h:110
#define NULL
Definition: c.h:229
static int list_length(const List *l)
Definition: pg_list.h:89
int SPI_keepplan ( SPIPlanPtr  plan)

Definition at line 559 of file spi.c.

References _SPI_PLAN_MAGIC, CacheMemoryContext, lfirst, _SPI_plan::magic, MemoryContextSetParent(), NULL, _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(), timetravel(), and ttdummy().

560 {
561  ListCell *lc;
562 
563  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
564  plan->saved || plan->oneshot)
565  return SPI_ERROR_ARGUMENT;
566 
567  /*
568  * Mark it saved, reparent it under CacheMemoryContext, and mark all the
569  * component CachedPlanSources as saved. This sequence cannot fail
570  * partway through, so there's no risk of long-term memory leakage.
571  */
572  plan->saved = true;
574 
575  foreach(lc, plan->plancache_list)
576  {
577  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
578 
579  SaveCachedPlan(plansource);
580  }
581 
582  return 0;
583 }
List * plancache_list
Definition: spi_priv.h:80
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:317
int magic
Definition: spi_priv.h:77
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
MemoryContext plancxt
Definition: spi_priv.h:81
bool saved
Definition: spi_priv.h:78
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:440
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
bool oneshot
Definition: spi_priv.h:79
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
HeapTuple SPI_modifytuple ( Relation  rel,
HeapTuple  tuple,
int  natts,
int *  attnum,
Datum Values,
const char *  Nulls 
)

Definition at line 689 of file spi.c.

References heap_deform_tuple(), heap_form_tuple(), HeapTupleGetOid, HeapTupleSetOid, i, MemoryContextSwitchTo(), tupleDesc::natts, NULL, 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, HeapTupleData::t_tableOid, and tupleDesc::tdhasoid.

Referenced by timetravel(), and ttdummy().

691 {
692  MemoryContext oldcxt;
693  HeapTuple mtuple;
694  int numberOfAttributes;
695  Datum *v;
696  bool *n;
697  int i;
698 
699  if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
700  {
702  return NULL;
703  }
704 
705  if (_SPI_current == NULL)
706  {
708  return NULL;
709  }
710 
712 
713  SPI_result = 0;
714 
715  numberOfAttributes = rel->rd_att->natts;
716  v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
717  n = (bool *) palloc(numberOfAttributes * sizeof(bool));
718 
719  /* fetch old values and nulls */
720  heap_deform_tuple(tuple, rel->rd_att, v, n);
721 
722  /* replace values and nulls */
723  for (i = 0; i < natts; i++)
724  {
725  if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
726  break;
727  v[attnum[i] - 1] = Values[i];
728  n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? true : false;
729  }
730 
731  if (i == natts) /* no errors in *attnum */
732  {
733  mtuple = heap_form_tuple(rel->rd_att, v, n);
734 
735  /*
736  * copy the identification info of the old tuple: t_ctid, t_self, and
737  * OID (if any)
738  */
739  mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
740  mtuple->t_self = tuple->t_self;
741  mtuple->t_tableOid = tuple->t_tableOid;
742  if (rel->rd_att->tdhasoid)
743  HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
744  }
745  else
746  {
747  mtuple = NULL;
749  }
750 
751  pfree(v);
752  pfree(n);
753 
754  MemoryContextSwitchTo(oldcxt);
755 
756  return mtuple;
757 }
bool tdhasoid
Definition: tupdesc.h:79
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:38
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static _SPI_connection * _SPI_current
Definition: spi.c:45
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
int natts
Definition: tupdesc.h:73
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleSetOid(tuple, oid)
Definition: htup_details.h:698
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
void pfree(void *pointer)
Definition: mcxt.c:950
ItemPointerData t_ctid
Definition: htup_details.h:150
ItemPointerData t_self
Definition: htup.h:65
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
Oid t_tableOid
Definition: htup.h:66
MemoryContext savedcxt
Definition: spi_priv.h:32
uintptr_t Datum
Definition: postgres.h:372
TupleDesc rd_att
Definition: rel.h:115
#define NULL
Definition: c.h:229
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:935
void * palloc(Size size)
Definition: mcxt.c:849
int i
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static bool Nulls[MAXATTR]
Definition: bootstrap.c:163
void* SPI_palloc ( Size  size)

Definition at line 921 of file spi.c.

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

Referenced by _SPI_strdup().

922 {
923  if (_SPI_current == NULL)
924  elog(ERROR, "SPI_palloc called while not connected to SPI");
925 
927 }
static _SPI_connection * _SPI_current
Definition: spi.c:45
#define ERROR
Definition: elog.h:43
MemoryContext savedcxt
Definition: spi_priv.h:32
#define NULL
Definition: c.h:229
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
#define elog
Definition: elog.h:219
void SPI_pfree ( void *  pointer)

Definition at line 937 of file spi.c.

References pfree().

938 {
939  /* No longer need to worry which context chunk was in... */
940  pfree(pointer);
941 }
void pfree(void *pointer)
Definition: mcxt.c:950
CachedPlan* SPI_plan_get_cached_plan ( SPIPlanPtr  plan)

Definition at line 1594 of file spi.c.

References _SPI_error_callback(), _SPI_PLAN_MAGIC, ErrorContextCallback::arg, Assert, ErrorContextCallback::callback, error_context_stack, GetCachedPlan(), CachedPlanSource::gplan, linitial, list_length(), _SPI_plan::magic, NULL, _SPI_plan::oneshot, _SPI_plan::plancache_list, ErrorContextCallback::previous, CachedPlanSource::query_string, and _SPI_plan::saved.

Referenced by exec_eval_simple_expr(), and exec_simple_check_plan().

1595 {
1596  CachedPlanSource *plansource;
1597  CachedPlan *cplan;
1598  ErrorContextCallback spierrcontext;
1599 
1600  Assert(plan->magic == _SPI_PLAN_MAGIC);
1601 
1602  /* Can't support one-shot plans here */
1603  if (plan->oneshot)
1604  return NULL;
1605 
1606  /* Must have exactly one CachedPlanSource */
1607  if (list_length(plan->plancache_list) != 1)
1608  return NULL;
1609  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1610 
1611  /* Setup error traceback support for ereport() */
1612  spierrcontext.callback = _SPI_error_callback;
1613  spierrcontext.arg = (void *) plansource->query_string;
1614  spierrcontext.previous = error_context_stack;
1615  error_context_stack = &spierrcontext;
1616 
1617  /* Get the generic plan for the query */
1618  cplan = GetCachedPlan(plansource, NULL, plan->saved);
1619  Assert(cplan == plansource->gplan);
1620 
1621  /* Pop the error context stack */
1622  error_context_stack = spierrcontext.previous;
1623 
1624  return cplan;
1625 }
List * plancache_list
Definition: spi_priv.h:80
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
struct ErrorContextCallback * previous
Definition: elog.h:238
struct CachedPlan * gplan
Definition: plancache.h:104
ErrorContextCallback * error_context_stack
Definition: elog.c:88
static void _SPI_error_callback(void *arg)
Definition: spi.c:2338
#define linitial(l)
Definition: pg_list.h:110
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, bool useResOwner)
Definition: plancache.c:1131
bool saved
Definition: spi_priv.h:78
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool oneshot
Definition: spi_priv.h:79
const char * query_string
Definition: plancache.h:83
static int list_length(const List *l)
Definition: pg_list.h:89
void(* callback)(void *arg)
Definition: elog.h:239
List* SPI_plan_get_plan_sources ( SPIPlanPtr  plan)

Definition at line 1578 of file spi.c.

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

Referenced by exec_simple_check_plan(), and exec_stmt_execsql().

1579 {
1580  Assert(plan->magic == _SPI_PLAN_MAGIC);
1581  return plan->plancache_list;
1582 }
List * plancache_list
Definition: spi_priv.h:80
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
#define Assert(condition)
Definition: c.h:675
bool SPI_plan_is_valid ( SPIPlanPtr  plan)

Definition at line 1485 of file spi.c.

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

Referenced by ri_FetchPreparedPlan().

1486 {
1487  ListCell *lc;
1488 
1489  Assert(plan->magic == _SPI_PLAN_MAGIC);
1490 
1491  foreach(lc, plan->plancache_list)
1492  {
1493  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1494 
1495  if (!CachedPlanIsValid(plansource))
1496  return false;
1497  }
1498  return true;
1499 }
List * plancache_list
Definition: spi_priv.h:80
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
bool CachedPlanIsValid(CachedPlanSource *plansource)
Definition: plancache.c:1408
SPIPlanPtr SPI_prepare ( const char *  src,
int  nargs,
Oid argtypes 
)
SPIPlanPtr SPI_prepare_cursor ( const char *  src,
int  nargs,
Oid argtypes,
int  cursorOptions 
)

Definition at line 487 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, NULL, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, result, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by SPI_prepare().

489 {
490  _SPI_plan plan;
492 
493  if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
494  {
496  return NULL;
497  }
498 
499  SPI_result = _SPI_begin_call(true);
500  if (SPI_result < 0)
501  return NULL;
502 
503  memset(&plan, 0, sizeof(_SPI_plan));
504  plan.magic = _SPI_PLAN_MAGIC;
505  plan.cursor_options = cursorOptions;
506  plan.nargs = nargs;
507  plan.argtypes = argtypes;
508  plan.parserSetup = NULL;
509  plan.parserSetupArg = NULL;
510 
511  _SPI_prepare_plan(src, &plan);
512 
513  /* copy plan to procedure context */
514  result = _SPI_make_plan_non_temp(&plan);
515 
516  _SPI_end_call(true);
517 
518  return result;
519 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1732
Oid * argtypes
Definition: spi_priv.h:84
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
return result
Definition: formatting.c:1618
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:2484
int nargs
Definition: spi_priv.h:83
#define NULL
Definition: c.h:229
ParserSetupHook parserSetup
Definition: spi_priv.h:85
void * parserSetupArg
Definition: spi_priv.h:86
int cursor_options
Definition: spi_priv.h:82
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
SPIPlanPtr SPI_prepare_params ( const char *  src,
ParserSetupHook  parserSetup,
void *  parserSetupArg,
int  cursorOptions 
)

Definition at line 522 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, NULL, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, result, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by exec_prepare_plan().

526 {
527  _SPI_plan plan;
529 
530  if (src == NULL)
531  {
533  return NULL;
534  }
535 
536  SPI_result = _SPI_begin_call(true);
537  if (SPI_result < 0)
538  return NULL;
539 
540  memset(&plan, 0, sizeof(_SPI_plan));
541  plan.magic = _SPI_PLAN_MAGIC;
542  plan.cursor_options = cursorOptions;
543  plan.nargs = 0;
544  plan.argtypes = NULL;
545  plan.parserSetup = parserSetup;
546  plan.parserSetupArg = parserSetupArg;
547 
548  _SPI_prepare_plan(src, &plan);
549 
550  /* copy plan to procedure context */
551  result = _SPI_make_plan_non_temp(&plan);
552 
553  _SPI_end_call(true);
554 
555  return result;
556 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1732
Oid * argtypes
Definition: spi_priv.h:84
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
return result
Definition: formatting.c:1618
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:2484
int nargs
Definition: spi_priv.h:83
#define NULL
Definition: c.h:229
ParserSetupHook parserSetup
Definition: spi_priv.h:85
void * parserSetupArg
Definition: spi_priv.h:86
int cursor_options
Definition: spi_priv.h:82
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
void* SPI_repalloc ( void *  pointer,
Size  size 
)

Definition at line 930 of file spi.c.

References repalloc().

931 {
932  /* No longer need to worry which context chunk was in... */
933  return repalloc(pointer, size);
934 }
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
const char* SPI_result_code_string ( int  code)

Definition at line 1509 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_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_REWRITTEN, SPI_OK_SELECT, SPI_OK_SELINTO, SPI_OK_UPDATE, SPI_OK_UPDATE_RETURNING, and SPI_OK_UTILITY.

Referenced by exec_dynquery_with_params(), exec_prepare_plan(), exec_run_select(), exec_stmt_dynexecute(), exec_stmt_execsql(), exec_stmt_forc(), exec_stmt_open(), 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(), and PLy_spi_prepare().

1510 {
1511  static char buf[64];
1512 
1513  switch (code)
1514  {
1515  case SPI_ERROR_CONNECT:
1516  return "SPI_ERROR_CONNECT";
1517  case SPI_ERROR_COPY:
1518  return "SPI_ERROR_COPY";
1519  case SPI_ERROR_OPUNKNOWN:
1520  return "SPI_ERROR_OPUNKNOWN";
1521  case SPI_ERROR_UNCONNECTED:
1522  return "SPI_ERROR_UNCONNECTED";
1523  case SPI_ERROR_ARGUMENT:
1524  return "SPI_ERROR_ARGUMENT";
1525  case SPI_ERROR_PARAM:
1526  return "SPI_ERROR_PARAM";
1527  case SPI_ERROR_TRANSACTION:
1528  return "SPI_ERROR_TRANSACTION";
1529  case SPI_ERROR_NOATTRIBUTE:
1530  return "SPI_ERROR_NOATTRIBUTE";
1531  case SPI_ERROR_NOOUTFUNC:
1532  return "SPI_ERROR_NOOUTFUNC";
1533  case SPI_ERROR_TYPUNKNOWN:
1534  return "SPI_ERROR_TYPUNKNOWN";
1535  case SPI_OK_CONNECT:
1536  return "SPI_OK_CONNECT";
1537  case SPI_OK_FINISH:
1538  return "SPI_OK_FINISH";
1539  case SPI_OK_FETCH:
1540  return "SPI_OK_FETCH";
1541  case SPI_OK_UTILITY:
1542  return "SPI_OK_UTILITY";
1543  case SPI_OK_SELECT:
1544  return "SPI_OK_SELECT";
1545  case SPI_OK_SELINTO:
1546  return "SPI_OK_SELINTO";
1547  case SPI_OK_INSERT:
1548  return "SPI_OK_INSERT";
1549  case SPI_OK_DELETE:
1550  return "SPI_OK_DELETE";
1551  case SPI_OK_UPDATE:
1552  return "SPI_OK_UPDATE";
1553  case SPI_OK_CURSOR:
1554  return "SPI_OK_CURSOR";
1556  return "SPI_OK_INSERT_RETURNING";
1558  return "SPI_OK_DELETE_RETURNING";
1560  return "SPI_OK_UPDATE_RETURNING";
1561  case SPI_OK_REWRITTEN:
1562  return "SPI_OK_REWRITTEN";
1563  }
1564  /* Unrecognized code ... return something useful ... */
1565  sprintf(buf, "Unrecognized SPI code %d", code);
1566  return buf;
1567 }
#define SPI_OK_CONNECT
Definition: spi.h:47
#define SPI_ERROR_PARAM
Definition: spi.h:41
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:38
#define SPI_OK_DELETE_RETURNING
Definition: spi.h:58
#define SPI_OK_DELETE
Definition: spi.h:54
#define SPI_ERROR_COPY
Definition: spi.h:36
#define SPI_ERROR_OPUNKNOWN
Definition: spi.h:37
#define SPI_ERROR_CONNECT
Definition: spi.h:35
#define SPI_OK_CURSOR
Definition: spi.h:56
#define SPI_ERROR_NOOUTFUNC
Definition: spi.h:44
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
#define SPI_OK_INSERT_RETURNING
Definition: spi.h:57
static char * buf
Definition: pg_test_fsync.c:65
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:43
#define SPI_OK_UTILITY
Definition: spi.h:50
#define SPI_OK_UPDATE_RETURNING
Definition: spi.h:59
#define SPI_OK_REWRITTEN
Definition: spi.h:60
#define SPI_ERROR_TRANSACTION
Definition: spi.h:42
#define SPI_OK_SELINTO
Definition: spi.h:52
#define SPI_OK_FETCH
Definition: spi.h:49
#define SPI_OK_SELECT
Definition: spi.h:51
#define SPI_OK_FINISH
Definition: spi.h:48
#define SPI_ERROR_TYPUNKNOWN
Definition: spi.h:45
#define SPI_OK_UPDATE
Definition: spi.h:55
#define SPI_OK_INSERT
Definition: spi.h:53
HeapTupleHeader SPI_returntuple ( HeapTuple  tuple,
TupleDesc  tupdesc 
)

Definition at line 657 of file spi.c.

References assign_record_type_typmod(), DatumGetHeapTupleHeader, heap_copy_tuple_as_datum(), MemoryContextSwitchTo(), NULL, RECORDOID, _SPI_connection::savedcxt, SPI_ERROR_ARGUMENT, SPI_ERROR_UNCONNECTED, SPI_result, tupleDesc::tdtypeid, and tupleDesc::tdtypmod.

Referenced by plpgsql_exec_function().

658 {
659  MemoryContext oldcxt;
660  HeapTupleHeader dtup;
661 
662  if (tuple == NULL || tupdesc == NULL)
663  {
665  return NULL;
666  }
667 
668  if (_SPI_current == NULL)
669  {
671  return NULL;
672  }
673 
674  /* For RECORD results, make sure a typmod has been assigned */
675  if (tupdesc->tdtypeid == RECORDOID &&
676  tupdesc->tdtypmod < 0)
677  assign_record_type_typmod(tupdesc);
678 
680 
681  dtup = DatumGetHeapTupleHeader(heap_copy_tuple_as_datum(tuple, tupdesc));
682 
683  MemoryContextSwitchTo(oldcxt);
684 
685  return dtup;
686 }
Oid tdtypeid
Definition: tupdesc.h:77
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:38
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static _SPI_connection * _SPI_current
Definition: spi.c:45
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:259
int32 tdtypmod
Definition: tupdesc.h:78
void assign_record_type_typmod(TupleDesc tupDesc)
Definition: typcache.c:1308
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
#define RECORDOID
Definition: pg_type.h:676
MemoryContext savedcxt
Definition: spi_priv.h:32
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:656
#define NULL
Definition: c.h:229
SPIPlanPtr SPI_saveplan ( SPIPlanPtr  plan)

Definition at line 586 of file spi.c.

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

587 {
588  SPIPlanPtr newplan;
589 
590  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
591  {
593  return NULL;
594  }
595 
596  SPI_result = _SPI_begin_call(false); /* don't change context */
597  if (SPI_result < 0)
598  return NULL;
599 
600  newplan = _SPI_save_plan(plan);
601 
602  SPI_result = _SPI_end_call(false);
603 
604  return newplan;
605 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:19
int magic
Definition: spi_priv.h:77
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:40
static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan)
Definition: spi.c:2554
static int _SPI_end_call(bool procmem)
Definition: spi.c:2447
#define NULL
Definition: c.h:229
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2430
void SPI_scroll_cursor_fetch ( Portal  ,
FetchDirection  direction,
long  count 
)

Definition at line 1372 of file spi.c.

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

Referenced by exec_stmt_fetch().

1373 {
1374  _SPI_cursor_operation(portal,
1375  direction, count,
1377  /* we know that the DestSPI receiver doesn't need a destroy call */
1378 }
Definition: dest.h:93
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:109
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2364
void SPI_scroll_cursor_move ( Portal  ,
FetchDirection  direction,
long  count 
)

Definition at line 1387 of file spi.c.

References _SPI_cursor_operation(), and None_Receiver.

Referenced by exec_stmt_fetch().

1388 {
1389  _SPI_cursor_operation(portal, direction, count, None_Receiver);
1390 }
DestReceiver * None_Receiver
Definition: dest.c:91
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2364

Variable Documentation