From 646ae53f8a8715c1a8d66de4696a101df7bc3924 Mon Sep 17 00:00:00 2001
From: unknown <Sinisa@sinisa.nasamreza.org>
Date: Sat, 2 Nov 2002 16:10:53 +0200
Subject: [PATCH 01/18] Added test case for the last fix

---
 mysql-test/r/func_test.result |  4 ++++
 mysql-test/t/func_test.test   | 10 ++++++++++
 2 files changed, 14 insertions(+)

diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index 586e345ea10..da82567db4d 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -26,6 +26,10 @@
 1	1	1
 -1.49 or -1.49	0.6 or 0.6
 1	1
+start	ctime1	ctime2
+2002-11-04 00:00:00	20021029165106	20021105164731
+start	ctime1	ctime2
+2002-11-04 00:00:00	20021029165106	20021105164731
 5 between 0 and 10 between 0 and 1	(5 between 0 and 10) between 0 and 1
 0	1
 1 and 2 between 2 and 10	2 between 2 and 10 and 1
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index ec44009b1a6..ccbb531e2e6 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -15,6 +15,16 @@ select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between
 select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
 select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
 select -1.49 or -1.49,0.6 or 0.6;
+drop table if exists t1,t2;
+CREATE TABLE t1 ( start datetime default NULL) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('2002-10-21 00:00:00');
+INSERT INTO t1 VALUES ('2002-10-28 00:00:00');
+INSERT INTO t1 VALUES ('2002-11-04 00:00:00');
+CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL) TYPE=MyISAM;
+INSERT INTO t2 VALUES (20021029165106,20021105164731);
+select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
+select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
+drop table if exists t1,t2;
 
 #
 # Wrong usage of functions

From 8e9a5a4f10a04ce793e76c91bd47b4ed146406b5 Mon Sep 17 00:00:00 2001
From: unknown <lenz@mysql.com>
Date: Tue, 19 Nov 2002 13:45:51 +0100
Subject: [PATCH 02/18]  - applied patch for AMD x86-64    (thanks to Gwenole
 Beauchesne <gbeauchesne@mandrakesoft.com>

bdb/dist/aclocal/mutex.m4:
   - applied patch for AMD x86-64
---
 bdb/dist/aclocal/mutex.m4 | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bdb/dist/aclocal/mutex.m4 b/bdb/dist/aclocal/mutex.m4
index a6b1fa1a053..5c9218da163 100644
--- a/bdb/dist/aclocal/mutex.m4
+++ b/bdb/dist/aclocal/mutex.m4
@@ -403,5 +403,7 @@ UTS/cc-assembly)	ADDITIONAL_OBJS="$ADDITIONAL_OBJS uts4.cc${o}"
 			AC_DEFINE(HAVE_MUTEX_UTS_CC_ASSEMBLY);;
 x86/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
 			AC_DEFINE(HAVE_MUTEX_X86_GCC_ASSEMBLY);;
+x86_64/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			AC_DEFINE(HAVE_MUTEX_X86_64_GCC_ASSEMBLY);;
 esac
 ])dnl

From 0b19cb1e2dcf180ced44403f3ce8d78437468348 Mon Sep 17 00:00:00 2001
From: unknown <lenz@mysql.com>
Date: Wed, 20 Nov 2002 22:16:29 +0100
Subject: [PATCH 03/18] Do-compile:

 - applied some changes from the 4.0 tree (enable multiple
   --conf-environment options, add --with-debug, don't add "-max"
   prefix just because BDB is enabled)


Build-tools/Do-compile:
   - applied some changes from the 4.0 tree (enable multiple
     --conf-environment options, add --with-debug, don't add "-max"
     prefix just because BDB is enabled)
---
 Build-tools/Do-compile | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile
