From e6a867c8a9724d37ce04b56bd132f8bfc571d659 Mon Sep 17 00:00:00 2001
From: Ronan Dunklau <ronan.dunklau@aiven.io>
Date: Thu, 26 Aug 2021 14:05:26 +0200
Subject: [PATCH v3 3/3] Check slot existence in pg_basebackup.

Use the newly introduced READ_REPLICATION_SLOT command to check for a
slot existence in pg_basebackup. That way, we can fail early.
---
 src/bin/pg_basebackup/pg_basebackup.c        | 17 +++++++++++++++++
 src/bin/pg_basebackup/t/010_pg_basebackup.pl |  7 ++++---
 src/test/perl/PostgresNode.pm                | 20 ++++++++++++++++++++
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 7296eb97d0..b93db32e23 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -1867,6 +1867,23 @@ BaseBackup(void)
 	if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
 		exit(1);
 
+	/*
+	 * Check the replication slot exists if applicable
+	 */
+	if (replication_slot && !(temp_replication_slot || create_slot) && PQserverVersion(conn) >= 15000)
+	{
+		char	   *slot_type = NULL;
+
+		if (!GetSlotInformation(conn, replication_slot, NULL, NULL, &slot_type))
+			exit(1);
+		if (strcmp(slot_type, "physical") != 0)
+		{
+			pg_log_error("Slot \"%s\" is not a physical replication slot",
+						 replication_slot);
+			exit(1);
+		}
+	}
+
 	/*
 	 * Start the actual backup
 	 */
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index a2cb2a7679..69fd262a97 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -10,7 +10,7 @@ use File::Path qw(rmtree);
 use Fcntl qw(:seek);
 use PostgresNode;
 use TestLib;
-use Test::More tests => 110;
+use Test::More tests => 111;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -465,14 +465,15 @@ $node->command_ok(
 	'pg_basebackup -X stream runs with --no-slot');
 rmtree("$tempdir/backupnoslot");
 
-$node->command_fails(
+$node->command_fails_like(
 	[
 		'pg_basebackup',             '-D',
 		"$tempdir/backupxs_sl_fail", '-X',
 		'stream',                    '-S',
 		'slot0'
 	],
-	'pg_basebackup fails with nonexistent replication slot');
+	qr/pg_basebackup: error: replication slot "slot0" does not exist/,
+	'pg_basebackup fails early with nonexistent replication slot');
 
 $node->command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backupxs_slot", '-C' ],
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
index 8158ea5b2f..c59da758c7 100644
--- a/src/test/perl/PostgresNode.pm
+++ b/src/test/perl/PostgresNode.pm
@@ -2267,6 +2267,26 @@ sub command_like
 
 =pod
 
+=item $node->command_fails_like(...)
+
+TestLib::command_fails_like with our connection parameters. See command_ok(...)
+
+=cut
+
+sub command_fails_like
+{
+	local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+	my $self = shift;
+
+	local %ENV = $self->_get_env();
+
+	TestLib::command_fails_like(@_);
+	return;
+}
+
+=pod
+
 =item $node->command_checks_all(...)
 
 TestLib::command_checks_all with our connection parameters. See
-- 
2.32.0

