diff options
author | Tom Lane | 2002-05-12 23:43:04 +0000 |
---|---|---|
committer | Tom Lane | 2002-05-12 23:43:04 +0000 |
commit | 3389a110d40a505951e7c7babdfb8681173bb2ca (patch) | |
tree | 438acebac5cfd161cf920bcda6ad168affcb96a7 /src/backend/executor/execFlatten.c | |
parent | f9e4f611a18f64fd9106a72ec9af9e2220075780 (diff) |
Get rid of long-since-vestigial Iter node type, in favor of adding a
returns-set boolean field in Func and Oper nodes. This allows cleaner,
more reliable tests for expressions returning sets in the planner and
parser. For example, a WHERE clause returning a set is now detected
and complained of in the parser, not only at runtime.
Diffstat (limited to 'src/backend/executor/execFlatten.c')
-rw-r--r-- | src/backend/executor/execFlatten.c | 243 |
1 files changed, 0 insertions, 243 deletions
diff --git a/src/backend/executor/execFlatten.c b/src/backend/executor/execFlatten.c deleted file mode 100644 index ecbe7b5d189..00000000000 --- a/src/backend/executor/execFlatten.c +++ /dev/null @@ -1,243 +0,0 @@ -/*------------------------------------------------------------------------- - * - * execFlatten.c - * This file handles the nodes associated with flattening sets in the - * target list of queries containing functions returning sets. - * - * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/Attic/execFlatten.c,v 1.16 2001/10/28 06:25:43 momjian Exp $ - * - *------------------------------------------------------------------------- - */ - -/* - * ExecEvalIter() - - * Iterate through the all return tuples/base types from a function one - * at time (i.e. one per ExecEvalIter call). Not really needed for - * postquel functions, but for reasons of orthogonality, these nodes - * exist above pq functions as well as c functions. - * - * ExecEvalFjoin() - - * Given N Iter nodes return a vector of all combinations of results - * one at a time (i.e. one result vector per ExecEvalFjoin call). This - * node does the actual flattening work. - */ -#include "postgres.h" -#include "executor/execFlatten.h" -#include "executor/executor.h" - -#ifdef SETS_FIXED -static bool FjoinBumpOuterNodes(TargetEntry *tlist, ExprContext *econtext, - DatumPtr results, char *nulls); -#endif - - -Datum -ExecEvalIter(Iter *iterNode, - ExprContext *econtext, - bool *isNull, - ExprDoneCond *isDone) -{ - Node *expression; - - expression = iterNode->iterexpr; - - /* - * Really Iter nodes are only needed for C functions, postquel - * function by their nature return 1 result at a time. For now we are - * only worrying about postquel functions, c functions will come - * later. - */ - return ExecEvalExpr(expression, econtext, isNull, isDone); -} - -void -ExecEvalFjoin(TargetEntry *tlist, - ExprContext *econtext, - bool *isNullVect, - ExprDoneCond *fj_isDone) -{ - -#ifdef SETS_FIXED - bool isDone; - int curNode; - List *tlistP; - - Fjoin *fjNode = tlist->fjoin; - DatumPtr resVect = fjNode->fj_results; - BoolPtr alwaysDone = fjNode->fj_alwaysDone; - - if (fj_isDone) - *fj_isDone = ExprMultipleResult; - - /* - * For the next tuple produced by the plan, we need to re-initialize - * the Fjoin node. - */ - if (!fjNode->fj_initialized) - { - /* - * Initialize all of the Outer nodes - */ - curNode = 1; - foreach(tlistP, lnext(tlist)) - { - TargetEntry *tle = lfirst(tlistP); - - resVect[curNode] = ExecEvalIter((Iter *) tle->expr, - econtext, - &isNullVect[curNode], - &isDone); - if (isDone) - isNullVect[curNode] = alwaysDone[curNode] = true; - else - alwaysDone[curNode] = false; - - curNode++; - } - - /* - * Initialize the inner node - */ - resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr, - econtext, - &isNullVect[0], - &isDone); - if (isDone) - isNullVect[0] = alwaysDone[0] = true; - else - alwaysDone[0] = false; - - /* - * Mark the Fjoin as initialized now. - */ - fjNode->fj_initialized = TRUE; - - /* - * If the inner node is always done, then we are done for now - */ - if (isDone) - return; - } - else - { - /* - * If we're already initialized, all we need to do is get the next - * inner result and pair it up with the existing outer node result - * vector. Watch out for the degenerate case, where the inner - * node never returns results. - */ - - /* - * Fill in nulls for every function that is always done. - */ - for (curNode = fjNode->fj_nNodes - 1; curNode >= 0; curNode--) - isNullVect[curNode] = alwaysDone[curNode]; - - if (alwaysDone[0] == true) - { - *fj_isDone = FjoinBumpOuterNodes(tlist, - econtext, - resVect, - isNullVect); - return; - } - else - resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr, - econtext, - &isNullVect[0], - &isDone); - } - - /* - * if the inner node is done - */ - if (isDone) - { - *fj_isDone = FjoinBumpOuterNodes(tlist, - econtext, - resVect, - isNullVect); - if (*fj_isDone) - return; - - resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr, - econtext, - &isNullVect[0], - &isDone); - - } -#endif - return; -} - -#ifdef SETS_FIXED -static bool -FjoinBumpOuterNodes(TargetEntry *tlist, - ExprContext *econtext, - DatumPtr results, - char *nulls) -{ - bool funcIsDone = true; - Fjoin *fjNode = tlist->fjoin; - char *alwaysDone = fjNode->fj_alwaysDone; - List *outerList = lnext(tlist); - List *trailers = lnext(tlist); - int trailNode = 1; - int curNode = 1; - - /* - * Run through list of functions until we get to one that isn't yet - * done returning values. Watch out for funcs that are always done. - */ - while ((funcIsDone == true) && (outerList != NIL)) - { - TargetEntry *tle = lfirst(outerList); - - if (alwaysDone[curNode] == true) - nulls[curNode] = 'n'; - else - results[curNode] = ExecEvalIter((Iter) tle->expr, - econtext, - &nulls[curNode], - &funcIsDone); - curNode++; - outerList = lnext(outerList); - } - - /* - * If every function is done, then we are done flattening. Mark the - * Fjoin node uninitialized, it is time to get the next tuple from the - * plan and redo all of the flattening. - */ - if (funcIsDone) - { - set_fj_initialized(fjNode, false); - return true; - } - - /* - * We found a function that wasn't done. Now re-run every function - * before it. As usual watch out for functions that are always done. - */ - trailNode = 1; - while (trailNode != curNode - 1) - { - TargetEntry *tle = lfirst(trailers); - - if (alwaysDone[trailNode] != true) - results[trailNode] = ExecEvalIter((Iter) tle->expr, - econtext, - &nulls[trailNode], - &funcIsDone); - trailNode++; - trailers = lnext(trailers); - } - return false; -} - -#endif |