/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*-------------------------------------------------------------------------
 *
 * nodeSeqscan.c
 *	  Support routines for sequential scans of relations.
 *
 * Portions Copyright (c) 2006-2008, Greenplum inc
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/executor/nodeSeqscan.c,v 1.61.2.1 2006/12/26 19:26:56 tgl 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"
#include "utils/lsyscache.h"

#include "cdb/cdbvars.h"
#include "miscadmin.h"
#include "cdb/cdbgang.h"

static void InitScanRelation(SeqScanState *node, EState *estate);

/* Open and close scanned relation Open/Close means resource acquisition.
 */
static void OpenScanRelation(SeqScanState *node);
static void CloseScanRelation(SeqScanState *node);

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;

	Assert((node->scan_state & SCAN_SCAN) != 0);

	/*
	 * 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)
	{
		if (estate->es_evTupleNull[scanrelid - 1])
			return ExecClearTuple(slot);

		ExecStoreGenericTuple(estate->es_evTuple[scanrelid - 1], slot, 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
	 */
	/* CKTAN- */
	if (node->ss_heapTupleData.bot == node->ss_heapTupleData.top
		&& !node->ss_heapTupleData.seen_EOS)
	{
		node->ss_heapTupleData.last = NULL;
		node->ss_heapTupleData.bot = 0;
		node->ss_heapTupleData.top = lengthof(node->ss_heapTupleData.item);
		heap_getnextx(scandesc, direction, node->ss_heapTupleData.item,
					  &node->ss_heapTupleData.top,
					  &node->ss_heapTupleData.seen_EOS);

		/* Gpmon */
		if(scandesc->rs_pageatatime)
                {
			Gpmon_M_Incr(GpmonPktFromSeqScanState(node), GPMON_SEQSCAN_PAGE);
                        CheckSendPlanStateGpmonPkt(&node->ps);
                }
	}

	node->ss_heapTupleData.last =
		((node->ss_heapTupleData.bot < node->ss_heapTupleData.top)
		 ? &node->ss_heapTupleData.item[node->ss_heapTupleData.bot++]
		 : 0);
	tuple = node->ss_heapTupleData.last;

	/*
	 * 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.
	 */
	if (tuple)
		ExecStoreHeapTuple(tuple,	/* tuple to store */
					   slot,	/* slot to store in */
					   scandesc->rs_cbuf,		/* buffer associated with this
												 * tuple */
					   false);	/* don't pfree this pointer */
	else
		ExecClearTuple(slot);

	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
	 */
	TupleTableSlot *slot;

	if((node->scan_state & SCAN_SCAN) == 0)
		OpenScanRelation(node);

	slot = ExecScan((ScanState *) node, (ExecScanAccessMtd) SeqNext);
     	if (!TupIsNull(slot))
        {
     		Gpmon_M_Incr_Rows_Out(GpmonPktFromSeqScanState(node));
                CheckSendPlanStateGpmonPkt(&node->ps);
        }

	if(TupIsNull(slot) && !node->ps.delayEagerFree)
	{
		CloseScanRelation(node);
	}

	return slot;
}

/* ----------------------------------------------------------------
 *		InitScanRelation
 *
 *		This does the initialization for scan relations and
 *		subplans of scans.
 * ----------------------------------------------------------------
 */
static void
InitScanRelation(SeqScanState *node, EState *estate)
{
	Relation	currentRelation;

	/*
	 * get the relation object id from the relid'th entry in the range table,
	 * open that relation and acquire appropriate lock on it.
	 */
	currentRelation = ExecOpenScanRelation(estate, ((SeqScan *) node->ps.plan)->scanrelid);

	node->ss_currentRelation = currentRelation;
	ExecAssignScanType(node, RelationGetDescr(currentRelation));
}

/* ---------------------------------------------------------------
 * Open underlying relation for scan.
 * Open means resource acquisition, in seq scan, file descriptor.
 *
 * We delay open as much as possible, and later, close as early as
 * possible to prevent from hogging lots of resources.  This is
 * very important because now some user partition a talbe to thousands
 * of smaller ones.  If we are not careful, we cannot even do a
 * scan on the table.
 *
 * We need to do this for all the scanners.  See nodeAppendOnlyscan.c
 * as well.
 * --------------------------------------------------------------
 */
