Hi,

On Tue, Aug 20, 2024 at 10:15:44AM -0400, Alvaro Herrera wrote:
> On 2024-Aug-19, Bertrand Drouvot wrote:
> 
> > diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h
> > index 6f006d5a93..a6cb091635 100644
> > --- a/src/include/common/relpath.h
> > +++ b/src/include/common/relpath.h
> > @@ -33,6 +33,10 @@ typedef Oid RelFileNumber;
> >  #define TABLESPACE_VERSION_DIRECTORY       "PG_" PG_MAJORVERSION "_" \
> >                                                                     
> > CppAsString2(CATALOG_VERSION_NO)
> >  
> > +#define PG_TBLSPC_DIR "pg_tblspc"
> 
> This one is missing some commentary along the lines of "This must not be
> changed, unless you want to break every tool in the universe".  As is,
> it's quite tempting.

Yeah, makes sense, thanks.

> > +#define PG_TBLSPC_DIR_SLASH PG_TBLSPC_DIR "/"
> 
> I would make this simply "pg_tblspc/", since it's not really possible to
> change pg_tblspc anyway.  Also, have a comment explaining why we have
> it.

Please find attached v3 that:

- takes care of your comments (and also removed the use of PG_TBLSPC_DIR in
RELATIVE_PG_TBLSPC_DIR).
- removes the new macros from the comments (see Michael's and Yugo-San's
comments in [0] resp. [1]).
- adds a missing sizeof() (see [1]).
- implements Ashutosh's idea of adding a new SLOT_DIRNAME_ARGS (see [2]). It's
done in 0002 (I used REPLSLOT_DIR_ARGS though).
- fixed a macro usage in ReorderBufferCleanupSerializedTXNs() (was not at the
right location, discovered while implementing 0002).

[0]: https://www.postgresql.org/message-id/ZsRYPcOtoqbWzjGG%40paquier.xyz
[1]: 
https://www.postgresql.org/message-id/20240820213048.207aade6a75e0dc1fe4d1067%40sraoss.co.jp
[2]: 
https://www.postgresql.org/message-id/CAExHW5vkjxuvyQ1fPPnuDW4nAT5jqox09ie36kciOV2%2BrhjbHA%40mail.gmail.com

Regards,

-- 
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
>From 12398b01fccb7437c4fb35282c576c317b9a7578 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot...@gmail.com>
Date: Wed, 14 Aug 2024 09:16:21 +0000
Subject: [PATCH v3 1/6] Define PG_REPLSLOT_DIR

Replace most of the places where "pg_replslot" is used in .c files with a new
PG_REPLSLOT_DIR define. The places where it is not done is for consistency with
the existing PG_STAT_TMP_DIR define.
---
 src/backend/backup/basebackup.c               |  3 +-
 .../replication/logical/reorderbuffer.c       | 17 ++++-----
 src/backend/replication/slot.c                | 36 +++++++++----------
 src/backend/utils/adt/genfile.c               |  3 +-
 src/bin/initdb/initdb.c                       |  2 +-
 src/bin/pg_rewind/filemap.c                   |  2 +-
 src/include/replication/slot.h                |  2 ++
 7 files changed, 35 insertions(+), 30 deletions(-)
  27.5% src/backend/replication/logical/
  60.8% src/backend/replication/
   3.9% src/backend/utils/adt/
   4.2% src/bin/
   3.3% src/

diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c
index 01b35e26bd..de16afac74 100644
--- a/src/backend/backup/basebackup.c
+++ b/src/backend/backup/basebackup.c
@@ -36,6 +36,7 @@
 #include "port.h"
 #include "postmaster/syslogger.h"
 #include "postmaster/walsummarizer.h"
+#include "replication/slot.h"
 #include "replication/walsender.h"
 #include "replication/walsender_private.h"
 #include "storage/bufpage.h"
@@ -161,7 +162,7 @@ static const char *const excludeDirContents[] =
 	 * even if the intention is to restore to another primary. See backup.sgml
 	 * for a more detailed description.
 	 */
-	"pg_replslot",
+	PG_REPLSLOT_DIR,
 
 	/* Contents removed on startup, see dsm_cleanup_for_mmap(). */
 	PG_DYNSHMEM_DIR,
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 00a8327e77..78166b6ab7 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -4571,9 +4571,9 @@ ReorderBufferCleanupSerializedTXNs(const char *slotname)
 	DIR		   *spill_dir;
 	struct dirent *spill_de;
 	struct stat statbuf;
-	char		path[MAXPGPATH * 2 + 12];
+	char		path[MAXPGPATH * 2 + sizeof(PG_REPLSLOT_DIR)];
 
-	sprintf(path, "pg_replslot/%s", slotname);
+	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, slotname);
 
 	/* we're only handling directories here, skip if it's not ours */
 	if (lstat(path, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode))
@@ -4586,14 +4586,14 @@ ReorderBufferCleanupSerializedTXNs(const char *slotname)
 		if (strncmp(spill_de->d_name, "xid", 3) == 0)
 		{
 			snprintf(path, sizeof(path),
-					 "pg_replslot/%s/%s", slotname,
+					 "%s/%s/%s", PG_REPLSLOT_DIR, slotname,
 					 spill_de->d_name);
 
 			if (unlink(path) != 0)
 				ereport(ERROR,
 						(errcode_for_file_access(),
-						 errmsg("could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m",
-								path, slotname)));
+						 errmsg("could not remove file \"%s\" during removal of %s/%s/xid*: %m",
+								path, PG_REPLSLOT_DIR, slotname)));
 		}
 	}
 	FreeDir(spill_dir);
@@ -4612,7 +4612,8 @@ ReorderBufferSerializedPath(char *path, ReplicationSlot *slot, TransactionId xid
 
 	XLogSegNoOffsetToRecPtr(segno, 0, wal_segment_size, recptr);
 
-	snprintf(path, MAXPGPATH, "pg_replslot/%s/xid-%u-lsn-%X-%X.spill",
+	snprintf(path, MAXPGPATH, "%s/%s/xid-%u-lsn-%X-%X.spill",
+			 PG_REPLSLOT_DIR,
 			 NameStr(MyReplicationSlot->data.name),
 			 xid, LSN_FORMAT_ARGS(recptr));
 }
@@ -4627,8 +4628,8 @@ StartupReorderBuffer(void)
 	DIR		   *logical_dir;
 	struct dirent *logical_de;
 
-	logical_dir = AllocateDir("pg_replslot");
-	while ((logical_de = ReadDir(logical_dir, "pg_replslot")) != NULL)
+	logical_dir = AllocateDir(PG_REPLSLOT_DIR);
+	while ((logical_de = ReadDir(logical_dir, PG_REPLSLOT_DIR)) != NULL)
 	{
 		if (strcmp(logical_de->d_name, ".") == 0 ||
 			strcmp(logical_de->d_name, "..") == 0)
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index c290339af5..1299d92696 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -916,8 +916,8 @@ ReplicationSlotDropPtr(ReplicationSlot *slot)
 	LWLockAcquire(ReplicationSlotAllocationLock, LW_EXCLUSIVE);
 
 	/* Generate pathnames. */
-	sprintf(path, "pg_replslot/%s", NameStr(slot->data.name));
-	sprintf(tmppath, "pg_replslot/%s.tmp", NameStr(slot->data.name));
+	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(slot->data.name));
+	sprintf(tmppath, "%s/%s.tmp", PG_REPLSLOT_DIR, NameStr(slot->data.name));
 
 	/*
 	 * Rename the slot directory on disk, so that we'll no longer recognize
@@ -938,7 +938,7 @@ ReplicationSlotDropPtr(ReplicationSlot *slot)
 		 */
 		START_CRIT_SECTION();
 		fsync_fname(tmppath, true);
-		fsync_fname("pg_replslot", true);
+		fsync_fname(PG_REPLSLOT_DIR, true);
 		END_CRIT_SECTION();
 	}
 	else
@@ -1016,7 +1016,7 @@ ReplicationSlotSave(void)
 
 	Assert(MyReplicationSlot != NULL);
 
-	sprintf(path, "pg_replslot/%s", NameStr(MyReplicationSlot->data.name));
+	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(MyReplicationSlot->data.name));
 	SaveSlotToPath(MyReplicationSlot, path, ERROR);
 }
 
@@ -1881,7 +1881,7 @@ CheckPointReplicationSlots(bool is_shutdown)
 			continue;
 
 		/* save the slot to disk, locking is handled in SaveSlotToPath() */