index 067b88888ac..dd082181200 100755
--- a/Build-tools/Do-compile
+++ b/Build-tools/Do-compile
@@ -14,7 +14,7 @@ $opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=0;
 GetOptions(
 	"bdb",
 	"build-thread=i",
-	"config-env=s",
+	"config-env=s" => \@config_env,
 	"config-options=s" => \@config_options,
 	"dbd-options=s",
 	"debug",
@@ -45,6 +45,7 @@ GetOptions(
 	"use-old-distribution",
 	"user=s",
 	"version-suffix=s",
+	"with-debug",
 	"with-low-memory",
 	"with-other-libc=s",
 	"with-small-disk",
@@ -53,11 +54,6 @@ GetOptions(
 usage() if ($opt_help);
 usage() if (!$opt_distribution);
 
-if ($opt_bdb && $opt_version_suffix eq "")
-{
-  $opt_version_suffix="-max";
-}
-
 if (@make_options > 0)
 {
 	chomp(@make_options);
@@ -70,6 +66,12 @@ if (@config_options > 0)
 	$opt_config_options= join(" ", @config_options);
 }
 
+if (@config_env > 0)
+{
+	chomp(@config_env);
+	$opt_config_env= join(" ", @config_env);
+}
+
 chomp($host=`hostname`);
 $full_host_name=$host;
 $connect_option= ($opt_tcpip ? "--host=$host" : "");
@@ -208,6 +210,7 @@ if ($opt_stage <= 1)
   $opt_config_options.= " --disable-shared" if (!$opt_enable_shared); # Default for binary versions
   $opt_config_options.= " --with-berkeley-db" if ($opt_bdb);
   $opt_config_options.= " --with-client-ldflags=-all-static" if ($opt_static_client);
+	$opt_config_options.= " --with-debug" if ($opt_with_debug);
   $opt_config_options.= " --with-libwrap" if ($opt_libwrap);
   $opt_config_options.= " --with-low-memory" if ($opt_with_low_memory);
   $opt_config_options.= " --with-mysqld-ldflags=-all-static" if ($opt_static_server);
@@ -258,7 +261,7 @@ if ($opt_stage <= 3)
   log_system("rm -fr mysql-3* mysql-4* $pwd/$host/*.tar.gz");
   log_system("nm -n sql/mysqld | gzip -9 -v 2>&1 > sql/mysqld.sym.gz | cat");
 
-  $flags.= "--no-strip" if ($opt_no_strip);
+  $flags.= "--no-strip" if ($opt_no_strip || $opt_with_debug);
   check_system("scripts/make_binary_distribution --tmp=$opt_tmp --suffix=$opt_suffix $flags",".tar.gz created");
   safe_system("mv mysql*.tar.gz $pwd/$host");
   if (-f "client/.libs/mysqladmin")
@@ -500,6 +503,9 @@ If user is empty then no mail is sent.
 --version-suffix suffix
 Set name suffix (e.g. 'com' or '-max') for a distribution
 
+--with-debug
+Build binaries with debug information (implies "--no-strip")
+
 --with-low-memory
 Use less memory when compiling.
 
@@ -530,7 +536,7 @@ sub abort
     print TMP "To: $email\n";
     print TMP "Subject: $ver$opt_version_suffix compilation failed\n\n";
     close TMP;
-    system("tail -40 $log > $log.mail");
+    system("tail -n 40 $log > $log.mail");
     system("cat $mail_header_file $log.mail | $sendmail -t -f $email");
     unlink($mail_header_file);
     unlink("$log.mail");
@@ -606,7 +612,7 @@ sub which
   my(@progs)=@_;
   foreach $prog (@progs)
   {
-    chomp($found=`which $prog | head -1`);
+    chomp($found=`which $prog | head -n 1`);
     if ($? == 0 && $found ne "" && index($found," ") == -1)
     {
       $found =~ s|/+|/|g;	# Make nicer output

From d0236e30a4c878ff352e4f6ee1f4c1ff74de9e26 Mon Sep 17 00:00:00 2001
From: unknown <Sinisa@sinisa.nasamreza.org>
Date: Thu, 21 Nov 2002 17:55:49 +0200
Subject: [PATCH 04/18] A fix for --bind-address=hostname

---
 sql/mysqld.cc | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 71b832f24f4..8d6a1a8a700 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3543,7 +3543,6 @@ static void set_options(void)
 #endif
   my_bind_addr = htonl( INADDR_ANY );
 }
-
 	/* Initiates DEBUG - but no debugging here ! */
 
 static void get_options(int argc,char **argv)
@@ -3893,7 +3892,7 @@ static void get_options(int argc,char **argv)
       else
       {
 	struct hostent *ent;
-	if (!optarg || !optarg[0])
+	if (optarg && optarg[0])
 	  ent=gethostbyname(optarg);
 	else
 	{

From 6f5b38b9dd0841e1841af1243dd19b5a12b59e34 Mon Sep 17 00:00:00 2001
From: unknown <Sinisa@sinisa.nasamreza.org>
Date: Thu, 21 Nov 2002 18:14:27 +0200
Subject: [PATCH 05/18] fix error in result

mysql-test/r/func_test.result:
  Fixing the error in result
---
 mysql-test/r/func_test.result | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index da82567db4d..2f40740d4aa 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -27,7 +27,6 @@
 -1.49 or -1.49	0.6 or 0.6
 1	1
 start	ctime1	ctime2
-2002-11-04 00:00:00	20021029165106	20021105164731
 start	ctime1	ctime2
 2002-11-04 00:00:00	20021029165106	20021105164731
 5 between 0 and 10 between 0 and 1	(5 between 0 and 10) between 0 and 1

From a3a99fc7cadc43a5efc071d33dc90ed7f7799034 Mon Sep 17 00:00:00 2001
From: unknown <Sinisa@sinisa.nasamreza.org>
Date: Thu, 21 Nov 2002 22:13:23 +0200
Subject: [PATCH 06/18] A fix for the bug with: delete from table where
 column<=>NULL on indexed columns

---
 mysql-test/r/delete.result | 6 ++++++
 mysql-test/t/delete.test   | 5 +++++
 sql/opt_range.cc           | 2 +-
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index c2230722aa6..e3e95c79fb7 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -24,3 +24,9 @@ create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
 insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
 delete from t1 where a=27;
 drop table t1;
+create table t1 (id int, index(id));
+insert into t1 values(NULL);
+delete from t1 where id <=> NULL;
+select * from t1;
+id
+drop table if exists t1;
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index 953e22cdd55..fc57fdabcd5 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -35,3 +35,8 @@ create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
 insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
 delete from t1 where a=27;
 drop table t1;
+create table t1 (id int, index(id));
+insert into t1 values(NULL);
+delete from t1 where id <=> NULL;
+select * from t1;
+drop table if exists t1;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index f33a2d312b4..14999097c62 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1024,7 +1024,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
       field->cmp_type() != value->result_type())
     DBUG_RETURN(0);
 
-  if (value->save_in_field(field))
+  if (value->save_in_field(field) || value->is_null())
   {
     // TODO; Check if we can we remove the following block.
     if (type == Item_func::EQUAL_FUNC)

From 9a2ac08bac0de5e0e42edb1e45ed28da4a7f1b1c Mon Sep 17 00:00:00 2001
From: unknown <lenz@mysql.com>
Date: Thu, 21 Nov 2002 21:42:44 +0100
Subject: [PATCH 07/18] configure.in:

 - fix MYSQL_NO_DASH_VERSION if version number ends on one digit only
   ("comment" test failed when MySQL version was changed from 4.0.5
   to 4.0.5a)


configure.in:
   - fix MYSQL_NO_DASH_VERSION if version number ends on one digit only
     ("comment" test failed when MySQL version was changed from 4.0.5
     to 4.0.5a)
---
 configure.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure.in b/configure.in
index cc9e9f772b4..4dfee69f1c0 100644
--- a/configure.in
+++ b/configure.in
@@ -15,6 +15,7 @@ SHARED_LIB_VERSION=11:0:0
 # Set all version vars based on $VERSION. How do we do this more elegant ?
 # Remember that regexps needs to quote [ and ] since this is run through m4
 MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"`
+MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[a-z]*-.*$||"`
 MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"`
 F_PART=`echo $MYSQL_BASE_VERSION | sed -e "s|\.||g"| sed -e "s|[a-zA-Z]\+||"|sed -e "s|^\(..\)$|\\10|"`
 L_PART=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|^[[0-9]]\.[[0-9]]*\.||" | sed -e "s|^\(.\)$|0\\1|" | sed -e "s|[[a-z]]||"`

From b473d7d6405e9ab2d65baff3e7a79faae0229c09 Mon Sep 17 00:00:00 2001
From: unknown <lenz@mysql.com>
Date: Thu, 21 Nov 2002 22:14:57 +0100
Subject: [PATCH 08/18] configure.in:

 - actually follow the hints in the comment above and "Remember that
   regexps needs to quote [ and ] since this is run through m4"...


configure.in:
   - actually follow the hints in the comment above and "Remember that
     regexps needs to quote [ and ] since this is run through m4"...
---
 configure.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure.in b/configure.in
index 4dfee69f1c0..9b70e81d088 100644
--- a/configure.in
+++ b/configure.in
@@ -15,7 +15,7 @@ SHARED_LIB_VERSION=11:0:0
 # Set all version vars based on $VERSION. How do we do this more elegant ?
 # Remember that regexps needs to quote [ and ] since this is run through m4
 MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"`
-MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[a-z]*-.*$||"`
+MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`
 MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"`
 F_PART=`echo $MYSQL_BASE_VERSION | sed -e "s|\.||g"| sed -e "s|[a-zA-Z]\+||"|sed -e "s|^\(..\)$|\\10|"`
 L_PART=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|^[[0-9]]\.[[0-9]]*\.||" | sed -e "s|^\(.\)$|0\\1|" | sed -e "s|[[a-z]]||"`

From 03ac294cceb5619557fffacbf95901f4c5b1997f Mon Sep 17 00:00:00 2001
From: unknown <bell@sanja.is.com.ua>
Date: Fri, 22 Nov 2002 00:33:15 +0200
Subject: [PATCH 09/18] fixed invalidation of query cache excluded double call
 of 'invalidate()'

mysql-test/r/innodb_cache.result:
  test of invalidation
mysql-test/t/innodb_cache.test:
  test of invalidation
sql/handler.cc:
  excluded double call of 'invalidate()'
sql/sql_delete.cc:
  fixed invalidation of query cache
sql/sql_insert.cc:
  fixed invalidation of query cache
sql/sql_update.cc:
  fixed invalidation of query cache
---
 mysql-test/r/innodb_cache.result | 10 ++++++++++
 mysql-test/t/innodb_cache.test   |  9 ++++++++-
 sql/handler.cc                   |  2 +-
 sql/sql_delete.cc                | 10 ++++------
 sql/sql_insert.cc                |  9 +++------
 sql/sql_update.cc                | 10 ++++------
 6 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/mysql-test/r/innodb_cache.result b/mysql-test/r/innodb_cache.result
index eaa030046da..47abcb45fe5 100644
--- a/mysql-test/r/innodb_cache.result
+++ b/mysql-test/r/innodb_cache.result
@@ -98,3 +98,13 @@ commit;
 show status like "Qcache_queries_in_cache";
 Variable_name	Value
 Qcache_queries_in_cache	1
+drop table if exists t1;
+CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY  (id)) TYPE=InnoDB;
+select count(*) from t1;
+count(*)
+0
+insert into t1 (id) values (0);
+select count(*) from t1;
+count(*)
+1
+drop table t1;
diff --git a/mysql-test/t/innodb_cache.test b/mysql-test/t/innodb_cache.test
index 21d30420eaf..9066a5f19ba 100644
--- a/mysql-test/t/innodb_cache.test
+++ b/mysql-test/t/innodb_cache.test
@@ -47,4 +47,11 @@ select * from t3;
 show status like "Qcache_queries_in_cache";
 show status like "Qcache_hits";
 commit;
-show status like "Qcache_queries_in_cache";
\ No newline at end of file
+show status like "Qcache_queries_in_cache";
+
+drop table if exists t1;
+CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY  (id)) TYPE=InnoDB;
+select count(*) from t1;
+insert into t1 (id) values (0);
+select count(*) from t1;
+drop table t1;
diff --git a/sql/handler.cc b/sql/handler.cc
index f07e90d2eb9..c4e742ef519 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -314,7 +314,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
     }
 #endif
 #ifdef HAVE_QUERY_CACHE
-    if (transaction_commited)
+    if (transaction_commited && thd->transaction.changed_tables)
       query_cache.invalidate(thd->transaction.changed_tables);
 #endif /*HAVE_QUERY_CACHE*/
     if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 5f2d7e36a04..1361ff39388 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -179,14 +179,12 @@ cleanup:
     if (ha_autocommit_or_rollback(thd,error >= 0))
       error=1;
   }
+
   /*
-    Only invalidate the query cache if something changed or if we
-    didn't commit the transacion (query cache is automaticly
-    invalidated on commit)
+    Store table for future invalidation  or invalidate it in
+    the query cache if something changed
   */
-  if (deleted &&
-      (!transactional_table ||
-       thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+  if (deleted)
   {
     query_cache_invalidate3(thd, table_list, 1);
   }
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 2508314c469..6ce2b50fc36 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -319,13 +319,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
       error=ha_autocommit_or_rollback(thd,error);
 
     /*
-      Only invalidate the query cache if something changed or if we
-      didn't commit the transacion (query cache is automaticly
-      invalidated on commit)
+      Store table for future invalidation  or invalidate it in
+      the query cache if something changed
     */
-    if ((info.copied || info.deleted) &&
-	(!transactional_table ||
-	 thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+    if (info.copied || info.deleted)
     {
       query_cache_invalidate3(thd, table_list, 1);
     }
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index b5263322301..97e6ea43bfd 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -318,14 +318,12 @@ int mysql_update(THD *thd,
     if (ha_autocommit_or_rollback(thd, error >= 0))
       error=1;
   }
+
   /*
-    Only invalidate the query cache if something changed or if we
-    didn't commit the transacion (query cache is automaticly
-    invalidated on commit)
+    Store table for future invalidation  or invalidate it in
+    the query cache if something changed
   */
-  if (updated &&
-      (!transactional_table ||
-       thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+  if (updated)
   {
     query_cache_invalidate3(thd, table_list, 1);
   }

From cb5a2b2fd5541bf019dd0fe1012e687ce1e68eaa Mon Sep 17 00:00:00 2001
From: unknown <monty@mashka.mysql.fi>
Date: Fri, 22 Nov 2002 13:35:43 +0200
Subject: [PATCH 10/18] Fixed bug with indexed NULL column <=> NULL Fix for Mac
 OS X shutdown

mysql-test/mysql-test-run.sh:
  Log client error messages
mysql-test/r/null_key.result:
  Test for bug in <=> NULL
mysql-test/t/null_key.test:
  Test for bug in <=> NULL
sql/mysqld.cc:
  Fix for Mac OS X shutdown
sql/opt_range.cc:
  Fixed bug with indexed NULL column <=> NULL
---
 mysql-test/mysql-test-run.sh |  3 ++-
 mysql-test/r/null_key.result | 17 +++++++++++++++++
 mysql-test/t/null_key.test   | 21 +++++++++++++++++++++
 sql/mysqld.cc                |  4 ++++
 sql/opt_range.cc             | 18 ++++++++++++------
 5 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 514ef9e704a..fcddf52c66b 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -249,6 +249,7 @@ SLAVE_MYPID="$MYRUN_DIR/mysqld-slave.pid"
 SLAVE_MYLOG="$MYSQL_TEST_DIR/var/log/mysqld-slave.log"
 SLAVE_MYERR="$MYSQL_TEST_DIR/var/log/mysqld-slave.err"
 
+CLIENT_MYLOG="$MYSQL_TEST_DIR/var/log/client.log"
 SMALL_SERVER="-O key_buffer_size=1M -O sort_buffer=256K -O max_heap_table_size=1M"
 
 export MASTER_MYPORT
@@ -344,7 +345,7 @@ SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov
 #--
 wait_for_server_start ()
 {
-   $MYSQLADMIN --no-defaults -u $DBUSER --silent -O connect_timeout=10 -w3 --host=$hostname --port=$1  ping >/dev/null 2>&1
+   $MYSQLADMIN --no-defaults -u $DBUSER --silent -O connect_timeout=10 -w3 --host=$hostname --port=$1  ping >> $CLIENT_MYLOG 2>&1
    exit_code=$?
    if [ $exit_code != 0 ]; then
 	echo "Error: Could not start $2, exit code $exit_code";
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index a0f88b804aa..46bcbebe170 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -126,3 +126,20 @@ order_id	product_id	product_type
 3d7ce39b5d4b3e3d22aaafe9b633de51	5880836	3
 id	id
 id	id
+id	id2
+NULL	0
+1	1
+id	id2
+NULL	0
+id	id2
+NULL	0
+1	1
+id	id2
+NULL	0
+1	1
+id	id2
+1	1
+id	id2
+1	1
+id	id2
+1	1
diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test
index 3ab8b993f43..b1cbd5cdfb0 100644
--- a/mysql-test/t/null_key.test
+++ b/mysql-test/t/null_key.test
@@ -135,3 +135,24 @@ select * from t1, t2 where t1.id = t2.id;
 alter table t1 add key id (id);
 select * from t1, t2 where t1.id = t2.id;
 drop table t1,t2;
+
+#
+# Check bug when doing <=> NULL on an indexed null field
+#
+
+create table t1 (
+  id  integer,
+  id2 integer not null,
+  index (id),
+  index (id2)
+);
+insert into t1 values(null,null),(1,1);
+select * from t1;
+select * from t1 where id <=> null;
+select * from t1 where id <=> null or id > 0;
+select * from t1 where id is null or id > 0;
+select * from t1 where id2 <=> null or id2 > 0;
+select * from t1 where id2 is null or id2 > 0;
+delete from t1 where id <=> NULL;
+select * from t1;
+drop table t1;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 71b832f24f4..7a33a3cfc49 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -739,7 +739,11 @@ static sig_handler print_signal_warning(int sig)
 void unireg_end(int signal_number __attribute__((unused)))
 {
   clean_up();
+#ifdef SIGNALS_DONT_BREAK_READ
+  exit(0);
+#else
   pthread_exit(0);				// Exit is in main thread
+#endif
 }
 
 
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 42f20c0f767..0645fe15df3 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -931,8 +931,11 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
     if (!(res= value->val_str(&tmp)))
       DBUG_RETURN(&null_element);
 
-    // Check if this was a function. This should have be optimized away
-    // in the sql_select.cc
+    /*
+      TODO:
+      Check if this was a function. This should have be optimized away
+      in the sql_select.cc
+    */
     if (res != &tmp)
     {
       tmp.copy(*res);				// Get own copy
@@ -1011,8 +1014,10 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
       type != Item_func::EQUAL_FUNC)
     DBUG_RETURN(0);				// Can't optimize this
 
-  /* We can't always use indexes when comparing a string index to a number */
-  /* cmp_type() is checked to allow compare of dates to numbers */
+  /*
+    We can't always use indexes when comparing a string index to a number
+    cmp_type() is checked to allow compare of dates to numbers
+  */
   if (field->result_type() == STRING_RESULT &&
       value->result_type() != STRING_RESULT &&
       field->cmp_type() != value->result_type())
@@ -1020,6 +1025,7 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
 
   if (value->save_in_field(field))
   {
+    /* This happens when we try to insert a NULL field in a not null column */
     if (type == Item_func::EQUAL_FUNC)
     {
       /* convert column_name <=> NULL -> column_name IS NULL */
@@ -1029,14 +1035,14 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
       *str = 1;
       DBUG_RETURN(new SEL_ARG(field,str,str));
     }
-    DBUG_RETURN(&null_element);			// NULL is never true
+    DBUG_RETURN(&null_element);			// cmp with NULL is never true
   }
   // Get local copy of key
   char *str= (char*) sql_alloc(key_part->part_length+maybe_null);
   if (!str)
     DBUG_RETURN(0);
   if (maybe_null)
-    *str=0;					// Not NULL
+    *str= (char) field->is_real_null();		// Set to 1 if null
   field->get_key_image(str+maybe_null,key_part->part_length);
   if (!(tree=new SEL_ARG(field,str,str)))
     DBUG_RETURN(0);

From 89083f2d6d078eb25f1fe013d8cd5bc46b9a631c Mon Sep 17 00:00:00 2001
From: unknown <Sinisa@sinisa.nasamreza.org>
Date: Fri, 22 Nov 2002 13:47:01 +0200
Subject: [PATCH 11/18] reverting a change

---
 sql/opt_range.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 14999097c62..f33a2d312b4 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1024,7 +1024,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
       field->cmp_type() != value->result_type())
     DBUG_RETURN(0);
 
-  if (value->save_in_field(field) || value->is_null())
+  if (value->save_in_field(field))
   {
     // TODO; Check if we can we remove the following block.
     if (type == Item_func::EQUAL_FUNC)

From 001446d97134edad95b3235082256c0202f51cd9 Mon Sep 17 00:00:00 2001
From: unknown <monty@mashka.mysql.fi>
Date: Fri, 22 Nov 2002 13:52:40 +0200
Subject: [PATCH 12/18] Moved test to correct file

---
 mysql-test/r/func_test.result |  3 ---
 mysql-test/r/func_time.result |  5 +++++
 mysql-test/t/func_test.test   | 10 ----------
 mysql-test/t/func_time.test   | 18 ++++++++++++++++++
 4 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index 2f40740d4aa..586e345ea10 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -26,9 +26,6 @@
 1	1	1
 -1.49 or -1.49	0.6 or 0.6
 1	1
-start	ctime1	ctime2
-start	ctime1	ctime2
-2002-11-04 00:00:00	20021029165106	20021105164731
 5 between 0 and 10 between 0 and 1	(5 between 0 and 10) between 0 and 1
 0	1
 1 and 2 between 2 and 10	2 between 2 and 10 and 1
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 71fc7e4b90b..a77d9b2cdff 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -220,3 +220,8 @@ to_days("0000-00-00")	to_days(d)	to_days(dt)	to_days(t)	to_days(c)
 NULL	NULL	NULL	NULL	NULL
 extract(MONTH FROM "0000-00-00")	extract(MONTH FROM d)	extract(MONTH FROM dt)	extract(MONTH FROM t)	extract(MONTH FROM c)
 0	0	0	0	0
+start	ctime1	ctime2
+start	ctime1	ctime2
+2002-11-04 00:00:00	20021029165106	20021105164731
+start	ctime1	ctime2
+2002-11-04 00:00:00	2002-10-29 16:51:06	2002-11-05 16:47:31
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index ccbb531e2e6..ec44009b1a6 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -15,16 +15,6 @@ select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between
 select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
 select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
 select -1.49 or -1.49,0.6 or 0.6;
-drop table if exists t1,t2;
-CREATE TABLE t1 ( start datetime default NULL) TYPE=MyISAM;
-INSERT INTO t1 VALUES ('2002-10-21 00:00:00');
-INSERT INTO t1 VALUES ('2002-10-28 00:00:00');
-INSERT INTO t1 VALUES ('2002-11-04 00:00:00');
-CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL) TYPE=MyISAM;
-INSERT INTO t2 VALUES (20021029165106,20021105164731);
-select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
-select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
-drop table if exists t1,t2;
 
 #
 # Wrong usage of functions
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index ffb0f8bbf1e..e267339d64c 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -150,3 +150,21 @@ select yearweek("0000-00-00"),yearweek(d),yearweek(dt),yearweek(t),yearweek(c) f
 select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t1;
 select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1;
 drop table t1;
+
+
+#
+# Test problem with TIMESTAMP and BETWEEN
+#
+
+CREATE TABLE t1 ( start datetime default NULL);
+INSERT INTO t1 VALUES ('2002-10-21 00:00:00'),('2002-10-28 00:00:00'),('2002-11-04 00:00:00');
+CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL);
+INSERT INTO t2 VALUES (20021029165106,20021105164731);
+CREATE TABLE t3 (ctime1 char(19) NOT NULL, ctime2 char(19) NOT NULL);
+INSERT INTO t3 VALUES ("2002-10-29 16:51:06","2002-11-05 16:47:31");
+
+# The following statement should be fixed to return a row in 4.1
+select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
+select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
+select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2;
+drop table t1,t2,t3;

From fa76afe6edbc6572f179d1dcf859f013e85ef7dd Mon Sep 17 00:00:00 2001
From: unknown <heikki@hundin.mysql.fi>
Date: Fri, 22 Nov 2002 13:59:06 +0200
Subject: [PATCH 13/18] ut0mem.c:   Flush stderr if we run out of memory, so
 that the error message more probably finds its way to the error log

innobase/ut/ut0mem.c:
  Flush stderr if we run out of memory, so that the error message more probably finds its way to the error log
---
 innobase/ut/ut0mem.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c
index 2a7643551ad..03f15031fdf 100644
--- a/innobase/ut/ut0mem.c
+++ b/innobase/ut/ut0mem.c
@@ -90,6 +90,12 @@ ut_malloc_low(
 		"InnoDB: on Linux we get a stack trace.\n",
 		                  n, ut_total_allocated_memory, errno);
 
+		/* Flush stderr to make more probable that the error
+		message gets in the error file before we generate a seg
+		fault */
+
+		fflush(stderr);
+
 	        os_fast_mutex_unlock(&ut_list_mutex);
 
 		/* Make an intentional seg fault so that we get a stack

From 3853ff4de26c9e7d3dee8b3b14292311a7ff85ab Mon Sep 17 00:00:00 2001
From: unknown <lenz@mysql.com>
Date: Fri, 22 Nov 2002 18:26:45 +0100
Subject: [PATCH 14/18] scripts/safe_mysqld.sh      - fix setting of niceness
 level

support-files/mysql.server.sh
     - applied some fixes from 4.0 mysql.server script
     - fix my.cnf parsing


scripts/safe_mysqld.sh:
   - fix setting of niceness level, if one adds "renice -20 $$" to safe_mysqld
     as hinted in the manual (which could result in NOHUP_NICENESS having a
     value of "-15" and hence there would be one dash too much)
support-files/mysql.server.sh:
   - applied some fixes from 4.0 mysql.server script
   - fix to actually parse the documented section ([mysql.server] not
     [mysql_server]) in my.cnf on startup
---
 scripts/safe_mysqld.sh        |  2 +-
 support-files/mysql.server.sh | 40 +++++++++++++++++++++++------------
 2 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/scripts/safe_mysqld.sh b/scripts/safe_mysqld.sh
index 2b625dbdfa3..2272443c972 100644
--- a/scripts/safe_mysqld.sh
+++ b/scripts/safe_mysqld.sh
@@ -159,7 +159,7 @@ then
   NOHUP_NICENESS=`nohup nice 2>&1`
  if test $? -eq 0 && test x"$NOHUP_NICENESS" != x0 && nice --1 echo foo > /dev/null 2>&1
  then
-    NOHUP_NICENESS="nice --$NOHUP_NICENESS nohup"
+    NOHUP_NICENESS="nice -n $NOHUP_NICENESS nohup"
   else
     NOHUP_NICENESS="nohup"
   fi
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index ecc49106c91..91821fd09e5 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -2,7 +2,7 @@
 # Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
 # This file is public domain and comes with NO WARRANTY of any kind
 
-# Mysql daemon start/stop script.
+# MySQL daemon start/stop script.
 
 # Usually this is put in /etc/init.d (at least on machines SYSV R4 based
 # systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql.
@@ -20,21 +20,31 @@
 # Required-Stop: $local_fs $network $remote_fs
 # Default-Start:  3 5
 # Default-Stop: 3 5
-# Short-Description: start and stop MySLQ
+# Short-Description: start and stop MySQL
 # Description: MySQL is a very fast and reliable SQL database engine.
 ### END INIT INFO
  
+# If you install MySQL on some other places than @prefix@, then you
+# have to do one of the following things for this script to work:
+#
+# - Run this script from within the MySQL installation directory
+# - Create a /etc/my.cnf file with the following information:
+#   [mysqld]
+#   basedir=<path-to-mysql-installation-directory>
+# - Add the above to any other configuration file (for example ~/.my.ini)
+#   and copy my_print_defaults to /usr/bin
+# - Add the path to the mysql-installation-directory to the basedir variable
+#   below.
+#
+# If you want to affect other MySQL variables, you should make your changes
+# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.
+
+basedir=
 
 # The following variables are only set for letting mysql.server find things.
-# If you want to affect other MySQL variables, you should make your changes
-# in the /etc/my.cnf or other configuration files.
-
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-export PATH
 
 # Set some defaults
 datadir=@localstatedir@
-basedir=
 pid_file=
 if test -z "$basedir"
 then
@@ -43,6 +53,10 @@ then
 else
   bindir="$basedir/bin"
 fi
+
+PATH=/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin
+export PATH
+
 if test -z "$pid_file"
 then
   pid_file=$datadir/`@HOSTNAME@`.pid
@@ -65,7 +79,7 @@ parse_arguments() {
   done
 }
 
-# Get arguments from the my.cnf file, groups [mysqld] and [mysql_server]
+# Get arguments from the my.cnf file, groups [mysqld] and [mysql.server]
 if test -x ./bin/my_print_defaults
 then
   print_defaults="./bin/my_print_defaults"
@@ -103,7 +117,7 @@ else
   test -z "$print_defaults" && print_defaults="my_print_defaults"
 fi
 
-parse_arguments `$print_defaults $defaults mysqld mysql_server`
+parse_arguments `$print_defaults $defaults mysqld mysql.server`
 
 # Safeguard (relative paths, core dumps..)
 cd $basedir
@@ -123,14 +137,14 @@ case "$mode" in
         touch /var/lock/subsys/mysql
       fi
     else
-      echo "Can't execute $bindir/safe_mysqld"
+      echo "Can't execute $bindir/safe_mysqld from dir $basedir"
     fi
     ;;
 
   'stop')
     # Stop daemon. We use a signal here to avoid having to know the
     # root password.
-    if test -f "$pid_file"
+    if test -s "$pid_file"
     then
       mysqld_pid=`cat $pid_file`
       echo "Killing mysqld with pid $mysqld_pid"
@@ -140,7 +154,7 @@ case "$mode" in
       sleep 1
       while [ -s $pid_file -a "$flags" != aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ]
       do
-        [ -z "$flags" ] && echo "Wait for mysqld to exit\c" || echo ".\c"
+        [ -z "$flags" ] && echo -n "Wait for mysqld to exit" || echo -n "."
         flags=a$flags
         sleep 1
       done

From fe9bbec4c0c48a680dbfeecd4d334679bc7bd5d4 Mon Sep 17 00:00:00 2001
From: unknown <Sinisa@sinisa.nasamreza.org>
Date: Sat, 23 Nov 2002 15:49:12 +0200
Subject: [PATCH 15/18] reverting a test that belongs to 3.23

---
 mysql-test/r/delete.result | 6 ------
 mysql-test/t/delete.test   | 5 -----
 2 files changed, 11 deletions(-)

diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index e3e95c79fb7..c2230722aa6 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -24,9 +24,3 @@ create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
 insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
 delete from t1 where a=27;
 drop table t1;
-create table t1 (id int, index(id));
-insert into t1 values(NULL);
-delete from t1 where id <=> NULL;
-select * from t1;
-id
-drop table if exists t1;
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index fc57fdabcd5..953e22cdd55 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -35,8 +35,3 @@ create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
 insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
 delete from t1 where a=27;
 drop table t1;
-create table t1 (id int, index(id));
-insert into t1 values(NULL);
-delete from t1 where id <=> NULL;
-select * from t1;
-drop table if exists t1;

From 72da2e4c9463aeb80083fd53cc0e6f5091b5f4f7 Mon Sep 17 00:00:00 2001
From: unknown <monty@mashka.mysql.fi>
Date: Sun, 24 Nov 2002 15:47:19 +0200
Subject: [PATCH 16/18] Added new ANSI functions LOCALTIME, LOCALTIMESTAMP and
 CURRENT_USER Added CEIL as an alias for CEILING Cleaned up CHECK constraint
 handling. (We don't anymore require braces after CHECK) Added casting to
 CHAR.

mysql-test/r/bigint.result:
  Moved casting test to cast.test
mysql-test/r/func_time.result:
  Test of new functions
mysql-test/t/bigint.test:
  Moved casting test to cast.test
mysql-test/t/func_time.test:
  Test of new functions
sql/item_create.cc:
  Added casting to CHAR
sql/item_func.h:
  Added casting to CHAR
sql/item_timefunc.h:
  Added casting to CHAR
sql/lex.h:
  Added new ANSI functions LOCALTIME, LOCALTIMESTAMP and CURRENT_USER
  Added CEIL as an alias for CEILING
sql/sql_yacc.yy:
  Cleaned up CHECK constraint handling.
---
 mysql-test/r/bigint.result      | 21 ------------------
 mysql-test/r/cast.result        | 39 +++++++++++++++++++++++++++++++++
 mysql-test/r/constraints.result | 16 ++++++++++++++
 mysql-test/r/func_time.result   |  6 +++++
 mysql-test/t/bigint.test        |  8 -------
 mysql-test/t/cast.test          | 22 +++++++++++++++++++
 mysql-test/t/constraints.test   | 21 ++++++++++++++++++
 mysql-test/t/func_time.test     |  2 ++
 sql/item_create.cc              |  1 +
 sql/item_func.h                 |  2 +-
 sql/item_timefunc.h             | 13 +++++++++++
 sql/lex.h                       |  4 ++++
 sql/sql_yacc.yy                 | 19 +++++++++++-----
 13 files changed, 138 insertions(+), 36 deletions(-)
 create mode 100644 mysql-test/r/cast.result
 create mode 100644 mysql-test/r/constraints.result
 create mode 100644 mysql-test/t/cast.test
 create mode 100644 mysql-test/t/constraints.test

diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index f666c5311b8..6afa74d20e2 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -52,24 +52,3 @@ select min(big),max(big),max(big)-1 from t1 group by a;
 min(big)	max(big)	max(big)-1
 -1	9223372036854775807	9223372036854775806
 drop table t1;
-select CAST(1-2 AS UNSIGNED);
-CAST(1-2 AS UNSIGNED)
-18446744073709551615
-select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
-CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
--1
-select CONVERT('-1',UNSIGNED);
-CONVERT('-1',UNSIGNED)
-18446744073709551615
-select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
-cast(-5 as unsigned) | 1	cast(-5 as unsigned) & -1
-18446744073709551611	18446744073709551611
-select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
-cast(-5 as unsigned) -1	cast(-5 as unsigned) + 1
-18446744073709551610	18446744073709551612
-select ~5, cast(~5 as signed);
-~5	cast(~5 as signed)
-18446744073709551610	-6
-select cast(5 as unsigned) -6.0;
-cast(5 as unsigned) -6.0
--1.0
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
new file mode 100644
index 00000000000..572b32c171c
--- /dev/null
+++ b/mysql-test/r/cast.result
@@ -0,0 +1,39 @@
+select CAST(1-2 AS UNSIGNED);
+CAST(1-2 AS UNSIGNED)
+18446744073709551615
+select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
+CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
+-1
+select CONVERT('-1',UNSIGNED);
+CONVERT('-1',UNSIGNED)
+18446744073709551615
+select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
+cast(-5 as unsigned) | 1	cast(-5 as unsigned) & -1
+18446744073709551611	18446744073709551611
+select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
+cast(-5 as unsigned) -1	cast(-5 as unsigned) + 1
+18446744073709551610	18446744073709551612
+select ~5, cast(~5 as signed);
+~5	cast(~5 as signed)
+18446744073709551610	-6
+select cast(5 as unsigned) -6.0;
+cast(5 as unsigned) -6.0
+-1.0
+select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
+cast("A" as binary) = "a"	cast(BINARY "a" as CHAR) = "A"
+0	1
+select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
+cast("2001-1-1" as DATE)	cast("2001-1-1" as DATETIME)
+2001-1-1	2001-1-1
+select cast("1:2:3" as TIME);
+cast("1:2:3" as TIME)
+1:2:3
+select cast("2001-1-1" as date) = "2001-01-01";
+cast("2001-1-1" as date) = "2001-01-01"
+0
+select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
+cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
+0
+select cast("1:2:3" as TIME) = "1:02:03";
+cast("1:2:3" as TIME) = "1:02:03"
+0
diff --git a/mysql-test/r/constraints.result b/mysql-test/r/constraints.result
new file mode 100644
index 00000000000..3b41e291e0f
--- /dev/null
+++ b/mysql-test/r/constraints.result
@@ -0,0 +1,16 @@
+drop table if exists t1;
+create table t1 (a int check (a>0));
+insert into t1 values (1);
+insert into t1 values (0);
+drop table t1;
+create table t1 (a int ,b int, check a>b);
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int ,b int, constraint abc check (a>b));
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int null);
+insert into t1 values (1),(NULL);
+drop table t1;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 4a1012f73bf..2941352c776 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -24,6 +24,12 @@ now()-curdate()*1000000-curtime()
 select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
 strcmp(current_timestamp(),concat(current_date()," ",current_time()))
 0
+select strcmp(localtime(),concat(current_date()," ",current_time()));
+strcmp(localtime(),concat(current_date()," ",current_time()))
+0
+select strcmp(localtimestamp(),concat(current_date()," ",current_time()));
+strcmp(localtimestamp(),concat(current_date()," ",current_time()))
+0
 select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
 date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")
 January Thursday 2nd 1997 97 01 02 03 04 05 4
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index 15b35ac7c87..15c61c2c0dc 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -35,11 +35,3 @@ alter table t1 modify big bigint not null;
 select min(big),max(big),max(big)-1 from t1;
 select min(big),max(big),max(big)-1 from t1 group by a;
 drop table t1;
-
-select CAST(1-2 AS UNSIGNED);
-select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
-select CONVERT('-1',UNSIGNED);
-select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
-select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
-select ~5, cast(~5 as signed);
-select cast(5 as unsigned) -6.0;
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
new file mode 100644
index 00000000000..7a120ef5005
--- /dev/null
+++ b/mysql-test/t/cast.test
@@ -0,0 +1,22 @@
+#
+# Test of cast function
+#
+
+select CAST(1-2 AS UNSIGNED);
+select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
+select CONVERT('-1',UNSIGNED);
+select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
+select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
+select ~5, cast(~5 as signed);
+select cast(5 as unsigned) -6.0;
+select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
+select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
+select cast("1:2:3" as TIME);
+
+#
+# The following should be fixed in 4.1
+#
+
+select cast("2001-1-1" as date) = "2001-01-01";
+select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
+select cast("1:2:3" as TIME) = "1:02:03";
diff --git a/mysql-test/t/constraints.test b/mysql-test/t/constraints.test
new file mode 100644
index 00000000000..8682cdc42a2
--- /dev/null
+++ b/mysql-test/t/constraints.test
@@ -0,0 +1,21 @@
+#
+# Testing of constraints
+# Currently MySQL only ignores the syntax.
+#
+drop table if exists t1;
+
+create table t1 (a int check (a>0));
+insert into t1 values (1);
+insert into t1 values (0);
+drop table t1;
+create table t1 (a int ,b int, check a>b);
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int ,b int, constraint abc check (a>b));
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int null);
+insert into t1 values (1),(NULL);
+drop table t1;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 2ff57959965..fdbc0f71dba 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -12,6 +12,8 @@ select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
 select sec_to_time(time_to_sec('-838:59:59'));
 select now()-curdate()*1000000-curtime();
 select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
+select strcmp(localtime(),concat(current_date()," ",current_time()));
+select strcmp(localtimestamp(),concat(current_date()," ",current_time()));
 select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
 select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"));
 select dayofmonth("1997-01-02"),dayofmonth(19970323);
diff --git a/sql/item_create.cc b/sql/item_create.cc
index f28e3248c61..c5f53f0d040 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -425,6 +425,7 @@ Item *create_func_cast(Item *a, Item_cast cast_type)
   LINT_INIT(res);
   switch (cast_type) {
   case ITEM_CAST_BINARY: 	res= new Item_func_binary(a); break;
+  case ITEM_CAST_CHAR:	 	res= new Item_char_typecast(a); break;
   case ITEM_CAST_SIGNED_INT:	res= new Item_func_signed(a); break;
   case ITEM_CAST_UNSIGNED_INT:  res= new Item_func_unsigned(a); break;
   case ITEM_CAST_DATE:		res= new Item_date_typecast(a); break;
diff --git a/sql/item_func.h b/sql/item_func.h
index 2e02d7cfd28..b7e0cee540a 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1003,7 +1003,7 @@ public:
 enum Item_cast
 {
   ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
-  ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME
+  ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR
 };
 
 Item *create_func_cast(Item *a, Item_cast cast_type);
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 0fe487b7983..c0255e71d27 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -410,6 +410,7 @@ public:
   unsigned int size_of() { return sizeof(*this);}  
 };
 
+
 class Item_extract :public Item_int_func
 {
   const interval_type int_type;
@@ -424,10 +425,12 @@ class Item_extract :public Item_int_func
   unsigned int size_of() { return sizeof(*this);}  
 };
 
+
 class Item_typecast :public Item_str_func
 {
 public:
   Item_typecast(Item *a) :Item_str_func(a) {}
+  const char *func_name() const { return "char"; }
   String *val_str(String *a)
   { a=args[0]->val_str(a); null_value=args[0]->null_value; return a; }
   void fix_length_and_dec() { max_length=args[0]->max_length; }
@@ -435,6 +438,14 @@ public:
 };
 
 
+class Item_char_typecast :public Item_typecast
+{
+public:
+  Item_char_typecast(Item *a) :Item_typecast(a) {}
+  void fix_length_and_dec() { binary=0; max_length=args[0]->max_length; }
+};
+
+
 class Item_date_typecast :public Item_typecast
 {
 public:
@@ -450,6 +461,7 @@ public:
   }  
 };
 
+
 class Item_time_typecast :public Item_typecast
 {
 public:
@@ -465,6 +477,7 @@ public:
   }
 };
 
+
 class Item_datetime_typecast :public Item_typecast
 {
 public:
diff --git a/sql/lex.h b/sql/lex.h
index 49b6a3811e5..717e8a355ca 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -210,6 +210,8 @@ static SYMBOL symbols[] = {
   { "LIMIT",		SYM(LIMIT),0,0},
   { "LOAD",		SYM(LOAD),0,0},
   { "LOCAL",		SYM(LOCAL_SYM),0,0},
+  { "LOCALTIME",	SYM(NOW_SYM),0,0},
+  { "LOCALTIMESTAMP",	SYM(NOW_SYM),0,0},
   { "LOCK",		SYM(LOCK_SYM),0,0},
   { "LOCKS",		SYM(LOCKS_SYM),0,0},
   { "LOGS",		SYM(LOGS_SYM),0,0},
@@ -394,7 +396,9 @@ static SYMBOL sql_functions[] = {
   { "BIT_OR",		SYM(BIT_OR),0,0},
   { "BIT_AND",		SYM(BIT_AND),0,0},
   { "CAST",		SYM(CAST_SYM),0,0},
+  { "CEIL",		SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
   { "CEILING",		SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
+  { "CURRENT_USER",	SYM(USER),0,0},
   { "BIT_LENGTH",	SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)},
   { "CHAR_LENGTH",	SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
   { "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index f6a0c483bb9..c3c6d8ad66b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -899,7 +899,7 @@ field_list:
 
 
 field_list_item:
-	  field_spec
+	  field_spec check_constraint
 	| field_spec references
 	  {
 	    Lex->col_list.empty();		/* Alloced by sql_alloc */
@@ -914,10 +914,16 @@ field_list_item:
 	  {
 	    Lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
-	| opt_constraint CHECK_SYM '(' expr ')'
+	| opt_constraint check_constraint
 	  {
 	    Lex->col_list.empty();		/* Alloced by sql_alloc */
-	  };
+	  }
+	;
+
+check_constraint:
+	/* empty */
+	| CHECK_SYM expr
+	;
 
 opt_constraint:
 	/* empty */
@@ -1986,13 +1992,15 @@ in_sum_expr:
 
 cast_type:
 	BINARY 			{ $$=ITEM_CAST_BINARY; }
+	| CHAR_SYM		{ $$=ITEM_CAST_CHAR; }
 	| SIGNED_SYM		{ $$=ITEM_CAST_SIGNED_INT; }
 	| SIGNED_SYM INT_SYM	{ $$=ITEM_CAST_SIGNED_INT; }
 	| UNSIGNED		{ $$=ITEM_CAST_UNSIGNED_INT; }
 	| UNSIGNED INT_SYM	{ $$=ITEM_CAST_UNSIGNED_INT; }
 	| DATE_SYM		{ $$=ITEM_CAST_DATE; }
 	| TIME_SYM		{ $$=ITEM_CAST_TIME; }
-	| DATETIME		{ $$=ITEM_CAST_DATETIME; };
+	| DATETIME		{ $$=ITEM_CAST_DATETIME; }
+	;
 
 expr_list:
 	{ Select->expr_list.push_front(new List<Item>); }
@@ -2437,7 +2445,7 @@ table_name:
 	{ if (!add_table_to_list($1,NULL,1)) YYABORT; };
 
 if_exists:
-	/* empty */ { $$=0; }
+	/* empty */ { $$= 0; }
 	| IF EXISTS { $$= 1; }
 	;
 
@@ -3154,7 +3162,6 @@ keyword:
 	| CACHE_SYM		{}
 	| CHANGED		{}
 	| CHECKSUM_SYM		{}
-	| CHECK_SYM		{}
 	| CIPHER_SYM		{}
 	| CLIENT_SYM		{}
 	| CLOSE_SYM		{}

From bb948c635507db07365554d0e33bc09522c77557 Mon Sep 17 00:00:00 2001
From: unknown <monty@mashka.mysql.fi>
Date: Sun, 24 Nov 2002 16:20:41 +0200
Subject: [PATCH 17/18] Rewrote nice handling to make more portable

---
 scripts/safe_mysqld.sh | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/scripts/safe_mysqld.sh b/scripts/safe_mysqld.sh
index 2272443c972..96568bd5d19 100644
--- a/scripts/safe_mysqld.sh
+++ b/scripts/safe_mysqld.sh
@@ -157,9 +157,14 @@ NOHUP_NICENESS="nohup"
 if test -w /
 then
   NOHUP_NICENESS=`nohup nice 2>&1`
- if test $? -eq 0 && test x"$NOHUP_NICENESS" != x0 && nice --1 echo foo > /dev/null 2>&1
- then
-    NOHUP_NICENESS="nice -n $NOHUP_NICENESS nohup"
+  if test $? -eq 0 && test x"$NOHUP_NICENESS" != x0 && nice --1 echo foo > /dev/null 2>&1
+  then
+    if $NOHUP_NICENESS -gt 0
+    then
+      $NOHUP_NICENESS="nice --$NOHUP_NICENESS nohup"
+    else
+      NOHUP_NICENESS="nice -$NOHUP_NICENESS nohup"
+    fi
   else
     NOHUP_NICENESS="nohup"
   fi

From 79cdd8773c365d80e6ed528668dfb03eda7406b3 Mon Sep 17 00:00:00 2001
From: unknown <monty@mashka.mysql.fi>
Date: Sun, 24 Nov 2002 21:39:22 +0200
Subject: [PATCH 18/18] Updated results after merge from 3.23

---
 mysql-test/r/innodb-deadlock.result | 20 +++++++++++++++
 mysql-test/r/null_key.result        | 16 ++++++++++++
 mysql-test/t/innodb-deadlock.test   | 38 +++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+)
 create mode 100644 mysql-test/r/innodb-deadlock.result
 create mode 100644 mysql-test/t/innodb-deadlock.test

diff --git a/mysql-test/r/innodb-deadlock.result b/mysql-test/r/innodb-deadlock.result
new file mode 100644
index 00000000000..121bfa8c6cb
--- /dev/null
+++ b/mysql-test/r/innodb-deadlock.result
@@ -0,0 +1,20 @@
+drop table if exists t1;
+create table t1 (id integer, x integer) type=INNODB;
+insert into t1 values(0, 0);
+set autocommit=0;
+SELECT * from t1 where id = 0 FOR UPDATE;
+id	x
+0	0
+set autocommit=0;
+update t1 set x=2 where id = 0;
+update t1 set x=1 where id = 0;
+select * from t1;
+id	x
+0	1
+commit;
+commit;
+select * from t1;
+id	x
+0	2
+commit;
+drop table t1;
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index b737f9254b0..236def64b5e 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -228,20 +228,36 @@ alter table t1 add key id (id);
 select * from t1, t2 where t1.id = t2.id;
 id	id
 drop table t1,t2;
+create table t1 (
+id  integer,
+id2 integer not null,
+index (id),
+index (id2)
+);
+insert into t1 values(null,null),(1,1);
+select * from t1;
 id	id2
 NULL	0
 1	1
+select * from t1 where id <=> null;
 id	id2
 NULL	0
+select * from t1 where id <=> null or id > 0;
 id	id2
 NULL	0
 1	1
+select * from t1 where id is null or id > 0;
 id	id2
 NULL	0
 1	1
+select * from t1 where id2 <=> null or id2 > 0;
 id	id2
 1	1
+select * from t1 where id2 is null or id2 > 0;
 id	id2
 1	1
+delete from t1 where id <=> NULL;
+select * from t1;
 id	id2
 1	1
+drop table t1;
diff --git a/mysql-test/t/innodb-deadlock.test b/mysql-test/t/innodb-deadlock.test
new file mode 100644
index 00000000000..bc2839bfb3a
--- /dev/null
+++ b/mysql-test/t/innodb-deadlock.test
@@ -0,0 +1,38 @@
+-- source include/have_innodb.inc
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+drop table if exists t1;
+
+#
+# Testing of FOR UPDATE
+#
+
+connection con1;
+create table t1 (id integer, x integer) type=INNODB;
+insert into t1 values(0, 0);
+set autocommit=0;
+SELECT * from t1 where id = 0 FOR UPDATE;
+
+connection con2;
+set autocommit=0;
+
+# The following query should hang because con1 is locking the page
+--send
+update t1 set x=2 where id = 0;
+--sleep 2;
+
+connection con1;
+update t1 set x=1 where id = 0;
+select * from t1;
+commit;
+
+connection con2;
+reap;
+commit;
+
+connection con1;
+select * from t1;
+commit;
+
+drop table t1;