static void
OpenScanRelation(SeqScanState *node)
{
	Assert(node->scan_state == SCAN_INIT || node->scan_state == SCAN_DONE);
	Assert(!node->ss_currentScanDesc);

	node->ss_currentScanDesc = heap_beginscan(
			node->ss_currentRelation,
			node->ps.state->es_snapshot,
			0,
			NULL);

	/* CKTAN- */
	node->ss_heapTupleData.bot = node->ss_heapTupleData.top
		= node->ss_heapTupleData.seen_EOS = 0;
	node->ss_heapTupleData.last = NULL;

	node->scan_state = SCAN_SCAN;
}

/* ----------------------------------------------------------------
 * Close the scanned relation.
 * Close means release resource.
 * ----------------------------------------------------------------
 */
static void
CloseScanRelation(SeqScanState *node)
{
	Assert((node->scan_state & SCAN_SCAN) != 0);

	heap_endscan(node->ss_currentScanDesc);

	node->ss_heapTupleData.top = 0;
	node->ss_heapTupleData.bot = 0;
	node->ss_heapTupleData.seen_EOS = 1;
	node->ss_heapTupleData.last = NULL;
	node->ss_currentScanDesc = NULL;
	node->scan_state = SCAN_INIT;
}


/* ----------------------------------------------------------------
 *		ExecInitSeqScan
 * ----------------------------------------------------------------
 */
SeqScanState *
ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
{
	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;
	scanstate->ss->scan_state = SCAN_INIT;

	/*
	 * 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);

	/*
	 * Initialize result tuple type and projection info.
	 */
	ExecAssignResultTypeFromTL(&scanstate->ps);
	ExecAssignScanProjectionInfo(scanstate);

	initGpmonPktForSeqScan((Plan *)node, &scanstate->ps.gpmon_pkt, estate);

	/*
	 * If eflag contains EXEC_FLAG_REWIND or EXEC_FLAG_BACKWARD or EXEC_FLAG_MARK,
	 * then this node is not eager free safe.
	 */
	scanstate->ps.delayEagerFree =
		((eflags & (EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)) != 0);

	return scanstate;
}

int
ExecCountSlotsSeqScan(SeqScan *node)
{
	return ExecCountSlotsNode(outerPlan(node)) +
		ExecCountSlotsNode(innerPlan(node)) +
		SEQSCAN_NSLOTS;
}

/* ----------------------------------------------------------------
 *		ExecEndSeqScan
 *
 *		frees any storage allocated through C routines.
 * ----------------------------------------------------------------
 */
void
ExecEndSeqScan(SeqScanState *node)
{
	Relation	relation;

	/*
	 * get information from node
	 */
	relation = node->ss_currentRelation;

	/*
	 * Free the exprcontext
	 */
	ExecFreeExprContext(&node->ps);

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

	ExecEagerFreeSeqScan(node);

	/*
	 * close the heap relation.
	 */
	ExecCloseScanRelation(relation);

	/* gpmon */
	EndPlanStateGpmonPkt(&node->ps);
}

/* ----------------------------------------------------------------
 *						Join Support
 * ----------------------------------------------------------------
 */

/* ----------------------------------------------------------------
 *		ExecSeqReScan
 *
 *		Rescans the relation.
 * ----------------------------------------------------------------
 */
void
ExecSeqReScan(SeqScanState *node, ExprContext *exprCtxt)
{
	EState	   *estate;
	Index		scanrelid;
	HeapScanDesc scan;

	estate = node->ps.state;
	scanrelid = ((SeqScan *) node->ps.plan)->scanrelid;

	/*node->ps.ps_TupFromTlist = false;*/

	/* 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;
	}

	if((node->scan_state & SCAN_SCAN) == 0)
		OpenScanRelation(node);

	scan = node->ss_currentScanDesc;

	heap_rescan(scan,			/* scan desc */
				NULL);			/* new scan keys */
	/* CKTAN */
	node->ss_heapTupleData.bot = node->ss_heapTupleData.top
		= node->ss_heapTupleData.seen_EOS = 0;
	node->ss_heapTupleData.last = NULL;

	Gpmon_M_Incr(GpmonPktFromSeqScanState(node), GPMON_SEQSCAN_RESCAN);
	CheckSendPlanStateGpmonPkt(&node->ps);
}

/* ----------------------------------------------------------------
 *		ExecSeqMarkPos(node)
 *
 *		Marks scan position.
 * ----------------------------------------------------------------
 */
void
ExecSeqMarkPos(SeqScanState *node)
{
	HeapScanDesc scan = node->ss_currentScanDesc;

	Assert((node->scan_state & SCAN_SCAN) != 0);

	/* CKTAN
	heap_markpos(scan);
	*/
	heap_markposx(scan, node->ss_heapTupleData.last);

	node->scan_state |= SCAN_MARKPOS;
}

