* ExecScanHashBucket * scan a hash bucket for matches to the current outer tuple * * The current outer tuple must be stored in econtext->ecxt_outertuple. * * On success, the inner tuple is stored into hjstate->hj_CurTuple and * econtext->ecxt_innertuple, using hjstate->hj_HashTupleSlot as the slot * for the latter. */
| 2251 | * for the latter. |
| 2252 | */ |
| 2253 | bool |
| 2254 | ExecScanHashBucket(HashState *hashState, HashJoinState *hjstate, |
| 2255 | ExprContext *econtext) |
| 2256 | { |
| 2257 | /* |
| 2258 | * Greenplum specific behavior. |
| 2259 | * Using hashqualclauses to support hash join on 'IS NOT DISTINCT FROM' |
| 2260 | * as well as '='. |
| 2261 | */ |
| 2262 | ExprState *hjclauses = hjstate->hashqualclauses; |
| 2263 | HashJoinTable hashtable = hjstate->hj_HashTable; |
| 2264 | HashJoinTuple hashTuple = hjstate->hj_CurTuple; |
| 2265 | uint32 hashvalue = hjstate->hj_CurHashValue; |
| 2266 | |
| 2267 | /* |
| 2268 | * hj_CurTuple is the address of the tuple last returned from the current |
| 2269 | * bucket, or NULL if it's time to start scanning a new bucket. |
| 2270 | * |
| 2271 | * If the tuple hashed to a skew bucket then scan the skew bucket |
| 2272 | * otherwise scan the standard hashtable bucket. |
| 2273 | */ |
| 2274 | if (hashTuple != NULL) |
| 2275 | hashTuple = hashTuple->next.unshared; |
| 2276 | else if (hjstate->hj_CurSkewBucketNo != INVALID_SKEW_BUCKET_NO) |
| 2277 | hashTuple = hashtable->skewBucket[hjstate->hj_CurSkewBucketNo]->tuples; |
| 2278 | else |
| 2279 | hashTuple = hashtable->buckets.unshared[hjstate->hj_CurBucketNo]; |
| 2280 | |
| 2281 | while (hashTuple != NULL) |
| 2282 | { |
| 2283 | if (hashTuple->hashvalue == hashvalue) |
| 2284 | { |
| 2285 | TupleTableSlot *inntuple; |
| 2286 | |
| 2287 | /* insert hashtable's tuple into exec slot so ExecQual sees it */ |
| 2288 | inntuple = ExecStoreMinimalTuple(HJTUPLE_MINTUPLE(hashTuple), |
| 2289 | hjstate->hj_HashTupleSlot, |
| 2290 | false); /* do not pfree */ |
| 2291 | econtext->ecxt_innertuple = inntuple; |
| 2292 | |
| 2293 | if (ExecQualAndReset(hjclauses, econtext)) |
| 2294 | { |
| 2295 | hjstate->hj_CurTuple = hashTuple; |
| 2296 | return true; |
| 2297 | } |
| 2298 | } |
| 2299 | |
| 2300 | hashTuple = hashTuple->next.unshared; |
| 2301 | } |
| 2302 | |
| 2303 | /* |
| 2304 | * no match |
| 2305 | */ |
| 2306 | return false; |
| 2307 | } |
| 2308 | |
| 2309 | /* |
| 2310 | * ExecParallelScanHashBucket |
no test coverage detected