diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index d4279c0f4e546fcf50435fea7c7e713f45068d50..a5cc48b47cc7fcbef32b3248906a59983a63a536 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -4368,6 +4368,7 @@ print_parameter_expr(Node *expr, ListCell *ancestor_cell,
 {
 	deparse_namespace save_dpns;
 	bool		save_varprefix;
+	bool		need_paren;
 
 	/* Switch attention to the ancestor plan node */
 	push_ancestor_plan(dpns, ancestor_cell, &save_dpns);
@@ -4380,13 +4381,21 @@ print_parameter_expr(Node *expr, ListCell *ancestor_cell,
 	context->varprefix = true;
 
 	/*
-	 * We don't need to add parentheses because a Param's expansion is
-	 * (currently) always a Var or Aggref.
+	 * A Param's expansion is typically a Var, Aggref, or upper-level Param,
+	 * which wouldn't need extra parentheses.  Otherwise, insert parens to
+	 * ensure the expression looks atomic.
 	 */
-	Assert(IsA(expr, Var) || IsA(expr, Aggref));
+	need_paren = !(IsA(expr, Var) ||
+				   IsA(expr, Aggref) ||
+				   IsA(expr, Param));
+	if (need_paren)
+		appendStringInfoChar(context->buf, '(');
 
 	get_rule_expr(expr, context, false);
 
+	if (need_paren)
+		appendStringInfoChar(context->buf, ')');
+
 	context->varprefix = save_varprefix;
 
 	pop_ancestor_plan(dpns, &save_dpns);