* MJEvalInnerValues * * Same as above, but for the inner tuple. Here, we have to be prepared * to load data from either the true current inner, or the marked inner, * so caller must tell us which slot to load from. */
| 370 | * so caller must tell us which slot to load from. |
| 371 | */ |
| 372 | static MJEvalResult |
| 373 | MJEvalInnerValues(MergeJoinState *mergestate, TupleTableSlot *innerslot) |
| 374 | { |
| 375 | ExprContext *econtext = mergestate->mj_InnerEContext; |
| 376 | MJEvalResult result = MJEVAL_MATCHABLE; |
| 377 | int i; |
| 378 | MemoryContext oldContext; |
| 379 | |
| 380 | /* Check for end of inner subplan */ |
| 381 | if (TupIsNull(innerslot)) |
| 382 | return MJEVAL_ENDOFJOIN; |
| 383 | |
| 384 | ResetExprContext(econtext); |
| 385 | |
| 386 | oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); |
| 387 | |
| 388 | econtext->ecxt_innertuple = innerslot; |
| 389 | |
| 390 | for (i = 0; i < mergestate->mj_NumClauses; i++) |
| 391 | { |
| 392 | MergeJoinClause clause = &mergestate->mj_Clauses[i]; |
| 393 | |
| 394 | clause->rdatum = ExecEvalExpr(clause->rexpr, econtext, |
| 395 | &clause->risnull); |
| 396 | if (clause->risnull && !clause->notdistinct) |
| 397 | { |
| 398 | /* match is impossible; can we end the join early? */ |
| 399 | if (i == 0 && !clause->ssup.ssup_nulls_first && |
| 400 | !mergestate->mj_FillInner) |
| 401 | result = MJEVAL_ENDOFJOIN; |
| 402 | else if (result == MJEVAL_MATCHABLE) |
| 403 | result = MJEVAL_NONMATCHABLE; |
| 404 | } |
| 405 | } |
| 406 | |
| 407 | MemoryContextSwitchTo(oldContext); |
| 408 | |
| 409 | return result; |
| 410 | } |
| 411 | |
| 412 | /* |
| 413 | * MJCompare |
no test coverage detected