#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,
+ ®TabPtr.p->m_default_value_location) == 0))
+ {
+ goto mem_error;
+ }
+
+ Var_part_ref ref;
+ ref.assign(®TabPtr.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(®TabPtr->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#4197 | Guangbao Ni | 5 Nov |