diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 2b21910a28071c434a560847eab435992b131655..782599c77b5c6fa6277d5990fb44e7eb2021841e 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1207,6 +1207,24 @@ selectDumpableDefaultACL(DefaultACLInfo *dinfo)
 		dinfo->dobj.dump = include_everything;
 }
 
+/*
+ * selectDumpableCast: policy-setting subroutine
+ *		Mark a cast as to be dumped or not
+ *
+ * Casts do not belong to any particular namespace (since they haven't got
+ * names), nor do they have identifiable owners.  To distinguish user-defined
+ * casts from built-in ones, we must resort to checking whether the cast's
+ * OID is in the range reserved for initdb.
+ */
+static void
+selectDumpableCast(CastInfo *cast)
+{
+	if (cast->dobj.catId.oid < (Oid) FirstNormalObjectId)
+		cast->dobj.dump = false;
+	else
+		cast->dobj.dump = include_everything;
+}
+
 /*
  * selectDumpableExtension: policy-setting subroutine
  *		Mark an extension as to be dumped or not
@@ -5605,12 +5623,13 @@ getCasts(Archive *fout, int *numCasts)
 							  sTypeInfo->dobj.name, tTypeInfo->dobj.name);
 		castinfo[i].dobj.name = namebuf.data;
 
-		if (OidIsValid(castinfo[i].castfunc))
+		if (fout->remoteVersion < 70300 &&
+			OidIsValid(castinfo[i].castfunc))
 		{
 			/*
 			 * We need to make a dependency to ensure the function will be
 			 * dumped first.  (In 7.3 and later the regular dependency
-			 * mechanism will handle this for us.)
+			 * mechanism handles this for us.)
 			 */
 			FuncInfo   *funcInfo;
 
@@ -5619,6 +5638,9 @@ getCasts(Archive *fout, int *numCasts)
 				addObjectDependency(&castinfo[i].dobj,
 									funcInfo->dobj.dumpId);
 		}
+
+		/* Decide whether we want to dump it */
+		selectDumpableCast(&(castinfo[i]));
 	}
 
 	PQclear(res);
@@ -9493,55 +9515,9 @@ dumpCast(Archive *fout, CastInfo *cast)
 	}
 
 	/*
-	 * As per discussion we dump casts if one or more of the underlying
-	 * objects (the conversion function and the two data types) are not
-	 * builtin AND if all of the non-builtin objects are included in the dump.
-	 * Builtin meaning, the namespace name does not start with "pg_".
-	 *
-	 * However, for a cast that belongs to an extension, we must not use this
-	 * heuristic, but just dump the cast iff we're told to (via dobj.dump).
+	 * Make sure we are in proper schema (needed for getFormattedTypeName).
+	 * Casts don't have a schema of their own, so use pg_catalog.
 	 */
-	if (!cast->dobj.ext_member)
-	{
-		TypeInfo   *sourceInfo = findTypeByOid(cast->castsource);
-		TypeInfo   *targetInfo = findTypeByOid(cast->casttarget);
-
-		if (sourceInfo == NULL || targetInfo == NULL)
-			return;
-
-		/*
-		 * Skip this cast if all objects are from pg_
-		 */
-		if ((funcInfo == NULL ||
-			 strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) &&
-			strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) == 0 &&
-			strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) == 0)
-			return;
-
-		/*
-		 * Skip cast if function isn't from pg_ and is not to be dumped.
-		 */
-		if (funcInfo &&
-			strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
-			!funcInfo->dobj.dump)
-			return;
-
-		/*
-		 * Same for the source type
-		 */
-		if (strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
-			!sourceInfo->dobj.dump)
-			return;
-
-		/*
-		 * and the target type.
-		 */
-		if (strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
-			!targetInfo->dobj.dump)
-			return;
-	}
-
-	/* Make sure we are in proper schema (needed for getFormattedTypeName) */
 	selectSourceSchema(fout, "pg_catalog");
 
 	defqry = createPQExpBuffer();