⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nodeseqscan.c

📁 PostgreSQL7.4.6 for Linux
💻 C
字号:
/*------------------------------------------------------------------------- * * nodeSeqscan.c *	  Support routines for sequential scans of relations. * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.46 2003/08/08 21:41:42 momjian Exp $ * *------------------------------------------------------------------------- *//* * INTERFACE ROUTINES *		ExecSeqScan				sequentially scans a relation. *		ExecSeqNext				retrieve next tuple in sequential order. *		ExecInitSeqScan			creates and initializes a seqscan node. *		ExecEndSeqScan			releases any storage allocated. *		ExecSeqReScan			rescans the relation *		ExecSeqMarkPos			marks scan position *		ExecSeqRestrPos			restores scan position */#include "postgres.h"#include "access/heapam.h"#include "executor/execdebug.h"#include "executor/nodeSeqscan.h"#include "parser/parsetree.h"static void InitScanRelation(SeqScanState *node, EState *estate);static TupleTableSlot *SeqNext(SeqScanState *node);/* ---------------------------------------------------------------- *						Scan Support * ---------------------------------------------------------------- *//* ---------------------------------------------------------------- *		SeqNext * *		This is a workhorse for ExecSeqScan * ---------------------------------------------------------------- */static TupleTableSlot *SeqNext(SeqScanState *node){	HeapTuple	tuple;	HeapScanDesc scandesc;	Index		scanrelid;	EState	   *estate;	ScanDirection direction;	TupleTableSlot *slot;	/*	 * get information from the estate and scan state	 */	estate = node->ps.state;	scandesc = node->ss_currentScanDesc;	scanrelid = ((SeqScan *) node->ps.plan)->scanrelid;	direction = estate->es_direction;	slot = node->ss_ScanTupleSlot;	/*	 * Check if we are evaluating PlanQual for tuple of this relation.	 * Additional checking is not good, but no other way for now. We could	 * introduce new nodes for this case and handle SeqScan --> NewNode	 * switching in Init/ReScan plan...	 */	if (estate->es_evTuple != NULL &&		estate->es_evTuple[scanrelid - 1] != NULL)	{		ExecClearTuple(slot);		if (estate->es_evTupleNull[scanrelid - 1])			return slot;		/* return empty slot */		ExecStoreTuple(estate->es_evTuple[scanrelid - 1],					   slot, InvalidBuffer, false);		/*		 * Note that unlike IndexScan, SeqScan never use keys in		 * heap_beginscan (and this is very bad) - so, here we do not		 * check are keys ok or not.		 */		/* Flag for the next call that no more tuples */		estate->es_evTupleNull[scanrelid - 1] = true;		return (slot);	}	/*	 * get the next tuple from the access methods	 */	tuple = heap_getnext(scandesc, direction);	/*	 * save the tuple and the buffer returned to us by the access methods	 * in our scan tuple slot and return the slot.	Note: we pass 'false'	 * because tuples returned by heap_getnext() are pointers onto disk	 * pages and were not created with palloc() and so should not be	 * pfree()'d.  Note also that ExecStoreTuple will increment the	 * refcount of the buffer; the refcount will not be dropped until the	 * tuple table slot is cleared.	 */	slot = ExecStoreTuple(tuple,	/* tuple to store */						  slot, /* slot to store in */						  scandesc->rs_cbuf,	/* buffer associated with												 * this tuple */						  false);		/* don't pfree this pointer */	return slot;}/* ---------------------------------------------------------------- *		ExecSeqScan(node) * *		Scans the relation sequentially and returns the next qualifying *		tuple. *		It calls the ExecScan() routine and passes it the access method *		which retrieve tuples sequentially. * */TupleTableSlot *ExecSeqScan(SeqScanState *node){	/*	 * use SeqNext as access method	 */	return ExecScan((ScanState *) node, (ExecScanAccessMtd) SeqNext);}/* ---------------------------------------------------------------- *		InitScanRelation * *		This does the initialization for scan relations and *		subplans of scans. * ---------------------------------------------------------------- */static voidInitScanRelation(SeqScanState *node, EState *estate){	Index		relid;	List	   *rangeTable;	RangeTblEntry *rtentry;	Oid			reloid;	Relation	currentRelation;	HeapScanDesc currentScanDesc;	/*	 * get the relation object id from the relid'th entry in the range	 * table, open that relation and initialize the scan state.	 *	 * We acquire AccessShareLock for the duration of the scan.	 */	relid = ((SeqScan *) node->ps.plan)->scanrelid;	rangeTable = estate->es_range_table;	rtentry = rt_fetch(relid, rangeTable);	reloid = rtentry->relid;	currentRelation = heap_open(reloid, AccessShareLock);	currentScanDesc = heap_beginscan(currentRelation,									 estate->es_snapshot,									 0,									 NULL);	node->ss_currentRelation = currentRelation;	node->ss_currentScanDesc = currentScanDesc;	ExecAssignScanType(node, RelationGetDescr(currentRelation), false);}/* ---------------------------------------------------------------- *		ExecInitSeqScan * ---------------------------------------------------------------- */SeqScanState *ExecInitSeqScan(SeqScan *node, EState *estate){	SeqScanState *scanstate;	/*	 * Once upon a time it was possible to have an outerPlan of a SeqScan,	 * but not any more.	 */	Assert(outerPlan(node) == NULL);	Assert(innerPlan(node) == NULL);	/*	 * create state structure	 */	scanstate = makeNode(SeqScanState);	scanstate->ps.plan = (Plan *) node;	scanstate->ps.state = estate;	/*	 * Miscellaneous initialization	 *	 * create expression context for node	 */	ExecAssignExprContext(estate, &scanstate->ps);	/*	 * initialize child expressions	 */	scanstate->ps.targetlist = (List *)		ExecInitExpr((Expr *) node->plan.targetlist,					 (PlanState *) scanstate);	scanstate->ps.qual = (List *)		ExecInitExpr((Expr *) node->plan.qual,					 (PlanState *) scanstate);#define SEQSCAN_NSLOTS 2	/*	 * tuple table initialization	 */	ExecInitResultTupleSlot(estate, &scanstate->ps);	ExecInitScanTupleSlot(estate, scanstate);	/*	 * initialize scan relation	 */	InitScanRelation(scanstate, estate);	scanstate->ps.ps_TupFromTlist = false;	/*	 * Initialize result tuple type and projection info.	 */	ExecAssignResultTypeFromTL(&scanstate->ps);	ExecAssignScanProjectionInfo(scanstate);	return scanstate;}intExecCountSlotsSeqScan(SeqScan *node){	return ExecCountSlotsNode(outerPlan(node)) +		ExecCountSlotsNode(innerPlan(node)) +		SEQSCAN_NSLOTS;}/* ---------------------------------------------------------------- *		ExecEndSeqScan * *		frees any storage allocated through C routines. * ---------------------------------------------------------------- */voidExecEndSeqScan(SeqScanState *node){	Relation	relation;	HeapScanDesc scanDesc;	/*	 * get information from node	 */	relation = node->ss_currentRelation;	scanDesc = node->ss_currentScanDesc;	/*	 * Free the exprcontext	 */	ExecFreeExprContext(&node->ps);	/*	 * clean out the tuple table	 */	ExecClearTuple(node->ps.ps_ResultTupleSlot);	ExecClearTuple(node->ss_ScanTupleSlot);	/*	 * close heap scan	 */	heap_endscan(scanDesc);	/*	 * close the heap relation.	 *	 * Currently, we do not release the AccessShareLock acquired by	 * InitScanRelation.  This lock should be held till end of	 * transaction. (There is a faction that considers this too much	 * locking, however.)	 */	heap_close(relation, NoLock);}/* ---------------------------------------------------------------- *						Join Support * ---------------------------------------------------------------- *//* ---------------------------------------------------------------- *		ExecSeqReScan * *		Rescans the relation. * ---------------------------------------------------------------- */voidExecSeqReScan(SeqScanState *node, ExprContext *exprCtxt){	EState	   *estate;	Index		scanrelid;	HeapScanDesc scan;	estate = node->ps.state;	scanrelid = ((SeqScan *) node->ps.plan)->scanrelid;	/* If this is re-scanning of PlanQual ... */	if (estate->es_evTuple != NULL &&		estate->es_evTuple[scanrelid - 1] != NULL)	{		estate->es_evTupleNull[scanrelid - 1] = false;		return;	}	scan = node->ss_currentScanDesc;	heap_rescan(scan,			/* scan desc */				NULL);			/* new scan keys */}/* ---------------------------------------------------------------- *		ExecSeqMarkPos(node) * *		Marks scan position. * ---------------------------------------------------------------- */voidExecSeqMarkPos(SeqScanState *node){	HeapScanDesc scan;	scan = node->ss_currentScanDesc;	heap_markpos(scan);}/* ---------------------------------------------------------------- *		ExecSeqRestrPos * *		Restores scan position. * ---------------------------------------------------------------- */voidExecSeqRestrPos(SeqScanState *node){	HeapScanDesc scan;	scan = node->ss_currentScanDesc;	heap_restrpos(scan);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -