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

Go to the source code of this file.

Data Structures

struct  SPITupleTable
 
struct  SPIPrepareOptions
 
struct  SPIExecuteOptions
 
struct  SPIParseOpenOptions
 

Macros

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

Typedefs

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

Functions

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

Variables

PGDLLIMPORT uint64 SPI_processed
 
PGDLLIMPORT SPITupleTableSPI_tuptable
 
PGDLLIMPORT int SPI_result
 

Macro Definition Documentation

◆ SPI_ERROR_ARGUMENT

#define SPI_ERROR_ARGUMENT   (-6)

Definition at line 73 of file spi.h.

◆ SPI_ERROR_CONNECT

#define SPI_ERROR_CONNECT   (-1)

Definition at line 68 of file spi.h.

◆ SPI_ERROR_COPY

#define SPI_ERROR_COPY   (-2)

Definition at line 69 of file spi.h.

◆ SPI_ERROR_CURSOR

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

Definition at line 72 of file spi.h.

◆ SPI_ERROR_NOATTRIBUTE

#define SPI_ERROR_NOATTRIBUTE   (-9)

Definition at line 76 of file spi.h.

◆ SPI_ERROR_NOOUTFUNC

#define SPI_ERROR_NOOUTFUNC   (-10)

Definition at line 77 of file spi.h.

◆ SPI_ERROR_OPUNKNOWN

#define SPI_ERROR_OPUNKNOWN   (-3)

Definition at line 70 of file spi.h.

◆ SPI_ERROR_PARAM

#define SPI_ERROR_PARAM   (-7)

Definition at line 74 of file spi.h.

◆ SPI_ERROR_REL_DUPLICATE

#define SPI_ERROR_REL_DUPLICATE   (-12)

Definition at line 79 of file spi.h.

◆ SPI_ERROR_REL_NOT_FOUND

#define SPI_ERROR_REL_NOT_FOUND   (-13)

Definition at line 80 of file spi.h.

◆ SPI_ERROR_TRANSACTION

#define SPI_ERROR_TRANSACTION   (-8)

Definition at line 75 of file spi.h.

◆ SPI_ERROR_TYPUNKNOWN

#define SPI_ERROR_TYPUNKNOWN   (-11)

Definition at line 78 of file spi.h.

◆ SPI_ERROR_UNCONNECTED

#define SPI_ERROR_UNCONNECTED   (-4)

Definition at line 71 of file spi.h.

◆ SPI_OK_CONNECT

#define SPI_OK_CONNECT   1

Definition at line 82 of file spi.h.

◆ SPI_OK_CURSOR

#define SPI_OK_CURSOR   10

Definition at line 91 of file spi.h.

◆ SPI_OK_DELETE

#define SPI_OK_DELETE   8

Definition at line 89 of file spi.h.

◆ SPI_OK_DELETE_RETURNING

#define SPI_OK_DELETE_RETURNING   12

Definition at line 93 of file spi.h.

◆ SPI_OK_FETCH

#define SPI_OK_FETCH   3

Definition at line 84 of file spi.h.

◆ SPI_OK_FINISH

#define SPI_OK_FINISH   2

Definition at line 83 of file spi.h.

◆ SPI_OK_INSERT

#define SPI_OK_INSERT   7

Definition at line 88 of file spi.h.

◆ SPI_OK_INSERT_RETURNING

#define SPI_OK_INSERT_RETURNING   11

Definition at line 92 of file spi.h.

◆ SPI_OK_MERGE

#define SPI_OK_MERGE   18

Definition at line 99 of file spi.h.

◆ SPI_OK_MERGE_RETURNING

#define SPI_OK_MERGE_RETURNING   19

Definition at line 100 of file spi.h.

◆ SPI_OK_REL_REGISTER

#define SPI_OK_REL_REGISTER   15

Definition at line 96 of file spi.h.

◆ SPI_OK_REL_UNREGISTER

#define SPI_OK_REL_UNREGISTER   16

Definition at line 97 of file spi.h.

◆ SPI_OK_REWRITTEN

#define SPI_OK_REWRITTEN   14

Definition at line 95 of file spi.h.

◆ SPI_OK_SELECT

#define SPI_OK_SELECT   5

Definition at line 86 of file spi.h.

◆ SPI_OK_SELINTO

#define SPI_OK_SELINTO   6

Definition at line 87 of file spi.h.

◆ SPI_OK_TD_REGISTER

#define SPI_OK_TD_REGISTER   17

Definition at line 98 of file spi.h.

◆ SPI_OK_UPDATE

#define SPI_OK_UPDATE   9

Definition at line 90 of file spi.h.

◆ SPI_OK_UPDATE_RETURNING

#define SPI_OK_UPDATE_RETURNING   13

Definition at line 94 of file spi.h.

◆ SPI_OK_UTILITY

#define SPI_OK_UTILITY   4

Definition at line 85 of file spi.h.

◆ SPI_OPT_NONATOMIC

#define SPI_OPT_NONATOMIC   (1 << 0)

Definition at line 102 of file spi.h.

Typedef Documentation

◆ SPIExecuteOptions

◆ SPIParseOpenOptions

◆ SPIPlanPtr

typedef struct _SPI_plan* SPIPlanPtr

Definition at line 66 of file spi.h.

◆ SPIPrepareOptions

◆ SPITupleTable

typedef struct SPITupleTable SPITupleTable

Function Documentation

◆ AtEOSubXact_SPI()

void AtEOSubXact_SPI ( bool  isCommit,
SubTransactionId  mySubid 
)

Definition at line 482 of file spi.c.

