From 65a0db19f48920d4be4607fca15634cf6b0a3d3b Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 5 Mar 2004 00:47:01 +0000 Subject: [PATCH] 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 --- doc/src/sgml/spi.sgml | 186 ++++++++++++++++++++++++++++++++++++- src/backend/executor/spi.c | 61 +++++++++++- 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 aab5b0dae1..a8ac6d67b8 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -1,5 +1,5 @@ @@ -573,6 +573,190 @@ void * SPI_prepare(const char * command, int n + + + SPI_getargcount + + + + SPI_getargcount + returns the number of arguments needed when executing a plan + prepared by SPI_prepare + + + SPI_getargcount + + + +int SPI_getargcount(void * plan) + + + + + Description + + + SPI_getargcount returns the number of arguments needed + when executing a plan prepared by SPI_prepare. + + + + + Arguments + + + + void * plan + + + execution plan (returned by SPI_prepare) + + + + + + + + Return Value + + The expected argument count for the plan or + SPI_ERROR_ARGUMENT if the plan + is NULL + + + + + + + + + SPI_getargtypeid + + + + SPI_getargtypeid + returns the expected typeid for the specified argument when + executing a plan prepared by SPI_prepare + + + SPI_getargtypeid + + + +Oid SPI_getargtypeid(void * plan, int argIndex) + + + + + Description + + + SPI_getargtypeid returns the Oid representing the type + id for argument at argIndex in a plan prepared by + SPI_prepare. First argument is at index zero. + + + + + Arguments + + + + void * plan + + + execution plan (returned by SPI_prepare) + + + + + + int argIndex + + + zero based index of the argument + + + + + + + + Return Value + + The type id of the argument at the given index or + SPI_ERROR_ARGUMENT if the plan is + NULL or argIndex is less than 0 or + not less than the number of arguments declared for the plan + + + + + + + + + + SPI_is_cursor_plan + + + + SPI_is_cursor_plan + returns true if a plan + prepared by SPI_prepare can be passed + as an argument to SPI_cursor_open + + + SPI_is_cursor_plan + + + +bool SPI_is_cursor_plan(void * plan) + + + + + Description + + + SPI_is_cursor_plan returns true + if a plan prepared by SPI_prepare can be passed + as an argument to SPI_cursor_open and + false if that is not the case. The criteria is that the + plan represents one single command and that this + command is a SELECT without an INTO + clause. + + + + + Arguments + + + + void * plan + + + execution plan (returned by SPI_prepare) + + + + + + + + Return Value + + true or false to indicate if the + plan can produce a cursor or not, or + SPI_ERROR_ARGUMENT if the plan + is NULL + + + + + + SPI_execp diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 5b4d92124d..128a063f3c 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 a6a6f97c52..6d0ce059a2 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, -- 2.40.0