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

Function ExecHashSubPlan

src/backend/executor/nodeSubplan.c:112–229  ·  view source on GitHub ↗

* ExecHashSubPlan: store subselect result in an in-memory hash table */

Source from the content-addressed store, hash-verified

110 * ExecHashSubPlan: store subselect result in an in-memory hash table
111 */
112static Datum
113ExecHashSubPlan(SubPlanState *node,
114 ExprContext *econtext,
115 bool *isNull)
116{
117 SubPlan *subplan = node->subplan;
118 PlanState *planstate = node->planstate;
119 TupleTableSlot *slot;
120
121 /* Shouldn't have any direct correlation Vars */
122 if (subplan->parParam != NIL || node->args != NIL)
123 elog(ERROR, "hashed subplan with direct correlation not supported");
124
125 /*
126 * If first time through or we need to rescan the subplan, build the hash
127 * table.
128 */
129 if (node->hashtable == NULL || planstate->chgParam != NULL)
130 buildSubPlanHash(node, econtext);
131
132 /*
133 * The result for an empty subplan is always FALSE; no need to evaluate
134 * lefthand side.
135 */
136 *isNull = false;
137 if (!node->havehashrows && !node->havenullrows)
138 return BoolGetDatum(false);
139
140 /*
141 * Evaluate lefthand expressions and form a projection tuple. First we
142 * have to set the econtext to use (hack alert!).
143 */
144 node->projLeft->pi_exprContext = econtext;
145 slot = ExecProject(node->projLeft);
146
147 /*
148 * Note: because we are typically called in a per-tuple context, we have
149 * to explicitly clear the projected tuple before returning. Otherwise,
150 * we'll have a double-free situation: the per-tuple context will probably
151 * be reset before we're called again, and then the tuple slot will think
152 * it still needs to free the tuple.
153 */
154
155 /*
156 * If the LHS is all non-null, probe for an exact match in the main hash
157 * table. If we find one, the result is TRUE. Otherwise, scan the
158 * partly-null table to see if there are any rows that aren't provably
159 * unequal to the LHS; if so, the result is UNKNOWN. (We skip that part
160 * if we don't care about UNKNOWN.) Otherwise, the result is FALSE.
161 *
162 * Note: the reason we can avoid a full scan of the main hash table is
163 * that the combining operators are assumed never to yield NULL when both
164 * inputs are non-null. If they were to do so, we might need to produce
165 * UNKNOWN instead of FALSE because of an UNKNOWN result in comparing the
166 * LHS to some main-table entry --- which is a comparison we will not even
167 * make, unless there's a chance match of hash keys.
168 */
169 if (slotNoNulls(slot))

Callers 1

ExecSubPlanFunction · 0.85

Calls 8

buildSubPlanHashFunction · 0.85
BoolGetDatumFunction · 0.85
ExecProjectFunction · 0.85
slotNoNullsFunction · 0.85
FindTupleHashEntryFunction · 0.85
ExecClearTupleFunction · 0.85
findPartialMatchFunction · 0.85
slotAllNullsFunction · 0.85

Tested by

no test coverage detected