List:Commits« Previous MessageNext Message »
From:Frazer Clement Date:April 29 2010 4:03pm
Subject:bzr commit into mysql-5.1-telco-7.1 branch (frazer:3584)
View as plain text  
#At file:///home/frazer/bzr/mysql-5.1-telco-7.1/ based on revid:bernhard.ocklin@stripped

 3584 Frazer Clement	2010-04-29 [merge]
      Merge 7.0->7.1

    added:
      mysql-test/include/ndb_desc_print.inc
      mysql-test/std_data/ndb_backup_before_native_default/
      mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.1.Data
      mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.2.Data
      mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.ctl
      mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.log
      mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.ctl
      mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.log
      mysql-test/suite/ndb/r/ndb_native_default_support.result
      mysql-test/suite/ndb/t/ndb_native_default_support.test
      storage/ndb/test/ndbapi/testNativeDefault.cpp
    modified:
      mysql-test/Makefile.am
      mysql-test/suite/ndb/r/ndb_restore_promotion.result
      mysql-test/suite/ndb/t/ndb_restore_promotion.test
      mysql-test/suite/rpl_ndb/r/rpl_ndb_2ndb.result
      mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      storage/ndb/include/kernel/ndb_limits.h
      storage/ndb/include/kernel/signaldata/DictTabInfo.hpp
      storage/ndb/include/kernel/signaldata/LqhFrag.hpp
      storage/ndb/include/kernel/signaldata/TupFrag.hpp
      storage/ndb/include/ndb_version.h.in
      storage/ndb/include/ndbapi/NdbDictionary.hpp
      storage/ndb/include/ndbapi/NdbRecAttr.hpp
      storage/ndb/include/util/UtilBuffer.hpp
      storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp
      storage/ndb/src/kernel/blocks/ERROR_codes.txt
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
      storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp
      storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
      storage/ndb/src/ndbapi/NdbDictionary.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
      storage/ndb/src/ndbapi/NdbRecAttr.cpp
      storage/ndb/src/ndbapi/ndberror.c
      storage/ndb/test/include/NDBT_Table.hpp
      storage/ndb/test/ndbapi/CMakeLists.txt
      storage/ndb/test/ndbapi/Makefile.am
      storage/ndb/test/ndbapi/testBasic.cpp
      storage/ndb/test/ndbapi/testBitfield.cpp
      storage/ndb/test/ndbapi/testDict.cpp
      storage/ndb/test/ndbapi/testUpgrade.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/src/NDBT_Tables.cpp
=== modified file 'mysql-test/Makefile.am'
--- a/mysql-test/Makefile.am	2010-03-15 14:38:19 +0000
+++ b/mysql-test/Makefile.am	2010-04-29 16:03:05 +0000
@@ -85,6 +85,7 @@ TEST_DIRS = t r include std_data std_dat
 	std_data/ndb_backup51_undolog_be \
 	std_data/ndb_backup51_undolog_le \
 	std_data/ndb_backup_hashmap \
+	std_data/ndb_backup_before_native_default \
 	std_data/funcs_1 \
 	extra/binlog_tests/ extra/rpl_tests \
 	suite/binlog suite/binlog/t suite/binlog/r suite/binlog/std_data \

=== added file 'mysql-test/include/ndb_desc_print.inc'
--- a/mysql-test/include/ndb_desc_print.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/ndb_desc_print.inc	2010-04-29 14:52:05 +0000
@@ -0,0 +1,5 @@
+# Use replace_regex to remove non-deterministic values from the
+# ndb_desc output
+#
+--replace_regex /Version: [0-9]*/Version: Any/  /t2_unique_index\(j\) - OrderedIndex/Index/ /t2_unique_index\$unique\(j\) - UniqueHashIndex/Index/ /PRIMARY\(i\) - OrderedIndex/Index/  /BT=NDB\$BLOB_[0-9]*_/BT=NDB$BLOB_XX_/ 
+--exec $NDB_DESC --no-defaults $ndb_desc_opts

=== added directory 'mysql-test/std_data/ndb_backup_before_native_default'
=== added file 'mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.1.Data'
Binary files a/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.1.Data	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.1.Data	2010-04-29 14:52:05 +0000 differ

=== added file 'mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.2.Data'
Binary files a/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.2.Data	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1-0.2.Data	2010-04-29 14:52:05 +0000 differ

=== added file 'mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.ctl'
Binary files a/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.ctl	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.ctl	2010-04-29 14:52:05 +0000 differ

=== added file 'mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.log'
Binary files a/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.log	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.1.log	2010-04-29 14:52:05 +0000 differ

=== added file 'mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.ctl'
Binary files a/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.ctl	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.ctl	2010-04-29 14:52:05 +0000 differ

=== added file 'mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.log'
Binary files a/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.log	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/ndb_backup_before_native_default/BACKUP-1.2.log	2010-04-29 14:52:05 +0000 differ