483{
484 bool found = false;
485
486 while (_SPI_connected >= 0)
487 {
489
490 if (connection->connectSubid != mySubid)
491 break; /* couldn't be any underneath it either */
492
493 if (connection->internal_xact)
494 break;
495
496 found = true;
497
498 /*
499 * Release procedure memory explicitly (see note in SPI_connect)
500 */
501 if (connection->execCxt)
502 {
504 connection->execCxt = NULL;
505 }
506 if (connection->procCxt)
507 {
509 connection->procCxt = NULL;
510 }
511
512 /*
513 * Restore outer global variables and pop the stack entry. Unlike
514 * SPI_finish(), we don't risk switching to memory contexts that might
515 * be already gone.
516 */
517 SPI_processed = connection->outer_processed;
518 SPI_tuptable = connection->outer_tuptable;
519 SPI_result = connection->outer_result;
520
522 if (_SPI_connected < 0)
523 _SPI_current = NULL;
524 else
526 }
527
528 if (found && isCommit)
530 (errcode(ERRCODE_WARNING),
531 errmsg("subtransaction left non-empty SPI stack"),
532 errhint("Check for missing \"SPI_finish\" calls.")));
533
534 /*
535 * If we are aborting a subtransaction and there is an open SPI context
536 * surrounding the subxact, clean up to prevent memory leakage.
537 */
538 if (_SPI_current && !isCommit)
539 {
540 slist_mutable_iter siter;
541
542 /*
543 * Throw away executor state if current executor operation was started
544 * within current subxact (essentially, force a _SPI_end_call(true)).
545 */
546 if (_SPI_current->execSubid >= mySubid)
547 {
550 }
551
552 /* throw away any tuple tables created within current subxact */
554 {
555 SPITupleTable *tuptable;
556
557 tuptable = slist_container(SPITupleTable, next, siter.cur);
558 if (tuptable->subid >= mySubid)
559 {
560 /*
561 * If we used SPI_freetuptable() here, its internal search of
562 * the tuptables list would make this operation O(N^2).
563 * Instead, just free the tuptable manually. This should
564 * match what SPI_freetuptable() does.
565 */
566 slist_delete_current(&siter);
567 if (tuptable == _SPI_current->tuptable)
568 _SPI_current->tuptable = NULL;
569 if (tuptable == SPI_tuptable)
570 SPI_tuptable = NULL;
572 }
573 }
574 }
575}
static int32 next
Definition: blutils.c:224
#define InvalidSubTransactionId
Definition: c.h:629
int errhint(const char *fmt,...)
Definition: elog.c:1318
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define WARNING
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:149
static void slist_delete_current(slist_mutable_iter *iter)
Definition: ilist.h:1084
#define slist_foreach_modify(iter, lhead)
Definition: ilist.h:1148
#define slist_container(type, membername, ptr)
Definition: ilist.h:1106
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
static int _SPI_connected
Definition: spi.c:51
uint64 SPI_processed
Definition: spi.c:44
static _SPI_connection * _SPI_stack
Definition: spi.c:48
SPITupleTable * SPI_tuptable
Definition: spi.c:45
int SPI_result
Definition: spi.c:46
static _SPI_connection * _SPI_current
Definition: spi.c:49
MemoryContext tuptabcxt
Definition: spi.h:31
SubTransactionId subid
Definition: spi.h:33
slist_head tuptables
Definition: spi_priv.h:32
MemoryContext execCxt
Definition: spi_priv.h:34
SubTransactionId execSubid
Definition: spi_priv.h:29
SPITupleTable * tuptable
Definition: spi_priv.h:26
slist_node * cur
Definition: ilist.h:274

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_SPI()

void AtEOXact_SPI ( bool  isCommit)

Definition at line 428 of file spi.c.

429{
430 bool found = false;
431
432 /*
433 * Pop stack entries, stopping if we find one marked internal_xact (that
434 * one belongs to the caller of SPI_commit or SPI_rollback).
435 */
436 while (_SPI_connected >= 0)
437 {
439
440 if (connection->internal_xact)
441 break;
442
443 found = true;
444
445 /*
446 * We need not release the procedure's memory contexts explicitly, as
447 * they'll go away automatically when their parent context does; see
448 * notes in SPI_connect_ext.
449 */
450
451 /*
452 * Restore outer global variables and pop the stack entry. Unlike
453 * SPI_finish(), we don't risk switching to memory contexts that might
454 * be already gone.
455 */
456 SPI_processed = connection->outer_processed;
457 SPI_tuptable = connection->outer_tuptable;
458 SPI_result = connection->outer_result;
459
461 if (_SPI_connected < 0)
462 _SPI_current = NULL;
463 else
465 }
466
467 /* We should only find entries to pop during an ABORT. */
468 if (found && isCommit)
470 (errcode(ERRCODE_WARNING),
471 errmsg("transaction left non-empty SPI stack"),
472 errhint("Check for missing \"SPI_finish\" calls.")));
473}

References _SPI_connected, _SPI_current, _SPI_stack, ereport, errcode(), errhint(), errmsg(), SPI_processed, SPI_result, SPI_tuptable, and WARNING.

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

◆ SPI_commit()

void SPI_commit ( void  )

Definition at line 320 of file spi.c.

321{
322 _SPI_commit(false);
323}
static void _SPI_commit(bool chain)
Definition: spi.c:227

References _SPI_commit().

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

◆ SPI_commit_and_chain()

void SPI_commit_and_chain ( void  )

Definition at line 326 of file spi.c.

327{
328 _SPI_commit(true);
329}

References _SPI_commit().

Referenced by exec_stmt_commit().

◆ SPI_connect()

◆ SPI_connect_ext()

int SPI_connect_ext ( int  options)

Definition at line 100 of file spi.c.

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

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

Referenced by plperl_func_handler(), plperl_inline_handler(), plpgsql_call_handler(), plpgsql_inline_handler(), plpython3_call_handler(), plpython3_inline_handler(), pltcl_func_handler(), and SPI_connect().

◆ SPI_copytuple()

HeapTuple SPI_copytuple ( HeapTuple  tuple)

Definition at line 1047 of file spi.c.

1048{
1049 MemoryContext oldcxt;
1050 HeapTuple ctuple;
1051
1052 if (tuple == NULL)
1053 {
1055 return NULL;
1056 }
1057
1058 if (_SPI_current == NULL)
1059 {
1061 return NULL;
1062 }
1063
1065
1066 ctuple = heap_copytuple(tuple);
1067
1068 MemoryContextSwitchTo(oldcxt);
1069
1070 return ctuple;
1071}
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:778
#define SPI_ERROR_UNCONNECTED
Definition: spi.h:71
#define SPI_ERROR_ARGUMENT
Definition: spi.h:73

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

Referenced by get_tuple_of_interest(), and plpgsql_exec_trigger().

◆ SPI_cursor_close()

void SPI_cursor_close ( Portal  portal)

Definition at line 1862 of file spi.c.

1863{
1864 if (!PortalIsValid(portal))
1865 elog(ERROR, "invalid portal in SPI cursor operation");
1866
1867 PortalDrop(portal, false);
1868}
#define PortalIsValid(p)
Definition: portal.h:211
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:468

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

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

◆ SPI_cursor_fetch()

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

Definition at line 1806 of file spi.c.

1807{
1808 _SPI_cursor_operation(portal,
1809 forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1811 /* we know that the DestSPI receiver doesn't need a destroy call */
1812}
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:113
@ DestSPI
Definition: dest.h:92
@ FETCH_FORWARD
Definition: parsenodes.h:3413
@ FETCH_BACKWARD
Definition: parsenodes.h:3414
static void _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest)
Definition: spi.c:3007

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

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

◆ SPI_cursor_find()

Portal SPI_cursor_find ( const char *  name)

Definition at line 1794 of file spi.c.

1795{
1796 return GetPortalByName(name);
1797}
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
const char * name

References GetPortalByName(), and name.

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

◆ SPI_cursor_move()

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

Definition at line 1821 of file spi.c.

1822{
1823 _SPI_cursor_operation(portal,
1824 forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1826}
DestReceiver * None_Receiver
Definition: dest.c:96

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

◆ SPI_cursor_open()

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

Definition at line 1445 of file spi.c.

1448{
1449 Portal portal;
1450 ParamListInfo paramLI;
1451
1452 /* build transient ParamListInfo in caller's context */
1453 paramLI = _SPI_convert_params(plan->nargs, plan->argtypes,
1454 Values, Nulls);
1455
1456 portal = SPI_cursor_open_internal(name, plan, paramLI, read_only);
1457
1458 /* done with the transient ParamListInfo */
1459 if (paramLI)
1460 pfree(paramLI);
1461
1462 return portal;
1463}
static bool Nulls[MAXATTR]
Definition: bootstrap.c:152
void pfree(void *pointer)
Definition: mcxt.c:1528
#define plan(x)
Definition: pg_regress.c:161
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls)
Definition: spi.c:2849
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only)
Definition: spi.c:1577

