PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_lsn.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_lsn.c
4  * Operations for the pg_lsn datatype.
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/backend/utils/adt/pg_lsn.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15 
16 #include "access/hash.h"
17 #include "funcapi.h"
18 #include "libpq/pqformat.h"
19 #include "utils/builtins.h"
20 #include "utils/pg_lsn.h"
21 
22 #define MAXPG_LSNLEN 17
23 #define MAXPG_LSNCOMPONENT 8
24 
25 /*----------------------------------------------------------
26  * Formatting and conversion routines.
27  *---------------------------------------------------------*/
28 
29 Datum
31 {
32  char *str = PG_GETARG_CSTRING(0);
33  int len1,
34  len2;
35  uint32 id,
36  off;
38 
39  /* Sanity check input format. */
40  len1 = strspn(str, "0123456789abcdefABCDEF");
41  if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
42  ereport(ERROR,
43  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
44  errmsg("invalid input syntax for type %s: \"%s\"",
45  "pg_lsn", str)));
46  len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF");
47  if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0')
48  ereport(ERROR,
49  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
50  errmsg("invalid input syntax for type %s: \"%s\"",
51  "pg_lsn", str)));
52 
53  /* Decode result. */
54  id = (uint32) strtoul(str, NULL, 16);
55  off = (uint32) strtoul(str + len1 + 1, NULL, 16);
56  result = ((uint64) id << 32) | off;
57 
58  PG_RETURN_LSN(result);
59 }
60 
61 Datum
63 {
64  XLogRecPtr lsn = PG_GETARG_LSN(0);
65  char buf[MAXPG_LSNLEN + 1];
66  char *result;
67  uint32 id,
68  off;
69 
70  /* Decode ID and offset */
71  id = (uint32) (lsn >> 32);
72  off = (uint32) lsn;
73 
74  snprintf(buf, sizeof buf, "%X/%X", id, off);
75  result = pstrdup(buf);
76  PG_RETURN_CSTRING(result);
77 }
78 
79 Datum
81 {
84 
85  result = pq_getmsgint64(buf);
86  PG_RETURN_LSN(result);
87 }
88 
89 Datum
91 {
92  XLogRecPtr lsn = PG_GETARG_LSN(0);
94 
95  pq_begintypsend(&buf);
96  pq_sendint64(&buf, lsn);
98 }
99 
100 
101 /*----------------------------------------------------------
102  * Operators for PostgreSQL LSNs
103  *---------------------------------------------------------*/
104 
105 Datum
107 {
108  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
109  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
110 
111  PG_RETURN_BOOL(lsn1 == lsn2);
112 }
113 
114 Datum
116 {
117  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
118  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
119 
120  PG_RETURN_BOOL(lsn1 != lsn2);
121 }
122 
123 Datum
125 {
126  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
127  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
128 
129  PG_RETURN_BOOL(lsn1 < lsn2);
130 }
131 
132 Datum
134 {
135  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
136  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
137 
138  PG_RETURN_BOOL(lsn1 > lsn2);
139 }
140 
141 Datum
143 {
144  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
145  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
146 
147  PG_RETURN_BOOL(lsn1 <= lsn2);
148 }
149 
150 Datum
152 {
153  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
154  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
155 
156  PG_RETURN_BOOL(lsn1 >= lsn2);
157 }
158 
159 /* btree index opclass support */
160 Datum
162 {
163  XLogRecPtr a = PG_GETARG_LSN(0);
164  XLogRecPtr b = PG_GETARG_LSN(1);
165 
166  if (a > b)
167  PG_RETURN_INT32(1);
168  else if (a == b)
169  PG_RETURN_INT32(0);
170  else
171  PG_RETURN_INT32(-1);
172 }
173 
174 /* hash index opclass support */
175 Datum
177 {
178  /* We can use hashint8 directly */
179  return hashint8(fcinfo);
180 }
181 
182 
183 /*----------------------------------------------------------
184  * Arithmetic operators on PostgreSQL LSNs.
185  *---------------------------------------------------------*/
186 
187 Datum
189 {
190  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
191  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
192  char buf[256];
193  Datum result;
194 
195  /* Output could be as large as plus or minus 2^63 - 1. */
196  if (lsn1 < lsn2)
197  snprintf(buf, sizeof buf, "-" UINT64_FORMAT, lsn2 - lsn1);
198  else
199  snprintf(buf, sizeof buf, UINT64_FORMAT, lsn1 - lsn2);
200 
201  /* Convert to numeric. */
203  CStringGetDatum(buf),
204  ObjectIdGetDatum(0),
205  Int32GetDatum(-1));
206 
207  return result;
208 }
#define MAXPG_LSNLEN
Definition: pg_lsn.c:22
Datum pg_lsn_le(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:142
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:62
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
Datum pg_lsn_mi(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:188
char * pstrdup(const char *in)
Definition: mcxt.c:1077
StringInfoData * StringInfo
Definition: stringinfo.h:46
Datum pg_lsn_send(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:90
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
Datum pg_lsn_in(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:30
#define PG_RETURN_LSN(x)
Definition: pg_lsn.h:25
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Datum pg_lsn_recv(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:80
static char * buf
Definition: pg_test_fsync.c:66
#define CStringGetDatum(X)
Definition: postgres.h:584
unsigned int uint32
Definition: c.h:268
Datum pg_lsn_ge(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:151
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:559
#define ereport(elevel, rest)
Definition: elog.h:122
Datum pg_lsn_eq(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:106
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:588
Datum pg_lsn_gt(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:133
#define PG_GETARG_LSN(n)
Definition: pg_lsn.h:24
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
Datum pg_lsn_out(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:62
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
Datum pg_lsn_lt(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:124
#define Int32GetDatum(X)
Definition: postgres.h:485
int errmsg(const char *fmt,...)
Definition: elog.c:797
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:486
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
Datum pg_lsn_cmp(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:161
#define MAXPG_LSNCOMPONENT
Definition: pg_lsn.c:23
Datum pg_lsn_hash(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:176
void pq_sendint64(StringInfo buf, int64 i)
Definition: pqformat.c:271
#define UINT64_FORMAT
Definition: c.h:316
Datum pg_lsn_ne(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:115