|
| 1 | +# index-only-bitmapscan test showing wrong results |
| 2 | +# |
| 3 | +setup |
| 4 | +{ |
| 5 | + -- by using a low fillfactor and a wide tuple we can get multiple blocks |
| 6 | + -- with just few rows |
| 7 | + CREATE TABLE ios_bitmap (a int NOT NULL, b int not null, pad char(1024) default '') |
| 8 | + WITH (AUTOVACUUM_ENABLED = false, FILLFACTOR = 10); |
| 9 | + |
| 10 | + INSERT INTO ios_bitmap SELECT g.i, g.i FROM generate_series(1, 10) g(i); |
| 11 | + |
| 12 | + CREATE INDEX ios_bitmap_a ON ios_bitmap(a); |
| 13 | + CREATE INDEX ios_bitmap_b ON ios_bitmap(b); |
| 14 | +} |
| 15 | + |
| 16 | +teardown |
| 17 | +{ |
| 18 | + DROP TABLE ios_bitmap; |
| 19 | +} |
| 20 | + |
| 21 | + |
| 22 | +session s1 |
| 23 | + |
| 24 | +setup { |
| 25 | + SET enable_seqscan = false; |
| 26 | +} |
| 27 | + |
| 28 | +step s1_begin { BEGIN; } |
| 29 | +step s1_commit { COMMIT; } |
| 30 | + |
| 31 | + |
| 32 | +# The test query uses an or between two indexes to ensure make it more likely |
| 33 | +# to use a bitmap index scan |
| 34 | +# |
| 35 | +# The row_number() hack is a way to have something returned (isolationtester |
| 36 | +# doesn't display empty rows) while still allowing for the index-only scan |
| 37 | +# optimization in bitmap heap scans, which requires an empty targetlist. |
| 38 | +step s1_prepare { |
| 39 | + DECLARE foo NO SCROLL CURSOR FOR SELECT row_number() OVER () FROM ios_bitmap WHERE a > 0 or b > 0; |
| 40 | +} |
| 41 | + |
| 42 | +step s1_fetch_1 { |
| 43 | + FETCH FROM foo; |
| 44 | +} |
| 45 | + |
| 46 | +step s1_fetch_all { |
| 47 | + FETCH ALL FROM foo; |
| 48 | +} |
| 49 | + |
| 50 | + |
| 51 | +session s2 |
| 52 | + |
| 53 | +# Don't delete row 1 so we have a row for the cursor to "rest" on. |
| 54 | +step s2_mod |
| 55 | +{ |
| 56 | + DELETE FROM ios_bitmap WHERE a > 1; |
| 57 | +} |
| 58 | + |
| 59 | +# Disable truncation, as otherwise we'll just wait for a timeout while trying |
| 60 | +# to acquire the lock |
| 61 | +step s2_vacuum { VACUUM (TRUNCATE false) ios_bitmap; } |
| 62 | + |
| 63 | +permutation |
| 64 | + # Vacuum first, to ensure VM exists, otherwise the bitmapscan will consider |
| 65 | + # VM to be size 0, due to caching. Can't do that in setup because |
| 66 | + s2_vacuum |
| 67 | + |
| 68 | + # delete nearly all rows, to make issue visible |
| 69 | + s2_mod |
| 70 | + # create a cursor |
| 71 | + s1_begin |
| 72 | + s1_prepare |
| 73 | + |
| 74 | + # fetch one row from the cursor, that ensures the index scan portion is done |
| 75 | + # before the vacuum in the next step |
| 76 | + s1_fetch_1 |
| 77 | + |
| 78 | + # with the bug this vacuum will mark pages as all-visible that the scan in |
| 79 | + # the next step then considers all-visible, despite all rows from those |
| 80 | + # pages having been removed. |
| 81 | + s2_vacuum |
| 82 | + # if this returns any rows, we're busted |
| 83 | + s1_fetch_all |
| 84 | + |
| 85 | + s1_commit |
0 commit comments