References _SPI_convert_params(), name, Nulls, pfree(), plan, and SPI_cursor_open_internal().

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

◆ SPI_cursor_open_with_args()

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

Definition at line 1472 of file spi.c.

1477{
1478 Portal result;
1480 ParamListInfo paramLI;
1481
1482 if (src == NULL || nargs < 0)
1483 elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
1484
1485 if (nargs > 0 && (argtypes == NULL || Values == NULL))
1486 elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
1487
1489 if (SPI_result < 0)
1490 elog(ERROR, "SPI_cursor_open_with_args called while not connected");
1491
1492 memset(&plan, 0, sizeof(_SPI_plan));
1493 plan.magic = _SPI_PLAN_MAGIC;
1494 plan.parse_mode = RAW_PARSE_DEFAULT;
1495 plan.cursor_options = cursorOptions;
1496 plan.nargs = nargs;
1497 plan.argtypes = argtypes;
1498 plan.parserSetup = NULL;
1499 plan.parserSetupArg = NULL;
1500
1501 /* build transient ParamListInfo in executor context */
1502 paramLI = _SPI_convert_params(nargs, argtypes,
1503 Values, Nulls);
1504
1505 _SPI_prepare_plan(src, &plan);
1506
1507 /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1508
1509 result = SPI_cursor_open_internal(name, &plan, paramLI, read_only);
1510
1511 /* And clean up */
1512 _SPI_end_call(true);
1513
1514 return result;
1515}
@ RAW_PARSE_DEFAULT
Definition: parser.h:39
static int _SPI_end_call(bool use_exec)
Definition: spi.c:3101
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2221
static int _SPI_begin_call(bool use_exec)
Definition: spi.c:3077
#define _SPI_PLAN_MAGIC
Definition: spi_priv.h:20

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), elog, ERROR, name, Nulls, plan, RAW_PARSE_DEFAULT, SPI_cursor_open_internal(), and SPI_result.

◆ SPI_cursor_open_with_paramlist()

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

Definition at line 1525 of file spi.c.

1527{
1528 return SPI_cursor_open_internal(name, plan, params, read_only);
1529}

References name, plan, and SPI_cursor_open_internal().

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

◆ SPI_cursor_parse_open()

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

Definition at line 1533 of file spi.c.

1536{
1537 Portal result;
1539
1540 if (src == NULL || options == NULL)
1541 elog(ERROR, "SPI_cursor_parse_open called with invalid arguments");
1542
1544 if (SPI_result < 0)
1545 elog(ERROR, "SPI_cursor_parse_open called while not connected");
1546
1547 memset(&plan, 0, sizeof(_SPI_plan));
1548 plan.magic = _SPI_PLAN_MAGIC;
1549 plan.parse_mode = RAW_PARSE_DEFAULT;
1550 plan.cursor_options = options->cursorOptions;
1551 if (options->params)
1552 {
1553 plan.parserSetup = options->params->parserSetup;
1554 plan.parserSetupArg = options->params->parserSetupArg;
1555 }
1556
1557 _SPI_prepare_plan(src, &plan);
1558
1559 /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1560
1562 options->params, options->read_only);
1563
1564 /* And clean up */
1565 _SPI_end_call(true);
1566
1567 return result;
1568}

References _SPI_begin_call(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), elog, ERROR, name, plan, RAW_PARSE_DEFAULT, SPI_cursor_open_internal(), and SPI_result.

Referenced by exec_dynquery_with_params().

◆ SPI_datumTransfer()

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

Definition at line 1361 of file spi.c.

1362{
1363 MemoryContext oldcxt;
1364 Datum result;
1365
1366 if (_SPI_current == NULL)
1367 elog(ERROR, "SPI_datumTransfer called while not connected to SPI");
1368
1370
1371 result = datumTransfer(value, typByVal, typLen);
1372
1373 MemoryContextSwitchTo(oldcxt);
1374
1375 return result;
1376}
Datum datumTransfer(Datum value, bool typByVal, int typLen)
Definition: datum.c:194
static struct @165 value
uintptr_t Datum
Definition: postgres.h:69

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

Referenced by coerce_function_result_tuple(), and plpgsql_exec_function().

◆ SPI_exec()

int SPI_exec ( const char *  src,
long  tcount 
)

Definition at line 630 of file spi.c.

631{
632 return SPI_execute(src, false, tcount);
633}
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:596

References SPI_execute().

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

◆ SPI_execp()

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

Definition at line 704 of file spi.c.

705{
706 return SPI_execute_plan(plan, Values, Nulls, false, tcount);
707}
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
Definition: spi.c:672

References Nulls, plan, and SPI_execute_plan().

Referenced by check_foreign_key(), and check_primary_key().

◆ SPI_execute()

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

Definition at line 596 of file spi.c.

597{
600 int res;
601
602 if (src == NULL || tcount < 0)
603 return SPI_ERROR_ARGUMENT;
604
605 res = _SPI_begin_call(true);
606 if (res < 0)
607 return res;
608
609 memset(&plan, 0, sizeof(_SPI_plan));
610 plan.magic = _SPI_PLAN_MAGIC;
611 plan.parse_mode = RAW_PARSE_DEFAULT;
612 plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
613
615
616 memset(&options, 0, sizeof(options));
617 options.read_only = read_only;
618 options.tcount = tcount;
619
622 true);
623
624 _SPI_end_call(true);
625 return res;
626}
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:3385
static char ** options
#define InvalidSnapshot
Definition: snapshot.h:119
static int _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options, Snapshot snapshot, Snapshot crosscheck_snapshot, bool fire_triggers)
Definition: spi.c:2399
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
Definition: spi.c:2329

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_prepare_oneshot_plan(), CURSOR_OPT_PARALLEL_OK, InvalidSnapshot, options, plan, RAW_PARSE_DEFAULT, and SPI_ERROR_ARGUMENT.

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

◆ SPI_execute_extended()

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

Definition at line 637 of file spi.c.

639{
640 int res;
642
643 if (src == NULL || options == NULL)
644 return SPI_ERROR_ARGUMENT;
645
646 res = _SPI_begin_call(true);
647 if (res < 0)
648 return res;
649
650 memset(&plan, 0, sizeof(_SPI_plan));
651 plan.magic = _SPI_PLAN_MAGIC;
652 plan.parse_mode = RAW_PARSE_DEFAULT;
653 plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
654 if (options->params)
655 {
656 plan.parserSetup = options->params->parserSetup;
657 plan.parserSetupArg = options->params->parserSetupArg;
658 }
659
661
664 true);
665
666 _SPI_end_call(true);
667 return res;
668}

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_prepare_oneshot_plan(), CURSOR_OPT_PARALLEL_OK, InvalidSnapshot, plan, RAW_PARSE_DEFAULT, and SPI_ERROR_ARGUMENT.

Referenced by exec_stmt_dynexecute(), and exec_stmt_return_query().

◆ SPI_execute_plan()

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

Definition at line 672 of file spi.c.

