Skip to content

Commit 65a0db1

Browse files
committed
Add new SPI functions for use by PL/Java:
+extern Oid SPI_getargtypeid(void *plan, int argIndex); +extern int SPI_getargcount(void *plan); +extern bool SPI_is_cursor_plan(void *plan); Thomas Hallgren
1 parent 202cbdc commit 65a0db1

File tree

3 files changed

+250
-3
lines changed

3 files changed

+250
-3
lines changed

doc/src/sgml/spi.sgml

Lines changed: 185 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.30 2003/12/01 22:07:57 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.31 2004/03/05 00:47:01 momjian Exp $
33
-->
44

55
<chapter id="spi">
@@ -573,6 +573,190 @@ void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>n
573573

574574
<!-- *********************************************** -->
575575

576+
<refentry id="spi-spi-getargcount">
577+
<refmeta>
578+
<refentrytitle>SPI_getargcount</refentrytitle>
579+
</refmeta>
580+
581+
<refnamediv>
582+
<refname>SPI_getargcount</refname>
583+
<refpurpose>returns the number of arguments needed when executing a plan
584+
prepared by <function>SPI_prepare</function></refpurpose>
585+
</refnamediv>
586+
587+
<indexterm><primary>SPI_getargcount</primary></indexterm>
588+
589+
<refsynopsisdiv>
590+
<synopsis>
591+
int SPI_getargcount(void * <parameter>plan</parameter>)
592+
</synopsis>
593+
</refsynopsisdiv>
594+
595+
<refsect1>
596+
<title>Description</title>
597+
598+
<para>
599+
<function>SPI_getargcount</function> returns the number of arguments needed
600+
when executing a plan prepared by <function>SPI_prepare</function>.
601+
</para>
602+
</refsect1>
603+
604+
<refsect1>
605+
<title>Arguments</title>
606+
607+
<variablelist>
608+
<varlistentry>
609+
<term><literal>void * <parameter>plan</parameter></literal></term>
610+
<listitem>
611+
<para>
612+
execution plan (returned by <function>SPI_prepare</function>)
613+
</para>
614+
</listitem>
615+
</varlistentry>
616+
</variablelist>
617+
</refsect1>
618+
619+
<refsect1>
620+
<title>Return Value</title>
621+
<para>
622+
The expected argument count for the <parameter>plan</parameter> or
623+
<symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan
624+
</parameter> is <symbol>NULL</symbol>
625+
</para>
626+
</refsect1>
627+
</refentry>
628+
629+
<!-- *********************************************** -->
630+
631+
<refentry id="spi-spi-getargtypeid">
632+
<refmeta>
633+
<refentrytitle>SPI_getargtypeid</refentrytitle>
634+
</refmeta>
635+
636+
<refnamediv>
637+
<refname>SPI_getargtypeid</refname>
638+
<refpurpose>returns the expected typeid for the specified argument when
639+
executing a plan prepared by <function>SPI_prepare</function></refpurpose>
640+
</refnamediv>
641+
642+
<indexterm><primary>SPI_getargtypeid</primary></indexterm>
643+
644+
<refsynopsisdiv>
645+
<synopsis>
646+
Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex</parameter>)
647+
</synopsis>
648+
</refsynopsisdiv>
649+
650+
<refsect1>
651+
<title>Description</title>
652+
653+
<para>
654+
<function>SPI_getargtypeid</function> returns the Oid representing the type
655+
id for argument at <parameter>argIndex</parameter> in a plan prepared by
656+
<function>SPI_prepare</function>. First argument is at index zero.
657+
</para>
658+
</refsect1>
659+
660+
<refsect1>
661+
<title>Arguments</title>
662+
663+
<variablelist>
664+
<varlistentry>
665+
<term><literal>void * <parameter>plan</parameter></literal></term>
666+
<listitem>
667+
<para>
668+
execution plan (returned by <function>SPI_prepare</function>)
669+
</para>
670+
</listitem>
671+
</varlistentry>
672+
673+
<varlistentry>
674+
<term><literal>int <parameter>argIndex</parameter></literal></term>
675+
<listitem>
676+
<para>
677+
zero based index of the argument
678+
</para>
679+
</listitem>
680+
</varlistentry>
681+
</variablelist>
682+
</refsect1>
683+
684+
<refsect1>
685+
<title>Return Value</title>
686+
<para>
687+
The type id of the argument at the given index or <symbol>
688+
SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter> is
689+
<symbol>NULL</symbol> or <parameter>argIndex</parameter> is less than 0 or
690+
not less than the number of arguments declared for the <parameter>plan
691+
</parameter>
692+
</para>
693+
</refsect1>
694+
</refentry>
695+
696+
<!-- *********************************************** -->
697+
698+
<refentry id="spi-spi-is_cursor_plan">
699+
<refmeta>
700+
<refentrytitle>SPI_is_cursor_plan</refentrytitle>
701+
</refmeta>
702+
703+
<refnamediv>
704+
<refname>SPI_is_cursor_plan</refname>
705+
<refpurpose>returns <symbol>true</symbol> if a plan
706+
prepared by <function>SPI_prepare</function> can be passed
707+
as an argument to <function>SPI_cursor_open</function></refpurpose>
708+
</refnamediv>
709+
710+
<indexterm><primary>SPI_is_cursor_plan</primary></indexterm>
711+
712+
<refsynopsisdiv>
713+
<synopsis>
714+
bool SPI_is_cursor_plan(void * <parameter>plan</parameter>)
715+
</synopsis>
716+
</refsynopsisdiv>
717+
718+
<refsect1>
719+
<title>Description</title>
720+
721+
<para>
722+
<function>SPI_is_cursor_plan</function> returns <symbol>true</symbol>
723+
if a plan prepared by <function>SPI_prepare</function> can be passed
724+
as an argument to <function>SPI_cursor_open</function> and <symbol>
725+
false</symbol> if that is not the case. The criteria is that the
726+
<parameter>plan</parameter> represents one single command and that this
727+
command is a <command>SELECT</command> without an <command>INTO</command>
728+
clause.
729+
</para>
730+
</refsect1>
731+
732+
<refsect1>
733+
<title>Arguments</title>
734+
735+
<variablelist>
736+
<varlistentry>
737+
<term><literal>void * <parameter>plan</parameter></literal></term>
738+
<listitem>
739+
<para>
740+
execution plan (returned by <function>SPI_prepare</function>)
741+
</para>
742+
</listitem>
743+
</varlistentry>
744+
</variablelist>
745+
</refsect1>
746+
747+
<refsect1>
748+
<title>Return Value</title>
749+
<para>
750+
<symbol>true</symbol> or <symbol>false</symbol> to indicate if the
751+
<parameter>plan</parameter> can produce a cursor or not, or
752+
<symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter>
753+
is <symbol>NULL</symbol>
754+
</para>
755+
</refsect1>
756+
</refentry>
757+
758+
<!-- *********************************************** -->
759+
576760
<refentry id="spi-spi-execp">
577761
<refmeta>
578762
<refentrytitle>SPI_execp</refentrytitle>