/* ----------------------------------------------------------------
 *		ExecSeqRestrPos
 *
 *		Restores scan position.
 * ----------------------------------------------------------------
 */
void
ExecSeqRestrPos(SeqScanState *node)
{
	HeapScanDesc scan = node->ss_currentScanDesc;

	Assert((node->scan_state & SCAN_SCAN) != 0);
	Assert((node->scan_state & SCAN_MARKPOS) != 0);

	/*
	 * Clear any reference to the previously returned tuple.  This is needed
	 * because the slot is simply pointing at scan->rs_cbuf, which
	 * heap_restrpos will change; we'd have an internally inconsistent slot if
	 * we didn't do this.
	 */
	ExecClearTuple(node->ss_ScanTupleSlot);

	heap_restrpos(scan);
	Gpmon_M_Incr(GpmonPktFromSeqScanState(node), GPMON_SEQSCAN_RESTOREPOS);
	CheckSendPlanStateGpmonPkt(&node->ps);

	node->scan_state &= (~ ((int) SCAN_MARKPOS));
}

/* Gpmon helpers. */
char * GetScanRelNameGpmon(Oid relid, char schema_rel_name[SCAN_REL_NAME_BUF_SIZE])
{
	if (relid > 0)
	{
		char *relname = get_rel_name(relid);
		char *schemaname = get_namespace_name(get_rel_namespace(relid));
		snprintf(schema_rel_name, SCAN_REL_NAME_BUF_SIZE, "%s.%s", schemaname, relname);
		if (relname)
			pfree(relname);
		if (schemaname)
			pfree(schemaname);
	}
	return schema_rel_name;
}

/*
 * toSendGpmonExecutingPkt
 *   Return true if a perfmon executing packet needs to be sent for the given plan node.
 *
 * In most cases, this function will return true. The exception is for a Sort/Material
 * that is called by the SharedNode and is not in a driver slice.
 */
static bool
toSendGpmonExecutingPkt(Plan *plan, EState *estate)
{
	bool doSend = true;
	Assert(plan != NULL);
	if (IsA(plan, Material))
	{
		Material *ma = (Material *)plan;
		doSend = (ma->share_type == SHARE_NOTSHARED ||
				  ma->share_type == SHARE_MATERIAL ||
				  ma->driver_slice == LocallyExecutingSliceIndex(estate));
	}
	
	else if (IsA(plan, Sort))
	{
		Sort *sort = (Sort *)plan;
		doSend = (sort->share_type == SHARE_NOTSHARED ||
				  sort->share_type == SHARE_MATERIAL ||
				  sort->driver_slice == LocallyExecutingSliceIndex(estate));
		
	}

	return doSend;
}


void CheckSendPlanStateGpmonPkt(PlanState *ps)
{
	if(ps == NULL ||
	   ps->state == NULL)
	{
		return;
	}

	if(gp_enable_gpperfmon)
	{
		/*
		 * When Sort/Material is called by the SharedNode that is not
		 * a driver slice, do not send gpmon packet.
		 */
		Assert(ps->plan != NULL);
		bool doSend = toSendGpmonExecutingPkt(ps->plan, ps->state);
		if (!doSend)
		{
			return;
		}

		if(!ps->fHadSentGpmon || ps->gpmon_plan_tick != gpmon_tick)
		{
			gpmon_send(&ps->gpmon_pkt);
			ps->fHadSentGpmon = true;
		}

		ps->gpmon_plan_tick = gpmon_tick;
	}
}

/*
 * NodeInExecutingSlice
 *   Return true if the given node is running in the same slice of the
 * executing QE.
 *
 * Each motion node has a sender and a receiver slice, so for the same
 * motion node, this function returns true in two slices.
 *
 * For all other nodes, the node's slice id is stored in
 * estate->currentExecutingSliceId.
 */
static bool
NodeInExecutingSlice(Plan *plan, EState *estate)
{
	Assert(plan != NULL && estate != NULL);
	
	/*
	 * For Motion node, check either the sender slice or the receiver
	 * slice is running on the same slice as this QE. For the Motion
	 * nodes in the top slice of an InitPlan, the executing slice
	 * id might be different from the receiver slice id. We need to
	 * check that as well.
	 */
	if (IsA(plan, Motion))
	{
		Motion *motion = (Motion *)plan;

		SliceTable *sliceTable = estate->es_sliceTable;

		Slice *sendSlice = (Slice *)list_nth(sliceTable->slices, motion->motionID);
		Assert(sendSlice->parentIndex >= 0);
		Slice *recvSlice = (Slice *)list_nth(sliceTable->slices, sendSlice->parentIndex);
		int localSliceId = LocallyExecutingSliceIndex(estate);
		
		return (localSliceId == recvSlice->sliceIndex ||
				localSliceId == sendSlice->sliceIndex ||
				localSliceId == estate->currentExecutingSliceId);
	}

	/* For other nodes except for Motion, simple check estate->currentExecutingSliceId. */
	return (LocallyExecutingSliceIndex(estate) == estate->currentExecutingSliceId);
}

