diff --git a/doc/xml/release.xml b/doc/xml/release.xml
index a512577a1..14363868f 100644
--- a/doc/xml/release.xml
+++ b/doc/xml/release.xml
@@ -118,6 +118,14 @@
Inline strPtr()
to increase profiling accuracy.
+
+
+
+
+
+
+ Add pgLsnFromWalSegment()
.
+
diff --git a/src/postgres/interface.c b/src/postgres/interface.c
index e1ac097ff..6699dfe0c 100644
--- a/src/postgres/interface.c
+++ b/src/postgres/interface.c
@@ -627,6 +627,23 @@ pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize)
strNewFmt("%08X%08X%08X", timeline, (unsigned int)(lsn >> 32), (unsigned int)(lsn & 0xFFFFFFFF) / walSegmentSize));
}
+uint64_t
+pgLsnFromWalSegment(const String *walSegment, unsigned int walSegmentSize)
+{
+ FUNCTION_TEST_BEGIN();
+ FUNCTION_TEST_PARAM(STRING, walSegment);
+ FUNCTION_TEST_PARAM(UINT, walSegmentSize);
+ FUNCTION_TEST_END();
+
+ ASSERT(walSegment != NULL);
+ ASSERT(strSize(walSegment) == 24);
+ ASSERT(walSegmentSize > 0);
+
+ FUNCTION_TEST_RETURN(
+ (cvtZToUInt64Base(strPtr(strSubN(walSegment, 8, 8)), 16) << 32) +
+ (cvtZToUInt64Base(strPtr(strSubN(walSegment, 16, 8)), 16) * walSegmentSize));
+}
+
/**********************************************************************************************************************************/
StringList *
pgLsnRangeToWalSegmentList(
diff --git a/src/postgres/interface.h b/src/postgres/interface.h
index ffc291225..05d8d0b32 100644
--- a/src/postgres/interface.h
+++ b/src/postgres/interface.h
@@ -137,8 +137,9 @@ String *pgTablespaceId(unsigned int pgVersion);
uint64_t pgLsnFromStr(const String *lsn);
String *pgLsnToStr(uint64_t lsn);
-// Convert a timeline and lsn to a wal segment
+// Convert a timeline and lsn to a wal segment and vice versa
String *pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize);
+uint64_t pgLsnFromWalSegment(const String *walSegment, unsigned int walSegmentSize);
// Convert a timeline and lsn range to a list of wal segments
StringList *pgLsnRangeToWalSegmentList(
diff --git a/test/src/module/postgres/interfaceTest.c b/test/src/module/postgres/interfaceTest.c
index 0eb8d7e8d..ee71b964e 100644
--- a/test/src/module/postgres/interfaceTest.c
+++ b/test/src/module/postgres/interfaceTest.c
@@ -105,7 +105,7 @@ testRun(void)
}
// *****************************************************************************************************************************
- if (testBegin("pgLsnFromStr(), pgLsnToStr(), pgLsnToWalSegment(), and pgLsnRangeToWalSegmentList()"))
+ if (testBegin("pgLsnFromStr(), pgLsnToStr(), pgLsnToWalSegment(), pgLsnFromWalSegment(), and pgLsnRangeToWalSegmentList()"))
{
TEST_RESULT_UINT(pgLsnFromStr(STRDEF("1/1")), 0x0000000100000001, "lsn to string");
TEST_RESULT_UINT(pgLsnFromStr(STRDEF("ffffffff/ffffffff")), 0xFFFFFFFFFFFFFFFF, "lsn to string");
@@ -119,6 +119,13 @@ testRun(void)
TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFFAAAAAAAA, 0x40000000), "00000001FFFFFFFF00000002", "lsn to wal segment");
TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFF40000000, 0x40000000), "00000001FFFFFFFF00000001", "lsn to wal segment");
+ TEST_RESULT_UINT(
+ pgLsnFromWalSegment(STRDEF("00000001FFFFFFFF000000AA"), 0x1000000), 0xFFFFFFFFAA000000, "16M wal segment to lsn");
+ TEST_RESULT_UINT(
+ pgLsnFromWalSegment(STRDEF("00000001FFFFFFFF00000002"), 0x40000000), 0xFFFFFFFF80000000, "1G wal segment to lsn");
+ TEST_RESULT_UINT(
+ pgLsnFromWalSegment(STRDEF("00000001FFFFFFFF00000001"), 0x40000000), 0xFFFFFFFF40000000, "1G wal segment to lsn");
+
TEST_RESULT_STR_Z(
strLstJoin(
pgLsnRangeToWalSegmentList(