On Thu, Feb 23, 2023 at 09:24:46PM +0100, Tomas Vondra wrote:
> On 2/23/23 16:26, Tomas Vondra wrote:
> > Thanks for v30 with the updated commit messages. I've pushed 0001 after
> > fixing a comment typo and removing (I think) an unnecessary change in an
> > error message.
> > 
> > I'll give the buildfarm a bit of time before pushing 0002 and 0003.
> > 
> 
> I've now pushed 0002 and 0003, after minor tweaks (a couple typos etc.),
> and marked the CF entry as committed. Thanks for the patch!

I found that e9960732a broke writing of empty gzip-compressed data,
specifically LOs.  pg_dump succeeds, but then the restore fails:

postgres=# SELECT lo_create(1234);
lo_create | 1234

$ time ./src/bin/pg_dump/pg_dump -h /tmp -d postgres -Fc 
|./src/bin/pg_dump/pg_restore -f /dev/null -v 
pg_restore: implied data-only restore
pg_restore: executing BLOB 1234
pg_restore: processing BLOBS
pg_restore: restoring large object with OID 1234
pg_restore: error: could not uncompress data: (null)

The inline patch below fixes it, but you won't be able to apply it
directly, as it's on top of other patches which rename the functions
back to "Zlib" and rearranges the functions to their original order, to
allow running:

git diff --diff-algorithm=minimal -w e9960732a~:./src/bin/pg_dump/compress_io.c 
./src/bin/pg_dump/compress_gzip.c

The current function order avoids 3 lines of declarations, but it's
obviously pretty useful to be able to run that diff command.  I already
argued for not calling the functions "Gzip" on the grounds that the name
was inaccurate.

I'd want to create an empty large object in src/test/sql/largeobject.sql
to exercise this tested during pgupgrade.  But unfortunately that
doesn't use -Fc, so this isn't hit.  Empty input is an important enough
test case to justify a tap test, if there's no better way.

diff --git a/src/bin/pg_dump/compress_gzip.c b/src/bin/pg_dump/compress_gzip.c
index f3f5e87c9a8..68f3111b2fe 100644
--- a/src/bin/pg_dump/compress_gzip.c
+++ b/src/bin/pg_dump/compress_gzip.c
@@ -55,6 +55,32 @@ InitCompressorZlib(CompressorState *cs,
        gzipcs = (ZlibCompressorState *) 
pg_malloc0(sizeof(ZlibCompressorState));
 
        cs->private_data = gzipcs;
+
+       if (cs->writeF)
+       {
+               z_streamp       zp;
+               zp = gzipcs->zp = (z_streamp) pg_malloc0(sizeof(z_stream));
+               zp->zalloc = Z_NULL;
+               zp->zfree = Z_NULL;
+               zp->opaque = Z_NULL;
+
+               /*
+                * outsize is the buffer size we tell zlib it can output to.  We
+                * actually allocate one extra byte because some routines want 
to append a
+                * trailing zero byte to the zlib output.
+                */
+
+               gzipcs->outbuf = pg_malloc(ZLIB_OUT_SIZE + 1);
+               gzipcs->outsize = ZLIB_OUT_SIZE;
+
+               if (deflateInit(gzipcs->zp, cs->compression_spec.level) != Z_OK)
+                       pg_fatal("could not initialize compression library: %s",
+                                       zp->msg);
+
+               /* Just be paranoid - maybe End is called after Start, with no 
Write */
+               zp->next_out = gzipcs->outbuf;
+               zp->avail_out = gzipcs->outsize;
+       }
 }
 
 static void
@@ -63,7 +89,7 @@ EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
        ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
        z_streamp       zp;
 
