MCPcopy Create free account
hub / github.com/apache/cloudberry / ExecRecursiveUnion

Function ExecRecursiveUnion

src/backend/executor/nodeRecursiveunion.c:74–173  ·  view source on GitHub ↗

---------------------------------------------------------------- * ExecRecursiveUnion(node) * * Scans the recursive query sequentially and returns the next * qualifying tuple. * * 1. evaluate non recursive term and assign the result to RT * * 2. execute recursive terms * * 2.1 WT := RT * 2.2 while WT is not empty repeat 2.3 to 2.6. if WT is empty returns RT * 2.3 replace the name of

Source from the content-addressed store, hash-verified

72 * ----------------------------------------------------------------
73 */
74static TupleTableSlot *
75ExecRecursiveUnion(PlanState *pstate)
76{
77 RecursiveUnionState *node = castNode(RecursiveUnionState, pstate);
78 PlanState *outerPlan = outerPlanState(node);
79 PlanState *innerPlan = innerPlanState(node);
80 RecursiveUnion *plan = (RecursiveUnion *) node->ps.plan;
81 TupleTableSlot *slot;
82 bool isnew;
83
84 CHECK_FOR_INTERRUPTS();
85
86 /* 1. Evaluate non-recursive term */
87 if (!node->recursing)
88 {
89 for (;;)
90 {
91 slot = ExecProcNode(outerPlan);
92 if (TupIsNull(slot))
93 break;
94 /*
95 * RECURSIVE_CTE_FIXME: It suppose plan->numCols should be 0 if we don't
96 * support recursive union. QP should fix this later.
97 */
98 if (plan->numCols > 0)
99 {
100 /* Find or build hashtable entry for this tuple's group */
101 LookupTupleHashEntry(node->hashtable, slot, &isnew, NULL);
102 /* Must reset temp context after each hashtable lookup */
103 MemoryContextReset(node->tempContext);
104 /* Ignore tuple if already seen */
105 if (!isnew)
106 continue;
107 }
108 /* Each non-duplicate tuple goes to the working table ... */
109 tuplestore_puttupleslot(node->working_table, slot);
110 /* ... and to the caller */
111 return slot;
112 }
113 node->recursing = true;
114 }
115
116 /* 2. Execute recursive term */
117 for (;;)
118 {
119 slot = ExecProcNode(innerPlan);
120 if (TupIsNull(slot))
121 {
122 /* Done if there's nothing in the intermediate table */
123 if (node->intermediate_empty)
124 break;
125
126 /* done with old working table ... */
127 tuplestore_end(node->working_table);
128
129 /* intermediate table becomes working table */
130 node->working_table = node->intermediate_table;
131 for (int k = 1; k < node->refcount; k++)

Callers

nothing calls this directly

Calls 8

ExecProcNodeFunction · 0.85
LookupTupleHashEntryFunction · 0.85
MemoryContextResetFunction · 0.85
tuplestore_puttupleslotFunction · 0.85
tuplestore_endFunction · 0.85
tuplestore_begin_heapFunction · 0.85
bms_add_memberFunction · 0.85

Tested by

no test coverage detected