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

#include "postgres.h"

#include "executor/execdebug.h"
#include "executor/nodeWorktablescan.h"

static TupleTableSlot *WorkTableScanNext(WorkTableScanState *node);

/* ----------------------------------------------------------------
 *		WorkTableScanNext
 *
 *		This is a workhorse for ExecWorkTableScan
 * ----------------------------------------------------------------
 */
static TupleTableSlot *
WorkTableScanNext(WorkTableScanState *node)
{
	TupleTableSlot *slot;
	Tuplestorestate *tuplestorestate;

	/*
	 * get information from the estate and scan state
	 *
	 * Note: we intentionally do not support backward scan.  Although it would
	 * take only a couple more lines here, it would force nodeRecursiveunion.c
	 * to create the tuplestore with backward scan enabled, which has a
	 * performance cost.  In practice backward scan is never useful for a
	 * worktable plan node, since it cannot appear high enough in the plan
	 * tree of a scrollable cursor to be exposed to a backward-scan
	 * requirement.  So it's not worth expending effort to support it.
	 *
	 * Note: we are also assuming that this node is the only reader of the
	 * worktable.  Therefore, we don't need a private read pointer for the
	 * tuplestore, nor do we need to tell tuplestore_gettupleslot to copy.
	 */

	/*
	 * RECURSIVE_CTE_FIXME: Double check we don't have backward scan required by
	 * plan (both planner and ORCA).
	 */
	Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));

	tuplestorestate = node->rustate->working_table;
	tuplestore_select_read_pointer(tuplestorestate, node->readptr);

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

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

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

	return ExecScan(&node->ss,
					(ExecScanAccessMtd) WorkTableScanNext,
					(ExecScanRecheckMtd) WorkTableScanRecheck);
}


/* ----------------------------------------------------------------
 *		ExecInitWorkTableScan
 * ----------------------------------------------------------------
 */
WorkTableScanState *
ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
{
	WorkTableScanState *scanstate;
	ParamExecData *param;

	/* check for unsupported flags */
	/*
	 * RECURSIVE_CTE_FIXME: Make sure we don't require EXEC_FLAG_BACKWARD
	 * in GPDB.
	 */
	Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));

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

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

	/* In postgres, it can generate CTE SubPlans for WITH subqueries, if a CTE subplan have outer
	 * recursive refs with outer recursive CTE, it will exist a WorkTable in subplan. And initialize
	 * state information for subplans will be before initialize on the main query tree, so there are
	 * corner cases where we'll get the init call before the RecursiveUnion does.
	 * IN GPDB, we don't have CTE scan node, so we won't generate CTE subplan for WITH subqueries,
	 * also we won't call the ExecInitWorkTableScan func before ExecInitRecursiveUnion. Set rustate
	 * in the INIT step.
	 */
	param = &(estate->es_param_exec_vals[node->wtParam]);
	Assert(param->execPlan == NULL);
	Assert(!param->isnull);
	scanstate->rustate = castNode(RecursiveUnionState, DatumGetPointer(param->value));
	if (scanstate->rustate->refcount == 0)
		scanstate->readptr = 0;
	else
	{
		/* during node init, the work table hasn't been scanned yet, it must be at start, don't need to rescan here*/
		scanstate->readptr = tuplestore_alloc_read_pointer(scanstate->rustate->working_table, EXEC_FLAG_REWIND);
	}
	scanstate->rustate->refcount++;

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

	/*
	 * tuple table initialization
	 */
	ExecInitResultTypeTL(&scanstate->ss.ps);

	/* signal that return type is not yet known */
	scanstate->ss.ps.resultopsset = true;
	scanstate->ss.ps.resultopsfixed = false;

	/* The scan tuple type (ie, the rowtype we expect to find in the work
	 * table) is the same as the result rowtype of the ancestor
	 * RecursiveUnion node.  Note this depends on the assumption that
	 * RecursiveUnion doesn't allow projection.
	 */
	ExecInitScanTupleSlot(estate, &scanstate->ss, ExecGetResultType(&scanstate->rustate->ps), &TTSOpsMinimalTuple);
	ExecAssignScanProjectionInfo(&scanstate->ss);

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

	/*
	 * Do not yet initialize projection info, see ExecWorkTableScan() for
	 * details.
	 */

	return scanstate;
}

/* ----------------------------------------------------------------
 *		ExecEndWorkTableScan
 *
 *		frees any storage allocated through C routines.
 * ----------------------------------------------------------------
 */
void
ExecEndWorkTableScan(WorkTableScanState *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);
}

/* ----------------------------------------------------------------
 *		ExecReScanWorkTableScan
 *
 *		Rescans the relation.
 * ----------------------------------------------------------------
 */
void
ExecReScanWorkTableScan(WorkTableScanState *node)
{
	if (node->ss.ps.ps_ResultTupleSlot)
		ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

	ExecScanReScan(&node->ss);

	/* No need (or way) to rescan if ExecWorkTableScan not called yet */
	if (node->rustate)
	{
		tuplestore_select_read_pointer(node->rustate->working_table, node->readptr);
		tuplestore_rescan(node->rustate->working_table);
	}
}