-       if (gzipcs->zp)
+       if (cs->writeF != NULL)
        {
                zp = gzipcs->zp;
                zp->next_in = NULL;
@@ -131,29 +157,6 @@ WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState 
*cs,
                                           const void *data, size_t dLen)
 {
        ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
-       z_streamp       zp;
-
-       if (!gzipcs->zp)
-       {
-               zp = gzipcs->zp = (z_streamp) pg_malloc(sizeof(z_stream));
-               zp->zalloc = Z_NULL;
-               zp->zfree = Z_NULL;
-               zp->opaque = Z_NULL;
-
-               /*
-                * outsize is the buffer size we tell zlib it can output to.  We
-                * actually allocate one extra byte because some routines want 
to
-                * append a trailing zero byte to the zlib output.
-                */
-               gzipcs->outbuf = pg_malloc(ZLIB_OUT_SIZE + 1);
-               gzipcs->outsize = ZLIB_OUT_SIZE;
-
-               if (deflateInit(zp, cs->compression_spec.level) != Z_OK)
-                       pg_fatal("could not initialize compression library: 
%s", zp->msg);
-
-               zp->next_out = gzipcs->outbuf;
-               zp->avail_out = gzipcs->outsize;
-       }
 
        gzipcs->zp->next_in = (void *) unconstify(void *, data);
        gzipcs->zp->avail_in = dLen;
>From 1c707279596f3cffde9c97b450dcbef0b6ddbd94 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryz...@telsasoft.com>
Date: Sun, 26 Feb 2023 17:12:03 -0600
Subject: [PATCH 1/3] Rename functions/structures/comments which don't use
 "gzip"

zlib's "deflate" functions use a header other than gzip's, so it's
misleading to use names that say gzip.

https://www.postgresql.org/message-id/20221217232615.GS1153%40telsasoft.com
https://www.postgresql.org/message-id/20230127172320.GZ22427%40telsasoft.com
---
 src/bin/pg_dump/compress_gzip.c | 42 ++++++++++++++++-----------------
 src/bin/pg_dump/compress_gzip.h |  2 +-
 src/bin/pg_dump/compress_io.c   |  2 +-
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/src/bin/pg_dump/compress_gzip.c b/src/bin/pg_dump/compress_gzip.c
index 52f41c2e58c..dd769750c8f 100644
--- a/src/bin/pg_dump/compress_gzip.c
+++ b/src/bin/pg_dump/compress_gzip.c
@@ -1,50 +1,50 @@
 /*-------------------------------------------------------------------------
  *
  * compress_gzip.c
- *	 Routines for archivers to read or write a gzip compressed data stream.
+ *	 Routines for archivers to read or write a zlib/gzip compressed data streams.
  *
  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
  *	   src/bin/pg_dump/compress_gzip.c
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres_fe.h"
 #include <unistd.h>
 
 #include "compress_gzip.h"
 #include "pg_backup_utils.h"
 
 #ifdef HAVE_LIBZ
 #include "zlib.h"
 
 /*----------------------
  * Compressor API
  *----------------------
  */
-typedef struct GzipCompressorState
+typedef struct ZlibCompressorState
 {
 	z_streamp	zp;
 
 	void	   *outbuf;
 	size_t		outsize;
-} GzipCompressorState;
+} ZlibCompressorState;
 
-/* Private routines that support gzip compressed data I/O */
+/* Private routines that support zlib compressed data I/O */
 static void
-DeflateCompressorGzip(ArchiveHandle *AH, CompressorState *cs, bool flush)
+DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
 {
-	GzipCompressorState *gzipcs = (GzipCompressorState *) cs->private_data;
+	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
 	z_streamp	zp = gzipcs->zp;
 	void	   *out = gzipcs->outbuf;
 	int			res = Z_OK;
 
 	while (gzipcs->zp->avail_in != 0 || flush)
 	{
 		res = deflate(zp, flush ? Z_FINISH : Z_NO_FLUSH);
 		if (res == Z_STREAM_ERROR)
 			pg_fatal("could not compress data: %s", zp->msg);
 		if ((flush && (zp->avail_out < gzipcs->outsize))
 			|| (zp->avail_out == 0)
@@ -68,52 +68,52 @@ DeflateCompressorGzip(ArchiveHandle *AH, CompressorState *cs, bool flush)
 			}
 			zp->next_out = out;
 			zp->avail_out = gzipcs->outsize;
 		}
 
 		if (res == Z_STREAM_END)
 			break;
 	}
 }
 
 static void
-EndCompressorGzip(ArchiveHandle *AH, CompressorState *cs)
+EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
 {
-	GzipCompressorState *gzipcs = (GzipCompressorState *) cs->private_data;
+	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
 	z_streamp	zp;
 
 	if (gzipcs->zp)
 	{
 		zp = gzipcs->zp;
 		zp->next_in = NULL;
 		zp->avail_in = 0;
 
 		/* Flush any remaining data from zlib buffer */
-		DeflateCompressorGzip(AH, cs, true);
+		DeflateCompressorZlib(AH, cs, true);
 
 		if (deflateEnd(zp) != Z_OK)
 			pg_fatal("could not close compression stream: %s", zp->msg);
 
 		pg_free(gzipcs->outbuf);
 		pg_free(gzipcs->zp);
 	}
 
 	pg_free(gzipcs);
 	cs->private_data = NULL;
 }
 
 static void
