PostgreSQL Source Code: src/backend/executor/nodeMemoize.c File Reference (original) (raw)
Go to the source code of this file.
Data Structures | |
---|---|
struct | MemoizeTuple |
struct | MemoizeKey |
struct | MemoizeEntry |
Macros | |
---|---|
#define | MEMO_CACHE_LOOKUP 1 /* Attempt to perform a cache lookup */ |
#define | MEMO_CACHE_FETCH_NEXT_TUPLE 2 /* Get another tuple from the cache */ |
#define | MEMO_FILLING_CACHE 3 /* Read outer node to fill cache */ |
#define | MEMO_CACHE_BYPASS_MODE |
#define | MEMO_END_OF_SCAN 5 /* Ready for rescan */ |
#define | EMPTY_ENTRY_MEMORY_BYTES(e) |
#define | CACHE_TUPLE_BYTES(t) |
#define | SH_PREFIX memoize |
#define | SH_ELEMENT_TYPE MemoizeEntry |
#define | SH_KEY_TYPE MemoizeKey * |
#define | SH_SCOPE static inline |
#define | SH_DECLARE |
#define | SH_PREFIX memoize |
#define | SH_ELEMENT_TYPE MemoizeEntry |
#define | SH_KEY_TYPE MemoizeKey * |
#define | SH_KEY key |
#define | SH_HASH_KEY(tb, key) MemoizeHash_hash(tb, key) |
#define | SH_EQUAL(tb, a, b) MemoizeHash_equal(tb, a, b) |
#define | SH_SCOPE static inline |
#define | SH_STORE_HASH |
#define | SH_GET_HASH(tb, a) a->hash |
#define | SH_DEFINE |
Typedefs | |
---|---|
typedef struct MemoizeTuple | MemoizeTuple |
typedef struct MemoizeKey | MemoizeKey |
typedef struct MemoizeEntry | MemoizeEntry |
◆ CACHE_TUPLE_BYTES
| #define CACHE_TUPLE_BYTES | ( | | t | ) | | --------------------------- | - | | - | - |
Value:
(t)->mintuple->t_len)
struct MemoizeTuple MemoizeTuple
Definition at line 89 of file nodeMemoize.c.
◆ EMPTY_ENTRY_MEMORY_BYTES
| #define EMPTY_ENTRY_MEMORY_BYTES | ( | | e | ) | | ----------------------------------- | - | | ------------------------------------------------------------- | - |
Value:
struct MemoizeEntry MemoizeEntry
Definition at line 86 of file nodeMemoize.c.
◆ MEMO_CACHE_BYPASS_MODE
#define MEMO_CACHE_BYPASS_MODE
◆ MEMO_CACHE_FETCH_NEXT_TUPLE
#define MEMO_CACHE_FETCH_NEXT_TUPLE 2 /* Get another tuple from the cache */
◆ MEMO_CACHE_LOOKUP
#define MEMO_CACHE_LOOKUP 1 /* Attempt to perform a cache lookup */
◆ MEMO_END_OF_SCAN
#define MEMO_END_OF_SCAN 5 /* Ready for rescan */
◆ MEMO_FILLING_CACHE
#define MEMO_FILLING_CACHE 3 /* Read outer node to fill cache */
◆ SH_DECLARE
◆ SH_DEFINE
◆ SH_ELEMENT_TYPE [1/2]
◆ SH_ELEMENT_TYPE [2/2]
◆ SH_EQUAL
◆ SH_GET_HASH
| #define SH_GET_HASH | ( | | tb, | | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | --- | | | a | | | | | ) | a->hash | | |
◆ SH_HASH_KEY
◆ SH_KEY
◆ SH_KEY_TYPE [1/2]
◆ SH_KEY_TYPE [2/2]
◆ SH_PREFIX [1/2]
#define SH_PREFIX memoize
◆ SH_PREFIX [2/2]
#define SH_PREFIX memoize
◆ SH_SCOPE [1/2]
#define SH_SCOPE static inline
◆ SH_SCOPE [2/2]
#define SH_SCOPE static inline
◆ SH_STORE_HASH
◆ MemoizeEntry
◆ MemoizeKey
◆ MemoizeTuple
◆ build_hash_table()
◆ cache_lookup()
Definition at line 527 of file nodeMemoize.c.
529{
533
534
536
537
538
539
540
541 entry = memoize_insert(mstate->hashtable, NULL, found);
542
543 if (*found)
544 {
545
546
547
548
550
551 return entry;
552 }
553
555
556
559
560
562
563
566
567
568
569
570
572
574
576
577
578
579
580
582 {
583
584
585
586
587
588
590 return NULL;
591
592
593
594
595
596
597
598
599
600 if (entry->status != memoize_SH_IN_USE || entry->key != key)
601 {
602
603
604
605
607
608
609 entry = memoize_lookup(mstate->hashtable, NULL);
610 Assert(entry != NULL);
611 }
612 }
613
614 return entry;
static void dlist_push_tail(dlist_head *head, dlist_node *node)
static void dlist_move_tail(dlist_head *head, dlist_node *node)
static bool cache_reduce_memory(MemoizeState *mstate, MemoizeKey *specialkey)
static void prepare_probe_slot(MemoizeState *mstate, MemoizeKey *key)
#define EMPTY_ENTRY_MEMORY_BYTES(e)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
TupleTableSlot * probeslot
struct MemoizeTuple * last_tuple
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
References Assert(), cache_reduce_memory(), MemoizeEntry::complete, dlist_move_tail(), dlist_push_tail(), EMPTY_ENTRY_MEMORY_BYTES, ExecCopySlotMinimalTuple(), MemoizeState::hashtable, MemoizeEntry::key, sort-test::key, MemoizeState::last_tuple, MemoizeState::lru_list, MemoizeKey::lru_node, MemoizeState::mem_limit, MemoizeState::mem_used, MemoryContextSwitchTo(), palloc(), prepare_probe_slot(), MemoizeState::probeslot, MemoizeEntry::status, MemoizeState::tableContext, MemoizeEntry::tuplehead, and unlikely.
Referenced by ExecMemoize().
◆ cache_purge_all()
◆ cache_reduce_memory()
Definition at line 439 of file nodeMemoize.c.
441{
442 bool specialkey_intact = true;
444 uint64 evictions = 0;
445
446
449
450
452
453
455 {
458
459
460
461
462
464
465
466
467
468
469
470
471
472
473
474
475
476 entry = memoize_lookup(mstate->hashtable, NULL);
477
478
479
480
481
482
484 elog(ERROR, "could not find memoization table entry");
485
486
487
488
489
490
491
492
493
494
495 if (key == specialkey)
496 specialkey_intact = false;
497
498
499
500
502
503 evictions++;
504
505
507 break;
508 }
509
511
512 return specialkey_intact;
#define dlist_foreach_modify(iter, lhead)
#define dlist_container(type, membername, ptr)
static void remove_cache_entry(MemoizeState *mstate, MemoizeEntry *entry)
References Assert(), MemoizeInstrumentation::cache_evictions, dlist_mutable_iter::cur, dlist_container, dlist_foreach_modify, elog, ERROR, MemoizeState::hashtable, MemoizeEntry::key, sort-test::key, MemoizeState::lru_list, MemoizeState::mem_limit, MemoizeInstrumentation::mem_peak, MemoizeState::mem_used, prepare_probe_slot(), remove_cache_entry(), MemoizeState::stats, and unlikely.
Referenced by cache_lookup(), and cache_store_tuple().
◆ cache_store_tuple()
Definition at line 624 of file nodeMemoize.c.
626{
630
631 Assert(slot != NULL);
632 Assert(entry != NULL);
633
635
638 tuple->next = NULL;
639
640
642
644 {
645
646
647
648
650 }
651 else
652 {
653
655 }
656
659
660
661
662
663
665 {
667
669 return false;
670
671
672
673
674
675
676
677
678
679 if (entry->status != memoize_SH_IN_USE || entry->key != key)
680 {
681
682
683
684
686
687
688 mstate->entry = entry = memoize_lookup(mstate->hashtable, NULL);
689 Assert(entry != NULL);
690 }
691 }
692
693 return true;
#define CACHE_TUPLE_BYTES(t)
struct MemoizeTuple * next
References Assert(), cache_reduce_memory(), CACHE_TUPLE_BYTES, MemoizeState::entry, ExecCopySlotMinimalTuple(), MemoizeState::hashtable, MemoizeEntry::key, sort-test::key, MemoizeState::last_tuple, MemoizeState::mem_limit, MemoizeState::mem_used, MemoryContextSwitchTo(), MemoizeTuple::mintuple, MemoizeTuple::next, palloc(), prepare_probe_slot(), MemoizeEntry::status, MemoizeState::tableContext, and MemoizeEntry::tuplehead.
Referenced by ExecMemoize().
◆ entry_purge_tuples()
◆ ExecEndMemoize()
Definition at line 1079 of file nodeMemoize.c.
1081{
1082#ifdef USE_ASSERT_CHECKING
1083
1085 {
1086 int count;
1088 memoize_iterator i;
1090
1091 memoize_start_iterate(node->hashtable, &i);
1092
1093 count = 0;
1094 while ((entry = memoize_iterate(node->hashtable, &i)) != NULL)
1095 {
1097
1099 while (tuple != NULL)
1100 {
1102 tuple = tuple->next;
1103 }
1104 count++;
1105 }
1106
1109 }
1110#endif
1111
1112
1113
1114
1115
1116
1118 {
1120
1121
1124
1125 Assert(ParallelWorkerNumber <= node->shared_info->num_workers);
1128 }
1129
1130
1132
1133
1134
1135
void ExecEndNode(PlanState *node)
#define outerPlanState(node)
#define IsParallelWorker()
void MemoryContextDelete(MemoryContext context)
SharedMemoizeInfo * shared_info
References Assert(), CACHE_TUPLE_BYTES, EMPTY_ENTRY_MEMORY_BYTES, ExecEndNode(), MemoizeState::hashtable, i, IsParallelWorker, MemoizeInstrumentation::mem_peak, MemoizeState::mem_used, MemoryContextDelete(), MemoizeTuple::next, outerPlanState, ParallelWorkerNumber, MemoizeState::shared_info, SharedMemoizeInfo::sinstrument, MemoizeState::stats, MemoizeState::tableContext, and MemoizeEntry::tuplehead.
Referenced by ExecEndNode().
◆ ExecEstimateCacheEntryOverheadBytes()
double ExecEstimateCacheEntryOverheadBytes | ( | double | ntuples | ) |
---|
◆ ExecInitMemoize()
Definition at line 951 of file nodeMemoize.c.
953{
955 Plan *outerNode;
956 int i;
957 int nkeys;
958 Oid *eqfuncoids;
959
960
962
966
967
968
969
970
971
973
976
977
978
979
980
983
984
985
986
988
989
990
991
992
993
995
1002
1004 mstate->collations = node->collations;
1005
1007
1008 eqfuncoids = palloc(nkeys * sizeof(Oid));
1009
1010 for (i = 0; i < nkeys; i++)
1011 {
1012 Oid hashop = node->hashOperators[i];
1013 Oid left_hashfn;
1014 Oid right_hashfn;
1016
1018 elog(ERROR, "could not find hash function for hash operator %u",
1019 hashop);
1020
1022
1025 }
1026
1030 eqfuncoids,
1031 node->collations,
1034
1035 pfree(eqfuncoids);
1037
1038
1040
1041
1043 "MemoizeHashTable",
1045
1048 mstate->entry = NULL;
1049
1050
1051
1052
1053
1054
1055
1056
1057
1060
1061
1062
1063
1064
1066
1067
1069
1070
1071
1072
1073
1075
1076 return mstate;
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
ExprState * ExecBuildParamSetEqual(TupleDesc desc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, const Oid *eqfunctions, const Oid *collations, const List *param_exprs, PlanState *parent)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsVirtual
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsMinimalTuple
TupleDesc ExecTypeFromExprList(List *exprList)
void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
#define EXEC_FLAG_BACKWARD
void fmgr_info(Oid functionId, FmgrInfo *finfo)
RegProcedure get_opcode(Oid opno)
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
MemoryContext CurrentMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
size_t get_hash_memory_limit(void)
#define MEMO_CACHE_LOOKUP
static TupleTableSlot * ExecMemoize(PlanState *pstate)
static void * list_nth(const List *list, int n)
ExprState * cache_eq_expr
TupleTableSlot * tableslot
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), MemoizeState::binary_mode, Memoize::binary_mode, MemoizeState::cache_eq_expr, MemoizeState::collations, CurrentMemoryContext, dlist_init(), elog, MemoizeState::entry, ERROR, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecBuildParamSetEqual(), ExecCreateScanSlotFromOuterPlan(), ExecInitExpr(), ExecInitNode(), ExecInitResultTupleSlotTL(), ExecMemoize(), PlanState::ExecProcNode, ExecTypeFromExprList(), fmgr_info(), get_hash_memory_limit(), get_op_hash_functions(), get_opcode(), MemoizeState::hashfunctions, MemoizeState::hashkeydesc, MemoizeState::hashtable, i, MemoizeState::keyparamids, Memoize::keyparamids, MemoizeState::last_tuple, list_nth(), MemoizeState::lru_list, makeNode, MakeSingleTupleTableSlot(), MemoizeState::mem_limit, MemoizeState::mem_used, MEMO_CACHE_LOOKUP, MemoizeState::mstatus, MemoizeState::nkeys, Memoize::numKeys, outerPlan, outerPlanState, palloc(), MemoizeState::param_exprs, Memoize::param_exprs, pfree(), PlanState::plan, MemoizeState::probeslot, ScanState::ps, PlanState::ps_ProjInfo, MemoizeState::singlerow, Memoize::singlerow, MemoizeState::ss, PlanState::state, MemoizeState::stats, MemoizeState::tableContext, MemoizeState::tableslot, TTSOpsMinimalTuple, and TTSOpsVirtual.
Referenced by ExecInitNode().
◆ ExecMemoize()
Definition at line 696 of file nodeMemoize.c.
698{
703
705
706
707
708
709
711
713 {
715 {
718 bool found;
719
721
722
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
741
742 if (found && entry->complete)
743 {
745
746
747
748
749
750
752 node->entry = entry;
753
754
756 {
758
761 slot, false);
762
763 return slot;
764 }
765
766
768 return NULL;
769 }
770
771
773
774 if (found)
775 {
776
777
778
779
780
781
782
783
785 }
786
787
791 {
792
793
794
795
796
797
798
801
803 return NULL;
804 }
805
806 node->entry = entry;
807
808
809
810
811
812 if (unlikely(entry == NULL ||
814 {
816
818
819
820
821
822
823 }
824 else
825 {
826
827
828
829
830
831
834 }
835
838 return slot;
839 }
840
842 {
843
846
847
849
850
852 {
854 return NULL;
855 }
856
859 false);
860
861 return slot;
862 }
863
865 {
868
869
870 Assert(entry != NULL);
871
872
873
874
875
876
880 {
881
884 return NULL;
885 }
886
887
888
889
890
891
893 elog(ERROR, "cache entry already complete");
894
895
897 {
898
900
902
903
904
905
906
907 }
908
911 return slot;
912 }
913
915 {
917
918
919
920
921
922
926 {
928 return NULL;
929 }
930
933 return slot;
934 }
935
937
938
939
940
941
942 return NULL;
943
944 default:
945 elog(ERROR, "unrecognized memoize state: %d",
947 return NULL;
948 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
#define ResetExprContext(econtext)
static TupleTableSlot * ExecProcNode(PlanState *node)
#define CHECK_FOR_INTERRUPTS()
#define MEMO_CACHE_FETCH_NEXT_TUPLE
static bool cache_store_tuple(MemoizeState *mstate, TupleTableSlot *slot)
#define MEMO_CACHE_BYPASS_MODE
static MemoizeEntry * cache_lookup(MemoizeState *mstate, bool *found)
#define MEMO_FILLING_CACHE
static void entry_purge_tuples(MemoizeState *mstate, MemoizeEntry *entry)
static void build_hash_table(MemoizeState *mstate, uint32 size)
#define castNode(_type_, nodeptr)
ExprContext * ps_ExprContext
TupleTableSlot * ps_ResultTupleSlot
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
References Assert(), build_hash_table(), MemoizeInstrumentation::cache_hits, cache_lookup(), MemoizeInstrumentation::cache_misses, MemoizeInstrumentation::cache_overflows, cache_store_tuple(), castNode, CHECK_FOR_INTERRUPTS, MemoizeEntry::complete, elog, MemoizeState::entry, entry_purge_tuples(), ERROR, ExecCopySlot(), ExecProcNode(), ExecStoreMinimalTuple(), MemoizeState::hashtable, MemoizeState::last_tuple, likely, MEMO_CACHE_BYPASS_MODE, MEMO_CACHE_FETCH_NEXT_TUPLE, MEMO_CACHE_LOOKUP, MEMO_END_OF_SCAN, MEMO_FILLING_CACHE, MemoizeTuple::mintuple, MemoizeState::mstatus, MemoizeTuple::next, outerPlanState, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, PlanState::ps_ResultTupleSlot, ResetExprContext, MemoizeState::singlerow, MemoizeState::ss, MemoizeState::stats, TupIsNull, MemoizeEntry::tuplehead, and unlikely.
Referenced by ExecInitMemoize().
◆ ExecMemoizeEstimate()
Definition at line 1189 of file nodeMemoize.c.
1191{
1193
1194
1196 return;
1197
#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 MemoizeState::ss.
Referenced by ExecParallelEstimate().
◆ ExecMemoizeInitializeDSM()
Definition at line 1210 of file nodeMemoize.c.
1212{
1214
1215
1217 return;
1218
1222
struct MemoizeInstrumentation MemoizeInstrumentation
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
References PlanState::instrument, SharedMemoizeInfo::num_workers, ParallelContext::nworkers, PlanState::plan, Plan::plan_node_id, ScanState::ps, MemoizeState::shared_info, shm_toc_allocate(), shm_toc_insert(), MemoizeState::ss, and ParallelContext::toc.
Referenced by ExecParallelInitializeDSM().
◆ ExecMemoizeInitializeWorker()
◆ ExecMemoizeRetrieveInstrumentation()
void ExecMemoizeRetrieveInstrumentation | ( | MemoizeState * | node | ) |
---|
◆ ExecReScanMemoize()
Definition at line 1139 of file nodeMemoize.c.
1141{
1143
1144
1146
1147
1148 node->entry = NULL;
1150
1151
1152
1153
1154
1155 if (outerPlan->chgParam == NULL)
1157
1158
1159
1160
1161
bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
void ExecReScan(PlanState *node)
static void cache_purge_all(MemoizeState *mstate)
References bms_nonempty_difference(), cache_purge_all(), MemoizeState::entry, ExecReScan(), MemoizeState::keyparamids, MemoizeState::last_tuple, MEMO_CACHE_LOOKUP, MemoizeState::mstatus, outerPlan, and outerPlanState.
Referenced by ExecReScan().
◆ MemoizeHash_equal()
static bool MemoizeHash_equal ( struct memoize_hash * tb, const MemoizeKey * key1, const MemoizeKey * key2 ) | static |
---|
Definition at line 220 of file nodeMemoize.c.
223{
228
229
231
233 {
235 int numkeys = mstate->nkeys;
236 bool match = true;
237
239
242
243 for (int i = 0; i < numkeys; i++)
244 {
246
247 if (tslot->tts_isnull[i] != pslot->tts_isnull[i])
248 {
249 match = false;
250 break;
251 }
252
253
254 if (tslot->tts_isnull[i])
255 continue;
256
257
259 if ((tslot->tts_values[i], pslot->tts_values[i],
261 {
262 match = false;
263 break;
264 }
265 }
266
268 return match;
269 }
270 else
271 {
272 econtext->ecxt_innertuple = tslot;
273 econtext->ecxt_outertuple = pslot;
275 }
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
static bool ExecQual(ExprState *state, ExprContext *econtext)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static void slot_getallattrs(TupleTableSlot *slot)
References CompactAttribute::attbyval, CompactAttribute::attlen, MemoizeState::binary_mode, MemoizeState::cache_eq_expr, datum_image_eq(), ExecQual(), ExecStoreMinimalTuple(), i, MemoryContextSwitchTo(), MemoizeState::nkeys, MemoizeKey::params, MemoizeState::probeslot, ScanState::ps, PlanState::ps_ExprContext, slot_getallattrs(), MemoizeState::ss, MemoizeState::tableslot, and TupleDescCompactAttr().
◆ MemoizeHash_hash()
static uint32 MemoizeHash_hash ( struct memoize_hash * tb, const MemoizeKey * key ) | static |
---|
Definition at line 157 of file nodeMemoize.c.
159{
165 int numkeys = mstate->nkeys;
166
168
170 {
171 for (int i = 0; i < numkeys; i++)
172 {
173
175
176 if (!pslot->tts_isnull[i])
177 {
180
182
184
185 hashkey ^= hkey;
186 }
187 }
188 }
189 else
190 {
193
194 for (int i = 0; i < numkeys; i++)
195 {
196
198
199 if (!pslot->tts_isnull[i])
200 {
202
204 collations[i], pslot->tts_values[i]));
205 hashkey ^= hkey;
206 }
207 }
208 }
209
uint32 datum_image_hash(Datum value, bool typByVal, int typLen)
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
static uint32 murmurhash32(uint32 data)
static uint32 pg_rotate_left32(uint32 word, int n)
static uint32 DatumGetUInt32(Datum X)
References CompactAttribute::attbyval, CompactAttribute::attlen, MemoizeState::binary_mode, MemoizeState::collations, datum_image_hash(), DatumGetUInt32(), FunctionCall1Coll(), MemoizeState::hashfunctions, i, MemoryContextSwitchTo(), murmurhash32(), MemoizeState::nkeys, pg_rotate_left32(), MemoizeState::probeslot, ScanState::ps, PlanState::ps_ExprContext, MemoizeState::ss, and TupleDescCompactAttr().
◆ prepare_probe_slot()
Definition at line 301 of file nodeMemoize.c.
303{
306 int numKeys = mstate->nkeys;
307
309
310 if (key == NULL)
311 {
314
316
317
318 for (int i = 0; i < numKeys; i++)
320 econtext,
322
324 }
325 else
326 {
327
332 }
333
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
MemoryContext ecxt_per_tuple_memory
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
References ExprContext::ecxt_per_tuple_memory, ExecClearTuple(), ExecEvalExpr(), ExecStoreMinimalTuple(), ExecStoreVirtualTuple(), i, sort-test::key, MemoryContextSwitchTo(), MemoizeState::nkeys, MemoizeState::param_exprs, MemoizeState::probeslot, ScanState::ps, PlanState::ps_ExprContext, slot_getallattrs(), MemoizeState::ss, MemoizeState::tableslot, TupleTableSlot::tts_isnull, and TupleTableSlot::tts_values.
Referenced by cache_lookup(), cache_reduce_memory(), and cache_store_tuple().