PostgreSQL Source Code: src/backend/executor/nodeIncrementalSort.c File Reference (original) (raw)
Go to the source code of this file.
Macros | |
---|---|
#define | INSTRUMENT_SORT_GROUP(node, groupName) |
#define | DEFAULT_MIN_GROUP_SIZE 32 |
#define | DEFAULT_MAX_FULL_SORT_GROUP_SIZE (2 * DEFAULT_MIN_GROUP_SIZE) |
Functions | |
---|---|
static void | instrumentSortedGroup (IncrementalSortGroupInfo *groupInfo, Tuplesortstate *sortState) |
static void | preparePresortedCols (IncrementalSortState *node) |
static bool | isCurrentGroup (IncrementalSortState *node, TupleTableSlot *pivot, TupleTableSlot *tuple) |
static void | switchToPresortedPrefixMode (PlanState *pstate) |
static TupleTableSlot * | ExecIncrementalSort (PlanState *pstate) |
IncrementalSortState * | ExecInitIncrementalSort (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 *pwcxt) |
void | ExecIncrementalSortRetrieveInstrumentation (IncrementalSortState *node) |
◆ DEFAULT_MAX_FULL_SORT_GROUP_SIZE
◆ DEFAULT_MIN_GROUP_SIZE
#define DEFAULT_MIN_GROUP_SIZE 32
◆ INSTRUMENT_SORT_GROUP
| #define INSTRUMENT_SORT_GROUP | ( | | node, | | ------------------------------- | - | | ----- | | | groupName | | | | | ) | | | |
Value:
do { \
if ((node)->ss.ps.instrument != NULL) \
{ \
if ((node)->shared_info && (node)->am_worker) \
{ \
instrumentSortedGroup(&(node)->shared_info->sinfo[ParallelWorkerNumber].groupName##GroupInfo, \
(node)->groupName##_state); \
} \
else \
{ \
instrumentSortedGroup(&(node)->incsort_info.groupName##GroupInfo, \
(node)->groupName##_state); \
} \
} \
} while (0)
#define IsParallelWorker()
Definition at line 98 of file nodeIncrementalSort.c.
◆ ExecEndIncrementalSort()
◆ ExecIncrementalSort()
Definition at line 495 of file nodeIncrementalSort.c.
496{
506 int64 nTuples = 0;
507 int64 minGroupSize;
508
510
514
515
516
517
518
519
522 {
523
524
525
529
530
531
532
533
534
535
536
537
540
541
542
543
544
545
546 return slot;
548 {
549
550
551
552
553
554
555
556
557
558
559
560 SO1_printf("Re-calling switchToPresortedPrefixMode() because n_fullsort_remaining is > 0 (" INT64_FORMAT ")\n",
563 }
564 else
565 {
566
567
568
569
570
571
572 SO_printf("Setting execution_status to INCSORT_LOADFULLSORT (n_fullsort_remaining > 0)\n");
574 }
575 }
576
577
578
579
580
582
585
586
588 {
589
590
591
592 if (fullsort_state == NULL)
593 {
594
595
596
597
598
599
600
602
603
604
605
606
607
608
609
612 plannode->sort.sortColIdx,
613 plannode->sort.sortOperators,
614 plannode->sort.collations,
615 plannode->sort.nullsFirst,
617 NULL,
622 }
623 else
624 {
625
627 }
628
629
630
631
632
634 {
636
637
638
639
640
641
642
645
647 }
648 else
650
651
652
653
654
655
656
658 {
660 nTuples++;
661
662
663
664
665
666
667
668
669 if (nTuples != minGroupSize)
671 }
672
673
674
675
676
677
678 for (;;)
679 {
681
682
683
684
685
687 {
688
689
690
691
692
694
697
699
700 SO_printf("Setting execution_status to INCSORT_READFULLSORT (final tuple)\n");
702 break;
703 }
704
705
706 if (nTuples < minGroupSize)
707 {
708
709
710
711
712
713
714
716 nTuples++;
717
718
719
720
721
722 if (nTuples == minGroupSize)
724 }
725 else
726 {
727
728
729
730
731
732
733
734
736 {
737
738
739
740
742 nTuples++;
743 }
744 else
745 {
746
747
748
749
750
751
752
754
756 {
757
758
759
760
761
762
763
768 }
769
770
771
772
773
774
776 nTuples);
778
780
781 SO_printf("Setting execution_status to INCSORT_READFULLSORT (found end of group)\n");
783 break;
784 }
785 }
786
787
788
789
790
791
792
793
794
797 {
798
799
800
801
802
803
804
805
806
808
809
810
811
812
813
814
815
818
820
821
822
823
824
825
826
827
828
829
830
832 {
834
836 nTuples, Min(currentBound, nTuples));
837 nTuples = Min(currentBound, nTuples);
838 }
839
840 SO1_printf("Setting n_fullsort_remaining to " INT64_FORMAT " and calling switchToPresortedPrefixMode()\n",
841 nTuples);
842
843
844
845
846
847
848
850
851
853
854
855
856
857
858
859
860
861
862
863
864
865
866 break;
867 }
868 }
869 }
870
872 {
873
874
875
876
877
878
879
881
882
883
884
885
886
887
888 for (;;)
889 {
891
892
893
894
895
897 {
898
899
900
901
902
904 break;
905 }
906
907
908
909
910
911
912
913
915 {
917 nTuples++;
918 }
919 else
920 {
922 break;
923 }
924 }
925
926
927
928
929
930 SO1_printf("Sorting presorted prefix tuplesort with " INT64_FORMAT " tuples\n", nTuples);
932
934
935 SO_printf("Setting execution_status to INCSORT_READPREFIXSORT (found end of group)\n");
937
939 {
940
941
942
943
944
945
950 }
951 }
952
953
955
956
957
958
959
964 false, slot, NULL);
965 return slot;
966}
TupleDesc ExecGetResultType(PlanState *planstate)
#define SO2_printf(s, p1, p2)
static TupleTableSlot * ExecProcNode(PlanState *node)
Assert(PointerIsAligned(start, uint64))
#define CHECK_FOR_INTERRUPTS()
static void switchToPresortedPrefixMode(PlanState *pstate)
#define INSTRUMENT_SORT_GROUP(node, groupName)
static bool isCurrentGroup(IncrementalSortState *node, TupleTableSlot *pivot, TupleTableSlot *tuple)
static void preparePresortedCols(IncrementalSortState *node)
#define DEFAULT_MAX_FULL_SORT_GROUP_SIZE
#define DEFAULT_MIN_GROUP_SIZE
#define castNode(_type_, nodeptr)
#define ScanDirectionIsForward(direction)
ScanDirection es_direction
IncrementalSortExecutionStatus execution_status
int64 n_fullsort_remaining
TupleTableSlot * ps_ResultTupleSlot
void tuplesort_performsort(Tuplesortstate *state)
void tuplesort_reset(Tuplesortstate *state)
bool tuplesort_used_bound(Tuplesortstate *state)
void tuplesort_set_bound(Tuplesortstate *state, int64 bound)
#define TUPLESORT_ALLOWBOUNDED
void tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
Tuplesortstate * tuplesort_begin_heap(TupleDesc tupDesc, int nkeys, AttrNumber *attNums, Oid *sortOperators, Oid *sortCollations, bool *nullsFirstFlags, int workMem, SortCoordinate coordinate, int sortopt)
bool tuplesort_gettupleslot(Tuplesortstate *state, bool forward, bool copy, TupleTableSlot *slot, Datum *abbrev)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
References Assert(), IncrementalSortState::bound, IncrementalSortState::bound_Done, IncrementalSortState::bounded, castNode, CHECK_FOR_INTERRUPTS, DEFAULT_MAX_FULL_SORT_GROUP_SIZE, DEFAULT_MIN_GROUP_SIZE, EState::es_direction, ExecClearTuple(), ExecCopySlot(), ExecGetResultType(), ExecProcNode(), IncrementalSortState::execution_status, ForwardScanDirection, IncrementalSortState::fullsort_state, IncrementalSortState::group_pivot, INCSORT_LOADFULLSORT, INCSORT_LOADPREFIXSORT, INCSORT_READFULLSORT, INCSORT_READPREFIXSORT, INSTRUMENT_SORT_GROUP, INT64_FORMAT, isCurrentGroup(), Min, IncrementalSortState::n_fullsort_remaining, Sort::numCols, IncrementalSortState::outerNodeDone, outerPlanState, PlanState::plan, IncrementalSortState::prefixsort_state, preparePresortedCols(), ScanState::ps, PlanState::ps_ResultTupleSlot, ScanDirectionIsForward, SO1_printf, SO2_printf, SO_printf, IncrementalSort::sort, IncrementalSortState::ss, PlanState::state, switchToPresortedPrefixMode(), TupIsNull, TUPLESORT_ALLOWBOUNDED, tuplesort_begin_heap(), tuplesort_gettupleslot(), TUPLESORT_NONE, tuplesort_performsort(), tuplesort_puttupleslot(), tuplesort_reset(), tuplesort_set_bound(), tuplesort_used_bound(), and work_mem.
Referenced by ExecInitIncrementalSort().
◆ ExecIncrementalSortEstimate()
Definition at line 1173 of file nodeIncrementalSort.c.
1174{
1176
1177
1179 return;
1180
1185}
#define shm_toc_estimate_chunk(e, sz)
#define shm_toc_estimate_keys(e, cnt)
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
shm_toc_estimator estimator
Instrumentation * instrument
References add_size(), ParallelContext::estimator, PlanState::instrument, mul_size(), ParallelContext::nworkers, ScanState::ps, shm_toc_estimate_chunk, shm_toc_estimate_keys, and IncrementalSortState::ss.
Referenced by ExecParallelEstimate().
◆ ExecIncrementalSortInitializeDSM()
Definition at line 1194 of file nodeIncrementalSort.c.
1195{
1197
1198
1200 return;
1201
1205
1210}
struct IncrementalSortInfo IncrementalSortInfo
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SharedIncrementalSortInfo * shared_info
References PlanState::instrument, SharedIncrementalSortInfo::num_workers, ParallelContext::nworkers, 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().
◆ ExecIncrementalSortInitializeWorker()
◆ ExecIncrementalSortRetrieveInstrumentation()
◆ ExecInitIncrementalSort()
Definition at line 976 of file nodeIncrementalSort.c.
977{
979
980 SO_printf("ExecInitIncrementalSort: initializing sort node\n");
981
982
983
984
985
986
988
989
992 incrsortstate->ss.ps.state = estate;
994
996 incrsortstate->bounded = false;
1005
1007 {
1012
1019 prefixsortGroupInfo->groupCount = 0;
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1043
1044
1045
1046
1048
1049
1050
1051
1052
1055
1056
1057
1058
1059
1066
1067 SO_printf("ExecInitIncrementalSort: sort node initialized\n");
1068
1069 return incrsortstate;
1070}
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsMinimalTuple
void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
#define EXEC_FLAG_BACKWARD
static TupleTableSlot * ExecIncrementalSort(PlanState *pstate)
int64 totalMemorySpaceUsed
IncrementalSortGroupInfo prefixsortGroupInfo
IncrementalSortGroupInfo fullsortGroupInfo
PresortedKeyData * presorted_keys
IncrementalSortInfo incsort_info
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
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().
◆ ExecReScanIncrementalSort()
Definition at line 1107 of file nodeIncrementalSort.c.
1108{
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1128
1133
1137
1139
1140
1141
1142
1143
1144
1145
1146
1147
1152
1153
1154
1155
1156
1157 if (outerPlan->chgParam == NULL)
1159}
void ExecReScan(PlanState *node)
References IncrementalSortState::bound_Done, ExecClearTuple(), ExecReScan(), IncrementalSortState::execution_status, IncrementalSortState::fullsort_state, IncrementalSortState::group_pivot, INCSORT_LOADFULLSORT, IncrementalSortState::n_fullsort_remaining, IncrementalSortState::outerNodeDone, outerPlan, outerPlanState, IncrementalSortState::prefixsort_state, ScanState::ps, PlanState::ps_ResultTupleSlot, IncrementalSortState::ss, IncrementalSortState::transfer_tuple, and tuplesort_reset().
Referenced by ExecReScan().
◆ instrumentSortedGroup()
Definition at line 127 of file nodeIncrementalSort.c.
129{
131
133
135
136
138 {
143
144 break;
149
150 break;
151 }
152
153
155}
TuplesortMethod sortMethod
TuplesortSpaceType spaceType
void tuplesort_get_stats(Tuplesortstate *state, TuplesortInstrumentation *stats)
References IncrementalSortGroupInfo::groupCount, IncrementalSortGroupInfo::maxDiskSpaceUsed, IncrementalSortGroupInfo::maxMemorySpaceUsed, SORT_SPACE_TYPE_DISK, SORT_SPACE_TYPE_MEMORY, TuplesortInstrumentation::sortMethod, IncrementalSortGroupInfo::sortMethods, TuplesortInstrumentation::spaceType, TuplesortInstrumentation::spaceUsed, IncrementalSortGroupInfo::totalDiskSpaceUsed, IncrementalSortGroupInfo::totalMemorySpaceUsed, and tuplesort_get_stats().
◆ isCurrentGroup()
Definition at line 212 of file nodeIncrementalSort.c.
213{
214 int nPresortedCols;
215
217
218
219
220
221
222
223
224 for (int i = nPresortedCols - 1; i >= 0; i--)
225 {
227 datumB,
228 result;
229 bool isnullA,
230 isnullB;
233
234 datumA = slot_getattr(pivot, attno, &isnullA);
235 datumB = slot_getattr(tuple, attno, &isnullB);
236
237
238 if (isnullA || isnullB)
239 {
240 if (isnullA == isnullB)
241 continue;
242 else
243 return false;
244 }
245
247
248 key->fcinfo->args[0].value = datumA;
249 key->fcinfo->args[1].value = datumB;
250
251
252 key->fcinfo->isnull = false;
253
255
256
257 if (key->fcinfo->isnull)
258 elog(ERROR, "function %u returned NULL", key->flinfo.fn_oid);
259
261 return false;
262 }
263 return true;
264}
#define FunctionCallInvoke(fcinfo)
static bool DatumGetBool(Datum X)
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
References PresortedKeyData::attno, castNode, DatumGetBool(), elog, ERROR, FunctionCallInvoke, i, sort-test::key, PlanState::plan, IncrementalSortState::presorted_keys, ScanState::ps, slot_getattr(), and IncrementalSortState::ss.
Referenced by ExecIncrementalSort(), and switchToPresortedPrefixMode().
◆ preparePresortedCols()
Definition at line 164 of file nodeIncrementalSort.c.
165{
167
171
172
174 {
175 Oid equalityOp,
176 equalityFunc;
178
180 key->attno = plannode->sort.sortColIdx[i];
181
183 NULL);
185 elog(ERROR, "missing equality operator for ordering operator %u",
186 plannode->sort.sortOperators[i]);
187
188 equalityFunc = get_opcode(equalityOp);
190 elog(ERROR, "missing function for operator %u", equalityOp);
191
192
194
195
198 plannode->sort.collations[i], NULL, NULL);
199 key->fcinfo->args[0].isnull = false;
200 key->fcinfo->args[1].isnull = false;
201 }
202}
#define OidIsValid(objectId)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
#define SizeForFunctionCallInfo(nargs)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse)
RegProcedure get_opcode(Oid opno)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
References castNode, CurrentMemoryContext, elog, ERROR, fmgr_info_cxt(), get_equality_op_for_ordering_op(), get_opcode(), i, InitFunctionCallInfoData, sort-test::key, IncrementalSort::nPresortedCols, OidIsValid, palloc(), palloc0(), PlanState::plan, IncrementalSortState::presorted_keys, ScanState::ps, SizeForFunctionCallInfo, IncrementalSort::sort, and IncrementalSortState::ss.
Referenced by ExecIncrementalSort().
◆ switchToPresortedPrefixMode()
static void switchToPresortedPrefixMode ( PlanState * pstate) | static |
---|
Definition at line 286 of file nodeIncrementalSort.c.
287{
294
298
299
301 {
304
305
306
307
308
311 &(plannode->sort.sortColIdx[nPresortedCols]),
312 &(plannode->sort.sortOperators[nPresortedCols]),
313 &(plannode->sort.collations[nPresortedCols]),
314 &(plannode->sort.nullsFirst[nPresortedCols]),
316 NULL,
319 }
320 else
321 {
322
324 }
325
326
327
328
329
330
332 {
337 }
338
339
340
341
342
344 {
345
346
347
348
349
351 {
353
355 }
356 else
357 {
361
362
363
364
365
368
370 {
372 }
373 else
374 {
375
376
377
378
379
380
381
382
383
384
385
386
387
389
390
391 break;
392 }
393 }
394 }
395
396
397
398
399
400
401
402 SO1_printf("Moving " INT64_FORMAT " tuples to presorted prefix tuplesort\n", nTuples);
405
407 {
408
409
410
411
412
413
414
415
417 SO_printf("Setting execution_status to INCSORT_LOADPREFIXSORT (switchToPresortedPrefixMode)\n");
419
420
421
422
423
424
426 }
427 else
428 {
429
430
431
432
433
434
435 SO1_printf("Sorting presorted prefix tuplesort with " INT64_FORMAT " tuples\n", nTuples);
437
439
441 {
442
443
444
445
446
447
451 }
452
453 SO_printf("Setting execution_status to INCSORT_READPREFIXSORT (switchToPresortedPrefixMode)\n");
455 }
456}
References IncrementalSortState::bound, IncrementalSortState::bound_Done, IncrementalSortState::bounded, castNode, EState::es_direction, ExecClearTuple(), ExecCopySlot(), ExecGetResultType(), IncrementalSortState::execution_status, IncrementalSortState::fullsort_state, IncrementalSortState::group_pivot, INCSORT_LOADPREFIXSORT, INCSORT_READPREFIXSORT, INSTRUMENT_SORT_GROUP, INT64_FORMAT, isCurrentGroup(), Min, IncrementalSortState::n_fullsort_remaining, IncrementalSort::nPresortedCols, Sort::numCols, outerPlanState, PlanState::plan, IncrementalSortState::prefixsort_state, ScanState::ps, ScanDirectionIsForward, SO1_printf, SO2_printf, SO_printf, IncrementalSort::sort, IncrementalSortState::ss, PlanState::state, IncrementalSortState::transfer_tuple, TupIsNull, TUPLESORT_ALLOWBOUNDED, tuplesort_begin_heap(), tuplesort_gettupleslot(), TUPLESORT_NONE, tuplesort_performsort(), tuplesort_puttupleslot(), tuplesort_reset(), tuplesort_set_bound(), and work_mem.
Referenced by ExecIncrementalSort().