diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 0b2a164057..5b81e2c4cf 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -8869,12 +8869,43 @@ get_rule_expr(Node *node, deparse_context *context,
 				 * We cannot see an already-planned subplan in rule deparsing,
 				 * only while EXPLAINing a query plan.  We don't try to
 				 * reconstruct the original SQL, just reference the subplan
-				 * that appears elsewhere in EXPLAIN's result.
+				 * that appears elsewhere in EXPLAIN's result.  It does seem
+				 * useful to show the testexpr, however, and we also note
+				 * whether the subplan will be hashed.
 				 */
+				switch (subplan->subLinkType)
+				{
+					case EXISTS_SUBLINK:
+						appendStringInfoString(buf, "(EXISTS");
+						break;
+					case ALL_SUBLINK:
+						appendStringInfoString(buf, "(ALL ");
+						break;
+					case ANY_SUBLINK:
+						appendStringInfoString(buf, "(ANY ");
+						break;
+					case ROWCOMPARE_SUBLINK:
+						appendStringInfoString(buf, "(ROWCOMPARE ");
+						break;
+					case EXPR_SUBLINK:
+						appendStringInfoString(buf, "(EXPR");
+						break;
+					case MULTIEXPR_SUBLINK:
+						appendStringInfoString(buf, "(MULTIEXPR");
+						break;
+					case ARRAY_SUBLINK:
+						appendStringInfoString(buf, "(ARRAY");
+						break;
+					case CTE_SUBLINK:
+						/* This case is probably unreachable */
+						appendStringInfoString(buf, "(CTE");
+						break;
+				}
+				get_rule_expr(subplan->testexpr, context, showimplicit);
 				if (subplan->useHashTable)
-					appendStringInfo(buf, "(hashed %s)", subplan->plan_name);
+					appendStringInfo(buf, " FROM hashed %s)", subplan->plan_name);
 				else
-					appendStringInfo(buf, "(%s)", subplan->plan_name);
+					appendStringInfo(buf, " FROM %s)", subplan->plan_name);
 			}
 			break;
 
