List:Commits« Previous MessageNext Message »
From:Bjorn Munch Date:August 26 2011 12:33pm
Subject:bzr push into mysql-trunk-mtr branch (bjorn.munch:3105 to 3108)
View as plain text  
 3108 Bjorn Munch	2011-08-26 [merge]
      merge some more from trunk

    modified:
      dbug/dbug.c
      mysql-test/collections/default.experimental
      mysql-test/include/range.inc
      mysql-test/r/derived.result
      mysql-test/r/range_icp.result
      mysql-test/r/range_icp_mrr.result
      mysql-test/r/range_mrr.result
      mysql-test/r/range_mrr_cost.result
      mysql-test/r/range_none.result
      mysql-test/suite/rpl/r/rpl_spec_variables.result
      mysql-test/suite/rpl/t/disabled.def
      mysql-test/suite/rpl/t/rpl_spec_variables.test
      mysql-test/t/derived.test
      sql/filesort.cc
      sql/opt_range.cc
      sql/records.cc
      sql/sql_base.cc
      sql/sql_select.cc
      sql/uniques.cc
 3107 Bjorn Munch	2011-08-26 [merge]
      merge from trunk after 5.6.3 clone-off

    added:
      mysql-test/suite/sys_vars/r/ssl_crl_basic.result
      mysql-test/suite/sys_vars/r/ssl_crlpath_basic.result
      mysql-test/suite/sys_vars/t/ssl_crl_basic.test
      mysql-test/suite/sys_vars/t/ssl_crlpath_basic.test
      unittest/gunit/decimal-t.cc
    modified:
      VERSION
      extra/innochecksum.c
      include/mysql/psi/mysql_socket.h
      include/mysql/psi/psi.h
      include/mysql/psi/psi_abi_v1.h.pp
      mysql-test/collections/default.experimental
      mysql-test/r/derived.result
      mysql-test/r/func_math.result
      mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
      mysql-test/suite/perfschema/include/socket_check1.inc
      mysql-test/suite/perfschema/include/socket_summary_check.inc
      mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result
      mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test
      mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test
      mysql-test/suite/rpl/r/rpl_row_mts_rec_crash_safe.result
      mysql-test/t/derived.test
      mysql-test/t/func_math.test
      mysys/psi_noop.cc
      sql/table.cc
      storage/innobase/dict/dict0stats.c
      storage/innobase/handler/ha_innodb.cc
      storage/perfschema/pfs.cc
      storage/perfschema/pfs_account.cc
      storage/perfschema/pfs_host.cc
      storage/perfschema/pfs_instr.cc
      storage/perfschema/pfs_instr_class.cc
      storage/perfschema/pfs_setup_actor.cc
      storage/perfschema/pfs_setup_object.cc
      storage/perfschema/pfs_user.cc
      strings/decimal.c
      unittest/gunit/CMakeLists.txt
 3106 Bjorn Munch	2011-08-26 [merge]
      MTR: small fix to read_plugin_defs for RPM builds:
        Also look into directories lib64 in addition to lib

    modified:
      mysql-test/mysql-test-run.pl
 3105 Bjorn Munch	2011-08-22 [merge]
      upmerge 11759877,12793170

    added:
      mysql-test/suite/sys_vars/t/plugin_dir_basic-master.opt
    modified:
      client/mysqltest.cc
      mysql-test/include/mtr_check.sql
      mysql-test/include/mysqld--help.inc
      mysql-test/mysql-test-run.pl
      mysql-test/r/execution_constants.result
      mysql-test/r/mysqltest.result
      mysql-test/suite/sys_vars/r/plugin_dir_basic.result
      mysql-test/suite/sys_vars/t/plugin_dir_basic.test
      mysql-test/t/execution_constants.test
      mysql-test/t/mysqltest.test
=== modified file 'VERSION'
--- a/VERSION	2011-08-18 11:40:27 +0000
+++ b/VERSION	2011-08-26 09:18:33 +0000
@@ -1,4 +1,4 @@
 MYSQL_VERSION_MAJOR=5
 MYSQL_VERSION_MINOR=6
-MYSQL_VERSION_PATCH=3
+MYSQL_VERSION_PATCH=4
 MYSQL_VERSION_EXTRA=-m5

=== modified file 'dbug/dbug.c'
--- a/dbug/dbug.c	2011-07-19 15:11:15 +0000
+++ b/dbug/dbug.c	2011-08-25 10:54:34 +0000
@@ -1179,7 +1179,7 @@ void _db_return_(uint _line_, struct _db
         pthread_mutex_lock(&THR_LOCK_dbug);
       DoPrefix(cs, _line_);
       Indent(cs, cs->level);
-      (void) fprintf(cs->stack->out_file, "<%s\n", cs->func);
+      (void) fprintf(cs->stack->out_file, "<%s %u\n", cs->func, _line_);
       DbugFlush(cs);
     }
   }

=== modified file 'extra/innochecksum.c'
--- a/extra/innochecksum.c	2011-08-22 07:46:51 +0000
+++ b/extra/innochecksum.c	2011-08-25 14:50:23 +0000
@@ -699,20 +699,8 @@ buf_calc_page_old_checksum(
 
 #endif /* INNOCHECKSUM_SOLARIS */
 
-/* needed to have access to 64 bit file functions */
-#ifndef _LARGEFILE_SOURCE
-#define _LARGEFILE_SOURCE
-#endif /* _LARGEFILE_SOURCE */
-
-#ifndef _LARGEFILE64_SOURCE
-#define _LARGEFILE64_SOURCE
-#endif /* _LARGEFILE64_SOURCE */
-
-#ifdef _XOPEN_SOURCE
-#undef _XOPEN_SOURCE
-#endif /* _XOPEN_SOURCE */
-#define _XOPEN_SOURCE 500 /* needed to include getopt.h on some platforms. */
 
+#include <my_global.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>

=== modified file 'include/mysql/psi/mysql_socket.h'
--- a/include/mysql/psi/mysql_socket.h	2011-08-18 12:27:21 +0000
+++ b/include/mysql/psi/mysql_socket.h	2011-08-25 07:53:21 +0000
@@ -901,9 +901,10 @@ inline_mysql_socket_accept
     PSI_CALL(set_socket_info)(socket_accept.m_psi, &socket_accept.fd, addr,
                               addr_length);
   return socket_accept;
-#endif
+#else
   socket_accept.fd= accept(socket_listen.fd, addr, addr_len);
   return socket_accept;
+#endif
 }
 
 /** mysql_socket_close */

