From 17333b6d0946ed71ec17d186014259ae76326d11 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 13 Oct 2007 22:59:43 +0000 Subject: [PATCH] Remove contrib/txid, in preparation for migrating it into core. --- contrib/Makefile | 3 +- contrib/txid/Makefile | 18 - contrib/txid/README.txid | 106 ------ contrib/txid/expected/txid.out | 221 ------------ contrib/txid/sql/txid.sql | 61 ---- contrib/txid/txid.c | 603 -------------------------------- contrib/txid/txid.sql.in | 87 ----- contrib/txid/uninstall_txid.sql | 11 - 8 files changed, 1 insertion(+), 1109 deletions(-) delete mode 100644 contrib/txid/Makefile delete mode 100644 contrib/txid/README.txid delete mode 100644 contrib/txid/expected/txid.out delete mode 100644 contrib/txid/sql/txid.sql delete mode 100644 contrib/txid/txid.c delete mode 100644 contrib/txid/txid.sql.in delete mode 100644 contrib/txid/uninstall_txid.sql diff --git a/contrib/Makefile b/contrib/Makefile index dc03cf981f..3f49645036 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -1,4 +1,4 @@ -# $PostgreSQL: pgsql/contrib/Makefile,v 1.79 2007/10/07 23:32:19 wieck Exp $ +# $PostgreSQL: pgsql/contrib/Makefile,v 1.80 2007/10/13 22:59:43 tgl Exp $ subdir = contrib top_builddir = .. @@ -30,7 +30,6 @@ WANTED_DIRS = \ pgstattuple \ seg \ spi \ - txid \ tablefunc \ vacuumlo diff --git a/contrib/txid/Makefile b/contrib/txid/Makefile deleted file mode 100644 index 2d71ee7269..0000000000 --- a/contrib/txid/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $PostgreSQL: pgsql/contrib/txid/Makefile,v 1.2 2007/10/11 19:54:17 tgl Exp $ - -MODULES = txid -DATA_built = txid.sql -DATA = uninstall_txid.sql -DOCS = README.txid -REGRESS = txid - -ifdef USE_PGXS -PG_CONFIG = pg_config -PGXS := $(shell $(PG_CONFIG) --pgxs) -include $(PGXS) -else -subdir = contrib/txid -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global -include $(top_srcdir)/contrib/contrib-global.mk -endif diff --git a/contrib/txid/README.txid b/contrib/txid/README.txid deleted file mode 100644 index 7b39235bf3..0000000000 --- a/contrib/txid/README.txid +++ /dev/null @@ -1,106 +0,0 @@ -txid - export transaction IDs to user level -=========================================== - -The goal is to make PostgreSQL's internal transaction ID and snapshot -data usable externally. This allows very efficient queue -implementation done inside database. - -[towrite: what snapshot means] - -The module defines type txid_snapshot and following functions: - - -txid_current() returns int8 - - Current transaction ID. - -txid_current_snapshot() returns txid_snapshot - - Current snapshot. - -txid_snapshot_xmin( snap ) returns int8 - - Smallest TXID in snapshot. TXID's smaller than this - are all visible in snapshot. - -txid_snapshot_xmax( snap ) returns int8 - - Largest TXID in snapshot. TXID's starting from this one are - all invisible in snapshot. - -txid_snapshot_xip( snap ) setof int8 - - List of in-progress TXID's in snapshot, that are invisible. - Values are between xmin (inclusive) and xmax (exclusive). - -txid_visible_in_snapshot(id, snap) returns bool - - Is TXID visible in snapshot? - - -Fetching events ---------------- - -Lets say there is following event table: - - CREATE TABLE events ( - ev_txid int8 not null default txid_current(), - ev_data text - ); - CREATE INDEX ev_txid_idx ON events (ev_txid); - -Then event between 2 snapshots snap1 and snap2 can be fetched -with followign query: - - SELECT ev_data FROM events - WHERE ev_txid >= txid_snapshot_xmin(:snap1) - AND ev_txid < txid_snapshot_xmax(:snap2) - AND NOT txid_visible_in_snapshot(ev_txid, :snap1) - AND txid_visible_in_snapshot(ev_txid, :snap2); - -This is the simplest query but it has problem if there are long -transactions running - the txid_snapshot_xmin(snap1) will stay low -and the range will get very large. - -This can be fixed by fetching only snap1.xmax ... snap1.xmax by range and -fetching possible txids below snap1.xmax explicitly: - - SELECT ev_data FROM events - WHERE ((ev_txid >= txid_snapshot_xmax(:snap1) AND ev_txid < txid_snapshot_xmax(:snap2)) - OR - (ev_txid IN (SELECT * FROM txid_snapshot_xip(:snap1)))) - AND NOT txid_visible_in_snapshot(ev_txid, :snap1) - AND txid_visible_in_snapshot(ev_txid, :snap2); - -Note that although the above queries work, PostgreSQL fails to -plan them efficiently. For actual usage the values for txid_snapshot_xmin, -txid_snapshot_xmax and txid_snapshot_xip should be filled in directly, -only then will they use index. - -There are few more optimizations possible, like: - -- Picking out only TXIDs that were actually committed between snap1 and snap2. - -- Lowering the range from txid_snapshot_xmax(snap1) to decrease the list if TXIDs to be fetched separately. - -To see example code for that it's best to see pgq.batch_event_sql() function in Skytools. - - http://pgfoundry.org/projects/skytools/ - - -Dumping and restoring data containing TXIDs. --------------------------------------------- - -When reloading TXID data you will typically want to be sure that the current -XID counter is beyond the reloaded data. The easiest way to do this is to -increase the XID epoch to beyond the largest one in the input data. - -You can look at current epoch with queries such as: - - SELECT MAX(txid) >> 32 as epoch FROM ...; - -Epoch can be changed with pg_resetxlog command: - - pg_resetxlog -e NEWEPOCH DATADIR - -Database needs to be shut down for that moment. diff --git a/contrib/txid/expected/txid.out b/contrib/txid/expected/txid.out deleted file mode 100644 index 1b0da20b5f..0000000000 --- a/contrib/txid/expected/txid.out +++ /dev/null @@ -1,221 +0,0 @@ --- init -\set ECHO none --- i/o -select '12:13:'::txid_snapshot; - txid_snapshot ---------------- - 12:13: -(1 row) - -select '12:13:1,2'::txid_snapshot; -ERROR: invalid input for txid_snapshot: "12:13:1,2" --- errors -select '31:12:'::txid_snapshot; -ERROR: invalid input for txid_snapshot: "31:12:" -select '0:1:'::txid_snapshot; -ERROR: invalid input for txid_snapshot: "0:1:" -select '12:13:0'::txid_snapshot; -ERROR: invalid input for txid_snapshot: "12:13:0" -select '12:16:14,13'::txid_snapshot; -ERROR: invalid input for txid_snapshot: "12:16:14,13" -select '12:16:14,14'::txid_snapshot; -ERROR: invalid input for txid_snapshot: "12:16:14,14" -create table snapshot_test ( - nr integer, - snap txid_snapshot -); -insert into snapshot_test values (1, '12:13:'); -insert into snapshot_test values (2, '12:20:13,15,18'); -insert into snapshot_test values (3, '100001:100009:100005,100007,100008'); -insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131'); -select snap from snapshot_test order by nr; - snap -------------------------------------------------------------------------------------------------------------------------------------- - 12:13: - 12:20:13,15,18 - 100001:100009:100005,100007,100008 - 100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131 -(4 rows) - -select txid_snapshot_xmin(snap), - txid_snapshot_xmax(snap), - txid_snapshot_xip(snap) -from snapshot_test order by nr; - txid_snapshot_xmin | txid_snapshot_xmax | txid_snapshot_xip ---------------------+--------------------+------------------- - 12 | 20 | 13 - 12 | 20 | 15 - 12 | 20 | 18 - 100001 | 100009 | 100005 - 100001 | 100009 | 100007 - 100001 | 100009 | 100008 - 100 | 150 | 101 - 100 | 150 | 102 - 100 | 150 | 103 - 100 | 150 | 104 - 100 | 150 | 105 - 100 | 150 | 106 - 100 | 150 | 107 - 100 | 150 | 108 - 100 | 150 | 109 - 100 | 150 | 110 - 100 | 150 | 111 - 100 | 150 | 112 - 100 | 150 | 113 - 100 | 150 | 114 - 100 | 150 | 115 - 100 | 150 | 116 - 100 | 150 | 117 - 100 | 150 | 118 - 100 | 150 | 119 - 100 | 150 | 120 - 100 | 150 | 121 - 100 | 150 | 122 - 100 | 150 | 123 - 100 | 150 | 124 - 100 | 150 | 125 - 100 | 150 | 126 - 100 | 150 | 127 - 100 | 150 | 128 - 100 | 150 | 129 - 100 | 150 | 130 - 100 | 150 | 131 -(37 rows) - -select id, txid_visible_in_snapshot(id, snap) -from snapshot_test, generate_series(11, 21) id -where nr = 2; - id | txid_visible_in_snapshot -----+-------------------------- - 11 | t - 12 | t - 13 | f - 14 | t - 15 | f - 16 | t - 17 | t - 18 | f - 19 | t - 20 | f - 21 | f -(11 rows) - --- test bsearch -select id, txid_visible_in_snapshot(id, snap) -from snapshot_test, generate_series(90, 160) id -where nr = 4; - id | txid_visible_in_snapshot ------+-------------------------- - 90 | t - 91 | t - 92 | t - 93 | t - 94 | t - 95 | t - 96 | t - 97 | t - 98 | t - 99 | t - 100 | t - 101 | f - 102 | f - 103 | f - 104 | f - 105 | f - 106 | f - 107 | f - 108 | f - 109 | f - 110 | f - 111 | f - 112 | f - 113 | f - 114 | f - 115 | f - 116 | f - 117 | f - 118 | f - 119 | f - 120 | f - 121 | f - 122 | f - 123 | f - 124 | f - 125 | f - 126 | f - 127 | f - 128 | f - 129 | f - 130 | f - 131 | f - 132 | t - 133 | t - 134 | t - 135 | t - 136 | t - 137 | t - 138 | t - 139 | t - 140 | t - 141 | t - 142 | t - 143 | t - 144 | t - 145 | t - 146 | t - 147 | t - 148 | t - 149 | t - 150 | f - 151 | f - 152 | f - 153 | f - 154 | f - 155 | f - 156 | f - 157 | f - 158 | f - 159 | f - 160 | f -(71 rows) - --- test current values also -select txid_current() >= txid_snapshot_xmin(txid_current_snapshot()); - ?column? ----------- - t -(1 row) - -/* due to lazy xid alloc in 8.3 those are different in 8.2 and 8.3 -select txid_current() < txid_snapshot_xmax(txid_current_snapshot()); - -select txid_visible_in_snapshot(txid_current(), txid_current_snapshot()); -*/ --- test 64bitness -select txid_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013'; - txid_snapshot ---------------------------------------------------------------------- - 1000100010001000:1000100010001100:1000100010001012,1000100010001013 -(1 row) - -select txid_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); - txid_visible_in_snapshot --------------------------- - f -(1 row) - -select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); - txid_visible_in_snapshot --------------------------- - t -(1 row) - --- test 64bit overflow -SELECT txid_snapshot '1:9223372036854775807:3'; - txid_snapshot -------------------------- - 1:9223372036854775807:3 -(1 row) - -SELECT txid_snapshot '1:9223372036854775808:3'; -ERROR: invalid input for txid_snapshot: "1:9223372036854775808:3" diff --git a/contrib/txid/sql/txid.sql b/contrib/txid/sql/txid.sql deleted file mode 100644 index efedb86bfa..0000000000 --- a/contrib/txid/sql/txid.sql +++ /dev/null @@ -1,61 +0,0 @@ --- init -\set ECHO none -set client_min_messages = 'warning'; -\i txid.sql -set client_min_messages = 'notice'; -\set ECHO all - --- i/o -select '12:13:'::txid_snapshot; -select '12:13:1,2'::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 table snapshot_test ( - nr integer, - snap txid_snapshot -); - -insert into snapshot_test values (1, '12:13:'); -insert into snapshot_test values (2, '12:20:13,15,18'); -insert into snapshot_test values (3, '100001:100009:100005,100007,100008'); -insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131'); -select snap from snapshot_test order by nr; - -select txid_snapshot_xmin(snap), - txid_snapshot_xmax(snap), - txid_snapshot_xip(snap) -from snapshot_test order by nr; - -select id, txid_visible_in_snapshot(id, snap) -from snapshot_test, generate_series(11, 21) id -where nr = 2; - --- test bsearch -select id, txid_visible_in_snapshot(id, snap) -from snapshot_test, generate_series(90, 160) id -where nr = 4; - --- test current values also -select txid_current() >= txid_snapshot_xmin(txid_current_snapshot()); - -/* due to lazy xid alloc in 8.3 those are different in 8.2 and 8.3 -select txid_current() < txid_snapshot_xmax(txid_current_snapshot()); - -select txid_visible_in_snapshot(txid_current(), txid_current_snapshot()); -*/ - --- test 64bitness - -select txid_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013'; -select txid_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); -select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); - --- test 64bit overflow -SELECT txid_snapshot '1:9223372036854775807:3'; -SELECT txid_snapshot '1:9223372036854775808:3'; diff --git a/contrib/txid/txid.c b/contrib/txid/txid.c deleted file mode 100644 index 9a89a0631a..0000000000 --- a/contrib/txid/txid.c +++ /dev/null @@ -1,603 +0,0 @@ -/*------------------------------------------------------------------------- - * txid.c - * - * Export internal transaction IDs to user level. - * - * Note that only top-level transaction IDs are ever converted to TXID. - * This is important because TXIDs frequently persist beyond the global - * xmin horizon, or may even be shipped to other machines, so we cannot - * rely on being able to correlate subtransaction IDs with their parents - * via functions such as SubTransGetTopmostTransaction(). - * - * - * Copyright (c) 2003-2007, PostgreSQL Global Development Group - * Author: Jan Wieck, Afilias USA INC. - * 64-bit txids: Marko Kreen, Skype Technologies - * - * $PostgreSQL: pgsql/contrib/txid/txid.c,v 1.4 2007/10/11 19:54:17 tgl Exp $ - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include "access/transam.h" -#include "access/xact.h" -#include "funcapi.h" -#include "libpq/pqformat.h" - - -PG_MODULE_MAGIC; - -#ifdef INT64_IS_BUSTED -#error txid needs working int64 -#endif - -/* txid will be signed int8 in database, so must limit to 63 bits */ -#define MAX_TXID UINT64CONST(0x7FFFFFFFFFFFFFFF) - -/* Use unsigned variant internally */ -typedef uint64 txid; - -/* sprintf format code for uint64 */ -#define TXID_FMT UINT64_FORMAT - -/* - * If defined, use bsearch() function for searching for txids in snapshots - * that have more than the specified number of values. - */ -#define USE_BSEARCH_IF_NXIP_GREATER 30 - - -/* - * Snapshot containing 8byte txids. - */ -typedef struct -{ - /* - * 4-byte length hdr, should not be touched directly. - * - * Explicit embedding is ok as we want always correct - * alignment anyway. - */ - int32 __varsz; - - uint32 nxip; /* number of txids in xip array */ - txid xmin; - txid xmax; - txid xip[1]; /* in-progress txids, xmin <= xip[i] < xmax */ -} TxidSnapshot; - -#define TXID_SNAPSHOT_SIZE(nxip) \ - (offsetof(TxidSnapshot, xip) + sizeof(txid) * (nxip)) - -/* - * Epoch values from xact.c - */ -typedef struct -{ - TransactionId last_xid; - uint32 epoch; -} TxidEpoch; - - -/* 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_snapshot_xmax(PG_FUNCTION_ARGS); -Datum txid_snapshot_xip(PG_FUNCTION_ARGS); -Datum txid_visible_in_snapshot(PG_FUNCTION_ARGS); - -/* 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); -PG_FUNCTION_INFO_V1(txid_snapshot_xmax); -PG_FUNCTION_INFO_V1(txid_snapshot_xip); -PG_FUNCTION_INFO_V1(txid_visible_in_snapshot); - - -/* - * Fetch epoch data from xact.c. - */ -static void -load_xid_epoch(TxidEpoch *state) -{ - GetNextXidAndEpoch(&state->last_xid, &state->epoch); -} - -/* - * do a TransactionId -> txid conversion for an XID near the given epoch - */ -static txid -convert_xid(TransactionId xid, const TxidEpoch *state) -{ - uint64 epoch; - - /* return special xid's as-is */ - if (!TransactionIdIsNormal(xid)) - return (txid) xid; - - /* xid can be on either side when near wrap-around */ - epoch = (uint64) state->epoch; - if (xid > state->last_xid && - TransactionIdPrecedes(xid, state->last_xid)) - epoch--; - else if (xid < state->last_xid && - TransactionIdFollows(xid, state->last_xid)) - epoch++; - - return (epoch << 32) | xid; -} - -/* - * txid comparator for qsort/bsearch - */ -static int -cmp_txid(const void *aa, const void *bb) -{ - txid a = *(const txid *) aa; - txid b = *(const txid *) bb; - - if (a < b) - return -1; - if (a > b) - return 1; - return 0; -} - -/* - * 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); -} - -/* - * check txid visibility. - */ -static bool -is_visible_txid(txid value, const TxidSnapshot *snap) -{ - if (value < snap->xmin) - return true; - else if (value >= snap->xmax) - return false; -#ifdef USE_BSEARCH_IF_NXIP_GREATER - else if (snap->nxip > USE_BSEARCH_IF_NXIP_GREATER) - { - void *res; - - res = bsearch(&value, snap->xip, snap->nxip, sizeof(txid), cmp_txid); - /* if found, transaction is still in progress */ - return (res) ? false : true; - } -#endif - else - { - uint32 i; - - for (i = 0; i < snap->nxip; i++) - { - if (value == snap->xip[i]) - return false; - } - return true; - } -} - -/* - * helper functions to use StringInfo for TxidSnapshot creation. - */ - -static StringInfo -buf_init(txid xmin, txid xmax) -{ - TxidSnapshot snap; - StringInfo buf; - - snap.xmin = xmin; - snap.xmax = xmax; - snap.nxip = 0; - - buf = makeStringInfo(); - appendBinaryStringInfo(buf, (char *)&snap, TXID_SNAPSHOT_SIZE(0)); - return buf; -} - -static void -buf_add_txid(StringInfo buf, txid xid) -{ - TxidSnapshot *snap = (TxidSnapshot *)buf->data; - - /* do this before possible realloc */ - snap->nxip++; - - appendBinaryStringInfo(buf, (char *)&xid, sizeof(xid)); -} - -static TxidSnapshot * -buf_finalize(StringInfo buf) -{ - TxidSnapshot *snap = (TxidSnapshot *)buf->data; - - SET_VARSIZE(snap, buf->len); - - /* buf is not needed anymore */ - buf->data = NULL; - pfree(buf); - - return snap; -} - -/* - * simple number parser. - * - * We return 0 on error, which is invalid value for txid. - */ -static txid -str2txid(const char *s, const char **endp) -{ - txid val = 0; - txid cutoff = MAX_TXID / 10; - txid cutlim = MAX_TXID % 10; - - for (; *s; s++) - { - unsigned d; - - if (*s < '0' || *s > '9') - break; - d = *s - '0'; - - /* - * check for overflow - */ - if (val > cutoff || (val == cutoff && d > cutlim)) - { - val = 0; - break; - } - - val = val * 10 + d; - } - if (endp) - *endp = s; - return val; -} - -/* - * parse snapshot from cstring - */ -static TxidSnapshot * -parse_snapshot(const char *str) -{ - txid xmin; - txid xmax; - txid last_val = 0, val; - const char *str_start = str; - const char *endp; - StringInfo buf; - - xmin = str2txid(str, &endp); - if (*endp != ':') - goto bad_format; - str = endp + 1; - - xmax = str2txid(str, &endp); - if (*endp != ':') - goto bad_format; - str = endp + 1; - - /* it should look sane */ - if (xmin == 0 || xmax == 0 || xmin > xmax) - goto bad_format; - - /* allocate buffer */ - buf = buf_init(xmin, xmax); - - /* loop over values */ - while (*str != '\0') - { - /* read next value */ - 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 == ',') - str++; - else if (*str != '\0') - goto bad_format; - } - - return buf_finalize(buf); - -bad_format: - elog(ERROR, "invalid input for txid_snapshot: \"%s\"", str_start); - return NULL; -} - -/* - * Public functions. - * - * txid_current() and txid_current_snapshot() are the only ones that - * communicate with core xid machinery. All the others work on data - * returned by them. - */ - -/* - * txid_current() returns int8 - * - * Return the current toplevel transaction ID as TXID - */ -Datum -txid_current(PG_FUNCTION_ARGS) -{ - txid val; - TxidEpoch state; - - load_xid_epoch(&state); - - val = convert_xid(GetTopTransactionId(), &state); - - PG_RETURN_INT64(val); -} - -/* - * txid_current_snapshot() returns txid_snapshot - * - * Return current snapshot in TXID format - * - * Note that only top-transaction XIDs are included in the snapshot. - */ -Datum -txid_current_snapshot(PG_FUNCTION_ARGS) -{ - TxidSnapshot *snap; - uint32 nxip, i, size; - TxidEpoch state; - Snapshot cur; - - cur = ActiveSnapshot; - if (cur == NULL) - elog(ERROR, "txid_current_snapshot: ActiveSnapshot == NULL"); - - load_xid_epoch(&state); - - /* allocate */ - nxip = cur->xcnt; - size = TXID_SNAPSHOT_SIZE(nxip); - snap = palloc(size); - SET_VARSIZE(snap, size); - - /* fill */ - snap->xmin = convert_xid(cur->xmin, &state); - snap->xmax = convert_xid(cur->xmax, &state); - snap->nxip = nxip; - for (i = 0; i < nxip; i++) - snap->xip[i] = convert_xid(cur->xip[i], &state); - - /* we want them guaranteed to be in ascending order */ - sort_snapshot(snap); - - PG_RETURN_POINTER(snap); -} - -/* - * txid_snapshot_in(cstring) returns txid_snapshot - * - * input function for type txid_snapshot - */ -Datum -txid_snapshot_in(PG_FUNCTION_ARGS) -{ - char *str = PG_GETARG_CSTRING(0); - TxidSnapshot *snap; - - snap = parse_snapshot(str); - - PG_RETURN_POINTER(snap); -} - -/* - * txid_snapshot_out(txid_snapshot) returns cstring - * - * output function for type txid_snapshot - */ -Datum -txid_snapshot_out(PG_FUNCTION_ARGS) -{ - TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(0); - StringInfoData str; - uint32 i; - - initStringInfo(&str); - - appendStringInfo(&str, TXID_FMT ":", snap->xmin); - appendStringInfo(&str, TXID_FMT ":", snap->xmax); - - for (i = 0; i < snap->nxip; i++) - { - if (i > 0) - appendStringInfoChar(&str, ','); - appendStringInfo(&str, TXID_FMT, snap->xip[i]); - } - - 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 = (TxidSnapshot *)PG_GETARG_VARLENA_P(0); - StringInfoData buf; - uint32 i; - - 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 - * - * is txid visible in snapshot ? - */ -Datum -txid_visible_in_snapshot(PG_FUNCTION_ARGS) -{ - txid value = PG_GETARG_INT64(0); - TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(1); - - PG_RETURN_BOOL(is_visible_txid(value, snap)); -} - -/* - * txid_snapshot_xmin(txid_snapshot) returns int8 - * - * return snapshot's xmin - */ -Datum -txid_snapshot_xmin(PG_FUNCTION_ARGS) -{ - TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(0); - - PG_RETURN_INT64(snap->xmin); -} - -/* - * txid_snapshot_xmax(txid_snapshot) returns int8 - * - * return snapshot's xmax - */ -Datum -txid_snapshot_xmax(PG_FUNCTION_ARGS) -{ - TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(0); - - PG_RETURN_INT64(snap->xmax); -} - -/* - * txid_snapshot_xip(txid_snapshot) returns setof int8 - * - * return in-progress TXIDs in snapshot. - */ -Datum -txid_snapshot_xip(PG_FUNCTION_ARGS) -{ - FuncCallContext *fctx; - TxidSnapshot *snap; - txid value; - - /* on first call initialize snap_state and get copy of snapshot */ - if (SRF_IS_FIRSTCALL()) { - TxidSnapshot *arg = (TxidSnapshot *) PG_GETARG_VARLENA_P(0); - - fctx = SRF_FIRSTCALL_INIT(); - - /* make a copy of user snapshot */ - snap = MemoryContextAlloc(fctx->multi_call_memory_ctx, VARSIZE(arg)); - memcpy(snap, arg, VARSIZE(arg)); - - fctx->user_fctx = snap; - } - - /* return values one-by-one */ - fctx = SRF_PERCALL_SETUP(); - snap = fctx->user_fctx; - if (fctx->call_cntr < snap->nxip) { - value = snap->xip[fctx->call_cntr]; - SRF_RETURN_NEXT(fctx, Int64GetDatum(value)); - } else { - SRF_RETURN_DONE(fctx); - } -} diff --git a/contrib/txid/txid.sql.in b/contrib/txid/txid.sql.in deleted file mode 100644 index ce5cded738..0000000000 --- a/contrib/txid/txid.sql.in +++ /dev/null @@ -1,87 +0,0 @@ --- ---------- --- txid.sql --- --- SQL script for loading the transaction ID compatible datatype --- --- Copyright (c) 2003-2007, PostgreSQL Global Development Group --- Author: Jan Wieck, Afilias USA INC. --- 64-bit txids: Marko Kreen, Skype Technologies --- --- $PostgreSQL: pgsql/contrib/txid/txid.sql.in,v 1.2 2007/10/11 19:54:17 tgl Exp $ --- --- ---------- - --- Adjust this setting to control where the objects get created. -SET search_path = public; - -BEGIN; - --- --- A special transaction snapshot data type for faster visibility checks --- -CREATE TYPE txid_snapshot; - -CREATE FUNCTION txid_snapshot_in(cstring) - RETURNS txid_snapshot - AS 'MODULE_PATHNAME' LANGUAGE C - IMMUTABLE STRICT; -CREATE FUNCTION txid_snapshot_out(txid_snapshot) - RETURNS cstring - AS 'MODULE_PATHNAME' LANGUAGE C - IMMUTABLE STRICT; -CREATE FUNCTION txid_snapshot_recv(internal) - RETURNS txid_snapshot - AS 'MODULE_PATHNAME' LANGUAGE C - IMMUTABLE STRICT; -CREATE FUNCTION txid_snapshot_send(txid_snapshot) - RETURNS bytea - AS 'MODULE_PATHNAME' LANGUAGE C - IMMUTABLE STRICT; - --- --- The data type itself --- -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 -); - --- --- Functions for txid --- -CREATE FUNCTION txid_current() - RETURNS bigint - AS 'MODULE_PATHNAME', 'txid_current' LANGUAGE C - STABLE; - -CREATE FUNCTION txid_current_snapshot() - RETURNS txid_snapshot - AS 'MODULE_PATHNAME', 'txid_current_snapshot' LANGUAGE C - STABLE; - -CREATE FUNCTION txid_snapshot_xmin(txid_snapshot) - RETURNS bigint - AS 'MODULE_PATHNAME', 'txid_snapshot_xmin' LANGUAGE C - IMMUTABLE STRICT; - -CREATE FUNCTION txid_snapshot_xmax(txid_snapshot) - RETURNS bigint - AS 'MODULE_PATHNAME', 'txid_snapshot_xmax' LANGUAGE C - IMMUTABLE STRICT; - -CREATE FUNCTION txid_snapshot_xip(txid_snapshot) - RETURNS setof bigint - AS 'MODULE_PATHNAME', 'txid_snapshot_xip' LANGUAGE C - IMMUTABLE STRICT; - -CREATE FUNCTION txid_visible_in_snapshot(bigint, txid_snapshot) - RETURNS boolean - AS 'MODULE_PATHNAME', 'txid_visible_in_snapshot' LANGUAGE C - IMMUTABLE STRICT; - -COMMIT; diff --git a/contrib/txid/uninstall_txid.sql b/contrib/txid/uninstall_txid.sql deleted file mode 100644 index ac126d60e0..0000000000 --- a/contrib/txid/uninstall_txid.sql +++ /dev/null @@ -1,11 +0,0 @@ -SET search_path = public; - -DROP FUNCTION txid_current(); -DROP FUNCTION txid_current_snapshot(); -DROP FUNCTION txid_snapshot_xmin(txid_snapshot); -DROP FUNCTION txid_snapshot_xmax(txid_snapshot); -DROP FUNCTION txid_snapshot_xip(txid_snapshot); -DROP FUNCTION txid_visible_in_snapshot(bigint, txid_snapshot); - -DROP TYPE txid_snapshot CASCADE; --- need cascade to drop the I/O functions -- 2.40.0