v10-0005-POC-Add-test-in-pg_dump.pl.patch
application/x-patch
Filename: v10-0005-POC-Add-test-in-pg_dump.pl.patch
Type: application/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v10-0005
Subject: [POC] Add test in pg_dump.pl * Make a couple of code changes to fix the test. If they pass, we'll rebase.
| File | + | − |
|---|---|---|
| src/bin/pg_dump/compress_none.c | 6 | 4 |
| src/bin/pg_dump/pg_backup_archiver.c | 25 | 2 |
| src/bin/pg_dump/pg_dump.c | 10 | 10 |
| src/bin/pg_dump/t/002_pg_dump.pl | 19 | 0 |
From e702603beba8943efcda66c9b751d5ee56ad9084 Mon Sep 17 00:00:00 2001
From: Nitin Motiani <nitinmotiani@google.com>
Date: Fri, 1 May 2026 07:49:14 +0000
Subject: [PATCH v10 5/5] [POC] Add test in pg_dump.pl * Make a couple of code
changes to fix the test. If they pass, we'll rebase.
---
src/bin/pg_dump/compress_none.c | 10 ++++++----
src/bin/pg_dump/pg_backup_archiver.c | 27 +++++++++++++++++++++++++--
src/bin/pg_dump/pg_dump.c | 20 ++++++++++----------
src/bin/pg_dump/t/002_pg_dump.pl | 19 +++++++++++++++++++
4 files changed, 60 insertions(+), 16 deletions(-)
diff --git a/src/bin/pg_dump/compress_none.c b/src/bin/pg_dump/compress_none.c
index 8c2f95b520d..9ecdf18eec4 100644
--- a/src/bin/pg_dump/compress_none.c
+++ b/src/bin/pg_dump/compress_none.c
@@ -14,6 +14,7 @@
#include "postgres_fe.h"
#include <unistd.h>
+#include "port.h"
#include "compress_none.h"
#include "pg_backup_utils.h"
@@ -210,13 +211,14 @@ close_none(CompressFileHandle *CFH)
if (fp)
{
- errno = 0;
if (CFH->path_is_pipe_command)
- ret = pclose(fp);
+ ret = pclose_check(fp);
else
+ {
ret = fclose(fp);
- if (ret != 0)
- pg_log_error("could not close file: %m");
+ if (ret != 0)
+ pg_log_error("could not close file: %m");
+ }
}
return ret == 0;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 4ef9dae49ed..8358bd97df5 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -1744,7 +1744,19 @@ SetOutput(ArchiveHandle *AH, const char *filename,
else
mode = PG_BINARY_W;
- CFH = InitCompressFileHandle(compression_spec, AH->fSpecIsPipe);
+ /*
+ * The output handle (usually stdout) should never be a pipe command
+ * managed by our popen logic, even if the archive itself is a pipe. Our
+ * pipe command implementation for directory mode is a template for the
+ * data files, not for this primary output stream.
+ *
+ * Furthermore, marking this as a pipe command would cause it to be closed
+ * with pclose() instead of fclose(). Since this handle is opened via
+ * fdopen() (for stdout) or fopen() (for a regular file), using pclose()
+ * on it is a bug that causes failures on BSD-based systems (like FreeBSD
+ * or macOS).
+ */
+ CFH = InitCompressFileHandle(compression_spec, false);
if (!CFH->open_func(filename, fn, mode, CFH))
{
@@ -2463,7 +2475,18 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
/* Open stdout with no compression for AH output handle */
out_compress_spec.algorithm = PG_COMPRESSION_NONE;
- CFH = InitCompressFileHandle(out_compress_spec, AH->fSpecIsPipe);
+ /*
+ * The output handle (usually stdout) should never be a pipe command
+ * managed by our popen logic, even if the archive itself is a pipe. Our
+ * pipe command implementation for directory mode is a template for the
+ * data files, not for this primary output stream.
+ *
+ * Furthermore, marking this as a pipe command would cause it to be closed
+ * with pclose() instead of fclose(). Since this handle is opened via
+ * fdopen() (for stdout), using pclose() on it is a bug that causes
+ * failures on BSD-based systems (like FreeBSD or macOS).
+ */
+ CFH = InitCompressFileHandle(out_compress_spec, false);
if (!CFH->open_func(NULL, fileno(stdout), PG_BINARY_A, CFH))
pg_fatal("could not open stdout for appending: %m");
AH->OF = CFH;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 7345e6c7a4b..e4ae64c1495 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -420,6 +420,8 @@ main(int argc, char **argv)
int c;
const char *filename = NULL;
bool filename_is_pipe = false;
+ bool file_specified = false;
+ bool pipe_specified = false;
const char *format = "p";
TableInfo *tblinfo;
int numTables;
@@ -608,11 +610,7 @@ main(int argc, char **argv)
break;
case 'f':
- if (filename != NULL)
- {
- pg_log_error_hint("Only one of [--file, --pipe-command] allowed");
- exit_nicely(1);
- }
+ file_specified = true;
filename = pg_strdup(optarg);
filename_is_pipe = false; /* it already is, setting again
* here just for clarity */
@@ -809,11 +807,7 @@ main(int argc, char **argv)
break;
case 26: /* pipe command */
- if (filename != NULL)
- {
- pg_log_error_hint("Only one of [--file, --pipe-command] allowed");
- exit_nicely(1);
- }
+ pipe_specified = true;
filename = pg_strdup(optarg);
filename_is_pipe = true;
break;
@@ -825,6 +819,12 @@ main(int argc, char **argv)
}
}
+ if (file_specified && pipe_specified)
+ {
+ pg_log_error_hint("Only one of [--file, --pipe-command] allowed");
+ exit_nicely(1);
+ }
+
/*
* Non-option argument specifies database name as long as it wasn't
* already specified with -d / --dbname
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 3bc8e51561d..06b2f2619e2 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -223,6 +223,25 @@ my %pgdump_runs = (
],
},
+ # This test kept failing.
+ defaults_dir_format_pipe => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '--format' => 'directory',
+ '--pipe-command' => "cat > $tempdir/defaults_dir_format/%f",
+ '--statistics',
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '--format' => 'directory',
+ '--file' => "$tempdir/defaults_dir_format_pipe.sql",
+ '--statistics',
+ "$tempdir/defaults_dir_format",
+ ],
+ },
+
# Do not use --no-sync to give test coverage for data sync.
defaults_parallel => {
test_key => 'defaults',
--
2.54.0.545.g6539524ca2-goog