Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1833f1a

Browse files
committed
Simplify code by getting rid of SPI_push, SPI_pop, SPI_restore_connection.
The idea behind SPI_push was to allow transitioning back into an"unconnected" state when a SPI-using procedure calls unrelated code thatmight or might not invoke SPI. That sounds good, but in practice the onlything it does for us is to catch cases where a called SPI-using functionforgets to call SPI_connect --- which is a highly improbable failure mode,since it would be exposed immediately by direct testing of said function.As against that, we've had multiple bugs induced by forgetting to callSPI_push/SPI_pop around code that might invoke SPI-using functions; theseare much harder to catch and indeed have gone undetected for years in somecases. And we've had to band-aid around some problems of this ilk byintroducing conditional push/pop pairs in some places, which really kindof defeats the purpose altogether; if we can't draw bright lines betweenconnected and unconnected code, what's the point?Hence, get rid of SPI_push[_conditional], SPI_pop[_conditional], and theunderlying state variable _SPI_curid. It turns out SPI_restore_connectioncan go away too, which is a nice side benefit since it was never more thana kluge. Provide no-op macros for the deleted functions so as to avoid anAPI break for external modules.A side effect of this removal is that SPI_palloc and allied functions nolonger permit being called when unconnected; they'll throw an errorinstead. The apparent usefulness of the previous behavior was a mirageas well, because it was depended on by only a few places (which I fixed inpreceding commits), and it posed a risk of allocations being unexpectedlylong-lived if someone forgot a SPI_push call.Discussion: <20808.1478481403@sss.pgh.pa.us>
1 parent577f0bd commit1833f1a

File tree

12 files changed

+105
-493
lines changed

12 files changed

+105
-493
lines changed

‎doc/src/sgml/spi.sgml

Lines changed: 45 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,6 @@ int SPI_connect(void)
9090
function if you want to execute commands through SPI. Some utility
9191
SPI functions can be called from unconnected procedures.
9292
</para>
93-
94-
<para>
95-
If your procedure is already connected,
96-
<function>SPI_connect</function> will return the error code
97-
<returnvalue>SPI_ERROR_CONNECT</returnvalue>. This could happen if
98-
a procedure that has called <function>SPI_connect</function>
99-
directly calls another procedure that calls
100-
<function>SPI_connect</function>. While recursive calls to the
101-
<acronym>SPI</acronym> manager are permitted when an SQL command
102-
called through SPI invokes another function that uses
103-
<acronym>SPI</acronym>, directly nested calls to
104-
<function>SPI_connect</function> and
105-
<function>SPI_finish</function> are forbidden.
106-
(But see <function>SPI_push</function> and <function>SPI_pop</function>.)
107-
</para>
10893
</refsect1>
10994

11095
<refsect1>
@@ -164,13 +149,6 @@ int SPI_finish(void)
164149
abort the transaction via <literal>elog(ERROR)</literal>. In that
165150
case SPI will clean itself up automatically.
166151
</para>
167-
168-
<para>
169-
If <function>SPI_finish</function> is called without having a valid
170-
connection, it will return <symbol>SPI_ERROR_UNCONNECTED</symbol>.
171-
There is no fundamental problem with this; it means that the SPI
172-
manager has nothing to do.
173-
</para>
174152
</refsect1>
175153

176154
<refsect1>
@@ -200,86 +178,6 @@ int SPI_finish(void)
200178

201179
<!-- *********************************************** -->
202180

