Index: contrib/txid/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/txid/Makefile,v
retrieving revision 1.1
diff -p -u -c -r1.1 Makefile
*** contrib/txid/Makefile	7 Oct 2007 23:32:19 -0000	1.1
--- contrib/txid/Makefile	11 Oct 2007 12:30:51 -0000
*************** include $(top_builddir)/src/Makefile.glo
*** 17,26 ****
  include $(top_srcdir)/contrib/contrib-global.mk
  endif
  
- 
- test: install
- 	$(MAKE) installcheck || { less regression.diffs; exit 1; }
- 
- ack:
- 	cp results/* expected/
- 
--- 17,19 ----
Index: contrib/txid/txid.c
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/txid/txid.c,v
retrieving revision 1.3
diff -p -u -c -r1.3 txid.c
*** contrib/txid/txid.c	8 Oct 2007 22:07:16 -0000	1.3
--- contrib/txid/txid.c	11 Oct 2007 12:30:51 -0000
***************
*** 15,20 ****
--- 15,21 ----
  #include "access/transam.h"
  #include "access/xact.h"
  #include "funcapi.h"
+ #include "libpq/pqformat.h"
  
  #ifdef PG_MODULE_MAGIC
  PG_MODULE_MAGIC;
*************** typedef struct {
*** 71,76 ****
--- 72,79 ----
  /* public functions */
  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_current(PG_FUNCTION_ARGS);
  Datum       txid_current_snapshot(PG_FUNCTION_ARGS);
  Datum       txid_snapshot_xmin(PG_FUNCTION_ARGS);
