Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Functions | Variables

spi.h File Reference

#include "nodes/parsenodes.h"
#include "utils/portal.h"
Include dependency graph for spi.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SPITupleTable

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_planSPIPlanPtr

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)
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)
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 SPITupleTableSPI_tuptable
PGDLLIMPORT int SPI_result

Define Documentation

#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)
#define SPI_ERROR_CURSOR   (-5)

Definition at line 36 of file spi.h.

#define SPI_ERROR_NOATTRIBUTE   (-9)
#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)
#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
#define SPI_OK_CURSOR   10

Definition at line 53 of file spi.h.

Referenced by SPI_result_code_string().

#define SPI_OK_DELETE   8
#define SPI_OK_DELETE_RETURNING   12
#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
#define SPI_OK_INSERT   7
#define SPI_OK_INSERT_RETURNING   11
#define SPI_OK_REWRITTEN   14
#define SPI_OK_SELECT   5
#define SPI_OK_SELINTO   6
#define SPI_OK_UPDATE   9
#define SPI_OK_UPDATE_RETURNING   13
#define SPI_OK_UTILITY   4

Typedef Documentation

typedef struct _SPI_plan* SPIPlanPtr

Definition at line 30 of file spi.h.

typedef struct SPITupleTable SPITupleTable

Function Documentation

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;
}

HeapTuple SPI_copytuple ( HeapTuple  tuple  ) 

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  ) 
void SPI_cursor_fetch ( Portal  portal,
bool  forward,
long  count 
)
Portal SPI_cursor_find ( const char *  name  ) 
void SPI_cursor_move ( Portal  portal,
bool  forward,
long  count 
)

Definition at line 1357 of file spi.c.

References _SPI_cursor_operation(), FETCH_BACKWARD, FETCH_FORWARD, and 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 
)
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  ) 
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];
}

Datum SPI_getbinval ( HeapTuple  tuple,
TupleDesc  tupdesc,
int  fnumber,
bool isnull 
)
char* SPI_getnspname ( Relation  rel  ) 
char* SPI_getrelname ( Relation  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;
}

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

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  ) 

Definition at line 1002 of file spi.c.

References pfree().

{
    /* No longer need to worry which context chunk was in... */
    pfree(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 
)
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   ) 
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);
}


Variable Documentation

PGDLLIMPORT Oid SPI_lastoid
PGDLLIMPORT uint32 SPI_processed
PGDLLIMPORT int SPI_result