src/backend/executor/spi.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.109 2003/12/02 19:26:47 joe Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.110 2004/03/05 00:47:01 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -918,6 +918,65 @@ SPI_cursor_close(Portal portal)
918918
PortalDrop(portal, false);
919919
}
920920

921+
/*
922+
* Returns the Oid representing the type id for argument at argIndex. First
923+
* parameter is at index zero.
924+
*/
925+
Oid
926+
SPI_getargtypeid(void *plan, int argIndex)
927+
{
928+
if (plan == NULL || argIndex < 0 || argIndex >= ((_SPI_plan*)plan)->nargs)
929+
{
930+
SPI_result = SPI_ERROR_ARGUMENT;
931+
return InvalidOid;
932+
}
933+
return ((_SPI_plan *) plan)->argtypes[argIndex];
934+
}
935+
936+
/*
937+
* Returns the number of arguments for the prepared plan.
938+
*/
939+
int
940+
SPI_getargcount(void *plan)
941+
{
942+
if (plan == NULL)
943+
{
944+
SPI_result = SPI_ERROR_ARGUMENT;
945+
return -1;
946+
}
947+
return ((_SPI_plan *) plan)->nargs;
948+
}
949+
950+
/*
951+
* Returns true if the plan contains exactly one command
952+
* and that command originates from normal SELECT (i.e.
953+
* *not* a SELECT ... INTO). In essence, the result indicates
954+
* if the command can be used with SPI_cursor_open
955+
*
956+
* Parameters
957+
* plan A plan previously prepared using SPI_prepare
958+
*/
959+
bool
960+
SPI_is_cursor_plan(void *plan)
961+
{
962+
List *qtlist;
963+
_SPI_plan *spiplan = (_SPI_plan *) plan;
964+
if (spiplan == NULL)
965+
{
966+
SPI_result = SPI_ERROR_ARGUMENT;
967+
return false;
968+
}
969+
970+
qtlist = spiplan->qtlist;
971+
if(length(spiplan->ptlist) == 1 && length(qtlist) == 1)
972+
{
973+
Query *queryTree = (Query *) lfirst((List *) lfirst(qtlist));
974+
if(queryTree->commandType == CMD_SELECT && queryTree->into == NULL)
975+
return true;
976+
}
977+
return false;
978+
}
979+
921980
/* =================== private functions =================== */
922981

923982
/*

src/include/executor/spi.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*
33
* spi.h
44
*
5-
* $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.41 2003/12/02 19:26:47 joe Exp $
5+
* $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.42 2004/03/05 00:47:01 momjian Exp $
66
*
77
*-------------------------------------------------------------------------
88
*/
@@ -90,6 +90,10 @@ extern void *SPI_prepare(const char *src, int nargs, Oid *argtypes);
9090
extern void *SPI_saveplan(void *plan);
9191
extern int SPI_freeplan(void *plan);
9292

93+
extern Oid SPI_getargtypeid(void *plan, int argIndex);
94+
extern int SPI_getargcount(void *plan);
95+
extern bool SPI_is_cursor_plan(void *plan);
96+
9397
extern HeapTuple SPI_copytuple(HeapTuple tuple);
9498
extern TupleDesc SPI_copytupledesc(TupleDesc tupdesc);
9599
extern TupleTableSlot *SPI_copytupleintoslot(HeapTuple tuple,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy