PostgreSQL Source Code  git master
nodeIncrementalSort.h File Reference
#include "access/parallel.h"
#include "nodes/execnodes.h"
Include dependency graph for nodeIncrementalSort.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

IncrementalSortStateExecInitIncrementalSort (IncrementalSort *node, EState *estate, int eflags)
 
void ExecEndIncrementalSort (IncrementalSortState *node)
 
void ExecReScanIncrementalSort (IncrementalSortState *node)
 
void ExecIncrementalSortEstimate (IncrementalSortState *node, ParallelContext *pcxt)
 
void ExecIncrementalSortInitializeDSM (IncrementalSortState *node, ParallelContext *pcxt)
 
void ExecIncrementalSortInitializeWorker (IncrementalSortState *node, ParallelWorkerContext *pcxt)
 
void ExecIncrementalSortRetrieveInstrumentation (IncrementalSortState *node)
 

Function Documentation

◆ ExecEndIncrementalSort()

void ExecEndIncrementalSort ( IncrementalSortState node)

Definition at line 1092 of file nodeIncrementalSort.c.

References ExecClearTuple(), ExecDropSingleTupleTableSlot(), ExecEndNode(), IncrementalSortState::fullsort_state, IncrementalSortState::group_pivot, outerPlanState, IncrementalSortState::prefixsort_state, ScanState::ps, PlanState::ps_ResultTupleSlot, SO_printf, IncrementalSortState::ss, ScanState::ss_ScanTupleSlot, IncrementalSortState::transfer_tuple, and tuplesort_end().

Referenced by ExecEndNode().

1093 {
1094  SO_printf("ExecEndIncrementalSort: shutting down sort node\n");
1095 
1096  /* clean out the scan tuple */
1098  /* must drop pointer to sort result tuple */
1100  /* must drop stanalone tuple slots from outer node */
1103 
1104  /*
1105  * Release tuplesort resources.
1106  */
1107  if (node->fullsort_state != NULL)
1108  {
1110  node->fullsort_state = NULL;
1111  }
1112  if (node->prefixsort_state != NULL)
1113  {
1115  node->prefixsort_state = NULL;
1116  }
1117 
1118  /*
1119  * Shut down the subplan.
1120  */
1121  ExecEndNode(outerPlanState(node));
1122 
1123  SO_printf("ExecEndIncrementalSort: sort node shutdown\n");
1124 }
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:543
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1331
PlanState ps
Definition: execnodes.h:1328
#define SO_printf(s)
Definition: execdebug.h:92
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:977
#define outerPlanState(node)
Definition: execnodes.h:1033
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
Tuplesortstate * fullsort_state
Definition: execnodes.h:2076
Tuplesortstate * prefixsort_state
Definition: execnodes.h:2077
TupleTableSlot * group_pivot
Definition: execnodes.h:2084
void tuplesort_end(Tuplesortstate *state)
Definition: tuplesort.c:1445
TupleTableSlot * transfer_tuple
Definition: execnodes.h:2085

◆ ExecIncrementalSortEstimate()

void ExecIncrementalSortEstimate ( IncrementalSortState node,
ParallelContext pcxt 
)

Definition at line 1200 of file nodeIncrementalSort.c.

References add_size(), ParallelContext::estimator, PlanState::instrument, mul_size(), ParallelContext::nworkers, offsetof, ScanState::ps, shm_toc_estimate_chunk, shm_toc_estimate_keys, and IncrementalSortState::ss.

Referenced by ExecParallelEstimate().

1201 {
1202  Size size;
1203 
1204  /* don't need this if not instrumenting or no workers */
1205  if (!node->ss.ps.instrument || pcxt->nworkers == 0)
1206  return;
1207 
1208  size = mul_size(pcxt->nworkers, sizeof(IncrementalSortInfo));
1209  size = add_size(size, offsetof(SharedIncrementalSortInfo, sinfo));
1210  shm_toc_estimate_chunk(&pcxt->estimator, size);
1211  shm_toc_estimate_keys(&pcxt->estimator, 1);
1212 }
Instrumentation * instrument
Definition: execnodes.h:949
shm_toc_estimator estimator
Definition: parallel.h:42
#define shm_toc_estimate_chunk(e, sz)
Definition: shm_toc.h:51
PlanState ps
Definition: execnodes.h:1328
Size mul_size(Size s1, Size s2)
Definition: shmem.c:515
Size add_size(Size s1, Size s2)
Definition: shmem.c:498
size_t Size
Definition: c.h:474
#define shm_toc_estimate_keys(e, cnt)
Definition: shm_toc.h:53
#define offsetof(type, field)
Definition: c.h:669

◆ ExecIncrementalSortInitializeDSM()

void ExecIncrementalSortInitializeDSM ( IncrementalSortState node,
ParallelContext pcxt 
)

Definition at line 1221 of file nodeIncrementalSort.c.

References PlanState::instrument, SharedIncrementalSortInfo::num_workers, ParallelContext::nworkers, offsetof, PlanState::plan, Plan::plan_node_id, ScanState::ps, IncrementalSortState::shared_info, shm_toc_allocate(), shm_toc_insert(), IncrementalSortState::ss, and ParallelContext::toc.

Referenced by ExecParallelInitializeDSM().

1222 {
1223  Size size;
1224 
1225  /* don't need this if not instrumenting or no workers */
1226  if (!node->ss.ps.instrument || pcxt->nworkers == 0)
1227  return;
1228 
1229  size = offsetof(SharedIncrementalSortInfo, sinfo)
1230  + pcxt->nworkers * sizeof(IncrementalSortInfo);
1231  node->shared_info = shm_toc_allocate(pcxt->toc, size);
1232  /* ensure any unfilled slots will contain zeroes */
1233  memset(node->shared_info, 0, size);
1234  node->shared_info->num_workers = pcxt->nworkers;
1235  shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id,
1236  node->shared_info);
1237 }
Instrumentation * instrument
Definition: execnodes.h:949
int plan_node_id
Definition: plannodes.h:135
PlanState ps
Definition: execnodes.h:1328
Plan * plan
Definition: execnodes.h:939
struct IncrementalSortInfo IncrementalSortInfo
size_t Size
Definition: c.h:474
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
Definition: shm_toc.c:88
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Definition: shm_toc.c:171
SharedIncrementalSortInfo * shared_info
Definition: execnodes.h:2087
#define offsetof(type, field)
Definition: c.h:669
shm_toc * toc
Definition: parallel.h:45

◆ ExecIncrementalSortInitializeWorker()

void ExecIncrementalSortInitializeWorker ( IncrementalSortState node,
ParallelWorkerContext pcxt 
)

Definition at line 1246 of file nodeIncrementalSort.c.

References IncrementalSortState::am_worker, PlanState::plan, Plan::plan_node_id, ScanState::ps, IncrementalSortState::shared_info, shm_toc_lookup(), IncrementalSortState::ss, and ParallelWorkerContext::toc.

Referenced by ExecParallelInitializeWorker().

1247 {
1248  node->shared_info =
1249  shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, true);
1250  node->am_worker = true;
1251 }
int plan_node_id
Definition: plannodes.h:135
PlanState ps
Definition: execnodes.h:1328
Plan * plan
Definition: execnodes.h:939
SharedIncrementalSortInfo * shared_info
Definition: execnodes.h:2087
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
Definition: shm_toc.c:232

◆ ExecIncrementalSortRetrieveInstrumentation()

void ExecIncrementalSortRetrieveInstrumentation ( IncrementalSortState node)

Definition at line 1260 of file nodeIncrementalSort.c.

References SharedIncrementalSortInfo::num_workers, offsetof, palloc(), and IncrementalSortState::shared_info.

Referenced by ExecParallelRetrieveInstrumentation().

