diff options
Diffstat (limited to '')
-rw-r--r-- | src/test/regress/expected/tidscan.out | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/src/test/regress/expected/tidscan.out b/src/test/regress/expected/tidscan.out new file mode 100644 index 0000000..13c3c36 --- /dev/null +++ b/src/test/regress/expected/tidscan.out @@ -0,0 +1,296 @@ +-- tests for tidscans +CREATE TABLE tidscan(id integer); +-- only insert a few rows, we don't want to spill onto a second table page +INSERT INTO tidscan VALUES (1), (2), (3); +-- show ctids +SELECT ctid, * FROM tidscan; + ctid | id +-------+---- + (0,1) | 1 + (0,2) | 2 + (0,3) | 3 +(3 rows) + +-- ctid equality - implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)'; + QUERY PLAN +----------------------------------- + Tid Scan on tidscan + TID Cond: (ctid = '(0,1)'::tid) +(2 rows) + +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)'; + ctid | id +-------+---- + (0,1) | 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid; + QUERY PLAN +----------------------------------- + Tid Scan on tidscan + TID Cond: ('(0,1)'::tid = ctid) +(2 rows) + +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid; + ctid | id +-------+---- + (0,1) | 1 +(1 row) + +-- OR'd clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; + QUERY PLAN +-------------------------------------------------------------- + Tid Scan on tidscan + TID Cond: ((ctid = '(0,2)'::tid) OR ('(0,1)'::tid = ctid)) +(2 rows) + +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; + ctid | id +-------+---- + (0,1) | 1 + (0,2) | 2 +(2 rows) + +-- ctid = ScalarArrayOp - implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + QUERY PLAN +------------------------------------------------------- + Tid Scan on tidscan + TID Cond: (ctid = ANY ('{"(0,1)","(0,2)"}'::tid[])) +(2 rows) + +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + ctid | id +-------+---- + (0,1) | 1 + (0,2) | 2 +(2 rows) + +-- ctid != ScalarArrayOp - can't be implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + QUERY PLAN +------------------------------------------------------ + Seq Scan on tidscan + Filter: (ctid <> ANY ('{"(0,1)","(0,2)"}'::tid[])) +(2 rows) + +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + ctid | id +-------+---- + (0,1) | 1 + (0,2) | 2 + (0,3) | 3 +(3 rows) + +-- tid equality extracted from sub-AND clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------- + Tid Scan on tidscan + TID Cond: ((ctid = ANY ('{"(0,2)","(0,3)"}'::tid[])) OR (ctid = '(0,1)'::tid)) + Filter: (((id = 3) AND (ctid = ANY ('{"(0,2)","(0,3)"}'::tid[]))) OR ((ctid = '(0,1)'::tid) AND (id = 1))) +(3 rows) + +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1); + ctid | id +-------+---- + (0,1) | 1 + (0,3) | 3 +(2 rows) + +-- nestloop-with-inner-tidscan joins on tid +SET enable_hashjoin TO off; -- otherwise hash join might win +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + QUERY PLAN +------------------------------------ + Nested Loop + -> Seq Scan on tidscan t1 + Filter: (id = 1) + -> Tid Scan on tidscan t2 + TID Cond: (ctid = t1.ctid) +(5 rows) + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + ctid | id | ctid | id +-------+----+-------+---- + (0,1) | 1 | (0,1) | 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + QUERY PLAN +------------------------------------ + Nested Loop Left Join + -> Seq Scan on tidscan t1 + Filter: (id = 1) + -> Tid Scan on tidscan t2 + TID Cond: (t1.ctid = ctid) +(5 rows) + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + ctid | id | ctid | id +-------+----+-------+---- + (0,1) | 1 | (0,1) | 1 +(1 row) + +RESET enable_hashjoin; +-- exercise backward scan and rewind +BEGIN; +DECLARE c CURSOR FOR +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); +FETCH ALL FROM c; + ctid | id +-------+---- + (0,1) | 1 + (0,2) | 2 +(2 rows) + +FETCH BACKWARD 1 FROM c; + ctid | id +-------+---- + (0,2) | 2 +(1 row) + +FETCH FIRST FROM c; + ctid | id +-------+---- + (0,1) | 1 +(1 row) + +ROLLBACK; +-- tidscan via CURRENT OF +BEGIN; +DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan; +FETCH NEXT FROM c; -- skip one row + ctid | id +-------+---- + (0,1) | 1 +(1 row) + +FETCH NEXT FROM c; + ctid | id +-------+---- + (0,2) | 2 +(1 row) + +-- perform update +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; + QUERY PLAN +--------------------------------------------------- + Update on tidscan (actual rows=1 loops=1) + -> Tid Scan on tidscan (actual rows=1 loops=1) + TID Cond: CURRENT OF c +(3 rows) + +FETCH NEXT FROM c; + ctid | id +-------+---- + (0,3) | 3 +(1 row) + +-- perform update +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; + QUERY PLAN +--------------------------------------------------- + Update on tidscan (actual rows=1 loops=1) + -> Tid Scan on tidscan (actual rows=1 loops=1) + TID Cond: CURRENT OF c +(3 rows) + +SELECT * FROM tidscan; + id +---- + 1 + -2 + -3 +(3 rows) + +-- position cursor past any rows +FETCH NEXT FROM c; + ctid | id +------+---- +(0 rows) + +-- should error out +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; +ERROR: cursor "c" is not positioned on a row +ROLLBACK; +-- bulk joins on CTID +-- (these plans don't use TID scans, but this still seems like an +-- appropriate place for these tests) +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Join + Hash Cond: (t1.ctid = t2.ctid) + -> Seq Scan on tenk1 t1 + -> Hash + -> Seq Scan on tenk1 t2 +(6 rows) + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + count +------- + 10000 +(1 row) + +SET enable_hashjoin TO off; +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + QUERY PLAN +----------------------------------------- + Aggregate + -> Merge Join + Merge Cond: (t1.ctid = t2.ctid) + -> Sort + Sort Key: t1.ctid + -> Seq Scan on tenk1 t1 + -> Sort + Sort Key: t2.ctid + -> Seq Scan on tenk1 t2 +(9 rows) + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + count +------- + 10000 +(1 row) + +RESET enable_hashjoin; +-- check predicate lock on CTID +BEGIN ISOLATION LEVEL SERIALIZABLE; +SELECT * FROM tidscan WHERE ctid = '(0,1)'; + id +---- + 1 +(1 row) + +-- locktype should be 'tuple' +SELECT locktype, mode FROM pg_locks WHERE pid = pg_backend_pid() AND mode = 'SIReadLock'; + locktype | mode +----------+------------ + tuple | SIReadLock +(1 row) + +ROLLBACK; +DROP TABLE tidscan; |