* make_op() * Operator expression construction. * * Transform operator expression ensuring type compatibility. * This is where some type conversion happens. * * last_srf should be a copy of pstate->p_last_srf from just before we * started transforming the operator's arguments; this is used for nested-SRF * detection. If the caller will throw an error anyway for a set-returning * express
| 669 | * expression, it's okay to cheat and just pass pstate->p_last_srf. |
| 670 | */ |
| 671 | Expr * |
| 672 | make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, |
| 673 | Node *last_srf, int location) |
| 674 | { |
| 675 | Oid ltypeId, |
| 676 | rtypeId; |
| 677 | Operator tup; |
| 678 | Form_pg_operator opform; |
| 679 | Oid actual_arg_types[2]; |
| 680 | Oid declared_arg_types[2]; |
| 681 | int nargs; |
| 682 | List *args; |
| 683 | Oid rettype; |
| 684 | OpExpr *result; |
| 685 | |
| 686 | /* Check it's not a postfix operator */ |
| 687 | if (rtree == NULL) |
| 688 | ereport(ERROR, |
| 689 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 690 | errmsg("postfix operators are not supported"))); |
| 691 | |
| 692 | /* Select the operator */ |
| 693 | if (ltree == NULL) |
| 694 | { |
| 695 | /* prefix operator */ |
| 696 | rtypeId = exprType(rtree); |
| 697 | ltypeId = InvalidOid; |
| 698 | tup = left_oper(pstate, opname, rtypeId, false, location); |
| 699 | } |
| 700 | else |
| 701 | { |
| 702 | /* otherwise, binary operator */ |
| 703 | ltypeId = exprType(ltree); |
| 704 | rtypeId = exprType(rtree); |
| 705 | tup = oper(pstate, opname, ltypeId, rtypeId, false, location); |
| 706 | } |
| 707 | |
| 708 | opform = (Form_pg_operator) GETSTRUCT(tup); |
| 709 | |
| 710 | /* Check it's not a shell */ |
| 711 | if (!RegProcedureIsValid(opform->oprcode)) |
| 712 | ereport(ERROR, |
| 713 | (errcode(ERRCODE_UNDEFINED_FUNCTION), |
| 714 | errmsg("operator is only a shell: %s", |
| 715 | op_signature_string(opname, |
| 716 | opform->oprkind, |
| 717 | opform->oprleft, |
| 718 | opform->oprright)), |
| 719 | parser_errposition(pstate, location))); |
| 720 | |
| 721 | /* Do typecasting and build the expression tree */ |
| 722 | if (ltree == NULL) |
| 723 | { |
| 724 | /* prefix operator */ |
| 725 | args = list_make1(rtree); |
| 726 | actual_arg_types[0] = rtypeId; |
| 727 | declared_arg_types[0] = opform->oprright; |
| 728 | nargs = 1; |
no test coverage detected