#!/usr/bin/perl use strict; use warnings; use Config; use PostgreSQL::Test::Cluster; use PostgreSQL::Test::Utils; use Test::More; use File::Spec; use IPC::Run qw( run timeout ); note "setting up PostgreSQL instance"; my $node = PostgreSQL::Test::Cluster->new('master'); $node->init(extra => ["--data-checksums"]); $node->append_conf('postgresql.conf', 'fsync = True'); $node->start; my $query = qq( drop table if exists t1; checkpoint; create table t1(a int, b text, c bigint, filler char(400)); insert into t1 values (1, 'asdasd1', 29347293874234444); insert into t1 values (2, 'asdasd2', 29347293874234445); insert into t1 values (3, 'asdasd', 29347293874234446); insert into t1 values (4, 'asdasd', 29347293874234447); checkpoint; ); $node->safe_psql('postgres', $query); note "running tests"; sub setup_test { # for test isolation purposes $node->safe_psql('postgres', $query); } test_basic_output(); test_btree_output(); test_spgist_output(); test_gin_output(); $node->stop; done_testing(); sub get_table_location { return File::Spec->catfile( $node->data_dir, $node->safe_psql('postgres', qq(SELECT pg_relation_filepath('@_');)) ); } sub run_pg_filedump { my ($rel, @options) = @_; my ($stdout, $stderr); my $loc = get_table_location($rel); my $cmd = [ 'pg_filedump', @options, $loc ]; my $result = run $cmd, '>', \$stdout, '2>', \$stderr or die "Error: could not execute pg_filedump"; ok($stdout !~ qr/Error/, "error not found"); return $stdout; } sub test_basic_output { setup_test(); my $out_ = run_pg_filedump('t1', ("-D", "int,text,bigint")); ok($out_ =~ qr/Header/, "Header found"); ok($out_ =~ qr/COPY: 1/, "first COPY found"); ok($out_ =~ qr/COPY: 2/, "second COPY found"); ok($out_ =~ qr/COPY: 3/, "third COPY found"); ok($out_ =~ qr/COPY: 4/, "fourth COPY found"); ok($out_ =~ qr/29347293874234447/, "number found"); ok($out_ =~ qr/asdasd/, "string found"); } sub test_btree_output { setup_test(); my $query = qq( insert into t1 select * FROM generate_series(1, 10000); create index i1 on t1(b); checkpoint; ); $node->safe_psql('postgres', $query); my $out_ = run_pg_filedump('i1', ('-i')); ok($out_ =~ qr/Header/, "Header found"); ok($out_ =~ qr/BTree Index Section/, "BTree Index Section found"); ok($out_ =~ qr/BTree Meta Data/, "BTree Meta Data found"); ok($out_ =~ qr/Item 3/, "Item found"); ok($out_ =~ qr/Previous/, "Previous item found"); ok($out_ =~ qr/Next/, "Next item found"); ok($out_ =~ qr/Level/, "Level found"); ok($out_ !~ qr/Next XID/, "Next XID not found"); # make leaf with BTP_DELETED flag $node->safe_psql('postgres', "delete from t1 where a >= 2000 and a < 4000;"); $node->safe_psql('postgres', "vacuum t1; checkpoint;"); $out_ = run_pg_filedump('i1', ('-i')); ok($out_ =~ qr/Next XID/, "Next XID found"); } sub test_spgist_output { setup_test(); $node->safe_psql('postgres', "create index i2 on t1 using spgist(b); checkpoint;"); my $out_ = run_pg_filedump('i2'); ok($out_ =~ qr/Header/, "Header found"); ok($out_ =~ qr/SPGIST Index Section/, "SPGIST Index Section found"); ok($out_ =~ qr/Item 4/, "Item found"); } sub test_gin_output { setup_test(); my $query = qq( create extension btree_gin; create index i3 on t1 using gin(b); checkpoint; ); $node->safe_psql('postgres', $query); my $out_ = run_pg_filedump('i3'); ok($out_ =~ qr/GIN Meta Data/, "Metadata found"); ok($out_ =~ qr/Leaf Page of Element B-tree/, "Leaf Page of Element B-tree found"); ok($out_ =~ qr/Posting List 1/, "Posting List 1 found"); ok($out_ =~ qr/ItemPointer 1/, "ItemPointer 1 found"); ok($out_ =~ qr/ItemPointer 2/, "ItemPointer 2 found"); ok($out_ =~ qr/Posting List 2/, "Posting List 2 found"); ok($out_ =~ qr/ItemPointer 1/, "ItemPointer 3 found"); ok($out_ =~ qr/Posting List 3/, "Posting List 3 found"); ok($out_ =~ qr/ItemPointer 1/, "ItemPointer 4 found"); ok($out_ =~ qr/GIN Index Section/, "GIN Index Section found"); }