1- <!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.53 2007/02/18 01:47:40 momjian Exp $ -->
1+ <!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.54 2007/03/15 23:12:06 tgl Exp $ -->
22
33<chapter id="spi">
44 <title>Server Programming Interface</title>
1414 <acronym>SQL</acronym> commands inside their functions.
1515 <acronym>SPI</acronym> is a set of
1616 interface functions to simplify access to the parser, planner,
17- optimizer, and executor. <acronym>SPI</acronym> also does some
17+ and executor. <acronym>SPI</acronym> also does some
1818 memory management.
1919 </para>
2020
@@ -322,7 +322,8 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
322322
323323 <para>
324324 You can pass multiple commands in one string, but later commands cannot
325- depend on the creation of objects earlier in the string.
325+ depend on the creation of objects earlier in the string, because the
326+ whole string will be parsed and planned before execution begins.
326327 <function>SPI_execute</function> returns the
327328 result for the command executed last. The <parameter>count</parameter>
328329 limit applies to each command separately, but it is not applied to
@@ -699,7 +700,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count<
699700
700701 <refsynopsisdiv>
701702<synopsis>
702- void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>nargs</parameter>, Oid * <parameter>argtypes</parameter>)
703+ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <parameter>nargs</parameter>, Oid * <parameter>argtypes</parameter>)
703704</synopsis>
704705 </refsynopsisdiv>
705706
@@ -790,6 +791,13 @@ void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>n
790791 <refsect1>
791792 <title>Notes</title>
792793
794+ <para>
795+ <type>SPIPlanPtr</> is declared as a pointer to an opaque struct type in
796+ <filename>spi.h</>. It is unwise to try to access its contents
797+ directly, as that makes your code much more likely to break in
798+ future revisions of <productname>PostgreSQL</productname>.
799+ </para>
800+
793801 <para>
794802 There is a disadvantage to using parameters: since the planner does
795803 not know the values that will be supplied for the parameters, it
@@ -816,7 +824,7 @@ void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>n
816824
817825 <refsynopsisdiv>
818826<synopsis>
819- int SPI_getargcount(void * <parameter>plan</parameter>)
827+ int SPI_getargcount(SPIPlanPtr <parameter>plan</parameter>)
820828</synopsis>
821829 </refsynopsisdiv>
822830
@@ -834,7 +842,7 @@ int SPI_getargcount(void * <parameter>plan</parameter>)
834842
835843 <variablelist>
836844 <varlistentry>
837- <term><literal>void * <parameter>plan</parameter></literal></term>
845+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
838846 <listitem>
839847 <para>
840848 execution plan (returned by <function>SPI_prepare</function>)
@@ -847,9 +855,10 @@ int SPI_getargcount(void * <parameter>plan</parameter>)
847855 <refsect1>
848856 <title>Return Value</title>
849857 <para>
850- The expected argument count for the <parameter>plan</parameter>, or
851- <symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan
852- </parameter> is <symbol>NULL</symbol>
858+ The count of expected arguments for the <parameter>plan</parameter>.
859+ If the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
860+ <varname>SPI_result</varname> is set to <symbol>SPI_ERROR_ARGUMENT</symbol>
861+ and <literal>-1</literal> is returned.
853862 </para>
854863 </refsect1>
855864</refentry>
@@ -871,7 +880,7 @@ int SPI_getargcount(void * <parameter>plan</parameter>)
871880
872881 <refsynopsisdiv>
873882<synopsis>
874- Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex</parameter>)
883+ Oid SPI_getargtypeid(SPIPlanPtr <parameter>plan</parameter>, int <parameter>argIndex</parameter>)
875884</synopsis>
876885 </refsynopsisdiv>
877886
@@ -890,7 +899,7 @@ Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex
890899
891900 <variablelist>
892901 <varlistentry>
893- <term><literal>void * <parameter>plan</parameter></literal></term>
902+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
894903 <listitem>
895904 <para>
896905 execution plan (returned by <function>SPI_prepare</function>)
@@ -912,11 +921,13 @@ Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex
912921 <refsect1>
913922 <title>Return Value</title>
914923 <para>
915- The type id of the argument at the given index, or
916- <symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter> is
917- <symbol>NULL</symbol> or <parameter>argIndex</parameter> is less than 0 or
924+ The type id of the argument at the given index.
925+ If the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
926+ or <parameter>argIndex</parameter> is less than 0 or
918927 not less than the number of arguments declared for the
919- <parameter>plan</parameter>
928+ <parameter>plan</parameter>,
929+ <varname>SPI_result</varname> is set to <symbol>SPI_ERROR_ARGUMENT</symbol>
930+ and <symbol>InvalidOid</symbol> is returned.
920931 </para>
921932 </refsect1>
922933</refentry>
@@ -939,7 +950,7 @@ Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex
939950
940951 <refsynopsisdiv>
941952<synopsis>
942- bool SPI_is_cursor_plan(void * <parameter>plan</parameter>)
953+ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>)
943954</synopsis>
944955 </refsynopsisdiv>
945956
@@ -964,7 +975,7 @@ bool SPI_is_cursor_plan(void * <parameter>plan</parameter>)
964975
965976 <variablelist>
966977 <varlistentry>
967- <term><literal>void * <parameter>plan</parameter></literal></term>
978+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
968979 <listitem>
969980 <para>
970981 execution plan (returned by <function>SPI_prepare</function>)
@@ -978,9 +989,10 @@ bool SPI_is_cursor_plan(void * <parameter>plan</parameter>)
978989 <title>Return Value</title>
979990 <para>
980991 <symbol>true</symbol> or <symbol>false</symbol> to indicate if the
981- <parameter>plan</parameter> can produce a cursor or not, or
982- <symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter>
983- is <symbol>NULL</symbol>
992+ <parameter>plan</parameter> can produce a cursor or not.
993+ If the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
994+ <varname>SPI_result</varname> is set to <symbol>SPI_ERROR_ARGUMENT</symbol>
995+ and <symbol>false</symbol> is returned.
984996 </para>
985997 </refsect1>
986998</refentry>
@@ -1001,7 +1013,7 @@ bool SPI_is_cursor_plan(void * <parameter>plan</parameter>)
10011013
10021014 <refsynopsisdiv>
10031015<synopsis>
1004- int SPI_execute_plan(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
1016+ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
10051017 bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
10061018</synopsis>
10071019 </refsynopsisdiv>
@@ -1022,7 +1034,7 @@ int SPI_execute_plan(void * <parameter>plan</parameter>, Datum * <parameter>valu
10221034
10231035 <variablelist>
10241036 <varlistentry>
1025- <term><literal>void * <parameter>plan</parameter></literal></term>
1037+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
10261038 <listitem>
10271039 <para>
10281040 execution plan (returned by <function>SPI_prepare</function>)
@@ -1091,8 +1103,8 @@ int SPI_execute_plan(void * <parameter>plan</parameter>, Datum * <parameter>valu
10911103 <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
10921104 <listitem>
10931105 <para>
1094- if <parameter>plan</parameter> is <symbol>NULL</symbol> or
1095- <parameter>count</parameter> is less than 0
1106+ if <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
1107+ or <parameter>count</parameter> is less than 0
10961108 </para>
10971109 </listitem>
10981110 </varlistentry>
@@ -1143,7 +1155,7 @@ int SPI_execute_plan(void * <parameter>plan</parameter>, Datum * <parameter>valu
11431155
11441156 <refsynopsisdiv>
11451157<synopsis>
1146- int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>)
1158+ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>)
11471159</synopsis>
11481160 </refsynopsisdiv>
11491161
@@ -1163,7 +1175,7 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par
11631175
11641176 <variablelist>
11651177 <varlistentry>
1166- <term><literal>void * <parameter>plan</parameter></literal></term>
1178+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
11671179 <listitem>
11681180 <para>
11691181 execution plan (returned by <function>SPI_prepare</function>)
@@ -1242,7 +1254,7 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par
12421254
12431255 <refsynopsisdiv>
12441256<synopsis>
1245- Portal SPI_cursor_open(const char * <parameter>name</parameter>, void * <parameter>plan</parameter>,
1257+ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>,
12461258 Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
12471259 bool <parameter>read_only</parameter>)
12481260</synopsis>
@@ -1268,6 +1280,11 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, void * <paramet
12681280 to the procedure's caller provides a way of returning a row set as
12691281 result.
12701282 </para>
1283+
1284+ <para>
1285+ The passed-in data will be copied into the cursor's portal, so it
1286+ can be freed while the cursor still exists.
1287+ </para>
12711288 </refsect1>
12721289
12731290 <refsect1>
@@ -1285,7 +1302,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, void * <paramet
12851302 </varlistentry>
12861303
12871304 <varlistentry>
1288- <term><literal>void * <parameter>plan</parameter></literal></term>
1305+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
12891306 <listitem>
12901307 <para>
12911308 execution plan (returned by <function>SPI_prepare</function>)
@@ -1602,7 +1619,7 @@ void SPI_cursor_close(Portal <parameter>portal</parameter>)
16021619
16031620 <refsynopsisdiv>
16041621<synopsis>
1605- void * SPI_saveplan(void * <parameter>plan</parameter>)
1622+ SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
16061623</synopsis>
16071624 </refsynopsisdiv>
16081625
@@ -1611,8 +1628,8 @@ void * SPI_saveplan(void * <parameter>plan</parameter>)
16111628
16121629 <para>
16131630 <function>SPI_saveplan</function> saves a passed plan (prepared by
1614- <function>SPI_prepare</function>) in memory protected from freeing
1615- by <function>SPI_finish</function> and by the transaction manager
1631+ <function>SPI_prepare</function>) in memory that will not be freed
1632+ by <function>SPI_finish</function> nor by the transaction manager,
16161633 and returns a pointer to the saved plan. This gives you the
16171634 ability to reuse prepared plans in the subsequent invocations of
16181635 your procedure in the current session.
@@ -1624,7 +1641,7 @@ void * SPI_saveplan(void * <parameter>plan</parameter>)
16241641
16251642 <variablelist>
16261643 <varlistentry>
1627- <term><literal>void * <parameter>plan</parameter></literal></term>
1644+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
16281645 <listitem>
16291646 <para>
16301647 the plan to be saved
@@ -1646,7 +1663,7 @@ void * SPI_saveplan(void * <parameter>plan</parameter>)
16461663 <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
16471664 <listitem>
16481665 <para>
1649- if <parameter>plan</parameter> is <symbol>NULL</symbol>
1666+ if <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid
16501667 </para>
16511668 </listitem>
16521669 </varlistentry>
@@ -1666,10 +1683,17 @@ void * SPI_saveplan(void * <parameter>plan</parameter>)
16661683 <refsect1>
16671684 <title>Notes</title>
16681685
1686+ <para>
1687+ The passed-in plan is not freed, so you might wish to do
1688+ <function>SPI_freeplan</function> on it to avoid leaking memory
1689+ until <function>SPI_finish</>.
1690+ </para>
1691+
16691692 <para>
16701693 If one of the objects (a table, function, etc.) referenced by the
1671- prepared plan is dropped during the session then the results of
1672- <function>SPI_execute_plan</function> for this plan will be unpredictable.
1694+ prepared plan is dropped or redefined, then future executions of
1695+ <function>SPI_execute_plan</function> may fail or return different
1696+ results than the plan initially indicates.
16731697 </para>
16741698 </refsect1>
16751699</refentry>
@@ -2879,7 +2903,7 @@ void SPI_freetuptable(SPITupleTable * <parameter>tuptable</parameter>)
28792903
28802904 <refsynopsisdiv>
28812905<synopsis>
2882- int SPI_freeplan(void * <parameter>plan</parameter>)
2906+ int SPI_freeplan(SPIPlanPtr <parameter>plan</parameter>)
28832907</synopsis>
28842908 </refsynopsisdiv>
28852909
@@ -2898,7 +2922,7 @@ int SPI_freeplan(void *<parameter>plan</parameter>)
28982922
28992923 <variablelist>
29002924 <varlistentry>
2901- <term><literal>void * <parameter>plan</parameter></literal></term>
2925+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
29022926 <listitem>
29032927 <para>
29042928 pointer to plan to free
@@ -2913,7 +2937,7 @@ int SPI_freeplan(void *<parameter>plan</parameter>)
29132937
29142938 <para>
29152939 <symbol>SPI_ERROR_ARGUMENT</symbol> if <parameter>plan</parameter>
2916- is <symbol>NULL</symbol>.
2940+ is <symbol>NULL</symbol> or invalid
29172941 </para>
29182942 </refsect1>
29192943</refentry>
0 commit comments