diff --git a/src/backend/utils/adt/txid.c b/src/backend/utils/adt/txid.c index a005e67..44f7880 100644 *** a/src/backend/utils/adt/txid.c --- b/src/backend/utils/adt/txid.c *************** cmp_txid(const void *aa, const void *bb) *** 131,146 **** } /* ! * sort a snapshot's txids, so we can use bsearch() later. * * For consistency of on-disk representation, we always sort even if bsearch ! * will not be used. */ static void sort_snapshot(TxidSnapshot *snap) { if (snap->nxip > 1) qsort(snap->xip, snap->nxip, sizeof(txid), cmp_txid); } /* --- 131,161 ---- } /* ! * unique sort a snapshot's txids, so we can use bsearch() later. * * For consistency of on-disk representation, we always sort even if bsearch ! * will not be used. */ static void sort_snapshot(TxidSnapshot *snap) { + txid last = 0; + int nxip, idx1, idx2; + if (snap->nxip > 1) + { qsort(snap->xip, snap->nxip, sizeof(txid), cmp_txid); + nxip = snap->nxip; + idx1 = idx2 = 0; + while (idx1 < nxip) + { + if (snap->xip[idx1] != last) + last = snap->xip[idx2++] = snap->xip[idx1]; + else + snap->nxip--; + idx1++; + } + } } /* *************** parse_snapshot(const char *str) *** 294,304 **** val = str2txid(str, &endp); str = endp; ! /* require the input to be in order */ ! if (val < xmin || val >= xmax || val <= last_val) goto bad_format; ! buf_add_txid(buf, val); last_val = val; if (*str == ',') --- 309,320 ---- val = str2txid(str, &endp); str = endp; ! /* require the input to be in order and skip duplicates */ ! if (val < xmin || val >= xmax || val < last_val) goto bad_format; ! if (val != last_val) ! buf_add_txid(buf, val); last_val = val; if (*str == ',') diff --git a/src/test/regress/expected/txid.out b/src/test/regress/expected/txid.out index 930b86a..7750b7b 100644 *** a/src/test/regress/expected/txid.out --- b/src/test/regress/expected/txid.out *************** select '12:18:14,16'::txid_snapshot; *** 12,17 **** --- 12,23 ---- 12:18:14,16 (1 row) + select '12:16:14,14'::txid_snapshot; + txid_snapshot + --------------- + 12:16:14 + (1 row) + -- errors select '31:12:'::txid_snapshot; ERROR: invalid input for txid_snapshot: "31:12:" *************** select '12:16:14,13'::txid_snapshot; *** 29,38 **** ERROR: invalid input for txid_snapshot: "12:16:14,13" LINE 1: select '12:16:14,13'::txid_snapshot; ^ - select '12:16:14,14'::txid_snapshot; - ERROR: invalid input for txid_snapshot: "12:16:14,14" - LINE 1: select '12:16:14,14'::txid_snapshot; - ^ create temp table snapshot_test ( nr integer, snap txid_snapshot --- 35,40 ---- diff --git a/src/test/regress/sql/txid.sql b/src/test/regress/sql/txid.sql index ecae10e..b6650b9 100644 *** a/src/test/regress/sql/txid.sql --- b/src/test/regress/sql/txid.sql *************** *** 3,15 **** -- i/o select '12:13:'::txid_snapshot; select '12:18:14,16'::txid_snapshot; -- errors select '31:12:'::txid_snapshot; select '0:1:'::txid_snapshot; select '12:13:0'::txid_snapshot; select '12:16:14,13'::txid_snapshot; - select '12:16:14,14'::txid_snapshot; create temp table snapshot_test ( nr integer, --- 3,15 ---- -- i/o select '12:13:'::txid_snapshot; select '12:18:14,16'::txid_snapshot; + select '12:16:14,14'::txid_snapshot; -- errors select '31:12:'::txid_snapshot; select '0:1:'::txid_snapshot; select '12:13:0'::txid_snapshot; select '12:16:14,13'::txid_snapshot; create temp table snapshot_test ( nr integer,