-WriteDataToArchiveGzip(ArchiveHandle *AH, CompressorState *cs,
+WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
 					   const void *data, size_t dLen)
 {
-	GzipCompressorState *gzipcs = (GzipCompressorState *) cs->private_data;
+	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
 	z_streamp	zp;
 
 	if (!gzipcs->zp)
 	{
 		zp = gzipcs->zp = (z_streamp) pg_malloc(sizeof(z_stream));
 		zp->zalloc = Z_NULL;
 		zp->zfree = Z_NULL;
 		zp->opaque = Z_NULL;
 
 		/*
 		 * outsize is the buffer size we tell zlib it can output to.  We
@@ -124,27 +124,27 @@ WriteDataToArchiveGzip(ArchiveHandle *AH, CompressorState *cs,
 		gzipcs->outsize = ZLIB_OUT_SIZE;
 
 		if (deflateInit(zp, cs->compression_spec.level) != Z_OK)
 			pg_fatal("could not initialize compression library: %s", zp->msg);
 
 		zp->next_out = gzipcs->outbuf;
 		zp->avail_out = gzipcs->outsize;
 	}
 
 	gzipcs->zp->next_in = (void *) unconstify(void *, data);
 	gzipcs->zp->avail_in = dLen;
-	DeflateCompressorGzip(AH, cs, false);
+	DeflateCompressorZlib(AH, cs, false);
 }
 
 static void
-ReadDataFromArchiveGzip(ArchiveHandle *AH, CompressorState *cs)
+ReadDataFromArchiveZlib(ArchiveHandle *AH, CompressorState *cs)
 {
 	z_streamp	zp;
 	char	   *out;
 	int			res = Z_OK;
 	size_t		cnt;
 	char	   *buf;
 	size_t		buflen;
 
 	zp = (z_streamp) pg_malloc(sizeof(z_stream));
 	zp->zalloc = Z_NULL;
 	zp->zfree = Z_NULL;
@@ -193,36 +193,36 @@ ReadDataFromArchiveGzip(ArchiveHandle *AH, CompressorState *cs)
 		ahwrite(out, 1, ZLIB_OUT_SIZE - zp->avail_out, AH);
 	}
 
 	if (inflateEnd(zp) != Z_OK)
 		pg_fatal("could not close compression library: %s", zp->msg);
 
 	free(buf);
 	free(out);
 	free(zp);
 }
 
-/* Public routines that support gzip compressed data I/O */
+/* Public routines that support zlib compressed data I/O */
 void
-InitCompressorGzip(CompressorState *cs,
+InitCompressorZlib(CompressorState *cs,
 				   const pg_compress_specification compression_spec)
 {
-	GzipCompressorState *gzipcs;
+	ZlibCompressorState *gzipcs;
 
-	cs->readData = ReadDataFromArchiveGzip;
-	cs->writeData = WriteDataToArchiveGzip;
-	cs->end = EndCompressorGzip;
+	cs->readData = ReadDataFromArchiveZlib;
+	cs->writeData = WriteDataToArchiveZlib;
+	cs->end = EndCompressorZlib;
 
 	cs->compression_spec = compression_spec;
 
-	gzipcs = (GzipCompressorState *) pg_malloc0(sizeof(GzipCompressorState));
+	gzipcs = (ZlibCompressorState *) pg_malloc0(sizeof(ZlibCompressorState));
 
 	cs->private_data = gzipcs;
 }
 
 
 /*----------------------
  * Compress File API
  *----------------------
  */
 
 static size_t
@@ -370,23 +370,23 @@ InitCompressFileHandleGzip(CompressFileHandle *CFH,
 	CFH->getc_func = Gzip_getc;
 	CFH->close_func = Gzip_close;
 	CFH->eof_func = Gzip_eof;
 	CFH->get_error_func = Gzip_get_error;
 
 	CFH->compression_spec = compression_spec;
 
 	CFH->private_data = NULL;
 }
 #else							/* HAVE_LIBZ */
 void
-InitCompressorGzip(CompressorState *cs,
+InitCompressorZlib(CompressorState *cs,
 				   const pg_compress_specification compression_spec)
 {
 	pg_fatal("this build does not support compression with %s", "gzip");
 }
 
 void
 InitCompressFileHandleGzip(CompressFileHandle *CFH,
 						   const pg_compress_specification compression_spec)
 {
 	pg_fatal("this build does not support compression with %s", "gzip");
 }
diff --git a/src/bin/pg_dump/compress_gzip.h b/src/bin/pg_dump/compress_gzip.h
index 2392c697b4c..784a45edaae 100644
--- a/src/bin/pg_dump/compress_gzip.h
+++ b/src/bin/pg_dump/compress_gzip.h
@@ -8,17 +8,17 @@
  *
  * IDENTIFICATION
  *	   src/bin/pg_dump/compress_gzip.h
  *
  *-------------------------------------------------------------------------
  */
 #ifndef _COMPRESS_GZIP_H_
 #define _COMPRESS_GZIP_H_
 
 #include "compress_io.h"
 
-extern void InitCompressorGzip(CompressorState *cs,
+extern void InitCompressorZlib(CompressorState *cs,
 							   const pg_compress_specification compression_spec);
 extern void InitCompressFileHandleGzip(CompressFileHandle *CFH,
 									   const pg_compress_specification compression_spec);
 
 #endif							/* _COMPRESS_GZIP_H_ */
diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c
index ce06f1eac9c..e8277a1e13a 100644
--- a/src/bin/pg_dump/compress_io.c
+++ b/src/bin/pg_dump/compress_io.c
@@ -119,23 +119,23 @@ AllocateCompressor(const pg_compress_specification compression_spec,
 				   ReadFunc readF, WriteFunc writeF)
 {
 	CompressorState *cs;
 
 	cs = (CompressorState *) pg_malloc0(sizeof(CompressorState));
 	cs->readF = readF;
 	cs->writeF = writeF;
 
 	if (compression_spec.algorithm == PG_COMPRESSION_NONE)
 		InitCompressorNone(cs, compression_spec);
 	else if (compression_spec.algorithm == PG_COMPRESSION_GZIP)
-		InitCompressorGzip(cs, compression_spec);
+		InitCompressorZlib(cs, compression_spec);
 	else if (compression_spec.algorithm == PG_COMPRESSION_LZ4)
 		InitCompressorLZ4(cs, compression_spec);
 
 	return cs;
 }
 
 /*
  * Terminate compression library context and flush its buffers.
  */
 void
 EndCompressor(ArchiveHandle *AH, CompressorState *cs)
-- 
2.34.1

>From f8529ab684ab2957a775b6add1e6fc94a4a12476 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryz...@telsasoft.com>
Date: Tue, 28 Feb 2023 13:34:06 -0600
Subject: [PATCH 2/3] +also rearrange the functions to their original order..

This allows comparing like:
git diff --diff-algorithm=minimal -w e9960732a~:../src/bin/pg_dump/compress_io.c ../src/bin/pg_dump/compress_gzip.c
---
 src/bin/pg_dump/compress_gzip.c | 95 ++++++++++++++++++---------------
 1 file changed, 51 insertions(+), 44 deletions(-)

diff --git a/src/bin/pg_dump/compress_gzip.c b/src/bin/pg_dump/compress_gzip.c
index dd769750c8f..f3f5e87c9a8 100644
--- a/src/bin/pg_dump/compress_gzip.c
+++ b/src/bin/pg_dump/compress_gzip.c
@@ -24,22 +24,73 @@
  * Compressor API
  *----------------------
  */
 typedef struct ZlibCompressorState
 {
 	z_streamp	zp;
 
 	void	   *outbuf;
 	size_t		outsize;
 } ZlibCompressorState;
 
+static void ReadDataFromArchiveZlib(ArchiveHandle *AH, CompressorState *cs);
+static void WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
+		const void *data, size_t dLen);
+static void EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs);
+static void DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs,
+		bool flush);
+
+/* Public routines that support zlib compressed data I/O */
+void
+InitCompressorZlib(CompressorState *cs,
+				   const pg_compress_specification compression_spec)
+{
+	ZlibCompressorState *gzipcs;
+
+	cs->readData = ReadDataFromArchiveZlib;
+	cs->writeData = WriteDataToArchiveZlib;
+	cs->end = EndCompressorZlib;
+
+	cs->compression_spec = compression_spec;
+
+	gzipcs = (ZlibCompressorState *) pg_malloc0(sizeof(ZlibCompressorState));
+
+	cs->private_data = gzipcs;
+}
+
+static void
+EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
+{
+	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
+	z_streamp	zp;
+
+	if (gzipcs->zp)
+	{
+		zp = gzipcs->zp;
+		zp->next_in = NULL;
+		zp->avail_in = 0;
+
+		/* Flush any remaining data from zlib buffer */
+		DeflateCompressorZlib(AH, cs, true);
+
+		if (deflateEnd(zp) != Z_OK)
+			pg_fatal("could not close compression stream: %s", zp->msg);
+
+		pg_free(gzipcs->outbuf);
+		pg_free(gzipcs->zp);
+	}
+
+	pg_free(gzipcs);
+	cs->private_data = NULL;
+}
+
 /* Private routines that support zlib compressed data I/O */
 static void
 DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
 {
 	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
 	z_streamp	zp = gzipcs->zp;
 	void	   *out = gzipcs->outbuf;
 	int			res = Z_OK;
 
 	while (gzipcs->zp->avail_in != 0 || flush)
 	{
@@ -67,48 +118,22 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
 				cs->writeF(AH, (char *) out, len);
 			}
 			zp->next_out = out;
 			zp->avail_out = gzipcs->outsize;
 		}
 
 		if (res == Z_STREAM_END)
 			break;
 	}
 }
 
