diff options
author | Alvaro Herrera | 2010-03-11 21:53:53 +0000 |
---|---|---|
committer | Alvaro Herrera | 2010-03-11 21:53:53 +0000 |
commit | bfc04a92abcc8da6690c05292715396492a658c5 (patch) | |
tree | ee9d62e744345e2c9d60c41ee1bedc8ca59ca2b8 | |
parent | eb9954e362127c582efe22e99f7b6c2db9d95dab (diff) |
Improve PL/Perl documentation of database access functions. (Backpatch to 8.4
of a patch previously applied by Bruce Momjian to CVS HEAD)
Alexey Klyukin
-rw-r--r-- | doc/src/sgml/plperl.sgml | 141 |
1 files changed, 112 insertions, 29 deletions
diff --git a/doc/src/sgml/plperl.sgml b/doc/src/sgml/plperl.sgml index dfb15b3bd1..eff01540ff 100644 --- a/doc/src/sgml/plperl.sgml +++ b/doc/src/sgml/plperl.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.69 2008/04/10 15:16:46 alvherre Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.69.2.1 2010/03/11 21:53:53 alvherre Exp $ --> <chapter id="plperl"> <title>PL/Perl - Perl Procedural Language</title> @@ -310,6 +310,7 @@ BEGIN { strict->import(); } <para> Access to the database itself from your Perl function can be done via the following functions: + </para> <variablelist> <varlistentry> @@ -317,16 +318,36 @@ BEGIN { strict->import(); } <primary>spi_exec_query</primary> <secondary>in PL/Perl</secondary> </indexterm> + <indexterm> + <primary>spi_query</primary> + <secondary>in PL/Perl</secondary> + </indexterm> + <indexterm> + <primary>spi_fetchrow</primary> + <secondary>in PL/Perl</secondary> + </indexterm> + <indexterm> + <primary>spi_prepare</primary> + <secondary>in PL/Perl</secondary> + </indexterm> + <indexterm> + <primary>spi_exec_prepared</primary> + <secondary>in PL/Perl</secondary> + </indexterm> + <indexterm> + <primary>spi_query_prepared</primary> + <secondary>in PL/Perl</secondary> + </indexterm> + <indexterm> + <primary>spi_cursor_close</primary> + <secondary>in PL/Perl</secondary> + </indexterm> + <indexterm> + <primary>spi_freeplan</primary> + <secondary>in PL/Perl</secondary> + </indexterm> <term><literal><function>spi_exec_query</>(<replaceable>query</replaceable> [, <replaceable>max-rows</replaceable>])</literal></term> - <term><literal><function>spi_query</>(<replaceable>command</replaceable>)</literal></term> - <term><literal><function>spi_fetchrow</>(<replaceable>cursor</replaceable>)</literal></term> - <term><literal><function>spi_prepare</>(<replaceable>command</replaceable>, <replaceable>argument types</replaceable>)</literal></term> - <term><literal><function>spi_exec_prepared</>(<replaceable>plan</replaceable>)</literal></term> - <term><literal><function>spi_query_prepared</>(<replaceable>plan</replaceable> [, <replaceable>attributes</replaceable>], <replaceable>arguments</replaceable>)</literal></term> - <term><literal><function>spi_cursor_close</>(<replaceable>cursor</replaceable>)</literal></term> - <term><literal><function>spi_freeplan</>(<replaceable>plan</replaceable>)</literal></term> - <listitem> <para> <literal>spi_exec_query</literal> executes an SQL command and @@ -399,7 +420,15 @@ $$ LANGUAGE plperl; SELECT * FROM test_munge(); </programlisting> </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal><function>spi_query</>(<replaceable>command</replaceable>)</literal></term> + <term><literal><function>spi_fetchrow</>(<replaceable>cursor</replaceable>)</literal></term> + <term><literal><function>spi_cursor_close</>(<replaceable>cursor</replaceable>)</literal></term> + + <listitem> <para> <literal>spi_query</literal> and <literal>spi_fetchrow</literal> work together as a pair for row sets which might be large, or for cases @@ -437,36 +466,64 @@ $$ LANGUAGE plperlu; SELECT * from lotsa_md5(500); </programlisting> </para> - + <para> - <literal>spi_prepare</literal>, <literal>spi_query_prepared</literal>, <literal>spi_exec_prepared</literal>, - and <literal>spi_freeplan</literal> implement the same functionality but for prepared queries. Once - a query plan is prepared by a call to <literal>spi_prepare</literal>, the plan can be used instead + Normally, <function>spi_fetchrow</> should be repeated until it + returns <literal>undef</literal>, indicating that there are no more + rows to read. The cursor returned by <literal>spi_query</literal> + is automatically freed when + <function>spi_fetchrow</> returns <literal>undef</literal>. + If you do not wish to read all the rows, instead call + <function>spi_cursor_close</> to free the cursor. + Failure to do so will result in memory leaks. + </para> + + </listitem> + </varlistentry> + + <varlistentry> + <term><literal><function>spi_prepare</>(<replaceable>command</replaceable>, <replaceable>argument types</replaceable>)</literal></term> + <term><literal><function>spi_query_prepared</>(<replaceable>plan</replaceable>, <replaceable>arguments</replaceable>)</literal></term> + <term><literal><function>spi_exec_prepared</>(<replaceable>plan</replaceable> [, <replaceable>attributes</replaceable>], <replaceable>arguments</replaceable>)</literal></term> + <term><literal><function>spi_freeplan</>(<replaceable>plan</replaceable>)</literal></term> + + <listitem> + <para> + <literal>spi_prepare</literal>, <literal>spi_query_prepared</literal>, <literal>spi_exec_prepared</literal>, + and <literal>spi_freeplan</literal> implement the same functionality but for prepared queries. + <literal>spi_prepare</literal> accepts a query string with numbered argument placeholders ($1, $2, etc) + and a string list of argument types: +<programlisting> +$plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', 'INTEGER', 'TEXT'); +</programlisting> + Once a query plan is prepared by a call to <literal>spi_prepare</literal>, the plan can be used instead of the string query, either in <literal>spi_exec_prepared</literal>, where the result is the same as returned by <literal>spi_exec_query</literal>, or in <literal>spi_query_prepared</literal> which returns a cursor exactly as <literal>spi_query</literal> does, which can be later passed to <literal>spi_fetchrow</literal>. + The optional second parameter to <literal>spi_exec_prepared</literal> is a hash reference of attributes; + the only attribute currently supported is <literal>limit</literal>, which sets the maximum number of rows returned by a query. </para> - + <para> The advantage of prepared queries is that is it possible to use one prepared plan for more - than one query execution. After the plan is not needed anymore, it can be freed with + than one query execution. After the plan is not needed anymore, it can be freed with <literal>spi_freeplan</literal>: </para> <para> <programlisting> -CREATE OR REPLACE FUNCTION init() RETURNS INTEGER AS $$ +CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ $_SHARED{my_plan} = spi_prepare( 'SELECT (now() + $1)::date AS now', 'INTERVAL'); $$ LANGUAGE plperl; CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$ - return spi_exec_prepared( + return spi_exec_prepared( $_SHARED{my_plan}, - $_[0], + $_[0] )->{rows}->[0]->{now}; $$ LANGUAGE plperl; -CREATE OR REPLACE FUNCTION done() RETURNS INTEGER AS $$ +CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$ spi_freeplan( $_SHARED{my_plan}); undef $_SHARED{my_plan}; $$ LANGUAGE plperl; @@ -475,7 +532,7 @@ SELECT init(); SELECT add_time('1 day'), add_time('2 days'), add_time('3 days'); SELECT done(); - add_time | add_time | add_time + add_time | add_time | add_time ------------+------------+------------ 2005-12-10 | 2005-12-11 | 2005-12-12 </programlisting> @@ -488,15 +545,42 @@ SELECT done(); </para> <para> - Normally, <function>spi_fetchrow</> should be repeated until it - returns <literal>undef</literal>, indicating that there are no more - rows to read. The cursor is automatically freed when - <function>spi_fetchrow</> returns <literal>undef</literal>. - If you do not wish to read all the rows, instead call - <function>spi_cursor_close</> to free the cursor. - Failure to do so will result in memory leaks. + Another example illustrates usage of an optional parameter in <literal>spi_exec_prepared</literal>: </para> - </listitem> + + <para> + <programlisting> +CREATE TABLE hosts AS SELECT id, ('192.168.1.'||id)::inet AS address FROM generate_series(1,3) AS id; + +CREATE OR REPLACE FUNCTION init_hosts_query() RETURNS VOID AS $$ + $_SHARED{plan} = spi_prepare('SELECT * FROM hosts WHERE address << $1', 'inet'); +$$ LANGUAGE plperl; + +CREATE OR REPLACE FUNCTION query_hosts(inet) RETURNS SETOF hosts AS $$ + return spi_exec_prepared( + $_SHARED{plan}, + {limit => 2}, + $_[0] + )->{rows}; +$$ LANGUAGE plperl; + +CREATE OR REPLACE FUNCTION release_hosts_query() RETURNS VOID AS $$ + spi_freeplan($_SHARED{plan}); + undef $_SHARED{plan}; +$$ LANGUAGE plperl; + +SELECT init_hosts_query(); +SELECT query_hosts('192.168.1.0/30'); +SELECT release_hosts_query(); + + query_hosts +----------------- + (1,192.168.1.1) + (2,192.168.1.2) +(2 rows) + </programlisting> + </para> + </listitem> </varlistentry> <varlistentry> @@ -528,7 +612,6 @@ SELECT done(); </listitem> </varlistentry> </variablelist> - </para> </sect1> <sect1 id="plperl-data"> |