text: --
  -- Test Statistics Collector
  --
  -- Must be run after tenk2 has been created (by create_table),
  -- populated (by create_misc) and indexed (by create_index).
  --
  
  -- conditio sine qua non
  SHOW track_counts;  -- must be on
  
  -- ensure that both seqscan and indexscan plans are allowed
  SET enable_seqscan TO on;
  SET enable_indexscan TO on;
  -- for the moment, we don't want index-only scans here
  SET enable_indexonlyscan TO off;
  
  -- test effects of TRUNCATE on n_live_tup/n_dead_tup counters
  --DDL_STATEMENT_BEGIN--
  CREATE TABLE trunc_stats_test(id serial);
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  CREATE TABLE trunc_stats_test1(id serial, stuff text);
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  CREATE TABLE trunc_stats_test2(id serial);
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  CREATE TABLE trunc_stats_test3(id serial, stuff text);
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  CREATE TABLE trunc_stats_test4(id serial);
  --DDL_STATEMENT_END--
  
  -- check that n_live_tup is reset to 0 after truncate
  INSERT INTO trunc_stats_test DEFAULT VALUES;
  INSERT INTO trunc_stats_test DEFAULT VALUES;
  INSERT INTO trunc_stats_test DEFAULT VALUES;
  delete from trunc_stats_test;
  
  -- test involving a truncate in a transaction; 4 ins but only 1 live
  INSERT INTO trunc_stats_test1 DEFAULT VALUES;
  INSERT INTO trunc_stats_test1 DEFAULT VALUES;
  INSERT INTO trunc_stats_test1 DEFAULT VALUES;
  UPDATE trunc_stats_test1 SET id = id + 10 WHERE id IN (1, 2);
  DELETE FROM trunc_stats_test1 WHERE id = 3;
  
  BEGIN;
  UPDATE trunc_stats_test1 SET id = id + 100;
  delete from trunc_stats_test1;
  INSERT INTO trunc_stats_test1 DEFAULT VALUES;
  COMMIT;
  
  -- use a savepoint: 1 insert, 1 live
  BEGIN;
  INSERT INTO trunc_stats_test2 DEFAULT VALUES;
  INSERT INTO trunc_stats_test2 DEFAULT VALUES;
  SAVEPOINT p1;
  INSERT INTO trunc_stats_test2 DEFAULT VALUES;
  delete from trunc_stats_test2;
  INSERT INTO trunc_stats_test2 DEFAULT VALUES;
  --crash: RELEASE SAVEPOINT p1;
  COMMIT;
  
  -- rollback a savepoint: this should count 4 inserts and have 2
  -- live tuples after commit (and 2 dead ones due to aborted subxact)
  BEGIN;
  INSERT INTO trunc_stats_test3 DEFAULT VALUES;
  INSERT INTO trunc_stats_test3 DEFAULT VALUES;
  SAVEPOINT p1;
  INSERT INTO trunc_stats_test3 DEFAULT VALUES;
  INSERT INTO trunc_stats_test3 DEFAULT VALUES;
  delete from trunc_stats_test3;
  INSERT INTO trunc_stats_test3 DEFAULT VALUES;
  ROLLBACK TO SAVEPOINT p1;
  COMMIT;
  
  -- rollback a truncate: this should count 2 inserts and produce 2 dead tuples
  BEGIN;
  INSERT INTO trunc_stats_test4 DEFAULT VALUES;
  INSERT INTO trunc_stats_test4 DEFAULT VALUES;
  delete from trunc_stats_test4;
  INSERT INTO trunc_stats_test4 DEFAULT VALUES;
  ROLLBACK;
  
  -- do a seqscan
  SELECT count(*) FROM tenk2;
  -- do an indexscan
  -- make sure it is not a bitmap scan, which might skip fetching heap tuples
  SET enable_bitmapscan TO off;
  SELECT count(*) FROM tenk2 WHERE unique1 = 1;
  RESET enable_bitmapscan;
  
  -- check effects
  SELECT relname, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup
    FROM pg_stat_user_tables
   WHERE relname like 'trunc_stats_test%' order by relname;
  
  SELECT st.seq_scan >= pr.seq_scan + 1,
         st.seq_tup_read >= pr.seq_tup_read + cl.reltuples,
         st.idx_scan >= pr.idx_scan + 1,
         st.idx_tup_fetch >= pr.idx_tup_fetch + 1
    FROM pg_stat_user_tables AS st, pg_class AS cl, prevstats AS pr
   WHERE st.relname='tenk2' AND cl.relname='tenk2';
  
  SELECT st.heap_blks_read + st.heap_blks_hit >= pr.heap_blks + cl.relpages,
         st.idx_blks_read + st.idx_blks_hit >= pr.idx_blks + 1
    FROM pg_statio_user_tables AS st, pg_class AS cl, prevstats AS pr
   WHERE st.relname='tenk2' AND cl.relname='tenk2';
  
  SELECT pr.snap_ts < pg_stat_get_snapshot_timestamp() as snapshot_newer
  FROM prevstats AS pr;
  
  --DDL_STATEMENT_BEGIN--
  DROP TABLE trunc_stats_test;
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  drop table trunc_stats_test1;
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  drop table trunc_stats_test2;
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  drop table trunc_stats_test3;
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  drop table trunc_stats_test4;
  --DDL_STATEMENT_END--
  --DDL_STATEMENT_BEGIN--
  DROP TABLE prevstats;
  --DDL_STATEMENT_END--
  -- End of Stats Test
  