PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
txid.c File Reference
#include "postgres.h"
#include "access/transam.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "libpq/pqformat.h"
#include "postmaster/postmaster.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/snapmgr.h"
Include dependency graph for txid.c:

Go to the source code of this file.

Data Structures

struct  TxidSnapshot
 
struct  TxidEpoch
 

Macros

#define MAX_TXID   ((uint64) PG_INT64_MAX)
 
#define TXID_FMT   UINT64_FORMAT
 
#define USE_BSEARCH_IF_NXIP_GREATER   30
 
#define TXID_SNAPSHOT_SIZE(nxip)   (offsetof(TxidSnapshot, xip) + sizeof(txid) * (nxip))
 
#define TXID_SNAPSHOT_MAX_NXIP   ((MaxAllocSize - offsetof(TxidSnapshot, xip)) / sizeof(txid))
 

Typedefs

typedef uint64 txid
 

Functions

static void load_xid_epoch (TxidEpoch *state)
 
static txid convert_xid (TransactionId xid, const TxidEpoch *state)
 
static int cmp_txid (const void *aa, const void *bb)
 
static void sort_snapshot (TxidSnapshot *snap)
 
static bool is_visible_txid (txid value, const TxidSnapshot *snap)
 
static StringInfo buf_init (txid xmin, txid xmax)
 
static void buf_add_txid (StringInfo buf, txid xid)
 
static TxidSnapshotbuf_finalize (StringInfo buf)
 
static txid str2txid (const char *s, const char **endp)
 
static TxidSnapshotparse_snapshot (const char *str)
 
Datum txid_current (PG_FUNCTION_ARGS)
 
Datum txid_current_if_assigned (PG_FUNCTION_ARGS)
 
Datum txid_current_snapshot (PG_FUNCTION_ARGS)
 
Datum txid_snapshot_in (PG_FUNCTION_ARGS)
 
Datum txid_snapshot_out (PG_FUNCTION_ARGS)
 
Datum txid_snapshot_recv (PG_FUNCTION_ARGS)
 
Datum txid_snapshot_send (PG_FUNCTION_ARGS)
 
Datum txid_visible_in_snapshot (PG_FUNCTION_ARGS)
 
Datum txid_snapshot_xmin (PG_FUNCTION_ARGS)
 
Datum txid_snapshot_xmax (PG_FUNCTION_ARGS)
 
