List:Commits« Previous MessageNext Message »
From:Guangbao Ni Date:November 5 2008 3:55pm
Subject:bzr commit into mysql-5.1 branch (gni:2999) WL#4197
View as plain text  
#At file:///home/ngb/mysql/bzr/wl4197-review/

 2999 Guangbao Ni	2008-11-05
      WL#4197 Ndb native default value support
modified:
  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/ndbapi/NdbDictionary.hpp
  storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp
  storage/ndb/src/common/util/BaseString.cpp
  storage/ndb/src/common/util/SimpleProperties.cpp
  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
  storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
  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/DbtupRoutines.cpp
  storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
  storage/ndb/src/ndbapi/NdbDictionary.cpp
  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp

per-file messages:
  mysql-test/suite/rpl_ndb/r/rpl_ndb_2ndb.result
    Attribute values should be default value in slave when insert a row in master after having altered table add column with a default value in slave.
  mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result
    Attribute values should be default value in slave when insert a row in master after having altered table add column with a default value in slave.
  sql/ha_ndbcluster.cc
    There are two function:
    1. Set correct default values for columns when creating a table
    2. Mask the default value when inserting a row into a table
  sql/ha_ndbcluster.h
    Add a method function to get the default values of columns for a table when creating it.
  storage/ndb/include/kernel/ndb_limits.h
    Changing the max length of column default values equals to the max length of types (excluding blob and text type, because they don't have default value).
  storage/ndb/include/kernel/signaldata/DictTabInfo.hpp
    Add the information of attribute default value length when transfering Dictionary table info back and forth between NDBAPI and ndbd kernel.
  storage/ndb/include/kernel/signaldata/LqhFrag.hpp
    Add a data for default value length of an attribute.
  storage/ndb/include/kernel/signaldata/TupFrag.hpp
    Add a data for default value length of an attribute.
  storage/ndb/include/ndbapi/NdbDictionary.hpp
    Add two member functions for processing the attribute default values with length parameter
  storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp
    Changing the type of attribute default values from SimpleProperties::StringValue to SimpleProperties::BinaryValue, for the default values probably include the '\0' data
  storage/ndb/src/common/util/BaseString.cpp
    Making the operator= can handles BinaryValue type correctly.
  storage/ndb/src/common/util/SimpleProperties.cpp
    For backward compatibility when ndb_restore restores data.
  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
    Transfering the default value to LQH when creating table.
  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
    Add a data for default value length.
  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
    Add member variables for default values.
  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
    Receiving the default values from Dbdict and sending the default values to DBTUP when creating table.
  storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
    Add a member variable DefaultValuesFragment for default values storing of all tables.
    Add some member functions to handle DefaultValuesFragment.
    Add some member functions for receiving and storing default values.
  storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
    Don't insert default values firstly when updating a row.
  storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
    Initialize the DefaultValuesFragment
  storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
    Receiving and storing the default values when creating a table.
  storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
    Inserting default values firstly when inserting a record.
  storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
    Free the memory of default values when droping a table.
  storage/ndb/src/ndbapi/NdbDictionary.cpp
    Implementing the setDefaultValue memthod with length parameter.
  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
    Transfering the default values of attributes from ndbapi to kernel when creating table.
=== 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	2008-11-05 15:54:58 +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	2008-03-27 23:34:06 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result	2008-11-05 15:54:58 +0000
@@ -28,9 +28,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
 *** Drop t1  ***
 DROP TABLE t1;
 *** Create t2 on slave  ***
@@ -381,9 +381,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  ***
@@ -608,9 +608,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 ****
@@ -640,9 +640,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 *** 
@@ -676,9 +676,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;
@@ -706,9 +706,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 ***
@@ -733,12 +733,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;
@@ -751,9 +751,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  ***
@@ -784,9 +784,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;
 ********************************************
@@ -845,9 +845,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;
@@ -879,9 +879,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	2008-10-09 10:14:43 +0000
+++ b/sql/ha_ndbcluster.cc	2008-11-05 15:54:58 +0000
@@ -2237,7 +2237,12 @@ int ha_ndbcluster::ndb_pk_update_row(THD
   {
     DBUG_RETURN(error);
   }
+
+  my_bitmap_map *old_map=
+    dbug_tmp_use_all_columns(table, table->write_set);
   error= ndb_write_row(new_data, TRUE, batched_update);
+  dbug_tmp_restore_column_map(table->write_set, old_map);
+
   if (error)
   {
     DBUG_PRINT("info", ("insert failed"));
@@ -3280,11 +3285,11 @@ int ha_ndbcluster::ndb_write_row(uchar *
     key_row= record;
   }
 
-  const MY_BITMAP *user_cols_written_bitmap;
-  
+  MY_BITMAP *user_cols_written_bitmap;
+  uchar *mask;
+
   if (m_use_write)
   {
-    uchar *mask;
 
 #ifdef HAVE_NDB_BINLOG
     /*
@@ -3318,10 +3323,22 @@ int ha_ndbcluster::ndb_write_row(uchar *
   }
   else
   {
+    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)
+      {
+        if (!bitmap_is_set(user_cols_written_bitmap, field->field_index))
+          bitmap_set_bit(user_cols_written_bitmap, field->field_index);
+      }
+    }
+
+    mask= (uchar *)(user_cols_written_bitmap->bitmap);  
+
     /* Using insert, we write all user visible columns */
-    user_cols_written_bitmap= NULL;
     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))
@@ -4211,6 +4228,57 @@ void ha_ndbcluster::unpack_record(uchar 
   }
 }
 
+
+/**
+  Get the default value of the field from default_values of the table.
+*/
+static void get_default_value(char *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)
+      {
+      }
+      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(dev_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(););
 */
@@ -5855,6 +5923,8 @@ static int create_ndb_column(THD *thd,
   NDBCOL::StorageType type= NDBCOL::StorageTypeMemory;
   bool dynamic= FALSE;
 
+  uint32 actual_length= field->used_length();
+  char buf[field->pack_length() + 1];
   DBUG_ENTER("create_ndb_column");
   // Set name
   if (col.setName(field->field_name))
@@ -5865,6 +5935,37 @@ 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();
+
+  {
+    if (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)
+    {
+      memset(buf, 0, field->pack_length() + 1);
+      get_default_value(buf, field);
+      if (!(field->flags & NO_DEFAULT_VALUE_FLAG))
+      {
+        my_ptrdiff_t src_offset= field->table->s->default_values - field->table->record[0];
+        if (!(field->flags & NOT_NULL_FLAG) && 
+              field->is_null_in_record_with_offset(src_offset))
+        {
+          col.setDefaultValue(NULL, 0);
+        }
+        else
+        {
+          col.setDefaultValue(static_cast<const char*>(buf), field->used_length());
+        }
+      }
+      else
+      {
+        col.setDefaultValue(NULL, 0);
+      }
+    }
+    else
+      col.setDefaultValue(NULL, 0);
+  }
   switch (mysql_type) {
   // Numeric types
   case MYSQL_TYPE_TINY:        
@@ -6430,6 +6531,12 @@ int ha_ndbcluster::create(const char *na
   /*
     Setup columns
   */
+  my_bitmap_map *old_map;
+  {
+    restore_record(form, s->default_values);
+    old_map= dbug_tmp_use_all_columns(form, form->read_set);
+  }
+
   for (i= 0; i < form->s->fields; i++) 
   {
     Field *field= form->field[i];
@@ -6455,6 +6562,7 @@ int ha_ndbcluster::create(const char *na
       pk_length += (field->pack_length() + 3) / 4;
   }
 
+  dbug_tmp_restore_column_map(form->read_set, old_map);
   if (use_disk)
   { 
     tab.setLogging(TRUE);
@@ -6520,6 +6628,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	2008-10-08 01:57:24 +0000
+++ b/sql/ha_ndbcluster.h	2008-11-05 15:54:58 +0000
@@ -634,6 +634,7 @@ private:
   int next_result(uchar *buf); 
   int close_scan();
   void unpack_record(uchar *dst_row, const uchar *src_row);
+  void ha_ndbcluster::get_default_value(uchar *def_val, Field *field);
   int get_ndb_lock_type(enum thr_lock_type type,
                         const MY_BITMAP *column_bitmap);
 

=== modified file 'storage/ndb/include/kernel/ndb_limits.h'
--- a/storage/ndb/include/kernel/ndb_limits.h	2008-08-21 05:08:36 +0000
+++ b/storage/ndb/include/kernel/ndb_limits.h	2008-11-05 15:54:58 +0000
@@ -73,7 +73,7 @@
 #define 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 256
 #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	2008-10-02 21:58:44 +0000
+++ b/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2008-11-05 15:54:58 +0000
@@ -165,6 +165,7 @@ public:
     AttributeAutoIncrement = 1017, //Default false
     AttributeDefaultValue  = 1018, //Default value (printable string),
     AttributeArrayType     = 1019, //Default NDB_ARRAYTYPE_FIXED
+    AttributeDefaultValueLen = 1020, //Actual Length saved in AttributeDefaultValue
     AttributeEnd           = 1999  //
   };
   // ----------------------------------------------------------------------
@@ -431,6 +432,7 @@ public:
     Uint32 AttributeAutoIncrement;
     Uint32 AttributeStorageType;
     Uint32 AttributeDynamic;
+    Uint32 AttributeDefaultValueLen;
     char   AttributeDefaultValue[MAX_ATTR_DEFAULT_VALUE_SIZE];
     
     Attribute() {}
@@ -585,6 +587,8 @@ public:
       fprintf(out, "AttributeExtPrecision = %d\n", AttributeExtPrecision);
       fprintf(out, "AttributeExtScale = %d\n", AttributeExtScale);
       fprintf(out, "AttributeExtLength = %d\n", AttributeExtLength);
+      fprintf(out, "AttributeDefaultValueLen = %d\n", 
+              AttributeDefaultValueLen);
       fprintf(out, "AttributeDefaultValue = \"%s\"\n",
         AttributeDefaultValue ? AttributeDefaultValue : "");
     }

=== modified file 'storage/ndb/include/kernel/signaldata/LqhFrag.hpp'
--- a/storage/ndb/include/kernel/signaldata/LqhFrag.hpp	2008-08-11 11:42:06 +0000
+++ b/storage/ndb/include/kernel/signaldata/LqhFrag.hpp	2008-11-05 15:54:58 +0000
@@ -210,12 +210,14 @@ class LqhAddAttrReq {
   friend bool printLQH_ADD_ATTR_REQ(FILE *, const Uint32 *, Uint32, Uint16);
 public:
   STATIC_CONST( HeaderLength = 4 );
-  STATIC_CONST( EntryLength = 3 );
-  STATIC_CONST( MAX_ATTRIBUTES = 6 );
+  STATIC_CONST( EntryLength = 4 );
+  STATIC_CONST( MAX_ATTRIBUTES = 5 );
+  STATIC_CONST( DEFAULT_VALUES = 0 );
   struct Entry {
     Uint32 attrId;              // for index, includes primary attr id << 16
     Uint32 attrDescriptor;      // 2 words type info
     Uint32 extTypeInfo;
+    Uint32 defValueLen;         //The total bytes 
   };
 private:
   Uint32 lqhFragPtr;

=== modified file 'storage/ndb/include/kernel/signaldata/TupFrag.hpp'
--- a/storage/ndb/include/kernel/signaldata/TupFrag.hpp	2008-06-05 20:19:01 +0000
+++ b/storage/ndb/include/kernel/signaldata/TupFrag.hpp	2008-11-05 15:54:58 +0000
@@ -120,9 +120,10 @@ class TupAddAttrReq {
   friend class Dbtux;
 public:
   STATIC_CONST( SignalLength = 5 );
+  STATIC_CONST( DEFAULT_VALUES = 0 );
 private:
   Uint32 tupConnectPtr;
-  Uint32 notused1;
+  Uint32 defValueLen;  //The total bytes
   Uint32 attrId;
   Uint32 attrDescriptor;
   Uint32 extTypeInfo;

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp	2008-06-05 20:25:12 +0000
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp	2008-11-05 15:54:58 +0000
@@ -560,7 +560,8 @@ public:
     bool getAutoIncrement() const;
     void setAutoIncrementInitialValue(Uint64 val);
     int setDefaultValue(const char*);   
-    const char* getDefaultValue() const;
+    int setDefaultValue(const char* buf, unsigned int len); 
+    const char* getDefaultValue(unsigned int* len = 0) const;
 
     static const Column * FRAGMENT;
     static const Column * FRAGMENT_FIXED_MEMORY;

=== modified file 'storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp'
--- a/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp	2008-06-02 13:27:27 +0000
+++ b/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp	2008-11-05 15:54:58 +0000
@@ -97,8 +97,13 @@ 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)
 };
 
@@ -195,6 +200,7 @@ DictTabInfo::Attribute::init(){
   AttributeAutoIncrement = false;
   AttributeStorageType = 0;
   AttributeDynamic = 0;                         // Default is not dynamic
+  AttributeDefaultValueLen = 0;                 //Default the length of default value is 0
   memset(AttributeDefaultValue, 0, sizeof(AttributeDefaultValue));//AttributeDefaultValue[0] = 0;
 }
 

=== modified file 'storage/ndb/src/common/util/BaseString.cpp'
--- a/storage/ndb/src/common/util/BaseString.cpp	2007-04-11 13:51:09 +0000
+++ b/storage/ndb/src/common/util/BaseString.cpp	2008-11-05 15:54:58 +0000
@@ -239,7 +239,7 @@ BaseString&
 BaseString::operator=(const BaseString& str)
 {
     if (this != &str) {
-	this->assign(str);
+	this->assign(str, str.length());
     }
     return *this;
 }

=== modified file 'storage/ndb/src/common/util/SimpleProperties.cpp'
--- a/storage/ndb/src/common/util/SimpleProperties.cpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/common/util/SimpleProperties.cpp	2008-11-05 15:54:58 +0000
@@ -196,8 +196,13 @@ SimpleProperties::unpack(Reader & it, vo
 	found = true;
 	if(_map[i].Type == InvalidValue)
 	  return Break;
-	if(_map[i].Type != it.getValueType())
-	  return TypeMismatch;
+        if (key == 1018){ //For backward compatibility when restoring data
+          if ((it.getValueType() != SimpleProperties::BinaryValue) && 
+              (it.getValueType() != SimpleProperties::StringValue))
+            return TypeMismatch;
+        } else
+   	  if(_map[i].Type != it.getValueType())
+	    return TypeMismatch;
 	
 	char * _dst = (char *)dst;
 	_dst += _map[i].Offset;

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-10-10 11:39:51 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-11-05 15:54:58 +0000
@@ -672,9 +672,10 @@ Dbdict::packTableIntoPages(SimplePropert
     else
       w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_MEMORY);
     
+    w.add(DictTabInfo::AttributeDefaultValueLen, attrPtr.p->defaultValueLen);
     ConstRope def(c_rope_pool, attrPtr.p->defaultValue);
     def.copy(defaultValue);
-    w.add(DictTabInfo::AttributeDefaultValue, defaultValue);
+    w.add(DictTabInfo::AttributeDefaultValue, defaultValue, attrPtr.p->defaultValueLen);
     
     w.add(DictTabInfo::AttributeEnd, 1);
   }
@@ -4664,9 +4665,10 @@ void Dbdict::handleTabInfo(SimplePropert
     AttributeDescriptor::setDynamic(desc, attrDesc.AttributeDynamic);
     attrPtr.p->attributeDescriptor = desc;
     attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement;
+    attrPtr.p->defaultValueLen = attrDesc.AttributeDefaultValueLen;
     {
       Rope defaultValue(c_rope_pool, attrPtr.p->defaultValue);
-      defaultValue.assign(attrDesc.AttributeDefaultValue);
+      defaultValue.assign(attrDesc.AttributeDefaultValue, attrDesc.AttributeDefaultValueLen);
     }
     
     keyCount += attrDesc.AttributeKeyFlag;
@@ -5512,6 +5514,9 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal
   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
   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;
@@ -5522,6 +5527,14 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal
     entry.extTypeInfo = 0;
     // charset number passed to TUP, TUX in upper half
     entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
+
+    entry.defValueLen = attrPtr.p->defaultValueLen;
+    ConstRope def(c_rope_pool, attrPtr.p->defaultValue);
+    def.copy((char*)defVal_dst);
+ 
+    defVal_length += (entry.defValueLen + 3)/4;
+    defVal_dst += (entry.defValueLen + 3)/4;
+
     if (tabPtr.p->isIndex()) {
       Uint32 primaryAttrId;
       if (attrPtr.p->nextList != RNIL) {
@@ -5540,8 +5553,12 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal
   req->senderAttrPtr = attributePtrI;
   req->noOfAttributes = i;
 
+  LinearSectionPtr ptr[3];
+  ptr[0].p= &signal->theData[25];
+  ptr[0].sz= defVal_length;
+
   sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
-	     LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
+	     LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB, ptr, 1);
 }
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2008-10-05 07:14:21 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2008-11-05 15:54:58 +0000
@@ -183,6 +183,7 @@ public:
 
     /* Default value as null-terminated string, only for ODBC/SQL */
     RopeHandle defaultValue;
+    Uint32 defaultValueLen;
 
     struct {
       Uint32 m_name_len;

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2008-10-09 19:17:11 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2008-11-05 15:54:58 +0000
@@ -428,6 +428,9 @@ public:
       TUP_ATTR_WAIT = 7,
       TUX_ATTR_WAIT = 9
     };
+    enum DefBufLength {
+      DEF_BUF_LEN = LqhAddAttrReq::MAX_ATTRIBUTES*((MAX_ATTR_DEFAULT_VALUE_SIZE + 3)/4)
+    };
     AddFragStatus addfragStatus;
     UintR fragmentPtr;
     UintR nextAddfragrec;
@@ -445,6 +448,8 @@ public:
     Uint16 attrReceived;
     Uint16 totalAttrReceived;
     Uint16 fragCopyCreation;
+    Uint16 defValIndex;
+    Uint32 defValBuf[DEF_BUF_LEN];
   };
   typedef Ptr<AddFragRecord> AddFragRecordPtr;
   

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-10-09 19:17:11 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-11-05 15:54:58 +0000
@@ -1275,6 +1275,16 @@ void Dblqh::execLQHADDATTREQ(Signal* sig
 
   const Uint32 tnoOfAttr = req->noOfAttributes;
 
+  SectionHandle handle(this, signal);
+  SegmentedSectionPtr ptr;
+  handle.getSection(ptr, LqhAddAttrReq::DEFAULT_VALUES);
+  Uint32 defaultbuf_len = AddFragRecord::DEF_BUF_LEN;
+  memset(addfragptr.p->defValBuf, 0, defaultbuf_len);
+  copy(addfragptr.p->defValBuf, ptr);
+  addfragptr.p->defValIndex = 0;
+
+  releaseSections(handle);
+
   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::WAIT_ADD_ATTR);
   ndbrequire((tnoOfAttr != 0) && (tnoOfAttr <= LqhAddAttrReq::MAX_ATTRIBUTES));
   addfragptr.p->totalAttrReceived += tnoOfAttr;
@@ -1450,13 +1460,27 @@ Dblqh::sendAddAttrReq(Signal* signal)
       jam();
       TupAddAttrReq* const tupreq = (TupAddAttrReq*)signal->getDataPtrSend();
       tupreq->tupConnectPtr = addfragptr.p->tupConnectptr;
-      tupreq->notused1 = 0;
+      tupreq->defValueLen = entry.defValueLen;
       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 defValueWords = (entry.defValueLen +3)/4;
+      {
+        arrGuard((addfragptr.p->defValIndex + defValueWords), AddFragRecord::DEF_BUF_LEN);
+        Uint32 startIndex = TupAddAttrReq::SignalLength;
+        Uint32 *dst = &signal->theData[startIndex];
+        Uint32 *src = addfragptr.p->defValBuf + addfragptr.p->defValIndex;
+        memcpy(dst, src, entry.defValueLen);
+        memset(((char*)dst + entry.defValueLen), 0, defValueWords*4 - entry.defValueLen);
+        addfragptr.p->defValIndex += defValueWords;
+        LinearSectionPtr ptr[3];
+        ptr[0].p= &signal->theData[startIndex];
+        ptr[0].sz= defValueWords;
+        sendSignal(tupRef, GSN_TUP_ADD_ATTRREQ,
+                   signal, TupAddAttrReq::SignalLength, JBB, ptr, 1);
+      }
+
       return;
     }
     if (DictTabInfo::isOrderedIndex(tabptr.p->tableType) &&

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2008-10-10 09:32:12 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2008-11-05 15:54:58 +0000
@@ -1067,6 +1067,8 @@ ArrayPool<TupTriggerData> c_triggerPool;
       } m_dropTable;
       struct {
         Uint32 m_fragOpPtrI;
+        Uint32 receivedWords; 
+        Uint32 totalDefWords;
       } m_createTable;
       struct {
         Uint32 m_gci_hi;
@@ -1074,6 +1076,7 @@ ArrayPool<TupTriggerData> c_triggerPool;
     };
 
     State tableStatus;
+    Local_key m_default_value_location;
   };  
 
   /*
@@ -2015,7 +2018,8 @@ private:
 //------------------------------------------------------------------
   int updateAttributes(KeyReqStruct *req_struct,
                        Uint32*     inBuffer,
-                       Uint32      inBufLen);
+                       Uint32      inBufLen,
+                       bool        insertDefaultValue = true);
 
 //------------------------------------------------------------------
 //------------------------------------------------------------------
@@ -2453,6 +2457,8 @@ private:
 //------------------------------------------------------------------
 //------------------------------------------------------------------
 
+  int  store_default_record(const TablerecPtr& regTabPtr);
+  void receive_defvalue(Signal* signal, const TablerecPtr& regTabPtr);
 //------------------------------------------------------------------
 //------------------------------------------------------------------
   void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen);
@@ -2773,6 +2779,7 @@ private:
   void initializeTablerec();
   void initializeTabDescr();
   void initializeUndoPage();
+  void intializeDefaultValuesFrag();
 
   void initTab(Tablerec* regTabPtr);
 
@@ -2923,6 +2930,7 @@ private:
 // Public methods
   Uint32* alloc_var_rec(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(Fragrecord*, Tablerec*, Uint32, Local_key*);
   Uint32 *realloc_var_part(Fragrecord*, Tablerec*, 
                            PagePtr, Var_part_ref*, Uint32, Uint32);
@@ -2974,6 +2982,7 @@ private:
   Uint32 cnoOfFragrec;
   RSS_OP_COUNTER(cnoOfFreeFragrec);
   RSS_OP_SNAPSHOT(cnoOfFreeFragrec);
+  FragrecordPtr DefaultValuesFragment;
 
   AlterTabOperation *alterTabOperRec;
   Uint32 cfirstfreeAlterTabOp;

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2008-10-01 07:57:51 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2008-11-05 15:54:58 +0000
@@ -1004,7 +1004,8 @@ int Dbtup::handleUpdateReq(Signal* signa
     jam();
     int retValue = updateAttributes(req_struct,
 				    &cinBuffer[0],
-				    req_struct->attrinfo_len);
+				    req_struct->attrinfo_len,
+                                    false);
     if (unlikely(retValue == -1))
       goto error;
   } else {

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2008-10-07 13:01:20 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2008-11-05 15:54:58 +0000
@@ -535,6 +535,7 @@ void Dbtup::execNDB_STTOR(Signal* signal
     jam();
     cownNodeId = ownNodeId;
     cownref = calcInstanceBlockRef(DBTUP);
+    intializeDefaultValuesFrag();
     break;
   case ZSTARTPHASE2:
     jam();
@@ -570,6 +571,32 @@ void Dbtup::startphase3Lab(Signal* signa
 {
 }//Dbtup::startphase3Lab()
 
+void Dbtup::intializeDefaultValuesFrag()
+{
+  seizeFragrecord(DefaultValuesFragment);
+  DefaultValuesFragment.p->fragStatus = Fragrecord::FS_ONLINE;
+/*
+  DefaultValuesFragment.p->fragTableId= regTabPtr.i;
+  DefaultValuesFragment.p->fragmentId= fragId;
+  DefaultValuesFragment.p->m_tablespace_id= tablespace_id;
+*/
+  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;
@@ -667,6 +694,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	2008-10-10 09:32:12 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2008-11-05 15:54:58 +0000
@@ -35,6 +35,7 @@
 #include "AttributeOffset.hpp"
 #include <my_sys.h>
 #include <signaldata/LqhFrag.hpp>
+#include <signaldata/AttrInfo.hpp>
 
 void
 Dbtup::execCREATE_TAB_REQ(Signal* signal)
@@ -72,6 +73,8 @@ Dbtup::execCREATE_TAB_REQ(Signal* signal
   fragOperPtr.p->lqhBlockrefFrag = req->senderRef;
 
   regTabPtr.p->m_createTable.m_fragOpPtrI = fragOperPtr.i;
+  regTabPtr.p->m_createTable.receivedWords = 0;
+  regTabPtr.p->m_createTable.totalDefWords = 0;
   regTabPtr.p->tableStatus= DEFINING;
   regTabPtr.p->m_bits = 0;
   regTabPtr.p->m_bits |= (req->checksumIndicator ? Tablerec::TR_Checksum : 0);
@@ -153,6 +156,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
 {
   FragoperrecPtr fragOperPtr;
   TablerecPtr regTabPtr;
+  Operationrec* regOperPtr;
 
   jamEntry();
   fragOperPtr.i= signal->theData[0];
@@ -169,6 +173,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
   fragOperPtr.p->attributeCount--;
   const bool lastAttr = (fragOperPtr.p->attributeCount == 0);
 
+
   Uint32 firstTabDesIndex= regTabPtr.p->tabDescriptor + (attrId * ZAD_SIZE);
   setTabDescrWord(firstTabDesIndex, attrDescriptor);
   Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
@@ -177,6 +182,8 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
   Uint32 bytes= AttributeDescriptor::getSizeInBytes(attrDescriptor);
   Uint32 words= (bytes + 3) / 4;
   Uint32 ind= AttributeDescriptor::getDiskBased(attrDescriptor);
+
+
   if (!AttributeDescriptor::getDynamic(attrDescriptor)) {
     jam();
     Uint32 null_pos;
@@ -193,7 +200,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
         || ind==DD)
     {
       jam();
-      regTabPtr.p->m_attributes[ind].m_no_of_fixsize++;
+      regTabPtr.p->m_attributes[ind].m_no_of_fixsize++;      
       if(attrLen == 0)
       {
         /* Static bit type. */
@@ -268,6 +275,8 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
     }
     AttributeOffset::setNullFlagPos(attrDes2, null_pos);
 
+    AttributeOffset::setNullFlagPos(attrDes2, null_pos);
+
     ndbassert((regTabPtr.p->m_attributes[ind].m_no_of_dyn_var +
                regTabPtr.p->m_attributes[ind].m_no_of_dyn_fix) <=
               regTabPtr.p->m_attributes[ind].m_no_of_dynamic);
@@ -286,6 +295,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
     goto error;
   }
 
+  receive_defvalue(signal, regTabPtr);
   if (! lastAttr)
   {
     jam();
@@ -295,7 +305,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
 	       signal, 2, JBB);
     return;
   }
-  
+ 
 #define BTW(x) ((x+31) >> 5)
   regTabPtr.p->m_offsets[MM].m_null_words= BTW(fragOperPtr.p->m_null_bits[MM]);
   regTabPtr.p->m_offsets[DD].m_null_words= BTW(fragOperPtr.p->m_null_bits[DD]);
@@ -387,6 +397,120 @@ error:
   return;
 }
 
+void Dbtup::receive_defvalue(Signal* signal, const TablerecPtr& regTabPtr)
+{
+  Uint32 defValueBytes = signal->theData[1];
+  Uint32 defValueWords = (defValueBytes +3)/4;
+  Uint32 attrId = signal->theData[2];
+  Uint32 attrDescriptor = signal->theData[3];
+
+  Uint32 bytes= AttributeDescriptor::getSizeInBytes(attrDescriptor);
+  Uint32 words= (bytes + 3) / 4;
+
+  Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
+  Uint32 array = AttributeDescriptor::getArrayType(attrDescriptor);  
+  Uint32 arraySize = AttributeDescriptor::getArraySize(attrDescriptor);
+  Uint32 nullable = AttributeDescriptor::getNullable(attrDescriptor);
+  Uint32 byteSizes = 0;
+  SectionHandle handle(this, signal);
+
+  if (defValueBytes == 0)
+  {
+    releaseSections(handle);  
+    return ;
+  }
+  if (attrLen)
+  {
+    if (array == NDB_ARRAYTYPE_FIXED)
+      byteSizes = bytes;
+    else
+    {
+      if (defValueBytes)
+      {
+        byteSizes = defValueBytes;
+      }
+      else if (!nullable)
+      {
+        if (array == NDB_ARRAYTYPE_SHORT_VAR) 
+          byteSizes = 1;
+        else if (array == NDB_ARRAYTYPE_MEDIUM_VAR)
+          byteSizes = 2;
+      }
+    }
+  }
+  else 
+  {
+    words = (arraySize + AD_SIZE_IN_WORDS_OFFSET)
+                              >> AD_SIZE_IN_WORDS_SHIFT;
+    bytes = words * 4;
+    byteSizes = bytes;
+  }
+
+  if (nullable && !defValueBytes)
+    byteSizes = 0;
+
+  AttributeHeader ah(attrId, byteSizes);
+
+  SegmentedSectionPtr ptr;
+  handle.getSection(ptr, TupAddAttrReq::DEFAULT_VALUES);
+  SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
+  r.reset();
+
+  Uint32 remainingLen = defValueWords;
+  Uint32 *dst = NULL;
+  cinBuffer[regTabPtr.p->m_createTable.receivedWords] = ah.m_value;
+  regTabPtr.p->m_createTable.receivedWords++;
+
+  dst = cinBuffer + regTabPtr.p->m_createTable.receivedWords;
+
+  if (remainingLen)
+  {
+    if (r.getWords(dst, remainingLen))
+    {
+      regTabPtr.p->m_createTable.receivedWords += remainingLen;
+      remainingLen = 0;
+    }
+    else
+    {
+      jam();
+      ndbrequire(false);
+    }
+  }
+
+  releaseSections(handle);
+
+
+  Uint32 dynamic = AttributeDescriptor::getDynamic(attrDescriptor);
+  Uint32 theAttrWords = defValueWords;
+
+/*
+  if ((nullable) && (defValueBytes == 0))
+  {
+    regTabPtr.p->m_createTable.totalDefWords += 1; //only one AttributeHeader
+    return;
+  }
+*/
+
+//  if (!dynamic && (array == NDB_ARRAYTYPE_FIXED) && (attrLen != 0))
+  if (array == NDB_ARRAYTYPE_FIXED)
+  {
+    theAttrWords = words;
+    if (defValueWords < words)
+    {
+      remainingLen = words - defValueWords;
+      if (remainingLen)
+      {
+        dst = cinBuffer + regTabPtr.p->m_createTable.receivedWords;
+
+        memset(dst, 0, remainingLen * 4);
+        regTabPtr.p->m_createTable.receivedWords += remainingLen;
+        remainingLen = 0;
+      }
+    }
+  }
+  regTabPtr.p->m_createTable.totalDefWords += theAttrWords + 1;
+}
+
 void Dbtup::execTUPFRAGREQ(Signal* signal)
 {
   jamEntry();
@@ -530,6 +654,15 @@ void Dbtup::execTUPFRAGREQ(Signal* signa
     regFragPtr.p->fragStatus = Fragrecord::FS_REORG_NEW;
   }
 
+
+  if (fragId == 0)
+  {
+    if (store_default_record(regTabPtr) < 0)
+    {
+      ndbrequire(false);
+      goto sendref;
+    }
+  }
   signal->theData[0]= userptr;
   signal->theData[1]= fragId;
   signal->theData[2]= regFragPtr.i;
@@ -538,12 +671,50 @@ void Dbtup::execTUPFRAGREQ(Signal* signa
   return;
 
 sendref:
-
   signal->theData[0]= userptr;
   signal->theData[1]= terrorCode;
   sendSignal(userRef, GSN_TUPFRAGREF, signal, 2, JBB);
 }
 
+int Dbtup::store_default_record(const TablerecPtr& regTabPtr)
+{
+  FragrecordPtr regFragPtr;
+
+  Uint32 RnoOfFragrec= cnoOfFragrec;
+  Uint32 RnoOfTablerec= cnoOfTablerec;
+  jamEntry();
+
+
+  Uint32 sizes = regTabPtr.p->m_createTable.totalDefWords;
+
+  /**
+   * Alloc memory
+   */
+
+  if (unlikely(alloc_var_part(DefaultValuesFragment.p, 
+                              regTabPtr.p, 
+                              sizes, 
+                              &regTabPtr.p->m_default_value_location) == 0))
+  {
+    goto mem_error;
+  }
+ 
+  Var_part_ref ref;
+  ref.assign(&regTabPtr.p->m_default_value_location);
+  PagePtr page;
+  Uint32 *dst = get_ptr(&page, ref);
+
+  memcpy(dst, &cinBuffer[0], regTabPtr.p->m_createTable.totalDefWords * 4);
+  
+  return 0;
+
+mem_error:
+  jam();
+  terrorCode= ZMEM_NOMEM_ERROR;
+  return -1;
+}
+
+
 bool Dbtup::addfragtotab(Tablerec* const regTabPtr,
                          Uint32 fragId,
                          Uint32 fragIndex)
@@ -1862,6 +2033,7 @@ 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);
   initTab(tabPtr.p);
 }
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2008-10-10 09:32:12 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2008-11-05 15:54:58 +0000
@@ -1561,7 +1561,8 @@ Dbtup::readDiskBitsNULLable(Uint8* outBu
 /* ---------------------------------------------------------------------- */
 int Dbtup::updateAttributes(KeyReqStruct *req_struct,
                             Uint32* inBuffer,
-                            Uint32 inBufLen)
+                            Uint32 inBufLen,
+                            bool insertDefaultValue)
 {
   Tablerec* const regTabPtr=  tabptr.p;
   Operationrec* const regOperPtr= operPtr.p;
@@ -1569,6 +1570,51 @@ int Dbtup::updateAttributes(KeyReqStruct
   TableDescriptor *attr_descr= req_struct->attr_descr;
 
   Uint32 inBufIndex= 0;
+
+  if (!insertDefaultValue)
+    goto skipInsertDefault;
+
+  req_struct->in_buf_index= 0;
+  req_struct->in_buf_len= regTabPtr->m_createTable.totalDefWords;
+
+  Var_part_ref ref;
+  ref.assign(&regTabPtr->m_default_value_location);
+  PagePtr page;
+  Uint32 *defData = get_ptr(&page, ref);
+  while (inBufIndex < regTabPtr->m_createTable.totalDefWords) {
+    AttributeHeader ahIn(defData[inBufIndex]);
+    Uint32 attributeId= ahIn.getAttributeId();
+    Uint32 attrDescriptorIndex= attributeId << ZAD_LOG_SIZE;
+    if (likely(attributeId < numAttributes)) {
+      Uint32 attrDescriptor= attr_descr[attrDescriptorIndex].tabDescr;
+      Uint32 attributeOffset= attr_descr[attrDescriptorIndex + 1].tabDescr;
+      if ((AttributeDescriptor::getPrimaryKey(attrDescriptor)) &&
+          (regOperPtr->op_struct.op_type != ZINSERT)) {
+        req_struct->in_buf_index += 1;
+        req_struct->in_buf_index += ahIn.getDataSize();
+        inBufIndex= req_struct->in_buf_index;
+        continue;
+      } 
+
+      UpdateFunction f= regTabPtr->updateFunctionArray[attributeId];
+      jam();
+      req_struct->attr_descriptor= attrDescriptor;
+      req_struct->changeMask.set(attributeId);
+      if ((this->*f)(defData,
+                     req_struct,
+                     attributeOffset)) {
+       inBufIndex= req_struct->in_buf_index;
+        continue;
+      } else {
+        jam();
+        return -1;
+      }
+    }
+  }
+
+skipInsertDefault:
+
+  inBufIndex= 0;
   req_struct->in_buf_index= 0;
   req_struct->in_buf_len= inBufLen;
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp	2008-01-11 11:04:51 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp	2008-11-05 15:54:58 +0000
@@ -132,6 +132,33 @@ Dbtup::alloc_var_part(Fragrecord* fragPt
   return ((Var_page*)pagePtr.p)->get_ptr(idx);
 }
 
+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
@@ -288,6 +315,7 @@ Dbtup::move_var_part(Fragrecord* fragPtr
        * the page is the desition where old varpart move to
        */
       new_pagePtr.i = fragPtr->free_var_page_array[i].firstItem;
+      break; 
     }
   }
  

=== modified file 'storage/ndb/src/ndbapi/NdbDictionary.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp	2008-06-02 13:27:27 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp	2008-11-05 15:54:58 +0000
@@ -346,9 +346,17 @@ NdbDictionary::Column::setDefaultValue(c
   return !m_impl.m_defaultValue.assign(defaultValue);
 }
 
+int
+NdbDictionary::Column::setDefaultValue(const char* defaultValue, size_t n)
+{
+  return !m_impl.m_defaultValue.assign(defaultValue, n);
+}
+
 const char*
-NdbDictionary::Column::getDefaultValue() const
+NdbDictionary::Column::getDefaultValue(size_t* len) const
 {
+  if (!len)
+    *len = m_impl.m_defaultValue.length();
   return m_impl.m_defaultValue.c_str();
 }
 

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2008-10-10 09:32:12 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2008-11-05 15:54:58 +0000
@@ -2638,13 +2638,13 @@ 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))
+    if (!col->m_defaultValue.assign(attrDesc.AttributeDefaultValue, attrDesc.AttributeDefaultValueLen))
     {
       delete col;
       delete impl;
       DBUG_RETURN(4000);
     }
-
+ 
     col->m_column_no = impl->m_columns.size();
     impl->m_columns.push_back(col);
     it.next();
@@ -3301,9 +3301,12 @@ loop:
     }
 
     tmpAttr.AttributeAutoIncrement = col->m_autoIncrement;
-    BaseString::snprintf(tmpAttr.AttributeDefaultValue, 
-                         sizeof(tmpAttr.AttributeDefaultValue),
-                         "%s", col->m_defaultValue.c_str());
+    {
+      tmpAttr.AttributeDefaultValueLen = col->m_defaultValue.length(); 
+
+      memcpy(tmpAttr.AttributeDefaultValue, col->m_defaultValue.c_str(),
+             tmpAttr.AttributeDefaultValueLen);
+    } 
     s = SimpleProperties::pack(w, 
 			       &tmpAttr,
 			       DictTabInfo::AttributeMapping, 

Thread
bzr commit into mysql-5.1 branch (gni:2999) WL#4197Guangbao Ni5 Nov