mirror of
https://github.com/postgres/postgres.git
synced 2025-05-12 16:21:30 +03:00
Improve regression test coverage for TID scanning.
TidScan plan nodes were not systematically tested before. These additions raise the LOC coverage number for the basic regression tests from 52% to 92% in nodeTidscan.c, and from 60% to 93% in tidpath.c. Andres Freund, tweaked a bit by me Discussion: https://postgr.es/m/20170320062511.hp5qeurtxrwsvfxr@alap3.anarazel.de
This commit is contained in:
parent
9cf6033281
commit
be6c3d19fd
179
src/test/regress/expected/tidscan.out
Normal file
179
src/test/regress/expected/tidscan.out
Normal file
@ -0,0 +1,179 @@
|
||||
-- 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)
|
||||
|
||||
-- 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)
|
||||
|
||||
-- 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;
|
||||
DROP TABLE tidscan;
|
@ -89,7 +89,7 @@ test: brin gin gist spgist privileges init_privs security_label collate matview
|
||||
# ----------
|
||||
# Another group of parallel tests
|
||||
# ----------
|
||||
test: alter_generic alter_operator misc psql async dbsize misc_functions sysviews tsrf
|
||||
test: alter_generic alter_operator misc psql async dbsize misc_functions sysviews tsrf tidscan
|
||||
|
||||
# rules cannot run concurrently with any test that creates a view
|
||||
test: rules psql_crosstab amutils
|
||||
|
@ -129,6 +129,7 @@ test: dbsize
|
||||
test: misc_functions
|
||||
test: sysviews
|
||||
test: tsrf
|
||||
test: tidscan
|
||||
test: rules
|
||||
test: psql_crosstab
|
||||
test: select_parallel
|
||||
|
66
src/test/regress/sql/tidscan.sql
Normal file
66
src/test/regress/sql/tidscan.sql
Normal file
@ -0,0 +1,66 @@
|
||||
-- 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 equality - implemented as tidscan
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)';
|
||||
SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)';
|
||||
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid;
|
||||
SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid;
|
||||
|
||||
-- ctid = ScalarArrayOp - implemented as tidscan
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]);
|
||||
SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]);
|
||||
|
||||
-- ctid != ScalarArrayOp - can't be implemented as tidscan
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]);
|
||||
SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]);
|
||||
|
||||
-- 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);
|
||||
SELECT ctid, * FROM tidscan
|
||||
WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1);
|
||||
|
||||
-- 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;
|
||||
FETCH BACKWARD 1 FROM c;
|
||||
FETCH FIRST FROM c;
|
||||
ROLLBACK;
|
||||
|
||||
-- tidscan via CURRENT OF
|
||||
BEGIN;
|
||||
DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan;
|
||||
FETCH NEXT FROM c; -- skip one row
|
||||
FETCH NEXT FROM c;
|
||||
-- perform update
|
||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||
FETCH NEXT FROM c;
|
||||
-- perform update
|
||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||
SELECT * FROM tidscan;
|
||||
-- position cursor past any rows
|
||||
FETCH NEXT FROM c;
|
||||
-- should error out
|
||||
EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
|
||||
UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *;
|
||||
ROLLBACK;
|
||||
|
||||
DROP TABLE tidscan;
|
Loading…
x
Reference in New Issue
Block a user