Datum txid_snapshot_xip (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

#define MAX_TXID   ((uint64) PG_INT64_MAX)

Definition at line 37 of file txid.c.

Referenced by str2txid(), and txid_snapshot_recv().

#define TXID_FMT   UINT64_FORMAT

Definition at line 43 of file txid.c.

Referenced by txid_snapshot_out().

#define TXID_SNAPSHOT_MAX_NXIP   ((MaxAllocSize - offsetof(TxidSnapshot, xip)) / sizeof(txid))

Definition at line 73 of file txid.c.

Referenced by txid_current_snapshot(), and txid_snapshot_recv().

#define TXID_SNAPSHOT_SIZE (   nxip)    (offsetof(TxidSnapshot, xip) + sizeof(txid) * (nxip))

Definition at line 71 of file txid.c.

Referenced by buf_init(), txid_current_snapshot(), and txid_snapshot_recv().

#define USE_BSEARCH_IF_NXIP_GREATER   30

Definition at line 49 of file txid.c.

Referenced by is_visible_txid().

Typedef Documentation

typedef uint64 txid

Definition at line 40 of file txid.c.

Function Documentation

static void buf_add_txid ( StringInfo  buf,
txid  xid 
)
static

Definition at line 221 of file txid.c.

References appendBinaryStringInfo(), StringInfoData::data, and TxidSnapshot::nxip.

Referenced by parse_snapshot().

222 {
223  TxidSnapshot *snap = (TxidSnapshot *) buf->data;
224 
225  /* do this before possible realloc */
226  snap->nxip++;
227 
228  appendBinaryStringInfo(buf, (char *) &xid, sizeof(xid));
229 }
uint32 nxip
Definition: txid.c:64
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
static TxidSnapshot* buf_finalize ( StringInfo  buf)
static

Definition at line 232 of file txid.c.

References StringInfoData::data, StringInfoData::len, NULL, pfree(), and SET_VARSIZE.

Referenced by parse_snapshot().

233 {
234  TxidSnapshot *snap = (TxidSnapshot *) buf->data;
235 
236  SET_VARSIZE(snap, buf->len);
237 
238  /* buf is not needed anymore */
239  buf->data = NULL;
240  pfree(buf);
241 
242  return snap;
243 }
void pfree(void *pointer)
Definition: mcxt.c:992
#define NULL
Definition: c.h:226
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
static StringInfo buf_init ( txid  xmin,
txid  xmax 
)
static

Definition at line 206 of file txid.c.

References appendBinaryStringInfo(), buf, makeStringInfo(), TxidSnapshot::nxip, TXID_SNAPSHOT_SIZE, TxidSnapshot::xmax, and TxidSnapshot::xmin.

Referenced by parse_snapshot().

207 {
208  TxidSnapshot snap;
209  StringInfo buf;
210 
211  snap.xmin = xmin;
212  snap.xmax = xmax;
213  snap.nxip = 0;
214 
215  buf = makeStringInfo();
216  appendBinaryStringInfo(buf, (char *) &snap, TXID_SNAPSHOT_SIZE(0));
217  return buf;
218 }
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
txid xmin
Definition: txid.c:65
static char * buf
Definition: pg_test_fsync.c:65
#define TXID_SNAPSHOT_SIZE(nxip)
Definition: txid.c:71
uint32 nxip
Definition: txid.c:64
txid xmax
Definition: txid.c:66
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
static int cmp_txid ( const void *  aa,
const void *  bb 
)
static

Definition at line 123 of file txid.c.

Referenced by is_visible_txid(), and sort_snapshot().

124 {
125  txid a = *(const txid *) aa;
126  txid b = *(const txid *) bb;
127 
128  if (a < b)
129  return -1;
130  if (a > b)
131  return 1;
132  return 0;
133 }
uint64 txid
Definition: txid.c:40
static txid convert_xid ( TransactionId  xid,
const TxidEpoch state 
)
static

Definition at line 99 of file txid.c.

References epoch, TxidEpoch::epoch, TxidEpoch::last_xid, TransactionIdFollows(), TransactionIdIsNormal, and TransactionIdPrecedes().

Referenced by txid_current(), txid_current_if_assigned(), and txid_current_snapshot().

100 {
101  uint64 epoch;
102 
103  /* return special xid's as-is */
104  if (!TransactionIdIsNormal(xid))
105  return (txid) xid;
106 
107  /* xid can be on either side when near wrap-around */
108  epoch = (uint64) state->epoch;
109  if (xid > state->last_xid &&
110  TransactionIdPrecedes(xid, state->last_xid))
111  epoch--;
112  else if (xid < state->last_xid &&
113  TransactionIdFollows(xid, state->last_xid))
114  epoch++;
115 
116  return (epoch << 32) | xid;
117 }
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition: transam.c:334
TransactionId last_xid
Definition: txid.c:81
uint64 txid
Definition: txid.c:40
uint32 epoch
Definition: txid.c:82
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
static const unsigned __int64 epoch
Definition: gettimeofday.c:34
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
static bool is_visible_txid ( txid  value,
const TxidSnapshot snap 
)
static

Definition at line 172 of file txid.c.

References cmp_txid(), i, TxidSnapshot::nxip, USE_BSEARCH_IF_NXIP_GREATER, TxidSnapshot::xip, and TxidSnapshot::xmax.

Referenced by txid_visible_in_snapshot().

173 {
174  if (value < snap->xmin)
175  return true;
176  else if (value >= snap->xmax)
177  return false;
178 #ifdef USE_BSEARCH_IF_NXIP_GREATER
179  else if (snap->nxip > USE_BSEARCH_IF_NXIP_GREATER)
180  {
181  void *res;
182 
183  res = bsearch(&value, snap->xip, snap->nxip, sizeof(txid), cmp_txid);
184  /* if found, transaction is still in progress */
185  return (res) ? false : true;
186  }
187 #endif
188  else
189  {
190  uint32 i;
191 
192  for (i = 0; i < snap->nxip; i++)
193  {
194  if (value == snap->xip[i])
195  return false;
196  }
197  return true;
198  }
199 }
txid xip[FLEXIBLE_ARRAY_MEMBER]
Definition: txid.c:68
static struct @76 value
#define USE_BSEARCH_IF_NXIP_GREATER
Definition: txid.c:49
uint64 txid
Definition: txid.c:40
static int cmp_txid(const void *aa, const void *bb)
Definition: txid.c:123
unsigned int uint32
Definition: c.h:265
int i
uint32 nxip
Definition: txid.c:64
txid xmax
Definition: txid.c:66
static void load_xid_epoch ( TxidEpoch state)
static

Definition at line 90 of file txid.c.

References TxidEpoch::epoch, GetNextXidAndEpoch(), and TxidEpoch::last_xid.

Referenced by txid_current(), txid_current_if_assigned(), and txid_current_snapshot().

91 {
92  GetNextXidAndEpoch(&state->last_xid, &state->epoch);
93 }
TransactionId last_xid
Definition: txid.c:81
void GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch)
Definition: xlog.c:8223
uint32 epoch
Definition: txid.c:82
static TxidSnapshot* parse_snapshot ( const char *  str)
static

