v1-0002-introduce-pg_walfile_offset_lsn.patch
application/x-patch
Filename: v1-0002-introduce-pg_walfile_offset_lsn.patch
Type: application/x-patch
Part: 1
Patch
Format: format-patch
Series: patch v1-0002
Subject: introduce pg_walfile_offset_lsn()
| File | + | − |
|---|---|---|
| doc/src/sgml/func.sgml | 14 | 0 |
| src/backend/access/transam/xlogfuncs.c | 39 | 0 |
| src/include/catalog/pg_proc.dat | 5 | 0 |
| src/test/regress/expected/misc_functions.out | 19 | 0 |
| src/test/regress/sql/misc_functions.sql | 9 | 0 |
From f8ed45d9fa59690d8b3375d658c1baedb8510195 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandbossart@gmail.com>
Date: Mon, 19 Sep 2022 20:24:10 -0700
Subject: [PATCH v1 1/1] introduce pg_walfile_offset_lsn()
---
doc/src/sgml/func.sgml | 14 +++++++
src/backend/access/transam/xlogfuncs.c | 39 ++++++++++++++++++++
src/include/catalog/pg_proc.dat | 5 +++
src/test/regress/expected/misc_functions.out | 19 ++++++++++
src/test/regress/sql/misc_functions.sql | 9 +++++
5 files changed, 86 insertions(+)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 67eb380632..318ac22769 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -25891,6 +25891,20 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560
</para></entry>
</row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_walfile_offset_lsn</primary>
+ </indexterm>
+ <function>pg_walfile_offset_lsn</function> ( <parameter>file_name</parameter> <type>text</type>, <parameter>file_offset</parameter> <type>integer</type> )
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Converts a WAL file name and byte offset within that file to a
+ write-ahead log location.
+ </para></entry>
+ </row>
+
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 27aeb6e281..75f58cb118 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -313,6 +313,45 @@ pg_last_wal_replay_lsn(PG_FUNCTION_ARGS)
PG_RETURN_LSN(recptr);
}
+/*
+ * Compute an LSN given a WAL file name and decimal byte offset.
+ */
+Datum
+pg_walfile_offset_lsn(PG_FUNCTION_ARGS)
+{
+ char *filename = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ int offset = PG_GETARG_INT32(1);
+ TimeLineID tli;
+ XLogSegNo segno;
+ XLogRecPtr result;
+ uint32 log;
+ uint32 seg;
+
+ if (!IsXLogFileName(filename))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid WAL file name \"%s\"", filename)));
+
+ sscanf(filename, "%08X%08X%08X", &tli, &log, &seg);
+ if (seg >= XLogSegmentsPerXLogId(wal_segment_size) ||
+ (log == 0 && seg == 0) ||
+ tli == 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid WAL file name \"%s\"", filename)));
+
+ if (offset < 0 || offset >= wal_segment_size)
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("\"offset\" must not be negative or greater than or "
+ "equal to WAL segment size")));
+
+ XLogFromFileName(filename, &tli, &segno, wal_segment_size);
+ XLogSegNoOffsetToRecPtr(segno, offset, wal_segment_size, result);
+
+ PG_RETURN_LSN(result);
+}
+
/*
* Compute an xlog file name and decimal byte offset given a WAL location,
* such as is returned by pg_backup_stop() or pg_switch_wal().
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index a07e737a33..224fe590ac 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6328,6 +6328,11 @@
proargtypes => 'pg_lsn', proallargtypes => '{pg_lsn,text,int4}',
proargmodes => '{i,o,o}', proargnames => '{lsn,file_name,file_offset}',
prosrc => 'pg_walfile_name_offset' },
+{ oid => '8205',
+ descr => 'wal location, given a wal filename and byte offset',
+ proname => 'pg_walfile_offset_lsn', prorettype => 'pg_lsn',
+ proargtypes => 'text int4', proargnames => '{file_name,file_offset}',
+ prosrc => 'pg_walfile_offset_lsn' },
{ oid => '2851', descr => 'wal filename, given a wal location',
proname => 'pg_walfile_name', prorettype => 'text', proargtypes => 'pg_lsn',
prosrc => 'pg_walfile_name' },
diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out
index 9f106c2a10..b2d6f23ac1 100644
--- a/src/test/regress/expected/misc_functions.out
+++ b/src/test/regress/expected/misc_functions.out
@@ -594,3 +594,22 @@ SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g;
Index Cond: (unique1 = g.g)
(4 rows)
+-- pg_walfile_offset_lsn
+SELECT pg_walfile_offset_lsn('invalid', 15);
+ERROR: invalid WAL file name "invalid"
+SELECT pg_walfile_offset_lsn('0000000100000000FFFFFFFF', 15);
+ERROR: invalid WAL file name "0000000100000000FFFFFFFF"
+SELECT pg_walfile_offset_lsn('000000010000000000000000', 15);
+ERROR: invalid WAL file name "000000010000000000000000"
+SELECT pg_walfile_offset_lsn('000000000000000100000000', 15);
+ERROR: invalid WAL file name "000000000000000100000000"
+SELECT pg_walfile_offset_lsn('000000010000000100000000', -1);
+ERROR: "offset" must not be negative or greater than or equal to WAL segment size
+SELECT pg_walfile_offset_lsn('000000010000000100000000', 2000000000);
+ERROR: "offset" must not be negative or greater than or equal to WAL segment size
+SELECT pg_walfile_offset_lsn('000000010000000100000000', 15);
+ pg_walfile_offset_lsn
+-----------------------
+ 1/F
+(1 row)
+
diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql
index 639e9b352c..cb54901029 100644
--- a/src/test/regress/sql/misc_functions.sql
+++ b/src/test/regress/sql/misc_functions.sql
@@ -223,3 +223,12 @@ SELECT * FROM tenk1 a JOIN my_gen_series(1,1000) g ON a.unique1 = g;
EXPLAIN (COSTS OFF)
SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g;
+
+-- pg_walfile_offset_lsn
+SELECT pg_walfile_offset_lsn('invalid', 15);
+SELECT pg_walfile_offset_lsn('0000000100000000FFFFFFFF', 15);
+SELECT pg_walfile_offset_lsn('000000010000000000000000', 15);
+SELECT pg_walfile_offset_lsn('000000000000000100000000', 15);
+SELECT pg_walfile_offset_lsn('000000010000000100000000', -1);
+SELECT pg_walfile_offset_lsn('000000010000000100000000', 2000000000);
+SELECT pg_walfile_offset_lsn('000000010000000100000000', 15);
--
2.25.1