diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 50ecf7e884c1dbba7f4110d5fe16d2b2027c39a5..660d06934606aabf314aaf1a87413ff38871b64e 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -633,6 +633,7 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect, foreach(tllist, targetList) { TargetEntry *tle = (TargetEntry *) lfirst(tllist); + Oid tletypid; int32 tletypmod; Form_pg_attribute attr; char *attname; @@ -664,19 +665,32 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot convert relation containing dropped columns to view"))); + /* Check name match if required; no need for two error texts here */ if (requireColumnNameMatch && strcmp(tle->resname, attname) != 0) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("SELECT rule's target entry %d has different column name from \"%s\"", i, attname))); - - if (attr->atttypid != exprType((Node *) tle->expr)) + errmsg("SELECT rule's target entry %d has different column name from column \"%s\"", + i, attname), + errdetail("SELECT target entry is named \"%s\".", + tle->resname))); + + /* Check type match. */ + tletypid = exprType((Node *) tle->expr); + if (attr->atttypid != tletypid) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), isSelect ? errmsg("SELECT rule's target entry %d has different type from column \"%s\"", i, attname) : errmsg("RETURNING list's entry %d has different type from column \"%s\"", - i, attname))); + i, attname), + isSelect ? + errdetail("SELECT target entry has type %s, but column has type %s.", + format_type_be(tletypid), + format_type_be(attr->atttypid)) : + errdetail("RETURNING list entry has type %s, but column has type %s.", + format_type_be(tletypid), + format_type_be(attr->atttypid)))); /* * Allow typmods to be different only if one of them is -1, ie, @@ -693,7 +707,16 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect, errmsg("SELECT rule's target entry %d has different size from column \"%s\"", i, attname) : errmsg("RETURNING list's entry %d has different size from column \"%s\"", - i, attname))); + i, attname), + isSelect ? + errdetail("SELECT target entry has type %s, but column has type %s.", + format_type_with_typemod(tletypid, tletypmod), + format_type_with_typemod(attr->atttypid, + attr->atttypmod)) : + errdetail("RETURNING list entry has type %s, but column has type %s.", + format_type_with_typemod(tletypid, tletypmod), + format_type_with_typemod(attr->atttypid, + attr->atttypmod)))); } if (i != resultDesc->natts)