* applyRelabelType * Add a RelabelType node if needed to make the expression expose * the specified type, typmod, and collation. * * This is primarily intended to be used during planning. Therefore, it must * maintain the post-eval_const_expressions invariants that there are not * adjacent RelabelTypes, and that the tree is fully const-folded (hence, * we mustn't return a RelabelType ato
| 600 | * passed as true if caller knows the Const is newly generated. |
| 601 | */ |
| 602 | Node * |
| 603 | applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, |
| 604 | CoercionForm rformat, int rlocation, bool overwrite_ok) |
| 605 | { |
| 606 | /* |
| 607 | * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard |
| 608 | * all but the top one, and must do so to ensure that semantically |
| 609 | * equivalent expressions are equal(). |
| 610 | */ |
| 611 | while (arg && IsA(arg, RelabelType)) |
| 612 | arg = (Node *) ((RelabelType *) arg)->arg; |
| 613 | |
| 614 | if (arg && IsA(arg, Const)) |
| 615 | { |
| 616 | /* Modify the Const directly to preserve const-flatness. */ |
| 617 | Const *con = (Const *) arg; |
| 618 | |
| 619 | if (!overwrite_ok) |
| 620 | con = copyObject(con); |
| 621 | con->consttype = rtype; |
| 622 | con->consttypmod = rtypmod; |
| 623 | con->constcollid = rcollid; |
| 624 | /* We keep the Const's original location. */ |
| 625 | return (Node *) con; |
| 626 | } |
| 627 | else if (exprType(arg) == rtype && |
| 628 | exprTypmod(arg) == rtypmod && |
| 629 | exprCollation(arg) == rcollid) |
| 630 | { |
| 631 | /* Sometimes we find a nest of relabels that net out to nothing. */ |
| 632 | return arg; |
| 633 | } |
| 634 | else |
| 635 | { |
| 636 | /* Nope, gotta have a RelabelType. */ |
| 637 | RelabelType *newrelabel = makeNode(RelabelType); |
| 638 | |
| 639 | newrelabel->arg = (Expr *) arg; |
| 640 | newrelabel->resulttype = rtype; |
| 641 | newrelabel->resulttypmod = rtypmod; |
| 642 | newrelabel->resultcollid = rcollid; |
| 643 | newrelabel->relabelformat = rformat; |
| 644 | newrelabel->location = rlocation; |
| 645 | return (Node *) newrelabel; |
| 646 | } |
| 647 | } |
| 648 | |
| 649 | /* |
| 650 | * relabel_to_typmod |
no test coverage detected