greenplumn nodeNamedtuplestorescan 源码

  • 2022-08-18
  • 浏览 (347)

greenplumn nodeNamedtuplestorescan 代码

文件路径:/src/backend/executor/nodeNamedtuplestorescan.c

/*-------------------------------------------------------------------------
 *
 * nodeNamedtuplestorescan.c
 *	  routines to handle NamedTuplestoreScan nodes.
 *
 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/executor/nodeNamedtuplestorescan.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "executor/execdebug.h"
#include "executor/nodeNamedtuplestorescan.h"
#include "miscadmin.h"
#include "utils/queryenvironment.h"

static TupleTableSlot *NamedTuplestoreScanNext(NamedTuplestoreScanState *node);

/* ----------------------------------------------------------------
 *		NamedTuplestoreScanNext
 *
 *		This is a workhorse for ExecNamedTuplestoreScan
 * ----------------------------------------------------------------
 */
static TupleTableSlot *
NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
{
	TupleTableSlot *slot;

	/* We intentionally do not support backward scan. */
	Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));

	/*
	 * Get the next tuple from tuplestore. Return NULL if no more tuples.
	 */
	slot = node->ss.ss_ScanTupleSlot;
	tuplestore_select_read_pointer(node->relation, node->readptr);
	(void) tuplestore_gettupleslot(node->relation, true, false, slot);
	return slot;
}

/*
 * NamedTuplestoreScanRecheck -- access method routine to recheck a tuple in
 * EvalPlanQual
 */
static bool
NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
{
	/* nothing to check */
	return true;
}

/* ----------------------------------------------------------------
 *		ExecNamedTuplestoreScan(node)
 *
 *		Scans the CTE sequentially and returns the next qualifying tuple.
 *		We call the ExecScan() routine and pass it the appropriate
 *		access method functions.
 * ----------------------------------------------------------------
 */
static TupleTableSlot *
ExecNamedTuplestoreScan(PlanState *pstate)
{
	NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);

	return ExecScan(&node->ss,
					(ExecScanAccessMtd) NamedTuplestoreScanNext,
					(ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
}


/* ----------------------------------------------------------------
 *		ExecInitNamedTuplestoreScan
 * ----------------------------------------------------------------
 */
NamedTuplestoreScanState *
ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
{
	NamedTuplestoreScanState *scanstate;
	EphemeralNamedRelation enr;

	/* check for unsupported flags */
	Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));

	/*
	 * NamedTuplestoreScan should not have any children.
	 */
	Assert(outerPlan(node) == NULL);
	Assert(innerPlan(node) == NULL);

	/*
	 * create new NamedTuplestoreScanState for node
	 */
	scanstate = makeNode(NamedTuplestoreScanState);
	scanstate->ss.ps.plan = (Plan *) node;
	scanstate->ss.ps.state = estate;
	scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;

	enr = get_ENR(estate->es_queryEnv, node->enrname);
	if (!enr)
		elog(ERROR, "executor could not find named tuplestore \"%s\"",
			 node->enrname);

	Assert(enr->reldata);
	scanstate->relation = (Tuplestorestate *) enr->reldata;
	scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
	scanstate->readptr =
		tuplestore_alloc_read_pointer(scanstate->relation, EXEC_FLAG_REWIND);

	/*
	 * The new read pointer copies its position from read pointer 0, which
	 * could be anywhere, so explicitly rewind it.
	 */
	tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
	tuplestore_rescan(scanstate->relation);

	/*
	 * XXX: Should we add a function to free that read pointer when done?
	 *
	 * This was attempted, but it did not improve performance or memory usage
	 * in any tested cases.
	 */

	/*
	 * Miscellaneous initialization
	 *
	 * create expression context for node
	 */
	ExecAssignExprContext(estate, &scanstate->ss.ps);

	/*
	 * The scan tuple type is specified for the tuplestore.
	 */
	ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
						  &TTSOpsMinimalTuple);

	/*
	 * Initialize result type and projection.
	 */
	ExecInitResultTypeTL(&scanstate->ss.ps);
	ExecAssignScanProjectionInfo(&scanstate->ss);

	/*
	 * initialize child expressions
	 */
	scanstate->ss.ps.qual =
		ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);

	return scanstate;
}

/* ----------------------------------------------------------------
 *		ExecEndNamedTuplestoreScan
 *
 *		frees any storage allocated through C routines.
 * ----------------------------------------------------------------
 */
void
ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
{
	/*
	 * Free exprcontext
	 */
	ExecFreeExprContext(&node->ss.ps);

	/*
	 * clean out the tuple table
	 */
	if (node->ss.ps.ps_ResultTupleSlot)
		ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
	ExecClearTuple(node->ss.ss_ScanTupleSlot);
}

/* ----------------------------------------------------------------
 *		ExecReScanNamedTuplestoreScan
 *
 *		Rescans the relation.
 * ----------------------------------------------------------------
 */
void
ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
{
	Tuplestorestate *tuplestorestate = node->relation;

	if (node->ss.ps.ps_ResultTupleSlot)
		ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

	ExecScanReScan(&node->ss);

	/*
	 * Rewind my own pointer.
	 */
	tuplestore_select_read_pointer(tuplestorestate, node->readptr);
	tuplestore_rescan(tuplestorestate);
}

相关信息

greenplumn 源码目录

相关文章

greenplumn execAmi 源码

greenplumn execCurrent 源码

greenplumn execExpr 源码

greenplumn execExprInterp 源码

greenplumn execGrouping 源码

greenplumn execIndexing 源码

greenplumn execJunk 源码

greenplumn execMain 源码

greenplumn execParallel 源码

greenplumn execPartition 源码

0  赞