1261 {
1262  Size size;
1264 
1265  if (node->shared_info == NULL)
1266  return;
1267 
1268  size = offsetof(SharedIncrementalSortInfo, sinfo)
1269  + node->shared_info->num_workers * sizeof(IncrementalSortInfo);
1270  si = palloc(size);
1271  memcpy(si, node->shared_info, size);
1272  node->shared_info = si;
1273 }
struct IncrementalSortInfo IncrementalSortInfo
size_t Size
Definition: c.h:474
void * palloc(Size size)
Definition: mcxt.c:950
SharedIncrementalSortInfo * shared_info
Definition: execnodes.h:2087
#define offsetof(type, field)
Definition: c.h:669

◆ ExecInitIncrementalSort()

IncrementalSortState* ExecInitIncrementalSort ( IncrementalSort node,
EState estate,
int  eflags 
)

Definition at line 991 of file nodeIncrementalSort.c.

References Assert, IncrementalSortState::bound_Done, IncrementalSortState::bounded, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecCreateScanSlotFromOuterPlan(), ExecGetResultType(), ExecIncrementalSort(), ExecInitNode(), ExecInitResultTupleSlotTL(), PlanState::ExecProcNode, IncrementalSortState::execution_status, IncrementalSortState::fullsort_state, IncrementalSortInfo::fullsortGroupInfo, IncrementalSortState::group_pivot, IncrementalSortGroupInfo::groupCount, IncrementalSortState::incsort_info, INCSORT_LOADFULLSORT, PlanState::instrument, makeNode, MakeSingleTupleTableSlot(), IncrementalSortGroupInfo::maxDiskSpaceUsed, IncrementalSortGroupInfo::maxMemorySpaceUsed, IncrementalSortState::n_fullsort_remaining, IncrementalSortState::outerNodeDone, outerPlan, outerPlanState, PlanState::plan, IncrementalSortState::prefixsort_state, IncrementalSortInfo::prefixsortGroupInfo, IncrementalSortState::presorted_keys, ScanState::ps, PlanState::ps_ProjInfo, SO_printf, IncrementalSortGroupInfo::sortMethods, IncrementalSortState::ss, PlanState::state, IncrementalSortGroupInfo::totalDiskSpaceUsed, IncrementalSortGroupInfo::totalMemorySpaceUsed, IncrementalSortState::transfer_tuple, and TTSOpsMinimalTuple.

Referenced by ExecInitNode().

