From be9034622d4a1448f6a2810511e3156071e44b43 Mon Sep 17 00:00:00 2001
From: Rui Zhao <xiyuan.zr@alibaba-inc.com>
Date: Sat, 29 Jul 2023 22:49:42 +0800
Subject: [PATCH] Fix pg_upgrade with in-place tablespaces.

---
 src/backend/utils/adt/misc.c             | 3 ++-
 src/bin/pg_dump/pg_dumpall.c             | 4 ++++
 src/bin/pg_upgrade/t/002_pg_upgrade.pl   | 5 +++++
 src/bin/pg_upgrade/tablespace.c          | 4 +++-
 src/test/regress/expected/tablespace.out | 2 +-
 5 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 5d78d6dc06..baed55281b 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -341,8 +341,9 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
 						sourcepath)));
 	}
 
+	/* The path of the in-place tablespace is always pg_tblspc/<oid>. */
 	if (!S_ISLNK(st.st_mode))
-		PG_RETURN_TEXT_P(cstring_to_text(sourcepath));
+		PG_RETURN_TEXT_P(cstring_to_text(""));
 
 	/*
 	 * In presence of a link or a junction point, return the path pointing to.
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 2cad796d3f..63afb45d2c 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -1282,6 +1282,10 @@ dumpTablespaces(PGconn *conn)
 			appendPQExpBuffer(buf, "SELECT pg_catalog.binary_upgrade_set_next_pg_tablespace_oid('%u'::pg_catalog.oid);\n", spcoid);
 		}
 
+		/* Allow to create in-place tablespace. */
+		if (!is_absolute_path(spclocation))
+			appendPQExpBuffer(buf, "SET allow_in_place_tablespaces = true;\n");
+
 		appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
 		appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
 
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index a5688a1cf2..6011c1e02d 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -212,6 +212,11 @@ else
 	is($rc, 0, 'regression tests pass');
 }
 
+# Test with in-place tablespace
+$oldnode->append_conf('postgresql.conf', 'allow_in_place_tablespaces = on');
+$oldnode->reload;
+$oldnode->safe_psql('postgres', "CREATE TABLESPACE space_test LOCATION ''");
+
 # Initialize a new node for the upgrade.
 my $newnode = PostgreSQL::Test::Cluster->new('new_node');
 
diff --git a/src/bin/pg_upgrade/tablespace.c b/src/bin/pg_upgrade/tablespace.c
index 69cef7fa6b..f260d95f7d 100644
--- a/src/bin/pg_upgrade/tablespace.c
+++ b/src/bin/pg_upgrade/tablespace.c
@@ -45,11 +45,13 @@ get_tablespace_paths(void)
 	int			i_spclocation;
 	char		query[QUERY_ALLOC];
 
+	/* No need to check in-place tablespace. */
 	snprintf(query, sizeof(query),
 			 "SELECT pg_catalog.pg_tablespace_location(oid) AS spclocation "
 			 "FROM	pg_catalog.pg_tablespace "
 			 "WHERE	spcname != 'pg_default' AND "
-			 "		spcname != 'pg_global'");
+			 "		spcname != 'pg_global' AND "
+			 "		pg_catalog.pg_tablespace_location(oid) != ''");
 
 	res = executeQueryOrDie(conn, "%s", query);
 
diff --git a/src/test/regress/expected/tablespace.out b/src/test/regress/expected/tablespace.out
index 9aabb85349..9a19aac166 100644
--- a/src/test/regress/expected/tablespace.out
+++ b/src/test/regress/expected/tablespace.out
@@ -28,7 +28,7 @@ SELECT regexp_replace(pg_tablespace_location(oid), '(pg_tblspc)/(\d+)', '\1/NNN'
   FROM pg_tablespace  WHERE spcname = 'regress_tblspace';
  regexp_replace 
 ----------------
- pg_tblspc/NNN
+ 
 (1 row)
 
 -- try setting and resetting some properties for the new tablespace
-- 
2.32.0.3.g01195cf9f

