Index: doc/src/sgml/spi.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/spi.sgml,v retrieving revision 1.35 diff -u -r1.35 spi.sgml --- doc/src/sgml/spi.sgml 13 Sep 2004 20:05:25 -0000 1.35 +++ doc/src/sgml/spi.sgml 1 Dec 2004 19:05:28 -0000 @@ -1305,6 +1305,82 @@ + + + SPI_iterate_query_roots + + + + SPI_iterate_query_roots + investigate the semantics of a query + + + SPI_iterate_query_roots + + + +bool SPI_iterate_query_roots(void * plan, QueryVisitor callback, void * clientData) + + + + + Description + + + The SPI_iterate_query_roots will invoke the + queryVisitor callback once for each top level + Query found in the supplied execution plan. + The iteration is cancelled when a callback returns false. + If no callback returns false, or if the plan is + NULL, the function returns true. + + + + + Arguments + + + + void * plan + + + execution plan (returned by SPI_prepare) + + + + + + QueryVisitor callback + + + the callback to invoke for each query found + + + + + + void * clientData + + + user defined data that will be passed on to the callback + + + + + + + + Return Value + + true when all callbacks returned true or + false when a callback returned false and + thus terminated the iteration. + + + + + + SPI_cursor_find Index: src/backend/executor/spi.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/executor/spi.c,v retrieving revision 1.132 diff -u -r1.132 spi.c --- src/backend/executor/spi.c 16 Nov 2004 18:10:13 -0000 1.132 +++ src/backend/executor/spi.c 1 Dec 2004 19:05:29 -0000 @@ -1064,6 +1064,42 @@ return false; } +/** + * Invokes the queryVisitor callback for each top level Query found in an + * execution plan. The iteration is cancelled when a callback returns + * false. If no callbacks returns false, or if the plan is NULL, this + * function returns true. + * + * Arguments: + * plan An ExecutionPlan created by SPI_prepare + * queryVisitor The callback function + * clientData User defined data that will be passed on to the callback + * Returns: true if the plan is NULL or if all callback invocation returns true + */ +bool +SPI_iterate_query_roots(void *plan, QueryVisitor queryVisitor, void *clientData) +{ + _SPI_plan *spiplan = (_SPI_plan *) plan; + + if (spiplan != NULL) + { + ListCell *query_list_list_item; + List *query_list_list = spiplan->qtlist; + foreach(query_list_list_item, query_list_list) + { + List *query_list = lfirst(query_list_list_item); + ListCell *query_list_item; + + foreach(query_list_item, query_list) + { + if(!queryVisitor((Query *)lfirst(query_list_item), clientData)) + return false; + } + } + } + return true; +} + /* * SPI_result_code_string --- convert any SPI return code to a string * Index: src/include/executor/spi.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/executor/spi.h,v retrieving revision 1.50 diff -u -r1.50 spi.h --- src/include/executor/spi.h 16 Nov 2004 18:10:13 -0000 1.50 +++ src/include/executor/spi.h 1 Dec 2004 19:05:30 -0000 @@ -119,6 +119,9 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); +typedef bool (*QueryVisitor)(Query* query, void *clientData); +extern bool SPI_iterate_query_roots(void *plan, QueryVisitor queryVisitor, void* clientData); + extern Portal SPI_cursor_open(const char *name, void *plan, Datum *Values, const char *Nulls, bool read_only); extern Portal SPI_cursor_find(const char *name);