PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
spi.h File Reference
#include "commands/trigger.h"
#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_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_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)
 
int SPI_register_relation (EphemeralNamedRelation enr)
 
int SPI_unregister_relation (const char *name)
 
int SPI_register_trigger_data (TriggerData *tdata)
 
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 36 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 40 of file spi.h.

#define SPI_ERROR_NOOUTFUNC   (-10)

Definition at line 45 of file spi.h.

Referenced by SPI_result_code_string().

#define SPI_ERROR_OPUNKNOWN   (-3)

Definition at line 38 of file spi.h.

Referenced by _SPI_pquery(), and SPI_result_code_string().

#define SPI_ERROR_PARAM   (-7)
#define SPI_ERROR_REL_DUPLICATE   (-12)

Definition at line 47 of file spi.h.

Referenced by SPI_register_relation(), and SPI_result_code_string().

#define SPI_ERROR_REL_NOT_FOUND   (-13)

Definition at line 48 of file spi.h.

Referenced by SPI_result_code_string(), and SPI_unregister_relation().

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

Definition at line 46 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 59 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 52 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_REL_REGISTER   15

Definition at line 64 of file spi.h.

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

#define SPI_OK_REL_UNREGISTER   16

Definition at line 65 of file spi.h.

Referenced by SPI_result_code_string(), and SPI_unregister_relation().

#define SPI_OK_REWRITTEN   14
#define SPI_OK_SELINTO   6
#define SPI_OK_TD_REGISTER   17

Definition at line 66 of file spi.h.

Referenced by SPI_register_trigger_data().

#define SPI_OK_UPDATE_RETURNING   13
#define SPI_pop ( )    ((void) 0)

Definition at line 70 of file spi.h.

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

Definition at line 72 of file spi.h.

#define SPI_push ( )    ((void) 0)

Definition at line 69 of file spi.h.

#define SPI_push_conditional ( )    false

Definition at line 71 of file spi.h.

#define SPI_restore_connection ( )    ((void) 0)

Definition at line 73 of file spi.h.

Typedef Documentation

Definition at line 34 of file spi.h.

Function Documentation

void AtEOSubXact_SPI ( bool  isCommit,
SubTransactionId  mySubid 
)

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

216 {
217  bool found = false;
218 
219  while (_SPI_connected >= 0)
220  {
222 
223  if (connection->connectSubid != mySubid)
224  break; /* couldn't be any underneath it either */
225 
226  found = true;
227 
228  /*
229  * Release procedure memory explicitly (see note in SPI_connect)
230  */
231  if (connection->execCxt)
232  {
233  MemoryContextDelete(connection->execCxt);
234  connection->execCxt = NULL;
235  }
236  if (connection->procCxt)
237  {
238  MemoryContextDelete(connection->procCxt);
239  connection->procCxt = NULL;
240  }
241 
242  /*
243  * Pop the stack entry and reset global variables. Unlike
244  * SPI_finish(), we don't risk switching to memory contexts that might
245  * be already gone.
246  */
247  _SPI_connected--;
248  if (_SPI_connected < 0)
249  _SPI_current = NULL;
250  else
252  SPI_processed = 0;
254  SPI_tuptable = NULL;
255  }
256 
257  if (found && isCommit)
259  (errcode(ERRCODE_WARNING),
260  errmsg("subtransaction left non-empty SPI stack"),
261  errhint("Check for missing \"SPI_finish\" calls.")));
262 
263  /*
264  * If we are aborting a subtransaction and there is an open SPI context
265  * surrounding the subxact, clean up to prevent memory leakage.
266  */
267  if (_SPI_current && !isCommit)
268  {
269  slist_mutable_iter siter;
270 
271  /* free Executor memory the same as _SPI_end_call would do */
273 
274  /* throw away any tuple tables created within current subxact */
276  {
277  SPITupleTable *tuptable;
278 
279  tuptable = slist_container(SPITupleTable, next, siter.cur);
280  if (tuptable->subid >= mySubid)
281  {
282  /*
283  * If we used SPI_freetuptable() here, its internal search of
284  * the tuptables list would make this operation O(N^2).
285  * Instead, just free the tuptable manually. This should
286  * match what SPI_freetuptable() does.
287  */
288  slist_delete_current(&siter);
289  if (tuptable == _SPI_current->tuptable)
291  if (tuptable == SPI_tuptable)
292  SPI_tuptable = NULL;
293  MemoryContextDelete(tuptable->tuptabcxt);
294  }
295  }
296  /* in particular we should have gotten rid of any in-progress table */
298  }
299 }
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:34
SPITupleTable * tuptable
Definition: spi_priv.h:27
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:31
Oid SPI_lastoid
Definition: spi.c:40
MemoryContext execCxt
Definition: spi_priv.h:32
#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:30
slist_head tuptables
Definition: spi_priv.h:30
MemoryContext tuptabcxt
Definition: spi.h:24
void AtEOXact_SPI ( bool  isCommit)

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

