aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/domains.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-09-09 09:20:34 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-09-09 09:20:34 -0400
commit967a7b0fc9c8f4e07b697148238566203cb060de (patch)
treeaad24f6e20944c97c181afeed6e8c7b125386d05 /src/backend/utils/adt/domains.c
parentec253de1fd2e6002122de80815ac5b963af8277c (diff)
downloadpostgresql-967a7b0fc9c8f4e07b697148238566203cb060de.tar.gz
postgresql-967a7b0fc9c8f4e07b697148238566203cb060de.zip
Avoid reporting "cache lookup failed" for some user-reachable cases.
We have a not-terribly-thoroughly-enforced-yet project policy that internal errors with SQLSTATE XX000 (ie, plain elog) should not be triggerable from SQL. record_in, domain_in, and PL validator functions all failed to meet this standard, because they threw plain elog("cache lookup failed for XXX") errors on bad OIDs, and those are all invokable from SQL. For record_in, the best fix is to upgrade typcache.c (lookup_type_cache) to throw a user-facing error for this case. That seems consistent because it was more than halfway there already, having user-facing errors for shell types and non-composite types. Having done that, tweak domain_in to rely on the typcache to throw an appropriate error. (This costs little because InitDomainConstraintRef would fetch the typcache entry anyway.) For the PL validator functions, we already have a single choke point at CheckFunctionValidatorAccess, so just fix its error to be user-facing. Dilip Kumar, reviewed by Haribabu Kommi Discussion: <87wpxfygg9.fsf@credativ.de>
Diffstat (limited to 'src/backend/utils/adt/domains.c')
-rw-r--r--src/backend/utils/adt/domains.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/backend/utils/adt/domains.c b/src/backend/utils/adt/domains.c
index 19ee4ce9d16..26bbbb59797 100644
--- a/src/backend/utils/adt/domains.c
+++ b/src/backend/utils/adt/domains.c
@@ -72,19 +72,28 @@ static DomainIOData *
domain_state_setup(Oid domainType, bool binary, MemoryContext mcxt)
{
DomainIOData *my_extra;
+ TypeCacheEntry *typentry;
Oid baseType;
my_extra = (DomainIOData *) MemoryContextAlloc(mcxt, sizeof(DomainIOData));
- /* Find out the base type */
- my_extra->typtypmod = -1;
- baseType = getBaseTypeAndTypmod(domainType, &my_extra->typtypmod);
- if (baseType == domainType)
+ /*
+ * Verify that domainType represents a valid domain type. We need to be
+ * careful here because domain_in and domain_recv can be called from SQL,
+ * possibly with incorrect arguments. We use lookup_type_cache mainly
+ * because it will throw a clean user-facing error for a bad OID.
+ */
+ typentry = lookup_type_cache(domainType, 0);
+ if (typentry->typtype != TYPTYPE_DOMAIN)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("type %s is not a domain",
format_type_be(domainType))));
+ /* Find out the base type */
+ my_extra->typtypmod = -1;
+ baseType = getBaseTypeAndTypmod(domainType, &my_extra->typtypmod);
+
/* Look up underlying I/O function */
if (binary)
getTypeBinaryInputInfo(baseType,