992 {
993  IncrementalSortState *incrsortstate;
994 
995  SO_printf("ExecInitIncrementalSort: initializing sort node\n");
996 
997  /*
998  * Incremental sort can't be used with EXEC_FLAG_BACKWARD or
999  * EXEC_FLAG_MARK, because the current sort state contains only one sort
1000  * batch rather than the full result set.
1001  */
1002  Assert((eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)) == 0);
1003 
1004  /* Initialize state structure. */
1005  incrsortstate = makeNode(IncrementalSortState);
1006  incrsortstate->ss.ps.plan = (Plan *) node;
1007  incrsortstate->ss.ps.state = estate;
1008  incrsortstate->ss.ps.ExecProcNode = ExecIncrementalSort;
1009 
1010  incrsortstate->execution_status = INCSORT_LOADFULLSORT;
1011  incrsortstate->bounded = false;
1012  incrsortstate->outerNodeDone = false;
1013  incrsortstate->bound_Done = 0;
1014  incrsortstate->fullsort_state = NULL;
1015  incrsortstate->prefixsort_state = NULL;
1016  incrsortstate->group_pivot = NULL;
1017  incrsortstate->transfer_tuple = NULL;
1018  incrsortstate->n_fullsort_remaining = 0;
1019  incrsortstate->presorted_keys = NULL;
1020 
1021  if (incrsortstate->ss.ps.instrument != NULL)
1022  {
1023  IncrementalSortGroupInfo *fullsortGroupInfo =
1024  &incrsortstate->incsort_info.fullsortGroupInfo;
1025  IncrementalSortGroupInfo *prefixsortGroupInfo =
1026  &incrsortstate->incsort_info.prefixsortGroupInfo;
1027 
1028  fullsortGroupInfo->groupCount = 0;
1029  fullsortGroupInfo->maxDiskSpaceUsed = 0;
1030  fullsortGroupInfo->totalDiskSpaceUsed = 0;
1031  fullsortGroupInfo->maxMemorySpaceUsed = 0;
1032  fullsortGroupInfo->totalMemorySpaceUsed = 0;
1033  fullsortGroupInfo->sortMethods = 0;
1034  prefixsortGroupInfo->groupCount = 0;
1035  prefixsortGroupInfo->maxDiskSpaceUsed = 0;
1036  prefixsortGroupInfo->totalDiskSpaceUsed = 0;
1037  prefixsortGroupInfo->maxMemorySpaceUsed = 0;
1038  prefixsortGroupInfo->totalMemorySpaceUsed = 0;
1039  prefixsortGroupInfo->sortMethods = 0;
1040  }
1041 
1042  /*
1043  * Miscellaneous initialization
1044  *
1045  * Sort nodes don't initialize their ExprContexts because they never call
1046  * ExecQual or ExecProject.
1047  */
1048 
1049  /*
1050  * Initialize child nodes.
1051  *
1052  * Incremental sort does not support backwards scans and mark/restore, so
1053  * we don't bother removing the flags from eflags here. We allow passing a
1054  * REWIND flag, because although incremental sort can't use it, the child
1055  * nodes may be able to do something more useful.
1056  */
1057  outerPlanState(incrsortstate) = ExecInitNode(outerPlan(node), estate, eflags);
1058 
1059  /*
1060  * Initialize scan slot and type.
1061  */
1062  ExecCreateScanSlotFromOuterPlan(estate, &incrsortstate->ss, &TTSOpsMinimalTuple);
1063 
1064  /*
1065  * Initialize return slot and type. No need to initialize projection info
1066  * because we don't do any projections.
1067  */
1069  incrsortstate->ss.ps.ps_ProjInfo = NULL;
1070 
1071  /*
1072  * Initialize standalone slots to store a tuple for pivot prefix keys and
1073  * for carrying over a tuple from one batch to the next.
1074  */
1075  incrsortstate->group_pivot =
1078  incrsortstate->transfer_tuple =
1081 
1082  SO_printf("ExecInitIncrementalSort: sort node initialized\n");
1083 
1084  return incrsortstate;
1085 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:979
Instrumentation * instrument
Definition: execnodes.h:949
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1208
IncrementalSortGroupInfo prefixsortGroupInfo
Definition: execnodes.h:2042
PresortedKeyData * presorted_keys
Definition: execnodes.h:2079
EState * state
Definition: execnodes.h:941
PlanState ps
Definition: execnodes.h:1328
#define SO_printf(s)
Definition: execdebug.h:92
IncrementalSortInfo incsort_info
Definition: execnodes.h:2081
#define EXEC_FLAG_BACKWARD
Definition: executor.h:58
#define outerPlanState(node)
Definition: execnodes.h:1033
IncrementalSortExecutionStatus execution_status
Definition: execnodes.h:2074
static TupleTableSlot * ExecIncrementalSort(PlanState *pstate)
#define outerPlan(node)
Definition: plannodes.h:166
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:945
IncrementalSortGroupInfo fullsortGroupInfo
Definition: execnodes.h:2041
Tuplesortstate * fullsort_state
Definition: execnodes.h:2076
Plan * plan
Definition: execnodes.h:939
#define makeNode(_type_)
Definition: nodes.h:576
#define Assert(condition)
Definition: c.h:746
#define EXEC_FLAG_MARK
Definition: executor.h:59
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1769
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:489
Tuplesortstate * prefixsort_state
Definition: execnodes.h:2077
TupleTableSlot * group_pivot
Definition: execnodes.h:2084
void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
Definition: execUtils.c:681
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
const TupleTableSlotOps TTSOpsMinimalTuple
Definition: execTuples.c:85
TupleTableSlot * transfer_tuple
Definition: execnodes.h:2085