*************** Datum       txid_visible_in_snapshot(PG_
*** 81,86 ****
--- 84,91 ----
  /* public function tags */
  PG_FUNCTION_INFO_V1(txid_snapshot_in);
  PG_FUNCTION_INFO_V1(txid_snapshot_out);
+ PG_FUNCTION_INFO_V1(txid_snapshot_recv);
+ PG_FUNCTION_INFO_V1(txid_snapshot_send);
  PG_FUNCTION_INFO_V1(txid_current);
  PG_FUNCTION_INFO_V1(txid_current_snapshot);
  PG_FUNCTION_INFO_V1(txid_snapshot_xmin);
*************** bad_format:
*** 319,325 ****
  }
  
  /*
!  * Public functions
   */
  
  /*
--- 324,341 ----
  }
  
  /*
!  * Public functions.
!  *
!  * txid_current() and txid_current_snapshot() are the only ones that
!  * communicate with backend xid machinery.  All the others work on data
!  * returned by them.
!  *
!  * So they define what an external transaction will be and their
!  * definitions must match.  Eg. if one returns subtransactions ids
!  * then other must also.
!  *
!  * Currently only top-level transaction id's are tracked, so they use
!  * GetTopTransactionId() and ActiveSnapshot->xip respectively.
   */
  
  /*
*************** txid_current_snapshot(PG_FUNCTION_ARGS)
*** 353,361 ****
  	TxidEpoch state;
  	Snapshot cur;
  
! 	cur = SerializableSnapshot;
  	if (cur == NULL)
! 		elog(ERROR, "get_current_snapshot: SerializableSnapshot == NULL");
  
  	load_xid_epoch(&state);
  
--- 369,377 ----
  	TxidEpoch state;
  	Snapshot cur;
  
! 	cur = ActiveSnapshot;
  	if (cur == NULL)
! 		elog(ERROR, "txid_current_snapshot: ActiveSnapshot == NULL");
  
  	load_xid_epoch(&state);
  
*************** txid_snapshot_out(PG_FUNCTION_ARGS)
*** 425,430 ****
--- 441,526 ----
  	PG_RETURN_CSTRING(str.data);
  }
  
+ /*
+  * txid_snapshot_recv(internal) returns txid_snapshot
+  *
+  *		binary input function for type txid_snapshot
+  *
+  *		format: int4 nxip, int8 xmin, int8 xmax, int8 xip
+  */
+ Datum
+ txid_snapshot_recv(PG_FUNCTION_ARGS)
+ {
+ 	StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
+ 	TxidSnapshot *snap;
+ 	txid last = 0;
+ 	int nxip;
+ 	int i;
+ 	int avail;
+ 	int expect;
+ 	txid xmin, xmax;
+ 
+ 	/*
+ 	 * load nxip and check for nonsense.
+ 	 *
+ 	 * (nxip > avail) check is against int overflows in 'expect'.
+ 	 */
+ 	nxip = pq_getmsgint(buf, 4);
+ 	avail = buf->len - buf->cursor;
+ 	expect = 8 + 8 + nxip * 8;
+ 	if (nxip < 0 || nxip > avail || expect > avail)
+ 		goto bad_format;
+ 
+ 	xmin = pq_getmsgint64(buf);
+ 	xmax = pq_getmsgint64(buf);
+ 	if (xmin == 0 || xmax == 0 || xmin > xmax || xmax > MAX_TXID)
+ 		goto bad_format;
+ 
+ 	snap = palloc(TXID_SNAPSHOT_SIZE(nxip));
+ 	snap->xmin = xmin;
+ 	snap->xmax = xmax;
+ 	snap->nxip = nxip;
+ 	SET_VARSIZE(snap, TXID_SNAPSHOT_SIZE(nxip));
+ 
+ 	for (i = 0; i < nxip; i++)
+ 	{
+ 		txid cur =  pq_getmsgint64(buf);
+ 		if (cur <= last || cur < xmin || cur >= xmax)
+ 			goto bad_format;
+ 		snap->xip[i] = cur;
+ 		last = cur;
+ 	}
+ 	PG_RETURN_POINTER(snap);
+ 
+ bad_format:
+ 	elog(ERROR, "invalid snapshot data");
+ 	return (Datum)NULL;
+ }
+ 
+ /*
+  * txid_snapshot_send(txid_snapshot) returns bytea
+  *
+  *		binary output function for type txid_snapshot
+  *
+  *		format: int4 nxip, int8 xmin, int8 xmax, int8 xip
+  */
+ Datum
+ txid_snapshot_send(PG_FUNCTION_ARGS)
+ {
+ 	TxidSnapshot *snap;
+ 	StringInfoData buf;
+ 	int i;
+ 
+ 	snap = (TxidSnapshot *)PG_GETARG_VARLENA_P(0);
+ 
+ 	pq_begintypsend(&buf);
+ 	pq_sendint(&buf, snap->nxip, 4);
+ 	pq_sendint64(&buf, snap->xmin);
+ 	pq_sendint64(&buf, snap->xmax);
+ 	for (i = 0; i < snap->nxip; i++)
+ 		pq_sendint64(&buf, snap->xip[i]);
+ 	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+ }
  
  /*
   * txid_visible_in_snapshot(int8, txid_snapshot) returns bool
Index: contrib/txid/txid.sql.in
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/txid/txid.sql.in,v
retrieving revision 1.1
diff -p -u -c -r1.1 txid.sql.in
*** contrib/txid/txid.sql.in	7 Oct 2007 23:32:19 -0000	1.1
--- contrib/txid/txid.sql.in	11 Oct 2007 12:30:52 -0000
*************** CREATE OR REPLACE FUNCTION txid_snapshot
*** 20,25 ****
--- 20,33 ----
  	RETURNS cstring
  	AS 'MODULE_PATHNAME' LANGUAGE C
  	IMMUTABLE STRICT;
+ CREATE OR REPLACE FUNCTION txid_snapshot_recv(internal)
+ 	RETURNS txid_snapshot
+ 	AS 'MODULE_PATHNAME' LANGUAGE C
+ 	IMMUTABLE STRICT;
+ CREATE OR REPLACE FUNCTION txid_snapshot_send(txid_snapshot)
+ 	RETURNS bytea
+ 	AS 'MODULE_PATHNAME' LANGUAGE C
+ 	IMMUTABLE STRICT;
  
  --
  -- The data type itself
*************** CREATE OR REPLACE FUNCTION txid_snapshot
*** 27,32 ****
--- 35,42 ----
  CREATE TYPE txid_snapshot (
  	INPUT = txid_snapshot_in,
  	OUTPUT = txid_snapshot_out,
+ 	RECEIVE = txid_snapshot_recv,
+ 	SEND = txid_snapshot_send,
  	INTERNALLENGTH = variable,
  	STORAGE = extended,
  	ALIGNMENT = double