203-
<refentry id="spi-spi-push">
204-
<indexterm><primary>SPI_push</primary></indexterm>
205-
206-
<refmeta>
207-
<refentrytitle>SPI_push</refentrytitle>
208-
<manvolnum>3</manvolnum>
209-
</refmeta>
210-
211-
<refnamediv>
212-
<refname>SPI_push</refname>
213-
<refpurpose>push SPI stack to allow recursive SPI usage</refpurpose>
214-
</refnamediv>
215-
216-
<refsynopsisdiv>
217-
<synopsis>
218-
void SPI_push(void)
219-
</synopsis>
220-
</refsynopsisdiv>
221-
222-
<refsect1>
223-
<title>Description</title>
224-
225-
<para>
226-
<function>SPI_push</function> should be called before executing another
227-
procedure that might itself wish to use SPI.
228-
After <function>SPI_push</function>, SPI is no longer in a
229-
<quote>connected</> state, and SPI function calls will be rejected unless
230-
a fresh <function>SPI_connect</function> is done. This ensures a clean
231-
separation between your procedure's SPI state and that of another procedure
232-
you call. After the other procedure returns, call
233-
<function>SPI_pop</function> to restore access to your own SPI state.
234-
</para>
235-
236-
<para>
237-
Note that <function>SPI_execute</function> and related functions
238-
automatically do the equivalent of <function>SPI_push</function> before
239-
passing control back to the SQL execution engine, so it is not necessary
240-
for you to worry about this when using those functions.
241-
Only when you are directly calling arbitrary code that might contain
242-
<function>SPI_connect</function> calls do you need to issue
243-
<function>SPI_push</function> and <function>SPI_pop</function>.
244-
</para>
245-
</refsect1>
246-
247-
</refentry>
248-
249-
<!-- *********************************************** -->
250-
251-
<refentry id="spi-spi-pop">
252-
<indexterm><primary>SPI_pop</primary></indexterm>
253-
254-
<refmeta>
255-
<refentrytitle>SPI_pop</refentrytitle>
256-
<manvolnum>3</manvolnum>
257-
</refmeta>
258-
259-
<refnamediv>
260-
<refname>SPI_pop</refname>
261-
<refpurpose>pop SPI stack to return from recursive SPI usage</refpurpose>
262-
</refnamediv>
263-
264-
<refsynopsisdiv>
265-
<synopsis>
266-
void SPI_pop(void)
267-
</synopsis>
268-
</refsynopsisdiv>
269-
270-
<refsect1>
271-
<title>Description</title>
272-
273-
<para>
274-
<function>SPI_pop</function> pops the previous environment from the
275-
SPI call stack. See <function>SPI_push</function>.
276-
</para>
277-
</refsect1>
278-
279-
</refentry>
280-
281-
<!-- *********************************************** -->
282-
283181
<refentry id="spi-spi-execute">
284182
<indexterm><primary>SPI_execute</primary></indexterm>
285183

@@ -3361,43 +3259,23 @@ char * SPI_getnspname(Relation <parameter>rel</parameter>)
33613259
<quote>upper executor context</quote>, that is, the memory context
33623260
that was current when <function>SPI_connect</function> was called,
33633261
which is precisely the right context for a value returned from your
3364-
procedure.
3365-
</para>
3366-
3367-
<para>
3368-
If <function>SPI_palloc</function> is called while the procedure is
3369-
not connected to SPI, then it acts the same as a normal
3370-
<function>palloc</function>. Before a procedure connects to the
3371-
SPI manager, the current memory context is the upper executor
3372-
context, so all allocations made by the procedure via
3373-
<function>palloc</function> or by SPI utility functions are made in
3374-
this context.
3262+
procedure. Several of the other utility procedures described in
3263+
this section also return objects created in the upper executor context.
33753264
</para>
33763265

33773266
<para>
33783267
When <function>SPI_connect</function> is called, the private
33793268
context of the procedure, which is created by
33803269
<function>SPI_connect</function>, is made the current context. All
33813270
allocations made by <function>palloc</function>,
3382-
<function>repalloc</function>, or SPI utility functions (except for
3383-
<function>SPI_copytuple</function>,
3384-
<function>SPI_returntuple</function>,
3385-
<function>SPI_modifytuple</function>,
3386-
<function>SPI_palloc</function>, and
3387-
<function>SPI_datumTransfer</function>) are made in this context. When a
3271+
<function>repalloc</function>, or SPI utility functions (except as
3272+
described in this section) are made in this context. When a
33883273
procedure disconnects from the SPI manager (via
33893274
<function>SPI_finish</function>) the current context is restored to
33903275
the upper executor context, and all allocations made in the
33913276
procedure memory context are freed and cannot be used any more.
33923277
</para>
33933278

3394-
<para>
3395-
All functions described in this section can be used by both
3396-
connected and unconnected procedures. In an unconnected procedure,
3397-
they act the same as the underlying ordinary server functions
3398-
(<function>palloc</>, etc.).
3399-
</para>
3400-
34013279
<!-- *********************************************** -->
34023280

34033281
<refentry id="spi-spi-palloc">
@@ -3426,6 +3304,11 @@ void * SPI_palloc(Size <parameter>size</parameter>)
34263304
<function>SPI_palloc</function> allocates memory in the upper
34273305
executor context.
34283306
</para>
3307+
3308+
<para>
3309+
This function can only be used while connected to SPI.
3310+
Otherwise, it throws an error.
3311+
</para>
34293312
</refsect1>
34303313