Definition at line 285 of file txid.c.

References buf, buf_add_txid(), buf_finalize(), buf_init(), ereport, errcode(), errmsg(), ERROR, NULL, str2txid(), and val.

Referenced by txid_snapshot_in().

286 {
287  txid xmin;
288  txid xmax;
289  txid last_val = 0,
290  val;
291  const char *str_start = str;
292  const char *endp;
293  StringInfo buf;
294 
295  xmin = str2txid(str, &endp);
296  if (*endp != ':')
297  goto bad_format;
298  str = endp + 1;
299 
300  xmax = str2txid(str, &endp);
301  if (*endp != ':')
302  goto bad_format;
303  str = endp + 1;
304 
305  /* it should look sane */
306  if (xmin == 0 || xmax == 0 || xmin > xmax)
307  goto bad_format;
308 
309  /* allocate buffer */
310  buf = buf_init(xmin, xmax);
311 
312  /* loop over values */
313  while (*str != '\0')
314  {
315  /* read next value */
316  val = str2txid(str, &endp);
317  str = endp;
318 
319  /* require the input to be in order */
320  if (val < xmin || val >= xmax || val < last_val)
321  goto bad_format;
322 
323  /* skip duplicates */
324  if (val != last_val)
325  buf_add_txid(buf, val);
326  last_val = val;
327 
328  if (*str == ',')
329  str++;
330  else if (*str != '\0')
331  goto bad_format;
332  }
333 
334  return buf_finalize(buf);
335 
336 bad_format:
337  ereport(ERROR,
338  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
339  errmsg("invalid input syntax for type %s: \"%s\"",
340  "txid_snapshot", str_start)));
341  return NULL; /* keep compiler quiet */
342 }
static void buf_add_txid(StringInfo buf, txid xid)
Definition: txid.c:221
static TxidSnapshot * buf_finalize(StringInfo buf)
Definition: txid.c:232
int errcode(int sqlerrcode)
Definition: elog.c:575
uint64 txid
Definition: txid.c:40
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:65
static StringInfo buf_init(txid xmin, txid xmax)
Definition: txid.c:206
#define ereport(elevel, rest)
Definition: elog.h:122
static txid str2txid(const char *s, const char **endp)
Definition: txid.c:251
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
long val
Definition: informix.c:689
static void sort_snapshot ( TxidSnapshot snap)
static

Definition at line 143 of file txid.c.

References cmp_txid(), TxidSnapshot::nxip, qsort, and TxidSnapshot::xip.

Referenced by txid_current_snapshot().

144 {
145  txid last = 0;
146  int nxip,
147  idx1,
148  idx2;
149 
150  if (snap->nxip > 1)
151  {
152  qsort(snap->xip, snap->nxip, sizeof(txid), cmp_txid);
153 
154  /* remove duplicates */
155  nxip = snap->nxip;
156  idx1 = idx2 = 0;
157  while (idx1 < nxip)
158  {
159  if (snap->xip[idx1] != last)
160  last = snap->xip[idx2++] = snap->xip[idx1];
161  else
162  snap->nxip--;
163  idx1++;
164  }
165  }
166 }
txid xip[FLEXIBLE_ARRAY_MEMBER]
Definition: txid.c:68
uint64 txid
Definition: txid.c:40
static int cmp_txid(const void *aa, const void *bb)
Definition: txid.c:123
uint32 nxip
Definition: txid.c:64
#define qsort(a, b, c, d)
Definition: port.h:440
static txid str2txid ( const char *  s,
const char **  endp 
)
static

