#include "nodes/parsenodes.h"
#include "utils/portal.h"
Go to the source code of this file.
Data Structures | |
struct | SPITupleTable |
Defines | |
#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) |
#define | SPI_ERROR_ARGUMENT (-6) |
#define | SPI_ERROR_PARAM (-7) |
#define | SPI_ERROR_TRANSACTION (-8) |
#define | SPI_ERROR_NOATTRIBUTE (-9) |
#define | SPI_ERROR_NOOUTFUNC (-10) |
#define | SPI_ERROR_TYPUNKNOWN (-11) |
#define | SPI_OK_CONNECT 1 |
#define | SPI_OK_FINISH 2 |
#define | SPI_OK_FETCH 3 |
#define | SPI_OK_UTILITY 4 |
#define | SPI_OK_SELECT 5 |
#define | SPI_OK_SELINTO 6 |
#define | SPI_OK_INSERT 7 |
#define | SPI_OK_DELETE 8 |
#define | SPI_OK_UPDATE 9 |
#define | SPI_OK_CURSOR 10 |
#define | SPI_OK_INSERT_RETURNING 11 |
#define | SPI_OK_DELETE_RETURNING 12 |
#define | SPI_OK_UPDATE_RETURNING 13 |
#define | SPI_OK_REWRITTEN 14 |
Typedefs | |
typedef struct SPITupleTable | SPITupleTable |
typedef struct _SPI_plan * | SPIPlanPtr |
Functions | |
int | SPI_connect (void) |
int | SPI_finish (void) |
void | SPI_push (void) |
void | SPI_pop (void) |
bool | SPI_push_conditional (void) |
void | SPI_pop_conditional (bool pushed) |
void | SPI_restore_connection (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) |
List * | SPI_plan_get_plan_sources (SPIPlanPtr plan) |
CachedPlan * | SPI_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) |
void | SPI_freetuple (HeapTuple pointer) |
void | SPI_freetuptable (SPITupleTable *tuptable) |
Portal | SPI_cursor_open (const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only) |
Portal | SPI_cursor_open_with_args (const char *name, const char *src, int nargs, Oid *argtypes, Datum *Values, const char *Nulls, bool read_only, int cursorOptions) |
Portal | SPI_cursor_open_with_paramlist (const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only) |
Portal | SPI_cursor_find (const char *name) |
void | SPI_cursor_fetch (Portal portal, bool forward, long count) |
void | SPI_cursor_move (Portal portal, bool forward, long count) |
void | SPI_scroll_cursor_fetch (Portal, FetchDirection direction, long count) |
void | SPI_scroll_cursor_move (Portal, FetchDirection direction, long count) |
void | SPI_cursor_close (Portal portal) |
void | AtEOXact_SPI (bool isCommit) |
void | AtEOSubXact_SPI (bool isCommit, SubTransactionId mySubid) |
Variables | |
PGDLLIMPORT uint32 | SPI_processed |
PGDLLIMPORT Oid | SPI_lastoid |
PGDLLIMPORT SPITupleTable * | SPI_tuptable |
PGDLLIMPORT int | SPI_result |
#define SPI_ERROR_ARGUMENT (-6) |
Definition at line 37 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_ERROR_CONNECT (-1) |
Definition at line 32 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_ERROR_COPY (-2) |
Definition at line 33 of file spi.h.
Referenced by exec_prepare_plan(), exec_stmt_dynexecute(), exec_stmt_execsql(), and SPI_result_code_string().
#define SPI_ERROR_NOATTRIBUTE (-9) |
Definition at line 40 of file spi.h.
Referenced by exec_eval_datum(), exec_get_datum_type(), exec_get_datum_type_info(), pltcl_trigger_handler(), PLy_modify_tuple(), SPI_result_code_string(), and tsvector_update_trigger().
#define SPI_ERROR_NOOUTFUNC (-10) |
Definition at line 41 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_ERROR_OPUNKNOWN (-3) |
Definition at line 34 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_ERROR_PARAM (-7) |
Definition at line 38 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_ERROR_TRANSACTION (-8) |
Definition at line 39 of file spi.h.
Referenced by exec_prepare_plan(), exec_stmt_dynexecute(), exec_stmt_execsql(), and SPI_result_code_string().
#define SPI_ERROR_TYPUNKNOWN (-11) |
Definition at line 42 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_ERROR_UNCONNECTED (-4) |
Definition at line 35 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_OK_CONNECT 1 |
Definition at line 44 of file spi.h.
Referenced by pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_func_handler(), plperl_inline_handler(), plperl_trigger_handler(), plpgsql_call_handler(), plpgsql_inline_handler(), plpgsql_validator(), plpython_call_handler(), pltcl_func_handler(), 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_restrict_del(), ri_restrict_upd(), and SPI_result_code_string().
#define SPI_OK_CURSOR 10 |
Definition at line 53 of file spi.h.
Referenced by SPI_result_code_string().
#define SPI_OK_DELETE 8 |
Definition at line 51 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), RI_FKey_cascade_del(), and SPI_result_code_string().
#define SPI_OK_DELETE_RETURNING 12 |
Definition at line 55 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), and SPI_result_code_string().
#define SPI_OK_FETCH 3 |
Definition at line 46 of file spi.h.
Referenced by PLy_cursor_fetch(), and SPI_result_code_string().
#define SPI_OK_FINISH 2 |
Definition at line 45 of file spi.h.
Referenced by get_crosstab_tuplestore(), load_categories_hash(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_func_handler(), plperl_inline_handler(), plpgsql_call_handler(), plpgsql_inline_handler(), plpgsql_validator(), pltcl_func_handler(), pltcl_trigger_handler(), PLy_exec_function(), PLy_exec_trigger(), 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(), and SPI_result_code_string().
#define SPI_OK_INSERT 7 |
Definition at line 50 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), and SPI_result_code_string().
#define SPI_OK_INSERT_RETURNING 11 |
Definition at line 54 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), and SPI_result_code_string().
#define SPI_OK_REWRITTEN 14 |
Definition at line 57 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), and SPI_result_code_string().
#define SPI_OK_SELECT 5 |
Definition at line 48 of file spi.h.
Referenced by _SPI_pquery(), build_tuplestore_recursively(), crosstab(), exec_eval_expr(), exec_run_select(), exec_stmt_dynexecute(), exec_stmt_execsql(), get_crosstab_tuplestore(), get_tuple_of_interest(), initialize_worker_spi(), load_categories_hash(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), pltcl_init_load_unknown(), pltcl_process_SPI_result(), query_to_xml_internal(), ri_Check_Pk_Match(), RI_FKey_check(), RI_Initial_Check(), ri_PerformCheck(), ri_restrict_del(), ri_restrict_upd(), SPI_result_code_string(), and xpath_table().
#define SPI_OK_SELINTO 6 |
Definition at line 49 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), and SPI_result_code_string().
#define SPI_OK_UPDATE 9 |
Definition at line 52 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), RI_FKey_cascade_upd(), RI_FKey_setdefault_del(), RI_FKey_setdefault_upd(), RI_FKey_setnull_del(), RI_FKey_setnull_upd(), and SPI_result_code_string().
#define SPI_OK_UPDATE_RETURNING 13 |
Definition at line 56 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_process_SPI_result(), SPI_result_code_string(), and worker_spi_main().
#define SPI_OK_UTILITY 4 |
Definition at line 47 of file spi.h.
Referenced by exec_stmt_dynexecute(), exec_stmt_execsql(), initialize_worker_spi(), pltcl_process_SPI_result(), and SPI_result_code_string().
typedef struct _SPI_plan* SPIPlanPtr |
typedef struct SPITupleTable SPITupleTable |
void AtEOSubXact_SPI | ( | bool | isCommit, | |
SubTransactionId | mySubid | |||
) |
Definition at line 230 of file spi.c.
References _SPI_connected, _SPI_curid, _SPI_connection::connectSubid, ereport, errcode(), errhint(), errmsg(), _SPI_connection::execCxt, MemoryContextDelete(), MemoryContextResetAndDeleteChildren(), _SPI_connection::procCxt, SPI_freetuptable(), SPI_lastoid, SPI_processed, _SPI_connection::tuptable, and WARNING.
Referenced by AbortSubTransaction(), and CommitSubTransaction().
{ bool found = false; while (_SPI_connected >= 0) { _SPI_connection *connection = &(_SPI_stack[_SPI_connected]); if (connection->connectSubid != mySubid) break; /* couldn't be any underneath it either */ found = true; /* * Release procedure memory explicitly (see note in SPI_connect) */ if (connection->execCxt) { MemoryContextDelete(connection->execCxt); connection->execCxt = NULL; } if (connection->procCxt) { MemoryContextDelete(connection->procCxt); connection->procCxt = NULL; } /* * Pop the stack entry and reset global variables. Unlike * SPI_finish(), we don't risk switching to memory contexts that might * be already gone. */ _SPI_connected--; _SPI_curid = _SPI_connected; if (_SPI_connected == -1) _SPI_current = NULL; else _SPI_current = &(_SPI_stack[_SPI_connected]); SPI_processed = 0; SPI_lastoid = InvalidOid; SPI_tuptable = NULL; } if (found && isCommit) ereport(WARNING, (errcode(ERRCODE_WARNING), errmsg("subtransaction left non-empty SPI stack"), errhint("Check for missing \"SPI_finish\" calls."))); /* * If we are aborting a subtransaction and there is an open SPI context * surrounding the subxact, clean up to prevent memory leakage. */ if (_SPI_current && !isCommit) { /* free Executor memory the same as _SPI_end_call would do */ MemoryContextResetAndDeleteChildren(_SPI_current->execCxt); /* throw away any partially created tuple-table */ SPI_freetuptable(_SPI_current->tuptable); _SPI_current->tuptable = NULL; } }
void AtEOXact_SPI | ( | bool | isCommit | ) |
Definition at line 202 of file spi.c.
References _SPI_connected, _SPI_curid, _SPI_stack_depth, ereport, errcode(), errhint(), errmsg(), SPI_lastoid, SPI_processed, and WARNING.
Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().
{ /* * Note that memory contexts belonging to SPI stack entries will be freed * automatically, so we can ignore them here. We just need to restore our * static variables to initial state. */ if (isCommit && _SPI_connected != -1) ereport(WARNING, (errcode(ERRCODE_WARNING), errmsg("transaction left non-empty SPI stack"), errhint("Check for missing \"SPI_finish\" calls."))); _SPI_current = _SPI_stack = NULL; _SPI_stack_depth = 0; _SPI_connected = _SPI_curid = -1; SPI_processed = 0; SPI_lastoid = InvalidOid; SPI_tuptable = NULL; }
int SPI_connect | ( | void | ) |
Definition at line 84 of file spi.c.
References _SPI_connected, _SPI_curid, _SPI_stack_depth, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), Assert, _SPI_connection::connectSubid, elog, ERROR, _SPI_connection::execCxt, GetCurrentSubTransactionId(), _SPI_connection::lastoid, MemoryContextAlloc(), MemoryContextSwitchTo(), NULL, _SPI_connection::procCxt, _SPI_connection::processed, repalloc(), _SPI_connection::savedcxt, TopTransactionContext, and _SPI_connection::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(), funny_dup17(), get_crosstab_tuplestore(), get_tuple_of_interest(), initialize_worker_spi(), load_categories_hash(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_func_handler(), plperl_inline_handler(), plperl_trigger_handler(), plpgsql_call_handler(), plpgsql_inline_handler(), plpgsql_validator(), plpython_call_handler(), plpython_inline_handler(), pltcl_func_handler(), pltcl_trigger_handler(), query_to_xml_and_xmlschema(), query_to_xml_internal(), query_to_xmlschema(), 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(), worker_spi_main(), and xpath_table().
{ int newdepth; /* * When procedure called by Executor _SPI_curid expected to be equal to * _SPI_connected */ if (_SPI_curid != _SPI_connected) return SPI_ERROR_CONNECT; if (_SPI_stack == NULL) { if (_SPI_connected != -1 || _SPI_stack_depth != 0) elog(ERROR, "SPI stack corrupted"); newdepth = 16; _SPI_stack = (_SPI_connection *) MemoryContextAlloc(TopTransactionContext, newdepth * sizeof(_SPI_connection)); _SPI_stack_depth = newdepth; } else { if (_SPI_stack_depth <= 0 || _SPI_stack_depth <= _SPI_connected) elog(ERROR, "SPI stack corrupted"); if (_SPI_stack_depth == _SPI_connected + 1) { newdepth = _SPI_stack_depth * 2; _SPI_stack = (_SPI_connection *) repalloc(_SPI_stack, newdepth * sizeof(_SPI_connection)); _SPI_stack_depth = newdepth; } } /* * We're entering procedure where _SPI_curid == _SPI_connected - 1 */ _SPI_connected++; Assert(_SPI_connected >= 0 && _SPI_connected < _SPI_stack_depth); _SPI_current = &(_SPI_stack[_SPI_connected]); _SPI_current->processed = 0; _SPI_current->lastoid = InvalidOid; _SPI_current->tuptable = NULL; _SPI_current->procCxt = NULL; /* in case we fail to create 'em */ _SPI_current->execCxt = NULL; _SPI_current->connectSubid = GetCurrentSubTransactionId(); /* * Create memory contexts for this procedure * * XXX it would be better to use PortalContext as the parent context, but * we may not be inside a portal (consider deferred-trigger execution). * Perhaps CurTransactionContext would do? For now it doesn't matter * because we clean up explicitly in AtEOSubXact_SPI(). */ _SPI_current->procCxt = AllocSetContextCreate(TopTransactionContext, "SPI Proc", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); _SPI_current->execCxt = AllocSetContextCreate(TopTransactionContext, "SPI Exec", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); /* ... and switch to procedure's context */ _SPI_current->savedcxt = MemoryContextSwitchTo(_SPI_current->procCxt); return SPI_OK_CONNECT; }
Definition at line 670 of file spi.c.
References _SPI_connected, _SPI_curid, elog, ERROR, heap_copytuple(), MemoryContextSwitchTo(), NULL, _SPI_connection::savedcxt, and SPI_result.
Referenced by get_tuple_of_interest(), plpgsql_exec_trigger(), and ttdummy().
{ MemoryContext oldcxt = NULL; HeapTuple ctuple; if (tuple == NULL) { SPI_result = SPI_ERROR_ARGUMENT; return NULL; } if (_SPI_curid + 1 == _SPI_connected) /* connected */ { if (_SPI_current != &(_SPI_stack[_SPI_curid + 1])) elog(ERROR, "SPI stack corrupted"); oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt); } ctuple = heap_copytuple(tuple); if (oldcxt) MemoryContextSwitchTo(oldcxt); return ctuple; }
void SPI_cursor_close | ( | Portal | portal | ) |
Definition at line 1398 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().
{ if (!PortalIsValid(portal)) elog(ERROR, "invalid portal in SPI cursor operation"); PortalDrop(portal, false); }
Definition at line 1342 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().
{ _SPI_cursor_operation(portal, forward ? FETCH_FORWARD : FETCH_BACKWARD, count, CreateDestReceiver(DestSPI)); /* we know that the DestSPI receiver doesn't need a destroy call */ }
Portal SPI_cursor_find | ( | const char * | name | ) |
Definition at line 1330 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().
{ return GetPortalByName(name); }
Definition at line 1357 of file spi.c.
References _SPI_cursor_operation(), FETCH_BACKWARD, FETCH_FORWARD, and None_Receiver.
{ _SPI_cursor_operation(portal, forward ? FETCH_FORWARD : FETCH_BACKWARD, count, None_Receiver); }
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().
{ Portal portal; ParamListInfo paramLI; /* build transient ParamListInfo in caller's context */ paramLI = _SPI_convert_params(plan->nargs, plan->argtypes, Values, Nulls); portal = SPI_cursor_open_internal(name, plan, paramLI, read_only); /* done with the transient ParamListInfo */ if (paramLI) pfree(paramLI); return portal; }
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_curid, _SPI_end_call(), _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, SPI_cursor_open_internal(), and SPI_result.
Referenced by exec_dynquery_with_params().
{ Portal result; _SPI_plan plan; ParamListInfo paramLI; if (src == NULL || nargs < 0) elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments"); if (nargs > 0 && (argtypes == NULL || Values == NULL)) elog(ERROR, "SPI_cursor_open_with_args called with missing parameters"); SPI_result = _SPI_begin_call(true); if (SPI_result < 0) elog(ERROR, "SPI_cursor_open_with_args called while not connected"); memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; plan.cursor_options = cursorOptions; plan.nargs = nargs; plan.argtypes = argtypes; plan.parserSetup = NULL; plan.parserSetupArg = NULL; /* build transient ParamListInfo in executor context */ paramLI = _SPI_convert_params(nargs, argtypes, Values, Nulls); _SPI_prepare_plan(src, &plan); /* We needn't copy the plan; SPI_cursor_open_internal will do so */ /* Adjust stack so that SPI_cursor_open_internal doesn't complain */ _SPI_curid--; result = SPI_cursor_open_internal(name, &plan, paramLI, read_only); /* And clean up */ _SPI_curid++; _SPI_end_call(true); return result; }
Portal SPI_cursor_open_with_paramlist | ( | const char * | name, | |
SPIPlanPtr | plan, | |||
ParamListInfo | params, | |||
bool | read_only | |||
) |
Definition at line 1112 of file spi.c.
References SPI_cursor_open_internal().
Referenced by exec_run_select(), exec_stmt_forc(), and exec_stmt_open().
{ return SPI_cursor_open_internal(name, plan, params, read_only); }
int SPI_exec | ( | const char * | src, | |
long | tcount | |||
) |
Definition at line 371 of file spi.c.
References SPI_execute().
Referenced by funny_dup17(), get_tuple_of_interest(), and xpath_table().
{ return SPI_execute(src, false, tcount); }
int SPI_execp | ( | SPIPlanPtr | plan, | |
Datum * | Values, | |||
const char * | Nulls, | |||
long | tcount | |||
) |
Definition at line 405 of file spi.c.
References SPI_execute_plan().
Referenced by check_foreign_key(), check_primary_key(), timetravel(), and ttdummy().
{ return SPI_execute_plan(plan, Values, Nulls, false, tcount); }
int SPI_execute | ( | const char * | src, | |
bool | read_only, | |||
long | tcount | |||
) |
Definition at line 343 of file spi.c.
References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_prepare_oneshot_plan(), _SPI_plan::cursor_options, InvalidSnapshot, _SPI_plan::magic, and NULL.
Referenced by build_tuplestore_recursively(), crosstab(), exec_stmt_dynexecute(), get_crosstab_tuplestore(), initialize_worker_spi(), load_categories_hash(), plperl_spi_exec(), pltcl_init_load_unknown(), pltcl_SPI_execute(), PLy_spi_execute_query(), query_to_oid_list(), query_to_xml_internal(), SPI_exec(), and worker_spi_main().
{ _SPI_plan plan; int res; if (src == NULL || tcount < 0) return SPI_ERROR_ARGUMENT; res = _SPI_begin_call(true); if (res < 0) return res; memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; plan.cursor_options = 0; _SPI_prepare_oneshot_plan(src, &plan); res = _SPI_execute_plan(&plan, NULL, InvalidSnapshot, InvalidSnapshot, read_only, true, tcount); _SPI_end_call(true); return res; }
int SPI_execute_plan | ( | SPIPlanPtr | plan, | |
Datum * | Values, | |||
const char * | Nulls, | |||
bool | read_only, | |||
long | tcount | |||
) |
Definition at line 378 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, and NULL.
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().
{ int res; if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0) return SPI_ERROR_ARGUMENT; if (plan->nargs > 0 && Values == NULL) return SPI_ERROR_PARAM; res = _SPI_begin_call(true); if (res < 0) return res; res = _SPI_execute_plan(plan, _SPI_convert_params(plan->nargs, plan->argtypes, Values, Nulls), InvalidSnapshot, InvalidSnapshot, read_only, true, tcount); _SPI_end_call(true); return res; }
int SPI_execute_plan_with_paramlist | ( | SPIPlanPtr | plan, | |
ParamListInfo | params, | |||
bool | read_only, | |||
long | tcount | |||
) |
Definition at line 412 of file spi.c.
References _SPI_begin_call(), _SPI_end_call(), _SPI_execute_plan(), _SPI_PLAN_MAGIC, InvalidSnapshot, _SPI_plan::magic, and NULL.
Referenced by exec_run_select(), and exec_stmt_execsql().
{ int res; if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0) return SPI_ERROR_ARGUMENT; res = _SPI_begin_call(true); if (res < 0) return res; res = _SPI_execute_plan(plan, params, InvalidSnapshot, InvalidSnapshot, read_only, true, tcount); _SPI_end_call(true); return res; }
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 446 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, and NULL.
Referenced by RI_Initial_Check(), and ri_PerformCheck().
{ int res; if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0) return SPI_ERROR_ARGUMENT; if (plan->nargs > 0 && Values == NULL) return SPI_ERROR_PARAM; res = _SPI_begin_call(true); if (res < 0) return res; res = _SPI_execute_plan(plan, _SPI_convert_params(plan->nargs, plan->argtypes, Values, Nulls), snapshot, crosscheck_snapshot, read_only, fire_triggers, tcount); _SPI_end_call(true); return res; }
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 480 of file spi.c.
References _SPI_begin_call(), _SPI_convert_params(), _SPI_end_call(), _SPI_execute_plan(), _SPI_prepare_oneshot_plan(), _SPI_plan::argtypes, _SPI_plan::cursor_options, InvalidSnapshot, _SPI_plan::magic, _SPI_plan::nargs, NULL, _SPI_plan::parserSetup, and _SPI_plan::parserSetupArg.
Referenced by exec_stmt_dynexecute().
{ int res; _SPI_plan plan; ParamListInfo paramLI; if (src == NULL || nargs < 0 || tcount < 0) return SPI_ERROR_ARGUMENT; if (nargs > 0 && (argtypes == NULL || Values == NULL)) return SPI_ERROR_PARAM; res = _SPI_begin_call(true); if (res < 0) return res; memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; plan.cursor_options = 0; plan.nargs = nargs; plan.argtypes = argtypes; plan.parserSetup = NULL; plan.parserSetupArg = NULL; paramLI = _SPI_convert_params(nargs, argtypes, Values, Nulls); _SPI_prepare_oneshot_plan(src, &plan); res = _SPI_execute_plan(&plan, paramLI, InvalidSnapshot, InvalidSnapshot, read_only, true, tcount); _SPI_end_call(true); return res; }
int SPI_finish | ( | void | ) |
Definition at line 158 of file spi.c.
References _SPI_begin_call(), _SPI_connected, _SPI_curid, _SPI_connection::execCxt, MemoryContextDelete(), MemoryContextSwitchTo(), _SPI_connection::procCxt, _SPI_connection::savedcxt, SPI_lastoid, 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_func_handler(), plperl_inline_handler(), plperl_trigger_handler(), plpgsql_call_handler(), plpgsql_inline_handler(), plpgsql_validator(), pltcl_func_handler(), pltcl_trigger_handler(), PLy_exec_function(), PLy_exec_trigger(), query_to_xml_and_xmlschema(), query_to_xml_internal(), query_to_xmlschema(), 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(), worker_spi_main(), and xpath_table().
{ int res; res = _SPI_begin_call(false); /* live in procedure memory */ if (res < 0) return res; /* Restore memory context as it was before procedure call */ MemoryContextSwitchTo(_SPI_current->savedcxt); /* Release memory used in procedure call */ MemoryContextDelete(_SPI_current->execCxt); _SPI_current->execCxt = NULL; MemoryContextDelete(_SPI_current->procCxt); _SPI_current->procCxt = NULL; /* * Reset result variables, especially SPI_tuptable which is probably * pointing at a just-deleted tuptable */ SPI_processed = 0; SPI_lastoid = InvalidOid; SPI_tuptable = NULL; /* * After _SPI_begin_call _SPI_connected == _SPI_curid. Now we are closing * connection to SPI and returning to upper Executor and so _SPI_connected * must be equal to _SPI_curid. */ _SPI_connected--; _SPI_curid--; if (_SPI_connected == -1) _SPI_current = NULL; else _SPI_current = &(_SPI_stack[_SPI_connected]); return SPI_OK_FINISH; }
char* SPI_fname | ( | TupleDesc | tupdesc, | |
int | fnumber | |||
) |
Definition at line 823 of file spi.c.
References tupleDesc::attrs, FirstLowInvalidHeapAttributeNumber, NameStr, tupleDesc::natts, pstrdup(), SPI_result, and SystemAttributeDefinition().
Referenced by funny_dup17(), get_pkey_attnames(), ri_ReportViolation(), and SPI_sql_row_to_xmlelement().
{ Form_pg_attribute att; SPI_result = 0; if (fnumber > tupdesc->natts || fnumber == 0 || fnumber <= FirstLowInvalidHeapAttributeNumber) { SPI_result = SPI_ERROR_NOATTRIBUTE; return NULL; } if (fnumber > 0) att = tupdesc->attrs[fnumber - 1]; else att = SystemAttributeDefinition(fnumber, true); return pstrdup(NameStr(att->attname)); }
int SPI_fnumber | ( | TupleDesc | tupdesc, | |
const char * | fname | |||
) |
Definition at line 803 of file spi.c.
References tupleDesc::attrs, namestrcmp(), tupleDesc::natts, NULL, and SystemAttributeByName().
Referenced by autoinc(), check_foreign_key(), check_primary_key(), exec_assign_value(), exec_eval_datum(), exec_get_datum_type(), exec_get_datum_type_info(), insert_username(), lo_manage(), make_ruledef(), make_viewdef(), moddatetime(), plperl_build_tuple_result(), plperl_modify_tuple(), pltcl_init_load_unknown(), pltcl_trigger_handler(), PLy_modify_tuple(), timetravel(), tsvector_update_trigger(), and ttdummy().
{ int res; Form_pg_attribute sysatt; for (res = 0; res < tupdesc->natts; res++) { if (namestrcmp(&tupdesc->attrs[res]->attname, fname) == 0) return res + 1; } sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ ); if (sysatt != NULL) return sysatt->attnum; /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */ return SPI_ERROR_NOATTRIBUTE; }
int SPI_freeplan | ( | SPIPlanPtr | plan | ) |
Definition at line 648 of file spi.c.
References _SPI_PLAN_MAGIC, DropCachedPlan(), lfirst, _SPI_plan::magic, MemoryContextDelete(), NULL, _SPI_plan::plancache_list, and _SPI_plan::plancxt.
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().
{ ListCell *lc; if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC) return SPI_ERROR_ARGUMENT; /* Release the plancache entries */ foreach(lc, plan->plancache_list) { CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc); DropCachedPlan(plansource); } /* Now get rid of the _SPI_plan and subsidiary data in its plancxt */ MemoryContextDelete(plan->plancxt); return 0; }
void SPI_freetuple | ( | HeapTuple | pointer | ) |
Definition at line 1009 of file spi.c.
References heap_freetuple().
Referenced by ttdummy().
{ /* No longer need to worry which context tuple was in... */ heap_freetuple(tuple); }
void SPI_freetuptable | ( | SPITupleTable * | tuptable | ) |
Definition at line 1016 of file spi.c.
References MemoryContextDelete(), NULL, and SPITupleTable::tuptabcxt.
Referenced by _SPI_execute_plan(), AtEOSubXact_SPI(), 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_init_load_unknown(), pltcl_process_SPI_result(), PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_spi_execute_fetch_result(), ts_stat_sql(), and tsquery_rewrite_query().
{ if (tuptable != NULL) MemoryContextDelete(tuptable->tuptabcxt); }
int SPI_getargcount | ( | SPIPlanPtr | plan | ) |
Definition at line 1426 of file spi.c.
References _SPI_PLAN_MAGIC, _SPI_plan::magic, _SPI_plan::nargs, NULL, and SPI_result.
{ if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC) { SPI_result = SPI_ERROR_ARGUMENT; return -1; } return plan->nargs; }
Oid SPI_getargtypeid | ( | SPIPlanPtr | plan, | |
int | argIndex | |||
) |
Definition at line 1411 of file spi.c.
References _SPI_PLAN_MAGIC, _SPI_plan::argtypes, _SPI_plan::magic, _SPI_plan::nargs, NULL, and SPI_result.
{ if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || argIndex < 0 || argIndex >= plan->nargs) { SPI_result = SPI_ERROR_ARGUMENT; return InvalidOid; } return plan->argtypes[argIndex]; }
Definition at line 894 of file spi.c.
References FirstLowInvalidHeapAttributeNumber, heap_getattr, tupleDesc::natts, 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(), ttdummy(), and worker_spi_main().
{ SPI_result = 0; if (fnumber > tupdesc->natts || fnumber == 0 || fnumber <= FirstLowInvalidHeapAttributeNumber) { SPI_result = SPI_ERROR_NOATTRIBUTE; *isnull = true; return (Datum) NULL; } return heap_getattr(tuple, fnumber, tupdesc, isnull); }
char* SPI_getnspname | ( | Relation | rel | ) |
Definition at line 968 of file spi.c.
References get_namespace_name(), and RelationGetNamespace.
Referenced by plperl_trigger_build_args(), pltcl_trigger_handler(), and PLy_trigger_build_args().
{ return get_namespace_name(RelationGetNamespace(rel)); }
char* SPI_getrelname | ( | Relation | rel | ) |
Definition at line 962 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().
{ return pstrdup(RelationGetRelationName(rel)); }
char* SPI_gettype | ( | TupleDesc | tupdesc, | |
int | fnumber | |||
) |
Definition at line 910 of file spi.c.
References tupleDesc::attrs, FirstLowInvalidHeapAttributeNumber, GETSTRUCT, HeapTupleIsValid, NameStr, tupleDesc::natts, ObjectIdGetDatum, pstrdup(), ReleaseSysCache(), SearchSysCache1, SPI_result, SystemAttributeDefinition(), and TYPEOID.
Referenced by check_foreign_key(), and funny_dup17().
{ Oid typoid; HeapTuple typeTuple; char *result; SPI_result = 0; if (fnumber > tupdesc->natts || fnumber == 0 || fnumber <= FirstLowInvalidHeapAttributeNumber) { SPI_result = SPI_ERROR_NOATTRIBUTE; return NULL; } if (fnumber > 0) typoid = tupdesc->attrs[fnumber - 1]->atttypid; else typoid = (SystemAttributeDefinition(fnumber, true))->atttypid; typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid)); if (!HeapTupleIsValid(typeTuple)) { SPI_result = SPI_ERROR_TYPUNKNOWN; return NULL; } result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname)); ReleaseSysCache(typeTuple); return result; }
Definition at line 944 of file spi.c.
References tupleDesc::attrs, FirstLowInvalidHeapAttributeNumber, tupleDesc::natts, SPI_result, and SystemAttributeDefinition().
Referenced by autoinc(), check_foreign_key(), check_primary_key(), exec_assign_value(), exec_eval_datum(), exec_eval_expr(), exec_get_datum_type(), exec_get_datum_type_info(), exec_move_row(), insert_username(), moddatetime(), SPI_sql_row_to_xmlelement(), timetravel(), ts_stat_sql(), tsquery_rewrite_query(), tsvector_update_trigger(), and ttdummy().
{ SPI_result = 0; if (fnumber > tupdesc->natts || fnumber == 0 || fnumber <= FirstLowInvalidHeapAttributeNumber) { SPI_result = SPI_ERROR_NOATTRIBUTE; return InvalidOid; } if (fnumber > 0) return tupdesc->attrs[fnumber - 1]->atttypid; else return (SystemAttributeDefinition(fnumber, true))->atttypid; }
Definition at line 845 of file spi.c.
References tupleDesc::attrs, DatumGetPointer, FirstLowInvalidHeapAttributeNumber, getTypeOutputInfo(), heap_getattr, tupleDesc::natts, OidOutputFunctionCall(), pfree(), PG_DETOAST_DATUM, PointerGetDatum, 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(), pltcl_init_load_unknown(), ri_ReportViolation(), triggered_change_notification(), and xpath_table().
{ char *result; Datum origval, val; bool isnull; Oid typoid, foutoid; bool typisvarlena; SPI_result = 0; if (fnumber > tupdesc->natts || fnumber == 0 || fnumber <= FirstLowInvalidHeapAttributeNumber) { SPI_result = SPI_ERROR_NOATTRIBUTE; return NULL; } origval = heap_getattr(tuple, fnumber, tupdesc, &isnull); if (isnull) return NULL; if (fnumber > 0) typoid = tupdesc->attrs[fnumber - 1]->atttypid; else typoid = (SystemAttributeDefinition(fnumber, true))->atttypid; getTypeOutputInfo(typoid, &foutoid, &typisvarlena); /* * If we have a toasted datum, forcibly detoast it here to avoid memory * leakage inside the type's output routine. */ if (typisvarlena) val = PointerGetDatum(PG_DETOAST_DATUM(origval)); else val = origval; result = OidOutputFunctionCall(foutoid, val); /* Clean up detoasted copy, if any */ if (val != origval) pfree(DatumGetPointer(val)); return result; }
bool SPI_is_cursor_plan | ( | SPIPlanPtr | plan | ) |
Definition at line 1446 of file spi.c.
References _SPI_PLAN_MAGIC, linitial, list_length(), _SPI_plan::magic, NULL, _SPI_plan::plancache_list, CachedPlanSource::resultDesc, and SPI_result.
Referenced by SPI_cursor_open_internal().
{ CachedPlanSource *plansource; if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC) { SPI_result = SPI_ERROR_ARGUMENT; return false; } if (list_length(plan->plancache_list) != 1) { SPI_result = 0; return false; /* not exactly 1 pre-rewrite command */ } plansource = (CachedPlanSource *) linitial(plan->plancache_list); /* * We used to force revalidation of the cached plan here, but that seems * unnecessary: invalidation could mean a change in the rowtype of the * tuples returned by a plan, but not whether it returns tuples at all. */ SPI_result = 0; /* Does it return tuples? */ if (plansource->resultDesc) return true; return false; }
int SPI_keepplan | ( | SPIPlanPtr | plan | ) |
Definition at line 599 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(), and _SPI_plan::saved.
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().
{ ListCell *lc; if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || plan->saved || plan->oneshot) return SPI_ERROR_ARGUMENT; /* * Mark it saved, reparent it under CacheMemoryContext, and mark all the * component CachedPlanSources as saved. This sequence cannot fail * partway through, so there's no risk of long-term memory leakage. */ plan->saved = true; MemoryContextSetParent(plan->plancxt, CacheMemoryContext); foreach(lc, plan->plancache_list) { CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc); SaveCachedPlan(plansource); } return 0; }
HeapTuple SPI_modifytuple | ( | Relation | rel, | |
HeapTuple | tuple, | |||
int | natts, | |||
int * | attnum, | |||
Datum * | Values, | |||
const char * | Nulls | |||
) |
Definition at line 734 of file spi.c.
References _SPI_connected, _SPI_curid, elog, ERROR, heap_deform_tuple(), heap_form_tuple(), HeapTupleGetOid, HeapTupleSetOid, i, MemoryContextSwitchTo(), tupleDesc::natts, NULL, palloc(), pfree(), RelationData::rd_att, _SPI_connection::savedcxt, SPI_result, HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_self, HeapTupleData::t_tableOid, and tupleDesc::tdhasoid.
Referenced by autoinc(), insert_username(), moddatetime(), plperl_modify_tuple(), pltcl_trigger_handler(), PLy_modify_tuple(), timetravel(), tsvector_update_trigger(), and ttdummy().
{ MemoryContext oldcxt = NULL; HeapTuple mtuple; int numberOfAttributes; Datum *v; bool *n; int i; if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL) { SPI_result = SPI_ERROR_ARGUMENT; return NULL; } if (_SPI_curid + 1 == _SPI_connected) /* connected */ { if (_SPI_current != &(_SPI_stack[_SPI_curid + 1])) elog(ERROR, "SPI stack corrupted"); oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt); } SPI_result = 0; numberOfAttributes = rel->rd_att->natts; v = (Datum *) palloc(numberOfAttributes * sizeof(Datum)); n = (bool *) palloc(numberOfAttributes * sizeof(bool)); /* fetch old values and nulls */ heap_deform_tuple(tuple, rel->rd_att, v, n); /* replace values and nulls */ for (i = 0; i < natts; i++) { if (attnum[i] <= 0 || attnum[i] > numberOfAttributes) break; v[attnum[i] - 1] = Values[i]; n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? true : false; } if (i == natts) /* no errors in *attnum */ { mtuple = heap_form_tuple(rel->rd_att, v, n); /* * copy the identification info of the old tuple: t_ctid, t_self, and * OID (if any) */ mtuple->t_data->t_ctid = tuple->t_data->t_ctid; mtuple->t_self = tuple->t_self; mtuple->t_tableOid = tuple->t_tableOid; if (rel->rd_att->tdhasoid) HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple)); } else { mtuple = NULL; SPI_result = SPI_ERROR_NOATTRIBUTE; } pfree(v); pfree(n); if (oldcxt) MemoryContextSwitchTo(oldcxt); return mtuple; }
void* SPI_palloc | ( | Size | size | ) |
Definition at line 974 of file spi.c.
References _SPI_connected, _SPI_curid, elog, ERROR, MemoryContextSwitchTo(), palloc(), and _SPI_connection::savedcxt.
Referenced by _SPI_strdup(), and plpgsql_exec_function().
{ MemoryContext oldcxt = NULL; void *pointer; if (_SPI_curid + 1 == _SPI_connected) /* connected */ { if (_SPI_current != &(_SPI_stack[_SPI_curid + 1])) elog(ERROR, "SPI stack corrupted"); oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt); } pointer = palloc(size); if (oldcxt) MemoryContextSwitchTo(oldcxt); return pointer; }
void SPI_pfree | ( | void * | pointer | ) |
CachedPlan* SPI_plan_get_cached_plan | ( | SPIPlanPtr | plan | ) |
Definition at line 1593 of file spi.c.
References _SPI_PLAN_MAGIC, ErrorContextCallback::arg, Assert, ErrorContextCallback::callback, error_context_stack, GetCachedPlan(), CachedPlanSource::gplan, linitial, list_length(), _SPI_plan::magic, NULL, _SPI_plan::oneshot, _SPI_plan::plancache_list, ErrorContextCallback::previous, CachedPlanSource::query_string, and _SPI_plan::saved.
Referenced by exec_eval_simple_expr(), and exec_simple_check_plan().
{ CachedPlanSource *plansource; CachedPlan *cplan; ErrorContextCallback spierrcontext; Assert(plan->magic == _SPI_PLAN_MAGIC); /* Can't support one-shot plans here */ if (plan->oneshot) return NULL; /* Must have exactly one CachedPlanSource */ if (list_length(plan->plancache_list) != 1) return NULL; plansource = (CachedPlanSource *) linitial(plan->plancache_list); /* Setup error traceback support for ereport() */ spierrcontext.callback = _SPI_error_callback; spierrcontext.arg = (void *) plansource->query_string; spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; /* Get the generic plan for the query */ cplan = GetCachedPlan(plansource, NULL, plan->saved); Assert(cplan == plansource->gplan); /* Pop the error context stack */ error_context_stack = spierrcontext.previous; return cplan; }
List* SPI_plan_get_plan_sources | ( | SPIPlanPtr | plan | ) |
Definition at line 1577 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().
{ Assert(plan->magic == _SPI_PLAN_MAGIC); return plan->plancache_list; }
bool SPI_plan_is_valid | ( | SPIPlanPtr | plan | ) |
Definition at line 1484 of file spi.c.
References _SPI_PLAN_MAGIC, Assert, CachedPlanIsValid(), lfirst, _SPI_plan::magic, and _SPI_plan::plancache_list.
Referenced by ri_FetchPreparedPlan().
{ ListCell *lc; Assert(plan->magic == _SPI_PLAN_MAGIC); foreach(lc, plan->plancache_list) { CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc); if (!CachedPlanIsValid(plansource)) return false; } return true; }
void SPI_pop | ( | void | ) |
Definition at line 303 of file spi.c.
References _SPI_curid.
Referenced by database_to_xml_internal(), exec_eval_simple_expr(), and schema_to_xml_internal().
{ _SPI_curid--; }
void SPI_pop_conditional | ( | bool | pushed | ) |
Definition at line 325 of file spi.c.
References _SPI_connected, _SPI_curid, and Assert.
Referenced by BuildCachedPlan(), InputFunctionCall(), OutputFunctionCall(), ReceiveFunctionCall(), and SendFunctionCall().
{ /* We should be in a state where SPI_connect would succeed */ Assert(_SPI_curid == _SPI_connected); if (pushed) _SPI_curid--; }
SPIPlanPtr SPI_prepare | ( | const char * | src, | |
int | nargs, | |||
Oid * | argtypes | |||
) |
Definition at line 521 of file spi.c.
References SPI_prepare_cursor().
Referenced by check_foreign_key(), check_primary_key(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_spi_prepare(), plperl_spi_query(), pltcl_SPI_prepare(), PLy_cursor_query(), PLy_spi_prepare(), query_to_xml_and_xmlschema(), query_to_xmlschema(), RI_Initial_Check(), ri_PlanCheck(), timetravel(), ts_stat_sql(), tsquery_rewrite_query(), and ttdummy().
{ return SPI_prepare_cursor(src, nargs, argtypes, 0); }
SPIPlanPtr SPI_prepare_cursor | ( | const char * | src, | |
int | nargs, | |||
Oid * | argtypes, | |||
int | cursorOptions | |||
) |
Definition at line 527 of file spi.c.
References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_prepare_plan(), _SPI_plan::argtypes, _SPI_plan::cursor_options, _SPI_plan::magic, _SPI_plan::nargs, NULL, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, and SPI_result.
Referenced by SPI_prepare().
{ _SPI_plan plan; SPIPlanPtr result; if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL)) { SPI_result = SPI_ERROR_ARGUMENT; return NULL; } SPI_result = _SPI_begin_call(true); if (SPI_result < 0) return NULL; memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; plan.cursor_options = cursorOptions; plan.nargs = nargs; plan.argtypes = argtypes; plan.parserSetup = NULL; plan.parserSetupArg = NULL; _SPI_prepare_plan(src, &plan); /* copy plan to procedure context */ result = _SPI_make_plan_non_temp(&plan); _SPI_end_call(true); return result; }
SPIPlanPtr SPI_prepare_params | ( | const char * | src, | |
ParserSetupHook | parserSetup, | |||
void * | parserSetupArg, | |||
int | cursorOptions | |||
) |
Definition at line 562 of file spi.c.
References _SPI_begin_call(), _SPI_end_call(), _SPI_make_plan_non_temp(), _SPI_prepare_plan(), _SPI_plan::argtypes, _SPI_plan::cursor_options, _SPI_plan::magic, _SPI_plan::nargs, NULL, _SPI_plan::parserSetup, _SPI_plan::parserSetupArg, and SPI_result.
Referenced by exec_prepare_plan().
{ _SPI_plan plan; SPIPlanPtr result; if (src == NULL) { SPI_result = SPI_ERROR_ARGUMENT; return NULL; } SPI_result = _SPI_begin_call(true); if (SPI_result < 0) return NULL; memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; plan.cursor_options = cursorOptions; plan.nargs = 0; plan.argtypes = NULL; plan.parserSetup = parserSetup; plan.parserSetupArg = parserSetupArg; _SPI_prepare_plan(src, &plan); /* copy plan to procedure context */ result = _SPI_make_plan_non_temp(&plan); _SPI_end_call(true); return result; }
void SPI_push | ( | void | ) |
Definition at line 296 of file spi.c.
References _SPI_curid.
Referenced by database_to_xml_internal(), exec_eval_simple_expr(), and schema_to_xml_internal().
{ _SPI_curid++; }
bool SPI_push_conditional | ( | void | ) |
Definition at line 310 of file spi.c.
References _SPI_connected, _SPI_curid, and Assert.
Referenced by BuildCachedPlan(), InputFunctionCall(), OutputFunctionCall(), ReceiveFunctionCall(), and SendFunctionCall().
{ bool pushed = (_SPI_curid != _SPI_connected); if (pushed) { _SPI_curid++; /* We should now be in a state where SPI_connect would succeed */ Assert(_SPI_curid == _SPI_connected); } return pushed; }
void* SPI_repalloc | ( | void * | pointer, | |
Size | size | |||
) |
Definition at line 995 of file spi.c.
References repalloc().
{ /* No longer need to worry which context chunk was in... */ return repalloc(pointer, size); }
void SPI_restore_connection | ( | void | ) |
Definition at line 335 of file spi.c.
References _SPI_connected, _SPI_curid, and Assert.
Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_subtrans_abort(), pltcl_subtrans_commit(), PLy_abort_open_subtransactions(), PLy_spi_subtransaction_abort(), PLy_spi_subtransaction_commit(), and PLy_subtransaction_exit().
{ Assert(_SPI_connected >= 0); _SPI_curid = _SPI_connected - 1; }
const char* SPI_result_code_string | ( | int | code | ) |
Definition at line 1508 of file spi.c.
References buf, SPI_ERROR_ARGUMENT, SPI_ERROR_CONNECT, SPI_ERROR_COPY, SPI_ERROR_NOATTRIBUTE, SPI_ERROR_NOOUTFUNC, SPI_ERROR_OPUNKNOWN, SPI_ERROR_PARAM, SPI_ERROR_TRANSACTION, SPI_ERROR_TYPUNKNOWN, SPI_ERROR_UNCONNECTED, SPI_OK_CONNECT, SPI_OK_CURSOR, SPI_OK_DELETE, SPI_OK_DELETE_RETURNING, SPI_OK_FETCH, SPI_OK_FINISH, SPI_OK_INSERT, SPI_OK_INSERT_RETURNING, SPI_OK_REWRITTEN, SPI_OK_SELECT, SPI_OK_SELINTO, SPI_OK_UPDATE, SPI_OK_UPDATE_RETURNING, and SPI_OK_UTILITY.
Referenced by exec_dynquery_with_params(), exec_prepare_plan(), exec_run_select(), exec_stmt_dynexecute(), exec_stmt_execsql(), exec_stmt_forc(), exec_stmt_open(), plperl_modify_tuple(), 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().
{ static char buf[64]; switch (code) { case SPI_ERROR_CONNECT: return "SPI_ERROR_CONNECT"; case SPI_ERROR_COPY: return "SPI_ERROR_COPY"; case SPI_ERROR_OPUNKNOWN: return "SPI_ERROR_OPUNKNOWN"; case SPI_ERROR_UNCONNECTED: return "SPI_ERROR_UNCONNECTED"; case SPI_ERROR_ARGUMENT: return "SPI_ERROR_ARGUMENT"; case SPI_ERROR_PARAM: return "SPI_ERROR_PARAM"; case SPI_ERROR_TRANSACTION: return "SPI_ERROR_TRANSACTION"; case SPI_ERROR_NOATTRIBUTE: return "SPI_ERROR_NOATTRIBUTE"; case SPI_ERROR_NOOUTFUNC: return "SPI_ERROR_NOOUTFUNC"; case SPI_ERROR_TYPUNKNOWN: return "SPI_ERROR_TYPUNKNOWN"; case SPI_OK_CONNECT: return "SPI_OK_CONNECT"; case SPI_OK_FINISH: return "SPI_OK_FINISH"; case SPI_OK_FETCH: return "SPI_OK_FETCH"; case SPI_OK_UTILITY: return "SPI_OK_UTILITY"; case SPI_OK_SELECT: return "SPI_OK_SELECT"; case SPI_OK_SELINTO: return "SPI_OK_SELINTO"; case SPI_OK_INSERT: return "SPI_OK_INSERT"; case SPI_OK_DELETE: return "SPI_OK_DELETE"; case SPI_OK_UPDATE: return "SPI_OK_UPDATE"; case SPI_OK_CURSOR: return "SPI_OK_CURSOR"; case SPI_OK_INSERT_RETURNING: return "SPI_OK_INSERT_RETURNING"; case SPI_OK_DELETE_RETURNING: return "SPI_OK_DELETE_RETURNING"; case SPI_OK_UPDATE_RETURNING: return "SPI_OK_UPDATE_RETURNING"; case SPI_OK_REWRITTEN: return "SPI_OK_REWRITTEN"; } /* Unrecognized code ... return something useful ... */ sprintf(buf, "Unrecognized SPI code %d", code); return buf; }
HeapTupleHeader SPI_returntuple | ( | HeapTuple | tuple, | |
TupleDesc | tupdesc | |||
) |
Definition at line 697 of file spi.c.
References _SPI_connected, _SPI_curid, assign_record_type_typmod(), elog, ERROR, HeapTupleHeaderSetDatumLength, HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, MemoryContextSwitchTo(), NULL, palloc(), RECORDOID, _SPI_connection::savedcxt, SPI_result, HeapTupleData::t_data, HeapTupleData::t_len, tupleDesc::tdtypeid, and tupleDesc::tdtypmod.
Referenced by plpgsql_exec_function().
{ MemoryContext oldcxt = NULL; HeapTupleHeader dtup; if (tuple == NULL || tupdesc == NULL) { SPI_result = SPI_ERROR_ARGUMENT; return NULL; } /* For RECORD results, make sure a typmod has been assigned */ if (tupdesc->tdtypeid == RECORDOID && tupdesc->tdtypmod < 0) assign_record_type_typmod(tupdesc); if (_SPI_curid + 1 == _SPI_connected) /* connected */ { if (_SPI_current != &(_SPI_stack[_SPI_curid + 1])) elog(ERROR, "SPI stack corrupted"); oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt); } dtup = (HeapTupleHeader) palloc(tuple->t_len); memcpy((char *) dtup, (char *) tuple->t_data, tuple->t_len); HeapTupleHeaderSetDatumLength(dtup, tuple->t_len); HeapTupleHeaderSetTypeId(dtup, tupdesc->tdtypeid); HeapTupleHeaderSetTypMod(dtup, tupdesc->tdtypmod); if (oldcxt) MemoryContextSwitchTo(oldcxt); return dtup; }
SPIPlanPtr SPI_saveplan | ( | SPIPlanPtr | plan | ) |
Definition at line 626 of file spi.c.
References _SPI_begin_call(), _SPI_end_call(), _SPI_PLAN_MAGIC, _SPI_save_plan(), _SPI_plan::magic, NULL, and SPI_result.
{ SPIPlanPtr newplan; if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC) { SPI_result = SPI_ERROR_ARGUMENT; return NULL; } SPI_result = _SPI_begin_call(false); /* don't change context */ if (SPI_result < 0) return NULL; newplan = _SPI_save_plan(plan); SPI_result = _SPI_end_call(false); return newplan; }
void SPI_scroll_cursor_fetch | ( | Portal | , | |
FetchDirection | direction, | |||
long | count | |||
) |
Definition at line 1371 of file spi.c.
References _SPI_cursor_operation(), CreateDestReceiver(), and DestSPI.
Referenced by exec_stmt_fetch().
{ _SPI_cursor_operation(portal, direction, count, CreateDestReceiver(DestSPI)); /* we know that the DestSPI receiver doesn't need a destroy call */ }
void SPI_scroll_cursor_move | ( | Portal | , | |
FetchDirection | direction, | |||
long | count | |||
) |
Definition at line 1386 of file spi.c.
References _SPI_cursor_operation(), and None_Receiver.
Referenced by exec_stmt_fetch().
{ _SPI_cursor_operation(portal, direction, count, None_Receiver); }
PGDLLIMPORT Oid SPI_lastoid |
Definition at line 39 of file spi.c.
Referenced by _SPI_execute_plan(), AtEOSubXact_SPI(), AtEOXact_SPI(), exec_run_select(), exec_stmt_dynexecute(), exec_stmt_execsql(), pltcl_SPI_lastoid(), and SPI_finish().
PGDLLIMPORT uint32 SPI_processed |
Definition at line 38 of file spi.c.
Referenced by _SPI_cursor_operation(), _SPI_execute_plan(), AtEOSubXact_SPI(), AtEOXact_SPI(), build_tuplestore_recursively(), check_foreign_key(), check_primary_key(), crosstab(), cursor_to_xml(), exec_for_query(), exec_run_select(), exec_stmt_dynexecute(), exec_stmt_execsql(), exec_stmt_fetch(), exec_stmt_return_query(), funny_dup17(), get_crosstab_tuplestore(), get_tuple_of_interest(), initialize_worker_spi(), load_categories_hash(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), pltcl_init_load_unknown(), pltcl_SPI_execute(), pltcl_SPI_execute_plan(), PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_spi_execute_plan(), PLy_spi_execute_query(), query_to_oid_list(), query_to_xml_internal(), RI_Initial_Check(), ri_PerformCheck(), SPI_cursor_open_internal(), SPI_finish(), ts_stat_sql(), tsquery_rewrite_query(), worker_spi_main(), and xpath_table().
PGDLLIMPORT int SPI_result |
Definition at line 41 of file spi.c.
Referenced by autoinc(), check_foreign_key(), check_primary_key(), exec_dynquery_with_params(), exec_prepare_plan(), exec_run_select(), exec_stmt_forc(), exec_stmt_open(), insert_username(), moddatetime(), plperl_modify_tuple(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_trigger_handler(), PLy_cursor_plan(), PLy_cursor_query(), PLy_modify_tuple(), PLy_spi_prepare(), RI_Initial_Check(), ri_PlanCheck(), SPI_copytuple(), SPI_cursor_open_with_args(), SPI_fname(), SPI_getargcount(), SPI_getargtypeid(), SPI_getbinval(), SPI_gettype(), SPI_gettypeid(), SPI_getvalue(), SPI_is_cursor_plan(), SPI_modifytuple(), SPI_prepare_cursor(), SPI_prepare_params(), SPI_returntuple(), SPI_saveplan(), timetravel(), tsvector_update_trigger(), and ttdummy().
PGDLLIMPORT SPITupleTable* SPI_tuptable |
Definition at line 40 of file spi.c.
Referenced by build_tuplestore_recursively(), crosstab(), exec_for_query(), exec_run_select(), exec_stmt_dynexecute(), exec_stmt_execsql(), exec_stmt_fetch(), exec_stmt_return_query(), funny_dup17(), get_crosstab_tuplestore(), get_tuple_of_interest(), initialize_worker_spi(), load_categories_hash(), pg_get_ruledef_worker(), pg_get_viewdef_worker(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), pltcl_init_load_unknown(), pltcl_SPI_execute(), pltcl_SPI_execute_plan(), PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_spi_execute_plan(), PLy_spi_execute_query(), query_to_oid_list(), RI_Initial_Check(), SPI_sql_row_to_xmlelement(), ts_stat_sql(), tsquery_rewrite_query(), worker_spi_main(), and xpath_table().