void EndPlanStateGpmonPkt(PlanState *ps)
{
	if(ps == NULL ||
	   ps->state == NULL)
	{
		return;
	}

	/*
	 * If this operator is not running in this slice, do not
	 * send the finished packet.
	 */
	if (!NodeInExecutingSlice(ps->plan, ps->state))
	{
		return;
	}

	ps->gpmon_pkt.u.qexec.status = (uint8)PMNS_Finished;

	if(gp_enable_gpperfmon)
	{
		gpmon_send(&ps->gpmon_pkt);
	}
}

/*
 * InitPlanNodeGpmonPkt -- initialize the init gpmon package, and send it off.
 */
void InitPlanNodeGpmonPkt(Plan *plan, gpmon_packet_t *gpmon_pkt, EState *estate,
						  PerfmonNodeType type,
						  int64 rowsout_est,
						  char* relname)
{
	int rowsout_adjustment_factor = 0;

	if (plan == NULL ||
		estate == NULL)
		return;

	/*
	 * If this operator is not running in this slice, do not
	 * send the init packet.
	 */
	if (!NodeInExecutingSlice(plan, estate))
	{
		return;
	}

	/* The estimates are now global so we need to adjust by
	 * the number of segments in the array.
	 */
	rowsout_adjustment_factor = GetQEGangNum();

	/* Make sure we don't div by zero below */
	if (rowsout_adjustment_factor < 1)
		rowsout_adjustment_factor = 1;

	Assert(rowsout_adjustment_factor >= 1);

	memset(gpmon_pkt, 0, sizeof(gpmon_packet_t));

	gpmon_pkt->magic = GPMON_MAGIC;
	gpmon_pkt->version = GPMON_PACKET_VERSION;
	gpmon_pkt->pkttype = GPMON_PKTTYPE_QEXEC;

	gpmon_gettmid(&gpmon_pkt->u.qexec.key.tmid);
	gpmon_pkt->u.qexec.key.ssid = gp_session_id;
	gpmon_pkt->u.qexec.key.ccnt = gp_command_count;
	gpmon_pkt->u.qexec.key.hash_key.segid = GetQEIndex();
	gpmon_pkt->u.qexec.key.hash_key.pid = MyProcPid;
	gpmon_pkt->u.qexec.key.hash_key.nid = plan->plan_node_id;

	gpmon_pkt->u.qexec.pnid = plan->plan_parent_node_id;


	gpmon_pkt->u.qexec.nodeType = (apr_uint16_t)type;

	gpmon_pkt->u.qexec.rowsout = 0;
	gpmon_pkt->u.qexec.rowsout_est = rowsout_est / rowsout_adjustment_factor;

	if (relname)
	{
		snprintf(gpmon_pkt->u.qexec.relation_name, sizeof(gpmon_pkt->u.qexec.relation_name), "%s", relname);
	}

	gpmon_pkt->u.qexec.status = (uint8)PMNS_Initialize;

	if(gp_enable_gpperfmon)
	{
		gpmon_send(gpmon_pkt);
	}

	gpmon_pkt->u.qexec.status = (uint8)PMNS_Executing;
}

void
initGpmonPktForSeqScan(Plan *planNode, gpmon_packet_t *gpmon_pkt, EState *estate)
{
	Assert(planNode != NULL && gpmon_pkt != NULL && IsA(planNode, SeqScan));

	{
		RangeTblEntry *rte = rt_fetch(((Scan *)planNode)->scanrelid, estate->es_range_table);
		char schema_rel_name[SCAN_REL_NAME_BUF_SIZE] = {0};
		
		Assert(GPMON_SEQSCAN_TOTAL <= (int)GPMON_QEXEC_M_COUNT);
		InitPlanNodeGpmonPkt(planNode, gpmon_pkt, estate, PMNT_SeqScan,
							 (int64) planNode->plan_rows, GetScanRelNameGpmon(rte->relid, schema_rel_name));
	}
}

void
ExecEagerFreeSeqScan(SeqScanState *node)
{
	if (((node->scan_state & SCAN_SCAN) != 0))
	{
		CloseScanRelation(node);
	}
}