-static void
-EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
-{
-	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
-	z_streamp	zp;
-
-	if (gzipcs->zp)
-	{
-		zp = gzipcs->zp;
-		zp->next_in = NULL;
-		zp->avail_in = 0;
-
-		/* Flush any remaining data from zlib buffer */
-		DeflateCompressorZlib(AH, cs, true);
-
-		if (deflateEnd(zp) != Z_OK)
-			pg_fatal("could not close compression stream: %s", zp->msg);
-
-		pg_free(gzipcs->outbuf);
-		pg_free(gzipcs->zp);
-	}
-
-	pg_free(gzipcs);
-	cs->private_data = NULL;
-}
-
 static void
 WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
 					   const void *data, size_t dLen)
 {
 	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
 	z_streamp	zp;
 
 	if (!gzipcs->zp)
 	{
 		zp = gzipcs->zp = (z_streamp) pg_malloc(sizeof(z_stream));
 		zp->zalloc = Z_NULL;
@@ -193,40 +218,22 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, CompressorState *cs)
 		ahwrite(out, 1, ZLIB_OUT_SIZE - zp->avail_out, AH);
 	}
 
 	if (inflateEnd(zp) != Z_OK)
 		pg_fatal("could not close compression library: %s", zp->msg);
 
 	free(buf);
 	free(out);
 	free(zp);
 }
 
