From 0fe931a3e0f259bd2933e48ee09bd3d7435149b4 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 5 Aug 2002 00:21:27 +0000
Subject: [PATCH] Code review for anonymous-functions patch --- clean up some
 confusion in checkretval about which paths are for base or complex return
 type.

---
 src/backend/catalog/pg_proc.c | 49 ++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index a4dfc7fe295..c8f769db306 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.85 2002/08/04 23:49:59 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.86 2002/08/05 00:21:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -372,25 +372,27 @@ checkretval(Oid rettype, char fn_typtype, List *queryTreeList)
 
 	if (fn_typtype == 'b')
 	{
+		/* Shouldn't have a typerelid */
+		Assert(typerelid == InvalidOid);
+
 		/*
 		 * For base-type returns, the target list should have exactly one
 		 * entry, and its type should agree with what the user declared. (As
 		 * of Postgres 7.2, we accept binary-compatible types too.)
 		 */
+		if (tlistlen != 1)
+			elog(ERROR, "function declared to return %s returns multiple columns in final SELECT",
+				 format_type_be(rettype));
 
-		if (typerelid == InvalidOid)
-		{
-			if (tlistlen != 1)
-				elog(ERROR, "function declared to return %s returns multiple columns in final SELECT",
-					 format_type_be(rettype));
-
-			restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
-			if (!IsBinaryCompatible(restype, rettype))
-				elog(ERROR, "return type mismatch in function: declared to return %s, returns %s",
-					 format_type_be(rettype), format_type_be(restype));
-
-			return;
-		}
+		restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
+		if (!IsBinaryCompatible(restype, rettype))
+			elog(ERROR, "return type mismatch in function: declared to return %s, returns %s",
+				 format_type_be(rettype), format_type_be(restype));
+	}
+	else if (fn_typtype == 'c')
+	{
+		/* Must have a typerelid */
+		Assert(typerelid != InvalidOid);
 
 		/*
 		 * If the target list is of length 1, and the type of the varnode in
@@ -405,14 +407,13 @@ checkretval(Oid rettype, char fn_typtype, List *queryTreeList)
 			if (IsBinaryCompatible(restype, rettype))
 				return;
 		}
-	}
-	else if (fn_typtype == 'c')
-	{
+
 		/*
-		 * By here, the procedure returns a tuple or set of tuples.  This part
-		 * of the typechecking is a hack. We look up the relation that is the
-		 * declared return type, and scan the non-deleted attributes to ensure
-		 * that they match the datatypes of the non-resjunk columns.
+		 * Otherwise verify that the targetlist matches the return tuple type.
+		 * This part of the typechecking is a hack. We look up the relation
+		 * that is the declared return type, and scan the non-deleted
+		 * attributes to ensure that they match the datatypes of the
+		 * non-resjunk columns.
 		 */
 		reln = heap_open(typerelid, AccessShareLock);
 		relnatts = reln->rd_rel->relnatts;
@@ -462,16 +463,16 @@ checkretval(Oid rettype, char fn_typtype, List *queryTreeList)
 				 format_type_be(rettype), rellogcols);
 
 		heap_close(reln, AccessShareLock);
-
-		return;
 	}
 	else if (fn_typtype == 'p' && rettype == RECORDOID)
 	{
+		/* Shouldn't have a typerelid */
+		Assert(typerelid == InvalidOid);
+
 		/*
 		 * For RECORD return type, defer this check until we get the
 		 * first tuple.
 		 */
-		return;
 	}
 	else
 		elog(ERROR, "Unknown kind of return type specified for function");
-- 
GitLab