| -- This is intended to test lastSequence initialization during indexscan should be limited |
| -- to the scope of the target scanning AO/CO segfiles, rather than the max 128 segfiles. |
| -- The theory is comparing the count of indexscan (or pg_stat_all_tables.idx_scan) between |
| -- pre and post query on bitmapheapscan(could trigger indexscan) plan. |
| -- We are using gp_ao_or_aocs_seg() helper UDF to obtain the number of AO/CO segfiles (segnos), |
| -- then plus 1 to count in segfile0 due to the implementation constraint. |
| -- For BTREE index, we verify the equation: post_nscans - pre_nscans == segnos + 1; |
| -- for BRIN index, we verify the equation: post_nscans - pre_nscans == ((segnos + 1) * 2 - 1). |
| -- BRIN index doubles the number of nscans of BTREE because lastSequence was initialized twice |
| -- during BRIN indexed bitmapheapscan (in index_getbitmap and ao/co fetch_init), which is probably |
| -- optimizable, too. We also deduct 1 because gp_fastsequence is not scanned for |
| -- seg0 to determine block sequences for AO/CO tables (if seg0 is absent). |
| |
| create or replace function test_iscan_inits_same_as_aosegs(tablename text, icol text, itype text) returns bool as $$ |
| declare |
| segnos smallint; /* in func */ |
| pre_nscans smallint; /* in func */ |
| post_nscans smallint; /* in func */ |
| result bool; /* in func */ |
| begin |
| select count(segno) into segnos from gp_ao_or_aocs_seg(tablename); /* in func */ |
| |
| select pg_stat_get_xact_numscans('gp_fastsequence_objid_objmod_index'::regclass) into pre_nscans; /* get idx_scan before query */ |
| execute 'select * from ' || quote_ident(tablename) || ' where ' || quote_ident(icol) || ' = 2'; /* vaule 2 is distributed to the segment with content 0 */ |
| select pg_stat_get_xact_numscans('gp_fastsequence_objid_objmod_index'::regclass) into post_nscans; /* get idx_scan after query */ |
| |
| if quote_ident(itype) = 'btree' then /* for BTREE index */ |
| select post_nscans - pre_nscans = segnos + 1 into result; /* calculate the diff and compare to segnos plus 1 to count in segfile0, expect equal */ |
| raise notice '[BTREE] expect: post_nscans - pre_nscans == segnos + 1'; /* in func */ |
| elsif quote_ident(itype) = 'brin' then /* for BRIN index */ |
| select post_nscans - pre_nscans = ((segnos + 1) * 2 - 1) into result; /* BRIN doubles nscans(of BTREE) due to implementation constraint */ |
| raise notice '[BRIN] expect: post_nscans - pre_nscans == ((segnos + 1) * 2 - 1)'; /* in func */ |
| else /* in func */ |
| raise exception 'unexpected type of index %', itype::text; /* in func */ |
| end if; /* in func */ |
| |
| raise notice 'pre_nscans = %, post_nscans = %, segnos = %', pre_nscans, post_nscans, segnos; /* verbose */ |
| |
| return result; /* in func */ |
| end; /* in func */ |
| $$ language plpgsql; |
| |
| set default_table_access_method=@amname@; |
| |
| create table @amname@_limit_iscan_inits_tbl (a int, b int, c int, d int); |
| create index on @amname@_limit_iscan_inits_tbl(a); |
| create index on @amname@_limit_iscan_inits_tbl using brin (b); |
| |
| -- Start three concurrent writing sessions to generate three segment files. |
| 1: begin; |
| 1: insert into @amname@_limit_iscan_inits_tbl select a, a, a, a from generate_series(1, 10)a; |
| |
| 2: begin; |
| 2: insert into @amname@_limit_iscan_inits_tbl select a, a, a, a from generate_series(11, 20)a; |
| |
| 3: begin; |
| 3: insert into @amname@_limit_iscan_inits_tbl select a, a, a, a from generate_series(21, 30)a; |
| |
| 1: end; |
| 2: end; |
| 3: end; |
| |
| -- diable seqscan |
| 0U: set enable_seqscan = off; |
| -- make sure it goes to bitmapheapscan |
| -- start_ignore |
| 0U: explain (costs off) select * from @amname@_limit_iscan_inits_tbl where a = 2; |
| 0U: explain (costs off) select * from @amname@_limit_iscan_inits_tbl where b = 2; |
| -- end_ignore |
| -- expect to return true |
| 0U: select test_iscan_inits_same_as_aosegs('@amname@_limit_iscan_inits_tbl', 'a', 'btree'); |
| 0U: select test_iscan_inits_same_as_aosegs('@amname@_limit_iscan_inits_tbl', 'b', 'brin'); |
| 0Uq: |
| |
| drop table @amname@_limit_iscan_inits_tbl; |
| drop function test_iscan_inits_same_as_aosegs; |
| reset default_table_access_method; |