head 1.19; access; symbols release_4_2:1.19 aix_ok:1.18; locks; strict; comment @ * @; 1.19 date 94.02.07.11.34.44; author aoki; state Exp; branches; next 1.18; 1.18 date 93.09.25.23.49.37; author paxson; state Exp; branches; next 1.17; 1.17 date 92.08.04.17.37.46; author mer; state Exp; branches; next 1.16; 1.16 date 92.07.13.03.25.38; author hong; state Exp; branches; next 1.15; 1.15 date 92.07.09.03.54.04; author hong; state Exp; branches; next 1.14; 1.14 date 92.07.06.06.16.20; author mer; state Exp; branches; next 1.13; 1.13 date 92.07.04.04.30.16; author mer; state Exp; branches; next 1.12; 1.12 date 92.06.22.17.20.35; author mer; state Exp; branches; next 1.11; 1.11 date 92.03.31.23.10.44; author mer; state Exp; branches; next 1.10; 1.10 date 92.03.05.23.42.17; author mer; state Exp; branches; next 1.9; 1.9 date 91.11.17.21.10.46; author mer; state Exp; branches; next 1.8; 1.8 date 91.11.14.11.00.58; author glass; state Exp; branches; next 1.7; 1.7 date 91.11.14.10.52.29; author glass; state Exp; branches; next 1.6; 1.6 date 91.11.05.05.33.59; author mer; state Exp; branches; next 1.5; 1.5 date 91.09.22.22.01.26; author hong; state Exp; branches; next 1.4; 1.4 date 91.08.15.17.38.08; author caetta; state Exp; branches; next 1.3; 1.3 date 91.07.17.23.54.08; author hong; state Exp; branches; next 1.2; 1.2 date 91.07.09.02.44.57; author mao; state Exp; branches; next 1.1; 1.1 date 91.06.18.23.31.59; author cimarron; state Exp; branches; next ; desc @ reorganized executor to use tuple table properly for nested dot stuff @ 1.19 log @proto fixes @ text @/* ---------------------------------------------------------------- * FILE * ex_tuples.c * * DESCRIPTION * Routines dealing with the executor tuple tables. These * are used to ensure that the executor frees copies of tuples * (made by ExecTargetList) properly. * * Routines dealing with the type inforamtion for tuples. * Currently, the type information for a tuple is an array of * struct attribute. This information is needed by routines * manipulating tuples (getattribute, formtuple, etc.). * * INTERFACE ROUTINES * * TABLE CREATE/DELETE * ExecCreateTupleTable - create a new tuple table * ExecDestroyTupleTable - destroy a table * * SLOT RESERVERATION * ExecAllocTableSlot - find an available slot in the table * ExecGetTableSlot - get a slot corresponding to a table index * * SLOT ACCESSORS * ExecStoreTuple - store a tuple in the table * ExecFetchTuple - fetch a tuple from the table * ExecClearTuple - clear contents of a table slot * ExecSlotPolicy - return slot's tuple pfree policy * ExecSetSlotPolicy - diddle the slot policy * ExecSlotDescriptor - type of tuple in a slot * ExecSetSlotDescriptor - set a slot's tuple descriptor * ExecSetSlotDescriptorIsNew - diddle the slot-desc-is-new flag * ExecSetNewSlotDescriptor - set a desc and the is-new-flag all at once * ExecSlotBuffer - return buffer of tuple in slot * ExecSetSlotBuffer - set the buffer for tuple in slot * ExecIncrSlotBufferRefcnt - bump the refcnt of the slot buffer * * SLOT STATUS PREDICATES * ExecNullSlot - true when slot contains no tuple * ExecSlotDescriptorIsNew - true if we're now storing a different * type of tuple in a slot * * CONVENIENCE INITIALIZATION ROUTINES * ExecInitResultTupleSlot \ convience routines to initialize * ExecInitScanTupleSlot \ the various tuple slots for nodes * ExecInitRawTupleSlot \ which store copies of tuples. * ExecInitMarkedTupleSlot / * ExecInitOuterTupleSlot / * ExecInitHashTupleSlot / * * old routines: * ExecGetTupType - get type of tuple returned by this node * ExecTypeFromTL - form a TupleDescriptor from a target list * * EXAMPLE OF HOW TABLE ROUTINES WORK * Suppose we have a query such as retrieve (EMP.name) and we have * a single SeqScan node in the query plan. * * At ExecMain(EXEC_START) * ---------------- * - InitPlan() calls ExecCreateTupleTable() to create the tuple * table which will hold tuples processed by the executor. * * - ExecInitSeqScan() calls ExecInitScanTupleSlot() and * ExecInitResultTupleSlot() to reserve places in the tuple * table for the tuples returned by the access methods and the * tuples resulting from preforming target list projections. * * During ExecMain(EXEC_RUN) * ---------------- * - SeqNext() calls ExecStoreTuple() to place the tuple returned * by the access methods into the scan tuple slot. * * - ExecProcSeqScan() calls ExecStoreTuple() to take the result * tuple from ExecTargetList() and place it into the result tuple * slot. * * - ExecutePlan() calls ExecRetrieve() which gets the tuple out of * the slot passed to it by calling ExecFetchTuple(). this tuple * is then returned. * * At ExecMain(EXEC_END) * ---------------- * - EndPlan() calls ExecDestroyTupleTable() to clean up any remaining * tuples left over from executing the query. * * The important thing to watch in the executor code is how pointers * to the slots containing tuples are passed instead of the tuples * themselves. This facilitates the communication of related information * (such as whether or not a tuple should be pfreed, what buffer contains * this tuple, the tuple's tuple descriptor, etc). Note that much of * this information is also kept in the ExprContext of each node. * Soon the executor will be redesigned and ExprContext's will contain * only slot pointers. -cim 3/14/91 * * NOTES * The tuple table stuff is relatively new, put here to alleviate * the process growth problems in the executor. The other routines * are old (from the original lisp system) and may someday become * obsolete. -cim 6/23/90 * * In the implementation of nested-dot queries such as * "retrieve (EMP.hobbies.all)", a single scan may return tuples * of many types, so now we return pointers to tuple descriptors * along with tuples returned via the tuple table. This means * we now have a bunch of routines to diddle the slot descriptors * too. -cim 1/18/90 * * The tuple table stuff depends on the lib/H/executor/tuptable.h macros, * and the TupleTableSlot node in execnodes.h. * * IDENTIFICATION * $Header: /usr/local/devel/postgres/src/backend/executor/RCS/ex_tuples.c,v 1.18 1993/09/25 23:49:37 paxson Exp $ * ---------------------------------------------------------------- */ #include "executor/executor.h" #undef ExecStoreTuple #include "utils/palloc.h" RcsId("$Header: /usr/local/devel/postgres/src/backend/executor/RCS/ex_tuples.c,v 1.18 1993/09/25 23:49:37 paxson Exp $"); /* ---------------------------------------------------------------- * tuple table create/delete functions * ---------------------------------------------------------------- */ /* -------------------------------- * ExecCreateTupleTable * * This creates a new tuple table of the specified initial * size. If the size is insufficient, ExecAllocTableSlot() * will grow the table as necessary. * * This should be used by InitPlan() to allocate the table. * The table's address would then be stored somewhere * in the EState structure. * -------------------------------- */ TupleTable /* return: address of table */ ExecCreateTupleTable(initialSize) int initialSize; /* initial number of slots in table */ { TupleTable newtable; /* newly allocated table */ Pointer array; /* newly allocated table array */ /* ---------------- * sanity checks * ---------------- */ Assert(initialSize >= 1); /* ---------------- * Now allocate our new table along with space for the pointers * to the tuples. Note: our array is actually an array of * TupleTableCells (which is a subclass of LispValue). * This is for 2 reasons: 1) there's lots of code that expects * tuples to be returned "inside" lispCons cells and 2) the cdr * field may one day be useful. * -cim 6/23/90 * ---------------- */ newtable = (TupleTable) palloc(sizeof(TupleTableData)); array = (Pointer) palloc(initialSize * TableSlotSize); /* ---------------- * clean out the slots we just allocated * ---------------- */ bzero(array, initialSize * TableSlotSize); /* ---------------- * initialize the new table and return it to the caller. * ---------------- */ newtable->size = initialSize; newtable->next = 0; newtable->array = array; return newtable; } /* -------------------------------- * ExecDestroyTupleTable * * This pfrees the storage assigned to the tuple table and * optionally pfrees the contents of the table also. * It is expected that this routine be called by EndPlan(). * -------------------------------- */ void ExecDestroyTupleTable(table, shouldFree) TupleTable table; /* tuple table */ bool shouldFree; /* true if we should free slot contents */ { int next; /* next avaliable slot */ Pointer array; /* start of table array */ int i; /* counter */ /* ---------------- * sanity checks * ---------------- */ Assert(table != NULL); /* ---------------- * get information from the table * ---------------- */ array = table->array; next = table->next; /* ---------------- * first free all the valid pointers in the tuple array * if that's what the caller wants.. * * Note: we do nothing about the Buffer and Tuple Descriptor's * we store in the slots. This may have to change (ex: we should * probably worry about pfreeing tuple descs too) -cim 3/14/91 * ---------------- */ if (shouldFree) for (i = 0; i < next; i++) { Pointer slot; Pointer tuple; slot = TableSlot(array, i); tuple = SlotContents(slot); if (tuple != NULL) { SetSlotContents(slot, NULL); if (SlotShouldFree((TupleTableSlot) slot)) { /* ---------------- * since a tuple may contain a pointer to * lock information allocated along with the * tuple, we have to be careful to free any * rule locks also -cim 1/17/90 * ---------------- */ HeapTupleFreeRuleLock(tuple); pfree(tuple); } } } /* ---------------- * finally free the tuple array and the table itself. * ---------------- */ pfree(array); pfree(table); } /* ---------------------------------------------------------------- * tuple table slot reservation functions * ---------------------------------------------------------------- */ /* -------------------------------- * ExecAllocTableSlot * * This routine is used to reserve slots in the table for * use by the various plan nodes. It is expected to be * called by the node init routines (ex: ExecInitNestLoop). * once per slot needed by the node. Not all nodes need * slots (some just pass tuples around). * -------------------------------- */ int /* return: index into tuple table */ ExecAllocTableSlot(table) TupleTable table; /* tuple table */ { int slotnum; /* new slot number (returned) */ /* ---------------- * sanity checks * ---------------- */ Assert(table != NULL); /* ---------------- * if our table is full we have to allocate a larger * size table. Since ExecAllocTableSlot() is only called * before the table is ever used to store tuples, we don't * have to worry about the contents of the old table. * If this changes, then we will have to preserve the contents. * -cim 6/23/90 * * Unfortunately, we *cannot* do this. All of the nodes in * the plan that have already initialized their slots will have * pointers into _freed_ memory. This leads to bad ends. We * now count the number of slots we will need and create all the * slots we will need ahead of time. The if below should never * happen now. Give a WARN if it does. -mer 4 Aug 1992 * ---------------- */ if (table->next >= table->size) { /* * int newsize = NewTableSize(table->size); * * pfree(table->array); * table->array = (Pointer) palloc(newsize * TableSlotSize); * bzero(table->array, newsize * TableSlotSize); * table->size = newsize; */ elog(NOTICE, "Plan requires more slots than are available"); elog(WARN, "send mail to your local executor guru to fix this"); } /* ---------------- * at this point, space in the table is guaranteed so we * reserve the next slot, initialize and return it. * ---------------- */ slotnum = table->next; table->next++; InitSlot(ExecGetTableSlot(table, slotnum)); return slotnum; } /* -------------------------------- * ExecGetTableSlot * * This routine is used to get the slot (an address) corresponding * to a slot number (an index) for the specified tuple table. * -------------------------------- */ Pointer /* return: address of slot containing tuple */ ExecGetTableSlot(table, slotnum) TupleTable table; /* table */ int slotnum; /* number of slot */ { Pointer slot; /* slot corresponding to slotnum in table */ /* ---------------- * sanity checks * ---------------- */ Assert(table != NULL); Assert(slotnum >= 0 && slotnum < table->next); /* ---------------- * get information from the tuple table and return it. * ---------------- */ slot = TableSlot(table->array, slotnum); return slot; } /* ---------------------------------------------------------------- * tuple table slot accessor functions * ---------------------------------------------------------------- */ /* -------------------------------- * ExecStoreTuple * * This function is used to store a tuple into a specified * slot in the tuple table. Note: the only slots which should * be called with shouldFree == false are those slots used to * store tuples not allocated with pfree(). Currently the * seqscan and indexscan nodes use this for the tuples returned * by amgetattr, which are actually pointers onto disk pages. * -------------------------------- */ Pointer /* return: slot passed */ ExecStoreTuple(tuple, slot, buffer, shouldFree) Pointer tuple; /* tuple to store */ Pointer slot; /* slot in which to store tuple */ Buffer buffer; /* buffer associated with tuple */ bool shouldFree; /* true if we call pfree() when we gc. */ { Pointer oldtuple; /* prior contents of slot */ /* ---------------- * sanity checks * ---------------- */ Assert(slot != NULL); /* ---------------- * get information from the tuple table * ---------------- */ oldtuple = SlotContents(slot); /* ---------------- * free the old contents of the specified slot if necessary. * ---------------- */ if (SlotShouldFree((TupleTableSlot) slot) && oldtuple != NULL) { /* ---------------- * since a tuple may contain a pointer to * lock information allocated along with the * tuple, we have to be careful to free any * rule locks also -cim 1/17/90 * ---------------- */ HeapTupleFreeRuleLock(oldtuple); pfree(oldtuple); } /* ---------------- * if we have a buffer pinned, release it before stomping on it. * ---------------- */ if (BufferIsValid(SlotBuffer((TupleTableSlot) slot))) ReleaseBuffer(SlotBuffer((TupleTableSlot) slot)); /* ---------------- * store the new tuple into the specified slot and * return the slot into which we stored the tuple. * ---------------- */ SetSlotContents((TupleTableSlot) slot, tuple); SetSlotBuffer((TupleTableSlot) slot, buffer); SetSlotShouldFree((TupleTableSlot) slot, shouldFree); return slot; } Pointer /* return: slot passed */ ExecStoreTupleDebug(file, line, tuple, slot, buffer, shouldFree) String file; /* filename */ int line; /* line number */ Pointer tuple; /* tuple to store */ Pointer slot; /* slot in which to store tuple */ Buffer buffer; /* buffer associated with tuple */ bool shouldFree; /* true if we call pfree() when we gc. */ { printf(":EST f %s l %d t 0x%x s 0x%x b %d sf %d\n", file, line, tuple, slot, buffer, shouldFree); return ExecStoreTuple(tuple, slot, buffer, shouldFree); } /* -------------------------------- * ExecFetchTuple * * This function is used to get the heap tuple out of * a slot in the tuple table. * -------------------------------- * * Now a macro in tuptable.h -mer 5 March 1992 */ /* -------------------------------- * ExecClearTuple * * This function is used to clear out a slot in the tuple table. * -------------------------------- */ Pointer /* return: slot passed */ ExecClearTuple(slot) Pointer slot; /* slot in which to store tuple */ { Pointer oldtuple; /* prior contents of slot */ /* ---------------- * sanity checks * ---------------- */ Assert(slot != NULL); /* ---------------- * get information from the tuple table * ---------------- */ oldtuple = SlotContents(slot); /* ---------------- * free the old contents of the specified slot if necessary. * ---------------- */ if (SlotShouldFree((TupleTableSlot) slot) && oldtuple != NULL) { /* ---------------- * since a tuple may contain a pointer to * lock information allocated along with the * tuple, we have to be careful to free any * rule locks also -cim 1/17/90 * ---------------- */ HeapTupleFreeRuleLock(oldtuple); pfree(oldtuple); } /* ---------------- * store NULL into the specified slot and return the slot. * - also set buffer to InvalidBuffer -cim 3/14/91 * ---------------- */ SetSlotContents(slot, NULL); if (BufferIsValid(SlotBuffer((TupleTableSlot) slot))) ReleaseBuffer(SlotBuffer((TupleTableSlot) slot)); SetSlotBuffer((TupleTableSlot) slot, InvalidBuffer); SetSlotShouldFree((TupleTableSlot) slot, true); return slot; } /* -------------------------------- * ExecSlotPolicy * * This function is used to get the call/don't call pfree * setting of a slot. Most executor routines don't need this. * It's only when you do tricky things like marking tuples for * merge joins that you need to diddle the slot policy. * -------------------------------- */ bool /* return: slot policy */ ExecSlotPolicy(slot) Pointer slot; /* slot to inspect */ { bool shouldFree = SlotShouldFree((TupleTableSlot) slot); return shouldFree; } /* -------------------------------- * ExecSetSlotPolicy * * This function is used to change the call/don't call pfree * setting of a slot. Most executor routines don't need this. * It's only when you do tricky things like marking tuples for * merge joins that you need to diddle the slot policy. * -------------------------------- */ bool /* return: old slot policy */ ExecSetSlotPolicy(slot, shouldFree) Pointer slot; /* slot to change */ bool shouldFree; /* true if we call pfree() when we gc. */ { bool old_shouldFree = SlotShouldFree((TupleTableSlot) slot); SetSlotShouldFree((TupleTableSlot) slot, shouldFree); return old_shouldFree; } /* -------------------------------- * ExecSlotDescriptor * * This function is used to get the tuple descriptor associated * with the slot's tuple. * * Now a macro in tuptable.h -mer 5 March 1992 * -------------------------------- */ /* -------------------------------- * ExecSetSlotDescriptor * * This function is used to set the tuple descriptor associated * with the slot's tuple. * -------------------------------- */ TupleDescriptor /* return: old slot tuple descriptor */ ExecSetSlotDescriptor(slot, tupdesc) Pointer slot; /* slot to change */ TupleDescriptor tupdesc; /* tuple descriptor */ { TupleDescriptor old_tupdesc = SlotTupleDescriptor((TupleTableSlot) slot); SetSlotTupleDescriptor((TupleTableSlot) slot, tupdesc); return old_tupdesc; } /* -------------------------------- * ExecSetSlotDescriptorIsNew * * This function is used to change the setting of the "isNew" flag * -------------------------------- */ void ExecSetSlotDescriptorIsNew(slot, isNew) Pointer slot; /* slot to change */ bool isNew; /* "isNew" setting */ { SetSlotTupleDescriptorIsNew((TupleTableSlot) slot, isNew); } /* -------------------------------- * ExecSetNewSlotDescriptor * * This function is used to set the tuple descriptor associated * with the slot's tuple, and set the "isNew" flag at the same time. * -------------------------------- */ TupleDescriptor /* return: old slot tuple descriptor */ ExecSetNewSlotDescriptor(slot, tupdesc) Pointer slot; /* slot to change */ TupleDescriptor tupdesc; /* tuple descriptor */ { TupleDescriptor old_tupdesc = SlotTupleDescriptor((TupleTableSlot) slot); SetSlotTupleDescriptor((TupleTableSlot) slot, tupdesc); SetSlotTupleDescriptorIsNew((TupleTableSlot) slot, true); return old_tupdesc; } /* -------------------------------- * ExecSlotBuffer * * This function is used to get the tuple descriptor associated * with the slot's tuple. Be very careful with this as it does not * balance the reference counts. If the buffer returned is stored * someplace else, then also use ExecIncrSlotBufferRefcnt(). * * Now a macro in tuptable.h * -------------------------------- */ /* -------------------------------- * ExecSetSlotBuffer * * This function is used to set the tuple descriptor associated * with the slot's tuple. Be very careful with this as it does not * balance the reference counts. If we're using this then we should * also use ExecIncrSlotBufferRefcnt(). * -------------------------------- */ Buffer /* return: old slot buffer */ ExecSetSlotBuffer(slot, b) Pointer slot; /* slot to change */ Buffer b; /* tuple descriptor */ { Buffer oldb = SlotBuffer((TupleTableSlot) slot); SetSlotBuffer((TupleTableSlot) slot, b); return oldb; } /* -------------------------------- * ExecIncrSlotBufferRefcnt * * When we pass around buffers in the tuple table, we have to * be careful to increment reference counts appropriately. * This is used mainly in the mergejoin code. * -------------------------------- */ void ExecIncrSlotBufferRefcnt(slot) Pointer slot; /* slot to bump refcnt */ { Buffer b = SlotBuffer((TupleTableSlot) slot); if (BufferIsValid(b)) IncrBufferRefCount(b); } /* ---------------------------------------------------------------- * tuple table slot status predicates * ---------------------------------------------------------------- */ /* ---------------- * ExecNullSlot * * This is used mainly to detect when there are no more * tuples to process. The TupIsNull() macro calls this. * ---------------- */ bool /* return: true if tuple in slot is NULL */ ExecNullSlot(slot) Pointer slot; /* slot to check */ { Pointer tuple; /* contents of slot (returned) */ /* ---------------- * if the slot itself is null then we return true * ---------------- */ if (slot == NULL) return true; /* ---------------- * get information from the slot and return true or * false depending on the contents of the slot. * ---------------- */ tuple = SlotContents(slot); return (tuple == NULL ? true : false); } /* -------------------------------- * ExecSlotDescriptorIsNew * * This function is used to check if the tuple descriptor * associated with this slot has just changed. ie: we are * now storing a new type of tuple in this slot * -------------------------------- */ bool /* return: descriptor "is new" */ ExecSlotDescriptorIsNew(slot) Pointer slot; /* slot to inspect */ { bool isNew = SlotTupleDescriptorIsNew((TupleTableSlot) slot); return isNew; } /* ---------------------------------------------------------------- * convenience initialization routines * ---------------------------------------------------------------- */ /* -------------------------------- * ExecInit{Result,Scan,Raw,Marked,Outer,Hash}TupleSlot * * These are convience routines to initialize the specfied slot * in nodes inheriting the appropriate state. * -------------------------------- */ #define INIT_SLOT_DEFS \ TupleTable tupleTable; \ int slotnum; \ Pointer slot #define INIT_SLOT_ALLOC \ tupleTable = (TupleTable) get_es_tupleTable(estate); \ slotnum = ExecAllocTableSlot(tupleTable); \ slot = ExecGetTableSlot(tupleTable, slotnum); \ SetSlotContents((TupleTableSlot) slot, NULL); \ SetSlotShouldFree((TupleTableSlot) slot, true); \ SetSlotTupleDescriptor((TupleTableSlot) slot, (TupleDescriptor) NULL); \ SetSlotExecTupDescriptor((TupleTableSlot) slot, (ExecTupDescriptor) NULL); \ SetSlotWhichPlan((TupleTableSlot) slot, -1); \ SetSlotTupleDescriptorIsNew((TupleTableSlot) slot, true) /* ---------------- * ExecInitResultTupleSlot * ---------------- */ void ExecInitResultTupleSlot(estate, commonstate) EState estate; CommonState commonstate; { INIT_SLOT_DEFS; INIT_SLOT_ALLOC; set_cs_ResultTupleSlot(commonstate, (TupleTableSlot) slot); } /* ---------------- * ExecInitScanTupleSlot * ---------------- */ void ExecInitScanTupleSlot(estate, commonscanstate) EState estate; CommonScanState commonscanstate; { INIT_SLOT_DEFS; INIT_SLOT_ALLOC; set_css_ScanTupleSlot(commonscanstate, (TupleTableSlot)slot); } /* ---------------- * ExecInitRawTupleSlot * ---------------- */ void ExecInitRawTupleSlot(estate, commonscanstate) EState estate; CommonScanState commonscanstate; { INIT_SLOT_DEFS; INIT_SLOT_ALLOC; set_css_RawTupleSlot(commonscanstate, (TupleTableSlot)slot); } /* ---------------- * ExecInitMarkedTupleSlot * ---------------- */ void ExecInitMarkedTupleSlot(estate, mergestate) EState estate; MergeJoinState mergestate; { INIT_SLOT_DEFS; INIT_SLOT_ALLOC; set_mj_MarkedTupleSlot(mergestate, (TupleTableSlot) slot); } /* ---------------- * ExecInitOuterTupleSlot * ---------------- */ void ExecInitOuterTupleSlot(estate, hashstate) EState estate; HashJoinState hashstate; { INIT_SLOT_DEFS; INIT_SLOT_ALLOC; set_hj_OuterTupleSlot(hashstate, slot); } /* ---------------- * ExecInitHashTupleSlot * ---------------- */ void ExecInitHashTupleSlot(estate, hashstate) EState estate; HashJoinState hashstate; { INIT_SLOT_DEFS; INIT_SLOT_ALLOC; set_hj_HashTupleSlot(hashstate, slot); } TupleTableSlot NodeGetResultTupleSlot(node) Plan node; { TupleTableSlot slot; union { ResultState resstate; ScanState scanstate; NestLoopState nlstate; MaterialState matstate; SortState sortstate; AggState aggstate; HashState hashstate; UniqueState uniquestate; MergeJoinState mergestate; HashJoinState hashjoinstate; ScanTempState scantempstate; } s; switch(NodeType(node)) { case classTag(Result): s.resstate = get_resstate((Result) node); slot = get_cs_ResultTupleSlot( (CommonState) s.resstate); break; case classTag(SeqScan): s.scanstate = get_scanstate((Scan) node); slot = get_cs_ResultTupleSlot((CommonState) s.scanstate); break; case classTag(ScanTemps): s.scantempstate = get_scantempState((ScanTemps) node); slot = get_cs_ResultTupleSlot((CommonState) s.scantempstate); break; case classTag(NestLoop): s.nlstate = get_nlstate((NestLoop) node); slot = get_cs_ResultTupleSlot((CommonState) s.nlstate); break; case classTag(Append): { AppendState unionstate; List unionplans; int whichplan; Plan subplan; unionstate = get_unionstate((Append) node); unionplans = get_unionplans((Append) node); whichplan = get_as_whichplan(unionstate); subplan = (Plan) nth(whichplan, unionplans); slot = NodeGetResultTupleSlot(subplan); break; } case classTag(IndexScan): s.scanstate = get_scanstate((Scan) node); slot = get_cs_ResultTupleSlot((CommonState) s.scanstate); break; case classTag(Material): s.matstate = get_matstate((Material) node); slot = get_css_ScanTupleSlot((CommonScanState) s.matstate); break; case classTag(Sort): s.sortstate = get_sortstate((Sort) node); slot = get_css_ScanTupleSlot((CommonScanState) s.sortstate); break; case classTag(Agg): s.aggstate = get_aggstate((Agg) node); slot = get_cs_ResultTupleSlot((CommonState) s.aggstate); break; case classTag(Hash): s.hashstate = get_hashstate((Hash) node); slot = get_cs_ResultTupleSlot((CommonState) s.hashstate); break; case classTag(Unique): s.uniquestate = get_uniquestate((Unique) node); slot = get_cs_ResultTupleSlot((CommonState) s.uniquestate); break; case classTag(MergeJoin): s.mergestate = get_mergestate((MergeJoin) node); slot = get_cs_ResultTupleSlot((CommonState) s.mergestate); break; case classTag(HashJoin): s.hashjoinstate = get_hashjoinstate((HashJoin) node); slot = get_cs_ResultTupleSlot((CommonState) s.hashjoinstate); break; default: /* ---------------- * should never get here * ---------------- */ elog(DEBUG, "NodeGetResultTupleSlot: node not yet supported: %d ", NodeGetTag(node)); return NULL; } return slot; } /* ---------------------------------------------------------------- * old lisp support routines * ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- * ExecGetTupType * * this gives you the tuple descriptor for tuples returned * by this node. I really wish I could ditch this routine, * but since not all nodes store their type info in the same * place, we have to do something special for each node type. * * Soon, the system will have to adapt to deal with changing * tuple descriptors as we deal with dynamic tuple types * being returned from procedure nodes. Perhaps then this * routine can be retired. -cim 6/3/91 * * old comments * This routine just gets the type information out of the * node's state. If you already have a node's state, you * can get this information directly, but this is a useful * routine if you want to get the type information from * the node's inner or outer subplan easily without having * to inspect the subplan.. -cim 10/16/89 * * Assume that for existential nodes, we get the targetlist out * of the right node's targetlist * ---------------------------------------------------------------- */ TupleDescriptor ExecGetTupType(node) Plan node; { TupleTableSlot slot; TupleDescriptor tupType; if (node == NULL) return NULL; slot = NodeGetResultTupleSlot(node); tupType = ExecSlotDescriptor((Pointer) slot); return tupType; } TupleDescriptor ExecCopyTupType(td, natts) TupleDescriptor td; int natts; { TupleDescriptor newTd; int i; newTd = CreateTemplateTupleDesc(natts); i = 0; while (i < natts) { newTd->data[i] = (AttributeTupleForm)palloc( sizeof(AttributeTupleFormD) ); bcopy(td->data[i], newTd->data[i], sizeof(AttributeTupleFormD)); i++; } return newTd; } ExecTupDescriptor ExecGetExecTupDesc(node) Plan node; { TupleTableSlot slot; ExecTupDescriptor execTupDesc; if (node == NULL) return NULL; slot = NodeGetResultTupleSlot(node); execTupDesc = ExecSlotExecDescriptor(slot); return execTupDesc; } /* ---------------------------------------------------------------- * ExecTypeFromTL * * Currently there are about 4 different places where we create * TupleDescriptors. They should all be merged, or perhaps * be rewritten to call BuildDesc(). * * old comments * Forms attribute type info from the target list in the node. * It assumes all domains are individually specified in the target list. * It fails if the target list contains something like Emp.all * which represents all the attributes from EMP relation. * * Conditions: * The inner and outer subtrees should be initialized because it * might be necessary to know the type infos of the subtrees. * ---------------------------------------------------------------- */ /**** xxref: * ExecInitIndexScan * ExecInitMergeJoin * ExecInitNestLoop * ExecInitResult * ExecInitSeqScan ****/ TupleDescriptor ExecTypeFromTL(targetList) List targetList; { List tlcdr; TupleDescriptor typeInfo; Resdom resdom; ObjectId restype; int len; /* ---------------- * examine targetlist - if empty then return NULL * ---------------- */ len = ExecTargetListLength(targetList); if (len == 0) return NULL; /* ---------------- * allocate a new typeInfo * ---------------- */ typeInfo = ExecMakeTypeInfo(len); if (typeInfo == NULL) elog(DEBUG, "ExecTypeFromTL: ExecMakeTypeInfo returns null."); /* ---------------- * notes: get resdom from (resdom expr) * get_typbyval comes from src/lib/l-lisp/lsyscache.c * ---------------- */ tlcdr = targetList; while (! lispNullp(tlcdr)) { if (tl_is_resdom(CAR(tlcdr))) { resdom = (Resdom) tl_resdom(CAR(tlcdr)); restype = get_restype(resdom); ExecSetTypeInfo((int) get_resno(resdom) - 1, /* index */ (struct attribute **) typeInfo, /* type info addr */ (ObjectId) restype, /* type id */ (int) get_resno(resdom), /* att num */ (int) get_reslen(resdom), /* att len */ (char *) get_resname(resdom), /* att name */ get_typbyval(restype)); /* att by val */ } else { Resdom fjRes; List fjTlistP; List fjList = CAR(tlcdr); Fjoin fjNode = (Fjoin)tl_node(fjList); fjRes = (Resdom)tl_resdom(get_fj_innerNode(fjNode)); restype = get_restype(fjRes); ExecSetTypeInfo( (int) get_resno(fjRes) - 1, /* index */ (struct attribute **) typeInfo, /* addr of type info */ (ObjectId) restype, /* type id */ (int) get_resno(fjRes), /* att num */ (int) get_reslen(fjRes), /* att len */ (char *) get_resname(fjRes), /* att name */ get_typbyval(restype)); /* att by val */ foreach(fjTlistP, CDR(fjList)) { List fjTle = CAR(fjTlistP); fjRes = (Resdom)tl_resdom(fjTle); ExecSetTypeInfo( (int) get_resno(fjRes) - 1, /* index */ (struct attribute **) typeInfo, /* addr of type info */ (ObjectId) get_restype(fjRes), /* type id */ (int) get_resno(fjRes), /* att num */ (int) get_reslen(fjRes), /* att len */ (char *) get_resname(fjRes), /* att name */ get_typbyval(get_restype(fjRes))); /* att by val */ } /* foreach */ } /* else tl_is_resdom */ tlcdr = CDR(tlcdr); } /* while (! lispNullp(tlcdr)) */ return typeInfo; } /* * function to convert from an ExecTupDescriptor to a flat Tuple Descriptor */ TupleDescriptor ExecTupDescToTupDesc(execTupDesc,len) ExecTupDescriptor execTupDesc; int len; { int i, j; TupleDescriptor tupdesc; int tdlen; int count; tdlen = 0; for (i=0; idata[i]->len; tupdesc = CreateTemplateTupleDesc(tdlen); count = 0; for (i=0; idata[i]->len; j++) { tupdesc->data[count] = (AttributeTupleForm) palloc(sizeof(AttributeTupleFormD)); bcopy(execTupDesc->data[i]->attdesc->data[j], tupdesc->data[count], sizeof(AttributeTupleFormD)); tupdesc->data[count++]->attcacheoff = -1; } } return tupdesc; } /* * function to convert from a Tuple Descriptor to an ExecTupDescriptor */ ExecTupDescriptor TupDescToExecTupDesc(tupDesc, len) TupleDescriptor tupDesc; int len; { ExecTupDescriptor execTupDesc; int i; execTupDesc = ExecMakeExecTupDesc(len); for (i=0; idata[i] = MakeExecAttDesc(ATTVAL, 1, (TupleDescriptor)tupDesc->data[i]); } return execTupDesc; } @ 1.18 log @fixed bug in ExecTypeFromTL where every node in an Fjoin was getting assigned the type of the first node. @ text @d114 1 a114 1 * $Header: /local/src/postgres/src/backend/executor/RCS/ex_tuples.c,v 1.17 1992/08/04 17:37:46 mer Exp paxson $ d121 1 a121 1 RcsId("$Header: /local/src/postgres/src/backend/executor/RCS/ex_tuples.c,v 1.17 1992/08/04 17:37:46 mer Exp paxson $"); d123 2 @ 1.17 log @must recursively count needed slots for plans for table allocation @ text @d114 1 a114 1 * $Header: /users/mer/pg/src/executor/RCS/ex_tuples.c,v 1.16 1992/07/13 03:25:38 hong Exp mer $ d121 1 a121 1 RcsId("$Header: /users/mer/pg/src/executor/RCS/ex_tuples.c,v 1.16 1992/07/13 03:25:38 hong Exp mer $"); d1115 1 a1115 1 (ObjectId) restype, /* type id */ @ 1.16 log @prototyping @ text @d114 1 a114 1 * $Header: executor/RCS/ex_tuples.c,v 1.15 92/07/09 03:54:04 hong Exp Locker: hong $ d121 1 a121 1 RcsId("$Header: executor/RCS/ex_tuples.c,v 1.15 92/07/09 03:54:04 hong Exp Locker: hong $"); d288 7 d298 10 a307 6 int newsize = NewTableSize(table->size); pfree(table->array); table->array = (Pointer) palloc(newsize * TableSlotSize); bzero(table->array, newsize * TableSlotSize); table->size = newsize; @ 1.15 log @changes to allow arbitrary number of tuple arguments in functions @ text @d114 1 a114 1 * $Header: RCS/ex_tuples.c,v 1.14 92/07/06 06:16:20 mer Exp $ d121 1 a121 1 RcsId("$Header: RCS/ex_tuples.c,v 1.14 92/07/06 06:16:20 mer Exp $"); d1165 1 a1165 1 execTupDesc->data[i] = MakeExecAttDesc(ATTVAL, 1, tupDesc->data[i]); @ 1.14 log @wasn't setting restype at all for fjoin nodes in target list (oops) @ text @d114 1 a114 1 * $Header: /users/mer/pg/src/executor/RCS/ex_tuples.c,v 1.13 1992/07/04 04:30:16 mer Exp mer $ d121 1 a121 1 RcsId("$Header: /users/mer/pg/src/executor/RCS/ex_tuples.c,v 1.13 1992/07/04 04:30:16 mer Exp mer $"); d717 1 d805 3 a807 33 /* ---------------------------------------------------------------- * old lisp support routines * ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- * ExecGetTupType * * this gives you the tuple descriptor for tuples returned * by this node. I really wish I could ditch this routine, * but since not all nodes store their type info in the same * place, we have to do something special for each node type. * * Soon, the system will have to adapt to deal with changing * tuple descriptors as we deal with dynamic tuple types * being returned from procedure nodes. Perhaps then this * routine can be retired. -cim 6/3/91 * * old comments * This routine just gets the type information out of the * node's state. If you already have a node's state, you * can get this information directly, but this is a useful * routine if you want to get the type information from * the node's inner or outer subplan easily without having * to inspect the subplan.. -cim 10/16/89 * * Assume that for existential nodes, we get the targetlist out * of the right node's targetlist * ---------------------------------------------------------------- */ TupleDescriptor ExecGetTupType(node) Plan node; d809 1 a809 2 TupleTableSlot slot; TupleDescriptor tupType; a822 3 if (node == NULL) return NULL; d831 1 a831 2 tupType = ExecSlotDescriptor((Pointer) slot); return tupType; d837 1 a837 2 tupType = ExecSlotDescriptor((Pointer) slot); return tupType; d843 1 a843 2 tupType = ExecSlotDescriptor((Pointer) slot); return tupType; d849 1 a849 2 tupType = ExecSlotDescriptor((Pointer) slot); return tupType; d863 2 a864 2 return ExecGetTupType(subplan); d871 1 a871 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d877 1 a877 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d883 1 a883 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d889 1 a889 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d895 1 a895 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d901 1 a901 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d907 1 a907 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d913 1 a913 2 tupType = ExecSlotDescriptor( (Pointer) slot); return tupType; d920 1 a920 1 elog(DEBUG, "ExecGetTupType: node not yet supported: %d ", d925 1 d927 45 d973 35 d1119 49 @ 1.13 log @walk the new-fangled tlist correctly and set the result type @ text @d114 1 a114 1 * $Header: /private/mer/pg/src/executor/RCS/ex_tuples.c,v 1.12 1992/06/22 17:20:35 mer Exp mer $ d121 1 a121 1 RcsId("$Header: /private/mer/pg/src/executor/RCS/ex_tuples.c,v 1.12 1992/06/22 17:20:35 mer Exp mer $"); d1050 2 d1059 1 a1059 1 get_typbyval(get_restype(fjRes))); /* att by val */ @ 1.12 log @changes to support delete / replace with inheritance (append plans) @ text @d114 1 a114 1 * $Header: /private/mer/pg2/src/executor/RCS/ex_tuples.c,v 1.11 1992/03/31 23:10:44 mer Exp mer $ d121 1 a121 1 RcsId("$Header: /private/mer/pg2/src/executor/RCS/ex_tuples.c,v 1.11 1992/03/31 23:10:44 mer Exp mer $"); d1011 4 a1014 3 len = length(targetList); if (len == 0) return NULL; d1031 3 a1033 2 resdom = (Resdom) tl_resdom(CAR(tlcdr)); restype = get_restype(resdom); d1035 38 a1072 7 ExecSetTypeInfo((int) get_resno(resdom) - 1, /* index */ (struct attribute **) typeInfo, /* addr of type info */ (ObjectId) restype, /* type id */ (int) get_resno(resdom), /* att num */ (int) get_reslen(resdom), /* att len */ (char *) get_resname(resdom), /* att name */ get_typbyval(restype)); /* att by val */ d1074 2 d1077 2 a1078 1 } @ 1.11 log @change accessor functions into macros @ text @d114 1 a114 1 * $Header: /users/mer/pg/src/executor/RCS/ex_tuples.c,v 1.10 1992/03/05 23:42:17 mer Exp mer $ d121 1 a121 1 RcsId("$Header: /users/mer/pg/src/executor/RCS/ex_tuples.c,v 1.10 1992/03/05 23:42:17 mer Exp mer $"); d717 1 @ 1.10 log @change some heavily used functions into macros @ text @d114 1 a114 1 * $Header: RCS/ex_tuples.c,v 1.9 91/11/17 21:10:46 mer Exp Locker: mer $ d121 1 a121 1 RcsId("$Header: RCS/ex_tuples.c,v 1.9 91/11/17 21:10:46 mer Exp Locker: mer $"); d744 1 a744 1 set_css_ScanTupleSlot(commonscanstate, slot); d758 1 a758 1 set_css_RawTupleSlot(commonscanstate, slot); @ 1.9 log @prototyping @ text @d114 1 a114 1 * $Header: /users/mer/postgres/src/executor/RCS/ex_tuples.c,v 1.8 1991/11/14 11:00:58 glass Exp mer $ d121 1 a121 1 RcsId("$Header: /users/mer/postgres/src/executor/RCS/ex_tuples.c,v 1.8 1991/11/14 11:00:58 glass Exp mer $"); d434 2 a436 5 Pointer /* return: address of tuple */ ExecFetchTuple(slot) Pointer slot; /* slot from which fetch store tuple */ { Pointer tuple; /* contents of slot (returned) */ a437 18 /* ---------------- * if the slot itself is null then we return NULL. we do not * differentiate between a NULL slot pointer and a pointer to * a slot containing NULL. * ---------------- */ if (slot == NULL) return NULL; /* ---------------- * get information from the slot and return it * ---------------- */ tuple = SlotContents(slot); return tuple; } d537 2 a540 7 TupleDescriptor /* return: tuple descriptor */ ExecSlotDescriptor(slot) Pointer slot; /* slot to inspect */ { TupleDescriptor tupdesc = SlotTupleDescriptor((TupleTableSlot) slot); return tupdesc; } d600 2 a603 7 Buffer /* return: tuple descriptor */ ExecSlotBuffer(slot) Pointer slot; /* slot to inspect */ { Buffer b = SlotBuffer((TupleTableSlot) slot); return b; } @ 1.8 log @fixes due to prototypes @ text @d114 1 a114 1 * $Header: RCS/ex_tuples.c,v 1.6 91/11/05 05:33:59 mer Exp Locker: glass $ d121 1 a121 1 RcsId("$Header: RCS/ex_tuples.c,v 1.6 91/11/05 05:33:59 mer Exp Locker: glass $"); d1064 1 a1064 1 /*bug ??? - glass */ (struct attribute **) typeInfo, /* addr of type info */ d1068 2 a1069 2 (Name) get_resname(resdom), /* att name */ get_typbyval(restype)); /* att by val */ @ 1.7 log @fixes due to prototypes @ text @d114 1 a114 1 * $Header: executor/RCS/ex_tuples.c,v 1.5 91/09/22 22:01:26 hong Exp $ a116 2 #include "tmp/postgres.h" d118 2 a119 1 RcsId("$Header: executor/RCS/ex_tuples.c,v 1.5 91/09/22 22:01:26 hong Exp $"); d121 1 a121 12 /* ---------------- * FILE INCLUDE ORDER GUIDELINES * * 1) execdebug.h * 2) various support files ("everything else") * 3) node files * 4) catalog/ files * 5) execdefs.h and execmisc.h * 6) externs.h comes last * ---------------- */ #include "executor/execdebug.h" a122 18 #include "parser/parsetree.h" #include "utils/log.h" #include "nodes/pg_lisp.h" #include "nodes/primnodes.h" #include "nodes/primnodes.a.h" #include "nodes/plannodes.h" #include "nodes/plannodes.a.h" #include "nodes/execnodes.h" #include "nodes/execnodes.a.h" #include "executor/execdefs.h" #include "executor/execmisc.h" #include "executor/externs.h" #undef ExecStoreTuple d231 1 a231 1 if (SlotShouldFree(slot)) { d382 1 a382 1 if (SlotShouldFree(slot) && oldtuple != NULL) { d398 2 a399 2 if (BufferIsValid(SlotBuffer(slot))) ReleaseBuffer(SlotBuffer(slot)); d406 3 a408 3 SetSlotContents(slot, tuple); SetSlotBuffer(slot, buffer); SetSlotShouldFree(slot, shouldFree); d487 1 a487 1 if (SlotShouldFree(slot) && oldtuple != NULL) { d506 2 a507 2 if (BufferIsValid(SlotBuffer(slot))) ReleaseBuffer(SlotBuffer(slot)); d509 2 a510 2 SetSlotBuffer(slot, InvalidBuffer); SetSlotShouldFree(slot, true); d529 1 a529 1 bool shouldFree = SlotShouldFree(slot); d547 2 a548 2 bool old_shouldFree = SlotShouldFree(slot); SetSlotShouldFree(slot, shouldFree); d564 1 a564 1 TupleDescriptor tupdesc = SlotTupleDescriptor(slot); d580 2 a581 2 TupleDescriptor old_tupdesc = SlotTupleDescriptor(slot); SetSlotTupleDescriptor(slot, tupdesc); d597 1 a597 1 SetSlotTupleDescriptorIsNew(slot, isNew); d612 3 a614 3 TupleDescriptor old_tupdesc = SlotTupleDescriptor(slot); SetSlotTupleDescriptor(slot, tupdesc); SetSlotTupleDescriptorIsNew(slot, true); d632 1 a632 1 Buffer b = SlotBuffer(slot); d650 2 a651 2 Buffer oldb = SlotBuffer(slot); SetSlotBuffer(slot, b); d668 1 a668 1 Buffer b = SlotBuffer(slot); d721 1 a721 1 bool isNew = SlotTupleDescriptorIsNew(slot); d745 4 a748 4 SetSlotContents(slot, NULL); \ SetSlotShouldFree(slot, true); \ SetSlotTupleDescriptor(slot, (TupleDescriptor) NULL); \ SetSlotTupleDescriptorIsNew(slot, true) d761 1 a761 1 set_cs_ResultTupleSlot(commonstate, slot); d803 1 a803 1 set_mj_MarkedTupleSlot(mergestate, slot); d817 1 a817 1 set_hj_OuterTupleSlot(hashstate, slot); d890 5 a894 3 s.resstate = get_resstate(node); slot = get_cs_ResultTupleSlot(s.resstate); tupType = ExecSlotDescriptor(slot); d898 4 a901 3 s.scanstate = get_scanstate(node); slot = get_cs_ResultTupleSlot(s.scanstate); tupType = ExecSlotDescriptor(slot); d905 4 a908 3 s.scantempstate = get_scantempState(node); slot = get_cs_ResultTupleSlot(s.scantempstate); tupType = ExecSlotDescriptor(slot); d912 4 a915 3 s.nlstate = get_nlstate(node); slot = get_cs_ResultTupleSlot(s.nlstate); tupType = ExecSlotDescriptor(slot); d925 2 a926 2 unionstate = get_unionstate(node); unionplans = get_unionplans(node); d935 4 a938 3 s.scanstate = get_scanstate(node); slot = get_cs_ResultTupleSlot(s.scanstate); tupType = ExecSlotDescriptor(slot); d942 4 a945 3 s.matstate = get_matstate(node); slot = get_css_ScanTupleSlot(s.matstate); tupType = ExecSlotDescriptor(slot); d949 4 a952 3 s.sortstate = get_sortstate(node); slot = get_css_ScanTupleSlot(s.sortstate); tupType = ExecSlotDescriptor(slot); d956 4 a959 3 s.aggstate = get_aggstate(node); slot = get_css_ScanTupleSlot(s.aggstate); tupType = ExecSlotDescriptor(slot); d963 4 a966 3 s.hashstate = get_hashstate(node); slot = get_cs_ResultTupleSlot(s.hashstate); tupType = ExecSlotDescriptor(slot); d970 4 a973 3 s.uniquestate = get_uniquestate(node); slot = get_cs_ResultTupleSlot(s.uniquestate); tupType = ExecSlotDescriptor(slot); d977 4 a980 3 s.mergestate = get_mergestate(node); slot = get_cs_ResultTupleSlot(s.mergestate); tupType = ExecSlotDescriptor(slot); d984 4 a987 3 s.hashjoinstate = get_hashjoinstate(node); slot = get_cs_ResultTupleSlot(s.hashjoinstate); tupType = ExecSlotDescriptor(slot); d1063 6 a1068 6 ExecSetTypeInfo(get_resno(resdom) - 1, /* index */ typeInfo, /* addr of type info */ restype, /* type id */ get_resno(resdom), /* att num */ get_reslen(resdom), /* att len */ get_resname(resdom), /* att name */ @ 1.6 log @get aggregate tuple return type from the result slot (not scan) @ text @d114 1 a114 1 * $Header: /users/mer/postgres/src/executor/RCS/ex_tuples.c,v 1.5 1991/09/22 22:01:26 hong Exp mer $ d120 1 a120 1 RcsId("$Header: /users/mer/postgres/src/executor/RCS/ex_tuples.c,v 1.5 1991/09/22 22:01:26 hong Exp mer $"); d979 1 a979 1 slot = get_cs_ResultTupleSlot(s.aggstate); @ 1.5 log @fixed another problem of mis-using tuple descriptors @ text @d114 1 a114 1 * $Header: RCS/ex_tuples.c,v 1.4 91/08/15 17:38:08 caetta Exp $ d120 1 a120 1 RcsId("$Header: RCS/ex_tuples.c,v 1.4 91/08/15 17:38:08 caetta Exp $"); d979 1 a979 1 slot = get_css_ScanTupleSlot(s.aggstate); @ 1.4 log @more supplementing aggregates @ text @d49 2 a50 2 * ExecInitSavedTupleSlot / * ExecInitTemporaryTupleSlot / d114 1 a114 1 * $Header: executor/RCS/ex_tuples.c,v 1.3 91/07/17 23:54:08 hong Exp Locker: caetta $ d120 1 a120 1 RcsId("$Header: executor/RCS/ex_tuples.c,v 1.3 91/07/17 23:54:08 hong Exp Locker: caetta $"); d760 1 a760 1 * ExecInit{Result,Scan,Raw,Marked,Saved,Temporary}TupleSlot d837 1 a837 1 * ExecInitSavedTupleSlot d841 1 a841 1 ExecInitSavedTupleSlot(estate, hashstate) d847 1 a847 1 set_hj_SavedTupleSlot(hashstate, slot); d851 1 a851 1 * ExecInitTemporaryTupleSlot d855 1 a855 1 ExecInitTemporaryTupleSlot(estate, hashstate) d861 1 a861 1 set_hj_TemporaryTupleSlot(hashstate, slot); @ 1.3 log @get rid of a compile warning @ text @d114 1 a114 1 * $Header: RCS/ex_tuples.c,v 1.2 91/07/09 02:44:57 mao Exp Locker: hong $ d120 1 a120 1 RcsId("$Header: RCS/ex_tuples.c,v 1.2 91/07/09 02:44:57 mao Exp Locker: hong $"); d906 1 d977 6 @ 1.2 log @get rid of compile-time warnings @ text @d114 1 a114 1 * $Header: /users/mao/postgres/src/executor/RCS/ex_tuples.c,v 1.1 1991/06/18 23:31:59 cimarron Exp mao $ d120 1 a120 1 RcsId("$Header: /users/mao/postgres/src/executor/RCS/ex_tuples.c,v 1.1 1991/06/18 23:31:59 cimarron Exp mao $"); d966 1 a966 1 slot = (TupleTableSlot) get_css_ScanTupleSlot(s.matstate); d972 1 a972 1 slot = (TupleTableSlot) get_css_ScanTupleSlot(s.sortstate); @ 1.1 log @Initial revision @ text @d114 1 a114 1 * $Header: RCS/tuples.c,v 1.31 91/05/23 18:19:53 kemnitz Exp Locker: cimarron $ d120 1 a120 1 RcsId("$Header: RCS/tuples.c,v 1.31 91/05/23 18:19:53 kemnitz Exp Locker: cimarron $"); d966 1 a966 1 slot = get_css_ScanTupleSlot(s.matstate); d972 1 a972 1 slot = get_css_ScanTupleSlot(s.sortstate); @