=== added file 'mysql-test/suite/ndb/r/ndb_native_default_support.result'
--- a/mysql-test/suite/ndb/r/ndb_native_default_support.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_native_default_support.result	2010-04-29 14:52:05 +0000
@@ -0,0 +1,574 @@
+DROP TABLE IF EXISTS t1,bit1;
+DROP DATABASE IF EXISTS mysqltest;
+CREATE DATABASE mysqltest;
+USE mysqltest;
+***************************************************************
+* BASIC SQL STATEMENT TEST FOR NDB NATIVE DEFAULT VALUE SUPPORT
+***************************************************************
+CREATE TABLE t1( 
+i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+j INT DEFAULT 6, 
+f FLOAT NOT NULL DEFAULT 6.6, 
+d DOUBLE DEFAULT 8.8,
+d2 DOUBLE NOT NULL,  #d2 gets 'data-type-specific default', i.e. 0.
+ch CHAR(19) DEFAULT "aaa",
+vch VARCHAR(19) DEFAULT "bbb", 
+b BINARY(19) DEFAULT "ccc",
+vb VARBINARY(19) DEFAULT  "ddd", 
+blob1 BLOB,
+text1 TEXT,
+timestamp_c TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+)ENGINE=NDB;
+INSERT INTO t1 VALUES(),();
+INSERT INTO t1 VALUES(
+10, 10, 10.0, 10.0, 10.0,
+"nnnnn", "nnnnn", "nnnnn", "nnnnn", "nnnnn", "nnnnn", 
+"2008-11-16 08:13:32");
+INSERT INTO t1(i, ch) VALUES(11, "mmm");
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+10	10	10	10	10	nnnnn	nnnnn	6E6E6E6E6E0000000000000000000000000000	6E6E6E6E6E	6E6E6E6E6E	nnnnn	CURRENT_TIMESTAMP
+11	6	6.6	8.8	0	mmm	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+UPDATE t1 SET ch = "xxx" WHERE i = 10;
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+10	10	10	10	10	xxx	nnnnn	6E6E6E6E6E0000000000000000000000000000	6E6E6E6E6E	6E6E6E6E6E	nnnnn	CURRENT_TIMESTAMP
+11	6	6.6	8.8	0	mmm	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+UPDATE t1 SET blob1 = "yyy" WHERE j = 10;
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+10	10	10	10	10	xxx	nnnnn	6E6E6E6E6E0000000000000000000000000000	6E6E6E6E6E	797979	nnnnn	CURRENT_TIMESTAMP
+11	6	6.6	8.8	0	mmm	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+REPLACE INTO t1(i, j, ch) VALUES(1, 1, "zzz");
+REPLACE INTO t1(i, j, ch) VALUES(20, 20, "www");
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	1	6.6	8.8	0	zzz	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+10	10	10	10	10	xxx	nnnnn	6E6E6E6E6E0000000000000000000000000000	6E6E6E6E6E	797979	nnnnn	CURRENT_TIMESTAMP
+11	6	6.6	8.8	0	mmm	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+20	20	6.6	8.8	0	www	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+DELETE FROM t1 WHERE i > 9;
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	1	6.6	8.8	0	zzz	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+CREATE TABLE bit1(
+pk INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
+b1 BIT(3) DEFAULT B'111',
+b2 BIT(9) DEFAULT B'101',
+b3 BIT(23) DEFAULT B'110',
+b4 BIT(37) DEFAULT B'011',
+b5 BIT(63) DEFAULT B'101011'
+)ENGINE = NDB;
+INSERT INTO bit1 VALUES();
+INSERT INTO bit1(b1,b4) VALUES(B'101',B'111');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+pk	BIN(b1)	BIN(b2)	BIN(b3)	BIN(b4)	BIN(b5)
+1	111	101	110	11	101011
+2	101	101	110	111	101011
+UPDATE bit1 SET b5=B'11111' WHERE pk = 1;
+REPLACE INTO bit1(pk, b3) VALUES(2, B'1');
+REPLACE INTO bit1(pk, b3) VALUES(6, B'101');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+pk	BIN(b1)	BIN(b2)	BIN(b3)	BIN(b4)	BIN(b5)
+1	111	101	110	11	11111
+2	111	101	1	11	101011
+6	111	101	101	11	101011
+DELETE FROM bit1 WHERE pk = 2;
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+pk	BIN(b1)	BIN(b2)	BIN(b3)	BIN(b4)	BIN(b5)
+1	111	101	110	11	11111
+6	111	101	101	11	101011
+********************************************************
+* Alter table to add column with default value
+********************************************************
+ALTER TABLE t1 ADD COLUMN ch2 CHAR(30) DEFAULT "alter table";
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c	ch2
+1	1	6.6	8.8	0	zzz	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+INSERT INTO t1 VALUES();
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c	ch2
+1	1	6.6	8.8	0	zzz	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+21	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+********************************************************
+* Alter table with default value can fail safely
+********************************************************
+ALTER TABLE t1 ADD COLUMN ch2 CHAR(30) DEFAULT "alter table";
+ERROR 42S21: Duplicate column name 'ch2'
+ALTER TABLE t1 ADD COLUMN ch3 CHAR(3) DEFAULT "alter table";
+ERROR 42000: Invalid default value for 'ch3'
+INSERT INTO t1 VALUES();
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c	ch2
+1	1	6.6	8.8	0	zzz	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+21	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+22	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+********************************************************
+* The tables with default values BACKUP and RESTORE test
+********************************************************
+DROP TABLE IF EXISTS t1, bit1;
+********************************************************
+* Begin to restore data from backup 
+********************************************************
+SHOW TABLES;
+Tables_in_mysqltest
+bit1
+t1
+-- t1 --
+Version: Any
+Fragment type: 9
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 13
+Number of primary keys: 1
+Length of frm data: 518
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+i Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+j Int NULL AT=FIXED ST=MEMORY DEFAULT 6
+f Float NOT NULL AT=FIXED ST=MEMORY DEFAULT 6.600000
+d Double NULL AT=FIXED ST=MEMORY DEFAULT 8.800000
+d2 Double NOT NULL AT=FIXED ST=MEMORY
+ch Char(19;latin1_swedish_ci) NULL AT=FIXED ST=MEMORY DEFAULT "aaa"
+vch Varchar(19;latin1_swedish_ci) NULL AT=SHORT_VAR ST=MEMORY DEFAULT "bbb"
+b Binary(19) NULL AT=FIXED ST=MEMORY DEFAULT 0x636363
+vb Varbinary(19) NULL AT=SHORT_VAR ST=MEMORY DEFAULT 0x646464
+blob1 Blob(256,2000,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_XX_9
+text1 Text(256,2000,0;latin1_swedish_ci) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_XX_10
+timestamp_c Timestamp NOT NULL AT=FIXED ST=MEMORY DEFAULT 0
+ch2 Char(30;latin1_swedish_ci) NULL AT=FIXED ST=MEMORY DEFAULT "alter table"
+
+-- Indexes -- 
+PRIMARY KEY(i) - UniqueHashIndex
+Index
+
+
+NDBT_ProgramExit: 0 - OK
+
+-- bit1 --
+Version: Any
+Fragment type: 9
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 6
+Number of primary keys: 1
+Length of frm data: 324
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+pk Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+b1 Bit(3) NULL AT=FIXED ST=MEMORY DEFAULT H'0x7
+b2 Bit(9) NULL AT=FIXED ST=MEMORY DEFAULT H'0x5
+b3 Bit(23) NULL AT=FIXED ST=MEMORY DEFAULT H'0x6
+b4 Bit(37) NULL AT=FIXED ST=MEMORY DEFAULT H'0x3
+b5 Bit(63) NULL AT=FIXED ST=MEMORY DEFAULT H'0x2B
+
+-- Indexes -- 
+PRIMARY KEY(pk) - UniqueHashIndex
+PRIMARY(pk) - OrderedIndex
+
+
+NDBT_ProgramExit: 0 - OK
+
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+pk	BIN(b1)	BIN(b2)	BIN(b3)	BIN(b4)	BIN(b5)
+1	111	101	110	11	11111
+6	111	101	101	11	101011
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c	ch2
+1	1	6.6	8.8	0	zzz	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+21	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+22	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+INSERT INTO t1(i, ch) VALUES(99, "restore");
+INSERT INTO bit1(pk, b5) VALUES(99, B'11111111');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+pk	BIN(b1)	BIN(b2)	BIN(b3)	BIN(b4)	BIN(b5)
+1	111	101	110	11	11111
+6	111	101	101	11	101011
+99	111	101	110	11	11111111
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c	ch2
+1	1	6.6	8.8	0	zzz	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+21	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+22	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+99	6	6.6	8.8	0	restore	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+DROP TABLE IF EXISTS t1, bit1;
+SHOW TABLES;
+Tables_in_mysqltest
+bit1
+t1
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 WHERE i >= (SELECT MAX(i) FROM t1) ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c	ch2
+MAX_VALUE	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP	alter table
+DROP TABLE IF EXISTS t1, bit1;
+DROP DATABASE mysqltest;
+******************************************************************************
+* Restore the backup from 6.3 or 6.4, which don't support native default value
+******************************************************************************
+USE test;
+SHOW TABLES;
+Tables_in_test
+bit1
+t1
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `i` int(11) NOT NULL AUTO_INCREMENT,
+  `j` int(11) DEFAULT '6',
+  `f` float NOT NULL DEFAULT '6.6',
+  `d` double DEFAULT '8.8',
+  `d2` double NOT NULL,
+  `ch` char(19) DEFAULT 'aaa',
+  `vch` varchar(19) DEFAULT 'bbb',
+  `b` binary(19) DEFAULT 'ccc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
+  `vb` varbinary(19) DEFAULT 'ddd',
+  `blob1` blob,
+  `text1` text,
+  `timestamp_c` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY (`i`)
+) ENGINE=ndbcluster AUTO_INCREMENT=12 DEFAULT CHARSET=latin1
+SHOW CREATE TABLE bit1;
+Table	Create Table
+bit1	CREATE TABLE `bit1` (
+  `pk` int(11) NOT NULL AUTO_INCREMENT,
+  `b1` bit(3) DEFAULT b'111',
+  `b2` bit(9) DEFAULT b'101',
+  `b3` bit(23) DEFAULT b'110',
+  `b4` bit(37) DEFAULT b'11',
+  `b5` bit(63) DEFAULT b'101011',
+  PRIMARY KEY (`pk`)
+) ENGINE=ndbcluster AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+10	10	10	10	10	nnnnn	nnnnn	6E6E6E6E6E0000000000000000000000000000	6E6E6E6E6E	6E6E6E6E6E	nnnnn	CURRENT_TIMESTAMP
+11	6	6.6	8.8	0	mmm	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+pk	BIN(b1)	BIN(b2)	BIN(b3)	BIN(b4)	BIN(b5)
+1	111	101	110	11	101011
+2	101	101	110	111	101011
+INSERT INTO t1 VALUES();
+UPDATE t1 SET ch = "RESTORE FROM 6.3" WHERE i = 12;
+REPLACE INTO t1(i, j, ch) VALUES(20, 20, "RESTORE FROM 6.3");
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+10	10	10	10	10	nnnnn	nnnnn	6E6E6E6E6E0000000000000000000000000000	6E6E6E6E6E	6E6E6E6E6E	nnnnn	CURRENT_TIMESTAMP
+11	6	6.6	8.8	0	mmm	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+12	6	6.6	8.8	0	RESTORE FROM 6.3	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+20	20	6.6	8.8	0	RESTORE FROM 6.3	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+INSERT INTO bit1 VALUES();
+UPDATE bit1 SET b5=b'1111111' WHERE pk = 1;
+REPLACE INTO bit1(pk, b3) VALUES(6, B'110011');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+pk	BIN(b1)	BIN(b2)	BIN(b3)	BIN(b4)	BIN(b5)
+1	111	101	110	11	1111111
+2	101	101	110	111	101011
+3	111	101	110	11	101011
+6	111	101	110011	11	101011
+********************************************************************************
+* Alter table restoring from 6.3 backup to new table with native default support
+********************************************************************************
+-- t1 --
+Version: Any
+Fragment type: 5
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 12
+Number of primary keys: 1
+Length of frm data: 484
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+i Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+j Int NULL AT=FIXED ST=MEMORY
+f Float NOT NULL AT=FIXED ST=MEMORY
+d Double NULL AT=FIXED ST=MEMORY
+d2 Double NOT NULL AT=FIXED ST=MEMORY
+ch Char(19;latin1_swedish_ci) NULL AT=FIXED ST=MEMORY
+vch Varchar(19;latin1_swedish_ci) NULL AT=SHORT_VAR ST=MEMORY
+b Binary(19) NULL AT=FIXED ST=MEMORY
+vb Varbinary(19) NULL AT=SHORT_VAR ST=MEMORY
+blob1 Blob(256,2000,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_XX_9
+text1 Text(256,2000,0;latin1_swedish_ci) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_XX_10
+timestamp_c Timestamp NOT NULL AT=FIXED ST=MEMORY
+
+-- Indexes -- 
+PRIMARY KEY(i) - UniqueHashIndex
+Index
+
+
+NDBT_ProgramExit: 0 - OK
+
+ALTER TABLE t1 CHANGE COLUMN j j INT DEFAULT 6;
+-- t1 --
+Version: Any
+Fragment type: 9
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 12
+Number of primary keys: 1
+Length of frm data: 487
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+i Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+j Int NULL AT=FIXED ST=MEMORY DEFAULT 6
+f Float NOT NULL AT=FIXED ST=MEMORY DEFAULT 6.600000
+d Double NULL AT=FIXED ST=MEMORY DEFAULT 8.800000
+d2 Double NOT NULL AT=FIXED ST=MEMORY
+ch Char(19;latin1_swedish_ci) NULL AT=FIXED ST=MEMORY DEFAULT "aaa"
+vch Varchar(19;latin1_swedish_ci) NULL AT=SHORT_VAR ST=MEMORY DEFAULT "bbb"
+b Binary(19) NULL AT=FIXED ST=MEMORY DEFAULT 0x636363
+vb Varbinary(19) NULL AT=SHORT_VAR ST=MEMORY DEFAULT 0x646464
+blob1 Blob(256,2000,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_XX_9
+text1 Text(256,2000,0;latin1_swedish_ci) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_XX_10
+timestamp_c Timestamp NOT NULL AT=FIXED ST=MEMORY DEFAULT 0
+
+-- Indexes -- 
+PRIMARY KEY(i) - UniqueHashIndex
+Index
+
+
+NDBT_ProgramExit: 0 - OK
+
+INSERT INTO t1(i, ch) VALUES(99, "native default support");
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+i	j	f	d	d2	ch	vch	HEX(b)	HEX(vb)	HEX(blob1)	text1	timestamp_c
+1	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+2	6	6.6	8.8	0	aaa	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+10	10	10	10	10	nnnnn	nnnnn	6E6E6E6E6E0000000000000000000000000000	6E6E6E6E6E	6E6E6E6E6E	nnnnn	CURRENT_TIMESTAMP
+11	6	6.6	8.8	0	mmm	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+12	6	6.6	8.8	0	RESTORE FROM 6.3	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+20	20	6.6	8.8	0	RESTORE FROM 6.3	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+99	6	6.6	8.8	0	native default supp	bbb	63636300000000000000000000000000000000	646464	NULL	NULL	CURRENT_TIMESTAMP
+DROP TABLE IF EXISTS t1, bit1;
+*************************************************************
+* Test adding a unique index to a column with a default value
+*************************************************************
+CREATE TABLE t2(
+i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+j INT DEFAULT 6,
+f FLOAT NOT NULL DEFAULT 6.6,
+d DOUBLE DEFAULT 8.8,
+UNIQUE INDEX t2_unique_index(j) 
+)ENGINE =NDB;
+INSERT INTO t2 VALUES();
+INSERT INTO t2 VALUES();
+ERROR 23000: Duplicate entry '6' for key 't2_unique_index'
+INSERT INTO t2 VALUES(10, 10, 10.0, 10.0);
+SELECT * FROM t2 ORDER BY i;
+i	j	f	d
+1	6	6.6	8.8
+10	10	10	10
+*************************************************************
+* Test offline alter of default values
+*************************************************************
+ALTER TABLE t2 MODIFY COLUMN j INT DEFAULT 666;
+-- t2 --
+Version: Any
+Fragment type: 9
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 4
+Number of primary keys: 1
+Length of frm data: 331
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+i Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+j Int NULL AT=FIXED ST=MEMORY DEFAULT 666
+f Float NOT NULL AT=FIXED ST=MEMORY DEFAULT 6.600000
+d Double NULL AT=FIXED ST=MEMORY DEFAULT 8.800000
+
+-- Indexes -- 
+PRIMARY KEY(i) - UniqueHashIndex
+Index
+Index
+Index
+
+
+NDBT_ProgramExit: 0 - OK
+
+INSERT INTO t2 VALUES();
+SELECT * FROM t2 ORDER BY i;
+i	j	f	d
+1	6	6.6	8.8
+10	10	10	10
+11	666	6.6	8.8
+*************************************************************
+* Test that online alter of default values fails
+*************************************************************
+ALTER ONLINE TABLE t2 MODIFY COLUMN j INT DEFAULT 888;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER ONLINE TABLE t2 MODIFY COLUMN j INT DEFAULT 888'
+DROP TABLE IF EXISTS t2;
+**************************************************************
+* Test not null-after-defaults example that failed previously
+**************************************************************
+CREATE TABLE t1 (a int primary key, b int default 12, c char not null) engine=ndb;
+-- t1 --
+Version: Any
+Fragment type: 9
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 3
+Number of primary keys: 1
+Length of frm data: 267
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+a Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
+b Int NULL AT=FIXED ST=MEMORY DEFAULT 12
+c Char(1;latin1_swedish_ci) NOT NULL AT=FIXED ST=MEMORY
+
+-- Indexes -- 
+PRIMARY KEY(a) - UniqueHashIndex
+PRIMARY(a) - OrderedIndex
+
+
+NDBT_ProgramExit: 0 - OK
+
+DROP TABLE t1;
+**************************************************************
+* Test mix of null, not-null, default etc..
+**************************************************************
+CREATE TABLE t1 (a int primary key, 
+b int default 12, 
+c char not null, 
+d varchar(6) default 'Daniel',
+e char(3) default 'Stu',
+f enum('NBFry','Kebab') default 'NBFry',
+g set('Chips','Pie','Fish') default 'Fish,Chips',
+h enum('Pig','Lion') not null,
+i char(2) default '66') engine=ndb;
+-- t1 --
+Version: Any
+Fragment type: 9
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 9
+Number of primary keys: 1
+Length of frm data: 409
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+a Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
+b Int NULL AT=FIXED ST=MEMORY DEFAULT 12
+c Char(1;latin1_swedish_ci) NOT NULL AT=FIXED ST=MEMORY
+d Varchar(6;latin1_swedish_ci) NULL AT=SHORT_VAR ST=MEMORY DEFAULT "Daniel"
+e Char(3;latin1_swedish_ci) NULL AT=FIXED ST=MEMORY DEFAULT "Stu"
+f Char(1;binary) NULL AT=FIXED ST=MEMORY DEFAULT "0x01"
+g Char(1;binary) NULL AT=FIXED ST=MEMORY DEFAULT "0x05"
+h Char(1;binary) NOT NULL AT=FIXED ST=MEMORY
+i Char(2;latin1_swedish_ci) NULL AT=FIXED ST=MEMORY DEFAULT "66"
+
+-- Indexes -- 
+PRIMARY KEY(a) - UniqueHashIndex
+PRIMARY(a) - OrderedIndex
+
+
+NDBT_ProgramExit: 0 - OK
+
+DROP TABLE t1;
+******************************************
+* Test binary default with null char value
+******************************************
+CREATE TABLE t1 (a int primary key,
+b binary(10) default 0x4142430045464748494a,
+c varbinary(100) default 0x4142430045464748494a) engine=ndb;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` binary(10) DEFAULT 'ABC\0EFGHIJ',
+  `c` varbinary(100) DEFAULT 'ABC\0EFGHIJ',
+  PRIMARY KEY (`a`)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+-- t1 --
+Version: Any
+Fragment type: 9
+K Value: 6
+Min load factor: 78
+Max load factor: 80
+Temporary table: no
+Number of attributes: 3
+Number of primary keys: 1
+Length of frm data: 284
+Row Checksum: 1
+Row GCI: 1
+SingleUserMode: 0
+ForceVarPart: 1
+FragmentCount: 2
+TableStatus: Retrieved
+-- Attributes -- 
+a Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
+b Binary(10) NULL AT=FIXED ST=MEMORY DEFAULT 0x4142430045464748494A
+c Varbinary(100) NULL AT=SHORT_VAR ST=MEMORY DEFAULT 0x4142430045464748494A
+
+-- Indexes -- 
+PRIMARY KEY(a) - UniqueHashIndex
+PRIMARY(a) - OrderedIndex
+
+
+NDBT_ProgramExit: 0 - OK
+
+DROP TABLE t1;
+End of ndb native default support test

=== modified file 'mysql-test/suite/ndb/r/ndb_restore_promotion.result'
--- a/mysql-test/suite/ndb/r/ndb_restore_promotion.result	2009-08-18 13:02:20 +0000
+++ b/mysql-test/suite/ndb/r/ndb_restore_promotion.result	2010-04-29 14:52:05 +0000
@@ -197,3 +197,40 @@ a	c	d	e
 3	c	D	e
 4	c	d	E
 drop table t1;
+create table subject(pk int primary key, band varchar(50), pos int) engine=ndb;
+insert into subject values (1, 'Elbow', 1), (2, 'Franz Ferdinand', 2), (3, 'Proclaimers', 3);
+insert into subject values (4, 'David Bowie', 4), (5, 'Rufus Wainwright', 1);
+select * from subject order by pk;
+pk	band	pos
+1	Elbow	1
+2	Franz Ferdinand	2
+3	Proclaimers	3
+4	David Bowie	4
+5	Rufus Wainwright	1
+**************************
+Performing backup of table
+**************************
+******************
+Throwing away data
+******************
+delete from subject;
+select * from subject order by pk;
+pk	band	pos
+*******************************************************
+Modifying table to include new, native defaulted column
+*******************************************************
+alter table subject add column song varchar(50) default 'Unknown';
+***********************************************************
+Restoring data back into table and picking up default value
+***********************************************************
+****************************************************
+All restored entries should have song name 'Unknown'
+****************************************************
+select * from subject order by pk;
+pk	band	pos	song
+1	Elbow	1	Unknown
+2	Franz Ferdinand	2	Unknown
+3	Proclaimers	3	Unknown
+4	David Bowie	4	Unknown
+5	Rufus Wainwright	1	Unknown
+drop table subject;

=== added file 'mysql-test/suite/ndb/t/ndb_native_default_support.test'
--- a/mysql-test/suite/ndb/t/ndb_native_default_support.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_native_default_support.test	2010-04-29 14:52:05 +0000
@@ -0,0 +1,314 @@
+#############################################################
+# Author: Guangbao Ni
+# Date: 2008-12
+# Purpose: ndb native default support test
+##############################################################
+
+-- source include/have_ndb.inc
+-- source include/ndb_default_cluster.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,bit1;
+DROP DATABASE IF EXISTS mysqltest;
+--enable_warnings
+
+CREATE DATABASE mysqltest;
+USE mysqltest;
+###############################################################
+# BASIC SQL STATEMENT TEST FOR NDB NATIVE DEFAULT VALUE SUPPORT
+###############################################################
+# Create table with default values for some types.
+# Create table for bit type.
+# Test cases include:
+# 1. Create table with default values
+# 2. Insert statement:
+#  --Insert default values into, the default values can be inserted into table correctly
+#  --Insert record supplied by client, it can inserted correctly
+#  --Insert record (including default value and value supplied by client)
+# 3. Update statement:
+#  --Update with primary key condition
+#  --Update with non-primary key condtion
+# 4. Replace statement:
+#  --Replace with default values when the record isn't existed in table
+#  --Replace with part default values and part value supplied by client when the record isn't existed in table.
+#  --Replace with part default values and part value suppliced by client when the record already existed in table.
+# 5. Delete statement:
+
+--echo ***************************************************************
+--echo * BASIC SQL STATEMENT TEST FOR NDB NATIVE DEFAULT VALUE SUPPORT
+--echo ***************************************************************
+
+CREATE TABLE t1( 
+  i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  j INT DEFAULT 6, 
+  f FLOAT NOT NULL DEFAULT 6.6, 
+  d DOUBLE DEFAULT 8.8,
+  d2 DOUBLE NOT NULL,  #d2 gets 'data-type-specific default', i.e. 0.
+  ch CHAR(19) DEFAULT "aaa",
+  vch VARCHAR(19) DEFAULT "bbb", 
+  b BINARY(19) DEFAULT "ccc",
+  vb VARBINARY(19) DEFAULT  "ddd", 
+  blob1 BLOB,
+  text1 TEXT,
+  timestamp_c TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+)ENGINE=NDB;
+
+--disable_warnings
+INSERT INTO t1 VALUES(),();
+
+INSERT INTO t1 VALUES(
+  10, 10, 10.0, 10.0, 10.0,
+  "nnnnn", "nnnnn", "nnnnn", "nnnnn", "nnnnn", "nnnnn", 
+  "2008-11-16 08:13:32");
+INSERT INTO t1(i, ch) VALUES(11, "mmm");
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+
+UPDATE t1 SET ch = "xxx" WHERE i = 10;
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+
+UPDATE t1 SET blob1 = "yyy" WHERE j = 10;
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+
+REPLACE INTO t1(i, j, ch) VALUES(1, 1, "zzz");
+REPLACE INTO t1(i, j, ch) VALUES(20, 20, "www");
+--enable_warnings
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+DELETE FROM t1 WHERE i > 9;
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+
+#Test BIT TYPE
+CREATE TABLE bit1(
+  pk INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
+  b1 BIT(3) DEFAULT B'111',
+  b2 BIT(9) DEFAULT B'101',
+  b3 BIT(23) DEFAULT B'110',
+  b4 BIT(37) DEFAULT B'011',
+  b5 BIT(63) DEFAULT B'101011'
+)ENGINE = NDB;
+
+INSERT INTO bit1 VALUES();
+INSERT INTO bit1(b1,b4) VALUES(B'101',B'111');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+
+UPDATE bit1 SET b5=B'11111' WHERE pk = 1;
+REPLACE INTO bit1(pk, b3) VALUES(2, B'1');
+REPLACE INTO bit1(pk, b3) VALUES(6, B'101');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+
+DELETE FROM bit1 WHERE pk = 2;
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk; 
+
+#############################################################
+# ALTER TABLE WITH DEFAULT VALUES TEST
+#############################################################
+--echo ********************************************************
+--echo * Alter table to add column with default value
+--echo ********************************************************
+ALTER TABLE t1 ADD COLUMN ch2 CHAR(30) DEFAULT "alter table";
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+--disable_warnings
+INSERT INTO t1 VALUES();
+--enable_warnings
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+
+--echo ********************************************************
+--echo * Alter table with default value can fail safely
+--echo ********************************************************
+--disable_warnings
+--error 1060
+ALTER TABLE t1 ADD COLUMN ch2 CHAR(30) DEFAULT "alter table";
+--error 1067
+ALTER TABLE t1 ADD COLUMN ch3 CHAR(3) DEFAULT "alter table";
+INSERT INTO t1 VALUES();
+--enable_warnings
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+
+##############################################################
+# BACKUP AND RESTORE TEST FOR TABLE WITH DEFAULT VALUES
+##############################################################
+#the above two tables are backuped, they can restore correctly.
+#The default values can be inserted correctly after restored.
+--echo ********************************************************
+--echo * The tables with default values BACKUP and RESTORE test
+--echo ********************************************************
+--source include/ndb_backup.inc
+DROP TABLE IF EXISTS t1, bit1;
+
+--echo ********************************************************
+--echo * Begin to restore data from backup 
+--echo ********************************************************
+--exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 1 -A -m  -r --print --print_meta $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 2 -A -r --print --print_meta $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+
+--sorted_result
+SHOW TABLES;
+--let ndb_desc_opts= -d mysqltest t1
+--source include/ndb_desc_print.inc
+--let ndb_desc_opts= -d mysqltest bit1
+--source include/ndb_desc_print.inc
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+
+--disable_warnings
+INSERT INTO t1(i, ch) VALUES(99, "restore");
+--enable_warnings
+INSERT INTO bit1(pk, b5) VALUES(99, B'11111111');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 ORDER BY i;
+DROP TABLE IF EXISTS t1, bit1;
+
+
+--exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 1 -A -m  -r --print_meta $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 2 -A -r --print_meta $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--sorted_result
+SHOW TABLES;
+--replace_column 1 MAX_VALUE 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c, ch2 FROM t1 WHERE i >= (SELECT MAX(i) FROM t1) ORDER BY i;
+
+DROP TABLE IF EXISTS t1, bit1;
+DROP DATABASE mysqltest;
+
+###############################################################################
+# RESTORE THE BACKUP FROM 6.3 OR 6.4, WHICH DON'T SUPPORT NATIVE DEFAULT VALUE
+# SO DEFAULT VALUES AREN'T STORED IN NDBD KERNEL
+###############################################################################
+--echo ******************************************************************************
+--echo * Restore the backup from 6.3 or 6.4, which don't support native default value
+--echo ******************************************************************************
+
+--exec $NDB_RESTORE --no-defaults -b 1 -n 1 -m -r $MYSQL_TEST_DIR/std_data/ndb_backup_before_native_default >> $NDB_TOOLS_OUTPUT
+--exec $NDB_RESTORE --no-defaults -b 1 -n 2 -r $MYSQL_TEST_DIR/std_data/ndb_backup_before_native_default >> $NDB_TOOLS_OUTPUT
+
+USE test;
+--sorted_result
+SHOW TABLES;
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE bit1;
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+--disable_warnings
+INSERT INTO t1 VALUES();
+UPDATE t1 SET ch = "RESTORE FROM 6.3" WHERE i = 12;
+REPLACE INTO t1(i, j, ch) VALUES(20, 20, "RESTORE FROM 6.3");
+--enable_warnings
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+
+INSERT INTO bit1 VALUES();
+UPDATE bit1 SET b5=b'1111111' WHERE pk = 1;
+REPLACE INTO bit1(pk, b3) VALUES(6, B'110011');
+SELECT pk,BIN(b1),BIN(b2),BIN(b3),BIN(b4),BIN(b5) FROM bit1 ORDER BY pk;
+
+#########################################################################
+# OFFLINE ALTER OF 'OLD' TABLE WITH NO DEFAULTS TO 'NEW' TABLE 
+# WITH NATIVE DEFAULTS.
+#########################################################################
+--echo ********************************************************************************
+--echo * Alter table restoring from 6.3 backup to new table with native default support
+--echo ********************************************************************************
+--let ndb_desc_opts= -d test t1
+--source include/ndb_desc_print.inc
+
+ALTER TABLE t1 CHANGE COLUMN j j INT DEFAULT 6;
+
+--let ndb_desc_opts= -d test t1
+--source include/ndb_desc_print.inc
+
+--disable_warnings
+INSERT INTO t1(i, ch) VALUES(99, "native default support");
+--enable_warnings
+--replace_column 12 CURRENT_TIMESTAMP
+SELECT i, j, f, d, d2, ch, vch, HEX(b), HEX(vb), HEX(blob1), text1, timestamp_c FROM t1 ORDER BY i;
+
+DROP TABLE IF EXISTS t1, bit1;
+--echo *************************************************************
+--echo * Test adding a unique index to a column with a default value
+--echo *************************************************************
+CREATE TABLE t2(
+  i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  j INT DEFAULT 6,
+  f FLOAT NOT NULL DEFAULT 6.6,
+  d DOUBLE DEFAULT 8.8,
+  UNIQUE INDEX t2_unique_index(j) 
+)ENGINE =NDB;
+INSERT INTO t2 VALUES();
+--error 1062
+INSERT INTO t2 VALUES();
+INSERT INTO t2 VALUES(10, 10, 10.0, 10.0);
+SELECT * FROM t2 ORDER BY i;
+
+--echo *************************************************************
+--echo * Test offline alter of default values
+--echo *************************************************************
+ALTER TABLE t2 MODIFY COLUMN j INT DEFAULT 666;
+
+--let ndb_desc_opts= -d test t2
+--source include/ndb_desc_print.inc
+INSERT INTO t2 VALUES();
+SELECT * FROM t2 ORDER BY i;
+
+--echo *************************************************************
+--echo * Test that online alter of default values fails
+--echo *************************************************************
+--error 1235
+ALTER ONLINE TABLE t2 MODIFY COLUMN j INT DEFAULT 888;
+
+DROP TABLE IF EXISTS t2;
+
+--echo **************************************************************
+--echo * Test not null-after-defaults example that failed previously
+--echo **************************************************************
+
+CREATE TABLE t1 (a int primary key, b int default 12, c char not null) engine=ndb;
+--let ndb_desc_opts= -d test t1
+--source include/ndb_desc_print.inc
+
+DROP TABLE t1;
+
+--echo **************************************************************
+--echo * Test mix of null, not-null, default etc..
+--echo **************************************************************
+
+CREATE TABLE t1 (a int primary key, 
+                 b int default 12, 
+                 c char not null, 
+                 d varchar(6) default 'Daniel',
+                 e char(3) default 'Stu',
+                 f enum('NBFry','Kebab') default 'NBFry',
+                 g set('Chips','Pie','Fish') default 'Fish,Chips',
+                 h enum('Pig','Lion') not null,
+                 i char(2) default '66') engine=ndb;
+--let ndb_desc_opts= -d test t1
+--source include/ndb_desc_print.inc
+
+DROP TABLE t1;
+
+--echo ******************************************
+--echo * Test binary default with null char value
+--echo ******************************************
+
+CREATE TABLE t1 (a int primary key,
+                 b binary(10) default 0x4142430045464748494a,
+                 c varbinary(100) default 0x4142430045464748494a) engine=ndb;
+
+SHOW CREATE TABLE t1;
+
+--let ndb_desc_opts= -d test t1
+--source include/ndb_desc_print.inc
+
+DROP TABLE t1;
+
+
+
+--echo End of ndb native default support test

=== modified file 'mysql-test/suite/ndb/t/ndb_restore_promotion.test'
--- a/mysql-test/suite/ndb/t/ndb_restore_promotion.test	2009-08-18 13:21:50 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore_promotion.test	2010-04-29 14:52:05 +0000
@@ -256,3 +256,46 @@ create table t1(c char(1),
 
 select a,c,d,e from t1 order by a;
 drop table t1;
+ 
+# Testcase for restore with native default added to table (WL4197)
+create table subject(pk int primary key, band varchar(50), pos int) engine=ndb;
+
+insert into subject values (1, 'Elbow', 1), (2, 'Franz Ferdinand', 2), (3, 'Proclaimers', 3);
+insert into subject values (4, 'David Bowie', 4), (5, 'Rufus Wainwright', 1);
+
+select * from subject order by pk;
+
+--echo **************************
+--echo Performing backup of table
+--echo **************************
+
+--source include/ndb_backup.inc
+
+--echo ******************
+--echo Throwing away data
+--echo ******************
+delete from subject;
+
+select * from subject order by pk;
+
+--echo *******************************************************
+--echo Modifying table to include new, native defaulted column
+--echo *******************************************************
+alter table subject add column song varchar(50) default 'Unknown';
+
+--echo ***********************************************************
+--echo Restoring data back into table and picking up default value
+--echo ***********************************************************
+
+# Note testcase nastily assumes 2 nodes, called 1 + 2.
+--exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 1 -r --print --print_meta --skip-table-check $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_RESTORE --no-defaults -b $the_backup_id -n 2 -r --print --print_meta --skip-table-check $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
+
+--echo ****************************************************
+--echo All restored entries should have song name 'Unknown'
+--echo ****************************************************
+
+select * from subject order by pk;
+
+drop table subject;
+# End of testcase for WL4197
\ No newline at end of file

=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_2ndb.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_2ndb.result	2008-02-11 14:06:07 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_2ndb.result	2010-04-29 14:52:05 +0000
@@ -266,14 +266,14 @@ select *
 from t1 
 order by id;
 id	b1	vc	bc	d	f	total	y	t	u	v
-2	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1965-11-14	NULL	NULL
+2	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1965-11-14	NULL	default
 3	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1905-11-14	7	default
-4	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1985-11-14	NULL	NULL
+4	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1985-11-14	NULL	default
 20	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1965-11-14	7	explicit
-42	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1905-11-14	NULL	NULL
+42	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1905-11-14	NULL	default
 50	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1985-11-14	NULL	explicit
-142	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1995-11-14	NULL	NULL
-412	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	2005-11-14	NULL	NULL
+142	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	1995-11-14	NULL	default
+412	1	Testing MySQL databases is a cool 	Must make it bug free for the customer	654321.4321	15.21	0	1965	2005-11-14	NULL	default
 --- Perform basic operation on master ---
 --- and ensure replicated correctly ---
 --- Update t1 on master --
@@ -298,11 +298,11 @@ FROM t1 
 WHERE id < 100
 ORDER BY id;
 id	b1	vc	bc	d	f	total	y	t	u	v
-2	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	NULL	NULL
+2	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	NULL	default
 3	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	7	default
-4	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	NULL	NULL
+4	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	NULL	default
 20	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	7	explicit
-42	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	NULL	NULL
+42	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	NULL	default
 50	0	Testing MySQL databases is a cool 	updated	654321.4321	15.21	0	1965	2006-02-22	NULL	explicit
 --- Remove a record from t1 on master ---
 DELETE FROM t1 WHERE id = 412;

=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result	2010-03-16 07:53:04 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result	2010-04-29 14:52:05 +0000
@@ -31,9 +31,9 @@ a	b	c
 *** Select from slave ***
 SELECT * FROM t1 ORDER BY a;
 a	b	c	d	e
-1	2	TEXAS	NULL	NULL
-2	1	AUSTIN	NULL	NULL
-3	4	QA	NULL	NULL
+1	2	TEXAS	2	TEST
+2	1	AUSTIN	2	TEST
+3	4	QA	2	TEST
 SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
 *** Drop t1  ***
 DROP TABLE t1;
@@ -395,9 +395,9 @@ a	b	c
 *** Select from slave ***
 SELECT * FROM t7 ORDER BY a;
 a	b	c	d	e
-1	b1b1	Kyle	NULL	NULL
-2	b1b1	JOE	NULL	NULL
-3	b1b1	QA	NULL	NULL
+1	b1b1	Kyle	0000-00-00 00:00:00	Extra Column Testing
+2	b1b1	JOE	0000-00-00 00:00:00	Extra Column Testing
+3	b1b1	QA	0000-00-00 00:00:00	Extra Column Testing
 *** Drop t7  ***
 DROP TABLE t7;
 *** Create t8 on slave  ***
@@ -592,9 +592,9 @@ a	b	c
 *** Select on Slave ***
 SELECT * FROM t12 ORDER BY a;
 a	b	f	c	e
-1	b1b1b1b1b1b1b1b1	Kyle	NULL	NULL
-2	b1b1b1b1b1b1b1b1	JOE	NULL	NULL
-3	b1b1b1b1b1b1b1b1	QA	NULL	NULL
+1	b1b1b1b1b1b1b1b1	Kyle	test	1
+2	b1b1b1b1b1b1b1b1	JOE	test	1
+3	b1b1b1b1b1b1b1b1	QA	test	1
 *** Drop t12  ***
 DROP TABLE t12;
 **** Extra Colums End ****
@@ -624,9 +624,9 @@ a	b	c
 *** Select on Slave ****
 SELECT * FROM t13 ORDER BY a;
 a	b	c	d	e
-1	b1b1b1b1b1b1b1b1	Kyle	NULL	CURRENT_TIMESTAMP
-2	b1b1b1b1b1b1b1b1	JOE	NULL	CURRENT_TIMESTAMP
-3	b1b1b1b1b1b1b1b1	QA	NULL	CURRENT_TIMESTAMP
+1	b1b1b1b1b1b1b1b1	Kyle	1	CURRENT_TIMESTAMP
+2	b1b1b1b1b1b1b1b1	JOE	1	CURRENT_TIMESTAMP
+3	b1b1b1b1b1b1b1b1	QA	1	CURRENT_TIMESTAMP
 *** Drop t13  ***
 DROP TABLE t13;
 *** 22117 END *** 
@@ -660,9 +660,9 @@ c1	c2	c3	c4	c5
 *** Select on Slave ****
 SELECT * FROM t14 ORDER BY c1;
 c1	c2	c3	c4	c5	c6	c7
-1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	NULL	CURRENT_TIMESTAMP
-2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	NULL	CURRENT_TIMESTAMP
-3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	NULL	CURRENT_TIMESTAMP
+1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	1	CURRENT_TIMESTAMP
+2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	1	CURRENT_TIMESTAMP
+3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	1	CURRENT_TIMESTAMP
 *** Create t14a on slave  ***
 STOP SLAVE;
 RESET SLAVE;
@@ -690,9 +690,9 @@ c1	c4	c5
 *** Select on Slave ****
 SELECT * FROM t14a ORDER BY c1;
 c1	c4	c5	c6	c7
-1	b1b1b1b1b1b1b1b1	Kyle	NULL	CURRENT_TIMESTAMP
-2	b1b1b1b1b1b1b1b1	JOE	NULL	CURRENT_TIMESTAMP
-3	b1b1b1b1b1b1b1b1	QA	NULL	CURRENT_TIMESTAMP
+1	b1b1b1b1b1b1b1b1	Kyle	1	CURRENT_TIMESTAMP
+2	b1b1b1b1b1b1b1b1	JOE	1	CURRENT_TIMESTAMP
+3	b1b1b1b1b1b1b1b1	QA	1	CURRENT_TIMESTAMP
 STOP SLAVE;
 RESET SLAVE;
 *** Master Drop c5 ***
@@ -717,12 +717,12 @@ c1	c4
 *** Select on Slave ****
 SELECT * FROM t14a ORDER BY c1;
 c1	c4	c5	c6	c7
-1	b1b1b1b1b1b1b1b1	Kyle	NULL	CURRENT_TIMESTAMP
-2	b1b1b1b1b1b1b1b1	JOE	NULL	CURRENT_TIMESTAMP
-3	b1b1b1b1b1b1b1b1	QA	NULL	CURRENT_TIMESTAMP
-4	b1b1b1b1b1b1b1b1	NULL	NULL	CURRENT_TIMESTAMP
-5	b1b1b1b1b1b1b1b1	NULL	NULL	CURRENT_TIMESTAMP
-6	b1b1b1b1b1b1b1b1	NULL	NULL	CURRENT_TIMESTAMP
+1	b1b1b1b1b1b1b1b1	Kyle	1	CURRENT_TIMESTAMP
+2	b1b1b1b1b1b1b1b1	JOE	1	CURRENT_TIMESTAMP
+3	b1b1b1b1b1b1b1b1	QA	1	CURRENT_TIMESTAMP
+4	b1b1b1b1b1b1b1b1	NULL	1	CURRENT_TIMESTAMP
+5	b1b1b1b1b1b1b1b1	NULL	1	CURRENT_TIMESTAMP
+6	b1b1b1b1b1b1b1b1	NULL	1	CURRENT_TIMESTAMP
 *** connect to master and drop columns ***
 ALTER TABLE t14 DROP COLUMN c2;
 ALTER TABLE t14 DROP COLUMN c4;
@@ -735,9 +735,9 @@ c1	c3	c5
 *** Select from Slave ***
 SELECT * FROM t14 ORDER BY c1;
 c1	c3	c5	c6	c7
-1	Replication Testing Extra Col	Kyle	NULL	CURRENT_TIMESTAMP
-2	This Test Should work	JOE	NULL	CURRENT_TIMESTAMP
-3	If is does not, I will open a bug	QA	NULL	CURRENT_TIMESTAMP
+1	Replication Testing Extra Col	Kyle	1	CURRENT_TIMESTAMP
+2	This Test Should work	JOE	1	CURRENT_TIMESTAMP
+3	If is does not, I will open a bug	QA	1	CURRENT_TIMESTAMP
 *** Drop t14  ***
 DROP TABLE t14;
 *** Create t15 on slave  ***
@@ -768,9 +768,9 @@ c1	c2	c3	c4	c5
 *** Select on Slave ****
 SELECT * FROM t15 ORDER BY c1;
 c1	c2	c3	c4	c5	c6	c7
-1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	NULL	CURRENT_TIMESTAMP
-2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	NULL	CURRENT_TIMESTAMP
-3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	NULL	CURRENT_TIMESTAMP
+1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	1	CURRENT_TIMESTAMP
+2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	1	CURRENT_TIMESTAMP
+3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	1	CURRENT_TIMESTAMP
 *** Add column on master that is a Extra on Slave ***
 ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5;
 ********************************************
@@ -831,9 +831,9 @@ c1	c2	c3	c4	c5	c6
 *** Try to select from slave ****
 SELECT * FROM t15 ORDER BY c1;
 c1	c2	c3	c4	c5	c6	c7
-1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	NULL	CURRENT_TIMESTAMP
-2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	NULL	CURRENT_TIMESTAMP
-3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	NULL	CURRENT_TIMESTAMP
+1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	1	CURRENT_TIMESTAMP
+2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	1	CURRENT_TIMESTAMP
+3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	1	CURRENT_TIMESTAMP
 5	2.00	Replication Testing	b1b1b1b1b1b1b1b1	Buda	2	CURRENT_TIMESTAMP
 *** DROP TABLE t15 ***
 DROP TABLE t15;
@@ -865,9 +865,9 @@ c1	c2	c3	c4	c5
 *** Select on Slave ****
 SELECT * FROM t16 ORDER BY c1;
 c1	c2	c3	c4	c5	c6	c7
-1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	NULL	CURRENT_TIMESTAMP
-2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	NULL	CURRENT_TIMESTAMP
-3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	NULL	CURRENT_TIMESTAMP
+1	1.00	Replication Testing Extra Col	b1b1b1b1b1b1b1b1	Kyle	1	CURRENT_TIMESTAMP
+2	2.00	This Test Should work	b1b1b1b1b1b1b1b1	JOE	1	CURRENT_TIMESTAMP
+3	3.00	If is does not, I will open a bug	b1b1b1b1b1b1b1b1	QA	1	CURRENT_TIMESTAMP
 *** Add Partition on master ***
 ALTER TABLE t16 PARTITION BY KEY(c1) PARTITIONS 4;
 INSERT INTO t16 () VALUES(4,1.00,'Replication Rocks',@b1,'Omer');

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2010-04-26 10:39:15 +0000
+++ b/sql/ha_ndbcluster.cc	2010-04-29 14:52:05 +0000
@@ -45,6 +45,7 @@
 #include "ha_ndbcluster_connection.h"
 
 #include <mysql/plugin.h>
+#include <ndb_version.h>
 
 #ifdef ndb_dynamite
 #undef assert
@@ -1260,6 +1261,7 @@ ha_ndbcluster::set_blob_values(const Ndb
       ERR_RETURN(ndb_op->getNdbError());
     if (field->is_null_in_record_with_offset(row_offset))
     {
+      DBUG_PRINT("info", ("Setting Blob %d to NULL", field_no));
       if (ndb_blob->setNull() != 0)
         ERR_RETURN(ndb_op->getNdbError());
     }
@@ -1447,6 +1449,108 @@ int cmp_frm(const NDBTAB *ndbtab, const 
   DBUG_RETURN(0);
 }
 
+/*
+  Does type support a default value?
+*/
+static bool
+type_supports_default_value(enum_field_types mysql_type)
+{
+  bool ret = (mysql_type != MYSQL_TYPE_BLOB &&
+              mysql_type != MYSQL_TYPE_TINY_BLOB &&
+              mysql_type != MYSQL_TYPE_MEDIUM_BLOB &&
+              mysql_type != MYSQL_TYPE_LONG_BLOB &&
+              mysql_type != MYSQL_TYPE_GEOMETRY);
+
+  return ret;
+}
+
+/**
+   Check that Ndb data dictionary has the same default values
+   as MySQLD for the current table.
+   Called as part of a DBUG check as part of table open
+   
+   Returns
+     0  - Defaults are ok
+     -1 - Some default(s) are bad
+*/
+int ha_ndbcluster::check_default_values(const NDBTAB* ndbtab)
+{
+  /* Debug only method for checking table defaults aligned
+     between MySQLD and Ndb
+  */
+  bool defaults_aligned= true;
+
+  if (ndbtab->hasDefaultValues())
+  {
+    /* Ndb supports native defaults for non-pk columns */
+    my_bitmap_map *old_map= tmp_use_all_columns(table, table->read_set);
+
+    for (uint f=0; f < table_share->fields; f++)
+    {
+      Field* field= table->field[f]; // Use Field struct from MySQLD table rep
+      const NdbDictionary::Column* ndbCol= ndbtab->getColumn(field->field_index); 
+      if ((! (field->flags & (PRI_KEY_FLAG |
+                              NO_DEFAULT_VALUE_FLAG))) &&
+          (type_supports_default_value(field->real_type())))
+      {
+        /* We expect Ndb to have a native default for this
+         * column
+         */
+        my_ptrdiff_t src_offset= table_share->default_values - 
+          field->table->record[0];
+
+        /* Move field by offset to refer to default value */
+        field->move_field_offset(src_offset);
+        
+        const uchar* ndb_default= (const uchar*) ndbCol->getDefaultValue();
+
+        if (ndb_default == NULL)
+          /* MySQLD default must also be NULL */
+          defaults_aligned= field->is_null();
+        else
+        {
+          if (field->type() != MYSQL_TYPE_BIT)
+          {
+            defaults_aligned= (0 == field->cmp(ndb_default));
+          }
+          else
+          {
+            longlong value= (static_cast<Field_bit*>(field))->val_int();
+            defaults_aligned= (0 == memcmp(ndb_default, 
+                                           &value, 
+                                           field->used_length()));
+          }
+        }
+        
+        field->move_field_offset(-src_offset);
+
+        if (unlikely(!defaults_aligned))
+        {
+          DBUG_PRINT("info", ("Default values differ for column %u",
+                              field->field_index));
+          break;
+        }
+      }
+      else
+      {
+        /* We don't expect Ndb to have a native default for this column */
+        if (unlikely(ndbCol->getDefaultValue()))
+        {
+          /* Didn't expect that */
+          DBUG_PRINT("info", ("Column %u has native default, but shouldn't."
+                              " Flags=%u, type=%u",
+                              field->field_index, field->flags, field->real_type()));
+          defaults_aligned= false;
+          break;
+        }
+      }
+    } 
+    tmp_restore_column_map(table->read_set, old_map);
+  }
+
+  return (defaults_aligned? 0: -1);
+}
+
 int ha_ndbcluster::get_metadata(THD *thd, const char *path)
 {
   Ndb *ndb= get_thd_ndb(thd)->ndb;
@@ -1492,6 +1596,11 @@ int ha_ndbcluster::get_metadata(THD *thd
   my_free((char*)data, MYF(0));
   my_free((char*)pack_data, MYF(0));
 
+  /* Now check that any Ndb native defaults are aligned 
+     with MySQLD defaults
+  */
+  DBUG_ASSERT(check_default_values(tab) == 0);
+
   if (error)
     goto err;
 
@@ -2407,7 +2516,20 @@ int ha_ndbcluster::ndb_pk_update_row(THD
   {
     DBUG_RETURN(error);
   }
+
+  /*
+    We are mapping a MySQLD PK changing update to an NdbApi delete 
+    and insert.
+    The original PK changing update may not have written new values
+    to all columns, so the write set may be partial.
+    We set the write set to be all columns so that all values are
+    copied from the old row to the new row.
+  */
+  my_bitmap_map *old_map=
+    tmp_use_all_columns(table, table->write_set);
   error= ndb_write_row(new_data, TRUE, batched_update);
+  tmp_restore_column_map(table->write_set, old_map);
+
   if (error)
   {
     DBUG_PRINT("info", ("insert failed"));
@@ -3489,7 +3611,10 @@ int ha_ndbcluster::ndb_write_row(uchar *
   if (options.optionsPresent != 0)
     poptions=&options;
 
-  const MY_BITMAP *user_cols_written_bitmap;
+  const Uint32 bitmapSz= (NDB_MAX_ATTRIBUTES_IN_TABLE + 31)/32;
+  uint32 tmpBitmapSpace[bitmapSz];
+  MY_BITMAP tmpBitmap;
+  MY_BITMAP *user_cols_written_bitmap;
 #ifdef HAVE_NDB_BINLOG
   uchar* ex_data_buffer= NULL;
 #endif
@@ -3502,8 +3627,6 @@ int ha_ndbcluster::ndb_write_row(uchar *
 #endif
       )
   {
-    uchar *mask;
-    
     /* Should we use the supplied table writeset or not?
      * For a REPLACE command, we should ignore it, and write
      * all columns to get correct REPLACE behaviour.
@@ -3520,6 +3643,7 @@ int ha_ndbcluster::ndb_write_row(uchar *
      */
     useWriteSet |= thd->slave_thread;
 #endif
+    uchar* mask;
 
     if (useWriteSet)
     {
@@ -3607,10 +3731,54 @@ int ha_ndbcluster::ndb_write_row(uchar *
       poptions=&options;
     }
 #endif
-    /* Using insert, we write all user visible columns */
-    user_cols_written_bitmap= NULL;
+    uchar *mask;
+
+    /* Check whether Ndb table definition includes any default values. */
+    if (m_table->hasDefaultValues())
+    {
+      DBUG_PRINT("info", ("Not sending values for native defaulted columns"));
+
+      /*
+        If Ndb is unaware of the table's defaults, we must provide all column values to the insert.  
+        This is done using a NULL column mask.
+        If Ndb is aware of the table's defaults, we only need to provide 
+        the columns explicitly mentioned in the write set, 
+        plus any extra columns required due to bug#41616. 
+        plus the primary key columns required due to bug#42238.
+      */
+      /*
+        The following code for setting user_cols_written_bitmap
+        should be removed after BUG#41616 and Bug#42238 are fixed
+      */
+      /* Copy table write set so that we can add to it */
+      user_cols_written_bitmap= &tmpBitmap;
+      bitmap_init(user_cols_written_bitmap, tmpBitmapSpace,
+                  table->write_set->n_bits, false);
+      bitmap_copy(user_cols_written_bitmap, table->write_set);
+
+      for (uint i= 0; i < table->s->fields; i++)
+      {
+        Field *field= table->field[i];
+        if (field->flags & (NO_DEFAULT_VALUE_FLAG | // bug 41616
+                            PRI_KEY_FLAG))          // bug 42238
+        {
+          bitmap_set_bit(user_cols_written_bitmap, field->field_index);
+        }
+      }
+
+      mask= (uchar *)(user_cols_written_bitmap->bitmap);
+    }
+    else
+    {
+      /* No defaults in kernel, provide all columns ourselves */
+      DBUG_PRINT("info", ("No native defaults, sending all values"));
+      user_cols_written_bitmap= NULL;
+      mask = NULL;
+    }
+      
+    /* Using insert, we write all non default columns */
     op= trans->insertTuple(key_rec, (const char *)key_row, m_ndb_record,
-                           (char *)record, NULL, // No mask
+                           (char *)record, mask, // Default value should be masked
                            poptions, sizeof(NdbOperation::OperationOptions));
   }
   if (!(op))
@@ -4645,6 +4813,58 @@ void ha_ndbcluster::unpack_record(uchar 
   }
 }
 
+
+/**
+  Get the default value of the field from default_values of the table.
+*/
+static void get_default_value(void *def_val, Field *field)
+{
+  DBUG_ASSERT(field != NULL);
+
+  my_ptrdiff_t src_offset= field->table->s->default_values - field->table->record[0];
+
+  {
+    if (bitmap_is_set(field->table->read_set, field->field_index))
+    {
+      if (field->type() == MYSQL_TYPE_BIT)
+      {
+        Field_bit *field_bit= static_cast<Field_bit*>(field);
+        if (!field->is_null_in_record_with_offset(src_offset))
+        {
+          field->move_field_offset(src_offset);
+          longlong value= field_bit->val_int();
+          memcpy(def_val, &value, sizeof(longlong));
+         field->move_field_offset(-src_offset);
+        }
+      }
+      else if (field->flags & BLOB_FLAG)
+      {
+        assert(false);
+      }
+      else
+      {
+        field->move_field_offset(src_offset);
+        /* Normal field (not blob or bit type). */
+        if (!field->is_null())
+        {
+          /* Only copy actually used bytes of varstrings. */
+          uint32 actual_length= field->used_length();
+          uchar *src_ptr= field->ptr;
+          field->set_notnull();
+          memcpy(def_val, src_ptr, actual_length);
+#ifdef HAVE_purify
+          if (actual_length < field->pack_length())
+            bzero(((char*)def_val) + actual_length,
+                  field->pack_length() - actual_length);
+#endif
+        }
+        field->move_field_offset(-src_offset);
+        /* No action needed for a NULL field. */
+      }
+    }
+  }
+}
+
 /*
     DBUG_EXECUTE("value", print_results(););
 */
@@ -6399,6 +6619,7 @@ static int create_ndb_column(THD *thd,
   NDBCOL::StorageType type= NDBCOL::StorageTypeMemory;
   bool dynamic= FALSE;
 
+  char buf[MAX_ATTR_DEFAULT_VALUE_SIZE];
   DBUG_ENTER("create_ndb_column");
   // Set name
   if (col.setName(field->field_name))
@@ -6409,6 +6630,40 @@ static int create_ndb_column(THD *thd,
   CHARSET_INFO *cs= field->charset();
   // Set type and sizes
   const enum enum_field_types mysql_type= field->real_type();
+
+  {
+    /* Clear default value (col obj is reused for whole table def) */
+    col.setDefaultValue(NULL, 0); 
+
+    /* If the data nodes are capable then set native 
+     * default.
+     */
+    bool nativeDefaults =
+      ! (thd &&
+         (! ndb_native_default_support(get_thd_ndb(thd)->
+                                       ndb->getMinDbNodeVersion())));
+
+    if (likely( nativeDefaults ))
+    {
+      if ((!(field->flags & PRI_KEY_FLAG) ) &&
+          type_supports_default_value(mysql_type))
+      {
+        if (!(field->flags & NO_DEFAULT_VALUE_FLAG))
+        {
+          my_ptrdiff_t src_offset= field->table->s->default_values 
+            - field->table->record[0];
+          if ((! field->is_null_in_record_with_offset(src_offset)) ||
+              ((field->flags & NOT_NULL_FLAG)))
+          {
+            /* Set a non-null native default */
+            memset(buf, 0, MAX_ATTR_DEFAULT_VALUE_SIZE);
+            get_default_value(buf, field);
+            col.setDefaultValue(buf, field->used_length());
+          }
+        }
+      }
+    }
+  }
   switch (mysql_type) {
   // Numeric types
   case MYSQL_TYPE_TINY:        
@@ -7020,6 +7275,12 @@ int ha_ndbcluster::create(const char *na
   /*
     Setup columns
   */
+  my_bitmap_map *old_map;
+  {
+    restore_record(form, s->default_values);
+    old_map= tmp_use_all_columns(form, form->read_set);
+  }
+
   for (i= 0; i < form->s->fields; i++) 
   {
     Field *field= form->field[i];
@@ -7045,6 +7306,7 @@ int ha_ndbcluster::create(const char *na
       pk_length += (field->pack_length() + 3) / 4;
   }
 
+  tmp_restore_column_map(form->read_set, old_map);
   if (use_disk)
   { 
     tab.setLogging(TRUE);
@@ -7110,6 +7372,7 @@ int ha_ndbcluster::create(const char *na
     col.setNullable(FALSE);
     col.setPrimaryKey(TRUE);
     col.setAutoIncrement(TRUE);
+    col.setDefaultValue(NULL, 0);
     if (tab.addColumn(col))
     {
       my_errno= errno;

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2010-03-01 20:10:49 +0000
+++ b/sql/ha_ndbcluster.h	2010-04-29 14:52:05 +0000
@@ -619,6 +619,7 @@ private:
   int add_hidden_pk_ndb_record(NdbDictionary::Dictionary *dict);
   int add_index_ndb_record(NdbDictionary::Dictionary *dict,
                            KEY *key_info, uint index_no);
+  int check_default_values(const NdbDictionary::Table* ndbtab);
   int get_metadata(THD *thd, const char* path);
   void release_metadata(THD *thd, Ndb *ndb);
   NDB_INDEX_TYPE get_index_type(uint idx_no) const;

=== modified file 'storage/ndb/include/kernel/ndb_limits.h'
--- a/storage/ndb/include/kernel/ndb_limits.h	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/ndb_limits.h	2010-04-29 14:52:05 +0000
@@ -74,7 +74,7 @@
 #define NDB_MAX_TABLES 20320                /* SchemaFile.hpp */
 #define MAX_TAB_NAME_SIZE 128
 #define MAX_ATTR_NAME_SIZE NAME_LEN       /* From mysql_com.h */
-#define MAX_ATTR_DEFAULT_VALUE_SIZE 128
+#define MAX_ATTR_DEFAULT_VALUE_SIZE ((MAX_TUPLE_SIZE_IN_WORDS + 1) * 4)  //Add 1 word for AttributeHeader
 #define MAX_ATTRIBUTES_IN_TABLE 128
 #define MAX_ATTRIBUTES_IN_INDEX 32
 #define MAX_TUPLE_SIZE_IN_WORDS 2013

=== modified file 'storage/ndb/include/kernel/signaldata/DictTabInfo.hpp'
--- a/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2010-04-29 14:52:05 +0000
@@ -166,8 +166,14 @@ public:
     AttributeExtScale      = 1015, //Default 0
     AttributeExtLength     = 1016, //Default 0
     AttributeAutoIncrement = 1017, //Default false
-    AttributeDefaultValue  = 1018, //Default value (printable string),
     AttributeArrayType     = 1019, //Default NDB_ARRAYTYPE_FIXED
+    AttributeDefaultValueLen = 1020, //Actual Length saved in AttributeDefaultValue
+    /* Default value (Binary type, not printable as string),
+     * For backward compatibility, the new keyValue
+     * (not use the old keyValue 1018) is added
+       when restoring data from low backup version data.
+    */
+    AttributeDefaultValue = 1021,
     AttributeEnd           = 1999  //
   };
   // ----------------------------------------------------------------------
@@ -434,7 +440,8 @@ public:
     Uint32 AttributeAutoIncrement;
     Uint32 AttributeStorageType;
     Uint32 AttributeDynamic;
-    char   AttributeDefaultValue[MAX_ATTR_DEFAULT_VALUE_SIZE];
+    Uint32 AttributeDefaultValueLen;  //byte sizes
+    Uint8  AttributeDefaultValue[MAX_ATTR_DEFAULT_VALUE_SIZE];
     
     Attribute() {}
     void init();
@@ -588,8 +595,11 @@ public:
       fprintf(out, "AttributeExtPrecision = %d\n", AttributeExtPrecision);
       fprintf(out, "AttributeExtScale = %d\n", AttributeExtScale);
       fprintf(out, "AttributeExtLength = %d\n", AttributeExtLength);
-      fprintf(out, "AttributeDefaultValue = \"%s\"\n",
-        AttributeDefaultValue ? AttributeDefaultValue : "");
+      fprintf(out, "AttributeDefaultValueLen = %d\n",
+              AttributeDefaultValueLen);
+      fprintf(out, "AttributeDefaultValue: \n");
+      for (unsigned int i = 0; i < AttributeDefaultValueLen; i++)
+        fprintf(out, "0x%x", AttributeDefaultValue[i]);
     }
   };
   

=== modified file 'storage/ndb/include/kernel/signaldata/LqhFrag.hpp'
--- a/storage/ndb/include/kernel/signaldata/LqhFrag.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/signaldata/LqhFrag.hpp	2010-04-29 14:52:05 +0000
@@ -215,6 +215,7 @@ public:
   STATIC_CONST( HeaderLength = 4 );
   STATIC_CONST( EntryLength = 3 );
   STATIC_CONST( MAX_ATTRIBUTES = 6 );
+  STATIC_CONST( DEFAULT_VALUE_SECTION_NUM = 0 );
   struct Entry {
     Uint32 attrId;              // for index, includes primary attr id << 16
     Uint32 attrDescriptor;      // 2 words type info

=== modified file 'storage/ndb/include/kernel/signaldata/TupFrag.hpp'
--- a/storage/ndb/include/kernel/signaldata/TupFrag.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/signaldata/TupFrag.hpp	2010-04-29 14:52:05 +0000
@@ -123,6 +123,7 @@ class TupAddAttrReq {
   friend class Dbtux;
 public:
   STATIC_CONST( SignalLength = 5 );
+  STATIC_CONST( DEFAULT_VALUE_SECTION_NUM = 0 );
 private:
   Uint32 tupConnectPtr;
   Uint32 notused1;

=== modified file 'storage/ndb/include/ndb_version.h.in'
--- a/storage/ndb/include/ndb_version.h.in	2010-03-02 15:37:59 +0000
+++ b/storage/ndb/include/ndb_version.h.in	2010-04-29 14:52:05 +0000
@@ -386,4 +386,21 @@ ndb_route_exec_frag(Uint32 x)
   return x >= NDBD_ROUTE_EXEC_FRAG;
 }
 
+#define NDBD_NATIVE_DEFAULT_SUPPORT_70 NDB_MAKE_VERSION(7,0,15)
+#define NDBD_NATIVE_DEFAULT_SUPPORT_71 NDB_MAKE_VERSION(7,1,4)
+
+static
+inline
+int
+ndb_native_default_support(Uint32 x)
+{
+  const Uint32 major = (x >> 16) & 0xFF;
+  const Uint32 minor = (x >>  8) & 0xFF;
+
+  if (major == 7 && minor == 0)
+    return x >= NDBD_NATIVE_DEFAULT_SUPPORT_70;
+  
+  return x >= NDBD_NATIVE_DEFAULT_SUPPORT_71;
+}
+
 #endif

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp	2010-03-01 14:13:01 +0000
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp	2010-04-29 14:52:05 +0000
@@ -565,14 +565,32 @@ public:
 
     /** @} *******************************************************************/
 
+#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
+    int setDefaultValue(const char*);
+#endif
+    /* setDefaultValue
+     * Set buf to NULL for no default value, or null default value for
+     * NULLABLE column, otherwise set buf to pointer to default value.
+     * The len parameter is the number of significant bytes of default
+     * value supplied, which is the type size for fixed size types.
+     * For variable length types, the leading 1 or 2 bytes pointed to 
+     * by buf also contain length information as normal for the type.
+     */
+    int setDefaultValue(const void* buf, unsigned int len);
+
+    /* getDefaultValue
+     * Get the default value data for this column.
+     * Optional int len* will be updated with the significant length 
+     * of the default value, or set to 0 for NULL or no default.
+     */
+    const void* getDefaultValue(unsigned int* len = 0) const;
+
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
     const Table * getBlobTable() const;
 
     void setAutoIncrement(bool);
     bool getAutoIncrement() const;
     void setAutoIncrementInitialValue(Uint64 val);
-    int setDefaultValue(const char*);   
-    const char* getDefaultValue() const;
 
     static const Column * FRAGMENT;
     static const Column * FRAGMENT_FIXED_MEMORY;
@@ -1063,6 +1081,12 @@ public:
      */
     Uint32 getPartitionId(Uint32 hashvalue) const ;
 
+    /*
+     * Return TRUE if any of the columns in the table have a 
+     * non NULL default value defined
+     */ 
+    bool hasDefaultValues() const;
+
   private:
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
     friend class Ndb;
@@ -2518,8 +2542,32 @@ public:
       createRecord
     */
     void releaseRecord(NdbRecord *rec);
+  }; // class Dictionary
+
+  class NdbDataPrintFormat
+  {
+  public:
+    NdbDataPrintFormat();
+    virtual ~NdbDataPrintFormat();
+    const char *lines_terminated_by;
+    const char *fields_terminated_by;
+    const char *start_array_enclosure;
+    const char *end_array_enclosure;
+    const char *fields_enclosed_by;
+    const char *fields_optionally_enclosed_by;
+    const char *hex_prefix;
+    const char *null_string;
+    int hex_format;
   };
-};
+
+  static 
+  class NdbOut& printFormattedValue(class NdbOut& out, 
+                                    const NdbDataPrintFormat& format,
+                                    const NdbDictionary::Column* c,
+                                    const void* val);
+  
+
+}; // class NdbDictionary
 
 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Column& col);
 

=== modified file 'storage/ndb/include/ndbapi/NdbRecAttr.hpp'
--- a/storage/ndb/include/ndbapi/NdbRecAttr.hpp	2009-06-13 18:56:08 +0000
+++ b/storage/ndb/include/ndbapi/NdbRecAttr.hpp	2010-04-29 14:52:05 +0000
@@ -463,21 +463,15 @@ NdbRecAttr::setUNDEFINED()
 
 class NdbOut& operator <<(class NdbOut&, const NdbRecAttr &);
 
-class NdbRecordPrintFormat
+class NdbRecordPrintFormat : public NdbDictionary::NdbDataPrintFormat
 {
 public:
-  NdbRecordPrintFormat();
-  virtual ~NdbRecordPrintFormat();
-  const char *lines_terminated_by;
-  const char *fields_terminated_by;
-  const char *start_array_enclosure;
-  const char *end_array_enclosure;
-  const char *fields_enclosed_by;
-  const char *fields_optionally_enclosed_by;
-  const char *hex_prefix;
-  const char *null_string;
-  int hex_format;
+  NdbRecordPrintFormat() : NdbDataPrintFormat() {};
+  virtual ~NdbRecordPrintFormat() {};
 };
+
+/* See also NdbDictionary::printFormattedValue() */
+
 NdbOut&
 ndbrecattr_print_formatted(NdbOut& out, const NdbRecAttr &r,
                            const NdbRecordPrintFormat &f);

=== modified file 'storage/ndb/include/util/UtilBuffer.hpp'
--- a/storage/ndb/include/util/UtilBuffer.hpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/include/util/UtilBuffer.hpp	2010-04-29 14:52:05 +0000
@@ -104,6 +104,14 @@ public:
     else
       return (memcmp(get_data(), cmp.get_data(), len) == 0);
   }
+
+  int assign(const UtilBuffer& buf) {
+    int ret = 0;
+    if(this != &buf) {
+      ret = assign(buf.get_data(), buf.length());
+    }
+    return ret;
+  }
 private:
   void *data;          /* Pointer to data storage */
   size_t len;          /* Size of the stored data */

=== modified file 'storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp'
--- a/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp	2010-04-29 14:52:05 +0000
@@ -100,8 +100,12 @@ DictTabInfo::AttributeMapping[] = {
   DTIMAP(Attribute, AttributeExtScale, AttributeExtScale),
   DTIMAP(Attribute, AttributeExtLength, AttributeExtLength),
   DTIMAP2(Attribute, AttributeAutoIncrement, AttributeAutoIncrement, 0, 1),
-  DTIMAPS(Attribute, AttributeDefaultValue, AttributeDefaultValue,
-    0, MAX_ATTR_DEFAULT_VALUE_SIZE),
+
+  DTIMAP2(Attribute, AttributeDefaultValueLen, AttributeDefaultValueLen,
+          0, MAX_ATTR_DEFAULT_VALUE_SIZE),
+  DTIMAPB(Attribute, AttributeDefaultValue, AttributeDefaultValue,
+    0, MAX_ATTR_DEFAULT_VALUE_SIZE, AttributeDefaultValueLen),
+
   DTIBREAK(AttributeEnd)
 };
 
@@ -198,7 +202,8 @@ DictTabInfo::Attribute::init(){
   AttributeAutoIncrement = false;
   AttributeStorageType = 0;
   AttributeDynamic = 0;                         // Default is not dynamic
-  memset(AttributeDefaultValue, 0, sizeof(AttributeDefaultValue));//AttributeDefaultValue[0] = 0;
+  AttributeDefaultValueLen = 0;                 //Default byte sizes of binary default value is 0
+  memset(AttributeDefaultValue, 0, sizeof(AttributeDefaultValue));
 }
 
 //static 

=== modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt'
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2010-03-11 09:44:08 +0000
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt	2010-04-29 14:52:05 +0000
@@ -2,7 +2,7 @@ Next QMGR 938
 Next NDBCNTR 1002
 Next NDBFS 2000
 Next DBACC 3002
-Next DBTUP 4032
+Next DBTUP 4035
 Next DBLQH 5055
 Next DBDICT 6025
 Next DBDIH 7221
@@ -531,6 +531,9 @@ Failed Create Table:
 4010 12004: Fail create last attribute in 1st fragment
 4011 12005: Fail create 1st attribute in 2nd fragment
 4012 12006: Fail create last attribute in 2nd fragment
+4032 : Fail to receive first default value
+4033 : Fail to receive last default value
+4034 : Fail to store default values in def values fragment
 
 Drop Table/Index:
 -----------------

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2010-04-27 11:50:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2010-04-29 14:52:05 +0000
@@ -832,8 +832,9 @@ Dbdict::packTableIntoPages(SimplePropert
     
     ConstRope def(c_rope_pool, attrPtr.p->defaultValue);
     def.copy(defaultValue);
-    w.add(DictTabInfo::AttributeDefaultValue, defaultValue);
-    
+
+    w.add(DictTabInfo::AttributeDefaultValueLen, def.size());
+    w.add(DictTabInfo::AttributeDefaultValue, defaultValue, def.size());
     w.add(DictTabInfo::AttributeEnd, 1);
   }
   
@@ -5235,7 +5236,8 @@ void Dbdict::handleTabInfo(SimplePropert
     attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement;
     {
       Rope defaultValue(c_rope_pool, attrPtr.p->defaultValue);
-      defaultValue.assign(attrDesc.AttributeDefaultValue);
+      defaultValue.assign((const char*)attrDesc.AttributeDefaultValue,
+                          attrDesc.AttributeDefaultValueLen);
     }
     
     keyCount += attrDesc.AttributeKeyFlag;
@@ -6115,6 +6117,9 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal
 
   LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend();
   Uint32 i = 0;
+  Uint32 startIndex = 25;
+  Uint32 *defVal_dst = &signal->theData[startIndex];
+  Uint32 defVal_length = 0;
   for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){
     jam();
     AttributeRecordPtr attrPtr;
@@ -6125,6 +6130,14 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal
     entry.extTypeInfo = 0;
     // charset number passed to TUP, TUX in upper half
     entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
+
+    ConstRope def(c_rope_pool, attrPtr.p->defaultValue);
+    def.copy((char*)defVal_dst);
+
+    Uint32 defValueLen = def.size();
+    defVal_length += (defValueLen + 3)/4;
+    defVal_dst += (defValueLen + 3)/4;
+
     if (tabPtr.p->isIndex()) {
       Uint32 primaryAttrId;
       if (attrPtr.p->nextList != RNIL) {
@@ -6165,8 +6178,18 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal
   req->senderAttrPtr = attributePtrI;
   req->noOfAttributes = i;
 
-  sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
-	     LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
+  if (defVal_length != 0)
+  {
+    LinearSectionPtr ptr[3];
+    ptr[0].p= &signal->theData[startIndex];
+    ptr[0].sz= defVal_length;
+
+    sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
+       	       LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB, ptr, 1);
+  }
+  else
+    sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
+               LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
 }
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2010-03-25 14:41:35 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2010-04-29 14:52:05 +0000
@@ -454,6 +454,8 @@ public:
     Uint16 attrReceived;
     Uint16 totalAttrReceived;
     Uint16 fragCopyCreation;
+    Uint16 defValNextPos;
+    Uint32 defValSectionI;
   };
   typedef Ptr<AddFragRecord> AddFragRecordPtr;
   

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2010-03-25 14:41:35 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2010-04-29 14:52:05 +0000
@@ -1432,6 +1432,21 @@ void Dblqh::execLQHADDATTREQ(Signal* sig
   addfragptr.p->m_addAttrReq = * req;
 
   const Uint32 tnoOfAttr = req->noOfAttributes;
+  const Uint32 numSections = signal->getNoOfSections();
+  bool isLongReq= ( numSections != 0 );
+  addfragptr.p->defValSectionI = RNIL;
+  addfragptr.p->defValNextPos = 0;
+
+  if (isLongReq)
+  {
+    SectionHandle handle(this, signal);
+    SegmentedSectionPtr defValSection;
+    handle.getSection(defValSection, LqhAddAttrReq::DEFAULT_VALUE_SECTION_NUM);
+    addfragptr.p->defValSectionI = defValSection.i;
+    addfragptr.p->defValNextPos = 0;
+    //Don't free Section here. Section is freed after default values are trasfered to TUP
+    handle.clear();
+  }
 
   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::WAIT_ADD_ATTR);
   ndbrequire((tnoOfAttr != 0) && (tnoOfAttr <= LqhAddAttrReq::MAX_ATTRIBUTES));
@@ -1504,6 +1519,13 @@ void Dblqh::execTUP_ADD_ATTCONF(Signal* 
       return;
     }
 
+    if (addfragptr.p->defValSectionI != RNIL)
+    {
+      releaseSection(addfragptr.p->defValSectionI);
+      addfragptr.p->defValNextPos = 0;
+      addfragptr.p->defValSectionI = RNIL;
+    }
+
     { // Reply
       LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
       conf->senderData = addfragptr.p->m_addAttrReq.senderData;
@@ -1562,6 +1584,13 @@ void Dblqh::execTUP_ADD_ATTRREF(Signal* 
     break;
   }
 
+  if (addfragptr.p->defValSectionI != RNIL)
+  {
+    releaseSection(addfragptr.p->defValSectionI);
+    addfragptr.p->defValNextPos = 0;
+    addfragptr.p->defValSectionI = RNIL;
+  }
+
   const Uint32 Ref = addfragptr.p->m_createTabReq.senderRef;
   const Uint32 senderData = addfragptr.p->m_addAttrReq.senderData;
 
@@ -1608,13 +1637,49 @@ Dblqh::sendAddAttrReq(Signal* signal)
       jam();
       TupAddAttrReq* const tupreq = (TupAddAttrReq*)signal->getDataPtrSend();
       tupreq->tupConnectPtr = addfragptr.p->tupConnectptr;
-      tupreq->notused1 = 0;
       tupreq->attrId = attrId;
       tupreq->attrDescriptor = entry.attrDescriptor;
       tupreq->extTypeInfo = entry.extTypeInfo;
       BlockReference tupRef = calcInstanceBlockRef(DBTUP);
-      sendSignal(tupRef, GSN_TUP_ADD_ATTRREQ,
-                 signal, TupAddAttrReq::SignalLength, JBB);
+
+      Uint32 sectionLen = 0;
+      Uint32 startIndex = TupAddAttrReq::SignalLength;
+      if (addfragptr.p->defValSectionI != RNIL)
+      {
+        SegmentedSectionPtr defValSection;
+        getSection(defValSection, addfragptr.p->defValSectionI);
+
+        SectionReader defValueReader(defValSection, getSectionSegmentPool());
+        Uint32 defSectionWords = defValueReader.getSize();
+
+        ndbrequire(defValueReader.step(addfragptr.p->defValNextPos));
+
+        Uint32 defValueHeader;
+        ndbrequire(defValueReader.peekWord(&defValueHeader));
+
+        AttributeHeader ah(defValueHeader);
+        Uint32 defValueLen = ah.getByteSize();
+        Uint32 defValueWords = ((defValueLen +3)/4) + 1;
+        Uint32 *dst = &signal->theData[startIndex];
+        ndbassert(defSectionWords >= (addfragptr.p->defValNextPos + defValueWords));
+        ndbrequire(defValueReader.getWords(dst, defValueWords));
+        addfragptr.p->defValNextPos += defValueWords;
+        sectionLen = defValueWords;
+      }
+
+      //A long section is attached when a default value is sent.
+      if (sectionLen != 0)
+      {
+        LinearSectionPtr ptr[3];
+        ptr[0].p= &signal->theData[startIndex];
+        ptr[0].sz= sectionLen;
+        sendSignal(tupRef, GSN_TUP_ADD_ATTRREQ,
+                   signal, TupAddAttrReq::SignalLength, JBB, ptr, 1);
+      }
+      else
+        sendSignal(tupRef, GSN_TUP_ADD_ATTRREQ,
+                   signal, TupAddAttrReq::SignalLength, JBB);
+
       return;
     }
     if (DictTabInfo::isOrderedIndex(tabptr.p->tableType) &&
@@ -20505,6 +20570,8 @@ void Dblqh::seizeAddfragrec(Signal* sign
   addfragptr.p->accConnectptr = RNIL;
   addfragptr.p->tupConnectptr = RNIL;
   addfragptr.p->tuxConnectptr = RNIL;
+  addfragptr.p->defValSectionI = RNIL;
+  addfragptr.p->defValNextPos = 0;
   bzero(&addfragptr.p->m_createTabReq, sizeof(addfragptr.p->m_createTabReq));
   bzero(&addfragptr.p->m_lqhFragReq, sizeof(addfragptr.p->m_lqhFragReq));
   bzero(&addfragptr.p->m_addAttrReq, sizeof(addfragptr.p->m_addAttrReq));

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp	2010-03-26 11:52:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp	2010-04-29 14:52:05 +0000
@@ -269,6 +269,12 @@ DblqhProxy::execLQHADDATTREQ(Signal* sig
   ndbrequire(ss_main.m_req.noOfAttributes >= req->noOfAttributes);
   ss_main.m_req.noOfAttributes -= req->noOfAttributes;
 
+  /* Save long section(s) in ss for forwarding to 
+   * workers
+   */
+  SectionHandle handle(this, signal);
+  saveSections(ss, handle);
+  
   sendREQ(signal, ss);
 }
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2010-03-05 15:03:09 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2010-04-29 14:52:05 +0000
@@ -241,6 +241,7 @@ inline const Uint32* ALIGN_WORD(const vo
 #define ZAI_INCONSISTENCY_ERROR 829
 #define ZNO_ILLEGAL_NULL_ATTR 839
 #define ZNOT_NULL_ATTR 840
+#define ZBAD_DEFAULT_VALUE_LEN 850
 #define ZNO_INSTRUCTION_ERROR 871
 #define ZOUTSIDE_OF_PROGRAM_ERROR 876
 #define ZSTORED_PROC_ID_ERROR 877
@@ -1100,6 +1101,7 @@ ArrayPool<TupTriggerData> c_triggerPool;
       } m_dropTable;
       struct {
         Uint32 m_fragOpPtrI;
+        Uint32 defValSectionI;
       } m_createTable;
       struct {
         Uint32 m_gci_hi;
@@ -1107,6 +1109,7 @@ ArrayPool<TupTriggerData> c_triggerPool;
     };
 
     State tableStatus;
+    Local_key m_default_value_location;
   };  
 
   /*
@@ -2507,6 +2510,8 @@ private:
 //------------------------------------------------------------------
 //------------------------------------------------------------------
 
+  int  store_default_record(const TablerecPtr& regTabPtr);
+  bool  receive_defvalue(Signal* signal, const TablerecPtr& regTabPtr);
 //------------------------------------------------------------------
 //------------------------------------------------------------------
   void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen);
@@ -2836,6 +2841,7 @@ private:
   void initializeTablerec();
   void initializeTabDescr();
   void initializeUndoPage();
+  void initializeDefaultValuesFrag();
 
   void initTab(Tablerec* regTabPtr);
 
@@ -2979,6 +2985,7 @@ private:
 #endif
 
   Uint32 calculate_free_list_impl(Uint32) const ;
+  Uint64 calculate_used_var_words(Fragrecord* fragPtr);
   void remove_free_page(Fragrecord*, Var_page*, Uint32);
   void insert_free_page(Fragrecord*, Var_page*, Uint32);
 
@@ -2991,6 +2998,7 @@ private:
   Uint32* alloc_var_rec(Uint32 * err,
                         Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
   void free_var_rec(Fragrecord*, Tablerec*, Local_key*, Ptr<Page>);
+  void free_var_part(Fragrecord*, Tablerec*, Local_key*);
   Uint32* alloc_var_part(Uint32*err,Fragrecord*, Tablerec*, Uint32, Local_key*);
   Uint32 *realloc_var_part(Uint32 * err, Fragrecord*, Tablerec*,
                            PagePtr, Var_part_ref*, Uint32, Uint32);
@@ -3044,6 +3052,15 @@ private:
   Uint32 cnoOfFragrec;
   RSS_OP_COUNTER(cnoOfFreeFragrec);
   RSS_OP_SNAPSHOT(cnoOfFreeFragrec);
+  /*
+   * DefaultValuesFragment is a normal struct Fragrecord.
+   * It is TUP block-variable.
+   * There is only ONE DefaultValuesFragment shared
+   * among all table fragments stored by this TUP block.
+  */
+  FragrecordPtr DefaultValuesFragment;
+  RSS_OP_SNAPSHOT(defaultValueWordsHi);
+  RSS_OP_SNAPSHOT(defaultValueWordsLo);
 
   AlterTabOperation *alterTabOperRec;
   Uint32 cfirstfreeAlterTabOp;
@@ -3125,6 +3142,7 @@ private:
   Uint32* get_ptr(PagePtr*, Var_part_ref);
   Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
   Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
+  Uint32* get_default_ptr(const Tablerec*, Uint32&);
   Uint32 get_len(Ptr<Page>* pagePtr, Var_part_ref ref);
 
   Tuple_header* alloc_copy_tuple(const Tablerec* tabPtrP, Local_key* ptr){
@@ -3393,6 +3411,20 @@ Dbtup::get_ptr(PagePtr* pagePtr, 
 
 inline
 Uint32*
+Dbtup::get_default_ptr(const Tablerec* regTabPtr, Uint32& default_len)
+{
+  Var_part_ref ref;
+  ref.assign(&regTabPtr->m_default_value_location);
+  Ptr<Page> page;
+
+  Uint32* default_data = get_ptr(&page, ref);
+  default_len = get_len(&page, ref);
+
+  return default_data;
+}
+
+inline
+Uint32*
 Dbtup::get_dd_ptr(PagePtr* pagePtr, 
 		  const Local_key* key, const Tablerec* regTabPtr)
 {

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp	2010-03-05 15:03:09 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp	2010-04-29 14:52:05 +0000
@@ -379,6 +379,15 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal
 
   if (signal->theData[0] == DumpStateOrd::SchemaResourceSnapshot)
   {
+    {
+      Uint64 defaultValueWords= 0;
+      if (DefaultValuesFragment.i != RNIL)
+        defaultValueWords= calculate_used_var_words(DefaultValuesFragment.p);
+      Uint32 defaultValueWordsHi= (Uint32) (defaultValueWords >> 32);
+      Uint32 defaultValueWordsLo= (Uint32) (defaultValueWords & 0xFFFFFFFF);
+      RSS_OP_SNAPSHOT_SAVE(defaultValueWordsHi);
+      RSS_OP_SNAPSHOT_SAVE(defaultValueWordsLo);
+    }
     RSS_OP_SNAPSHOT_SAVE(cnoOfFreeFragoprec);
     RSS_OP_SNAPSHOT_SAVE(cnoOfFreeFragrec);
     RSS_OP_SNAPSHOT_SAVE(cnoOfFreeTabDescrRec);
@@ -387,6 +396,15 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal
 
   if (signal->theData[0] == DumpStateOrd::SchemaResourceCheckLeak)
   {
+    {
+      Uint64 defaultValueWords= 0;
+      if (DefaultValuesFragment.i != RNIL)
+        defaultValueWords= calculate_used_var_words(DefaultValuesFragment.p);
+      Uint32 defaultValueWordsHi= (Uint32) (defaultValueWords >> 32);
+      Uint32 defaultValueWordsLo= (Uint32) (defaultValueWords & 0xFFFFFFFF);
+      RSS_OP_SNAPSHOT_CHECK(defaultValueWordsHi);
+      RSS_OP_SNAPSHOT_CHECK(defaultValueWordsLo);
+    }
     RSS_OP_SNAPSHOT_CHECK(cnoOfFreeFragoprec);
     RSS_OP_SNAPSHOT_CHECK(cnoOfFreeFragrec);
     RSS_OP_SNAPSHOT_CHECK(cnoOfFreeTabDescrRec);

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2010-03-21 19:05:55 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2010-04-29 14:52:05 +0000
@@ -1466,7 +1466,27 @@ int Dbtup::handleInsertReq(Signal* signa
     terrorCode = ZAI_INCONSISTENCY_ERROR;
     goto update_error;
   }
-
+  
+  if (!regTabPtr->m_default_value_location.isNull())
+  {
+    jam();
+    Uint32 default_values_len;
+    /* Get default values ptr + len for this table */
+    Uint32* default_values = get_default_ptr(regTabPtr, default_values_len);
+    ndbrequire(default_values_len != 0 && default_values != NULL);
+    /*
+     * Update default values into row first,
+     * next update with data received from the client.
+     */
+    if(unlikely((res = updateAttributes(req_struct, default_values,
+                                        default_values_len)) < 0))
+    {
+      jam();
+      terrorCode = Uint32(-res);
+      goto update_error;
+    }
+  }
+  
   if(unlikely((res = updateAttributes(req_struct, &cinBuffer[0],
                                       req_struct->attrinfo_len)) < 0))
   {

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2010-03-05 15:03:09 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2010-04-29 14:52:05 +0000
@@ -630,6 +630,7 @@ void Dbtup::execNDB_STTOR(Signal* signal
     jam();
     cownNodeId = ownNodeId;
     cownref = calcInstanceBlockRef(DBTUP);
+    initializeDefaultValuesFrag();
     break;
   case ZSTARTPHASE2:
     jam();
@@ -657,6 +658,30 @@ void Dbtup::startphase3Lab(Signal* signa
 {
 }//Dbtup::startphase3Lab()
 
+void Dbtup::initializeDefaultValuesFrag()
+{
+  /* Grab and initialize a fragment record for storing default
+   * values for the table fragments held by this TUP instance
+   */
+  seizeFragrecord(DefaultValuesFragment);
+  DefaultValuesFragment.p->fragStatus = Fragrecord::FS_ONLINE;
+  DefaultValuesFragment.p->m_undo_complete= false;
+  DefaultValuesFragment.p->m_lcp_scan_op = RNIL;
+  DefaultValuesFragment.p->m_lcp_keep_list = RNIL;
+  DefaultValuesFragment.p->noOfPages = 0;
+  DefaultValuesFragment.p->noOfVarPages = 0;
+  DefaultValuesFragment.p->m_max_page_no = 0;
+  DefaultValuesFragment.p->m_free_page_id_list = FREE_PAGE_RNIL;
+  ndbrequire(DefaultValuesFragment.p->m_page_map.isEmpty());
+  DefaultValuesFragment.p->m_restore_lcp_id = RNIL;
+  for (Uint32 i = 0; i<MAX_FREE_LIST+1; i++)
+    ndbrequire(DefaultValuesFragment.p->free_var_page_array[i].isEmpty());
+
+  DefaultValuesFragment.p->m_logfile_group_id = RNIL;
+
+  return;
+}
+
 void Dbtup::initializeFragoperrec() 
 {
   FragoperrecPtr fragoperPtr;
@@ -755,6 +780,7 @@ Dbtup::initTab(Tablerec* const regTabPtr
   regTabPtr->m_dropTable.tabUserPtr = RNIL;
   regTabPtr->m_dropTable.tabUserRef = 0;
   regTabPtr->tableStatus = NOT_DEFINED;
+  regTabPtr->m_default_value_location.setNull();
 
   // Clear trigger data
   if (!regTabPtr->afterInsertTriggers.isEmpty())

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2010-01-13 13:28:03 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2010-04-29 14:52:05 +0000
@@ -38,6 +38,7 @@
 #include "AttributeOffset.hpp"
 #include <my_sys.h>
 #include <signaldata/LqhFrag.hpp>
+#include <signaldata/AttrInfo.hpp>
 
 #include <EventLogger.hpp>
 extern EventLogger * g_eventLogger;
@@ -78,6 +79,7 @@ Dbtup::execCREATE_TAB_REQ(Signal* signal
   fragOperPtr.p->lqhBlockrefFrag = req->senderRef;
 
   regTabPtr.p->m_createTable.m_fragOpPtrI = fragOperPtr.i;
+  regTabPtr.p->m_createTable.defValSectionI = RNIL;
   regTabPtr.p->tableStatus= DEFINING;
   regTabPtr.p->m_bits = 0;
   regTabPtr.p->m_bits |= (req->checksumIndicator ? Tablerec::TR_Checksum : 0);
@@ -297,6 +299,18 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
     goto error;
   }
 
+  if (!receive_defvalue(signal, regTabPtr))
+    goto error;
+
+  if ((ERROR_INSERTED(4032) && (attrId == 0)) ||
+      (ERROR_INSERTED(4033) && lastAttr))
+  {
+    jam();
+    CLEAR_ERROR_INSERT_VALUE;
+    terrorCode = 1;
+    goto error;
+  }
+
   if (! lastAttr)
   {
     jam();
@@ -382,6 +396,12 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
   }
 #endif
 
+  if (store_default_record(regTabPtr) < 0)
+  {
+    jam();
+    goto error;
+  }
+
   ndbrequire(regTabPtr.p->tableStatus == DEFINING);
   regTabPtr.p->tableStatus= DEFINED;
 
@@ -393,6 +413,17 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
   releaseFragoperrec(fragOperPtr);
   return;
 error:
+  {
+    /* Release any unprocessed sections */
+    SectionHandle handle(this, signal);
+    releaseSections(handle);
+  }
+  /* Release segmented section used to receive Attr default value */
+  releaseSection(regTabPtr.p->m_createTable.defValSectionI);
+  regTabPtr.p->m_createTable.defValSectionI = RNIL;
+  free_var_part(DefaultValuesFragment.p, regTabPtr.p, &regTabPtr.p->m_default_value_location);
+  regTabPtr.p->m_default_value_location.setNull();
+
   signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
   signal->theData[1]= terrorCode;
   sendSignal(fragOperPtr.p->lqhBlockrefFrag,
@@ -401,6 +432,156 @@ error:
   return;
 }
 
+bool Dbtup::receive_defvalue(Signal* signal, const TablerecPtr& regTabPtr)
+{
+  jam();
+  Uint32 defValueBytes = 0;
+  Uint32 defValueWords = 0;
+  Uint32 attrId = signal->theData[2];
+  Uint32 attrDescriptor = signal->theData[3];
+
+  Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
+  Uint32 arrayType = AttributeDescriptor::getArrayType(attrDescriptor);
+  Uint32 arraySize = AttributeDescriptor::getArraySize(attrDescriptor);
+
+  const Uint32 numSections = signal->getNoOfSections();
+
+  if (numSections == 0)
+    return true;
+
+  jam();
+  SectionHandle handle(this, signal);
+  SegmentedSectionPtr ptr;
+  handle.getSection(ptr, TupAddAttrReq::DEFAULT_VALUE_SECTION_NUM);
+
+  SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
+  r.reset();
+
+  Uint32 ahIn;
+  ndbrequire(r.getWord(&ahIn));
+
+  defValueBytes = AttributeHeader::getByteSize(ahIn);
+  defValueWords = (defValueBytes + 3) / 4;
+
+  Uint32 *dst = NULL;
+  AttributeHeader ah(attrId, defValueBytes);
+
+  if (defValueBytes == 0)
+  {
+    jam();
+    releaseSections(handle);
+    return true;
+  }
+
+  /* We have a default value, double check to be sure this is not
+   * a primary key
+   */
+  if (AttributeDescriptor::getPrimaryKey(attrDescriptor))
+  {
+    jam();
+    releaseSections(handle);
+    /* Default value for primary key column not supported */
+    terrorCode = 792;
+    return false;
+  }
+
+  Uint32 bytes;
+  if (attrLen)
+    bytes= AttributeDescriptor::getSizeInBytes(attrDescriptor);
+  else
+    bytes= ((arraySize + AD_SIZE_IN_WORDS_OFFSET)
+                              >> AD_SIZE_IN_WORDS_SHIFT) * 4;
+
+  terrorCode= 0;
+
+  if (attrLen)
+  {
+    if (arrayType == NDB_ARRAYTYPE_FIXED)
+    {
+      if (defValueBytes != bytes)
+      {
+        terrorCode = ZBAD_DEFAULT_VALUE_LEN;
+      }
+    }
+    else
+    {
+      if (defValueBytes > bytes)
+      {
+        terrorCode = ZBAD_DEFAULT_VALUE_LEN;
+      }
+    }
+  }
+  else
+  {
+    /*
+     * The condition is for BIT type.
+     * Even though it is fixed, the compare operator should be > rather than ==,
+     * for the 4-byte alignemnt, the space for BIT type occupied 4 bytes at least.
+     * yet the bytes of default value can be 1, 2, 3, 4, 5, 6, 7, 8 bytes.
+     */
+    if (defValueBytes > bytes)
+    {
+      terrorCode = ZBAD_DEFAULT_VALUE_LEN;
+    }
+  }
+  
+  jam();
+
+  if (likely( !terrorCode ))
+  {
+    dst = cinBuffer;
+    
+    ndbrequire(r.getWords(dst, defValueWords));
+    
+    /* Check that VAR types have valid inline length */
+    if ((attrLen) &&
+        (arrayType != NDB_ARRAYTYPE_FIXED))
+    {
+      jam();
+      const uchar* valPtr = (const uchar*) dst;
+      Uint32 internalVarSize = 0;
+      
+      if (arrayType == NDB_ARRAYTYPE_SHORT_VAR)
+      {
+        internalVarSize = 1 + valPtr[0];
+      }
+      else if (arrayType == NDB_ARRAYTYPE_MEDIUM_VAR)
+      {
+        internalVarSize = 2 + valPtr[0] + (256 * Uint32(valPtr[1]));
+      }
+      else
+      {
+        ndbrequire(false);
+      }
+      
+      if (unlikely(internalVarSize != defValueBytes))
+      {
+        jam();
+        terrorCode = ZBAD_DEFAULT_VALUE_LEN;
+        releaseSections(handle);
+        return false;
+      }
+    }
+
+    if (likely( appendToSection(regTabPtr.p->m_createTable.defValSectionI, 
+                                (const Uint32 *)&ah, 1) ))
+    {  
+      if (likely( appendToSection(regTabPtr.p->m_createTable.defValSectionI, 
+                                  (const Uint32*)dst, 
+                                  defValueWords)))
+      {
+        jam();
+        releaseSections(handle);
+        return true;
+      }
+    }
+    terrorCode = ZMEM_NOMEM_ERROR;
+  }
+
+  releaseSections(handle);
+  return false;
+}
+
 void Dbtup::execTUPFRAGREQ(Signal* signal)
 {
   jamEntry();
@@ -553,12 +734,75 @@ void Dbtup::execTUPFRAGREQ(Signal* signa
   return;
 
 sendref:
-
   signal->theData[0]= userptr;
   signal->theData[1]= terrorCode;
   sendSignal(userRef, GSN_TUPFRAGREF, signal, 2, JBB);
 }
 
+/*
+  Store the default values for a table, as the ATTRINFO "program"
+  (i.e AttributeHeader|Data AttributeHeader|Data...)
+  in varsize memory associated with the dummy fragment(DefaultValuesFragment).
+  There is a DBTUP global set of defaults records in DefaultValuesFragment.
+  One record per table stored on varsize pages.
+  
+  Each Table_record has a Local_key pointing to start of its default values
+  in TUP's default values fragment.
+*/
+int Dbtup::store_default_record(const TablerecPtr& regTabPtr)
+{
+  Uint32 RdefValSectionI = regTabPtr.p->m_createTable.defValSectionI;
+  jam();
+
+  if (RdefValSectionI == RNIL) //No default values are stored for the table
+  {
+    jam();
+    if (ERROR_INSERTED(4034))
+    {
+      jam();
+      CLEAR_ERROR_INSERT_VALUE;
+      terrorCode = 1;
+      return -1;
+    }
+
+    return 0;
+  }
+
+  SegmentedSectionPtr defValSection;
+  getSection(defValSection, RdefValSectionI);
+  Uint32 sizes = defValSection.p->m_sz;
+  /**
+   * Alloc var-length memory for storing defaults
+   */
+  Uint32* var_data_ptr= alloc_var_part(&terrorCode,
+                                       DefaultValuesFragment.p,
+                                       regTabPtr.p,
+                                       sizes,
+                                       &regTabPtr.p->m_default_value_location);
+  if (unlikely( var_data_ptr == 0 ))
+  {
+    jam();
+    /* Caller releases the default values section */
+    return -1;
+  }
+
+  if (ERROR_INSERTED(4034))
+  {
+    jam();
+    CLEAR_ERROR_INSERT_VALUE;
+    terrorCode = 1;
+    return -1;
+  }
+      
+  
+  copy(var_data_ptr, RdefValSectionI);
+  releaseSection(RdefValSectionI);
+  regTabPtr.p->m_createTable.defValSectionI= RNIL;
+
+  return 0;
+}
+
+
 bool Dbtup::addfragtotab(Tablerec* const regTabPtr,
                          Uint32 fragId,
                          Uint32 fragIndex)
@@ -1889,6 +2133,8 @@ Dbtup::drop_table_logsync_callback(Signa
              signal, DropTabConf::SignalLength, JBB);
   
   releaseTabDescr(tabPtr.p);
+  free_var_part(DefaultValuesFragment.p, tabPtr.p, &tabPtr.p->m_default_value_location);
+  tabPtr.p->m_default_value_location.setNull();
   initTab(tabPtr.p);
 }
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp	2009-12-14 10:58:03 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp	2010-04-29 14:52:05 +0000
@@ -139,6 +139,39 @@ Dbtup::alloc_var_part(Uint32 * err,
 }
 
 /*
+  free_var_part is used to free the variable length storage associated
+  with the passed local key.
+  It is not assumed that there is a corresponding fixed-length part.
+  // TODO : Any need for tabPtr?
+*/
+void Dbtup::free_var_part(Fragrecord* fragPtr,
+                          Tablerec* tabPtr,
+                          Local_key* key)
+{
+  Ptr<Page> pagePtr;
+  if (key->m_page_no != RNIL)
+  {
+    c_page_pool.getPtr(pagePtr, key->m_page_no);
+    ((Var_page*)pagePtr.p)->free_record(key->m_page_idx, Var_page::CHAIN);
+
+    ndbassert(pagePtr.p->free_space <= Var_page::DATA_WORDS);
+    if (pagePtr.p->free_space == Var_page::DATA_WORDS - 1)
+    {
+      jam();
+      Uint32 idx = pagePtr.p->list_index;
+      LocalDLList<Page> list(c_page_pool, fragPtr->free_var_page_array[idx]);
+      list.remove(pagePtr);
+      returnCommonArea(pagePtr.i, 1);
+      fragPtr->noOfVarPages --;
+    } else {
+      jam();
+      update_free_page_list(fragPtr, pagePtr);
+    }
+  }
+  return;
+}
+
+/*
   Deallocator for variable sized segments
   Part of the external interface for variable sized segments
 
@@ -474,6 +507,30 @@ Uint32 Dbtup::calculate_free_list_impl(U
   return 0;
 }
 
+Uint64 Dbtup::calculate_used_var_words(Fragrecord* fragPtr)
+{
+  /* Loop over all VarSize pages in this fragment, summing
+   * their used space
+   */
+  Uint64 totalUsed= 0;
+  for (Uint32 freeList= 0; freeList <= MAX_FREE_LIST; freeList++)
+  {
+    LocalDLList<Page> list(c_page_pool, 
+                           fragPtr->free_var_page_array[freeList]);
+    Ptr<Page> pagePtr;
+
+    if (list.first(pagePtr))
+    {
+      do
+      {
+        totalUsed+= (Tup_varsize_page::DATA_WORDS - pagePtr.p->free_space);
+      } while (list.next(pagePtr));
+    };
+  };
+
+  return totalUsed;
+}
+
 Uint32* 
 Dbtup::alloc_var_rowid(Uint32 * err,
                        Fragrecord* fragPtr,

=== modified file 'storage/ndb/src/ndbapi/NdbDictionary.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp	2010-03-01 14:13:01 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp	2010-04-29 14:52:05 +0000
@@ -20,6 +20,10 @@
 #include "NdbDictionaryImpl.hpp"
 #include <NdbOut.hpp>
 #include <signaldata/CreateHashMap.hpp>
+#include <NdbBlob.hpp>
+C_MODE_START
+#include <decimal.h>
+C_MODE_END
 
 /* NdbRecord static helper methods */
 
@@ -350,16 +354,37 @@ NdbDictionary::Column::setAutoIncrementI
   m_impl.m_autoIncrementInitialValue = val;
 }
 
+/*
+* setDefaultValue() with only one const char * parameter is reserved
+* for backward compatible api consideration, but is broken.
+*/
 int
 NdbDictionary::Column::setDefaultValue(const char* defaultValue)
 {
-  return !m_impl.m_defaultValue.assign(defaultValue);
+  return -1;
 }
 
-const char*
-NdbDictionary::Column::getDefaultValue() const
+/*
+  The significant length of a column can't easily be calculated before
+  the column type is fully defined, so the length of the default value 
+  is passed in as a parameter explicitly.
+*/
+int
+NdbDictionary::Column::setDefaultValue(const void* defaultValue, unsigned int n)
 {
-  return m_impl.m_defaultValue.c_str();
+  if (defaultValue == NULL)
+    return m_impl.m_defaultValue.assign(NULL, 0);
+
+  return m_impl.m_defaultValue.assign(defaultValue, n);
+}
+
+const void*
+NdbDictionary::Column::getDefaultValue(unsigned int* len) const
+{
+  if (len)
+   *len = m_impl.m_defaultValue.length();
+
+  return m_impl.m_defaultValue.get_data();
 }
 
 int
@@ -899,6 +924,11 @@ NdbDictionary::Table::getForceVarPart() 
   return m_impl.m_force_var_part;
 }
 
+bool
+NdbDictionary::Table::hasDefaultValues() const {
+  return m_impl.m_has_default_values;
+}
+
 const NdbRecord*
 NdbDictionary::Table::getDefaultRecord() const {
   return m_impl.m_ndbrecord;
@@ -1031,6 +1061,9 @@ NdbDictionary::Index::addColumn(const Co
   (* col) = NdbColumnImpl::getImpl(c);
 
   col->m_indexSourced=true;
+  
+  /* Remove defaults from indexed columns */
+  col->m_defaultValue.clear();
 
   if (m_impl.m_columns.push_back(col))
   {
@@ -2614,6 +2647,436 @@ NdbDictionary::Dictionary::getWarningFla
 
 // printers
 
+void
+pretty_print_string(NdbOut& out, 
+                    const NdbDictionary::NdbDataPrintFormat &f,
+                    const char *type, bool is_binary,
+                    const void *aref, unsigned sz)
+{
+  const unsigned char* ref = (const unsigned char*)aref;
+  int i, len, printable= 1;
+  // trailing zeroes are not printed
+  for (i=sz-1; i >= 0; i--)
+    if (ref[i] == 0) sz--;
+    else break;
+  if (!is_binary)
+  {
+    // trailing spaces are not printed
+    for (i=sz-1; i >= 0; i--)
+      if (ref[i] == 32) sz--;
+      else break;
+  }
+  if (is_binary && f.hex_format)
+  {
+    if (sz == 0)
+    {
+      out.print("0x0");
+      return;
+    }
+    out.print("0x");
+    for (len = 0; len < (int)sz; len++)
+      out.print("%02X", (int)ref[len]);
+    return;
+  }
+  if (sz == 0) return; // empty
+
+  for (len=0; len < (int)sz && ref[i] != 0; len++)
+    if (printable && !isprint((int)ref[i]))
+      printable= 0;
+
+  if (printable)
+    out.print("%.*s", len, ref);
+  else
+  {
+    out.print("0x");
+    for (i=0; i < len; i++)
+      out.print("%02X", (int)ref[i]);
+  }
+  if (len != (int)sz)
+  {
+    out.print("[");
+    for (i= len+1; ref[i] != 0; i++)
+    out.print("%u]",len-i);
+    assert((int)sz > i);
+    pretty_print_string(out,f,type,is_binary,ref+i,sz-i);
+  }
+}
+
+/* Three MySQL defs duplicated here : */ 
+static const int MaxMySQLDecimalPrecision= 65;
+static const int MaxMySQLDecimalScale= 30;
+static const int DigitsPerDigit_t= 9; // (Decimal digits in 2^32)
+
+/* Implications */
+/* Space for -, . and \0 */
+static const int MaxDecimalStrLen= MaxMySQLDecimalPrecision + 3;
+static const int IntPartDigit_ts= 
+  ((MaxMySQLDecimalPrecision - 
+    MaxMySQLDecimalScale) +
+   DigitsPerDigit_t -1) / DigitsPerDigit_t;
+static const int FracPartDigit_ts= 
+  (MaxMySQLDecimalScale + 
+   DigitsPerDigit_t - 1) / DigitsPerDigit_t;
+static const int DigitArraySize= IntPartDigit_ts + FracPartDigit_ts;
+
+NdbOut&
+NdbDictionary::printFormattedValue(NdbOut& out, 
+                                   const NdbDataPrintFormat& format,
+                                   const NdbDictionary::Column* c,
+                                   const void* val)
+{
+  if (val == NULL)
+  {
+    out << format.null_string;
+    return out;
+  }
+  
+  const unsigned char* val_p= (const unsigned char*) val;
+
+  uint length = c->getLength();
+  Uint32 j;
+  {
+    const char *fields_optionally_enclosed_by;
+    if (format.fields_enclosed_by[0] == '\0')
+      fields_optionally_enclosed_by=
+        format.fields_optionally_enclosed_by;
+    else
+      fields_optionally_enclosed_by= "";
+    out << format.fields_enclosed_by;
+
+    switch(c->getType()){
+    case NdbDictionary::Column::Bigunsigned:
+    {
+      Uint64 temp;
+      memcpy(&temp, val, 8); 
+      out << temp;
+      break;
+    }
+    case NdbDictionary::Column::Bit:
+    {
+      out << format.hex_prefix << "0x";
+      {
+        const Uint32 *buf = (const Uint32 *)val;
+        unsigned int k = (length+31)/32;
+        const unsigned int sigbits= length & 31;
+        Uint32 wordMask= (1 << sigbits) -1;
+        
+        /* Skip leading all-0 words */
+        while (k > 0)
+        {
+          const Uint32 v= buf[--k] & wordMask;
+          if (v != 0)
+            break;
+          /* Following words have all bits significant */
+          wordMask= ~0;
+        }
+        
+        /* Write first sig word with non-zero bits */
+        out.print("%X", (buf[k] & wordMask));
+        
+        /* Write remaining words (less significant) */
+        while (k > 0)
+          out.print("%.8X", buf[--k]);
+      }
+      break;
+    }
+    case NdbDictionary::Column::Unsigned:
+    {
+      if (length > 1)
+        out << format.start_array_enclosure;
+      out << *(const Uint32*)val;
+      for (j = 1; j < length; j++)
+        out << " " << *((const Uint32*)val) + j;
+      if (length > 1)
+        out << format.end_array_enclosure;
+      break;
+    }
+    case NdbDictionary::Column::Mediumunsigned:
+      out << (const Uint32) uint3korr(val_p);
+      break;
+    case NdbDictionary::Column::Smallunsigned:
+      out << *((const Uint16*) val);
+      break;
+    case NdbDictionary::Column::Tinyunsigned:
+      out << *((const Uint8*) val);
+      break;
+    case NdbDictionary::Column::Bigint:
+    {
+      Int64 temp;
+      memcpy(&temp, val, 8);
+      out << temp;
+      break;
+    }
+    case NdbDictionary::Column::Int:
+      out << *((Int32*)val);
+      break;
+    case NdbDictionary::Column::Mediumint:
+      out << sint3korr(val_p);
+      break;
+    case NdbDictionary::Column::Smallint:
+      out << *((const short*) val);
+      break;
+    case NdbDictionary::Column::Tinyint:
+      out << *((Int8*) val);
+      break;
+    case NdbDictionary::Column::Binary:
+      if (!format.hex_format)
+        out << fields_optionally_enclosed_by;
+      j = c->getLength();
+      pretty_print_string(out,format,"Binary", true, val, j);
+      if (!format.hex_format)
+        out << fields_optionally_enclosed_by;
+      break;
+    case NdbDictionary::Column::Char:
+      out << fields_optionally_enclosed_by;
+      j = c->getLength();
+      pretty_print_string(out,format,"Char", false, val, j);
+      out << fields_optionally_enclosed_by;
+      break;
+    case NdbDictionary::Column::Varchar:
+    {
+      out << fields_optionally_enclosed_by;
+      unsigned len = *val_p;
+      pretty_print_string(out,format,"Varchar", false, val_p+1,len);
+      j = length;
+      out << fields_optionally_enclosed_by;
+    }
+    break;
+    case NdbDictionary::Column::Varbinary:
+    {
+      if (!format.hex_format)
+        out << fields_optionally_enclosed_by;
+      unsigned len = *val_p;
+      pretty_print_string(out,format,"Varbinary", true, val_p+1,len);
+      j = length;
+      if (!format.hex_format)
+        out << fields_optionally_enclosed_by;
+    }
+    break;
+    case NdbDictionary::Column::Float:
+    {
+      float temp;
+      memcpy(&temp, val, sizeof(temp));
+      out << temp;
+      break;
+    }
+    case NdbDictionary::Column::Double:
+    {
+      double temp;
+      memcpy(&temp, val, sizeof(temp));
+      out << temp;
+      break;
+    }
+    case NdbDictionary::Column::Olddecimal:
+    {
+      short len = 1 + c->getPrecision() + (c->getScale() > 0);
+      out.print("%.*s", len, val_p);
+    }
+    break;
+    case NdbDictionary::Column::Olddecimalunsigned:
+    {
+      short len = 0 + c->getPrecision() + (c->getScale() > 0);
+      out.print("%.*s", len, val_p);
+    }
+    break;
+    case NdbDictionary::Column::Decimal:
+    case NdbDictionary::Column::Decimalunsigned:
+    {
+      int precision= c->getPrecision();
+      int scale= c->getScale();
+      
+      assert(precision <= MaxMySQLDecimalPrecision);
+      assert(scale <= MaxMySQLDecimalScale);
+      assert(decimal_size(precision, scale) <= DigitArraySize );
+      decimal_digit_t buff[ DigitArraySize ];
+      decimal_t tmpDec;
+      tmpDec.buf= buff;
+      tmpDec.len= DigitArraySize;
+      decimal_make_zero(&tmpDec);
+      int rc;
+
+      const uchar* data= (const uchar*) val_p;
+      if ((rc= bin2decimal(data, &tmpDec, precision, scale)))
+      {
+        out.print("***Error : Bad bin2decimal conversion %d ***",
+                  rc);
+        break;
+      }
+      
+      /* Get null terminated var-length string representation */
+      char decStr[MaxDecimalStrLen];
+      assert(decimal_string_size(&tmpDec) <= MaxDecimalStrLen);
+      int len= MaxDecimalStrLen;
+      if ((rc= decimal2string(&tmpDec, decStr, 
+                              &len,
+                              0,   // 0 = Var length output length
+                              0,   // 0 = Var length fractional part
+                              0))) // Filler char for fixed length
+      {
+        out.print("***Error : bad decimal2string conversion %d ***",
+                  rc);
+        break;
+      }
+
+      out.print("%s", decStr);
+      
+      break;
+    }
+      // for dates cut-and-paste from field.cc
+    case NdbDictionary::Column::Datetime:
+    {
+      ulonglong tmp;
+      memcpy(&tmp, val, 8);
+
+      long part1,part2,part3;
+      part1=(long) (tmp/LL(1000000));
+      part2=(long) (tmp - (ulonglong) part1*LL(1000000));
+      char buf[40];
+      char* pos=(char*) buf+19;
+      *pos--=0;
+      *pos--= (char) ('0'+(char) (part2%10)); part2/=10; 
+      *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
+      *pos--= ':';
+      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+      *pos--= ':';
+      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+      *pos--= (char) ('0'+(char) part3);
+      *pos--= '/';
+      *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+      *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+      *pos--= '-';
+      *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+      *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
+      *pos--= '-';
+      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+      *pos=(char) ('0'+(char) part3);
+      out << buf;
+    }
+    break;
+    case NdbDictionary::Column::Date:
+    {
+      uint32 tmp=(uint32) uint3korr(val_p);
+      int part;
+      char buf[40];
+      char *pos=(char*) buf+10;
+      *pos--=0;
+      part=(int) (tmp & 31);
+      *pos--= (char) ('0'+part%10);
+      *pos--= (char) ('0'+part/10);
+      *pos--= '-';
+      part=(int) (tmp >> 5 & 15);
+      *pos--= (char) ('0'+part%10);
+      *pos--= (char) ('0'+part/10);
+      *pos--= '-';
+      part=(int) (tmp >> 9);
+      *pos--= (char) ('0'+part%10); part/=10;
+      *pos--= (char) ('0'+part%10); part/=10;
+      *pos--= (char) ('0'+part%10); part/=10;
+      *pos=   (char) ('0'+part);
+      out << buf;
+    }
+    break;
+    case NdbDictionary::Column::Time:
+    {
+      long tmp=(long) sint3korr(val_p);
+      int hour=(uint) (tmp/10000);
+      int minute=(uint) (tmp/100 % 100);
+      int second=(uint) (tmp % 100);
+      char buf[40];
+      sprintf(buf, "%02d:%02d:%02d", hour, minute, second);
+      out << buf;
+    }
+    break;
+    case NdbDictionary::Column::Year:
+    {
+      uint year = 1900 + *((const Uint8*) val);
+      char buf[40];
+      sprintf(buf, "%04d", year);
+      out << buf;
+    }
+    break;
+    case NdbDictionary::Column::Timestamp:
+    {
+      time_t time = *(const Uint32*) val;
+      out << (uint)time;
+    }
+    break;
+    case NdbDictionary::Column::Blob:
+    case NdbDictionary::Column::Text:
+    {
+      NdbBlob::Head head;
+      NdbBlob::unpackBlobHead(head, (const char*) val_p, c->getBlobVersion());
+      out << head.length << ":";
+      const unsigned char* p = val_p + head.headsize;
+      if ((unsigned int) c->getLength() < head.headsize)
+        out << "***error***"; // really cannot happen
+      else {
+        unsigned n = c->getLength() - head.headsize;
+        for (unsigned k = 0; k < n && k < head.length; k++) {
+          if (c->getType() == NdbDictionary::Column::Blob)
+            out.print("%02X", (int)p[k]);
+          else
+            out.print("%c", (int)p[k]);
+        }
+      }
+      j = length;
+    }
+    break;
+    case NdbDictionary::Column::Longvarchar:
+    {
+      out << fields_optionally_enclosed_by;
+      unsigned len = uint2korr(val_p);
+      pretty_print_string(out,format,"Longvarchar", false, 
+                          val_p+2,len);
+      j = length;
+      out << fields_optionally_enclosed_by;
+    }
+    break;
+    case NdbDictionary::Column::Longvarbinary:
+    {
+      if (!format.hex_format)
+        out << fields_optionally_enclosed_by;
+      unsigned len = uint2korr(val_p);
+      pretty_print_string(out,format,"Longvarbinary", true, 
+                          val_p+2,len);
+      j = length;
+      if (!format.hex_format)
+        out << fields_optionally_enclosed_by;
+    }
+    break;
+
+    default: /* no print functions for the rest, just print type */
+      out << "Unable to format type (" 
+          << (int) c->getType()
+          << ")";
+      if (length > 1)
+        out << " " << length << " times";
+      break;
+    }
+    out << format.fields_enclosed_by;
+  }
+  
+  return out;
+}
+
+NdbDictionary::NdbDataPrintFormat::NdbDataPrintFormat()
+{
+  fields_terminated_by= ";";
+  start_array_enclosure= "[";
+  end_array_enclosure= "]";
+  fields_enclosed_by= "";
+  fields_optionally_enclosed_by= "\"";
+  lines_terminated_by= "\n";
+  hex_prefix= "H'";
+  null_string= "[NULL]";
+  hex_format= 0;
+}
+NdbDictionary::NdbDataPrintFormat::~NdbDataPrintFormat() {};
+
+
 NdbOut&
 operator<<(NdbOut& out, const NdbDictionary::Column& col)
 {
@@ -2792,6 +3255,23 @@ operator<<(NdbOut& out, const NdbDiction
   if(col.getDynamic())
     out << " DYNAMIC";
 
+  const void *default_data = col.getDefaultValue();
+
+  if (default_data != NULL)
+  {
+    NdbDictionary::NdbDataPrintFormat f;
+
+    /* Display binary field defaults as hex */
+    f.hex_format = 1;
+
+    out << " DEFAULT ";
+    
+    NdbDictionary::printFormattedValue(out,
+                                       f,
+                                       &col,
+                                       default_data);
+  }
+  
   return out;
 }
 

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2010-03-26 07:13:06 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2010-04-29 14:52:05 +0000
@@ -101,7 +101,7 @@ NdbColumnImpl::operator=(const NdbColumn
   m_nullable = col.m_nullable;
   m_autoIncrement = col.m_autoIncrement;
   m_autoIncrementInitialValue = col.m_autoIncrementInitialValue;
-  m_defaultValue = col.m_defaultValue;
+  m_defaultValue.assign(col.m_defaultValue);
   m_attrSize = col.m_attrSize; 
   m_arraySize = col.m_arraySize;
   m_arrayType = col.m_arrayType;
@@ -307,7 +307,10 @@ NdbColumnImpl::equal(const NdbColumnImpl
   if (m_autoIncrement != col.m_autoIncrement){
     DBUG_RETURN(false);
   }
-  if(strcmp(m_defaultValue.c_str(), col.m_defaultValue.c_str()) != 0){
+  if (m_defaultValue.length() != col.m_defaultValue.length())
+    DBUG_RETURN(false);
+
+  if(memcmp(m_defaultValue.get_data(), col.m_defaultValue.get_data(), m_defaultValue.length()) != 0){
     DBUG_RETURN(false);
   }
 
@@ -585,6 +588,7 @@ NdbTableImpl::init(){
   m_row_gci = true;
   m_row_checksum = true;
   m_force_var_part = false;
+  m_has_default_values = false;
   m_kvalue= 6;
   m_minLoadFactor= 78;
   m_maxLoadFactor= 80;
@@ -858,6 +862,7 @@ NdbTableImpl::assign(const NdbTableImpl&
   m_row_gci = org.m_row_gci;
   m_row_checksum = org.m_row_checksum;
   m_force_var_part = org.m_force_var_part;
+  m_has_default_values = org.m_has_default_values;
   m_kvalue = org.m_kvalue;
   m_minLoadFactor = org.m_minLoadFactor;
   m_maxLoadFactor = org.m_maxLoadFactor;
@@ -2776,13 +2781,19 @@ NdbDictInterface::parseTableInfo(NdbTabl
     col->m_nullable = attrDesc.AttributeNullableFlag;
     col->m_autoIncrement = (attrDesc.AttributeAutoIncrement != 0);
     col->m_autoIncrementInitialValue = ~0;
-    if (!col->m_defaultValue.assign(attrDesc.AttributeDefaultValue))
+    AttributeHeader ah(*(Uint32*)attrDesc.AttributeDefaultValue);
+    Uint32 bytesize = ah.getByteSize();
+
+    if (col->m_defaultValue.assign((const char*)(attrDesc.AttributeDefaultValue + 4), bytesize))
     {
       delete col;
       delete impl;
       DBUG_RETURN(4000);
     }
 
+    if (bytesize > 0)
+      impl->m_has_default_values = true;
+
     col->m_column_no = impl->m_columns.size();
     impl->m_columns.push_back(col);
     it.next();
@@ -2867,6 +2878,12 @@ NdbDictionaryImpl::createTable(NdbTableI
       autoIncrement = true;
       initialValue = c->m_autoIncrementInitialValue;
     }
+
+    if (c->m_pk && (! c->m_defaultValue.empty())) {
+      /* Default value for primary key column not supported */
+      m_error.code = 792;
+      DBUG_RETURN(-1);
+    }
   }
  
   // create table
@@ -3461,9 +3478,31 @@ loop:
     }
 
     tmpAttr.AttributeAutoIncrement = col->m_autoIncrement;
-    BaseString::snprintf(tmpAttr.AttributeDefaultValue, 
-                         sizeof(tmpAttr.AttributeDefaultValue),
-                         "%s", col->m_defaultValue.c_str());
+    {
+      Uint32 ah;
+      Uint32 byteSize = col->m_defaultValue.length();
+
+      if (byteSize)
+      {
+        if (unlikely(! ndb_native_default_support(ndb.getMinDbNodeVersion())))
+        {
+          /* We can't create a table with native defaults with
+           * this kernel version
+           * Schema feature requires data node upgrade
+           */
+          m_error.code = 794;
+          DBUG_RETURN(-1);
+        }
+      }   
+
+      //The AttributeId of a column isn't decided now, so 0 is used.
+      AttributeHeader::init(&ah, 0, byteSize);
+
+      memcpy(tmpAttr.AttributeDefaultValue, &ah, 4);
+      memcpy(tmpAttr.AttributeDefaultValue + 4, col->m_defaultValue.get_data(), byteSize);
+
+      tmpAttr.AttributeDefaultValueLen = (((col->m_defaultValue.length() + 3) / 4) * 4) + 4;
+    }
     s = SimpleProperties::pack(w, 
 			       &tmpAttr,
 			       DictTabInfo::AttributeMapping, 

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2010-03-01 14:13:01 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2010-04-29 14:52:05 +0000
@@ -96,7 +96,7 @@ public:
   bool m_nullable;
   bool m_autoIncrement;
   Uint64 m_autoIncrementInitialValue;
-  BaseString m_defaultValue;
+  UtilBuffer m_defaultValue;
   /*
    * Table holding the blob parts.
    *
@@ -226,6 +226,7 @@ public:
   bool m_row_gci;
   bool m_row_checksum;
   bool m_force_var_part;
+  bool m_has_default_values; 
   int m_kvalue;
   int m_minLoadFactor;
   int m_maxLoadFactor;

=== modified file 'storage/ndb/src/ndbapi/NdbRecAttr.cpp'
--- a/storage/ndb/src/ndbapi/NdbRecAttr.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/ndbapi/NdbRecAttr.cpp	2010-04-29 14:52:05 +0000
@@ -23,9 +23,6 @@
 #include <NdbBlob.hpp>
 #include "NdbDictionaryImpl.hpp"
 #include <NdbTCP.h>
-C_MODE_START
-#include <decimal.h>
-C_MODE_END
 
 NdbRecAttr::NdbRecAttr(Ndb*)
 {
@@ -177,390 +174,16 @@ NdbRecAttr::receive_data(const Uint32 * 
   return false;
 }
 
-NdbRecordPrintFormat::NdbRecordPrintFormat()
-{
-  fields_terminated_by= ";";
-  start_array_enclosure= "[";
-  end_array_enclosure= "]";
-  fields_enclosed_by= "";
-  fields_optionally_enclosed_by= "\"";
-  lines_terminated_by= "\n";
-  hex_prefix= "H'";
-  null_string= "[NULL]";
-  hex_format= 0;
-}
-NdbRecordPrintFormat::~NdbRecordPrintFormat() {}
 static const NdbRecordPrintFormat default_print_format;
 
-static void
-ndbrecattr_print_string(NdbOut& out, const NdbRecordPrintFormat &f,
-                        const char *type, bool is_binary,
-			const char *aref, unsigned sz)
-{
-  const unsigned char* ref = (const unsigned char*)aref;
-  int i, len, printable= 1;
-  // trailing zeroes are not printed
-  for (i=sz-1; i >= 0; i--)
-    if (ref[i] == 0) sz--;
-    else break;
-  if (!is_binary)
-  {
-    // trailing spaces are not printed
-    for (i=sz-1; i >= 0; i--)
-      if (ref[i] == 32) sz--;
-      else break;
-  }
-  if (is_binary && f.hex_format)
-  {
-    if (sz == 0)
-    {
-      out.print("0x0");
-      return;
-    }
-    out.print("0x");
-    for (len = 0; len < (int)sz; len++)
-      out.print("%02X", (int)ref[len]);
-    return;
-  }
-  if (sz == 0) return; // empty
-
-  for (len=0; len < (int)sz && ref[i] != 0; len++)
-    if (printable && !isprint((int)ref[i]))
-      printable= 0;
-
-  if (printable)
-    out.print("%.*s", len, ref);
-  else
-  {
-    out.print("0x");
-    for (i=0; i < len; i++)
-      out.print("%02X", (int)ref[i]);
-  }
-  if (len != (int)sz)
-  {
-    out.print("[");
-    for (i= len+1; ref[i] != 0; i++)
-    out.print("%u]",len-i);
-    assert((int)sz > i);
-    ndbrecattr_print_string(out,f,type,is_binary,aref+i,sz-i);
-  }
-}
-
-/* Three MySQL defs duplicated here : */ 
-static const int MaxMySQLDecimalPrecision= 65;
-static const int MaxMySQLDecimalScale= 30;
-static const int DigitsPerDigit_t= 9; // (Decimal digits in 2^32)
-
-/* Implications */
-/* Space for -, . and \0 */
-static const int MaxDecimalStrLen= MaxMySQLDecimalPrecision + 3;
-static const int IntPartDigit_ts= 
-  ((MaxMySQLDecimalPrecision - 
-    MaxMySQLDecimalScale) +
-   DigitsPerDigit_t -1) / DigitsPerDigit_t;
-static const int FracPartDigit_ts= 
-  (MaxMySQLDecimalScale + 
-   DigitsPerDigit_t - 1) / DigitsPerDigit_t;
-static const int DigitArraySize= IntPartDigit_ts + FracPartDigit_ts;
-
 NdbOut&
 ndbrecattr_print_formatted(NdbOut& out, const NdbRecAttr &r,
                            const NdbRecordPrintFormat &f)
 {
-  if (r.isNULL())
-  {
-    out << f.null_string;
-    return out;
-  }
-  
-  const NdbDictionary::Column* c = r.getColumn();
-  uint length = c->getLength();
-  {
-    const char *fields_optionally_enclosed_by;
-    if (f.fields_enclosed_by[0] == '\0')
-      fields_optionally_enclosed_by=
-        f.fields_optionally_enclosed_by;
-    else
-      fields_optionally_enclosed_by= "";
-    out << f.fields_enclosed_by;
-    Uint32 j;
-    switch(r.getType()){
-    case NdbDictionary::Column::Bigunsigned:
-      out << r.u_64_value();
-      break;
-    case NdbDictionary::Column::Bit:
-      out << f.hex_prefix << "0x";
-      {
-        const Uint32 *buf = (Uint32 *)r.aRef();
-        int k = (length+31)/32;
-        while (k > 0 && (buf[--k] == 0));
-        out.print("%X", buf[k]);
-        while (k > 0)
-          out.print("%.8X", buf[--k]);
-      }
-      break;
-    case NdbDictionary::Column::Unsigned:
-      if (length > 1)
-        out << f.start_array_enclosure;
-      out << *(Uint32*)r.aRef();
-      for (j = 1; j < length; j++)
-        out << " " << *((Uint32*)r.aRef() + j);
-      if (length > 1)
-        out << f.end_array_enclosure;
-      break;
-    case NdbDictionary::Column::Mediumunsigned:
-      out << r.u_medium_value();
-      break;
-    case NdbDictionary::Column::Smallunsigned:
-      out << r.u_short_value();
-      break;
-    case NdbDictionary::Column::Tinyunsigned:
-      out << (unsigned) r.u_8_value();
-      break;
-    case NdbDictionary::Column::Bigint:
-      out << r.int64_value();
-      break;
-    case NdbDictionary::Column::Int:
-      out << r.int32_value();
-      break;
-    case NdbDictionary::Column::Mediumint:
-      out << r.medium_value();
-      break;
-    case NdbDictionary::Column::Smallint:
-      out << r.short_value();
-      break;
-    case NdbDictionary::Column::Tinyint:
-      out << (int) r.int8_value();
-      break;
-    case NdbDictionary::Column::Binary:
-      if (!f.hex_format)
-        out << fields_optionally_enclosed_by;
-      j = r.get_size_in_bytes();
-      ndbrecattr_print_string(out,f,"Binary", true, r.aRef(), j);
-      if (!f.hex_format)
-        out << fields_optionally_enclosed_by;
-      break;
-    case NdbDictionary::Column::Char:
-      out << fields_optionally_enclosed_by;
-      j = r.get_size_in_bytes();
-      ndbrecattr_print_string(out,f,"Char", false, r.aRef(), j);
-      out << fields_optionally_enclosed_by;
-      break;
-    case NdbDictionary::Column::Varchar:
-    {
-      out << fields_optionally_enclosed_by;
-      unsigned len = *(const unsigned char*)r.aRef();
-      ndbrecattr_print_string(out,f,"Varchar", false, r.aRef()+1,len);
-      j = length;
-      out << fields_optionally_enclosed_by;
-    }
-    break;
-    case NdbDictionary::Column::Varbinary:
-    {
-      if (!f.hex_format)
-        out << fields_optionally_enclosed_by;
-      unsigned len = *(const unsigned char*)r.aRef();
-      ndbrecattr_print_string(out,f,"Varbinary", true, r.aRef()+1,len);
-      j = length;
-      if (!f.hex_format)
-        out << fields_optionally_enclosed_by;
-    }
-    break;
-    case NdbDictionary::Column::Float:
-      out << r.float_value();
-      break;
-    case NdbDictionary::Column::Double:
-      out << r.double_value();
-      break;
-    case NdbDictionary::Column::Olddecimal:
-    {
-      short len = 1 + c->getPrecision() + (c->getScale() > 0);
-      out.print("%.*s", len, r.aRef());
-    }
-    break;
-    case NdbDictionary::Column::Olddecimalunsigned:
-    {
-      short len = 0 + c->getPrecision() + (c->getScale() > 0);
-      out.print("%.*s", len, r.aRef());
-    }
-    break;
-    case NdbDictionary::Column::Decimal:
-    case NdbDictionary::Column::Decimalunsigned:
-    { 
-      int precision= c->getPrecision();
-      int scale= c->getScale();
-      
-      assert(precision <= MaxMySQLDecimalPrecision);
-      assert(scale <= MaxMySQLDecimalScale);
-      assert(decimal_size(precision, scale) <= DigitArraySize );
-      decimal_digit_t buff[ DigitArraySize ];
-      decimal_t tmpDec;
-      tmpDec.buf= buff;
-      tmpDec.len= DigitArraySize;
-      decimal_make_zero(&tmpDec);
-      int rc;
-
-      const uchar* data= (const uchar*) r.aRef();
-      if ((rc= bin2decimal(data, &tmpDec, precision, scale)))
-      {
-        out.print("***Error : Bad bin2decimal conversion %d ***",
-                  rc);
-        break;
-      }
-      
-      /* Get null terminated var-length string representation */
-      char decStr[MaxDecimalStrLen];
-      assert(decimal_string_size(&tmpDec) <= MaxDecimalStrLen);
-      int len= MaxDecimalStrLen;
-      if ((rc= decimal2string(&tmpDec, decStr, 
-                              &len,
-                              0,   // 0 = Var length output length
-                              0,   // 0 = Var length fractional part
-                              0))) // Filler char for fixed length
-      {
-        out.print("***Error : bad decimal2string conversion %d ***",
-                  rc);
-        break;
-      }
-
-      out.print("%s", decStr);
-      
-      break;
-    }
-      // for dates cut-and-paste from field.cc
-    case NdbDictionary::Column::Datetime:
-    {
-      ulonglong tmp=r.u_64_value();
-      long part1,part2,part3;
-      part1=(long) (tmp/LL(1000000));
-      part2=(long) (tmp - (ulonglong) part1*LL(1000000));
-      char buf[40];
-      char* pos=(char*) buf+19;
-      *pos--=0;
-      *pos--= (char) ('0'+(char) (part2%10)); part2/=10; 
-      *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
-      *pos--= ':';
-      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
-      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
-      *pos--= ':';
-      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
-      *pos--= (char) ('0'+(char) part3);
-      *pos--= '/';
-      *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
-      *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
-      *pos--= '-';
-      *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
-      *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
-      *pos--= '-';
-      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
-      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
-      *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
-      *pos=(char) ('0'+(char) part3);
-      out << buf;
-    }
-    break;
-    case NdbDictionary::Column::Date:
-    {
-      uint32 tmp=(uint32) uint3korr(r.aRef());
-      int part;
-      char buf[40];
-      char *pos=(char*) buf+10;
-      *pos--=0;
-      part=(int) (tmp & 31);
-      *pos--= (char) ('0'+part%10);
-      *pos--= (char) ('0'+part/10);
-      *pos--= '-';
-      part=(int) (tmp >> 5 & 15);
-      *pos--= (char) ('0'+part%10);
-      *pos--= (char) ('0'+part/10);
-      *pos--= '-';
-      part=(int) (tmp >> 9);
-      *pos--= (char) ('0'+part%10); part/=10;
-      *pos--= (char) ('0'+part%10); part/=10;
-      *pos--= (char) ('0'+part%10); part/=10;
-      *pos=   (char) ('0'+part);
-      out << buf;
-    }
-    break;
-    case NdbDictionary::Column::Time:
-    {
-      long tmp=(long) sint3korr(r.aRef());
-      int hour=(uint) (tmp/10000);
-      int minute=(uint) (tmp/100 % 100);
-      int second=(uint) (tmp % 100);
-      char buf[40];
-      sprintf(buf, "%02d:%02d:%02d", hour, minute, second);
-      out << buf;
-    }
-    break;
-    case NdbDictionary::Column::Year:
-    {
-      uint year = 1900 + r.u_8_value();
-      char buf[40];
-      sprintf(buf, "%04d", year);
-      out << buf;
-    }
-    break;
-    case NdbDictionary::Column::Timestamp:
-    {
-      time_t time = r.u_32_value();
-      out << (uint)time;
-    }
-    break;
-    case NdbDictionary::Column::Blob:
-    case NdbDictionary::Column::Text:
-    {
-      NdbBlob::Head head;
-      NdbBlob::unpackBlobHead(head, r.aRef(), c->getBlobVersion());
-      out << head.length << ":";
-      const unsigned char* p = (const unsigned char*)r.aRef() + head.headsize;
-      if (r.get_size_in_bytes() < head.headsize)
-        out << "***error***"; // really cannot happen
-      else {
-        unsigned n = r.get_size_in_bytes() - head.headsize;
-        for (unsigned k = 0; k < n && k < head.length; k++) {
-          if (r.getType() == NdbDictionary::Column::Blob)
-            out.print("%02X", (int)p[k]);
-          else
-            out.print("%c", (int)p[k]);
-        }
-      }
-      j = length;
-    }
-    break;
-    case NdbDictionary::Column::Longvarchar:
-    {
-      out << fields_optionally_enclosed_by;
-      unsigned len = uint2korr(r.aRef());
-      ndbrecattr_print_string(out,f,"Longvarchar", false, r.aRef()+2,len);
-      j = length;
-      out << fields_optionally_enclosed_by;
-    }
-    break;
-    case NdbDictionary::Column::Longvarbinary:
-    {
-      if (!f.hex_format)
-        out << fields_optionally_enclosed_by;
-      unsigned len = uint2korr(r.aRef());
-      ndbrecattr_print_string(out,f,"Longvarbinary", true, r.aRef()+2,len);
-      j = length;
-      if (!f.hex_format)
-        out << fields_optionally_enclosed_by;
-    }
-    break;
-
-    default: /* no print functions for the rest, just print type */
-      out << "Unable to format type (" 
-          << (int) r.getType()
-          << ")";
-      if (length > 1)
-        out << " " << length << " times";
-      break;
-    }
-    out << f.fields_enclosed_by;
-  }
-
-  return out;
+  return NdbDictionary::printFormattedValue(out,
+                                            f,
+                                            r.getColumn(),
+                                            r.aRef());
 }
 
 NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)

=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c	2010-04-01 05:20:25 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c	2010-04-29 14:52:05 +0000
@@ -317,6 +317,7 @@ ErrorBundle ErrorCodes[] = {
   { 823,  DMEC, AE, "Too much attrinfo from application in tuple manager" },
   { 829,  DMEC, AE, "Corrupt data received for insert/update" },
   { 831,  DMEC, AE, "Too many nullable/bitfields in table definition" },
+  { 850,  DMEC, AE, "Too long or too short default value"},
   { 876,  DMEC, AE, "876" },
   { 877,  DMEC, AE, "877" },
   { 878,  DMEC, AE, "878" },
@@ -472,6 +473,8 @@ ErrorBundle ErrorCodes[] = {
   { 777,  DMEC, AE, "Cannot create a temporary index on a non-temporary table" },
   { 778,  DMEC, AE, "A temporary table or index must be specified as not logging" },
   { 786,  DMEC, NR, "Schema transaction aborted due to node-failure" },
+  { 792,  DMEC, SE, "Default value for primary key column not supported" },
+  { 794,  DMEC, AE, "Schema feature requires data node upgrade" },
   
   /**
    * FunctionNotImplemented

=== modified file 'storage/ndb/test/include/NDBT_Table.hpp'
--- a/storage/ndb/test/include/NDBT_Table.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/test/include/NDBT_Table.hpp	2010-04-29 14:52:05 +0000
@@ -33,7 +33,9 @@ public:
 		 bool _nullable = false,
 		 CHARSET_INFO *cs= 0,
 		 NdbDictionary::Column::StorageType storage = NdbDictionary::Column::StorageTypeMemory,
-                 bool dynamic = false):
+                 bool dynamic = false,
+                 const void* defaultVal = NULL,
+                 Uint32 defaultValBytes = 0):
     NdbDictionary::Column(_name)
   {
     assert(_name != 0);
@@ -48,6 +50,7 @@ public:
     }
     setStorageType(storage);
     setDynamic(dynamic);
+    setDefaultValue(defaultVal, defaultValBytes);
   }
 };
 

=== modified file 'storage/ndb/test/ndbapi/CMakeLists.txt'
--- a/storage/ndb/test/ndbapi/CMakeLists.txt	2010-04-16 12:25:53 +0000
+++ b/storage/ndb/test/ndbapi/CMakeLists.txt	2010-04-29 14:52:05 +0000
@@ -66,6 +66,7 @@ ADD_EXECUTABLE(DbAsyncGenerator bench/ma
 ADD_EXECUTABLE(testSRBank testSRBank.cpp)
 ADD_EXECUTABLE(test_event_merge test_event_merge.cpp)
 Add_EXECUTABLE(testNdbinfo testNdbinfo.cpp)
+ADD_EXECUTABLE(testNativeDefault testNativeDefault.cpp)
 ##testDict_INCLUDES = $(INCLUDES) -I$(top_srcdir)/ndb/include/kernel
 ##testIndex_INCLUDES = $(INCLUDES) -I$(top_srcdir)/ndb/include/kernel
 ##testSystemRestart_INCLUDES = $(INCLUDES) -I$(top_srcdir)/ndb/include/kernel

=== modified file 'storage/ndb/test/ndbapi/Makefile.am'
--- a/storage/ndb/test/ndbapi/Makefile.am	2009-11-08 12:52:27 +0000
+++ b/storage/ndb/test/ndbapi/Makefile.am	2010-04-29 14:52:05 +0000
@@ -37,6 +37,7 @@ testLimits \
 testMgm \
 testMgmd \
 testSingleUserMode \
+testNativeDefault \
 testNdbApi \
 testNodeRestart \
 testUpgrade \
@@ -104,6 +105,7 @@ testMgmd_SOURCES = testMgmd.cpp \
 testMgmd_LDFLAGS = -static
 testMgmd_CXXFLAGS = -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/storage/ndb/include/debugger  
 testSingleUserMode_SOURCES = testSingleUserMode.cpp
+testNativeDefault_SOURCES = testNativeDefault.cpp
 testNdbApi_SOURCES = testNdbApi.cpp
 testNodeRestart_SOURCES = testNodeRestart.cpp
 testUpgrade_SOURCES = testUpgrade.cpp

=== modified file 'storage/ndb/test/ndbapi/testBasic.cpp'
--- a/storage/ndb/test/ndbapi/testBasic.cpp	2010-01-28 15:16:46 +0000
+++ b/storage/ndb/test/ndbapi/testBasic.cpp	2010-04-29 14:52:05 +0000
@@ -1497,19 +1497,19 @@ runBug20535(NDBT_Context* ctx, NDBT_Step
 {
   Ndb* pNdb = GETNDB(step);
   const NdbDictionary::Table * tab = ctx->getTab();
-  NdbDictionary::Dictionary * dict = pNdb->getDictionary();
 
-  bool null = false;
+  bool hasDefault = false;
   for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
   {
-    if (tab->getColumn(i)->getNullable())
+    if (tab->getColumn(i)->getNullable() ||
+        tab->getColumn(i)->getDefaultValue())
     {
-      null = true;
+      hasDefault = true;
       break;
     }
   }
   
-  if (!null)
+  if (!hasDefault)
     return NDBT_OK;
 
   HugoTransactions hugoTrans(* tab);
@@ -1528,7 +1528,8 @@ runBug20535(NDBT_Context* ctx, NDBT_Step
   for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
   {
     if (!tab->getColumn(i)->getPrimaryKey() &&
-        !tab->getColumn(i)->getNullable())
+        !tab->getColumn(i)->getNullable() &&
+        !tab->getColumn(i)->getDefaultValue())
     {
       hugoTrans.setValueForAttr(pOp, i, 0, 1);
     }
@@ -1547,7 +1548,8 @@ runBug20535(NDBT_Context* ctx, NDBT_Step
   for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
   {
     if (!tab->getColumn(i)->getPrimaryKey() &&
-        tab->getColumn(i)->getNullable())
+        (tab->getColumn(i)->getNullable() ||
+         tab->getColumn(i)->getDefaultValue()))
     {
       values.push_back(pOp->getValue(i));
     }
@@ -1556,19 +1558,48 @@ runBug20535(NDBT_Context* ctx, NDBT_Step
   if (pTrans->execute(Commit) != 0)
     return NDBT_FAILED;
 
-  null = true;
+  bool defaultOk = true;
   for (unsigned int i = 0; i<values.size(); i++)
   {
-    if (!values[i]->isNULL())
+    const NdbRecAttr* recAttr = values[i];
+    const NdbDictionary::Column* col = recAttr->getColumn();
+    unsigned int defaultLen = 0;
+    const char* def = (const char*) col->getDefaultValue(&defaultLen);
+      
+    if (def)
+    {
+      /* Column has a native default, check that it was set */
+
+      if (!recAttr->isNULL())
+      {
+        if (memcmp(def, recAttr->aRef(), defaultLen) != 0)
+        {
+          defaultOk = false;
+          ndbout_c("column %s does not have correct default value",
+                   recAttr->getColumn()->getName());
+        }
+      }
+      else
+      {
+        defaultOk = false;
+        ndbout_c("column %s is null, should have default value",
+                 recAttr->getColumn()->getName());
+      }
+    }
+    else
     {
-      null = false;
-      ndbout_c("column %s is not NULL", values[i]->getColumn()->getName());
+      /* Column has Null as its default */      
+      if (!recAttr->isNULL())
+      {
+        defaultOk = false;
+        ndbout_c("column %s is not NULL", recAttr->getColumn()->getName());
+      }
     }
   }
   
   pTrans->close();  
   
-  if (null)
+  if (defaultOk)
     return NDBT_OK;
   else
     return NDBT_FAILED;

=== modified file 'storage/ndb/test/ndbapi/testBitfield.cpp'
--- a/storage/ndb/test/ndbapi/testBitfield.cpp	2009-09-25 14:08:15 +0000
+++ b/storage/ndb/test/ndbapi/testBitfield.cpp	2010-04-29 14:52:05 +0000
@@ -69,7 +69,7 @@ main(int argc, char** argv){
   Ndb* pNdb;
   pNdb = new Ndb(&con, _dbname);  
   pNdb->init();
-  while (pNdb->waitUntilReady() != 0);
+  while (pNdb->waitUntilReady() != 0) {};
 
   NdbDictionary::Dictionary * dict = pNdb->getDictionary();
 
@@ -130,7 +130,9 @@ create_random_table(Ndb* pNdb)
   do {
     NdbDictionary::Table tab;
     Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1));
-    Uint32 length = 4090;
+    const Uint32 maxLength = 4090;
+    Uint32 length = maxLength;
+    Uint8  defbuf[(maxLength + 7)/8];
     
     BaseString name; 
     name.assfmt("TAB_%d", rand() & 65535);
@@ -153,6 +155,10 @@ create_random_table(Ndb* pNdb)
       col.setType(NdbDictionary::Column::Bit);
       
       Uint32 len = 1 + (rand() % (length - 1));
+      memset(defbuf, 0, (length + 7)/8);
+      for (Uint32 j = 0; j < len/8; j++)
+        defbuf[j] = 0x63;
+      col.setDefaultValue(defbuf, (len + 7)/8);
       col.setLength(len); length -= len;
       int nullable = (rand() >> 16) & 1;
       col.setNullable(nullable); length -= nullable;

=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp	2010-01-18 11:12:17 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp	2010-04-29 14:52:05 +0000
@@ -25,6 +25,7 @@
 #include <signaldata/DumpStateOrd.hpp>
 #include <../../include/kernel/ndb_limits.h>
 #include <../../include/kernel/trigger_definitions.h>
+#include <signaldata/DictTabInfo.hpp>
 #include <random.h>
 #include <NdbAutoPtr.hpp>
 #include <NdbMixRestarter.hpp>
@@ -1854,13 +1855,38 @@ runCreateDiskTable(NDBT_Context* ctx, ND
   return NDBT_OK;
 }
 
+int getColumnMaxLength(const NdbDictionary::Column* c)
+{
+  int length= c->getLength();
+  if (c->getArrayType() == NDB_ARRAYTYPE_FIXED)
+  {
+    /* Not yet set - need to calculate from type etc. */
+    DictTabInfo::Attribute attrDesc;
+
+    attrDesc.init();
+    attrDesc.AttributeExtType= c->getType();
+    attrDesc.AttributeExtLength= c->getLength();
+    attrDesc.AttributeExtPrecision= c->getPrecision();
+    attrDesc.AttributeExtScale= c->getScale();
+
+    if (!attrDesc.translateExtType())
+    {
+      return 0;
+    }
+
+    length= ((1 << attrDesc.AttributeSize) * c->getLength()) >> 3;
+  }
+
+  return length;
+}
+
 #include <NDBT_Tables.hpp>
 
 #define SAFTY 300
 
 int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
   static int acclst[] = { 3001, 6200, 6202 };
-  static int tuplst[] = { 4007, 4008, 4009, 4010 };
+  static int tuplst[] = { 4007, 4008, 4009, 4010, 4032, 4033, 4034 };
   static int tuxlst[] = { 12001, 12002, 12003, 12004, 
                           6201, 6203 };
   static unsigned acccnt = sizeof(acclst)/sizeof(acclst[0]);
@@ -1881,7 +1907,44 @@ int runFailAddFragment(NDBT_Context* ctx
     errNo = atoi(buf);
     ndbout_c("Using errno: %u", errNo);
   }
-  
+
+  const NdbDictionary::Table* origTab= ctx->getTab();
+  HugoCalculator calc(*origTab);
+
+  // Add defaults to some columns
+  for (int colNum= 0; colNum < tab.getNoOfColumns(); colNum++)
+  {
+    const NdbDictionary::Column* origCol= origTab->getColumn(colNum);
+    NdbDictionary::Column* col= tab.getColumn(colNum);
+    if (!origCol->getPrimaryKey())
+    {
+      if (myRandom48(2) == 0)
+      {
+        char defaultBuf[ NDB_MAX_TUPLE_SIZE ];
+        Uint32 real_len;
+        Uint32 updatesVal = myRandom48(1 << 16);
+        const char* def= calc.calcValue(0, colNum, updatesVal, 
+                                        defaultBuf,
+                                        getColumnMaxLength(origCol),
+                                        &real_len);
+        if (col->setDefaultValue(def, real_len) != 0)
+        {
+          ndbout_c("Error setting default value\n");
+          return NDBT_FAILED;
+        }
+        NdbDictionary::NdbDataPrintFormat dpf;
+        ndbout << "Set default for column " << origCol->getName()
+               << " to ";
+        
+        NdbDictionary::printFormattedValue(ndbout,
+                                           dpf,
+                                           col,
+                                           def);
+        ndbout << endl;
+      }
+    }
+  }
+
   // ordered index on first few columns
   NdbDictionary::Index idx("X");
   idx.setTable(tab.getName());

=== added file 'storage/ndb/test/ndbapi/testNativeDefault.cpp'
--- a/storage/ndb/test/ndbapi/testNativeDefault.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/ndbapi/testNativeDefault.cpp	2010-04-29 14:52:05 +0000
@@ -0,0 +1,810 @@
+/* Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+#include <NdbOut.hpp>
+#include <NdbApi.hpp>
+#include <NdbSleep.h>
+#include <NDBT.hpp>
+#include <NdbError.hpp>
+
+static Ndb_cluster_connection *g_cluster_connection= 0;
+static Ndb* g_ndb = 0;
+static const char* g_tablename1 = "T_DEF1"; //The normal table with default values
+static const char* g_tablename2 = "T_DEF2"; //The table for Test that maximum length defaults work
+//The table for Test that an attempt to insert to a table containing defaults 
+//without supplying a value for a not-null, non-defaulted column still fails
+static const char* g_tablename3 = "T_DEF3"; 
+static NdbDictionary::Dictionary* g_dict = 0;
+static const unsigned int column_count_table1 = 8;
+static const unsigned int column_count_table2 = 2;
+static const unsigned int column_count_table3 = 2;
+
+static int connect_ndb();
+static int disconnect_ndb();
+
+static struct NdbError g_ndberror;
+static int create_table();
+
+static int connect_ndb()
+{
+  g_cluster_connection = new Ndb_cluster_connection();
+  if(g_cluster_connection->connect(12, 5, 1) != 0)
+  {
+    return NDBT_FAILED;
+  }
+  g_ndb = new Ndb(g_cluster_connection, "TEST");
+  g_ndb->init();
+  if(g_ndb->waitUntilReady(30) == 0){
+    return NDBT_OK;
+  }
+  return NDBT_FAILED;
+}
+
+static int disconnect_ndb()                                            {
+  delete g_ndb;
+  delete g_cluster_connection;
+  g_ndb = 0;
+//  g_table = 0;
+  g_cluster_connection= 0;
+  return NDBT_OK;
+}
+
+#define PRINT_ERROR(error) \
+   ndbout << "Error in " << __FILE__ << ", line: " << __LINE__ \
+            << ", code: " << error.code \
+            << ", msg: " << error.message << "." << endl
+#define FAIL(error_msg) \
+  ndbout << error_msg << " at line " << __LINE__ << endl; \
+  return NDBT_FAILED
+
+static const int            tab1_c1_default= 6; 
+static const float          tab1_c2_default= float(1234.56);
+static const double         tab1_c3_default= 4567.89;
+static const char           tab1_c4_default[]= "aaaaaa      ";
+static const unsigned int   tab1_c4_default_siglen= 12;
+static const char           tab1_c5_default[]= "\x6" "aaaaaa\0\0\0\0";
+static const unsigned int   tab1_c5_default_siglen= 7;
+static const char           tab1_c6_default[]= "aaaaaa      ";
+static const unsigned int   tab1_c6_default_siglen= 0;
+static const char           tab1_c7_default[]= "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+static const char           tab1_c7_default_siglen= 1;
+
+static const int            tab2_c1_default_len= 8052 - 4 - 2;
+/* Max row length minus 4 bytes for key, minus 2 bytes for length info */
+static const char           tab2_c1_default_char= 'V';
+
+static int 
+create_table()
+{
+  g_dict = g_ndb->getDictionary();
+  if ((g_dict->getTable(g_tablename1) != 0) &&
+      (g_dict->dropTable(g_tablename1) != 0))
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if ((g_dict->getTable(g_tablename2) != 0) &&
+      (g_dict->dropTable(g_tablename2) != 0))
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if ((g_dict->getTable(g_tablename3) != 0) &&
+      (g_dict->dropTable(g_tablename3) != 0))
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  NdbDictionary::Table tab(g_tablename1);
+  tab.setLogging(false);
+  
+  NdbDictionary::Table tab2(g_tablename2);
+  tab2.setLogging(false);
+
+  NdbDictionary::Table tab3(g_tablename3);
+  tab3.setLogging(false);
+
+  // col PK - Uint32
+  { NdbDictionary::Column col("PK");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setAutoIncrement(TRUE);
+    col.setDefaultValue(NULL);
+    tab.addColumn(col);
+  }
+ 
+  { 
+    NdbDictionary::Column col("C1");
+    col.setType(NdbDictionary::Column::Int);
+    col.setDefaultValue(&tab1_c1_default,sizeof(int));
+    tab.addColumn(col);
+  }
+  
+  { 
+    NdbDictionary::Column col("C2");
+    col.setType(NdbDictionary::Column::Float);
+    col.setDefaultValue(&tab1_c2_default, sizeof(float));
+    tab.addColumn(col);
+  }
+
+  { 
+    NdbDictionary::Column col("C3");
+    col.setType(NdbDictionary::Column::Double);
+    col.setDefaultValue(&tab1_c3_default, sizeof(double));
+    tab.addColumn(col);
+  }
+
+  { 
+    NdbDictionary::Column col("C4");
+    col.setType(NdbDictionary::Column::Char);
+    col.setLength(12);
+    col.setDefaultValue(tab1_c4_default, 12);
+    tab.addColumn(col);
+  }
+
+  { 
+    NdbDictionary::Column col("C5");
+    col.setType(NdbDictionary::Column::Varchar);
+    col.setLength(199);
+    col.setDefaultValue(tab1_c5_default, tab1_c5_default_siglen);
+    tab.addColumn(col);
+  }
+
+
+  { 
+    /* Test non-null pointer passed, but with zero length? */
+    NdbDictionary::Column col("C6");
+    col.setType(NdbDictionary::Column::Char);
+    col.setLength(12);
+    col.setNullable(TRUE);
+    col.setDefaultValue(tab1_c6_default, tab1_c6_default_siglen);
+    tab.addColumn(col);
+  }
+
+  //Test that a zero-length VARCHAR default works
+  { 
+    NdbDictionary::Column col("C7");
+    col.setType(NdbDictionary::Column::Varchar);
+    col.setLength(10);
+    col.setDefaultValue(tab1_c7_default, tab1_c7_default_siglen);
+    tab.addColumn(col);
+  }
+
+  //create table T_DEF2
+  { NdbDictionary::Column col("PK");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setAutoIncrement(FALSE);
+    col.setDefaultValue(NULL, 0);
+    tab2.addColumn(col);
+  }
+
+  //Test that maximum length defaults work
+  { 
+    char default_data[tab2_c1_default_len + 2];
+    default_data[0] = (tab2_c1_default_len >> 0) & 0xff;
+    default_data[1] = (tab2_c1_default_len >> 8) & 0xff;
+    memset(default_data + 2, tab2_c1_default_char, tab2_c1_default_len);
+    NdbDictionary::Column col("C1");
+    col.setType(NdbDictionary::Column::Longvarchar);
+    col.setLength(tab2_c1_default_len);
+    col.setDefaultValue(default_data, tab2_c1_default_len + 2);
+    tab2.addColumn(col);
+  }
+
+  //Create table T_DEF3
+  { NdbDictionary::Column col("PK");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setAutoIncrement(FALSE);
+    col.setDefaultValue(NULL, 0);
+    tab3.addColumn(col);
+  }
+
+  //For column without supplying a value for a not-null, non-defaulted column
+  { NdbDictionary::Column col("C1");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setNullable(FALSE);
+    col.setDefaultValue(NULL, 0);
+    tab3.addColumn(col);
+  }
+  
+  // create table
+  if(g_dict->createTable(tab) != 0)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if(g_dict->createTable(tab2) != 0)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  if(g_dict->createTable(tab3) != 0)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  return NDBT_OK;
+}
+
+static int
+ndb_error_check(const struct NdbError& error, unsigned int line)
+{
+  if (error.code != 850)
+  {
+    PRINT_ERROR(error);
+    ndbout << " at line " << line << "\n";
+    return NDBT_FAILED;
+  }
+  return NDBT_OK;
+}
+
+#define CHECK_ERROR(error) {                           \
+  if (ndb_error_check(error, __LINE__) == NDBT_FAILED) \
+    return NDBT_FAILED;                                \
+  }
+
+static int
+create_table_error()
+{
+  g_dict = g_ndb->getDictionary();
+
+  /*
+   * 1. The following test case is for fixed columns that
+   *    there are too long or too short default values.
+   */
+  //for too long default value
+  NdbDictionary::Table tab1("T_DEF_TEST1");
+  tab1.setLogging(false);
+
+  { NdbDictionary::Column col("PK");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setDefaultValue(NULL);
+    tab1.addColumn(col);
+  }
+
+  { int default_data = 6;
+    NdbDictionary::Column col("C1");
+    col.setType(NdbDictionary::Column::Int);
+    col.setDefaultValue(&default_data, 8);
+    tab1.addColumn(col);
+  }
+
+  if(g_dict->createTable(tab1) != 0)
+  {
+    CHECK_ERROR(g_dict->getNdbError());
+  }
+  else
+  {
+    FAIL("Create table should not have succeeded");
+  }
+  
+  //for too short default value
+  NdbDictionary::Table tab2("T_DEF_TEST2");
+  tab2.setLogging(false);
+
+  { NdbDictionary::Column col("PK");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setAutoIncrement(TRUE);
+    col.setDefaultValue(NULL);
+    tab2.addColumn(col);
+  }
+
+  { const char default_data[] = "aaaaaa";
+    NdbDictionary::Column col("C4");
+    col.setType(NdbDictionary::Column::Char);
+    col.setLength(12);
+    col.setDefaultValue(default_data, 6);
+    tab2.addColumn(col);
+  }
+
+  if(g_dict->createTable(tab2) != 0)
+  {
+    CHECK_ERROR(g_dict->getNdbError());
+  }
+  else
+  {
+    FAIL("Create table should not have succeeded");
+  }
+
+  /*
+   * 2. The following test case is for Var-type columns that
+   *    there are too long default values.
+   */
+  NdbDictionary::Table tab3("T_DEF_TEST3");
+  tab3.setLogging(false);
+
+  { NdbDictionary::Column col("PK");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setAutoIncrement(TRUE);
+    col.setDefaultValue(NULL);
+    tab3.addColumn(col);
+  }
+
+  { char default_data[20];
+    memset(default_data, 0, 20);
+    Uint8 * p = (Uint8*)default_data;
+    *p = 10;
+    memcpy(default_data + 1, "aaaaaaaaaa", 10);
+    NdbDictionary::Column col("C5");
+    col.setType(NdbDictionary::Column::Varchar);
+    col.setLength(9);
+    col.setDefaultValue(default_data, 11);
+    tab3.addColumn(col);
+  }
+
+  if(g_dict->createTable(tab3) != 0)
+  {
+    CHECK_ERROR(g_dict->getNdbError());
+  }
+  else
+  {
+    FAIL("Create table should not have succeeded");
+  }
+
+
+  /*
+   * 3. Test attempt to set default value for primary key
+   */
+  NdbDictionary::Table tab4("T_DEF_TEST4");
+  tab4.setLogging(false);
+
+  { NdbDictionary::Column col("PK");
+    unsigned int default_val=22;
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setAutoIncrement(TRUE);
+    col.setDefaultValue(&default_val, sizeof(default_val));
+    tab4.addColumn(col);
+  }
+
+  if(g_dict->createTable(tab4) == 0)
+  {
+    FAIL("Create table should not have succeeded");
+  }
+
+  if(g_dict->getNdbError().code != 792)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+ 
+  /*
+   * 4. The following test case is for Var-type columns that
+   *    there are too long default values, where the passed
+   *    value is short, but the implied value is too long
+   */
+  NdbDictionary::Table tab5("T_DEF_TEST5");
+  tab5.setLogging(false);
+
+  { NdbDictionary::Column col("PK");
+    col.setType(NdbDictionary::Column::Unsigned);
+    col.setPrimaryKey(true);
+    col.setNullable(FALSE);
+    col.setAutoIncrement(TRUE);
+    col.setDefaultValue(NULL);
+    tab5.addColumn(col);
+  }
+
+  { char default_data[20];
+    memset(default_data, 0, 20);
+    Uint8 * p = (Uint8*)default_data;
+    *p = 15;
+    memcpy(default_data + 1, "aaaaaaaaaa", 15);
+    NdbDictionary::Column col("C5");
+    col.setType(NdbDictionary::Column::Varchar);
+    col.setLength(9);
+    /* Within range, but contained VARCHAR is too long */
+    col.setDefaultValue(default_data, 10);
+    tab5.addColumn(col);
+  }
+
+  if(g_dict->createTable(tab5) != 0)
+  {
+    CHECK_ERROR(g_dict->getNdbError());
+  }
+  else
+  {
+    FAIL("Create table should not have succeeded");
+  }
+
+  return NDBT_OK;
+}
+
+static int 
+drop_table()
+{
+  if ((g_dict != 0) && ( g_dict->getTable(g_tablename1) != 0))
+  {
+    if(g_dict->dropTable(g_tablename1))
+      PRINT_ERROR(g_dict->getNdbError());
+  }
+
+  if ((g_dict != 0) && ( g_dict->getTable(g_tablename2) != 0))
+  {
+    if(g_dict->dropTable(g_tablename2))
+      PRINT_ERROR(g_dict->getNdbError());
+  }
+
+  if ((g_dict != 0) && ( g_dict->getTable(g_tablename3) != 0))
+  {
+    if(g_dict->dropTable(g_tablename3))
+      PRINT_ERROR(g_dict->getNdbError());
+  }
+
+  return NDBT_OK;
+}
+
+static int do_insert()
+{
+  const NdbDictionary::Table *myTable= g_dict->getTable(g_tablename1);
+
+  if (myTable == NULL)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED; 
+  }
+
+  NdbTransaction *myTransaction= g_ndb->startTransaction(); 
+  if (myTransaction == NULL)
+  {
+    PRINT_ERROR(g_ndb->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
+  NdbOperation *myOperation1= myTransaction->getNdbOperation(myTable); 
+  if (myOperation == NULL || myOperation1 == NULL) 
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  myOperation->insertTuple();
+  myOperation->equal("PK", 1);
+  myOperation1->insertTuple();
+  myOperation1->equal("PK", 2);
+
+  //insert the second table T_DEF2
+  const NdbDictionary::Table *myTable2= g_dict->getTable(g_tablename2);
+
+  if (myTable == NULL)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+  NdbOperation *myOperation2 = myTransaction->getNdbOperation(myTable2);
+  if (myOperation2 == NULL)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  myOperation2->insertTuple();
+  myOperation2->equal("PK", 1);
+
+
+  /* Test insert of max length tuple with max length default
+   * Could theoretically expose kernel overflow with default 
+   * + supplied value
+   */
+  myOperation2=myTransaction->getNdbOperation(myTable2);
+  if (myOperation2 == NULL)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+  
+  myOperation2->insertTuple();
+  myOperation2->equal("PK", 2);
+
+  {
+    char default_data[tab2_c1_default_len + 2];
+    default_data[0] = (tab2_c1_default_len >> 0) & 0xff;
+    default_data[1] = (tab2_c1_default_len >> 8) & 0xff;
+    memset(default_data + 2, tab2_c1_default_char, tab2_c1_default_len);
+    
+    myOperation2->setValue("C1", default_data);
+  }
+
+  if (myTransaction->execute(NdbTransaction::Commit) == -1)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+  
+  g_ndb->closeTransaction(myTransaction);
+
+  //The following insert should fail, and return error code
+  const NdbDictionary::Table *myTable3= g_dict->getTable(g_tablename3);
+
+  if (myTable3 == NULL)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  NdbTransaction *myTransaction3 = g_ndb->startTransaction();
+  if (myTransaction3 == NULL)
+  {
+    PRINT_ERROR(g_ndb->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  NdbOperation *myOperation3 = myTransaction3->getNdbOperation(myTable3);
+  if (myOperation3 == NULL)
+  {
+    PRINT_ERROR(myTransaction3->getNdbError());
+    g_ndb->closeTransaction(myTransaction3);
+    return NDBT_FAILED;
+  }
+  myOperation3->insertTuple();
+  myOperation3->equal("PK", 1);
+
+  /* It should return error code 839 ( msg: Illegal null attribute)
+   * for an attempt to insert to a table containing defaults 
+   * without supplying a value for a not-null, non-defaulted column
+  */
+  if (myTransaction3->execute(NdbTransaction::Commit) == -1)
+  {
+    PRINT_ERROR(myTransaction3->getNdbError());
+    
+    if (myTransaction3->getNdbError().code != 839)
+    {
+      ndbout << "Expected error 839" << endl;
+      g_ndb->closeTransaction(myTransaction3);
+      return NDBT_FAILED;
+    }
+  }
+  g_ndb->closeTransaction(myTransaction3);
+
+  return NDBT_OK;
+}
+
+#define CHECK_VAL_EQ(ref, test) {                \
+    if ((ref) != (test)) {                       \
+      ndbout << "Equality failed at line " << __LINE__ << "\n" \
+             << test << " != " << ref << "\n"; \
+      return NDBT_FAILED;                      \
+    } }
+
+#define CHECK_BYTES_EQ(ref, test, len) {        \
+    if (memcmp((ref), (test), (len))) {         \
+      ndbout << "Bytes differ at line " << __LINE__ << "\n"; \
+      return NDBT_FAILED;                                    \
+    }} 
+
+
+
+
+static int do_read()
+{
+  NdbRecAttr *myRecAttr[column_count_table1];
+  NdbRecAttr *myRecAttr2[column_count_table2];
+  NdbRecAttr *myRecAttr3[column_count_table3];
+
+  const NdbDictionary::Table *myTable= g_dict->getTable(g_tablename1);
+  const NdbDictionary::Table *myTable2 = g_dict->getTable(g_tablename2);
+  const NdbDictionary::Table *myTable3 = g_dict->getTable(g_tablename3);
+
+  if (myTable == NULL || myTable2 == NULL || myTable3 == NULL)
+  {
+    PRINT_ERROR(g_dict->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  NdbTransaction *myTransaction= g_ndb->startTransaction();
+  if (myTransaction == NULL)
+  {
+    PRINT_ERROR(g_ndb->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  //Define Scan Operation for T_DEF1
+  NdbScanOperation *myScanOp = myTransaction->getNdbScanOperation(myTable);
+  if (myScanOp == NULL)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  if(myScanOp->readTuples(NdbOperation::LM_CommittedRead) == -1)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  myRecAttr[0] = myScanOp->getValue("PK");
+  myRecAttr[1] = myScanOp->getValue("C1");
+  myRecAttr[2] = myScanOp->getValue("C2");
+  myRecAttr[3] = myScanOp->getValue("C3");
+  myRecAttr[4] = myScanOp->getValue("C4");
+  myRecAttr[5] = myScanOp->getValue("C5");
+  myRecAttr[6] = myScanOp->getValue("C6");
+  myRecAttr[7] = myScanOp->getValue("C7");
+
+  for (unsigned int i = 0; i < column_count_table1; i++)
+    if (myRecAttr[i] == NULL)
+    {
+      PRINT_ERROR(myTransaction->getNdbError());
+      g_ndb->closeTransaction(myTransaction);
+      return NDBT_FAILED;
+    }
+
+  //Define Scan Operation for T_DEF2
+  NdbScanOperation *myScanOp2 = myTransaction->getNdbScanOperation(myTable2);
+  if (myScanOp2 == NULL)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  if(myScanOp2->readTuples(NdbOperation::LM_CommittedRead) == -1)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  myRecAttr2[0] = myScanOp2->getValue("PK");
+  myRecAttr2[1] = myScanOp2->getValue("C1");
+  if (myRecAttr2[0] == NULL || myRecAttr2[1] == NULL)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  //Define Scan Operation for T_DEF3  
+  NdbScanOperation *myScanOp3 = myTransaction->getNdbScanOperation(myTable3);
+  if (myScanOp3 == NULL)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  if(myScanOp3->readTuples(NdbOperation::LM_CommittedRead) == -1)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  myRecAttr3[0] = myScanOp3->getValue("PK");
+  myRecAttr3[1] = myScanOp3->getValue("C1");
+  if (myRecAttr3[0] == NULL || myRecAttr3[1] == NULL)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  //Execute the Transcation for the 3 scan operations
+  if(myTransaction->execute(NdbTransaction::NoCommit) != 0)
+  {
+    PRINT_ERROR(myTransaction->getNdbError());
+    g_ndb->closeTransaction(myTransaction);
+    return NDBT_FAILED;
+  }
+
+  //The following print out the result
+  int check;
+  ndbout<< "Table: " << g_tablename1 << endl;
+//   ndbout << "PK";
+//   for (unsigned int i = 0; i < column_count_table1; i++)
+//     ndbout << "\tC" << i ;
+//   ndbout << endl;
+  while((check = myScanOp->nextResult(true)) == 0){
+    do {
+//       for (Uint32 i = 0; i < column_count_table1; i++)
+//         ndbout << *myRecAttr[i] << "\t";
+//       ndbout << endl;
+      
+      for (Uint32 i = 0; i < column_count_table1; i++)
+      {
+        /* Check that all columns are non NULL except c6 */
+        CHECK_VAL_EQ((i == 6), myRecAttr[i]->isNULL());
+      }
+
+      CHECK_VAL_EQ(tab1_c1_default, (int) myRecAttr[1]->int32_value());
+      CHECK_VAL_EQ(tab1_c2_default, myRecAttr[2]->float_value());
+      CHECK_VAL_EQ(tab1_c3_default, myRecAttr[3]->double_value());
+      CHECK_BYTES_EQ(tab1_c4_default, (const char*) myRecAttr[4]->aRef(), tab1_c4_default_siglen);
+      CHECK_BYTES_EQ(tab1_c5_default, (const char*) myRecAttr[5]->aRef(), tab1_c5_default_siglen); 
+      CHECK_BYTES_EQ(tab1_c6_default, (const char*) myRecAttr[6]->aRef(), tab1_c6_default_siglen);
+      CHECK_BYTES_EQ(tab1_c7_default, (const char*) myRecAttr[7]->aRef(), tab1_c7_default_siglen);
+    } while((check = myScanOp->nextResult(false)) == 0);
+
+    if(check == -1)
+    {
+      ndbout << "Error with transaction " << check << " " 
+             << myTransaction->getNdbError().code << "\n";
+      return NDBT_FAILED;
+    }
+  }
+
+  ndbout<< "Table: " << g_tablename2 << endl;
+  // ndbout << "PK\tC1" << endl;
+  while((check = myScanOp2->nextResult(true)) == 0){
+    do {
+//       for (Uint32 i = 0; i < column_count_table2; i++)
+//       {
+//         if (i == 1)
+//           ndbout << myRecAttr2[i]->get_size_in_bytes() << "  ";
+//         ndbout << *myRecAttr2[i] << "\t";
+//       }
+//       ndbout << endl;
+      const char* valPtr= (const char*)myRecAttr2[1]->aRef();
+      char default_data[tab2_c1_default_len + 2];
+      default_data[0] = (tab2_c1_default_len >> 0) & 0xff;
+      default_data[1] = (tab2_c1_default_len >> 8) & 0xff;
+      memset(default_data + 2, tab2_c1_default_char, tab2_c1_default_len);
+
+      CHECK_BYTES_EQ(default_data, valPtr, tab2_c1_default_len + 2);
+
+    } while((check = myScanOp2->nextResult(false)) == 0);
+  }
+
+
+  return NDBT_OK;
+}
+
+int main(int argc, char* argv[])
+{
+  int ret = NDBT_OK;
+  ndb_init();
+  connect_ndb();
+  if ((ret = create_table_error()) == NDBT_FAILED)
+   return ret;
+
+  if ((ret = create_table()) == NDBT_FAILED)
+    return ret;
+  if ((ret = do_insert()) == NDBT_FAILED)
+    return ret;
+  if ((ret = do_read()) == NDBT_FAILED)
+    return ret;
+
+  if ((ret = drop_table()) == NDBT_FAILED)
+    return ret;
+
+  disconnect_ndb();
+
+  ndbout << "All tests successful" << endl;
+  return NDBT_OK;
+}

=== modified file 'storage/ndb/test/ndbapi/testUpgrade.cpp'
--- a/storage/ndb/test/ndbapi/testUpgrade.cpp	2010-03-22 12:38:39 +0000
+++ b/storage/ndb/test/ndbapi/testUpgrade.cpp	2010-04-29 14:52:05 +0000
@@ -847,11 +847,14 @@ runPostUpgradeChecks(NDBT_Context* ctx, 
   ndbout << "done" << endl;
 
 
-  if (ctx->getProperty("NoDDL", Uint32(0)) == 0)
+  if ((ctx->getProperty("NoDDL", Uint32(0)) == 0) &&
+      (ctx->getProperty("KeepFS", Uint32(0)) != 0))
   {
     /**
      * Bug48227
-     *   
+     * Upgrade with FS 6.3->7.0, followed by table
+     * create, followed by Sys restart resulted in 
+     * table loss.
      */
     Ndb* pNdb = GETNDB(step);
     NdbDictionary::Dictionary *pDict = pNdb->getDictionary();
@@ -915,6 +918,17 @@ runWait(NDBT_Context* ctx, NDBT_Step* st
   return NDBT_OK;
 }
 
+bool versionsSpanBoundary(int verA, int verB, int incBoundaryVer)
+{
+  int minPeerVer = MIN(verA, verB);
+  int maxPeerVer = MAX(verA, verB);
+
+  return ( (minPeerVer <  incBoundaryVer) &&
+           (maxPeerVer >= incBoundaryVer) );
+}
+
+#define SchemaTransVersion NDB_MAKE_VERSION(6,4,0)
+
 int runPostUpgradeDecideDDL(NDBT_Context* ctx, NDBT_Step* step)
 {
   /* We are running post-upgrade, now examine the versions
@@ -923,10 +937,11 @@ int runPostUpgradeDecideDDL(NDBT_Context
    */
   /* DDL should be ok as long as
    *  1) All data nodes have the same version
-   *  2) We are at the same version as the data nodes
+   *  2) There is not some version specific exception
    */
   bool useDDL = true;
 
+  Ndb* pNdb = GETNDB(step);
   NdbRestarter restarter;
   int minNdbVer = 0;
   int maxNdbVer = 0;
@@ -945,14 +960,53 @@ int runPostUpgradeDecideDDL(NDBT_Context
     useDDL = false;
     ndbout << "Ndbd nodes have mixed versions, DDL not supported" << endl;
   }
-  if (myVer != minNdbVer)
+  if (versionsSpanBoundary(myVer, minNdbVer, SchemaTransVersion))
   {
     useDDL = false;
-    ndbout << "Api has different version to Ndbd nodes, DDL not supported" << endl;
+    ndbout << "Api and Ndbd versions span schema-trans boundary, DDL not supported" << endl;
   }
 
   ctx->setProperty("NoDDL", useDDL?0:1);
 
+  if (useDDL)
+  {
+    ndbout << "Dropping and recreating tables..." << endl;
+    
+    for (int i=0; i < NDBT_Tables::getNumTables(); i++)
+    {  
+      /* Drop table (ignoring rc if it doesn't exist etc...) */
+      pNdb->getDictionary()->dropTable(NDBT_Tables::getTable(i)->getName());
+      int ret= NDBT_Tables::createTable(pNdb, 
+                                        NDBT_Tables::getTable(i)->getName(),
+                                        false,   // temp
+                                        false);  // exists ok
+      if(ret)
+      {
+        NdbError err = pNdb->getDictionary()->getNdbError();
+
+        g_err << "Failed to create table "
+              << NDBT_Tables::getTable(i)->getName()
+              << " error : " 
+              << err
+              << endl;
+
+        /* Check for allowed exceptions during upgrade */
+        if (err.code == 794)
+        {
+          /* Schema feature requires data node upgrade */
+          if (minNdbVer >= myVer)
+          {
+            g_err << "Error 794 received, but data nodes are upgraded" << endl;
+            // TODO : Dump versions here
+            return NDBT_FAILED;
+          }
+          g_err << "Create table failure due to old version NDBDs, continuing" << endl;
+        }
+      }
+    }
+    ndbout << "Done" << endl;
+  }
+
   return NDBT_OK;
 }
 

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2010-03-17 12:37:40 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2010-04-29 14:52:05 +0000
@@ -1548,3 +1548,7 @@ max-time: 300
 cmd: testNodeRestart
 args: -n MixReadUnlockRestart T1
 
+mas-time: 500
+cmd: testNativeDefault
+args: 
+

=== modified file 'storage/ndb/test/src/NDBT_Tables.cpp'
--- a/storage/ndb/test/src/NDBT_Tables.cpp	2010-01-20 09:51:06 +0000
+++ b/storage/ndb/test/src/NDBT_Tables.cpp	2010-04-29 14:52:05 +0000
@@ -407,16 +407,42 @@ const
 NDBT_Table D1("D1", sizeof(D1Attribs)/sizeof(NDBT_Attribute), D1Attribs);
 
 static
+const char* BigVarDefault =
+  "\x80\x1"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2"
+  "KOL7 default in table D2";
+
+static unsigned smallUintDefault = 77;
+
+static
 const
 NDBT_Attribute D2Attribs[] = {
   NDBT_Attribute("KOL1", NdbDictionary::Column::Varbinary, 127, true), 
-  NDBT_Attribute("KOL2", NdbDictionary::Column::Unsigned, 1, false, false, 0, NdbDictionary::Column::StorageTypeDisk),
+  NDBT_Attribute("KOL2", NdbDictionary::Column::Unsigned, 1, false, false, 0, NdbDictionary::Column::StorageTypeDisk, false,
+                 &smallUintDefault, sizeof(unsigned)),
   NDBT_Attribute("KOL3", NdbDictionary::Column::Unsigned),
-  NDBT_Attribute("KOL4", NdbDictionary::Column::Varbinary, 133, false, true, 0, MM, true),
+  NDBT_Attribute("KOL4", NdbDictionary::Column::Varbinary, 133, false, true, 0, MM, true, 
+                 "\x1E" "A default value for KOL4 in D2", 31),
   NDBT_Attribute("KOL5", NdbDictionary::Column::Char, 199, false, true, 0, NdbDictionary::Column::StorageTypeDisk),
   NDBT_Attribute("KOL6", NdbDictionary::Column::Bit, 21, false, false, 0, NdbDictionary::Column::StorageTypeDisk),
-  NDBT_Attribute("KOL7", NdbDictionary::Column::Longvarbinary, 384, false, true, 0, NdbDictionary::Column::StorageTypeDisk),
-  NDBT_Attribute("KOL8", NdbDictionary::Column::Varbinary, 88, false, true, 0, NdbDictionary::Column::StorageTypeDisk)
+  NDBT_Attribute("KOL7", NdbDictionary::Column::Longvarbinary, 384, false, true, 0, NdbDictionary::Column::StorageTypeDisk, false, 
+                 BigVarDefault, 386),
+  NDBT_Attribute("KOL8", NdbDictionary::Column::Varbinary, 88, false, true, 0, NdbDictionary::Column::StorageTypeDisk, false, 
+                 "\x1E""A default value for KOL8 in D2", 31)
 
 };
 static


Attachment: [text/bzr-bundle] bzr/frazer@mysql.com-20100429160305-6115p1it2wltva83.bundle
Thread
bzr commit into mysql-5.1-telco-7.1 branch (frazer:3584)Frazer Clement29 Apr