-
Notifications
You must be signed in to change notification settings - Fork 1
/
lab2.patch
126 lines (123 loc) · 4.05 KB
/
lab2.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c
index b479358..87ac2b6 100644
--- a/src/backend/executor/nodeNestloop.c
+++ b/src/backend/executor/nodeNestloop.c
@@ -56,13 +56,55 @@
* are prepared to return the first tuple.
* ----------------------------------------------------------------
*/
+
+static inline TupleTableSlot *duplicateSlot(TupleTableSlot *slot) {
+ TupleTableSlot *ret = MakeSingleTupleTableSlot(slot->tts_tupleDescriptor);
+ ExecCopySlot(ret, slot);
+
+ return ret;
+}
+
+static inline TupleTableSlot **fetchNextBlock(PlanState *plan) {
+ /* NEVER set outerTupleSlots[BLOCK_SIZE] to value other than NULL, it's the terimiator of the loop! */
+ TupleTableSlot **blockData = palloc(sizeof(TupleTableSlot *) * (BLOCK_SIZE + 1));
+ TupleTableSlot *data;
+ blockData[BLOCK_SIZE] = NULL;
+ unsigned long idx;
+ elog(DEBUG1, "fetchNextBlock");
+ for (idx = 0; idx < BLOCK_SIZE; ++ idx) {
+ data = ExecProcNode(plan);
+ if (TupIsNull(data)) {
+ blockData[idx] = NULL;
+ if (idx == 0) {
+ elog(DEBUG1, "end of plan");
+ return NULL;
+ } else {
+ elog(DEBUG1, "blockSize: %lu", idx);
+ return blockData;
+ }
+ }
+ blockData[idx] = duplicateSlot(data);
+ // elog(DEBUG1, "heapdata: %lu", blockData[idx]->tts_tuple);
+ }
+ elog(DEBUG1, "fullBlock: %lu", idx);
+ return blockData;
+}
+
+static inline void freeBlock(TupleTableSlot **block) {
+ void *ptr = block;
+ for ( ;!TupIsNull(*block); ++ block) {
+ ExecDropSingleTupleTableSlot(*block);
+ }
+ pfree(ptr);
+}
+
TupleTableSlot *
ExecNestLoop(NestLoopState *node)
{
NestLoop *nl;
PlanState *innerPlan;
PlanState *outerPlan;
- TupleTableSlot *outerTupleSlot;
+ TupleTableSlot *outerTupleSlot = NULL;
TupleTableSlot *innerTupleSlot;
List *joinqual;
List *otherqual;
@@ -90,7 +132,6 @@ ExecNestLoop(NestLoopState *node)
{
TupleTableSlot *result;
ExprDoneCond isDone;
-
result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
if (isDone == ExprMultipleResult)
return result;
@@ -119,8 +160,24 @@ ExecNestLoop(NestLoopState *node)
*/
if (node->nl_NeedNewOuter)
{
- ENL1_printf("getting new outer tuple");
- outerTupleSlot = ExecProcNode(outerPlan);
+ ENL1_printf("getting new outer tuples");
+ if (econtext->ecxt_outertuples) {
+ outerTupleSlot = *(++ econtext->ecxt_outertuples);
+ // elog(DEBUG1, "Next item");
+ }
+ if (TupIsNull(outerTupleSlot)) {
+ // elog(DEBUG1, "New block");
+ if (econtext->ecxt_outertuples_head) {
+ freeBlock(econtext->ecxt_outertuples_head);
+ if (econtext->ecxt_outertuples - (TupleTableSlot **)econtext->ecxt_outertuples_head != BLOCK_SIZE) return NULL;
+ }
+ if ((econtext->ecxt_outertuples = fetchNextBlock(outerPlan)) == NULL) {
+ ENL1_printf("no outer tuple, ending join");
+ return NULL;
+ }
+ econtext->ecxt_outertuples_head = econtext->ecxt_outertuples;
+ outerTupleSlot = *econtext->ecxt_outertuples;
+ }
/*
* if there are no more outer tuples, then the join is complete..
@@ -439,3 +496,5 @@ ExecReScanNestLoop(NestLoopState *node)
node->nl_NeedNewOuter = true;
node->nl_MatchedOuter = false;
}
+
+
diff --git a/src/include/executor/nodeNestloop.h b/src/include/executor/nodeNestloop.h
index f249d9d..e4a9635 100644
--- a/src/include/executor/nodeNestloop.h
+++ b/src/include/executor/nodeNestloop.h
@@ -21,4 +21,6 @@ extern TupleTableSlot *ExecNestLoop(NestLoopState *node);
extern void ExecEndNestLoop(NestLoopState *node);
extern void ExecReScanNestLoop(NestLoopState *node);
+#define BLOCK_SIZE 1024
+
#endif /* NODENESTLOOP_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 187c70a..a863472 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -116,6 +116,8 @@ typedef struct ExprContext
TupleTableSlot *ecxt_scantuple;
TupleTableSlot *ecxt_innertuple;
TupleTableSlot *ecxt_outertuple;
+ TupleTableSlot **ecxt_outertuples;
+ void *ecxt_outertuples_head;
/* Memory contexts for expression evaluation --- see notes above */
MemoryContext ecxt_per_query_memory;