-/* Public routines that support zlib compressed data I/O */
-void
-InitCompressorZlib(CompressorState *cs,
-				   const pg_compress_specification compression_spec)
-{
-	ZlibCompressorState *gzipcs;
-
-	cs->readData = ReadDataFromArchiveZlib;
-	cs->writeData = WriteDataToArchiveZlib;
-	cs->end = EndCompressorZlib;
-
-	cs->compression_spec = compression_spec;
-
-	gzipcs = (ZlibCompressorState *) pg_malloc0(sizeof(ZlibCompressorState));
-
-	cs->private_data = gzipcs;
-}
-
 
 /*----------------------
  * Compress File API
  *----------------------
  */
 
 static size_t
 Gzip_read(void *ptr, size_t size, CompressFileHandle *CFH)
 {
 	gzFile		gzfp = (gzFile) CFH->private_data;
 	size_t		ret;
-- 
2.34.1

>From d27585f527365bdb32f032e789ed924d6bb2dca5 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryz...@telsasoft.com>
Date: Tue, 28 Feb 2023 17:06:59 -0600
Subject: [PATCH 3/3] pg_dump: call deflateInit() in Init() rather than in
 Write()..

This resolves an issue in e9960732a causing empty LOs to be dumped
incorrectly, resulting in errors during pg_restore.
---
 src/bin/pg_dump/compress_gzip.c | 51 +++++++++++++++++----------------
 1 file changed, 27 insertions(+), 24 deletions(-)

diff --git a/src/bin/pg_dump/compress_gzip.c b/src/bin/pg_dump/compress_gzip.c
index f3f5e87c9a8..68f3111b2fe 100644
--- a/src/bin/pg_dump/compress_gzip.c
+++ b/src/bin/pg_dump/compress_gzip.c
@@ -47,31 +47,57 @@ InitCompressorZlib(CompressorState *cs,
 	ZlibCompressorState *gzipcs;
 
 	cs->readData = ReadDataFromArchiveZlib;
 	cs->writeData = WriteDataToArchiveZlib;
 	cs->end = EndCompressorZlib;
 
 	cs->compression_spec = compression_spec;
 
 	gzipcs = (ZlibCompressorState *) pg_malloc0(sizeof(ZlibCompressorState));
 
 	cs->private_data = gzipcs;
+
+	if (cs->writeF)
+	{
+		z_streamp	zp;
+		zp = gzipcs->zp = (z_streamp) pg_malloc0(sizeof(z_stream));
+		zp->zalloc = Z_NULL;
+		zp->zfree = Z_NULL;
+		zp->opaque = Z_NULL;
+
+		/*
+		 * outsize is the buffer size we tell zlib it can output to.  We
+		 * actually allocate one extra byte because some routines want to append a
+		 * trailing zero byte to the zlib output.
+		 */
+
+		gzipcs->outbuf = pg_malloc(ZLIB_OUT_SIZE + 1);
+		gzipcs->outsize = ZLIB_OUT_SIZE;
+
+		if (deflateInit(gzipcs->zp, cs->compression_spec.level) != Z_OK)
+			pg_fatal("could not initialize compression library: %s",
+					zp->msg);
+
+		/* Just be paranoid - maybe End is called after Start, with no Write */
+		zp->next_out = gzipcs->outbuf;
+		zp->avail_out = gzipcs->outsize;
+	}
 }
 
 static void
 EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
 {
 	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
 	z_streamp	zp;
 
-	if (gzipcs->zp)
+	if (cs->writeF != NULL)
 	{
 		zp = gzipcs->zp;
 		zp->next_in = NULL;
 		zp->avail_in = 0;
 
 		/* Flush any remaining data from zlib buffer */
 		DeflateCompressorZlib(AH, cs, true);
 
 		if (deflateEnd(zp) != Z_OK)
 			pg_fatal("could not close compression stream: %s", zp->msg);
 
@@ -123,45 +149,22 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
 
 		if (res == Z_STREAM_END)
 			break;
 	}
 }
 
 static void
 WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
 					   const void *data, size_t dLen)
 {
 	ZlibCompressorState *gzipcs = (ZlibCompressorState *) cs->private_data;
-	z_streamp	zp;
-
-	if (!gzipcs->zp)
-	{
-		zp = gzipcs->zp = (z_streamp) pg_malloc(sizeof(z_stream));
-		zp->zalloc = Z_NULL;
-		zp->zfree = Z_NULL;
-		zp->opaque = Z_NULL;
-
-		/*
-		 * outsize is the buffer size we tell zlib it can output to.  We
-		 * actually allocate one extra byte because some routines want to
-		 * append a trailing zero byte to the zlib output.
-		 */
-		gzipcs->outbuf = pg_malloc(ZLIB_OUT_SIZE + 1);
-		gzipcs->outsize = ZLIB_OUT_SIZE;
-
-		if (deflateInit(zp, cs->compression_spec.level) != Z_OK)
-			pg_fatal("could not initialize compression library: %s", zp->msg);
-
-		zp->next_out = gzipcs->outbuf;
-		zp->avail_out = gzipcs->outsize;
-	}
 
 	gzipcs->zp->next_in = (void *) unconstify(void *, data);
 	gzipcs->zp->avail_in = dLen;
 	DeflateCompressorZlib(AH, cs, false);
 }
 
 static void
 ReadDataFromArchiveZlib(ArchiveHandle *AH, CompressorState *cs)
 {
 	z_streamp	zp;
 	char	   *out;
-- 
2.34.1

Reply via email to