diff --git a/include/config-win.h b/include/config-win.h
index 475141a1989..ba1a987f14c 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -310,9 +310,6 @@ inline double ulonglong2double(ulonglong value)
 #define HAVE_SETFILEPOINTER
 #define HAVE_VIO
 
-#define HAME_MMAP               /* in mysys/my_mmap.c */
-#define HAVE_GETPAGESIZE        /* in mysys/my_mmap.c */
-
 #ifdef NOT_USED
 #define HAVE_SNPRINTF		/* Gave link error */
 #define _snprintf snprintf
diff --git a/include/my_sys.h b/include/my_sys.h
index 9cce13e53dd..498a1bd30fe 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -796,7 +796,7 @@ void my_free_open_file_info(void);
 ulonglong my_getsystime(void);
 my_bool my_gethwaddr(uchar *to);
 
-#ifdef HAVE_MMAP
+#ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 
 #ifndef MAP_NOSYNC
@@ -815,6 +815,7 @@ my_bool my_gethwaddr(uchar *to);
 #define MAP_NOSYNC       0x0800
 #define MAP_FAILED       ((void *)-1)
 #define MS_SYNC          0x0000
+#define HAVE_MMAP
 
 int my_getpagesize(void);
 void *my_mmap(void *, size_t, int, int, int, my_off_t);
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index ee0047934ab..df117479814 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -111,10 +111,14 @@ insert into t1 values ("Alas");
 /*!40019 SET @@session.max_insert_delayed_threads=0*/;
 ROLLBACK;
 use test;
-SET TIMESTAMP=1065204671;
+SET TIMESTAMP=1108844556;
 BEGIN;
+SET TIMESTAMP=1108844555;
+insert t1 values (1);
 /*!40019 SET @@session.max_insert_delayed_threads=0*/;
 use test;
-SET TIMESTAMP=1065204671;
+SET TIMESTAMP=1108844556;
 BEGIN;
+SET TIMESTAMP=1108844555;
+insert t1 values (1);
 drop table t1, t2;
diff --git a/mysql-test/r/rpl_trunc_binlog.result b/mysql-test/r/rpl_trunc_binlog.result
index 5eb5f810a8f..2663fffe4d4 100644
--- a/mysql-test/r/rpl_trunc_binlog.result
+++ b/mysql-test/r/rpl_trunc_binlog.result
@@ -6,8 +6,12 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 start slave;
 stop slave;
 flush logs;
+create table t1 (a int) engine=bdb;
 reset slave;
 start slave;
 show slave status;
 Slave_IO_State	Master_Host	Master_User	Master_Port	Connect_Retry	Master_Log_File	Read_Master_Log_Pos	Relay_Log_File	Relay_Log_Pos	Relay_Master_Log_File	Slave_IO_Running	Slave_SQL_Running	Replicate_Do_DB	Replicate_Ignore_DB	Replicate_Do_Table	Replicate_Ignore_Table	Replicate_Wild_Do_Table	Replicate_Wild_Ignore_Table	Last_Errno	Last_Error	Skip_Counter	Exec_Master_Log_Pos	Relay_Log_Space	Until_Condition	Until_Log_File	Until_Log_Pos	Master_SSL_Allowed	Master_SSL_CA_File	Master_SSL_CA_Path	Master_SSL_Cert	Master_SSL_Cipher	Master_SSL_Key	Seconds_Behind_Master