-		sprintf(path, "pg_replslot/%s", NameStr(s->data.name));
+		sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(s->data.name));
 
 		/*
 		 * Slot's data is not flushed each time the confirmed_flush LSN is
@@ -1922,17 +1922,17 @@ StartupReplicationSlots(void)
 	elog(DEBUG1, "starting up replication slots");
 
 	/* restore all slots by iterating over all on-disk entries */
-	replication_dir = AllocateDir("pg_replslot");
-	while ((replication_de = ReadDir(replication_dir, "pg_replslot")) != NULL)
+	replication_dir = AllocateDir(PG_REPLSLOT_DIR);
+	while ((replication_de = ReadDir(replication_dir, PG_REPLSLOT_DIR)) != NULL)
 	{
-		char		path[MAXPGPATH + 12];
+		char		path[MAXPGPATH + sizeof(PG_REPLSLOT_DIR)];
 		PGFileType	de_type;
 
 		if (strcmp(replication_de->d_name, ".") == 0 ||
 			strcmp(replication_de->d_name, "..") == 0)
 			continue;
 
-		snprintf(path, sizeof(path), "pg_replslot/%s", replication_de->d_name);
+		snprintf(path, sizeof(path), "%s/%s", PG_REPLSLOT_DIR, replication_de->d_name);
 		de_type = get_dirent_type(path, replication_de, false, DEBUG1);
 
 		/* we're only creating directories here, skip if it's not our's */
@@ -1949,7 +1949,7 @@ StartupReplicationSlots(void)
 								path)));
 				continue;
 			}
-			fsync_fname("pg_replslot", true);
+			fsync_fname(PG_REPLSLOT_DIR, true);
 			continue;
 		}
 
@@ -1987,8 +1987,8 @@ CreateSlotOnDisk(ReplicationSlot *slot)
 	 * takes out the lock, if we'd take the lock here, we'd deadlock.
 	 */
 
-	sprintf(path, "pg_replslot/%s", NameStr(slot->data.name));
-	sprintf(tmppath, "pg_replslot/%s.tmp", NameStr(slot->data.name));
+	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(slot->data.name));
+	sprintf(tmppath, "%s/%s.tmp", PG_REPLSLOT_DIR, NameStr(slot->data.name));
 
 	/*
 	 * It's just barely possible that some previous effort to create or drop a
@@ -2027,7 +2027,7 @@ CreateSlotOnDisk(ReplicationSlot *slot)
 	START_CRIT_SECTION();
 
 	fsync_fname(path, true);
-	fsync_fname("pg_replslot", true);
+	fsync_fname(PG_REPLSLOT_DIR, true);
 
 	END_CRIT_SECTION();
 }
@@ -2170,7 +2170,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
 
 	fsync_fname(path, false);
 	fsync_fname(dir, true);
-	fsync_fname("pg_replslot", true);
+	fsync_fname(PG_REPLSLOT_DIR, true);
 
 	END_CRIT_SECTION();
 
@@ -2195,8 +2195,8 @@ RestoreSlotFromDisk(const char *name)
 {
 	ReplicationSlotOnDisk cp;
 	int			i;
-	char		slotdir[MAXPGPATH + 12];
-	char		path[MAXPGPATH + 22];
+	char		slotdir[MAXPGPATH + sizeof(PG_REPLSLOT_DIR)];
+	char		path[MAXPGPATH + sizeof(PG_REPLSLOT_DIR) + 10];
 	int			fd;
 	bool		restored = false;
 	int			readBytes;
@@ -2205,7 +2205,7 @@ RestoreSlotFromDisk(const char *name)
 	/* no need to lock here, no concurrent access allowed yet */
 
 	/* delete temp file if it exists */
-	sprintf(slotdir, "pg_replslot/%s", name);
+	sprintf(slotdir, "%s/%s", PG_REPLSLOT_DIR, name);
 	sprintf(path, "%s/state.tmp", slotdir);
 	if (unlink(path) < 0 && errno != ENOENT)
 		ereport(PANIC,
@@ -2332,7 +2332,7 @@ RestoreSlotFromDisk(const char *name)
 					(errmsg("could not remove directory \"%s\"",
 							slotdir)));
 		}
-		fsync_fname("pg_replslot", true);
+		fsync_fname(PG_REPLSLOT_DIR, true);
 		return;
 	}
 
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 0d82557417..d95683d041 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -728,6 +728,7 @@ pg_ls_replslotdir(PG_FUNCTION_ARGS)
 				 errmsg("replication slot \"%s\" does not exist",
 						slotname)));
 
-	snprintf(path, sizeof(path), "pg_replslot/%s", slotname);
+	snprintf(path, sizeof(path), "%s/%s", PG_REPLSLOT_DIR, slotname);
+
 	return pg_ls_dir_files(fcinfo, path, false);
 }
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index f00718a015..2ee55eced0 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -242,7 +242,7 @@ static const char *const subdirs[] = {
 	"pg_multixact/offsets",
 	"base",
 	"base/1",
-	"pg_replslot",
+	"pg_replslot",				/* defined as PG_REPLSLOT_DIR */
 	"pg_tblspc",
 	"pg_stat",
 	"pg_stat_tmp",
diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c
index 4458324c9d..00e644d988 100644
--- a/src/bin/pg_rewind/filemap.c
+++ b/src/bin/pg_rewind/filemap.c
@@ -97,7 +97,7 @@ static const char *const excludeDirContents[] =
 	 * even if the intention is to restore to another primary. See backup.sgml
 	 * for a more detailed description.
 	 */
-	"pg_replslot",
+	"pg_replslot",				/* defined as PG_REPLSLOT_DIR */
 
 	/* Contents removed on startup, see dsm_cleanup_for_mmap(). */
 	"pg_dynshmem",				/* defined as PG_DYNSHMEM_DIR */
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index c2ee149fd6..9665faac1c 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -17,6 +17,8 @@
 #include "storage/spin.h"
 #include "replication/walreceiver.h"
 
+#define PG_REPLSLOT_DIR     "pg_replslot"
+
 /*
  * Behaviour of replication slots, upon release or crash.
  *
-- 
2.34.1

>From 92299c4e7e6a53f53527498c9eff76c2595f82c2 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot...@gmail.com>
Date: Tue, 20 Aug 2024 15:21:30 +0000
Subject: [PATCH v3 2/6] Define REPLSLOT_DIR_ARGS

Adding a new macro REPLSLOT_DIR_ARGS used when a slot name needs to be concatenated
to PG_REPLSLOT_DIR.
---
 src/backend/replication/logical/reorderbuffer.c |  9 ++++-----
 src/backend/replication/slot.c                  | 16 ++++++++--------
 src/backend/utils/adt/genfile.c                 |  2 +-
 src/include/replication/slot.h                  |  1 +
 4 files changed, 14 insertions(+), 14 deletions(-)
  23.5% src/backend/replication/logical/
  64.9% src/backend/replication/
   7.7% src/backend/utils/adt/
   3.7% src/include/replication/

diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 78166b6ab7..e4c2851c57 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -4573,7 +4573,7 @@ ReorderBufferCleanupSerializedTXNs(const char *slotname)
 	struct stat statbuf;
 	char		path[MAXPGPATH * 2 + sizeof(PG_REPLSLOT_DIR)];
 
-	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, slotname);
+	sprintf(path, "%s/%s", REPLSLOT_DIR_ARGS(slotname));
 
 	/* we're only handling directories here, skip if it's not ours */
 	if (lstat(path, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode))
@@ -4586,14 +4586,14 @@ ReorderBufferCleanupSerializedTXNs(const char *slotname)
 		if (strncmp(spill_de->d_name, "xid", 3) == 0)
 		{
 			snprintf(path, sizeof(path),
-					 "%s/%s/%s", PG_REPLSLOT_DIR, slotname,
+					 "%s/%s/%s", REPLSLOT_DIR_ARGS(slotname),
 					 spill_de->d_name);
 
 			if (unlink(path) != 0)
 				ereport(ERROR,
 						(errcode_for_file_access(),
 						 errmsg("could not remove file \"%s\" during removal of %s/%s/xid*: %m",
-								path, PG_REPLSLOT_DIR, slotname)));
+								path, REPLSLOT_DIR_ARGS(slotname))));
 		}
 	}
 	FreeDir(spill_dir);
