* build_coercion_expression() * Construct an expression tree for applying a pg_cast entry. * * This is used for both type-coercion and length-coercion operations, * since there is no difference in terms of the calling convention. */
| 880 | * since there is no difference in terms of the calling convention. |
| 881 | */ |
| 882 | static Node * |
| 883 | build_coercion_expression(Node *node, |
| 884 | CoercionPathType pathtype, |
| 885 | Oid funcId, |
| 886 | Oid targetTypeId, int32 targetTypMod, |
| 887 | CoercionContext ccontext, CoercionForm cformat, |
| 888 | int location) |
| 889 | { |
| 890 | int nargs = 0; |
| 891 | |
| 892 | if (OidIsValid(funcId)) |
| 893 | { |
| 894 | HeapTuple tp; |
| 895 | Form_pg_proc procstruct; |
| 896 | |
| 897 | tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcId)); |
| 898 | if (!HeapTupleIsValid(tp)) |
| 899 | elog(ERROR, "cache lookup failed for function %u", funcId); |
| 900 | procstruct = (Form_pg_proc) GETSTRUCT(tp); |
| 901 | |
| 902 | /* |
| 903 | * These Asserts essentially check that function is a legal coercion |
| 904 | * function. We can't make the seemingly obvious tests on prorettype |
| 905 | * and proargtypes[0], even in the COERCION_PATH_FUNC case, because of |
| 906 | * various binary-compatibility cases. |
| 907 | */ |
| 908 | /* Assert(targetTypeId == procstruct->prorettype); */ |
| 909 | Assert(!procstruct->proretset); |
| 910 | Assert(procstruct->prokind == PROKIND_FUNCTION); |
| 911 | nargs = procstruct->pronargs; |
| 912 | Assert(nargs >= 1 && nargs <= 3); |
| 913 | /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */ |
| 914 | Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID); |
| 915 | Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID); |
| 916 | |
| 917 | ReleaseSysCache(tp); |
| 918 | } |
| 919 | |
| 920 | if (pathtype == COERCION_PATH_FUNC) |
| 921 | { |
| 922 | /* We build an ordinary FuncExpr with special arguments */ |
| 923 | FuncExpr *fexpr; |
| 924 | List *args; |
| 925 | Const *cons; |
| 926 | |
| 927 | Assert(OidIsValid(funcId)); |
| 928 | |
| 929 | args = list_make1(node); |
| 930 | |
| 931 | if (nargs >= 2) |
| 932 | { |
| 933 | /* Pass target typmod as an int4 constant */ |
| 934 | cons = makeConst(INT4OID, |
| 935 | -1, |
| 936 | InvalidOid, |
| 937 | sizeof(int32), |
| 938 | Int32GetDatum(targetTypMod), |
| 939 | false, |
no test coverage detected