#!/bin/sh

PGPATH=/home/hlinnaka/pgsql.cvshead

PATH=${PATH}:${PGPATH}/bin

rm -rf /tmp/temppgdata
initdb -D /tmp/temppgdata
postgres -D /tmp/temppgdata &
sleep 2

mkdir /tmp/crashtest-expected
mkdir /tmp/crashtest-results

psql postgres < ${PGPATH}/share/contrib/pgstattuple.sql

psql postgres -c "CREATE VIEW testindexcontents AS SELECT pn, (a.b).ctid, (a.b).itemoffset, (a.b).itemlen, substr((a.b).data, length((a.b).data)-20) FROM (select pn, bt_page_items('test_index', pn) AS b FROM generate_series(1, (SELECT pg_relpages('test_index'))) pn) AS a;"

psql postgres -c "DROP TABLE IF EXISTS test;"

psql postgres -c "CREATE TABLE test (key text);"
psql postgres -c "CREATE index test_index on test (key);"

psql postgres -c "CHECKPOINT;"

############ Tests begin. 


##### Test 1: Root split, new item on left

psql postgres -c "truncate test";

# Insert just enough tuples to fill the page but not split.
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(1,70) n;"

# split
psql postgres -a -c "INSERT INTO test (key) VALUES (lpad(10, 100, '0'))";

# Let's see what the page looks like *before* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-expected/1.txt

killall -9 postgres
sleep 1
postgres -D /tmp/temppgdata &
sleep 5 # should be enough for log replay to finish

# Let's see what the page looks like *after* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-results/1.txt




##### Test 2: Root split, new item on right

psql postgres -c "truncate test";

# Insert just enough tuples to fill the page but not split.
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(1,70) n;"

# split
psql postgres -a -c "INSERT INTO test (key) VALUES (lpad(99, 100, '0'))";

# Let's see what the page looks like *before* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-expected/2.txt

killall -9 postgres
sleep 1
postgres -D /tmp/temppgdata &
sleep 5 # should be enough for log replay to finish

# Let's see what the page looks like *after* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-results/2.txt



##### Test 3: Leaf page split, new item on left page

psql postgres -c "truncate test";

# Insert just enough tuples to create a two-level index.
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(1,71) n;"

# Insert just enough tuples to fill the left leaf page
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(1,7) n;"

# split
psql postgres -a -c "INSERT INTO test (key) VALUES (lpad(10, 100, '0'))";

# Let's see what the page looks like *before* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-expected/3.txt

killall -9 postgres
sleep 1
postgres -D /tmp/temppgdata &
sleep 5 # should be enough for log replay to finish

# Let's see what the page looks like *after* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-results/3.txt


##### Test 4: Leaf page split, new item on right page

psql postgres -c "truncate test";

# Insert just enough tuples to create a two-level index.
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(1,71) n;"

# Insert just enough tuples to fill the right leaf page
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(100,160) n;"

# split
psql postgres -a -c "INSERT INTO test (key) VALUES (lpad(999, 100, '0'))";

# Let's see what the page looks like *before* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-expected/4.txt

killall -9 postgres
sleep 1
postgres -D /tmp/temppgdata &
sleep 5 # should be enough for log replay to finish

# Let's see what the page looks like *after* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-results/4.txt


##### Test 5: Leaf page split, new item on right page. full-page-write

psql postgres -c "truncate test";

# Insert just enough tuples to create a two-level index.
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(1,71) n;"

# Insert just enough tuples to fill the right leaf page
psql postgres -c " insert into test (key) select lpad(n, 100, '0') from generate_series(100,160) n;"

psql postgres -c "CHECKPOINT;"

# split
psql postgres -a -c "INSERT INTO test (key) VALUES (lpad(999, 100, '0'))";

# Let's see what the page looks like *before* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-expected/5.txt

killall -9 postgres
sleep 1
postgres -D /tmp/temppgdata &
sleep 5 # should be enough for log replay to finish

# Let's see what the page looks like *after* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-results/5.txt

##### Test 6: Non-leaf page split, new item on rightmost page

psql postgres -c "truncate test";

# Insert just enough tuples to create a full two-level index.
psql postgres -c "  insert into test (key) select lpad(n, 100, '0') from generate_series(1,4410) n;"

# Insert a tuple to rightmost page, causing a split
psql postgres -a -c "INSERT INTO test (key) VALUES (lpad(99999, 100, '0'))";

# Let's see what the page looks like *before* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-expected/6.txt

killall -9 postgres
sleep 1
postgres -D /tmp/temppgdata &
sleep 5 # should be enough for log replay to finish

# Let's see what the page looks like *after* crash
psql postgres -a -c "SELECT * FROM testindexcontents" > /tmp/crashtest-results/6.txt





diff -c /tmp/crashtest-expected /tmp/crashtest-results > crashtest.diff

killall -9 postgres