@@ -4613,8 +4613,7 @@ ReorderBufferSerializedPath(char *path, ReplicationSlot *slot, TransactionId xid
 	XLogSegNoOffsetToRecPtr(segno, 0, wal_segment_size, recptr);
 
 	snprintf(path, MAXPGPATH, "%s/%s/xid-%u-lsn-%X-%X.spill",
-			 PG_REPLSLOT_DIR,
-			 NameStr(MyReplicationSlot->data.name),
+			 REPLSLOT_DIR_ARGS(NameStr(MyReplicationSlot->data.name)),
 			 xid, LSN_FORMAT_ARGS(recptr));
 }
 
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 1299d92696..45225ca314 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -916,8 +916,8 @@ ReplicationSlotDropPtr(ReplicationSlot *slot)
 	LWLockAcquire(ReplicationSlotAllocationLock, LW_EXCLUSIVE);
 
 	/* Generate pathnames. */
-	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(slot->data.name));
-	sprintf(tmppath, "%s/%s.tmp", PG_REPLSLOT_DIR, NameStr(slot->data.name));
+	sprintf(path, "%s/%s", REPLSLOT_DIR_ARGS(NameStr(slot->data.name)));
+	sprintf(tmppath, "%s/%s.tmp", REPLSLOT_DIR_ARGS(NameStr(slot->data.name)));
 
 	/*
 	 * Rename the slot directory on disk, so that we'll no longer recognize
@@ -1016,7 +1016,7 @@ ReplicationSlotSave(void)
 
 	Assert(MyReplicationSlot != NULL);
 
-	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(MyReplicationSlot->data.name));
+	sprintf(path, "%s/%s", REPLSLOT_DIR_ARGS(NameStr(MyReplicationSlot->data.name)));
 	SaveSlotToPath(MyReplicationSlot, path, ERROR);
 }
 
@@ -1881,7 +1881,7 @@ CheckPointReplicationSlots(bool is_shutdown)
 			continue;
 
 		/* save the slot to disk, locking is handled in SaveSlotToPath() */
-		sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(s->data.name));
+		sprintf(path, "%s/%s", REPLSLOT_DIR_ARGS(NameStr(s->data.name)));
 
 		/*
 		 * Slot's data is not flushed each time the confirmed_flush LSN is
@@ -1932,7 +1932,7 @@ StartupReplicationSlots(void)
 			strcmp(replication_de->d_name, "..") == 0)
 			continue;
 
-		snprintf(path, sizeof(path), "%s/%s", PG_REPLSLOT_DIR, replication_de->d_name);
+		snprintf(path, sizeof(path), "%s/%s", REPLSLOT_DIR_ARGS(replication_de->d_name));
 		de_type = get_dirent_type(path, replication_de, false, DEBUG1);
 
 		/* we're only creating directories here, skip if it's not our's */
@@ -1987,8 +1987,8 @@ CreateSlotOnDisk(ReplicationSlot *slot)
 	 * takes out the lock, if we'd take the lock here, we'd deadlock.
 	 */
 
-	sprintf(path, "%s/%s", PG_REPLSLOT_DIR, NameStr(slot->data.name));
-	sprintf(tmppath, "%s/%s.tmp", PG_REPLSLOT_DIR, NameStr(slot->data.name));
+	sprintf(path, "%s/%s", REPLSLOT_DIR_ARGS(NameStr(slot->data.name)));
+	sprintf(tmppath, "%s/%s.tmp", REPLSLOT_DIR_ARGS(NameStr(slot->data.name)));
 
 	/*
 	 * It's just barely possible that some previous effort to create or drop a
@@ -2205,7 +2205,7 @@ RestoreSlotFromDisk(const char *name)
 	/* no need to lock here, no concurrent access allowed yet */
 
 	/* delete temp file if it exists */
-	sprintf(slotdir, "%s/%s", PG_REPLSLOT_DIR, name);
+	sprintf(slotdir, "%s/%s", REPLSLOT_DIR_ARGS(name));
 	sprintf(path, "%s/state.tmp", slotdir);
 	if (unlink(path) < 0 && errno != ENOENT)
 		ereport(PANIC,
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index d95683d041..82d68b0caa 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -728,7 +728,7 @@ pg_ls_replslotdir(PG_FUNCTION_ARGS)
 				 errmsg("replication slot \"%s\" does not exist",
 						slotname)));
 
-	snprintf(path, sizeof(path), "%s/%s", PG_REPLSLOT_DIR, slotname);
+	snprintf(path, sizeof(path), "%s/%s", REPLSLOT_DIR_ARGS(slotname));
 
 	return pg_ls_dir_files(fcinfo, path, false);
 }
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index 9665faac1c..150e3a228c 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -18,6 +18,7 @@
 #include "replication/walreceiver.h"
 
 #define PG_REPLSLOT_DIR     "pg_replslot"
+#define REPLSLOT_DIR_ARGS(slotname) (PG_REPLSLOT_DIR), (slotname)
 
 /*
  * Behaviour of replication slots, upon release or crash.
-- 
2.34.1

>From 5ae8849d4bb81e9141a7bd7dd8fda39de18442b2 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot...@gmail.com>
Date: Mon, 19 Aug 2024 09:30:16 +0000
Subject: [PATCH v3 3/6] Define PG_LOGICAL_MAPPINGS_DIR

Replace most of the places where "pg_logical/mappings" is used in .c files with
a new PG_LOGICAL_MAPPINGS_DIR define. The places where it is not done is for
consistency with the existing PG_STAT_TMP_DIR define.
---
 src/backend/access/heap/rewriteheap.c          | 18 +++++++++---------
 .../replication/logical/reorderbuffer.c        |  6 +++---
 src/backend/utils/adt/genfile.c                |  2 +-
 src/include/replication/reorderbuffer.h        |  2 ++
 4 files changed, 15 insertions(+), 13 deletions(-)
  63.2% src/backend/access/heap/
  24.4% src/backend/replication/logical/
   8.5% src/backend/utils/adt/
   3.6% src/include/replication/

diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 473f3aa9be..09ef220449 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -961,8 +961,8 @@ logical_rewrite_log_mapping(RewriteState state, TransactionId xid,
 			dboid = MyDatabaseId;
 
 		snprintf(path, MAXPGPATH,
-				 "pg_logical/mappings/" LOGICAL_REWRITE_FORMAT,
-				 dboid, relid,
+				 "%s/" LOGICAL_REWRITE_FORMAT,
+				 PG_LOGICAL_MAPPINGS_DIR, dboid, relid,
 				 LSN_FORMAT_ARGS(state->rs_begin_lsn),
 				 xid, GetCurrentTransactionId());
 
@@ -1081,8 +1081,8 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
 	xlrec = (xl_heap_rewrite_mapping *) XLogRecGetData(r);
 
 	snprintf(path, MAXPGPATH,
-			 "pg_logical/mappings/" LOGICAL_REWRITE_FORMAT,
-			 xlrec->mapped_db, xlrec->mapped_rel,
+			 "%s/" LOGICAL_REWRITE_FORMAT,
+			 PG_LOGICAL_MAPPINGS_DIR, xlrec->mapped_db, xlrec->mapped_rel,
 			 LSN_FORMAT_ARGS(xlrec->start_lsn),
 			 xlrec->mapped_xid, XLogRecGetXid(r));
 
@@ -1158,7 +1158,7 @@ CheckPointLogicalRewriteHeap(void)
 	XLogRecPtr	redo;
 	DIR		   *mappings_dir;
 	struct dirent *mapping_de;
-	char		path[MAXPGPATH + 20];
+	char		path[MAXPGPATH + sizeof(PG_LOGICAL_MAPPINGS_DIR)];
 
 	/*
 	 * We start of with a minimum of the last redo pointer. No new decoding
@@ -1173,8 +1173,8 @@ CheckPointLogicalRewriteHeap(void)
 	if (cutoff != InvalidXLogRecPtr && redo < cutoff)
 		cutoff = redo;
 
-	mappings_dir = AllocateDir("pg_logical/mappings");
-	while ((mapping_de = ReadDir(mappings_dir, "pg_logical/mappings")) != NULL)
+	mappings_dir = AllocateDir(PG_LOGICAL_MAPPINGS_DIR);
+	while ((mapping_de = ReadDir(mappings_dir, PG_LOGICAL_MAPPINGS_DIR)) != NULL)
 	{
 		Oid			dboid;
 		Oid			relid;
@@ -1189,7 +1189,7 @@ CheckPointLogicalRewriteHeap(void)
 			strcmp(mapping_de->d_name, "..") == 0)
 			continue;
 
-		snprintf(path, sizeof(path), "pg_logical/mappings/%s", mapping_de->d_name);
+		snprintf(path, sizeof(path), "%s/%s", PG_LOGICAL_MAPPINGS_DIR, mapping_de->d_name);
 		de_type = get_dirent_type(path, mapping_de, false, DEBUG1);
 
 		if (de_type != PGFILETYPE_ERROR && de_type != PGFILETYPE_REG)
@@ -1249,5 +1249,5 @@ CheckPointLogicalRewriteHeap(void)
 	FreeDir(mappings_dir);
 
 	/* persist directory entries to disk */
