diff options
-rw-r--r-- | doc/src/sgml/spi.sgml | 186 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 61 | ||||
-rw-r--r-- | src/include/executor/spi.h | 6 |
3 files changed, 250 insertions, 3 deletions
diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index aab5b0dae16..a8ac6d67b84 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.30 2003/12/01 22:07:57 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.31 2004/03/05 00:47:01 momjian Exp $ --> <chapter id="spi"> @@ -573,6 +573,190 @@ void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>n <!-- *********************************************** --> +<refentry id="spi-spi-getargcount"> + <refmeta> + <refentrytitle>SPI_getargcount</refentrytitle> + </refmeta> + + <refnamediv> + <refname>SPI_getargcount</refname> + <refpurpose>returns the number of arguments needed when executing a plan + prepared by <function>SPI_prepare</function></refpurpose> + </refnamediv> + + <indexterm><primary>SPI_getargcount</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +int SPI_getargcount(void * <parameter>plan</parameter>) +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <function>SPI_getargcount</function> returns the number of arguments needed + when executing a plan prepared by <function>SPI_prepare</function>. + </para> + </refsect1> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><literal>void * <parameter>plan</parameter></literal></term> + <listitem> + <para> + execution plan (returned by <function>SPI_prepare</function>) + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Return Value</title> + <para> + The expected argument count for the <parameter>plan</parameter> or + <symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan + </parameter> is <symbol>NULL</symbol> + </para> + </refsect1> +</refentry> + +<!-- *********************************************** --> + +<refentry id="spi-spi-getargtypeid"> + <refmeta> + <refentrytitle>SPI_getargtypeid</refentrytitle> + </refmeta> + + <refnamediv> + <refname>SPI_getargtypeid</refname> + <refpurpose>returns the expected typeid for the specified argument when + executing a plan prepared by <function>SPI_prepare</function></refpurpose> + </refnamediv> + + <indexterm><primary>SPI_getargtypeid</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex</parameter>) +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <function>SPI_getargtypeid</function> returns the Oid representing the type + id for argument at <parameter>argIndex</parameter> in a plan prepared by + <function>SPI_prepare</function>. First argument is at index zero. + </para> + </refsect1> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><literal>void * <parameter>plan</parameter></literal></term> + <listitem> + <para> + execution plan (returned by <function>SPI_prepare</function>) + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>int <parameter>argIndex</parameter></literal></term> + <listitem> + <para> + zero based index of the argument + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Return Value</title> + <para> + The type id of the argument at the given index or <symbol> + SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter> is + <symbol>NULL</symbol> or <parameter>argIndex</parameter> is less than 0 or + not less than the number of arguments declared for the <parameter>plan + </parameter> + </para> + </refsect1> +</refentry> + +<!-- *********************************************** --> + +<refentry id="spi-spi-is_cursor_plan"> + <refmeta> + <refentrytitle>SPI_is_cursor_plan</refentrytitle> + </refmeta> + + <refnamediv> + <refname>SPI_is_cursor_plan</refname> + <refpurpose>returns <symbol>true</symbol> if a plan + prepared by <function>SPI_prepare</function> can be passed + as an argument to <function>SPI_cursor_open</function></refpurpose> + </refnamediv> + + <indexterm><primary>SPI_is_cursor_plan</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +bool SPI_is_cursor_plan(void * <parameter>plan</parameter>) +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <function>SPI_is_cursor_plan</function> returns <symbol>true</symbol> + if a plan prepared by <function>SPI_prepare</function> can be passed + as an argument to <function>SPI_cursor_open</function> and <symbol> + false</symbol> if that is not the case. The criteria is that the + <parameter>plan</parameter> represents one single command and that this + command is a <command>SELECT</command> without an <command>INTO</command> + clause. + </para> + </refsect1> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><literal>void * <parameter>plan</parameter></literal></term> + <listitem> + <para> + execution plan (returned by <function>SPI_prepare</function>) + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Return Value</title> + <para> + <symbol>true</symbol> or <symbol>false</symbol> to indicate if the + <parameter>plan</parameter> can produce a cursor or not, or + <symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter> + is <symbol>NULL</symbol> + </para> + </refsect1> +</refentry> + +<!-- *********************************************** --> + <refentry id="spi-spi-execp"> <refmeta> <refentrytitle>SPI_execp</refentrytitle> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 5b4d92124d7..128a063f3c6 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.109 2003/12/02 19:26:47 joe Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.110 2004/03/05 00:47:01 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -918,6 +918,65 @@ SPI_cursor_close(Portal portal) PortalDrop(portal, false); } +/* + * Returns the Oid representing the type id for argument at argIndex. First + * parameter is at index zero. + */ +Oid +SPI_getargtypeid(void *plan, int argIndex) +{ + if (plan == NULL || argIndex < 0 || argIndex >= ((_SPI_plan*)plan)->nargs) + { + SPI_result = SPI_ERROR_ARGUMENT; + return InvalidOid; + } + return ((_SPI_plan *) plan)->argtypes[argIndex]; +} + +/* + * Returns the number of arguments for the prepared plan. + */ +int +SPI_getargcount(void *plan) +{ + if (plan == NULL) + { + SPI_result = SPI_ERROR_ARGUMENT; + return -1; + } + return ((_SPI_plan *) plan)->nargs; +} + +/* + * Returns true if the plan contains exactly one command + * and that command originates from normal SELECT (i.e. + * *not* a SELECT ... INTO). In essence, the result indicates + * if the command can be used with SPI_cursor_open + * + * Parameters + * plan A plan previously prepared using SPI_prepare + */ +bool +SPI_is_cursor_plan(void *plan) +{ + List *qtlist; + _SPI_plan *spiplan = (_SPI_plan *) plan; + if (spiplan == NULL) + { + SPI_result = SPI_ERROR_ARGUMENT; + return false; + } + + qtlist = spiplan->qtlist; + if(length(spiplan->ptlist) == 1 && length(qtlist) == 1) + { + Query *queryTree = (Query *) lfirst((List *) lfirst(qtlist)); + if(queryTree->commandType == CMD_SELECT && queryTree->into == NULL) + return true; + } + return false; +} + /* =================== private functions =================== */ /* diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index a6a6f97c526..6d0ce059a20 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -2,7 +2,7 @@ * * spi.h * - * $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.41 2003/12/02 19:26:47 joe Exp $ + * $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.42 2004/03/05 00:47:01 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -90,6 +90,10 @@ extern void *SPI_prepare(const char *src, int nargs, Oid *argtypes); extern void *SPI_saveplan(void *plan); extern int SPI_freeplan(void *plan); +extern Oid SPI_getargtypeid(void *plan, int argIndex); +extern int SPI_getargcount(void *plan); +extern bool SPI_is_cursor_plan(void *plan); + extern HeapTuple SPI_copytuple(HeapTuple tuple); extern TupleDesc SPI_copytupledesc(TupleDesc tupdesc); extern TupleTableSlot *SPI_copytupleintoslot(HeapTuple tuple, |