diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-04-16 01:14:58 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-04-16 01:14:58 +0000 |
commit | 66888f7424f7d6c7cea2c26e181054d1455d4e7a (patch) | |
tree | d7224be67b7a912f5d65315afb1c121622373a0a /src/backend/executor | |
parent | fa92d21a486de868b21bbc03944649af3e1ac90f (diff) | |
download | postgresql-66888f7424f7d6c7cea2c26e181054d1455d4e7a.tar.gz postgresql-66888f7424f7d6c7cea2c26e181054d1455d4e7a.zip |
Expose more cursor-related functionality in SPI: specifically, allow
access to the planner's cursor-related planning options, and provide new
FETCH/MOVE routines that allow access to the full power of those commands.
Small refactoring of planner(), pg_plan_query(), and pg_plan_queries()
APIs to make it convenient to pass the planning options down from SPI.
This is the core-code portion of Pavel Stehule's patch for scrollable
cursor support in plpgsql; I'll review and apply the plpgsql changes
separately.
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/functions.c | 4 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 63 |
2 files changed, 53 insertions, 14 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 1e1d450be57..b59228b0c9e 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.114 2007/04/02 18:49:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.115 2007/04/16 01:14:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -115,7 +115,7 @@ init_execution_state(List *queryTree_list, bool readonly_func) if (queryTree->commandType == CMD_UTILITY) stmt = queryTree->utilityStmt; else - stmt = (Node *) pg_plan_query(queryTree, NULL); + stmt = (Node *) pg_plan_query(queryTree, 0, NULL); /* Precheck all commands for validity in a function */ if (IsA(stmt, TransactionStmt)) diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 655503cd708..bf3bbdbceb3 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.175 2007/03/25 23:42:43 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.176 2007/04/16 01:14:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,8 @@ static int _SPI_stack_depth = 0; /* allocated size of _SPI_stack */ static int _SPI_connected = -1; static int _SPI_curid = -1; -static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan); +static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan, + int cursorOptions); static int _SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, @@ -45,8 +46,9 @@ static int _SPI_pquery(QueryDesc *queryDesc, long tcount); static void _SPI_error_callback(void *arg); -static void _SPI_cursor_operation(Portal portal, bool forward, long count, - DestReceiver *dest); +static void _SPI_cursor_operation(Portal portal, + FetchDirection direction, long count, + DestReceiver *dest); static SPIPlanPtr _SPI_copy_plan(SPIPlanPtr plan, MemoryContext parentcxt); static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan); @@ -310,7 +312,7 @@ SPI_execute(const char *src, bool read_only, long tcount) memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; - _SPI_prepare_plan(src, &plan); + _SPI_prepare_plan(src, &plan, 0); res = _SPI_execute_plan(&plan, NULL, NULL, InvalidSnapshot, InvalidSnapshot, @@ -399,6 +401,13 @@ SPI_execute_snapshot(SPIPlanPtr plan, SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes) { + return SPI_prepare_cursor(src, nargs, argtypes, 0); +} + +SPIPlanPtr +SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes, + int cursorOptions) +{ _SPI_plan plan; SPIPlanPtr result; @@ -417,7 +426,7 @@ SPI_prepare(const char *src, int nargs, Oid *argtypes) plan.nargs = nargs; plan.argtypes = argtypes; - _SPI_prepare_plan(src, &plan); + _SPI_prepare_plan(src, &plan, cursorOptions); /* copy plan to procedure context */ result = _SPI_copy_plan(&plan, _SPI_current->procCxt); @@ -1032,7 +1041,8 @@ SPI_cursor_find(const char *name) void SPI_cursor_fetch(Portal portal, bool forward, long count) { - _SPI_cursor_operation(portal, forward, count, + _SPI_cursor_operation(portal, + forward ? FETCH_FORWARD : FETCH_BACKWARD, count, CreateDestReceiver(DestSPI, NULL)); /* we know that the DestSPI receiver doesn't need a destroy call */ } @@ -1046,7 +1056,36 @@ SPI_cursor_fetch(Portal portal, bool forward, long count) void SPI_cursor_move(Portal portal, bool forward, long count) { - _SPI_cursor_operation(portal, forward, count, None_Receiver); + _SPI_cursor_operation(portal, + forward ? FETCH_FORWARD : FETCH_BACKWARD, count, + None_Receiver); +} + + +/* + * SPI_scroll_cursor_fetch() + * + * Fetch rows in a scrollable cursor + */ +void +SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, long count) +{ + _SPI_cursor_operation(portal, + direction, count, + CreateDestReceiver(DestSPI, NULL)); + /* we know that the DestSPI receiver doesn't need a destroy call */ +} + + +/* + * SPI_scroll_cursor_move() + * + * Move in a scrollable cursor + */ +void +SPI_scroll_cursor_move(Portal portal, FetchDirection direction, long count) +{ + _SPI_cursor_operation(portal, direction, count, None_Receiver); } @@ -1299,7 +1338,7 @@ spi_printtup(TupleTableSlot *slot, DestReceiver *self) * and need to be copied somewhere to survive. */ static void -_SPI_prepare_plan(const char *src, SPIPlanPtr plan) +_SPI_prepare_plan(const char *src, SPIPlanPtr plan, int cursorOptions) { List *raw_parsetree_list; List *plancache_list; @@ -1345,7 +1384,7 @@ _SPI_prepare_plan(const char *src, SPIPlanPtr plan) /* Need a copyObject here to keep parser from modifying raw tree */ stmt_list = pg_analyze_and_rewrite(copyObject(parsetree), src, argtypes, nargs); - stmt_list = pg_plan_queries(stmt_list, NULL, false); + stmt_list = pg_plan_queries(stmt_list, cursorOptions, NULL, false); plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource)); cplan = (CachedPlan *) palloc0(sizeof(CachedPlan)); @@ -1739,7 +1778,7 @@ _SPI_error_callback(void *arg) * Do a FETCH or MOVE in a cursor */ static void -_SPI_cursor_operation(Portal portal, bool forward, long count, +_SPI_cursor_operation(Portal portal, FetchDirection direction, long count, DestReceiver *dest) { long nfetched; @@ -1760,7 +1799,7 @@ _SPI_cursor_operation(Portal portal, bool forward, long count, /* Run the cursor */ nfetched = PortalRunFetch(portal, - forward ? FETCH_FORWARD : FETCH_BACKWARD, + direction, count, dest); |