List:Commits« Previous MessageNext Message »
From:Martin Zaun Date:October 22 2010 6:10am
Subject:bzr commit into mysql-5.1-telco-6.3 branch (martin.zaun:3318)
View as plain text  
#At file:///Users/mz/mysql/ndb-6.3/ based on revid:martin.zaun@stripped

 3318 Martin Zaun	2010-10-21 [merge]
      merge from ndb-6.3-wl5421 to ndb-6.3

    added:
      mysql-test/suite/ndb/r/ndb_restore_lossy_charbinary_conv.result
      mysql-test/suite/ndb/r/ndb_restore_lossy_integral_conv.result
      mysql-test/suite/ndb/r/ndb_restore_padding_preservation.result
      mysql-test/suite/ndb/t/ndb_restore_lossy_charbinary_conv.test
      mysql-test/suite/ndb/t/ndb_restore_lossy_integral_conv.test
      mysql-test/suite/ndb/t/ndb_restore_padding_preservation.test
    modified:
      storage/ndb/tools/restore/Restore.cpp
      storage/ndb/tools/restore/Restore.hpp
      storage/ndb/tools/restore/consumer_restore.cpp
      storage/ndb/tools/restore/consumer_restore.hpp
      storage/ndb/tools/restore/restore_main.cpp
