* MJCompare * * Compare the mergejoinable values of the current two input tuples * and return 0 if they are equal (ie, the mergejoin equalities all * succeed), >0 if outer > inner, <0 if outer < inner. * * MJEvalOuterValues and MJEvalInnerValues must already have been called * for the current outer and inner tuples, respectively. */
| 420 | * for the current outer and inner tuples, respectively. |
| 421 | */ |
| 422 | static int |
| 423 | MJCompare(MergeJoinState *mergestate) |
| 424 | { |
| 425 | int result = 0; |
| 426 | bool nulleqnull = false; |
| 427 | ExprContext *econtext = mergestate->js.ps.ps_ExprContext; |
| 428 | int i; |
| 429 | MemoryContext oldContext; |
| 430 | |
| 431 | /* |
| 432 | * Call the comparison functions in short-lived context, in case they leak |
| 433 | * memory. |
| 434 | */ |
| 435 | ResetExprContext(econtext); |
| 436 | |
| 437 | oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); |
| 438 | |
| 439 | for (i = 0; i < mergestate->mj_NumClauses; i++) |
| 440 | { |
| 441 | MergeJoinClause clause = &mergestate->mj_Clauses[i]; |
| 442 | |
| 443 | /* |
| 444 | * Special case for NULL-vs-NULL, else use standard comparison. |
| 445 | */ |
| 446 | if (clause->lisnull && clause->risnull) |
| 447 | { |
| 448 | nulleqnull = true; /* NULL "=" NULL */ |
| 449 | continue; |
| 450 | } |
| 451 | |
| 452 | result = ApplySortComparator(clause->ldatum, clause->lisnull, |
| 453 | clause->rdatum, clause->risnull, |
| 454 | &clause->ssup); |
| 455 | |
| 456 | if (result != 0) |
| 457 | break; |
| 458 | } |
| 459 | |
| 460 | /* |
| 461 | * If we had any NULL-vs-NULL inputs, we do not want to report that the |
| 462 | * tuples are equal. Instead, if result is still 0, change it to +1. This |
| 463 | * will result in advancing the inner side of the join. |
| 464 | * |
| 465 | * Likewise, if there was a constant-false joinqual, do not report |
| 466 | * equality. We have to check this as part of the mergequals, else the |
| 467 | * rescan logic will do the wrong thing. |
| 468 | */ |
| 469 | if (result == 0 && |
| 470 | (nulleqnull || mergestate->mj_ConstFalseJoin)) |
| 471 | result = 1; |
| 472 | |
| 473 | MemoryContextSwitchTo(oldContext); |
| 474 | |
| 475 | return result; |
| 476 | } |
| 477 | |
| 478 | |
| 479 | /* |
no test coverage detected