Definition at line 251 of file txid.c.

References MAX_TXID, and val.

Referenced by parse_snapshot().

252 {
253  txid val = 0;
254  txid cutoff = MAX_TXID / 10;
255  txid cutlim = MAX_TXID % 10;
256 
257  for (; *s; s++)
258  {
259  unsigned d;
260 
261  if (*s < '0' || *s > '9')
262  break;
263  d = *s - '0';
264 
265  /*
266  * check for overflow
267  */
268  if (val > cutoff || (val == cutoff && d > cutlim))
269  {
270  val = 0;
271  break;
272  }
273 
274  val = val * 10 + d;
275  }
276  if (endp)
277  *endp = s;
278  return val;
279 }
uint64 txid
Definition: txid.c:40
#define MAX_TXID
Definition: txid.c:37
long val
Definition: informix.c:689
Datum txid_current ( PG_FUNCTION_ARGS  )

Definition at line 359 of file txid.c.

References convert_xid(), GetTopTransactionId(), load_xid_epoch(), PG_RETURN_INT64, PreventCommandDuringRecovery(), and val.

360 {
361  txid val;
363 
364  /*
365  * Must prevent during recovery because if an xid is not assigned we try
366  * to assign one, which would fail. Programs already rely on this function
367  * to always return a valid current xid, so we should not change this to
368  * return NULL or similar invalid xid.
369  */
370  PreventCommandDuringRecovery("txid_current()");
371 
372  load_xid_epoch(&state);
373 
374  val = convert_xid(GetTopTransactionId(), &state);
375 
376  PG_RETURN_INT64(val);
377 }
static void load_xid_epoch(TxidEpoch *state)
Definition: txid.c:90
Definition: txid.c:79
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
TransactionId GetTopTransactionId(void)
Definition: xact.c:388
uint64 txid
Definition: txid.c:40
static txid convert_xid(TransactionId xid, const TxidEpoch *state)
Definition: txid.c:99
void PreventCommandDuringRecovery(const char *cmdname)
Definition: utility.c:272
long val
Definition: informix.c:689
Datum txid_current_if_assigned ( PG_FUNCTION_ARGS  )

Definition at line 384 of file txid.c.

References convert_xid(), GetTopTransactionIdIfAny(), InvalidTransactionId, load_xid_epoch(), PG_RETURN_INT64, PG_RETURN_NULL, and val.

385 {
386  txid val;
389 
390  if (topxid == InvalidTransactionId)
391  PG_RETURN_NULL();
392 
393  load_xid_epoch(&state);
394 
395  val = convert_xid(topxid, &state);
396 
397  PG_RETURN_INT64(val);
398 }
static void load_xid_epoch(TxidEpoch *state)
Definition: txid.c:90
Definition: txid.c:79
uint32 TransactionId
Definition: c.h:394
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
uint64 txid
Definition: txid.c:40
static txid convert_xid(TransactionId xid, const TxidEpoch *state)
Definition: txid.c:99
#define InvalidTransactionId
Definition: transam.h:31
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:403
long val
Definition: informix.c:689
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum txid_current_snapshot ( PG_FUNCTION_ARGS  )

Definition at line 408 of file txid.c.

References convert_xid(), cur, elog, ERROR, GetActiveSnapshot(), i, load_xid_epoch(), MAX_BACKENDS, NULL, TxidSnapshot::nxip, palloc(), PG_RETURN_POINTER, SET_VARSIZE, sort_snapshot(), StaticAssertStmt, TXID_SNAPSHOT_MAX_NXIP, TXID_SNAPSHOT_SIZE, SnapshotData::xcnt, TxidSnapshot::xip, SnapshotData::xip, TxidSnapshot::xmax, SnapshotData::xmax, TxidSnapshot::xmin, and SnapshotData::xmin.