674{
676 int res;
677
678 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
679 return SPI_ERROR_ARGUMENT;
680
681 if (plan->nargs > 0 && Values == NULL)
682 return SPI_ERROR_PARAM;
683
684 res = _SPI_begin_call(true);
685 if (res < 0)
686 return res;
687
688 memset(&options, 0, sizeof(options));
689 options.params = _SPI_convert_params(plan->nargs, plan->argtypes,
690 Values, Nulls);
691 options.read_only = read_only;
692 options.tcount = tcount;
693
696 true);
697
698 _SPI_end_call(true);
699 return res;
700}
#define SPI_ERROR_PARAM
Definition: spi.h:74

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, InvalidSnapshot, Nulls, options, plan, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

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

◆ SPI_execute_plan_extended()

int SPI_execute_plan_extended ( SPIPlanPtr  plan,
const SPIExecuteOptions options 
)

Definition at line 711 of file spi.c.

713{
714 int res;
715
716 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || options == NULL)
717 return SPI_ERROR_ARGUMENT;
718
719 res = _SPI_begin_call(true);
720 if (res < 0)
721 return res;
722
725 true);
726
727 _SPI_end_call(true);
728 return res;
729}

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, InvalidSnapshot, plan, and SPI_ERROR_ARGUMENT.

Referenced by exec_stmt_call(), and exec_stmt_return_query().

◆ SPI_execute_plan_with_paramlist()

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

Definition at line 733 of file spi.c.

735{
737 int res;
738
739 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
740 return SPI_ERROR_ARGUMENT;
741
742 res = _SPI_begin_call(true);
743 if (res < 0)
744 return res;
745
746 memset(&options, 0, sizeof(options));
747 options.params = params;
748 options.read_only = read_only;
749 options.tcount = tcount;
750
753 true);
754
755 _SPI_end_call(true);
756 return res;
757}

References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, InvalidSnapshot, options, plan, and SPI_ERROR_ARGUMENT.

Referenced by exec_run_select(), and exec_stmt_execsql().

◆ SPI_execute_snapshot()

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

Definition at line 773 of file spi.c.

777{
779 int res;
780
781 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
782 return SPI_ERROR_ARGUMENT;
783
784 if (plan->nargs > 0 && Values == NULL)
785 return SPI_ERROR_PARAM;
786
787 res = _SPI_begin_call(true);
788 if (res < 0)
789 return res;
790
791 memset(&options, 0, sizeof(options));
792 options.params = _SPI_convert_params(plan->nargs, plan->argtypes,
793 Values, Nulls);
794 options.read_only = read_only;
795 options.tcount = tcount;
796
798 snapshot, crosscheck_snapshot,
799 fire_triggers);
800
801 _SPI_end_call(true);
802 return res;
803}

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, Nulls, options, plan, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

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

◆ SPI_execute_with_args()

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

Definition at line 812 of file spi.c.

816{
817 int res;
819 ParamListInfo paramLI;
821
822 if (src == NULL || nargs < 0 || tcount < 0)
823 return SPI_ERROR_ARGUMENT;
824
825 if (nargs > 0 && (argtypes == NULL || Values == NULL))
826 return SPI_ERROR_PARAM;
827
828 res = _SPI_begin_call(true);
829 if (res < 0)
830 return res;
831
832 memset(&plan, 0, sizeof(_SPI_plan));
833 plan.magic = _SPI_PLAN_MAGIC;
834 plan.parse_mode = RAW_PARSE_DEFAULT;
835 plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
836 plan.nargs = nargs;
837 plan.argtypes = argtypes;
838 plan.parserSetup = NULL;
839 plan.parserSetupArg = NULL;
840
841 paramLI = _SPI_convert_params(nargs, argtypes,
842 Values, Nulls);
843
845
846 memset(&options, 0, sizeof(options));
847 options.params = paramLI;
848 options.read_only = read_only;
849 options.tcount = tcount;
850
853 true);
854
855 _SPI_end_call(true);
856 return res;
857}

References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, _SPI_prepare_oneshot_plan(), CURSOR_OPT_PARALLEL_OK, InvalidSnapshot, Nulls, options, plan, RAW_PARSE_DEFAULT, SPI_ERROR_ARGUMENT, and SPI_ERROR_PARAM.

◆ SPI_finish()

int SPI_finish ( void  )

Definition at line 182 of file spi.c.

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

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

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

◆ SPI_fname()

char * SPI_fname ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1198 of file spi.c.

1199{
1200 const FormData_pg_attribute *att;
1201
1202 SPI_result = 0;
1203
1204 if (fnumber > tupdesc->natts || fnumber == 0 ||
1206 {
1208 return NULL;
1209 }
1210
1211 if (fnumber > 0)
1212 att = TupleDescAttr(tupdesc, fnumber - 1);
1213 else
1214 att = SystemAttributeDefinition(fnumber);
1215
1216 return pstrdup(NameStr(att->attname));
1217}
#define NameStr(name)
Definition: c.h:717
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition: heap.c:236
char * pstrdup(const char *in)
Definition: mcxt.c:1703
FormData_pg_attribute
Definition: pg_attribute.h:186
#define SPI_ERROR_NOATTRIBUTE
Definition: spi.h:76
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160

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

Referenced by get_pkey_attnames(), and SPI_sql_row_to_xmlelement().

◆ SPI_fnumber()

int SPI_fnumber ( TupleDesc  tupdesc,
const char *  fname 
)

Definition at line 1175 of file spi.c.

1176{
1177 int res;
1178 const FormData_pg_attribute *sysatt;
1179
1180 for (res = 0; res < tupdesc->natts; res++)
1181 {
1182 Form_pg_attribute attr = TupleDescAttr(tupdesc, res);
1183
1184 if (namestrcmp(&attr->attname, fname) == 0 &&
1185 !attr->attisdropped)
1186 return res + 1;
1187 }
1188
1189 sysatt = SystemAttributeByName(fname);
1190 if (sysatt != NULL)
1191 return sysatt->attnum;
1192
1193 /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
1194 return SPI_ERROR_NOATTRIBUTE;
1195}
const FormData_pg_attribute * SystemAttributeByName(const char *attname)
Definition: heap.c:248
int namestrcmp(Name name, const char *str)
Definition: name.c:247
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202

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

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

◆ SPI_freeplan()

int SPI_freeplan ( SPIPlanPtr  plan)

Definition at line 1025 of file spi.c.

1026{
1027 ListCell *lc;
1028
1029 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1030 return SPI_ERROR_ARGUMENT;
1031
1032 /* Release the plancache entries */
1033 foreach(lc, plan->plancache_list)
1034 {
1035 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1036
1037 DropCachedPlan(plansource);
1038 }
1039
1040 /* Now get rid of the _SPI_plan and subsidiary data in its plancxt */
1041 MemoryContextDelete(plan->plancxt);
1042
1043 return 0;
1044}
#define lfirst(lc)
Definition: pg_list.h:172
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:574

References _SPI_PLAN_MAGIC, DropCachedPlan(), lfirst, MemoryContextDelete(), plan, and SPI_ERROR_ARGUMENT.

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

◆ SPI_freetuple()

void SPI_freetuple ( HeapTuple  tuple)

Definition at line 1379 of file spi.c.

1380{
1381 /* No longer need to worry which context tuple was in... */
1382 heap_freetuple(tuple);
1383}
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435

References heap_freetuple().

◆ SPI_freetuptable()

void SPI_freetuptable ( SPITupleTable tuptable)

Definition at line 1386 of file spi.c.

1387{
1388 bool found = false;
1389
1390 /* ignore call if NULL pointer */
1391 if (tuptable == NULL)
1392 return;
1393
1394 /*
1395 * Search only the topmost SPI context for a matching tuple table.
1396 */
1397 if (_SPI_current != NULL)
1398 {
1399 slist_mutable_iter siter;
1400
1401 /* find tuptable in active list, then remove it */
1403 {
1404 SPITupleTable *tt;
1405
1406 tt = slist_container(SPITupleTable, next, siter.cur);
1407 if (tt == tuptable)
1408 {
1409 slist_delete_current(&siter);
1410 found = true;
1411 break;
1412 }
1413 }
1414 }
1415
1416 /*
1417 * Refuse the deletion if we didn't find it in the topmost SPI context.
1418 * This is primarily a guard against double deletion, but might prevent
1419 * other errors as well. Since the worst consequence of not deleting a
1420 * tuptable would be a transient memory leak, this is just a WARNING.
1421 */
1422 if (!found)
1423 {
1424 elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);
1425 return;
1426 }
1427
1428 /* for safety, reset global variables that might point at tuptable */
1429 if (tuptable == _SPI_current->tuptable)
1430 _SPI_current->tuptable = NULL;
1431 if (tuptable == SPI_tuptable)
1432 SPI_tuptable = NULL;
1433
1434 /* release all memory belonging to tuptable */
1435 MemoryContextDelete(tuptable->tuptabcxt);
1436}

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

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