=== added file 'mysql-test/suite/ndb/r/ndb_restore_lossy_charbinary_conv.result'
--- a/mysql-test/suite/ndb/r/ndb_restore_lossy_charbinary_conv.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_restore_lossy_charbinary_conv.result	2010-10-22 06:00:55 +0000
@@ -0,0 +1,373 @@
+************************************************************
+* Creating table with char+binary types
+************************************************************
+CREATE TABLE t2(
+c1 char(2), c2 char(128), c3 char(255),
+b1 binary(2), b2 binary(128), b3 binary(255),
+vc1 varchar(2), vc2 varchar(255), vc3 varchar(1024),
+vb1 varbinary(2), vb2 varbinary(255), vb3 varbinary(1024)
+) ENGINE=NDB;
+INSERT INTO t2 VALUES(
+repeat('a', 2), repeat('b', 128), repeat('c', 255),
+repeat('d', 2), repeat('e', 128), repeat('f', 255),
+repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+************************************************************
+* Backing up table with char+binary types
+************************************************************
+************************************************************
+* Restoring table with unchanged char+binary types:
+*     char(2)            -->    char(2)
+*     char(128)          -->    char(128)
+*     char(255)          -->    char(255)
+*     binary(2)          -->    binary(2)
+*     binary(128)        -->    binary(128)
+*     binary(255)        -->    binary(255)
+*     varchar(2)         -->    varchar(2)
+*     varchar(255)       -->    varchar(255)
+*     varchar(1024)      -->    varchar(1024)
+*     varbinary(2)       -->    varbinary(2)
+*     varbinary(255)     -->    varbinary(255)
+*     varbinary(1024)    -->    varbinary(1024)
+************************************************************
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+2	128	255	2	128	128	2	255	1024	2	255	1024
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Restoring table with 1st degree demoted char+binary types:
+*     char(2)            -->    char(1)
+*     char(128)          -->    char(2)
+*     char(255)          -->    char(128)
+*     binary(2)          -->    binary(1)
+*     binary(128)        -->    binary(2)
+*     binary(255)        -->    binary(128)
+*     varchar(2)         -->    varchar(1)
+*     varchar(255)       -->    varchar(2)
+*     varchar(1024)      -->    varchar(512)
+*     varbinary(2)       -->    varbinary(1)
+*     varbinary(255)     -->    varbinary(2)
+*     varbinary(1024)    -->    varbinary(512)
+************************************************************
+ALTER TABLE t2
+modify c1 char(1), modify c2 char(2), modify c3 char(128),
+modify b1 binary(1), modify b2 binary(2), modify b3 binary(128),
+modify vc1 varchar(1), modify vc2 varchar(2), modify vc3 varchar(512),
+modify vb1 varbinary(1), modify vb2 varbinary(2), modify vb3 varbinary(512);
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	2	128	1	2	2	1	2	512	1	2	512
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	2	128	1	2	2	1	2	512	1	2	512
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Restoring table with 2nd degree demoted char+binary types:
+*     char(2)            -->    char(1)
+*     char(128)          -->    char(1)
+*     char(255)          -->    char(2)
+*     binary(2)          -->    binary(1)
+*     binary(128)        -->    binary(1)
+*     binary(255)        -->    binary(2)
+*     varchar(2)         -->    varchar(1)
+*     varchar(255)       -->    varchar(1)
+*     varchar(1024)      -->    varchar(255)
+*     varbinary(2)       -->    varbinary(1)
+*     varbinary(255)     -->    varbinary(1)
+*     varbinary(1024)    -->    varbinary(255)
+************************************************************
+ALTER TABLE t2
+modify c1 char(1), modify c2 char(1), modify c3 char(2),
+modify b1 binary(1), modify b2 binary(1), modify b3 binary(2),
+modify vc1 varchar(1), modify vc2 varchar(1), modify vc3 varchar(255),
+modify vb1 varbinary(1), modify vb2 varbinary(1), modify vb3 varbinary(255);
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	2	1	1	1	1	1	255	1	1	255
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	2	1	1	1	1	1	255	1	1	255
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Restoring table with 3rd degree demoted char+binary types:
+*     char(2)            -->    char(1)
+*     char(128)          -->    char(1)
+*     char(255)          -->    char(1)
+*     binary(2)          -->    binary(1)
+*     binary(128)        -->    binary(1)
+*     binary(255)        -->    binary(1)
+*     varchar(2)         -->    varchar(1)
+*     varchar(255)       -->    varchar(1)
+*     varchar(1024)      -->    varchar(1)
+*     varbinary(2)       -->    varbinary(1)
+*     varbinary(255)     -->    varbinary(1)
+*     varbinary(1024)    -->    varbinary(1)
+************************************************************
+ALTER TABLE t2
+modify c1 char(1), modify c2 char(1), modify c3 char(1),
+modify b1 binary(1), modify b2 binary(1), modify b3 binary(1),
+modify vc1 varchar(1), modify vc2 varchar(1), modify vc3 varchar(1),
+modify vb1 varbinary(1), modify vb2 varbinary(1), modify vb3 varbinary(1);
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	1	1	1	1	1	1	1	1	1	1
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	1	1	1	1	1	1	1	1	1	1
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Restoring table with changed var-ness of char+binary types:
+*     char(2)            -->    varchar(2)
+*     char(128)          -->    varchar(128)
+*     char(255)          -->    varchar(255)
+*     binary(2)          -->    varbinary(2)
+*     binary(128)        -->    varbinary(128)
+*     binary(255)        -->    varbinary(255)
+*     varchar(2)         -->    char(2)
+*     varchar(255)       -->    char(255)
+*     varchar(1024)      -->    varchar(1024)
+*     varbinary(2)       -->    binary(2)
+*     varbinary(255)     -->    binary(255)
+*     varbinary(1024)    -->    varbinary(1024)
+************************************************************
+DELETE FROM t2;
+ALTER TABLE t2
+modify c1 varchar(2), modify c2 varchar(128), modify c3 varchar(255),
+modify b1 varbinary(2), modify b2 varbinary(128), modify b3 varbinary(255),
+modify vc1 char(2), modify vc2 char(255), modify vc3 varchar(1024),
+modify vb1 binary(2), modify vb2 binary(255), modify vb3 varbinary(1024);
+INSERT INTO t2 VALUES(
+repeat('a', 2), repeat('b', 128), repeat('c', 255),
+repeat('d', 2), repeat('e', 128), repeat('f', 255),
+repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+2	128	255	2	128	128	2	255	1024	2	255	1024
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+2	128	255	2	128	128	2	255	1024	2	255	1024
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Restoring table with changed varness + 1st degree demoted types:
+*     char(2)            -->    varchar(1)
+*     char(128)          -->    varchar(2)
+*     char(255)          -->    varchar(128)
+*     binary(2)          -->    varbinary(1)
+*     binary(128)        -->    varbinary(2)
+*     binary(255)        -->    varbinary(128)
+*     varchar(2)         -->    char(1)
+*     varchar(255)       -->    char(2)
+*     varchar(1024)      -->    char(255)
+*     varbinary(2)       -->    binary(1)
+*     varbinary(255)     -->    binary(2)
+*     varbinary(1024)    -->    binary(255)
+************************************************************
+DELETE FROM t2;
+ALTER TABLE t2
+modify c1 varchar(1), modify c2 varchar(2), modify c3 varchar(128),
+modify b1 varbinary(1), modify b2 varbinary(2), modify b3 varbinary(128),
+modify vc1 char(1), modify vc2 char(2), modify vc3 char(255),
+modify vb1 binary(1), modify vb2 binary(2), modify vb3 binary(255);
+INSERT INTO t2 VALUES(
+repeat('a', 2), repeat('b', 128), repeat('c', 255),
+repeat('d', 2), repeat('e', 128), repeat('f', 255),
+repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	2	128	1	2	2	1	2	255	1	2	255
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	2	128	1	2	2	1	2	255	1	2	255
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Restoring table with changed varness + 2nd degree demoted types:
+*     char(2)            -->    varchar(1)
+*     char(128)          -->    varchar(1)
+*     char(255)          -->    varchar(2)
+*     binary(2)          -->    varbinary(1)
+*     binary(128)        -->    varbinary(1)
+*     binary(255)        -->    varbinary(2)
+*     varchar(2)         -->    char(1)
+*     varchar(255)       -->    char(1)
+*     varchar(1024)      -->    char(255)
+*     varbinary(2)       -->    binary(1)
+*     varbinary(255)     -->    binary(1)
+*     varbinary(1024)    -->    binary(255)
+************************************************************
+DELETE FROM t2;
+ALTER TABLE t2
+modify c1 varchar(1), modify c2 varchar(1), modify c3 varchar(2),
+modify b1 varbinary(1), modify b2 varbinary(1), modify b3 varbinary(2),
+modify vc1 char(1), modify vc2 char(1), modify vc3 char(255),
+modify vb1 binary(1), modify vb2 binary(1), modify vb3 binary(255);
+INSERT INTO t2 VALUES(
+repeat('a', 2), repeat('b', 128), repeat('c', 255),
+repeat('d', 2), repeat('e', 128), repeat('f', 255),
+repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	2	1	1	1	1	1	255	1	1	255
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	2	1	1	1	1	1	255	1	1	255
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Restoring table with changed varness + 3rd degree demoted types:
+*     char(2)            -->    varchar(1)
+*     char(128)          -->    varchar(1)
+*     char(255)          -->    varchar(1)
+*     binary(2)          -->    varbinary(1)
+*     binary(128)        -->    varbinary(1)
+*     binary(255)        -->    varbinary(1)
+*     varchar(2)         -->    char(1)
+*     varchar(255)       -->    char(1)
+*     varchar(1024)      -->    char(1)
+*     varbinary(2)       -->    binary(1)
+*     varbinary(255)     -->    binary(1)
+*     varbinary(1024)    -->    binary(1)
+************************************************************
+DELETE FROM t2;
+ALTER TABLE t2
+modify c1 varchar(1), modify c2 varchar(1), modify c3 varchar(1),
+modify b1 varbinary(1), modify b2 varbinary(1), modify b3 varbinary(1),
+modify vc1 char(1), modify vc2 char(1), modify vc3 char(1),
+modify vb1 binary(1), modify vb2 binary(1), modify vb3 binary(1);
+INSERT INTO t2 VALUES(
+repeat('a', 2), repeat('b', 128), repeat('c', 255),
+repeat('d', 2), repeat('e', 128), repeat('f', 255),
+repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	1	1	1	1	1	1	1	1	1	1
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+DELETE FROM t2;
+SELECT
+length(c1), length(c2), length(c3),
+length(b1), length(b2), length(b2),
+length(vc1), length(vc2), length(vc3),
+length(vb1), length(vb2), length(vb3)
+FROM t2;
+length(c1)	length(c2)	length(c3)	length(b1)	length(b2)	length(b2)	length(vc1)	length(vc2)	length(vc3)	length(vb1)	length(vb2)	length(vb3)
+1	1	1	1	1	1	1	1	1	1	1	1
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+COUNT(*)
+1
+DROP TABLE t2_myisam;
+************************************************************
+* Deleting table with char+binary types
+************************************************************
+DROP TABLE t2;

=== added file 'mysql-test/suite/ndb/r/ndb_restore_lossy_integral_conv.result'
--- a/mysql-test/suite/ndb/r/ndb_restore_lossy_integral_conv.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_restore_lossy_integral_conv.result	2010-10-22 06:00:55 +0000
@@ -0,0 +1,451 @@
+************************************************************
+* Creating table with integral types
+************************************************************
+CREATE TABLE t1(
+t1 tinyint,  t2 tinyint,  ut1 tinyint unsigned,
+s1 smallint,  s2 smallint,  us1 smallint unsigned,
+m1 mediumint,  m2 mediumint,  um1 mediumint unsigned,
+i1 int,  i2 int,  ui1 int unsigned,
+b1 bigint,  b2 bigint,  ub1 bigint unsigned
+) ENGINE=NDB;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+************************************************************
+* Backing up table with integral types
+************************************************************
+************************************************************
+* Restoring table with unchanged integral types:
+*     tinyint[unsigned]  -->    tinyint[unsigned]
+*    smallint[unsigned]  -->   smallint[unsigned]
+*   mediumint[unsigned]  -->  mediumint[unsigned]
+*         int[unsigned]  -->        int[unsigned]
+*      bigint[unsigned]  -->     bigint[unsigned]
+************************************************************
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-32768	32767	65535	-8388608	8388607	16777215	-2147483648	2147483647	4294967295	-9223372036854775808	9223372036854775807	18446744073709551615
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with 1st degree demoted integral types:
+*     tinyint[unsigned]  -->    tinyint[unsigned]
+*    smallint[unsigned]  -->    tinyint[unsigned]
+*   mediumint[unsigned]  -->   smallint[unsigned]
+*         int[unsigned]  -->  mediumint[unsigned]
+*      bigint[unsigned]  -->        int[unsigned]
+************************************************************
+ALTER TABLE t1
+modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+modify m1 smallint,  modify m2 smallint,  modify um1 smallint unsigned,
+modify i1 mediumint,  modify i2 mediumint,  modify ui1 mediumint unsigned,
+modify b1 int,  modify b2 int,  modify ub1 int unsigned;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-32768	32767	65535	-8388608	8388607	16777215	-2147483648	2147483647	4294967295
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-32768	32767	65535	-8388608	8388607	16777215	-2147483648	2147483647	4294967295
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with 2nd degree demoted integral types:
+*     tinyint[unsigned]  -->    tinyint[unsigned]
+*    smallint[unsigned]  -->    tinyint[unsigned]
+*   mediumint[unsigned]  -->    tinyint[unsigned]
+*         int[unsigned]  -->   smallint[unsigned]
+*      bigint[unsigned]  -->  mediumint[unsigned]
+************************************************************
+ALTER TABLE t1
+modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+modify m1 tinyint,  modify m2 tinyint,  modify um1 tinyint unsigned,
+modify i1 smallint,  modify i2 smallint,  modify ui1 smallint unsigned,
+modify b1 mediumint,  modify b2 mediumint,  modify ub1 mediumint unsigned;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-128	127	255	-32768	32767	65535	-8388608	8388607	16777215
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-128	127	255	-32768	32767	65535	-8388608	8388607	16777215
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with 3rd degree demoted integral types:
+*     tinyint[unsigned]  -->    tinyint[unsigned]
+*    smallint[unsigned]  -->    tinyint[unsigned]
+*   mediumint[unsigned]  -->    tinyint[unsigned]
+*         int[unsigned]  -->    tinyint[unsigned]
+*      bigint[unsigned]  -->   smallint[unsigned]
+************************************************************
+ALTER TABLE t1
+modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+modify m1 tinyint,  modify m2 tinyint,  modify um1 tinyint unsigned,
+modify i1 tinyint,  modify i2 tinyint,  modify ui1 tinyint unsigned,
+modify b1 smallint,  modify b2 smallint,  modify ub1 smallint unsigned;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-128	127	255	-128	127	255	-32768	32767	65535
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-128	127	255	-128	127	255	-32768	32767	65535
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with 4th degree demoted integral types:
+*     tinyint[unsigned]  -->    tinyint[unsigned]
+*    smallint[unsigned]  -->    tinyint[unsigned]
+*   mediumint[unsigned]  -->    tinyint[unsigned]
+*         int[unsigned]  -->    tinyint[unsigned]
+*      bigint[unsigned]  -->    tinyint[unsigned]
+************************************************************
+ALTER TABLE t1
+modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+modify m1 tinyint,  modify m2 tinyint,  modify um1 tinyint unsigned,
+modify i1 tinyint,  modify i2 tinyint,  modify ui1 tinyint unsigned,
+modify b1 tinyint,  modify b2 tinyint,  modify ub1 tinyint unsigned;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-128	127	255	-128	127	255	-128	127	255
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+-128	127	255	-128	127	255	-128	127	255	-128	127	255	-128	127	255
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness:
+*     tinyint unsigned/signed  -->    tinyint signed/unsigned
+*    smallint unsigned/signed  -->   smallint signed/unsigned
+*   mediumint unsigned/signed  -->  mediumint signed/unsigned
+*         int unsigned/signed  -->        int signed/unsigned
+*      bigint unsigned/signed  -->     bigint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+modify s1 smallint unsigned,  modify s2 smallint unsigned,  modify us1 smallint signed,
+modify m1 mediumint unsigned,  modify m2 mediumint unsigned,  modify um1 mediumint signed,
+modify i1 int unsigned,  modify i2 int unsigned,  modify ui1 int signed,
+modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	32767	32767	0	8388607	8388607	0	2147483647	2147483647	0	9223372036854775807	9223372036854775807
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	32767	32767	0	8388607	8388607	0	2147483647	2147483647	0	9223372036854775807	9223372036854775807
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 1st degree promoted types:
+*     tinyint unsigned/signed  -->   smallint signed/unsigned
+*    smallint unsigned/signed  -->  mediumint signed/unsigned
+*   mediumint unsigned/signed  -->        int signed/unsigned
+*         int unsigned/signed  -->     bigint signed/unsigned
+*      bigint unsigned/signed  -->     bigint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 smallint unsigned,  modify t2 smallint unsigned,  modify ut1 smallint signed,
+modify s1 mediumint unsigned,  modify s2 mediumint unsigned,  modify us1 mediumint signed,
+modify m1 int unsigned,  modify m2 int unsigned,  modify um1 int signed,
+modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 2nd degree promoted types:
+*     tinyint unsigned/signed  -->  mediumint signed/unsigned
+*    smallint unsigned/signed  -->        int signed/unsigned
+*   mediumint unsigned/signed  -->     bigint signed/unsigned
+*         int unsigned/signed  -->     bigint signed/unsigned
+*      bigint unsigned/signed  -->     bigint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 mediumint unsigned,  modify t2 mediumint unsigned,  modify ut1 mediumint signed,
+modify s1 int unsigned,  modify s2 int unsigned,  modify us1 int signed,
+modify m1 bigint unsigned,  modify m2 bigint unsigned,  modify um1 bigint signed,
+modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 3rd degree promoted types:
+*     tinyint unsigned/signed  -->        int signed/unsigned
+*    smallint unsigned/signed  -->     bigint signed/unsigned
+*   mediumint unsigned/signed  -->     bigint signed/unsigned
+*         int unsigned/signed  -->     bigint signed/unsigned
+*      bigint unsigned/signed  -->     bigint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 int unsigned,  modify t2 int unsigned,  modify ut1 int signed,
+modify s1 bigint unsigned,  modify s2 bigint unsigned,  modify us1 bigint signed,
+modify m1 bigint unsigned,  modify m2 bigint unsigned,  modify um1 bigint signed,
+modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 4th degree promoted types:
+*     tinyint unsigned/signed  -->     bigint signed/unsigned
+*    smallint unsigned/signed  -->     bigint signed/unsigned
+*   mediumint unsigned/signed  -->     bigint signed/unsigned
+*         int unsigned/signed  -->     bigint signed/unsigned
+*      bigint unsigned/signed  -->     bigint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 bigint unsigned,  modify t2 bigint unsigned,  modify ut1 bigint signed,
+modify s1 bigint unsigned,  modify s2 bigint unsigned,  modify us1 bigint signed,
+modify m1 bigint unsigned,  modify m2 bigint unsigned,  modify um1 bigint signed,
+modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	255	0	32767	65535	0	8388607	16777215	0	2147483647	4294967295	0	9223372036854775807	9223372036854775807
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 1st degree demoted types:
+*     tinyint unsigned/signed  -->    tinyint signed/unsigned
+*    smallint unsigned/signed  -->    tinyint signed/unsigned
+*   mediumint unsigned/signed  -->   smallint signed/unsigned
+*         int unsigned/signed  -->  mediumint signed/unsigned
+*      bigint unsigned/signed  -->        int signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+modify m1 smallint unsigned,  modify m2 smallint unsigned,  modify um1 smallint signed,
+modify i1 mediumint unsigned,  modify i2 mediumint unsigned,  modify ui1 mediumint signed,
+modify b1 int unsigned,  modify b2 int unsigned,  modify ub1 int signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	65535	32767	0	16777215	8388607	0	4294967295	2147483647
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	65535	32767	0	16777215	8388607	0	4294967295	2147483647
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 2nd degree demoted types:
+*     tinyint unsigned/signed  -->    tinyint signed/unsigned
+*    smallint unsigned/signed  -->    tinyint signed/unsigned
+*   mediumint unsigned/signed  -->    tinyint signed/unsigned
+*         int unsigned/signed  -->   smallint signed/unsigned
+*      bigint unsigned/signed  -->  mediumint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+modify m1 tinyint unsigned,  modify m2 tinyint unsigned,  modify um1 tinyint signed,
+modify i1 smallint unsigned,  modify i2 smallint unsigned,  modify ui1 smallint signed,
+modify b1 mediumint unsigned,  modify b2 mediumint unsigned,  modify ub1 mediumint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	255	127	0	65535	32767	0	16777215	8388607
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	255	127	0	65535	32767	0	16777215	8388607
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 3rd degree demoted types:
+*     tinyint unsigned/signed  -->    tinyint signed/unsigned
+*    smallint unsigned/signed  -->    tinyint signed/unsigned
+*   mediumint unsigned/signed  -->    tinyint signed/unsigned
+*         int unsigned/signed  -->    tinyint signed/unsigned
+*      bigint unsigned/signed  -->   smallint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+modify m1 tinyint unsigned,  modify m2 tinyint unsigned,  modify um1 tinyint signed,
+modify i1 tinyint unsigned,  modify i2 tinyint unsigned,  modify ui1 tinyint signed,
+modify b1 smallint unsigned,  modify b2 smallint unsigned,  modify ub1 smallint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	255	127	0	255	127	0	65535	32767
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	255	127	0	255	127	0	65535	32767
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Restoring table with changed signedness + 4th degree demoted types:
+*     tinyint unsigned/signed  -->    tinyint signed/unsigned
+*    smallint unsigned/signed  -->    tinyint signed/unsigned
+*   mediumint unsigned/signed  -->    tinyint signed/unsigned
+*         int unsigned/signed  -->    tinyint signed/unsigned
+*      bigint unsigned/signed  -->    tinyint signed/unsigned
+************************************************************
+DELETE FROM t1;
+ALTER TABLE t1
+modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+modify m1 tinyint unsigned,  modify m2 tinyint unsigned,  modify um1 tinyint signed,
+modify i1 tinyint unsigned,  modify i2 tinyint unsigned,  modify ui1 tinyint signed,
+modify b1 tinyint unsigned,  modify b2 tinyint unsigned,  modify ub1 tinyint signed;
+INSERT INTO t1 VALUES(
+-128, 127, 255,
+-32768, 32767, 65535,
+-8388608, 8388607, 16777215,
+-2147483648, 2147483647, 4294967295,
+-9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	255	127	0	255	127	0	255	127
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+DELETE FROM t1;
+SELECT * FROM t1;
+t1	t2	ut1	s1	s2	us1	m1	m2	um1	i1	i2	ui1	b1	b2	ub1
+0	127	127	0	255	127	0	255	127	0	255	127	0	255	127
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+COUNT(*)
+1
+DROP TABLE t1_myisam;
+************************************************************
+* Deleting table with integral types
+************************************************************
+DROP TABLE t1;

=== added file 'mysql-test/suite/ndb/r/ndb_restore_padding_preservation.result'
--- a/mysql-test/suite/ndb/r/ndb_restore_padding_preservation.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_restore_padding_preservation.result	2010-10-22 06:00:55 +0000
@@ -0,0 +1,178 @@
+************************************************************
+* Creating table with char+binary types
+************************************************************
+CREATE TABLE t3(
+c1 char(32),
+b1 binary(32)
+) ENGINE=NDB;
+INSERT INTO t3 VALUES('aaaaaaaa', 'bbbbbbbb');
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	32
+************************************************************
+* Backing up table with char+binary types
+************************************************************
+************************************************************
+* Restoring table with unchanged char+binary types (sanity check):
+*     char(32)           -->    char(32)
+*     binary(32)         -->    binary(32)
+************************************************************
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	32
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with promoted char+binary types preserving padding:
+*     char(32)           -->    varchar(32)
+*     binary(32)         -->    varbinary(32)
+************************************************************
+ALTER TABLE t3 MODIFY c1 varchar(32), MODIFY b1 varbinary(32);
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	32
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+32	32
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with promoted char+binary types preserving padding:
+*     char(32)           -->    varchar(64)
+*     binary(32)         -->    varbinary(64)
+************************************************************
+ALTER TABLE t3 MODIFY c1 varchar(64), MODIFY b1 varbinary(64);
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+32	32
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+32	32
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with promoted char+binary types preserving padding:
+*     char(32)           -->    varchar(512)
+*     binary(32)         -->    varbinary(512)
+************************************************************
+ALTER TABLE t3 MODIFY c1 varchar(512), MODIFY b1 varbinary(512);
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+32	32
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+32	32
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with demoted char+binary types preserving padding:
+*     char(32)           -->    varchar(16)
+*     binary(32)         -->    varbinary(16)
+************************************************************
+ALTER TABLE t3 MODIFY c1 varchar(16), MODIFY b1 varbinary(16);
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+16	16
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+16	16
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with promoted char+binary types discarding padding:
+*     char(32)           -->    varchar(32)
+*     binary(32)         -->    varbinary(32)
+************************************************************
+DELETE FROM t3;
+ALTER TABLE t3 MODIFY c1 varchar(32), MODIFY b1 varbinary(32);
+INSERT INTO t3 VALUES('aaaaaaaa', 'bbbbbbbb');
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with promoted char+binary types discarding padding:
+*     char(32)           -->    varchar(64)
+*     binary(32)         -->    varbinary(64)
+************************************************************
+ALTER TABLE t3 MODIFY c1 varchar(64), MODIFY b1 varbinary(64);
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with promoted char+binary types discarding padding:
+*     char(32)           -->    varchar(512)
+*     binary(32)         -->    varbinary(512)
+************************************************************
+ALTER TABLE t3 MODIFY c1 varchar(512), MODIFY b1 varbinary(512);
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Restoring table with demoted char+binary types discarding padding:
+*     char(32)           -->    varchar(16)
+*     binary(32)         -->    varbinary(16)
+************************************************************
+ALTER TABLE t3 MODIFY c1 varchar(16), MODIFY b1 varbinary(16);
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+DELETE FROM t3;
+SELECT length(c1), length(b1) FROM t3;
+length(c1)	length(b1)
+8	8
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+COUNT(*)
+1
+DROP TABLE t3_myisam;
+************************************************************
+* Deleting table with char+binary types
+************************************************************
+DROP TABLE t3;

=== added file 'mysql-test/suite/ndb/t/ndb_restore_lossy_charbinary_conv.test'
--- a/mysql-test/suite/ndb/t/ndb_restore_lossy_charbinary_conv.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore_lossy_charbinary_conv.test	2010-10-22 06:00:55 +0000
@@ -0,0 +1,455 @@
+######################################################################
+# Author: Martin Zaun
+# Date: 2010-10
+# Purpose: Lossy conversion test for [var]char and [var]binary types
+######################################################################
+
+-- source include/have_ndb.inc
+
+# mysqld's configuration is not relevant to this test
+-- source include/not_embedded.inc
+
+--echo ************************************************************
+--echo * Creating table with char+binary types
+--echo ************************************************************
+
+CREATE TABLE t2(
+  c1 char(2), c2 char(128), c3 char(255),
+  b1 binary(2), b2 binary(128), b3 binary(255),
+  vc1 varchar(2), vc2 varchar(255), vc3 varchar(1024),
+  vb1 varbinary(2), vb2 varbinary(255), vb3 varbinary(1024)
+) ENGINE=NDB;
+
+INSERT INTO t2 VALUES(
+  repeat('a', 2), repeat('b', 128), repeat('c', 255),
+  repeat('d', 2), repeat('e', 128), repeat('f', 255),
+  repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+  repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+
+--echo ************************************************************
+--echo * Backing up table with char+binary types
+--echo ************************************************************
+
+--source include/ndb_backup.inc
+
+# command shortcuts
+#--let $restore_cmd=$NDB_RESTORE --no-defaults -b $the_backup_id -r
+#--let $restore_cmd=$restore_cmd --backup_path=$NDB_BACKUPS-$the_backup_id
+# for ndb 6.3:
+--let $restore_cmd=$NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id
+--let $restore_cmd=$restore_cmd -r --backup_path=$NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id
+
+--echo ************************************************************
+--echo * Restoring table with unchanged char+binary types:
+--echo *     char(2)            -->    char(2)
+--echo *     char(128)          -->    char(128)
+--echo *     char(255)          -->    char(255)
+--echo *     binary(2)          -->    binary(2)
+--echo *     binary(128)        -->    binary(128)
+--echo *     binary(255)        -->    binary(255)
+--echo *     varchar(2)         -->    varchar(2)
+--echo *     varchar(255)       -->    varchar(255)
+--echo *     varchar(1024)      -->    varchar(1024)
+--echo *     varbinary(2)       -->    varbinary(2)
+--echo *     varbinary(255)     -->    varbinary(255)
+--echo *     varbinary(1024)    -->    varbinary(1024)
+--echo ************************************************************
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+# for debugging:
+#    --exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 1 -L -r --print $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+#    --exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 2 -L -r --print $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with 1st degree demoted char+binary types:
+--echo *     char(2)            -->    char(1)
+--echo *     char(128)          -->    char(2)
+--echo *     char(255)          -->    char(128)
+--echo *     binary(2)          -->    binary(1)
+--echo *     binary(128)        -->    binary(2)
+--echo *     binary(255)        -->    binary(128)
+--echo *     varchar(2)         -->    varchar(1)
+--echo *     varchar(255)       -->    varchar(2)
+--echo *     varchar(1024)      -->    varchar(512)
+--echo *     varbinary(2)       -->    varbinary(1)
+--echo *     varbinary(255)     -->    varbinary(2)
+--echo *     varbinary(1024)    -->    varbinary(512)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t2
+  modify c1 char(1), modify c2 char(2), modify c3 char(128),
+  modify b1 binary(1), modify b2 binary(2), modify b3 binary(128),
+  modify vc1 varchar(1), modify vc2 varchar(2), modify vc3 varchar(512),
+  modify vb1 varbinary(1), modify vb2 varbinary(2), modify vb3 varbinary(512);
+--enable_warnings
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with 2nd degree demoted char+binary types:
+--echo *     char(2)            -->    char(1)
+--echo *     char(128)          -->    char(1)
+--echo *     char(255)          -->    char(2)
+--echo *     binary(2)          -->    binary(1)
+--echo *     binary(128)        -->    binary(1)
+--echo *     binary(255)        -->    binary(2)
+--echo *     varchar(2)         -->    varchar(1)
+--echo *     varchar(255)       -->    varchar(1)
+--echo *     varchar(1024)      -->    varchar(255)
+--echo *     varbinary(2)       -->    varbinary(1)
+--echo *     varbinary(255)     -->    varbinary(1)
+--echo *     varbinary(1024)    -->    varbinary(255)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t2
+  modify c1 char(1), modify c2 char(1), modify c3 char(2),
+  modify b1 binary(1), modify b2 binary(1), modify b3 binary(2),
+  modify vc1 varchar(1), modify vc2 varchar(1), modify vc3 varchar(255),
+  modify vb1 varbinary(1), modify vb2 varbinary(1), modify vb3 varbinary(255);
+--enable_warnings
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with 3rd degree demoted char+binary types:
+--echo *     char(2)            -->    char(1)
+--echo *     char(128)          -->    char(1)
+--echo *     char(255)          -->    char(1)
+--echo *     binary(2)          -->    binary(1)
+--echo *     binary(128)        -->    binary(1)
+--echo *     binary(255)        -->    binary(1)
+--echo *     varchar(2)         -->    varchar(1)
+--echo *     varchar(255)       -->    varchar(1)
+--echo *     varchar(1024)      -->    varchar(1)
+--echo *     varbinary(2)       -->    varbinary(1)
+--echo *     varbinary(255)     -->    varbinary(1)
+--echo *     varbinary(1024)    -->    varbinary(1)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t2
+  modify c1 char(1), modify c2 char(1), modify c3 char(1),
+  modify b1 binary(1), modify b2 binary(1), modify b3 binary(1),
+  modify vc1 varchar(1), modify vc2 varchar(1), modify vc3 varchar(1),
+  modify vb1 varbinary(1), modify vb2 varbinary(1), modify vb3 varbinary(1);
+--enable_warnings
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed var-ness of char+binary types:
+--echo *     char(2)            -->    varchar(2)
+--echo *     char(128)          -->    varchar(128)
+--echo *     char(255)          -->    varchar(255)
+--echo *     binary(2)          -->    varbinary(2)
+--echo *     binary(128)        -->    varbinary(128)
+--echo *     binary(255)        -->    varbinary(255)
+--echo *     varchar(2)         -->    char(2)
+--echo *     varchar(255)       -->    char(255)
+--echo *     varchar(1024)      -->    varchar(1024)
+--echo *     varbinary(2)       -->    binary(2)
+--echo *     varbinary(255)     -->    binary(255)
+--echo *     varbinary(1024)    -->    varbinary(1024)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+DELETE FROM t2;
+ALTER TABLE t2
+  modify c1 varchar(2), modify c2 varchar(128), modify c3 varchar(255),
+  modify b1 varbinary(2), modify b2 varbinary(128), modify b3 varbinary(255),
+  modify vc1 char(2), modify vc2 char(255), modify vc3 varchar(1024),
+  modify vb1 binary(2), modify vb2 binary(255), modify vb3 varbinary(1024);
+INSERT INTO t2 VALUES(
+  repeat('a', 2), repeat('b', 128), repeat('c', 255),
+  repeat('d', 2), repeat('e', 128), repeat('f', 255),
+  repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+  repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+--enable_warnings
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+--exec $restore_cmd -n 1 --print -A > /dev/null
+--exec $restore_cmd -n 2 --print -A > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed varness + 1st degree demoted types:
+--echo *     char(2)            -->    varchar(1)
+--echo *     char(128)          -->    varchar(2)
+--echo *     char(255)          -->    varchar(128)
+--echo *     binary(2)          -->    varbinary(1)
+--echo *     binary(128)        -->    varbinary(2)
+--echo *     binary(255)        -->    varbinary(128)
+--echo *     varchar(2)         -->    char(1)
+--echo *     varchar(255)       -->    char(2)
+--echo *     varchar(1024)      -->    char(255)
+--echo *     varbinary(2)       -->    binary(1)
+--echo *     varbinary(255)     -->    binary(2)
+--echo *     varbinary(1024)    -->    binary(255)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+DELETE FROM t2;
+ALTER TABLE t2
+  modify c1 varchar(1), modify c2 varchar(2), modify c3 varchar(128),
+  modify b1 varbinary(1), modify b2 varbinary(2), modify b3 varbinary(128),
+  modify vc1 char(1), modify vc2 char(2), modify vc3 char(255),
+  modify vb1 binary(1), modify vb2 binary(2), modify vb3 binary(255);
+INSERT INTO t2 VALUES(
+  repeat('a', 2), repeat('b', 128), repeat('c', 255),
+  repeat('d', 2), repeat('e', 128), repeat('f', 255),
+  repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+  repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+--enable_warnings
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed varness + 2nd degree demoted types:
+--echo *     char(2)            -->    varchar(1)
+--echo *     char(128)          -->    varchar(1)
+--echo *     char(255)          -->    varchar(2)
+--echo *     binary(2)          -->    varbinary(1)
+--echo *     binary(128)        -->    varbinary(1)
+--echo *     binary(255)        -->    varbinary(2)
+--echo *     varchar(2)         -->    char(1)
+--echo *     varchar(255)       -->    char(1)
+--echo *     varchar(1024)      -->    char(255)
+--echo *     varbinary(2)       -->    binary(1)
+--echo *     varbinary(255)     -->    binary(1)
+--echo *     varbinary(1024)    -->    binary(255)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+DELETE FROM t2;
+ALTER TABLE t2
+  modify c1 varchar(1), modify c2 varchar(1), modify c3 varchar(2),
+  modify b1 varbinary(1), modify b2 varbinary(1), modify b3 varbinary(2),
+  modify vc1 char(1), modify vc2 char(1), modify vc3 char(255),
+  modify vb1 binary(1), modify vb2 binary(1), modify vb3 binary(255);
+INSERT INTO t2 VALUES(
+  repeat('a', 2), repeat('b', 128), repeat('c', 255),
+  repeat('d', 2), repeat('e', 128), repeat('f', 255),
+  repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+  repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+--enable_warnings
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed varness + 3rd degree demoted types:
+--echo *     char(2)            -->    varchar(1)
+--echo *     char(128)          -->    varchar(1)
+--echo *     char(255)          -->    varchar(1)
+--echo *     binary(2)          -->    varbinary(1)
+--echo *     binary(128)        -->    varbinary(1)
+--echo *     binary(255)        -->    varbinary(1)
+--echo *     varchar(2)         -->    char(1)
+--echo *     varchar(255)       -->    char(1)
+--echo *     varchar(1024)      -->    char(1)
+--echo *     varbinary(2)       -->    binary(1)
+--echo *     varbinary(255)     -->    binary(1)
+--echo *     varbinary(1024)    -->    binary(1)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+DELETE FROM t2;
+ALTER TABLE t2
+  modify c1 varchar(1), modify c2 varchar(1), modify c3 varchar(1),
+  modify b1 varbinary(1), modify b2 varbinary(1), modify b3 varbinary(1),
+  modify vc1 char(1), modify vc2 char(1), modify vc3 char(1),
+  modify vb1 binary(1), modify vb2 binary(1), modify vb3 binary(1);
+INSERT INTO t2 VALUES(
+  repeat('a', 2), repeat('b', 128), repeat('c', 255),
+  repeat('d', 2), repeat('e', 128), repeat('f', 255),
+  repeat('g', 2), repeat('h', 255), repeat('i', 1024),
+  repeat('j', 2), repeat('k', 255), repeat('l', 1024)
+);
+--enable_warnings
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t2_myisam ENGINE=MYISAM AS SELECT * FROM t2;
+
+# restore table
+DELETE FROM t2;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT
+  length(c1), length(c2), length(c3),
+  length(b1), length(b2), length(b2),
+  length(vc1), length(vc2), length(vc3),
+  length(vb1), length(vb2), length(vb3)
+FROM t2;
+
+# verify data
+SELECT COUNT(*) FROM t2 NATURAL JOIN t2_myisam;
+DROP TABLE t2_myisam;
+
+--echo ************************************************************
+--echo * Deleting table with char+binary types
+--echo ************************************************************
+
+DROP TABLE t2;

=== added file 'mysql-test/suite/ndb/t/ndb_restore_lossy_integral_conv.test'
--- a/mysql-test/suite/ndb/t/ndb_restore_lossy_integral_conv.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore_lossy_integral_conv.test	2010-10-22 06:00:55 +0000
@@ -0,0 +1,575 @@
+######################################################################
+# Author: Martin Zaun
+# Date: 2010-10
+# Purpose: Lossy conversion test for integral types
+######################################################################
+
+-- source include/have_ndb.inc
+
+# mysqld's configuration is not relevant to this test
+-- source include/not_embedded.inc
+
+--echo ************************************************************
+--echo * Creating table with integral types
+--echo ************************************************************
+
+CREATE TABLE t1(
+  t1 tinyint,  t2 tinyint,  ut1 tinyint unsigned,
+  s1 smallint,  s2 smallint,  us1 smallint unsigned,
+  m1 mediumint,  m2 mediumint,  um1 mediumint unsigned,
+  i1 int,  i2 int,  ui1 int unsigned,
+  b1 bigint,  b2 bigint,  ub1 bigint unsigned
+) ENGINE=NDB;
+
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+
+--echo ************************************************************
+--echo * Backing up table with integral types
+--echo ************************************************************
+
+--source include/ndb_backup.inc
+
+# command shortcuts
+#--let $restore_cmd=$NDB_RESTORE --no-defaults -b $the_backup_id -r
+#--let $restore_cmd=$restore_cmd --backup_path=$NDB_BACKUPS-$the_backup_id
+# for ndb 6.3:
+--let $restore_cmd=$NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id
+--let $restore_cmd=$restore_cmd -r --backup_path=$NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id
+
+--echo ************************************************************
+--echo * Restoring table with unchanged integral types:
+--echo *     tinyint[unsigned]  -->    tinyint[unsigned]
+--echo *    smallint[unsigned]  -->   smallint[unsigned]
+--echo *   mediumint[unsigned]  -->  mediumint[unsigned]
+--echo *         int[unsigned]  -->        int[unsigned]
+--echo *      bigint[unsigned]  -->     bigint[unsigned]
+--echo ************************************************************
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+# for debugging:
+#    --exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 1 -L -r --print $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+#    --exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 2 -L -r --print $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with 1st degree demoted integral types:
+--echo *     tinyint[unsigned]  -->    tinyint[unsigned]
+--echo *    smallint[unsigned]  -->    tinyint[unsigned]
+--echo *   mediumint[unsigned]  -->   smallint[unsigned]
+--echo *         int[unsigned]  -->  mediumint[unsigned]
+--echo *      bigint[unsigned]  -->        int[unsigned]
+--echo ************************************************************
+
+# demote integral type attibutes
+--disable_warnings
+ALTER TABLE t1
+  modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+  modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+  modify m1 smallint,  modify m2 smallint,  modify um1 smallint unsigned,
+  modify i1 mediumint,  modify i2 mediumint,  modify ui1 mediumint unsigned,
+  modify b1 int,  modify b2 int,  modify ub1 int unsigned;
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with 2nd degree demoted integral types:
+--echo *     tinyint[unsigned]  -->    tinyint[unsigned]
+--echo *    smallint[unsigned]  -->    tinyint[unsigned]
+--echo *   mediumint[unsigned]  -->    tinyint[unsigned]
+--echo *         int[unsigned]  -->   smallint[unsigned]
+--echo *      bigint[unsigned]  -->  mediumint[unsigned]
+--echo ************************************************************
+
+# demote integral type attibutes
+--disable_warnings
+ALTER TABLE t1
+  modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+  modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+  modify m1 tinyint,  modify m2 tinyint,  modify um1 tinyint unsigned,
+  modify i1 smallint,  modify i2 smallint,  modify ui1 smallint unsigned,
+  modify b1 mediumint,  modify b2 mediumint,  modify ub1 mediumint unsigned;
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with 3rd degree demoted integral types:
+--echo *     tinyint[unsigned]  -->    tinyint[unsigned]
+--echo *    smallint[unsigned]  -->    tinyint[unsigned]
+--echo *   mediumint[unsigned]  -->    tinyint[unsigned]
+--echo *         int[unsigned]  -->    tinyint[unsigned]
+--echo *      bigint[unsigned]  -->   smallint[unsigned]
+--echo ************************************************************
+
+# demote integral type attibutes
+--disable_warnings
+ALTER TABLE t1
+  modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+  modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+  modify m1 tinyint,  modify m2 tinyint,  modify um1 tinyint unsigned,
+  modify i1 tinyint,  modify i2 tinyint,  modify ui1 tinyint unsigned,
+  modify b1 smallint,  modify b2 smallint,  modify ub1 smallint unsigned;
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with 4th degree demoted integral types:
+--echo *     tinyint[unsigned]  -->    tinyint[unsigned]
+--echo *    smallint[unsigned]  -->    tinyint[unsigned]
+--echo *   mediumint[unsigned]  -->    tinyint[unsigned]
+--echo *         int[unsigned]  -->    tinyint[unsigned]
+--echo *      bigint[unsigned]  -->    tinyint[unsigned]
+--echo ************************************************************
+
+# demote integral type attibutes
+--disable_warnings
+ALTER TABLE t1
+  modify t1 tinyint,  modify t2 tinyint,  modify ut1 tinyint unsigned,
+  modify s1 tinyint,  modify s2 tinyint,  modify us1 tinyint unsigned,
+  modify m1 tinyint,  modify m2 tinyint,  modify um1 tinyint unsigned,
+  modify i1 tinyint,  modify i2 tinyint,  modify ui1 tinyint unsigned,
+  modify b1 tinyint,  modify b2 tinyint,  modify ub1 tinyint unsigned;
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness:
+--echo *     tinyint unsigned/signed  -->    tinyint signed/unsigned
+--echo *    smallint unsigned/signed  -->   smallint signed/unsigned
+--echo *   mediumint unsigned/signed  -->  mediumint signed/unsigned
+--echo *         int unsigned/signed  -->        int signed/unsigned
+--echo *      bigint unsigned/signed  -->     bigint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+  modify s1 smallint unsigned,  modify s2 smallint unsigned,  modify us1 smallint signed,
+  modify m1 mediumint unsigned,  modify m2 mediumint unsigned,  modify um1 mediumint signed,
+  modify i1 int unsigned,  modify i2 int unsigned,  modify ui1 int signed,
+  modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 1st degree promoted types:
+--echo *     tinyint unsigned/signed  -->   smallint signed/unsigned
+--echo *    smallint unsigned/signed  -->  mediumint signed/unsigned
+--echo *   mediumint unsigned/signed  -->        int signed/unsigned
+--echo *         int unsigned/signed  -->     bigint signed/unsigned
+--echo *      bigint unsigned/signed  -->     bigint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 smallint unsigned,  modify t2 smallint unsigned,  modify ut1 smallint signed,
+  modify s1 mediumint unsigned,  modify s2 mediumint unsigned,  modify us1 mediumint signed,
+  modify m1 int unsigned,  modify m2 int unsigned,  modify um1 int signed,
+  modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+  modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 2nd degree promoted types:
+--echo *     tinyint unsigned/signed  -->  mediumint signed/unsigned
+--echo *    smallint unsigned/signed  -->        int signed/unsigned
+--echo *   mediumint unsigned/signed  -->     bigint signed/unsigned
+--echo *         int unsigned/signed  -->     bigint signed/unsigned
+--echo *      bigint unsigned/signed  -->     bigint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 mediumint unsigned,  modify t2 mediumint unsigned,  modify ut1 mediumint signed,
+  modify s1 int unsigned,  modify s2 int unsigned,  modify us1 int signed,
+  modify m1 bigint unsigned,  modify m2 bigint unsigned,  modify um1 bigint signed,
+  modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+  modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 3rd degree promoted types:
+--echo *     tinyint unsigned/signed  -->        int signed/unsigned
+--echo *    smallint unsigned/signed  -->     bigint signed/unsigned
+--echo *   mediumint unsigned/signed  -->     bigint signed/unsigned
+--echo *         int unsigned/signed  -->     bigint signed/unsigned
+--echo *      bigint unsigned/signed  -->     bigint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 int unsigned,  modify t2 int unsigned,  modify ut1 int signed,
+  modify s1 bigint unsigned,  modify s2 bigint unsigned,  modify us1 bigint signed,
+  modify m1 bigint unsigned,  modify m2 bigint unsigned,  modify um1 bigint signed,
+  modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+  modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 4th degree promoted types:
+--echo *     tinyint unsigned/signed  -->     bigint signed/unsigned
+--echo *    smallint unsigned/signed  -->     bigint signed/unsigned
+--echo *   mediumint unsigned/signed  -->     bigint signed/unsigned
+--echo *         int unsigned/signed  -->     bigint signed/unsigned
+--echo *      bigint unsigned/signed  -->     bigint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 bigint unsigned,  modify t2 bigint unsigned,  modify ut1 bigint signed,
+  modify s1 bigint unsigned,  modify s2 bigint unsigned,  modify us1 bigint signed,
+  modify m1 bigint unsigned,  modify m2 bigint unsigned,  modify um1 bigint signed,
+  modify i1 bigint unsigned,  modify i2 bigint unsigned,  modify ui1 bigint signed,
+  modify b1 bigint unsigned,  modify b2 bigint unsigned,  modify ub1 bigint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 1st degree demoted types:
+--echo *     tinyint unsigned/signed  -->    tinyint signed/unsigned
+--echo *    smallint unsigned/signed  -->    tinyint signed/unsigned
+--echo *   mediumint unsigned/signed  -->   smallint signed/unsigned
+--echo *         int unsigned/signed  -->  mediumint signed/unsigned
+--echo *      bigint unsigned/signed  -->        int signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+  modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+  modify m1 smallint unsigned,  modify m2 smallint unsigned,  modify um1 smallint signed,
+  modify i1 mediumint unsigned,  modify i2 mediumint unsigned,  modify ui1 mediumint signed,
+  modify b1 int unsigned,  modify b2 int unsigned,  modify ub1 int signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 2nd degree demoted types:
+--echo *     tinyint unsigned/signed  -->    tinyint signed/unsigned
+--echo *    smallint unsigned/signed  -->    tinyint signed/unsigned
+--echo *   mediumint unsigned/signed  -->    tinyint signed/unsigned
+--echo *         int unsigned/signed  -->   smallint signed/unsigned
+--echo *      bigint unsigned/signed  -->  mediumint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+  modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+  modify m1 tinyint unsigned,  modify m2 tinyint unsigned,  modify um1 tinyint signed,
+  modify i1 smallint unsigned,  modify i2 smallint unsigned,  modify ui1 smallint signed,
+  modify b1 mediumint unsigned,  modify b2 mediumint unsigned,  modify ub1 mediumint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 3rd degree demoted types:
+--echo *     tinyint unsigned/signed  -->    tinyint signed/unsigned
+--echo *    smallint unsigned/signed  -->    tinyint signed/unsigned
+--echo *   mediumint unsigned/signed  -->    tinyint signed/unsigned
+--echo *         int unsigned/signed  -->    tinyint signed/unsigned
+--echo *      bigint unsigned/signed  -->   smallint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+  modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+  modify m1 tinyint unsigned,  modify m2 tinyint unsigned,  modify um1 tinyint signed,
+  modify i1 tinyint unsigned,  modify i2 tinyint unsigned,  modify ui1 tinyint signed,
+  modify b1 smallint unsigned,  modify b2 smallint unsigned,  modify ub1 smallint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with changed signedness + 4th degree demoted types:
+--echo *     tinyint unsigned/signed  -->    tinyint signed/unsigned
+--echo *    smallint unsigned/signed  -->    tinyint signed/unsigned
+--echo *   mediumint unsigned/signed  -->    tinyint signed/unsigned
+--echo *         int unsigned/signed  -->    tinyint signed/unsigned
+--echo *      bigint unsigned/signed  -->    tinyint signed/unsigned
+--echo ************************************************************
+
+# convert signedness of integral type attibutes
+--disable_warnings
+DELETE FROM t1;
+ALTER TABLE t1
+  modify t1 tinyint unsigned,  modify t2 tinyint unsigned,  modify ut1 tinyint signed,
+  modify s1 tinyint unsigned,  modify s2 tinyint unsigned,  modify us1 tinyint signed,
+  modify m1 tinyint unsigned,  modify m2 tinyint unsigned,  modify um1 tinyint signed,
+  modify i1 tinyint unsigned,  modify i2 tinyint unsigned,  modify ui1 tinyint signed,
+  modify b1 tinyint unsigned,  modify b2 tinyint unsigned,  modify ub1 tinyint signed;
+INSERT INTO t1 VALUES(
+  -128, 127, 255,
+  -32768, 32767, 65535,
+  -8388608, 8388607, 16777215,
+  -2147483648, 2147483647, 4294967295,
+  -9223372036854775808, 9223372036854775807, 18446744073709551615
+);
+--enable_warnings
+SELECT * FROM t1;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t1_myisam ENGINE=MYISAM AS SELECT * FROM t1;
+
+# restore table
+DELETE FROM t1;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT * FROM t1;
+
+# verify data
+SELECT COUNT(*) FROM t1 NATURAL JOIN t1_myisam;
+DROP TABLE t1_myisam;
+
+--echo ************************************************************
+--echo * Deleting table with integral types
+--echo ************************************************************
+
+DROP TABLE t1;

=== added file 'mysql-test/suite/ndb/t/ndb_restore_padding_preservation.test'
--- a/mysql-test/suite/ndb/t/ndb_restore_padding_preservation.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore_padding_preservation.test	2010-10-22 06:00:55 +0000
@@ -0,0 +1,265 @@
+######################################################################
+# Author: Martin Zaun
+# Date: 2010-10
+# Purpose: Right-padding preservation test for char and binary types
+######################################################################
+
+-- source include/have_ndb.inc
+
+# mysqld's configuration is not relevant to this test
+-- source include/not_embedded.inc
+
+--echo ************************************************************
+--echo * Creating table with char+binary types
+--echo ************************************************************
+
+CREATE TABLE t3(
+  c1 char(32),
+  b1 binary(32)
+) ENGINE=NDB;
+
+INSERT INTO t3 VALUES('aaaaaaaa', 'bbbbbbbb');
+SELECT length(c1), length(b1) FROM t3;
+
+--echo ************************************************************
+--echo * Backing up table with char+binary types
+--echo ************************************************************
+
+--source include/ndb_backup.inc
+
+# command shortcuts
+#--let $restore_cmd=$NDB_RESTORE --no-defaults -b $the_backup_id -r
+#--let $restore_cmd=$restore_cmd --backup_path=$NDB_BACKUPS-$the_backup_id
+# for ndb 6.3:
+--let $restore_cmd=$NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id
+--let $restore_cmd=$restore_cmd -r --backup_path=$NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id
+
+--echo ************************************************************
+--echo * Restoring table with unchanged char+binary types (sanity check):
+--echo *     char(32)           -->    char(32)
+--echo *     binary(32)         -->    binary(32)
+--echo ************************************************************
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+# for debugging:
+#    --exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 1 -L -r --print $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+#    --exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 2 -L -r --print $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $restore_cmd -n 1 --print > /dev/null
+--exec $restore_cmd -n 2 --print > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with promoted char+binary types preserving padding:
+--echo *     char(32)           -->    varchar(32)
+--echo *     binary(32)         -->    varbinary(32)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t3 MODIFY c1 varchar(32), MODIFY b1 varbinary(32);
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -A -P > /dev/null
+--exec $restore_cmd -n 2 --print -A -P > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with promoted char+binary types preserving padding:
+--echo *     char(32)           -->    varchar(64)
+--echo *     binary(32)         -->    varbinary(64)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t3 MODIFY c1 varchar(64), MODIFY b1 varbinary(64);
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -A -P > /dev/null
+--exec $restore_cmd -n 2 --print -A -P > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with promoted char+binary types preserving padding:
+--echo *     char(32)           -->    varchar(512)
+--echo *     binary(32)         -->    varbinary(512)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t3 MODIFY c1 varchar(512), MODIFY b1 varbinary(512);
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -A -P > /dev/null
+--exec $restore_cmd -n 2 --print -A -P > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with demoted char+binary types preserving padding:
+--echo *     char(32)           -->    varchar(16)
+--echo *     binary(32)         -->    varbinary(16)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t3 MODIFY c1 varchar(16), MODIFY b1 varbinary(16);
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -L -P > /dev/null
+--exec $restore_cmd -n 2 --print -L -P > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with promoted char+binary types discarding padding:
+--echo *     char(32)           -->    varchar(32)
+--echo *     binary(32)         -->    varbinary(32)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+DELETE FROM t3;
+ALTER TABLE t3 MODIFY c1 varchar(32), MODIFY b1 varbinary(32);
+INSERT INTO t3 VALUES('aaaaaaaa', 'bbbbbbbb');
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -A > /dev/null
+--exec $restore_cmd -n 2 --print -A > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with promoted char+binary types discarding padding:
+--echo *     char(32)           -->    varchar(64)
+--echo *     binary(32)         -->    varbinary(64)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t3 MODIFY c1 varchar(64), MODIFY b1 varbinary(64);
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -A > /dev/null
+--exec $restore_cmd -n 2 --print -A > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with promoted char+binary types discarding padding:
+--echo *     char(32)           -->    varchar(512)
+--echo *     binary(32)         -->    varbinary(512)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t3 MODIFY c1 varchar(512), MODIFY b1 varbinary(512);
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -A > /dev/null
+--exec $restore_cmd -n 2 --print -A > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Restoring table with demoted char+binary types discarding padding:
+--echo *     char(32)           -->    varchar(16)
+--echo *     binary(32)         -->    varbinary(16)
+--echo ************************************************************
+
+# demote char+binary type attibutes
+--disable_warnings
+ALTER TABLE t3 MODIFY c1 varchar(16), MODIFY b1 varbinary(16);
+--enable_warnings
+SELECT length(c1), length(b1) FROM t3;
+
+# create a MyISAM table from NDB table, against which to compare data
+CREATE TABLE t3_myisam ENGINE=MYISAM AS SELECT * FROM t3;
+
+# restore table
+DELETE FROM t3;
+--exec $restore_cmd -n 1 --print -L > /dev/null
+--exec $restore_cmd -n 2 --print -L > /dev/null
+SELECT length(c1), length(b1) FROM t3;
+
+# verify data
+SELECT COUNT(*) FROM t3 NATURAL JOIN t3_myisam;
+DROP TABLE t3_myisam;
+
+--echo ************************************************************
+--echo * Deleting table with char+binary types
+--echo ************************************************************
+
+DROP TABLE t3;

=== modified file 'storage/ndb/tools/restore/Restore.cpp'
--- a/storage/ndb/tools/restore/Restore.cpp	2010-05-24 09:51:13 +0000
+++ b/storage/ndb/tools/restore/Restore.cpp	2010-10-22 01:15:45 +0000
@@ -813,7 +813,7 @@ TableS * TupleS::getTable() const {
   return m_currentTable;
 }
 
-const AttributeDesc * TupleS::getDesc(int i) const {
+AttributeDesc * TupleS::getDesc(int i) const {
   return m_currentTable->allAttributesDesc[i];
 }
 
@@ -932,6 +932,11 @@ RestoreDataIterator::getNextTuple(int  &
   return &m_tuple;
 } // RestoreDataIterator::getNextTuple
 
+TableS *
+RestoreDataIterator::getCurrentTable()
+{
+  return m_currentTable;
+}
 
 int
 RestoreDataIterator::readTupleData_packed(Uint32 *buf_ptr, 
@@ -1584,7 +1589,7 @@ RestoreDataIterator::validateFragmentFoo
 } // RestoreDataIterator::getFragmentFooter
 
 AttributeDesc::AttributeDesc(NdbDictionary::Column *c)
-  : m_column(c)
+  : m_column(c), truncation_detected(false)
 {
   size = 8*NdbColumnImpl::getImpl(* c).m_attrSize;
   arraySize = NdbColumnImpl::getImpl(* c).m_arraySize;
@@ -1644,7 +1649,7 @@ TableS::get_auto_data(const TupleS & tup
     the found SYSKEY value is a valid table_id (< 0x10000000).
    */
   AttributeData * attr_data = tuple.getData(0);
-  const AttributeDesc * attr_desc = tuple.getDesc(0);
+  AttributeDesc * attr_desc = tuple.getDesc(0);
   const AttributeS attr1 = {attr_desc, *attr_data};
   memcpy(syskey ,attr1.Data.u_int32_value, sizeof(Uint32));
   attr_data = tuple.getData(1);
@@ -1810,7 +1815,7 @@ RestoreLogIterator::getNextLogEntry(int 
     if(unlikely(!m_hostByteOrder))
       *(Uint32*)ah = Twiddle32(*(Uint32*)ah);
 
-    attr->Desc = (* tab)[ah->getAttributeId()];
+    attr->Desc = tab->getAttributeDesc(ah->getAttributeId());
     assert(attr->Desc != 0);
 
     const Uint32 sz = ah->getDataSize();
@@ -1862,7 +1867,7 @@ operator<<(NdbOut& ndbout, const TupleS&
     if (i > 0)
       ndbout << g_ndbrecord_print_format.fields_terminated_by;
     AttributeData * attr_data = tuple.getData(i);
-    const AttributeDesc * attr_desc = tuple.getDesc(i);
+    AttributeDesc * attr_desc = tuple.getDesc(i);
     const AttributeS attr = {attr_desc, *attr_data};
     debug << i << " " << attr_desc->m_column->getName();
     ndbout << attr;

=== modified file 'storage/ndb/tools/restore/Restore.hpp'
--- a/storage/ndb/tools/restore/Restore.hpp	2010-08-20 10:18:47 +0000
+++ b/storage/ndb/tools/restore/Restore.hpp	2010-10-22 01:15:45 +0000
@@ -34,14 +34,19 @@
 enum TableChangesMask
 {
   /**
-   * Allow attribute promotion
+   * Allow attribute type promotion
    */
   TCM_ATTRIBUTE_PROMOTION = 0x1,
 
   /**
    * Allow missing columns
    */
-  TCM_EXCLUDE_MISSING_COLUMNS = 0x2
+  TCM_EXCLUDE_MISSING_COLUMNS = 0x2,
+
+  /**
+   * Allow attribute type demotion and integral signed/unsigned type changes.
+   */
+  TCM_ATTRIBUTE_DEMOTION = 0x4
 };
 
 inline
@@ -53,10 +58,9 @@ isDrop6(Uint32 version)
 
 typedef NdbDictionary::Table NDBTAB;
 typedef NdbDictionary::Column NDBCOL;
-typedef  bool (*AttrCheckCompatFunc)(const NDBCOL &old_col,
-                                     const NDBCOL &new_col);
 typedef  void* (*AttrConvertFunc)(const void *old_data, 
-                                  void *parameter);
+                                  void *parameter,
+                                  bool &truncated);
 
 struct AttributeData {
   bool null;
@@ -96,6 +100,8 @@ struct AttributeDesc {
   Uint32 m_nullBitIndex;
   AttrConvertFunc convertFunc;
   void *parameter;
+  bool truncation_detected;
+
 public:
   
   AttributeDesc(NdbDictionary::Column *column);
@@ -109,7 +115,7 @@ public:
 }; // AttributeDesc
 
 struct AttributeS {
-  const AttributeDesc * Desc;
+  AttributeDesc * Desc;
   AttributeData Data;
 };
 
@@ -135,7 +141,7 @@ public:
   TupleS & operator=(const TupleS& tuple);
   int getNoOfAttributes() const;
   TableS * getTable() const;
-  const AttributeDesc * getDesc(int i) const;
+  AttributeDesc * getDesc(int i) const;
   AttributeData * getData(int i) const;
 }; // class TupleS
 
@@ -418,6 +424,7 @@ public:
   bool validateFragmentFooter();
 
   const TupleS *getNextTuple(int & res);
+  TableS *getCurrentTable();
 
 private:
   void init_bitfield_storage(const NdbDictionary::Table*);

=== modified file 'storage/ndb/tools/restore/consumer_restore.cpp'
--- a/storage/ndb/tools/restore/consumer_restore.cpp	2010-10-21 08:51:09 +0000
+++ b/storage/ndb/tools/restore/consumer_restore.cpp	2010-10-22 01:15:45 +0000
@@ -44,42 +44,132 @@ bool BackupRestore::m_preserve_trailing_
 
 const PromotionRules 
 BackupRestore::m_allowed_promotion_attrs[] = {
-  {NDBCOL::Char,           NDBCOL::Char,           check_compat_common,     convert_char_char},
-  {NDBCOL::Varchar,        NDBCOL::Varchar,        check_compat_common,     convert_var_var},
-  {NDBCOL::Longvarchar,    NDBCOL::Longvarchar,    check_compat_common,     convert_longvar_longvar},
-  {NDBCOL::Varchar,        NDBCOL::Longvarchar,    check_compat_common,     convert_var_longvar},
-  {NDBCOL::Varbinary,      NDBCOL::Varbinary,      check_compat_common,     convert_var_var},
-  {NDBCOL::Longvarbinary,  NDBCOL::Longvarbinary,  check_compat_common,     convert_longvar_longvar},
-  {NDBCOL::Varbinary,      NDBCOL::Longvarbinary,  check_compat_common,     convert_var_longvar},
-  {NDBCOL::Binary,         NDBCOL::Binary,         check_compat_common,     convert_binary_binary},
-  {NDBCOL::Char,           NDBCOL::Varchar,        check_compat_common,     convert_char_varchar},
-  {NDBCOL::Char,           NDBCOL::Longvarchar,    check_compat_common,     convert_char_longvarchar},  
-  {NDBCOL::Binary,         NDBCOL::Varbinary,      check_compat_common,     convert_binary_varbinary},
-  {NDBCOL::Binary,         NDBCOL::Longvarbinary,  check_compat_common,     convert_binary_longvarbinary},
-  {NDBCOL::Bit,            NDBCOL::Bit,            check_compat_common,     convert_bit_bit},
-
-  {NDBCOL::Tinyint,        NDBCOL::Smallint,       check_compat_alwaystrue, convert_int8_int16},
-  {NDBCOL::Tinyint,        NDBCOL::Mediumint,      check_compat_alwaystrue, convert_int8_int24},
-  {NDBCOL::Tinyint,        NDBCOL::Int,            check_compat_alwaystrue, convert_int8_int32},
-  {NDBCOL::Tinyint,        NDBCOL::Bigint,         check_compat_alwaystrue, convert_int8_int64},
-  {NDBCOL::Smallint,       NDBCOL::Mediumint,      check_compat_alwaystrue, convert_int16_int24},
-  {NDBCOL::Smallint,       NDBCOL::Int,            check_compat_alwaystrue, convert_int16_int32},
-  {NDBCOL::Smallint,       NDBCOL::Bigint,         check_compat_alwaystrue, convert_int16_int64},
-  {NDBCOL::Mediumint,      NDBCOL::Int,            check_compat_alwaystrue, convert_int24_int32},
-  {NDBCOL::Mediumint,      NDBCOL::Bigint,         check_compat_alwaystrue, convert_int24_int64},
-  {NDBCOL::Int,            NDBCOL::Bigint,         check_compat_alwaystrue, convert_int32_int64},
-  {NDBCOL::Tinyunsigned,   NDBCOL::Smallunsigned,  check_compat_alwaystrue, convert_uint8_uint16},
-  {NDBCOL::Tinyunsigned,   NDBCOL::Mediumunsigned, check_compat_alwaystrue, convert_uint8_uint24},
-  {NDBCOL::Tinyunsigned,   NDBCOL::Unsigned,       check_compat_alwaystrue, convert_uint8_uint32},
-  {NDBCOL::Tinyunsigned,   NDBCOL::Bigunsigned,    check_compat_alwaystrue, convert_uint8_uint64},
-  {NDBCOL::Smallunsigned,  NDBCOL::Mediumunsigned, check_compat_alwaystrue, convert_uint16_uint24},
-  {NDBCOL::Smallunsigned,  NDBCOL::Unsigned,       check_compat_alwaystrue, convert_uint16_uint32},
-  {NDBCOL::Smallunsigned,  NDBCOL::Bigunsigned,    check_compat_alwaystrue, convert_uint16_uint64},
-  {NDBCOL::Mediumunsigned, NDBCOL::Unsigned,       check_compat_alwaystrue, convert_uint24_uint32},
-  {NDBCOL::Mediumunsigned, NDBCOL::Bigunsigned,    check_compat_alwaystrue, convert_uint24_uint64},
-  {NDBCOL::Unsigned,       NDBCOL::Bigunsigned,    check_compat_alwaystrue, convert_uint32_uint64},
+  // char promotions/demotions
+  {NDBCOL::Char,           NDBCOL::Char,           check_compat_sizes,     convert_char_char},
+  {NDBCOL::Char,           NDBCOL::Varchar,        check_compat_sizes,     convert_char_varchar},
+  {NDBCOL::Char,           NDBCOL::Longvarchar,    check_compat_sizes,     convert_char_longvarchar},
+  {NDBCOL::Varchar,        NDBCOL::Char,           check_compat_sizes,     convert_varchar_char},
+  {NDBCOL::Varchar,        NDBCOL::Varchar,        check_compat_sizes,     convert_var_var},
+  {NDBCOL::Varchar,        NDBCOL::Longvarchar,    check_compat_sizes,     convert_var_longvar},
+  {NDBCOL::Longvarchar,    NDBCOL::Char,           check_compat_sizes,     convert_longvarchar_char},
+  {NDBCOL::Longvarchar,    NDBCOL::Varchar,        check_compat_sizes,     convert_longvar_var},
+  {NDBCOL::Longvarchar,    NDBCOL::Longvarchar,    check_compat_sizes,     convert_longvar_longvar},
+
+  // binary promotions/demotions
+  {NDBCOL::Binary,         NDBCOL::Binary,         check_compat_sizes,     convert_binary_binary},
+  {NDBCOL::Binary,         NDBCOL::Varbinary,      check_compat_sizes,     convert_binary_varbinary},
+  {NDBCOL::Binary,         NDBCOL::Longvarbinary,  check_compat_sizes,     convert_binary_longvarbinary},
+  {NDBCOL::Varbinary,      NDBCOL::Binary,         check_compat_sizes,     convert_varbinary_binary},
+  {NDBCOL::Varbinary,      NDBCOL::Varbinary,      check_compat_sizes,     convert_var_var},
+  {NDBCOL::Varbinary,      NDBCOL::Longvarbinary,  check_compat_sizes,     convert_var_longvar},
+  {NDBCOL::Longvarbinary,  NDBCOL::Binary,         check_compat_sizes,     convert_longvarbinary_binary},
+  {NDBCOL::Longvarbinary,  NDBCOL::Varbinary,      check_compat_sizes,     convert_longvar_var},
+  {NDBCOL::Longvarbinary,  NDBCOL::Longvarbinary,  check_compat_sizes,     convert_longvar_longvar},
+
+  // bitset promotions/demotions
+  {NDBCOL::Bit,            NDBCOL::Bit,            check_compat_sizes,     convert_bit_bit},
+
+  // integral promotions
+  {NDBCOL::Tinyint,        NDBCOL::Smallint,       check_compat_promotion, convert_int8_int16},
+  {NDBCOL::Tinyint,        NDBCOL::Mediumint,      check_compat_promotion, convert_int8_int24},
+  {NDBCOL::Tinyint,        NDBCOL::Int,            check_compat_promotion, convert_int8_int32},
+  {NDBCOL::Tinyint,        NDBCOL::Bigint,         check_compat_promotion, convert_int8_int64},
+  {NDBCOL::Smallint,       NDBCOL::Mediumint,      check_compat_promotion, convert_int16_int24},
+  {NDBCOL::Smallint,       NDBCOL::Int,            check_compat_promotion, convert_int16_int32},
+  {NDBCOL::Smallint,       NDBCOL::Bigint,         check_compat_promotion, convert_int16_int64},
+  {NDBCOL::Mediumint,      NDBCOL::Int,            check_compat_promotion, convert_int24_int32},
+  {NDBCOL::Mediumint,      NDBCOL::Bigint,         check_compat_promotion, convert_int24_int64},
+  {NDBCOL::Int,            NDBCOL::Bigint,         check_compat_promotion, convert_int32_int64},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Smallunsigned,  check_compat_promotion, convert_uint8_uint16},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Mediumunsigned, check_compat_promotion, convert_uint8_uint24},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Unsigned,       check_compat_promotion, convert_uint8_uint32},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Bigunsigned,    check_compat_promotion, convert_uint8_uint64},
+  {NDBCOL::Smallunsigned,  NDBCOL::Mediumunsigned, check_compat_promotion, convert_uint16_uint24},
+  {NDBCOL::Smallunsigned,  NDBCOL::Unsigned,       check_compat_promotion, convert_uint16_uint32},
+  {NDBCOL::Smallunsigned,  NDBCOL::Bigunsigned,    check_compat_promotion, convert_uint16_uint64},
+  {NDBCOL::Mediumunsigned, NDBCOL::Unsigned,       check_compat_promotion, convert_uint24_uint32},
+  {NDBCOL::Mediumunsigned, NDBCOL::Bigunsigned,    check_compat_promotion, convert_uint24_uint64},
+  {NDBCOL::Unsigned,       NDBCOL::Bigunsigned,    check_compat_promotion, convert_uint32_uint64},
+
+  // integral demotions
+  {NDBCOL::Smallint,       NDBCOL::Tinyint,        check_compat_lossy, convert_int16_int8},
+  {NDBCOL::Mediumint,      NDBCOL::Tinyint,        check_compat_lossy, convert_int24_int8},
+  {NDBCOL::Mediumint,      NDBCOL::Smallint,       check_compat_lossy, convert_int24_int16},
+  {NDBCOL::Int,            NDBCOL::Tinyint,        check_compat_lossy, convert_int32_int8},
+  {NDBCOL::Int,            NDBCOL::Smallint,       check_compat_lossy, convert_int32_int16},
+  {NDBCOL::Int,            NDBCOL::Mediumint,      check_compat_lossy, convert_int32_int24},
+  {NDBCOL::Bigint,         NDBCOL::Tinyint,        check_compat_lossy, convert_int64_int8},
+  {NDBCOL::Bigint,         NDBCOL::Smallint,       check_compat_lossy, convert_int64_int16},
+  {NDBCOL::Bigint,         NDBCOL::Mediumint,      check_compat_lossy, convert_int64_int24},
+  {NDBCOL::Bigint,         NDBCOL::Int,            check_compat_lossy, convert_int64_int32},
+  {NDBCOL::Smallunsigned,  NDBCOL::Tinyunsigned,   check_compat_lossy, convert_uint16_uint8},
+  {NDBCOL::Mediumunsigned, NDBCOL::Tinyunsigned,   check_compat_lossy, convert_uint24_uint8},
+  {NDBCOL::Mediumunsigned, NDBCOL::Smallunsigned,  check_compat_lossy, convert_uint24_uint16},
+  {NDBCOL::Unsigned,       NDBCOL::Tinyunsigned,   check_compat_lossy, convert_uint32_uint8},
+  {NDBCOL::Unsigned,       NDBCOL::Smallunsigned,  check_compat_lossy, convert_uint32_uint16},
+  {NDBCOL::Unsigned,       NDBCOL::Mediumunsigned, check_compat_lossy, convert_uint32_uint24},
+  {NDBCOL::Bigunsigned,    NDBCOL::Tinyunsigned,   check_compat_lossy, convert_uint64_uint8},
+  {NDBCOL::Bigunsigned,    NDBCOL::Smallunsigned,  check_compat_lossy, convert_uint64_uint16},
+  {NDBCOL::Bigunsigned,    NDBCOL::Mediumunsigned, check_compat_lossy, convert_uint64_uint24},
+  {NDBCOL::Bigunsigned,    NDBCOL::Unsigned,       check_compat_lossy, convert_uint64_uint32},
+
+  // integral signedness conversions
+  {NDBCOL::Tinyint,        NDBCOL::Tinyunsigned,   check_compat_lossy, convert_int8_uint8},
+  {NDBCOL::Smallint,       NDBCOL::Smallunsigned,  check_compat_lossy, convert_int16_uint16},
+  {NDBCOL::Mediumint,      NDBCOL::Mediumunsigned, check_compat_lossy, convert_int24_uint24},
+  {NDBCOL::Int,            NDBCOL::Unsigned,       check_compat_lossy, convert_int32_uint32},
+  {NDBCOL::Bigint,         NDBCOL::Bigunsigned,    check_compat_lossy, convert_int64_uint64},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Tinyint,        check_compat_lossy, convert_uint8_int8},
+  {NDBCOL::Smallunsigned,  NDBCOL::Smallint,       check_compat_lossy, convert_uint16_int16},
+  {NDBCOL::Mediumunsigned, NDBCOL::Mediumint,      check_compat_lossy, convert_uint24_int24},
+  {NDBCOL::Unsigned,       NDBCOL::Int,            check_compat_lossy, convert_uint32_int32},
+  {NDBCOL::Bigunsigned,    NDBCOL::Bigint,         check_compat_lossy, convert_uint64_int64},
+
+  // integral signedness+promotion conversions
+  {NDBCOL::Tinyint,        NDBCOL::Smallunsigned,  check_compat_lossy, convert_int8_uint16},
+  {NDBCOL::Tinyint,        NDBCOL::Mediumunsigned, check_compat_lossy, convert_int8_uint24},
+  {NDBCOL::Tinyint,        NDBCOL::Unsigned,       check_compat_lossy, convert_int8_uint32},
+  {NDBCOL::Tinyint,        NDBCOL::Bigunsigned,    check_compat_lossy, convert_int8_uint64},
+  {NDBCOL::Smallint,       NDBCOL::Mediumunsigned, check_compat_lossy, convert_int16_uint24},
+  {NDBCOL::Smallint,       NDBCOL::Unsigned,       check_compat_lossy, convert_int16_uint32},
+  {NDBCOL::Smallint,       NDBCOL::Bigunsigned,    check_compat_lossy, convert_int16_uint64},
+  {NDBCOL::Mediumint,      NDBCOL::Unsigned,       check_compat_lossy, convert_int24_uint32},
+  {NDBCOL::Mediumint,      NDBCOL::Bigunsigned,    check_compat_lossy, convert_int24_uint64},
+  {NDBCOL::Int,            NDBCOL::Bigunsigned,    check_compat_lossy, convert_int32_uint64},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Smallint,       check_compat_lossy, convert_uint8_int16},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Mediumint,      check_compat_lossy, convert_uint8_int24},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Int,            check_compat_lossy, convert_uint8_int32},
+  {NDBCOL::Tinyunsigned,   NDBCOL::Bigint,         check_compat_lossy, convert_uint8_int64},
+  {NDBCOL::Smallunsigned,  NDBCOL::Mediumint,      check_compat_lossy, convert_uint16_int24},
+  {NDBCOL::Smallunsigned,  NDBCOL::Int,            check_compat_lossy, convert_uint16_int32},
+  {NDBCOL::Smallunsigned,  NDBCOL::Bigint,         check_compat_lossy, convert_uint16_int64},
+  {NDBCOL::Mediumunsigned, NDBCOL::Int,            check_compat_lossy, convert_uint24_int32},
+  {NDBCOL::Mediumunsigned, NDBCOL::Bigint,         check_compat_lossy, convert_uint24_int64},
+  {NDBCOL::Unsigned,       NDBCOL::Bigint,         check_compat_lossy, convert_uint32_int64},
+
+  // integral signedness+demotion conversions
+  {NDBCOL::Smallint,       NDBCOL::Tinyunsigned,   check_compat_lossy, convert_int16_uint8},
+  {NDBCOL::Mediumint,      NDBCOL::Tinyunsigned,   check_compat_lossy, convert_int24_uint8},
+  {NDBCOL::Mediumint,      NDBCOL::Smallunsigned,  check_compat_lossy, convert_int24_uint16},
+  {NDBCOL::Int,            NDBCOL::Tinyunsigned,   check_compat_lossy, convert_int32_uint8},
+  {NDBCOL::Int,            NDBCOL::Smallunsigned,  check_compat_lossy, convert_int32_uint16},
+  {NDBCOL::Int,            NDBCOL::Mediumunsigned, check_compat_lossy, convert_int32_uint24},
+  {NDBCOL::Bigint,         NDBCOL::Tinyunsigned,   check_compat_lossy, convert_int64_uint8},
+  {NDBCOL::Bigint,         NDBCOL::Smallunsigned,  check_compat_lossy, convert_int64_uint16},
+  {NDBCOL::Bigint,         NDBCOL::Mediumunsigned, check_compat_lossy, convert_int64_uint24},
+  {NDBCOL::Bigint,         NDBCOL::Unsigned,       check_compat_lossy, convert_int64_uint32},
+  {NDBCOL::Smallunsigned,  NDBCOL::Tinyint,        check_compat_lossy, convert_uint16_int8},
+  {NDBCOL::Mediumunsigned, NDBCOL::Tinyint,        check_compat_lossy, convert_uint24_int8},
+  {NDBCOL::Mediumunsigned, NDBCOL::Smallint,       check_compat_lossy, convert_uint24_int16},
+  {NDBCOL::Unsigned,       NDBCOL::Tinyint,        check_compat_lossy, convert_uint32_int8},
+  {NDBCOL::Unsigned,       NDBCOL::Smallint,       check_compat_lossy, convert_uint32_int16},
+  {NDBCOL::Unsigned,       NDBCOL::Mediumint,      check_compat_lossy, convert_uint32_int24},
+  {NDBCOL::Bigunsigned,    NDBCOL::Tinyint,        check_compat_lossy, convert_uint64_int8},
+  {NDBCOL::Bigunsigned,    NDBCOL::Smallint,       check_compat_lossy, convert_uint64_int16},
+  {NDBCOL::Bigunsigned,    NDBCOL::Mediumint,      check_compat_lossy, convert_uint64_int24},
+  {NDBCOL::Bigunsigned,    NDBCOL::Int,            check_compat_lossy, convert_uint64_int32},
 
-  {NDBCOL::Undefined,      NDBCOL::Undefined,      NULL,                     NULL}
+  {NDBCOL::Undefined,      NDBCOL::Undefined,      NULL,                  NULL}
 };
 
 bool
@@ -922,7 +1012,8 @@ BackupRestore::column_compatible_check(c
   if (backupCol->getType() != dbCol->getType())
   {
     info << "Column " << tableName << "." << backupCol->getName()
-         << " has different type in DB.  Promotion may be required." << endl;
+         << (" has different type in DB; promotion or lossy type conversion"
+             " (demotion, signed/unsigned) may be required.") << endl;
     similarEnough = false;
   }
 
@@ -1165,74 +1256,92 @@ BackupRestore::table_compatible_check(co
     {
       continue;
     }
-    else
-    {
+
+    NDBCOL::Type type_in_backup = col_in_backup->getType();
+    NDBCOL::Type type_in_kernel = col_in_kernel->getType();
+    attrCheckCompatFunc = get_attr_check_compatability(type_in_backup,
+                                                       type_in_kernel);
+    AttrConvType compat
+      = (attrCheckCompatFunc == NULL ? ACT_UNSUPPORTED
+         : attrCheckCompatFunc(*col_in_backup, *col_in_kernel));
+    switch (compat) {
+    case ACT_UNSUPPORTED:
+      {
+        err << "Table: "<< tablename
+            << " column: " << col_in_backup->getName()
+            << " incompatible with kernel's definition" << endl;
+        return false;
+      }
+    case ACT_PRESERVING:
       if ((m_tableChangesMask & TCM_ATTRIBUTE_PROMOTION) == 0)
       {
         err << "Table: "<< tablename
             << " column: " << col_in_backup->getName()
-            << " not equal with DB's definition"
+            << " promotable to kernel's definition but option"
             << " promote-attributes not specified" << endl;
         return false;
       }
+      break;
+    case ACT_LOSSY:
+      if ((m_tableChangesMask & TCM_ATTRIBUTE_DEMOTION) == 0)
+      {
+        err << "Table: "<< tablename
+            << " column: " << col_in_backup->getName()
+            << " convertable to kernel's definition but option"
+            << " lossy-conversions not specified" << endl;
+        return false;
+      }
+      break;
+    default:
+      err << "internal error: illegal value of compat = " << compat << endl;
+      assert(false);
+      return false;
+    };
 
-      NDBCOL::Type type_in_backup = col_in_backup->getType();
-      NDBCOL::Type type_in_kernel = col_in_kernel->getType();
-      attrCheckCompatFunc = get_attr_check_compatability(type_in_backup,
-                                                         type_in_kernel);
-      if (attrCheckCompatFunc &&
-          attrCheckCompatFunc(*col_in_backup, *col_in_kernel))
-      {
-        attr_desc->convertFunc = get_convert_func(type_in_backup,
-                                                  type_in_kernel);
-        Uint32 m_attrSize = NdbColumnImpl::getImpl(*col_in_kernel).m_attrSize;
-        Uint32 m_arraySize = NdbColumnImpl::getImpl(*col_in_kernel).m_arraySize;
-
-        if (type_in_backup == NDBCOL::Char || 
-            type_in_backup == NDBCOL::Binary || 
-            type_in_backup == NDBCOL::Bit)
-        {
-          unsigned int size = sizeof(struct char_n_padding_struct) + 
-                              m_attrSize * m_arraySize;  
-          struct char_n_padding_struct *s = (struct char_n_padding_struct *) 
-                                            malloc(size +2);
-          if (!s)
-          {
-            err << "No more memory available!" << endl;
-            exitHandler();
-          } 
-          s->n_old = (attr_desc->size * attr_desc->arraySize) / 8;
-          s->n_new = m_attrSize * m_arraySize; 
-          memset(s->new_row, 0 , m_attrSize * m_arraySize + 2);
-          attr_desc->parameter = s;
-        }
-        else
-        {
-          unsigned int size = m_attrSize * m_arraySize; 
-          attr_desc->parameter = malloc(size + 2);
-          if (!attr_desc->parameter)
-          {
-            err << "No more memory available!" << endl;
-            exitHandler();
-          }
-
-          memset(attr_desc->parameter, 0, size + 2); 
-        }
-
-        info << "Data for column " 
-             << tablename << "."
-             << col_in_backup->getName()
-             << " will be converted from Backup type into DB type." << endl;
+    attr_desc->convertFunc = get_convert_func(type_in_backup,
+                                              type_in_kernel);
+    Uint32 m_attrSize = NdbColumnImpl::getImpl(*col_in_kernel).m_attrSize;
+    Uint32 m_arraySize = NdbColumnImpl::getImpl(*col_in_kernel).m_arraySize;
+
+    // use a char_n_padding_struct to pass length information to convert()
+    if (type_in_backup == NDBCOL::Char ||
+        type_in_backup == NDBCOL::Binary ||
+        type_in_backup == NDBCOL::Bit ||
+        type_in_backup == NDBCOL::Varchar ||
+        type_in_backup == NDBCOL::Longvarchar ||
+        type_in_backup == NDBCOL::Varbinary ||
+        type_in_backup == NDBCOL::Longvarbinary)
+    {
+      unsigned int size = sizeof(struct char_n_padding_struct) +
+        m_attrSize * m_arraySize;
+      struct char_n_padding_struct *s = (struct char_n_padding_struct *)
+        malloc(size +2);
+      if (!s)
+      {
+        err << "No more memory available!" << endl;
+        exitHandler();
       }
-      else
+      s->n_old = (attr_desc->size * attr_desc->arraySize) / 8;
+      s->n_new = m_attrSize * m_arraySize;
+      memset(s->new_row, 0 , m_attrSize * m_arraySize + 2);
+      attr_desc->parameter = s;
+    }
+    else
+    {
+      unsigned int size = m_attrSize * m_arraySize;
+      attr_desc->parameter = malloc(size + 2);
+      if (!attr_desc->parameter)
       {
-        err << "Table: "<< tablename << endl
-            << "  Column: " << col_in_backup->getName() << endl
-            << "  AttrId = " << i << endl
-            << "  Incompatible with kernel's" << endl;
-        return false; 
+        err << "No more memory available!" << endl;
+        exitHandler();
       }
+      memset(attr_desc->parameter, 0, size + 2);
     }
+
+    info << "Data for column "
+         << tablename << "."
+         << col_in_backup->getName()
+         << " will be converted from Backup type into DB type." << endl;
   }
 
   return true;  
@@ -1664,7 +1773,7 @@ void BackupRestore::tuple_a(restore_call
     {
       for (int i = 0; i < tup.getNoOfAttributes(); i++) 
       {
-	const AttributeDesc * attr_desc = tup.getDesc(i);
+	AttributeDesc * attr_desc = tup.getDesc(i);
 	const AttributeData * attr_data = tup.getData(i);
 	int size = attr_desc->size;
 	int arraySize = attr_desc->arraySize;
@@ -1699,13 +1808,22 @@ void BackupRestore::tuple_a(restore_call
           if ((attr_desc->m_column->getPrimaryKey() && j == 0) ||
               (j == 1 && !attr_data->null))
           {
-
-            dataPtr = (char*)attr_desc->convertFunc(dataPtr, attr_desc->parameter);
+            bool truncated = true; // assume data truncation until overridden
+            dataPtr = (char*)attr_desc->convertFunc(dataPtr,
+                                                    attr_desc->parameter,
+                                                    truncated);
             if (!dataPtr)
             {
               err << "Error: Convert data failed when restoring tuples!" << endl;
               exitHandler();
             }
+            if (truncated)
+            {
+              // wl5421: option to report data truncation on tuple of desired
+              //err << "======  data truncation detected for column: "
+              //    << attr_desc->m_column->getName() << endl;
+              attr_desc->truncation_detected = true;
+            }
           }            
         }
 
@@ -2063,13 +2181,22 @@ retry:
 
     if (attr->Desc->convertFunc)
     {
-      dataPtr = (char*)attr->Desc->convertFunc(dataPtr, attr->Desc->parameter);
-
+      bool truncated = true; // assume data truncation until overridden
+      dataPtr = (char*)attr->Desc->convertFunc(dataPtr,
+                                               attr->Desc->parameter,
+                                               truncated);
       if (!dataPtr)
       {
         err << "Error: Convert data failed when restoring tuples!" << endl;
         exitHandler();
       }            
+      if (truncated)
+      {
+        // wl5421: option to report data truncation on tuple of desired
+        //err << "******  data truncation detected for column: "
+        //    << attr->Desc->m_column->getName() << endl;
+        attr->Desc->truncation_detected = true;
+      }
     } 
  
     if (attr->Desc->m_column->getPrimaryKey())
@@ -2202,34 +2329,73 @@ BackupRestore::get_convert_func(const ND
 
 }
 
-bool
-BackupRestore::check_compat_alwaystrue(const NDBCOL &old_col,
-                                            const NDBCOL &new_col)
+AttrConvType
+BackupRestore::check_compat_promotion(const NDBCOL &old_col,
+                                      const NDBCOL &new_col)
 {
-  return true;
+  return ACT_PRESERVING;
 }
 
-bool 
-BackupRestore::check_compat_common(const NDBCOL &old_col, 
-                                        const NDBCOL &new_col)
-{
-  Uint32 new_attrSize = NdbColumnImpl::getImpl(new_col).m_attrSize;
-  Uint32 old_attrSize = NdbColumnImpl::getImpl(old_col).m_attrSize;
-  Uint32 new_arraySize = NdbColumnImpl::getImpl(new_col).m_arraySize;
-  Uint32 old_arraySize = NdbColumnImpl::getImpl(old_col).m_arraySize;
-  if ((new_attrSize >= old_attrSize) && (new_arraySize >= old_arraySize)) {
-    return true;
+AttrConvType
+BackupRestore::check_compat_lossy(const NDBCOL &old_col,
+                                  const NDBCOL &new_col)
+{
+  return ACT_LOSSY;
+}
+
+/**
+ * Returns a negative integer, zero, or a positive integer as x is less than,
+ * equal to, or greater than y.
+ */
+static int
+compare(Uint32 x, Uint32 y)
+{
+  return (x < y ? -1 : (x > y ? 1 : 0));
+}
+
+AttrConvType
+BackupRestore::check_compat_sizes(const NDBCOL &old_col,
+                                  const NDBCOL &new_col)
+{
+  // the size (width) of the element type
+  Uint32 new_size = new_col.getSize();
+  Uint32 old_size = old_col.getSize();
+  // the fixed/max array length (1 for scalars)
+  Uint32 new_length = new_col.getLength();
+  Uint32 old_length = old_col.getLength();
+
+  // identity conversions have been handled by column_compatible_check()
+  assert(new_size != old_size
+         || new_length != old_length
+         || new_col.getArrayType() != old_col.getArrayType());
+
+  // test for loss of element width or array length
+  if (new_size < old_size || new_length < old_length) {
+    return ACT_LOSSY;
   }
 
-  return false;
+  // not tested: conversions varying in both, array length and element width
+  if (new_size != old_size && new_length != old_length) {
+    return ACT_UNSUPPORTED;
+  }
+
+  assert(new_size >= old_size && new_length >= old_length);
+  return ACT_PRESERVING;
 }
 
+// ----------------------------------------------------------------------
+// integral attribute promotion conversions
+// ----------------------------------------------------------------------
+
 void *
 BackupRestore::convert_int8_int16(const void *old_data,
-                                  void *parameter)
+                                  void *parameter,
+                                  bool &truncated)
 {
-  Int8 old_data8 = *(Int8 *) old_data;
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Int16 new_data16 = old_data8;
+  truncated = false;
   memcpy(parameter, &new_data16, 2);
 
   return parameter;
@@ -2237,22 +2403,27 @@ BackupRestore::convert_int8_int16(const 
 
 void *
 BackupRestore::convert_int8_int24(const void *old_data,
-                                    void *parameter)
+                                  void *parameter,
+                                  bool &truncated)
 {
-  Int8 old_data8 = *(Int8 *) old_data;
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Int32 new_data24 = old_data8;
+  truncated = false;
   int3store((char*)parameter, new_data24);
- 
-  return parameter; 
+
+  return parameter;
 }
 
 void *
 BackupRestore::convert_int8_int32(const void *old_data,
-                                  void *parameter)
+                                  void *parameter,
+                                  bool &truncated)
 {
-  Int8 old_data8 = *(Int8 *) old_data;
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Int32 new_data32 = old_data8;
-  
+  truncated = false;
   memcpy(parameter, &new_data32, 4);
 
   return parameter;
@@ -2260,11 +2431,13 @@ BackupRestore::convert_int8_int32(const 
 
 void *
 BackupRestore::convert_int8_int64(const void *old_data,
-                                  void *parameter)
+                                  void *parameter,
+                                  bool &truncated)
 {
-  Int8 old_data8 = *(Int8 *) old_data;
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Int64 new_data64 = old_data8;
-
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
@@ -2272,14 +2445,13 @@ BackupRestore::convert_int8_int64(const 
 
 void *
 BackupRestore::convert_int16_int24(const void *old_data,
-                                   void *parameter)
+                                   void *parameter,
+                                   bool &truncated)
 {
-  Int16 old_data16 = 0;
-  Int32 new_data24 = 0;
-
+  Int16 old_data16;
   memcpy(&old_data16, old_data, 2);
-  new_data24 = old_data16;
-
+  Int32 new_data24 = old_data16;
+  truncated = false;
   int3store((char*)parameter, new_data24);
 
   return parameter;
@@ -2287,14 +2459,13 @@ BackupRestore::convert_int16_int24(const
 
 void *
 BackupRestore::convert_int16_int32(const void *old_data,
-                                   void *parameter)
+                                   void *parameter,
+                                   bool &truncated)
 {
-  Int16 old_data16 = 0;
-  Int32 new_data32 = 0;
-  
+  Int16 old_data16;
   memcpy(&old_data16, old_data, 2);
-  new_data32 = old_data16;
-
+  Int32 new_data32 = old_data16;
+  truncated = false;
   memcpy(parameter, &new_data32, 4);
 
   return parameter;
@@ -2302,14 +2473,13 @@ BackupRestore::convert_int16_int32(const
 
 void *
 BackupRestore::convert_int16_int64(const void *old_data,
-                                   void *parameter)
+                                   void *parameter,
+                                   bool &truncated)
 {
-  Int16 old_data16 = 0;
-  Int64 new_data64 = 0;
-
+  Int16 old_data16;
   memcpy(&old_data16, old_data, 2);
-  new_data64 = old_data16;
-
+  Int64 new_data64 = old_data16;
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
@@ -2317,11 +2487,12 @@ BackupRestore::convert_int16_int64(const
 
 void *
 BackupRestore::convert_int24_int32(const void *old_data,
-                                   void *parameter)
+                                   void *parameter,
+                                   bool &truncated)
 {
   Int32 old_data24 = sint3korr((char*)old_data);
   Int32 new_data32 = old_data24;
-  
+  truncated = false;
   memcpy(parameter, &new_data32, 4);
 
   return parameter;
@@ -2329,11 +2500,12 @@ BackupRestore::convert_int24_int32(const
 
 void *
 BackupRestore::convert_int24_int64(const void *old_data,
-                                   void *parameter)
+                                   void *parameter,
+                                   bool &truncated)
 {
   Int32 old_data24 = sint3korr((char*)old_data);
   Int64 new_data64 = old_data24;
-
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
@@ -2341,14 +2513,13 @@ BackupRestore::convert_int24_int64(const
 
 void *
 BackupRestore::convert_int32_int64(const void *old_data,
-                                   void *parameter)
+                                   void *parameter,
+                                   bool &truncated)
 {
-  Int32 old_data32 = 0;
-  Int64 new_data64 = 0;
-
+  Int32 old_data32;
   memcpy(&old_data32, old_data, 4);
-  new_data64 = old_data32;
-
+  Int64 new_data64 = old_data32;
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
@@ -2356,10 +2527,13 @@ BackupRestore::convert_int32_int64(const
 
 void *
 BackupRestore::convert_uint8_uint16(const void *old_data,
-                                   void *parameter)
+                                    void *parameter,
+                                    bool &truncated)
 {
-  Uint8 old_data8 = *(Uint8 *) old_data;
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Uint16 new_data16 = old_data8;
+  truncated = false;
   memcpy(parameter, &new_data16, 2);
 
   return parameter;
@@ -2367,11 +2541,13 @@ BackupRestore::convert_uint8_uint16(cons
 
 void *
 BackupRestore::convert_uint8_uint24(const void *old_data,
-                                   void *parameter)
+                                    void *parameter,
+                                    bool &truncated)
 {
-  Uint8 old_data8 = *(Uint8 *) old_data;
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Uint32 new_data24 = old_data8;
-
+  truncated = false;
   int3store((char*)parameter, new_data24);
 
   return parameter;
@@ -2379,11 +2555,13 @@ BackupRestore::convert_uint8_uint24(cons
 
 void *
 BackupRestore::convert_uint8_uint32(const void *old_data,
-                                    void *parameter)
+                                    void *parameter,
+                                    bool &truncated)
 {
-  Uint8 old_data8 = *(Uint8 *) old_data;
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Uint32 new_data32 = old_data8;
-
+  truncated = false;
   memcpy(parameter, &new_data32, 4);
 
   return parameter;
@@ -2391,11 +2569,13 @@ BackupRestore::convert_uint8_uint32(cons
 
 void *
 BackupRestore::convert_uint8_uint64(const void *old_data,
-                                    void *parameter)
+                                    void *parameter,
+                                    bool &truncated)
 {
-  Uint8 old_data8 = *(Uint8 *) old_data;
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
   Uint64 new_data64 = old_data8;
-
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
@@ -2403,14 +2583,13 @@ BackupRestore::convert_uint8_uint64(cons
 
 void *
 BackupRestore::convert_uint16_uint24(const void *old_data,
-                                     void *parameter)
+                                     void *parameter,
+                                     bool &truncated)
 {
-  Uint16 old_data16 = 0;
-  Uint32 new_data24 = 0;
-
+  Uint16 old_data16;
   memcpy(&old_data16, old_data, 2);
-  new_data24 = old_data16;
-
+  Uint32 new_data24 = old_data16;
+  truncated = false;
   int3store((char*)parameter, new_data24);
 
   return parameter;
@@ -2418,14 +2597,13 @@ BackupRestore::convert_uint16_uint24(con
 
 void *
 BackupRestore::convert_uint16_uint32(const void *old_data,
-                                     void *parameter)
+                                     void *parameter,
+                                     bool &truncated)
 {
-  Uint16 old_data16 = 0;
-  Uint32 new_data32 = 0;
-
+  Uint16 old_data16;
   memcpy(&old_data16, old_data, 2);
-  new_data32 = old_data16;
-
+  Uint32 new_data32 = old_data16;
+  truncated = false;
   memcpy(parameter, &new_data32, 4);
 
   return parameter;
@@ -2433,14 +2611,13 @@ BackupRestore::convert_uint16_uint32(con
 
 void *
 BackupRestore::convert_uint16_uint64(const void *old_data,
-                                     void *parameter)
+                                     void *parameter,
+                                     bool &truncated)
 {
-  Uint16 old_data16 = 0;
-  Uint64 new_data64 = 0;
-
+  Uint16 old_data16;
   memcpy(&old_data16, old_data, 2);
-  new_data64 = old_data16;
-
+  Uint64 new_data64 = old_data16;
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
@@ -2448,23 +2625,25 @@ BackupRestore::convert_uint16_uint64(con
 
 void *
 BackupRestore::convert_uint24_uint32(const void *old_data,
-                                     void *parameter)
+                                     void *parameter,
+                                     bool &truncated)
 {
   Uint32 old_data24 = uint3korr((char*)old_data);
-  Uint32 new_data32 = old_data24; 
-
+  Uint32 new_data32 = old_data24;
+  truncated = false;
   memcpy(parameter, &new_data32, 4);
 
-  return parameter; 
+  return parameter;
 }
 
 void *
 BackupRestore::convert_uint24_uint64(const void *old_data,
-                                     void *parameter)
+                                     void *parameter,
+                                     bool &truncated)
 {
   Uint32 old_data24 = uint3korr((char*)old_data);
   Uint64 new_data64 = old_data24;
-
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
@@ -2472,215 +2651,1963 @@ BackupRestore::convert_uint24_uint64(con
 
 void *
 BackupRestore::convert_uint32_uint64(const void *old_data,
-                                     void *parameter)
+                                     void *parameter,
+                                     bool &truncated)
 {
-  Uint32 old_data32 = 0;
-  Uint64 new_data64 = 0;
-
+  Uint32 old_data32;
   memcpy(&old_data32, old_data, 4);
-  new_data64 = old_data32;
-
+  Uint64 new_data64 = old_data32;
+  truncated = false;
   memcpy(parameter, &new_data64, 8);
 
   return parameter;
-
 }
 
-void * 
-BackupRestore::convert_char_char(const void *old_data, 
-                                      void *parameter)
-{
-  if (!old_data || !parameter)
-    return NULL;
-  
-  struct char_n_padding_struct * padding_struct = 
-               (struct char_n_padding_struct * )parameter;
-  assert(padding_struct->n_new >= padding_struct->n_old);
+// ----------------------------------------------------------------------
+// integral attribute demotion conversions
+// (follows MySQL replication semantics truncating to nearest legal value)
+// ----------------------------------------------------------------------
 
-  Uint32 len = padding_struct->n_new - padding_struct->n_old;
+void *
+BackupRestore::convert_int16_int8(const void *old_data,
+                                  void *parameter,
+                                  bool &truncated)
+{
+  Int16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Int8 new_data8;
+  if (old_data16 < INT_MIN8) {
+    new_data8 = (Int8)(INT_MIN8);
+    truncated = true;
+  } else if (old_data16 > INT_MAX8) {
+    new_data8 = (Int8)(INT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Int8)(old_data16);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
 
-  memcpy(padding_struct->new_row, old_data, padding_struct->n_old);
-  memset(padding_struct->new_row + padding_struct->n_old, ' ', len);
- 
-  return padding_struct->new_row;
+  return parameter;
 }
 
 void *
-BackupRestore::convert_binary_binary(const void *old_data,
-                                          void *parameter)
+BackupRestore::convert_int24_int8(const void *old_data,
+                                  void *parameter,
+                                  bool &truncated)
 {
-  if (!old_data || !parameter)
-    return NULL;
- 
-  struct char_n_padding_struct * padding_struct = 
-                (struct char_n_padding_struct * )parameter;
+  Int32 old_data24 = sint3korr((char*)old_data);
+  Int8 new_data8;
+  if (old_data24 < INT_MIN8) {
+    new_data8 = (Int8)(INT_MIN8);
+    truncated = true;
+  } else if (old_data24 > INT_MAX8) {
+    new_data8 = (Int8)(INT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Int8)(old_data24);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
 
-  assert(padding_struct->n_new >= padding_struct->n_old);
- 
-  Uint32 len = padding_struct->n_new - padding_struct->n_old;
+  return parameter;
+}
 
-  memcpy(padding_struct->new_row, old_data, padding_struct->n_old);
-  memset(padding_struct->new_row + padding_struct->n_old, 0x00, len);
- 
-  return padding_struct->new_row;
+void *
+BackupRestore::convert_int24_int16(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int32 old_data24 = sint3korr((char*)old_data);
+  Int16 new_data16;
+  if (old_data24 < INT_MIN16) {
+    new_data16 = (Int16)(INT_MIN16);
+    truncated = true;
+  } else if (old_data24 > INT_MAX16) {
+    new_data16 = (Int16)(INT_MAX16);
+    truncated = true;
+  } else {
+    new_data16 = (Int16)(old_data24);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
 }
 
 void *
-BackupRestore::convert_char_varchar(const void *old_data,
-                                         void *parameter)
+BackupRestore::convert_int32_int8(const void *old_data,
+                                  void *parameter,
+                                  bool &truncated)
 {
-  if (!old_data || !parameter)
-    return NULL;
- 
-  struct char_n_padding_struct * padding_struct = 
-                (struct char_n_padding_struct * )parameter;
-  assert(padding_struct->n_new >= padding_struct->n_old);
- 
-  Uint32 len = padding_struct->n_old;
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int8 new_data8;
+  if (old_data32 < INT_MIN8) {
+    new_data8 = (Int8)(INT_MIN8);
+    truncated = true;
+  } else if (old_data32 > INT_MAX8) {
+    new_data8 = (Int8)(INT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Int8)(old_data32);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
 
-  if (!m_preserve_trailing_spaces)
-  {
-    while (len > 0 && ((char*)old_data)[len-1] == ' ')
-     len--;
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int32_int16(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int16 new_data16;
+  if (old_data32 < INT_MIN16) {
+    new_data16 = (Int16)(INT_MIN16);
+    truncated = true;
+  } else if (old_data32 > INT_MAX16) {
+    new_data16 = (Int16)(INT_MAX16);
+    truncated = true;
+  } else {
+    new_data16 = (Int16)(old_data32);
+    truncated = false;
   }
-  padding_struct->new_row[0] = len & 0x000000FF;
-  memcpy(padding_struct->new_row + 1, old_data, len);
-  return padding_struct->new_row;
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
 }
 
 void *
-BackupRestore::convert_char_longvarchar(const void *old_data,
-                                         void *parameter)
+BackupRestore::convert_int32_int24(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
 {
-  if (!old_data || !parameter)
-    return NULL;
- 
-  struct char_n_padding_struct * padding_struct = 
-                (struct char_n_padding_struct * )parameter;
-  assert(padding_struct->n_new >= padding_struct->n_old);
- 
-  Uint32 len = padding_struct->n_old;
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int32 new_data24;
+  if (old_data32 < INT_MIN24) {
+    new_data24 = (Int32)(INT_MIN24);
+    truncated = true;
+  } else if (old_data32 > INT_MAX24) {
+    new_data24 = (Int32)(INT_MAX24);
+    truncated = true;
+  } else {
+    new_data24 = (Int32)(old_data32);
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
 
-  if (!m_preserve_trailing_spaces)
-  {
-    while (len > 0 && ((char*)old_data)[len-1] == ' ')
-     len--;
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int64_int8(const void *old_data,
+                                  void *parameter,
+                                  bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int8 new_data8;
+  if (old_data64 < INT_MIN8) {
+    new_data8 = (Int8)(INT_MIN8);
+    truncated = true;
+  } else if (old_data64 > INT_MAX8) {
+    new_data8 = (Int8)(INT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Int8)(old_data64);
+    truncated = false;
   }
-  padding_struct->new_row[0] = len & 0x000000FF;
-  padding_struct->new_row[1] = (len & 0x0000FF00) >> 8;
-  memcpy(padding_struct->new_row + 2, old_data, len);
- 
-  return padding_struct->new_row;
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
 }
 
 void *
-BackupRestore::convert_binary_varbinary(const void *old_data,
-                                             void *parameter)
-{
-  if (!old_data || !parameter)
-    return NULL;
- 
-  struct char_n_padding_struct * padding_struct = 
-                (struct char_n_padding_struct * )parameter;
-  assert(padding_struct->n_new >= padding_struct->n_old);
- 
-  Uint32 len = padding_struct->n_old;
+BackupRestore::convert_int64_int16(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int16 new_data16;
+  if (old_data64 < INT_MIN16) {
+    new_data16 = (Int16)(INT_MIN16);
+    truncated = true;
+  } else if (old_data64 > INT_MAX16) {
+    new_data16 = (Int16)(INT_MAX16);
+    truncated = true;
+  } else {
+    new_data16 = (Int16)(old_data64);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
 
-  if (!m_preserve_trailing_spaces)
-  {
-    while (len > 0 && ((char*)old_data)[len-1] == 0x00)
-     len--;
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int64_int24(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int32 new_data24;
+  if (old_data64 < INT_MIN24) {
+    new_data24 = (Int32)(INT_MIN24);
+    truncated = true;
+  } else if (old_data64 > INT_MAX24) {
+    new_data24 = (Int32)(INT_MAX24);
+    truncated = true;
+  } else {
+    new_data24 = (Int32)(old_data64);
+    truncated = false;
   }
-  padding_struct->new_row[0] = len & 0x000000FF;
-  memcpy(padding_struct->new_row + 1, old_data, len);
- 
-  return padding_struct->new_row;
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
 }
 
 void *
-BackupRestore::convert_binary_longvarbinary(const void *old_data,
-                                             void *parameter)
+BackupRestore::convert_int64_int32(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int32 new_data32;
+  if (old_data64 < INT_MIN32) {
+    new_data32 = (Int32)(INT_MIN32);
+    truncated = true;
+  } else if (old_data64 > INT_MAX32) {
+    new_data32 = (Int32)(INT_MAX32);
+    truncated = true;
+  } else {
+    new_data32 = (Int32)(old_data64);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint16_uint8(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
 {
-  if (!old_data || !parameter)
-    return NULL;
- 
-  struct char_n_padding_struct * padding_struct = 
-                (struct char_n_padding_struct * )parameter;
-  assert(padding_struct->n_new >= padding_struct->n_old);
- 
-  Uint32 len = padding_struct->n_old;
- 
-  if (!m_preserve_trailing_spaces)
-  {
-    while (len > 0 && ((char*)old_data)[len-1] == 0x00)
-     len--;
+  Uint16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Uint8 new_data8;
+  if (old_data16 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data16 > UINT_MAX8) {
+    new_data8 = (Uint8)(UINT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)(old_data16);
+    truncated = false;
   }
-  padding_struct->new_row[0] = len & 0x000000FF;
-  padding_struct->new_row[1] = (len & 0x0000FF00) >> 8;
-  memcpy(padding_struct->new_row + 2, old_data, len);
- 
-  return padding_struct->new_row;
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
 }
 
 void *
-BackupRestore::convert_bit_bit(const void *old_data,
-                                    void *parameter)
+BackupRestore::convert_uint24_uint8(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
 {
-  if (!old_data || !parameter)
-    return NULL;
- 
-  struct char_n_padding_struct * padding_struct = 
-                (struct char_n_padding_struct * )parameter;
-  assert(padding_struct->n_new >= padding_struct->n_old);
+  Uint32 old_data24 = uint3korr((char*)old_data);
+  Uint8 new_data8;
+  if (old_data24 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data24 > UINT_MAX8) {
+    new_data8 = (Uint8)(UINT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)(old_data24);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
 
-  memset(padding_struct->new_row, 0, padding_struct->n_new); 
-  memcpy(padding_struct->new_row, old_data, padding_struct->n_old);
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint24_uint16(const void *old_data,
+                                     void *parameter,
+                                     bool &truncated)
+{
+  Uint32 old_data24 = uint3korr((char*)old_data);
+  Uint16 new_data16;
+  if (old_data24 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else if (old_data24 > UINT_MAX16) {
+    new_data16 = (Uint16)(UINT_MAX16);
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)(old_data24);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
 
-  return padding_struct->new_row;
+  return parameter;
 }
 
 void *
-BackupRestore::convert_var_var(const void *old_data, 
-                                    void *parameter)
+BackupRestore::convert_uint32_uint8(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
 {
-  if (!old_data || !parameter)
-    return NULL;
-  Uint32 len = ((unsigned char*)old_data)[0] + 1;
- 
-  memcpy(parameter, old_data, len);
- 
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint8 new_data8;
+  if (old_data32 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data32 > UINT_MAX8) {
+    new_data8 = (Uint8)(UINT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)(old_data32);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
   return parameter;
 }
 
 void *
-BackupRestore::convert_longvar_longvar(const void *old_data,
-                                    void *parameter)
+BackupRestore::convert_uint32_uint16(const void *old_data,
+                                     void *parameter,
+                                     bool &truncated)
 {
-  if (!old_data || !parameter)
-    return NULL;
-  Uint32 len = ((unsigned char*)old_data)[0] + (((unsigned char*)old_data)[1] << 8) + 2;
-  memcpy(parameter, old_data, len);
- 
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint16 new_data16;
+  if (old_data32 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else if (old_data32 > UINT_MAX16) {
+    new_data16 = (Uint16)(UINT_MAX16);
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)(old_data32);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
   return parameter;
 }
 
 void *
-BackupRestore::convert_var_longvar(const void *old_data,
-                                    void *parameter)
+BackupRestore::convert_uint32_uint24(const void *old_data,
+                                     void *parameter,
+                                     bool &truncated)
 {
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint32 new_data24;
+  if (old_data32 < 0) {
+    new_data24 = (Uint32)0;
+    truncated = true;
+  } else if (old_data32 > UINT_MAX24) {
+    new_data24 = (Uint32)(UINT_MAX24);
+    truncated = true;
+  } else {
+    new_data24 = (Uint32)(old_data32);
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
 
-  Uint32 length = 0;
-  if (!old_data || !parameter)
-    return NULL;
- 
-  length = ((unsigned char *)old_data)[0];
-  memcpy((unsigned char*)parameter + 2, (unsigned char*)old_data + 1 , length);
-  ((char *)parameter)[0] = length & 0x000000FF;
-  ((char *)parameter)[1] = (length & 0x0000FF00) >> 8;
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_uint8(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint8 new_data8;
+  if (old_data64 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX8) {
+    new_data8 = (Uint8)(UINT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)(old_data64);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_uint16(const void *old_data,
+                                     void *parameter,
+                                     bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint16 new_data16;
+  if (old_data64 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX16) {
+    new_data16 = (Uint16)(UINT_MAX16);
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)(old_data64);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
 
   return parameter;
 }
 
+void *
+BackupRestore::convert_uint64_uint24(const void *old_data,
+                                     void *parameter,
+                                     bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint32 new_data24;
+  if (old_data64 < 0) {
+    new_data24 = (Uint32)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX24) {
+    new_data24 = (Uint32)(UINT_MAX24);
+    truncated = true;
+  } else {
+    new_data24 = (Uint32)(old_data64);
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_uint32(const void *old_data,
+                                     void *parameter,
+                                     bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint32 new_data32;
+  if (old_data64 < 0) {
+    new_data32 = (Uint32)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX32) {
+    new_data32 = (Uint32)(UINT_MAX32);
+    truncated = true;
+  } else {
+    new_data32 = (Uint32)(old_data64);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+// ----------------------------------------------------------------------
+// integral attribute signedness conversions
+// (follows MySQL replication semantics truncating to nearest legal value)
+// ----------------------------------------------------------------------
+
+void *
+BackupRestore::convert_int8_uint8(const void *old_data,
+                                  void *parameter,
+                                  bool &truncated)
+{
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Uint8 new_data8;
+  if (old_data8 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)(old_data8);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int16_uint16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Uint16 new_data16;
+  if (old_data16 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)(old_data16);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int24_uint24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data24 = sint3korr((char*)old_data);
+  Uint32 new_data24;
+  if (old_data24 < 0) {
+    new_data24 = (Uint32)0;
+    truncated = true;
+  } else {
+    new_data24 = (Uint32)(old_data24);
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int32_uint32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint32 new_data32;
+  if (old_data32 < 0) {
+    new_data32 = (Uint32)0;
+    truncated = true;
+  } else {
+    new_data32 = (Uint32)(old_data32);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int64_uint64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint64 new_data64;
+  if (old_data64 < 0) {
+    new_data64 = (Uint64)0;
+    truncated = true;
+  } else {
+    new_data64 = (Uint64)(old_data64);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint8_int8(const void *old_data,
+                                  void *parameter,
+                                  bool &truncated)
+{
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Int8 new_data8;
+  if (old_data8 > INT_MAX8) {
+    new_data8 = (Int8)(INT_MAX8);
+    truncated = true;
+  } else {
+    new_data8 = (Int8)(old_data8);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint16_int16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Int16 new_data16;
+  if (old_data16 > INT_MAX16) {
+    new_data16 = (Int16)(INT_MAX16);
+    truncated = true;
+  } else {
+    new_data16 = (Int16)(old_data16);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint24_int24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data24 = uint3korr((char*)old_data);
+  Int32 new_data24 = (Int32)((old_data24 > INT_MAX24) ? INT_MAX24
+                             : old_data24);
+  if (old_data24 > INT_MAX24) {
+    new_data24 = (Int32)(INT_MAX24);
+    truncated = true;
+  } else {
+    new_data24 = (Int32)(old_data24);
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint32_int32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int32 new_data32;
+  if (old_data32 > INT_MAX32) {
+    new_data32 = (Int32)(INT_MAX32);
+    truncated = true;
+  } else {
+    new_data32 = (Int32)(old_data32);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_int64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int64 new_data64;
+  if (old_data64 > INT_MAX64) {
+    new_data64 = (Int64)(INT_MAX64);
+    truncated = true;
+  } else {
+    new_data64 = (Int64)(old_data64);
+    truncated = false;
+  }
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+// ----------------------------------------------------------------------
+// integral attribute signedness+promotion conversions
+// (follows MySQL replication semantics truncating to nearest legal value)
+// ----------------------------------------------------------------------
+
+void *
+BackupRestore::convert_int8_uint16(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Uint16 new_data16;
+  if (old_data8 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)old_data8;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int8_uint24(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Uint32 new_data24;
+  if (old_data8 < 0) {
+    new_data24 = (Uint32)0;
+    truncated = true;
+  } else {
+    new_data24 = (Uint32)old_data8;
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int8_uint32(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Uint32 new_data32;
+  if (old_data8 < 0) {
+    new_data32 = (Uint32)0;
+    truncated = true;
+  } else {
+    new_data32 = (Uint32)old_data8;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int8_uint64(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Uint64 new_data64;
+  if (old_data8 < 0) {
+    new_data64 = (Uint64)0;
+    truncated = true;
+  } else {
+    new_data64 = (Uint64)old_data8;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int16_uint24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Uint32 new_data24;
+  if (old_data16 < 0) {
+    new_data24 = (Uint32)0;
+    truncated = true;
+  } else {
+    new_data24 = (Uint32)old_data16;
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int16_uint32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Uint32 new_data32;
+  if (old_data16 < 0) {
+    new_data32 = (Uint32)0;
+    truncated = true;
+  } else {
+    new_data32 = (Uint32)old_data16;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int16_uint64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Uint64 new_data64;
+  if (old_data16 < 0) {
+    new_data64 = (Uint64)0;
+    truncated = true;
+  } else {
+    new_data64 = (Uint64)old_data16;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int24_uint32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data24 = sint3korr((char*)old_data);
+  Uint32 new_data32;
+  if (old_data24 < 0) {
+    new_data32 = (Uint32)0;
+    truncated = true;
+  } else {
+    new_data32 = (Uint32)old_data24;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int24_uint64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data24 = sint3korr((char*)old_data);
+  Uint64 new_data64;
+  if (old_data24 < 0) {
+    new_data64 = (Uint64)0;
+    truncated = true;
+  } else {
+    new_data64 = (Uint64)old_data24;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int32_uint64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint64 new_data64;
+  if (old_data32 < 0) {
+    new_data64 = (Uint64)0;
+    truncated = true;
+  } else {
+    new_data64 = (Uint64)old_data32;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint8_int16(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Int16 new_data16 = old_data8;
+  truncated = false;
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint8_int24(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Int32 new_data24 = old_data8;
+  truncated = false;
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint8_int32(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Int32 new_data32 = old_data8;
+  truncated = false;
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint8_int64(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint8 old_data8;
+  memcpy(&old_data8, old_data, 1);
+  Int64 new_data64 = old_data8;
+  truncated = false;
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint16_int24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Int32 new_data24 = old_data16;
+  truncated = false;
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint16_int32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Int32 new_data32 = old_data16;
+  truncated = false;
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint16_int64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Int64 new_data64 = old_data16;
+  truncated = false;
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint24_int32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data24 = uint3korr((char*)old_data);
+  Int32 new_data32 = old_data24;
+  truncated = false;
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint24_int64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data24 = uint3korr((char*)old_data);
+  Int64 new_data64 = old_data24;
+  truncated = false;
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint32_int64(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int64 new_data64 = old_data32;
+  truncated = false;
+  memcpy(parameter, &new_data64, 8);
+
+  return parameter;
+}
+
+// ----------------------------------------------------------------------
+// integral attribute signedness+demotion conversions
+// (follows MySQL replication semantics truncating to nearest legal value)
+// ----------------------------------------------------------------------
+
+void *
+BackupRestore::convert_int16_uint8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Uint8 new_data8;
+  if (old_data16 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data16 > UINT_MAX8) {
+    new_data8 = (Uint8)UINT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)old_data16;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int24_uint8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int32 old_data24 = sint3korr((char*)old_data);
+  Uint8 new_data8;
+  if (old_data24 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data24 > UINT_MAX8) {
+    new_data8 = (Uint8)UINT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)old_data24;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int24_uint16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data24 = sint3korr((char*)old_data);
+  Uint16 new_data16;
+  if (old_data24 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else if (old_data24 > UINT_MAX16) {
+    new_data16 = (Uint16)UINT_MAX16;
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)old_data24;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int32_uint8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint8 new_data8;
+  if (old_data32 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data32 > UINT_MAX8) {
+    new_data8 = (Uint8)UINT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)old_data32;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int32_uint16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint16 new_data16;
+  if (old_data32 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else if (old_data32 > UINT_MAX16) {
+    new_data16 = (Uint16)UINT_MAX16;
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)old_data32;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int32_uint24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Uint32 new_data24;
+  if (old_data32 < 0) {
+    new_data24 = (Uint32)0;
+    truncated = true;
+  } else if (old_data32 > UINT_MAX24) {
+    new_data24 = (Uint32)UINT_MAX24;
+    truncated = true;
+  } else {
+    new_data24 = (Uint32)old_data32;
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int64_uint8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint8 new_data8;
+  if (old_data64 < 0) {
+    new_data8 = (Uint8)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX8) {
+    new_data8 = (Uint8)UINT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Uint8)old_data64;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int64_uint16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint16 new_data16;
+  if (old_data64 < 0) {
+    new_data16 = (Uint16)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX16) {
+    new_data16 = (Uint16)UINT_MAX16;
+    truncated = true;
+  } else {
+    new_data16 = (Uint16)old_data64;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int64_uint24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint32 new_data24;
+  if (old_data64 < 0) {
+    new_data24 = (Uint32)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX24) {
+    new_data24 = (Uint32)UINT_MAX24;
+    truncated = true;
+  } else {
+    new_data24 = (Uint32)old_data64;
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_int64_uint32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Int64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Uint32 new_data32;
+  if (old_data64 < 0) {
+    new_data32 = (Uint32)0;
+    truncated = true;
+  } else if (old_data64 > UINT_MAX32) {
+    new_data32 = (Uint32)UINT_MAX32;
+    truncated = true;
+  } else {
+    new_data32 = (Uint32)old_data64;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint16_int8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint16 old_data16;
+  memcpy(&old_data16, old_data, 2);
+  Int8 new_data8;
+  if (old_data16 > INT_MAX8) {
+    new_data8 = (Int8)INT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Int8)old_data16;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint24_int8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint32 old_data24 = uint3korr((char*)old_data);
+  Int8 new_data8;
+  if (old_data24 > INT_MAX8) {
+    new_data8 = (Int8)INT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Int8)old_data24;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint24_int16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data24 = uint3korr((char*)old_data);
+  Int16 new_data16;
+  if (old_data24 > INT_MAX16) {
+    new_data16 = (Int16)INT_MAX16;
+    truncated = true;
+  } else {
+    new_data16 = (Int16)old_data24;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint32_int8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int8 new_data8;
+  if (old_data32 > INT_MAX8) {
+    new_data8 = (Int8)INT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Int8)old_data32;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint32_int16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int16 new_data16;
+  if (old_data32 > INT_MAX16) {
+    new_data16 = (Int16)INT_MAX16;
+    truncated = true;
+  } else {
+    new_data16 = (Int16)old_data32;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint32_int24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint32 old_data32;
+  memcpy(&old_data32, old_data, 4);
+  Int32 new_data24;
+  if (old_data32 > INT_MAX24) {
+    new_data24 = (Int32)INT_MAX24;
+    truncated = true;
+  } else {
+    new_data24 = (Int32)old_data32;
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_int8(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int8 new_data8;
+  if (old_data64 > INT_MAX8) {
+    new_data8 = (Int8)INT_MAX8;
+    truncated = true;
+  } else {
+    new_data8 = (Int8)old_data64;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data8, 1);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_int16(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int16 new_data16;
+  if (old_data64 > INT_MAX16) {
+    new_data16 = (Int16)INT_MAX16;
+    truncated = true;
+  } else {
+    new_data16 = (Int16)old_data64;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data16, 2);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_int24(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int32 new_data24;
+  if (old_data64 > INT_MAX24) {
+    new_data24 = (Int32)INT_MAX24;
+    truncated = true;
+  } else {
+    new_data24 = (Int32)old_data64;
+    truncated = false;
+  }
+  int3store((char*)parameter, new_data24);
+
+  return parameter;
+}
+
+void *
+BackupRestore::convert_uint64_int32(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  Uint64 old_data64;
+  memcpy(&old_data64, old_data, 8);
+  Int32 new_data32;
+  if (old_data64 > INT_MAX32) {
+    new_data32 = (Int32)INT_MAX32;
+    truncated = true;
+  } else {
+    new_data32 = (Int32)old_data64;
+    truncated = false;
+  }
+  memcpy(parameter, &new_data32, 4);
+
+  return parameter;
+}
+
+// ----------------------------------------------------------------------
+// attribute promotion/demotion conversions
+// ----------------------------------------------------------------------
+
+void *
+BackupRestore::convert_bit_bit(const void *old_data,
+                               void *parameter,
+                               bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+
+  // write data
+  if (t->n_new >= t->n_old)
+  {
+    // clear all bits
+    memset(t->new_row, 0, t->n_new);
+
+    memcpy(t->new_row, s, t->n_old);
+    truncated = false;
+  } else {
+    // set all bits, for parity with replication's demotion semantics
+    memset(t->new_row, 0xFF, t->n_new);
+    truncated = true;
+  }
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_char_char(const void *old_data,
+                                 void *parameter,
+                                 bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const char * const s = (const char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 0;
+  const Uint32 t_prefix_length = 0;
+
+  // read and adjust length
+  Uint32 length = t->n_old;
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (!m_preserve_trailing_spaces) {
+    // ignore padding chars for data copying or truncation reporting
+    while (length > 0 && s[length - 1] == ' ')
+      length--;
+  }
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write data and padding
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+  const Uint32 l = max_length - length;
+  memset(t->new_row + t_prefix_length + length, ' ', l);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_binary_binary(const void *old_data,
+                                     void *parameter,
+                                     bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const char * const s = (const char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 0;
+  const Uint32 t_prefix_length = 0;
+
+  // read and adjust length
+  Uint32 length = t->n_old;
+  if (!m_preserve_trailing_spaces) {
+    // ignore padding chars for data copying or truncation reporting
+    while (length > 0 && s[length - 1] == 0x00)
+      length--;
+  }
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write data and padding
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+  const Uint32 l = max_length - length;
+  memset(t->new_row + t_prefix_length + length, 0x00, l);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_char_varchar(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const char * const s = (const char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 0;
+  const Uint32 t_prefix_length = 1;
+
+  // read and adjust length
+  Uint32 length = t->n_old;
+  if (!m_preserve_trailing_spaces) {
+    // ignore padding chars for data copying or truncation reporting
+    while (length > 0 && s[length - 1] == ' ')
+      length--;
+  }
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_varchar_char(const void *old_data,
+                                    void *parameter,
+                                    bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 1;
+  const Uint32 t_prefix_length = 0;
+
+  // read and adjust length
+  Uint32 length = s[0];
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write data and padding
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+  const Uint32 l = max_length - length;
+  memset(t->new_row + t_prefix_length + length, ' ', l);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_char_longvarchar(const void *old_data,
+                                        void *parameter,
+                                        bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const char * const s = (const char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 0;
+  const Uint32 t_prefix_length = 2;
+
+  // read and adjust length
+  Uint32 length = t->n_old;
+  if (!m_preserve_trailing_spaces) {
+    // ignore padding chars for data copying or truncation reporting
+    while (length > 0 && s[length - 1] == ' ')
+      length--;
+  }
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  t->new_row[1] = (length & 0x0000FF00) >> 8;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_longvarchar_char(const void *old_data,
+                                        void *parameter,
+                                        bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 2;
+  const Uint32 t_prefix_length = 0;
+
+  // read and adjust length
+  Uint32 length = s[0] + (s[1] << 8);
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write data and padding
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+  const Uint32 l = max_length - length;
+  memset(t->new_row + t_prefix_length + length, ' ', l);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_binary_varbinary(const void *old_data,
+                                        void *parameter,
+                                        bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const char * const s = (const char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 0;
+  const Uint32 t_prefix_length = 1;
+
+  // read and adjust length
+  Uint32 length = t->n_old;
+  if (!m_preserve_trailing_spaces) {
+    // ignore padding chars for data copying or truncation reporting
+    while (length > 0 && s[length - 1] == 0x00)
+      length--;
+  }
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_varbinary_binary(const void *old_data,
+                                        void *parameter,
+                                        bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 1;
+  const Uint32 t_prefix_length = 0;
+
+  // read and adjust length
+  Uint32 length = s[0];
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write data and padding
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+  const Uint32 l = max_length - length;
+  memset(t->new_row + t_prefix_length + length, 0x00, l);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_binary_longvarbinary(const void *old_data,
+                                            void *parameter,
+                                            bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const char * const s = (const char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 0;
+  const Uint32 t_prefix_length = 2;
+
+  // read and adjust length
+  Uint32 length = t->n_old;
+  if (!m_preserve_trailing_spaces) {
+    // ignore padding chars for data copying or truncation reporting
+    while (length > 0 && s[length - 1] == 0x00)
+      length--;
+  }
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  t->new_row[1] = (length & 0x0000FF00) >> 8;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_longvarbinary_binary(const void *old_data,
+                                            void *parameter,
+                                            bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 2;
+  const Uint32 t_prefix_length = 0;
+
+  // read and adjust length
+  Uint32 length = s[0] + (s[1] << 8);
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write data and padding
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+  const Uint32 l = max_length - length;
+  memset(t->new_row + t_prefix_length + length, 0x00, l);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_var_var(const void *old_data,
+                               void *parameter,
+                               bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 1;
+  const Uint32 t_prefix_length = 1;
+
+  // read and adjust length
+  Uint32 length = s[0];
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_var_longvar(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 1;
+  const Uint32 t_prefix_length = 2;
+
+  // read and adjust length
+  Uint32 length = s[0];
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  t->new_row[1] = (length & 0x0000FF00) >> 8;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_longvar_var(const void *old_data,
+                                   void *parameter,
+                                   bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 2;
+  const Uint32 t_prefix_length = 1;
+
+  // read and adjust length
+  Uint32 length = s[0] + (s[1] << 8);
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
+void *
+BackupRestore::convert_longvar_longvar(const void *old_data,
+                                       void *parameter,
+                                       bool &truncated)
+{
+  if (!old_data || !parameter)
+    return NULL;
+
+  // shortcuts
+  const unsigned char * const s = (const unsigned char *)old_data;
+  char_n_padding_struct * const t = (char_n_padding_struct *)parameter;
+  const Uint32 s_prefix_length = 2;
+  const Uint32 t_prefix_length = 2;
+
+  // read and adjust length
+  Uint32 length = s[0] + (s[1] << 8);
+  const Uint32 max_length = t->n_new - t_prefix_length;
+  if (length <= max_length) {
+    truncated = false;
+  } else {
+    length = max_length;
+    truncated = true;
+  }
+
+  // write length prefix and data
+  t->new_row[0] = length & 0x000000FF;
+  t->new_row[1] = (length & 0x0000FF00) >> 8;
+  memcpy(t->new_row + t_prefix_length, s + s_prefix_length, length);
+
+  return t->new_row;
+}
+
 template class Vector<NdbDictionary::Table*>;
 template class Vector<const NdbDictionary::Table*>;
 template class Vector<NdbDictionary::Tablespace*>;

=== modified file 'storage/ndb/tools/restore/consumer_restore.hpp'
--- a/storage/ndb/tools/restore/consumer_restore.hpp	2010-06-11 10:36:04 +0000
+++ b/storage/ndb/tools/restore/consumer_restore.hpp	2010-10-22 01:15:45 +0000
@@ -40,6 +40,10 @@ Uint32 n_new;
 char new_row[1];
 };
 
+enum AttrConvType { ACT_UNSUPPORTED = 0, ACT_PRESERVING = 1, ACT_LOSSY =-1 };
+typedef  AttrConvType (*AttrCheckCompatFunc)(const NDBCOL &old_col,
+                                             const NDBCOL &new_col);
+
 struct PromotionRules {
   NDBCOL::Type old_type;
   NDBCOL::Type new_type;
@@ -124,46 +128,241 @@ public:
   Uint32 map_ng(Uint32 ng);
   bool translate_frm(NdbDictionary::Table *table);
 
-  static bool check_compat_common(const NDBCOL &old_col, 
-                                  const NDBCOL &new_col); 
-  static bool check_compat_alwaystrue(const NDBCOL &old_col,
-                                      const NDBCOL &new_col);
-  static void* convert_int8_int16(const void *old_data,    void *parameter);
-  static void* convert_int8_int24(const void *old_data,    void *parameter);
-  static void* convert_int8_int32(const void *old_data,    void *parameter);
-  static void* convert_int8_int64(const void *old_data,    void *parameter);
-  static void* convert_int16_int24(const void *old_data,   void *parameter);
-  static void* convert_int16_int32(const void *old_data,   void *parameter);
-  static void* convert_int16_int64(const void *old_data,   void *parameter);
-  static void* convert_int24_int32(const void *old_data,   void *parameter);
-  static void* convert_int24_int64(const void *old_data,   void *parameter);
-  static void* convert_int32_int64(const void *old_data,   void *parameter);
-  static void* convert_uint8_uint16(const void *old_data,  void *parameter);
-  static void* convert_uint8_uint24(const void *old_data,  void *parameter);
-  static void* convert_uint8_uint32(const void *old_data,  void *parameter);
-  static void* convert_uint8_uint64(const void *old_data,  void *parameter);
-  static void* convert_uint16_uint24(const void *old_data, void *parameter);
-  static void* convert_uint16_uint32(const void *old_data, void *parameter);
-  static void* convert_uint16_uint64(const void *old_data, void *parameter);
-  static void* convert_uint24_uint32(const void *old_data, void *parameter);
-  static void* convert_uint24_uint64(const void *old_data, void *parameter);
-  static void* convert_uint32_uint64(const void *old_data, void *parameter);
-
-  static void* convert_char_char(const void *old_data,            void *parameter);
-  static void* convert_binary_binary(const void *old_data,        void *parameter);
-  static void* convert_char_varchar(const void *old_data,         void *parameter);
-  static void* convert_char_longvarchar(const void *old_data,     void *parameter);
-  static void* convert_binary_varbinary(const void *old_data,     void *parameter);
-  static void* convert_binary_longvarbinary(const void *old_data, void *parameter);
-  static void* convert_bit_bit(const void *old_data,              void *parameter);
-  static void* convert_var_var(const void *old_data,              void *parameter);
-  static void* convert_var_longvar(const void *old_data,          void *parameter);
-  static void* convert_longvar_longvar(const void *old_data,      void *parameter);
-
+  static AttrConvType check_compat_sizes(const NDBCOL &old_col,
+                                         const NDBCOL &new_col);
+  static AttrConvType check_compat_promotion(const NDBCOL &old_col,
+                                             const NDBCOL &new_col);
+  static AttrConvType check_compat_lossy(const NDBCOL &old_col,
+                                         const NDBCOL &new_col);
+
+  // integral attribute promotion conversions
+  static void* convert_int8_int16(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int8_int24(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int8_int32(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int8_int64(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int16_int24(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int16_int32(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int16_int64(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int24_int32(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int24_int64(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int32_int64(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint8_uint16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint8_uint24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint8_uint32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint8_uint64(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint16_uint24(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint16_uint32(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint16_uint64(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint24_uint32(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint24_uint64(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint32_uint64(const void *old_data,
+                                     void *parameter, bool &truncated);
+
+  // integral attribute demotion conversions
+  static void* convert_int16_int8(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int24_int8(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int24_int16(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int32_int8(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int32_int16(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int32_int24(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int64_int8(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int64_int16(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int64_int24(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int64_int32(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint16_uint8(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint24_uint8(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint24_uint16(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint32_uint8(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint32_uint16(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint32_uint24(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint64_uint8(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint64_uint16(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint64_uint24(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_uint64_uint32(const void *old_data,
+                                     void *parameter, bool &truncated);
+
+  // integral attribute signedness conversions
+  static void* convert_int8_uint8(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_int16_uint16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int24_uint24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int32_uint32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int64_uint64(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint8_int8(const void *old_data,
+                                  void *parameter, bool &truncated);
+  static void* convert_uint16_int16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint24_int24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint32_int32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint64_int64(const void *old_data,
+                                    void *parameter, bool &truncated);
+
+  // integral attribute signedness+promotion conversions
+  static void* convert_int8_uint16(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int8_uint24(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int8_uint32(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int8_uint64(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int16_uint24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int16_uint32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int16_uint64(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int24_uint32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int24_uint64(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int32_uint64(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint8_int16(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint8_int24(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint8_int32(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint8_int64(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint16_int24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint16_int32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint16_int64(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint24_int32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint24_int64(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint32_int64(const void *old_data,
+                                    void *parameter, bool &truncated);
+
+  // integral attribute signedness+demotion conversions
+  static void* convert_int16_uint8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int24_uint8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int24_uint16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int32_uint8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int32_uint16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int32_uint24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int64_uint8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_int64_uint16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int64_uint24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_int64_uint32(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint16_int8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint24_int8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint24_int16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint32_int8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint32_int16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint32_int24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint64_int8(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_uint64_int16(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint64_int24(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_uint64_int32(const void *old_data,
+                                    void *parameter, bool &truncated);
+
+  // char/binary promotion/demotion conversions
+  static void* convert_bit_bit(const void *old_data,
+                               void *parameter, bool &truncated);
+  static void* convert_char_char(const void *old_data,
+                                 void *parameter, bool &truncated);
+  static void* convert_binary_binary(const void *old_data,
+                                     void *parameter, bool &truncated);
+  static void* convert_char_varchar(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_varchar_char(const void *old_data,
+                                    void *parameter, bool &truncated);
+  static void* convert_char_longvarchar(const void *old_data,
+                                        void *parameter, bool &truncated);
+  static void* convert_longvarchar_char(const void *old_data,
+                                        void *parameter, bool &truncated);
+  static void* convert_binary_varbinary(const void *old_data,
+                                        void *parameter, bool &truncated);
+  static void* convert_varbinary_binary(const void *old_data,
+                                        void *parameter, bool &truncated);
+  static void* convert_binary_longvarbinary(const void *old_data,
+                                            void *parameter, bool &truncated);
+  static void* convert_longvarbinary_binary(const void *old_data,
+                                            void *parameter, bool &truncated);
+  static void* convert_var_var(const void *old_data,
+                               void *parameter, bool &truncated);
+  static void* convert_var_longvar(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_longvar_var(const void *old_data,
+                                   void *parameter, bool &truncated);
+  static void* convert_longvar_longvar(const void *old_data,
+                                       void *parameter, bool &truncated);
 
+  // returns the handler function checking type conversion compatibility
   AttrCheckCompatFunc 
-    get_attr_check_compatability(const NDBCOL::Type &old_type,
-                                 const NDBCOL::Type &new_type);
+  get_attr_check_compatability(const NDBCOL::Type &old_type,
+                               const NDBCOL::Type &new_type);
+
+  // returns the handler function converting a value
   AttrConvertFunc
   get_convert_func(const NDBCOL::Type &old_type,
                    const NDBCOL::Type &new_type);

=== modified file 'storage/ndb/tools/restore/restore_main.cpp'
--- a/storage/ndb/tools/restore/restore_main.cpp	2010-06-11 10:36:04 +0000
+++ b/storage/ndb/tools/restore/restore_main.cpp	2010-10-22 01:15:45 +0000
@@ -40,6 +40,7 @@ static int ga_backupId = 0;
 bool ga_dont_ignore_systab_0 = false;
 static bool ga_no_upgrade = false;
 static bool ga_promote_attributes = false;
+static bool ga_demote_attributes = false;
 static Vector<class BackupConsumer *> g_consumers;
 static BackupPrinter* g_printer = NULL;
 
@@ -163,6 +164,11 @@ static struct my_option my_long_options[
     "Allow attributes to be promoted when restoring data from backup",
     (uchar**) &ga_promote_attributes, (uchar**) &ga_promote_attributes, 0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "lossy-conversions", 'L',
+    "Allow lossy conversions for attributes (type demotions or integral"
+    " signed/unsigned type changes) when restoring data from backup",
+    (uchar**) &ga_demote_attributes, (uchar**) &ga_demote_attributes, 0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
   { "preserve-trailing-spaces", 'P',
     "Allow to preserve the tailing spaces (including paddings) When char->varchar or binary->varbinary is promoted",
     (uchar**) &_preserve_trailing_spaces, (uchar**)_preserve_trailing_spaces , 0,
@@ -769,6 +775,11 @@ o verify nodegroup mapping
     g_tableCompabilityMask |= TCM_ATTRIBUTE_PROMOTION;
   }
 
+  if (ga_demote_attributes)
+  {
+    g_tableCompabilityMask |= TCM_ATTRIBUTE_DEMOTION;
+  }
+
   if (ga_exclude_missing_columns)
   {
     g_tableCompabilityMask |= TCM_EXCLUDE_MISSING_COLUMNS;
@@ -1056,6 +1067,27 @@ static void report_progress(const char *
     info << prefix << f.get_file_pos() << " bytes\n";
 }
 
+/**
+ * Reports, clears information on columns where data truncation was detected.
+ */
+static void
+check_data_truncations(const TableS * table)
+{
+  assert(table);
+  const char * tname = table->getTableName();
+  const int n = table->getNoOfAttributes();
+  for (int i = 0; i < n; i++) {
+    AttributeDesc * desc = table->getAttributeDesc(i);
+    if (desc->truncation_detected) {
+      const char * cname = desc->m_column->getName();
+      info.setLevel(254);
+      info << "Data truncation(s) detected for attribute: "
+           << tname << "." << cname << endl;
+      desc->truncation_detected = false;
+    }
+  }
+}
+
 int
 main(int argc, char** argv)
 {
@@ -1075,6 +1107,8 @@ main(int argc, char** argv)
     g_options.appfmt(" -u");
   if (ga_promote_attributes)
     g_options.appfmt(" -A");
+  if (ga_demote_attributes)
+    g_options.appfmt(" -L");
   if (_preserve_trailing_spaces)
     g_options.appfmt(" -P");
   if (ga_skip_table_check)
@@ -1406,9 +1440,10 @@ main(int argc, char** argv)
     
     if(_restore_data)
     {
-      for(i = 0; i<metaData.getNoOfTables(); i++)
+      for(i = 0; i < metaData.getNoOfTables(); i++)
       {
         const TableS* table = metaData[i];
+        check_data_truncations(table);
         OutputStream *output = table_output[table->getLocalId()];
         if (!output)
           continue;


Attachment: [text/bzr-bundle] bzr/martin.zaun@oracle.com-20101022061037-856h2lgb68idebl1.bundle
Thread
bzr commit into mysql-5.1-telco-6.3 branch (martin.zaun:3318) Martin Zaun22 Oct