diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 9fb266d0..f290a439 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -4631,6 +4631,15 @@ var_is_nonnullable(PlannerInfo *root, Var *var, NotNullSource source)
 	if (var->varlevelsup != 0)
 		return false;
 
+	/*
+	 * A Var with VAR_RETURNING_OLD or VAR_RETURNING_NEW refers to the OLD or
+	 * NEW tuple in a RETURNING list.  Such a Var can be NULL even if the
+	 * underlying column is defined NOT NULL, because the OLD tuple doesn't
+	 * exist for INSERT and the NEW tuple doesn't exist for DELETE.
+	 */
+	if (var->varreturningtype != VAR_RETURNING_DEFAULT)
+		return false;
+
 	/* could the Var be nulled by any outer joins or grouping sets? */
 	if (!bms_is_empty(var->varnullingrels))
 		return false;
