PostgreSQL Source Code  git master
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-2019, 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 "funcapi.h"
17 #include "libpq/pqformat.h"
18 #include "utils/builtins.h"
19 #include "utils/pg_lsn.h"
20 
21 #define MAXPG_LSNLEN 17
22 #define MAXPG_LSNCOMPONENT 8
23 
24 /*----------------------------------------------------------
25  * Formatting and conversion routines.
26  *---------------------------------------------------------*/
27 
29 pg_lsn_in_internal(const char *str, bool *have_error)
30 {
31  int len1,
32  len2;
33  uint32 id,
34  off;
35  XLogRecPtr result;
36 
37  Assert(have_error != NULL);
38  *have_error = false;
39 
40  /* Sanity check input format. */
41  len1 = strspn(str, "0123456789abcdefABCDEF");
42  if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
43  {
44  *have_error = true;
45  return InvalidXLogRecPtr;
46  }
47  len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF");
48  if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0')
49  {
50  *have_error = true;
51  return InvalidXLogRecPtr;
52  }
53 
54  /* Decode result. */
55  id = (uint32) strtoul(str, NULL, 16);
56  off = (uint32) strtoul(str + len1 + 1, NULL, 16);
57  result = ((uint64) id << 32) | off;
58 
59  return result;
60 }
61 
62 Datum
64 {
65  char *str = PG_GETARG_CSTRING(0);
66  XLogRecPtr result;
67  bool have_error = false;
68 
69  result = pg_lsn_in_internal(str, &have_error);
70  if (have_error)
71  ereport(ERROR,
72  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
73  errmsg("invalid input syntax for type %s: \"%s\"",
74  "pg_lsn", str)));
75 
76  PG_RETURN_LSN(result);
77 }
78 
79 Datum
81 {
82  XLogRecPtr lsn = PG_GETARG_LSN(0);
83  char buf[MAXPG_LSNLEN + 1];
84  char *result;
85  uint32 id,
86  off;
87 
88  /* Decode ID and offset */
89  id = (uint32) (lsn >> 32);
90  off = (uint32) lsn;
91 
92  snprintf(buf, sizeof buf, "%X/%X", id, off);
93  result = pstrdup(buf);
94  PG_RETURN_CSTRING(result);
95 }
96 
97 Datum
99 {
101  XLogRecPtr result;
102 
103  result = pq_getmsgint64(buf);
104  PG_RETURN_LSN(result);
105 }
106 
107 Datum
109 {
110  XLogRecPtr lsn = PG_GETARG_LSN(0);
112 
113  pq_begintypsend(&buf);
114  pq_sendint64(&buf, lsn);
116 }
117 
118 
119 /*----------------------------------------------------------
120  * Operators for PostgreSQL LSNs
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 Datum
161 {
162  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
163  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
164 
165  PG_RETURN_BOOL(lsn1 <= lsn2);
166 }
167 
168 Datum
170 {
171  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
172  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
173 
174  PG_RETURN_BOOL(lsn1 >= lsn2);
175 }
176 
177 Datum
179 {
180  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
181  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
182 
183  PG_RETURN_LSN((lsn1 > lsn2) ? lsn1 : lsn2);
184 }
185 
186 Datum
188 {
189  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
190  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
191 
192  PG_RETURN_LSN((lsn1 < lsn2) ? lsn1 : lsn2);
193 }
194 
195 /* btree index opclass support */
196 Datum
198 {
199  XLogRecPtr a = PG_GETARG_LSN(0);
200  XLogRecPtr b = PG_GETARG_LSN(1);
201 
202  if (a > b)
203  PG_RETURN_INT32(1);
204  else if (a == b)
205  PG_RETURN_INT32(0);
206  else
207  PG_RETURN_INT32(-1);
208 }
209 
210 /* hash index opclass support */
211 Datum
213 {
214  /* We can use hashint8 directly */
215  return hashint8(fcinfo);
216 }
217 
218 Datum
220 {
221  return hashint8extended(fcinfo);
222 }
223 
224 
225 /*----------------------------------------------------------
226  * Arithmetic operators on PostgreSQL LSNs.
227  *---------------------------------------------------------*/
228 
229 Datum
231 {
232  XLogRecPtr lsn1 = PG_GETARG_LSN(0);
233  XLogRecPtr lsn2 = PG_GETARG_LSN(1);
234  char buf[256];
235  Datum result;
236 
237  /* Output could be as large as plus or minus 2^63 - 1. */
238  if (lsn1 < lsn2)
239  snprintf(buf, sizeof buf, "-" UINT64_FORMAT, lsn2 - lsn1);
240  else
241  snprintf(buf, sizeof buf, UINT64_FORMAT, lsn1 - lsn2);
242 
243  /* Convert to numeric. */
245  CStringGetDatum(buf),
246  ObjectIdGetDatum(0),
247  Int32GetDatum(-1));
248 
249  return result;
250 }
#define MAXPG_LSNLEN
Definition: pg_lsn.c:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
Datum pg_lsn_le(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:160
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:83
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
Datum pg_lsn_mi(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:230
char * pstrdup(const char *in)
Definition: mcxt.c:1186
Datum pg_lsn_hash_extended(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:219
StringInfoData * StringInfo
Definition: stringinfo.h:44
Datum pg_lsn_send(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:108
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:103
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:153
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
Datum pg_lsn_in(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:63
#define PG_RETURN_LSN(x)
Definition: pg_lsn.h:25
Datum pg_lsn_smaller(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:187
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Datum pg_lsn_recv(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:98
static char * buf
Definition: pg_test_fsync.c:67
#define CStringGetDatum(X)
Definition: postgres.h:578
unsigned int uint32
Definition: c.h:359
Datum pg_lsn_ge(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:169
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:573
#define ereport(elevel, rest)
Definition: elog.h:141
Datum pg_lsn_eq(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:124
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:619
Datum pg_lsn_gt(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:151
#define PG_GETARG_LSN(n)
Definition: pg_lsn.h:24
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:367
Datum pg_lsn_out(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:80
XLogRecPtr pg_lsn_in_internal(const char *str, bool *have_error)
Definition: pg_lsn.c:29
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:739
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:352
Datum pg_lsn_lt(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:142
#define Int32GetDatum(X)
Definition: postgres.h:479
int errmsg(const char *fmt,...)
Definition: elog.c:822
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:455
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272
#define PG_FUNCTION_ARGS
Definition: fmgr.h:188
Datum pg_lsn_cmp(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:197
#define MAXPG_LSNCOMPONENT
Definition: pg_lsn.c:22
Datum pg_lsn_hash(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:212
#define snprintf
Definition: port.h:192
#define UINT64_FORMAT
Definition: c.h:402
Datum pg_lsn_larger(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:178
Datum pg_lsn_ne(PG_FUNCTION_ARGS)
Definition: pg_lsn.c:133