#!/bin/sh
#
# Copyright (c) 2006 MySQL AB
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

echo "######################################################################"
echo "#"
echo "# Test Bug#18544 - LOCK TABLES timeout causes MyISAM table corruption"
echo "#"

#######################################################################
#
# Settings. CAUTION: Paths are not space safe.
#

# BASEDIR="install directory"
# DATADIR="databases directory e.g. $BASEDIR/var"

MYSQLD="$BASEDIR/libexec/mysqld"
MYSQLC="$BASEDIR/bin/mysql"
MYSQLA="$BASEDIR/bin/mysqladmin"
MYSQLT="$BASEDIR/bin/mysqltest"

PORT_1="${MYSQL_TCP_PORT:+--port=$MYSQL_TCP_PORT}"
SOCK_1="${MYSQL_UNIX_PORT:+--socket=$MYSQL_UNIX_PORT}"
USER_1="-u root -D test"
CLNT_1="-A -v"
TEST_1="-v"
DATA_1="--basedir=$BASEDIR --datadir=$DATADIR"
SERV_1="--log-error --core"
SERV_1="$SERV_1 --innodb_lock_wait_timeout=1"
DBUG_1= #"--debug=t:d:i:O,$DATADIR/mysqld.trace"

cd $DATADIR || exit $?
rm -f *.trace *.err core* test/#sql* bug18544*


echo "######################################################################"
echo "#"
echo "# Starting database server."
"$MYSQLD" $PORT_1 $SOCK_1 $DATA_1 $SERV_1 $DBUG_1 &
SERV_1_PID=$!
echo "Process_id $SERV_1_PID"
echo
sleep 3


echo "######################################################################"
echo "#"
echo "# Running test #1."
"$MYSQLT" $PORT_1 $SOCK_1 $USER_1 $TEST_1 <<\EOF
  --disable_warnings
  drop table if exists t1, t2;
  --enable_warnings

  #
  # Bug#18544 - LOCK TABLES timeout causes MyISAM table corruption
  # Case 1: Locking error in lock_external() due to InnoDB timeout.
  #
  create table t1 (c varchar(255), primary key(c)) engine=innodb;
  create table t2 (c varchar(255), primary key(c)) engine=myisam;
  #
  connect (con1,localhost,root,,);
  connect (con2,localhost,root,,);
  #
  connection con1;
  set autocommit=0;
  insert into t1 values ('anything');
  insert into t2 values ('anything');
  #
  connection con2;
  set autocommit=0;
  # The next statement waits because of the innodb lock taken by connection 1.
  # It waits until the lock times out (~ innodb_lock_wait_timeout seconds).
  # It leaves behind t2 marked as being read locked if the bug is present.
  --error 1205
  lock tables t1 read, t2 read;
  #
  connection con1;
  # This insert works on a read locked table if the bug is present.
  insert into t2 values ('anything else');
  # The following shows table corruption if the bug is present.
  check table t2;
  #
  connection default;
  disconnect con1;
  disconnect con2;
  drop table t1, t2;
EOF
echo


echo "######################################################################"
echo "#"
echo "# Running test #2."
"$MYSQLT" $PORT_1 $SOCK_1 $USER_1 $TEST_1 <<\EOF
  --disable_warnings
  drop table if exists t1, t2;
  --enable_warnings

  #
  # Bug#18544 - LOCK TABLES timeout causes MyISAM table corruption
  # Case 2: Locking error in get_lock_data() due to missing write permission.
  #
  create table t1 (c varchar(255), primary key(c)) engine=myisam;
  create table t2 (c varchar(255), primary key(c)) engine=myisam;
  #
  connect (con1,localhost,root,,);
  connect (con2,localhost,root,,);
  #
  connection con1;
  insert into t1 values ('anything');
  lock tables t1 write;
  #
  connection con2;
  system chmod a-w test/t2.*;
  # The next statement fails because of missing write permission on t2.
  # It leaves behind t1 marked as being read locked if the bug is present.
  --error 1036
  send lock tables t1 read, t2 write;
  #
  connection con1;
  --sleep 2
  unlock tables;
  # This insert works on a read locked table if the bug is present.
  insert into t1 values ('anything else');
  # The following shows table corruption if the bug is present.
  check table t1;
  #
  connection con2;
  system chmod +w test/t2.*;
  --error 1036
  reap;
  connection default;
  disconnect con1;
  disconnect con2;
  drop table t1, t2;
EOF
echo


echo "######################################################################"
echo "#"
echo "# Running test #3."
"$MYSQLT" $PORT_1 $SOCK_1 $USER_1 $TEST_1 <<\EOF
  --disable_warnings
  drop table if exists t1, t2;
  --enable_warnings

  #
  # Bug#18544 - LOCK TABLES timeout causes MyISAM table corruption
  # Case 3: Locking error in wait_if_global_read_lock() due to lock conflict.
  #
  create table t1 (c varchar(255), primary key(c)) engine=myisam;
  create table t2 (c varchar(255), primary key(c)) engine=myisam;
  #
  insert into t1 values ('anything');
  flush tables with read lock;
  #
  # The next statement fails because of the lock conflict on t2.
  # It leaves behind t1 marked as being read locked if the bug is present.
  --error 1223
  lock tables t1 read, t2 write;
  #
  unlock tables;
  # This insert works on a read locked table if the bug is present.
  insert into t1 values ('anything else');
  # The following shows table corruption if the bug is present.
  check table t1;
  #
  drop table t1, t2;
EOF
echo


echo "######################################################################"
echo "#"
echo "# Stopping database server."
"$MYSQLA" $PORT_1 $SOCK_1 -u root shutdown
sleep 3
echo


echo "# End of Test."
echo "#"
echo "######################################################################"