◆ SPI_getargcount()

int SPI_getargcount ( SPIPlanPtr  plan)

Definition at line 1890 of file spi.c.

1891{
1892 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1893 {
1895 return -1;
1896 }
1897 return plan->nargs;
1898}

References _SPI_PLAN_MAGIC, plan, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_getargtypeid()

Oid SPI_getargtypeid ( SPIPlanPtr  plan,
int  argIndex 
)

Definition at line 1875 of file spi.c.

1876{
1877 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
1878 argIndex < 0 || argIndex >= plan->nargs)
1879 {
1881 return InvalidOid;
1882 }
1883 return plan->argtypes[argIndex];
1884}
#define InvalidOid
Definition: postgres_ext.h:35

References _SPI_PLAN_MAGIC, InvalidOid, plan, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_getbinval()

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

Definition at line 1252 of file spi.c.

1253{
1254 SPI_result = 0;
1255
1256 if (fnumber > tupdesc->natts || fnumber == 0 ||
1258 {
1260 *isnull = true;
1261 return (Datum) NULL;
1262 }
1263
1264 return heap_getattr(tuple, fnumber, tupdesc, isnull);
1265}
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:904

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

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

◆ SPI_getnspname()

char * SPI_getnspname ( Relation  rel)

Definition at line 1332 of file spi.c.

1333{
1335}
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3506
#define RelationGetNamespace(relation)
Definition: rel.h:557

References get_namespace_name(), and RelationGetNamespace.

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

◆ SPI_getrelname()

char * SPI_getrelname ( Relation  rel)

◆ SPI_gettype()

char * SPI_gettype ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1268 of file spi.c.

1269{
1270 Oid typoid;
1271 HeapTuple typeTuple;
1272 char *result;
1273
1274 SPI_result = 0;
1275
1276 if (fnumber > tupdesc->natts || fnumber == 0 ||
1278 {
1280 return NULL;
1281 }
1282
1283 if (fnumber > 0)
1284 typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1285 else
1286 typoid = (SystemAttributeDefinition(fnumber))->atttypid;
1287
1288 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
1289
1290 if (!HeapTupleIsValid(typeTuple))
1291 {
1293 return NULL;
1294 }
1295
1296 result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
1297 ReleaseSysCache(typeTuple);
1298 return result;
1299}
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
NameData typname
Definition: pg_type.h:41
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
unsigned int Oid
Definition: postgres_ext.h:30
#define SPI_ERROR_TYPUNKNOWN
Definition: spi.h:78
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

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

Referenced by check_foreign_key().

◆ SPI_gettypeid()

Oid SPI_gettypeid ( TupleDesc  tupdesc,
int  fnumber 
)

Definition at line 1308 of file spi.c.

1309{
1310 SPI_result = 0;
1311
1312 if (fnumber > tupdesc->natts || fnumber == 0 ||
1314 {
1316 return InvalidOid;
1317 }
1318
1319 if (fnumber > 0)
1320 return TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1321 else
1322 return (SystemAttributeDefinition(fnumber))->atttypid;
1323}

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

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

◆ SPI_getvalue()

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

Definition at line 1220 of file spi.c.

1221{
1222 Datum val;
1223 bool isnull;
1224 Oid typoid,
1225 foutoid;
1226 bool typisvarlena;
1227
1228 SPI_result = 0;
1229
1230 if (fnumber > tupdesc->natts || fnumber == 0 ||
1232 {
1234 return NULL;
1235 }
1236
1237 val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
1238 if (isnull)
1239 return NULL;
1240
1241 if (fnumber > 0)
1242 typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
1243 else
1244 typoid = (SystemAttributeDefinition(fnumber))->atttypid;
1245
1246 getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
1247
1248 return OidOutputFunctionCall(foutoid, val);
1249}
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1763
long val
Definition: informix.c:689
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:3047

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

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

◆ SPI_inside_nonatomic_context()

bool SPI_inside_nonatomic_context ( void  )

Definition at line 581 of file spi.c.

582{
583 if (_SPI_current == NULL)
584 return false; /* not in any SPI context at all */
585 /* these tests must match _SPI_commit's opinion of what's atomic: */
586 if (_SPI_current->atomic)
587 return false; /* it's atomic (ie function not procedure) */
588 if (IsSubTransaction())
589 return false; /* if within subtransaction, it's atomic */
590 return true;
591}
bool IsSubTransaction(void)
Definition: xact.c:5044

References _SPI_current, _SPI_connection::atomic, and IsSubTransaction().

Referenced by StartTransaction().

◆ SPI_is_cursor_plan()

bool SPI_is_cursor_plan ( SPIPlanPtr  plan)

Definition at line 1910 of file spi.c.

1911{
1912 CachedPlanSource *plansource;
1913
1914 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1915 {
1917 return false;
1918 }
1919
1920 if (list_length(plan->plancache_list) != 1)
1921 {
1922 SPI_result = 0;
1923 return false; /* not exactly 1 pre-rewrite command */
1924 }
1925 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1926
1927 /*
1928 * We used to force revalidation of the cached plan here, but that seems
1929 * unnecessary: invalidation could mean a change in the rowtype of the
1930 * tuples returned by a plan, but not whether it returns tuples at all.
1931 */
1932 SPI_result = 0;
1933
1934 /* Does it return tuples? */
1935 if (plansource->resultDesc)
1936 return true;
1937
1938 return false;
1939}
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial(l)
Definition: pg_list.h:178
TupleDesc resultDesc
Definition: plancache.h:120

References _SPI_PLAN_MAGIC, linitial, list_length(), plan, CachedPlanSource::resultDesc, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by SPI_cursor_open_internal().

◆ SPI_keepplan()

int SPI_keepplan ( SPIPlanPtr  plan)

Definition at line 976 of file spi.c.

977{
978 ListCell *lc;
979
980 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
981 plan->saved || plan->oneshot)
982 return SPI_ERROR_ARGUMENT;
983
984 /*
985 * Mark it saved, reparent it under CacheMemoryContext, and mark all the
986 * component CachedPlanSources as saved. This sequence cannot fail
987 * partway through, so there's no risk of long-term memory leakage.
988 */
989 plan->saved = true;
991
992 foreach(lc, plan->plancache_list)
993 {
994 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
995
996 SaveCachedPlan(plansource);
997 }
998
999 return 0;
1000}
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:637
MemoryContext CacheMemoryContext
Definition: mcxt.c:152
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:530

References _SPI_PLAN_MAGIC, CacheMemoryContext, lfirst, MemoryContextSetParent(), plan, SaveCachedPlan(), 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(), and ri_PlanCheck().

◆ SPI_modifytuple()

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

Definition at line 1106 of file spi.c.

1108{
1109 MemoryContext oldcxt;
1110 HeapTuple mtuple;
1111 int numberOfAttributes;
1112 Datum *v;
1113 bool *n;
1114 int i;
1115
1116 if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
1117 {
1119 return NULL;
1120 }
1121
1122 if (_SPI_current == NULL)
1123 {
1125 return NULL;
1126 }
1127
1129
1130 SPI_result = 0;
1131
1132 numberOfAttributes = rel->rd_att->natts;
1133 v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
1134 n = (bool *) palloc(numberOfAttributes * sizeof(bool));
1135
1136 /* fetch old values and nulls */
1137 heap_deform_tuple(tuple, rel->rd_att, v, n);
1138
1139 /* replace values and nulls */
1140 for (i = 0; i < natts; i++)
1141 {
1142 if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
1143 break;
1144 v[attnum[i] - 1] = Values[i];
1145 n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n');
1146 }
1147
1148 if (i == natts) /* no errors in *attnum */
1149 {
1150 mtuple = heap_form_tuple(rel->rd_att, v, n);
1151
1152 /*
1153 * copy the identification info of the old tuple: t_ctid, t_self, and
1154 * OID (if any)
1155 */
1156 mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
1157 mtuple->t_self = tuple->t_self;
1158 mtuple->t_tableOid = tuple->t_tableOid;
1159 }
1160 else
1161 {
1162 mtuple = NULL;
1164 }
1165
1166 pfree(v);
1167 pfree(n);
1168
1169 MemoryContextSwitchTo(oldcxt);
1170
1171 return mtuple;
1172}
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1346
int i
Definition: isn.c:77
void * palloc(Size size)
Definition: mcxt.c:1321
int16 attnum
Definition: pg_attribute.h:74
ItemPointerData t_self
Definition: htup.h:65
HeapTupleHeader t_data
Definition: htup.h:68
Oid t_tableOid
Definition: htup.h:66
ItemPointerData t_ctid
Definition: htup_details.h:161
TupleDesc rd_att
Definition: rel.h:112

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

◆ SPI_palloc()

void * SPI_palloc ( Size  size)

Definition at line 1338 of file spi.c.

1339{
1340 if (_SPI_current == NULL)
1341 elog(ERROR, "SPI_palloc called while not connected to SPI");
1342
1344}

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

Referenced by _SPI_strdup(), and coerce_function_result_tuple().

◆ SPI_pfree()

void SPI_pfree ( void *  pointer)

Definition at line 1354 of file spi.c.

1355{
1356 /* No longer need to worry which context chunk was in... */
1357 pfree(pointer);
1358}

References pfree().

◆ SPI_plan_get_cached_plan()

CachedPlan * SPI_plan_get_cached_plan ( SPIPlanPtr  plan)

Definition at line 2076 of file spi.c.

2077{
2078 CachedPlanSource *plansource;
2079 CachedPlan *cplan;
2080 SPICallbackArg spicallbackarg;
2081 ErrorContextCallback spierrcontext;
2082
2083 Assert(plan->magic == _SPI_PLAN_MAGIC);
2084
2085 /* Can't support one-shot plans here */
2086 if (plan->oneshot)
2087 return NULL;
2088
2089 /* Must have exactly one CachedPlanSource */
2090 if (list_length(plan->plancache_list) != 1)
2091 return NULL;
2092 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
2093
2094 /* Setup error traceback support for ereport() */
2095 spicallbackarg.query = plansource->query_string;
2096 spicallbackarg.mode = plan->parse_mode;
2097 spierrcontext.callback = _SPI_error_callback;
2098 spierrcontext.arg = &spicallbackarg;
2099 spierrcontext.previous = error_context_stack;
2100 error_context_stack = &spierrcontext;
2101
2102 /* Get the generic plan for the query */
2103 cplan = GetCachedPlan(plansource, NULL,
2104 plan->saved ? CurrentResourceOwner : NULL,
2106 Assert(cplan == plansource->gplan);
2107
2108 /* Pop the error context stack */
2109 error_context_stack = spierrcontext.previous;
2110
2111 return cplan;
2112}
ErrorContextCallback * error_context_stack
Definition: elog.c:95
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
Definition: plancache.c:1280
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
static void _SPI_error_callback(void *arg)
Definition: spi.c:2961
struct CachedPlan * gplan
Definition: plancache.h:133
const char * query_string
Definition: plancache.h:110
struct ErrorContextCallback * previous
Definition: elog.h:296
void(* callback)(void *arg)
Definition: elog.h:297
const char * query
Definition: spi.c:55
RawParseMode mode
Definition: spi.c:56

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

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

◆ SPI_plan_get_plan_sources()

List * SPI_plan_get_plan_sources ( SPIPlanPtr  plan)

Definition at line 2057 of file spi.c.

2058{
2059 Assert(plan->magic == _SPI_PLAN_MAGIC);
2060 return plan->plancache_list;
2061}

References _SPI_PLAN_MAGIC, Assert(), and plan.

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

◆ SPI_plan_is_valid()

bool SPI_plan_is_valid ( SPIPlanPtr  plan)

Definition at line 1948 of file spi.c.

1949{
1950 ListCell *lc;
1951
1952 Assert(plan->magic == _SPI_PLAN_MAGIC);
1953
1954 foreach(lc, plan->plancache_list)
1955 {
1956 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1957
1958 if (!CachedPlanIsValid(plansource))
1959 return false;
1960 }
1961 return true;
1962}
bool CachedPlanIsValid(CachedPlanSource *plansource)
Definition: plancache.c:1742

References _SPI_PLAN_MAGIC, Assert(), CachedPlanIsValid(), lfirst, and plan.

Referenced by ri_FetchPreparedPlan().

◆ SPI_prepare()

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

◆ SPI_prepare_cursor()

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

Definition at line 866 of file spi.c.

868{
870 SPIPlanPtr result;
871
872 if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
873 {
875 return NULL;
876 }
877
879 if (SPI_result < 0)
880 return NULL;
881
882 memset(&plan, 0, sizeof(_SPI_plan));
883 plan.magic = _SPI_PLAN_MAGIC;
884 plan.parse_mode = RAW_PARSE_DEFAULT;
885 plan.cursor_options = cursorOptions;
886 plan.nargs = nargs;
887 plan.argtypes = argtypes;
888 plan.parserSetup = NULL;
889 plan.parserSetupArg = NULL;
890
891 _SPI_prepare_plan(src, &plan);
892
893 /* copy plan to procedure context */
894 result = _SPI_make_plan_non_temp(&plan);
895
896 _SPI_end_call(true);
897
898 return result;
899}
static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan)
Definition: spi.c:3141

References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), plan, RAW_PARSE_DEFAULT, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by SPI_prepare().

◆ SPI_prepare_extended()

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

Definition at line 902 of file spi.c.

904{
906 SPIPlanPtr result;
907
908 if (src == NULL || options == NULL)
909 {
911 return NULL;
912 }
913
915 if (SPI_result < 0)
916 return NULL;
917
918 memset(&plan, 0, sizeof(_SPI_plan));
919 plan.magic = _SPI_PLAN_MAGIC;
920 plan.parse_mode = options->parseMode;
921 plan.cursor_options = options->cursorOptions;
922 plan.nargs = 0;
923 plan.argtypes = NULL;
924 plan.parserSetup = options->parserSetup;
925 plan.parserSetupArg = options->parserSetupArg;
926
927 _SPI_prepare_plan(src, &plan);
928
929 /* copy plan to procedure context */
930 result = _SPI_make_plan_non_temp(&plan);
931
932 _SPI_end_call(true);
933
934 return result;
935}

References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), plan, SPI_ERROR_ARGUMENT, and SPI_result.

Referenced by exec_prepare_plan().

◆ SPI_prepare_params()

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

Definition at line 938 of file spi.c.

942{
944 SPIPlanPtr result;
945
946 if (src == NULL)
947 {
949 return NULL;
950 }
951
953 if (SPI_result < 0)
954 return NULL;
955
956 memset(&plan, 0, sizeof(_SPI_plan));
957 plan.magic = _SPI_PLAN_MAGIC;
958 plan.parse_mode = RAW_PARSE_DEFAULT;
959 plan.cursor_options = cursorOptions;
960 plan.nargs = 0;
961 plan.argtypes = NULL;
962 plan.parserSetup = parserSetup;
963 plan.parserSetupArg = parserSetupArg;
964
965 _SPI_prepare_plan(src, &plan);
966
967 /* copy plan to procedure context */
968 result = _SPI_make_plan_non_temp(&plan);
969
970 _SPI_end_call(true);
971
972 return result;
973}

References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_PLAN_MAGIC, _SPI_prepare_plan(), plan, RAW_PARSE_DEFAULT, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_register_relation()

int SPI_register_relation ( EphemeralNamedRelation  enr)

Definition at line 3297 of file spi.c.

3298{
3300 int res;
3301
3302 if (enr == NULL || enr->md.name == NULL)
3303 return SPI_ERROR_ARGUMENT;
3304
3305 res = _SPI_begin_call(false); /* keep current memory context */
3306 if (res < 0)
3307 return res;
3308
3309 match = _SPI_find_ENR_by_name(enr->md.name);
3310 if (match)
3312 else
3313 {
3314 if (_SPI_current->queryEnv == NULL)
3316
3318 res = SPI_OK_REL_REGISTER;
3319 }
3320
3321 _SPI_end_call(false);
3322
3323 return res;
3324}
QueryEnvironment * create_queryEnv(void)
void register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr)
static EphemeralNamedRelation _SPI_find_ENR_by_name(const char *name)
Definition: spi.c:3280
#define SPI_ERROR_REL_DUPLICATE
Definition: spi.h:79
#define SPI_OK_REL_REGISTER
Definition: spi.h:96
EphemeralNamedRelationMetadataData md

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

