lsn.patch
application/octet-stream
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: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/lsn.c | 189 | 0 |
| src/backend/utils/adt/Makefile | 1 | 1 |
| src/include/catalog/pg_operator.h | 16 | 0 |
| src/include/catalog/pg_proc.h | 17 | 0 |
| src/include/catalog/pg_type.h | 5 | 0 |
| src/include/utils/lsn.h | 33 | 0 |
diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 5f968b0..e79aeef 100644
--- a/src/backend/utils/adt/Makefile
+++ b/src/backend/utils/adt/Makefile
@@ -18,7 +18,7 @@ endif
OBJS = acl.o arrayfuncs.o array_userfuncs.o arrayutils.o bool.o \
cash.o char.o date.o datetime.o datum.o domains.o \
enum.o float.o format_type.o \
- geo_ops.o geo_selfuncs.o int.o int8.o like.o lockfuncs.o \
+ geo_ops.o geo_selfuncs.o int.o int8.o like.o lockfuncs.o lsn.o \
misc.o nabstime.o name.o numeric.o numutils.o \
oid.o oracle_compat.o pseudotypes.o rangetypes.o rangetypes_gist.o \
rowtypes.o regexp.o regproc.o ruleutils.o selfuncs.o \
diff --git a/src/backend/utils/adt/lsn.c b/src/backend/utils/adt/lsn.c
new file mode 100644
index 0000000..839ff37
--- /dev/null
+++ b/src/backend/utils/adt/lsn.c
@@ -0,0 +1,189 @@
+/*-------------------------------------------------------------------------
+ *
+ * lsn.c
+ * Internal LSN operations
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/backend/utils/adt/lsn.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "funcapi.h"
+#include "libpq/pqformat.h"
+#include "utils/builtins.h"
+#include "utils/lsn.h"
+
+#define MAXINT4LEN 12
+#define MAXINT8LEN 25
+#define MAXLSNLEN 17
+#define MAXLSNCOMPONENT 8
+
+/*----------------------------------------------------------
+ * Formatting and conversion routines.
+ *---------------------------------------------------------*/
+
+Datum
+lsn_in(PG_FUNCTION_ARGS)
+{
+ char *str = PG_GETARG_CSTRING(0);
+ int len1,
+ len2;
+ XLogRecPtr *result;
+
+ /* Sanity check input format. */
+ len1 = strspn(str, "0123456789abcdefABCDEF");
+ if (len1 < 1 || len1 > MAXLSNCOMPONENT || str[len1] != '/')
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for lsn: \"%s\"", str)));
+ len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF");
+ if (len2 < 1 || len2 > MAXLSNCOMPONENT || str[len1 + 1 + len2] != '\0')
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for lsn: \"%s\"", str)));
+
+ /* Decode result. */
+ result = palloc(sizeof(XLogRecPtr));
+ result->xlogid = (uint32) strtoul(str, NULL, 16);
+ result->xrecoff = (uint32) strtoul(str + len1 + 1, NULL, 16);
+
+ PG_RETURN_POINTER(result);
+}
+
+Datum
+lsn_out(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ char buf[MAXLSNLEN + 1];
+ char *result;
+
+ sprintf(buf, "%X/%X", lsn->xlogid, lsn->xrecoff);
+ result = pstrdup(buf);
+ PG_RETURN_CSTRING(result);
+}
+
+Datum
+lsn_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ XLogRecPtr *result;
+
+ result = palloc(sizeof(XLogRecPtr));
+ result->xlogid = pq_getmsgint(buf, 4);
+ result->xrecoff = pq_getmsgint(buf, 4);
+
+ PG_RETURN_POINTER(result);
+}
+
+Datum
+lsn_send(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ StringInfoData buf;
+
+ pq_begintypsend(&buf);
+ pq_sendint(&buf, lsn->xlogid, 4);
+ pq_sendint(&buf, lsn->xrecoff, 4);
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
+
+/*----------------------------------------------------------
+ * Relational operators for LSNs
+ *---------------------------------------------------------*/
+
+Datum
+lsn_eq(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn1 = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ XLogRecPtr *lsn2 = (XLogRecPtr *) PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(XLByteEQ(*lsn1, *lsn2));
+}
+
+Datum
+lsn_ne(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn1 = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ XLogRecPtr *lsn2 = (XLogRecPtr *) PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(!XLByteEQ(*lsn1, *lsn2));
+}
+
+Datum
+lsn_lt(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn1 = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ XLogRecPtr *lsn2 = (XLogRecPtr *) PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(XLByteLT(*lsn1, *lsn2));
+}
+
+Datum
+lsn_gt(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn1 = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ XLogRecPtr *lsn2 = (XLogRecPtr *) PG_GETARG_POINTER(1);
+
+ /* note order of arguments */
+ PG_RETURN_BOOL(XLByteLT(*lsn2, *lsn1));
+}
+
+Datum
+lsn_le(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn1 = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ XLogRecPtr *lsn2 = (XLogRecPtr *) PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(XLByteLE(*lsn1, *lsn2));
+}
+
+Datum
+lsn_ge(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn1 = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ XLogRecPtr *lsn2 = (XLogRecPtr *) PG_GETARG_POINTER(1);
+
+ /* note order of arguments */
+ PG_RETURN_BOOL(XLByteLE(*lsn2, *lsn1));
+}
+
+
+/*----------------------------------------------------------
+ * Arithmetic operators on LSNs.
+ *---------------------------------------------------------*/
+
+Datum
+lsn_mi(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr *lsn1 = (XLogRecPtr *) PG_GETARG_POINTER(0);
+ XLogRecPtr *lsn2 = (XLogRecPtr *) PG_GETARG_POINTER(1);
+ uint64 v1;
+ uint64 v2;
+ char buf[256];
+ Datum result;
+
+ /* Flatten values to 64-bit unsigned integers. */
+ v1 = (((uint64) lsn1->xlogid) << 32) | ((uint64) lsn1->xrecoff);
+ v2 = (((uint64) lsn2->xlogid) << 32) | ((uint64) lsn2->xrecoff);
+
+ /* Negative results are not allowed. */
+ if (v1 < v2)
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("LSN out of range")));
+
+ /* Convert to numeric. */
+ sprintf(buf, UINT64_FORMAT, v1 - v2);
+ result = DirectFunctionCall3(numeric_in,
+ CStringGetDatum(buf),
+ ObjectIdGetDatum(0),
+ Int32GetDatum(-1));
+
+ return result;
+}
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index eac5cb9..07b8f63 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -1578,6 +1578,22 @@ DESCR("less than or equal");
DATA(insert OID = 2977 ( ">=" PGNSP PGUID b f f 2950 2950 16 2976 2974 uuid_ge scalargtsel scalargtjoinsel ));
DESCR("greater than or equal");
+/* lsn operators */
+DATA(insert OID = 3788 ( "=" PGNSP PGUID b f f 3813 3813 16 3788 3789 lsn_eq eqsel eqjoinsel ));
+DESCR("equal");
+DATA(insert OID = 3789 ( "<>" PGNSP PGUID b f f 3813 3813 16 3789 3788 lsn_ne neqsel neqjoinsel ));
+DESCR("not equal");
+DATA(insert OID = 3790 ( "<" PGNSP PGUID b f f 3813 3813 16 3791 3793 lsn_lt scalarltsel scalarltjoinsel ));
+DESCR("less than");
+DATA(insert OID = 3791 ( ">" PGNSP PGUID b f f 3813 3813 16 3790 3792 lsn_gt scalargtsel scalargtjoinsel ));
+DESCR("greater than");
+DATA(insert OID = 3792 ( "<=" PGNSP PGUID b f f 3813 3813 16 3793 3791 lsn_le scalarltsel scalarltjoinsel ));
+DESCR("less than or equal");
+DATA(insert OID = 3793 ( ">=" PGNSP PGUID b f f 3813 3813 16 3792 3790 lsn_ge scalargtsel scalargtjoinsel ));
+DESCR("greater than or equal");
+DATA(insert OID = 3795 ( "-" PGNSP PGUID b f f 3813 3813 1700 0 0 lsn_mi - - ));
+DESCR("minus");
+
/* enum operators */
DATA(insert OID = 3516 ( "=" PGNSP PGUID b t t 3500 3500 16 3516 3517 enum_eq eqsel eqjoinsel ));
DESCR("equal");
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 28e53b7..0ddc956 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3983,6 +3983,23 @@ DESCR("I/O");
DATA(insert OID = 2963 ( uuid_hash PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 23 "2950" _null_ _null_ _null_ _null_ uuid_hash _null_ _null_ _null_ ));
DESCR("hash");
+/* lsn */
+DATA(insert OID = 3778 ( lsn_in PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 3813 "2275" _null_ _null_ _null_ _null_ lsn_in _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3779 ( lsn_out PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 2275 "3813" _null_ _null_ _null_ _null_ lsn_out _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3780 ( lsn_lt PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "3813 3813" _null_ _null_ _null_ _null_ lsn_lt _null_ _null_ _null_ ));
+DATA(insert OID = 3781 ( lsn_le PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "3813 3813" _null_ _null_ _null_ _null_ lsn_le _null_ _null_ _null_ ));
+DATA(insert OID = 3782 ( lsn_eq PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "3813 3813" _null_ _null_ _null_ _null_ lsn_eq _null_ _null_ _null_ ));
+DATA(insert OID = 3783 ( lsn_ge PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "3813 3813" _null_ _null_ _null_ _null_ lsn_ge _null_ _null_ _null_ ));
+DATA(insert OID = 3784 ( lsn_gt PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "3813 3813" _null_ _null_ _null_ _null_ lsn_gt _null_ _null_ _null_ ));
+DATA(insert OID = 3785 ( lsn_ne PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "3813 3813" _null_ _null_ _null_ _null_ lsn_ne _null_ _null_ _null_ ));
+DATA(insert OID = 3794 ( lsn_mi PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 1700 "3813 3813" _null_ _null_ _null_ _null_ lsn_mi _null_ _null_ _null_ ));
+DATA(insert OID = 3786 ( lsn_recv PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 3813 "2281" _null_ _null_ _null_ _null_ lsn_recv _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3787 ( lsn_send PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 17 "3813" _null_ _null_ _null_ _null_ lsn_send _null_ _null_ _null_ ));
+DESCR("I/O");
+
/* enum related procs */
DATA(insert OID = 3504 ( anyenum_in PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 3500 "2275" _null_ _null_ _null_ _null_ anyenum_in _null_ _null_ _null_ ));
DESCR("I/O");
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 406241a..aec9a24 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -565,6 +565,11 @@ DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b U f t \054 0 0 2951 uuid_in u
DESCR("UUID datatype");
DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b A f t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
+/* lsn */
+DATA(insert OID = 3813 ( lsn PGNSP PGUID 16 f b U f t \054 0 0 3814 lsn_in lsn_out lsn_recv lsn_send - - - i p f 0 -1 0 0 _null_ _null_ ));
+DESCR("LSN datatype");
+DATA(insert OID = 3814 ( _lsn PGNSP PGUID -1 f b A f t \054 0 3813 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
+
/* text search */
DATA(insert OID = 3614 ( tsvector PGNSP PGUID -1 f b U f t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 0 _null_ _null_ ));
DESCR("text representation for text search");
diff --git a/src/include/utils/lsn.h b/src/include/utils/lsn.h
new file mode 100644
index 0000000..7e4be7b
--- /dev/null
+++ b/src/include/utils/lsn.h
@@ -0,0 +1,33 @@
+/*-------------------------------------------------------------------------
+ *
+ * lsn.h
+ * Declarations for operations on log sequence numbers (LSNs).
+ *
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/lsn.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LSN_H
+#define LSN_H
+
+#include "fmgr.h"
+
+extern Datum lsn_in(PG_FUNCTION_ARGS);
+extern Datum lsn_out(PG_FUNCTION_ARGS);
+extern Datum lsn_recv(PG_FUNCTION_ARGS);
+extern Datum lsn_send(PG_FUNCTION_ARGS);
+
+extern Datum lsn_eq(PG_FUNCTION_ARGS);
+extern Datum lsn_ne(PG_FUNCTION_ARGS);
+extern Datum lsn_lt(PG_FUNCTION_ARGS);
+extern Datum lsn_gt(PG_FUNCTION_ARGS);
+extern Datum lsn_le(PG_FUNCTION_ARGS);
+extern Datum lsn_ge(PG_FUNCTION_ARGS);
+
+extern Datum lsn_mi(PG_FUNCTION_ARGS);
+
+#endif /* LSN_H */