* CREATE CAST */
| 2020 | * CREATE CAST |
| 2021 | */ |
| 2022 | ObjectAddress |
| 2023 | CreateCast(CreateCastStmt *stmt) |
| 2024 | { |
| 2025 | Oid sourcetypeid; |
| 2026 | Oid targettypeid; |
| 2027 | char sourcetyptype; |
| 2028 | char targettyptype; |
| 2029 | Oid funcid; |
| 2030 | int nargs; |
| 2031 | char castcontext; |
| 2032 | char castmethod; |
| 2033 | HeapTuple tuple; |
| 2034 | AclResult aclresult; |
| 2035 | ObjectAddress myself; |
| 2036 | |
| 2037 | sourcetypeid = typenameTypeId(NULL, stmt->sourcetype); |
| 2038 | targettypeid = typenameTypeId(NULL, stmt->targettype); |
| 2039 | sourcetyptype = get_typtype(sourcetypeid); |
| 2040 | targettyptype = get_typtype(targettypeid); |
| 2041 | |
| 2042 | /* No pseudo-types allowed */ |
| 2043 | if (sourcetyptype == TYPTYPE_PSEUDO) |
| 2044 | ereport(ERROR, |
| 2045 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 2046 | errmsg("source data type %s is a pseudo-type", |
| 2047 | TypeNameToString(stmt->sourcetype)))); |
| 2048 | |
| 2049 | if (targettyptype == TYPTYPE_PSEUDO) |
| 2050 | ereport(ERROR, |
| 2051 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 2052 | errmsg("target data type %s is a pseudo-type", |
| 2053 | TypeNameToString(stmt->targettype)))); |
| 2054 | |
| 2055 | /* Permission check */ |
| 2056 | if (!pg_type_ownercheck(sourcetypeid, GetUserId()) |
| 2057 | && !pg_type_ownercheck(targettypeid, GetUserId())) |
| 2058 | ereport(ERROR, |
| 2059 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
| 2060 | errmsg("must be owner of type %s or type %s", |
| 2061 | format_type_be(sourcetypeid), |
| 2062 | format_type_be(targettypeid)))); |
| 2063 | |
| 2064 | aclresult = pg_type_aclcheck(sourcetypeid, GetUserId(), ACL_USAGE); |
| 2065 | if (aclresult != ACLCHECK_OK) |
| 2066 | aclcheck_error_type(aclresult, sourcetypeid); |
| 2067 | |
| 2068 | aclresult = pg_type_aclcheck(targettypeid, GetUserId(), ACL_USAGE); |
| 2069 | if (aclresult != ACLCHECK_OK) |
| 2070 | aclcheck_error_type(aclresult, targettypeid); |
| 2071 | |
| 2072 | /* Domains are allowed for historical reasons, but we warn */ |
| 2073 | if (sourcetyptype == TYPTYPE_DOMAIN) |
| 2074 | ereport(WARNING, |
| 2075 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 2076 | errmsg("cast will be ignored because the source data type is a domain"))); |
| 2077 | |
| 2078 | else if (targettyptype == TYPTYPE_DOMAIN) |
| 2079 | ereport(WARNING, |
no test coverage detected