-#	127.0.0.1	root	MASTER_PORT	1	master-bin.000002	4	#	#	master-bin.000001	Yes	No							0	Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. A probable cause is that the master died while writing the transaction to its binary log.	0	79	#	None		0	No						#
+#	127.0.0.1	root	MASTER_PORT	1	master-bin.000002	4	#	#	master-bin.000002	Yes	Yes							0	Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. A probable cause is that the master died while writing the transaction to its binary log.	0	4	#	None		0	No						#
+select * from t1;
+a
+drop table t1;
diff --git a/mysql-test/std_data/trunc_binlog.000001 b/mysql-test/std_data/trunc_binlog.000001
index 2c2b4ec6ce4..3da2490eab2 100644
Binary files a/mysql-test/std_data/trunc_binlog.000001 and b/mysql-test/std_data/trunc_binlog.000001 differ
diff --git a/mysql-test/t/rpl_trunc_binlog.test b/mysql-test/t/rpl_trunc_binlog.test
index b2e7e52f5e4..eec36532275 100644
--- a/mysql-test/t/rpl_trunc_binlog.test
+++ b/mysql-test/t/rpl_trunc_binlog.test
@@ -1,21 +1,28 @@
 # We are testing if a binlog which contains BEGIN but not COMMIT (the
-# master did while writing the transaction to the binlog) triggers an
-# error on slave.  So we use such a truncated binlog and simulate that
+# master died while writing the transaction to the binlog) triggers a
+# rollback on slave.  So we use such a truncated binlog and simulate that
 # the master restarted after this.
 
 source include/master-slave.inc;
 
 connection slave;
-# If we are not supporting transactions in the slave, the unfinished transaction
-# won't cause any error, so we need to skip the test. In the 4.0 testsuite, the
-# slave always runs without InnoDB, so we check for BDB.
+# If we are not supporting transactions in the slave, the unfinished
+# transaction won't cause any error, so we need to skip the test. In the 4.0
+# testsuite, the slave always runs without InnoDB, so we check for BDB.
 source include/have_bdb.inc;
 stop slave;
+
 connection master;
 flush logs;
 system mv -f var/log/master-bin.000001 var/log/master-bin.000002;
 system cp std_data/trunc_binlog.000001 var/log/master-bin.000001;
+
 connection slave;
+
+# truncated binlog contains: BEGIN; INSERT t1 VALUES (1);
+# so let's create the table t1 on slave
+
+create table t1 (a int) engine=bdb;
 reset slave;
 start slave;
 # can't sync_with_master so we must sleep
@@ -23,3 +30,6 @@ sleep 3;
 --replace_result $MASTER_MYPORT MASTER_PORT
 --replace_column 1 # 8 # 9 # 23 # 33 #
 show slave status;
+select * from t1;
+drop table t1;
+
diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c
index 883181edd6c..0225e7fac24 100644
--- a/mysys/my_mmap.c
+++ b/mysys/my_mmap.c
@@ -16,7 +16,7 @@
 
 #include "mysys_priv.h"
 
