/*
 * 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.
 */

/*-------------------------------------------------------------------------
 *
 * execBitmapTableScan.c
 *	  Support routines for nodeBitmapTableScan.c
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * Portions Copyright (c) 2014, Pivotal, Inc.
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/heapam.h"
#include "access/relscan.h"
#include "access/transam.h"
#include "executor/execdebug.h"
#include "executor/nodeBitmapTableScan.h"
#include "pgstat.h"
#include "storage/bufmgr.h"
#include "utils/memutils.h"
#include "miscadmin.h"
#include "parser/parsetree.h"
#include "cdb/cdbvars.h" /* gp_select_invisible */
#include "nodes/tidbitmap.h"

/*
 * Returns BitmapTableScanMethod for a given table type. Returns NULL
 * if the given type is TableTypeInvalid or not defined in TableType.
 */
static const ScanMethod *
getBitmapTableScanMethod(TableType tableType)
{
	/*
	 * scanMethods
	 *    Array that specifies different scan methods for various table types.
	 *
	 * The index in this array for a specific table type should match the enum value
	 * defined in TableType.
	 */
	static const ScanMethod scanMethods[] =
	{
		{
			&BitmapHeapScanNext, &BitmapHeapScanBegin, &BitmapHeapScanEnd,
			&BitmapHeapScanReScan, &MarkRestrNotAllowed, &MarkRestrNotAllowed
		}
	};

	/* COMPILE_ASSERT(ARRAY_SIZE(scanMethods) == TableTypeInvalid); */

	if (tableType < TableTypeHeap || tableType >= TableTypeInvalid)
    {
		return NULL;
	}

	return &scanMethods[tableType];
}

/*
 * Initializes the state relevant to bitmaps.
 */
static inline void
initBitmapState(BitmapTableScanState *scanstate)
{
	if (scanstate->tbmres == NULL)
	{
		scanstate->tbmres =
			palloc0(sizeof(TBMIterateResult) +
					MAX_TUPLES_PER_PAGE * sizeof(OffsetNumber));
	}
}

/*
 * Frees the state relevant to bitmaps.
 */
static inline void
freeBitmapState(BitmapTableScanState *scanstate)
{
	if (scanstate->tbm != NULL)
	{
		if(IsA(scanstate->tbm, HashBitmap))
		{
			tbm_free((HashBitmap *)scanstate->tbm);
		}
		else
		{
            tbm_bitmap_free(scanstate->tbm);
		}

		scanstate->tbm = NULL;
	}

	if (scanstate->tbmres != NULL)
	{
		pfree(scanstate->tbmres);
		scanstate->tbmres = NULL;
	}

	tbm_reset_bitmaps(outerPlanState(scanstate));
}

static TupleTableSlot*
BitmapTableScanPlanQualTuple(BitmapTableScanState *node)
{
	EState	   *estate = node->ss.ps.state;
	Index		scanrelid = ((BitmapTableScan *) node->ss.ps.plan)->scan.scanrelid;
	ExprContext *econtext = node->ss.ps.ps_ExprContext;
	TupleTableSlot *slot = node->ss.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 IndexScan --> 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);

		/* Does the tuple meet the original qual conditions? */
		econtext->ecxt_scantuple = slot;

		ResetExprContext(econtext);

		if (!ExecQual(node->bitmapqualorig, econtext, false))
		{
			ExecClearTuple(slot);		/* would not be returned by scan */
		}

		/* Flag for the next call that no more tuples */
		estate->es_evTupleNull[scanrelid - 1] = true;

		return slot;
	}

	return ExecClearTuple(slot);
}

/*
 * Reads a bitmap (with possibly many pages) from the underlying node.
 */
static void
readBitmap(BitmapTableScanState *scanState)
{
	if (scanState->tbm != NULL)
	{
		return;
	}

	Node *tbm = (Node *) MultiExecProcNode(outerPlanState(scanState));

	if (tbm != NULL && (!(IsA(tbm, HashBitmap) ||
						  IsA(tbm, StreamBitmap))))
	{
		elog(ERROR, "unrecognized result from subplan");
	}

	/*
	 * When a HashBitmap is returned, set the returning bitmaps
	 * in the subplan to NULL, so that the subplan nodes do not
	 * mistakenly try to release the space during the rescan.
	 */
	if (tbm != NULL && IsA(tbm, HashBitmap))
	{
		tbm_reset_bitmaps(outerPlanState(scanState));
	}

	scanState->tbm = tbm;
	scanState->needNewBitmapPage = true;
}

/*
 * Reads the next bitmap page from the current bitmap.
 */
static bool
fetchNextBitmapPage(BitmapTableScanState *scanState)
{
	if (scanState->tbm == NULL)
	{
		return false;
	}

	TBMIterateResult *tbmres = (TBMIterateResult *)scanState->tbmres;

	Assert(scanState->needNewBitmapPage);

	bool gotBitmapPage = true;

	/* Set to 0 so that we can enter the while loop */
	tbmres->ntuples = 0;

	while (gotBitmapPage && tbmres->ntuples == 0)
	{
		gotBitmapPage = tbm_iterate(scanState->tbm, (TBMIterateResult *)scanState->tbmres);
	}

	if (gotBitmapPage)
	{
		scanState->iterator = NULL;
		scanState->needNewBitmapPage = false;

		if (tbmres->ntuples == BITMAP_IS_LOSSY)
		{
			scanState->isLossyBitmapPage = true;
		}
		else
		{
			scanState->isLossyBitmapPage = false;
		}
	}

	return gotBitmapPage;
}

/*
 * Initializes perfmon details for BitmapTableScan node.
 */
