1
- <!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.61 2008/03/25 22:42:42 tgl Exp $ -->
1
+ <!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.62 2008/04/01 03:09:30 tgl Exp $ -->
2
2
3
3
<chapter id="spi">
4
4
<title>Server Programming Interface</title>
@@ -267,7 +267,7 @@ void SPI_pop(void)
267
267
<title>Description</title>
268
268
269
269
<para>
270
- <function>SPI_pop</function> pops the previous environment from the
270
+ <function>SPI_pop</function> pops the previous environment from the
271
271
SPI call stack. See <function>SPI_push</function>.
272
272
</para>
273
273
</refsect1>
@@ -371,7 +371,7 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
371
371
then you can use the
372
372
global pointer <literal>SPITupleTable *SPI_tuptable</literal> to
373
373
access the result rows. Some utility commands (such as
374
- <command>EXPLAIN</>) also return row sets, and <literal>SPI_tuptable</>
374
+ <command>EXPLAIN</>) also return row sets, and <literal>SPI_tuptable</>
375
375
will contain the result in these cases too.
376
376
</para>
377
377
@@ -676,6 +676,150 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count<
676
676
677
677
<!-- *********************************************** -->
678
678
679
+ <refentry id="spi-spi-execute-with-args">
680
+ <refmeta>
681
+ <refentrytitle>SPI_execute_with_args</refentrytitle>
682
+ </refmeta>
683
+
684
+ <refnamediv>
685
+ <refname>SPI_execute_with_args</refname>
686
+ <refpurpose>execute a command with out-of-line parameters</refpurpose>
687
+ </refnamediv>
688
+
689
+ <indexterm><primary>SPI_execute_with_args</primary></indexterm>
690
+
691
+ <refsynopsisdiv>
692
+ <synopsis>
693
+ int SPI_execute_with_args(const char *<parameter>command</parameter>,
694
+ int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>,
695
+ Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>,
696
+ bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
697
+ </synopsis>
698
+ </refsynopsisdiv>
699
+
700
+ <refsect1>
701
+ <title>Description</title>
702
+
703
+ <para>
704
+ <function>SPI_execute_with_args</function> executes a command that might
705
+ include references to externally supplied parameters. The command text
706
+ refers to a parameter as <literal>$<replaceable>n</></literal>, and
707
+ the call specifies data types and values for each such symbol.
708
+ <parameter>read_only</parameter> and <parameter>count</parameter> have
709
+ the same interpretation as in <function>SPI_execute</function>.
710
+ </para>
711
+
712
+ <para>
713
+ The main advantage of this routine compared to
714
+ <function>SPI_execute</function> is that data values can be inserted
715
+ into the command without tedious quoting/escaping, and thus with much
716
+ less risk of SQL-injection attacks.
717
+ </para>
718
+
719
+ <para>
720
+ Similar results can be achieved with <function>SPI_prepare</> followed by
721
+ <function>SPI_execute_plan</function>; however, when using this function
722
+ the query plan is customized to the specific parameter values provided.
723
+ For one-time query execution, this function should be preferred.
724
+ If the same command is to be executed with many different parameters,
725
+ either method might be faster, depending on the cost of re-planning
726
+ versus the benefit of custom plans.
727
+ </para>
728
+ </refsect1>
729
+
730
+ <refsect1>
731
+ <title>Arguments</title>
732
+
733
+ <variablelist>
734
+ <varlistentry>
735
+ <term><literal>const char * <parameter>command</parameter></literal></term>
736
+ <listitem>
737
+ <para>
738
+ command string
739
+ </para>
740
+ </listitem>
741
+ </varlistentry>
742
+
743
+ <varlistentry>
744
+ <term><literal>int <parameter>nargs</parameter></literal></term>
745
+ <listitem>
746
+ <para>
747
+ number of input parameters (<literal>$1</>, <literal>$2</>, etc.)
748
+ </para>
749
+ </listitem>
750
+ </varlistentry>
751
+
752
+ <varlistentry>
753
+ <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
754
+ <listitem>
755
+ <para>
756
+ an array containing the <acronym>OID</acronym>s of
757
+ the data types of the parameters
758
+ </para>
759
+ </listitem>
760
+ </varlistentry>
761
+
762
+ <varlistentry>
763
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
764
+ <listitem>
765
+ <para>
766
+ an array of actual parameter values
767
+ </para>
768
+ </listitem>
769
+ </varlistentry>
770
+
771
+ <varlistentry>
772
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
773
+ <listitem>
774
+ <para>
775
+ an array describing which parameters are null
776
+ </para>
777
+
778
+ <para>
779
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
780
+ <function>SPI_execute_with_args</function> assumes that no parameters are
781
+ null.
782
+ </para>
783
+ </listitem>
784
+ </varlistentry>
785
+
786
+ <varlistentry>
787
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
788
+ <listitem>
789
+ <para>
790
+ <literal>true</> for read-only execution
791
+ </para>
792
+ </listitem>
793
+ </varlistentry>
794
+
795
+ <varlistentry>
796
+ <term><literal>long <parameter>count</parameter></literal></term>
797
+ <listitem>
798
+ <para>
799
+ maximum number of rows to process or return
800
+ </para>
801
+ </listitem>
802
+ </varlistentry>
803
+ </variablelist>
804
+ </refsect1>
805
+
806
+ <refsect1>
807
+ <title>Return Value</title>
808
+
809
+ <para>
810
+ The return value is the same as for <function>SPI_execute</function>.
811
+ </para>
812
+
813
+ <para>
814
+ <varname>SPI_processed</varname> and
815
+ <varname>SPI_tuptable</varname> are set as in
816
+ <function>SPI_execute</function> if successful.
817
+ </para>
818
+ </refsect1>
819
+ </refentry>
820
+
821
+ <!-- *********************************************** -->
822
+
679
823
<refentry id="spi-spi-prepare">
680
824
<refmeta>
681
825
<refentrytitle>SPI_prepare</refentrytitle>
@@ -861,7 +1005,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * <parameter>command</parameter>, int <
861
1005
</para>
862
1006
</listitem>
863
1007
</varlistentry>
864
-
1008
+
865
1009
<varlistentry>
866
1010
<term><literal>int <parameter>cursorOptions</parameter></literal></term>
867
1011
<listitem>
@@ -1453,6 +1597,152 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par
1453
1597
1454
1598
<!-- *********************************************** -->
1455
1599
1600
+ <refentry id="spi-spi-cursor-open-with-args">
1601
+ <refmeta>
1602
+ <refentrytitle>SPI_cursor_open_with_args</refentrytitle>
1603
+ </refmeta>
1604
+
1605
+ <refnamediv>
1606
+ <refname>SPI_cursor_open_with_args</refname>
1607
+ <refpurpose>set up a cursor using a query and parameters</refpurpose>
1608
+ </refnamediv>
1609
+
1610
+ <indexterm><primary>SPI_cursor_open_with_args</primary></indexterm>
1611
+
1612
+ <refsynopsisdiv>
1613
+ <synopsis>
1614
+ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>,
1615
+ const char *<parameter>command</parameter>,
1616
+ int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>,
1617
+ Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>,
1618
+ bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>)
1619
+ </synopsis>
1620
+ </refsynopsisdiv>
1621
+
1622
+ <refsect1>
1623
+ <title>Description</title>
1624
+
1625
+ <para>
1626
+ <function>SPI_cursor_open_with_args</function> sets up a cursor
1627
+ (internally, a portal) that will execute the specified query.
1628
+ Most of the parameters have the same meanings as the corresponding
1629
+ parameters to <function>SPI_prepare_cursor</function>
1630
+ and <function>SPI_cursor_open</function>.
1631
+ </para>
1632
+
1633
+ <para>
1634
+ For one-time query execution, this function should be preferred
1635
+ over <function>SPI_prepare_cursor</function> followed by
1636
+ <function>SPI_cursor_open</function>.
1637
+ If the same command is to be executed with many different parameters,
1638
+ either method might be faster, depending on the cost of re-planning
1639
+ versus the benefit of custom plans.
1640
+ </para>
1641
+
1642
+ <para>
1643
+ The passed-in data will be copied into the cursor's portal, so it
1644
+ can be freed while the cursor still exists.
1645
+ </para>
1646
+ </refsect1>
1647
+
1648
+ <refsect1>
1649
+ <title>Arguments</title>
1650
+
1651
+ <variablelist>
1652
+ <varlistentry>
1653
+ <term><literal>const char * <parameter>name</parameter></literal></term>
1654
+ <listitem>
1655
+ <para>
1656
+ name for portal, or <symbol>NULL</symbol> to let the system
1657
+ select a name
1658
+ </para>
1659
+ </listitem>
1660
+ </varlistentry>
1661
+
1662
+ <varlistentry>
1663
+ <term><literal>const char * <parameter>command</parameter></literal></term>
1664
+ <listitem>
1665
+ <para>
1666
+ command string
1667
+ </para>
1668
+ </listitem>
1669
+ </varlistentry>
1670
+
1671
+ <varlistentry>
1672
+ <term><literal>int <parameter>nargs</parameter></literal></term>
1673
+ <listitem>
1674
+ <para>
1675
+ number of input parameters (<literal>$1</>, <literal>$2</>, etc.)
1676
+ </para>
1677
+ </listitem>
1678
+ </varlistentry>
1679
+
1680
+ <varlistentry>
1681
+ <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
1682
+ <listitem>
1683
+ <para>
1684
+ an array containing the <acronym>OID</acronym>s of
1685
+ the data types of the parameters
1686
+ </para>
1687
+ </listitem>
1688
+ </varlistentry>
1689
+
1690
+ <varlistentry>
1691
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
1692
+ <listitem>
1693
+ <para>
1694
+ an array of actual parameter values
1695
+ </para>
1696
+ </listitem>
1697
+ </varlistentry>
1698
+
1699
+ <varlistentry>
1700
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
1701
+ <listitem>
1702
+ <para>
1703
+ an array describing which parameters are null
1704
+ </para>
1705
+
1706
+ <para>
1707
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
1708
+ <function>SPI_cursor_open_with_args</function> assumes that no
1709
+ parameters are null.
1710
+ </para>
1711
+ </listitem>
1712
+ </varlistentry>
1713
+
1714
+ <varlistentry>
1715
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
1716
+ <listitem>
1717
+ <para>
1718
+ <literal>true</> for read-only execution
1719
+ </para>
1720
+ </listitem>
1721
+ </varlistentry>
1722
+
1723
+ <varlistentry>
1724
+ <term><literal>int <parameter>cursorOptions</parameter></literal></term>
1725
+ <listitem>
1726
+ <para>
1727
+ integer bitmask of cursor options; zero produces default behavior
1728
+ </para>
1729
+ </listitem>
1730
+ </varlistentry>
1731
+ </variablelist>
1732
+ </refsect1>
1733
+
1734
+ <refsect1>
1735
+ <title>Return Value</title>
1736
+
1737
+ <para>
1738
+ Pointer to portal containing the cursor. Note there is no error
1739
+ return convention; any error will be reported via <function>elog</>.
1740
+ </para>
1741
+ </refsect1>
1742
+ </refentry>
1743
+
1744
+ <!-- *********************************************** -->
1745
+
1456
1746
<refentry id="spi-spi-cursor-find">
1457
1747
<refmeta>
1458
1748
<refentrytitle>SPI_cursor_find</refentrytitle>
@@ -1748,7 +2038,7 @@ void SPI_scroll_cursor_fetch(Portal <parameter>portal</parameter>, FetchDirectio
1748
2038
1749
2039
<para>
1750
2040
See the SQL <xref linkend="sql-fetch" endterm="sql-fetch-title"> command
1751
- for details of the interpretation of the
2041
+ for details of the interpretation of the
1752
2042
<parameter>direction</parameter> and
1753
2043
<parameter>count</parameter> parameters.
1754
2044
</para>
@@ -1847,7 +2137,7 @@ void SPI_scroll_cursor_move(Portal <parameter>portal</parameter>, FetchDirection
1847
2137
1848
2138
<para>
1849
2139
See the SQL <xref linkend="sql-fetch" endterm="sql-fetch-title"> command
1850
- for details of the interpretation of the
2140
+ for details of the interpretation of the
1851
2141
<parameter>direction</parameter> and
1852
2142
<parameter>count</parameter> parameters.
1853
2143
</para>
@@ -3346,9 +3636,9 @@ execq(text *sql, int cnt)
3346
3636
command = text_to_cstring(sql);
3347
3637
3348
3638
SPI_connect();
3349
-
3639
+
3350
3640
ret = SPI_exec(command, cnt);
3351
-
3641
+
3352
3642
proc = SPI_processed;
3353
3643
/*
3354
3644
* If some rows were fetched, print them via elog(INFO).
@@ -3359,11 +3649,11 @@ execq(text *sql, int cnt)
3359
3649
SPITupleTable *tuptable = SPI_tuptable;
3360
3650
char buf[8192];
3361
3651
int i, j;
3362
-
3652
+
3363
3653
for (j = 0; j < proc; j++)
3364
3654
{
3365
3655
HeapTuple tuple = tuptable->vals[j];
3366
-
3656
+
3367
3657
for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
3368
3658
snprintf(buf + strlen (buf), sizeof(buf) - strlen(buf), " %s%s",
3369
3659
SPI_getvalue(tuple, tupdesc, i),
@@ -3469,7 +3759,7 @@ INSERT 0 2
3469
3759
2
3470
3760
2 -- 2 rows * 1 (x in first row)
3471
3761
6 -- 3 rows (2 + 1 just inserted) * 2 (x in second row)
3472
- (4 rows) ^^^^^^
3762
+ (4 rows) ^^^^^^
3473
3763
rows visible to execq() in different invocations
3474
3764
</programlisting>
3475
3765
</para>
0 commit comments