409 {
410  TxidSnapshot *snap;
411  uint32 nxip,
412  i;
414  Snapshot cur;
415 
416  cur = GetActiveSnapshot();
417  if (cur == NULL)
418  elog(ERROR, "no active snapshot set");
419 
420  load_xid_epoch(&state);
421 
422  /*
423  * Compile-time limits on the procarray (MAX_BACKENDS processes plus
424  * MAX_BACKENDS prepared transactions) guarantee nxip won't be too large.
425  */
427  "possible overflow in txid_current_snapshot()");
428 
429  /* allocate */
430  nxip = cur->xcnt;
431  snap = palloc(TXID_SNAPSHOT_SIZE(nxip));
432 
433  /* fill */
434  snap->xmin = convert_xid(cur->xmin, &state);
435  snap->xmax = convert_xid(cur->xmax, &state);
436  snap->nxip = nxip;
437  for (i = 0; i < nxip; i++)
438  snap->xip[i] = convert_xid(cur->xip[i], &state);
439 
440  /*
441  * We want them guaranteed to be in ascending order. This also removes
442  * any duplicate xids. Normally, an XID can only be assigned to one
443  * backend, but when preparing a transaction for two-phase commit, there
444  * is a transient state when both the original backend and the dummy
445  * PGPROC entry reserved for the prepared transaction hold the same XID.
446  */
447  sort_snapshot(snap);
448 
449  /* set size after sorting, because it may have removed duplicate xips */
450  SET_VARSIZE(snap, TXID_SNAPSHOT_SIZE(snap->nxip));
451 
452  PG_RETURN_POINTER(snap);
453 }
static void load_xid_epoch(TxidEpoch *state)
Definition: txid.c:90
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
txid xip[FLEXIBLE_ARRAY_MEMBER]
Definition: txid.c:68
Definition: txid.c:79
static void sort_snapshot(TxidSnapshot *snap)
Definition: txid.c:143
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:834
struct cursor * cur
Definition: ecpg.c:28
txid xmin
Definition: txid.c:65
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:753
static txid convert_xid(TransactionId xid, const TxidEpoch *state)
Definition: txid.c:99
#define ERROR
Definition: elog.h:43
#define MAX_BACKENDS
Definition: postmaster.h:75
unsigned int uint32
Definition: c.h:265
TransactionId xmax
Definition: snapshot.h:67
TransactionId xmin
Definition: snapshot.h:66
TransactionId * xip
Definition: snapshot.h:77
#define TXID_SNAPSHOT_SIZE(nxip)
Definition: txid.c:71
#define NULL
Definition: c.h:226
uint32 xcnt
Definition: snapshot.h:78
void * palloc(Size size)
Definition: mcxt.c:891
int i
uint32 nxip
Definition: txid.c:64
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
#define elog
Definition: elog.h:219
txid xmax
Definition: txid.c:66
#define TXID_SNAPSHOT_MAX_NXIP
Definition: txid.c:73
Datum txid_snapshot_in ( PG_FUNCTION_ARGS  )

Definition at line 461 of file txid.c.

References parse_snapshot(), PG_GETARG_CSTRING, and PG_RETURN_POINTER.