188 {
189  /*
190  * Note that memory contexts belonging to SPI stack entries will be freed
191  * automatically, so we can ignore them here. We just need to restore our
192  * static variables to initial state.
193  */
194  if (isCommit && _SPI_connected != -1)
196  (errcode(ERRCODE_WARNING),
197  errmsg("transaction left non-empty SPI stack"),
198  errhint("Check for missing \"SPI_finish\" calls.")));
199 
201  _SPI_stack_depth = 0;
202  _SPI_connected = -1;
203  SPI_processed = 0;
205  SPI_tuptable = NULL;
206 }
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, _SPI_connection::queryEnv, 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 */
126 
127  /*
128  * Create memory contexts for this procedure
129  *
130  * XXX it would be better to use PortalContext as the parent context, but
131  * we may not be inside a portal (consider deferred-trigger execution).
132  * Perhaps CurTransactionContext would do? For now it doesn't matter
133  * because we clean up explicitly in AtEOSubXact_SPI().
134  */
136  "SPI Proc",
139  "SPI Exec",
141  /* ... and switch to procedure's context */
143 
144  return SPI_OK_CONNECT;
145 }
#define SPI_OK_CONNECT
Definition: spi.h:50
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:34
static void slist_init(slist_head *head)
Definition: ilist.h:554
#define ERROR
Definition: elog.h:43
QueryEnvironment * queryEnv
Definition: spi_priv.h:35
SPITupleTable * tuptable
Definition: spi_priv.h:27
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
static _SPI_connection * _SPI_stack
Definition: spi.c:44
MemoryContext savedcxt
Definition: spi_priv.h:33
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
MemoryContext procCxt
Definition: spi_priv.h:31
MemoryContext execCxt
Definition: spi_priv.h:32
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
uint64 processed
Definition: spi_priv.h:25
#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:30
HeapTuple SPI_copytuple ( HeapTuple  tuple)

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

