301 lines
6.4 KiB
Plaintext
301 lines
6.4 KiB
Plaintext
-- tests for tidrangescans
|
|
SET enable_seqscan TO off;
|
|
CREATE TABLE tidrangescan(id integer, data text);
|
|
-- empty table
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)';
|
|
QUERY PLAN
|
|
-----------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid < '(1,0)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)';
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)';
|
|
QUERY PLAN
|
|
-----------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid > '(9,0)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)';
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
-- insert enough tuples to fill at least two pages
|
|
INSERT INTO tidrangescan SELECT i,repeat('x', 100) FROM generate_series(1,200) AS s(i);
|
|
-- remove all tuples after the 10th tuple on each page. Trying to ensure
|
|
-- we get the same layout with all CPU architectures and smaller than standard
|
|
-- page sizes.
|
|
DELETE FROM tidrangescan
|
|
WHERE substring(ctid::text FROM ',(\d+)\)')::integer > 10 OR substring(ctid::text FROM '\((\d+),')::integer > 2;
|
|
VACUUM tidrangescan;
|
|
-- range scans with upper bound
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)';
|
|
QUERY PLAN
|
|
-----------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid < '(1,0)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)';
|
|
ctid
|
|
--------
|
|
(0,1)
|
|
(0,2)
|
|
(0,3)
|
|
(0,4)
|
|
(0,5)
|
|
(0,6)
|
|
(0,7)
|
|
(0,8)
|
|
(0,9)
|
|
(0,10)
|
|
(10 rows)
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)';
|
|
QUERY PLAN
|
|
------------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid <= '(1,5)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)';
|
|
ctid
|
|
--------
|
|
(0,1)
|
|
(0,2)
|
|
(0,3)
|
|
(0,4)
|
|
(0,5)
|
|
(0,6)
|
|
(0,7)
|
|
(0,8)
|
|
(0,9)
|
|
(0,10)
|
|
(1,1)
|
|
(1,2)
|
|
(1,3)
|
|
(1,4)
|
|
(1,5)
|
|
(15 rows)
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)';
|
|
QUERY PLAN
|
|
-----------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid < '(0,0)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)';
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
-- range scans with lower bound
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)';
|
|
QUERY PLAN
|
|
-----------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid > '(2,8)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)';
|
|
ctid
|
|
--------
|
|
(2,9)
|
|
(2,10)
|
|
(2 rows)
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid;
|
|
QUERY PLAN
|
|
-----------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: ('(2,8)'::tid < ctid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid;
|
|
ctid
|
|
--------
|
|
(2,9)
|
|
(2,10)
|
|
(2 rows)
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)';
|
|
QUERY PLAN
|
|
------------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid >= '(2,8)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)';
|
|
ctid
|
|
--------
|
|
(2,8)
|
|
(2,9)
|
|
(2,10)
|
|
(3 rows)
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)';
|
|
QUERY PLAN
|
|
--------------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid >= '(100,0)'::tid)
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)';
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
-- range scans with both bounds
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: ((ctid > '(1,4)'::tid) AND ('(1,7)'::tid >= ctid))
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid;
|
|
ctid
|
|
-------
|
|
(1,5)
|
|
(1,6)
|
|
(1,7)
|
|
(3 rows)
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)';
|
|
QUERY PLAN
|
|
----------------------------------------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (('(1,7)'::tid >= ctid) AND (ctid > '(1,4)'::tid))
|
|
(2 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)';
|
|
ctid
|
|
-------
|
|
(1,5)
|
|
(1,6)
|
|
(1,7)
|
|
(3 rows)
|
|
|
|
-- extreme offsets
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(0,65535)' AND ctid < '(1,0)' LIMIT 1;
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' LIMIT 1;
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid > '(4294967295,65535)';
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)';
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
-- NULLs in the range cannot return tuples
|
|
SELECT ctid FROM tidrangescan WHERE ctid >= (SELECT NULL::tid);
|
|
ctid
|
|
------
|
|
(0 rows)
|
|
|
|
-- rescans
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT t.ctid,t2.c FROM tidrangescan t,
|
|
LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2
|
|
WHERE t.ctid < '(1,0)';
|
|
QUERY PLAN
|
|
-----------------------------------------------
|
|
Nested Loop
|
|
-> Tid Range Scan on tidrangescan t
|
|
TID Cond: (ctid < '(1,0)'::tid)
|
|
-> Aggregate
|
|
-> Tid Range Scan on tidrangescan t2
|
|
TID Cond: (ctid <= t.ctid)
|
|
(6 rows)
|
|
|
|
SELECT t.ctid,t2.c FROM tidrangescan t,
|
|
LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2
|
|
WHERE t.ctid < '(1,0)';
|
|
ctid | c
|
|
--------+----
|
|
(0,1) | 1
|
|
(0,2) | 2
|
|
(0,3) | 3
|
|
(0,4) | 4
|
|
(0,5) | 5
|
|
(0,6) | 6
|
|
(0,7) | 7
|
|
(0,8) | 8
|
|
(0,9) | 9
|
|
(0,10) | 10
|
|
(10 rows)
|
|
|
|
-- cursors
|
|
-- Ensure we get a TID Range scan without a Materialize node.
|
|
EXPLAIN (COSTS OFF)
|
|
DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)';
|
|
QUERY PLAN
|
|
-----------------------------------
|
|
Tid Range Scan on tidrangescan
|
|
TID Cond: (ctid < '(1,0)'::tid)
|
|
(2 rows)
|
|
|
|
BEGIN;
|
|
DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)';
|
|
FETCH NEXT c;
|
|
ctid
|
|
-------
|
|
(0,1)
|
|
(1 row)
|
|
|
|
FETCH NEXT c;
|
|
ctid
|
|
-------
|
|
(0,2)
|
|
(1 row)
|
|
|
|
FETCH PRIOR c;
|
|
ctid
|
|
-------
|
|
(0,1)
|
|
(1 row)
|
|
|
|
FETCH FIRST c;
|
|
ctid
|
|
-------
|
|
(0,1)
|
|
(1 row)
|
|
|
|
FETCH LAST c;
|
|
ctid
|
|
--------
|
|
(0,10)
|
|
(1 row)
|
|
|
|
COMMIT;
|
|
DROP TABLE tidrangescan;
|
|
RESET enable_seqscan;
|