* paraminfo_get_equal_hashops * Determine if param_info and innerrel's lateral_vars can be hashed. * Returns true the hashing is possible, otherwise return false. * * Additionally we also collect the outer exprs and the hash operators for * each parameter to innerrel. These set in 'param_exprs', 'operators' and * 'binary_mode' when we return true. */
| 485 | * 'binary_mode' when we return true. |
| 486 | */ |
| 487 | static bool |
| 488 | paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, |
| 489 | RelOptInfo *outerrel, RelOptInfo *innerrel, |
| 490 | List **param_exprs, List **operators, |
| 491 | bool *binary_mode) |
| 492 | |
| 493 | { |
| 494 | ListCell *lc; |
| 495 | |
| 496 | *param_exprs = NIL; |
| 497 | *operators = NIL; |
| 498 | *binary_mode = false; |
| 499 | |
| 500 | if (param_info != NULL) |
| 501 | { |
| 502 | List *clauses = param_info->ppi_clauses; |
| 503 | |
| 504 | foreach(lc, clauses) |
| 505 | { |
| 506 | RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); |
| 507 | OpExpr *opexpr; |
| 508 | Node *expr; |
| 509 | |
| 510 | /* can't use a memoize node without a valid hash equals operator */ |
| 511 | if (!OidIsValid(rinfo->hasheqoperator) || |
| 512 | !clause_sides_match_join(rinfo, outerrel, innerrel)) |
| 513 | { |
| 514 | list_free(*operators); |
| 515 | list_free(*param_exprs); |
| 516 | return false; |
| 517 | } |
| 518 | |
| 519 | /* |
| 520 | * We already checked that this is an OpExpr with 2 args when |
| 521 | * setting hasheqoperator. |
| 522 | */ |
| 523 | opexpr = (OpExpr *) rinfo->clause; |
| 524 | if (rinfo->outer_is_left) |
| 525 | expr = (Node *) linitial(opexpr->args); |
| 526 | else |
| 527 | expr = (Node *) lsecond(opexpr->args); |
| 528 | |
| 529 | *operators = lappend_oid(*operators, rinfo->hasheqoperator); |
| 530 | *param_exprs = lappend(*param_exprs, expr); |
| 531 | |
| 532 | /* |
| 533 | * When the join operator is not hashable then it's possible that |
| 534 | * the operator will be able to distinguish something that the |
| 535 | * hash equality operator could not. For example with floating |
| 536 | * point types -0.0 and +0.0 are classed as equal by the hash |
| 537 | * function and equality function, but some other operator may be |
| 538 | * able to tell those values apart. This means that we must put |
| 539 | * memoize into binary comparison mode so that it does bit-by-bit |
| 540 | * comparisons rather than a "logical" comparison as it would |
| 541 | * using the hash equality operator. |
| 542 | */ |
| 543 | if (!OidIsValid(rinfo->hashjoinoperator)) |
| 544 | *binary_mode = true; |
no test coverage detected