v3-0002-Introduce-GetRelationPathInPlace.patch
text/x-patch
Filename: v3-0002-Introduce-GetRelationPathInPlace.patch
Type: text/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 v3-0002
Subject: Introduce GetRelationPathInPlace().
| File | + | − |
|---|---|---|
| src/common/relpath.c | 45 | 12 |
| src/include/common/relpath.h | 3 | 0 |
From 1ca15dcd52fd77a70a596a944becb62a366e6cbe Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 6 Sep 2024 10:32:24 +1200
Subject: [PATCH v3 2/3] Introduce GetRelationPathInPlace().
This is like GetRelationPath(), but writes the result into a
caller-supplied buffer. This variant can be used in a critical section,
because it doesn't allocate memory.
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/18146-04e908c662113ad5%40postgresql.org
---
src/common/relpath.c | 57 ++++++++++++++++++++++++++++--------
src/include/common/relpath.h | 3 ++
2 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/src/common/relpath.c b/src/common/relpath.c
index 9f2e00e83e4..f880ea4d0ba 100644
--- a/src/common/relpath.c
+++ b/src/common/relpath.c
@@ -142,7 +142,32 @@ char *
GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
int procNumber, ForkNumber forkNumber)
{
- char *path;
+ char path[MAXPGPATH];
+ char *result;
+ size_t size;
+
+ size = GetRelationPathInPlace(path, dbOid, spcOid, relNumber, procNumber, forkNumber);
+
+ /* String plus NUL terminator. */
+ result = palloc(size + 1);
+ memcpy(result, path, size + 1);
+
+ return result;
+}
+
+/*
+ * GetRelationPathInPlace - construct path to a relation's file
+ *
+ * Result is written to path, which must have space for MAXPGPATH characters.
+ * The size of the string is returned. If it is >= MAXPGPATH, the path has
+ * been truncated due to lack of space.
+ */
+size_t
+GetRelationPathInPlace(char *path,
+ Oid dbOid, Oid spcOid, RelFileNumber relNumber,
+ int procNumber, ForkNumber forkNumber)
+{
+ size_t size;
if (spcOid == GLOBALTABLESPACE_OID)
{
@@ -150,10 +175,10 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
Assert(dbOid == 0);
Assert(procNumber == INVALID_PROC_NUMBER);
if (forkNumber != MAIN_FORKNUM)
- path = psprintf("global/%u_%s",
+ size = snprintf(path, MAXPGPATH, "global/%u_%s",
relNumber, forkNames[forkNumber]);
else
- path = psprintf("global/%u", relNumber);
+ size = snprintf(path, MAXPGPATH, "global/%u", relNumber);
}
else if (spcOid == DEFAULTTABLESPACE_OID)
{
@@ -161,21 +186,25 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
if (procNumber == INVALID_PROC_NUMBER)
{
if (forkNumber != MAIN_FORKNUM)
- path = psprintf("base/%u/%u_%s",
+ size = snprintf(path, MAXPGPATH,
+ "base/%u/%u_%s",
dbOid, relNumber,
forkNames[forkNumber]);
else
- path = psprintf("base/%u/%u",
+ size = snprintf(path, MAXPGPATH,
+ "base/%u/%u",
dbOid, relNumber);
}
else
{
if (forkNumber != MAIN_FORKNUM)
- path = psprintf("base/%u/t%d_%u_%s",
+ size = snprintf(path, MAXPGPATH,
+ "base/%u/t%d_%u_%s",
dbOid, procNumber, relNumber,
forkNames[forkNumber]);
else
- path = psprintf("base/%u/t%d_%u",
+ size = snprintf(path, MAXPGPATH,
+ "base/%u/t%d_%u",
dbOid, procNumber, relNumber);
}
}
@@ -185,13 +214,15 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
if (procNumber == INVALID_PROC_NUMBER)
{
if (forkNumber != MAIN_FORKNUM)
- path = psprintf("%s/%u/%s/%u/%u_%s",
+ size = snprintf(path, MAXPGPATH,
+ "%s/%u/%s/%u/%u_%s",
PG_TBLSPC_DIR, spcOid,
TABLESPACE_VERSION_DIRECTORY,
dbOid, relNumber,
forkNames[forkNumber]);
else
- path = psprintf("%s/%u/%s/%u/%u",
+ size = snprintf(path, MAXPGPATH,
+ "%s/%u/%s/%u/%u",
PG_TBLSPC_DIR, spcOid,
TABLESPACE_VERSION_DIRECTORY,
dbOid, relNumber);
@@ -199,17 +230,19 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
else
{
if (forkNumber != MAIN_FORKNUM)
- path = psprintf("%s/%u/%s/%u/t%d_%u_%s",
+ size = snprintf(path, MAXPGPATH,
+ "%s/%u/%s/%u/t%d_%u_%s",
PG_TBLSPC_DIR, spcOid,
TABLESPACE_VERSION_DIRECTORY,
dbOid, procNumber, relNumber,
forkNames[forkNumber]);
else
- path = psprintf("%s/%u/%s/%u/t%d_%u",
+ size = snprintf(path, MAXPGPATH,
+ "%s/%u/%s/%u/t%d_%u",
PG_TBLSPC_DIR, spcOid,
TABLESPACE_VERSION_DIRECTORY,
dbOid, procNumber, relNumber);
}
}
- return path;
+ return size;
}
diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h
index 2dabbe01ecd..ec21ecab9ee 100644
--- a/src/include/common/relpath.h
+++ b/src/include/common/relpath.h
@@ -84,6 +84,9 @@ extern char *GetDatabasePath(Oid dbOid, Oid spcOid);
extern char *GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
int procNumber, ForkNumber forkNumber);
+extern size_t GetRelationPathInPlace(char *path,
+ Oid dbOid, Oid spcOid, RelFileNumber relNumber,
+ int procNumber, ForkNumber forkNumber);
/*
* Wrapper macros for GetRelationPath. Beware of multiple
--
2.46.0