void
initGpmonPktForBitmapTableScan(Plan *planNode, gpmon_packet_t *gpmon_pkt, EState *estate)
{
	Assert(planNode != NULL && gpmon_pkt != NULL && IsA(planNode, BitmapTableScan));

	{
		RangeTblEntry *rte = rt_fetch(((BitmapTableScan *)planNode)->scan.scanrelid,
									  estate->es_range_table);
		char schema_rel_name[SCAN_REL_NAME_BUF_SIZE] = {0};

		Assert(GPMON_BITMAPTABLESCAN_TOTAL <= (int)GPMON_QEXEC_M_COUNT);
		InitPlanNodeGpmonPkt(planNode, gpmon_pkt, estate, PMNT_BitmapTableScan,
							 (int64)planNode->plan_rows,
							 GetScanRelNameGpmon(rte->relid, schema_rel_name));
	}
}

/*
 * Checks eligibility of a tuple.
 *
 * Note, a tuple may fail to meet visibility requirement. Moreover,
 * for a lossy bitmap, we need to check for every tuple to make sure
 * that it satisfies the qual.
 */
bool
BitmapTableScanRecheckTuple(BitmapTableScanState *scanState, TupleTableSlot *slot)
{
	/*
	 * If we are using lossy info or we are required to recheck each tuple
	 * because of visibility or other causes, then evaluate the tuple
	 * eligibility.
	 */
	if (scanState->isLossyBitmapPage || scanState->recheckTuples)
	{
		ExprContext *econtext = scanState->ss.ps.ps_ExprContext;

		econtext->ecxt_scantuple = slot;
		ResetExprContext(econtext);

		return ExecQual(scanState->bitmapqualorig, econtext, false);
	}

	return true;
}

/*
 * Prepares for a new scan such as initializing bitmap states, preparing
 * the corresponding scan method etc.
 */
void
BitmapTableScanBegin(BitmapTableScanState *scanState, Plan *plan, EState *estate, int eflags)
{
	DynamicScan_Begin((ScanState *)scanState, plan, estate, eflags);
}

/*
 * Prepares for scanning of a new partition/relation.
 */
void
BitmapTableScanBeginPartition(ScanState *node, bool initExpressions)
{
	Assert(node != NULL);
	BitmapTableScanState *scanState = (BitmapTableScanState *)node;

	Assert(SCAN_NEXT == scanState->ss.scan_state);

	initBitmapState(scanState);

	if (scanState->bitmapqualorig == NULL || initExpressions)
	{
		/* TODO rahmaf2 [JIRA: MPP-23293]: remap columns per-partition to handle dropped columns */
		scanState->bitmapqualorig = (List *)
			ExecInitExpr((Expr *) ((BitmapTableScan*)(node->ps.plan))->bitmapqualorig,
						 (PlanState *) scanState);
	}

	scanState->needNewBitmapPage = true;
	scanState->recheckTuples = true;

	getBitmapTableScanMethod(node->tableType)->beginScanMethod(node);

	/*
	 * Prepare child node to produce new bitmaps for the new partition (and cleanup
	 * any leftover state from old partition).
	 */
	ExecReScan(outerPlanState(node), NULL);
}

/*
 * Cleans up once scanning of a partition/relation is done.
 */
void
BitmapTableScanEndPartition(ScanState *node)
{
	Assert(SCAN_SCAN == node->scan_state);

	BitmapTableScanState *scanState = (BitmapTableScanState *) node;

	freeBitmapState(scanState);

	getBitmapTableScanMethod(node->tableType)->endScanMethod(node);

	Assert(scanState->tbm == NULL);
}

/*
 * Executes underlying scan method to fetch the next matching tuple.
 */
TupleTableSlot *
BitmapTableScanFetchNext(ScanState *node)
{
	BitmapTableScanState *scanState = (BitmapTableScanState *) node;
	TupleTableSlot *slot = BitmapTableScanPlanQualTuple(scanState);

	while (TupIsNull(slot))
	{
		/* If we haven't already obtained the required bitmap, do so */
		readBitmap(scanState);

		/* If we have exhausted the current bitmap page, fetch the next one */
		if (!scanState->needNewBitmapPage || fetchNextBitmapPage(scanState))
		{
			slot = ExecScan(&scanState->ss, (ExecScanAccessMtd) getBitmapTableScanMethod(scanState->ss.tableType)->accessMethod);
		}
		else
		{
			/*
			 * Needed a new bitmap page, but couldn't fetch one. Therefore,
			 * try the next partition.
			 */
			break;
		}
	}

	return slot;
}

/*
 * Cleans up after the scanning has finished.
 */
void
BitmapTableScanEnd(BitmapTableScanState *scanState)
{
	DynamicScan_End((ScanState *)scanState, BitmapTableScanEndPartition);
}

/*
 * Prepares for a rescan.
 */
void
BitmapTableScanReScan(BitmapTableScanState *node, ExprContext *exprCtxt)
{
	ScanState *scanState = &node->ss;
	Assert(scanState->tableType >= 0 && scanState->tableType < TableTypeInvalid);

	/*
	 * If we are being passed an outer tuple, link it into the "regular"
	 * per-tuple econtext for possible qual eval.
	 */
	if (exprCtxt != NULL)
	{
		ExprContext *stdecontext = node->ss.ps.ps_ExprContext;
		stdecontext->ecxt_outertuple = exprCtxt->ecxt_outertuple;
	}

	EState	   *estate = node->ss.ps.state;
	Index scanrelid = ((Scan *)(scanState->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;
	}

	DynamicScan_ReScan((ScanState *)node, BitmapTableScanEndPartition, exprCtxt);

	ExecReScan(outerPlanState(node), exprCtxt);
}