-	fsync_fname("pg_logical/mappings", true);
+	fsync_fname(PG_LOGICAL_MAPPINGS_DIR, true);
 }
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index e4c2851c57..75fb6ef61a 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -5056,7 +5056,7 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, Oid relid, const char *fname)
 	int			readBytes;
 	LogicalRewriteMappingData map;
 
-	sprintf(path, "pg_logical/mappings/%s", fname);
+	sprintf(path, "%s/%s", PG_LOGICAL_MAPPINGS_DIR, fname);
 	fd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
 	if (fd < 0)
 		ereport(ERROR,
@@ -5172,8 +5172,8 @@ UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, Snapshot snapshot)
 	ListCell   *file;
 	Oid			dboid = IsSharedRelation(relid) ? InvalidOid : MyDatabaseId;
 
-	mapping_dir = AllocateDir("pg_logical/mappings");
-	while ((mapping_de = ReadDir(mapping_dir, "pg_logical/mappings")) != NULL)
+	mapping_dir = AllocateDir(PG_LOGICAL_MAPPINGS_DIR);
+	while ((mapping_de = ReadDir(mapping_dir, PG_LOGICAL_MAPPINGS_DIR)) != NULL)
 	{
 		Oid			f_dboid;
 		Oid			f_relid;
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 82d68b0caa..625b966b6a 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -704,7 +704,7 @@ pg_ls_logicalsnapdir(PG_FUNCTION_ARGS)
 Datum
 pg_ls_logicalmapdir(PG_FUNCTION_ARGS)
 {
-	return pg_ls_dir_files(fcinfo, "pg_logical/mappings", false);
+	return pg_ls_dir_files(fcinfo, PG_LOGICAL_MAPPINGS_DIR, false);
 }
 
 /*
diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h
index 851a001c8b..bf3b8010f6 100644
--- a/src/include/replication/reorderbuffer.h
+++ b/src/include/replication/reorderbuffer.h
@@ -18,6 +18,8 @@
 #include "utils/snapshot.h"
 #include "utils/timestamp.h"
 
+#define PG_LOGICAL_MAPPINGS_DIR "pg_logical/mappings"
+
 /* GUC variables */
 extern PGDLLIMPORT int logical_decoding_work_mem;
 extern PGDLLIMPORT int debug_logical_replication_streaming;
-- 
2.34.1

>From d2781a8eff5f0311c7ac6bcb617b92c3f7989d3e Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot...@gmail.com>
Date: Mon, 19 Aug 2024 09:42:40 +0000
Subject: [PATCH v3 4/6] Define PG_LOGICAL_SNAPSHOTS_DIR

Replace most of the places where "pg_logical/snapshots" is used in .c files with
a new PG_LOGICAL_SNAPSHOTS_DIR define. The places where it is not done is for
consistency with the existing PG_STAT_TMP_DIR define.
---
 src/backend/replication/logical/snapbuild.c | 28 ++++++++++++---------
 src/backend/utils/adt/genfile.c             |  2 +-
 src/include/replication/reorderbuffer.h     |  1 +
 3 files changed, 18 insertions(+), 13 deletions(-)
  87.6% src/backend/replication/logical/
   8.6% src/backend/utils/adt/
   3.7% src/include/replication/

diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index ae676145e6..0450f94ba8 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1654,7 +1654,8 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 	 * unless the user used pg_resetwal or similar. If a user did so, there's
 	 * no hope continuing to decode anyway.
 	 */
-	sprintf(path, "pg_logical/snapshots/%X-%X.snap",
+	sprintf(path, "%s/%X-%X.snap",
+			PG_LOGICAL_SNAPSHOTS_DIR,
 			LSN_FORMAT_ARGS(lsn));
 
 	/*
@@ -1681,7 +1682,7 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 		 * be safely on disk.
 		 */
 		fsync_fname(path, false);
-		fsync_fname("pg_logical/snapshots", true);
+		fsync_fname(PG_LOGICAL_SNAPSHOTS_DIR, true);
 
 		builder->last_serialized_snapshot = lsn;
 		goto out;
@@ -1697,7 +1698,8 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 	elog(DEBUG1, "serializing snapshot to %s", path);
 
 	/* to make sure only we will write to this tempfile, include pid */
-	sprintf(tmppath, "pg_logical/snapshots/%X-%X.snap.%d.tmp",
+	sprintf(tmppath, "%s/%X-%X.snap.%d.tmp",
+			PG_LOGICAL_SNAPSHOTS_DIR,
 			LSN_FORMAT_ARGS(lsn), MyProcPid);
 
 	/*
@@ -1818,7 +1820,7 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 				(errcode_for_file_access(),
 				 errmsg("could not close file \"%s\": %m", tmppath)));
 
-	fsync_fname("pg_logical/snapshots", true);
+	fsync_fname(PG_LOGICAL_SNAPSHOTS_DIR, true);
 
 	/*
 	 * We may overwrite the work from some other backend, but that's ok, our
@@ -1834,7 +1836,7 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 
 	/* make sure we persist */
 	fsync_fname(path, false);
-	fsync_fname("pg_logical/snapshots", true);
+	fsync_fname(PG_LOGICAL_SNAPSHOTS_DIR, true);
 
 	/*
 	 * Now there's no way we can lose the dumped state anymore, remember this
@@ -1871,7 +1873,8 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 	if (builder->state == SNAPBUILD_CONSISTENT)
 		return false;
 
-	sprintf(path, "pg_logical/snapshots/%X-%X.snap",
+	sprintf(path, "%s/%X-%X.snap",
+			PG_LOGICAL_SNAPSHOTS_DIR,
 			LSN_FORMAT_ARGS(lsn));
 
 	fd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
@@ -1892,7 +1895,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 	 * ----
 	 */
 	fsync_fname(path, false);
-	fsync_fname("pg_logical/snapshots", true);
+	fsync_fname(PG_LOGICAL_SNAPSHOTS_DIR, true);
 
 
 	/* read statically sized portion of snapshot */
@@ -2074,7 +2077,7 @@ CheckPointSnapBuild(void)
 	XLogRecPtr	redo;
 	DIR		   *snap_dir;
 	struct dirent *snap_de;
-	char		path[MAXPGPATH + 21];
+	char		path[MAXPGPATH + sizeof(PG_LOGICAL_SNAPSHOTS_DIR)];
 
 	/*
 	 * We start off with a minimum of the last redo pointer. No new
@@ -2090,8 +2093,8 @@ CheckPointSnapBuild(void)
 	if (redo < cutoff)
 		cutoff = redo;
 
-	snap_dir = AllocateDir("pg_logical/snapshots");
-	while ((snap_de = ReadDir(snap_dir, "pg_logical/snapshots")) != NULL)
+	snap_dir = AllocateDir(PG_LOGICAL_SNAPSHOTS_DIR);
+	while ((snap_de = ReadDir(snap_dir, PG_LOGICAL_SNAPSHOTS_DIR)) != NULL)
 	{
 		uint32		hi;
 		uint32		lo;
@@ -2102,7 +2105,7 @@ CheckPointSnapBuild(void)
 			strcmp(snap_de->d_name, "..") == 0)
 			continue;
 
-		snprintf(path, sizeof(path), "pg_logical/snapshots/%s", snap_de->d_name);
+		snprintf(path, sizeof(path), "%s/%s", PG_LOGICAL_SNAPSHOTS_DIR, snap_de->d_name);
 		de_type = get_dirent_type(path, snap_de, false, DEBUG1);
 
 		if (de_type != PGFILETYPE_ERROR && de_type != PGFILETYPE_REG)
@@ -2162,7 +2165,8 @@ SnapBuildSnapshotExists(XLogRecPtr lsn)
 	int			ret;
 	struct stat stat_buf;
 
-	sprintf(path, "pg_logical/snapshots/%X-%X.snap",
+	sprintf(path, "%s/%X-%X.snap",
+			PG_LOGICAL_SNAPSHOTS_DIR,
 			LSN_FORMAT_ARGS(lsn));
 
 	ret = stat(path, &stat_buf);
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 625b966b6a..a480e35693 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -695,7 +695,7 @@ pg_ls_archive_statusdir(PG_FUNCTION_ARGS)
 Datum
 pg_ls_logicalsnapdir(PG_FUNCTION_ARGS)
 {
-	return pg_ls_dir_files(fcinfo, "pg_logical/snapshots", false);
+	return pg_ls_dir_files(fcinfo, PG_LOGICAL_SNAPSHOTS_DIR, false);
 }
 
 /*
diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h
index bf3b8010f6..60a30763c9 100644
--- a/src/include/replication/reorderbuffer.h
+++ b/src/include/replication/reorderbuffer.h
@@ -19,6 +19,7 @@
 #include "utils/timestamp.h"
 
 #define PG_LOGICAL_MAPPINGS_DIR "pg_logical/mappings"
+#define PG_LOGICAL_SNAPSHOTS_DIR "pg_logical/snapshots"
 
 /* GUC variables */
 extern PGDLLIMPORT int logical_decoding_work_mem;
-- 
2.34.1

>From a67f92196998e1f27bcdedb955546e137ee4e8b6 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot...@gmail.com>
Date: Mon, 19 Aug 2024 09:53:03 +0000
Subject: [PATCH v3 5/6] Define PG_LOGICAL_REPLORIGIN_CHECKPOINT_DIR

Replace the places where "pg_logical/replorigin_checkpoint" is used in .c files
with a new PG_LOGICAL_REPLORIGIN_CHECKPOINT_DIR define.
---
 src/backend/replication/logical/origin.c | 6 +++---
 src/include/replication/origin.h         | 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)
  67.1% src/backend/replication/logical/
  32.8% src/include/replication/

diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 419e4814f0..a4aaefa97c 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -572,8 +572,8 @@ ReplicationOriginShmemInit(void)
 void
 CheckPointReplicationOrigin(void)
 {
-	const char *tmppath = "pg_logical/replorigin_checkpoint.tmp";
-	const char *path = "pg_logical/replorigin_checkpoint";
+	const char *tmppath = PG_LOGICAL_REPLORIGIN_CHECKPOINT_TMP_DIR;
+	const char *path = PG_LOGICAL_REPLORIGIN_CHECKPOINT_DIR;
 	int			tmpfd;
 	int			i;
 	uint32		magic = REPLICATION_STATE_MAGIC;
@@ -698,7 +698,7 @@ CheckPointReplicationOrigin(void)
 void
 StartupReplicationOrigin(void)
 {
-	const char *path = "pg_logical/replorigin_checkpoint";
+	const char *path = PG_LOGICAL_REPLORIGIN_CHECKPOINT_DIR;
 	int			fd;
 	int			readBytes;
 	uint32		magic = REPLICATION_STATE_MAGIC;
diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h
index 7189ba9e76..1cb44be58d 100644
--- a/src/include/replication/origin.h
+++ b/src/include/replication/origin.h
@@ -15,6 +15,9 @@
 #include "access/xlogreader.h"
 #include "catalog/pg_replication_origin.h"
 
+#define PG_LOGICAL_REPLORIGIN_CHECKPOINT_DIR "pg_logical/replorigin_checkpoint"
+#define PG_LOGICAL_REPLORIGIN_CHECKPOINT_TMP_DIR PG_LOGICAL_REPLORIGIN_CHECKPOINT_DIR ".tmp"
+
 typedef struct xl_replorigin_set
 {
 	XLogRecPtr	remote_lsn;
-- 
2.34.1

>From a30ab33122eb972b18c5f33dcf4b7feb7df2c433 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot...@gmail.com>
Date: Mon, 19 Aug 2024 07:40:10 +0000
Subject: [PATCH v3 6/6] Define PG_TBLSPC_DIR

Replace most of the places where "pg_tblspc" is used in .c files with a new
PG_TBLSPC_DIR define. The places where it is not done is for consistency with
the existing PG_STAT_TMP_DIR define.
---
 src/backend/access/transam/xlog.c           | 12 ++++-----
 src/backend/access/transam/xlogrecovery.c   | 14 +++++-----
 src/backend/backup/backup_manifest.c        |  3 ++-
 src/backend/backup/basebackup.c             |  6 ++---
 src/backend/commands/dbcommands.c           |  2 +-
 src/backend/commands/tablespace.c           |  4 +--
 src/backend/storage/file/fd.c               | 29 +++++++++++----------
 src/backend/storage/file/reinit.c           | 10 +++----
 src/backend/utils/adt/dbsize.c              |  8 +++---
 src/backend/utils/adt/misc.c                |  4 +--
 src/backend/utils/cache/relcache.c          |  4 +--
 src/bin/pg_checksums/pg_checksums.c         |  6 ++---
 src/bin/pg_combinebackup/pg_combinebackup.c | 18 ++++++-------
 src/bin/pg_rewind/file_ops.c                |  2 +-
 src/bin/pg_upgrade/exec.c                   |  2 +-
 src/common/file_utils.c                     |  3 ++-
 src/common/relpath.c                        | 20 +++++++-------
 src/fe_utils/astreamer_file.c               |  7 +++--
 src/include/common/relpath.h                |  8 ++++++
 19 files changed, 88 insertions(+), 74 deletions(-)
  14.9% src/backend/access/transam/
   6.4% src/backend/backup/
   4.3% src/backend/commands/
  25.8% src/backend/storage/file/
   8.5% src/backend/utils/adt/
   4.1% src/bin/pg_checksums/
  11.2% src/bin/pg_combinebackup/
  12.8% src/common/
   3.5% src/fe_utils/
   3.0% src/include/common/
   5.0% src/

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index ee0fb0e28f..4e06d86196 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8944,10 +8944,10 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
 		datadirpathlen = strlen(DataDir);
 
 		/* Collect information about all tablespaces */
-		tblspcdir = AllocateDir("pg_tblspc");
-		while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
+		tblspcdir = AllocateDir(PG_TBLSPC_DIR);
+		while ((de = ReadDir(tblspcdir, PG_TBLSPC_DIR)) != NULL)
 		{
-			char		fullpath[MAXPGPATH + 10];
+			char		fullpath[MAXPGPATH + sizeof(PG_TBLSPC_DIR)];
 			char		linkpath[MAXPGPATH];
 			char	   *relpath = NULL;
 			char	   *s;
@@ -8970,7 +8970,7 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
 			if (*badp != '\0' || errno == EINVAL || errno == ERANGE)
 				continue;
 
-			snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
+			snprintf(fullpath, sizeof(fullpath), "%s/%s", PG_TBLSPC_DIR, de->d_name);
 
 			de_type = get_dirent_type(fullpath, de, false, ERROR);
 
@@ -9031,8 +9031,8 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
 				 * In this case, we store a relative path rather than an
 				 * absolute path into the tablespaceinfo.
 				 */
-				snprintf(linkpath, sizeof(linkpath), "pg_tblspc/%s",
-						 de->d_name);
+				snprintf(linkpath, sizeof(linkpath), "%s/%s",
+						 PG_TBLSPC_DIR, de->d_name);
 				relpath = pstrdup(linkpath);
 			}
 			else
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index ad817fbca6..5d2755ef79 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -677,7 +677,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
 				tablespaceinfo *ti = lfirst(lc);
 				char	   *linkloc;
 
-				linkloc = psprintf("pg_tblspc/%u", ti->oid);
+				linkloc = psprintf("%s/%u", PG_TBLSPC_DIR, ti->oid);
 
 				/*
 				 * Remove the existing symlink if any and Create the symlink
@@ -2157,23 +2157,23 @@ CheckTablespaceDirectory(void)
 	DIR		   *dir;
 	struct dirent *de;
 
-	dir = AllocateDir("pg_tblspc");
-	while ((de = ReadDir(dir, "pg_tblspc")) != NULL)
+	dir = AllocateDir(PG_TBLSPC_DIR);
+	while ((de = ReadDir(dir, PG_TBLSPC_DIR)) != NULL)
 	{
-		char		path[MAXPGPATH + 10];
+		char		path[MAXPGPATH + sizeof(PG_TBLSPC_DIR)];
 
 		/* Skip entries of non-oid names */
 		if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
 			continue;
 
-		snprintf(path, sizeof(path), "pg_tblspc/%s", de->d_name);
+		snprintf(path, sizeof(path), "%s/%s", PG_TBLSPC_DIR, de->d_name);
 
 		if (get_dirent_type(path, de, false, ERROR) != PGFILETYPE_LNK)
 			ereport(allow_in_place_tablespaces ? WARNING : PANIC,
 					(errcode(ERRCODE_DATA_CORRUPTED),
 					 errmsg("unexpected directory entry \"%s\" found in %s",
-							de->d_name, "pg_tblspc/"),
-					 errdetail("All directory entries in pg_tblspc/ should be symbolic links."),
+							de->d_name, PG_TBLSPC_DIR),
+					 errdetail("All directory entries in %s/ should be symbolic links.", PG_TBLSPC_DIR),
 					 errhint("Remove those directories, or set \"allow_in_place_tablespaces\" to ON transiently to let recovery complete.")));
 	}
 }
diff --git a/src/backend/backup/backup_manifest.c b/src/backend/backup/backup_manifest.c
index 4357cfa31d..a2e2f86332 100644
--- a/src/backend/backup/backup_manifest.c
+++ b/src/backend/backup/backup_manifest.c
@@ -16,6 +16,7 @@
 #include "access/xlog.h"
 #include "backup/backup_manifest.h"
 #include "backup/basebackup_sink.h"
+#include "common/relpath.h"
 #include "mb/pg_wchar.h"
 #include "utils/builtins.h"
 #include "utils/json.h"
@@ -117,7 +118,7 @@ AddFileToBackupManifest(backup_manifest_info *manifest, Oid spcoid,
 	 */
 	if (OidIsValid(spcoid))
 	{
-		snprintf(pathbuf, sizeof(pathbuf), "pg_tblspc/%u/%s", spcoid,
+		snprintf(pathbuf, sizeof(pathbuf), "%s/%u/%s", PG_TBLSPC_DIR, spcoid,
 				 pathname);
 		pathname = pathbuf;
 	}
diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c
index de16afac74..15805ce90e 100644
--- a/src/backend/backup/basebackup.c
+++ b/src/backend/backup/basebackup.c
@@ -1406,7 +1406,7 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
 		}
 
 		/* Allow symbolic links in pg_tblspc only */
-		if (strcmp(path, "./pg_tblspc") == 0 && S_ISLNK(statbuf.st_mode))
+		if (strcmp(path, RELATIVE_PG_TBLSPC_DIR) == 0 && S_ISLNK(statbuf.st_mode))
 		{
 			char		linkpath[MAXPGPATH];
 			int			rllen;
@@ -1464,7 +1464,7 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
 			/*
 			 * skip sending directories inside pg_tblspc, if not required.
 			 */
-			if (strcmp(pathbuf, "./pg_tblspc") == 0 && !sendtblspclinks)
+			if (strcmp(pathbuf, RELATIVE_PG_TBLSPC_DIR) == 0 && !sendtblspclinks)
 				skip_this_dir = true;
 
 			if (!skip_this_dir)
@@ -1488,7 +1488,7 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
 				if (OidIsValid(spcoid))
 				{
 					relspcoid = spcoid;
-					lookup_path = psprintf("pg_tblspc/%u/%s", spcoid,
+					lookup_path = psprintf("%s/%u/%s", PG_TBLSPC_DIR, spcoid,
 										   tarfilename);
 				}
 				else
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index d00ae40e19..8be435a79e 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -3257,7 +3257,7 @@ recovery_create_dbdir(char *path, bool only_tblspc)
 	if (stat(path, &st) == 0)
 		return;
 
-	if (only_tblspc && strstr(path, "pg_tblspc/") == NULL)
+	if (only_tblspc && strstr(path, PG_TBLSPC_DIR_SLASH) == NULL)
 		elog(PANIC, "requested to created invalid directory: %s", path);
 
 	if (reachedConsistency && !allow_in_place_tablespaces)
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 113b480731..00c1ed19fd 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -576,7 +576,7 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid)
 	struct stat st;
 	bool		in_place;
 
-	linkloc = psprintf("pg_tblspc/%u", tablespaceoid);
+	linkloc = psprintf("%s/%u", PG_TBLSPC_DIR, tablespaceoid);
 
 	/*
 	 * If we're asked to make an 'in place' tablespace, create the directory
@@ -692,7 +692,7 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
 	char	   *subfile;
 	struct stat st;
 
-	linkloc_with_version_dir = psprintf("pg_tblspc/%u/%s", tablespaceoid,
+	linkloc_with_version_dir = psprintf("%s/%u/%s", PG_TBLSPC_DIR, tablespaceoid,
 										TABLESPACE_VERSION_DIRECTORY);
 
 	/*
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 3944321ff3..db24343bf9 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -1790,8 +1790,8 @@ TempTablespacePath(char *path, Oid tablespace)
 	else
 	{
 		/* All other tablespaces are accessed via symlinks */
-		snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
-				 tablespace, TABLESPACE_VERSION_DIRECTORY,
+		snprintf(path, MAXPGPATH, "%s/%u/%s/%s",
+				 PG_TBLSPC_DIR, tablespace, TABLESPACE_VERSION_DIRECTORY,
 				 PG_TEMP_FILES_DIR);
 	}
 }
@@ -3273,7 +3273,7 @@ CleanupTempFiles(bool isCommit, bool isProcExit)
 void
 RemovePgTempFiles(void)
 {
-	char		temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
+	char		temp_path[MAXPGPATH + sizeof(PG_TBLSPC_DIR) + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
 	DIR		   *spc_dir;
 	struct dirent *spc_de;
 
@@ -3287,20 +3287,21 @@ RemovePgTempFiles(void)
 	/*
 	 * Cycle through temp directories for all non-default tablespaces.
 	 */
-	spc_dir = AllocateDir("pg_tblspc");
+	spc_dir = AllocateDir(PG_TBLSPC_DIR);
 
-	while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
+	while ((spc_de = ReadDirExtended(spc_dir, PG_TBLSPC_DIR, LOG)) != NULL)
 	{
 		if (strcmp(spc_de->d_name, ".") == 0 ||
 			strcmp(spc_de->d_name, "..") == 0)
 			continue;
 
-		snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
-				 spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR);
+		snprintf(temp_path, sizeof(temp_path), "%s/%s/%s/%s",
+				 PG_TBLSPC_DIR, spc_de->d_name, TABLESPACE_VERSION_DIRECTORY,
+				 PG_TEMP_FILES_DIR);
 		RemovePgTempFilesInDir(temp_path, true, false);
 
-		snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
-				 spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
+		snprintf(temp_path, sizeof(temp_path), "%s/%s/%s",
+				 PG_TBLSPC_DIR, spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
 		RemovePgTempRelationFiles(temp_path);
 	}
 
@@ -3587,15 +3588,15 @@ SyncDataDirectory(void)
 		/* Sync the top level pgdata directory. */
 		do_syncfs(".");
 		/* If any tablespaces are configured, sync each of those. */
-		dir = AllocateDir("pg_tblspc");
-		while ((de = ReadDirExtended(dir, "pg_tblspc", LOG)))
+		dir = AllocateDir(PG_TBLSPC_DIR);
+		while ((de = ReadDirExtended(dir, PG_TBLSPC_DIR, LOG)))
 		{
 			char		path[MAXPGPATH];
 
 			if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
 				continue;
 
-			snprintf(path, MAXPGPATH, "pg_tblspc/%s", de->d_name);
+			snprintf(path, MAXPGPATH, "%s/%s", PG_TBLSPC_DIR, de->d_name);
 			do_syncfs(path);
 		}
 		FreeDir(dir);
@@ -3618,7 +3619,7 @@ SyncDataDirectory(void)
 	walkdir(".", pre_sync_fname, false, DEBUG1);
 	if (xlog_is_symlink)
 		walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
-	walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
+	walkdir(PG_TBLSPC_DIR, pre_sync_fname, true, DEBUG1);
 #endif
 
 	/* Prepare to report progress syncing the data directory via fsync. */
@@ -3636,7 +3637,7 @@ SyncDataDirectory(void)
 	walkdir(".", datadir_fsync_fname, false, LOG);
 	if (xlog_is_symlink)
 		walkdir("pg_wal", datadir_fsync_fname, false, LOG);
-	walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
+	walkdir(PG_TBLSPC_DIR, datadir_fsync_fname, true, LOG);
 }
 
 /*
diff --git a/src/backend/storage/file/reinit.c b/src/backend/storage/file/reinit.c
index f1cd1a38d9..01e267abf9 100644
--- a/src/backend/storage/file/reinit.c
+++ b/src/backend/storage/file/reinit.c
@@ -46,7 +46,7 @@ typedef struct
 void
 ResetUnloggedRelations(int op)
 {
-	char		temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY)];
+	char		temp_path[MAXPGPATH + sizeof(PG_TBLSPC_DIR) + sizeof(TABLESPACE_VERSION_DIRECTORY)];
 	DIR		   *spc_dir;
 	struct dirent *spc_de;
 	MemoryContext tmpctx,
@@ -77,16 +77,16 @@ ResetUnloggedRelations(int op)
 	/*
 	 * Cycle through directories for all non-default tablespaces.
 	 */
-	spc_dir = AllocateDir("pg_tblspc");
+	spc_dir = AllocateDir(PG_TBLSPC_DIR);
 
-	while ((spc_de = ReadDir(spc_dir, "pg_tblspc")) != NULL)
+	while ((spc_de = ReadDir(spc_dir, PG_TBLSPC_DIR)) != NULL)
 	{
 		if (strcmp(spc_de->d_name, ".") == 0 ||
 			strcmp(spc_de->d_name, "..") == 0)
 			continue;
 
-		snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
-				 spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
+		snprintf(temp_path, sizeof(temp_path), "%s/%s/%s",
+				 PG_TBLSPC_DIR, spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
 		ResetUnloggedRelationsInTablespaceDir(temp_path, op);
 	}
 
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index b2d9cc2792..e63e99c141 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -143,7 +143,7 @@ calculate_database_size(Oid dbOid)
 	totalsize = db_dir_size(pathname);
 
 	/* Scan the non-default tablespaces */
-	snprintf(dirpath, MAXPGPATH, "pg_tblspc");
+	snprintf(dirpath, MAXPGPATH, PG_TBLSPC_DIR);
 	dirdesc = AllocateDir(dirpath);
 
 	while ((direntry = ReadDir(dirdesc, dirpath)) != NULL)
@@ -154,8 +154,8 @@ calculate_database_size(Oid dbOid)
 			strcmp(direntry->d_name, "..") == 0)
 			continue;
 
-		snprintf(pathname, sizeof(pathname), "pg_tblspc/%s/%s/%u",
-				 direntry->d_name, TABLESPACE_VERSION_DIRECTORY, dbOid);
+		snprintf(pathname, sizeof(pathname), "%s/%s/%s/%u",
+				 PG_TBLSPC_DIR, direntry->d_name, TABLESPACE_VERSION_DIRECTORY, dbOid);
 		totalsize += db_dir_size(pathname);
 	}
 
@@ -227,7 +227,7 @@ calculate_tablespace_size(Oid tblspcOid)
 	else if (tblspcOid == GLOBALTABLESPACE_OID)
 		snprintf(tblspcPath, MAXPGPATH, "global");
 	else
-		snprintf(tblspcPath, MAXPGPATH, "pg_tblspc/%u/%s", tblspcOid,
+		snprintf(tblspcPath, MAXPGPATH, "%s/%u/%s", PG_TBLSPC_DIR, tblspcOid,
 				 TABLESPACE_VERSION_DIRECTORY);
 
 	dirdesc = AllocateDir(tblspcPath);
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 0e6c45807a..1aa8bbb306 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -242,7 +242,7 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
 	if (tablespaceOid == DEFAULTTABLESPACE_OID)
 		location = "base";
 	else
-		location = psprintf("pg_tblspc/%u/%s", tablespaceOid,
+		location = psprintf("%s/%u/%s", PG_TBLSPC_DIR, tablespaceOid,
 							TABLESPACE_VERSION_DIRECTORY);
 
 	dirdesc = AllocateDir(location);
@@ -325,7 +325,7 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
 	 * Find the location of the tablespace by reading the symbolic link that
 	 * is in pg_tblspc/<oid>.
 	 */
-	snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid);
+	snprintf(sourcepath, sizeof(sourcepath), "%s/%u", PG_TBLSPC_DIR, tablespaceOid);
 
 	/*
 	 * Before reading the link, check if the source path is a link or a
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 66ed24e401..63efc55f09 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -6800,10 +6800,10 @@ RelationCacheInitFilePostInvalidate(void)
 void
 RelationCacheInitFileRemove(void)
 {
-	const char *tblspcdir = "pg_tblspc";
+	const char *tblspcdir = PG_TBLSPC_DIR;
 	DIR		   *dir;
 	struct dirent *de;
-	char		path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY)];
+	char		path[MAXPGPATH + sizeof(PG_TBLSPC_DIR) + sizeof(TABLESPACE_VERSION_DIRECTORY)];
 
 	snprintf(path, sizeof(path), "global/%s",
 			 RELCACHE_INIT_FILENAME);
diff --git a/src/bin/pg_checksums/pg_checksums.c b/src/bin/pg_checksums/pg_checksums.c
index b5bb0e7887..68a68eb0fa 100644
--- a/src/bin/pg_checksums/pg_checksums.c
+++ b/src/bin/pg_checksums/pg_checksums.c
@@ -388,7 +388,7 @@ scan_directory(const char *basedir, const char *subdir, bool sizeonly)
 			 * is valid, resolving the linked locations and dive into them
 			 * directly.
 			 */
-			if (strncmp("pg_tblspc", subdir, strlen("pg_tblspc")) == 0)
+			if (strncmp(PG_TBLSPC_DIR, subdir, strlen(PG_TBLSPC_DIR)) == 0)
 			{
 				char		tblspc_path[MAXPGPATH];
 				struct stat tblspc_st;
@@ -593,12 +593,12 @@ main(int argc, char *argv[])
 		{
 			total_size = scan_directory(DataDir, "global", true);
 			total_size += scan_directory(DataDir, "base", true);
-			total_size += scan_directory(DataDir, "pg_tblspc", true);
+			total_size += scan_directory(DataDir, PG_TBLSPC_DIR, true);
 		}
 
 		(void) scan_directory(DataDir, "global", false);
 		(void) scan_directory(DataDir, "base", false);
-		(void) scan_directory(DataDir, "pg_tblspc", false);
+		(void) scan_directory(DataDir, PG_TBLSPC_DIR, false);
 
 		if (showprogress)
 			progress_report(true);
diff --git a/src/bin/pg_combinebackup/pg_combinebackup.c b/src/bin/pg_combinebackup/pg_combinebackup.c
index 9ded5a2140..61a97dd206 100644
--- a/src/bin/pg_combinebackup/pg_combinebackup.c
+++ b/src/bin/pg_combinebackup/pg_combinebackup.c
@@ -373,7 +373,7 @@ main(int argc, char *argv[])
 		{
 			char		linkpath[MAXPGPATH];
 
-			snprintf(linkpath, MAXPGPATH, "%s/pg_tblspc/%u", opt.output,
+			snprintf(linkpath, MAXPGPATH, "%s/%s/%u", opt.output, PG_TBLSPC_DIR,
 					 ts->oid);
 
 			if (opt.dry_run)
@@ -867,12 +867,12 @@ process_directory_recursively(Oid tsoid,
 		is_incremental_dir = true;
 	else if (relative_path != NULL)
 	{
-		is_pg_tblspc = strcmp(relative_path, "pg_tblspc") == 0;
+		is_pg_tblspc = strcmp(relative_path, PG_TBLSPC_DIR) == 0;
 		is_pg_wal = (strcmp(relative_path, "pg_wal") == 0 ||
 					 strncmp(relative_path, "pg_wal/", 7) == 0);
 		is_incremental_dir = strncmp(relative_path, "base/", 5) == 0 ||
 			strcmp(relative_path, "global") == 0 ||
-			strncmp(relative_path, "pg_tblspc/", 10) == 0;
+			strncmp(relative_path, PG_TBLSPC_DIR_SLASH, 10) == 0;
 	}
 
 	/*
@@ -895,7 +895,7 @@ process_directory_recursively(Oid tsoid,
 		strlcpy(ifulldir, input_directory, MAXPGPATH);
 		strlcpy(ofulldir, output_directory, MAXPGPATH);
 		if (OidIsValid(tsoid))
-			snprintf(manifest_prefix, MAXPGPATH, "pg_tblspc/%u/", tsoid);
+			snprintf(manifest_prefix, MAXPGPATH, "%s/%u/", PG_TBLSPC_DIR, tsoid);
 		else
 			manifest_prefix[0] = '\0';
 	}
@@ -906,8 +906,8 @@ process_directory_recursively(Oid tsoid,
 		snprintf(ofulldir, MAXPGPATH, "%s/%s", output_directory,
 				 relative_path);
 		if (OidIsValid(tsoid))
-			snprintf(manifest_prefix, MAXPGPATH, "pg_tblspc/%u/%s/",
-					 tsoid, relative_path);
+			snprintf(manifest_prefix, MAXPGPATH, "%s/%u/%s/",
+					 PG_TBLSPC_DIR, tsoid, relative_path);
 		else
 			snprintf(manifest_prefix, MAXPGPATH, "%s/", relative_path);
 	}
@@ -1249,7 +1249,7 @@ scan_for_existing_tablespaces(char *pathname, cb_options *opt)
 	struct dirent *de;
 	cb_tablespace *tslist = NULL;
 
-	snprintf(pg_tblspc, MAXPGPATH, "%s/pg_tblspc", pathname);
+	snprintf(pg_tblspc, MAXPGPATH, "%s/%s", pathname, PG_TBLSPC_DIR);
 	pg_log_debug("scanning \"%s\"", pg_tblspc);
 
 	if ((dir = opendir(pg_tblspc)) == NULL)
@@ -1344,8 +1344,8 @@ scan_for_existing_tablespaces(char *pathname, cb_options *opt)
 			 * we just record the paths within the data directories.
 			 */
 			snprintf(ts->old_dir, MAXPGPATH, "%s/%s", pg_tblspc, de->d_name);
-			snprintf(ts->new_dir, MAXPGPATH, "%s/pg_tblspc/%s", opt->output,
-					 de->d_name);
+			snprintf(ts->new_dir, MAXPGPATH, "%s/%s/%s", opt->output,
+					 PG_TBLSPC_DIR, de->d_name);
 			ts->in_place = true;
 		}
 
diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c
index d93580bb41..67a86bb4c5 100644
--- a/src/bin/pg_rewind/file_ops.c
+++ b/src/bin/pg_rewind/file_ops.c
@@ -452,7 +452,7 @@ recurse_dir(const char *datadir, const char *parentpath,
 			 * to process all the tablespaces.  We also follow a symlink if
 			 * it's for pg_wal.  Symlinks elsewhere are ignored.
 			 */
-			if ((parentpath && strcmp(parentpath, "pg_tblspc") == 0) ||
+			if ((parentpath && strcmp(parentpath, PG_TBLSPC_DIR) == 0) ||
 				strcmp(path, "pg_wal") == 0)
 				recurse_dir(datadir, path, callback);
 		}
diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c
index 058530ab3e..78db321ace 100644
--- a/src/bin/pg_upgrade/exec.c
+++ b/src/bin/pg_upgrade/exec.c
@@ -350,7 +350,7 @@ check_data_dir(ClusterInfo *cluster)
 	check_single_dir(pg_data, "global");
 	check_single_dir(pg_data, "pg_multixact");
 	check_single_dir(pg_data, "pg_subtrans");
-	check_single_dir(pg_data, "pg_tblspc");
+	check_single_dir(pg_data, PG_TBLSPC_DIR);
 	check_single_dir(pg_data, "pg_twophase");
 
 	/* pg_xlog has been renamed to pg_wal in v10 */
diff --git a/src/common/file_utils.c b/src/common/file_utils.c
index 6bac537a1e..761873d519 100644
--- a/src/common/file_utils.c
+++ b/src/common/file_utils.c
@@ -25,6 +25,7 @@
 #include <unistd.h>
 
 #include "common/file_utils.h"
+#include "common/relpath.h"
 #ifdef FRONTEND
 #include "common/logging.h"
 #endif
@@ -105,7 +106,7 @@ sync_pgdata(const char *pg_data,
 	/* handle renaming of pg_xlog to pg_wal in post-10 clusters */
 	snprintf(pg_wal, MAXPGPATH, "%s/%s", pg_data,
 			 serverVersion < MINIMUM_VERSION_FOR_PG_WAL ? "pg_xlog" : "pg_wal");
-	snprintf(pg_tblspc, MAXPGPATH, "%s/pg_tblspc", pg_data);
+	snprintf(pg_tblspc, MAXPGPATH, "%s/%s", pg_data, PG_TBLSPC_DIR);
 
 	/*
 	 * If pg_wal is a symlink, we'll need to recurse into it separately,
diff --git a/src/common/relpath.c b/src/common/relpath.c
index f54c36ef7a..426a0114f8 100644
--- a/src/common/relpath.c
+++ b/src/common/relpath.c
@@ -123,8 +123,8 @@ GetDatabasePath(Oid dbOid, Oid spcOid)
 	else
 	{
 		/* All other tablespaces are accessed via symlinks */
-		return psprintf("pg_tblspc/%u/%s/%u",
-						spcOid, TABLESPACE_VERSION_DIRECTORY, dbOid);
+		return psprintf("%s/%u/%s/%u",
+						PG_TBLSPC_DIR, spcOid, TABLESPACE_VERSION_DIRECTORY, dbOid);
 	}
 }
 
@@ -184,25 +184,25 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
 		if (procNumber == INVALID_PROC_NUMBER)
 		{
 			if (forkNumber != MAIN_FORKNUM)
-				path = psprintf("pg_tblspc/%u/%s/%u/%u_%s",
-								spcOid, TABLESPACE_VERSION_DIRECTORY,
+				path = psprintf("%s/%u/%s/%u/%u_%s",
+								PG_TBLSPC_DIR, spcOid, TABLESPACE_VERSION_DIRECTORY,
 								dbOid, relNumber,
 								forkNames[forkNumber]);
 			else
-				path = psprintf("pg_tblspc/%u/%s/%u/%u",
-								spcOid, TABLESPACE_VERSION_DIRECTORY,
+				path = psprintf("%s/%u/%s/%u/%u",
+								PG_TBLSPC_DIR, spcOid, TABLESPACE_VERSION_DIRECTORY,
 								dbOid, relNumber);
 		}
 		else
 		{
 			if (forkNumber != MAIN_FORKNUM)
-				path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
-								spcOid, TABLESPACE_VERSION_DIRECTORY,
+				path = psprintf("%s/%u/%s/%u/t%d_%u_%s",
+								PG_TBLSPC_DIR, spcOid, TABLESPACE_VERSION_DIRECTORY,
 								dbOid, procNumber, relNumber,
 								forkNames[forkNumber]);
 			else
-				path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
-								spcOid, TABLESPACE_VERSION_DIRECTORY,
+				path = psprintf("%s/%u/%s/%u/t%d_%u",
+								PG_TBLSPC_DIR, spcOid, TABLESPACE_VERSION_DIRECTORY,
 								dbOid, procNumber, relNumber);
 		}
 	}
diff --git a/src/fe_utils/astreamer_file.c b/src/fe_utils/astreamer_file.c
index c9a030853b..98fc36a033 100644
--- a/src/fe_utils/astreamer_file.c
+++ b/src/fe_utils/astreamer_file.c
@@ -19,6 +19,7 @@
 
 #include "common/file_perm.h"
 #include "common/logging.h"
+#include "common/relpath.h"
 #include "common/string.h"
 #include "fe_utils/astreamer.h"
 
@@ -295,23 +296,25 @@ astreamer_extractor_content(astreamer *streamer, astreamer_member *member,
 static bool
 should_allow_existing_directory(const char *pathname)
 {
+#define PG_TBLSPC_DIR_CONCAT "/" PG_TBLSPC_DIR "/"
 	const char *filename = last_dir_separator(pathname) + 1;
 
 	if (strcmp(filename, "pg_wal") == 0 ||
 		strcmp(filename, "pg_xlog") == 0 ||
 		strcmp(filename, "archive_status") == 0 ||
 		strcmp(filename, "summaries") == 0 ||
-		strcmp(filename, "pg_tblspc") == 0)
+		strcmp(filename, PG_TBLSPC_DIR) == 0)
 		return true;
 
 	if (strspn(filename, "0123456789") == strlen(filename))
 	{
-		const char *pg_tblspc = strstr(pathname, "/pg_tblspc/");
+		const char *pg_tblspc = strstr(pathname, PG_TBLSPC_DIR_CONCAT);
 
 		return pg_tblspc != NULL && pg_tblspc + 11 == filename;
 	}
 
 	return false;
+#undef PG_TBLSPC_DIR_CONCAT
 }
 
 /*
diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h
index 6f006d5a93..b0b463e9aa 100644
--- a/src/include/common/relpath.h
+++ b/src/include/common/relpath.h
@@ -33,6 +33,14 @@ typedef Oid RelFileNumber;
 #define TABLESPACE_VERSION_DIRECTORY	"PG_" PG_MAJORVERSION "_" \
 									CppAsString2(CATALOG_VERSION_NO)
 
+/*
+ * Don't change the value of those pg_tblspc related macros, as many tools
+ * probably rely on it.
+ */
+#define PG_TBLSPC_DIR "pg_tblspc"
+#define RELATIVE_PG_TBLSPC_DIR "./pg_tblspc"
+#define PG_TBLSPC_DIR_SLASH "pg_tblspc/" /* needed for strings manipulations */
+
 /* Characters to allow for an OID in a relation path */
 #define OIDCHARS		10		/* max chars printed by %u */
 
-- 
2.34.1

Reply via email to