Referenced by SPI_register_trigger_data().

◆ SPI_register_trigger_data()

int SPI_register_trigger_data ( TriggerData tdata)

Definition at line 3364 of file spi.c.

3365{
3366 if (tdata == NULL)
3367 return SPI_ERROR_ARGUMENT;
3368
3369 if (tdata->tg_newtable)
3370 {
3373 int rc;
3374
3375 enr->md.name = tdata->tg_trigger->tgnewtable;
3376 enr->md.reliddesc = tdata->tg_relation->rd_id;
3377 enr->md.tupdesc = NULL;
3380 enr->reldata = tdata->tg_newtable;
3381 rc = SPI_register_relation(enr);
3382 if (rc != SPI_OK_REL_REGISTER)
3383 return rc;
3384 }
3385
3386 if (tdata->tg_oldtable)
3387 {
3390 int rc;
3391
3392 enr->md.name = tdata->tg_trigger->tgoldtable;
3393 enr->md.reliddesc = tdata->tg_relation->rd_id;
3394 enr->md.tupdesc = NULL;
3397 enr->reldata = tdata->tg_oldtable;
3398 rc = SPI_register_relation(enr);
3399 if (rc != SPI_OK_REL_REGISTER)
3400 return rc;
3401 }
3402
3403 return SPI_OK_TD_REGISTER;
3404}
@ ENR_NAMED_TUPLESTORE
int SPI_register_relation(EphemeralNamedRelation enr)
Definition: spi.c:3297
#define SPI_OK_TD_REGISTER
Definition: spi.h:98
EphemeralNameRelationType enrtype
Oid rd_id
Definition: rel.h:113
Tuplestorestate * tg_oldtable
Definition: trigger.h:41
Relation tg_relation
Definition: trigger.h:35
Tuplestorestate * tg_newtable
Definition: trigger.h:42
Trigger * tg_trigger
Definition: trigger.h:38
char * tgoldtable
Definition: reltrigger.h:43
char * tgnewtable
Definition: reltrigger.h:44
int64 tuplestore_tuple_count(Tuplestorestate *state)
Definition: tuplestore.c:580

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

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