-#ifdef HAVE_MMAP
+#ifdef HAVE_SYS_MMAN_H
 
 /*
   system msync() only syncs mmap'ed area to fs cache.
@@ -84,6 +84,6 @@ int my_msync(int fd, void *addr, size_t len, int flags)
 }
 
 #endif
-#error "no mmap!"
+#warning "no mmap!"
 #endif
 
diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc
index cb0780ea74d..d043a66e71a 100644
--- a/sql/examples/ha_example.cc
+++ b/sql/examples/ha_example.cc
@@ -414,7 +414,7 @@ int ha_example::rnd_next(byte *buf)
   position() is called after each call to rnd_next() if the data needs
   to be ordered. You can do something like the following to store
   the position:
-  ha_store_ptr(ref, ref_length, current_position);
+  my_store_ptr(ref, ref_length, current_position);
 
   The server uses ref to store data. ref_length in the above case is
   the size needed to store current_position. ref is just a byte array
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index 695c71677c0..518f59eb853 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -1503,7 +1503,7 @@ int ha_federated::rnd_next(byte *buf)
 /*
   'position()' is called after each call to rnd_next() if the data needs to be
   ordered. You can do something like the following to store the position:
-  ha_store_ptr(ref, ref_length, current_position);
+  my_store_ptr(ref, ref_length, current_position);
 
   The server uses ref to store data. ref_length in the above case is the size
   needed to store current_position. ref is just a byte array that the server
@@ -1516,7 +1516,7 @@ int ha_federated::rnd_next(byte *buf)
 void ha_federated::position(const byte *record)
 {
   DBUG_ENTER("ha_federated::position");
-  //ha_store_ptr Add seek storage
+  //my_store_ptr Add seek storage
   *(MYSQL_ROW_OFFSET *)ref=current_position; // ref is always aligned
   DBUG_VOID_RETURN;
 }
diff --git a/sql/log.cc b/sql/log.cc
index cb776cff0e9..b048323aa76 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2415,6 +2415,7 @@ void sql_print_information(const char *format, ...)
   DBUG_VOID_RETURN;
 }
 
+#ifdef HAVE_MMAP
 /********* transaction coordinator log for 2pc - mmap() based solution *******/
 
 /*
@@ -2460,10 +2461,6 @@ uint opt_tc_log_size=TC_LOG_MIN_SIZE;
 uint tc_log_max_pages_used=0, tc_log_page_size=0,
      tc_log_page_waits=0, tc_log_cur_pages_used=0;
 
-TC_LOG *tc_log;
-TC_LOG_MMAP tc_log_mmap;
-TC_LOG_DUMMY tc_log_dummy;
-
 int TC_LOG_MMAP::open(const char *opt_name)
 {
   uint i;
@@ -2473,12 +2470,8 @@ int TC_LOG_MMAP::open(const char *opt_name)
   DBUG_ASSERT(total_ha_2pc > 1);
   DBUG_ASSERT(opt_name && opt_name[0]);
 
-#ifdef HAVE_GETPAGESIZE
   tc_log_page_size= my_getpagesize();
   DBUG_ASSERT(TC_LOG_PAGE_SIZE % tc_log_page_size == 0);
-#else
-  tc_log_page_size= TC_LOG_PAGE_SIZE;
-#endif
 
   fn_format(logname,opt_name,mysql_data_home,"",MY_UNPACK_FILENAME);
   fd= my_open(logname, O_RDWR, MYF(0));
@@ -2861,6 +2854,11 @@ err1:
                   "--tc-heuristic-recover={commit|rollback}");
   return 1;
 }
+#endif
+
+TC_LOG *tc_log;
+TC_LOG_DUMMY tc_log_dummy;
+TC_LOG_MMAP  tc_log_mmap;
 
 /*
   Perform heuristic recovery, if --tc-heuristic-recover was used
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 05fd1fdea58..34019e73f96 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -80,6 +80,7 @@ class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
   void unlog(ulong cookie, my_xid xid)  { }
 };
 
+#ifdef HAVE_MMAP
 class TC_LOG_MMAP: public TC_LOG
 {
   private:
@@ -103,7 +104,8 @@ class TC_LOG_MMAP: public TC_LOG
 
   char logname[FN_REFLEN];
   File fd;
-  uint file_length, npages, inited;
+  my_off_t file_length;
+  uint npages, inited;
   uchar *data;
   struct st_page *pages, *syncing, *active, *pool, *pool_last;
   /*
@@ -128,6 +130,9 @@ class TC_LOG_MMAP: public TC_LOG
   int sync();
   int overflow();
 };
+#else
+#define TC_LOG_MMAP TC_LOG_DUMMY
+#endif
 
 extern TC_LOG *tc_log;
 extern TC_LOG_MMAP tc_log_mmap;
diff --git a/strings/decimal.c b/strings/decimal.c
index 212bd7204f6..e6d2d9b14dd 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -14,7 +14,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-#line __LINE__ "decimal.c"
+#line 18 "decimal.c"
 
 /*
 =======================================================================
@@ -107,14 +107,29 @@
 #include <m_string.h>
 #include <decimal.h>
 
+/*
+  Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
+  So one "decimal_digit" is
+
+      0 < decimal_digit <= DIG_MAX < DIG_BASE
+
+  in the struct st_decimal:
+
+    intg is the number of *decimal* digits (NOT number of decimal_digit's !)
+         before the point
+    frac - number of decimal digits after the point
+    buf is an array of decimal_digit's
+    len is the length of buf (length of allocated space) in decimal_digit's,
+        not in bytes
+*/
 typedef decimal_digit dec1;
 typedef longlong      dec2;
 
 #define DIG_PER_DEC1 9
 #define DIG_MASK     100000000
 #define DIG_BASE     1000000000
