1 /*-------------------------------------------------------------------------
4 * Server Programming Interface
6 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/executor/spi.c
13 *-------------------------------------------------------------------------
17 #include "access/htup_details.h"
18 #include "access/printtup.h"
19 #include "access/sysattr.h"
20 #include "access/xact.h"
21 #include "catalog/heap.h"
22 #include "catalog/pg_type.h"
23 #include "commands/trigger.h"
24 #include "executor/executor.h"
25 #include "executor/spi_priv.h"
26 #include "miscadmin.h"
27 #include "tcop/pquery.h"
28 #include "tcop/utility.h"
29 #include "utils/builtins.h"
30 #include "utils/datum.h"
31 #include "utils/lsyscache.h"
32 #include "utils/memutils.h"
33 #include "utils/rel.h"
34 #include "utils/snapmgr.h"
35 #include "utils/syscache.h"
36 #include "utils/typcache.h"
39 uint64 SPI_processed = 0;
40 Oid SPI_lastoid = InvalidOid;
41 SPITupleTable *SPI_tuptable = NULL;
44 static _SPI_connection *_SPI_stack = NULL;
45 static _SPI_connection *_SPI_current = NULL;
46 static int _SPI_stack_depth = 0; /* allocated size of _SPI_stack */
47 static int _SPI_connected = -1; /* current stack index */
49 static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
50 ParamListInfo paramLI, bool read_only);
52 static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan);
54 static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan);
56 static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
57 Snapshot snapshot, Snapshot crosscheck_snapshot,
58 bool read_only, bool fire_triggers, uint64 tcount);
60 static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes,
61 Datum *Values, const char *Nulls);
63 static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount);
65 static void _SPI_error_callback(void *arg);
67 static void _SPI_cursor_operation(Portal portal,
68 FetchDirection direction, long count,
71 static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan);
72 static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan);
74 static int _SPI_begin_call(bool execmem);
75 static int _SPI_end_call(bool procmem);
76 static MemoryContext _SPI_execmem(void);
77 static MemoryContext _SPI_procmem(void);
78 static bool _SPI_checktuples(void);
81 /* =================== interface functions =================== */
88 /* Enlarge stack if necessary */
89 if (_SPI_stack == NULL)
91 if (_SPI_connected != -1 || _SPI_stack_depth != 0)
92 elog(ERROR, "SPI stack corrupted");
94 _SPI_stack = (_SPI_connection *)
95 MemoryContextAlloc(TopTransactionContext,
96 newdepth * sizeof(_SPI_connection));
97 _SPI_stack_depth = newdepth;
101 if (_SPI_stack_depth <= 0 || _SPI_stack_depth <= _SPI_connected)
102 elog(ERROR, "SPI stack corrupted");
103 if (_SPI_stack_depth == _SPI_connected + 1)
105 newdepth = _SPI_stack_depth * 2;
106 _SPI_stack = (_SPI_connection *)
108 newdepth * sizeof(_SPI_connection));
109 _SPI_stack_depth = newdepth;
113 /* Enter new stack level */
115 Assert(_SPI_connected >= 0 && _SPI_connected < _SPI_stack_depth);
117 _SPI_current = &(_SPI_stack[_SPI_connected]);
118 _SPI_current->processed = 0;
119 _SPI_current->lastoid = InvalidOid;
120 _SPI_current->tuptable = NULL;
121 slist_init(&_SPI_current->tuptables);
122 _SPI_current->procCxt = NULL; /* in case we fail to create 'em */
123 _SPI_current->execCxt = NULL;
124 _SPI_current->connectSubid = GetCurrentSubTransactionId();
127 * Create memory contexts for this procedure
129 * XXX it would be better to use PortalContext as the parent context, but
130 * we may not be inside a portal (consider deferred-trigger execution).
131 * Perhaps CurTransactionContext would do? For now it doesn't matter
132 * because we clean up explicitly in AtEOSubXact_SPI().
134 _SPI_current->procCxt = AllocSetContextCreate(TopTransactionContext,
136 ALLOCSET_DEFAULT_SIZES);
137 _SPI_current->execCxt = AllocSetContextCreate(TopTransactionContext,
139 ALLOCSET_DEFAULT_SIZES);
140 /* ... and switch to procedure's context */
141 _SPI_current->savedcxt = MemoryContextSwitchTo(_SPI_current->procCxt);
143 return SPI_OK_CONNECT;
151 res = _SPI_begin_call(false); /* live in procedure memory */
155 /* Restore memory context as it was before procedure call */
156 MemoryContextSwitchTo(_SPI_current->savedcxt);
158 /* Release memory used in procedure call (including tuptables) */
159 MemoryContextDelete(_SPI_current->execCxt);
160 _SPI_current->execCxt = NULL;
161 MemoryContextDelete(_SPI_current->procCxt);
162 _SPI_current->procCxt = NULL;
165 * Reset result variables, especially SPI_tuptable which is probably
166 * pointing at a just-deleted tuptable
169 SPI_lastoid = InvalidOid;
172 /* Exit stack level */
174 if (_SPI_connected < 0)
177 _SPI_current = &(_SPI_stack[_SPI_connected]);
179 return SPI_OK_FINISH;
183 * Clean up SPI state at transaction commit or abort.
186 AtEOXact_SPI(bool isCommit)
189 * Note that memory contexts belonging to SPI stack entries will be freed
190 * automatically, so we can ignore them here. We just need to restore our
191 * static variables to initial state.
193 if (isCommit && _SPI_connected != -1)
195 (errcode(ERRCODE_WARNING),
196 errmsg("transaction left non-empty SPI stack"),
197 errhint("Check for missing \"SPI_finish\" calls.")));
199 _SPI_current = _SPI_stack = NULL;
200 _SPI_stack_depth = 0;
203 SPI_lastoid = InvalidOid;
208 * Clean up SPI state at subtransaction commit or abort.
210 * During commit, there shouldn't be any unclosed entries remaining from
211 * the current subtransaction; we emit a warning if any are found.
214 AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
218 while (_SPI_connected >= 0)
220 _SPI_connection *connection = &(_SPI_stack[_SPI_connected]);
222 if (connection->connectSubid != mySubid)
223 break; /* couldn't be any underneath it either */
228 * Release procedure memory explicitly (see note in SPI_connect)
230 if (connection->execCxt)
232 MemoryContextDelete(connection->execCxt);
233 connection->execCxt = NULL;
235 if (connection->procCxt)
237 MemoryContextDelete(connection->procCxt);
238 connection->procCxt = NULL;
242 * Pop the stack entry and reset global variables. Unlike
243 * SPI_finish(), we don't risk switching to memory contexts that might
247 if (_SPI_connected < 0)
250 _SPI_current = &(_SPI_stack[_SPI_connected]);
252 SPI_lastoid = InvalidOid;
256 if (found && isCommit)
258 (errcode(ERRCODE_WARNING),
259 errmsg("subtransaction left non-empty SPI stack"),
260 errhint("Check for missing \"SPI_finish\" calls.")));
263 * If we are aborting a subtransaction and there is an open SPI context
264 * surrounding the subxact, clean up to prevent memory leakage.
266 if (_SPI_current && !isCommit)
268 slist_mutable_iter siter;
270 /* free Executor memory the same as _SPI_end_call would do */
271 MemoryContextResetAndDeleteChildren(_SPI_current->execCxt);
273 /* throw away any tuple tables created within current subxact */
274 slist_foreach_modify(siter, &_SPI_current->tuptables)
276 SPITupleTable *tuptable;
278 tuptable = slist_container(SPITupleTable, next, siter.cur);
279 if (tuptable->subid >= mySubid)
282 * If we used SPI_freetuptable() here, its internal search of
283 * the tuptables list would make this operation O(N^2).
284 * Instead, just free the tuptable manually. This should
285 * match what SPI_freetuptable() does.
287 slist_delete_current(&siter);
288 if (tuptable == _SPI_current->tuptable)
289 _SPI_current->tuptable = NULL;
290 if (tuptable == SPI_tuptable)
292 MemoryContextDelete(tuptable->tuptabcxt);
295 /* in particular we should have gotten rid of any in-progress table */
296 Assert(_SPI_current->tuptable == NULL);
301 /* Parse, plan, and execute a query string */
303 SPI_execute(const char *src, bool read_only, long tcount)
308 if (src == NULL || tcount < 0)
309 return SPI_ERROR_ARGUMENT;
311 res = _SPI_begin_call(true);
315 memset(&plan, 0, sizeof(_SPI_plan));
316 plan.magic = _SPI_PLAN_MAGIC;
317 plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
319 _SPI_prepare_oneshot_plan(src, &plan);
321 res = _SPI_execute_plan(&plan, NULL,
322 InvalidSnapshot, InvalidSnapshot,
323 read_only, true, tcount);
329 /* Obsolete version of SPI_execute */
331 SPI_exec(const char *src, long tcount)
333 return SPI_execute(src, false, tcount);
336 /* Execute a previously prepared plan */
338 SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls,
339 bool read_only, long tcount)
343 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
344 return SPI_ERROR_ARGUMENT;
346 if (plan->nargs > 0 && Values == NULL)
347 return SPI_ERROR_PARAM;
349 res = _SPI_begin_call(true);
353 res = _SPI_execute_plan(plan,
354 _SPI_convert_params(plan->nargs, plan->argtypes,
356 InvalidSnapshot, InvalidSnapshot,
357 read_only, true, tcount);
363 /* Obsolete version of SPI_execute_plan */
365 SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount)
367 return SPI_execute_plan(plan, Values, Nulls, false, tcount);
370 /* Execute a previously prepared plan */
372 SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params,
373 bool read_only, long tcount)
377 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
378 return SPI_ERROR_ARGUMENT;
380 res = _SPI_begin_call(true);
384 res = _SPI_execute_plan(plan, params,
385 InvalidSnapshot, InvalidSnapshot,
386 read_only, true, tcount);
393 * SPI_execute_snapshot -- identical to SPI_execute_plan, except that we allow
394 * the caller to specify exactly which snapshots to use, which will be
395 * registered here. Also, the caller may specify that AFTER triggers should be
396 * queued as part of the outer query rather than being fired immediately at the
397 * end of the command.
399 * This is currently not documented in spi.sgml because it is only intended
400 * for use by RI triggers.
402 * Passing snapshot == InvalidSnapshot will select the normal behavior of
403 * fetching a new snapshot for each query.
406 SPI_execute_snapshot(SPIPlanPtr plan,
407 Datum *Values, const char *Nulls,
408 Snapshot snapshot, Snapshot crosscheck_snapshot,
409 bool read_only, bool fire_triggers, long tcount)
413 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
414 return SPI_ERROR_ARGUMENT;
416 if (plan->nargs > 0 && Values == NULL)
417 return SPI_ERROR_PARAM;
419 res = _SPI_begin_call(true);
423 res = _SPI_execute_plan(plan,
424 _SPI_convert_params(plan->nargs, plan->argtypes,
426 snapshot, crosscheck_snapshot,
427 read_only, fire_triggers, tcount);
434 * SPI_execute_with_args -- plan and execute a query with supplied arguments
436 * This is functionally equivalent to SPI_prepare followed by
440 SPI_execute_with_args(const char *src,
441 int nargs, Oid *argtypes,
442 Datum *Values, const char *Nulls,
443 bool read_only, long tcount)
447 ParamListInfo paramLI;
449 if (src == NULL || nargs < 0 || tcount < 0)
450 return SPI_ERROR_ARGUMENT;
452 if (nargs > 0 && (argtypes == NULL || Values == NULL))
453 return SPI_ERROR_PARAM;
455 res = _SPI_begin_call(true);
459 memset(&plan, 0, sizeof(_SPI_plan));
460 plan.magic = _SPI_PLAN_MAGIC;
461 plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
463 plan.argtypes = argtypes;
464 plan.parserSetup = NULL;
465 plan.parserSetupArg = NULL;
467 paramLI = _SPI_convert_params(nargs, argtypes,
470 _SPI_prepare_oneshot_plan(src, &plan);
472 res = _SPI_execute_plan(&plan, paramLI,
473 InvalidSnapshot, InvalidSnapshot,
474 read_only, true, tcount);
481 SPI_prepare(const char *src, int nargs, Oid *argtypes)
483 return SPI_prepare_cursor(src, nargs, argtypes, 0);
487 SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes,
493 if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
495 SPI_result = SPI_ERROR_ARGUMENT;
499 SPI_result = _SPI_begin_call(true);
503 memset(&plan, 0, sizeof(_SPI_plan));
504 plan.magic = _SPI_PLAN_MAGIC;
505 plan.cursor_options = cursorOptions;
507 plan.argtypes = argtypes;
508 plan.parserSetup = NULL;
509 plan.parserSetupArg = NULL;
511 _SPI_prepare_plan(src, &plan);
513 /* copy plan to procedure context */
514 result = _SPI_make_plan_non_temp(&plan);
522 SPI_prepare_params(const char *src,
523 ParserSetupHook parserSetup,
524 void *parserSetupArg,
532 SPI_result = SPI_ERROR_ARGUMENT;
536 SPI_result = _SPI_begin_call(true);
540 memset(&plan, 0, sizeof(_SPI_plan));
541 plan.magic = _SPI_PLAN_MAGIC;
542 plan.cursor_options = cursorOptions;
544 plan.argtypes = NULL;
545 plan.parserSetup = parserSetup;
546 plan.parserSetupArg = parserSetupArg;
548 _SPI_prepare_plan(src, &plan);
550 /* copy plan to procedure context */
551 result = _SPI_make_plan_non_temp(&plan);
559 SPI_keepplan(SPIPlanPtr plan)
563 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
564 plan->saved || plan->oneshot)
565 return SPI_ERROR_ARGUMENT;
568 * Mark it saved, reparent it under CacheMemoryContext, and mark all the
569 * component CachedPlanSources as saved. This sequence cannot fail
570 * partway through, so there's no risk of long-term memory leakage.
573 MemoryContextSetParent(plan->plancxt, CacheMemoryContext);
575 foreach(lc, plan->plancache_list)
577 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
579 SaveCachedPlan(plansource);
586 SPI_saveplan(SPIPlanPtr plan)
590 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
592 SPI_result = SPI_ERROR_ARGUMENT;
596 SPI_result = _SPI_begin_call(false); /* don't change context */
600 newplan = _SPI_save_plan(plan);
602 SPI_result = _SPI_end_call(false);
608 SPI_freeplan(SPIPlanPtr plan)
612 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
613 return SPI_ERROR_ARGUMENT;
615 /* Release the plancache entries */
616 foreach(lc, plan->plancache_list)
618 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
620 DropCachedPlan(plansource);
623 /* Now get rid of the _SPI_plan and subsidiary data in its plancxt */
624 MemoryContextDelete(plan->plancxt);
630 SPI_copytuple(HeapTuple tuple)
632 MemoryContext oldcxt;
637 SPI_result = SPI_ERROR_ARGUMENT;
641 if (_SPI_current == NULL)
643 SPI_result = SPI_ERROR_UNCONNECTED;
647 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
649 ctuple = heap_copytuple(tuple);
651 MemoryContextSwitchTo(oldcxt);
657 SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc)
659 MemoryContext oldcxt;
660 HeapTupleHeader dtup;
662 if (tuple == NULL || tupdesc == NULL)
664 SPI_result = SPI_ERROR_ARGUMENT;
668 if (_SPI_current == NULL)
670 SPI_result = SPI_ERROR_UNCONNECTED;
674 /* For RECORD results, make sure a typmod has been assigned */
675 if (tupdesc->tdtypeid == RECORDOID &&
676 tupdesc->tdtypmod < 0)
677 assign_record_type_typmod(tupdesc);
679 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
681 dtup = DatumGetHeapTupleHeader(heap_copy_tuple_as_datum(tuple, tupdesc));
683 MemoryContextSwitchTo(oldcxt);
689 SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
690 Datum *Values, const char *Nulls)
692 MemoryContext oldcxt;
694 int numberOfAttributes;
699 if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
701 SPI_result = SPI_ERROR_ARGUMENT;
705 if (_SPI_current == NULL)
707 SPI_result = SPI_ERROR_UNCONNECTED;
711 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
715 numberOfAttributes = rel->rd_att->natts;
716 v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
717 n = (bool *) palloc(numberOfAttributes * sizeof(bool));
719 /* fetch old values and nulls */
720 heap_deform_tuple(tuple, rel->rd_att, v, n);
722 /* replace values and nulls */
723 for (i = 0; i < natts; i++)
725 if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
727 v[attnum[i] - 1] = Values[i];
728 n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? true : false;
731 if (i == natts) /* no errors in *attnum */
733 mtuple = heap_form_tuple(rel->rd_att, v, n);
736 * copy the identification info of the old tuple: t_ctid, t_self, and
739 mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
740 mtuple->t_self = tuple->t_self;
741 mtuple->t_tableOid = tuple->t_tableOid;
742 if (rel->rd_att->tdhasoid)
743 HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
748 SPI_result = SPI_ERROR_NOATTRIBUTE;
754 MemoryContextSwitchTo(oldcxt);
760 SPI_fnumber(TupleDesc tupdesc, const char *fname)
763 Form_pg_attribute sysatt;
765 for (res = 0; res < tupdesc->natts; res++)
767 if (namestrcmp(&tupdesc->attrs[res]->attname, fname) == 0 &&
768 !tupdesc->attrs[res]->attisdropped)
772 sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ );
774 return sysatt->attnum;
776 /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
777 return SPI_ERROR_NOATTRIBUTE;
781 SPI_fname(TupleDesc tupdesc, int fnumber)
783 Form_pg_attribute att;
787 if (fnumber > tupdesc->natts || fnumber == 0 ||
788 fnumber <= FirstLowInvalidHeapAttributeNumber)
790 SPI_result = SPI_ERROR_NOATTRIBUTE;
795 att = tupdesc->attrs[fnumber - 1];
797 att = SystemAttributeDefinition(fnumber, true);
799 return pstrdup(NameStr(att->attname));
803 SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
813 if (fnumber > tupdesc->natts || fnumber == 0 ||
814 fnumber <= FirstLowInvalidHeapAttributeNumber)
816 SPI_result = SPI_ERROR_NOATTRIBUTE;
820 val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
825 typoid = tupdesc->attrs[fnumber - 1]->atttypid;
827 typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
829 getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
831 return OidOutputFunctionCall(foutoid, val);
835 SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
839 if (fnumber > tupdesc->natts || fnumber == 0 ||
840 fnumber <= FirstLowInvalidHeapAttributeNumber)
842 SPI_result = SPI_ERROR_NOATTRIBUTE;
847 return heap_getattr(tuple, fnumber, tupdesc, isnull);
851 SPI_gettype(TupleDesc tupdesc, int fnumber)
859 if (fnumber > tupdesc->natts || fnumber == 0 ||
860 fnumber <= FirstLowInvalidHeapAttributeNumber)
862 SPI_result = SPI_ERROR_NOATTRIBUTE;
867 typoid = tupdesc->attrs[fnumber - 1]->atttypid;
869 typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
871 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
873 if (!HeapTupleIsValid(typeTuple))
875 SPI_result = SPI_ERROR_TYPUNKNOWN;
879 result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
880 ReleaseSysCache(typeTuple);
885 * Get the data type OID for a column.
887 * There's nothing similar for typmod and typcollation. The rare consumers
888 * thereof should inspect the TupleDesc directly.
891 SPI_gettypeid(TupleDesc tupdesc, int fnumber)
895 if (fnumber > tupdesc->natts || fnumber == 0 ||
896 fnumber <= FirstLowInvalidHeapAttributeNumber)
898 SPI_result = SPI_ERROR_NOATTRIBUTE;
903 return tupdesc->attrs[fnumber - 1]->atttypid;
905 return (SystemAttributeDefinition(fnumber, true))->atttypid;
909 SPI_getrelname(Relation rel)
911 return pstrdup(RelationGetRelationName(rel));
915 SPI_getnspname(Relation rel)
917 return get_namespace_name(RelationGetNamespace(rel));
921 SPI_palloc(Size size)
923 if (_SPI_current == NULL)
924 elog(ERROR, "SPI_palloc called while not connected to SPI");
926 return MemoryContextAlloc(_SPI_current->savedcxt, size);
930 SPI_repalloc(void *pointer, Size size)
932 /* No longer need to worry which context chunk was in... */
933 return repalloc(pointer, size);
937 SPI_pfree(void *pointer)
939 /* No longer need to worry which context chunk was in... */
944 SPI_datumTransfer(Datum value, bool typByVal, int typLen)
946 MemoryContext oldcxt;
949 if (_SPI_current == NULL)
950 elog(ERROR, "SPI_datumTransfer called while not connected to SPI");
952 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
954 result = datumTransfer(value, typByVal, typLen);
956 MemoryContextSwitchTo(oldcxt);
962 SPI_freetuple(HeapTuple tuple)
964 /* No longer need to worry which context tuple was in... */
965 heap_freetuple(tuple);
969 SPI_freetuptable(SPITupleTable *tuptable)
973 /* ignore call if NULL pointer */
974 if (tuptable == NULL)
978 * Search only the topmost SPI context for a matching tuple table.
980 if (_SPI_current != NULL)
982 slist_mutable_iter siter;
984 /* find tuptable in active list, then remove it */
985 slist_foreach_modify(siter, &_SPI_current->tuptables)
989 tt = slist_container(SPITupleTable, next, siter.cur);
992 slist_delete_current(&siter);
1000 * Refuse the deletion if we didn't find it in the topmost SPI context.
1001 * This is primarily a guard against double deletion, but might prevent
1002 * other errors as well. Since the worst consequence of not deleting a
1003 * tuptable would be a transient memory leak, this is just a WARNING.
1007 elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);
1011 /* for safety, reset global variables that might point at tuptable */
1012 if (tuptable == _SPI_current->tuptable)
1013 _SPI_current->tuptable = NULL;
1014 if (tuptable == SPI_tuptable)
1015 SPI_tuptable = NULL;
1017 /* release all memory belonging to tuptable */
1018 MemoryContextDelete(tuptable->tuptabcxt);
1025 * Open a prepared SPI plan as a portal
1028 SPI_cursor_open(const char *name, SPIPlanPtr plan,
1029 Datum *Values, const char *Nulls,
1033 ParamListInfo paramLI;
1035 /* build transient ParamListInfo in caller's context */
1036 paramLI = _SPI_convert_params(plan->nargs, plan->argtypes,
1039 portal = SPI_cursor_open_internal(name, plan, paramLI, read_only);
1041 /* done with the transient ParamListInfo */
1050 * SPI_cursor_open_with_args()
1052 * Parse and plan a query and open it as a portal.
1055 SPI_cursor_open_with_args(const char *name,
1057 int nargs, Oid *argtypes,
1058 Datum *Values, const char *Nulls,
1059 bool read_only, int cursorOptions)
1063 ParamListInfo paramLI;
1065 if (src == NULL || nargs < 0)
1066 elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
1068 if (nargs > 0 && (argtypes == NULL || Values == NULL))
1069 elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
1071 SPI_result = _SPI_begin_call(true);
1073 elog(ERROR, "SPI_cursor_open_with_args called while not connected");
1075 memset(&plan, 0, sizeof(_SPI_plan));
1076 plan.magic = _SPI_PLAN_MAGIC;
1077 plan.cursor_options = cursorOptions;
1079 plan.argtypes = argtypes;
1080 plan.parserSetup = NULL;
1081 plan.parserSetupArg = NULL;
1083 /* build transient ParamListInfo in executor context */
1084 paramLI = _SPI_convert_params(nargs, argtypes,
1087 _SPI_prepare_plan(src, &plan);
1089 /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1091 result = SPI_cursor_open_internal(name, &plan, paramLI, read_only);
1094 _SPI_end_call(true);
1101 * SPI_cursor_open_with_paramlist()
1103 * Same as SPI_cursor_open except that parameters (if any) are passed
1104 * as a ParamListInfo, which supports dynamic parameter set determination
1107 SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan,
1108 ParamListInfo params, bool read_only)
1110 return SPI_cursor_open_internal(name, plan, params, read_only);
1115 * SPI_cursor_open_internal()
1117 * Common code for SPI_cursor_open variants
1120 SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
1121 ParamListInfo paramLI, bool read_only)
1123 CachedPlanSource *plansource;
1128 MemoryContext oldcontext;
1130 ErrorContextCallback spierrcontext;
1133 * Check that the plan is something the Portal code will special-case as
1134 * returning one tupleset.
1136 if (!SPI_is_cursor_plan(plan))
1138 /* try to give a good error message */
1139 if (list_length(plan->plancache_list) != 1)
1141 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
1142 errmsg("cannot open multi-query plan as cursor")));
1143 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1145 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
1146 /* translator: %s is name of a SQL command, eg INSERT */
1147 errmsg("cannot open %s query as cursor",
1148 plansource->commandTag)));
1151 Assert(list_length(plan->plancache_list) == 1);
1152 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1154 /* Push the SPI stack */
1155 if (_SPI_begin_call(true) < 0)
1156 elog(ERROR, "SPI_cursor_open called while not connected");
1158 /* Reset SPI result (note we deliberately don't touch lastoid) */
1160 SPI_tuptable = NULL;
1161 _SPI_current->processed = 0;
1162 _SPI_current->tuptable = NULL;
1164 /* Create the portal */
1165 if (name == NULL || name[0] == '\0')
1167 /* Use a random nonconflicting name */
1168 portal = CreateNewPortal();
1172 /* In this path, error if portal of same name already exists */
1173 portal = CreatePortal(name, false, false);
1176 /* Copy the plan's query string into the portal */
1177 query_string = MemoryContextStrdup(PortalGetHeapMemory(portal),
1178 plansource->query_string);
1181 * Setup error traceback support for ereport(), in case GetCachedPlan
1184 spierrcontext.callback = _SPI_error_callback;
1185 spierrcontext.arg = (void *) plansource->query_string;
1186 spierrcontext.previous = error_context_stack;
1187 error_context_stack = &spierrcontext;
1190 * Note: for a saved plan, we mustn't have any failure occur between
1191 * GetCachedPlan and PortalDefineQuery; that would result in leaking our
1192 * plancache refcount.
1195 /* Replan if needed, and increment plan refcount for portal */
1196 cplan = GetCachedPlan(plansource, paramLI, false);
1197 stmt_list = cplan->stmt_list;
1199 /* Pop the error context stack */
1200 error_context_stack = spierrcontext.previous;
1205 * We don't want the portal to depend on an unsaved CachedPlanSource,
1206 * so must copy the plan into the portal's context. An error here
1207 * will result in leaking our refcount on the plan, but it doesn't
1208 * matter because the plan is unsaved and hence transient anyway.
1210 oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
1211 stmt_list = copyObject(stmt_list);
1212 MemoryContextSwitchTo(oldcontext);
1213 ReleaseCachedPlan(cplan, false);
1214 cplan = NULL; /* portal shouldn't depend on cplan */
1218 * Set up the portal.
1220 PortalDefineQuery(portal,
1221 NULL, /* no statement name */
1223 plansource->commandTag,
1228 * Set up options for portal. Default SCROLL type is chosen the same way
1229 * as PerformCursorOpen does it.
1231 portal->cursorOptions = plan->cursor_options;
1232 if (!(portal->cursorOptions & (CURSOR_OPT_SCROLL | CURSOR_OPT_NO_SCROLL)))
1234 if (list_length(stmt_list) == 1 &&
1235 castNode(PlannedStmt, linitial(stmt_list))->commandType != CMD_UTILITY &&
1236 castNode(PlannedStmt, linitial(stmt_list))->rowMarks == NIL &&
1237 ExecSupportsBackwardScan(castNode(PlannedStmt, linitial(stmt_list))->planTree))
1238 portal->cursorOptions |= CURSOR_OPT_SCROLL;
1240 portal->cursorOptions |= CURSOR_OPT_NO_SCROLL;
1244 * Disallow SCROLL with SELECT FOR UPDATE. This is not redundant with the
1245 * check in transformDeclareCursorStmt because the cursor options might
1246 * not have come through there.
1248 if (portal->cursorOptions & CURSOR_OPT_SCROLL)
1250 if (list_length(stmt_list) == 1 &&
1251 castNode(PlannedStmt, linitial(stmt_list))->commandType != CMD_UTILITY &&
1252 castNode(PlannedStmt, linitial(stmt_list))->rowMarks != NIL)
1254 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1255 errmsg("DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported"),
1256 errdetail("Scrollable cursors must be READ ONLY.")));
1260 * If told to be read-only, or in parallel mode, verify that this query is
1261 * in fact read-only. This can't be done earlier because we need to look
1262 * at the finished, planned queries. (In particular, we don't want to do
1263 * it between GetCachedPlan and PortalDefineQuery, because throwing an
1264 * error between those steps would result in leaking our plancache
1267 if (read_only || IsInParallelMode())
1271 foreach(lc, stmt_list)
1273 PlannedStmt *pstmt = castNode(PlannedStmt, lfirst(lc));
1275 if (!CommandIsReadOnly(pstmt))
1279 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1280 /* translator: %s is a SQL statement name */
1281 errmsg("%s is not allowed in a non-volatile function",
1282 CreateCommandTag((Node *) pstmt))));
1284 PreventCommandIfParallelMode(CreateCommandTag((Node *) pstmt));
1289 /* Set up the snapshot to use. */
1291 snapshot = GetActiveSnapshot();
1294 CommandCounterIncrement();
1295 snapshot = GetTransactionSnapshot();
1299 * If the plan has parameters, copy them into the portal. Note that this
1300 * must be done after revalidating the plan, because in dynamic parameter
1301 * cases the set of parameters could have changed during re-parsing.
1305 oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
1306 paramLI = copyParamList(paramLI);
1307 MemoryContextSwitchTo(oldcontext);
1311 * Start portal execution.
1313 PortalStart(portal, paramLI, 0, snapshot);
1315 Assert(portal->strategy != PORTAL_MULTI_QUERY);
1317 /* Pop the SPI stack */
1318 _SPI_end_call(true);
1320 /* Return the created portal */
1328 * Find the portal of an existing open cursor
1331 SPI_cursor_find(const char *name)
1333 return GetPortalByName(name);
1338 * SPI_cursor_fetch()
1340 * Fetch rows in a cursor
1343 SPI_cursor_fetch(Portal portal, bool forward, long count)
1345 _SPI_cursor_operation(portal,
1346 forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1347 CreateDestReceiver(DestSPI));
1348 /* we know that the DestSPI receiver doesn't need a destroy call */
1358 SPI_cursor_move(Portal portal, bool forward, long count)
1360 _SPI_cursor_operation(portal,
1361 forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1367 * SPI_scroll_cursor_fetch()
1369 * Fetch rows in a scrollable cursor
1372 SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, long count)
1374 _SPI_cursor_operation(portal,
1376 CreateDestReceiver(DestSPI));
1377 /* we know that the DestSPI receiver doesn't need a destroy call */
1382 * SPI_scroll_cursor_move()
1384 * Move in a scrollable cursor
1387 SPI_scroll_cursor_move(Portal portal, FetchDirection direction, long count)
1389 _SPI_cursor_operation(portal, direction, count, None_Receiver);
1394 * SPI_cursor_close()
1399 SPI_cursor_close(Portal portal)
1401 if (!PortalIsValid(portal))
1402 elog(ERROR, "invalid portal in SPI cursor operation");
1404 PortalDrop(portal, false);
1408 * Returns the Oid representing the type id for argument at argIndex. First
1409 * parameter is at index zero.
1412 SPI_getargtypeid(SPIPlanPtr plan, int argIndex)
1414 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
1415 argIndex < 0 || argIndex >= plan->nargs)
1417 SPI_result = SPI_ERROR_ARGUMENT;
1420 return plan->argtypes[argIndex];
1424 * Returns the number of arguments for the prepared plan.
1427 SPI_getargcount(SPIPlanPtr plan)
1429 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1431 SPI_result = SPI_ERROR_ARGUMENT;
1438 * Returns true if the plan contains exactly one command
1439 * and that command returns tuples to the caller (eg, SELECT or
1440 * INSERT ... RETURNING, but not SELECT ... INTO). In essence,
1441 * the result indicates if the command can be used with SPI_cursor_open
1444 * plan: A plan previously prepared using SPI_prepare
1447 SPI_is_cursor_plan(SPIPlanPtr plan)
1449 CachedPlanSource *plansource;
1451 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1453 SPI_result = SPI_ERROR_ARGUMENT;
1457 if (list_length(plan->plancache_list) != 1)
1460 return false; /* not exactly 1 pre-rewrite command */
1462 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1465 * We used to force revalidation of the cached plan here, but that seems
1466 * unnecessary: invalidation could mean a change in the rowtype of the
1467 * tuples returned by a plan, but not whether it returns tuples at all.
1471 /* Does it return tuples? */
1472 if (plansource->resultDesc)
1479 * SPI_plan_is_valid --- test whether a SPI plan is currently valid
1480 * (that is, not marked as being in need of revalidation).
1482 * See notes for CachedPlanIsValid before using this.
1485 SPI_plan_is_valid(SPIPlanPtr plan)
1489 Assert(plan->magic == _SPI_PLAN_MAGIC);
1491 foreach(lc, plan->plancache_list)
1493 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1495 if (!CachedPlanIsValid(plansource))
1502 * SPI_result_code_string --- convert any SPI return code to a string
1504 * This is often useful in error messages. Most callers will probably
1505 * only pass negative (error-case) codes, but for generality we recognize
1506 * the success codes too.
1509 SPI_result_code_string(int code)
1511 static char buf[64];
1515 case SPI_ERROR_CONNECT:
1516 return "SPI_ERROR_CONNECT";
1517 case SPI_ERROR_COPY:
1518 return "SPI_ERROR_COPY";
1519 case SPI_ERROR_OPUNKNOWN:
1520 return "SPI_ERROR_OPUNKNOWN";
1521 case SPI_ERROR_UNCONNECTED:
1522 return "SPI_ERROR_UNCONNECTED";
1523 case SPI_ERROR_ARGUMENT:
1524 return "SPI_ERROR_ARGUMENT";
1525 case SPI_ERROR_PARAM:
1526 return "SPI_ERROR_PARAM";
1527 case SPI_ERROR_TRANSACTION:
1528 return "SPI_ERROR_TRANSACTION";
1529 case SPI_ERROR_NOATTRIBUTE:
1530 return "SPI_ERROR_NOATTRIBUTE";
1531 case SPI_ERROR_NOOUTFUNC:
1532 return "SPI_ERROR_NOOUTFUNC";
1533 case SPI_ERROR_TYPUNKNOWN:
1534 return "SPI_ERROR_TYPUNKNOWN";
1535 case SPI_OK_CONNECT:
1536 return "SPI_OK_CONNECT";
1538 return "SPI_OK_FINISH";
1540 return "SPI_OK_FETCH";
1541 case SPI_OK_UTILITY:
1542 return "SPI_OK_UTILITY";
1544 return "SPI_OK_SELECT";
1545 case SPI_OK_SELINTO:
1546 return "SPI_OK_SELINTO";
1548 return "SPI_OK_INSERT";
1550 return "SPI_OK_DELETE";
1552 return "SPI_OK_UPDATE";
1554 return "SPI_OK_CURSOR";
1555 case SPI_OK_INSERT_RETURNING:
1556 return "SPI_OK_INSERT_RETURNING";
1557 case SPI_OK_DELETE_RETURNING:
1558 return "SPI_OK_DELETE_RETURNING";
1559 case SPI_OK_UPDATE_RETURNING:
1560 return "SPI_OK_UPDATE_RETURNING";
1561 case SPI_OK_REWRITTEN:
1562 return "SPI_OK_REWRITTEN";
1564 /* Unrecognized code ... return something useful ... */
1565 sprintf(buf, "Unrecognized SPI code %d", code);
1570 * SPI_plan_get_plan_sources --- get a SPI plan's underlying list of
1571 * CachedPlanSources.
1573 * This is exported so that pl/pgsql can use it (this beats letting pl/pgsql
1574 * look directly into the SPIPlan for itself). It's not documented in
1575 * spi.sgml because we'd just as soon not have too many places using this.
1578 SPI_plan_get_plan_sources(SPIPlanPtr plan)
1580 Assert(plan->magic == _SPI_PLAN_MAGIC);
1581 return plan->plancache_list;
1585 * SPI_plan_get_cached_plan --- get a SPI plan's generic CachedPlan,
1586 * if the SPI plan contains exactly one CachedPlanSource. If not,
1587 * return NULL. Caller is responsible for doing ReleaseCachedPlan().
1589 * This is exported so that pl/pgsql can use it (this beats letting pl/pgsql
1590 * look directly into the SPIPlan for itself). It's not documented in
1591 * spi.sgml because we'd just as soon not have too many places using this.
1594 SPI_plan_get_cached_plan(SPIPlanPtr plan)
1596 CachedPlanSource *plansource;
1598 ErrorContextCallback spierrcontext;
1600 Assert(plan->magic == _SPI_PLAN_MAGIC);
1602 /* Can't support one-shot plans here */
1606 /* Must have exactly one CachedPlanSource */
1607 if (list_length(plan->plancache_list) != 1)
1609 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1611 /* Setup error traceback support for ereport() */
1612 spierrcontext.callback = _SPI_error_callback;
1613 spierrcontext.arg = (void *) plansource->query_string;
1614 spierrcontext.previous = error_context_stack;
1615 error_context_stack = &spierrcontext;
1617 /* Get the generic plan for the query */
1618 cplan = GetCachedPlan(plansource, NULL, plan->saved);
1619 Assert(cplan == plansource->gplan);
1621 /* Pop the error context stack */
1622 error_context_stack = spierrcontext.previous;
1628 /* =================== private functions =================== */
1632 * Initialize to receive tuples from Executor into SPITupleTable
1633 * of current SPI procedure
1636 spi_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
1638 SPITupleTable *tuptable;
1639 MemoryContext oldcxt;
1640 MemoryContext tuptabcxt;
1642 if (_SPI_current == NULL)
1643 elog(ERROR, "spi_dest_startup called while not connected to SPI");
1645 if (_SPI_current->tuptable != NULL)
1646 elog(ERROR, "improper call to spi_dest_startup");
1648 /* We create the tuple table context as a child of procCxt */
1650 oldcxt = _SPI_procmem(); /* switch to procedure memory context */
1652 tuptabcxt = AllocSetContextCreate(CurrentMemoryContext,
1654 ALLOCSET_DEFAULT_SIZES);
1655 MemoryContextSwitchTo(tuptabcxt);
1657 _SPI_current->tuptable = tuptable = (SPITupleTable *)
1658 palloc0(sizeof(SPITupleTable));
1659 tuptable->tuptabcxt = tuptabcxt;
1660 tuptable->subid = GetCurrentSubTransactionId();
1663 * The tuptable is now valid enough to be freed by AtEOSubXact_SPI, so put
1664 * it onto the SPI context's tuptables list. This will ensure it's not
1665 * leaked even in the unlikely event the following few lines fail.
1667 slist_push_head(&_SPI_current->tuptables, &tuptable->next);
1669 /* set up initial allocations */
1670 tuptable->alloced = tuptable->free = 128;
1671 tuptable->vals = (HeapTuple *) palloc(tuptable->alloced * sizeof(HeapTuple));
1672 tuptable->tupdesc = CreateTupleDescCopy(typeinfo);
1674 MemoryContextSwitchTo(oldcxt);
1679 * store tuple retrieved by Executor into SPITupleTable
1680 * of current SPI procedure
1683 spi_printtup(TupleTableSlot *slot, DestReceiver *self)
1685 SPITupleTable *tuptable;
1686 MemoryContext oldcxt;
1688 if (_SPI_current == NULL)
1689 elog(ERROR, "spi_printtup called while not connected to SPI");
1691 tuptable = _SPI_current->tuptable;
1692 if (tuptable == NULL)
1693 elog(ERROR, "improper call to spi_printtup");
1695 oldcxt = MemoryContextSwitchTo(tuptable->tuptabcxt);
1697 if (tuptable->free == 0)
1699 /* Double the size of the pointer array */
1700 tuptable->free = tuptable->alloced;
1701 tuptable->alloced += tuptable->free;
1702 tuptable->vals = (HeapTuple *) repalloc_huge(tuptable->vals,
1703 tuptable->alloced * sizeof(HeapTuple));
1706 tuptable->vals[tuptable->alloced - tuptable->free] =
1707 ExecCopySlotTuple(slot);
1710 MemoryContextSwitchTo(oldcxt);
1720 * Parse and analyze a querystring.
1722 * At entry, plan->argtypes and plan->nargs (or alternatively plan->parserSetup
1723 * and plan->parserSetupArg) must be valid, as must plan->cursor_options.
1725 * Results are stored into *plan (specifically, plan->plancache_list).
1726 * Note that the result data is all in CurrentMemoryContext or child contexts
1727 * thereof; in practice this means it is in the SPI executor context, and
1728 * what we are creating is a "temporary" SPIPlan. Cruft generated during
1729 * parsing is also left in CurrentMemoryContext.
1732 _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
1734 List *raw_parsetree_list;
1735 List *plancache_list;
1736 ListCell *list_item;
1737 ErrorContextCallback spierrcontext;
1740 * Setup error traceback support for ereport()
1742 spierrcontext.callback = _SPI_error_callback;
1743 spierrcontext.arg = (void *) src;
1744 spierrcontext.previous = error_context_stack;
1745 error_context_stack = &spierrcontext;
1748 * Parse the request string into a list of raw parse trees.
1750 raw_parsetree_list = pg_parse_query(src);
1753 * Do parse analysis and rule rewrite for each raw parsetree, storing the
1754 * results into unsaved plancache entries.
1756 plancache_list = NIL;
1758 foreach(list_item, raw_parsetree_list)
1760 RawStmt *parsetree = castNode(RawStmt, lfirst(list_item));
1762 CachedPlanSource *plansource;
1765 * Create the CachedPlanSource before we do parse analysis, since it
1766 * needs to see the unmodified raw parse tree.
1768 plansource = CreateCachedPlan(parsetree,
1770 CreateCommandTag(parsetree->stmt));
1773 * Parameter datatypes are driven by parserSetup hook if provided,
1774 * otherwise we use the fixed parameter list.
1776 if (plan->parserSetup != NULL)
1778 Assert(plan->nargs == 0);
1779 stmt_list = pg_analyze_and_rewrite_params(parsetree,
1782 plan->parserSetupArg);
1786 stmt_list = pg_analyze_and_rewrite(parsetree,
1792 /* Finish filling in the CachedPlanSource */
1793 CompleteCachedPlan(plansource,
1799 plan->parserSetupArg,
1800 plan->cursor_options,
1801 false); /* not fixed result */
1803 plancache_list = lappend(plancache_list, plansource);
1806 plan->plancache_list = plancache_list;
1807 plan->oneshot = false;
1810 * Pop the error context stack
1812 error_context_stack = spierrcontext.previous;
1816 * Parse, but don't analyze, a querystring.
1818 * This is a stripped-down version of _SPI_prepare_plan that only does the
1819 * initial raw parsing. It creates "one shot" CachedPlanSources
1820 * that still require parse analysis before execution is possible.
1822 * The advantage of using the "one shot" form of CachedPlanSource is that
1823 * we eliminate data copying and invalidation overhead. Postponing parse
1824 * analysis also prevents issues if some of the raw parsetrees are DDL
1825 * commands that affect validity of later parsetrees. Both of these
1826 * attributes are good things for SPI_execute() and similar cases.
1828 * Results are stored into *plan (specifically, plan->plancache_list).
1829 * Note that the result data is all in CurrentMemoryContext or child contexts
1830 * thereof; in practice this means it is in the SPI executor context, and
1831 * what we are creating is a "temporary" SPIPlan. Cruft generated during
1832 * parsing is also left in CurrentMemoryContext.
1835 _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
1837 List *raw_parsetree_list;
1838 List *plancache_list;
1839 ListCell *list_item;
1840 ErrorContextCallback spierrcontext;
1843 * Setup error traceback support for ereport()
1845 spierrcontext.callback = _SPI_error_callback;
1846 spierrcontext.arg = (void *) src;
1847 spierrcontext.previous = error_context_stack;
1848 error_context_stack = &spierrcontext;
1851 * Parse the request string into a list of raw parse trees.
1853 raw_parsetree_list = pg_parse_query(src);
1856 * Construct plancache entries, but don't do parse analysis yet.
1858 plancache_list = NIL;
1860 foreach(list_item, raw_parsetree_list)
1862 RawStmt *parsetree = castNode(RawStmt, lfirst(list_item));
1863 CachedPlanSource *plansource;
1865 plansource = CreateOneShotCachedPlan(parsetree,
1867 CreateCommandTag(parsetree->stmt));
1869 plancache_list = lappend(plancache_list, plansource);
1872 plan->plancache_list = plancache_list;
1873 plan->oneshot = true;
1876 * Pop the error context stack
1878 error_context_stack = spierrcontext.previous;
1882 * Execute the given plan with the given parameter values
1884 * snapshot: query snapshot to use, or InvalidSnapshot for the normal
1885 * behavior of taking a new snapshot for each query.
1886 * crosscheck_snapshot: for RI use, all others pass InvalidSnapshot
1887 * read_only: TRUE for read-only execution (no CommandCounterIncrement)
1888 * fire_triggers: TRUE to fire AFTER triggers at end of query (normal case);
1889 * FALSE means any AFTER triggers are postponed to end of outer query
1890 * tcount: execution tuple-count limit, or 0 for none
1893 _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
1894 Snapshot snapshot, Snapshot crosscheck_snapshot,
1895 bool read_only, bool fire_triggers, uint64 tcount)
1898 uint64 my_processed = 0;
1899 Oid my_lastoid = InvalidOid;
1900 SPITupleTable *my_tuptable = NULL;
1902 bool pushed_active_snap = false;
1903 ErrorContextCallback spierrcontext;
1904 CachedPlan *cplan = NULL;
1908 * Setup error traceback support for ereport()
1910 spierrcontext.callback = _SPI_error_callback;
1911 spierrcontext.arg = NULL; /* we'll fill this below */
1912 spierrcontext.previous = error_context_stack;
1913 error_context_stack = &spierrcontext;
1916 * We support four distinct snapshot management behaviors:
1918 * snapshot != InvalidSnapshot, read_only = true: use exactly the given
1921 * snapshot != InvalidSnapshot, read_only = false: use the given snapshot,
1922 * modified by advancing its command ID before each querytree.
1924 * snapshot == InvalidSnapshot, read_only = true: use the entry-time
1925 * ActiveSnapshot, if any (if there isn't one, we run with no snapshot).
1927 * snapshot == InvalidSnapshot, read_only = false: take a full new
1928 * snapshot for each user command, and advance its command ID before each
1929 * querytree within the command.
1931 * In the first two cases, we can just push the snap onto the stack once
1932 * for the whole plan list.
1934 if (snapshot != InvalidSnapshot)
1938 PushActiveSnapshot(snapshot);
1939 pushed_active_snap = true;
1943 /* Make sure we have a private copy of the snapshot to modify */
1944 PushCopiedSnapshot(snapshot);
1945 pushed_active_snap = true;
1949 foreach(lc1, plan->plancache_list)
1951 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc1);
1955 spierrcontext.arg = (void *) plansource->query_string;
1958 * If this is a one-shot plan, we still need to do parse analysis.
1962 RawStmt *parsetree = plansource->raw_parse_tree;
1963 const char *src = plansource->query_string;
1967 * Parameter datatypes are driven by parserSetup hook if provided,
1968 * otherwise we use the fixed parameter list.
1970 if (parsetree == NULL)
1972 else if (plan->parserSetup != NULL)
1974 Assert(plan->nargs == 0);
1975 stmt_list = pg_analyze_and_rewrite_params(parsetree,
1978 plan->parserSetupArg);
1982 stmt_list = pg_analyze_and_rewrite(parsetree,
1988 /* Finish filling in the CachedPlanSource */
1989 CompleteCachedPlan(plansource,
1995 plan->parserSetupArg,
1996 plan->cursor_options,
1997 false); /* not fixed result */
2001 * Replan if needed, and increment plan refcount. If it's a saved
2002 * plan, the refcount must be backed by the CurrentResourceOwner.
2004 cplan = GetCachedPlan(plansource, paramLI, plan->saved);
2005 stmt_list = cplan->stmt_list;
2008 * In the default non-read-only case, get a new snapshot, replacing
2009 * any that we pushed in a previous cycle.
2011 if (snapshot == InvalidSnapshot && !read_only)
2013 if (pushed_active_snap)
2014 PopActiveSnapshot();
2015 PushActiveSnapshot(GetTransactionSnapshot());
2016 pushed_active_snap = true;
2019 foreach(lc2, stmt_list)
2021 PlannedStmt *stmt = castNode(PlannedStmt, lfirst(lc2));
2022 bool canSetTag = stmt->canSetTag;
2025 _SPI_current->processed = 0;
2026 _SPI_current->lastoid = InvalidOid;
2027 _SPI_current->tuptable = NULL;
2029 if (stmt->utilityStmt)
2031 if (IsA(stmt->utilityStmt, CopyStmt))
2033 CopyStmt *cstmt = (CopyStmt *) stmt->utilityStmt;
2035 if (cstmt->filename == NULL)
2037 my_res = SPI_ERROR_COPY;
2041 else if (IsA(stmt->utilityStmt, TransactionStmt))
2043 my_res = SPI_ERROR_TRANSACTION;
2048 if (read_only && !CommandIsReadOnly(stmt))
2050 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2051 /* translator: %s is a SQL statement name */
2052 errmsg("%s is not allowed in a non-volatile function",
2053 CreateCommandTag((Node *) stmt))));
2055 if (IsInParallelMode() && !CommandIsReadOnly(stmt))
2056 PreventCommandIfParallelMode(CreateCommandTag((Node *) stmt));
2059 * If not read-only mode, advance the command counter before each
2060 * command and update the snapshot.
2064 CommandCounterIncrement();
2065 UpdateActiveSnapshotCommandId();
2068 dest = CreateDestReceiver(canSetTag ? DestSPI : DestNone);
2070 if (stmt->utilityStmt == NULL)
2075 if (ActiveSnapshotSet())
2076 snap = GetActiveSnapshot();
2078 snap = InvalidSnapshot;
2080 qdesc = CreateQueryDesc(stmt,
2081 plansource->query_string,
2082 snap, crosscheck_snapshot,
2085 res = _SPI_pquery(qdesc, fire_triggers,
2086 canSetTag ? tcount : 0);
2087 FreeQueryDesc(qdesc);
2091 char completionTag[COMPLETION_TAG_BUFSIZE];
2093 ProcessUtility(stmt,
2094 plansource->query_string,
2095 PROCESS_UTILITY_QUERY,
2100 /* Update "processed" if stmt returned tuples */
2101 if (_SPI_current->tuptable)
2102 _SPI_current->processed = _SPI_current->tuptable->alloced -
2103 _SPI_current->tuptable->free;
2105 res = SPI_OK_UTILITY;
2108 * Some utility statements return a row count, even though the
2109 * tuples are not returned to the caller.
2111 if (IsA(stmt->utilityStmt, CreateTableAsStmt))
2113 CreateTableAsStmt *ctastmt = (CreateTableAsStmt *) stmt->utilityStmt;
2115 if (strncmp(completionTag, "SELECT ", 7) == 0)
2116 _SPI_current->processed =
2117 pg_strtouint64(completionTag + 7, NULL, 10);
2121 * Must be an IF NOT EXISTS that did nothing, or a
2122 * CREATE ... WITH NO DATA.
2124 Assert(ctastmt->if_not_exists ||
2125 ctastmt->into->skipData);
2126 _SPI_current->processed = 0;
2130 * For historical reasons, if CREATE TABLE AS was spelled
2131 * as SELECT INTO, return a special return code.
2133 if (ctastmt->is_select_into)
2134 res = SPI_OK_SELINTO;
2136 else if (IsA(stmt->utilityStmt, CopyStmt))
2138 Assert(strncmp(completionTag, "COPY ", 5) == 0);
2139 _SPI_current->processed = pg_strtouint64(completionTag + 5,
2145 * The last canSetTag query sets the status values returned to the
2146 * caller. Be careful to free any tuptables not returned, to
2147 * avoid intratransaction memory leak.
2151 my_processed = _SPI_current->processed;
2152 my_lastoid = _SPI_current->lastoid;
2153 SPI_freetuptable(my_tuptable);
2154 my_tuptable = _SPI_current->tuptable;
2159 SPI_freetuptable(_SPI_current->tuptable);
2160 _SPI_current->tuptable = NULL;
2162 /* we know that the receiver doesn't need a destroy call */
2170 /* Done with this plan, so release refcount */
2171 ReleaseCachedPlan(cplan, plan->saved);
2175 * If not read-only mode, advance the command counter after the last
2176 * command. This ensures that its effects are visible, in case it was
2177 * DDL that would affect the next CachedPlanSource.
2180 CommandCounterIncrement();
2185 /* Pop the snapshot off the stack if we pushed one */
2186 if (pushed_active_snap)
2187 PopActiveSnapshot();
2189 /* We no longer need the cached plan refcount, if any */
2191 ReleaseCachedPlan(cplan, plan->saved);
2194 * Pop the error context stack
2196 error_context_stack = spierrcontext.previous;
2198 /* Save results for caller */
2199 SPI_processed = my_processed;
2200 SPI_lastoid = my_lastoid;
2201 SPI_tuptable = my_tuptable;
2203 /* tuptable now is caller's responsibility, not SPI's */
2204 _SPI_current->tuptable = NULL;
2207 * If none of the queries had canSetTag, return SPI_OK_REWRITTEN. Prior to
2208 * 8.4, we used return the last query's result code, but not its auxiliary
2209 * results, but that's confusing.
2212 my_res = SPI_OK_REWRITTEN;
2218 * Convert arrays of query parameters to form wanted by planner and executor
2220 static ParamListInfo
2221 _SPI_convert_params(int nargs, Oid *argtypes,
2222 Datum *Values, const char *Nulls)
2224 ParamListInfo paramLI;
2230 paramLI = (ParamListInfo) palloc(offsetof(ParamListInfoData, params) +
2231 nargs * sizeof(ParamExternData));
2232 /* we have static list of params, so no hooks needed */
2233 paramLI->paramFetch = NULL;
2234 paramLI->paramFetchArg = NULL;
2235 paramLI->parserSetup = NULL;
2236 paramLI->parserSetupArg = NULL;
2237 paramLI->numParams = nargs;
2238 paramLI->paramMask = NULL;
2240 for (i = 0; i < nargs; i++)
2242 ParamExternData *prm = ¶mLI->params[i];
2244 prm->value = Values[i];
2245 prm->isnull = (Nulls && Nulls[i] == 'n');
2246 prm->pflags = PARAM_FLAG_CONST;
2247 prm->ptype = argtypes[i];
2256 _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount)
2258 int operation = queryDesc->operation;
2265 if (queryDesc->dest->mydest != DestSPI)
2267 /* Don't return SPI_OK_SELECT if we're discarding result */
2268 res = SPI_OK_UTILITY;
2271 res = SPI_OK_SELECT;
2274 if (queryDesc->plannedstmt->hasReturning)
2275 res = SPI_OK_INSERT_RETURNING;
2277 res = SPI_OK_INSERT;
2280 if (queryDesc->plannedstmt->hasReturning)
2281 res = SPI_OK_DELETE_RETURNING;
2283 res = SPI_OK_DELETE;
2286 if (queryDesc->plannedstmt->hasReturning)
2287 res = SPI_OK_UPDATE_RETURNING;
2289 res = SPI_OK_UPDATE;
2292 return SPI_ERROR_OPUNKNOWN;
2295 #ifdef SPI_EXECUTOR_STATS
2296 if (ShowExecutorStats)
2300 /* Select execution options */
2302 eflags = 0; /* default run-to-completion flags */
2304 eflags = EXEC_FLAG_SKIP_TRIGGERS;
2306 ExecutorStart(queryDesc, eflags);
2308 ExecutorRun(queryDesc, ForwardScanDirection, tcount, true);
2310 _SPI_current->processed = queryDesc->estate->es_processed;
2311 _SPI_current->lastoid = queryDesc->estate->es_lastoid;
2313 if ((res == SPI_OK_SELECT || queryDesc->plannedstmt->hasReturning) &&
2314 queryDesc->dest->mydest == DestSPI)
2316 if (_SPI_checktuples())
2317 elog(ERROR, "consistency check on SPI tuple count failed");
2320 ExecutorFinish(queryDesc);
2321 ExecutorEnd(queryDesc);
2322 /* FreeQueryDesc is done by the caller */
2324 #ifdef SPI_EXECUTOR_STATS
2325 if (ShowExecutorStats)
2326 ShowUsage("SPI EXECUTOR STATS");
2333 * _SPI_error_callback
2335 * Add context information when a query invoked via SPI fails
2338 _SPI_error_callback(void *arg)
2340 const char *query = (const char *) arg;
2341 int syntaxerrposition;
2344 * If there is a syntax error position, convert to internal syntax error;
2345 * otherwise treat the query as an item of context stack
2347 syntaxerrposition = geterrposition();
2348 if (syntaxerrposition > 0)
2351 internalerrposition(syntaxerrposition);
2352 internalerrquery(query);
2355 errcontext("SQL statement \"%s\"", query);
2359 * _SPI_cursor_operation()
2361 * Do a FETCH or MOVE in a cursor
2364 _SPI_cursor_operation(Portal portal, FetchDirection direction, long count,
2369 /* Check that the portal is valid */
2370 if (!PortalIsValid(portal))
2371 elog(ERROR, "invalid portal in SPI cursor operation");
2373 /* Push the SPI stack */
2374 if (_SPI_begin_call(true) < 0)
2375 elog(ERROR, "SPI cursor operation called while not connected");
2377 /* Reset the SPI result (note we deliberately don't touch lastoid) */
2379 SPI_tuptable = NULL;
2380 _SPI_current->processed = 0;
2381 _SPI_current->tuptable = NULL;
2383 /* Run the cursor */
2384 nfetched = PortalRunFetch(portal,
2390 * Think not to combine this store with the preceding function call. If
2391 * the portal contains calls to functions that use SPI, then SPI_stack is
2392 * likely to move around while the portal runs. When control returns,
2393 * _SPI_current will point to the correct stack entry... but the pointer
2394 * may be different than it was beforehand. So we must be sure to re-fetch
2395 * the pointer after the function call completes.
2397 _SPI_current->processed = nfetched;
2399 if (dest->mydest == DestSPI && _SPI_checktuples())
2400 elog(ERROR, "consistency check on SPI tuple count failed");
2402 /* Put the result into place for access by caller */
2403 SPI_processed = _SPI_current->processed;
2404 SPI_tuptable = _SPI_current->tuptable;
2406 /* tuptable now is caller's responsibility, not SPI's */
2407 _SPI_current->tuptable = NULL;
2409 /* Pop the SPI stack */
2410 _SPI_end_call(true);
2414 static MemoryContext
2417 return MemoryContextSwitchTo(_SPI_current->execCxt);
2420 static MemoryContext
2423 return MemoryContextSwitchTo(_SPI_current->procCxt);
2427 * _SPI_begin_call: begin a SPI operation within a connected procedure
2430 _SPI_begin_call(bool execmem)
2432 if (_SPI_current == NULL)
2433 return SPI_ERROR_UNCONNECTED;
2435 if (execmem) /* switch to the Executor memory context */
2442 * _SPI_end_call: end a SPI operation within a connected procedure
2444 * Note: this currently has no failure return cases, so callers don't check
2447 _SPI_end_call(bool procmem)
2449 if (procmem) /* switch to the procedure memory context */
2452 /* and free Executor memory */
2453 MemoryContextResetAndDeleteChildren(_SPI_current->execCxt);
2460 _SPI_checktuples(void)
2462 uint64 processed = _SPI_current->processed;
2463 SPITupleTable *tuptable = _SPI_current->tuptable;
2464 bool failed = false;
2466 if (tuptable == NULL) /* spi_dest_startup was not called */
2468 else if (processed != (tuptable->alloced - tuptable->free))
2475 * Convert a "temporary" SPIPlan into an "unsaved" plan.
2477 * The passed _SPI_plan struct is on the stack, and all its subsidiary data
2478 * is in or under the current SPI executor context. Copy the plan into the
2479 * SPI procedure context so it will survive _SPI_end_call(). To minimize
2480 * data copying, this destructively modifies the input plan, by taking the
2481 * plancache entries away from it and reparenting them to the new SPIPlan.
2484 _SPI_make_plan_non_temp(SPIPlanPtr plan)
2487 MemoryContext parentcxt = _SPI_current->procCxt;
2488 MemoryContext plancxt;
2489 MemoryContext oldcxt;
2492 /* Assert the input is a temporary SPIPlan */
2493 Assert(plan->magic == _SPI_PLAN_MAGIC);
2494 Assert(plan->plancxt == NULL);
2495 /* One-shot plans can't be saved */
2496 Assert(!plan->oneshot);
2499 * Create a memory context for the plan, underneath the procedure context.
2500 * We don't expect the plan to be very large.
2502 plancxt = AllocSetContextCreate(parentcxt,
2504 ALLOCSET_SMALL_SIZES);
2505 oldcxt = MemoryContextSwitchTo(plancxt);
2507 /* Copy the SPI_plan struct and subsidiary data into the new context */
2508 newplan = (SPIPlanPtr) palloc(sizeof(_SPI_plan));
2509 newplan->magic = _SPI_PLAN_MAGIC;
2510 newplan->saved = false;
2511 newplan->oneshot = false;
2512 newplan->plancache_list = NIL;
2513 newplan->plancxt = plancxt;
2514 newplan->cursor_options = plan->cursor_options;
2515 newplan->nargs = plan->nargs;
2516 if (plan->nargs > 0)
2518 newplan->argtypes = (Oid *) palloc(plan->nargs * sizeof(Oid));
2519 memcpy(newplan->argtypes, plan->argtypes, plan->nargs * sizeof(Oid));
2522 newplan->argtypes = NULL;
2523 newplan->parserSetup = plan->parserSetup;
2524 newplan->parserSetupArg = plan->parserSetupArg;
2527 * Reparent all the CachedPlanSources into the procedure context. In
2528 * theory this could fail partway through due to the pallocs, but we don't
2529 * care too much since both the procedure context and the executor context
2530 * would go away on error.
2532 foreach(lc, plan->plancache_list)
2534 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
2536 CachedPlanSetParentContext(plansource, parentcxt);
2538 /* Build new list, with list cells in plancxt */
2539 newplan->plancache_list = lappend(newplan->plancache_list, plansource);
2542 MemoryContextSwitchTo(oldcxt);
2544 /* For safety, unlink the CachedPlanSources from the temporary plan */
2545 plan->plancache_list = NIL;
2551 * Make a "saved" copy of the given plan.
2554 _SPI_save_plan(SPIPlanPtr plan)
2557 MemoryContext plancxt;
2558 MemoryContext oldcxt;
2561 /* One-shot plans can't be saved */
2562 Assert(!plan->oneshot);
2565 * Create a memory context for the plan. We don't expect the plan to be
2566 * very large, so use smaller-than-default alloc parameters. It's a
2567 * transient context until we finish copying everything.
2569 plancxt = AllocSetContextCreate(CurrentMemoryContext,
2571 ALLOCSET_SMALL_SIZES);
2572 oldcxt = MemoryContextSwitchTo(plancxt);
2574 /* Copy the SPI plan into its own context */
2575 newplan = (SPIPlanPtr) palloc(sizeof(_SPI_plan));
2576 newplan->magic = _SPI_PLAN_MAGIC;
2577 newplan->saved = false;
2578 newplan->oneshot = false;
2579 newplan->plancache_list = NIL;
2580 newplan->plancxt = plancxt;
2581 newplan->cursor_options = plan->cursor_options;
2582 newplan->nargs = plan->nargs;
2583 if (plan->nargs > 0)
2585 newplan->argtypes = (Oid *) palloc(plan->nargs * sizeof(Oid));
2586 memcpy(newplan->argtypes, plan->argtypes, plan->nargs * sizeof(Oid));
2589 newplan->argtypes = NULL;
2590 newplan->parserSetup = plan->parserSetup;
2591 newplan->parserSetupArg = plan->parserSetupArg;
2593 /* Copy all the plancache entries */
2594 foreach(lc, plan->plancache_list)
2596 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
2597 CachedPlanSource *newsource;
2599 newsource = CopyCachedPlan(plansource);
2600 newplan->plancache_list = lappend(newplan->plancache_list, newsource);
2603 MemoryContextSwitchTo(oldcxt);
2606 * Mark it saved, reparent it under CacheMemoryContext, and mark all the
2607 * component CachedPlanSources as saved. This sequence cannot fail
2608 * partway through, so there's no risk of long-term memory leakage.
2610 newplan->saved = true;
2611 MemoryContextSetParent(newplan->plancxt, CacheMemoryContext);
2613 foreach(lc, newplan->plancache_list)
2615 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
2617 SaveCachedPlan(plansource);