Skip to content

Commit 03d02f5

Browse files
committed
Prepare pg_dump internals for additional compression methods
Commit bf9aa49 introduced a compression API in compress_io.{c,h} to make reuse easier, and allow adding more compression algorithms. However, pg_backup_archiver.c was not switched to this API and continued to call the compression directly. This commit teaches pg_backup_archiver.c about the compression API, so that it can benefit from bf9aa49 (simpler code, easier addition of new compression methods). Author: Georgios Kokolatos Reviewed-by: Michael Paquier, Rachel Heaton, Justin Pryzby, Tomas Vondra Discussion: https://postgr.es/m/faUNEOpts9vunEaLnmxmG-DldLSg_ql137OC3JYDmgrOMHm1RvvWY2IdBkv_CRxm5spCCb_OmKNk2T03TMm0fBEWveFF9wA1WizPuAgB7Ss%3D%40protonmail.com
1 parent 009eeee commit 03d02f5

File tree

4 files changed

+138
-128
lines changed

4 files changed

+138
-128
lines changed

src/bin/pg_dump/compress_io.c

Lines changed: 84 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,41 @@
5656
#include "compress_io.h"
5757
#include "pg_backup_utils.h"
5858

59+
#ifdef HAVE_LIBZ
60+
#include <zlib.h>
61+
#endif
62+
63+
/*----------------------
64+
* Generic functions
65+
*----------------------
66+
*/
67+
68+
/*
69+
* Checks whether a compression algorithm is supported.
70+
*
71+
* On success returns NULL, otherwise returns a malloc'ed string which can be
72+
* used by the caller in an error message.
73+
*/
74+
char *
75+
supports_compression(const pg_compress_specification compression_spec)
76+
{
77+
const pg_compress_algorithm algorithm = compression_spec.algorithm;
78+
bool supported = false;
79+
80+
if (algorithm == PG_COMPRESSION_NONE)
81+
supported = true;
82+
#ifdef HAVE_LIBZ
83+
if (algorithm == PG_COMPRESSION_GZIP)
84+
supported = true;
85+
#endif
86+
87+
if (!supported)
88+
return psprintf("this build does not support compression with %s",
89+
get_compress_algorithm_name(algorithm));
90+
91+
return NULL;
92+
}
93+
5994
/*----------------------
6095
* Compressor API
6196
*----------------------
@@ -490,16 +525,19 @@ cfopen_write(const char *path, const char *mode,
490525
}
491526

492527
/*
493-
* Opens file 'path' in 'mode'. If compression is GZIP, the file
494-
* is opened with libz gzopen(), otherwise with plain fopen().
528+
* This is the workhorse for cfopen() or cfdopen(). It opens file 'path' or
529+
* associates a stream 'fd', if 'fd' is a valid descriptor, in 'mode'. The
530+
* descriptor is not dup'ed and it is the caller's responsibility to do so.
531+
* The caller must verify that the 'compress_algorithm' is supported by the
532+
* current build.
495533
*
496534
* On failure, return NULL with an error code in errno.
497535
*/
498-
cfp *
499-
cfopen(const char *path, const char *mode,
500-
const pg_compress_specification compression_spec)
536+
static cfp *
537+
cfopen_internal(const char *path, int fd, const char *mode,
538+
pg_compress_specification compression_spec)
501539
{
502-
cfp *fp = pg_malloc(sizeof(cfp));
540+
cfp *fp = pg_malloc0(sizeof(cfp));
503541

504542
if (compression_spec.algorithm == PG_COMPRESSION_GZIP)
505543
{
@@ -511,15 +549,20 @@ cfopen(const char *path, const char *mode,
511549

512550
snprintf(mode_compression, sizeof(mode_compression), "%s%d",
513551
mode, compression_spec.level);
514-
fp->compressedfp = gzopen(path, mode_compression);
552+
if (fd >= 0)
553+
fp->compressedfp = gzdopen(fd, mode_compression);
554+
else
555+
fp->compressedfp = gzopen(path, mode_compression);
515556
}
516557
else
517558
{
518559
/* don't specify a level, just use the zlib default */
519-
fp->compressedfp = gzopen(path, mode);
560+
if (fd >= 0)
561+
fp->compressedfp = gzdopen(fd, mode);
562+
else
563+
fp->compressedfp = gzopen(path, mode);
520564
}
521565

522-
fp->uncompressedfp = NULL;
523566
if (fp->compressedfp == NULL)
524567
{
525568
free_keep_errno(fp);
@@ -531,10 +574,11 @@ cfopen(const char *path, const char *mode,
531574
}
532575
else
533576
{
534-
#ifdef HAVE_LIBZ
535-
fp->compressedfp = NULL;
536-
#endif
537-
fp->uncompressedfp = fopen(path, mode);
577+
if (fd >= 0)
578+
fp->uncompressedfp = fdopen(fd, mode);
579+
else
580+
fp->uncompressedfp = fopen(path, mode);
581+
538582
if (fp->uncompressedfp == NULL)
539583
{
540584
free_keep_errno(fp);
@@ -545,6 +589,33 @@ cfopen(const char *path, const char *mode,
545589
return fp;
546590
}
547591

592+
/*
593+
* Opens file 'path' in 'mode' and compression as defined in
594+
* compression_spec. The caller must verify that the compression
595+
* is supported by the current build.
596+
*
597+
* On failure, return NULL with an error code in errno.
598+
*/
599+
cfp *
600+
cfopen(const char *path, const char *mode,
601+
const pg_compress_specification compression_spec)
602+
{
603+
return cfopen_internal(path, -1, mode, compression_spec);
604+
}
605+
606+
/*
607+
* Associates a stream 'fd', if 'fd' is a valid descriptor, in 'mode'
608+
* and compression as defined in compression_spec. The caller must
609+
* verify that the compression is supported by the current build.
610+
*
611+
* On failure, return NULL with an error code in errno.
612+
*/
613+
cfp *
614+
cfdopen(int fd, const char *mode,
615+
const pg_compress_specification compression_spec)
616+
{
617+
return cfopen_internal(NULL, fd, mode, compression_spec);
618+
}
548619

549620
int
550621
cfread(void *ptr, int size, cfp *fp)

src/bin/pg_dump/compress_io.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#define ZLIB_OUT_SIZE 4096
2222
#define ZLIB_IN_SIZE 4096
2323

24+
extern char *supports_compression(const pg_compress_specification compression_spec);
25+
2426
/* Prototype for callback function to WriteDataToArchive() */
2527
typedef void (*WriteFunc) (ArchiveHandle *AH, const char *buf, size_t len);
2628

@@ -54,6 +56,8 @@ typedef struct cfp cfp;
5456

5557
extern cfp *cfopen(const char *path, const char *mode,
5658
const pg_compress_specification compression_spec);
59+
extern cfp *cfdopen(int fd, const char *mode,
60+
const pg_compress_specification compression_spec);
5761
extern cfp *cfopen_read(const char *path, const char *mode);
5862
extern cfp *cfopen_write(const char *path, const char *mode,
5963
const pg_compress_specification compression_spec);

0 commit comments

Comments
 (0)