diff options
author | Bruce Momjian <bruce@momjian.us> | 1997-09-07 05:04:48 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1997-09-07 05:04:48 +0000 |
commit | 1ccd423235a48739d6f7a4d7889705b5f9ecc69b (patch) | |
tree | 8001c4e839dfad8f29ceda7f8c5f5dbb8759b564 /src/backend/executor/nodeTee.c | |
parent | 8fecd4febf8357f3cc20383ed29ced484877d5ac (diff) | |
download | postgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.tar.gz postgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.zip |
Massive commit to run PGINDENT on all *.c and *.h files.
Diffstat (limited to 'src/backend/executor/nodeTee.c')
-rw-r--r-- | src/backend/executor/nodeTee.c | 899 |
1 files changed, 472 insertions, 427 deletions
diff --git a/src/backend/executor/nodeTee.c b/src/backend/executor/nodeTee.c index 6ddbecc3a49..8a1e233125a 100644 --- a/src/backend/executor/nodeTee.c +++ b/src/backend/executor/nodeTee.c @@ -1,21 +1,21 @@ /*------------------------------------------------------------------------- * * nodeTee.c-- - * + * * * Copyright (c) 1994, Regents of the University of California * - * DESCRIPTION - * This code provides support for a tee node, which allows multiple - * parent in a megaplan. - * - * INTERFACE ROUTINES - * ExecTee - * ExecInitTee - * ExecEndTee + * DESCRIPTION + * This code provides support for a tee node, which allows multiple + * parent in a megaplan. + * + * INTERFACE ROUTINES + * ExecTee + * ExecInitTee + * ExecEndTee * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/Attic/nodeTee.c,v 1.6 1997/07/28 00:54:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/Attic/nodeTee.c,v 1.7 1997/09/07 04:41:46 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -25,9 +25,9 @@ #include "postgres.h" #include "utils/palloc.h" -#include "utils/relcache.h" +#include "utils/relcache.h" #include "utils/mcxt.h" -#include "storage/bufmgr.h" /* for IncrBufferRefCount */ +#include "storage/bufmgr.h" /* for IncrBufferRefCount */ #include "storage/smgr.h" #include "optimizer/internal.h" #include "executor/executor.h" @@ -38,475 +38,520 @@ #include "access/heapam.h" /* ------------------------------------------------------------------ - * ExecInitTee + * ExecInitTee * - * Create tee state + * Create tee state * * ------------------------------------------------------------------ */ bool -ExecInitTee(Tee* node, EState *currentEstate, Plan * parent) +ExecInitTee(Tee * node, EState * currentEstate, Plan * parent) { - TeeState *teeState; - Plan *outerPlan; - int len; - Relation bufferRel; - TupleDesc tupType; - EState *estate; - - /* it is possible that the Tee has already been initialized - since it can be reached by multiple parents. - If it is already initialized, simply return and do - not initialize the children nodes again - */ - if (node->plan.state) - return TRUE; - - /* ---------------- - * assign the node's execution state - * ---------------- - */ - /* make a new executor state, because we have a different - es_range_table */ - -/* node->plan.state = estate;*/ - - estate = CreateExecutorState(); - estate->es_direction = currentEstate->es_direction; - estate->es_BaseId = currentEstate->es_BaseId; - estate->es_BaseId = currentEstate->es_BaseId; - estate->es_tupleTable = currentEstate->es_tupleTable; - estate->es_refcount = currentEstate->es_refcount; - estate->es_junkFilter = currentEstate->es_junkFilter; - - /* use the range table for Tee subplan since the range tables - for the two parents may be different */ - if (node->rtentries) - estate->es_range_table = node->rtentries; - else - estate->es_range_table = currentEstate->es_range_table; - - node->plan.state = estate; - - - /* ---------------- - * create teeState structure - * ---------------- - */ - teeState = makeNode(TeeState); - teeState->tee_leftPlace = 0; - teeState->tee_rightPlace = 0; - teeState->tee_lastPlace = 0; - teeState->tee_bufferRel = NULL; - teeState->tee_leftScanDesc = NULL; - teeState->tee_rightScanDesc = NULL; - - - node->teestate = teeState; - - /* ---------------- - * Miscellanious initialization - * - * + assign node's base_id - * + assign debugging hooks and - * + create expression context for node - * ---------------- - */ - ExecAssignNodeBaseInfo(estate, &(teeState->cstate), parent); - ExecAssignExprContext(estate, &(teeState->cstate)); + TeeState *teeState; + Plan *outerPlan; + int len; + Relation bufferRel; + TupleDesc tupType; + EState *estate; + + /* + * it is possible that the Tee has already been initialized since it + * can be reached by multiple parents. If it is already initialized, + * simply return and do not initialize the children nodes again + */ + if (node->plan.state) + return TRUE; + + /* ---------------- + * assign the node's execution state + * ---------------- + */ + + /* + * make a new executor state, because we have a different + * es_range_table + */ + +/* node->plan.state = estate;*/ + + estate = CreateExecutorState(); + estate->es_direction = currentEstate->es_direction; + estate->es_BaseId = currentEstate->es_BaseId; + estate->es_BaseId = currentEstate->es_BaseId; + estate->es_tupleTable = currentEstate->es_tupleTable; + estate->es_refcount = currentEstate->es_refcount; + estate->es_junkFilter = currentEstate->es_junkFilter; + + /* + * use the range table for Tee subplan since the range tables for the + * two parents may be different + */ + if (node->rtentries) + estate->es_range_table = node->rtentries; + else + estate->es_range_table = currentEstate->es_range_table; + + node->plan.state = estate; + + + /* ---------------- + * create teeState structure + * ---------------- + */ + teeState = makeNode(TeeState); + teeState->tee_leftPlace = 0; + teeState->tee_rightPlace = 0; + teeState->tee_lastPlace = 0; + teeState->tee_bufferRel = NULL; + teeState->tee_leftScanDesc = NULL; + teeState->tee_rightScanDesc = NULL; + + + node->teestate = teeState; + + /* ---------------- + * Miscellanious initialization + * + * + assign node's base_id + * + assign debugging hooks and + * + create expression context for node + * ---------------- + */ + ExecAssignNodeBaseInfo(estate, &(teeState->cstate), parent); + ExecAssignExprContext(estate, &(teeState->cstate)); #define TEE_NSLOTS 2 - /* ---------------- - * initialize tuple slots - * ---------------- - */ - ExecInitResultTupleSlot(estate, &(teeState->cstate)); - - /* initialize child nodes */ - outerPlan = outerPlan((Plan*) node); - ExecInitNode(outerPlan, estate, (Plan*) node); - - /* ---------------- - * the tuple type info is from the outer plan of this node - * the result type is also the same as the outerplan - */ - ExecAssignResultTypeFromOuterPlan((Plan*) node, &(teeState->cstate)); - ExecAssignProjectionInfo((Plan*)node, &teeState->cstate); - - /* --------------------------------------- - initialize temporary relation to buffer tuples - */ - tupType = ExecGetResultType(&(teeState->cstate)); - len = ExecTargetListLength(((Plan*)node)->targetlist); - -/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID_); */ - - /* create a catalogued relation even though this is a temporary relation */ - /* cleanup of catalogued relations is easier to do */ - - if (node->teeTableName[0] != '\0') { - Relation r; - - teeState->tee_bufferRelname = pstrdup(node->teeTableName); - - /* we are given an tee table name, - if a relation by that name exists, then we open it, - else we create it and then open it */ - r = RelationNameGetRelation(teeState->tee_bufferRelname); - - if (RelationIsValid(r)) - bufferRel = heap_openr(teeState->tee_bufferRelname); + /* ---------------- + * initialize tuple slots + * ---------------- + */ + ExecInitResultTupleSlot(estate, &(teeState->cstate)); + + /* initialize child nodes */ + outerPlan = outerPlan((Plan *) node); + ExecInitNode(outerPlan, estate, (Plan *) node); + + /* ---------------- + * the tuple type info is from the outer plan of this node + * the result type is also the same as the outerplan + */ + ExecAssignResultTypeFromOuterPlan((Plan *) node, &(teeState->cstate)); + ExecAssignProjectionInfo((Plan *) node, &teeState->cstate); + + /* --------------------------------------- + initialize temporary relation to buffer tuples + */ + tupType = ExecGetResultType(&(teeState->cstate)); + len = ExecTargetListLength(((Plan *) node)->targetlist); + +/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID_); */ + + /* + * create a catalogued relation even though this is a temporary + * relation + */ + /* cleanup of catalogued relations is easier to do */ + + if (node->teeTableName[0] != '\0') + { + Relation r; + + teeState->tee_bufferRelname = pstrdup(node->teeTableName); + + /* + * we are given an tee table name, if a relation by that name + * exists, then we open it, else we create it and then open it + */ + r = RelationNameGetRelation(teeState->tee_bufferRelname); + + if (RelationIsValid(r)) + bufferRel = heap_openr(teeState->tee_bufferRelname); + else + bufferRel = heap_open(heap_create(teeState->tee_bufferRelname, + /*FIX */ NULL, + 'n', + DEFAULT_SMGR, + tupType)); + } else - bufferRel = heap_open(heap_create(teeState->tee_bufferRelname, -/*FIX */ NULL, - 'n', - DEFAULT_SMGR, - tupType)); - } - else { - sprintf(teeState->tee_bufferRelname, - "ttemp_%d", /* 'ttemp' for 'tee' temporary*/ - newoid()); -/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID); */ - bufferRel = heap_open(heap_create(teeState->tee_bufferRelname, - NULL, /*XXX */ - 'n', - DEFAULT_SMGR, - tupType)); - } - - teeState->tee_bufferRel = bufferRel; - - /*initialize a memory context for allocating thing like scan descriptors */ - /* we do this so that on cleanup of the tee, we can free things. - if we didn't have our own memory context, we would be in the memory - context of the portal that we happen to be using at the moment */ - - teeState->tee_mcxt = (MemoryContext)CreateGlobalMemory(teeState->tee_bufferRelname); - - /* don't initialize the scan descriptors here - because it's not good to initialize scan descriptors on empty - rels. Wait until the scan descriptors are needed - before initializing them. */ - - teeState->tee_leftScanDesc = NULL; - teeState->tee_rightScanDesc = NULL; - - return TRUE; + { + sprintf(teeState->tee_bufferRelname, + "ttemp_%d", /* 'ttemp' for 'tee' temporary */ + newoid()); +/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID); */ + bufferRel = heap_open(heap_create(teeState->tee_bufferRelname, + NULL, /* XXX */ + 'n', + DEFAULT_SMGR, + tupType)); + } + + teeState->tee_bufferRel = bufferRel; + + /* + * initialize a memory context for allocating thing like scan + * descriptors + */ + + /* + * we do this so that on cleanup of the tee, we can free things. if we + * didn't have our own memory context, we would be in the memory + * context of the portal that we happen to be using at the moment + */ + + teeState->tee_mcxt = (MemoryContext) CreateGlobalMemory(teeState->tee_bufferRelname); + + /* + * don't initialize the scan descriptors here because it's not good to + * initialize scan descriptors on empty rels. Wait until the scan + * descriptors are needed before initializing them. + */ + + teeState->tee_leftScanDesc = NULL; + teeState->tee_rightScanDesc = NULL; + + return TRUE; } -int -ExecCountSlotsTee(Tee *node) +int +ExecCountSlotsTee(Tee * node) { - /* Tee nodes can't have innerPlans */ - return ExecCountSlotsNode(outerPlan(node)) + TEE_NSLOTS; + /* Tee nodes can't have innerPlans */ + return ExecCountSlotsNode(outerPlan(node)) + TEE_NSLOTS; } /* ---------------------------------------------------------------- initTeeScanDescs - initializes the left and right scandescs on the temporary - relation of a Tee node + initializes the left and right scandescs on the temporary + relation of a Tee node - must open two separate scan descriptors, - because the left and right scans may be at different points + must open two separate scan descriptors, + because the left and right scans may be at different points * ---------------------------------------------------------------- */ -static void -initTeeScanDescs(Tee* node) +static void +initTeeScanDescs(Tee * node) { - TeeState *teeState; - Relation bufferRel; - ScanDirection dir; - MemoryContext orig; - - teeState = node->teestate; - if (teeState->tee_leftScanDesc && teeState->tee_rightScanDesc) - return; - - orig = CurrentMemoryContext; - MemoryContextSwitchTo(teeState->tee_mcxt); - - bufferRel = teeState->tee_bufferRel; - dir = ((Plan*)node)->state->es_direction; /* backwards not handled yet XXX */ - - if (teeState->tee_leftScanDesc == NULL) - { - teeState->tee_leftScanDesc = heap_beginscan(bufferRel, - ScanDirectionIsBackward(dir), - NowTimeQual, /* time qual */ - 0, /* num scan keys */ - NULL /* scan keys */ - ); - } - if (teeState->tee_rightScanDesc == NULL) - { - teeState->tee_rightScanDesc = heap_beginscan(bufferRel, - ScanDirectionIsBackward(dir), - NowTimeQual, /* time qual */ - 0, /* num scan keys */ - NULL /* scan keys */ - ); - } - - MemoryContextSwitchTo(orig); + TeeState *teeState; + Relation bufferRel; + ScanDirection dir; + MemoryContext orig; + + teeState = node->teestate; + if (teeState->tee_leftScanDesc && teeState->tee_rightScanDesc) + return; + + orig = CurrentMemoryContext; + MemoryContextSwitchTo(teeState->tee_mcxt); + + bufferRel = teeState->tee_bufferRel; + dir = ((Plan *) node)->state->es_direction; /* backwards not handled + * yet XXX */ + + if (teeState->tee_leftScanDesc == NULL) + { + teeState->tee_leftScanDesc = heap_beginscan(bufferRel, + ScanDirectionIsBackward(dir), + NowTimeQual, /* time qual */ + 0, /* num scan keys */ + NULL /* scan keys */ + ); + } + if (teeState->tee_rightScanDesc == NULL) + { + teeState->tee_rightScanDesc = heap_beginscan(bufferRel, + ScanDirectionIsBackward(dir), + NowTimeQual, /* time qual */ + 0, /* num scan keys */ + NULL /* scan keys */ + ); + } + + MemoryContextSwitchTo(orig); } /* ---------------------------------------------------------------- - * ExecTee(node) + * ExecTee(node) + * * + * A Tee serves to connect a subplan to multiple parents. + * the subplan is always the outplan of the Tee node. * - * A Tee serves to connect a subplan to multiple parents. - * the subplan is always the outplan of the Tee node. - * - * The Tee gets requests from either leftParent or rightParent, - * fetches the result tuple from the child, and then - * stored the result into a temporary relation (serving as a queue). - * leftPlace and rightPlace keep track of where the left and rightParents - * are. - * If a parent requests a tuple and that parent is not at the end - * of the temporary relation, then the request is satisfied from - * the queue instead of by executing the child plan + * The Tee gets requests from either leftParent or rightParent, + * fetches the result tuple from the child, and then + * stored the result into a temporary relation (serving as a queue). + * leftPlace and rightPlace keep track of where the left and rightParents + * are. + * If a parent requests a tuple and that parent is not at the end + * of the temporary relation, then the request is satisfied from + * the queue instead of by executing the child plan * * ---------------------------------------------------------------- */ -TupleTableSlot* -ExecTee(Tee *node, Plan *parent) +TupleTableSlot * +ExecTee(Tee * node, Plan * parent) { - EState *estate; - TeeState *teeState; - int leftPlace, rightPlace, lastPlace; - int branch; - TupleTableSlot* result; - TupleTableSlot* slot; - Plan *childNode; - ScanDirection dir; - HeapTuple heapTuple; - Relation bufferRel; - HeapScanDesc scanDesc; - Buffer buffer; - - estate = ((Plan*)node)->state; - teeState = node->teestate; - leftPlace = teeState->tee_leftPlace; - rightPlace = teeState->tee_rightPlace; - lastPlace = teeState->tee_lastPlace; - bufferRel = teeState->tee_bufferRel; - - childNode = outerPlan(node); - - dir = estate->es_direction; - - /* XXX doesn't handle backwards direction yet */ - - if (parent == node->leftParent) { - branch = leftPlace; - } - else - if ( (parent == node->rightParent) || (parent == (Plan*) node)) - /* the tee node could be the root node of the plan, - in which case, we treat it like a right-parent pull*/ + EState *estate; + TeeState *teeState; + int leftPlace, + rightPlace, + lastPlace; + int branch; + TupleTableSlot *result; + TupleTableSlot *slot; + Plan *childNode; + ScanDirection dir; + HeapTuple heapTuple; + Relation bufferRel; + HeapScanDesc scanDesc; + Buffer buffer; + + estate = ((Plan *) node)->state; + teeState = node->teestate; + leftPlace = teeState->tee_leftPlace; + rightPlace = teeState->tee_rightPlace; + lastPlace = teeState->tee_lastPlace; + bufferRel = teeState->tee_bufferRel; + + childNode = outerPlan(node); + + dir = estate->es_direction; + + /* XXX doesn't handle backwards direction yet */ + + if (parent == node->leftParent) + { + branch = leftPlace; + } + else if ((parent == node->rightParent) || (parent == (Plan *) node)) + + /* + * the tee node could be the root node of the plan, in which case, + * we treat it like a right-parent pull + */ + { + branch = rightPlace; + } + else + { + elog(WARN, "A Tee node can only be executed from its left or right parent\n"); + return NULL; + } + + if (branch == lastPlace) + { /* we're at the end of the queue already, + * - get a new tuple from the child plan, + * - store it in the queue, - increment + * lastPlace, - increment leftPlace or + * rightPlace as appropriate, - and return + * result */ + slot = ExecProcNode(childNode, (Plan *) node); + if (!TupIsNull(slot)) + { + heapTuple = slot->val; + + /* insert into temporary relation */ + heap_insert(bufferRel, heapTuple); + + /* + * once there is data in the temporary relation, ensure that + * the left and right scandescs are initialized + */ + initTeeScanDescs(node); + + scanDesc = (parent == node->leftParent) ? + teeState->tee_leftScanDesc : teeState->tee_rightScanDesc; + + { + + /* + * move the scandesc forward so we don't re-read this + * tuple later + */ + HeapTuple throwAway; + + /* Buffer buffer; */ + throwAway = heap_getnext(scanDesc, + ScanDirectionIsBackward(dir), + /* &buffer */ + (Buffer *) NULL); + } + + /* + * set the shouldFree field of the child's slot so that when + * the child's slot is free'd, this tuple isn't free'd also + */ + + /* + * does this mean this tuple has to be garbage collected + * later?? + */ + slot->ttc_shouldFree = false; + + teeState->tee_lastPlace = lastPlace + 1; + } + result = slot; + } + else + { /* the desired data already exists in the + * temporary relation */ + scanDesc = (parent == node->leftParent) ? + teeState->tee_leftScanDesc : teeState->tee_rightScanDesc; + + heapTuple = heap_getnext(scanDesc, + ScanDirectionIsBackward(dir), + &buffer); + + /* + * Increase the pin count on the buffer page, because the tuple + * stored in the slot also points to it (as well as the scan + * descriptor). If we don't, ExecStoreTuple will decrease the pin + * count on the next iteration. + */ + + if (buffer != InvalidBuffer) + IncrBufferRefCount(buffer); + + slot = teeState->cstate.cs_ResultTupleSlot; + slot->ttc_tupleDescriptor = RelationGetTupleDescriptor(bufferRel); + + result = ExecStoreTuple(heapTuple, /* tuple to store */ + slot, /* slot to store in */ + buffer, /* this tuple's buffer */ + false); /* don't free stuff from + * heap_getnext */ + + } + + if (parent == node->leftParent) { - branch = rightPlace; - } - else - { - elog(WARN,"A Tee node can only be executed from its left or right parent\n"); - return NULL; - } - - if (branch == lastPlace) - { /* we're at the end of the queue already, - - get a new tuple from the child plan, - - store it in the queue, - - increment lastPlace, - - increment leftPlace or rightPlace as appropriate, - - and return result - */ - slot = ExecProcNode(childNode, (Plan*)node); - if (!TupIsNull(slot)) - { - heapTuple = slot->val; - - /* insert into temporary relation */ - heap_insert(bufferRel, heapTuple); - - /* once there is data in the temporary relation, - ensure that the left and right scandescs are initialized */ - initTeeScanDescs(node); - - scanDesc = (parent == node->leftParent) ? - teeState->tee_leftScanDesc : teeState->tee_rightScanDesc; - - { - /* move the scandesc forward so we don't re-read this tuple later */ - HeapTuple throwAway; - /* Buffer buffer;*/ - throwAway = heap_getnext(scanDesc, - ScanDirectionIsBackward(dir), - /* &buffer */ - (Buffer*)NULL); - } - - /* set the shouldFree field of the child's slot so that - when the child's slot is free'd, this tuple isn't free'd also */ - /* does this mean this tuple has to be garbage collected later??*/ - slot->ttc_shouldFree = false; - - teeState->tee_lastPlace = lastPlace + 1; - } - result = slot; - } - else - {/* the desired data already exists in the temporary relation */ - scanDesc = (parent == node->leftParent) ? - teeState->tee_leftScanDesc : teeState->tee_rightScanDesc; - - heapTuple = heap_getnext(scanDesc, - ScanDirectionIsBackward(dir), - &buffer); - - /* Increase the pin count on the buffer page, because the - tuple stored in the slot also points to it (as well as - the scan descriptor). If we don't, ExecStoreTuple will - decrease the pin count on the next iteration. */ - - if (buffer != InvalidBuffer) - IncrBufferRefCount(buffer); - - slot = teeState->cstate.cs_ResultTupleSlot; - slot->ttc_tupleDescriptor = RelationGetTupleDescriptor(bufferRel); - - result = ExecStoreTuple(heapTuple,/* tuple to store */ - slot, /* slot to store in */ - buffer,/* this tuple's buffer */ - false); /* don't free stuff from heap_getnext */ - - } - - if (parent == node->leftParent) - { - teeState->tee_leftPlace = leftPlace+1; - } - else - { - teeState->tee_rightPlace = rightPlace+1; - } - - return result; + teeState->tee_leftPlace = leftPlace + 1; + } + else + { + teeState->tee_rightPlace = rightPlace + 1; + } + + return result; } /* ---------------------------------------------------------------- - * ExecTeeReScan(node) - * - * Rescans the relation. + * ExecTeeReScan(node) + * + * Rescans the relation. * ---------------------------------------------------------------- */ void -ExecTeeReScan(Tee *node, ExprContext *exprCtxt, Plan *parent) +ExecTeeReScan(Tee * node, ExprContext * exprCtxt, Plan * parent) { - EState *estate; - TeeState *teeState; - ScanDirection dir; + EState *estate; + TeeState *teeState; + ScanDirection dir; - estate = ((Plan*)node)->state; - teeState = node->teestate; + estate = ((Plan *) node)->state; + teeState = node->teestate; - dir = estate->es_direction; - - /* XXX doesn't handle backwards direction yet */ + dir = estate->es_direction; - if (parent == node->leftParent) { - if (teeState->tee_leftScanDesc) + /* XXX doesn't handle backwards direction yet */ + + if (parent == node->leftParent) + { + if (teeState->tee_leftScanDesc) + { + heap_rescan(teeState->tee_leftScanDesc, + ScanDirectionIsBackward(dir), + NULL); + teeState->tee_leftPlace = 0; + } + } + else { - heap_rescan(teeState->tee_leftScanDesc, - ScanDirectionIsBackward(dir), - NULL); - teeState->tee_leftPlace = 0; + if (teeState->tee_rightScanDesc) + { + heap_rescan(teeState->tee_leftScanDesc, + ScanDirectionIsBackward(dir), + NULL); + teeState->tee_rightPlace = 0; + } } - } - else - { - if (teeState->tee_rightScanDesc) - { - heap_rescan(teeState->tee_leftScanDesc, - ScanDirectionIsBackward(dir), - NULL); - teeState->tee_rightPlace = 0; - } - } } /* --------------------------------------------------------------------- - * ExecEndTee + * ExecEndTee * - * End the Tee node, and free up any storage + * End the Tee node, and free up any storage * since a Tee node can be downstream of multiple parent nodes, * only free when both parents are done * -------------------------------------------------------------------- */ -void -ExecEndTee(Tee* node, Plan* parent) +void +ExecEndTee(Tee * node, Plan * parent) { - EState *estate; - TeeState *teeState; - int leftPlace, rightPlace, lastPlace; - Relation bufferRel; - MemoryContext orig; - - estate = ((Plan*)node)->state; - teeState = node->teestate; - leftPlace = teeState->tee_leftPlace; - rightPlace = teeState->tee_rightPlace; - lastPlace = teeState->tee_lastPlace; - - if (!node->leftParent || parent == node->leftParent) - leftPlace = -1; - - if (!node->rightParent || parent == node->rightParent) - rightPlace = -1; - - if (parent == (Plan*)node) - rightPlace = leftPlace = -1; - - teeState->tee_leftPlace = leftPlace; - teeState->tee_rightPlace = rightPlace; - if ( (leftPlace == -1) && (rightPlace == -1) ) - { - /* remove the temporary relations */ - /* and close the scan descriptors */ - - bufferRel = teeState->tee_bufferRel; - if (bufferRel) { - heap_destroyr(bufferRel); - teeState->tee_bufferRel = NULL; - if (teeState->tee_mcxt) { - orig = CurrentMemoryContext; - MemoryContextSwitchTo(teeState->tee_mcxt); - } - else - orig = 0; - - if (teeState->tee_leftScanDesc) - { - heap_endscan(teeState->tee_leftScanDesc); - teeState->tee_leftScanDesc = NULL; - } - if (teeState->tee_rightScanDesc) - { - heap_endscan(teeState->tee_rightScanDesc); - teeState->tee_rightScanDesc = NULL; - } - - if (teeState->tee_mcxt) { - MemoryContextSwitchTo(orig); - teeState->tee_mcxt = NULL; - } + EState *estate; + TeeState *teeState; + int leftPlace, + rightPlace, + lastPlace; + Relation bufferRel; + MemoryContext orig; + + estate = ((Plan *) node)->state; + teeState = node->teestate; + leftPlace = teeState->tee_leftPlace; + rightPlace = teeState->tee_rightPlace; + lastPlace = teeState->tee_lastPlace; + + if (!node->leftParent || parent == node->leftParent) + leftPlace = -1; + + if (!node->rightParent || parent == node->rightParent) + rightPlace = -1; + + if (parent == (Plan *) node) + rightPlace = leftPlace = -1; + + teeState->tee_leftPlace = leftPlace; + teeState->tee_rightPlace = rightPlace; + if ((leftPlace == -1) && (rightPlace == -1)) + { + /* remove the temporary relations */ + /* and close the scan descriptors */ + + bufferRel = teeState->tee_bufferRel; + if (bufferRel) + { + heap_destroyr(bufferRel); + teeState->tee_bufferRel = NULL; + if (teeState->tee_mcxt) + { + orig = CurrentMemoryContext; + MemoryContextSwitchTo(teeState->tee_mcxt); + } + else + orig = 0; + + if (teeState->tee_leftScanDesc) + { + heap_endscan(teeState->tee_leftScanDesc); + teeState->tee_leftScanDesc = NULL; + } + if (teeState->tee_rightScanDesc) + { + heap_endscan(teeState->tee_rightScanDesc); + teeState->tee_rightScanDesc = NULL; + } + + if (teeState->tee_mcxt) + { + MemoryContextSwitchTo(orig); + teeState->tee_mcxt = NULL; + } + } } - } - -} +} |