1 /*-------------------------------------------------------------------------
4 * Server Programming Interface
6 * Portions Copyright (c) 1996-2013, 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 "tcop/pquery.h"
27 #include "tcop/utility.h"
28 #include "utils/builtins.h"
29 #include "utils/datum.h"
30 #include "utils/lsyscache.h"
31 #include "utils/memutils.h"
32 #include "utils/rel.h"
33 #include "utils/snapmgr.h"
34 #include "utils/syscache.h"
35 #include "utils/typcache.h"
38 uint32 SPI_processed = 0;
39 Oid SPI_lastoid = InvalidOid;
40 SPITupleTable *SPI_tuptable = NULL;
43 static _SPI_connection *_SPI_stack = NULL;
44 static _SPI_connection *_SPI_current = NULL;
45 static int _SPI_stack_depth = 0; /* allocated size of _SPI_stack */
46 static int _SPI_connected = -1;
47 static int _SPI_curid = -1;
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, long 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, long 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 =================== */
89 * When procedure called by Executor _SPI_curid expected to be equal to
92 if (_SPI_curid != _SPI_connected)
93 return SPI_ERROR_CONNECT;
95 if (_SPI_stack == NULL)
97 if (_SPI_connected != -1 || _SPI_stack_depth != 0)
98 elog(ERROR, "SPI stack corrupted");
100 _SPI_stack = (_SPI_connection *)
101 MemoryContextAlloc(TopTransactionContext,
102 newdepth * sizeof(_SPI_connection));
103 _SPI_stack_depth = newdepth;
107 if (_SPI_stack_depth <= 0 || _SPI_stack_depth <= _SPI_connected)
108 elog(ERROR, "SPI stack corrupted");
109 if (_SPI_stack_depth == _SPI_connected + 1)
111 newdepth = _SPI_stack_depth * 2;
112 _SPI_stack = (_SPI_connection *)
114 newdepth * sizeof(_SPI_connection));
115 _SPI_stack_depth = newdepth;
120 * We're entering procedure where _SPI_curid == _SPI_connected - 1
123 Assert(_SPI_connected >= 0 && _SPI_connected < _SPI_stack_depth);
125 _SPI_current = &(_SPI_stack[_SPI_connected]);
126 _SPI_current->processed = 0;
127 _SPI_current->lastoid = InvalidOid;
128 _SPI_current->tuptable = NULL;
129 slist_init(&_SPI_current->tuptables);
130 _SPI_current->procCxt = NULL; /* in case we fail to create 'em */
131 _SPI_current->execCxt = NULL;
132 _SPI_current->connectSubid = GetCurrentSubTransactionId();
135 * Create memory contexts for this procedure
137 * XXX it would be better to use PortalContext as the parent context, but
138 * we may not be inside a portal (consider deferred-trigger execution).
139 * Perhaps CurTransactionContext would do? For now it doesn't matter
140 * because we clean up explicitly in AtEOSubXact_SPI().
142 _SPI_current->procCxt = AllocSetContextCreate(TopTransactionContext,
144 ALLOCSET_DEFAULT_MINSIZE,
145 ALLOCSET_DEFAULT_INITSIZE,
146 ALLOCSET_DEFAULT_MAXSIZE);
147 _SPI_current->execCxt = AllocSetContextCreate(TopTransactionContext,
149 ALLOCSET_DEFAULT_MINSIZE,
150 ALLOCSET_DEFAULT_INITSIZE,
151 ALLOCSET_DEFAULT_MAXSIZE);
152 /* ... and switch to procedure's context */
153 _SPI_current->savedcxt = MemoryContextSwitchTo(_SPI_current->procCxt);
155 return SPI_OK_CONNECT;
163 res = _SPI_begin_call(false); /* live in procedure memory */
167 /* Restore memory context as it was before procedure call */
168 MemoryContextSwitchTo(_SPI_current->savedcxt);
170 /* Release memory used in procedure call (including tuptables) */
171 MemoryContextDelete(_SPI_current->execCxt);
172 _SPI_current->execCxt = NULL;
173 MemoryContextDelete(_SPI_current->procCxt);
174 _SPI_current->procCxt = NULL;
177 * Reset result variables, especially SPI_tuptable which is probably
178 * pointing at a just-deleted tuptable
181 SPI_lastoid = InvalidOid;
185 * After _SPI_begin_call _SPI_connected == _SPI_curid. Now we are closing
186 * connection to SPI and returning to upper Executor and so _SPI_connected
187 * must be equal to _SPI_curid.
191 if (_SPI_connected == -1)
194 _SPI_current = &(_SPI_stack[_SPI_connected]);
196 return SPI_OK_FINISH;
200 * Clean up SPI state at transaction commit or abort.
203 AtEOXact_SPI(bool isCommit)
206 * Note that memory contexts belonging to SPI stack entries will be freed
207 * automatically, so we can ignore them here. We just need to restore our
208 * static variables to initial state.
210 if (isCommit && _SPI_connected != -1)
212 (errcode(ERRCODE_WARNING),
213 errmsg("transaction left non-empty SPI stack"),
214 errhint("Check for missing \"SPI_finish\" calls.")));
216 _SPI_current = _SPI_stack = NULL;
217 _SPI_stack_depth = 0;
218 _SPI_connected = _SPI_curid = -1;
220 SPI_lastoid = InvalidOid;
225 * Clean up SPI state at subtransaction commit or abort.
227 * During commit, there shouldn't be any unclosed entries remaining from
228 * the current subtransaction; we emit a warning if any are found.
231 AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
235 while (_SPI_connected >= 0)
237 _SPI_connection *connection = &(_SPI_stack[_SPI_connected]);
239 if (connection->connectSubid != mySubid)
240 break; /* couldn't be any underneath it either */
245 * Release procedure memory explicitly (see note in SPI_connect)
247 if (connection->execCxt)
249 MemoryContextDelete(connection->execCxt);
250 connection->execCxt = NULL;
252 if (connection->procCxt)
254 MemoryContextDelete(connection->procCxt);
255 connection->procCxt = NULL;
259 * Pop the stack entry and reset global variables. Unlike
260 * SPI_finish(), we don't risk switching to memory contexts that might
264 _SPI_curid = _SPI_connected;
265 if (_SPI_connected == -1)
268 _SPI_current = &(_SPI_stack[_SPI_connected]);
270 SPI_lastoid = InvalidOid;
274 if (found && isCommit)
276 (errcode(ERRCODE_WARNING),
277 errmsg("subtransaction left non-empty SPI stack"),
278 errhint("Check for missing \"SPI_finish\" calls.")));
281 * If we are aborting a subtransaction and there is an open SPI context
282 * surrounding the subxact, clean up to prevent memory leakage.
284 if (_SPI_current && !isCommit)
286 slist_mutable_iter siter;
288 /* free Executor memory the same as _SPI_end_call would do */
289 MemoryContextResetAndDeleteChildren(_SPI_current->execCxt);
291 /* throw away any tuple tables created within current subxact */
292 slist_foreach_modify(siter, &_SPI_current->tuptables)
294 SPITupleTable *tuptable;
296 tuptable = slist_container(SPITupleTable, next, siter.cur);
297 if (tuptable->subid >= mySubid)
300 * If we used SPI_freetuptable() here, its internal search of
301 * the tuptables list would make this operation O(N^2).
302 * Instead, just free the tuptable manually. This should
303 * match what SPI_freetuptable() does.
305 slist_delete_current(&siter);
306 if (tuptable == _SPI_current->tuptable)
307 _SPI_current->tuptable = NULL;
308 if (tuptable == SPI_tuptable)
310 MemoryContextDelete(tuptable->tuptabcxt);
313 /* in particular we should have gotten rid of any in-progress table */
314 Assert(_SPI_current->tuptable == NULL);
319 /* Pushes SPI stack to allow recursive SPI calls */
326 /* Pops SPI stack to allow recursive SPI calls */
333 /* Conditional push: push only if we're inside a SPI procedure */
335 SPI_push_conditional(void)
337 bool pushed = (_SPI_curid != _SPI_connected);
342 /* We should now be in a state where SPI_connect would succeed */
343 Assert(_SPI_curid == _SPI_connected);
348 /* Conditional pop: pop only if SPI_push_conditional pushed */
350 SPI_pop_conditional(bool pushed)
352 /* We should be in a state where SPI_connect would succeed */
353 Assert(_SPI_curid == _SPI_connected);
358 /* Restore state of SPI stack after aborting a subtransaction */
360 SPI_restore_connection(void)
362 Assert(_SPI_connected >= 0);
363 _SPI_curid = _SPI_connected - 1;
366 /* Parse, plan, and execute a query string */
368 SPI_execute(const char *src, bool read_only, long tcount)
373 if (src == NULL || tcount < 0)
374 return SPI_ERROR_ARGUMENT;
376 res = _SPI_begin_call(true);
380 memset(&plan, 0, sizeof(_SPI_plan));
381 plan.magic = _SPI_PLAN_MAGIC;
382 plan.cursor_options = 0;
384 _SPI_prepare_oneshot_plan(src, &plan);
386 res = _SPI_execute_plan(&plan, NULL,
387 InvalidSnapshot, InvalidSnapshot,
388 read_only, true, tcount);
394 /* Obsolete version of SPI_execute */
396 SPI_exec(const char *src, long tcount)
398 return SPI_execute(src, false, tcount);
401 /* Execute a previously prepared plan */
403 SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls,
404 bool read_only, long tcount)
408 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
409 return SPI_ERROR_ARGUMENT;
411 if (plan->nargs > 0 && Values == NULL)
412 return SPI_ERROR_PARAM;
414 res = _SPI_begin_call(true);
418 res = _SPI_execute_plan(plan,
419 _SPI_convert_params(plan->nargs, plan->argtypes,
421 InvalidSnapshot, InvalidSnapshot,
422 read_only, true, tcount);
428 /* Obsolete version of SPI_execute_plan */
430 SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount)
432 return SPI_execute_plan(plan, Values, Nulls, false, tcount);
435 /* Execute a previously prepared plan */
437 SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params,
438 bool read_only, long tcount)
442 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
443 return SPI_ERROR_ARGUMENT;
445 res = _SPI_begin_call(true);
449 res = _SPI_execute_plan(plan, params,
450 InvalidSnapshot, InvalidSnapshot,
451 read_only, true, tcount);
458 * SPI_execute_snapshot -- identical to SPI_execute_plan, except that we allow
459 * the caller to specify exactly which snapshots to use, which will be
460 * registered here. Also, the caller may specify that AFTER triggers should be
461 * queued as part of the outer query rather than being fired immediately at the
462 * end of the command.
464 * This is currently not documented in spi.sgml because it is only intended
465 * for use by RI triggers.
467 * Passing snapshot == InvalidSnapshot will select the normal behavior of
468 * fetching a new snapshot for each query.
471 SPI_execute_snapshot(SPIPlanPtr plan,
472 Datum *Values, const char *Nulls,
473 Snapshot snapshot, Snapshot crosscheck_snapshot,
474 bool read_only, bool fire_triggers, long tcount)
478 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0)
479 return SPI_ERROR_ARGUMENT;
481 if (plan->nargs > 0 && Values == NULL)
482 return SPI_ERROR_PARAM;
484 res = _SPI_begin_call(true);
488 res = _SPI_execute_plan(plan,
489 _SPI_convert_params(plan->nargs, plan->argtypes,
491 snapshot, crosscheck_snapshot,
492 read_only, fire_triggers, tcount);
499 * SPI_execute_with_args -- plan and execute a query with supplied arguments
501 * This is functionally equivalent to SPI_prepare followed by
505 SPI_execute_with_args(const char *src,
506 int nargs, Oid *argtypes,
507 Datum *Values, const char *Nulls,
508 bool read_only, long tcount)
512 ParamListInfo paramLI;
514 if (src == NULL || nargs < 0 || tcount < 0)
515 return SPI_ERROR_ARGUMENT;
517 if (nargs > 0 && (argtypes == NULL || Values == NULL))
518 return SPI_ERROR_PARAM;
520 res = _SPI_begin_call(true);
524 memset(&plan, 0, sizeof(_SPI_plan));
525 plan.magic = _SPI_PLAN_MAGIC;
526 plan.cursor_options = 0;
528 plan.argtypes = argtypes;
529 plan.parserSetup = NULL;
530 plan.parserSetupArg = NULL;
532 paramLI = _SPI_convert_params(nargs, argtypes,
535 _SPI_prepare_oneshot_plan(src, &plan);
537 res = _SPI_execute_plan(&plan, paramLI,
538 InvalidSnapshot, InvalidSnapshot,
539 read_only, true, tcount);
546 SPI_prepare(const char *src, int nargs, Oid *argtypes)
548 return SPI_prepare_cursor(src, nargs, argtypes, 0);
552 SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes,
558 if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
560 SPI_result = SPI_ERROR_ARGUMENT;
564 SPI_result = _SPI_begin_call(true);
568 memset(&plan, 0, sizeof(_SPI_plan));
569 plan.magic = _SPI_PLAN_MAGIC;
570 plan.cursor_options = cursorOptions;
572 plan.argtypes = argtypes;
573 plan.parserSetup = NULL;
574 plan.parserSetupArg = NULL;
576 _SPI_prepare_plan(src, &plan);
578 /* copy plan to procedure context */
579 result = _SPI_make_plan_non_temp(&plan);
587 SPI_prepare_params(const char *src,
588 ParserSetupHook parserSetup,
589 void *parserSetupArg,
597 SPI_result = SPI_ERROR_ARGUMENT;
601 SPI_result = _SPI_begin_call(true);
605 memset(&plan, 0, sizeof(_SPI_plan));
606 plan.magic = _SPI_PLAN_MAGIC;
607 plan.cursor_options = cursorOptions;
609 plan.argtypes = NULL;
610 plan.parserSetup = parserSetup;
611 plan.parserSetupArg = parserSetupArg;
613 _SPI_prepare_plan(src, &plan);
615 /* copy plan to procedure context */
616 result = _SPI_make_plan_non_temp(&plan);
624 SPI_keepplan(SPIPlanPtr plan)
628 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
629 plan->saved || plan->oneshot)
630 return SPI_ERROR_ARGUMENT;
633 * Mark it saved, reparent it under CacheMemoryContext, and mark all the
634 * component CachedPlanSources as saved. This sequence cannot fail
635 * partway through, so there's no risk of long-term memory leakage.
638 MemoryContextSetParent(plan->plancxt, CacheMemoryContext);
640 foreach(lc, plan->plancache_list)
642 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
644 SaveCachedPlan(plansource);
651 SPI_saveplan(SPIPlanPtr plan)
655 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
657 SPI_result = SPI_ERROR_ARGUMENT;
661 SPI_result = _SPI_begin_call(false); /* don't change context */
665 newplan = _SPI_save_plan(plan);
667 SPI_result = _SPI_end_call(false);
673 SPI_freeplan(SPIPlanPtr plan)
677 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
678 return SPI_ERROR_ARGUMENT;
680 /* Release the plancache entries */
681 foreach(lc, plan->plancache_list)
683 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
685 DropCachedPlan(plansource);
688 /* Now get rid of the _SPI_plan and subsidiary data in its plancxt */
689 MemoryContextDelete(plan->plancxt);
695 SPI_copytuple(HeapTuple tuple)
697 MemoryContext oldcxt = NULL;
702 SPI_result = SPI_ERROR_ARGUMENT;
706 if (_SPI_curid + 1 == _SPI_connected) /* connected */
708 if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
709 elog(ERROR, "SPI stack corrupted");
710 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
713 ctuple = heap_copytuple(tuple);
716 MemoryContextSwitchTo(oldcxt);
722 SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc)
724 MemoryContext oldcxt = NULL;
725 HeapTupleHeader dtup;
727 if (tuple == NULL || tupdesc == NULL)
729 SPI_result = SPI_ERROR_ARGUMENT;
733 /* For RECORD results, make sure a typmod has been assigned */
734 if (tupdesc->tdtypeid == RECORDOID &&
735 tupdesc->tdtypmod < 0)
736 assign_record_type_typmod(tupdesc);
738 if (_SPI_curid + 1 == _SPI_connected) /* connected */
740 if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
741 elog(ERROR, "SPI stack corrupted");
742 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
745 dtup = (HeapTupleHeader) palloc(tuple->t_len);
746 memcpy((char *) dtup, (char *) tuple->t_data, tuple->t_len);
748 HeapTupleHeaderSetDatumLength(dtup, tuple->t_len);
749 HeapTupleHeaderSetTypeId(dtup, tupdesc->tdtypeid);
750 HeapTupleHeaderSetTypMod(dtup, tupdesc->tdtypmod);
753 MemoryContextSwitchTo(oldcxt);
759 SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
760 Datum *Values, const char *Nulls)
762 MemoryContext oldcxt = NULL;
764 int numberOfAttributes;
769 if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
771 SPI_result = SPI_ERROR_ARGUMENT;
775 if (_SPI_curid + 1 == _SPI_connected) /* connected */
777 if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
778 elog(ERROR, "SPI stack corrupted");
779 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
782 numberOfAttributes = rel->rd_att->natts;
783 v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
784 n = (bool *) palloc(numberOfAttributes * sizeof(bool));
786 /* fetch old values and nulls */
787 heap_deform_tuple(tuple, rel->rd_att, v, n);
789 /* replace values and nulls */
790 for (i = 0; i < natts; i++)
792 if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
794 v[attnum[i] - 1] = Values[i];
795 n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? true : false;
798 if (i == natts) /* no errors in *attnum */
800 mtuple = heap_form_tuple(rel->rd_att, v, n);
803 * copy the identification info of the old tuple: t_ctid, t_self, and
806 mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
807 mtuple->t_self = tuple->t_self;
808 mtuple->t_tableOid = tuple->t_tableOid;
809 if (rel->rd_att->tdhasoid)
810 HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
815 SPI_result = SPI_ERROR_NOATTRIBUTE;
822 MemoryContextSwitchTo(oldcxt);
828 SPI_fnumber(TupleDesc tupdesc, const char *fname)
831 Form_pg_attribute sysatt;
833 for (res = 0; res < tupdesc->natts; res++)
835 if (namestrcmp(&tupdesc->attrs[res]->attname, fname) == 0)
839 sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ );
841 return sysatt->attnum;
843 /* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
844 return SPI_ERROR_NOATTRIBUTE;
848 SPI_fname(TupleDesc tupdesc, int fnumber)
850 Form_pg_attribute att;
854 if (fnumber > tupdesc->natts || fnumber == 0 ||
855 fnumber <= FirstLowInvalidHeapAttributeNumber)
857 SPI_result = SPI_ERROR_NOATTRIBUTE;
862 att = tupdesc->attrs[fnumber - 1];
864 att = SystemAttributeDefinition(fnumber, true);
866 return pstrdup(NameStr(att->attname));
870 SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
880 if (fnumber > tupdesc->natts || fnumber == 0 ||
881 fnumber <= FirstLowInvalidHeapAttributeNumber)
883 SPI_result = SPI_ERROR_NOATTRIBUTE;
887 val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
892 typoid = tupdesc->attrs[fnumber - 1]->atttypid;
894 typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
896 getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
898 return OidOutputFunctionCall(foutoid, val);
902 SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
906 if (fnumber > tupdesc->natts || fnumber == 0 ||
907 fnumber <= FirstLowInvalidHeapAttributeNumber)
909 SPI_result = SPI_ERROR_NOATTRIBUTE;
914 return heap_getattr(tuple, fnumber, tupdesc, isnull);
918 SPI_gettype(TupleDesc tupdesc, int fnumber)
926 if (fnumber > tupdesc->natts || fnumber == 0 ||
927 fnumber <= FirstLowInvalidHeapAttributeNumber)
929 SPI_result = SPI_ERROR_NOATTRIBUTE;
934 typoid = tupdesc->attrs[fnumber - 1]->atttypid;
936 typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
938 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
940 if (!HeapTupleIsValid(typeTuple))
942 SPI_result = SPI_ERROR_TYPUNKNOWN;
946 result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
947 ReleaseSysCache(typeTuple);
952 * Get the data type OID for a column.
954 * There's nothing similar for typmod and typcollation. The rare consumers
955 * thereof should inspect the TupleDesc directly.
958 SPI_gettypeid(TupleDesc tupdesc, int fnumber)
962 if (fnumber > tupdesc->natts || fnumber == 0 ||
963 fnumber <= FirstLowInvalidHeapAttributeNumber)
965 SPI_result = SPI_ERROR_NOATTRIBUTE;
970 return tupdesc->attrs[fnumber - 1]->atttypid;
972 return (SystemAttributeDefinition(fnumber, true))->atttypid;
976 SPI_getrelname(Relation rel)
978 return pstrdup(RelationGetRelationName(rel));
982 SPI_getnspname(Relation rel)
984 return get_namespace_name(RelationGetNamespace(rel));
988 SPI_palloc(Size size)
990 MemoryContext oldcxt = NULL;
993 if (_SPI_curid + 1 == _SPI_connected) /* connected */
995 if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
996 elog(ERROR, "SPI stack corrupted");
997 oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
1000 pointer = palloc(size);
1003 MemoryContextSwitchTo(oldcxt);
1009 SPI_repalloc(void *pointer, Size size)
1011 /* No longer need to worry which context chunk was in... */
1012 return repalloc(pointer, size);
1016 SPI_pfree(void *pointer)
1018 /* No longer need to worry which context chunk was in... */
1023 SPI_freetuple(HeapTuple tuple)
1025 /* No longer need to worry which context tuple was in... */
1026 heap_freetuple(tuple);
1030 SPI_freetuptable(SPITupleTable *tuptable)
1034 /* ignore call if NULL pointer */
1035 if (tuptable == NULL)
1039 * Since this function might be called during error recovery, it seems
1040 * best not to insist that the caller be actively connected. We just
1041 * search the topmost SPI context, connected or not.
1043 if (_SPI_connected >= 0)
1045 slist_mutable_iter siter;
1047 if (_SPI_current != &(_SPI_stack[_SPI_connected]))
1048 elog(ERROR, "SPI stack corrupted");
1050 /* find tuptable in active list, then remove it */
1051 slist_foreach_modify(siter, &_SPI_current->tuptables)
1055 tt = slist_container(SPITupleTable, next, siter.cur);
1058 slist_delete_current(&siter);
1066 * Refuse the deletion if we didn't find it in the topmost SPI context.
1067 * This is primarily a guard against double deletion, but might prevent
1068 * other errors as well. Since the worst consequence of not deleting a
1069 * tuptable would be a transient memory leak, this is just a WARNING.
1073 elog(WARNING, "attempt to delete invalid SPITupleTable %p", tuptable);
1077 /* for safety, reset global variables that might point at tuptable */
1078 if (tuptable == _SPI_current->tuptable)
1079 _SPI_current->tuptable = NULL;
1080 if (tuptable == SPI_tuptable)
1081 SPI_tuptable = NULL;
1083 /* release all memory belonging to tuptable */
1084 MemoryContextDelete(tuptable->tuptabcxt);
1091 * Open a prepared SPI plan as a portal
1094 SPI_cursor_open(const char *name, SPIPlanPtr plan,
1095 Datum *Values, const char *Nulls,
1099 ParamListInfo paramLI;
1101 /* build transient ParamListInfo in caller's context */
1102 paramLI = _SPI_convert_params(plan->nargs, plan->argtypes,
1105 portal = SPI_cursor_open_internal(name, plan, paramLI, read_only);
1107 /* done with the transient ParamListInfo */
1116 * SPI_cursor_open_with_args()
1118 * Parse and plan a query and open it as a portal.
1121 SPI_cursor_open_with_args(const char *name,
1123 int nargs, Oid *argtypes,
1124 Datum *Values, const char *Nulls,
1125 bool read_only, int cursorOptions)
1129 ParamListInfo paramLI;
1131 if (src == NULL || nargs < 0)
1132 elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
1134 if (nargs > 0 && (argtypes == NULL || Values == NULL))
1135 elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
1137 SPI_result = _SPI_begin_call(true);
1139 elog(ERROR, "SPI_cursor_open_with_args called while not connected");
1141 memset(&plan, 0, sizeof(_SPI_plan));
1142 plan.magic = _SPI_PLAN_MAGIC;
1143 plan.cursor_options = cursorOptions;
1145 plan.argtypes = argtypes;
1146 plan.parserSetup = NULL;
1147 plan.parserSetupArg = NULL;
1149 /* build transient ParamListInfo in executor context */
1150 paramLI = _SPI_convert_params(nargs, argtypes,
1153 _SPI_prepare_plan(src, &plan);
1155 /* We needn't copy the plan; SPI_cursor_open_internal will do so */
1157 /* Adjust stack so that SPI_cursor_open_internal doesn't complain */
1160 result = SPI_cursor_open_internal(name, &plan, paramLI, read_only);
1164 _SPI_end_call(true);
1171 * SPI_cursor_open_with_paramlist()
1173 * Same as SPI_cursor_open except that parameters (if any) are passed
1174 * as a ParamListInfo, which supports dynamic parameter set determination
1177 SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan,
1178 ParamListInfo params, bool read_only)
1180 return SPI_cursor_open_internal(name, plan, params, read_only);
1185 * SPI_cursor_open_internal()
1187 * Common code for SPI_cursor_open variants
1190 SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
1191 ParamListInfo paramLI, bool read_only)
1193 CachedPlanSource *plansource;
1198 MemoryContext oldcontext;
1200 ErrorContextCallback spierrcontext;
1203 * Check that the plan is something the Portal code will special-case as
1204 * returning one tupleset.
1206 if (!SPI_is_cursor_plan(plan))
1208 /* try to give a good error message */
1209 if (list_length(plan->plancache_list) != 1)
1211 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
1212 errmsg("cannot open multi-query plan as cursor")));
1213 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1215 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
1216 /* translator: %s is name of a SQL command, eg INSERT */
1217 errmsg("cannot open %s query as cursor",
1218 plansource->commandTag)));
1221 Assert(list_length(plan->plancache_list) == 1);
1222 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1224 /* Push the SPI stack */
1225 if (_SPI_begin_call(true) < 0)
1226 elog(ERROR, "SPI_cursor_open called while not connected");
1228 /* Reset SPI result (note we deliberately don't touch lastoid) */
1230 SPI_tuptable = NULL;
1231 _SPI_current->processed = 0;
1232 _SPI_current->tuptable = NULL;
1234 /* Create the portal */
1235 if (name == NULL || name[0] == '\0')
1237 /* Use a random nonconflicting name */
1238 portal = CreateNewPortal();
1242 /* In this path, error if portal of same name already exists */
1243 portal = CreatePortal(name, false, false);
1246 /* Copy the plan's query string into the portal */
1247 query_string = MemoryContextStrdup(PortalGetHeapMemory(portal),
1248 plansource->query_string);
1251 * Setup error traceback support for ereport(), in case GetCachedPlan
1254 spierrcontext.callback = _SPI_error_callback;
1255 spierrcontext.arg = (void *) plansource->query_string;
1256 spierrcontext.previous = error_context_stack;
1257 error_context_stack = &spierrcontext;
1260 * Note: for a saved plan, we mustn't have any failure occur between
1261 * GetCachedPlan and PortalDefineQuery; that would result in leaking our
1262 * plancache refcount.
1265 /* Replan if needed, and increment plan refcount for portal */
1266 cplan = GetCachedPlan(plansource, paramLI, false);
1267 stmt_list = cplan->stmt_list;
1269 /* Pop the error context stack */
1270 error_context_stack = spierrcontext.previous;
1275 * We don't want the portal to depend on an unsaved CachedPlanSource,
1276 * so must copy the plan into the portal's context. An error here
1277 * will result in leaking our refcount on the plan, but it doesn't
1278 * matter because the plan is unsaved and hence transient anyway.
1280 oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
1281 stmt_list = copyObject(stmt_list);
1282 MemoryContextSwitchTo(oldcontext);
1283 ReleaseCachedPlan(cplan, false);
1284 cplan = NULL; /* portal shouldn't depend on cplan */
1288 * Set up the portal.
1290 PortalDefineQuery(portal,
1291 NULL, /* no statement name */
1293 plansource->commandTag,
1298 * Set up options for portal. Default SCROLL type is chosen the same way
1299 * as PerformCursorOpen does it.
1301 portal->cursorOptions = plan->cursor_options;
1302 if (!(portal->cursorOptions & (CURSOR_OPT_SCROLL | CURSOR_OPT_NO_SCROLL)))
1304 if (list_length(stmt_list) == 1 &&
1305 IsA((Node *) linitial(stmt_list), PlannedStmt) &&
1306 ((PlannedStmt *) linitial(stmt_list))->rowMarks == NIL &&
1307 ExecSupportsBackwardScan(((PlannedStmt *) linitial(stmt_list))->planTree))
1308 portal->cursorOptions |= CURSOR_OPT_SCROLL;
1310 portal->cursorOptions |= CURSOR_OPT_NO_SCROLL;
1314 * Disallow SCROLL with SELECT FOR UPDATE. This is not redundant with the
1315 * check in transformDeclareCursorStmt because the cursor options might
1316 * not have come through there.
1318 if (portal->cursorOptions & CURSOR_OPT_SCROLL)
1320 if (list_length(stmt_list) == 1 &&
1321 IsA((Node *) linitial(stmt_list), PlannedStmt) &&
1322 ((PlannedStmt *) linitial(stmt_list))->rowMarks != NIL)
1324 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1325 errmsg("DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported"),
1326 errdetail("Scrollable cursors must be READ ONLY.")));
1330 * If told to be read-only, we'd better check for read-only queries. This
1331 * can't be done earlier because we need to look at the finished, planned
1332 * queries. (In particular, we don't want to do it between GetCachedPlan
1333 * and PortalDefineQuery, because throwing an error between those steps
1334 * would result in leaking our plancache refcount.)
1340 foreach(lc, stmt_list)
1342 Node *pstmt = (Node *) lfirst(lc);
1344 if (!CommandIsReadOnly(pstmt))
1346 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1347 /* translator: %s is a SQL statement name */
1348 errmsg("%s is not allowed in a non-volatile function",
1349 CreateCommandTag(pstmt))));
1353 /* Set up the snapshot to use. */
1355 snapshot = GetActiveSnapshot();
1358 CommandCounterIncrement();
1359 snapshot = GetTransactionSnapshot();
1363 * If the plan has parameters, copy them into the portal. Note that this
1364 * must be done after revalidating the plan, because in dynamic parameter
1365 * cases the set of parameters could have changed during re-parsing.
1369 oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
1370 paramLI = copyParamList(paramLI);
1371 MemoryContextSwitchTo(oldcontext);
1375 * Start portal execution.
1377 PortalStart(portal, paramLI, 0, snapshot);
1379 Assert(portal->strategy != PORTAL_MULTI_QUERY);
1381 /* Pop the SPI stack */
1382 _SPI_end_call(true);
1384 /* Return the created portal */
1392 * Find the portal of an existing open cursor
1395 SPI_cursor_find(const char *name)
1397 return GetPortalByName(name);
1402 * SPI_cursor_fetch()
1404 * Fetch rows in a cursor
1407 SPI_cursor_fetch(Portal portal, bool forward, long count)
1409 _SPI_cursor_operation(portal,
1410 forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1411 CreateDestReceiver(DestSPI));
1412 /* we know that the DestSPI receiver doesn't need a destroy call */
1422 SPI_cursor_move(Portal portal, bool forward, long count)
1424 _SPI_cursor_operation(portal,
1425 forward ? FETCH_FORWARD : FETCH_BACKWARD, count,
1431 * SPI_scroll_cursor_fetch()
1433 * Fetch rows in a scrollable cursor
1436 SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, long count)
1438 _SPI_cursor_operation(portal,
1440 CreateDestReceiver(DestSPI));
1441 /* we know that the DestSPI receiver doesn't need a destroy call */
1446 * SPI_scroll_cursor_move()
1448 * Move in a scrollable cursor
1451 SPI_scroll_cursor_move(Portal portal, FetchDirection direction, long count)
1453 _SPI_cursor_operation(portal, direction, count, None_Receiver);
1458 * SPI_cursor_close()
1463 SPI_cursor_close(Portal portal)
1465 if (!PortalIsValid(portal))
1466 elog(ERROR, "invalid portal in SPI cursor operation");
1468 PortalDrop(portal, false);
1472 * Returns the Oid representing the type id for argument at argIndex. First
1473 * parameter is at index zero.
1476 SPI_getargtypeid(SPIPlanPtr plan, int argIndex)
1478 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC ||
1479 argIndex < 0 || argIndex >= plan->nargs)
1481 SPI_result = SPI_ERROR_ARGUMENT;
1484 return plan->argtypes[argIndex];
1488 * Returns the number of arguments for the prepared plan.
1491 SPI_getargcount(SPIPlanPtr plan)
1493 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1495 SPI_result = SPI_ERROR_ARGUMENT;
1502 * Returns true if the plan contains exactly one command
1503 * and that command returns tuples to the caller (eg, SELECT or
1504 * INSERT ... RETURNING, but not SELECT ... INTO). In essence,
1505 * the result indicates if the command can be used with SPI_cursor_open
1508 * plan: A plan previously prepared using SPI_prepare
1511 SPI_is_cursor_plan(SPIPlanPtr plan)
1513 CachedPlanSource *plansource;
1515 if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC)
1517 SPI_result = SPI_ERROR_ARGUMENT;
1521 if (list_length(plan->plancache_list) != 1)
1524 return false; /* not exactly 1 pre-rewrite command */
1526 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1529 * We used to force revalidation of the cached plan here, but that seems
1530 * unnecessary: invalidation could mean a change in the rowtype of the
1531 * tuples returned by a plan, but not whether it returns tuples at all.
1535 /* Does it return tuples? */
1536 if (plansource->resultDesc)
1543 * SPI_plan_is_valid --- test whether a SPI plan is currently valid
1544 * (that is, not marked as being in need of revalidation).
1546 * See notes for CachedPlanIsValid before using this.
1549 SPI_plan_is_valid(SPIPlanPtr plan)
1553 Assert(plan->magic == _SPI_PLAN_MAGIC);
1555 foreach(lc, plan->plancache_list)
1557 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
1559 if (!CachedPlanIsValid(plansource))
1566 * SPI_result_code_string --- convert any SPI return code to a string
1568 * This is often useful in error messages. Most callers will probably
1569 * only pass negative (error-case) codes, but for generality we recognize
1570 * the success codes too.
1573 SPI_result_code_string(int code)
1575 static char buf[64];
1579 case SPI_ERROR_CONNECT:
1580 return "SPI_ERROR_CONNECT";
1581 case SPI_ERROR_COPY:
1582 return "SPI_ERROR_COPY";
1583 case SPI_ERROR_OPUNKNOWN:
1584 return "SPI_ERROR_OPUNKNOWN";
1585 case SPI_ERROR_UNCONNECTED:
1586 return "SPI_ERROR_UNCONNECTED";
1587 case SPI_ERROR_ARGUMENT:
1588 return "SPI_ERROR_ARGUMENT";
1589 case SPI_ERROR_PARAM:
1590 return "SPI_ERROR_PARAM";
1591 case SPI_ERROR_TRANSACTION:
1592 return "SPI_ERROR_TRANSACTION";
1593 case SPI_ERROR_NOATTRIBUTE:
1594 return "SPI_ERROR_NOATTRIBUTE";
1595 case SPI_ERROR_NOOUTFUNC:
1596 return "SPI_ERROR_NOOUTFUNC";
1597 case SPI_ERROR_TYPUNKNOWN:
1598 return "SPI_ERROR_TYPUNKNOWN";
1599 case SPI_OK_CONNECT:
1600 return "SPI_OK_CONNECT";
1602 return "SPI_OK_FINISH";
1604 return "SPI_OK_FETCH";
1605 case SPI_OK_UTILITY:
1606 return "SPI_OK_UTILITY";
1608 return "SPI_OK_SELECT";
1609 case SPI_OK_SELINTO:
1610 return "SPI_OK_SELINTO";
1612 return "SPI_OK_INSERT";
1614 return "SPI_OK_DELETE";
1616 return "SPI_OK_UPDATE";
1618 return "SPI_OK_CURSOR";
1619 case SPI_OK_INSERT_RETURNING:
1620 return "SPI_OK_INSERT_RETURNING";
1621 case SPI_OK_DELETE_RETURNING:
1622 return "SPI_OK_DELETE_RETURNING";
1623 case SPI_OK_UPDATE_RETURNING:
1624 return "SPI_OK_UPDATE_RETURNING";
1625 case SPI_OK_REWRITTEN:
1626 return "SPI_OK_REWRITTEN";
1628 /* Unrecognized code ... return something useful ... */
1629 sprintf(buf, "Unrecognized SPI code %d", code);
1634 * SPI_plan_get_plan_sources --- get a SPI plan's underlying list of
1635 * CachedPlanSources.
1637 * This is exported so that pl/pgsql can use it (this beats letting pl/pgsql
1638 * look directly into the SPIPlan for itself). It's not documented in
1639 * spi.sgml because we'd just as soon not have too many places using this.
1642 SPI_plan_get_plan_sources(SPIPlanPtr plan)
1644 Assert(plan->magic == _SPI_PLAN_MAGIC);
1645 return plan->plancache_list;
1649 * SPI_plan_get_cached_plan --- get a SPI plan's generic CachedPlan,
1650 * if the SPI plan contains exactly one CachedPlanSource. If not,
1651 * return NULL. Caller is responsible for doing ReleaseCachedPlan().
1653 * This is exported so that pl/pgsql can use it (this beats letting pl/pgsql
1654 * look directly into the SPIPlan for itself). It's not documented in
1655 * spi.sgml because we'd just as soon not have too many places using this.
1658 SPI_plan_get_cached_plan(SPIPlanPtr plan)
1660 CachedPlanSource *plansource;
1662 ErrorContextCallback spierrcontext;
1664 Assert(plan->magic == _SPI_PLAN_MAGIC);
1666 /* Can't support one-shot plans here */
1670 /* Must have exactly one CachedPlanSource */
1671 if (list_length(plan->plancache_list) != 1)
1673 plansource = (CachedPlanSource *) linitial(plan->plancache_list);
1675 /* Setup error traceback support for ereport() */
1676 spierrcontext.callback = _SPI_error_callback;
1677 spierrcontext.arg = (void *) plansource->query_string;
1678 spierrcontext.previous = error_context_stack;
1679 error_context_stack = &spierrcontext;
1681 /* Get the generic plan for the query */
1682 cplan = GetCachedPlan(plansource, NULL, plan->saved);
1683 Assert(cplan == plansource->gplan);
1685 /* Pop the error context stack */
1686 error_context_stack = spierrcontext.previous;
1692 /* =================== private functions =================== */
1696 * Initialize to receive tuples from Executor into SPITupleTable
1697 * of current SPI procedure
1700 spi_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
1702 SPITupleTable *tuptable;
1703 MemoryContext oldcxt;
1704 MemoryContext tuptabcxt;
1707 * When called by Executor _SPI_curid expected to be equal to
1710 if (_SPI_curid != _SPI_connected || _SPI_connected < 0)
1711 elog(ERROR, "improper call to spi_dest_startup");
1712 if (_SPI_current != &(_SPI_stack[_SPI_curid]))
1713 elog(ERROR, "SPI stack corrupted");
1715 if (_SPI_current->tuptable != NULL)
1716 elog(ERROR, "improper call to spi_dest_startup");
1718 /* We create the tuple table context as a child of procCxt */
1720 oldcxt = _SPI_procmem(); /* switch to procedure memory context */
1722 tuptabcxt = AllocSetContextCreate(CurrentMemoryContext,
1724 ALLOCSET_DEFAULT_MINSIZE,
1725 ALLOCSET_DEFAULT_INITSIZE,
1726 ALLOCSET_DEFAULT_MAXSIZE);
1727 MemoryContextSwitchTo(tuptabcxt);
1729 _SPI_current->tuptable = tuptable = (SPITupleTable *)
1730 palloc0(sizeof(SPITupleTable));
1731 tuptable->tuptabcxt = tuptabcxt;
1732 tuptable->subid = GetCurrentSubTransactionId();
1735 * The tuptable is now valid enough to be freed by AtEOSubXact_SPI, so put
1736 * it onto the SPI context's tuptables list. This will ensure it's not
1737 * leaked even in the unlikely event the following few lines fail.
1739 slist_push_head(&_SPI_current->tuptables, &tuptable->next);
1741 /* set up initial allocations */
1742 tuptable->alloced = tuptable->free = 128;
1743 tuptable->vals = (HeapTuple *) palloc(tuptable->alloced * sizeof(HeapTuple));
1744 tuptable->tupdesc = CreateTupleDescCopy(typeinfo);
1746 MemoryContextSwitchTo(oldcxt);
1751 * store tuple retrieved by Executor into SPITupleTable
1752 * of current SPI procedure
1755 spi_printtup(TupleTableSlot *slot, DestReceiver *self)
1757 SPITupleTable *tuptable;
1758 MemoryContext oldcxt;
1761 * When called by Executor _SPI_curid expected to be equal to
1764 if (_SPI_curid != _SPI_connected || _SPI_connected < 0)
1765 elog(ERROR, "improper call to spi_printtup");
1766 if (_SPI_current != &(_SPI_stack[_SPI_curid]))
1767 elog(ERROR, "SPI stack corrupted");
1769 tuptable = _SPI_current->tuptable;
1770 if (tuptable == NULL)
1771 elog(ERROR, "improper call to spi_printtup");
1773 oldcxt = MemoryContextSwitchTo(tuptable->tuptabcxt);
1775 if (tuptable->free == 0)
1777 tuptable->free = 256;
1778 tuptable->alloced += tuptable->free;
1779 tuptable->vals = (HeapTuple *) repalloc(tuptable->vals,
1780 tuptable->alloced * sizeof(HeapTuple));
1783 tuptable->vals[tuptable->alloced - tuptable->free] =
1784 ExecCopySlotTuple(slot);
1787 MemoryContextSwitchTo(oldcxt);
1795 * Parse and analyze a querystring.
1797 * At entry, plan->argtypes and plan->nargs (or alternatively plan->parserSetup
1798 * and plan->parserSetupArg) must be valid, as must plan->cursor_options.
1800 * Results are stored into *plan (specifically, plan->plancache_list).
1801 * Note that the result data is all in CurrentMemoryContext or child contexts
1802 * thereof; in practice this means it is in the SPI executor context, and
1803 * what we are creating is a "temporary" SPIPlan. Cruft generated during
1804 * parsing is also left in CurrentMemoryContext.
1807 _SPI_prepare_plan(const char *src, SPIPlanPtr plan)
1809 List *raw_parsetree_list;
1810 List *plancache_list;
1811 ListCell *list_item;
1812 ErrorContextCallback spierrcontext;
1815 * Setup error traceback support for ereport()
1817 spierrcontext.callback = _SPI_error_callback;
1818 spierrcontext.arg = (void *) src;
1819 spierrcontext.previous = error_context_stack;
1820 error_context_stack = &spierrcontext;
1823 * Parse the request string into a list of raw parse trees.
1825 raw_parsetree_list = pg_parse_query(src);
1828 * Do parse analysis and rule rewrite for each raw parsetree, storing the
1829 * results into unsaved plancache entries.
1831 plancache_list = NIL;
1833 foreach(list_item, raw_parsetree_list)
1835 Node *parsetree = (Node *) lfirst(list_item);
1837 CachedPlanSource *plansource;
1840 * Create the CachedPlanSource before we do parse analysis, since it
1841 * needs to see the unmodified raw parse tree.
1843 plansource = CreateCachedPlan(parsetree,
1845 CreateCommandTag(parsetree));
1848 * Parameter datatypes are driven by parserSetup hook if provided,
1849 * otherwise we use the fixed parameter list.
1851 if (plan->parserSetup != NULL)
1853 Assert(plan->nargs == 0);
1854 stmt_list = pg_analyze_and_rewrite_params(parsetree,
1857 plan->parserSetupArg);
1861 stmt_list = pg_analyze_and_rewrite(parsetree,
1867 /* Finish filling in the CachedPlanSource */
1868 CompleteCachedPlan(plansource,
1874 plan->parserSetupArg,
1875 plan->cursor_options,
1876 false); /* not fixed result */
1878 plancache_list = lappend(plancache_list, plansource);
1881 plan->plancache_list = plancache_list;
1882 plan->oneshot = false;
1885 * Pop the error context stack
1887 error_context_stack = spierrcontext.previous;
1891 * Parse, but don't analyze, a querystring.
1893 * This is a stripped-down version of _SPI_prepare_plan that only does the
1894 * initial raw parsing. It creates "one shot" CachedPlanSources
1895 * that still require parse analysis before execution is possible.
1897 * The advantage of using the "one shot" form of CachedPlanSource is that
1898 * we eliminate data copying and invalidation overhead. Postponing parse
1899 * analysis also prevents issues if some of the raw parsetrees are DDL
1900 * commands that affect validity of later parsetrees. Both of these
1901 * attributes are good things for SPI_execute() and similar cases.
1903 * Results are stored into *plan (specifically, plan->plancache_list).
1904 * Note that the result data is all in CurrentMemoryContext or child contexts
1905 * thereof; in practice this means it is in the SPI executor context, and
1906 * what we are creating is a "temporary" SPIPlan. Cruft generated during
1907 * parsing is also left in CurrentMemoryContext.
1910 _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
1912 List *raw_parsetree_list;
1913 List *plancache_list;
1914 ListCell *list_item;
1915 ErrorContextCallback spierrcontext;
1918 * Setup error traceback support for ereport()
1920 spierrcontext.callback = _SPI_error_callback;
1921 spierrcontext.arg = (void *) src;
1922 spierrcontext.previous = error_context_stack;
1923 error_context_stack = &spierrcontext;
1926 * Parse the request string into a list of raw parse trees.
1928 raw_parsetree_list = pg_parse_query(src);
1931 * Construct plancache entries, but don't do parse analysis yet.
1933 plancache_list = NIL;
1935 foreach(list_item, raw_parsetree_list)
1937 Node *parsetree = (Node *) lfirst(list_item);
1938 CachedPlanSource *plansource;
1940 plansource = CreateOneShotCachedPlan(parsetree,
1942 CreateCommandTag(parsetree));
1944 plancache_list = lappend(plancache_list, plansource);
1947 plan->plancache_list = plancache_list;
1948 plan->oneshot = true;
1951 * Pop the error context stack
1953 error_context_stack = spierrcontext.previous;
1957 * Execute the given plan with the given parameter values
1959 * snapshot: query snapshot to use, or InvalidSnapshot for the normal
1960 * behavior of taking a new snapshot for each query.
1961 * crosscheck_snapshot: for RI use, all others pass InvalidSnapshot
1962 * read_only: TRUE for read-only execution (no CommandCounterIncrement)
1963 * fire_triggers: TRUE to fire AFTER triggers at end of query (normal case);
1964 * FALSE means any AFTER triggers are postponed to end of outer query
1965 * tcount: execution tuple-count limit, or 0 for none
1968 _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
1969 Snapshot snapshot, Snapshot crosscheck_snapshot,
1970 bool read_only, bool fire_triggers, long tcount)
1973 uint32 my_processed = 0;
1974 Oid my_lastoid = InvalidOid;
1975 SPITupleTable *my_tuptable = NULL;
1977 bool pushed_active_snap = false;
1978 ErrorContextCallback spierrcontext;
1979 CachedPlan *cplan = NULL;
1983 * Setup error traceback support for ereport()
1985 spierrcontext.callback = _SPI_error_callback;
1986 spierrcontext.arg = NULL; /* we'll fill this below */
1987 spierrcontext.previous = error_context_stack;
1988 error_context_stack = &spierrcontext;
1991 * We support four distinct snapshot management behaviors:
1993 * snapshot != InvalidSnapshot, read_only = true: use exactly the given
1996 * snapshot != InvalidSnapshot, read_only = false: use the given snapshot,
1997 * modified by advancing its command ID before each querytree.
1999 * snapshot == InvalidSnapshot, read_only = true: use the entry-time
2000 * ActiveSnapshot, if any (if there isn't one, we run with no snapshot).
2002 * snapshot == InvalidSnapshot, read_only = false: take a full new
2003 * snapshot for each user command, and advance its command ID before each
2004 * querytree within the command.
2006 * In the first two cases, we can just push the snap onto the stack once
2007 * for the whole plan list.
2009 if (snapshot != InvalidSnapshot)
2013 PushActiveSnapshot(snapshot);
2014 pushed_active_snap = true;
2018 /* Make sure we have a private copy of the snapshot to modify */
2019 PushCopiedSnapshot(snapshot);
2020 pushed_active_snap = true;
2024 foreach(lc1, plan->plancache_list)
2026 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc1);
2030 spierrcontext.arg = (void *) plansource->query_string;
2033 * If this is a one-shot plan, we still need to do parse analysis.
2037 Node *parsetree = plansource->raw_parse_tree;
2038 const char *src = plansource->query_string;
2042 * Parameter datatypes are driven by parserSetup hook if provided,
2043 * otherwise we use the fixed parameter list.
2045 if (plan->parserSetup != NULL)
2047 Assert(plan->nargs == 0);
2048 stmt_list = pg_analyze_and_rewrite_params(parsetree,
2051 plan->parserSetupArg);
2055 stmt_list = pg_analyze_and_rewrite(parsetree,
2061 /* Finish filling in the CachedPlanSource */
2062 CompleteCachedPlan(plansource,
2068 plan->parserSetupArg,
2069 plan->cursor_options,
2070 false); /* not fixed result */
2074 * Replan if needed, and increment plan refcount. If it's a saved
2075 * plan, the refcount must be backed by the CurrentResourceOwner.
2077 cplan = GetCachedPlan(plansource, paramLI, plan->saved);
2078 stmt_list = cplan->stmt_list;
2081 * In the default non-read-only case, get a new snapshot, replacing
2082 * any that we pushed in a previous cycle.
2084 if (snapshot == InvalidSnapshot && !read_only)
2086 if (pushed_active_snap)
2087 PopActiveSnapshot();
2088 PushActiveSnapshot(GetTransactionSnapshot());
2089 pushed_active_snap = true;
2092 foreach(lc2, stmt_list)
2094 Node *stmt = (Node *) lfirst(lc2);
2098 _SPI_current->processed = 0;
2099 _SPI_current->lastoid = InvalidOid;
2100 _SPI_current->tuptable = NULL;
2102 if (IsA(stmt, PlannedStmt))
2104 canSetTag = ((PlannedStmt *) stmt)->canSetTag;
2108 /* utilities are canSetTag if only thing in list */
2109 canSetTag = (list_length(stmt_list) == 1);
2111 if (IsA(stmt, CopyStmt))
2113 CopyStmt *cstmt = (CopyStmt *) stmt;
2115 if (cstmt->filename == NULL)
2117 my_res = SPI_ERROR_COPY;
2121 else if (IsA(stmt, TransactionStmt))
2123 my_res = SPI_ERROR_TRANSACTION;
2128 if (read_only && !CommandIsReadOnly(stmt))
2130 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2131 /* translator: %s is a SQL statement name */
2132 errmsg("%s is not allowed in a non-volatile function",
2133 CreateCommandTag(stmt))));
2136 * If not read-only mode, advance the command counter before each
2137 * command and update the snapshot.
2141 CommandCounterIncrement();
2142 UpdateActiveSnapshotCommandId();
2145 dest = CreateDestReceiver(canSetTag ? DestSPI : DestNone);
2147 if (IsA(stmt, PlannedStmt) &&
2148 ((PlannedStmt *) stmt)->utilityStmt == NULL)
2153 if (ActiveSnapshotSet())
2154 snap = GetActiveSnapshot();
2156 snap = InvalidSnapshot;
2158 qdesc = CreateQueryDesc((PlannedStmt *) stmt,
2159 plansource->query_string,
2160 snap, crosscheck_snapshot,
2163 res = _SPI_pquery(qdesc, fire_triggers,
2164 canSetTag ? tcount : 0);
2165 FreeQueryDesc(qdesc);
2169 char completionTag[COMPLETION_TAG_BUFSIZE];
2171 ProcessUtility(stmt,
2172 plansource->query_string,
2173 PROCESS_UTILITY_QUERY,
2178 /* Update "processed" if stmt returned tuples */
2179 if (_SPI_current->tuptable)
2180 _SPI_current->processed = _SPI_current->tuptable->alloced -
2181 _SPI_current->tuptable->free;
2183 res = SPI_OK_UTILITY;
2186 * Some utility statements return a row count, even though the
2187 * tuples are not returned to the caller.
2189 if (IsA(stmt, CreateTableAsStmt))
2191 Assert(strncmp(completionTag, "SELECT ", 7) == 0);
2192 _SPI_current->processed = strtoul(completionTag + 7,
2196 * For historical reasons, if CREATE TABLE AS was spelled
2197 * as SELECT INTO, return a special return code.
2199 if (((CreateTableAsStmt *) stmt)->is_select_into)
2200 res = SPI_OK_SELINTO;
2202 else if (IsA(stmt, CopyStmt))
2204 Assert(strncmp(completionTag, "COPY ", 5) == 0);
2205 _SPI_current->processed = strtoul(completionTag + 5,
2211 * The last canSetTag query sets the status values returned to the
2212 * caller. Be careful to free any tuptables not returned, to
2213 * avoid intratransaction memory leak.
2217 my_processed = _SPI_current->processed;
2218 my_lastoid = _SPI_current->lastoid;
2219 SPI_freetuptable(my_tuptable);
2220 my_tuptable = _SPI_current->tuptable;
2225 SPI_freetuptable(_SPI_current->tuptable);
2226 _SPI_current->tuptable = NULL;
2228 /* we know that the receiver doesn't need a destroy call */
2236 /* Done with this plan, so release refcount */
2237 ReleaseCachedPlan(cplan, plan->saved);
2241 * If not read-only mode, advance the command counter after the last
2242 * command. This ensures that its effects are visible, in case it was
2243 * DDL that would affect the next CachedPlanSource.
2246 CommandCounterIncrement();
2251 /* Pop the snapshot off the stack if we pushed one */
2252 if (pushed_active_snap)
2253 PopActiveSnapshot();
2255 /* We no longer need the cached plan refcount, if any */
2257 ReleaseCachedPlan(cplan, plan->saved);
2260 * Pop the error context stack
2262 error_context_stack = spierrcontext.previous;
2264 /* Save results for caller */
2265 SPI_processed = my_processed;
2266 SPI_lastoid = my_lastoid;
2267 SPI_tuptable = my_tuptable;
2269 /* tuptable now is caller's responsibility, not SPI's */
2270 _SPI_current->tuptable = NULL;
2273 * If none of the queries had canSetTag, return SPI_OK_REWRITTEN. Prior to
2274 * 8.4, we used return the last query's result code, but not its auxiliary
2275 * results, but that's confusing.
2278 my_res = SPI_OK_REWRITTEN;
2284 * Convert arrays of query parameters to form wanted by planner and executor
2286 static ParamListInfo
2287 _SPI_convert_params(int nargs, Oid *argtypes,
2288 Datum *Values, const char *Nulls)
2290 ParamListInfo paramLI;
2296 /* sizeof(ParamListInfoData) includes the first array element */
2297 paramLI = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
2298 (nargs - 1) * sizeof(ParamExternData));
2299 /* we have static list of params, so no hooks needed */
2300 paramLI->paramFetch = NULL;
2301 paramLI->paramFetchArg = NULL;
2302 paramLI->parserSetup = NULL;
2303 paramLI->parserSetupArg = NULL;
2304 paramLI->numParams = nargs;
2306 for (i = 0; i < nargs; i++)
2308 ParamExternData *prm = ¶mLI->params[i];
2310 prm->value = Values[i];
2311 prm->isnull = (Nulls && Nulls[i] == 'n');
2312 prm->pflags = PARAM_FLAG_CONST;
2313 prm->ptype = argtypes[i];
2322 _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, long tcount)
2324 int operation = queryDesc->operation;
2331 Assert(queryDesc->plannedstmt->utilityStmt == NULL);
2332 if (queryDesc->dest->mydest != DestSPI)
2334 /* Don't return SPI_OK_SELECT if we're discarding result */
2335 res = SPI_OK_UTILITY;
2338 res = SPI_OK_SELECT;
2341 if (queryDesc->plannedstmt->hasReturning)
2342 res = SPI_OK_INSERT_RETURNING;
2344 res = SPI_OK_INSERT;
2347 if (queryDesc->plannedstmt->hasReturning)
2348 res = SPI_OK_DELETE_RETURNING;
2350 res = SPI_OK_DELETE;
2353 if (queryDesc->plannedstmt->hasReturning)
2354 res = SPI_OK_UPDATE_RETURNING;
2356 res = SPI_OK_UPDATE;
2359 return SPI_ERROR_OPUNKNOWN;
2362 #ifdef SPI_EXECUTOR_STATS
2363 if (ShowExecutorStats)
2367 /* Select execution options */
2369 eflags = 0; /* default run-to-completion flags */
2371 eflags = EXEC_FLAG_SKIP_TRIGGERS;
2373 ExecutorStart(queryDesc, eflags);
2375 ExecutorRun(queryDesc, ForwardScanDirection, tcount);
2377 _SPI_current->processed = queryDesc->estate->es_processed;
2378 _SPI_current->lastoid = queryDesc->estate->es_lastoid;
2380 if ((res == SPI_OK_SELECT || queryDesc->plannedstmt->hasReturning) &&
2381 queryDesc->dest->mydest == DestSPI)
2383 if (_SPI_checktuples())
2384 elog(ERROR, "consistency check on SPI tuple count failed");
2387 ExecutorFinish(queryDesc);
2388 ExecutorEnd(queryDesc);
2389 /* FreeQueryDesc is done by the caller */
2391 #ifdef SPI_EXECUTOR_STATS
2392 if (ShowExecutorStats)
2393 ShowUsage("SPI EXECUTOR STATS");
2400 * _SPI_error_callback
2402 * Add context information when a query invoked via SPI fails
2405 _SPI_error_callback(void *arg)
2407 const char *query = (const char *) arg;
2408 int syntaxerrposition;
2411 * If there is a syntax error position, convert to internal syntax error;
2412 * otherwise treat the query as an item of context stack
2414 syntaxerrposition = geterrposition();
2415 if (syntaxerrposition > 0)
2418 internalerrposition(syntaxerrposition);
2419 internalerrquery(query);
2422 errcontext("SQL statement \"%s\"", query);
2426 * _SPI_cursor_operation()
2428 * Do a FETCH or MOVE in a cursor
2431 _SPI_cursor_operation(Portal portal, FetchDirection direction, long count,
2436 /* Check that the portal is valid */
2437 if (!PortalIsValid(portal))
2438 elog(ERROR, "invalid portal in SPI cursor operation");
2440 /* Push the SPI stack */
2441 if (_SPI_begin_call(true) < 0)
2442 elog(ERROR, "SPI cursor operation called while not connected");
2444 /* Reset the SPI result (note we deliberately don't touch lastoid) */
2446 SPI_tuptable = NULL;
2447 _SPI_current->processed = 0;
2448 _SPI_current->tuptable = NULL;
2450 /* Run the cursor */
2451 nfetched = PortalRunFetch(portal,
2457 * Think not to combine this store with the preceding function call. If
2458 * the portal contains calls to functions that use SPI, then SPI_stack is
2459 * likely to move around while the portal runs. When control returns,
2460 * _SPI_current will point to the correct stack entry... but the pointer
2461 * may be different than it was beforehand. So we must be sure to re-fetch
2462 * the pointer after the function call completes.
2464 _SPI_current->processed = nfetched;
2466 if (dest->mydest == DestSPI && _SPI_checktuples())
2467 elog(ERROR, "consistency check on SPI tuple count failed");
2469 /* Put the result into place for access by caller */
2470 SPI_processed = _SPI_current->processed;
2471 SPI_tuptable = _SPI_current->tuptable;
2473 /* tuptable now is caller's responsibility, not SPI's */
2474 _SPI_current->tuptable = NULL;
2476 /* Pop the SPI stack */
2477 _SPI_end_call(true);
2481 static MemoryContext
2484 return MemoryContextSwitchTo(_SPI_current->execCxt);
2487 static MemoryContext
2490 return MemoryContextSwitchTo(_SPI_current->procCxt);
2494 * _SPI_begin_call: begin a SPI operation within a connected procedure
2497 _SPI_begin_call(bool execmem)
2499 if (_SPI_curid + 1 != _SPI_connected)
2500 return SPI_ERROR_UNCONNECTED;
2502 if (_SPI_current != &(_SPI_stack[_SPI_curid]))
2503 elog(ERROR, "SPI stack corrupted");
2505 if (execmem) /* switch to the Executor memory context */
2512 * _SPI_end_call: end a SPI operation within a connected procedure
2514 * Note: this currently has no failure return cases, so callers don't check
2517 _SPI_end_call(bool procmem)
2520 * We're returning to procedure where _SPI_curid == _SPI_connected - 1
2524 if (procmem) /* switch to the procedure memory context */
2527 /* and free Executor memory */
2528 MemoryContextResetAndDeleteChildren(_SPI_current->execCxt);
2535 _SPI_checktuples(void)
2537 uint32 processed = _SPI_current->processed;
2538 SPITupleTable *tuptable = _SPI_current->tuptable;
2539 bool failed = false;
2541 if (tuptable == NULL) /* spi_dest_startup was not called */
2543 else if (processed != (tuptable->alloced - tuptable->free))
2550 * Convert a "temporary" SPIPlan into an "unsaved" plan.
2552 * The passed _SPI_plan struct is on the stack, and all its subsidiary data
2553 * is in or under the current SPI executor context. Copy the plan into the
2554 * SPI procedure context so it will survive _SPI_end_call(). To minimize
2555 * data copying, this destructively modifies the input plan, by taking the
2556 * plancache entries away from it and reparenting them to the new SPIPlan.
2559 _SPI_make_plan_non_temp(SPIPlanPtr plan)
2562 MemoryContext parentcxt = _SPI_current->procCxt;
2563 MemoryContext plancxt;
2564 MemoryContext oldcxt;
2567 /* Assert the input is a temporary SPIPlan */
2568 Assert(plan->magic == _SPI_PLAN_MAGIC);
2569 Assert(plan->plancxt == NULL);
2570 /* One-shot plans can't be saved */
2571 Assert(!plan->oneshot);
2574 * Create a memory context for the plan, underneath the procedure context.
2575 * We don't expect the plan to be very large, so use smaller-than-default
2578 plancxt = AllocSetContextCreate(parentcxt,
2580 ALLOCSET_SMALL_MINSIZE,
2581 ALLOCSET_SMALL_INITSIZE,
2582 ALLOCSET_SMALL_MAXSIZE);
2583 oldcxt = MemoryContextSwitchTo(plancxt);
2585 /* Copy the SPI_plan struct and subsidiary data into the new context */
2586 newplan = (SPIPlanPtr) palloc(sizeof(_SPI_plan));
2587 newplan->magic = _SPI_PLAN_MAGIC;
2588 newplan->saved = false;
2589 newplan->oneshot = false;
2590 newplan->plancache_list = NIL;
2591 newplan->plancxt = plancxt;
2592 newplan->cursor_options = plan->cursor_options;
2593 newplan->nargs = plan->nargs;
2594 if (plan->nargs > 0)
2596 newplan->argtypes = (Oid *) palloc(plan->nargs * sizeof(Oid));
2597 memcpy(newplan->argtypes, plan->argtypes, plan->nargs * sizeof(Oid));
2600 newplan->argtypes = NULL;
2601 newplan->parserSetup = plan->parserSetup;
2602 newplan->parserSetupArg = plan->parserSetupArg;
2605 * Reparent all the CachedPlanSources into the procedure context. In
2606 * theory this could fail partway through due to the pallocs, but we don't
2607 * care too much since both the procedure context and the executor context
2608 * would go away on error.
2610 foreach(lc, plan->plancache_list)
2612 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
2614 CachedPlanSetParentContext(plansource, parentcxt);
2616 /* Build new list, with list cells in plancxt */
2617 newplan->plancache_list = lappend(newplan->plancache_list, plansource);
2620 MemoryContextSwitchTo(oldcxt);
2622 /* For safety, unlink the CachedPlanSources from the temporary plan */
2623 plan->plancache_list = NIL;
2629 * Make a "saved" copy of the given plan.
2632 _SPI_save_plan(SPIPlanPtr plan)
2635 MemoryContext plancxt;
2636 MemoryContext oldcxt;
2639 /* One-shot plans can't be saved */
2640 Assert(!plan->oneshot);
2643 * Create a memory context for the plan. We don't expect the plan to be
2644 * very large, so use smaller-than-default alloc parameters. It's a
2645 * transient context until we finish copying everything.
2647 plancxt = AllocSetContextCreate(CurrentMemoryContext,
2649 ALLOCSET_SMALL_MINSIZE,
2650 ALLOCSET_SMALL_INITSIZE,
2651 ALLOCSET_SMALL_MAXSIZE);
2652 oldcxt = MemoryContextSwitchTo(plancxt);
2654 /* Copy the SPI plan into its own context */
2655 newplan = (SPIPlanPtr) palloc(sizeof(_SPI_plan));
2656 newplan->magic = _SPI_PLAN_MAGIC;
2657 newplan->saved = false;
2658 newplan->oneshot = false;
2659 newplan->plancache_list = NIL;
2660 newplan->plancxt = plancxt;
2661 newplan->cursor_options = plan->cursor_options;
2662 newplan->nargs = plan->nargs;
2663 if (plan->nargs > 0)
2665 newplan->argtypes = (Oid *) palloc(plan->nargs * sizeof(Oid));
2666 memcpy(newplan->argtypes, plan->argtypes, plan->nargs * sizeof(Oid));
2669 newplan->argtypes = NULL;
2670 newplan->parserSetup = plan->parserSetup;
2671 newplan->parserSetupArg = plan->parserSetupArg;
2673 /* Copy all the plancache entries */
2674 foreach(lc, plan->plancache_list)
2676 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
2677 CachedPlanSource *newsource;
2679 newsource = CopyCachedPlan(plansource);
2680 newplan->plancache_list = lappend(newplan->plancache_list, newsource);
2683 MemoryContextSwitchTo(oldcxt);
2686 * Mark it saved, reparent it under CacheMemoryContext, and mark all the
2687 * component CachedPlanSources as saved. This sequence cannot fail
2688 * partway through, so there's no risk of long-term memory leakage.
2690 newplan->saved = true;
2691 MemoryContextSetParent(newplan->plancxt, CacheMemoryContext);
2693 foreach(lc, newplan->plancache_list)
2695 CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
2697 SaveCachedPlan(plansource);