◆ SPI_repalloc()

void * SPI_repalloc ( void *  pointer,
Size  size 
)

Definition at line 1347 of file spi.c.

1348{
1349 /* No longer need to worry which context chunk was in... */
1350 return repalloc(pointer, size);
1351}

References repalloc().

◆ SPI_result_code_string()

const char * SPI_result_code_string ( int  code)

Definition at line 1972 of file spi.c.

1973{
1974 static char buf[64];
1975
1976 switch (code)
1977 {
1978 case SPI_ERROR_CONNECT:
1979 return "SPI_ERROR_CONNECT";
1980 case SPI_ERROR_COPY:
1981 return "SPI_ERROR_COPY";
1983 return "SPI_ERROR_OPUNKNOWN";
1985 return "SPI_ERROR_UNCONNECTED";
1986 case SPI_ERROR_ARGUMENT:
1987 return "SPI_ERROR_ARGUMENT";
1988 case SPI_ERROR_PARAM:
1989 return "SPI_ERROR_PARAM";
1991 return "SPI_ERROR_TRANSACTION";
1993 return "SPI_ERROR_NOATTRIBUTE";
1995 return "SPI_ERROR_NOOUTFUNC";
1997 return "SPI_ERROR_TYPUNKNOWN";
1999 return "SPI_ERROR_REL_DUPLICATE";
2001 return "SPI_ERROR_REL_NOT_FOUND";
2002 case SPI_OK_CONNECT:
2003 return "SPI_OK_CONNECT";
2004 case SPI_OK_FINISH:
2005 return "SPI_OK_FINISH";
2006 case SPI_OK_FETCH:
2007 return "SPI_OK_FETCH";
2008 case SPI_OK_UTILITY:
2009 return "SPI_OK_UTILITY";
2010 case SPI_OK_SELECT:
2011 return "SPI_OK_SELECT";
2012 case SPI_OK_SELINTO:
2013 return "SPI_OK_SELINTO";
2014 case SPI_OK_INSERT:
2015 return "SPI_OK_INSERT";
2016 case SPI_OK_DELETE:
2017 return "SPI_OK_DELETE";
2018 case SPI_OK_UPDATE:
2019 return "SPI_OK_UPDATE";
2020 case SPI_OK_CURSOR:
2021 return "SPI_OK_CURSOR";
2023 return "SPI_OK_INSERT_RETURNING";
2025 return "SPI_OK_DELETE_RETURNING";
2027 return "SPI_OK_UPDATE_RETURNING";
2028 case SPI_OK_REWRITTEN:
2029 return "SPI_OK_REWRITTEN";
2031 return "SPI_OK_REL_REGISTER";
2033 return "SPI_OK_REL_UNREGISTER";
2034 case SPI_OK_TD_REGISTER:
2035 return "SPI_OK_TD_REGISTER";
2036 case SPI_OK_MERGE:
2037 return "SPI_OK_MERGE";
2039 return "SPI_OK_MERGE_RETURNING";
2040 }
2041 /* Unrecognized code ... return something useful ... */
2042 sprintf(buf, "Unrecognized SPI code %d", code);
2043 return buf;
2044}
static char * buf
Definition: pg_test_fsync.c:72
#define sprintf
Definition: port.h:241
#define SPI_ERROR_TRANSACTION
Definition: spi.h:75
#define SPI_ERROR_REL_NOT_FOUND
Definition: spi.h:80
#define SPI_OK_UTILITY
Definition: spi.h:85
#define SPI_OK_REWRITTEN
Definition: spi.h:95
#define SPI_OK_INSERT
Definition: spi.h:88
#define SPI_OK_UPDATE
Definition: spi.h:90
#define SPI_OK_CURSOR
Definition: spi.h:91
#define SPI_OK_FETCH
Definition: spi.h:84
#define SPI_OK_MERGE
Definition: spi.h:99
#define SPI_OK_SELINTO
Definition: spi.h:87
#define SPI_ERROR_OPUNKNOWN
Definition: spi.h:70
#define SPI_OK_UPDATE_RETURNING
Definition: spi.h:94
#define SPI_OK_DELETE
Definition: spi.h:89
#define SPI_OK_REL_UNREGISTER
Definition: spi.h:97
#define SPI_OK_INSERT_RETURNING
Definition: spi.h:92
#define SPI_ERROR_COPY
Definition: spi.h:69
#define SPI_ERROR_NOOUTFUNC
Definition: spi.h:77
#define SPI_OK_DELETE_RETURNING
Definition: spi.h:93
#define SPI_OK_MERGE_RETURNING
Definition: spi.h:100
#define SPI_ERROR_CONNECT
Definition: spi.h:68
#define SPI_OK_SELECT
Definition: spi.h:86

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

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

