2020-04-07 01:08:14 +02:00
|
|
|
-- xid and xid8
|
|
|
|
-- values in range, in octal, decimal, hex
|
|
|
|
select '010'::xid,
|
|
|
|
'42'::xid,
|
|
|
|
'0xffffffff'::xid,
|
|
|
|
'-1'::xid,
|
|
|
|
'010'::xid8,
|
|
|
|
'42'::xid8,
|
|
|
|
'0xffffffffffffffff'::xid8,
|
|
|
|
'-1'::xid8;
|
|
|
|
xid | xid | xid | xid | xid8 | xid8 | xid8 | xid8
|
|
|
|
-----+-----+------------+------------+------+------+----------------------+----------------------
|
|
|
|
8 | 42 | 4294967295 | 4294967295 | 8 | 42 | 18446744073709551615 | 18446744073709551615
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- garbage values are not yet rejected (perhaps they should be)
|
|
|
|
select ''::xid;
|
|
|
|
xid
|
|
|
|
-----
|
|
|
|
0
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select 'asdf'::xid;
|
|
|
|
xid
|
|
|
|
-----
|
|
|
|
0
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select ''::xid8;
|
|
|
|
xid8
|
|
|
|
------
|
|
|
|
0
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select 'asdf'::xid8;
|
|
|
|
xid8
|
|
|
|
------
|
|
|
|
0
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- equality
|
|
|
|
select '1'::xid = '1'::xid;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '1'::xid != '1'::xid;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '1'::xid8 = '1'::xid8;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '1'::xid8 != '1'::xid8;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- conversion
|
|
|
|
select '1'::xid = '1'::xid8::xid;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '1'::xid != '1'::xid8::xid;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- we don't want relational operators for xid, due to use of modular arithmetic
|
|
|
|
select '1'::xid < '2'::xid;
|
|
|
|
ERROR: operator does not exist: xid < xid
|
|
|
|
LINE 1: select '1'::xid < '2'::xid;
|
|
|
|
^
|
|
|
|
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
select '1'::xid <= '2'::xid;
|
|
|
|
ERROR: operator does not exist: xid <= xid
|
|
|
|
LINE 1: select '1'::xid <= '2'::xid;
|
|
|
|
^
|
|
|
|
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
select '1'::xid > '2'::xid;
|
|
|
|
ERROR: operator does not exist: xid > xid
|
|
|
|
LINE 1: select '1'::xid > '2'::xid;
|
|
|
|
^
|
|
|
|
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
select '1'::xid >= '2'::xid;
|
|
|
|
ERROR: operator does not exist: xid >= xid
|
|
|
|
LINE 1: select '1'::xid >= '2'::xid;
|
|
|
|
^
|
|
|
|
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
-- we want them for xid8 though
|
|
|
|
select '1'::xid8 < '2'::xid8, '2'::xid8 < '2'::xid8, '2'::xid8 < '1'::xid8;
|
|
|
|
?column? | ?column? | ?column?
|
|
|
|
----------+----------+----------
|
|
|
|
t | f | f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '1'::xid8 <= '2'::xid8, '2'::xid8 <= '2'::xid8, '2'::xid8 <= '1'::xid8;
|
|
|
|
?column? | ?column? | ?column?
|
|
|
|
----------+----------+----------
|
|
|
|
t | t | f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '1'::xid8 > '2'::xid8, '2'::xid8 > '2'::xid8, '2'::xid8 > '1'::xid8;
|
|
|
|
?column? | ?column? | ?column?
|
|
|
|
----------+----------+----------
|
|
|
|
f | f | t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '1'::xid8 >= '2'::xid8, '2'::xid8 >= '2'::xid8, '2'::xid8 >= '1'::xid8;
|
|
|
|
?column? | ?column? | ?column?
|
|
|
|
----------+----------+----------
|
|
|
|
f | t | t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- we also have a 3way compare for btrees
|
|
|
|
select xid8cmp('1', '2'), xid8cmp('2', '2'), xid8cmp('2', '1');
|
|
|
|
xid8cmp | xid8cmp | xid8cmp
|
|
|
|
---------+---------+---------
|
|
|
|
-1 | 0 | 1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- xid8 has btree and hash opclasses
|
|
|
|
create table xid8_t1 (x xid8);
|
|
|
|
create index on xid8_t1 using btree(x);
|
|
|
|
create index on xid8_t1 using hash(x);
|
|
|
|
drop table xid8_t1;
|
2020-04-07 01:33:56 +02:00
|
|
|
-- pg_snapshot data type and related functions
|
|
|
|
-- Note: another set of tests similar to this exists in txid.sql, for a limited
|
|
|
|
-- time (the relevant functions share C code)
|
|
|
|
-- i/o
|
|
|
|
select '12:13:'::pg_snapshot;
|
|
|
|
pg_snapshot
|
|
|
|
-------------
|
|
|
|
12:13:
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '12:18:14,16'::pg_snapshot;
|
|
|
|
pg_snapshot
|
|
|
|
-------------
|
|
|
|
12:18:14,16
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '12:16:14,14'::pg_snapshot;
|
|
|
|
pg_snapshot
|
|
|
|
-------------
|
|
|
|
12:16:14
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- errors
|
|
|
|
select '31:12:'::pg_snapshot;
|
|
|
|
ERROR: invalid input syntax for type pg_snapshot: "31:12:"
|
|
|
|
LINE 1: select '31:12:'::pg_snapshot;
|
|
|
|
^
|
|
|
|
select '0:1:'::pg_snapshot;
|
|
|
|
ERROR: invalid input syntax for type pg_snapshot: "0:1:"
|
|
|
|
LINE 1: select '0:1:'::pg_snapshot;
|
|
|
|
^
|
|
|
|
select '12:13:0'::pg_snapshot;
|
|
|
|
ERROR: invalid input syntax for type pg_snapshot: "12:13:0"
|
|
|
|
LINE 1: select '12:13:0'::pg_snapshot;
|
|
|
|
^
|
|
|
|
select '12:16:14,13'::pg_snapshot;
|
|
|
|
ERROR: invalid input syntax for type pg_snapshot: "12:16:14,13"
|
|
|
|
LINE 1: select '12:16:14,13'::pg_snapshot;
|
|
|
|
^
|
|
|
|
create temp table snapshot_test (
|
|
|
|
nr integer,
|
|
|
|
snap pg_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 pg_snapshot_xmin(snap),
|
|
|
|
pg_snapshot_xmax(snap),
|
|
|
|
pg_snapshot_xip(snap)
|
|
|
|
from snapshot_test order by nr;
|
|
|
|
pg_snapshot_xmin | pg_snapshot_xmax | pg_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, pg_visible_in_snapshot(id::text::xid8, snap)
|
|
|
|
from snapshot_test, generate_series(11, 21) id
|
|
|
|
where nr = 2;
|
|
|
|
id | pg_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, pg_visible_in_snapshot(id::text::xid8, snap)
|
|
|
|
from snapshot_test, generate_series(90, 160) id
|
|
|
|
where nr = 4;
|
|
|
|
id | pg_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 pg_current_xact_id() >= pg_snapshot_xmin(pg_current_snapshot());
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- we can't assume current is always less than xmax, however
|
|
|
|
select pg_visible_in_snapshot(pg_current_xact_id(), pg_current_snapshot());
|
|
|
|
pg_visible_in_snapshot
|
|
|
|
------------------------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- test 64bitness
|
|
|
|
select pg_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013';
|
|
|
|
pg_snapshot
|
|
|
|
---------------------------------------------------------------------
|
|
|
|
1000100010001000:1000100010001100:1000100010001012,1000100010001013
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');
|
|
|
|
pg_visible_in_snapshot
|
|
|
|
------------------------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');
|
|
|
|
pg_visible_in_snapshot
|
|
|
|
------------------------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- test 64bit overflow
|
|
|
|
SELECT pg_snapshot '1:9223372036854775807:3';
|
|
|
|
pg_snapshot
|
|
|
|
-------------------------
|
|
|
|
1:9223372036854775807:3
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT pg_snapshot '1:9223372036854775808:3';
|
|
|
|
ERROR: invalid input syntax for type pg_snapshot: "1:9223372036854775808:3"
|
|
|
|
LINE 1: SELECT pg_snapshot '1:9223372036854775808:3';
|
|
|
|
^
|
|
|
|
-- test pg_current_xact_id_if_assigned
|
|
|
|
BEGIN;
|
|
|
|
SELECT pg_current_xact_id_if_assigned() IS NULL;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT pg_current_xact_id() \gset
|
|
|
|
SELECT pg_current_xact_id_if_assigned() IS NOT DISTINCT FROM xid8 :'pg_current_xact_id';
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
COMMIT;
|
|
|
|
-- test xid status functions
|
|
|
|
BEGIN;
|
|
|
|
SELECT pg_current_xact_id() AS committed \gset
|
|
|
|
COMMIT;
|
|
|
|
BEGIN;
|
|
|
|
SELECT pg_current_xact_id() AS rolledback \gset
|
|
|
|
ROLLBACK;
|
|
|
|
BEGIN;
|
|
|
|
SELECT pg_current_xact_id() AS inprogress \gset
|
|
|
|
SELECT pg_xact_status(:committed::text::xid8) AS committed;
|
|
|
|
committed
|
|
|
|
-----------
|
|
|
|
committed
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT pg_xact_status(:rolledback::text::xid8) AS rolledback;
|
|
|
|
rolledback
|
|
|
|
------------
|
|
|
|
aborted
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT pg_xact_status(:inprogress::text::xid8) AS inprogress;
|
|
|
|
inprogress
|
|
|
|
-------------
|
|
|
|
in progress
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT pg_xact_status('1'::xid8); -- BootstrapTransactionId is always committed
|
|
|
|
pg_xact_status
|
|
|
|
----------------
|
|
|
|
committed
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT pg_xact_status('2'::xid8); -- FrozenTransactionId is always committed
|
|
|
|
pg_xact_status
|
|
|
|
----------------
|
|
|
|
committed
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT pg_xact_status('3'::xid8); -- in regress testing FirstNormalTransactionId will always be behind oldestXmin
|
|
|
|
pg_xact_status
|
|
|
|
----------------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
COMMIT;
|
|
|
|
BEGIN;
|
|
|
|
CREATE FUNCTION test_future_xid_status(xid8)
|
|
|
|
RETURNS void
|
|
|
|
LANGUAGE plpgsql
|
|
|
|
AS
|
|
|
|
$$
|
|
|
|
BEGIN
|
|
|
|
PERFORM pg_xact_status($1);
|
|
|
|
RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected';
|
|
|
|
EXCEPTION
|
|
|
|
WHEN invalid_parameter_value THEN
|
|
|
|
RAISE NOTICE 'Got expected error for xid in the future';
|
|
|
|
END;
|
|
|
|
$$;
|
|
|
|
SELECT test_future_xid_status((:inprogress + 10000)::text::xid8);
|
|
|
|
NOTICE: Got expected error for xid in the future
|
|
|
|
test_future_xid_status
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
ROLLBACK;
|