=== modified file 'include/mysql/psi/psi.h'
--- a/include/mysql/psi/psi.h	2011-08-16 03:57:30 +0000
+++ b/include/mysql/psi/psi.h	2011-08-25 07:53:21 +0000
@@ -1635,7 +1635,7 @@ typedef void (*set_statement_rows_examin
   @param count the metric increment value
 */
 typedef void (*inc_statement_created_tmp_disk_tables_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "created tmp tables" metric.
@@ -1643,7 +1643,7 @@ typedef void (*inc_statement_created_tmp
   @param count the metric increment value
 */
 typedef void (*inc_statement_created_tmp_tables_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "select full join" metric.
@@ -1651,7 +1651,7 @@ typedef void (*inc_statement_created_tmp
   @param count the metric increment value
 */
 typedef void (*inc_statement_select_full_join_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "select full range join" metric.
@@ -1659,7 +1659,7 @@ typedef void (*inc_statement_select_full
   @param count the metric increment value
 */
 typedef void (*inc_statement_select_full_range_join_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "select range join" metric.
@@ -1667,7 +1667,7 @@ typedef void (*inc_statement_select_full
   @param count the metric increment value
 */
 typedef void (*inc_statement_select_range_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "select range check" metric.
@@ -1675,7 +1675,7 @@ typedef void (*inc_statement_select_rang
   @param count the metric increment value
 */
 typedef void (*inc_statement_select_range_check_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "select scan" metric.
@@ -1683,7 +1683,7 @@ typedef void (*inc_statement_select_rang
   @param count the metric increment value
 */
 typedef void (*inc_statement_select_scan_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "sort merge passes" metric.
@@ -1691,7 +1691,7 @@ typedef void (*inc_statement_select_scan
   @param count the metric increment value
 */
 typedef void (*inc_statement_sort_merge_passes_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "sort range" metric.
@@ -1699,7 +1699,7 @@ typedef void (*inc_statement_sort_merge_
   @param count the metric increment value
 */
 typedef void (*inc_statement_sort_range_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "sort rows" metric.
@@ -1707,7 +1707,7 @@ typedef void (*inc_statement_sort_range_
   @param count the metric increment value
 */
 typedef void (*inc_statement_sort_rows_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Increment a statement event "sort scan" metric.
@@ -1715,7 +1715,7 @@ typedef void (*inc_statement_sort_rows_t
   @param count the metric increment value
 */
 typedef void (*inc_statement_sort_scan_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 
 /**
   Set a statement event "no index used" metric.

=== modified file 'include/mysql/psi/psi_abi_v1.h.pp'
--- a/include/mysql/psi/psi_abi_v1.h.pp	2011-08-16 15:12:11 +0000
+++ b/include/mysql/psi/psi_abi_v1.h.pp	2011-08-25 07:53:21 +0000
@@ -410,27 +410,27 @@ typedef void (*set_statement_rows_sent_t
 typedef void (*set_statement_rows_examined_t)
   (struct PSI_statement_locker *locker, ulonglong count);
 typedef void (*inc_statement_created_tmp_disk_tables_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_created_tmp_tables_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_select_full_join_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_select_full_range_join_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_select_range_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_select_range_check_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_select_scan_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_sort_merge_passes_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_sort_range_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_sort_rows_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*inc_statement_sort_scan_t)
-  (struct PSI_statement_locker *locker, ulonglong count);
+  (struct PSI_statement_locker *locker, ulong count);
 typedef void (*set_statement_no_index_used_t)
   (struct PSI_statement_locker *locker);
 typedef void (*set_statement_no_good_index_used_t)

=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental	2011-08-19 16:34:34 +0000
+++ b/mysql-test/collections/default.experimental	2011-08-26 10:18:24 +0000
@@ -31,6 +31,7 @@ rpl.rpl_row_ignorable_event
 rpl.rpl_row_sp011  @solaris              # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
 rpl.rpl_seconds_behind_master            # BUG#11765124 2010-11-24 luis fails sporadically on pb2
 rpl.rpl_show_slave_running               # BUG#12346048 2011-04-11 sven fails sporadically on pb2
+rpl.rpl_spec_variables                   # BUG#11755836 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux
 
 sys_vars.max_sp_recursion_depth_func @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
 sys_vars.wait_timeout_func                    # Bug#11750645 2010-04-26 alik wait_timeout_func fails
@@ -42,6 +43,6 @@ sys_vars.have_ndbcluster_basic
 sys_vars.ndb_log_updated_only_basic
 sys_vars.rpl_init_slave_func		 # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5
 
-rpl.rpl_mixed_mts_rec_crash_safe @solaris          # andrei : 2011-08-19 mts recovery tests are slow (todo: find a way to optimize time)
+rpl.rpl_mixed_mts_rec_crash_safe @solaris          # Bug 12902514 2011-08-19 andrei mts recovery tests are slow
 rpl.rpl_mixed_mts_rec_crash_safe_checksum @solaris # same as rpl_mixed_mts_rec_crash_safe
 rpl.rpl_mixed_mts_crash_safe @solaris              # same as rpl_mixed_mts_rec_crash_safe

=== modified file 'mysql-test/include/range.inc'
--- a/mysql-test/include/range.inc	2011-08-05 14:30:29 +0000
+++ b/mysql-test/include/range.inc	2011-08-25 10:54:34 +0000
@@ -1534,3 +1534,82 @@ eval EXPLAIN $query;
 eval $query;
 
 DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#12694872 - 
+--echo # VALGRIND: 18,816 BYTES IN 196 BLOCKS ARE DEFINITELY LOST IN UNIQUE::GET
+--echo #
+
+CREATE TABLE t1 (
+  pk INTEGER AUTO_INCREMENT,
+  col_int_nokey INTEGER NOT NULL,
+  col_int_key INTEGER NOT NULL,
+
+  col_date_key DATE NOT NULL,
+
+  col_varchar_key VARCHAR(1) NOT NULL,
+  col_varchar_nokey VARCHAR(1) NOT NULL,
+
+  PRIMARY KEY (pk),
+  KEY (col_int_key),
+  KEY (col_date_key),
+  KEY (col_varchar_key, col_int_key)
+);
+
+INSERT INTO t1 (
+   col_int_key,
+   col_int_nokey,
+   col_date_key,
+   col_varchar_key,
+   col_varchar_nokey
+) VALUES 
+(0, 4, '2011-08-25', 'j', 'j'),
+(8, 6, '2004-09-18', 'v', 'v'),
+(1, 3, '2009-12-01', 'c', 'c'),
+(8, 5, '2004-12-17', 'm', 'm'),
+(9, 3, '2000-03-14', 'd', 'd'),
+(6, 2, '2006-05-25', 'y', 'y'),
+(1, 9, '2008-01-23', 't', 't'),
+(6, 3, '2007-06-18', 'd', 'd'),
+(2, 8, '2002-10-13', 's', 's'),
+(4, 1, '1900-01-01', 'r', 'r'),
+(8, 8, '1959-04-25', 'm', 'm'),
+(4, 8, '2006-03-09', 'b', 'b'),
+(4, 5, '2001-06-05', 'x', 'x'),
+(7, 7, '2006-05-28', 'g', 'g'),
+(4, 5, '2001-04-19', 'p', 'p'),
+(1, 1, '1900-01-01', 'q', 'q'),
+(9, 6, '2004-08-20', 'w', 'w'),
+(4, 2, '2004-10-10', 'd', 'd'),
+(8, 9, '2000-04-02', 'e', 'e')
+;
+
+let $query=
+SELECT table2.col_date_key AS field1,
+       CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+       ON (( table2.pk <> table1.pk ) AND
+           ( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+        table1.pk < ( 226 + 102 ) OR
+        ( table1.col_int_key > 226 AND
+          table1.col_int_key < ( 226 + 36 ) OR
+          ( table1.col_varchar_key <= 'h' OR
+            table1.col_int_key > 226 AND
+            table1.col_int_key < ( 226 + 227 ) )
+        ) 
+      )
+;
+
+ALTER TABLE t1 DISABLE KEYS;
+sorted_result;
+eval $query;
+ALTER TABLE t1 ENABLE KEYS;
+
+eval CREATE TABLE t2 $query;
+
+sorted_result;
+eval SELECT * FROM t2
+     WHERE (field1, field2) IN ($query);
+
+DROP TABLE t1, t2;

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2011-08-22 13:24:38 +0000
+++ b/mysql-test/mysql-test-run.pl	2011-08-26 09:15:34 +0000
@@ -2149,8 +2149,10 @@ sub find_plugin($$)
   my $lib_plugin=
     mtr_file_exists(vs_config_dirs($location,$plugin_filename),
                     "$basedir/lib/plugin/".$plugin_filename,
+                    "$basedir/lib64/plugin/".$plugin_filename,
                     "$basedir/$location/.libs/".$plugin_filename,
                     "$basedir/lib/mysql/plugin/".$plugin_filename,
+                    "$basedir/lib64/mysql/plugin/".$plugin_filename,
                     );
   return $lib_plugin;
 }

=== modified file 'mysql-test/r/derived.result'
--- a/mysql-test/r/derived.result	2011-08-19 11:39:15 +0000
+++ b/mysql-test/r/derived.result	2011-08-26 08:55:54 +0000
@@ -1530,3 +1530,68 @@ Handler_write	1021
 set @@max_heap_table_size= @save_heap_size;
 drop table t1;
 #
+#
+# Bug#12896124: Crash on rqg_mdl_stability test
+#
+CREATE TABLE t1(f1 INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+CREATE FUNCTION func1 (param1 INTEGER) RETURNS INT NOT DETERMINISTIC
+return param1;
+CREATE FUNCTION func2 (param1 INTEGER) RETURNS INT 
+return param1;
+SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func1(f1);
+f1
+1
+2
+3
+EXPLAIN SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func1(f1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	3	Using where
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	3	
+SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func2(f1);
+f1
+1
+2
+3
+EXPLAIN SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func2(f1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	3	Using where
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	3	
+DROP FUNCTION func1;
+DROP FUNCTION func2;
+DROP TABLE t1;
+#
+#
+# Bug#12909844: Missing type cast caused false assertion
+#
+CREATE TABLE t1 ( fk INT) ENGINE=INNODB;
+CREATE TABLE t2 (
+f1 INT,  f2 INT,  f3 INT,  f4 INT,  f5 INT,  f6 INT,
+f7 INT,  f8 INT,  f9 INT,  f10 INT, f11 INT, f12 INT,
+f13 INT, f14 INT, f15 INT, f16 INT, f17 INT, f18 INT,
+f19 INT, f20 INT, f21 INT, f22 INT, f23 INT, f24 INT,
+f25 INT, f26 INT, f27 INT, f28 INT, f29 INT, f30 INT,
+f31 INT, f32 TEXT, fk INT) ENGINE=INNODB;
+SELECT alias2.fk AS field1 FROM t1 AS alias1 JOIN
+(SELECT * FROM t2 ) AS alias2 ON alias1.fk = alias2.fk;
+field1
+EXPLAIN 
+SELECT alias2.fk AS field1 FROM t1 AS alias1 JOIN
+(SELECT * FROM t2 ) AS alias2 ON alias1.fk = alias2.fk;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	<derived2>	ref	auto_key0	auto_key0	5	test.alias1.fk	2	
+2	DERIVED	t2	ALL	NULL	NULL	NULL	NULL	1	
+DROP TABLE t1, t2;
+#
+#
+# Bug#12910039: Incorrect merge caused segmentation fault.
+#
+CREATE TABLE t1 (f1 int) ENGINE=myisam;
+CREATE TABLE t2 (f1 text) ENGINE=innodb;
+SELECT 1 FROM (
+( SELECT * FROM ( SELECT * FROM t2 ) AS alias1 ) AS alias1,
+( SELECT * FROM t1 ) AS alias2 );
+1
+DROP TABLE t1,t2;
+#

=== modified file 'mysql-test/r/func_math.result'
--- a/mysql-test/r/func_math.result	2011-07-22 07:53:39 +0000
+++ b/mysql-test/r/func_math.result	2011-08-26 07:06:35 +0000
@@ -700,6 +700,21 @@ select (1.175494351E-37 div 1.7976931348
 Warnings:
 Warning	1292	Truncated incorrect DECIMAL value: ''
 #
+# Bug#12744991 - DECIMAL_ROUND(X,D) GIVES WRONG RESULTS WHEN D == N*(-9)
+#
+select round(999999999, -9);
+round(999999999, -9)
+1000000000
+select round(999999999.0, -9);
+round(999999999.0, -9)
+1000000000
+select round(999999999999999999, -18);
+round(999999999999999999, -18)
+1000000000000000000
+select round(999999999999999999.0, -18);
+round(999999999999999999.0, -18)
+1000000000000000000
+#
 # Bug#12537160 ASSERTION FAILED:
 # STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER.
 #

=== modified file 'mysql-test/r/range_icp.result'
--- a/mysql-test/r/range_icp.result	2011-08-08 14:16:20 +0000
+++ b/mysql-test/r/range_icp.result	2011-08-25 10:54:34 +0000
@@ -1909,4 +1909,294 @@ ON t2.col_int_key = t1.col_int WHERE t2.
 col_int	pk	col_int_key	col_varchar	pk
 1	6	1	GOOD	1
 DROP TABLE t1,t2;
+#
+# Bug#12694872 - 
+# VALGRIND: 18,816 BYTES IN 196 BLOCKS ARE DEFINITELY LOST IN UNIQUE::GET
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER NOT NULL,
+col_int_key INTEGER NOT NULL,
+col_date_key DATE NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+col_varchar_nokey VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_date_key),
+KEY (col_varchar_key, col_int_key)
+);
+INSERT INTO t1 (
+col_int_key,
+col_int_nokey,
+col_date_key,
+col_varchar_key,
+col_varchar_nokey
+) VALUES 
+(0, 4, '2011-08-25', 'j', 'j'),
+(8, 6, '2004-09-18', 'v', 'v'),
+(1, 3, '2009-12-01', 'c', 'c'),
+(8, 5, '2004-12-17', 'm', 'm'),
+(9, 3, '2000-03-14', 'd', 'd'),
+(6, 2, '2006-05-25', 'y', 'y'),
+(1, 9, '2008-01-23', 't', 't'),
+(6, 3, '2007-06-18', 'd', 'd'),
+(2, 8, '2002-10-13', 's', 's'),
+(4, 1, '1900-01-01', 'r', 'r'),
+(8, 8, '1959-04-25', 'm', 'm'),
+(4, 8, '2006-03-09', 'b', 'b'),
+(4, 5, '2001-06-05', 'x', 'x'),
+(7, 7, '2006-05-28', 'g', 'g'),
+(4, 5, '2001-04-19', 'p', 'p'),
+(1, 1, '1900-01-01', 'q', 'q'),
+(9, 6, '2004-08-20', 'w', 'w'),
+(4, 2, '2004-10-10', 'd', 'd'),
+(8, 9, '2000-04-02', 'e', 'e')
+;
+ALTER TABLE t1 DISABLE KEYS;
+SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+ALTER TABLE t1 ENABLE KEYS;
+CREATE TABLE t2 SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+SELECT * FROM t2
+WHERE (field1, field2) IN (SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+);
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+DROP TABLE t1, t2;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/range_icp_mrr.result'
--- a/mysql-test/r/range_icp_mrr.result	2011-08-08 14:16:20 +0000
+++ b/mysql-test/r/range_icp_mrr.result	2011-08-25 10:54:34 +0000
@@ -1909,4 +1909,294 @@ ON t2.col_int_key = t1.col_int WHERE t2.
 col_int	pk	col_int_key	col_varchar	pk
 1	6	1	GOOD	1
 DROP TABLE t1,t2;
+#
+# Bug#12694872 - 
+# VALGRIND: 18,816 BYTES IN 196 BLOCKS ARE DEFINITELY LOST IN UNIQUE::GET
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER NOT NULL,
+col_int_key INTEGER NOT NULL,
+col_date_key DATE NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+col_varchar_nokey VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_date_key),
+KEY (col_varchar_key, col_int_key)
+);
+INSERT INTO t1 (
+col_int_key,
+col_int_nokey,
+col_date_key,
+col_varchar_key,
+col_varchar_nokey
+) VALUES 
+(0, 4, '2011-08-25', 'j', 'j'),
+(8, 6, '2004-09-18', 'v', 'v'),
+(1, 3, '2009-12-01', 'c', 'c'),
+(8, 5, '2004-12-17', 'm', 'm'),
+(9, 3, '2000-03-14', 'd', 'd'),
+(6, 2, '2006-05-25', 'y', 'y'),
+(1, 9, '2008-01-23', 't', 't'),
+(6, 3, '2007-06-18', 'd', 'd'),
+(2, 8, '2002-10-13', 's', 's'),
+(4, 1, '1900-01-01', 'r', 'r'),
+(8, 8, '1959-04-25', 'm', 'm'),
+(4, 8, '2006-03-09', 'b', 'b'),
+(4, 5, '2001-06-05', 'x', 'x'),
+(7, 7, '2006-05-28', 'g', 'g'),
+(4, 5, '2001-04-19', 'p', 'p'),
+(1, 1, '1900-01-01', 'q', 'q'),
+(9, 6, '2004-08-20', 'w', 'w'),
+(4, 2, '2004-10-10', 'd', 'd'),
+(8, 9, '2000-04-02', 'e', 'e')
+;
+ALTER TABLE t1 DISABLE KEYS;
+SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+ALTER TABLE t1 ENABLE KEYS;
+CREATE TABLE t2 SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+SELECT * FROM t2
+WHERE (field1, field2) IN (SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+);
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+DROP TABLE t1, t2;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/range_mrr.result'
--- a/mysql-test/r/range_mrr.result	2011-08-08 14:16:20 +0000
+++ b/mysql-test/r/range_mrr.result	2011-08-25 10:54:34 +0000
@@ -1909,4 +1909,294 @@ ON t2.col_int_key = t1.col_int WHERE t2.
 col_int	pk	col_int_key	col_varchar	pk
 1	6	1	GOOD	1
 DROP TABLE t1,t2;
+#
+# Bug#12694872 - 
+# VALGRIND: 18,816 BYTES IN 196 BLOCKS ARE DEFINITELY LOST IN UNIQUE::GET
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER NOT NULL,
+col_int_key INTEGER NOT NULL,
+col_date_key DATE NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+col_varchar_nokey VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_date_key),
+KEY (col_varchar_key, col_int_key)
+);
+INSERT INTO t1 (
+col_int_key,
+col_int_nokey,
+col_date_key,
+col_varchar_key,
+col_varchar_nokey
+) VALUES 
+(0, 4, '2011-08-25', 'j', 'j'),
+(8, 6, '2004-09-18', 'v', 'v'),
+(1, 3, '2009-12-01', 'c', 'c'),
+(8, 5, '2004-12-17', 'm', 'm'),
+(9, 3, '2000-03-14', 'd', 'd'),
+(6, 2, '2006-05-25', 'y', 'y'),
+(1, 9, '2008-01-23', 't', 't'),
+(6, 3, '2007-06-18', 'd', 'd'),
+(2, 8, '2002-10-13', 's', 's'),
+(4, 1, '1900-01-01', 'r', 'r'),
+(8, 8, '1959-04-25', 'm', 'm'),
+(4, 8, '2006-03-09', 'b', 'b'),
+(4, 5, '2001-06-05', 'x', 'x'),
+(7, 7, '2006-05-28', 'g', 'g'),
+(4, 5, '2001-04-19', 'p', 'p'),
+(1, 1, '1900-01-01', 'q', 'q'),
+(9, 6, '2004-08-20', 'w', 'w'),
+(4, 2, '2004-10-10', 'd', 'd'),
+(8, 9, '2000-04-02', 'e', 'e')
+;
+ALTER TABLE t1 DISABLE KEYS;
+SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+ALTER TABLE t1 ENABLE KEYS;
+CREATE TABLE t2 SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+SELECT * FROM t2
+WHERE (field1, field2) IN (SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+);
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+DROP TABLE t1, t2;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/range_mrr_cost.result'
--- a/mysql-test/r/range_mrr_cost.result	2011-08-08 14:16:20 +0000
+++ b/mysql-test/r/range_mrr_cost.result	2011-08-25 10:54:34 +0000
@@ -1909,4 +1909,294 @@ ON t2.col_int_key = t1.col_int WHERE t2.
 col_int	pk	col_int_key	col_varchar	pk
 1	6	1	GOOD	1
 DROP TABLE t1,t2;
+#
+# Bug#12694872 - 
+# VALGRIND: 18,816 BYTES IN 196 BLOCKS ARE DEFINITELY LOST IN UNIQUE::GET
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER NOT NULL,
+col_int_key INTEGER NOT NULL,
+col_date_key DATE NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+col_varchar_nokey VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_date_key),
+KEY (col_varchar_key, col_int_key)
+);
+INSERT INTO t1 (
+col_int_key,
+col_int_nokey,
+col_date_key,
+col_varchar_key,
+col_varchar_nokey
+) VALUES 
+(0, 4, '2011-08-25', 'j', 'j'),
+(8, 6, '2004-09-18', 'v', 'v'),
+(1, 3, '2009-12-01', 'c', 'c'),
+(8, 5, '2004-12-17', 'm', 'm'),
+(9, 3, '2000-03-14', 'd', 'd'),
+(6, 2, '2006-05-25', 'y', 'y'),
+(1, 9, '2008-01-23', 't', 't'),
+(6, 3, '2007-06-18', 'd', 'd'),
+(2, 8, '2002-10-13', 's', 's'),
+(4, 1, '1900-01-01', 'r', 'r'),
+(8, 8, '1959-04-25', 'm', 'm'),
+(4, 8, '2006-03-09', 'b', 'b'),
+(4, 5, '2001-06-05', 'x', 'x'),
+(7, 7, '2006-05-28', 'g', 'g'),
+(4, 5, '2001-04-19', 'p', 'p'),
+(1, 1, '1900-01-01', 'q', 'q'),
+(9, 6, '2004-08-20', 'w', 'w'),
+(4, 2, '2004-10-10', 'd', 'd'),
+(8, 9, '2000-04-02', 'e', 'e')
+;
+ALTER TABLE t1 DISABLE KEYS;
+SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+ALTER TABLE t1 ENABLE KEYS;
+CREATE TABLE t2 SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+SELECT * FROM t2
+WHERE (field1, field2) IN (SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+);
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+DROP TABLE t1, t2;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/range_none.result'
--- a/mysql-test/r/range_none.result	2011-08-08 14:16:20 +0000
+++ b/mysql-test/r/range_none.result	2011-08-25 10:54:34 +0000
@@ -1908,4 +1908,294 @@ ON t2.col_int_key = t1.col_int WHERE t2.
 col_int	pk	col_int_key	col_varchar	pk
 1	6	1	GOOD	1
 DROP TABLE t1,t2;
+#
+# Bug#12694872 - 
+# VALGRIND: 18,816 BYTES IN 196 BLOCKS ARE DEFINITELY LOST IN UNIQUE::GET
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER NOT NULL,
+col_int_key INTEGER NOT NULL,
+col_date_key DATE NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+col_varchar_nokey VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_date_key),
+KEY (col_varchar_key, col_int_key)
+);
+INSERT INTO t1 (
+col_int_key,
+col_int_nokey,
+col_date_key,
+col_varchar_key,
+col_varchar_nokey
+) VALUES 
+(0, 4, '2011-08-25', 'j', 'j'),
+(8, 6, '2004-09-18', 'v', 'v'),
+(1, 3, '2009-12-01', 'c', 'c'),
+(8, 5, '2004-12-17', 'm', 'm'),
+(9, 3, '2000-03-14', 'd', 'd'),
+(6, 2, '2006-05-25', 'y', 'y'),
+(1, 9, '2008-01-23', 't', 't'),
+(6, 3, '2007-06-18', 'd', 'd'),
+(2, 8, '2002-10-13', 's', 's'),
+(4, 1, '1900-01-01', 'r', 'r'),
+(8, 8, '1959-04-25', 'm', 'm'),
+(4, 8, '2006-03-09', 'b', 'b'),
+(4, 5, '2001-06-05', 'x', 'x'),
+(7, 7, '2006-05-28', 'g', 'g'),
+(4, 5, '2001-04-19', 'p', 'p'),
+(1, 1, '1900-01-01', 'q', 'q'),
+(9, 6, '2004-08-20', 'w', 'w'),
+(4, 2, '2004-10-10', 'd', 'd'),
+(8, 9, '2000-04-02', 'e', 'e')
+;
+ALTER TABLE t1 DISABLE KEYS;
+SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+ALTER TABLE t1 ENABLE KEYS;
+CREATE TABLE t2 SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+;
+SELECT * FROM t2
+WHERE (field1, field2) IN (SELECT table2.col_date_key AS field1,
+CONCAT ( table2.col_varchar_nokey, table1.col_varchar_nokey ) AS field2
+FROM ( t1 AS table1 INNER JOIN t1 AS table2
+ON (( table2.pk <> table1.pk ) AND
+( table2.pk >= table1.col_int_nokey ) ) )
+WHERE ( table1.pk > 226 AND
+table1.pk < ( 226 + 102 ) OR
+( table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 36 ) OR
+( table1.col_varchar_key <= 'h' OR
+table1.col_int_key > 226 AND
+table1.col_int_key < ( 226 + 227 ) )
+) 
+)
+);
+field1	field2
+1900-01-01	qb
+1900-01-01	qc
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qd
+1900-01-01	qe
+1900-01-01	qg
+1900-01-01	rb
+1900-01-01	rc
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	rd
+1900-01-01	re
+1900-01-01	rg
+1959-04-25	mb
+1959-04-25	mc
+1959-04-25	md
+1959-04-25	md
+1959-04-25	md
+1959-04-25	me
+1959-04-25	mg
+2000-03-14	dc
+2000-03-14	dd
+2000-03-14	dd
+2000-04-02	eb
+2000-04-02	ec
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	ed
+2000-04-02	eg
+2001-04-19	pb
+2001-04-19	pc
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pd
+2001-04-19	pe
+2001-04-19	pg
+2001-06-05	xb
+2001-06-05	xc
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xd
+2001-06-05	xe
+2001-06-05	xg
+2002-10-13	sb
+2002-10-13	sc
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	sd
+2002-10-13	se
+2002-10-13	sg
+2004-08-20	wb
+2004-08-20	wc
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	wd
+2004-08-20	we
+2004-08-20	wg
+2004-09-18	vd
+2004-10-10	db
+2004-10-10	dc
+2004-10-10	dd
+2004-10-10	dd
+2004-10-10	de
+2004-10-10	dg
+2004-12-17	mc
+2004-12-17	md
+2004-12-17	md
+2004-12-17	md
+2006-03-09	bc
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	bd
+2006-03-09	be
+2006-03-09	bg
+2006-05-25	yc
+2006-05-25	yd
+2006-05-25	yd
+2006-05-25	yd
+2006-05-28	gb
+2006-05-28	gc
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	gd
+2006-05-28	ge
+2007-06-18	db
+2007-06-18	dc
+2007-06-18	dd
+2007-06-18	dd
+2007-06-18	dg
+2008-01-23	tc
+2008-01-23	td
+2008-01-23	td
+2008-01-23	td
+2008-01-23	tg
+2009-12-01	cd
+2009-12-01	cd
+2009-12-01	cd
+DROP TABLE t1, t2;
 set optimizer_switch=default;

=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result	2011-08-19 13:04:28 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result	2011-08-23 13:20:16 +0000
@@ -180,6 +180,8 @@ def	mysql	slave_master_info	Ssl_ca	11	NU
 def	mysql	slave_master_info	Ssl_capath	12	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text				The path to the Certificate Authority (CA) certificates.
 def	mysql	slave_master_info	Ssl_cert	13	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text				The name of the SSL certificate file.
 def	mysql	slave_master_info	Ssl_cipher	14	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text				The name of the cipher in use for the SSL connection.
+def	mysql	slave_master_info	Ssl_crl	22	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text				The file used for the Certificate Revocation List (CRL)
+def	mysql	slave_master_info	Ssl_crlpath	23	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text				The path used for Certificate Revocation List (CRL) files
 def	mysql	slave_master_info	Ssl_key	15	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text				The name of the SSL key file.
 def	mysql	slave_master_info	Ssl_verify_server_cert	16	NULL	NO	tinyint	NULL	NULL	3	0	NULL	NULL	tinyint(1)				Whether to verify the server certificate.
 def	mysql	slave_master_info	User_name	6	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text				The user name used to connect to the master.
@@ -536,6 +538,8 @@ NULL	mysql	slave_master_info	Heartbeat	f
 1.0000	mysql	slave_master_info	Ignored_server_ids	text	65535	65535	utf8	utf8_bin	text
 1.0000	mysql	slave_master_info	Uuid	text	65535	65535	utf8	utf8_bin	text
 NULL	mysql	slave_master_info	Retry_count	bigint	NULL	NULL	NULL	NULL	bigint(20) unsigned
+1.0000	mysql	slave_master_info	Ssl_crl	text	65535	65535	utf8	utf8_bin	text
+1.0000	mysql	slave_master_info	Ssl_crlpath	text	65535	65535	utf8	utf8_bin	text
 NULL	mysql	slave_relay_log_info	Master_id	int	NULL	NULL	NULL	NULL	int(10) unsigned
 NULL	mysql	slave_relay_log_info	Number_of_lines	int	NULL	NULL	NULL	NULL	int(10) unsigned
 1.0000	mysql	slave_relay_log_info	Relay_log_name	text	65535	65535	utf8	utf8_bin	text

=== modified file 'mysql-test/suite/perfschema/include/socket_check1.inc'
--- a/mysql-test/suite/perfschema/include/socket_check1.inc	2011-08-19 06:59:27 +0000
+++ b/mysql-test/suite/perfschema/include/socket_check1.inc	2011-08-23 10:12:13 +0000
@@ -134,6 +134,7 @@ if(`SELECT NOT ( $my_rules )
      AND EVENT_NAME LIKE ('%client_connection')
      AND run = 1
      AND statement IN('$stmt2','$stmt1');
+   let $print_details= 1;
 }
 # Initialize all variables which depend on the statements to be checked.
 # This prevents that we run with wrong data.

=== modified file 'mysql-test/suite/perfschema/include/socket_summary_check.inc'
--- a/mysql-test/suite/perfschema/include/socket_summary_check.inc	2011-08-19 06:59:27 +0000
+++ b/mysql-test/suite/perfschema/include/socket_summary_check.inc	2011-08-24 14:09:20 +0000
@@ -106,13 +106,7 @@ if(`SELECT SUM($my_rules) <> COUNT(*) FR
    FROM mysqltest.my_socket_summary_by_instance
    WHERE pk = 'After' AND NOT ($my_rules)
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN;
-
-   --echo # Debug 2a: Dump socket_summary_by_instance
-   eval
-   SELECT EVENT_NAME, OBJECT_INSTANCE_BEGIN,
-      $part
-   FROM performance_schema.socket_summary_by_instance
-   ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 
@@ -151,6 +145,7 @@ if(`SELECT SUM($my_rules) <> COUNT(*) FR
    FROM mysqltest.my_socket_summary_by_instance
    WHERE pk = 'After' AND NOT ($my_rules)
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 
@@ -184,6 +179,7 @@ if(`SELECT SUM($my_rules) <> COUNT(*) FR
    FROM mysqltest.my_socket_summary_by_instance
    WHERE pk = 'After'
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 
@@ -213,6 +209,7 @@ if(`SELECT SUM($my_rules) <> COUNT(*) FR
    FROM mysqltest.my_socket_summary_by_instance
    WHERE pk = 'After'
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 
@@ -242,6 +239,7 @@ if(`SELECT SUM($my_rules) <> COUNT(*) FR
    FROM mysqltest.my_socket_summary_by_instance
    WHERE pk = 'After'
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 --horizontal_results

=== modified file 'mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result'
--- a/mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result	2011-08-20 00:36:03 +0000
+++ b/mysql-test/suite/perfschema/r/socket_summary_by_instance_func.result	2011-08-24 14:09:20 +0000
@@ -16,6 +16,7 @@ SET INSTRUMENTED='NO' WHERE PROCESSLIST_
 #     It must reset all counters.
 TRUNCATE TABLE performance_schema.socket_summary_by_instance;
 # 1.3 Check the base line
+TRUNCATE TABLE mysqltest.my_socket_summary_by_instance;
 # 2. Variations on Connect
 # 2.1 Connect fails because the user is unknown
 #     length of user name = 4 character
@@ -97,13 +98,13 @@ col2
 #     - no change in COUNT_* leads to no change in
 #       SUM_TIMER_* and no change in SUM_NUMBER_OF_BYTES_*
 #     - increased COUNT_READ leads to increased
-#       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
+#       SUM_NUMBER_OF_BYTES_READ
 #     - increased COUNT_WRITE leads to increased
-#       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
-#     - increased COUNT_MISC leads to increased
-#       SUM_TIMER_MISC
-#       Attention: There are exceptions but they are not valid
-#                  for this test.
+#       SUM_NUMBER_OF_BYTES_WRITE
+#     Attention:
+#     The time required for some action might be below timer resolution.
+#     Therefore some increased COUNT_* does not need to lead to an
+#     increased SUM_TIMER_*.
 # 4.2 Results must be stable
 # 4.3 Counters must be 0 in client_connection for the default session
 #     Instrumenting is disabled since a long time and the counter were
@@ -178,13 +179,13 @@ col2
 #         COUNT_MISC = 0 AND SUM_TIMER_MISC = 0 must be valid
 #         because we run through server_unix_socket.
 # 4.5.2.2 For the instance with EVENT_NAME LIKE '%server_unix_socket'
-#         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+#         COUNT_MISC > 0 must be valid.
 # 4.5.3 Connects using for host a value <> 'localhost'
 # 4.5.3.1 For the instance with EVENT_NAME LIKE '%server_unix_socket'
 #         COUNT_MISC = 0 AND SUM_TIMER_MISC = 0 must be valid
 #         because we run through server_tcpip_socket.
 # 4.5.3.2 For the instance with EVENT_NAME LIKE '%server_tcpip_socket'
-#         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+#         COUNT_MISC > 0 must be valid.
 # 4.5.4 Failing Connects do not cause any row with EVENT_NAME
 #       LIKE '%client_connection'
 # 4.5.5 Successful Connects cause a new instance with EVENT_NAME

=== modified file 'mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test'
--- a/mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test	2011-08-20 00:36:03 +0000
+++ b/mysql-test/suite/perfschema/t/socket_summary_by_instance_func.test	2011-08-24 14:09:20 +0000
@@ -49,6 +49,7 @@
 --source include/not_embedded.inc
 --source include/not_windows.inc
 
+
 # The values in the performance_schema tables depend on how much communication
 # happens per SQL statement within our MTR tests. And there is a significant
 # difference between standard statement execution and execution via
@@ -110,6 +111,8 @@ if($my_socket_debug)
 #    cause that the test needs maintenance.
 # Advantage:
 #    More thorough checks.
+# If any of the checks detects some suspicious/unexpected state than
+# $print_details will be automatically switched to 1.
 #
 let $print_details= 0;
 
@@ -188,6 +191,29 @@ if(!$success)
 }
 
 --disable_query_log
+
+#
+# Lower the resolution of the wait timer from the default 'CYCLE'
+# to 'NANOSECOND'.
+# Hint: The timer columns contains values in picoseconds independent
+#       of the timer resolution.
+#       The timer resolution has an impact on the precision of the value.
+# This should prevent the failures seen on some suspicious PB boxes where
+# - calculations exceeded the BIGINT UNSIGNED (data type of the counter columns)
+#   value range.
+# - we have reached from whatever reason 20 digit values 
+# The consequence for the current test is the following:
+#    The common sense rule
+#       In case COUNT_<A> increases than SUM_TIMER_<A> must also increase
+#    is no more valid because some action might need less time than the
+#    timer resolution.
+#
+let $wait_timer= `SELECT TIMER_NAME FROM performance_schema.setup_timers
+                  WHERE NAME = 'wait'`;
+UPDATE performance_schema.setup_timers
+SET TIMER_NAME = 'NANOSECOND'
+WHERE NAME = 'wait';
+
 #
 # Additional SCHEMA used for
 # - detection of our "worker" session within the PROCESSLIST.
@@ -214,43 +240,73 @@ SET INSTRUMENTED='NO' WHERE PROCESSLIST_
 # - to have initial values from before some action
 # - to minimize the impact of statements used for the checks on results.
 # CREATE TEMPORARY TABLE my_socket_summary_by_instance AS
-# would be nice but the optimizer does not support important statements.
+# would be nice but some statements are not supported for temporary tables.
 #
-CREATE TABLE mysqltest.my_socket_summary_by_instance AS
-SELECT *, 'Pseudo_Before' AS pk FROM performance_schema.socket_summary_by_instance
-WHERE 1 = 0;
+# DECIMAL(60,0) is used instead of BIGINT UNSIGNED. The goal is to prevent
+# errors during calculations
+#   Example:
+#   -    A and B UNSIGNED BIGINT
+#   -    A < B
+#   -    A - B ---> Error
+# though the columns in all queries are orderd to avoid this too.
+#
+CREATE TABLE mysqltest.my_socket_summary_by_instance (
+  EVENT_NAME varchar(128) NOT NULL,
+  OBJECT_INSTANCE_BEGIN bigint(20) unsigned NOT NULL,
+  COUNT_STAR                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  COUNT_READ                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_READ  DECIMAL(60,0) NOT NULL,
+  COUNT_WRITE               DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_WRITE DECIMAL(60,0) NOT NULL,
+  COUNT_MISC                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  pk VARCHAR(20),
+  PRIMARY KEY(pk, EVENT_NAME, OBJECT_INSTANCE_BEGIN)
+) DEFAULT CHARSET=utf8;
+
 
-# The CAST(... AS DECIMAL) prevents errors which might show up in case
+# The CAST(... AS DECIMAL(60,0)) prevents errors which might show up in case
 # we run with the original data type UNSIGNED BIGINT.
-# Example:
-# -    A and B UNSIGNED BIGINT
-# -    A < B
-# -    A - B ---> Error
-CREATE TABLE mysqltest.socket_summary_by_instance_detail AS
-SELECT EVENT_NAME,OBJECT_INSTANCE_BEGIN,
-       CAST(COUNT_READ AS DECIMAL) AS COUNT_READ,
-       CAST(SUM_TIMER_READ AS DECIMAL) AS SUM_TIMER_READ,
-       CAST(SUM_NUMBER_OF_BYTES_READ AS DECIMAL) SUM_NUMBER_OF_BYTES_READ,
-       CAST(COUNT_WRITE AS DECIMAL) AS COUNT_WRITE,
-       CAST(SUM_TIMER_WRITE AS DECIMAL) AS SUM_TIMER_WRITE,
-       CAST(SUM_NUMBER_OF_BYTES_WRITE AS DECIMAL) AS SUM_NUMBER_OF_BYTES_WRITE,
-       CAST(COUNT_MISC AS DECIMAL) AS COUNT_MISC,
-       CAST(SUM_TIMER_MISC AS DECIMAL) AS SUM_TIMER_MISC
-FROM performance_schema.socket_summary_by_instance
-WHERE 1 = 2;
-ALTER TABLE mysqltest.socket_summary_by_instance_detail
-ADD statement VARCHAR(500), ADD run INTEGER;
+CREATE TABLE mysqltest.socket_summary_by_instance_detail (
+  EVENT_NAME varchar(128) NOT NULL,
+  OBJECT_INSTANCE_BEGIN bigint(20) unsigned NOT NULL,
+  COUNT_READ                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_READ  DECIMAL(60,0) NOT NULL,
+  COUNT_WRITE               DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_WRITE DECIMAL(60,0) NOT NULL,
+  COUNT_MISC                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  statement VARCHAR(500),
+  run INTEGER
+) DEFAULT CHARSET=utf8;
 
 #
 # Auxiliary SQL functions used to shorten some commands.
 #
 CREATE FUNCTION mysqltest.min_of_triple
-   (f1 BIGINT UNSIGNED, f2 BIGINT UNSIGNED, f3 BIGINT UNSIGNED)
-   RETURNS BIGINT UNSIGNED
+   (f1 DECIMAL(60,0), f2 DECIMAL(60,0), f3 DECIMAL(60,0))
+   RETURNS DECIMAL(60,0)
    RETURN IF(IF(f1 < f2,f1,f2) < f3,IF(f1 < f2,f1,f2), f3);
 CREATE FUNCTION mysqltest.max_of_triple
-   (f1 BIGINT UNSIGNED, f2 BIGINT UNSIGNED, f3 BIGINT UNSIGNED)
-   RETURNS BIGINT UNSIGNED
+   (f1 DECIMAL(60,0), f2 DECIMAL(60,0), f3 DECIMAL(60,0))
+   RETURNS DECIMAL(60,0)
    RETURN IF(IF(f1 > f2,f1,f2) > f3,IF(f1 > f2,f1,f2), f3);
 
 #
@@ -470,6 +526,7 @@ if(`SELECT COUNT(*) FROM performance_sch
 
 --echo # 1.3 Check the base line
 #===============================
+eval $truncate;
 --source ../include/socket_summary_check.inc
 
 # --disable_query_log
@@ -682,13 +739,13 @@ if(`SELECT NOT ( $my_rules ) $part `)
 --echo #     - no change in COUNT_* leads to no change in
 --echo #       SUM_TIMER_* and no change in SUM_NUMBER_OF_BYTES_*
 --echo #     - increased COUNT_READ leads to increased
---echo #       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
+--echo #       SUM_NUMBER_OF_BYTES_READ
 --echo #     - increased COUNT_WRITE leads to increased
---echo #       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
---echo #     - increased COUNT_MISC leads to increased
---echo #       SUM_TIMER_MISC
---echo #       Attention: There are exceptions but they are not valid
---echo #                  for this test.
+--echo #       SUM_NUMBER_OF_BYTES_WRITE
+--echo #     Attention:
+--echo #     The time required for some action might be below timer resolution.
+--echo #     Therefore some increased COUNT_* does not need to lead to an
+--echo #     increased SUM_TIMER_*.
 #==========================================================================
 # Enable the following lines for debugging the check.
 # Attention: socket_summary_by_instance_detail is after that rotten.
@@ -707,15 +764,15 @@ if(0)
 let $my_rules=
 ((COUNT_READ  = 0 AND SUM_TIMER_READ  = 0 AND SUM_NUMBER_OF_BYTES_READ  = 0)
   OR
- (COUNT_READ  > 0 AND SUM_TIMER_READ  > 0 AND SUM_NUMBER_OF_BYTES_READ  > 0))
+ (COUNT_READ  > 0                         AND SUM_NUMBER_OF_BYTES_READ  > 0))
 AND
 ((COUNT_WRITE = 0 AND SUM_TIMER_WRITE = 0 AND SUM_NUMBER_OF_BYTES_WRITE = 0)
   OR
- (COUNT_WRITE > 0 AND SUM_TIMER_WRITE > 0 AND SUM_NUMBER_OF_BYTES_WRITE > 0))
+ (COUNT_WRITE > 0                         AND SUM_NUMBER_OF_BYTES_WRITE > 0))
 AND
 ((COUNT_MISC  = 0 AND SUM_TIMER_MISC  = 0)
   OR
-(COUNT_MISC > 0 AND SUM_TIMER_MISC > 0));
+(COUNT_MISC > 0));
 if(`SELECT COUNT(*) FROM mysqltest.socket_summary_by_instance_detail
     WHERE NOT ( $my_rules ) `)
 {
@@ -731,6 +788,7 @@ if(`SELECT COUNT(*) FROM mysqltest.socke
    FROM mysqltest.socket_summary_by_instance_detail
    WHERE NOT ( $my_rules )
    ORDER BY EVENT_NAME, OBJECT_INSTANCE, STATEMENT, RUN;
+   let $print_details= 1;
 }
 
 --echo # 4.2 Results must be stable
@@ -798,6 +856,7 @@ if(`SELECT COUNT(statement) $part`)
          IN (SELECT EVENT_NAME, statement
              $part)
    ORDER BY EVENT_NAME, statement, run, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 --echo # 4.3 Counters must be 0 in client_connection for the default session
@@ -833,6 +892,7 @@ if(`SELECT COUNT(*) FROM performance_sch
       COUNT_MISC,SUM_TIMER_MISC
    FROM performance_schema.socket_summary_by_instance
    WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
+   let $print_details= 1;
 }
 
 #---------------------------------------------------------------------------
@@ -879,6 +939,7 @@ if(`SELECT COUNT(*) $part`)
       $column_list
    $part
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN, statement, run;
+   let $print_details= 1;
 }
 
 --echo # 4.4.2 In case of SELECT and our scenarios even COUNT_READ and COUNT_MISC
@@ -921,6 +982,7 @@ if(`SELECT COUNT(statement) $part`)
          IN (SELECT EVENT_NAME, statement
              $part)
    ORDER BY EVENT_NAME, statement, run, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 --echo # 4.4.3 In our testing scenarios we get for the client_connection entry
@@ -963,6 +1025,7 @@ if(`SELECT COUNT(*) $part`)
       $column_list
    $part
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN, statement, run;
+   let $print_details= 1;
 }
 
 # Initialize variables
@@ -1190,6 +1253,7 @@ if(`SELECT COUNT(*) $part `)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.2 Connects using for host the value 'localhost'
@@ -1231,10 +1295,11 @@ if(`SELECT COUNT(*) $part `)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.2.2 For the instance with EVENT_NAME LIKE '%server_unix_socket'
---echo #         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+--echo #         COUNT_MISC > 0 must be valid.
 #===========================================================================
 # Enable the following lines for debugging the check.
 # Attention: socket_summary_by_instance_detail is after that rotten.
@@ -1251,7 +1316,7 @@ if(0)
 }
 
 let $my_rules=
-COUNT_MISC  > 0 AND SUM_TIMER_MISC  > 0;
+COUNT_MISC  > 0;
 let $part=
 FROM mysqltest.socket_summary_by_instance_detail
 WHERE OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin
@@ -1270,6 +1335,7 @@ if(`SELECT COUNT(*) $part `)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.3 Connects using for host a value <> 'localhost'
@@ -1312,10 +1378,11 @@ if(`SELECT COUNT(*) $part `)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.3.2 For the instance with EVENT_NAME LIKE '%server_tcpip_socket'
---echo #         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+--echo #         COUNT_MISC > 0 must be valid.
 #===========================================================================
 # Enable the following lines for debugging the check.
 # Attention: socket_summary_by_instance_detail is after that rotten.
@@ -1333,7 +1400,7 @@ if(0)
 }
 
 let $my_rules=
-COUNT_MISC  > 0 AND SUM_TIMER_MISC  > 0;
+COUNT_MISC  > 0;
 let $part=
 FROM mysqltest.socket_summary_by_instance_detail
 WHERE OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin
@@ -1352,6 +1419,7 @@ if(`SELECT COUNT(*) $part `)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.4 Failing Connects do not cause any row with EVENT_NAME
@@ -1389,6 +1457,7 @@ if(`SELECT COUNT(*) $part`)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.5 Successful Connects cause a new instance with EVENT_NAME
@@ -1447,6 +1516,7 @@ if(`SELECT COUNT(*) $part`)
      AND statement IN
          (SELECT statement
           $part);
+   let $print_details= 1;
 }
 
 --echo # 4.6 Check the differences caused by Connects
@@ -1494,6 +1564,7 @@ if(`SELECT NOT ( $my_rules) $part`)
    SELECT
    statement, SUM_NUMBER_OF_BYTES_WRITE
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.6.2 The SUM_OF_BYTES_WRITE value hast to be > 100.
@@ -1519,6 +1590,7 @@ if(`SELECT COUNT(*) $part`)
    SELECT
    statement, SUM_NUMBER_OF_BYTES_WRITE
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.6.3 COUNT_READ, COUNT_WRITE and COUNT_MISC have to be to be > 0
@@ -1545,6 +1617,7 @@ if(`SELECT COUNT(*) $part`)
    SELECT
    statement, COUNT_READ, COUNT_WRITE, COUNT_MISC
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.6.4 Checks based on comparison of results for connects
@@ -1588,6 +1661,7 @@ if(`SELECT NOT ($my_rules)
    eval
    $part1
    AND statement IN('$stmt2','$stmt1');
+   let $print_details= 1;
 }
 
 --echo # 4.6.5 The database name length affects the SUM_OF_BYTES_READ value
@@ -1613,6 +1687,7 @@ if(`SELECT NOT ($my_rules)
    eval
    $part1
    AND statement IN('$stmt2','$stmt1');
+   let $print_details= 1;
 }
 
 if($print_details)
@@ -1657,12 +1732,20 @@ if($print_details)
    FROM mysqltest.socket_summary_by_instance_detail
    WHERE EVENT_NAME LIKE '%server_tcpip_socket%'
    ORDER BY statement,run;
+   --echo # 5. mysqltest.my_socket_summary_by_instance
+   --vertical_results
+   SELECT * FROM mysqltest.my_socket_summary_by_instance;
+   --horizontal_results
 }
 
 --echo # 5. Cleanup
 #==================
 # Cleanup
 --disable_query_log
+eval
+UPDATE performance_schema.setup_timers
+SET TIMER_NAME = '$wait_timer'
+WHERE NAME = 'wait';
 DROP SCHEMA mysqltest;
 DROP SCHEMA mysqlsupertest;
 --connection con1

=== modified file 'mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test'
--- a/mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test	2011-08-20 00:36:03 +0000
+++ b/mysql-test/suite/perfschema/t/socket_summary_by_instance_func_win.test	2011-08-24 14:09:20 +0000
@@ -112,6 +112,8 @@ if($my_socket_debug)
 #    cause that the test needs maintenance.
 # Advantage:
 #    More thorough checks.
+# If any of the checks detects some suspicious/unexpected state than
+# $print_details will be automatically switched to 1.
 #
 let $print_details= 0;
 
@@ -191,6 +193,29 @@ if(!$success)
 }
 
 --disable_query_log
+
+#
+# Lower the resolution of the wait timer from the default 'CYCLE'
+# to 'NANOSECOND'.
+# Hint: The timer columns contains values in picoseconds independent
+#       of the timer resolution.
+#       The timer resolution has an impact on the precision of the value.
+# This should prevent the failures seen on some suspicious PB boxes where
+# - calculations exceeded the BIGINT UNSIGNED (data type of the counter columns)
+#   value range.
+# - we have reached from whatever reason 20 digit values 
+# The consequence for the current test is the following:
+#    The common sense rule
+#       In case COUNT_<A> increases than SUM_TIMER_<A> must also increase
+#    is no more valid because some action might need less time than the
+#    timer resolution.
+#
+let $wait_timer= `SELECT TIMER_NAME FROM performance_schema.setup_timers
+                  WHERE NAME = 'wait'`;
+UPDATE performance_schema.setup_timers
+SET TIMER_NAME = 'NANOSECOND'
+WHERE NAME = 'wait';
+
 #
 # Additional SCHEMA used for
 # - detection of our "worker" session within the PROCESSLIST.
@@ -217,43 +242,73 @@ SET INSTRUMENTED='NO' WHERE PROCESSLIST_
 # - to have initial values from before some action
 # - to minimize the impact of statements used for the checks on results.
 # CREATE TEMPORARY TABLE my_socket_summary_by_instance AS
-# would be nice but the optimizer does not support important statements.
+# would be nice but some statements are not supported for temporary tables.
 #
-CREATE TABLE mysqltest.my_socket_summary_by_instance AS
-SELECT *, 'Pseudo_Before' AS pk FROM performance_schema.socket_summary_by_instance
-WHERE 1 = 0;
+# DECIMAL(60,0) is used instead of BIGINT UNSIGNED. The goal is to prevent
+# errors during calculations
+#   Example:
+#   -    A and B UNSIGNED BIGINT
+#   -    A < B
+#   -    A - B ---> Error
+# though the columns in all queries are orderd to avoid this too.
+#
+CREATE TABLE mysqltest.my_socket_summary_by_instance (
+  EVENT_NAME varchar(128) NOT NULL,
+  OBJECT_INSTANCE_BEGIN bigint(20) unsigned NOT NULL,
+  COUNT_STAR                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_WAIT            DECIMAL(60,0) NOT NULL,
+  COUNT_READ                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_READ  DECIMAL(60,0) NOT NULL,
+  COUNT_WRITE               DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_WRITE DECIMAL(60,0) NOT NULL,
+  COUNT_MISC                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  MIN_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  AVG_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  MAX_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  pk VARCHAR(20),
+  PRIMARY KEY(pk, EVENT_NAME, OBJECT_INSTANCE_BEGIN)
+) DEFAULT CHARSET=utf8;
 
-# The CAST(... AS DECIMAL) prevents errors which might show up in case
+
+# The CAST(... AS DECIMAL(60,0)) prevents errors which might show up in case
 # we run with the original data type UNSIGNED BIGINT.
-# Example:
-# -    A and B UNSIGNED BIGINT
-# -    A < B
-# -    A - B ---> Error
-CREATE TABLE mysqltest.socket_summary_by_instance_detail AS
-SELECT EVENT_NAME,OBJECT_INSTANCE_BEGIN,
-       CAST(COUNT_READ AS DECIMAL) AS COUNT_READ,
-       CAST(SUM_TIMER_READ AS DECIMAL) AS SUM_TIMER_READ,
-       CAST(SUM_NUMBER_OF_BYTES_READ AS DECIMAL) SUM_NUMBER_OF_BYTES_READ,
-       CAST(COUNT_WRITE AS DECIMAL) AS COUNT_WRITE,
-       CAST(SUM_TIMER_WRITE AS DECIMAL) AS SUM_TIMER_WRITE,
-       CAST(SUM_NUMBER_OF_BYTES_WRITE AS DECIMAL) AS SUM_NUMBER_OF_BYTES_WRITE,
-       CAST(COUNT_MISC AS DECIMAL) AS COUNT_MISC,
-       CAST(SUM_TIMER_MISC AS DECIMAL) AS SUM_TIMER_MISC
-FROM performance_schema.socket_summary_by_instance
-WHERE 1 = 2;
-ALTER TABLE mysqltest.socket_summary_by_instance_detail
-ADD statement VARCHAR(500), ADD run INTEGER;
+CREATE TABLE mysqltest.socket_summary_by_instance_detail (
+  EVENT_NAME varchar(128) NOT NULL,
+  OBJECT_INSTANCE_BEGIN bigint(20) unsigned NOT NULL,
+  COUNT_READ                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_READ            DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_READ  DECIMAL(60,0) NOT NULL,
+  COUNT_WRITE               DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_WRITE           DECIMAL(60,0) NOT NULL,
+  SUM_NUMBER_OF_BYTES_WRITE DECIMAL(60,0) NOT NULL,
+  COUNT_MISC                DECIMAL(60,0) NOT NULL,
+  SUM_TIMER_MISC            DECIMAL(60,0) NOT NULL,
+  statement VARCHAR(500),
+  run INTEGER
+) DEFAULT CHARSET=utf8;
 
 #
 # Auxiliary SQL functions used to shorten some commands.
 #
 CREATE FUNCTION mysqltest.min_of_triple
-   (f1 BIGINT UNSIGNED, f2 BIGINT UNSIGNED, f3 BIGINT UNSIGNED)
-   RETURNS BIGINT UNSIGNED
+   (f1 DECIMAL(60,0), f2 DECIMAL(60,0), f3 DECIMAL(60,0))
+   RETURNS DECIMAL(60,0)
    RETURN IF(IF(f1 < f2,f1,f2) < f3,IF(f1 < f2,f1,f2), f3);
 CREATE FUNCTION mysqltest.max_of_triple
-   (f1 BIGINT UNSIGNED, f2 BIGINT UNSIGNED, f3 BIGINT UNSIGNED)
-   RETURNS BIGINT UNSIGNED
+   (f1 DECIMAL(60,0), f2 DECIMAL(60,0), f3 DECIMAL(60,0))
+   RETURNS DECIMAL(60,0)
    RETURN IF(IF(f1 > f2,f1,f2) > f3,IF(f1 > f2,f1,f2), f3);
 
 #
@@ -473,6 +528,7 @@ if(`SELECT COUNT(*) FROM performance_sch
 
 --echo # 1.3 Check the base line
 #===============================
+eval $truncate;
 --source ../include/socket_summary_check.inc
 
 # --disable_query_log
@@ -687,13 +743,13 @@ if(`SELECT NOT ( $my_rules ) $part `)
 --echo #     - no change in COUNT_* leads to no change in
 --echo #       SUM_TIMER_* and no change in SUM_NUMBER_OF_BYTES_*
 --echo #     - increased COUNT_READ leads to increased
---echo #       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
+--echo #       SUM_NUMBER_OF_BYTES_READ
 --echo #     - increased COUNT_WRITE leads to increased
---echo #       SUM_TIMER_READ and SUM_NUMBER_OF_BYTES_READ
---echo #     - increased COUNT_MISC leads to increased
---echo #       SUM_TIMER_MISC
---echo #       Attention: There are exceptions but they are not valid
---echo #                  for this test.
+--echo #       SUM_NUMBER_OF_BYTES_WRITE
+--echo #     Attention:
+--echo #     The time required for some action might be below timer resolution.
+--echo #     Therefore some increased COUNT_* does not need to lead to an
+--echo #     increased SUM_TIMER_*.
 #==========================================================================
 # Enable the following lines for debugging the check.
 # Attention: socket_summary_by_instance_detail is after that rotten.
@@ -712,15 +768,15 @@ if(0)
 let $my_rules=
 ((COUNT_READ  = 0 AND SUM_TIMER_READ  = 0 AND SUM_NUMBER_OF_BYTES_READ  = 0)
   OR
- (COUNT_READ  > 0 AND SUM_TIMER_READ  > 0 AND SUM_NUMBER_OF_BYTES_READ  > 0))
+ (COUNT_READ  > 0                         AND SUM_NUMBER_OF_BYTES_READ  > 0))
 AND
 ((COUNT_WRITE = 0 AND SUM_TIMER_WRITE = 0 AND SUM_NUMBER_OF_BYTES_WRITE = 0)
   OR
- (COUNT_WRITE > 0 AND SUM_TIMER_WRITE > 0 AND SUM_NUMBER_OF_BYTES_WRITE > 0))
+ (COUNT_WRITE > 0                         AND SUM_NUMBER_OF_BYTES_WRITE > 0))
 AND
 ((COUNT_MISC  = 0 AND SUM_TIMER_MISC  = 0)
   OR
-(COUNT_MISC > 0 AND SUM_TIMER_MISC > 0));
+(COUNT_MISC > 0));
 if(`SELECT COUNT(*) FROM mysqltest.socket_summary_by_instance_detail
     WHERE NOT ( $my_rules ) `)
 {
@@ -736,6 +792,7 @@ if(`SELECT COUNT(*) FROM mysqltest.socke
    FROM mysqltest.socket_summary_by_instance_detail
    WHERE NOT ( $my_rules )
    ORDER BY EVENT_NAME, OBJECT_INSTANCE, STATEMENT, RUN;
+   let $print_details= 1;
 }
 
 --echo # 4.2 Results must be stable
@@ -803,6 +860,7 @@ if(`SELECT COUNT(statement) $part`)
          IN (SELECT EVENT_NAME, statement
              $part)
    ORDER BY EVENT_NAME, statement, run, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 --echo # 4.3 Counters must be 0 in client_connection for the default session
@@ -838,6 +896,7 @@ if(`SELECT COUNT(*) FROM performance_sch
       COUNT_MISC,SUM_TIMER_MISC
    FROM performance_schema.socket_summary_by_instance
    WHERE OBJECT_INSTANCE_BEGIN = @default_object_instance_begin;
+   let $print_details= 1;
 }
 
 #---------------------------------------------------------------------------
@@ -884,6 +943,7 @@ if(`SELECT COUNT(*) $part`)
       $column_list
    $part
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN, statement, run;
+   let $print_details= 1;
 }
 
 --echo # 4.4.2 In case of SELECT and our scenarios even COUNT_READ and COUNT_MISC
@@ -926,6 +986,7 @@ if(`SELECT COUNT(statement) $part`)
          IN (SELECT EVENT_NAME, statement
              $part)
    ORDER BY EVENT_NAME, statement, run, OBJECT_INSTANCE_BEGIN;
+   let $print_details= 1;
 }
 
 --echo # 4.4.3 In our testing scenarios we get for the client_connection entry
@@ -970,6 +1031,7 @@ if (0)
       $column_list
    $part
    ORDER BY EVENT_NAME, OBJECT_INSTANCE_BEGIN, statement, run;
+   let $print_details= 1;
 }
 
 # Initialize variables
@@ -1197,6 +1259,7 @@ if(`SELECT COUNT(*) $part `)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.2 Connects using for host the value 'localhost'
@@ -1240,10 +1303,11 @@ if (0)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.2.2 For the instance with EVENT_NAME LIKE '%server_unix_socket'
---echo #         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+--echo #         COUNT_MISC > 0 must be valid.
 --echo # SKIPPED FOR WINDOWS
 #===========================================================================
 # Enable the following lines for debugging the check.
@@ -1261,7 +1325,7 @@ if(0)
 }
 
 let $my_rules=
-COUNT_MISC  > 0 AND SUM_TIMER_MISC  > 0;
+COUNT_MISC  > 0;
 let $part=
 FROM mysqltest.socket_summary_by_instance_detail
 WHERE OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin
@@ -1281,6 +1345,7 @@ if (0)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.3 Connects using for host a value <> 'localhost'
@@ -1325,10 +1390,11 @@ if (0)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.3.2 For the instance with EVENT_NAME LIKE '%server_tcpip_socket'
---echo #         COUNT_MISC > 0 AND SUM_TIMER_MISC > 0 must be valid.
+--echo #         COUNT_MISC > 0 must be valid.
 #===========================================================================
 # Enable the following lines for debugging the check.
 # Attention: socket_summary_by_instance_detail is after that rotten.
@@ -1346,7 +1412,7 @@ if(0)
 }
 
 let $my_rules=
-COUNT_MISC  > 0 AND SUM_TIMER_MISC  > 0;
+COUNT_MISC  > 0;
 let $part=
 FROM mysqltest.socket_summary_by_instance_detail
 WHERE OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin
@@ -1365,6 +1431,7 @@ if(`SELECT COUNT(*) $part `)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.4 Failing Connects do not cause any row with EVENT_NAME
@@ -1402,6 +1469,7 @@ if(`SELECT COUNT(*) $part`)
    SELECT
    $column_list
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.5.5 Successful Connects cause a new instance with EVENT_NAME
@@ -1460,6 +1528,7 @@ if(`SELECT COUNT(*) $part`)
      AND statement IN
          (SELECT statement
           $part);
+   let $print_details= 1;
 }
 
 --echo # 4.6 Check the differences caused by Connects
@@ -1507,6 +1576,7 @@ if(`SELECT NOT ( $my_rules) $part`)
    SELECT
    statement, SUM_NUMBER_OF_BYTES_WRITE
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.6.2 The SUM_OF_BYTES_WRITE value hast to be > 100.
@@ -1532,6 +1602,7 @@ if(`SELECT COUNT(*) $part`)
    SELECT
    statement, SUM_NUMBER_OF_BYTES_WRITE
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.6.3 COUNT_READ, COUNT_WRITE and COUNT_MISC have to be to be > 0
@@ -1558,6 +1629,7 @@ if(`SELECT COUNT(*) $part`)
    SELECT
    statement, COUNT_READ, COUNT_WRITE, COUNT_MISC
    $part;
+   let $print_details= 1;
 }
 
 --echo # 4.6.4 Checks based on comparison of results for connects
@@ -1601,6 +1673,7 @@ if(`SELECT NOT ($my_rules)
    eval
    $part1
    AND statement IN('$stmt2','$stmt1');
+   let $print_details= 1;
 }
 
 --echo # 4.6.5 The database name length affects the SUM_OF_BYTES_READ value
@@ -1626,6 +1699,7 @@ if(`SELECT NOT ($my_rules)
    eval
    $part1
    AND statement IN('$stmt2','$stmt1');
+   let $print_details= 1;
 }
 
 if($print_details)
@@ -1670,12 +1744,20 @@ if($print_details)
    FROM mysqltest.socket_summary_by_instance_detail
    WHERE EVENT_NAME LIKE '%server_tcpip_socket%'
    ORDER BY statement,run;
+   --echo # 5. mysqltest.my_socket_summary_by_instance
+   --vertical_results
+   SELECT * FROM mysqltest.my_socket_summary_by_instance;
+   --horizontal_results
 }
 
 --echo # 5. Cleanup
 #==================
 # Cleanup
 --disable_query_log
+eval
+UPDATE performance_schema.setup_timers
+SET TIMER_NAME = '$wait_timer'
+WHERE NAME = 'wait';
 DROP SCHEMA mysqltest;
 DROP SCHEMA mysqlsupertest;
 --connection con1

=== modified file 'mysql-test/suite/rpl/r/rpl_row_mts_rec_crash_safe.result'
--- a/mysql-test/suite/rpl/r/rpl_row_mts_rec_crash_safe.result	2011-08-22 06:14:59 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_mts_rec_crash_safe.result	2011-08-22 15:04:09 +0000
@@ -309,7 +309,7 @@ slave_master_info	CREATE TABLE `slave_ma
   `Ssl_crl` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The file used for the Certificate Revocation List (CRL)',
   `Ssl_crlpath` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The path used for Certificate Revocation List (CRL) files',
   PRIMARY KEY (`Master_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Master Information'
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Master Information'
 SHOW CREATE TABLE mysql.slave_relay_log_info;
 Table	Create Table
 slave_relay_log_info	CREATE TABLE `slave_relay_log_info` (
@@ -322,7 +322,7 @@ slave_relay_log_info	CREATE TABLE `slave
   `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
   `Number_of_workers` int(10) unsigned NOT NULL,
   PRIMARY KEY (`Master_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Relay Log Information'
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Relay Log Information'
 SHOW CREATE TABLE mysql.slave_worker_info;
 Table	Create Table
 slave_worker_info	CREATE TABLE `slave_worker_info` (
@@ -340,7 +340,7 @@ slave_worker_info	CREATE TABLE `slave_wo
   `Checkpoint_group_size` int(10) unsigned NOT NULL,
   `Checkpoint_group_bitmap` blob NOT NULL,
   PRIMARY KEY (`Master_id`,`Worker_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Worker Information'
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Worker Information'
 ALTER TABLE mysql.slave_master_info ENGINE= Innodb;
 ALTER TABLE mysql.slave_relay_log_info ENGINE= Innodb;
 ALTER TABLE mysql.slave_worker_info ENGINE= Innodb;

=== modified file 'mysql-test/suite/rpl/r/rpl_spec_variables.result'
--- a/mysql-test/suite/rpl/r/rpl_spec_variables.result	2010-12-19 17:15:12 +0000
+++ b/mysql-test/suite/rpl/r/rpl_spec_variables.result	2011-08-26 11:16:40 +0000
@@ -141,11 +141,11 @@ DROP TABLE IF EXISTS t1,t2;
 
 * storage_engine *
 SET @restore_master_storage_engine=@@global.storage_engine;
-SET @@global.storage_engine=InnoDB;
-SET @@session.storage_engine=InnoDB;
+SET @@global.default_storage_engine=InnoDB;
+SET @@session.default_storage_engine=InnoDB;
 SET @restore_slave_storage_engine=@@global.storage_engine;
-SET @@global.storage_engine=Memory;
-SET @@session.storage_engine=Memory;
+SET @@global.default_storage_engine=Memory;
+SET @@session.default_storage_engine=Memory;
 CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10));
 CREATE TABLE t2 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB;
 CREATE TABLE t3 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10));
@@ -184,8 +184,8 @@ t3	CREATE TABLE `t3` (
   `b` varchar(10) DEFAULT NULL,
   PRIMARY KEY (`a`)
 ) ENGINE=MEMORY DEFAULT CHARSET=latin1
-SET @@global.storage_engine=InnoDB;
-SET @@session.storage_engine=InnoDB;
+SET @@global.default_storage_engine=InnoDB;
+SET @@session.default_storage_engine=InnoDB;
 DROP TABLE IF EXISTS t1,t2,t3;
 
 * sql_mode *
@@ -212,11 +212,11 @@ DROP TABLE t1;
 *** clean up ***
 SET @@global.character_set_database=@restore_master_character_set_database;
 SET @@global.collation_server=@restore_master_collation_server;
-SET @@global.storage_engine=@restore_master_storage_engine;
+SET @@global.default_storage_engine=@restore_master_storage_engine;
 SET @@global.character_set_database=@restore_slave_character_set_database;
 SET @@global.collation_server=@restore_slave_collation_server;
 SET @@global.max_heap_table_size=@restore_slave_max_heap_table_size;
-SET @@global.storage_engine=@restore_slave_storage_engine;
+SET @@global.default_storage_engine=@restore_slave_storage_engine;
 
 call mtr.add_suppression("The table 't[12]' is full");
 include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/t/disabled.def'
--- a/mysql-test/suite/rpl/t/disabled.def	2011-08-03 18:22:00 +0000
+++ b/mysql-test/suite/rpl/t/disabled.def	2011-08-26 10:18:24 +0000
@@ -11,7 +11,6 @@
 ##############################################################################
 
 rpl_row_create_table      : Bug#11759274 2010-02-27 andrei failed different way than earlier with bug#45576
-rpl_spec_variables        : BUG#11755836 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux
 rpl_delayed_slave         : Bug#11764654 2010-11-09 andrei rpl_delayed_slave fails sporadically in pb
 rpl_row_until             : BUG#12359942 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out
 rpl_stm_until             : BUG#12359942 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out

=== modified file 'mysql-test/suite/rpl/t/rpl_spec_variables.test'
--- a/mysql-test/suite/rpl/t/rpl_spec_variables.test	2010-12-19 17:15:12 +0000
+++ b/mysql-test/suite/rpl/t/rpl_spec_variables.test	2011-08-26 11:16:40 +0000
@@ -221,13 +221,13 @@ DROP TABLE IF EXISTS t1,t2;
 
 --connection master
 SET @restore_master_storage_engine=@@global.storage_engine;
-SET @@global.storage_engine=InnoDB;
-SET @@session.storage_engine=InnoDB;
+SET @@global.default_storage_engine=InnoDB;
+SET @@session.default_storage_engine=InnoDB;
 
 --connection slave
 SET @restore_slave_storage_engine=@@global.storage_engine;
-SET @@global.storage_engine=Memory;
-SET @@session.storage_engine=Memory;
+SET @@global.default_storage_engine=Memory;
+SET @@session.default_storage_engine=Memory;
 
 --connection master
 CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10));
@@ -245,8 +245,8 @@ SHOW CREATE TABLE t1;
 SHOW CREATE TABLE t2;
 SHOW CREATE TABLE t3;
 
-SET @@global.storage_engine=InnoDB;
-SET @@session.storage_engine=InnoDB;
+SET @@global.default_storage_engine=InnoDB;
+SET @@session.default_storage_engine=InnoDB;
 
 --connection master
 --disable_warnings
@@ -291,12 +291,12 @@ DROP TABLE t1;
 --connection master
 SET @@global.character_set_database=@restore_master_character_set_database;
 SET @@global.collation_server=@restore_master_collation_server;
-SET @@global.storage_engine=@restore_master_storage_engine;
+SET @@global.default_storage_engine=@restore_master_storage_engine;
 --sync_slave_with_master
 SET @@global.character_set_database=@restore_slave_character_set_database;
 SET @@global.collation_server=@restore_slave_collation_server;
 SET @@global.max_heap_table_size=@restore_slave_max_heap_table_size;
-SET @@global.storage_engine=@restore_slave_storage_engine;
+SET @@global.default_storage_engine=@restore_slave_storage_engine;
 
 # Put at the end since the test otherwise emptied the table.
 

=== added file 'mysql-test/suite/sys_vars/r/ssl_crl_basic.result'
--- a/mysql-test/suite/sys_vars/r/ssl_crl_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/ssl_crl_basic.result	2011-08-23 13:20:16 +0000
@@ -0,0 +1,5 @@
+# a simplified test to keep the suite happy.
+# the real test is in main.
+select @@ssl_crl;
+@@ssl_crl
+NULL

=== added file 'mysql-test/suite/sys_vars/r/ssl_crlpath_basic.result'
--- a/mysql-test/suite/sys_vars/r/ssl_crlpath_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/ssl_crlpath_basic.result	2011-08-23 13:20:16 +0000
@@ -0,0 +1,5 @@
+# a simplified test to keep the suite happy.
+# the real test is in main.
+select @@ssl_crlpath;
+@@ssl_crlpath
+NULL

=== added file 'mysql-test/suite/sys_vars/t/ssl_crl_basic.test'
--- a/mysql-test/suite/sys_vars/t/ssl_crl_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/ssl_crl_basic.test	2011-08-23 13:20:16 +0000
@@ -0,0 +1,3 @@
+--echo # a simplified test to keep the suite happy.
+--echo # the real test is in main.
+select @@ssl_crl;

=== added file 'mysql-test/suite/sys_vars/t/ssl_crlpath_basic.test'
--- a/mysql-test/suite/sys_vars/t/ssl_crlpath_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/ssl_crlpath_basic.test	2011-08-23 13:20:16 +0000
@@ -0,0 +1,3 @@
+--echo # a simplified test to keep the suite happy.
+--echo # the real test is in main.
+select @@ssl_crlpath;

=== modified file 'mysql-test/t/derived.test'
--- a/mysql-test/t/derived.test	2011-07-28 12:53:50 +0000
+++ b/mysql-test/t/derived.test	2011-08-26 08:55:54 +0000
@@ -905,3 +905,51 @@ drop table t1;
 
 --echo #
 
+--echo #
+--echo # Bug#12896124: Crash on rqg_mdl_stability test
+--echo #
+CREATE TABLE t1(f1 INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+CREATE FUNCTION func1 (param1 INTEGER) RETURNS INT NOT DETERMINISTIC
+return param1;
+CREATE FUNCTION func2 (param1 INTEGER) RETURNS INT 
+return param1;
+SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func1(f1);
+EXPLAIN SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func1(f1);
+SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func2(f1);
+EXPLAIN SELECT * FROM (SELECT * FROM t1) tt WHERE f1 = func2(f1);
+DROP FUNCTION func1;
+DROP FUNCTION func2;
+DROP TABLE t1;
+--echo #
+
+--echo #
+--echo # Bug#12909844: Missing type cast caused false assertion
+--echo #
+CREATE TABLE t1 ( fk INT) ENGINE=INNODB;
+CREATE TABLE t2 (
+f1 INT,  f2 INT,  f3 INT,  f4 INT,  f5 INT,  f6 INT,
+f7 INT,  f8 INT,  f9 INT,  f10 INT, f11 INT, f12 INT,
+f13 INT, f14 INT, f15 INT, f16 INT, f17 INT, f18 INT,
+f19 INT, f20 INT, f21 INT, f22 INT, f23 INT, f24 INT,
+f25 INT, f26 INT, f27 INT, f28 INT, f29 INT, f30 INT,
+f31 INT, f32 TEXT, fk INT) ENGINE=INNODB;
+SELECT alias2.fk AS field1 FROM t1 AS alias1 JOIN
+  (SELECT * FROM t2 ) AS alias2 ON alias1.fk = alias2.fk;
+EXPLAIN 
+SELECT alias2.fk AS field1 FROM t1 AS alias1 JOIN
+  (SELECT * FROM t2 ) AS alias2 ON alias1.fk = alias2.fk;
+DROP TABLE t1, t2;
+--echo #
+
+--echo #
+--echo # Bug#12910039: Incorrect merge caused segmentation fault.
+--echo #
+CREATE TABLE t1 (f1 int) ENGINE=myisam;
+CREATE TABLE t2 (f1 text) ENGINE=innodb;
+SELECT 1 FROM (
+  ( SELECT * FROM ( SELECT * FROM t2 ) AS alias1 ) AS alias1,
+  ( SELECT * FROM t1 ) AS alias2 );
+DROP TABLE t1,t2;
+--echo #
+

=== modified file 'mysql-test/t/func_math.test'
--- a/mysql-test/t/func_math.test	2011-07-18 09:38:13 +0000
+++ b/mysql-test/t/func_math.test	2011-08-26 07:06:35 +0000
@@ -538,6 +538,16 @@ SELECT 1 div null;
 select (1.175494351E-37 div 1.7976931348623157E+308);
 
 --echo #
+--echo # Bug#12744991 - DECIMAL_ROUND(X,D) GIVES WRONG RESULTS WHEN D == N*(-9)
+--echo #
+
+select round(999999999, -9);
+select round(999999999.0, -9);
+select round(999999999999999999, -18);
+select round(999999999999999999.0, -18);
+
+
+--echo #
 --echo # Bug#12537160 ASSERTION FAILED:
 --echo # STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER.
 --echo #

=== modified file 'mysys/psi_noop.cc'
--- a/mysys/psi_noop.cc	2011-07-22 20:08:29 +0000
+++ b/mysys/psi_noop.cc	2011-08-25 07:53:21 +0000
@@ -500,67 +500,67 @@ static void set_statement_rows_examined_
 }
 
 static void inc_statement_created_tmp_disk_tables_noop(PSI_statement_locker *locker,
-                                                       ulonglong count)
+                                                       ulong count)
 {
   return;
 }
 
 static void inc_statement_created_tmp_tables_noop(PSI_statement_locker *locker,
-                                                  ulonglong count)
+                                                  ulong count)
 {
   return;
 }
 
 static void inc_statement_select_full_join_noop(PSI_statement_locker *locker,
-                                                ulonglong count)
+                                                ulong count)
 {
   return;
 }
 
 static void inc_statement_select_full_range_join_noop(PSI_statement_locker *locker,
-                                                      ulonglong count)
+                                                      ulong count)
 {
   return;
 }
 
 static void inc_statement_select_range_noop(PSI_statement_locker *locker,
-                                            ulonglong count)
+                                            ulong count)
 {
   return;
 }
 
 static void inc_statement_select_range_check_noop(PSI_statement_locker *locker,
-                                                  ulonglong count)
+                                                  ulong count)
 {
   return;
 }
 
 static void inc_statement_select_scan_noop(PSI_statement_locker *locker,
-                                           ulonglong count)
+                                           ulong count)
 {
   return;
 }
 
 static void inc_statement_sort_merge_passes_noop(PSI_statement_locker *locker,
-                                                 ulonglong count)
+                                                 ulong count)
 {
   return;
 }
 
 static void inc_statement_sort_range_noop(PSI_statement_locker *locker,
-                                          ulonglong count)
+                                          ulong count)
 {
   return;
 }
 
 static void inc_statement_sort_rows_noop(PSI_statement_locker *locker,
-                                         ulonglong count)
+                                         ulong count)
 {
   return;
 }
 
 static void inc_statement_sort_scan_noop(PSI_statement_locker *locker,
-                                         ulonglong count)
+                                         ulong count)
 {
   return;
 }

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2011-06-30 15:50:45 +0000
+++ b/sql/filesort.cc	2011-08-25 10:54:34 +0000
@@ -176,6 +176,7 @@ ha_rows filesort(THD *thd, TABLE *table,
   */
   FILESORT_INFO table_sort= table->sort;
   table->sort.io_cache= NULL;
+  DBUG_ASSERT(table_sort.record_pointers == NULL);
   
   outfile= table_sort.io_cache;
   my_b_clear(&tempfile);
@@ -392,6 +393,7 @@ ha_rows filesort(THD *thd, TABLE *table,
 
 void filesort_free_buffers(TABLE *table, bool full)
 {
+  DBUG_ENTER("filesort_free_buffers");
   my_free(table->sort.record_pointers);
   table->sort.record_pointers= NULL;
 
@@ -408,6 +410,7 @@ void filesort_free_buffers(TABLE *table,
   my_free(table->sort.addon_field);
   table->sort.addon_buf= NULL;
   table->sort.addon_field= NULL;
+  DBUG_VOID_RETURN;
 }
 
 /**

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2011-08-16 19:33:03 +0000
+++ b/sql/opt_range.cc	2011-08-25 10:54:34 +0000
@@ -1380,7 +1380,8 @@ int QUICK_INDEX_MERGE_SELECT::init()
 int QUICK_INDEX_MERGE_SELECT::reset()
 {
   DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::reset");
-  DBUG_RETURN(read_keys_and_merge());
+  const int retval= read_keys_and_merge();
+  DBUG_RETURN(retval);
 }
 
 bool

=== modified file 'sql/records.cc'
--- a/sql/records.cc	2011-07-28 12:53:50 +0000
+++ b/sql/records.cc	2011-08-26 08:55:54 +0000
@@ -302,8 +302,7 @@ void end_read_record(READ_RECORD *info)
     my_free_lock(info->cache);
     info->cache=0;
   }
-  if (info->table &&
-      (info->table->s->tmp_table != INTERNAL_TMP_TABLE || info->table->created))
+  if (info->table && info->table->created)
   {
     filesort_free_buffers(info->table,0);
     (void) info->table->file->extra(HA_EXTRA_NO_CACHE);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2011-08-19 13:04:28 +0000
+++ b/sql/sql_base.cc	2011-08-26 08:55:54 +0000
@@ -6087,6 +6087,7 @@ TABLE *open_table_uncached(THD *thd, con
       modify_slave_open_temp_tables(thd, 1);
   }
   tmp_table->pos_in_table_list= 0;
+  tmp_table->created= true;
   DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' 0x%lx", tmp_table->s->db.str,
                           tmp_table->s->table_name.str, (long) tmp_table));
   DBUG_RETURN(tmp_table);

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-08-19 11:39:15 +0000
+++ b/sql/sql_select.cc	2011-08-25 10:54:34 +0000
@@ -12720,14 +12720,14 @@ void JOIN::cleanup(bool full)
   {
     JOIN_TAB *tab,*end;
     /*
-      Only a sorted table may be cached.  This sorted table is always the
-      first non const table in join->all_tables
+      Free resources allocated by filesort() and Unique::get()
     */
     if (tables > const_tables) // Test for not-const tables
-    {
-      free_io_cache(all_tables[const_tables]);
-      filesort_free_buffers(all_tables[const_tables],full);
-    }
+      for (uint ix= const_tables; ix < tables; ++ix)
+      {
+        free_io_cache(all_tables[ix]);
+        filesort_free_buffers(all_tables[ix], full);
+      }
 
     if (full)
     {

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2011-08-19 13:04:28 +0000
+++ b/sql/table.cc	2011-08-24 14:47:26 +0000
@@ -5283,7 +5283,8 @@ bool TABLE::add_tmp_key(ulonglong key_pa
   for (reg_field=field ; *reg_field; i++, reg_field++)
   {
     // Ensure that we're not creating a key over a blob field.
-    DBUG_ASSERT(!(key_parts & (1 << i) && (*reg_field)->flags & BLOB_FLAG));
+    DBUG_ASSERT(!((key_parts & (1ULL << i)) &&
+                (*reg_field)->flags & BLOB_FLAG));
     field_count++;
   }
   uint key_part_count= my_count_bits(key_parts);
@@ -5312,7 +5313,7 @@ bool TABLE::add_tmp_key(ulonglong key_pa
   keys_in_use_for_order_by.set_bit(s->keys);
   for (i= 0, reg_field=field ; *reg_field; i++, reg_field++)
   {
-    if (!(key_parts & (1 << i)))
+    if (!(key_parts & (1ULL << i)))
       continue;
 
     if (key_start)
@@ -5846,8 +5847,8 @@ bool TABLE_LIST::update_derived_keys(Fie
 
   for (uint i= 0; i < num_values; i++)
   {
-    table_map tables= values[i]->used_tables();
-    if (!tables)
+    table_map tables= values[i]->used_tables() & ~PSEUDO_TABLE_BITS;
+    if (!tables || values[i]->real_item()->type() != Item::FIELD_ITEM)
       continue;
     for (table_map tbl= 1; tables >= tbl; tbl<<= 1)
     {

=== modified file 'sql/uniques.cc'
--- a/sql/uniques.cc	2011-06-30 15:50:45 +0000
+++ b/sql/uniques.cc	2011-08-25 10:54:34 +0000
@@ -57,7 +57,10 @@ int unique_write_to_ptrs(uchar* key, ele
 
 Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
 	       uint size_arg, ulonglong max_in_memory_size_arg)
-  :max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0)
+  :max_in_memory_size(max_in_memory_size_arg),
+   record_pointers(NULL),
+   size(size_arg),
+   elements(0)
 {
   my_b_clear(&file);
   init_tree(&tree, (ulong) (max_in_memory_size / 16), 0, size, comp_func, 0,
@@ -581,6 +584,7 @@ bool Unique::get(TABLE *table)
   if (my_b_tell(&file) == 0)
   {
     /* Whole tree is in memory;  Don't use disk if you don't need to */
+    DBUG_ASSERT(table->sort.record_pointers == NULL);
     if ((record_pointers=table->sort.record_pointers= (uchar*)
 	 my_malloc(size * tree.elements_in_tree, MYF(0))))
     {
@@ -601,6 +605,7 @@ bool Unique::get(TABLE *table)
   bool error=1;
 
       /* Open cached file if it isn't open */
+  DBUG_ASSERT(table->sort.io_cache == NULL);
   outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
                                 MYF(MY_ZEROFILL));
 

=== modified file 'storage/innobase/dict/dict0stats.c'
--- a/storage/innobase/dict/dict0stats.c	2011-06-01 09:42:10 +0000
+++ b/storage/innobase/dict/dict0stats.c	2011-08-23 07:02:19 +0000
@@ -598,6 +598,7 @@ dict_stats_analyze_index_level(
 	/* now in n_diff_boundaries[i] there are exactly n_diff[i] integers,
 	for i=1..n_uniq */
 
+#ifdef UNIV_STATS_DEBUG
 	for (i = 1; i <= n_uniq; i++) {
 
 		DEBUG_PRINTF("    %s(): total recs: %llu, total pages: %llu, "
@@ -605,7 +606,6 @@ dict_stats_analyze_index_level(
 			     __func__, *total_recs, *total_pages,
 			     i, n_diff[i]);
 
-#if 0
 		if (n_diff_boundaries != NULL) {
 			ib_int64_t	j;
 
@@ -621,8 +621,8 @@ dict_stats_analyze_index_level(
 			}
 			printf("\n");
 		}
-#endif
 	}
+#endif /* UNIV_STATS_DEBUG */
 
 	btr_pcur_close(&pcur);
 

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2011-08-22 07:46:51 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2011-08-22 14:27:17 +0000
@@ -2713,7 +2713,8 @@ innobase_change_buffering_inited_ok:
 			" InnoDB: Warning: Using " 
 			"innodb_additional_mem_pool_size is DEPRECATED. "
 			"This option may be removed in future releases, "
-			"together with the InnoDB's internal memory "
+			"together with the option innodb_use_sys_malloc "
+			"and with the InnoDB's internal memory "
 			"allocator.\n");
 	}
 
@@ -2723,8 +2724,7 @@ innobase_change_buffering_inited_ok:
 			" InnoDB: Warning: Setting " 
 			"innodb_use_sys_malloc to FALSE is DEPRECATED. "
 			"This option may be removed in future releases, "
-			"together with the option innodb_use_sys_malloc "
-			"and with the InnoDB's internal memory "
+			"together with the InnoDB's internal memory "
 			"allocator.\n");
 	}
 

=== modified file 'storage/perfschema/pfs.cc'
--- a/storage/perfschema/pfs.cc	2011-08-18 16:15:02 +0000
+++ b/storage/perfschema/pfs.cc	2011-08-25 07:53:21 +0000
@@ -4395,67 +4395,67 @@ static void set_statement_rows_examined_
 }
 
 static void inc_statement_created_tmp_disk_tables_v1(PSI_statement_locker *locker,
-                                                    ulonglong count)
+                                                    ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_created_tmp_disk_tables, count);
 }
 
 static void inc_statement_created_tmp_tables_v1(PSI_statement_locker *locker,
-                                                ulonglong count)
+                                                ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_created_tmp_tables, count);
 }
 
 static void inc_statement_select_full_join_v1(PSI_statement_locker *locker,
-                                              ulonglong count)
+                                              ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_select_full_join, count);
 }
 
 static void inc_statement_select_full_range_join_v1(PSI_statement_locker *locker,
-                                                    ulonglong count)
+                                                    ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_select_full_range_join, count);
 }
 
 static void inc_statement_select_range_v1(PSI_statement_locker *locker,
-                                          ulonglong count)
+                                          ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_select_range, count);
 }
 
 static void inc_statement_select_range_check_v1(PSI_statement_locker *locker,
-                                                ulonglong count)
+                                                ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_select_range_check, count);
 }
 
 static void inc_statement_select_scan_v1(PSI_statement_locker *locker,
-                                         ulonglong count)
+                                         ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_select_scan, count);
 }
 
 static void inc_statement_sort_merge_passes_v1(PSI_statement_locker *locker,
-                                               ulonglong count)
+                                               ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_sort_merge_passes, count);
 }
 
 static void inc_statement_sort_range_v1(PSI_statement_locker *locker,
-                                        ulonglong count)
+                                        ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_sort_range, count);
 }
 
 static void inc_statement_sort_rows_v1(PSI_statement_locker *locker,
-                                       ulonglong count)
+                                       ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_sort_rows, count);
 }
 
 static void inc_statement_sort_scan_v1(PSI_statement_locker *locker,
-                                       ulonglong count)
+                                       ulong count)
 {
   INC_STATEMENT_ATTR_BODY(locker, m_sort_scan, count);
 }

=== modified file 'storage/perfschema/pfs_account.cc'
--- a/storage/perfschema/pfs_account.cc	2011-08-10 06:26:45 +0000
+++ b/storage/perfschema/pfs_account.cc	2011-08-25 07:53:21 +0000
@@ -122,6 +122,7 @@ void cleanup_account(void)
   account_max= 0;
 }
 
+C_MODE_START
 static uchar *account_hash_get_key(const uchar *entry, size_t *length,
                                 my_bool)
 {
@@ -136,6 +137,7 @@ static uchar *account_hash_get_key(const
   result= account->m_key.m_hash_key;
   return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
 }
+C_MODE_END
 
 /**
   Initialize the user hash.

=== modified file 'storage/perfschema/pfs_host.cc'
--- a/storage/perfschema/pfs_host.cc	2011-08-10 06:26:45 +0000
+++ b/storage/perfschema/pfs_host.cc	2011-08-25 07:53:21 +0000
@@ -123,6 +123,7 @@ void cleanup_host(void)
   host_max= 0;
 }
 
+C_MODE_START
 static uchar *host_hash_get_key(const uchar *entry, size_t *length,
                                 my_bool)
 {
@@ -137,6 +138,7 @@ static uchar *host_hash_get_key(const uc
   result= host->m_key.m_hash_key;
   return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
 }
+C_MODE_END
 
 /**
   Initialize the host hash.

=== modified file 'storage/perfschema/pfs_instr.cc'
--- a/storage/perfschema/pfs_instr.cc	2011-08-18 12:27:21 +0000
+++ b/storage/perfschema/pfs_instr.cc	2011-08-25 07:53:21 +0000
@@ -162,10 +162,6 @@ static PFS_events_statements *thread_sta
 static LF_HASH filename_hash;
 /** True if filename_hash is initialized. */
 static bool filename_hash_inited= false;
-C_MODE_START
-/** Get hash table key for instrumented files. */
-static uchar *filename_hash_get_key(const uchar *, size_t *, my_bool);
-C_MODE_END
 
 /**
   Initialize all the instruments instance buffers.
@@ -471,8 +467,8 @@ void cleanup_instruments(void)
   global_instr_class_statements_array= NULL;
 }
 
-extern "C"
-{
+C_MODE_START
+/** Get hash table key for instrumented files. */
 static uchar *filename_hash_get_key(const uchar *entry, size_t *length,
                                     my_bool)
 {
@@ -487,7 +483,7 @@ static uchar *filename_hash_get_key(cons
   result= file->m_filename;
   return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
 }
-}
+C_MODE_END
 
 /**
   Initialize the file name hash.
@@ -1681,16 +1677,12 @@ void aggregate_all_stages(PFS_stage_stat
   PFS_stage_stat *from;
   PFS_stage_stat *from_last;
   PFS_stage_stat *to_1;
-  PFS_stage_stat *to_1_last;
   PFS_stage_stat *to_2;
-  PFS_stage_stat *to_2_last;
 
   from= from_array;
   from_last= from_array + stage_class_max;
   to_1= to_array_1;
-  to_1_last= to_array_1 + stage_class_max;
   to_2= to_array_2;
-  to_2_last= to_array_2 + stage_class_max;
 
   for ( ; from < from_last ; from++, to_1++, to_2++)
   {
@@ -1731,16 +1723,12 @@ void aggregate_all_statements(PFS_statem
   PFS_statement_stat *from;
   PFS_statement_stat *from_last;
   PFS_statement_stat *to_1;
-  PFS_statement_stat *to_1_last;
   PFS_statement_stat *to_2;
-  PFS_statement_stat *to_2_last;
 
   from= from_array;
   from_last= from_array + statement_class_max;
   to_1= to_array_1;
-  to_1_last= to_array_1 + statement_class_max;
   to_2= to_array_2;
-  to_2_last= to_array_2 + statement_class_max;
 
   for ( ; from < from_last ; from++, to_1++, to_2++)
   {

=== modified file 'storage/perfschema/pfs_instr_class.cc'
--- a/storage/perfschema/pfs_instr_class.cc	2011-08-11 03:11:58 +0000
+++ b/storage/perfschema/pfs_instr_class.cc	2011-08-25 07:53:21 +0000
@@ -136,10 +136,6 @@ PFS_instr_class global_idle_class;
 static LF_HASH table_share_hash;
 /** True if table_share_hash is initialized. */
 static bool table_share_hash_inited= false;
-C_MODE_START
-/** Get hash table key for instrumented tables. */
-static uchar *table_share_hash_get_key(const uchar *, size_t *, my_bool);
-C_MODE_END
 
 static volatile uint32 file_class_dirty_count= 0;
 static volatile uint32 file_class_allocated_count= 0;
@@ -331,9 +327,8 @@ void cleanup_table_share(void)
   table_share_max= 0;
 }
 
-/**
-  get_key function for @c table_share_hash.
-*/
+C_MODE_START
+/** get_key function for @c table_share_hash. */
 static uchar *table_share_hash_get_key(const uchar *entry, size_t *length,
                                        my_bool)
 {
@@ -348,6 +343,7 @@ static uchar *table_share_hash_get_key(c
   result= &share->m_key.m_hash_key[0];
   return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
 }
+C_MODE_END
 
 /** Initialize the table share hash table. */
 int init_table_share_hash(void)

=== modified file 'storage/perfschema/pfs_setup_actor.cc'
--- a/storage/perfschema/pfs_setup_actor.cc	2011-08-10 07:06:02 +0000
+++ b/storage/perfschema/pfs_setup_actor.cc	2011-08-25 07:53:21 +0000
@@ -77,6 +77,7 @@ void cleanup_setup_actor(void)
   setup_actor_max= 0;
 }
 
+C_MODE_START
 static uchar *setup_actor_hash_get_key(const uchar *entry, size_t *length,
                                        my_bool)
 {
@@ -91,6 +92,7 @@ static uchar *setup_actor_hash_get_key(c
   result= setup_actor->m_key.m_hash_key;
   return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
 }
+C_MODE_END
 
 /**
   Initialize the setup actor hash.

=== modified file 'storage/perfschema/pfs_setup_object.cc'
--- a/storage/perfschema/pfs_setup_object.cc	2011-08-10 07:06:02 +0000
+++ b/storage/perfschema/pfs_setup_object.cc	2011-08-25 07:53:21 +0000
@@ -72,6 +72,7 @@ void cleanup_setup_object(void)
   setup_object_max= 0;
 }
 
+C_MODE_START
 static uchar *setup_object_hash_get_key(const uchar *entry, size_t *length,
                                         my_bool)
 {
@@ -86,6 +87,7 @@ static uchar *setup_object_hash_get_key(
   result= setup_object->m_key.m_hash_key;
   return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
 }
+C_MODE_END
 
 /**
   Initialize the setup objects hash.

=== modified file 'storage/perfschema/pfs_user.cc'
--- a/storage/perfschema/pfs_user.cc	2011-08-10 06:26:45 +0000
+++ b/storage/perfschema/pfs_user.cc	2011-08-25 07:53:21 +0000
@@ -123,6 +123,7 @@ void cleanup_user(void)
   user_max= 0;
 }
 
+C_MODE_START
 static uchar *user_hash_get_key(const uchar *entry, size_t *length,
                                 my_bool)
 {
@@ -137,6 +138,7 @@ static uchar *user_hash_get_key(const uc
   result= user->m_key.m_hash_key;
   return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
 }
+C_MODE_END
 
 /**
   Initialize the user hash.

=== modified file 'strings/decimal.c'
--- a/strings/decimal.c	2011-07-18 08:06:21 +0000
+++ b/strings/decimal.c	2011-08-26 07:06:35 +0000
@@ -1474,7 +1474,7 @@ int
 decimal_round(const decimal_t *from, decimal_t *to, int scale,
               decimal_round_mode mode)
 {
-  int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
+  int frac0=scale>0 ? ROUND_UP(scale) : (scale + 1)/DIG_PER_DEC1,
     frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
       intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
       intg1=ROUND_UP(from->intg +
@@ -2409,734 +2409,7 @@ int decimal_mod(const decimal_t *from1,
 }
 
 #ifdef MAIN
-
-int full= 0;
-decimal_t a, b, c;
-char buf1[100], buf2[100], buf3[100];
-
-void dump_decimal(decimal_t *d)
-{
-  int i;
-  printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
-  for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
-    printf("%09d, ", d->buf[i]);
-  printf("%09d} */ ", d->buf[i]);
-}
-
-
-void check_result_code(int actual, int want)
-{
-  if (actual != want)
-  {
-    printf("\n^^^^^^^^^^^^^ must return %d\n", want);
-    exit(1);
-  }
-}
-
-
-void print_decimal(decimal_t *d, const char *orig, int actual, int want)
-{
-  char s[100];
-  int slen=sizeof(s);
-
-  if (full) dump_decimal(d);
-  decimal2string(d, s, &slen, 0, 0, 0);
-  printf("'%s'", s);
-  check_result_code(actual, want);
-  if (orig && strcmp(orig, s))
-  {
-    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
-    exit(1);
-  }
-}
-
-void test_d2s()
-{
-  char s[100];
-  int slen, res;
-
-  /***********************************/
-  printf("==== decimal2string ====\n");
-  a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
-  slen=sizeof(s);
-  res=decimal2string(&a, s, &slen, 0, 0, 0);
-  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
-
-  a.buf[1]=987000000; a.frac=3;
-  slen=sizeof(s);
-  res=decimal2string(&a, s, &slen, 0, 0, 0);
-  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
-
-  a.sign=1;
-  slen=sizeof(s);
-  res=decimal2string(&a, s, &slen, 0, 0, 0);
-  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
-
-  slen=8;
-  res=decimal2string(&a, s, &slen, 0, 0, 0);
-  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
-
-  slen=5;
-  res=decimal2string(&a, s, &slen, 0, 0, 0);
-  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
-
-  a.buf[0]=987000000; a.frac=3; a.intg=0;
-  slen=sizeof(s);
-  res=decimal2string(&a, s, &slen, 0, 0, 0);
-  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
-}
-
-void test_s2d(const char *s, const char *orig, int ex)
-{
-  char s1[100], *end;
-  int res;
-  sprintf(s1, "'%s'", s);
-  end= strend(s);
-  printf("len=%2d %-30s => res=%d    ", a.len, s1,
-         (res= string2decimal(s, &a, &end)));
-  print_decimal(&a, orig, res, ex);
-  printf("\n");
-}
-
-void test_d2f(const char *s, int ex)
-{
-  char s1[100], *end;
-  double x;
-  int res;
-
-  sprintf(s1, "'%s'", s);
-  end= strend(s);
-  string2decimal(s, &a, &end);
-  res=decimal2double(&a, &x);
-  if (full) dump_decimal(&a);
-  printf("%-40s => res=%d    %.*g\n", s1, res, a.intg+a.frac, x);
-  check_result_code(res, ex);
-}
-
-void test_d2b2d(const char *str, int p, int s, const char *orig, int ex)
-{
-  char s1[100], buf[100], *end;
-  int res, i, size=decimal_bin_size(p, s);
-
-  sprintf(s1, "'%s'", str);
-  end= strend(str);
-  string2decimal(str, &a, &end);
-  res=decimal2bin(&a, buf, p, s);
-  printf("%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
-  if (full)
-  {
-    printf("0x");
-    for (i=0; i < size; i++)
-      printf("%02x", ((uchar *)buf)[i]);
-  }
-  res=bin2decimal(buf, &a, p, s);
-  printf(" => res=%d ", res);
-  print_decimal(&a, orig, res, ex);
-  printf("\n");
-}
-
-void test_f2d(double from, int ex)
-{
-  int res;
-
-  res=double2decimal(from, &a);
-  printf("%-40.*f => res=%d    ", DBL_DIG-2, from, res);
-  print_decimal(&a, 0, res, ex);
-  printf("\n");
-}
-
-void test_ull2d(ulonglong from, const char *orig, int ex)
-{
-  char s[100];
-  int res;
-
-  res=ulonglong2decimal(from, &a);
-  longlong10_to_str(from,s,10);
-  printf("%-40s => res=%d    ", s, res);
-  print_decimal(&a, orig, res, ex);
-  printf("\n");
-}
-
-void test_ll2d(longlong from, const char *orig, int ex)
-{
-  char s[100];
-  int res;
-
-  res=longlong2decimal(from, &a);
-  longlong10_to_str(from,s,-10);
-  printf("%-40s => res=%d    ", s, res);
-  print_decimal(&a, orig, res, ex);
-  printf("\n");
-}
-
-void test_d2ull(const char *s, const char *orig, int ex)
-{
-  char s1[100], *end;
-  ulonglong x;
-  int res;
-
-  end= strend(s);
-  string2decimal(s, &a, &end);
-  res=decimal2ulonglong(&a, &x);
-  if (full) dump_decimal(&a);
-  longlong10_to_str(x,s1,10);
-  printf("%-40s => res=%d    %s\n", s, res, s1);
-  check_result_code(res, ex);
-  if (orig && strcmp(orig, s1))
-  {
-    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
-    exit(1);
-  }
-}
-
-void test_d2ll(const char *s, const char *orig, int ex)
-{
-  char s1[100], *end;
-  longlong x;
-  int res;
-
-  end= strend(s);
-  string2decimal(s, &a, &end);
-  res=decimal2longlong(&a, &x);
-  if (full) dump_decimal(&a);
-  longlong10_to_str(x,s1,-10);
-  printf("%-40s => res=%d    %s\n", s, res, s1);
-  check_result_code(res, ex);
-  if (orig && strcmp(orig, s1))
-  {
-    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
-    exit(1);
-  }
-}
-
-void test_da(const char *s1, const char *s2, const char *orig, int ex)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s' + '%s'", s1, s2);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  end= strend(s2);
-  string2decimal(s2, &b, &end);
-  res=decimal_add(&a, &b, &c);
-  printf("%-40s => res=%d    ", s, res);
-  print_decimal(&c, orig, res, ex);
-  printf("\n");
-}
-
-void test_ds(const char *s1, const char *s2, const char *orig, int ex)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s' - '%s'", s1, s2);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  end= strend(s2);
-  string2decimal(s2, &b, &end);
-  res=decimal_sub(&a, &b, &c);
-  printf("%-40s => res=%d    ", s, res);
-  print_decimal(&c, orig, res, ex);
-  printf("\n");
-}
-
-void test_dc(const char *s1, const char *s2, int orig)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s' <=> '%s'", s1, s2);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  end= strend(s2);
-  string2decimal(s2, &b, &end);
-  res=decimal_cmp(&a, &b);
-  printf("%-40s => res=%d\n", s, res);
-  if (orig != res)
-  {
-    printf("\n^^^^^^^^^^^^^ must've been %d\n", orig);
-    exit(1);
-  }
-}
-
-void test_dm(const char *s1, const char *s2, const char *orig, int ex)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s' * '%s'", s1, s2);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  end= strend(s2);
-  string2decimal(s2, &b, &end);
-  res=decimal_mul(&a, &b, &c);
-  printf("%-40s => res=%d    ", s, res);
-  print_decimal(&c, orig, res, ex);
-  printf("\n");
-}
-
-void test_dv(const char *s1, const char *s2, const char *orig, int ex)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s' / '%s'", s1, s2);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  end= strend(s2);
-  string2decimal(s2, &b, &end);
-  res=decimal_div(&a, &b, &c, 5);
-  printf("%-40s => res=%d    ", s, res);
-  check_result_code(res, ex);
-  if (res == E_DEC_DIV_ZERO)
-    printf("E_DEC_DIV_ZERO");
-  else
-    print_decimal(&c, orig, res, ex);
-  printf("\n");
-}
-
-void test_md(const char *s1, const char *s2, const char *orig, int ex)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s' %% '%s'", s1, s2);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  end= strend(s2);
-  string2decimal(s2, &b, &end);
-  res=decimal_mod(&a, &b, &c);
-  printf("%-40s => res=%d    ", s, res);
-  check_result_code(res, ex);
-  if (res == E_DEC_DIV_ZERO)
-    printf("E_DEC_DIV_ZERO");
-  else
-    print_decimal(&c, orig, res, ex);
-  printf("\n");
-}
-
-const char *round_mode[]=
-{"TRUNCATE", "HALF_EVEN", "HALF_UP", "CEILING", "FLOOR"};
-
-void test_ro(const char *s1, int n, decimal_round_mode mode, const char *orig,
-             int ex)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  res=decimal_round(&a, &b, n, mode);
-  printf("%-40s => res=%d    ", s, res);
-  print_decimal(&b, orig, res, ex);
-  printf("\n");
-}
-
-
-void test_mx(int precision, int frac, const char *orig)
-{
-  char s[100];
-  sprintf(s, "%d, %d", precision, frac);
-  max_decimal(precision, frac, &a);
-  printf("%-40s =>          ", s);
-  print_decimal(&a, orig, 0, 0);
-  printf("\n");
-}
-
-
-void test_pr(const char *s1, int prec, int dec, char filler, const char *orig,
-             int ex)
-{
-  char s[100], *end;
-  char s2[100];
-  int slen= sizeof(s2);
-  int res;
-
-  sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
-          s1, prec, dec, filler);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  res= decimal2string(&a, s2, &slen, prec, dec, filler);
-  printf("%-40s => res=%d    '%s'", s, res, s2);
-  check_result_code(res, ex);
-  if (orig && strcmp(orig, s2))
-  {
-    printf("\n^^^^^^^^^^^^^ must've been '%s'\n", orig);
-    exit(1);
-  }
-  printf("\n");
-}
-
-
-void test_sh(const char *s1, int shift, const char *orig, int ex)
-{
-  char s[100], *end;
-  int res;
-  sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  res= decimal_shift(&a, shift);
-  printf("%-40s => res=%d    ", s, res);
-  print_decimal(&a, orig, res, ex);
-  printf("\n");
-}
-
-
-void test_fr(const char *s1, const char *orig)
-{
-  char s[100], *end;
-  sprintf(s, "'%s'", s1);
-  printf("%-40s =>          ", s);
-  end= strend(s1);
-  string2decimal(s1, &a, &end);
-  a.frac= decimal_actual_fraction(&a);
-  print_decimal(&a, orig, 0, 0);
-  printf("\n");
-}
-
-
-int main()
-{
-  a.buf=(void*)buf1;
-  a.len=sizeof(buf1)/sizeof(dec1);
-  b.buf=(void*)buf2;
-  b.len=sizeof(buf2)/sizeof(dec1);
-  c.buf=(void*)buf3;
-  c.len=sizeof(buf3)/sizeof(dec1);
-
-  if (full)
-    test_d2s();
-
-  printf("==== string2decimal ====\n");
-  test_s2d("12345", "12345", 0);
-  test_s2d("12345.", "12345", 0);
-  test_s2d("123.45", "123.45", 0);
-  test_s2d("-123.45", "-123.45", 0);
-  test_s2d(".00012345000098765", "0.00012345000098765", 0);
-  test_s2d(".12345000098765", "0.12345000098765", 0);
-  test_s2d("-.000000012345000098765", "-0.000000012345000098765", 0);
-  test_s2d("1234500009876.5", "1234500009876.5", 0);
-  a.len=1;
-  test_s2d("123450000098765", "98765", 2);
-  test_s2d("123450.000098765", "123450", 1);
-  a.len=sizeof(buf1)/sizeof(dec1);
-  test_s2d("123E5", "12300000", 0);
-  test_s2d("123E-2", "1.23", 0);
-
-  printf("==== decimal2double ====\n");
-  test_d2f("12345", 0);
-  test_d2f("123.45", 0);
-  test_d2f("-123.45", 0);
-  test_d2f("0.00012345000098765", 0);
-  test_d2f("1234500009876.5", 0);
-
-  printf("==== double2decimal ====\n");
-  test_f2d(12345, 0);
-  test_f2d(1.0/3, 0);
-  test_f2d(-123.45, 0);
-  test_f2d(0.00012345000098765, 0);
-  test_f2d(1234500009876.5, 0);
-
-  printf("==== ulonglong2decimal ====\n");
-  test_ull2d(ULL(12345), "12345", 0);
-  test_ull2d(ULL(0), "0", 0);
-  test_ull2d(ULL(18446744073709551615), "18446744073709551615", 0);
-
-  printf("==== decimal2ulonglong ====\n");
-  test_d2ull("12345", "12345", 0);
-  test_d2ull("0", "0", 0);
-  test_d2ull("18446744073709551615", "18446744073709551615", 0);
-  test_d2ull("18446744073709551616", "18446744073", 2);
-  test_d2ull("-1", "0", 2);
-  test_d2ull("1.23", "1", 1);
-  test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
-
-  printf("==== longlong2decimal ====\n");
-  test_ll2d(LL(-12345), "-12345", 0);
-  test_ll2d(LL(-1), "-1", 0);
-  test_ll2d(LL(-9223372036854775807), "-9223372036854775807", 0);
-  test_ll2d(ULL(9223372036854775808), "-9223372036854775808", 0);
-
-  printf("==== decimal2longlong ====\n");
-  test_d2ll("18446744073709551615", "18446744073", 2);
-  test_d2ll("-1", "-1", 0);
-  test_d2ll("-1.23", "-1", 1);
-  test_d2ll("-9223372036854775807", "-9223372036854775807", 0);
-  test_d2ll("-9223372036854775808", "-9223372036854775808", 0);
-  test_d2ll("9223372036854775808", "9223372036854775807", 2);
-
-  printf("==== do_add ====\n");
-  test_da(".00012345000098765" ,"123.45", "123.45012345000098765", 0);
-  test_da(".1" ,".45", "0.55", 0);
-  test_da("1234500009876.5" ,".00012345000098765", "1234500009876.50012345000098765", 0);
-  test_da("9999909999999.5" ,".555", "9999910000000.055", 0);
-  test_da("99999999" ,"1", "100000000", 0);
-  test_da("989999999" ,"1", "990000000", 0);
-  test_da("999999999" ,"1", "1000000000", 0);
-  test_da("12345" ,"123.45", "12468.45", 0);
-  test_da("-12345" ,"-123.45", "-12468.45", 0);
-  test_ds("-12345" ,"123.45", "-12468.45", 0);
-  test_ds("12345" ,"-123.45", "12468.45", 0);
-
-  printf("==== do_sub ====\n");
-  test_ds(".00012345000098765", "123.45","-123.44987654999901235", 0);
-  test_ds("1234500009876.5", ".00012345000098765","1234500009876.49987654999901235", 0);
-  test_ds("9999900000000.5", ".555","9999899999999.945", 0);
-  test_ds("1111.5551", "1111.555","0.0001", 0);
-  test_ds(".555", ".555","0", 0);
-  test_ds("10000000", "1","9999999", 0);
-  test_ds("1000001000", ".1","1000000999.9", 0);
-  test_ds("1000000000", ".1","999999999.9", 0);
-  test_ds("12345", "123.45","12221.55", 0);
-  test_ds("-12345", "-123.45","-12221.55", 0);
-  test_da("-12345", "123.45","-12221.55", 0);
-  test_da("12345", "-123.45","12221.55", 0);
-  test_ds("123.45", "12345","-12221.55", 0);
-  test_ds("-123.45", "-12345","12221.55", 0);
-  test_da("123.45", "-12345","-12221.55", 0);
-  test_da("-123.45", "12345","12221.55", 0);
-  test_da("5", "-6.0","-1.0", 0);
-
-  printf("==== decimal_mul ====\n");
-  test_dm("12", "10","120", 0);
-  test_dm("-123.456", "98765.4321","-12193185.1853376", 0);
-  test_dm("-123456000000", "98765432100000","-12193185185337600000000000", 0);
-  test_dm("123456", "987654321","121931851853376", 0);
-  test_dm("123456", "9876543210","1219318518533760", 0);
-  test_dm("123", "0.01","1.23", 0);
-  test_dm("123", "0","0", 0);
-
-  printf("==== decimal_div ====\n");
-  test_dv("120", "10","12.000000000", 0);
-  test_dv("123", "0.01","12300.000000000", 0);
-  test_dv("120", "100000000000.00000","0.000000001200000000", 0);
-  test_dv("123", "0","", 4);
-  test_dv("0", "0", "", 4);
-  test_dv("-12193185.1853376", "98765.4321","-123.456000000000000000", 0);
-  test_dv("121931851853376", "987654321","123456.000000000", 0);
-  test_dv("0", "987","0", 0);
-  test_dv("1", "3","0.333333333", 0);
-  test_dv("1.000000000000", "3","0.333333333333333333", 0);
-  test_dv("1", "1","1.000000000", 0);
-  test_dv("0.0123456789012345678912345", "9999999999","0.000000000001234567890246913578148141", 0);
-  test_dv("10.333000000", "12.34500","0.837019036046982584042122316", 0);
-  test_dv("10.000000000060", "2","5.000000000030000000", 0);
-
-  printf("==== decimal_mod ====\n");
-  test_md("234","10","4", 0);
-  test_md("234.567","10.555","2.357", 0);
-  test_md("-234.567","10.555","-2.357", 0);
-  test_md("234.567","-10.555","2.357", 0);
-  c.buf[1]=0x3ABECA;
-  test_md("99999999999999999999999999999999999999","3","0", 0);
-  if (c.buf[1] != 0x3ABECA)
-  {
-    printf("%X - overflow\n", c.buf[1]);
-    exit(1);
-  }
-
-  printf("==== decimal2bin/bin2decimal ====\n");
-  test_d2b2d("-10.55", 4, 2,"-10.55", 0);
-  test_d2b2d("0.0123456789012345678912345", 30, 25,"0.0123456789012345678912345", 0);
-  test_d2b2d("12345", 5, 0,"12345", 0);
-  test_d2b2d("12345", 10, 3,"12345.000", 0);
-  test_d2b2d("123.45", 10, 3,"123.450", 0);
-  test_d2b2d("-123.45", 20, 10,"-123.4500000000", 0);
-  test_d2b2d(".00012345000098765", 15, 14,"0.00012345000098", 0);
-  test_d2b2d(".00012345000098765", 22, 20,"0.00012345000098765000", 0);
-  test_d2b2d(".12345000098765", 30, 20,"0.12345000098765000000", 0);
-  test_d2b2d("-.000000012345000098765", 30, 20,"-0.00000001234500009876", 0);
-  test_d2b2d("1234500009876.5", 30, 5,"1234500009876.50000", 0);
-  test_d2b2d("111111111.11", 10, 2,"11111111.11", 0);
-  test_d2b2d("000000000.01", 7, 3,"0.010", 0);
-  test_d2b2d("123.4", 10, 2, "123.40", 0);
-
-
-  printf("==== decimal_cmp ====\n");
-  test_dc("12","13",-1);
-  test_dc("13","12",1);
-  test_dc("-10","10",-1);
-  test_dc("10","-10",1);
-  test_dc("-12","-13",1);
-  test_dc("0","12",-1);
-  test_dc("-10","0",-1);
-  test_dc("4","4",0);
-
-  printf("==== decimal_round ====\n");
-  test_ro("5678.123451",-4,TRUNCATE,"0", 0);
-  test_ro("5678.123451",-3,TRUNCATE,"5000", 0);
-  test_ro("5678.123451",-2,TRUNCATE,"5600", 0);
-  test_ro("5678.123451",-1,TRUNCATE,"5670", 0);
-  test_ro("5678.123451",0,TRUNCATE,"5678", 0);
-  test_ro("5678.123451",1,TRUNCATE,"5678.1", 0);
-  test_ro("5678.123451",2,TRUNCATE,"5678.12", 0);
-  test_ro("5678.123451",3,TRUNCATE,"5678.123", 0);
-  test_ro("5678.123451",4,TRUNCATE,"5678.1234", 0);
-  test_ro("5678.123451",5,TRUNCATE,"5678.12345", 0);
-  test_ro("5678.123451",6,TRUNCATE,"5678.123451", 0);
-  test_ro("-5678.123451",-4,TRUNCATE,"0", 0);
-  memset(buf2, 33, sizeof(buf2));
-  test_ro("99999999999999999999999999999999999999",-31,TRUNCATE,"99999990000000000000000000000000000000", 0);
-  test_ro("15.1",0,HALF_UP,"15", 0);
-  test_ro("15.5",0,HALF_UP,"16", 0);
-  test_ro("15.9",0,HALF_UP,"16", 0);
-  test_ro("-15.1",0,HALF_UP,"-15", 0);
-  test_ro("-15.5",0,HALF_UP,"-16", 0);
-  test_ro("-15.9",0,HALF_UP,"-16", 0);
-  test_ro("15.1",1,HALF_UP,"15.1", 0);
-  test_ro("-15.1",1,HALF_UP,"-15.1", 0);
-  test_ro("15.17",1,HALF_UP,"15.2", 0);
-  test_ro("15.4",-1,HALF_UP,"20", 0);
-  test_ro("-15.4",-1,HALF_UP,"-20", 0);
-  test_ro("5.4",-1,HALF_UP,"10", 0);
-  test_ro(".999", 0, HALF_UP, "1", 0);
-  memset(buf2, 33, sizeof(buf2));
-  test_ro("999999999", -9, HALF_UP, "1000000000", 0);
-  test_ro("15.1",0,HALF_EVEN,"15", 0);
-  test_ro("15.5",0,HALF_EVEN,"16", 0);
-  test_ro("14.5",0,HALF_EVEN,"14", 0);
-  test_ro("15.9",0,HALF_EVEN,"16", 0);
-  test_ro("15.1",0,CEILING,"16", 0);
-  test_ro("-15.1",0,CEILING,"-15", 0);
-  test_ro("15.1",0,FLOOR,"15", 0);
-  test_ro("-15.1",0,FLOOR,"-16", 0);
-  test_ro("999999999999999999999.999", 0, CEILING,"1000000000000000000000", 0);
-  test_ro("-999999999999999999999.999", 0, FLOOR,"-1000000000000000000000", 0);
-
-  b.buf[0]=DIG_BASE+1;
-  b.buf++;
-  test_ro(".3", 0, HALF_UP, "0", 0);
-  b.buf--;
-  if (b.buf[0] != DIG_BASE+1)
-  {
-    printf("%d - underflow\n", b.buf[0]);
-    exit(1);
-  }
-
-  printf("==== max_decimal ====\n");
-  test_mx(1,1,"0.9");
-  test_mx(1,0,"9");
-  test_mx(2,1,"9.9");
-  test_mx(4,2,"99.99");
-  test_mx(6,3,"999.999");
-  test_mx(8,4,"9999.9999");
-  test_mx(10,5,"99999.99999");
-  test_mx(12,6,"999999.999999");
-  test_mx(14,7,"9999999.9999999");
-  test_mx(16,8,"99999999.99999999");
-  test_mx(18,9,"999999999.999999999");
-  test_mx(20,10,"9999999999.9999999999");
-  test_mx(20,20,"0.99999999999999999999");
-  test_mx(20,0,"99999999999999999999");
-  test_mx(40,20,"99999999999999999999.99999999999999999999");
-
-  printf("==== decimal2string ====\n");
-  test_pr("123.123", 0, 0, 0, "123.123", 0);
-  test_pr("123.123", 7, 3, '0', "123.123", 0);
-  test_pr("123.123", 9, 3, '0', "00123.123", 0);
-  test_pr("123.123", 9, 4, '0', "0123.1230", 0);
-  test_pr("123.123", 9, 5, '0', "123.12300", 0);
-  test_pr("123.123", 9, 2, '0', "000123.12", 1);
-  test_pr("123.123", 9, 6, '0', "23.123000", 2);
-
-  printf("==== decimal_shift ====\n");
-  test_sh("123.123", 1, "1231.23", 0);
-  test_sh("123457189.123123456789000", 1, "1234571891.23123456789", 0);
-  test_sh("123457189.123123456789000", 4, "1234571891231.23456789", 0);
-  test_sh("123457189.123123456789000", 8, "12345718912312345.6789", 0);
-  test_sh("123457189.123123456789000", 9, "123457189123123456.789", 0);
-  test_sh("123457189.123123456789000", 10, "1234571891231234567.89", 0);
-  test_sh("123457189.123123456789000", 17, "12345718912312345678900000", 0);
-  test_sh("123457189.123123456789000", 18, "123457189123123456789000000", 0);
-  test_sh("123457189.123123456789000", 19, "1234571891231234567890000000", 0);
-  test_sh("123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
-  test_sh("123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
-  test_sh("123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
-  test_sh("000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
-  test_sh("00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
-  test_sh("00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
-  test_sh("123", 1, "1230", 0);
-  test_sh("123", 10, "1230000000000", 0);
-  test_sh(".123", 1, "1.23", 0);
-  test_sh(".123", 10, "1230000000", 0);
-  test_sh(".123", 14, "12300000000000", 0);
-  test_sh("000.000", 1000, "0", 0);
-  test_sh("000.", 1000, "0", 0);
-  test_sh(".000", 1000, "0", 0);
-  test_sh("1", 1000, "1", 2);
-  test_sh("123.123", -1, "12.3123", 0);
-  test_sh("123987654321.123456789000", -1, "12398765432.1123456789", 0);
-  test_sh("123987654321.123456789000", -2, "1239876543.21123456789", 0);
-  test_sh("123987654321.123456789000", -3, "123987654.321123456789", 0);
-  test_sh("123987654321.123456789000", -8, "1239.87654321123456789", 0);
-  test_sh("123987654321.123456789000", -9, "123.987654321123456789", 0);
-  test_sh("123987654321.123456789000", -10, "12.3987654321123456789", 0);
-  test_sh("123987654321.123456789000", -11, "1.23987654321123456789", 0);
-  test_sh("123987654321.123456789000", -12, "0.123987654321123456789", 0);
-  test_sh("123987654321.123456789000", -13, "0.0123987654321123456789", 0);
-  test_sh("123987654321.123456789000", -14, "0.00123987654321123456789", 0);
-  test_sh("00000087654321.123456789000", -14, "0.00000087654321123456789", 0);
-  a.len= 2;
-  test_sh("123.123", -2, "1.23123", 0);
-  test_sh("123.123", -3, "0.123123", 0);
-  test_sh("123.123", -6, "0.000123123", 0);
-  test_sh("123.123", -7, "0.0000123123", 0);
-  test_sh("123.123", -15, "0.000000000000123123", 0);
-  test_sh("123.123", -16, "0.000000000000012312", 1);
-  test_sh("123.123", -17, "0.000000000000001231", 1);
-  test_sh("123.123", -18, "0.000000000000000123", 1);
-  test_sh("123.123", -19, "0.000000000000000012", 1);
-  test_sh("123.123", -20, "0.000000000000000001", 1);
-  test_sh("123.123", -21, "0", 1);
-  test_sh(".000000000123", -1, "0.0000000000123", 0);
-  test_sh(".000000000123", -6, "0.000000000000000123", 0);
-  test_sh(".000000000123", -7, "0.000000000000000012", 1);
-  test_sh(".000000000123", -8, "0.000000000000000001", 1);
-  test_sh(".000000000123", -9, "0", 1);
-  test_sh(".000000000123", 1, "0.00000000123", 0);
-  test_sh(".000000000123", 8, "0.0123", 0);
-  test_sh(".000000000123", 9, "0.123", 0);
-  test_sh(".000000000123", 10, "1.23", 0);
-  test_sh(".000000000123", 17, "12300000", 0);
-  test_sh(".000000000123", 18, "123000000", 0);
-  test_sh(".000000000123", 19, "1230000000", 0);
-  test_sh(".000000000123", 20, "12300000000", 0);
-  test_sh(".000000000123", 21, "123000000000", 0);
-  test_sh(".000000000123", 22, "1230000000000", 0);
-  test_sh(".000000000123", 23, "12300000000000", 0);
-  test_sh(".000000000123", 24, "123000000000000", 0);
-  test_sh(".000000000123", 25, "1230000000000000", 0);
-  test_sh(".000000000123", 26, "12300000000000000", 0);
-  test_sh(".000000000123", 27, "123000000000000000", 0);
-  test_sh(".000000000123", 28, "0.000000000123", 2);
-  test_sh("123456789.987654321", -1, "12345678.998765432", 1);
-  test_sh("123456789.987654321", -2, "1234567.899876543", 1);
-  test_sh("123456789.987654321", -8, "1.234567900", 1);
-  test_sh("123456789.987654321", -9, "0.123456789987654321", 0);
-  test_sh("123456789.987654321", -10, "0.012345678998765432", 1);
-  test_sh("123456789.987654321", -17, "0.000000001234567900", 1);
-  test_sh("123456789.987654321", -18, "0.000000000123456790", 1);
-  test_sh("123456789.987654321", -19, "0.000000000012345679", 1);
-  test_sh("123456789.987654321", -26, "0.000000000000000001", 1);
-  test_sh("123456789.987654321", -27, "0", 1);
-  test_sh("123456789.987654321", 1, "1234567900", 1);
-  test_sh("123456789.987654321", 2, "12345678999", 1);
-  test_sh("123456789.987654321", 4, "1234567899877", 1);
-  test_sh("123456789.987654321", 8, "12345678998765432", 1);
-  test_sh("123456789.987654321", 9, "123456789987654321", 0);
-  test_sh("123456789.987654321", 10, "123456789.987654321", 2);
-  test_sh("123456789.987654321", 0, "123456789.987654321", 0);
-  a.len= sizeof(buf1)/sizeof(dec1);
-
-  printf("==== decimal_actual_fraction ====\n");
-  test_fr("1.123456789000000000", "1.123456789");
-  test_fr("1.12345678000000000", "1.12345678");
-  test_fr("1.1234567000000000", "1.1234567");
-  test_fr("1.123456000000000", "1.123456");
-  test_fr("1.12345000000000", "1.12345");
-  test_fr("1.1234000000000", "1.1234");
-  test_fr("1.123000000000", "1.123");
-  test_fr("1.12000000000", "1.12");
-  test_fr("1.1000000000", "1.1");
-  test_fr("1.000000000", "1");
-  test_fr("1.0", "1");
-  test_fr("10000000000000000000.0", "10000000000000000000");
-
-  return 0;
-}
+/*
+  The main() program has been converted into a unit test.
+ */
 #endif

=== modified file 'unittest/gunit/CMakeLists.txt'
--- a/unittest/gunit/CMakeLists.txt	2011-08-12 07:18:41 +0000
+++ b/unittest/gunit/CMakeLists.txt	2011-08-26 07:06:35 +0000
@@ -207,6 +207,7 @@ SET(TESTS
   bounded_queue
   bounds_checked_array
   dbug
+  decimal
   dynarray
   mdl
   mdl_mytap

=== added file 'unittest/gunit/decimal-t.cc'
--- a/unittest/gunit/decimal-t.cc	1970-01-01 00:00:00 +0000
+++ b/unittest/gunit/decimal-t.cc	2011-08-26 07:06:35 +0000
@@ -0,0 +1,866 @@
+/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   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; version 2 of the License.
+
+   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., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA */
+
+/*
+  NOTE: This is a more-or-less direct port of the main() program
+  in strings/decimal.c to a Google Test.
+ */
+
+#include "my_config.h"
+#include <gtest/gtest.h>
+
+#include <my_global.h>
+#include <m_string.h>
+
+extern "C" {
+#include <decimal.h>
+int decimal_shift(decimal_t *dec, int shift);
+}
+
+
+namespace {
+
+#define DIG_PER_DEC1 9
+#define DIG_BASE     1000000000
+#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
+typedef decimal_digit_t dec1;
+
+int full= 0;
+decimal_t a, b, c;
+decimal_digit_t buf1[25], buf2[25], buf3[25];
+
+void dump_decimal(decimal_t *d)
+{
+  int i;
+  printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
+  for (i=0; i < ROUND_UP(d->frac)+ROUND_UP(d->intg)-1; i++)
+    printf("%09d, ", d->buf[i]);
+  printf("%09d} */ ", d->buf[i]);
+}
+
+/*
+  The purpose of all these define wrappers is to get a "call stack"
+  whenever some EXPECT_XX generates a failure. A sample error message:
+
+  # .../unittest/gunit/decimal-t.cc:134: FailureValue of: s
+  #   Actual: "0"
+  # Expected: orig
+  # Which is: "1000000000"
+  #  arguments were: '999999999', -9, HALF_UP
+  # Google Test trace:
+  # .../unittest/gunit/decimal-t.cc:387: 
+  # .../unittest/gunit/decimal-t.cc:686: 
+ */
+
+#define check_result_code(p1, p2) \
+  { SCOPED_TRACE(""); do_check_result_code(p1, p2); }
+
+#define print_decimal(p1, p2, p3, p4, p5) \
+  { SCOPED_TRACE(""); do_print_decimal(p1, p2, p3, p4, p5); }
+
+#define test_s2d(p1, p2, p3) \
+  { SCOPED_TRACE(""); do_test_s2d(p1, p2, p3); }
+
+#define test_d2f(p1, p2) \
+  { SCOPED_TRACE(""); do_test_d2f(p1, p2); }
+
+#define test_d2b2d(p1, p2, p3, p4, p5) \
+  { SCOPED_TRACE(""); do_test_d2b2d(p1, p2, p3, p4, p5); }
+
+#define test_f2d(p1, p2) \
+  { SCOPED_TRACE(""); do_test_f2d(p1, p2); }
+
+#define test_ull2d(p1, p2, p3) \
+  { SCOPED_TRACE(""); do_test_ull2d(p1, p2, p3); }
+
+#define test_ll2d(p1, p2, p3) \
+  { SCOPED_TRACE(""); do_test_ll2d(p1, p2, p3); }
+
+#define test_d2ull(p1, p2, p3) \
+  { SCOPED_TRACE(""); do_test_d2ull(p1, p2, p3); }
+
+#define test_d2ll(p1, p2, p3) \
+  { SCOPED_TRACE(""); do_test_d2ll(p1, p2, p3); }
+
+#define test_da(p1, p2, p3, p4) \
+  { SCOPED_TRACE(""); do_test_da(p1, p2, p3, p4); }
+
+#define test_ds(p1, p2, p3, p4) \
+  { SCOPED_TRACE(""); do_test_ds(p1, p2, p3, p4); }
+
+#define test_dc(p1, p2, p3) \
+  { SCOPED_TRACE(""); do_test_dc(p1, p2, p3); }
+
+#define test_dm(p1, p2, p3, p4) \
+  { SCOPED_TRACE(""); do_test_dm(p1, p2, p3, p4); }
+
+#define test_dv(p1, p2, p3, p4) \
+  { SCOPED_TRACE(""); do_test_dv(p1, p2, p3, p4); }
+
+#define test_md(p1, p2, p3, p4) \
+  { SCOPED_TRACE(""); do_test_md(p1, p2, p3, p4); }
+
+#define test_ro(p1, p2, p3, p4, p5) \
+  { SCOPED_TRACE(""); do_test_ro(p1, p2, p3, p4, p5); }
+
+#define test_mx(p1, p2, p3) \
+  { SCOPED_TRACE(""); do_test_mx(p1, p2, p3); }
+
+#define test_pr(p1, p2, p3, p4, p5, p6) \
+  { SCOPED_TRACE(""); do_test_pr(p1, p2, p3, p4, p5, p6); }
+
+#define test_sh(p1, p2, p3, p4) \
+  { SCOPED_TRACE(""); do_test_sh(p1, p2, p3, p4); }
+
+#define test_fr(p1, p2) \
+  { SCOPED_TRACE(""); do_test_fr(p1, p2); }
+
+
+void do_check_result_code(int actual, int want)
+{
+  EXPECT_EQ(want, actual);
+}
+
+void do_print_decimal(decimal_t *d, const char *orig, int actual, int want,
+                      const char *msg)
+{
+  char s[100];
+  int slen=sizeof(s);
+
+  if (full) dump_decimal(d);
+  decimal2string(d, s, &slen, 0, 0, 0);
+  check_result_code(actual, want);
+  if (orig)
+  {
+    EXPECT_STREQ(orig, s) << " arguments were: " << msg;
+  }
+}
+
+void test_d2s()
+{
+  char s[100];
+  int slen, res;
+
+  /***********************************/
+  printf("==== decimal2string ====\n");
+  a.buf[0]=12345; a.intg=5; a.frac=0; a.sign=0;
+  slen=sizeof(s);
+  res=decimal2string(&a, s, &slen, 0, 0, 0);
+  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
+
+  a.buf[1]=987000000; a.frac=3;
+  slen=sizeof(s);
+  res=decimal2string(&a, s, &slen, 0, 0, 0);
+  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
+
+  a.sign=1;
+  slen=sizeof(s);
+  res=decimal2string(&a, s, &slen, 0, 0, 0);
+  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
+
+  slen=8;
+  res=decimal2string(&a, s, &slen, 0, 0, 0);
+  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
+
+  slen=5;
+  res=decimal2string(&a, s, &slen, 0, 0, 0);
+  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
+
+  a.buf[0]=987000000; a.frac=3; a.intg=0;
+  slen=sizeof(s);
+  res=decimal2string(&a, s, &slen, 0, 0, 0);
+  dump_decimal(&a); printf("  -->  res=%d str='%s' len=%d\n", res, s, slen);
+}
+
+void do_test_s2d(const char *s, const char *orig, int ex)
+{
+  char s1[100], *end;
+  int res;
+  sprintf(s1, "'%s'", s);
+  end= strend(s);
+  res= string2decimal(s, &a, &end);
+  print_decimal(&a, orig, res, ex, s1);
+}
+
+void do_test_d2f(const char *s, int ex)
+{
+  char s1[100], *end;
+  double x;
+  int res;
+
+  sprintf(s1, "'%s'", s);
+  end= strend(s);
+  string2decimal(s, &a, &end);
+  res=decimal2double(&a, &x);
+  if (full) dump_decimal(&a);
+  check_result_code(res, ex);
+}
+
+void do_test_d2b2d(const char *str, int p, int s, const char *orig, int ex)
+{
+  char s1[100];
+  char s2[100];
+  uchar buf[100];
+  char *end;
+  int res, i, size=decimal_bin_size(p, s);
+
+  sprintf(s1, "'%s'", str);
+  end= strend(str);
+  string2decimal(str, &a, &end);
+  res=decimal2bin(&a, buf, p, s);
+  sprintf(s2, "%-31s {%2d, %2d} => res=%d size=%-2d ", s1, p, s, res, size);
+  if (full)
+  {
+    printf("0x");
+    for (i=0; i < size; i++)
+      printf("%02x", ((uchar *)buf)[i]);
+  }
+  res=bin2decimal(buf, &a, p, s);
+  print_decimal(&a, orig, res, ex, s2);
+}
+
+void do_test_f2d(double from, int ex)
+{
+  int res;
+  char s1[100];
+
+  res=double2decimal(from, &a);
+  sprintf(s1, "%-40.*f => res=%d    ", DBL_DIG-2, from, res);
+  print_decimal(&a, 0, res, ex, s1);
+}
+
+void do_test_ull2d(ulonglong from, const char *orig, int ex)
+{
+  char s[100];
+  char s1[100];
+  int res;
+
+  res=ulonglong2decimal(from, &a);
+  longlong10_to_str(from,s,10);
+  sprintf(s1, "%-40s => res=%d    ", s, res);
+  print_decimal(&a, orig, res, ex, s1);
+}
+
+void do_test_ll2d(longlong from, const char *orig, int ex)
+{
+  char s[100];
+  char s1[100];
+  int res;
+
+  res=longlong2decimal(from, &a);
+  longlong10_to_str(from,s,-10);
+  sprintf(s1, "%-40s => res=%d    ", s, res);
+  print_decimal(&a, orig, res, ex, s1);
+}
+
+void do_test_d2ull(const char *s, const char *orig, int ex)
+{
+  char s1[100], *end;
+  char s2[100];
+  ulonglong x;
+  int res;
+
+  end= strend(s);
+  string2decimal(s, &a, &end);
+  res=decimal2ulonglong(&a, &x);
+  if (full) dump_decimal(&a);
+  longlong10_to_str(x,s1,10);
+  sprintf(s2, "%-40s => res=%d    %s\n", s, res, s1);
+  check_result_code(res, ex);
+  if (orig)
+  {
+    EXPECT_STREQ(orig, s1) << " arguments were: " << s2;
+  }
+}
+
+void do_test_d2ll(const char *s, const char *orig, int ex)
+{
+  char s1[100], *end;
+  char s2[100];
+  longlong x;
+  int res;
+
+  end= strend(s);
+  string2decimal(s, &a, &end);
+  res=decimal2longlong(&a, &x);
+  if (full) dump_decimal(&a);
+  longlong10_to_str(x,s1,-10);
+  sprintf(s2, "%-40s => res=%d    %s\n", s, res, s1);
+  check_result_code(res, ex);
+  if (orig)
+  {
+    EXPECT_STREQ(orig, s1) << " arguments were: " << s2;
+  }
+}
+
+void do_test_da(const char *s1, const char *s2, const char *orig, int ex)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s' + '%s'", s1, s2);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  end= strend(s2);
+  string2decimal(s2, &b, &end);
+  res=decimal_add(&a, &b, &c);
+  print_decimal(&c, orig, res, ex, s);
+}
+
+void do_test_ds(const char *s1, const char *s2, const char *orig, int ex)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s' - '%s'", s1, s2);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  end= strend(s2);
+  string2decimal(s2, &b, &end);
+  res=decimal_sub(&a, &b, &c);
+  print_decimal(&c, orig, res, ex, s);
+}
+
+void do_test_dc(const char *s1, const char *s2, int orig)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s' <=> '%s'", s1, s2);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  end= strend(s2);
+  string2decimal(s2, &b, &end);
+  res=decimal_cmp(&a, &b);
+  EXPECT_EQ(orig, res) << " arguments were: " << s;
+}
+
+void do_test_dm(const char *s1, const char *s2, const char *orig, int ex)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s' * '%s'", s1, s2);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  end= strend(s2);
+  string2decimal(s2, &b, &end);
+  res=decimal_mul(&a, &b, &c);
+  print_decimal(&c, orig, res, ex, s);
+}
+
+void do_test_dv(const char *s1, const char *s2, const char *orig, int ex)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s' / '%s'", s1, s2);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  end= strend(s2);
+  string2decimal(s2, &b, &end);
+  res=decimal_div(&a, &b, &c, 5);
+  check_result_code(res, ex);
+  if (res != E_DEC_DIV_ZERO)
+    print_decimal(&c, orig, res, ex, s);
+}
+
+void do_test_md(const char *s1, const char *s2, const char *orig, int ex)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s' %% '%s'", s1, s2);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  end= strend(s2);
+  string2decimal(s2, &b, &end);
+  res=decimal_mod(&a, &b, &c);
+  check_result_code(res, ex);
+  if (res != E_DEC_DIV_ZERO)
+    print_decimal(&c, orig, res, ex, s);
+}
+
+const char *round_mode[]=
+{"TRUNCATE", "HALF_EVEN", "HALF_UP", "CEILING", "FLOOR"};
+
+void do_test_ro(const char *s1, int n, decimal_round_mode mode,
+                const char *orig, int ex)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s', %d, %s", s1, n, round_mode[mode]);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  res=decimal_round(&a, &b, n, mode);
+  print_decimal(&b, orig, res, ex, s);
+}
+
+
+void do_test_mx(int precision, int frac, const char *orig)
+{
+  char s[100];
+  sprintf(s, "%d, %d", precision, frac);
+  max_decimal(precision, frac, &a);
+  print_decimal(&a, orig, 0, 0, s);
+}
+
+
+void do_test_pr(const char *s1, int prec, int dec, char filler,
+                const char *orig, int ex)
+{
+  char s[100], *end;
+  char s2[100];
+  int slen= sizeof(s2);
+  int res;
+
+  sprintf(s, filler ? "'%s', %d, %d, '%c'" : "'%s', %d, %d, '\\0'",
+          s1, prec, dec, filler);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  res= decimal2string(&a, s2, &slen, prec, dec, filler);
+  check_result_code(res, ex);
+  if (orig)
+  {
+    EXPECT_STREQ(orig, s2) << " arguments were: " << s;
+  }
+}
+
+
+void do_test_sh(const char *s1, int shift, const char *orig, int ex)
+{
+  char s[100], *end;
+  int res;
+  sprintf(s, "'%s' %s %d", s1, ((shift < 0) ? ">>" : "<<"), abs(shift));
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  res= decimal_shift(&a, shift);
+  print_decimal(&a, orig, res, ex, s);
+}
+
+
+void do_test_fr(const char *s1, const char *orig)
+{
+  char s[100], *end;
+  sprintf(s, "'%s'", s1);
+  end= strend(s1);
+  string2decimal(s1, &a, &end);
+  a.frac= decimal_actual_fraction(&a);
+  print_decimal(&a, orig, 0, 0, s);
+}
+
+
+class DecimalTest : public ::testing::Test
+{
+protected:
+  virtual void SetUp()
+  {
+    a.buf= buf1;
+    a.len= sizeof(buf1)/sizeof(dec1);
+    b.buf= buf2;
+    b.len= sizeof(buf2)/sizeof(dec1);
+    c.buf= buf3;
+    c.len= sizeof(buf3)/sizeof(dec1);
+  }
+};
+
+
+TEST_F(DecimalTest, String2Decimal)
+{
+  test_s2d("12345", "12345", 0);
+  test_s2d("12345.", "12345", 0);
+  test_s2d("123.45", "123.45", 0);
+  test_s2d("-123.45", "-123.45", 0);
+  test_s2d(".00012345000098765", "0.00012345000098765", 0);
+  test_s2d(".12345000098765", "0.12345000098765", 0);
+  test_s2d("-.000000012345000098765", "-0.000000012345000098765", 0);
+  test_s2d("1234500009876.5", "1234500009876.5", 0);
+  a.len=1;
+  test_s2d("123450000098765", "98765", 2);
+  test_s2d("123450.000098765", "123450", 1);
+  a.len=sizeof(buf1)/sizeof(dec1);
+  test_s2d("123E5", "12300000", 0);
+  test_s2d("123E-2", "1.23", 0);
+}
+
+
+TEST_F(DecimalTest, Decimal2Double)
+{
+  test_d2f("12345", 0);
+  test_d2f("123.45", 0);
+  test_d2f("-123.45", 0);
+  test_d2f("0.00012345000098765", 0);
+  test_d2f("1234500009876.5", 0);
+}
+
+
+TEST_F(DecimalTest, Double2Decimal)
+{
+  test_f2d(12345, 0);
+  test_f2d(1.0/3, 0);
+  test_f2d(-123.45, 0);
+  test_f2d(0.00012345000098765, 0);
+  test_f2d(1234500009876.5, 0);
+}
+
+
+TEST_F(DecimalTest, Ulonglong2Decimal)
+{
+  test_ull2d(ULL(12345), "12345", 0);
+  test_ull2d(ULL(0), "0", 0);
+  test_ull2d(ULL(18446744073709551615), "18446744073709551615", 0);
+}
+
+
+TEST_F(DecimalTest, Decimal2Ulonglong)
+{
+  test_d2ull("12345", "12345", 0);
+  test_d2ull("0", "0", 0);
+  /* ULLONG_MAX = 18446744073709551615ULL */
+  test_d2ull("18446744073709551615", "18446744073709551615", 0);
+  test_d2ull("18446744073709551616", "18446744073709551615", 2);
+  test_d2ull("-1", "0", 2);
+  test_d2ull("1.23", "1", 1);
+  test_d2ull("9999999999999999999999999.000", "18446744073709551615", 2);
+}
+
+
+TEST_F(DecimalTest, Longlong2Decimal)
+{
+  test_ll2d(LL(-12345), "-12345", 0);
+  test_ll2d(LL(-1), "-1", 0);
+  test_ll2d(LL(-9223372036854775807), "-9223372036854775807", 0);
+  test_ll2d(ULL(9223372036854775808), "-9223372036854775808", 0);
+}
+
+
+TEST_F(DecimalTest, Decimal2Longlong)
+{
+  /* LLONG_MAX = 9223372036854775807LL */
+  test_d2ll("18446744073709551615", "9223372036854775807", 2);
+  test_d2ll("-1", "-1", 0);
+  test_d2ll("-1.23", "-1", 1);
+  test_d2ll("-9223372036854775807", "-9223372036854775807", 0);
+  test_d2ll("-9223372036854775808", "-9223372036854775808", 0);
+  test_d2ll("9223372036854775808", "9223372036854775807", 2);
+}
+
+
+TEST_F(DecimalTest, DoAdd)
+{
+  test_da(".00012345000098765" ,"123.45", "123.45012345000098765", 0);
+  test_da(".1" ,".45", "0.55", 0);
+  test_da("1234500009876.5" ,".00012345000098765", "1234500009876.50012345000098765", 0);
+  test_da("9999909999999.5" ,".555", "9999910000000.055", 0);
+  test_da("99999999" ,"1", "100000000", 0);
+  test_da("989999999" ,"1", "990000000", 0);
+  test_da("999999999" ,"1", "1000000000", 0);
+  test_da("12345" ,"123.45", "12468.45", 0);
+  test_da("-12345" ,"-123.45", "-12468.45", 0);
+  test_ds("-12345" ,"123.45", "-12468.45", 0);
+  test_ds("12345" ,"-123.45", "12468.45", 0);
+}
+
+
+TEST_F(DecimalTest, DoSub)
+{
+  test_ds(".00012345000098765", "123.45","-123.44987654999901235", 0);
+  test_ds("1234500009876.5", ".00012345000098765","1234500009876.49987654999901235", 0);
+  test_ds("9999900000000.5", ".555","9999899999999.945", 0);
+  test_ds("1111.5551", "1111.555","0.0001", 0);
+  test_ds(".555", ".555","0", 0);
+  test_ds("10000000", "1","9999999", 0);
+  test_ds("1000001000", ".1","1000000999.9", 0);
+  test_ds("1000000000", ".1","999999999.9", 0);
+  test_ds("12345", "123.45","12221.55", 0);
+  test_ds("-12345", "-123.45","-12221.55", 0);
+  test_da("-12345", "123.45","-12221.55", 0);
+  test_da("12345", "-123.45","12221.55", 0);
+  test_ds("123.45", "12345","-12221.55", 0);
+  test_ds("-123.45", "-12345","12221.55", 0);
+  test_da("123.45", "-12345","-12221.55", 0);
+  test_da("-123.45", "12345","12221.55", 0);
+  test_da("5", "-6.0","-1.0", 0);
+}
+
+
+TEST_F(DecimalTest, DecimalMul)
+{
+  test_dm("12", "10","120", 0);
+  test_dm("-123.456", "98765.4321","-12193185.1853376", 0);
+  test_dm("-123456000000", "98765432100000","-12193185185337600000000000", 0);
+  test_dm("123456", "987654321","121931851853376", 0);
+  test_dm("123456", "9876543210","1219318518533760", 0);
+  test_dm("123", "0.01","1.23", 0);
+  test_dm("123", "0","0", 0);
+}
+
+
+TEST_F(DecimalTest, DecimalDiv)
+{
+  test_dv("120", "10","12.000000000", 0);
+  test_dv("123", "0.01","12300.000000000", 0);
+  test_dv("120", "100000000000.00000","0.000000001200000000", 0);
+  test_dv("123", "0","", 4);
+  test_dv("0", "0", "", 4);
+  test_dv("-12193185.1853376", "98765.4321","-123.456000000000000000", 0);
+  test_dv("121931851853376", "987654321","123456.000000000", 0);
+  test_dv("0", "987","0", 0);
+  test_dv("1", "3","0.333333333", 0);
+  test_dv("1.000000000000", "3","0.333333333333333333", 0);
+  test_dv("1", "1","1.000000000", 0);
+  test_dv("0.0123456789012345678912345", "9999999999","0.000000000001234567890246913578148141", 0);
+  test_dv("10.333000000", "12.34500","0.837019036046982584042122316", 0);
+  test_dv("10.000000000060", "2","5.000000000030000000", 0);
+}
+
+
+TEST_F(DecimalTest, DecimalMod)
+{
+  test_md("234","10","4", 0);
+  test_md("234.567","10.555","2.357", 0);
+  test_md("-234.567","10.555","-2.357", 0);
+  test_md("234.567","-10.555","2.357", 0);
+  c.buf[1]=0x3ABECA;
+  test_md("99999999999999999999999999999999999999","3","0", 0);
+  if (c.buf[1] != 0x3ABECA)
+  {
+    ADD_FAILURE() << "overflow " << c.buf[1];
+  }
+}
+
+
+TEST_F(DecimalTest, Decimal2BinBin2Decimal)
+{
+  test_d2b2d("-10.55", 4, 2,"-10.55", 0);
+  test_d2b2d("0.0123456789012345678912345", 30, 25,"0.0123456789012345678912345", 0);
+  test_d2b2d("12345", 5, 0,"12345", 0);
+  test_d2b2d("12345", 10, 3,"12345.000", 0);
+  test_d2b2d("123.45", 10, 3,"123.450", 0);
+  test_d2b2d("-123.45", 20, 10,"-123.4500000000", 0);
+  test_d2b2d(".00012345000098765", 15, 14,"0.00012345000098", 0);
+  test_d2b2d(".00012345000098765", 22, 20,"0.00012345000098765000", 0);
+  test_d2b2d(".12345000098765", 30, 20,"0.12345000098765000000", 0);
+  test_d2b2d("-.000000012345000098765", 30, 20,"-0.00000001234500009876", 0);
+  test_d2b2d("1234500009876.5", 30, 5,"1234500009876.50000", 0);
+  test_d2b2d("111111111.11", 10, 2,"11111111.11", 0);
+  test_d2b2d("000000000.01", 7, 3,"0.010", 0);
+  test_d2b2d("123.4", 10, 2, "123.40", 0);
+}
+
+
+TEST_F(DecimalTest, DecimalCmp)
+{
+  test_dc("12","13",-1);
+  test_dc("13","12",1);
+  test_dc("-10","10",-1);
+  test_dc("10","-10",1);
+  test_dc("-12","-13",1);
+  test_dc("0","12",-1);
+  test_dc("-10","0",-1);
+  test_dc("4","4",0);
+}
+
+
+TEST_F(DecimalTest, DecimalRound)
+{
+  test_ro("5678.123451",-4,TRUNCATE,"0", 0);
+  test_ro("5678.123451",-3,TRUNCATE,"5000", 0);
+  test_ro("5678.123451",-2,TRUNCATE,"5600", 0);
+  test_ro("5678.123451",-1,TRUNCATE,"5670", 0);
+  test_ro("5678.123451",0,TRUNCATE,"5678", 0);
+  test_ro("5678.123451",1,TRUNCATE,"5678.1", 0);
+  test_ro("5678.123451",2,TRUNCATE,"5678.12", 0);
+  test_ro("5678.123451",3,TRUNCATE,"5678.123", 0);
+  test_ro("5678.123451",4,TRUNCATE,"5678.1234", 0);
+  test_ro("5678.123451",5,TRUNCATE,"5678.12345", 0);
+  test_ro("5678.123451",6,TRUNCATE,"5678.123451", 0);
+  test_ro("-5678.123451",-4,TRUNCATE,"0", 0);
+  memset(buf2, 33, sizeof(buf2));
+  test_ro("99999999999999999999999999999999999999",-31,TRUNCATE,"99999990000000000000000000000000000000", 0);
+  test_ro("15.1",0,HALF_UP,"15", 0);
+  test_ro("15.5",0,HALF_UP,"16", 0);
+  test_ro("15.9",0,HALF_UP,"16", 0);
+  test_ro("-15.1",0,HALF_UP,"-15", 0);
+  test_ro("-15.5",0,HALF_UP,"-16", 0);
+  test_ro("-15.9",0,HALF_UP,"-16", 0);
+  test_ro("15.1",1,HALF_UP,"15.1", 0);
+  test_ro("-15.1",1,HALF_UP,"-15.1", 0);
+  test_ro("15.17",1,HALF_UP,"15.2", 0);
+  test_ro("15.4",-1,HALF_UP,"20", 0);
+  test_ro("-15.4",-1,HALF_UP,"-20", 0);
+  test_ro("5.4",-1,HALF_UP,"10", 0);
+  test_ro(".999", 0, HALF_UP, "1", 0);
+  memset(buf2, 33, sizeof(buf2));
+  test_ro("999999999", -9, HALF_UP, "1000000000", 0);
+  test_ro("15.1",0,HALF_EVEN,"15", 0);
+  test_ro("15.5",0,HALF_EVEN,"16", 0);
+  test_ro("14.5",0,HALF_EVEN,"14", 0);
+  test_ro("15.9",0,HALF_EVEN,"16", 0);
+  test_ro("15.1",0,CEILING,"16", 0);
+  test_ro("-15.1",0,CEILING,"-15", 0);
+  test_ro("15.1",0,FLOOR,"15", 0);
+  test_ro("-15.1",0,FLOOR,"-16", 0);
+  test_ro("999999999999999999999.999", 0, CEILING,"1000000000000000000000", 0);
+  test_ro("-999999999999999999999.999", 0, FLOOR,"-1000000000000000000000", 0);
+
+  b.buf[0]=DIG_BASE+1;
+  b.buf++;
+  test_ro(".3", 0, HALF_UP, "0", 0);
+  b.buf--;
+  if (b.buf[0] != DIG_BASE+1)
+  {
+    ADD_FAILURE() << "underflow " << b.buf[0];
+  }
+}
+
+
+TEST_F(DecimalTest, MaxDecimal)
+{
+  test_mx(1,1,"0.9");
+  test_mx(1,0,"9");
+  test_mx(2,1,"9.9");
+  test_mx(4,2,"99.99");
+  test_mx(6,3,"999.999");
+  test_mx(8,4,"9999.9999");
+  test_mx(10,5,"99999.99999");
+  test_mx(12,6,"999999.999999");
+  test_mx(14,7,"9999999.9999999");
+  test_mx(16,8,"99999999.99999999");
+  test_mx(18,9,"999999999.999999999");
+  test_mx(20,10,"9999999999.9999999999");
+  test_mx(20,20,"0.99999999999999999999");
+  test_mx(20,0,"99999999999999999999");
+  test_mx(40,20,"99999999999999999999.99999999999999999999");
+}
+
+
+TEST_F(DecimalTest, Decimal2String)
+{
+  test_pr("123.123", 0, 0, 0, "123.123", 0);
+  /* For fixed precision, we no longer count the '.' here. */
+  test_pr("123.123", 6, 3, '0', "123.123", 0);
+  test_pr("123.123", 8, 3, '0', "00123.123", 0);
+  test_pr("123.123", 8, 4, '0', "0123.1230", 0);
+  test_pr("123.123", 8, 5, '0', "123.12300", 0);
+  test_pr("123.123", 8, 2, '0', "000123.12", 1);
+  test_pr("123.123", 8, 6, '0', "23.123000", 2);
+}
+
+
+TEST_F(DecimalTest, DecimalShift)
+{
+  test_sh("123.123", 1, "1231.23", 0);
+  test_sh("123457189.123123456789000", 1, "1234571891.23123456789", 0);
+  test_sh("123457189.123123456789000", 4, "1234571891231.23456789", 0);
+  test_sh("123457189.123123456789000", 8, "12345718912312345.6789", 0);
+  test_sh("123457189.123123456789000", 9, "123457189123123456.789", 0);
+  test_sh("123457189.123123456789000", 10, "1234571891231234567.89", 0);
+  test_sh("123457189.123123456789000", 17, "12345718912312345678900000", 0);
+  test_sh("123457189.123123456789000", 18, "123457189123123456789000000", 0);
+  test_sh("123457189.123123456789000", 19, "1234571891231234567890000000", 0);
+  test_sh("123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
+  test_sh("123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
+  test_sh("123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
+  test_sh("000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", 0);
+  test_sh("00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", 0);
+  test_sh("00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", 0);
+  test_sh("123", 1, "1230", 0);
+  test_sh("123", 10, "1230000000000", 0);
+  test_sh(".123", 1, "1.23", 0);
+  test_sh(".123", 10, "1230000000", 0);
+  test_sh(".123", 14, "12300000000000", 0);
+  test_sh("000.000", 1000, "0", 0);
+  test_sh("000.", 1000, "0", 0);
+  test_sh(".000", 1000, "0", 0);
+  test_sh("1", 1000, "1", 2);
+  test_sh("123.123", -1, "12.3123", 0);
+  test_sh("123987654321.123456789000", -1, "12398765432.1123456789", 0);
+  test_sh("123987654321.123456789000", -2, "1239876543.21123456789", 0);
+  test_sh("123987654321.123456789000", -3, "123987654.321123456789", 0);
+  test_sh("123987654321.123456789000", -8, "1239.87654321123456789", 0);
+  test_sh("123987654321.123456789000", -9, "123.987654321123456789", 0);
+  test_sh("123987654321.123456789000", -10, "12.3987654321123456789", 0);
+  test_sh("123987654321.123456789000", -11, "1.23987654321123456789", 0);
+  test_sh("123987654321.123456789000", -12, "0.123987654321123456789", 0);
+  test_sh("123987654321.123456789000", -13, "0.0123987654321123456789", 0);
+  test_sh("123987654321.123456789000", -14, "0.00123987654321123456789", 0);
+  test_sh("00000087654321.123456789000", -14, "0.00000087654321123456789", 0);
+  a.len= 2;
+  test_sh("123.123", -2, "1.23123", 0);
+  test_sh("123.123", -3, "0.123123", 0);
+  test_sh("123.123", -6, "0.000123123", 0);
+  test_sh("123.123", -7, "0.0000123123", 0);
+  test_sh("123.123", -15, "0.000000000000123123", 0);
+  test_sh("123.123", -16, "0.000000000000012312", 1);
+  test_sh("123.123", -17, "0.000000000000001231", 1);
+  test_sh("123.123", -18, "0.000000000000000123", 1);
+  test_sh("123.123", -19, "0.000000000000000012", 1);
+  test_sh("123.123", -20, "0.000000000000000001", 1);
+  test_sh("123.123", -21, "0", 1);
+  test_sh(".000000000123", -1, "0.0000000000123", 0);
+  test_sh(".000000000123", -6, "0.000000000000000123", 0);
+  test_sh(".000000000123", -7, "0.000000000000000012", 1);
+  test_sh(".000000000123", -8, "0.000000000000000001", 1);
+  test_sh(".000000000123", -9, "0", 1);
+  test_sh(".000000000123", 1, "0.00000000123", 0);
+  test_sh(".000000000123", 8, "0.0123", 0);
+  test_sh(".000000000123", 9, "0.123", 0);
+  test_sh(".000000000123", 10, "1.23", 0);
+  test_sh(".000000000123", 17, "12300000", 0);
+  test_sh(".000000000123", 18, "123000000", 0);
+  test_sh(".000000000123", 19, "1230000000", 0);
+  test_sh(".000000000123", 20, "12300000000", 0);
+  test_sh(".000000000123", 21, "123000000000", 0);
+  test_sh(".000000000123", 22, "1230000000000", 0);
+  test_sh(".000000000123", 23, "12300000000000", 0);
+  test_sh(".000000000123", 24, "123000000000000", 0);
+  test_sh(".000000000123", 25, "1230000000000000", 0);
+  test_sh(".000000000123", 26, "12300000000000000", 0);
+  test_sh(".000000000123", 27, "123000000000000000", 0);
+  test_sh(".000000000123", 28, "0.000000000123", 2);
+  test_sh("123456789.987654321", -1, "12345678.998765432", 1);
+  test_sh("123456789.987654321", -2, "1234567.899876543", 1);
+  test_sh("123456789.987654321", -8, "1.234567900", 1);
+  test_sh("123456789.987654321", -9, "0.123456789987654321", 0);
+  test_sh("123456789.987654321", -10, "0.012345678998765432", 1);
+  test_sh("123456789.987654321", -17, "0.000000001234567900", 1);
+  test_sh("123456789.987654321", -18, "0.000000000123456790", 1);
+  test_sh("123456789.987654321", -19, "0.000000000012345679", 1);
+  test_sh("123456789.987654321", -26, "0.000000000000000001", 1);
+  test_sh("123456789.987654321", -27, "0", 1);
+  test_sh("123456789.987654321", 1, "1234567900", 1);
+  test_sh("123456789.987654321", 2, "12345678999", 1);
+  test_sh("123456789.987654321", 4, "1234567899877", 1);
+  test_sh("123456789.987654321", 8, "12345678998765432", 1);
+  test_sh("123456789.987654321", 9, "123456789987654321", 0);
+  test_sh("123456789.987654321", 10, "123456789.987654321", 2);
+  test_sh("123456789.987654321", 0, "123456789.987654321", 0);
+  a.len= sizeof(buf1)/sizeof(dec1);
+}
+
+
+TEST_F(DecimalTest, DecimalActualFraction)
+{
+  test_fr("1.123456789000000000", "1.123456789");
+  test_fr("1.12345678000000000", "1.12345678");
+  test_fr("1.1234567000000000", "1.1234567");
+  test_fr("1.123456000000000", "1.123456");
+  test_fr("1.12345000000000", "1.12345");
+  test_fr("1.1234000000000", "1.1234");
+  test_fr("1.123000000000", "1.123");
+  test_fr("1.12000000000", "1.12");
+  test_fr("1.1000000000", "1.1");
+  test_fr("1.000000000", "1");
+  test_fr("1.0", "1");
+  test_fr("10000000000000000000.0", "10000000000000000000");
+}
+
+
+}

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-mtr branch (bjorn.munch:3105 to 3108) Bjorn Munch26 Aug