◆ ExecReScanIncrementalSort()

void ExecReScanIncrementalSort ( IncrementalSortState node)

Definition at line 1127 of file nodeIncrementalSort.c.

References IncrementalSortState::bound_Done, PlanState::chgParam, ExecClearTuple(), ExecReScan(), IncrementalSortState::execution_status, IncrementalSortState::fullsort_state, IncrementalSortState::group_pivot, INCSORT_LOADFULLSORT, IncrementalSortState::n_fullsort_remaining, IncrementalSortState::outerNodeDone, outerPlan, outerPlanState, IncrementalSortState::prefixsort_state, IncrementalSortState::presorted_keys, ScanState::ps, PlanState::ps_ResultTupleSlot, IncrementalSortState::ss, IncrementalSortState::transfer_tuple, and tuplesort_reset().

Referenced by ExecReScan().

1128 {
1130 
1131  /*
1132  * Incremental sort doesn't support efficient rescan even when parameters
1133  * haven't changed (e.g., rewind) because unlike regular sort we don't
1134  * store all tuples at once for the full sort.
1135  *
1136  * So even if EXEC_FLAG_REWIND is set we just reset all of our state and
1137  * re-execute the sort along with the child node. Incremental sort itself
1138  * can't do anything smarter, but maybe the child nodes can.
1139  *
1140  * In theory if we've only filled the full sort with one batch (and
1141  * haven't reset it for a new batch yet) then we could efficiently rewind,
1142  * but that seems a narrow enough case that it's not worth handling
1143  * specially at this time.
1144  */
1145 
1146  /* must drop pointer to sort result tuple */
1148 
1149  if (node->group_pivot != NULL)
1150  ExecClearTuple(node->group_pivot);
1151  if (node->transfer_tuple != NULL)
1153 
1154  node->outerNodeDone = false;
1155  node->n_fullsort_remaining = 0;
1156  node->bound_Done = 0;
1157  node->presorted_keys = NULL;
1158 
1160 
1161  /*
1162  * If we've set up either of the sort states yet, we need to reset them.
1163  * We could end them and null out the pointers, but there's no reason to
1164  * repay the setup cost, and because ExecIncrementalSort guards presorted
1165  * column functions by checking to see if the full sort state has been
1166  * initialized yet, setting the sort states to null here might actually
1167  * cause a leak.
1168  */
1169  if (node->fullsort_state != NULL)
1170  {
1172  node->fullsort_state = NULL;
1173  }
1174  if (node->prefixsort_state != NULL)
1175  {
1177  node->prefixsort_state = NULL;
1178  }
1179 
1180  /*
1181  * If chgParam of subnode is not null, theni the plan will be re-scanned
1182  * by the first ExecProcNode.
1183  */
1184  if (outerPlan->chgParam == NULL)
1185  ExecReScan(outerPlan);
1186 }
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
PresortedKeyData * presorted_keys
Definition: execnodes.h:2079
PlanState ps
Definition: execnodes.h:1328
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:977
void tuplesort_reset(Tuplesortstate *state)
Definition: tuplesort.c:1513
#define outerPlanState(node)
Definition: execnodes.h:1033
IncrementalSortExecutionStatus execution_status
Definition: execnodes.h:2074
Bitmapset * chgParam
Definition: execnodes.h:971
#define outerPlan(node)
Definition: plannodes.h:166
Tuplesortstate * fullsort_state
Definition: execnodes.h:2076
Tuplesortstate * prefixsort_state
Definition: execnodes.h:2077
TupleTableSlot * group_pivot
Definition: execnodes.h:2084
TupleTableSlot * transfer_tuple
Definition: execnodes.h:2085