462 {
463  char *str = PG_GETARG_CSTRING(0);
464  TxidSnapshot *snap;
465 
466  snap = parse_snapshot(str);
467 
468  PG_RETURN_POINTER(snap);
469 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
static TxidSnapshot * parse_snapshot(const char *str)
Definition: txid.c:285
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:233
Datum txid_snapshot_out ( PG_FUNCTION_ARGS  )

Definition at line 477 of file txid.c.

References appendStringInfo(), appendStringInfoChar(), StringInfoData::data, i, initStringInfo(), TxidSnapshot::nxip, PG_GETARG_VARLENA_P, PG_RETURN_CSTRING, TXID_FMT, TxidSnapshot::xip, TxidSnapshot::xmax, and TxidSnapshot::xmin.

478 {
480  StringInfoData str;
481  uint32 i;
482 
483  initStringInfo(&str);
484 
485  appendStringInfo(&str, TXID_FMT ":", snap->xmin);
486  appendStringInfo(&str, TXID_FMT ":", snap->xmax);
487 
488  for (i = 0; i < snap->nxip; i++)
489  {
490  if (i > 0)
491  appendStringInfoChar(&str, ',');
492  appendStringInfo(&str, TXID_FMT, snap->xip[i]);
493  }
494 
495  PG_RETURN_CSTRING(str.data);
496 }
txid xip[FLEXIBLE_ARRAY_MEMBER]
Definition: txid.c:68
txid xmin
Definition: txid.c:65
#define TXID_FMT
Definition: txid.c:43
#define PG_GETARG_VARLENA_P(n)
Definition: fmgr.h:242
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
unsigned int uint32
Definition: c.h:265
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:306
int i
uint32 nxip
Definition: txid.c:64
txid xmax
Definition: txid.c:66
Datum txid_snapshot_recv ( PG_FUNCTION_ARGS  )

Definition at line 506 of file txid.c.

References buf, cur, ereport, errcode(), errmsg(), ERROR, i, MAX_TXID, NULL, TxidSnapshot::nxip, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, pq_getmsgint(), pq_getmsgint64(), SET_VARSIZE, TXID_SNAPSHOT_MAX_NXIP, TXID_SNAPSHOT_SIZE, TxidSnapshot::xip, TxidSnapshot::xmax, and TxidSnapshot::xmin.

507 {
509  TxidSnapshot *snap;
510  txid last = 0;
511  int nxip;
512  int i;
513  txid xmin,
514  xmax;
515 
516  /* load and validate nxip */
517  nxip = pq_getmsgint(buf, 4);
518  if (nxip < 0 || nxip > TXID_SNAPSHOT_MAX_NXIP)
519  goto bad_format;
520 
521  xmin = pq_getmsgint64(buf);
522  xmax = pq_getmsgint64(buf);
523  if (xmin == 0 || xmax == 0 || xmin > xmax || xmax > MAX_TXID)
524  goto bad_format;
525 
526  snap = palloc(TXID_SNAPSHOT_SIZE(nxip));
527  snap->xmin = xmin;
528  snap->xmax = xmax;
529 
530  for (i = 0; i < nxip; i++)
531  {
532  txid cur = pq_getmsgint64(buf);
533 
534  if (cur < last || cur < xmin || cur >= xmax)
535  goto bad_format;
536 
537  /* skip duplicate xips */
538  if (cur == last)
539  {
540  i--;
541  nxip--;
542  continue;
543  }
544 
545  snap->xip[i] = cur;
546  last = cur;
547  }
548  snap->nxip = nxip;
549  SET_VARSIZE(snap, TXID_SNAPSHOT_SIZE(nxip));
550  PG_RETURN_POINTER(snap);
551 
552 bad_format:
553  ereport(ERROR,
554  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
555  errmsg("invalid external txid_snapshot data")));
556  PG_RETURN_POINTER(NULL); /* keep compiler quiet */
557 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
txid xip[FLEXIBLE_ARRAY_MEMBER]
Definition: txid.c:68
StringInfoData * StringInfo
Definition: stringinfo.h:46
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
txid xmin
Definition: txid.c:65
uint64 txid
Definition: txid.c:40
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:65
#define ereport(elevel, rest)
Definition: elog.h:122
#define TXID_SNAPSHOT_SIZE(nxip)
Definition: txid.c:71
#define NULL
Definition: c.h:226
#define MAX_TXID
Definition: txid.c:37
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:486
uint32 nxip
Definition: txid.c:64
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:448
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
txid xmax
Definition: txid.c:66
#define TXID_SNAPSHOT_MAX_NXIP
Definition: txid.c:73
Datum txid_snapshot_send ( PG_FUNCTION_ARGS  )

Definition at line 567 of file txid.c.

References buf, i, TxidSnapshot::nxip, PG_GETARG_VARLENA_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint(), pq_sendint64(), TxidSnapshot::xip, TxidSnapshot::xmax, and TxidSnapshot::xmin.

568 {
571  uint32 i;
572 
573  pq_begintypsend(&buf);
574  pq_sendint(&buf, snap->nxip, 4);
575  pq_sendint64(&buf, snap->xmin);
576  pq_sendint64(&buf, snap->xmax);
577  for (i = 0; i < snap->nxip; i++)
578  pq_sendint64(&buf, snap->xip[i]);
580 }
txid xip[FLEXIBLE_ARRAY_MEMBER]
Definition: txid.c:68
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:313
txid xmin
Definition: txid.c:65
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
#define PG_GETARG_VARLENA_P(n)
Definition: fmgr.h:242
static char * buf
Definition: pg_test_fsync.c:65
unsigned int uint32
Definition: c.h:265
void pq_sendint(StringInfo buf, int i, int b)
Definition: pqformat.c:236
int i
uint32 nxip
Definition: txid.c:64
txid xmax
Definition: txid.c:66
void pq_sendint64(StringInfo buf, int64 i)
Definition: pqformat.c:271
Datum txid_snapshot_xip ( PG_FUNCTION_ARGS  )

Definition at line 628 of file txid.c.

References arg, FuncCallContext::call_cntr, Int64GetDatum(), MemoryContextAlloc(), FuncCallContext::multi_call_memory_ctx, TxidSnapshot::nxip, PG_GETARG_VARLENA_P, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, FuncCallContext::user_fctx, value, VARSIZE, and TxidSnapshot::xip.

629 {
630  FuncCallContext *fctx;
631  TxidSnapshot *snap;
632  txid value;
633 
634  /* on first call initialize snap_state and get copy of snapshot */
635  if (SRF_IS_FIRSTCALL())
636  {
638 
639  fctx = SRF_FIRSTCALL_INIT();
640 
641  /* make a copy of user snapshot */
643  memcpy(snap, arg, VARSIZE(arg));
644 
645  fctx->user_fctx = snap;
646  }
647 
648  /* return values one-by-one */
649  fctx = SRF_PERCALL_SETUP();
650  snap = fctx->user_fctx;
651  if (fctx->call_cntr < snap->nxip)
652  {
653  value = snap->xip[fctx->call_cntr];
654  SRF_RETURN_NEXT(fctx, Int64GetDatum(value));
655  }
656  else
657  {
658  SRF_RETURN_DONE(fctx);
659  }
660 }
uint64 call_cntr
Definition: funcapi.h:65
txid xip[FLEXIBLE_ARRAY_MEMBER]
Definition: txid.c:68
static struct @76 value
#define VARSIZE(PTR)
Definition: postgres.h:306
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:285
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:289
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:291
uint64 txid
Definition: txid.c:40
#define PG_GETARG_VARLENA_P(n)
Definition: fmgr.h:242
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:109
void * user_fctx
Definition: funcapi.h:90
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
uint32 nxip
Definition: txid.c:64
void * arg
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:309
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:287
Datum txid_snapshot_xmax ( PG_FUNCTION_ARGS  )

Definition at line 615 of file txid.c.

References PG_GETARG_VARLENA_P, PG_RETURN_INT64, and TxidSnapshot::xmax.

616 {
618 
619  PG_RETURN_INT64(snap->xmax);
620 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
#define PG_GETARG_VARLENA_P(n)
Definition: fmgr.h:242
txid xmax
Definition: txid.c:66
Datum txid_snapshot_xmin ( PG_FUNCTION_ARGS  )

Definition at line 602 of file txid.c.

References PG_GETARG_VARLENA_P, PG_RETURN_INT64, and TxidSnapshot::xmin.

603 {
605 
606  PG_RETURN_INT64(snap->xmin);
607 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
txid xmin
Definition: txid.c:65
#define PG_GETARG_VARLENA_P(n)
Definition: fmgr.h:242
Datum txid_visible_in_snapshot ( PG_FUNCTION_ARGS  )

Definition at line 588 of file txid.c.

References is_visible_txid(), PG_GETARG_INT64, PG_GETARG_VARLENA_P, PG_RETURN_BOOL, and value.

589 {
592 
593  PG_RETURN_BOOL(is_visible_txid(value, snap));
594 }
static struct @76 value
uint64 txid
Definition: txid.c:40
#define PG_GETARG_VARLENA_P(n)
Definition: fmgr.h:242
static bool is_visible_txid(txid value, const TxidSnapshot *snap)
Definition: txid.c:172
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
#define PG_GETARG_INT64(n)
Definition: fmgr.h:238