632 {
633  MemoryContext oldcxt;
634  HeapTuple ctuple;
635 
636  if (tuple == NULL)
637  {
639  return NULL;
640  }
641 
642  if (_SPI_current == NULL)
643  {
645  return NULL;
646  }
647 
649 
650  ctuple = heap_copytuple(tuple);
651 
652  MemoryContextSwitchTo(oldcxt);
653 
654  return ctuple;
655 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:39
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:41
MemoryContext savedcxt
Definition: spi_priv.h:33
#define NULL
Definition: c.h:229
void SPI_cursor_close ( Portal  portal)

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

1404 {
1405  if (!PortalIsValid(portal))
1406  elog(ERROR, "invalid portal in SPI cursor operation");
1407 
1408  PortalDrop(portal, false);
1409 }
#define ERROR
Definition: elog.h:43
#define PortalIsValid(p)
Definition: portal.h:199
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 1347 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().

1348 {
1349  _SPI_cursor_operation(portal,
1350  forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1352  /* we know that the DestSPI receiver doesn't need a destroy call */
1353 }
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:2383
Portal SPI_cursor_find ( const char *  name)

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

1336 {
1337  return GetPortalByName(name);
1338 }
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 1362 of file spi.c.

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

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

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

1032 {
1033  Portal portal;
1034  ParamListInfo paramLI;
1035 
1036  /* build transient ParamListInfo in caller's context */
1037  paramLI = _SPI_convert_params(plan->nargs, plan->argtypes,
1038  Values, Nulls);
1039 
1040  portal = SPI_cursor_open_internal(name, plan, paramLI, read_only);
1041 
1042  /* done with the transient ParamListInfo */
1043  if (paramLI)
1044  pfree(paramLI);
1045 
1046  return portal;
1047 }
Oid * argtypes
Definition: spi_priv.h:86
void pfree(void *pointer)
Definition: mcxt.c:950
int nargs
Definition: spi_priv.h:85
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:1121
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2240
static bool Nulls[MAXATTR]
Definition: bootstrap.c:164
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 1056 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().

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

Definition at line 1108 of file spi.c.

References SPI_cursor_open_internal().

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

1110 {
1111  return SPI_cursor_open_internal(name, plan, params, read_only);
1112 }
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:1121
Datum SPI_datumTransfer ( Datum  value,
bool  typByVal,
int  typLen 
)

Definition at line 945 of file spi.c.

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

Referenced by plpgsql_exec_function().

946 {
947  MemoryContext oldcxt;
948  Datum result;
949 
950  if (_SPI_current == NULL)
951  elog(ERROR, "SPI_datumTransfer called while not connected to SPI");
952 
954 
955  result = datumTransfer(value, typByVal, typLen);
956 
957  MemoryContextSwitchTo(oldcxt);
958 
959  return result;
960 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
return result
Definition: formatting.c:1632
static _SPI_connection * _SPI_current
Definition: spi.c:45
#define ERROR
Definition: elog.h:43
MemoryContext savedcxt
Definition: spi_priv.h:33
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
static struct @121 value
int SPI_exec ( const char *  src,
long  tcount 
)

Definition at line 332 of file spi.c.

References SPI_execute().

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

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

Definition at line 366 of file spi.c.

References SPI_execute_plan().

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

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

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

305 {
306  _SPI_plan plan;
307  int res;
308 
309  if (src == NULL || tcount < 0)
310  return SPI_ERROR_ARGUMENT;
311 
312  res = _SPI_begin_call(true);
313  if (res < 0)
314  return res;
315 
316  memset(&plan, 0, sizeof(_SPI_plan));
317  plan.magic = _SPI_PLAN_MAGIC;
319 
320  _SPI_prepare_oneshot_plan(src, &plan);
321 
322  res = _SPI_execute_plan(&plan, NULL,
324  read_only, true, tcount);
325 
326  _SPI_end_call(true);
327  return res;
328 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1850
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:1908
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
#define InvalidSnapshot
Definition: snapshot.h:25
#define NULL
Definition: c.h:229
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2603
int cursor_options
Definition: spi_priv.h:84
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
int SPI_execute_plan ( SPIPlanPtr  plan,
Datum Values,
const char *  Nulls,
bool  read_only,
long  tcount 
)

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

341 {
342  int res;
343 
344  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
345  return SPI_ERROR_ARGUMENT;
346 
347  if (plan->nargs > 0 && Values == NULL)
348  return SPI_ERROR_PARAM;
349 
350  res = _SPI_begin_call(true);
351  if (res < 0)
352  return res;
353 
354  res = _SPI_execute_plan(plan,
355  _SPI_convert_params(plan->nargs, plan->argtypes,
356  Values, Nulls),
358  read_only, true, tcount);
359 
360  _SPI_end_call(true);
361  return res;
362 }
Oid * argtypes
Definition: spi_priv.h:86
#define SPI_ERROR_PARAM
Definition: spi.h:42
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
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:1908
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
#define InvalidSnapshot
Definition: snapshot.h:25
int nargs
Definition: spi_priv.h:85
#define NULL
Definition: c.h:229
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2240
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
static bool Nulls[MAXATTR]
Definition: bootstrap.c:164
int SPI_execute_plan_with_paramlist ( SPIPlanPtr  plan,
ParamListInfo  params,
bool  read_only,
long  tcount 
)

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

375 {
376  int res;
377 
378  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
379  return SPI_ERROR_ARGUMENT;
380 
381  res = _SPI_begin_call(true);
382  if (res < 0)
383  return res;
384 
385  res = _SPI_execute_plan(plan, params,
387  read_only, true, tcount);
388 
389  _SPI_end_call(true);
390  return res;
391 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
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:1908
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
#define InvalidSnapshot
Definition: snapshot.h:25
#define NULL
Definition: c.h:229
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
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 407 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().

411 {
412  int res;
413 
414  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
415  return SPI_ERROR_ARGUMENT;
416 
417  if (plan->nargs > 0 && Values == NULL)
418  return SPI_ERROR_PARAM;
419 
420  res = _SPI_begin_call(true);
421  if (res < 0)
422  return res;
423 
424  res = _SPI_execute_plan(plan,
425  _SPI_convert_params(plan->nargs, plan->argtypes,
426  Values, Nulls),
427  snapshot, crosscheck_snapshot,
428  read_only, fire_triggers, tcount);
429 
430  _SPI_end_call(true);
431  return res;
432 }
Oid * argtypes
Definition: spi_priv.h:86
#define SPI_ERROR_PARAM
Definition: spi.h:42
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
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:1908
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
int nargs
Definition: spi_priv.h:85
#define NULL
Definition: c.h:229
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2240
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
static bool Nulls[MAXATTR]
Definition: bootstrap.c:164
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 441 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().

445 {
446  int res;
447  _SPI_plan plan;
448  ParamListInfo paramLI;
449 
450  if (src == NULL || nargs < 0 || tcount < 0)
451  return SPI_ERROR_ARGUMENT;
452 
453  if (nargs > 0 && (argtypes == NULL || Values == NULL))
454  return SPI_ERROR_PARAM;
455 
456  res = _SPI_begin_call(true);
457  if (res < 0)
458  return res;
459 
460  memset(&plan, 0, sizeof(_SPI_plan));
461  plan.magic = _SPI_PLAN_MAGIC;
463  plan.nargs = nargs;
464  plan.argtypes = argtypes;
465  plan.parserSetup = NULL;
466  plan.parserSetupArg = NULL;
467 
468  paramLI = _SPI_convert_params(nargs, argtypes,
469  Values, Nulls);
470 
471  _SPI_prepare_oneshot_plan(src, &plan);
472 
473  res = _SPI_execute_plan(&plan, paramLI,
475  read_only, true, tcount);
476 
477  _SPI_end_call(true);
478  return res;
479 }
Oid * argtypes
Definition: spi_priv.h:86
#define SPI_ERROR_PARAM
Definition: spi.h:42
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1850
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:1908
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
#define InvalidSnapshot
Definition: snapshot.h:25
int nargs
Definition: spi_priv.h:85
#define NULL
Definition: c.h:229
ParserSetupHook parserSetup
Definition: spi_priv.h:87
void * parserSetupArg
Definition: spi_priv.h:88
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2603
int cursor_options
Definition: spi_priv.h:84
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2240
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
static bool Nulls[MAXATTR]
Definition: bootstrap.c:164
int SPI_finish ( void  )

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

149 {
150  int res;
151 
152  res = _SPI_begin_call(false); /* live in procedure memory */
153  if (res < 0)
154  return res;
155 
156  /* Restore memory context as it was before procedure call */
158 
159  /* Release memory used in procedure call (including tuptables) */
164 
165  /*
166  * Reset result variables, especially SPI_tuptable which is probably
167  * pointing at a just-deleted tuptable
168  */
169  SPI_processed = 0;
171  SPI_tuptable = NULL;
172 
173  /* Exit stack level */
174  _SPI_connected--;
175  if (_SPI_connected < 0)
176  _SPI_current = NULL;
177  else
179 
180  return SPI_OK_FINISH;
181 }
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:33
MemoryContext procCxt
Definition: spi_priv.h:31
Oid SPI_lastoid
Definition: spi.c:40
MemoryContext execCxt
Definition: spi_priv.h:32
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define SPI_OK_FINISH
Definition: spi.h:51
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
char* SPI_fname ( TupleDesc  tupdesc,
int  fnumber 
)

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

783 {
784  Form_pg_attribute att;
785 
786  SPI_result = 0;
787 
788  if (fnumber > tupdesc->natts || fnumber == 0 ||
790  {
792  return NULL;
793  }
794 
795  if (fnumber > 0)
796  att = tupdesc->attrs[fnumber - 1];
797  else
798  att = SystemAttributeDefinition(fnumber, true);
799 
800  return pstrdup(NameStr(att->attname));
801 }
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:44
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
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 761 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().

762 {
763  int res;
764  Form_pg_attribute sysatt;
765 
766  for (res = 0; res < tupdesc->natts; res++)
767  {
768  if (namestrcmp(&tupdesc->attrs[res]->attname, fname) == 0 &&
769  !tupdesc->attrs[res]->attisdropped)
770  return res + 1;
771  }
772 
773  sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ );
774  if (sysatt != NULL)
775  return sysatt->attnum;
776 
777  /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
778  return SPI_ERROR_NOATTRIBUTE;
779 }
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:44
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define NULL
Definition: c.h:229
int SPI_freeplan ( SPIPlanPtr  plan)

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

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

Definition at line 963 of file spi.c.

References heap_freetuple().

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

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

971 {
972  bool found = false;
973 
974  /* ignore call if NULL pointer */
975  if (tuptable == NULL)
976  return;
977 
978  /*
979  * Search only the topmost SPI context for a matching tuple table.
980  */
981  if (_SPI_current != NULL)
982  {
983  slist_mutable_iter siter;
984 
985  /* find tuptable in active list, then remove it */
987  {
988  SPITupleTable *tt;
989 
990  tt = slist_container(SPITupleTable, next, siter.cur);
991  if (tt == tuptable)
992  {
993  slist_delete_current(&siter);
994  found = true;
995  break;
996  }
997  }
998  }
999 
1000  /*
1001  * Refuse the deletion if we didn't find it in the topmost SPI context.
1002  * This is primarily a guard against double deletion, but might prevent
1003  * other errors as well. Since the worst consequence of not deleting a
1004  * tuptable would be a transient memory leak, this is just a WARNING.
1005  */
1006  if (!found)
1007  {
1008  elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);
1009  return;
1010  }
1011 
1012  /* for safety, reset global variables that might point at tuptable */
1013  if (tuptable == _SPI_current->tuptable)
1015  if (tuptable == SPI_tuptable)
1016  SPI_tuptable = NULL;
1017 
1018  /* release all memory belonging to tuptable */
1019  MemoryContextDelete(tuptable->tuptabcxt);
1020 }
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:27
#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:30
MemoryContext tuptabcxt
Definition: spi.h:24
int SPI_getargcount ( SPIPlanPtr  plan)

Definition at line 1431 of file spi.c.

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

1432 {
1433  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1434  {
1436  return -1;
1437  }
1438  return plan->nargs;
1439 }
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
int nargs
Definition: spi_priv.h:85
#define NULL
Definition: c.h:229
Oid SPI_getargtypeid ( SPIPlanPtr  plan,
int  argIndex 
)

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

1417 {
1418  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
1419  argIndex < 0 || argIndex >= plan->nargs)
1420  {
1422  return InvalidOid;
1423  }
1424  return plan->argtypes[argIndex];
1425 }
Oid * argtypes
Definition: spi_priv.h:86
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
int nargs
Definition: spi_priv.h:85
#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 836 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().

837 {
838  SPI_result = 0;
839 
840  if (fnumber > tupdesc->natts || fnumber == 0 ||
842  {
844  *isnull = true;
845  return (Datum) NULL;
846  }
847 
848  return heap_getattr(tuple, fnumber, tupdesc, isnull);
849 }
#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:44
#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 916 of file spi.c.

References get_namespace_name(), and RelationGetNamespace.

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

917 {
919 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
#define RelationGetNamespace(relation)
Definition: rel.h:444
char* SPI_getrelname ( Relation  rel)

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

911 {
912  return pstrdup(RelationGetRelationName(rel));
913 }
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 852 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().

853 {
854  Oid typoid;
855  HeapTuple typeTuple;
856  char *result;
857 
858  SPI_result = 0;
859 
860  if (fnumber > tupdesc->natts || fnumber == 0 ||
862  {
864  return NULL;
865  }
866 
867  if (fnumber > 0)
868  typoid = tupdesc->attrs[fnumber - 1]->atttypid;
869  else
870  typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
871 
872  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
873 
874  if (!HeapTupleIsValid(typeTuple))
875  {
877  return NULL;
878  }
879 
880  result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
881  ReleaseSysCache(typeTuple);
882  return result;
883 }
#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:1632
#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:156
int SPI_result
Definition: spi.c:42
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:44
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
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:46
#define NameStr(name)
Definition: c.h:499
Oid SPI_gettypeid ( TupleDesc  tupdesc,
int  fnumber 
)

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

893 {
894  SPI_result = 0;
895 
896  if (fnumber > tupdesc->natts || fnumber == 0 ||
898  {
900  return InvalidOid;
901  }
902 
903  if (fnumber > 0)
904  return tupdesc->attrs[fnumber - 1]->atttypid;
905  else
906  return (SystemAttributeDefinition(fnumber, true))->atttypid;
907 }
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:44
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 804 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().

805 {
806  Datum val;
807  bool isnull;
808  Oid typoid,
809  foutoid;
810  bool typisvarlena;
811 
812  SPI_result = 0;
813 
814  if (fnumber > tupdesc->natts || fnumber == 0 ||
816  {
818  return NULL;
819  }
820 
821  val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
822  if (isnull)
823  return NULL;
824 
825  if (fnumber > 0)
826  typoid = tupdesc->attrs[fnumber - 1]->atttypid;
827  else
828  typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
829 
830  getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
831 
832  return OidOutputFunctionCall(foutoid, val);
833 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2632
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:44
#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:1747
long val
Definition: informix.c:689
bool SPI_is_cursor_plan ( SPIPlanPtr  plan)

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

1452 {
1453  CachedPlanSource *plansource;
1454 
1455  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1456  {
1458  return false;
1459  }
1460 
1461  if (list_length(plan->plancache_list) != 1)
1462  {
1463  SPI_result = 0;
1464  return false; /* not exactly 1 pre-rewrite command */
1465  }
1466  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1467 
1468  /*
1469  * We used to force revalidation of the cached plan here, but that seems
1470  * unnecessary: invalidation could mean a change in the rowtype of the
1471  * tuples returned by a plan, but not whether it returns tuples at all.
1472  */
1473  SPI_result = 0;
1474 
1475  /* Does it return tuples? */
1476  if (plansource->resultDesc)
1477  return true;
1478 
1479  return false;
1480 }
List * plancache_list
Definition: spi_priv.h:82
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
TupleDesc resultDesc
Definition: plancache.h:92
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
#define linitial(l)
Definition: pg_list.h:111
#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 560 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().

561 {
562  ListCell *lc;
563 
564  if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
565  plan->saved || plan->oneshot)
566  return SPI_ERROR_ARGUMENT;
567 
568  /*
569  * Mark it saved, reparent it under CacheMemoryContext, and mark all the
570  * component CachedPlanSources as saved. This sequence cannot fail
571  * partway through, so there's no risk of long-term memory leakage.
572  */
573  plan->saved = true;
575 
576  foreach(lc, plan->plancache_list)
577  {
578  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
579 
580  SaveCachedPlan(plansource);
581  }
582 
583  return 0;
584 }
List * plancache_list
Definition: spi_priv.h:82
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:317
int magic
Definition: spi_priv.h:79
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
MemoryContext plancxt
Definition: spi_priv.h:83
bool saved
Definition: spi_priv.h:80
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:441
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
bool oneshot
Definition: spi_priv.h:81
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 690 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().

692 {
693  MemoryContext oldcxt;
694  HeapTuple mtuple;
695  int numberOfAttributes;
696  Datum *v;
697  bool *n;
698  int i;
699 
700  if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
701  {
703  return NULL;
704  }
705 
706  if (_SPI_current == NULL)
707  {
709  return NULL;
710  }
711 
713 
714  SPI_result = 0;
715 
716  numberOfAttributes = rel->rd_att->natts;
717  v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
718  n = (bool *) palloc(numberOfAttributes * sizeof(bool));
719 
720  /* fetch old values and nulls */
721  heap_deform_tuple(tuple, rel->rd_att, v, n);
722 
723  /* replace values and nulls */
724  for (i = 0; i < natts; i++)
725  {
726  if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
727  break;
728  v[attnum[i] - 1] = Values[i];
729  n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? true : false;
730  }
731 
732  if (i == natts) /* no errors in *attnum */
733  {
734  mtuple = heap_form_tuple(rel->rd_att, v, n);
735 
736  /*
737  * copy the identification info of the old tuple: t_ctid, t_self, and
738  * OID (if any)
739  */
740  mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
741  mtuple->t_self = tuple->t_self;
742  mtuple->t_tableOid = tuple->t_tableOid;
743  if (rel->rd_att->tdhasoid)
744  HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
745  }
746  else
747  {
748  mtuple = NULL;
750  }
751 
752  pfree(v);
753  pfree(n);
754 
755  MemoryContextSwitchTo(oldcxt);
756 
757  return mtuple;
758 }
bool tdhasoid
Definition: tupdesc.h:79
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:39
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:41
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:44
Oid t_tableOid
Definition: htup.h:66
MemoryContext savedcxt
Definition: spi_priv.h:33
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:933
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:164
void* SPI_palloc ( Size  size)

Definition at line 922 of file spi.c.

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

Referenced by _SPI_strdup().

923 {
924  if (_SPI_current == NULL)
925  elog(ERROR, "SPI_palloc called while not connected to SPI");
926 
928 }
static _SPI_connection * _SPI_current
Definition: spi.c:45
#define ERROR
Definition: elog.h:43
MemoryContext savedcxt
Definition: spi_priv.h:33
#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 938 of file spi.c.

References pfree().

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

Definition at line 1606 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, _SPI_connection::queryEnv, and _SPI_plan::saved.

Referenced by exec_eval_simple_expr(), and exec_simple_check_plan().

1607 {
1608  CachedPlanSource *plansource;
1609  CachedPlan *cplan;
1610  ErrorContextCallback spierrcontext;
1611 
1612  Assert(plan->magic == _SPI_PLAN_MAGIC);
1613 
1614  /* Can't support one-shot plans here */
1615  if (plan->oneshot)
1616  return NULL;
1617 
1618  /* Must have exactly one CachedPlanSource */
1619  if (list_length(plan->plancache_list) != 1)
1620  return NULL;
1621  plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1622 
1623  /* Setup error traceback support for ereport() */
1624  spierrcontext.callback = _SPI_error_callback;
1625  spierrcontext.arg = (void *) plansource->query_string;
1626  spierrcontext.previous = error_context_stack;
1627  error_context_stack = &spierrcontext;
1628 
1629  /* Get the generic plan for the query */
1630  cplan = GetCachedPlan(plansource, NULL, plan->saved,
1632  Assert(cplan == plansource->gplan);
1633 
1634  /* Pop the error context stack */
1635  error_context_stack = spierrcontext.previous;
1636 
1637  return cplan;
1638 }
List * plancache_list
Definition: spi_priv.h:82
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, bool useResOwner, QueryEnvironment *queryEnv)
Definition: plancache.c:1135
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
static _SPI_connection * _SPI_current
Definition: spi.c:45
struct ErrorContextCallback * previous
Definition: elog.h:238
struct CachedPlan * gplan
Definition: plancache.h:105
ErrorContextCallback * error_context_stack
Definition: elog.c:88
static void _SPI_error_callback(void *arg)
Definition: spi.c:2357
#define linitial(l)
Definition: pg_list.h:111
QueryEnvironment * queryEnv
Definition: spi_priv.h:35
bool saved
Definition: spi_priv.h:80
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool oneshot
Definition: spi_priv.h:81
const char * query_string
Definition: plancache.h:84
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 1590 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().

1591 {
1592  Assert(plan->magic == _SPI_PLAN_MAGIC);
1593  return plan->plancache_list;
1594 }
List * plancache_list
Definition: spi_priv.h:82
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
#define Assert(condition)
Definition: c.h:675
bool SPI_plan_is_valid ( SPIPlanPtr  plan)

Definition at line 1489 of file spi.c.

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

Referenced by ri_FetchPreparedPlan().

1490 {
1491  ListCell *lc;
1492 
1493  Assert(plan->magic == _SPI_PLAN_MAGIC);
1494 
1495  foreach(lc, plan->plancache_list)
1496  {
1497  CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1498 
1499  if (!CachedPlanIsValid(plansource))
1500  return false;
1501  }
1502  return true;
1503 }
List * plancache_list
Definition: spi_priv.h:82
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
bool CachedPlanIsValid(CachedPlanSource *plansource)
Definition: plancache.c:1412
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 488 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().

490 {
491  _SPI_plan plan;
493 
494  if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
495  {
497  return NULL;
498  }
499 
500  SPI_result = _SPI_begin_call(true);
501  if (SPI_result < 0)
502  return NULL;
503 
504  memset(&plan, 0, sizeof(_SPI_plan));
505  plan.magic = _SPI_PLAN_MAGIC;
506  plan.cursor_options = cursorOptions;
507  plan.nargs = nargs;
508  plan.argtypes = argtypes;
509  plan.parserSetup = NULL;
510  plan.parserSetupArg = NULL;
511 
512  _SPI_prepare_plan(src, &plan);
513 
514  /* copy plan to procedure context */
515  result = _SPI_make_plan_non_temp(&plan);
516 
517  _SPI_end_call(true);
518 
519  return result;
520 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1745
Oid * argtypes
Definition: spi_priv.h:86
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
return result
Definition: formatting.c:1632
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:2503
int nargs
Definition: spi_priv.h:85
#define NULL
Definition: c.h:229
ParserSetupHook parserSetup
Definition: spi_priv.h:87
void * parserSetupArg
Definition: spi_priv.h:88
int cursor_options
Definition: spi_priv.h:84
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
SPIPlanPtr SPI_prepare_params ( const char *  src,
ParserSetupHook  parserSetup,
void *  parserSetupArg,
int  cursorOptions 
)

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

527 {
528  _SPI_plan plan;
530 
531  if (src == NULL)
532  {
534  return NULL;
535  }
536 
537  SPI_result = _SPI_begin_call(true);
538  if (SPI_result < 0)
539  return NULL;
540 
541  memset(&plan, 0, sizeof(_SPI_plan));
542  plan.magic = _SPI_PLAN_MAGIC;
543  plan.cursor_options = cursorOptions;
544  plan.nargs = 0;
545  plan.argtypes = NULL;
546  plan.parserSetup = parserSetup;
547  plan.parserSetupArg = parserSetupArg;
548 
549  _SPI_prepare_plan(src, &plan);
550 
551  /* copy plan to procedure context */
552  result = _SPI_make_plan_non_temp(&plan);
553 
554  _SPI_end_call(true);
555 
556  return result;
557 }
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:1745
Oid * argtypes
Definition: spi_priv.h:86
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20
int magic
Definition: spi_priv.h:79
return result
Definition: formatting.c:1632
int SPI_result
Definition: spi.c:42
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:2503
int nargs
Definition: spi_priv.h:85
#define NULL
Definition: c.h:229
ParserSetupHook parserSetup
Definition: spi_priv.h:87
void * parserSetupArg
Definition: spi_priv.h:88
int cursor_options
Definition: spi_priv.h:84
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
int SPI_register_relation ( EphemeralNamedRelation  enr)

Definition at line 2663 of file spi.c.

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

Referenced by SPI_register_trigger_data().

2664 {
2665  EphemeralNamedRelation match;
2666  int res;
2667 
2668  if (enr == NULL || enr->md.name == NULL)
2669  return SPI_ERROR_ARGUMENT;
2670 
2671  res = _SPI_begin_call(false); /* keep current memory context */
2672  if (res < 0)
2673  return res;
2674 
2675  match = _SPI_find_ENR_by_name(enr->md.name);
2676  if (match)
2678  else
2679  {
2680  if (_SPI_current->queryEnv == NULL)
2682 
2684  res = SPI_OK_REL_REGISTER;
2685  }
2686 
2687  _SPI_end_call(false);
2688 
2689  return res;
2690 }
EphemeralNamedRelationMetadataData md
#define SPI_ERROR_REL_DUPLICATE
Definition: spi.h:47
static EphemeralNamedRelation _SPI_find_ENR_by_name(const char *name)
Definition: spi.c:2646
static _SPI_connection * _SPI_current
Definition: spi.c:45
#define SPI_OK_REL_REGISTER
Definition: spi.h:64
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
QueryEnvironment * queryEnv
Definition: spi_priv.h:35
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
void register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr)
#define NULL
Definition: c.h:229
QueryEnvironment * create_queryEnv()
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
int SPI_register_trigger_data ( TriggerData tdata)

Definition at line 2730 of file spi.c.

References ENR_NAMED_TUPLESTORE, EphemeralNamedRelationMetadataData::enrtuples, EphemeralNamedRelationMetadataData::enrtype, EphemeralNamedRelationData::md, EphemeralNamedRelationMetadataData::name, NULL, 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().

2731 {
2732  if (tdata == NULL)
2733  return SPI_ERROR_ARGUMENT;
2734 
2735  if (tdata->tg_newtable)
2736  {
2739  int rc;
2740 
2741  enr->md.name = tdata->tg_trigger->tgnewtable;
2742  enr->md.reliddesc = tdata->tg_relation->rd_id;
2743  enr->md.tupdesc = NULL;
2746  enr->reldata = tdata->tg_newtable;
2747  rc = SPI_register_relation(enr);
2748  if (rc != SPI_OK_REL_REGISTER)
2749  return rc;
2750  }
2751 
2752  if (tdata->tg_oldtable)
2753  {
2756  int rc;
2757 
2758  enr->md.name = tdata->tg_trigger->tgoldtable;
2759  enr->md.reliddesc = tdata->tg_relation->rd_id;
2760  enr->md.tupdesc = NULL;
2763  enr->reldata = tdata->tg_oldtable;
2764  rc = SPI_register_relation(enr);
2765  if (rc != SPI_OK_REL_REGISTER)
2766  return rc;
2767  }
2768 
2769  return SPI_OK_TD_REGISTER;
2770 }
EphemeralNamedRelationMetadataData md
#define SPI_OK_REL_REGISTER
Definition: spi.h:64
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
#define SPI_OK_TD_REGISTER
Definition: spi.h:66
Oid rd_id
Definition: rel.h:116
char * tgnewtable
Definition: reltrigger.h:43
Trigger * tg_trigger
Definition: trigger.h:37
int64 tuplestore_tuple_count(Tuplestorestate *state)
Definition: tuplestore.c:546
#define NULL
Definition: c.h:229
Tuplestorestate * tg_oldtable
Definition: trigger.h:40
int SPI_register_relation(EphemeralNamedRelation enr)
Definition: spi.c:2663
void * palloc(Size size)
Definition: mcxt.c:849
Tuplestorestate * tg_newtable
Definition: trigger.h:41
EphemeralNameRelationType enrtype
char * tgoldtable
Definition: reltrigger.h:42
Relation tg_relation
Definition: trigger.h:34
void* SPI_repalloc ( void *  pointer,
Size  size 
)

Definition at line 931 of file spi.c.

References repalloc().

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

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

1514 {
1515  static char buf[64];
1516 
1517  switch (code)
1518  {
1519  case SPI_ERROR_CONNECT:
1520  return "SPI_ERROR_CONNECT";
1521  case SPI_ERROR_COPY:
1522  return "SPI_ERROR_COPY";
1523  case SPI_ERROR_OPUNKNOWN:
1524  return "SPI_ERROR_OPUNKNOWN";
1525  case SPI_ERROR_UNCONNECTED:
1526  return "SPI_ERROR_UNCONNECTED";
1527  case SPI_ERROR_ARGUMENT:
1528  return "SPI_ERROR_ARGUMENT";
1529  case SPI_ERROR_PARAM:
1530  return "SPI_ERROR_PARAM";
1531  case SPI_ERROR_TRANSACTION:
1532  return "SPI_ERROR_TRANSACTION";
1533  case SPI_ERROR_NOATTRIBUTE:
1534  return "SPI_ERROR_NOATTRIBUTE";
1535  case SPI_ERROR_NOOUTFUNC:
1536  return "SPI_ERROR_NOOUTFUNC";
1537  case SPI_ERROR_TYPUNKNOWN:
1538  return "SPI_ERROR_TYPUNKNOWN";
1540  return "SPI_ERROR_REL_DUPLICATE";
1542  return "SPI_ERROR_REL_NOT_FOUND";
1543  case SPI_OK_CONNECT:
1544  return "SPI_OK_CONNECT";
1545  case SPI_OK_FINISH:
1546  return "SPI_OK_FINISH";
1547  case SPI_OK_FETCH:
1548  return "SPI_OK_FETCH";
1549  case SPI_OK_UTILITY:
1550  return "SPI_OK_UTILITY";
1551  case SPI_OK_SELECT:
1552  return "SPI_OK_SELECT";
1553  case SPI_OK_SELINTO:
1554  return "SPI_OK_SELINTO";
1555  case SPI_OK_INSERT:
1556  return "SPI_OK_INSERT";
1557  case SPI_OK_DELETE:
1558  return "SPI_OK_DELETE";
1559  case SPI_OK_UPDATE:
1560  return "SPI_OK_UPDATE";
1561  case SPI_OK_CURSOR:
1562  return "SPI_OK_CURSOR";
1564  return "SPI_OK_INSERT_RETURNING";
1566  return "SPI_OK_DELETE_RETURNING";
1568  return "SPI_OK_UPDATE_RETURNING";
1569  case SPI_OK_REWRITTEN:
1570  return "SPI_OK_REWRITTEN";
1571  case SPI_OK_REL_REGISTER:
1572  return "SPI_OK_REL_REGISTER";
1573  case SPI_OK_REL_UNREGISTER:
1574  return "SPI_OK_REL_UNREGISTER";
1575  }
1576  /* Unrecognized code ... return something useful ... */
1577  sprintf(buf, "Unrecognized SPI code %d", code);
1578  return buf;
1579 }
#define SPI_OK_CONNECT
Definition: spi.h:50
#define SPI_ERROR_PARAM
Definition: spi.h:42
#define SPI_ERROR_REL_NOT_FOUND
Definition: spi.h:48
#define SPI_ERROR_REL_DUPLICATE
Definition: spi.h:47
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:39
#define SPI_OK_DELETE_RETURNING
Definition: spi.h:61
#define SPI_OK_DELETE
Definition: spi.h:57
#define SPI_ERROR_COPY
Definition: spi.h:37
#define SPI_ERROR_OPUNKNOWN
Definition: spi.h:38
#define SPI_OK_REL_REGISTER
Definition: spi.h:64
#define SPI_ERROR_CONNECT
Definition: spi.h:36
#define SPI_OK_CURSOR
Definition: spi.h:59
#define SPI_ERROR_NOOUTFUNC
Definition: spi.h:45
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
#define SPI_OK_INSERT_RETURNING
Definition: spi.h:60
static char * buf
Definition: pg_test_fsync.c:66
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:44
#define SPI_OK_UTILITY
Definition: spi.h:53
#define SPI_OK_UPDATE_RETURNING
Definition: spi.h:62
#define SPI_OK_REWRITTEN
Definition: spi.h:63
#define SPI_ERROR_TRANSACTION
Definition: spi.h:43
#define SPI_OK_SELINTO
Definition: spi.h:55
#define SPI_OK_FETCH
Definition: spi.h:52
#define SPI_OK_SELECT
Definition: spi.h:54
#define SPI_OK_FINISH
Definition: spi.h:51
#define SPI_ERROR_TYPUNKNOWN
Definition: spi.h:46
#define SPI_OK_UPDATE
Definition: spi.h:58
#define SPI_OK_INSERT
Definition: spi.h:56
#define SPI_OK_REL_UNREGISTER
Definition: spi.h:65
HeapTupleHeader SPI_returntuple ( HeapTuple  tuple,
TupleDesc  tupdesc 
)

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

659 {
660  MemoryContext oldcxt;
661  HeapTupleHeader dtup;
662 
663  if (tuple == NULL || tupdesc == NULL)
664  {
666  return NULL;
667  }
668 
669  if (_SPI_current == NULL)
670  {
672  return NULL;
673  }
674 
675  /* For RECORD results, make sure a typmod has been assigned */
676  if (tupdesc->tdtypeid == RECORDOID &&
677  tupdesc->tdtypmod < 0)
678  assign_record_type_typmod(tupdesc);
679 
681 
682  dtup = DatumGetHeapTupleHeader(heap_copy_tuple_as_datum(tuple, tupdesc));
683 
684  MemoryContextSwitchTo(oldcxt);
685 
686  return dtup;
687 }
Oid tdtypeid
Definition: tupdesc.h:77
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:39
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:41
#define RECORDOID
Definition: pg_type.h:680
MemoryContext savedcxt
Definition: spi_priv.h:33
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 587 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.

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

Definition at line 1376 of file spi.c.

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

Referenced by exec_stmt_fetch().

1377 {
1378  _SPI_cursor_operation(portal,
1379  direction, count,
1381  /* we know that the DestSPI receiver doesn't need a destroy call */
1382 }
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:2383
void SPI_scroll_cursor_move ( Portal  ,
FetchDirection  direction,
long  count 
)

Definition at line 1391 of file spi.c.

References _SPI_cursor_operation(), and None_Receiver.

Referenced by exec_stmt_fetch().

1392 {
1393  _SPI_cursor_operation(portal, direction, count, None_Receiver);
1394 }
DestReceiver * None_Receiver
Definition: dest.c:91
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:2383
int SPI_unregister_relation ( const char *  name)

Definition at line 2697 of file spi.c.

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

2698 {
2699  EphemeralNamedRelation match;
2700  int res;
2701 
2702  if (name == NULL)
2703  return SPI_ERROR_ARGUMENT;
2704 
2705  res = _SPI_begin_call(false); /* keep current memory context */
2706  if (res < 0)
2707  return res;
2708 
2709  match = _SPI_find_ENR_by_name(name);
2710  if (match)
2711  {
2713  res = SPI_OK_REL_UNREGISTER;
2714  }
2715  else
2717 
2718  _SPI_end_call(false);
2719 
2720  return res;
2721 }
EphemeralNamedRelationMetadataData md
#define SPI_ERROR_REL_NOT_FOUND
Definition: spi.h:48
static EphemeralNamedRelation _SPI_find_ENR_by_name(const char *name)
Definition: spi.c:2646
static _SPI_connection * _SPI_current
Definition: spi.c:45
#define SPI_ERROR_ARGUMENT
Definition: spi.h:41
QueryEnvironment * queryEnv
Definition: spi_priv.h:35
void unregister_ENR(QueryEnvironment *queryEnv, const char *name)
static int _SPI_end_call(bool procmem)
Definition: spi.c:2466
#define NULL
Definition: c.h:229
const char * name
Definition: encode.c:521
static int _SPI_begin_call(bool execmem)
Definition: spi.c:2449
#define SPI_OK_REL_UNREGISTER
Definition: spi.h:65

Variable Documentation