diff options
| author | Tom Lane | 2009-11-04 22:26:08 +0000 |
|---|---|---|
| committer | Tom Lane | 2009-11-04 22:26:08 +0000 |
| commit | 9bedd128d6ed83798004b3c7ddc33f33703ccf23 (patch) | |
| tree | 95a475a5da180f19c69b5bcf2f6e764b1bc69ea7 /doc | |
| parent | 48912acc089a6148529f12ab0a75b1bf026f231d (diff) | |
Add support for invoking parser callback hooks via SPI and in cached plans.
As proof of concept, modify plpgsql to use the hooks. plpgsql is still
inserting $n symbols textually, but the "back end" of the parsing process now
goes through the ParamRef hook instead of using a fixed parameter-type array,
and then execution only fetches actually-referenced parameters, using a hook
added to ParamListInfo.
Although there's a lot left to be done in plpgsql, this already cures the
"if (TG_OP = 'INSERT' and NEW.foo ...)" problem, as illustrated by the
changed regression test.
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/src/sgml/spi.sgml | 290 |
1 files changed, 281 insertions, 9 deletions
diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index 07fab82badc..8d40c60c8e7 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.65 2009/08/05 19:31:50 alvherre Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.66 2009/11/04 22:26:04 tgl Exp $ --> <chapter id="spi"> <title>Server Programming Interface</title> @@ -861,7 +861,7 @@ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <paramet <para> <function>SPI_prepare</function> creates and returns an execution - plan for the specified command but doesn't execute the command. + plan for the specified command, but doesn't execute the command. This function should only be called from a connected procedure. </para> @@ -990,7 +990,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * <parameter>command</parameter>, int < of the planner's <quote>cursor options</> parameter. This is a bitmask having the values shown in <filename>nodes/parsenodes.h</filename> for the <structfield>options</> field of <structname>DeclareCursorStmt</>. - <function>SPI_prepare</function> always takes these options as zero. + <function>SPI_prepare</function> always takes the cursor options as zero. </para> </refsect1> @@ -1061,6 +1061,94 @@ SPIPlanPtr SPI_prepare_cursor(const char * <parameter>command</parameter>, int < <!-- *********************************************** --> +<refentry id="spi-spi-prepare-params"> + <refmeta> + <refentrytitle>SPI_prepare_params</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>SPI_prepare_params</refname> + <refpurpose>prepare a plan for a command, without executing it yet</refpurpose> + </refnamediv> + + <indexterm><primary>SPI_prepare_params</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +SPIPlanPtr SPI_prepare_params(const char * <parameter>command</parameter>, + ParserSetupHook <parameter>parserSetup</parameter>, + void * <parameter>parserSetupArg</parameter>, + int <parameter>cursorOptions</parameter>) +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <function>SPI_prepare_params</function> creates and returns an execution + plan for the specified command, but doesn't execute the command. + This function is equivalent to <function>SPI_prepare_cursor</function>, + with the addition that the caller can specify parser hook functions + to control the parsing of external parameter references. + </para> + </refsect1> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><literal>const char * <parameter>command</parameter></literal></term> + <listitem> + <para> + command string + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>ParserSetupHook <parameter>parserSetup</parameter></literal></term> + <listitem> + <para> + Parser hook setup function + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>void * <parameter>parserSetupArg</parameter></literal></term> + <listitem> + <para> + passthrough argument for <parameter>parserSetup</parameter> + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>int <parameter>cursorOptions</parameter></literal></term> + <listitem> + <para> + integer bitmask of cursor options; zero produces default behavior + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para> + <function>SPI_prepare_params</function> has the same return conventions as + <function>SPI_prepare</function>. + </para> + </refsect1> +</refentry> + +<!-- *********************************************** --> + <refentry id="spi-spi-getargcount"> <refmeta> <refentrytitle>SPI_getargcount</refentrytitle> @@ -1386,14 +1474,100 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> <function>SPI_execute</function> if successful. </para> </refsect1> +</refentry> + +<!-- *********************************************** --> + +<refentry id="spi-spi-execute-plan-with-paramlist"> + <refmeta> + <refentrytitle>SPI_execute_plan_with_paramlist</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>SPI_execute_plan_with_paramlist</refname> + <refpurpose>execute a plan prepared by <function>SPI_prepare</function></refpurpose> + </refnamediv> + + <indexterm><primary>SPI_execute_plan_with_paramlist</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +int SPI_execute_plan_with_paramlist(SPIPlanPtr <parameter>plan</parameter>, + ParamListInfo <parameter>params</parameter>, + bool <parameter>read_only</parameter>, + long <parameter>count</parameter>) +</synopsis> + </refsynopsisdiv> <refsect1> - <title>Notes</title> + <title>Description</title> <para> - If one of the objects (a table, function, etc.) referenced by the - prepared plan is dropped during the session then the result of - <function>SPI_execute_plan</function> for this plan will be unpredictable. + <function>SPI_execute_plan_with_paramlist</function> executes a plan + prepared by <function>SPI_prepare</function>. + This function is equivalent to <function>SPI_execute_plan</function> + except that information about the parameter values to be passed to the + query is presented differently. The <literal>ParamListInfo</> + representation can be convenient for passing down values that are + already available in that format. It also supports use of dynamic + parameter sets via hook functions specified in <literal>ParamListInfo</>. + </para> + </refsect1> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term> + <listitem> + <para> + execution plan (returned by <function>SPI_prepare</function>) + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>ParamListInfo <parameter>params</parameter></literal></term> + <listitem> + <para> + data structure containing parameter types and values; NULL if none + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>bool <parameter>read_only</parameter></literal></term> + <listitem> + <para> + <literal>true</> for read-only execution + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>long <parameter>count</parameter></literal></term> + <listitem> + <para> + maximum number of rows to process or return + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para> + The return value is the same as for <function>SPI_execute_plan</function>. + </para> + + <para> + <varname>SPI_processed</varname> and + <varname>SPI_tuptable</varname> are set as in + <function>SPI_execute_plan</function> if successful. </para> </refsect1> </refentry> @@ -1543,7 +1717,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </para> <para> - The passed-in data will be copied into the cursor's portal, so it + The passed-in parameter data will be copied into the cursor's portal, so it can be freed while the cursor still exists. </para> </refsect1> @@ -1667,7 +1841,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </para> <para> - The passed-in data will be copied into the cursor's portal, so it + The passed-in parameter data will be copied into the cursor's portal, so it can be freed while the cursor still exists. </para> </refsect1> @@ -1770,6 +1944,104 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, <!-- *********************************************** --> +<refentry id="spi-spi-cursor-open-with-paramlist"> + <refmeta> + <refentrytitle>SPI_cursor_open_with_paramlist</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>SPI_cursor_open_with_paramlist</refname> + <refpurpose>set up a cursor using parameters</refpurpose> + </refnamediv> + + <indexterm><primary>SPI_cursor_open_with_paramlist</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +Portal SPI_cursor_open_with_paramlist(const char *<parameter>name</parameter>, + SPIPlanPtr <parameter>plan</parameter>, + ParamListInfo <parameter>params</parameter>, + bool <parameter>read_only</parameter>) +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <function>SPI_cursor_open_with_paramlist</function> sets up a cursor + (internally, a portal) that will execute a plan prepared by + <function>SPI_prepare</function>. + This function is equivalent to <function>SPI_cursor_open</function> + except that information about the parameter values to be passed to the + query is presented differently. The <literal>ParamListInfo</> + representation can be convenient for passing down values that are + already available in that format. It also supports use of dynamic + parameter sets via hook functions specified in <literal>ParamListInfo</>. + </para> + + <para> + The passed-in parameter data will be copied into the cursor's portal, so it + can be freed while the cursor still exists. + </para> + </refsect1> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><literal>const char * <parameter>name</parameter></literal></term> + <listitem> + <para> + name for portal, or <symbol>NULL</symbol> to let the system + select a name + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term> + <listitem> + <para> + execution plan (returned by <function>SPI_prepare</function>) + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>ParamListInfo <parameter>params</parameter></literal></term> + <listitem> + <para> + data structure containing parameter types and values; NULL if none + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>bool <parameter>read_only</parameter></literal></term> + <listitem> + <para> + <literal>true</> for read-only execution + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para> + Pointer to portal containing the cursor. Note there is no error + return convention; any error will be reported via <function>elog</>. + </para> + </refsect1> +</refentry> + +<!-- *********************************************** --> + <refentry id="spi-spi-cursor-find"> <refmeta> <refentrytitle>SPI_cursor_find</refentrytitle> |