-#define DIG_MAX      999999999
-#define DIG_BASE2    LL(1000000000000000000)
+#define DIG_MAX      (DIG_BASE-1)
+#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
 #define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
 static const dec1 powers10[DIG_PER_DEC1+1]={
   1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
@@ -1073,6 +1088,68 @@ int decimal2longlong(decimal *from, longlong *to)
 
   RETURN VALUE
     E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
+
+  DESCRIPTION
+    for storage decimal numbers are converted to the "binary" format.
+
+    This format has the following properties:
+      1. length of the binary representation depends on the {precision, scale}
+      as provided by the caller and NOT on the intg/frac of the decimal to
+      convert.
+      2. binary representations of the same {precision, scale} can be compared
+      with memcmp - with the same result as decimal_cmp() of the original
+      decimals (not taking into account possible precision loss during
+      conversion).
+
+    This binary format is as follows:
+      1. First the number is converted to have a requested precision and scale.
+      2. Every full DIG_PER_DEC1 digits of intg part are stored in 4 bytes
+         as is
+      3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
+         number of bytes (enough bytes to store this number of digits -
+         see dig2bytes)
+      4. same for frac - full decimal_digit's are stored as is,
+         the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
+      5. If the number is negative - every byte is inversed.
+      5. The very first bit of the resulting byte array is inverted (because
+         memcmp compares unsigned bytes, see property 2 above)
+
+    Example:
+
+      1234567890.1234
+
+    internally is represented as 3 decimal_digit's
+
+      1 234567890 123400000
+
+    (assuming we want a binary representation with precision=14, scale=4)
+    in hex it's
+
+      00-00-00-01  0D-FB-38-D2  07-5A-EF-40
+
+    now, middle decimal_digit is full - it stores 9 decimal digits. It goes
+    into binary representation as is:
+
+
+      ...........  0D-FB-38-D2 ............
+
+    First decimal_digit has only one decimal digit. We can store one digit in
+    one byte, no need to waste four:
+
+                01 0D-FB-38-D2 ............
+
+    now, last digit. It's 123400000. We can store 1234 in two bytes:
+
+                01 0D-FB-38-D2 04-D2
+
+    So, we've packed 12 bytes number in 7 bytes.
+    And now we invert the highest bit to get the final result:
+
+                81 0D FB 38 D2 04 D2
+
+    And for -1234567890.1234 it would be
+
+                7E F2 04 37 2D FB 2D
 */
 int decimal2bin(decimal *from, char *to, int precision, int frac)
 {
@@ -1415,6 +1492,11 @@ int decimal_round(decimal *from, decimal *to, int scale, decimal_round_mode mode
       else
         *(++buf1)=DIG_BASE;
     }
+    else if (frac0+intg0==0)
+    {
+      decimal_make_zero(to);
+      return E_DEC_OK;
+    }
   }
   else
   {
@@ -2666,11 +2748,12 @@ int main()
   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);
-  if (full)
+  c.buf[1]=0x3ABECA;
+  test_md("99999999999999999999999999999999999999","3","0", 0);
+  if (c.buf[1] != 0x3ABECA)
   {
-    c.buf[1]=0x3ABECA;
-    test_md("99999999999999999999999999999999999999","3","0", 0);
-    printf("%X\n", c.buf[1]);
+    printf("%X - overflow\n", c.buf[1]);
+    exit(1);
   }
 
   printf("==== decimal2bin/bin2decimal ====\n");
@@ -2741,6 +2824,16 @@ int main()
   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");