* Validator for SQL language functions * * Parse it here in order to be sure that it contains no syntax errors. */
| 890 | * Parse it here in order to be sure that it contains no syntax errors. |
| 891 | */ |
| 892 | Datum |
| 893 | fmgr_sql_validator(PG_FUNCTION_ARGS) |
| 894 | { |
| 895 | Oid funcoid = PG_GETARG_OID(0); |
| 896 | HeapTuple tuple; |
| 897 | Form_pg_proc proc; |
| 898 | List *raw_parsetree_list; |
| 899 | List *querytree_list; |
| 900 | ListCell *lc; |
| 901 | bool isnull; |
| 902 | Datum tmp; |
| 903 | char *prosrc; |
| 904 | parse_error_callback_arg callback_arg; |
| 905 | ErrorContextCallback sqlerrcontext; |
| 906 | bool haspolyarg; |
| 907 | int i; |
| 908 | |
| 909 | if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid)) |
| 910 | PG_RETURN_VOID(); |
| 911 | |
| 912 | tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid)); |
| 913 | if (!HeapTupleIsValid(tuple)) |
| 914 | elog(ERROR, "cache lookup failed for function %u", funcoid); |
| 915 | proc = (Form_pg_proc) GETSTRUCT(tuple); |
| 916 | |
| 917 | /* Disallow pseudotype result */ |
| 918 | /* except for RECORD, VOID, or polymorphic */ |
| 919 | if (get_typtype(proc->prorettype) == TYPTYPE_PSEUDO && |
| 920 | proc->prorettype != RECORDOID && |
| 921 | proc->prorettype != VOIDOID && |
| 922 | !IsPolymorphicType(proc->prorettype)) |
| 923 | ereport(ERROR, |
| 924 | (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), |
| 925 | errmsg("SQL functions cannot return type %s", |
| 926 | format_type_be(proc->prorettype)))); |
| 927 | |
| 928 | /* Disallow pseudotypes in arguments */ |
| 929 | /* except for polymorphic */ |
| 930 | haspolyarg = false; |
| 931 | for (i = 0; i < proc->pronargs; i++) |
| 932 | { |
| 933 | if (get_typtype(proc->proargtypes.values[i]) == TYPTYPE_PSEUDO) |
| 934 | { |
| 935 | if (IsPolymorphicType(proc->proargtypes.values[i])) |
| 936 | haspolyarg = true; |
| 937 | else |
| 938 | ereport(ERROR, |
| 939 | (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), |
| 940 | errmsg("SQL functions cannot have arguments of type %s", |
| 941 | format_type_be(proc->proargtypes.values[i])))); |
| 942 | } |
| 943 | } |
| 944 | |
| 945 | /* Postpone body checks if !check_function_bodies */ |
| 946 | if (check_function_bodies) |
| 947 | { |
| 948 | tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull); |
| 949 | if (isnull) |
nothing calls this directly
no test coverage detected