◆ SPI_returntuple()

HeapTupleHeader SPI_returntuple ( HeapTuple  tuple,
TupleDesc  tupdesc 
)

Definition at line 1074 of file spi.c.

1075{
1076 MemoryContext oldcxt;
1077 HeapTupleHeader dtup;
1078
1079 if (tuple == NULL || tupdesc == NULL)
1080 {
1082 return NULL;
1083 }
1084
1085 if (_SPI_current == NULL)
1086 {
1088 return NULL;
1089 }
1090
1091 /* For RECORD results, make sure a typmod has been assigned */
1092 if (tupdesc->tdtypeid == RECORDOID &&
1093 tupdesc->tdtypmod < 0)
1095
1097
1098 dtup = DatumGetHeapTupleHeader(heap_copy_tuple_as_datum(tuple, tupdesc));
1099
1100 MemoryContextSwitchTo(oldcxt);
1101
1102 return dtup;
1103}
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:295
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1081
int32 tdtypmod
Definition: tupdesc.h:139
Oid tdtypeid
Definition: tupdesc.h:138
void assign_record_type_typmod(TupleDesc tupDesc)
Definition: typcache.c:2042

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

Referenced by coerce_function_result_tuple().

◆ SPI_rollback()

void SPI_rollback ( void  )

Definition at line 413 of file spi.c.

414{
415 _SPI_rollback(false);
416}
static void _SPI_rollback(bool chain)
Definition: spi.c:332

References _SPI_rollback().

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

◆ SPI_rollback_and_chain()

void SPI_rollback_and_chain ( void  )

Definition at line 419 of file spi.c.

420{
421 _SPI_rollback(true);
422}

References _SPI_rollback().

Referenced by exec_stmt_rollback().

◆ SPI_saveplan()

SPIPlanPtr SPI_saveplan ( SPIPlanPtr  plan)

Definition at line 1003 of file spi.c.

1004{
1005 SPIPlanPtr newplan;
1006
1007 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1008 {
1010 return NULL;
1011 }
1012
1013 SPI_result = _SPI_begin_call(false); /* don't change context */
1014 if (SPI_result < 0)
1015 return NULL;
1016
1017 newplan = _SPI_save_plan(plan);
1018
1019 SPI_result = _SPI_end_call(false);
1020
1021 return newplan;
1022}
static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan)
Definition: spi.c:3209

References _SPI_begin_call(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_save_plan(), plan, SPI_ERROR_ARGUMENT, and SPI_result.

◆ SPI_scroll_cursor_fetch()

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

Definition at line 1835 of file spi.c.

1836{
1837 _SPI_cursor_operation(portal,
1838 direction, count,
1840 /* we know that the DestSPI receiver doesn't need a destroy call */
1841}

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

Referenced by exec_stmt_fetch().

◆ SPI_scroll_cursor_move()

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

Definition at line 1850 of file spi.c.

1851{
1852 _SPI_cursor_operation(portal, direction, count, None_Receiver);
1853}

References _SPI_cursor_operation(), and None_Receiver.

Referenced by exec_stmt_fetch().

◆ SPI_start_transaction()

void SPI_start_transaction ( void  )

Definition at line 222 of file spi.c.

223{
224}

◆ SPI_unregister_relation()

int SPI_unregister_relation ( const char *  name)

Definition at line 3331 of file spi.c.

3332{
3334 int res;
3335
3336 if (name == NULL)
3337 return SPI_ERROR_ARGUMENT;
3338
3339 res = _SPI_begin_call(false); /* keep current memory context */
3340 if (res < 0)
3341 return res;
3342
3343 match = _SPI_find_ENR_by_name(name);
3344 if (match)
3345 {
3348 }
3349 else
3351
3352 _SPI_end_call(false);
3353
3354 return res;
3355}
void unregister_ENR(QueryEnvironment *queryEnv, const char *name)

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

Variable Documentation

◆ SPI_processed

◆ SPI_result

◆ SPI_tuptable