diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-05-12 20:10:05 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-05-12 20:10:05 +0000 |
commit | f9e4f611a18f64fd9106a72ec9af9e2220075780 (patch) | |
tree | bfbc1d3d9fb5a008d8fe3405dce3366659c7e7cc /src/backend/executor/functions.c | |
parent | 71009354c848964e657e540e24dac6b4c9a81570 (diff) | |
download | postgresql-f9e4f611a18f64fd9106a72ec9af9e2220075780.tar.gz postgresql-f9e4f611a18f64fd9106a72ec9af9e2220075780.zip |
First pass at set-returning-functions in FROM, by Joe Conway with
some kibitzing from Tom Lane. Not everything works yet, and there's
no documentation or regression test, but let's commit this so Joe
doesn't need to cope with tracking changes in so many files ...
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r-- | src/backend/executor/functions.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 885d93a2aff..938f7e17f93 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.49 2002/02/27 19:34:51 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.50 2002/05/12 20:10:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,7 +28,7 @@ /* - * We have an execution_state record for each query in the function. + * We have an execution_state record for each query in a function. */ typedef enum { @@ -56,6 +56,7 @@ typedef struct int typlen; /* length of the return type */ bool typbyval; /* true if return type is pass by value */ bool returnsTuple; /* true if return type is a tuple */ + bool shutdown_reg; /* true if registered shutdown callback */ TupleTableSlot *funcSlot; /* if one result we need to copy it before * we end execution of the function and @@ -79,6 +80,7 @@ static void postquel_sub_params(execution_state *es, FunctionCallInfo fcinfo); static Datum postquel_execute(execution_state *es, FunctionCallInfo fcinfo, SQLFunctionCachePtr fcache); +static void ShutdownSQLFunction(Datum arg); static execution_state * @@ -546,6 +548,15 @@ fmgr_sql(PG_FUNCTION_ARGS) elog(ERROR, "Set-valued function called in context that cannot accept a set"); fcinfo->isnull = true; result = (Datum) 0; + + /* Deregister shutdown callback, if we made one */ + if (fcache->shutdown_reg) + { + UnregisterExprContextCallback(rsi->econtext, + ShutdownSQLFunction, + PointerGetDatum(fcache)); + fcache->shutdown_reg = false; + } } MemoryContextSwitchTo(oldcontext); @@ -570,9 +581,45 @@ fmgr_sql(PG_FUNCTION_ARGS) rsi->isDone = ExprMultipleResult; else elog(ERROR, "Set-valued function called in context that cannot accept a set"); + + /* + * Ensure we will get shut down cleanly if the exprcontext is + * not run to completion. + */ + if (!fcache->shutdown_reg) + { + RegisterExprContextCallback(rsi->econtext, + ShutdownSQLFunction, + PointerGetDatum(fcache)); + fcache->shutdown_reg = true; + } } MemoryContextSwitchTo(oldcontext); return result; } + +/* + * callback function in case a function-returning-set needs to be shut down + * before it has been run to completion + */ +static void +ShutdownSQLFunction(Datum arg) +{ + SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) DatumGetPointer(arg); + execution_state *es = fcache->func_state; + + while (es != NULL) + { + /* Shut down anything still running */ + if (es->status == F_EXEC_RUN) + postquel_end(es); + /* Reset states to START in case we're called again */ + es->status = F_EXEC_START; + es = es->next; + } + + /* execUtils will deregister the callback... */ + fcache->shutdown_reg = false; +} |