blob: 8f148de6323504d484209f621072389f45c4cf92 [file] [log] [blame]
-- 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;