34313314
<refsect1>
@@ -3605,6 +3488,12 @@ HeapTuple SPI_copytuple(HeapTuple <parameter>row</parameter>)
36053488
row from a trigger. In a function declared to return a composite
36063489
type, use <function>SPI_returntuple</function> instead.
36073490
</para>
3491+
3492+
<para>
3493+
This function can only be used while connected to SPI.
3494+
Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
3495+
<symbol>SPI_ERROR_UNCONNECTED</symbol>.
3496+
</para>
36083497
</refsect1>
36093498

36103499
<refsect1>
@@ -3626,8 +3515,8 @@ HeapTuple SPI_copytuple(HeapTuple <parameter>row</parameter>)
36263515
<title>Return Value</title>
36273516

36283517
<para>
3629-
the copied row;<symbol>NULL</symbol>only if
3630-
<parameter>tuple</parameter> is <symbol>NULL</symbol>
3518+
the copied row, or<symbol>NULL</symbol>on error
3519+
(see <varname>SPI_result</varname> for an error indication)
36313520
</para>
36323521
</refsect1>
36333522
</refentry>
@@ -3663,6 +3552,12 @@ HeapTupleHeader SPI_returntuple(HeapTuple <parameter>row</parameter>, TupleDesc
36633552
before returning.
36643553
</para>
36653554

3555+
<para>
3556+
This function can only be used while connected to SPI.
3557+
Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
3558+
<symbol>SPI_ERROR_UNCONNECTED</symbol>.
3559+
</para>
3560+
36663561
<para>
36673562
Note that this should be used for functions that are declared to return
36683563
composite types. It is not used for triggers; use
@@ -3699,10 +3594,9 @@ HeapTupleHeader SPI_returntuple(HeapTuple <parameter>row</parameter>, TupleDesc
36993594
<title>Return Value</title>
37003595

37013596
<para>
3702-
<type>HeapTupleHeader</type> pointing to copied row;
3703-
<symbol>NULL</symbol> only if
3704-
<parameter>row</parameter> or <parameter>rowdesc</parameter> is
3705-
<symbol>NULL</symbol>
3597+
<type>HeapTupleHeader</type> pointing to copied row,
3598+
or <symbol>NULL</symbol> on error
3599+
(see <varname>SPI_result</varname> for an error indication)
37063600
</para>
37073601
</refsect1>
37083602
</refentry>
@@ -3736,6 +3630,13 @@ HeapTuple SPI_modifytuple(Relation <parameter>rel</parameter>, HeapTuple <parame
37363630
<function>SPI_modifytuple</function> creates a new row by
37373631
substituting new values for selected columns, copying the original
37383632
row's columns at other positions. The input row is not modified.
3633+
The new row is returned in the upper executor context.
3634+
</para>
3635+
3636+
<para>
3637+
This function can only be used while connected to SPI.
3638+
Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
3639+
<symbol>SPI_ERROR_UNCONNECTED</symbol>.
37393640
</para>
37403641
</refsect1>
37413642

@@ -3821,8 +3722,8 @@ HeapTuple SPI_modifytuple(Relation <parameter>rel</parameter>, HeapTuple <parame
38213722

38223723
<para>
38233724
new row with modifications, allocated in the upper executor
3824-
context;<symbol>NULL</symbol>only if <parameter>row</parameter>
3825-
is <symbol>NULL</symbol>
3725+
context, or<symbol>NULL</symbol>on error
3726+
(see <varname>SPI_result</varname> for an error indication)
38263727
</para>
38273728

38283729
<para>
@@ -3845,11 +3746,20 @@ HeapTuple SPI_modifytuple(Relation <parameter>rel</parameter>, HeapTuple <parame
38453746
<listitem>
38463747
<para>
38473748
if <parameter>colnum</> contains an invalid column number (less
3848-
than or equal to 0 or greater than the number ofcolumn in
3749+
than or equal to 0 or greater than the number ofcolumns in
38493750
<parameter>row</>)
38503751
</para>
38513752
</listitem>
38523753
</varlistentry>
3754+
3755+
<varlistentry>
3756+
<term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
3757+
<listitem>
3758+
<para>
3759+
if SPI is not active
3760+
</para>
3761+
</listitem>
3762+
</varlistentry>
38533763
</variablelist>
38543764
</para>
38553765
</refsect1>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp