/*-------------------------------------------------------------------------
 *
 * nodeIncrementalSort.c
 *	  Routines to handle incremental sorting of relations.
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/executor/nodeIncrementalSort.c
 *
 * DESCRIPTION
 *
 *	Incremental sort is an optimized variant of multikey sort for cases
 *	when the input is already sorted by a prefix of the sort keys.  For
 *	example when a sort by (key1, key2 ... keyN) is requested, and the
 *	input is already sorted by (key1, key2 ... keyM), M < N, we can
 *	divide the input into groups where keys (key1, ... keyM) are equal,
 *	and only sort on the remaining columns.
 *
 *	Consider the following example.  We have input tuples consisting of
 *	two integers (X, Y) already presorted by X, while it's required to
 *	sort them by both X and Y.  Let input tuples be following.
 *
 *	(1, 5)
 *	(1, 2)
 *	(2, 9)
 *	(2, 1)
 *	(2, 5)
 *	(3, 3)
 *	(3, 7)
 *
 *	An incremental sort algorithm would split the input into the following
 *	groups, which have equal X, and then sort them by Y individually:
 *
 *		(1, 5) (1, 2)
 *		(2, 9) (2, 1) (2, 5)
 *		(3, 3) (3, 7)
 *
 *	After sorting these groups and putting them altogether, we would get
 *	the following result which is sorted by X and Y, as requested:
 *
 *	(1, 2)
 *	(1, 5)
 *	(2, 1)
 *	(2, 5)
 *	(2, 9)
 *	(3, 3)
 *	(3, 7)
 *
 *	Incremental sort may be more efficient than plain sort, particularly
 *	on large datasets, as it reduces the amount of data to sort at once,
 *	making it more likely it fits into work_mem (eliminating the need to
 *	spill to disk).  But the main advantage of incremental sort is that
 *	it can start producing rows early, before sorting the whole dataset,
 *	which is a significant benefit especially for queries with LIMIT.
 *
 *	The algorithm we've implemented here is modified from the theoretical
 *	base described above by operating in two different modes:
 *	  - Fetching a minimum number of tuples without checking prefix key
 *	    group membership and sorting on all columns when safe.
 *	  - Fetching all tuples for a single prefix key group and sorting on
 *	    solely the unsorted columns.
 *	We always begin in the first mode, and employ a heuristic to switch
 *	into the second mode if we believe it's beneficial.
 *
 *	Sorting incrementally can potentially use less memory, avoid fetching
 *	and sorting all tuples in the dataset, and begin returning tuples before
 *	the entire result set is available.
 *
 *	The hybrid mode approach allows us to optimize for both very small
 *	groups (where the overhead of a new tuplesort is high) and very large
 *	groups (where we can lower cost by not having to sort on already sorted
 *	columns), albeit at some extra cost while switching between modes.
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/htup_details.h"
#include "executor/execdebug.h"
#include "executor/nodeIncrementalSort.h"
#include "miscadmin.h"
#include "utils/lsyscache.h"
#include "utils/tuplesort.h"

/*
 * We need to store the instrumentation information in either local node's sort
 * info or, for a parallel worker process, in the shared info (this avoids
 * having to additionally memcpy the info from local memory to shared memory
 * at each instrumentation call). This macro expands to choose the proper sort
 * state and group info.
 *
 * Arguments:
 * - node: type IncrementalSortState *
 * - groupName: the token fullsort or prefixsort
 */
#define INSTRUMENT_SORT_GROUP(node, groupName) \
	do { \
		if ((node)->ss.ps.instrument != NULL) \
		{ \
			if ((node)->shared_info && (node)->am_worker) \
			{ \
				Assert(IsParallelWorker()); \
				Assert(ParallelWorkerNumber <= (node)->shared_info->num_workers); \
				instrumentSortedGroup(&(node)->shared_info->sinfo[ParallelWorkerNumber].groupName##GroupInfo, \
									  (node)->groupName##_state); \
			} \
			else \
			{ \
				instrumentSortedGroup(&(node)->incsort_info.groupName##GroupInfo, \
									  (node)->groupName##_state); \
			} \
		} \
	} while (0)


/* ----------------------------------------------------------------
 * instrumentSortedGroup
 *
 * Because incremental sort processes (potentially many) sort batches, we need
 * to capture tuplesort stats each time we finalize a sort state. This summary
 * data is later used for EXPLAIN ANALYZE output.
 * ----------------------------------------------------------------
 */
static void
instrumentSortedGroup(IncrementalSortGroupInfo *groupInfo,
					  Tuplesortstate *sortState)
{
	TuplesortInstrumentation sort_instr;

	groupInfo->groupCount++;

	tuplesort_get_stats(sortState, &sort_instr);

	/* Calculate total and maximum memory and disk space used. */
	switch (sort_instr.spaceType)
	{
		case SORT_SPACE_TYPE_DISK:
			groupInfo->totalDiskSpaceUsed += sort_instr.spaceUsed;
			if (sort_instr.spaceUsed > groupInfo->maxDiskSpaceUsed)
				groupInfo->maxDiskSpaceUsed = sort_instr.spaceUsed;

			break;
		case SORT_SPACE_TYPE_MEMORY:
			groupInfo->totalMemorySpaceUsed += sort_instr.spaceUsed;
			if (sort_instr.spaceUsed > groupInfo->maxMemorySpaceUsed)
				groupInfo->maxMemorySpaceUsed = sort_instr.spaceUsed;

			break;
	}

	/* Track each sort method we've used. */
	groupInfo->sortMethods |= sort_instr.sortMethod;
}

/* ----------------------------------------------------------------
 * preparePresortedCols
 *
 * Prepare information for presorted_keys comparisons.
 * ----------------------------------------------------------------
 */
static void
preparePresortedCols(IncrementalSortState *node)
{
	IncrementalSort *plannode = castNode(IncrementalSort, node->ss.ps.plan);

	node->presorted_keys =
		(PresortedKeyData *) palloc(plannode->nPresortedCols *
									sizeof(PresortedKeyData));

	/* Pre-cache comparison functions for each pre-sorted key. */
	for (int i = 0; i < plannode->nPresortedCols; i++)
	{
		Oid			equalityOp,
					equalityFunc;
		PresortedKeyData *key;

		key = &node->presorted_keys[i];
		key->attno = plannode->sort.sortColIdx[i];

		equalityOp = get_equality_op_for_ordering_op(plannode->sort.sortOperators[i],
													 NULL);
		if (!OidIsValid(equalityOp))
			elog(ERROR, "missing equality operator for ordering operator %u",
				 plannode->sort.sortOperators[i]);

		equalityFunc = get_opcode(equalityOp);
		if (!OidIsValid(equalityFunc))
			elog(ERROR, "missing function for operator %u", equalityOp);

		/* Lookup the comparison function */
		fmgr_info_cxt(equalityFunc, &key->flinfo, CurrentMemoryContext);

		/* We can initialize the callinfo just once and re-use it */
		key->fcinfo = palloc0(SizeForFunctionCallInfo(2));
		InitFunctionCallInfoData(*key->fcinfo, &key->flinfo, 2,
								 plannode->sort.collations[i], NULL, NULL);
		key->fcinfo->args[0].isnull = false;
		key->fcinfo->args[1].isnull = false;
	}
}

/* ----------------------------------------------------------------
 * isCurrentGroup
 *
 * Check whether a given tuple belongs to the current sort group by comparing
 * the presorted column values to the pivot tuple of the current group.
 * ----------------------------------------------------------------
 */
static bool
isCurrentGroup(IncrementalSortState *node, TupleTableSlot *pivot, TupleTableSlot *tuple)
{
	int			nPresortedCols;

	nPresortedCols = castNode(IncrementalSort, node->ss.ps.plan)->nPresortedCols;

	/*
	 * That the input is sorted by keys * (0, ... n) implies that the tail
	 * keys are more likely to change. Therefore we do our comparison starting
	 * from the last pre-sorted column to optimize for early detection of
	 * inequality and minimizing the number of function calls..
	 */
	for (int i = nPresortedCols - 1; i >= 0; i--)
	{
		Datum		datumA,
					datumB,
					result;
		bool		isnullA,
					isnullB;
		AttrNumber	attno = node->presorted_keys[i].attno;
		PresortedKeyData *key;

		datumA = slot_getattr(pivot, attno, &isnullA);
		datumB = slot_getattr(tuple, attno, &isnullB);

		/* Special case for NULL-vs-NULL, else use standard comparison */
		if (isnullA || isnullB)
		{
			if (isnullA == isnullB)
				continue;
			else
				return false;
		}

		key = &node->presorted_keys[i];

		key->fcinfo->args[0].value = datumA;
		key->fcinfo->args[1].value = datumB;

		/* just for paranoia's sake, we reset isnull each time */
		key->fcinfo->isnull = false;

		result = FunctionCallInvoke(key->fcinfo);

		/* Check for null result, since caller is clearly not expecting one */
		if (key->fcinfo->isnull)
			elog(ERROR, "function %u returned NULL", key->flinfo.fn_oid);

		if (!DatumGetBool(result))
			return false;
	}
	return true;
}

/* ----------------------------------------------------------------
 * switchToPresortedPrefixMode
 *
 * When we determine that we've likely encountered a large batch of tuples all
 * having the same presorted prefix values, we want to optimize tuplesort by
 * only sorting on unsorted suffix keys.
 *
 * The problem is that we've already accumulated several tuples in another
 * tuplesort configured to sort by all columns (assuming that there may be
 * more than one prefix key group). So to switch to presorted prefix mode we
 * have to go back and look at all the tuples we've already accumulated to
 * verify they're all part of the same prefix key group before sorting them
 * solely by unsorted suffix keys.
 *
 * While it's likely that all tuples already fetched are all part of a single
 * prefix group, we also have to handle the possibility that there is at least
 * one different prefix key group before the large prefix key group.
 * ----------------------------------------------------------------
 */
static void
switchToPresortedPrefixMode(PlanState *pstate)
{
	IncrementalSortState *node = castNode(IncrementalSortState, pstate);
	ScanDirection dir;
	int64		nTuples;
	TupleDesc	tupDesc;
	PlanState  *outerNode;
	IncrementalSort *plannode = castNode(IncrementalSort, node->ss.ps.plan);

	dir = node->ss.ps.state->es_direction;
	outerNode = outerPlanState(node);
	tupDesc = ExecGetResultType(outerNode);

	/* Configure the prefix sort state the first time around. */
	if (node->prefixsort_state == NULL)
	{
		Tuplesortstate *prefixsort_state;
		int			nPresortedCols = plannode->nPresortedCols;

		/*
		 * Optimize the sort by assuming the prefix columns are all equal and
		 * thus we only need to sort by any remaining columns.
		 */
		prefixsort_state = tuplesort_begin_heap(tupDesc,
												plannode->sort.numCols - nPresortedCols,
												&(plannode->sort.sortColIdx[nPresortedCols]),
												&(plannode->sort.sortOperators[nPresortedCols]),
												&(plannode->sort.collations[nPresortedCols]),
												&(plannode->sort.nullsFirst[nPresortedCols]),
												work_mem,
												NULL,
												node->bounded ? TUPLESORT_ALLOWBOUNDED : TUPLESORT_NONE);
		node->prefixsort_state = prefixsort_state;
	}
	else
	{
		/* Next group of presorted data */
		tuplesort_reset(node->prefixsort_state);
	}

	/*
	 * If the current node has a bound, then it's reasonably likely that a
	 * large prefix key group will benefit from bounded sort, so configure the
	 * tuplesort to allow for that optimization.
	 */
	if (node->bounded)
	{
		SO1_printf("Setting bound on presorted prefix tuplesort to: " INT64_FORMAT "\n",
				   node->bound - node->bound_Done);
		tuplesort_set_bound(node->prefixsort_state,
							node->bound - node->bound_Done);
	}

	/*
	 * Copy as many tuples as we can (i.e., in the same prefix key group) from
	 * the full sort state to the prefix sort state.
	 */
	for (nTuples = 0; nTuples < node->n_fullsort_remaining; nTuples++)
	{
		/*
		 * When we encounter multiple prefix key groups inside the full sort
		 * tuplesort we have to carry over the last read tuple into the next
		 * batch.
		 */
		if (nTuples == 0 && !TupIsNull(node->transfer_tuple))
		{
			tuplesort_puttupleslot(node->prefixsort_state, node->transfer_tuple);
			/* The carried over tuple is our new group pivot tuple. */
			ExecCopySlot(node->group_pivot, node->transfer_tuple);
		}
		else
		{
			tuplesort_gettupleslot(node->fullsort_state,
								   ScanDirectionIsForward(dir),
								   false, node->transfer_tuple, NULL);

			/*
			 * If this is our first time through the loop, then we need to
			 * save the first tuple we get as our new group pivot.
			 */
			if (TupIsNull(node->group_pivot))
				ExecCopySlot(node->group_pivot, node->transfer_tuple);

			if (isCurrentGroup(node, node->group_pivot, node->transfer_tuple))
			{
				tuplesort_puttupleslot(node->prefixsort_state, node->transfer_tuple);
			}
			else
			{
				/*
				 * The tuple isn't part of the current batch so we need to
				 * carry it over into the next batch of tuples we transfer out
				 * of the full sort tuplesort into the presorted prefix
				 * tuplesort. We don't actually have to do anything special to
				 * save the tuple since we've already loaded it into the
				 * node->transfer_tuple slot, and, even though that slot
				 * points to memory inside the full sort tuplesort, we can't
				 * reset that tuplesort anyway until we've fully transferred
				 * out its tuples, so this reference is safe. We do need to
				 * reset the group pivot tuple though since we've finished the
				 * current prefix key group.
				 */
				ExecClearTuple(node->group_pivot);

				/* Break out of for-loop early */
				break;
			}
		}
	}

	/*
	 * Track how many tuples remain in the full sort batch so that we know if
	 * we need to sort multiple prefix key groups before processing tuples
	 * remaining in the large single prefix key group we think we've
	 * encountered.
	 */
	SO1_printf("Moving " INT64_FORMAT " tuples to presorted prefix tuplesort\n", nTuples);
	node->n_fullsort_remaining -= nTuples;
	SO1_printf("Setting n_fullsort_remaining to " INT64_FORMAT "\n", node->n_fullsort_remaining);

	if (node->n_fullsort_remaining == 0)
	{
		/*
		 * We've found that all tuples remaining in the full sort batch are in
		 * the same prefix key group and moved all of those tuples into the
		 * presorted prefix tuplesort.  We don't know that we've yet found the
		 * last tuple in the current prefix key group, so save our pivot
		 * comparison tuple and continue fetching tuples from the outer
		 * execution node to load into the presorted prefix tuplesort.
		 */
		ExecCopySlot(node->group_pivot, node->transfer_tuple);
		SO_printf("Setting execution_status to INCSORT_LOADPREFIXSORT (switchToPresortedPrefixMode)\n");
		node->execution_status = INCSORT_LOADPREFIXSORT;

		/*
		 * Make sure we clear the transfer tuple slot so that next time we
		 * encounter a large prefix key group we don't incorrectly assume we
		 * have a tuple carried over from the previous group.
		 */
		ExecClearTuple(node->transfer_tuple);
	}
	else
	{
		/*
		 * We finished a group but didn't consume all of the tuples from the
		 * full sort state, so we'll sort this batch, let the outer node read
		 * out all of those tuples, and then come back around to find another
		 * batch.
		 */
		SO1_printf("Sorting presorted prefix tuplesort with " INT64_FORMAT " tuples\n", nTuples);
		tuplesort_performsort(node->prefixsort_state);

		INSTRUMENT_SORT_GROUP(node, prefixsort);

		if (node->bounded)
		{
			/*
			 * If the current node has a bound and we've already sorted n
			 * tuples, then the functional bound remaining is (original bound
			 * - n), so store the current number of processed tuples for use
			 * in configuring sorting bound.
			 */
			SO2_printf("Changing bound_Done from " INT64_FORMAT " to " INT64_FORMAT "\n",
					   Min(node->bound, node->bound_Done + nTuples), node->bound_Done);
			node->bound_Done = Min(node->bound, node->bound_Done + nTuples);
		}

		SO_printf("Setting execution_status to INCSORT_READPREFIXSORT  (switchToPresortedPrefixMode)\n");
		node->execution_status = INCSORT_READPREFIXSORT;
	}
}

/*
 * Sorting many small groups with tuplesort is inefficient. In order to
 * cope with this problem we don't start a new group until the current one
 * contains at least DEFAULT_MIN_GROUP_SIZE tuples (unfortunately this also
 * means we can't assume small groups of tuples all have the same prefix keys.)
 * When we have a bound that's less than DEFAULT_MIN_GROUP_SIZE we start looking
 * for the new group as soon as we've met our bound to avoid fetching more
 * tuples than we absolutely have to fetch.
 */
#define DEFAULT_MIN_GROUP_SIZE 32

/*
 * While we've optimized for small prefix key groups by not starting our prefix
 * key comparisons until we've reached a minimum number of tuples, we don't want
 * that optimization to cause us to lose out on the benefits of being able to
 * assume a large group of tuples is fully presorted by its prefix keys.
 * Therefore we use the DEFAULT_MAX_FULL_SORT_GROUP_SIZE cutoff as a heuristic
 * for determining when we believe we've encountered a large group, and, if we
 * get to that point without finding a new prefix key group we transition to
 * presorted prefix key mode.
 */
#define DEFAULT_MAX_FULL_SORT_GROUP_SIZE (2 * DEFAULT_MIN_GROUP_SIZE)

/* ----------------------------------------------------------------
 *		ExecIncrementalSort
 *
 *		Assuming that outer subtree returns tuple presorted by some prefix
 *		of target sort columns, performs incremental sort.
 *
 *		Conditions:
 *		  -- none.
 *
 *		Initial States:
 *		  -- the outer child is prepared to return the first tuple.
 * ----------------------------------------------------------------
 */
static TupleTableSlot *
ExecIncrementalSort(PlanState *pstate)
{
	IncrementalSortState *node = castNode(IncrementalSortState, pstate);
	EState	   *estate;
	ScanDirection dir;
	Tuplesortstate *read_sortstate;
	Tuplesortstate *fullsort_state;
	TupleTableSlot *slot;
	IncrementalSort *plannode = (IncrementalSort *) node->ss.ps.plan;
	PlanState  *outerNode;
	TupleDesc	tupDesc;
	int64		nTuples = 0;
	int64		minGroupSize;

	CHECK_FOR_INTERRUPTS();

	estate = node->ss.ps.state;
	dir = estate->es_direction;
	fullsort_state = node->fullsort_state;

	/*
	 * If a previous iteration has sorted a batch, then we need to check to
	 * see if there are any remaining tuples in that batch that we can return
	 * before moving on to other execution states.
	 */
	if (node->execution_status == INCSORT_READFULLSORT
		|| node->execution_status == INCSORT_READPREFIXSORT)
	{
		/*
		 * Return next tuple from the current sorted group set if available.
		 */
		read_sortstate = node->execution_status == INCSORT_READFULLSORT ?
			fullsort_state : node->prefixsort_state;
		slot = node->ss.ps.ps_ResultTupleSlot;

		/*
		 * We have to populate the slot from the tuplesort before checking
		 * outerNodeDone because it will set the slot to NULL if no more
		 * tuples remain. If the tuplesort is empty, but we don't have any
		 * more tuples available for sort from the outer node, then
		 * outerNodeDone will have been set so we'll return that now-empty
		 * slot to the caller.
		 */
		if (tuplesort_gettupleslot(read_sortstate, ScanDirectionIsForward(dir),
								   false, slot, NULL) || node->outerNodeDone)

			/*
			 * Note: there isn't a good test case for the node->outerNodeDone
			 * check directly, but we need it for any plan where the outer
			 * node will fail when trying to fetch too many tuples.
			 */
			return slot;
		else if (node->n_fullsort_remaining > 0)
		{
			/*
			 * When we transition to presorted prefix mode, we might have
			 * accumulated at least one additional prefix key group in the
			 * full sort tuplesort. The first call to
			 * switchToPresortedPrefixMode() will have pulled the first one of
			 * those groups out, and we've returned those tuples to the parent
			 * node, but if at this point we still have tuples remaining in
			 * the full sort state (i.e., n_fullsort_remaining > 0), then we
			 * need to re-execute the prefix mode transition function to pull
			 * out the next prefix key group.
			 */
			SO1_printf("Re-calling switchToPresortedPrefixMode() because n_fullsort_remaining is > 0 (" INT64_FORMAT ")\n",
					   node->n_fullsort_remaining);
			switchToPresortedPrefixMode(pstate);
		}
		else
		{
			/*
			 * If we don't have any sorted tuples to read and we're not
			 * currently transitioning into presorted prefix sort mode, then
			 * it's time to start the process all over again by building a new
			 * group in the full sort state.
			 */
			SO_printf("Setting execution_status to INCSORT_LOADFULLSORT (n_fullsort_remaining > 0)\n");
			node->execution_status = INCSORT_LOADFULLSORT;
		}
	}

	/*
	 * Scan the subplan in the forward direction while creating the sorted
	 * data.
	 */
	estate->es_direction = ForwardScanDirection;

	outerNode = outerPlanState(node);
	tupDesc = ExecGetResultType(outerNode);

	/* Load tuples into the full sort state. */
	if (node->execution_status == INCSORT_LOADFULLSORT)
	{
		/*
		 * Initialize sorting structures.
		 */
		if (fullsort_state == NULL)
		{
			/*
			 * Initialize presorted column support structures for
			 * isCurrentGroup(). It's correct to do this along with the
			 * initial initialization for the full sort state (and not for the
			 * prefix sort state) since we always load the full sort state
			 * first.
			 */
			preparePresortedCols(node);

			/*
			 * Since we optimize small prefix key groups by accumulating a
			 * minimum number of tuples before sorting, we can't assume that a
			 * group of tuples all have the same prefix key values. Hence we
			 * setup the full sort tuplesort to sort by all requested sort
			 * keys.
			 */
			fullsort_state = tuplesort_begin_heap(tupDesc,
												  plannode->sort.numCols,
												  plannode->sort.sortColIdx,
												  plannode->sort.sortOperators,
												  plannode->sort.collations,
												  plannode->sort.nullsFirst,
												  work_mem,
												  NULL,
												  node->bounded ?
												  TUPLESORT_ALLOWBOUNDED :
												  TUPLESORT_NONE);
			node->fullsort_state = fullsort_state;
		}
		else
		{
			/* Reset sort for the next batch. */
			tuplesort_reset(fullsort_state);
		}

		/*
		 * Calculate the remaining tuples left if bounded and configure both
		 * bounded sort and the minimum group size accordingly.
		 */
		if (node->bounded)
		{
			int64		currentBound = node->bound - node->bound_Done;

			/*
			 * Bounded sort isn't likely to be a useful optimization for full
			 * sort mode since we limit full sort mode to a relatively small
			 * number of tuples and tuplesort doesn't switch over to top-n
			 * heap sort anyway unless it hits (2 * bound) tuples.
			 */
			if (currentBound < DEFAULT_MIN_GROUP_SIZE)
				tuplesort_set_bound(fullsort_state, currentBound);

			minGroupSize = Min(DEFAULT_MIN_GROUP_SIZE, currentBound);
		}
		else
			minGroupSize = DEFAULT_MIN_GROUP_SIZE;

		/*
		 * Because we have to read the next tuple to find out that we've
		 * encountered a new prefix key group, on subsequent groups we have to
		 * carry over that extra tuple and add it to the new group's sort here
		 * before we read any new tuples from the outer node.
		 */
		if (!TupIsNull(node->group_pivot))
		{
			tuplesort_puttupleslot(fullsort_state, node->group_pivot);
			nTuples++;

			/*
			 * We're in full sort mode accumulating a minimum number of tuples
			 * and not checking for prefix key equality yet, so we can't
			 * assume the group pivot tuple will remain the same -- unless
			 * we're using a minimum group size of 1, in which case the pivot
			 * is obviously still the pivot.
			 */
			if (nTuples != minGroupSize)
				ExecClearTuple(node->group_pivot);
		}


		/*
		 * Pull as many tuples from the outer node as possible given our
		 * current operating mode.
		 */
		for (;;)
		{
			slot = ExecProcNode(outerNode);

			/*
			 * If the outer node can't provide us any more tuples, then we can
			 * sort the current group and return those tuples.
			 */
			if (TupIsNull(slot))
			{
				/*
				 * We need to know later if the outer node has completed to be
				 * able to distinguish between being done with a batch and
				 * being done with the whole node.
				 */
				node->outerNodeDone = true;

				SO1_printf("Sorting fullsort with " INT64_FORMAT " tuples\n", nTuples);
				tuplesort_performsort(fullsort_state);

				INSTRUMENT_SORT_GROUP(node, fullsort);

				SO_printf("Setting execution_status to INCSORT_READFULLSORT (final tuple)\n");
				node->execution_status = INCSORT_READFULLSORT;
				break;
			}

			/* Accumulate the next group of presorted tuples. */
			if (nTuples < minGroupSize)
			{
				/*
				 * If we haven't yet hit our target minimum group size, then
				 * we don't need to bother checking for inclusion in the
				 * current prefix group since at this point we'll assume that
				 * we'll full sort this batch to avoid a large number of very
				 * tiny (and thus inefficient) sorts.
				 */
				tuplesort_puttupleslot(fullsort_state, slot);
				nTuples++;

				/*
				 * If we've reached our minimum group size, then we need to
				 * store the most recent tuple as a pivot.
				 */
				if (nTuples == minGroupSize)
					ExecCopySlot(node->group_pivot, slot);
			}
			else
			{
				/*
				 * If we've already accumulated enough tuples to reach our
				 * minimum group size, then we need to compare any additional
				 * tuples to our pivot tuple to see if we reach the end of
				 * that prefix key group. Only after we find changed prefix
				 * keys can we guarantee sort stability of the tuples we've
				 * already accumulated.
				 */
				if (isCurrentGroup(node, node->group_pivot, slot))
				{
					/*
					 * As long as the prefix keys match the pivot tuple then
					 * load the tuple into the tuplesort.
					 */
					tuplesort_puttupleslot(fullsort_state, slot);
					nTuples++;
				}
				else
				{
					/*
					 * Since the tuple we fetched isn't part of the current
					 * prefix key group we don't want to sort it as part of
					 * the current batch. Instead we use the group_pivot slot
					 * to carry it over to the next batch (even though we
					 * won't actually treat it as a group pivot).
					 */
					ExecCopySlot(node->group_pivot, slot);

					if (node->bounded)
					{
						/*
						 * If the current node has a bound, and we've already
						 * sorted n tuples, then the functional bound
						 * remaining is (original bound - n), so store the
						 * current number of processed tuples for later use
						 * configuring the sort state's bound.
						 */
						SO2_printf("Changing bound_Done from " INT64_FORMAT " to " INT64_FORMAT "\n",
								   node->bound_Done,
								   Min(node->bound, node->bound_Done + nTuples));
						node->bound_Done = Min(node->bound, node->bound_Done + nTuples);
					}

					/*
					 * Once we find changed prefix keys we can complete the
					 * sort and transition modes to reading out the sorted
					 * tuples.
					 */
					SO1_printf("Sorting fullsort tuplesort with " INT64_FORMAT " tuples\n",
							   nTuples);
					tuplesort_performsort(fullsort_state);

					INSTRUMENT_SORT_GROUP(node, fullsort);

					SO_printf("Setting execution_status to INCSORT_READFULLSORT (found end of group)\n");
					node->execution_status = INCSORT_READFULLSORT;
					break;
				}
			}

			/*
			 * Unless we've already transitioned modes to reading from the
			 * full sort state, then we assume that having read at least
			 * DEFAULT_MAX_FULL_SORT_GROUP_SIZE tuples means it's likely we're
			 * processing a large group of tuples all having equal prefix keys
			 * (but haven't yet found the final tuple in that prefix key
			 * group), so we need to transition into presorted prefix mode.
			 */
			if (nTuples > DEFAULT_MAX_FULL_SORT_GROUP_SIZE &&
				node->execution_status != INCSORT_READFULLSORT)
			{
				/*
				 * The group pivot we have stored has already been put into
				 * the tuplesort; we don't want to carry it over. Since we
				 * haven't yet found the end of the prefix key group, it might
				 * seem like we should keep this, but we don't actually know
				 * how many prefix key groups might be represented in the full
				 * sort state, so we'll let the mode transition function
				 * manage this state for us.
				 */
				ExecClearTuple(node->group_pivot);

				/*
				 * Unfortunately the tuplesort API doesn't include a way to
				 * retrieve tuples unless a sort has been performed, so we
				 * perform the sort even though we could just as easily rely
				 * on FIFO retrieval semantics when transferring them to the
				 * presorted prefix tuplesort.
				 */
				SO1_printf("Sorting fullsort tuplesort with " INT64_FORMAT " tuples\n", nTuples);
				tuplesort_performsort(fullsort_state);

				INSTRUMENT_SORT_GROUP(node, fullsort);

				/*
				 * If the full sort tuplesort happened to switch into top-n
				 * heapsort mode then we will only be able to retrieve
				 * currentBound tuples (since the tuplesort will have only
				 * retained the top-n tuples). This is safe even though we
				 * haven't yet completed fetching the current prefix key group
				 * because the tuples we've "lost" already sorted "below" the
				 * retained ones, and we're already contractually guaranteed
				 * to not need any more than the currentBound tuples.
				 */
				if (tuplesort_used_bound(node->fullsort_state))
				{
					int64		currentBound = node->bound - node->bound_Done;

					SO2_printf("Read " INT64_FORMAT " tuples, but setting to " INT64_FORMAT " because we used bounded sort\n",
							   nTuples, Min(currentBound, nTuples));
					nTuples = Min(currentBound, nTuples);
				}

				SO1_printf("Setting n_fullsort_remaining to " INT64_FORMAT " and calling switchToPresortedPrefixMode()\n",
						   nTuples);

				/*
				 * We might have multiple prefix key groups in the full sort
				 * state, so the mode transition function needs to know that
				 * it needs to move from the fullsort to presorted prefix
				 * sort.
				 */
				node->n_fullsort_remaining = nTuples;

				/* Transition the tuples to the presorted prefix tuplesort. */
				switchToPresortedPrefixMode(pstate);

				/*
				 * Since we know we had tuples to move to the presorted prefix
				 * tuplesort, we know that unless that transition has verified
				 * that all tuples belonged to the same prefix key group (in
				 * which case we can go straight to continuing to load tuples
				 * into that tuplesort), we should have a tuple to return
				 * here.
				 *
				 * Either way, the appropriate execution status should have
				 * been set by switchToPresortedPrefixMode(), so we can drop
				 * out of the loop here and let the appropriate path kick in.
				 */
				break;
			}
		}
	}

	if (node->execution_status == INCSORT_LOADPREFIXSORT)
	{
		/*
		 * We only enter this state after the mode transition function has
		 * confirmed all remaining tuples from the full sort state have the
		 * same prefix and moved those tuples to the prefix sort state. That
		 * function has also set a group pivot tuple (which doesn't need to be
		 * carried over; it's already been put into the prefix sort state).
		 */
		Assert(!TupIsNull(node->group_pivot));

		/*
		 * Read tuples from the outer node and load them into the prefix sort
		 * state until we encounter a tuple whose prefix keys don't match the
		 * current group_pivot tuple, since we can't guarantee sort stability
		 * until we have all tuples matching those prefix keys.
		 */
		for (;;)
		{
			slot = ExecProcNode(outerNode);

			/*
			 * If we've exhausted tuples from the outer node we're done
			 * loading the prefix sort state.
			 */
			if (TupIsNull(slot))
			{
				/*
				 * We need to know later if the outer node has completed to be
				 * able to distinguish between being done with a batch and
				 * being done with the whole node.
				 */
				node->outerNodeDone = true;
				break;
			}

			/*
			 * If the tuple's prefix keys match our pivot tuple, we're not
			 * done yet and can load it into the prefix sort state. If not, we
			 * don't want to sort it as part of the current batch. Instead we
			 * use the group_pivot slot to carry it over to the next batch
			 * (even though we won't actually treat it as a group pivot).
			 */
			if (isCurrentGroup(node, node->group_pivot, slot))
			{
				tuplesort_puttupleslot(node->prefixsort_state, slot);
				nTuples++;
			}
			else
			{
				ExecCopySlot(node->group_pivot, slot);
				break;
			}
		}

		/*
		 * Perform the sort and begin returning the tuples to the parent plan
		 * node.
		 */
		SO1_printf("Sorting presorted prefix tuplesort with " INT64_FORMAT " tuples\n", nTuples);
		tuplesort_performsort(node->prefixsort_state);

		INSTRUMENT_SORT_GROUP(node, prefixsort);

		SO_printf("Setting execution_status to INCSORT_READPREFIXSORT (found end of group)\n");
		node->execution_status = INCSORT_READPREFIXSORT;

		if (node->bounded)
		{
			/*
			 * If the current node has a bound, and we've already sorted n
			 * tuples, then the functional bound remaining is (original bound
			 * - n), so store the current number of processed tuples for use
			 * in configuring sorting bound.
			 */
			SO2_printf("Changing bound_Done from " INT64_FORMAT " to " INT64_FORMAT "\n",
					   node->bound_Done,
					   Min(node->bound, node->bound_Done + nTuples));
			node->bound_Done = Min(node->bound, node->bound_Done + nTuples);
		}
	}

	/* Restore to user specified direction. */
	estate->es_direction = dir;

	/*
	 * Get the first or next tuple from tuplesort. Returns NULL if no more
	 * tuples.
	 */
	read_sortstate = node->execution_status == INCSORT_READFULLSORT ?
		fullsort_state : node->prefixsort_state;
	slot = node->ss.ps.ps_ResultTupleSlot;
	(void) tuplesort_gettupleslot(read_sortstate, ScanDirectionIsForward(dir),
								  false, slot, NULL);
	return slot;
}

/* ----------------------------------------------------------------
 *		ExecInitIncrementalSort
 *
 *		Creates the run-time state information for the sort node
 *		produced by the planner and initializes its outer subtree.
 * ----------------------------------------------------------------
 */
IncrementalSortState *
ExecInitIncrementalSort(IncrementalSort *node, EState *estate, int eflags)
{
	IncrementalSortState *incrsortstate;

	SO_printf("ExecInitIncrementalSort: initializing sort node\n");

	/*
	 * Incremental sort can't be used with EXEC_FLAG_BACKWARD or
	 * EXEC_FLAG_MARK, because the current sort state contains only one sort
	 * batch rather than the full result set.
	 */
	Assert((eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)) == 0);

	/* Initialize state structure. */
	incrsortstate = makeNode(IncrementalSortState);
	incrsortstate->ss.ps.plan = (Plan *) node;
	incrsortstate->ss.ps.state = estate;
	incrsortstate->ss.ps.ExecProcNode = ExecIncrementalSort;

	incrsortstate->execution_status = INCSORT_LOADFULLSORT;
	incrsortstate->bounded = false;
	incrsortstate->outerNodeDone = false;
	incrsortstate->bound_Done = 0;
	incrsortstate->fullsort_state = NULL;
	incrsortstate->prefixsort_state = NULL;
	incrsortstate->group_pivot = NULL;
	incrsortstate->transfer_tuple = NULL;
	incrsortstate->n_fullsort_remaining = 0;
	incrsortstate->presorted_keys = NULL;

	if (incrsortstate->ss.ps.instrument != NULL)
	{
		IncrementalSortGroupInfo *fullsortGroupInfo =
			&incrsortstate->incsort_info.fullsortGroupInfo;
		IncrementalSortGroupInfo *prefixsortGroupInfo =
			&incrsortstate->incsort_info.prefixsortGroupInfo;

		fullsortGroupInfo->groupCount = 0;
		fullsortGroupInfo->maxDiskSpaceUsed = 0;
		fullsortGroupInfo->totalDiskSpaceUsed = 0;
		fullsortGroupInfo->maxMemorySpaceUsed = 0;
		fullsortGroupInfo->totalMemorySpaceUsed = 0;
		fullsortGroupInfo->sortMethods = 0;
		prefixsortGroupInfo->groupCount = 0;
		prefixsortGroupInfo->maxDiskSpaceUsed = 0;
		prefixsortGroupInfo->totalDiskSpaceUsed = 0;
		prefixsortGroupInfo->maxMemorySpaceUsed = 0;
		prefixsortGroupInfo->totalMemorySpaceUsed = 0;
		prefixsortGroupInfo->sortMethods = 0;
	}

	/*
	 * Miscellaneous initialization
	 *
	 * Sort nodes don't initialize their ExprContexts because they never call
	 * ExecQual or ExecProject.
	 */

	/*
	 * Initialize child nodes.
	 *
	 * Incremental sort does not support backwards scans and mark/restore, so
	 * we don't bother removing the flags from eflags here. We allow passing a
	 * REWIND flag, because although incremental sort can't use it, the child
	 * nodes may be able to do something more useful.
	 */
	outerPlanState(incrsortstate) = ExecInitNode(outerPlan(node), estate, eflags);

	/*
	 * Initialize scan slot and type.
	 */
	ExecCreateScanSlotFromOuterPlan(estate, &incrsortstate->ss, &TTSOpsMinimalTuple);

	/*
	 * Initialize return slot and type. No need to initialize projection info
	 * because we don't do any projections.
	 */
	ExecInitResultTupleSlotTL(&incrsortstate->ss.ps, &TTSOpsMinimalTuple);
	incrsortstate->ss.ps.ps_ProjInfo = NULL;

	/*
	 * Initialize standalone slots to store a tuple for pivot prefix keys and
	 * for carrying over a tuple from one batch to the next.
	 */
	incrsortstate->group_pivot =
		MakeSingleTupleTableSlot(ExecGetResultType(outerPlanState(incrsortstate)),
								 &TTSOpsMinimalTuple);
	incrsortstate->transfer_tuple =
		MakeSingleTupleTableSlot(ExecGetResultType(outerPlanState(incrsortstate)),
								 &TTSOpsMinimalTuple);

	SO_printf("ExecInitIncrementalSort: sort node initialized\n");

	return incrsortstate;
}

/* ----------------------------------------------------------------
 *		ExecEndIncrementalSort(node)
 * ----------------------------------------------------------------
 */
void
ExecEndIncrementalSort(IncrementalSortState *node)
{
	SO_printf("ExecEndIncrementalSort: shutting down sort node\n");

	/* clean out the scan tuple */
	ExecClearTuple(node->ss.ss_ScanTupleSlot);
	/* must drop pointer to sort result tuple */
	ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
	/* must drop standalone tuple slots from outer node */
	ExecDropSingleTupleTableSlot(node->group_pivot);
	ExecDropSingleTupleTableSlot(node->transfer_tuple);

	/*
	 * Release tuplesort resources.
	 */
	if (node->fullsort_state != NULL)
	{
		tuplesort_end(node->fullsort_state);
		node->fullsort_state = NULL;
	}
	if (node->prefixsort_state != NULL)
	{
		tuplesort_end(node->prefixsort_state);
		node->prefixsort_state = NULL;
	}

	/*
	 * Shut down the subplan.
	 */
	ExecEndNode(outerPlanState(node));

	SO_printf("ExecEndIncrementalSort: sort node shutdown\n");
}

void
ExecReScanIncrementalSort(IncrementalSortState *node)
{
	PlanState  *outerPlan = outerPlanState(node);

	/*
	 * Incremental sort doesn't support efficient rescan even when parameters
	 * haven't changed (e.g., rewind) because unlike regular sort we don't
	 * store all tuples at once for the full sort.
	 *
	 * So even if EXEC_FLAG_REWIND is set we just reset all of our state and
	 * re-execute the sort along with the child node. Incremental sort itself
	 * can't do anything smarter, but maybe the child nodes can.
	 *
	 * In theory if we've only filled the full sort with one batch (and
	 * haven't reset it for a new batch yet) then we could efficiently rewind,
	 * but that seems a narrow enough case that it's not worth handling
	 * specially at this time.
	 */

	/* must drop pointer to sort result tuple */
	ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

	if (node->group_pivot != NULL)
		ExecClearTuple(node->group_pivot);
	if (node->transfer_tuple != NULL)
		ExecClearTuple(node->transfer_tuple);

	node->outerNodeDone = false;
	node->n_fullsort_remaining = 0;
	node->bound_Done = 0;

	node->execution_status = INCSORT_LOADFULLSORT;

	/*
	 * If we've set up either of the sort states yet, we need to reset them.
	 * We could end them and null out the pointers, but there's no reason to
	 * repay the setup cost, and because ExecIncrementalSort guards presorted
	 * column functions by checking to see if the full sort state has been
	 * initialized yet, setting the sort states to null here might actually
	 * cause a leak.
	 */
	if (node->fullsort_state != NULL)
		tuplesort_reset(node->fullsort_state);
	if (node->prefixsort_state != NULL)
		tuplesort_reset(node->prefixsort_state);

	/*
	 * If chgParam of subnode is not null, then the plan will be re-scanned by
	 * the first ExecProcNode.
	 */
	if (outerPlan->chgParam == NULL)
		ExecReScan(outerPlan);
}

void ExecSquelchIncrementalSort(IncrementalSortState *node, bool force)
{
	node->ss.ps.squelched = true;
	ExecSquelchNode(outerPlanState(node), force);
}

/* ----------------------------------------------------------------
 *						Parallel Query Support
 * ----------------------------------------------------------------
 */

/* ----------------------------------------------------------------
 *		ExecSortEstimate
 *
 *		Estimate space required to propagate sort statistics.
 * ----------------------------------------------------------------
 */
void
ExecIncrementalSortEstimate(IncrementalSortState *node, ParallelContext *pcxt)
{
	Size		size;

	/* don't need this if not instrumenting or no workers */
	if (!node->ss.ps.instrument || pcxt->nworkers == 0)
		return;

	size = mul_size(pcxt->nworkers, sizeof(IncrementalSortInfo));
	size = add_size(size, offsetof(SharedIncrementalSortInfo, sinfo));
	shm_toc_estimate_chunk(&pcxt->estimator, size);
	shm_toc_estimate_keys(&pcxt->estimator, 1);
}

/* ----------------------------------------------------------------
 *		ExecSortInitializeDSM
 *
 *		Initialize DSM space for sort statistics.
 * ----------------------------------------------------------------
 */
void
ExecIncrementalSortInitializeDSM(IncrementalSortState *node, ParallelContext *pcxt)
{
	Size		size;

	/* don't need this if not instrumenting or no workers */
	if (!node->ss.ps.instrument || pcxt->nworkers == 0)
		return;

	size = offsetof(SharedIncrementalSortInfo, sinfo)
		+ pcxt->nworkers * sizeof(IncrementalSortInfo);
	node->shared_info = shm_toc_allocate(pcxt->toc, size);
	/* ensure any unfilled slots will contain zeroes */
	memset(node->shared_info, 0, size);
	node->shared_info->num_workers = pcxt->nworkers;
	shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id,
				   node->shared_info);
}

/* ----------------------------------------------------------------
 *		ExecSortInitializeWorker
 *
 *		Attach worker to DSM space for sort statistics.
 * ----------------------------------------------------------------
 */
void
ExecIncrementalSortInitializeWorker(IncrementalSortState *node, ParallelWorkerContext *pwcxt)
{
	node->shared_info =
		shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, true);
	node->am_worker = true;
}

/* ----------------------------------------------------------------
 *		ExecSortRetrieveInstrumentation
 *
 *		Transfer sort statistics from DSM to private memory.
 * ----------------------------------------------------------------
 */
void
ExecIncrementalSortRetrieveInstrumentation(IncrementalSortState *node)
{
	Size		size;
	SharedIncrementalSortInfo *si;

	if (node->shared_info == NULL)
		return;

	size = offsetof(SharedIncrementalSortInfo, sinfo)
		+ node->shared_info->num_workers * sizeof(IncrementalSortInfo);
	si = palloc(size);
	memcpy(si, node->shared_info, size);
	node->shared_info = si;
}
