transformJoinUsingClause() * Build a complete ON clause from a partially-transformed USING list. * We are given lists of nodes representing left and right match columns. * Result is a transformed qualification expression. */
| 446 | * Result is a transformed qualification expression. |
| 447 | */ |
| 448 | static Node * |
| 449 | transformJoinUsingClause(ParseState *pstate, |
| 450 | List *leftVars, List *rightVars) |
| 451 | { |
| 452 | Node *result; |
| 453 | List *andargs = NIL; |
| 454 | ListCell *lvars, |
| 455 | *rvars; |
| 456 | |
| 457 | /* |
| 458 | * We cheat a little bit here by building an untransformed operator tree |
| 459 | * whose leaves are the already-transformed Vars. This requires collusion |
| 460 | * from transformExpr(), which normally could be expected to complain |
| 461 | * about already-transformed subnodes. However, this does mean that we |
| 462 | * have to mark the columns as requiring SELECT privilege for ourselves; |
| 463 | * transformExpr() won't do it. |
| 464 | */ |
| 465 | forboth(lvars, leftVars, rvars, rightVars) |
| 466 | { |
| 467 | Var *lvar = (Var *) lfirst(lvars); |
| 468 | Var *rvar = (Var *) lfirst(rvars); |
| 469 | A_Expr *e; |
| 470 | |
| 471 | /* Require read access to the join variables */ |
| 472 | markVarForSelectPriv(pstate, lvar); |
| 473 | markVarForSelectPriv(pstate, rvar); |
| 474 | |
| 475 | /* Now create the lvar = rvar join condition */ |
| 476 | e = makeSimpleA_Expr(AEXPR_OP, "=", |
| 477 | (Node *) copyObject(lvar), (Node *) copyObject(rvar), |
| 478 | -1); |
| 479 | |
| 480 | /* Prepare to combine into an AND clause, if multiple join columns */ |
| 481 | andargs = lappend(andargs, e); |
| 482 | } |
| 483 | |
| 484 | /* Only need an AND if there's more than one join column */ |
| 485 | if (list_length(andargs) == 1) |
| 486 | result = (Node *) linitial(andargs); |
| 487 | else |
| 488 | result = (Node *) makeBoolExpr(AND_EXPR, andargs, -1); |
| 489 | |
| 490 | /* |
| 491 | * Since the references are already Vars, and are certainly from the input |
| 492 | * relations, we don't have to go through the same pushups that |
| 493 | * transformJoinOnClause() does. Just invoke transformExpr() to fix up |
| 494 | * the operators, and we're done. |
| 495 | */ |
| 496 | result = transformExpr(pstate, result, EXPR_KIND_JOIN_USING); |
| 497 | |
| 498 | result = coerce_to_boolean(pstate, result, "JOIN/USING"); |
| 499 | |
| 500 | return result; |
| 501 | } |
| 502 | |
| 503 | /* transformJoinOnClause() |
| 504 | * Transform the qual conditions for JOIN/ON. |
no test coverage detected