List:Commits« Previous MessageNext Message »
From:tomas Date:May 15 2007 9:54am
Subject:bk commit into 5.1 tree (tomas:1.2522)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tomas. When tomas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-05-15 09:54:42+02:00, tomas@stripped +3 -0
  Merge whalegate.ndb.mysql.com:/home/tomas/mysql-5.0-ndb
  into  whalegate.ndb.mysql.com:/home/tomas/mysql-5.1-single-user
  MERGE: 1.1810.2870.46

  storage/ndb/include/mgmapi/ndbd_exit_codes.h@stripped, 2007-05-15 09:54:39+02:00, tomas@stripped +1 -2
    manual merge
    MERGE: 1.2.7.2

  storage/ndb/include/mgmapi/ndbd_exit_codes.h@stripped, 2007-05-15 09:47:50+02:00, tomas@stripped +0 -0
    Merge rename: ndb/include/mgmapi/ndbd_exit_codes.h -> storage/ndb/include/mgmapi/ndbd_exit_codes.h

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2007-05-15 09:54:39+02:00, tomas@stripped +0 -1
    manual merge
    MERGE: 1.40.53.2

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2007-05-15 09:47:50+02:00, tomas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/dbdict/Dbdict.cpp -> storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp

  storage/ndb/src/kernel/error/ndbd_exit_codes.c@stripped, 2007-05-15 09:47:50+02:00, tomas@stripped +0 -1
    Auto merged
    MERGE: 1.1.10.2

  storage/ndb/src/kernel/error/ndbd_exit_codes.c@stripped, 2007-05-15 09:47:50+02:00, tomas@stripped +0 -0
    Merge rename: ndb/src/kernel/error/ndbd_exit_codes.c -> storage/ndb/src/kernel/error/ndbd_exit_codes.c

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tomas
# Host:	whalegate.ndb.mysql.com
# Root:	/home/tomas/mysql-5.1-single-user/RESYNC

--- 1.40.53.1/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-05-15 09:02:58 +02:00
+++ 1.133/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-05-15 09:54:39 +02:00
@@ -18,6 +18,7 @@
 
 #define DBDICT_C
 #include "Dbdict.hpp"
+#include "diskpage.hpp"
 
 #include <ndb_limits.h>
 #include <NdbOut.hpp>
@@ -54,13 +55,15 @@
 #include <signaldata/DropIndx.hpp>
 #include <signaldata/BuildIndx.hpp>
 
+#include <signaldata/DropFilegroup.hpp>
+#include <signaldata/CreateFilegroup.hpp>
+#include <signaldata/CreateFilegroupImpl.hpp>
+
 #include <signaldata/CreateEvnt.hpp>
 #include <signaldata/UtilPrepare.hpp>
 #include <signaldata/UtilExecute.hpp>
 #include <signaldata/UtilRelease.hpp>
 #include <signaldata/SumaImpl.hpp> 
-#include <GrepError.hpp>
-//#include <signaldata/DropEvnt.hpp>
 
 #include <signaldata/LqhFrag.hpp>
 
@@ -79,6 +82,10 @@
 #include <NdbSleep.h>
 #include <signaldata/ApiBroadcast.hpp>
 
+#include <signaldata/DropObj.hpp>
+#include <signaldata/CreateObj.hpp>
+#include <SLList.hpp>
+
 #define ZNOT_FOUND 626
 #define ZALREADYEXIST 630
 
@@ -86,29 +93,122 @@
 //#define EVENT_PH3_DEBUG
 //#define EVENT_DEBUG
 
+static const char EVENT_SYSTEM_TABLE_NAME[] = "sys/def/NDB$EVENTS_0";
+
 #define EVENT_TRACE \
 //  ndbout_c("Event debug trace: File: %s Line: %u", __FILE__, __LINE__)
 
 #define DIV(x,y) (((x)+(y)-1)/(y))
+#define WORDS2PAGES(x) DIV(x, (ZSIZE_OF_PAGES_IN_WORDS - ZPAGE_HEADER_SIZE))
 #include <ndb_version.h>
 
 static
+struct {
+  Uint32 m_gsn_user_req;
+  Uint32 m_gsn_req;
+  Uint32 m_gsn_ref;
+  Uint32 m_gsn_conf;
+  void (Dbdict::* m_trans_commit_start)(Signal*, Dbdict::SchemaTransaction*);
+  void (Dbdict::* m_trans_commit_complete)(Signal*,Dbdict::SchemaTransaction*);
+  void (Dbdict::* m_trans_abort_start)(Signal*, Dbdict::SchemaTransaction*);
+  void (Dbdict::* m_trans_abort_complete)(Signal*, Dbdict::SchemaTransaction*);
+
+  void (Dbdict::* m_prepare_start)(Signal*, Dbdict::SchemaOp*);
+  void (Dbdict::* m_prepare_complete)(Signal*, Dbdict::SchemaOp*);
+  void (Dbdict::* m_commit)(Signal*, Dbdict::SchemaOp*);
+  void (Dbdict::* m_commit_start)(Signal*, Dbdict::SchemaOp*);
+  void (Dbdict::* m_commit_complete)(Signal*, Dbdict::SchemaOp*);
+  void (Dbdict::* m_abort)(Signal*, Dbdict::SchemaOp*);
+  void (Dbdict::* m_abort_start)(Signal*, Dbdict::SchemaOp*);
+  void (Dbdict::* m_abort_complete)(Signal*, Dbdict::SchemaOp*);
+  
+} f_dict_op[] = {
+  /**
+   * Create filegroup
+   */
+  { 
+    GSN_CREATE_FILEGROUP_REQ,
+    GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
+    0, 0, 0, 0,
+    &Dbdict::create_fg_prepare_start, &Dbdict::create_fg_prepare_complete,
+    &Dbdict::createObj_commit,
+    0, 0,
+    &Dbdict::createObj_abort,
+    &Dbdict::create_fg_abort_start, &Dbdict::create_fg_abort_complete,
+  }
+
+  /**
+   * Create file
+   */
+  ,{ 
+    GSN_CREATE_FILE_REQ,
+    GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
+    0, 0, 0, 0,
+    &Dbdict::create_file_prepare_start, &Dbdict::create_file_prepare_complete,
+    &Dbdict::createObj_commit,
+    &Dbdict::create_file_commit_start, 0,
+    &Dbdict::createObj_abort,
+    &Dbdict::create_file_abort_start, &Dbdict::create_file_abort_complete,
+  }
+
+  /**
+   * Drop file
+   */
+  ,{ 
+    GSN_DROP_FILE_REQ,
+    GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
+    0, 0, 0, 0,
+    &Dbdict::drop_file_prepare_start, 0,
+    &Dbdict::dropObj_commit,
+    &Dbdict::drop_file_commit_start, &Dbdict::drop_file_commit_complete,
+    &Dbdict::dropObj_abort,
+    &Dbdict::drop_file_abort_start, 0
+  }
+
+  /**
+   * Drop filegroup
+   */
+  ,{ 
+    GSN_DROP_FILEGROUP_REQ,
+    GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
+    0, 0, 0, 0,
+    &Dbdict::drop_fg_prepare_start, 0,
+    &Dbdict::dropObj_commit,
+    &Dbdict::drop_fg_commit_start, &Dbdict::drop_fg_commit_complete,
+    &Dbdict::dropObj_abort,
+    &Dbdict::drop_fg_abort_start, 0
+  }
+
+  /**
+   * Drop undofile
+   */
+  ,{ 
+    GSN_DROP_FILE_REQ,
+    GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
+    0, 0, 0, 0,
+    &Dbdict::drop_undofile_prepare_start, 0,
+    0,
+    0, 0,
+    0, 0, 0
+  }
+};
+
 Uint32
-alter_table_inc_schema_version(Uint32 old)
+alter_obj_inc_schema_version(Uint32 old)
 {
    return (old & 0x00FFFFFF) + ((old + 0x1000000) & 0xFF000000);
 }
 
 static
 Uint32
-alter_table_dec_schema_version(Uint32 old)
+alter_obj_dec_schema_version(Uint32 old)
 {
   return (old & 0x00FFFFFF) + ((old - 0x1000000) & 0xFF000000);
 }
 
 static
 Uint32
-create_table_inc_schema_version(Uint32 old)
+create_obj_inc_schema_version(Uint32 old)
 {
   return (old + 0x00000001) & 0x00FFFFFF;
 }
@@ -178,6 +278,25 @@
 	       DropTableReq::SignalLength, JBB);
   }
 #endif  
+#define MEMINFO(x, y) infoEvent(x ": %d %d", y.getSize(), y.getNoOfFree())
+  if(signal->theData[0] == 1226){
+    MEMINFO("c_obj_pool", c_obj_pool);
+    MEMINFO("c_opRecordPool", c_opRecordPool);
+    MEMINFO("c_rope_pool", c_rope_pool);
+  }
+
+  if (signal->theData[0] == 1227)
+  {
+    DLHashTable<DictObject>::Iterator iter;
+    bool ok = c_obj_hash.first(iter);
+    for(; ok; ok = c_obj_hash.next(iter))
+    {
+      Rope name(c_rope_pool, iter.curr.p->m_name);
+      char buf[1024];
+      name.copy(buf);
+      ndbout_c("%s m_ref_count: %d", buf, iter.curr.p->m_ref_count); 
+    }
+  }    
   
   return;
 }//Dbdict::execDUMP_STATE_ORD()
@@ -194,7 +313,7 @@
   switch (signal->theData[0]) {
   case ZPACK_TABLE_INTO_PAGES :
     jam();
-    packTableIntoPages(signal, signal->theData[1], signal->theData[2]);
+    packTableIntoPages(signal);
     break;
 
   case ZSEND_GET_TAB_RESPONSE :
@@ -220,32 +339,69 @@
 /* ---------------------------------------------------------------- */
 /* ---------------------------------------------------------------- */
 
-void Dbdict::packTableIntoPages(Signal* signal, Uint32 tableId, Uint32 pageId)
+void Dbdict::packTableIntoPages(Signal* signal)
 {
+  const Uint32 tableId= signal->theData[1];
+  const Uint32 type= signal->theData[2];
+  const Uint32 pageId= signal->theData[3];
 
   PageRecordPtr pagePtr;
-  TableRecordPtr tablePtr;
   c_pageRecordArray.getPtr(pagePtr, pageId);
-  
+
   memset(&pagePtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
-  c_tableRecordPool.getPtr(tablePtr, tableId);
   LinearWriter w(&pagePtr.p->word[ZPAGE_HEADER_SIZE], 
-		 8 * ZSIZE_OF_PAGES_IN_WORDS);
-
+		 ZMAX_PAGES_OF_TABLE_DEFINITION * ZSIZE_OF_PAGES_IN_WORDS);
   w.first();
-  packTableIntoPagesImpl(w, tablePtr, signal);
-    
+  switch((DictTabInfo::TableType)type) {
+  case DictTabInfo::SystemTable:
+  case DictTabInfo::UserTable:
+  case DictTabInfo::UniqueHashIndex:
+  case DictTabInfo::HashIndex:
+  case DictTabInfo::UniqueOrderedIndex:
+  case DictTabInfo::OrderedIndex:{
+    jam();
+    TableRecordPtr tablePtr;
+    c_tableRecordPool.getPtr(tablePtr, tableId);
+    packTableIntoPages(w, tablePtr, signal);
+    break;
+  }
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:{
+    FilegroupPtr fg_ptr;
+    ndbrequire(c_filegroup_hash.find(fg_ptr, tableId));
+    const Uint32 free_hi= signal->theData[4];
+    const Uint32 free_lo= signal->theData[5];
+    packFilegroupIntoPages(w, fg_ptr, free_hi, free_lo);
+    break;
+  }
+  case DictTabInfo::Datafile:{
+    FilePtr fg_ptr;
+    ndbrequire(c_file_hash.find(fg_ptr, tableId));
+    const Uint32 free_extents= signal->theData[4];
+    packFileIntoPages(w, fg_ptr, free_extents);
+    break;
+  }
+  case DictTabInfo::Undofile:{
+    FilePtr fg_ptr;
+    ndbrequire(c_file_hash.find(fg_ptr, tableId));
+    packFileIntoPages(w, fg_ptr, 0);
+    break;
+  }
+  case DictTabInfo::UndefTableType:
+  case DictTabInfo::HashIndexTrigger:
+  case DictTabInfo::SubscriptionTrigger:
+  case DictTabInfo::ReadOnlyConstraint:
+  case DictTabInfo::IndexTrigger:
+    ndbrequire(false);
+  }
+  
   Uint32 wordsOfTable = w.getWordsUsed();
-  Uint32 pagesUsed = 
-    DIV(wordsOfTable + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
+  Uint32 pagesUsed = WORDS2PAGES(wordsOfTable);
   pagePtr.p->word[ZPOS_CHECKSUM] = 
     computeChecksum(&pagePtr.p->word[0], pagesUsed * ZSIZE_OF_PAGES_IN_WORDS);
   
   switch (c_packTable.m_state) {
   case PackTable::PTS_IDLE:
-  case PackTable::PTS_ADD_TABLE_MASTER:
-  case PackTable::PTS_ADD_TABLE_SLAVE:
-  case PackTable::PTS_RESTART:
     ndbrequire(false);
     break;
   case PackTable::PTS_GET_TAB:
@@ -261,17 +417,23 @@
 }//packTableIntoPages()
 
 void
-Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w,
+Dbdict::packTableIntoPages(SimpleProperties::Writer & w,
 			       TableRecordPtr tablePtr,
 			       Signal* signal){
   
-  w.add(DictTabInfo::TableName, tablePtr.p->tableName);
+  union {
+    char tableName[MAX_TAB_NAME_SIZE];
+    char frmData[MAX_FRM_DATA_SIZE];
+    char rangeData[16*MAX_NDB_PARTITIONS];
+    char ngData[2*MAX_NDB_PARTITIONS];
+    char tsData[2*2*MAX_NDB_PARTITIONS];
+    char defaultValue[MAX_ATTR_DEFAULT_VALUE_SIZE];
+    char attributeName[MAX_ATTR_NAME_SIZE];
+  };
+  ConstRope r(c_rope_pool, tablePtr.p->tableName);
+  r.copy(tableName);
+  w.add(DictTabInfo::TableName, tableName);
   w.add(DictTabInfo::TableId, tablePtr.i);
-#ifdef HAVE_TABLE_REORG
-  w.add(DictTabInfo::SecondTableId, tablePtr.p->secondTable);
-#else
-  w.add(DictTabInfo::SecondTableId, (Uint32)0);
-#endif
   w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion);
   w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey);
   w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes);
@@ -279,7 +441,17 @@
   w.add(DictTabInfo::NoOfVariable, (Uint32)0);
   w.add(DictTabInfo::KeyLength, tablePtr.p->tupKeyLength);
   
-  w.add(DictTabInfo::TableLoggedFlag, tablePtr.p->storedTable);
+  w.add(DictTabInfo::TableLoggedFlag, 
+	!!(tablePtr.p->m_bits & TableRecord::TR_Logged));
+  w.add(DictTabInfo::RowGCIFlag, 
+	!!(tablePtr.p->m_bits & TableRecord::TR_RowGCI));
+  w.add(DictTabInfo::RowChecksumFlag, 
+	!!(tablePtr.p->m_bits & TableRecord::TR_RowChecksum));
+  w.add(DictTabInfo::TableTemporaryFlag, 
+	!!(tablePtr.p->m_bits & TableRecord::TR_Temporary));
+  w.add(DictTabInfo::ForceVarPartFlag,
+	!!(tablePtr.p->m_bits & TableRecord::TR_ForceVarPart));
+  
   w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor);
   w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor);
   w.add(DictTabInfo::TableKValue, tablePtr.p->kValue);
@@ -287,38 +459,46 @@
   w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType);
   w.add(DictTabInfo::MaxRowsLow, tablePtr.p->maxRowsLow);
   w.add(DictTabInfo::MaxRowsHigh, tablePtr.p->maxRowsHigh);
+  w.add(DictTabInfo::DefaultNoPartFlag, tablePtr.p->defaultNoPartFlag);
+  w.add(DictTabInfo::LinearHashFlag, tablePtr.p->linearHashFlag);
+  w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount);
   w.add(DictTabInfo::MinRowsLow, tablePtr.p->minRowsLow);
   w.add(DictTabInfo::MinRowsHigh, tablePtr.p->minRowsHigh);
   w.add(DictTabInfo::SingleUserMode, tablePtr.p->singleUserMode);
-  if(!signal)
-  {
-    w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount);
-  }
-  else
+
+  if(signal)
   {
+    /* Denna branch körs vid GET_TABINFOREQ */
+
     Uint32 * theData = signal->getDataPtrSend();
     CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
     req->senderRef = 0;
     req->senderData = RNIL;
     req->fragmentationType = tablePtr.p->fragmentType;
     req->noOfFragments = 0;
-    req->fragmentNode = 0;
     req->primaryTableId = tablePtr.i;
     EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
 		   CreateFragmentationReq::SignalLength);
-    if(signal->theData[0] == 0)
-    {
-      Uint16 *data = (Uint16*)&signal->theData[25];
-      Uint32 count = 2 + data[0] * data[1];
-      w.add(DictTabInfo::FragmentDataLen, 2*count);
-      w.add(DictTabInfo::FragmentData, data, 2*count);
-    }
+    ndbrequire(signal->theData[0] == 0);
+    Uint16 *data = (Uint16*)&signal->theData[25];
+    Uint32 count = 2 + (1 + data[0]) * data[1];
+    w.add(DictTabInfo::ReplicaDataLen, 2*count);
+    for (Uint32 i = 0; i < count; i++)
+      data[i] = htons(data[i]);
+    w.add(DictTabInfo::ReplicaData, data, 2*count);
+  }
+  else
+  {
+    /* Denna del körs vid CREATE_TABLEREQ, ALTER_TABLEREQ */
+    ;
   }
   
   if (tablePtr.p->primaryTableId != RNIL){
     TableRecordPtr primTab;
     c_tableRecordPool.getPtr(primTab, tablePtr.p->primaryTableId);
-    w.add(DictTabInfo::PrimaryTable, primTab.p->tableName);
+    ConstRope r2(c_rope_pool, primTab.p->tableName);
+    r2.copy(tableName);
+    w.add(DictTabInfo::PrimaryTable, tableName);
     w.add(DictTabInfo::PrimaryTableId, tablePtr.p->primaryTableId);
     w.add(DictTabInfo::IndexState, tablePtr.p->indexState);
     w.add(DictTabInfo::InsertTriggerId, tablePtr.p->insertTriggerId);
@@ -326,16 +506,48 @@
     w.add(DictTabInfo::DeleteTriggerId, tablePtr.p->deleteTriggerId);
     w.add(DictTabInfo::CustomTriggerId, tablePtr.p->customTriggerId);
   }
-  w.add(DictTabInfo::FrmLen, tablePtr.p->frmLen);
-  w.add(DictTabInfo::FrmData, tablePtr.p->frmData, tablePtr.p->frmLen);
-  
-  Uint32 nextAttribute = tablePtr.p->firstAttribute;
+
+  ConstRope frm(c_rope_pool, tablePtr.p->frmData);
+  frm.copy(frmData);
+  w.add(DictTabInfo::FrmLen, frm.size());
+  w.add(DictTabInfo::FrmData, frmData, frm.size());
+
+  {
+    jam();
+    ConstRope ts(c_rope_pool, tablePtr.p->tsData);
+    ts.copy(tsData);
+    w.add(DictTabInfo::TablespaceDataLen, ts.size());
+    w.add(DictTabInfo::TablespaceData, tsData, ts.size());
+
+    ConstRope ng(c_rope_pool, tablePtr.p->ngData);
+    ng.copy(ngData);
+    w.add(DictTabInfo::FragmentDataLen, ng.size());
+    w.add(DictTabInfo::FragmentData, ngData, ng.size());
+
+    ConstRope range(c_rope_pool, tablePtr.p->rangeData);
+    range.copy(rangeData);
+    w.add(DictTabInfo::RangeListDataLen, range.size());
+    w.add(DictTabInfo::RangeListData, rangeData, range.size());
+  }
+
+  if(tablePtr.p->m_tablespace_id != RNIL)
+  {
+    w.add(DictTabInfo::TablespaceId, tablePtr.p->m_tablespace_id);
+    FilegroupPtr tsPtr;
+    ndbrequire(c_filegroup_hash.find(tsPtr, tablePtr.p->m_tablespace_id));
+    w.add(DictTabInfo::TablespaceVersion, tsPtr.p->m_version);
+  }
+
   AttributeRecordPtr attrPtr;
-  do {
+  LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool, 
+				    tablePtr.p->m_attributes);
+  for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)){
     jam();
-    c_attributeRecordPool.getPtr(attrPtr, nextAttribute);
-    
-    w.add(DictTabInfo::AttributeName, attrPtr.p->attributeName);
+
+    ConstRope name(c_rope_pool, attrPtr.p->attributeName);
+    name.copy(attributeName);
+
+    w.add(DictTabInfo::AttributeName, attributeName);
     w.add(DictTabInfo::AttributeId, attrPtr.p->attributeId);
     w.add(DictTabInfo::AttributeKeyFlag, attrPtr.p->tupleKey > 0);
     
@@ -343,12 +555,16 @@
     const Uint32 attrType = AttributeDescriptor::getType(desc);
     const Uint32 attrSize = AttributeDescriptor::getSize(desc);
     const Uint32 arraySize = AttributeDescriptor::getArraySize(desc);
+    const Uint32 arrayType = AttributeDescriptor::getArrayType(desc);
     const Uint32 nullable = AttributeDescriptor::getNullable(desc);
     const Uint32 DKey = AttributeDescriptor::getDKey(desc);
+    const Uint32 disk= AttributeDescriptor::getDiskBased(desc);
+    
 
     // AttributeType deprecated
     w.add(DictTabInfo::AttributeSize, attrSize);
     w.add(DictTabInfo::AttributeArraySize, arraySize);
+    w.add(DictTabInfo::AttributeArrayType, arrayType);
     w.add(DictTabInfo::AttributeNullableFlag, nullable);
     w.add(DictTabInfo::AttributeDKey, DKey);
     w.add(DictTabInfo::AttributeExtType, attrType);
@@ -357,15 +573,93 @@
     w.add(DictTabInfo::AttributeExtLength, attrPtr.p->extLength);
     w.add(DictTabInfo::AttributeAutoIncrement, 
 	  (Uint32)attrPtr.p->autoIncrement);
-    w.add(DictTabInfo::AttributeDefaultValue, attrPtr.p->defaultValue);
+
+    if(disk)
+      w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_DISK);
+    else
+      w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_MEMORY);
+    
+    ConstRope def(c_rope_pool, attrPtr.p->defaultValue);
+    def.copy(defaultValue);
+    w.add(DictTabInfo::AttributeDefaultValue, defaultValue);
     
     w.add(DictTabInfo::AttributeEnd, 1);
-    nextAttribute = attrPtr.p->nextAttrInTable;
-  } while (nextAttribute != RNIL);
+  }
   
   w.add(DictTabInfo::TableEnd, 1);
 }
 
+void
+Dbdict::packFilegroupIntoPages(SimpleProperties::Writer & w,
+			       FilegroupPtr fg_ptr,
+			       const Uint32 undo_free_hi,
+			       const Uint32 undo_free_lo){
+  
+  DictFilegroupInfo::Filegroup fg; fg.init();
+  ConstRope r(c_rope_pool, fg_ptr.p->m_name);
+  r.copy(fg.FilegroupName);
+
+  fg.FilegroupId = fg_ptr.p->key;
+  fg.FilegroupType = fg_ptr.p->m_type;
+  fg.FilegroupVersion = fg_ptr.p->m_version;
+
+  switch(fg.FilegroupType){
+  case DictTabInfo::Tablespace:
+    //fg.TS_DataGrow = group.m_grow_spec;
+    fg.TS_ExtentSize = fg_ptr.p->m_tablespace.m_extent_size;
+    fg.TS_LogfileGroupId = fg_ptr.p->m_tablespace.m_default_logfile_group_id;
+    FilegroupPtr lfg_ptr;
+    ndbrequire(c_filegroup_hash.find(lfg_ptr, fg.TS_LogfileGroupId));
+    fg.TS_LogfileGroupVersion = lfg_ptr.p->m_version;
+    break;
+  case DictTabInfo::LogfileGroup:
+    fg.LF_UndoBufferSize = fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
+    fg.LF_UndoFreeWordsHi= undo_free_hi;
+    fg.LF_UndoFreeWordsLo= undo_free_lo;
+    //fg.LF_UndoGrow = ;
+    break;
+  default:
+    ndbrequire(false);
+  }
+  
+  SimpleProperties::UnpackStatus s;
+  s = SimpleProperties::pack(w, 
+			     &fg,
+			     DictFilegroupInfo::Mapping, 
+			     DictFilegroupInfo::MappingSize, true);
+  
+  ndbrequire(s == SimpleProperties::Eof);
+}
+
+void
+Dbdict::packFileIntoPages(SimpleProperties::Writer & w,
+			  FilePtr f_ptr, const Uint32 free_extents){
+  
+  DictFilegroupInfo::File f; f.init();
+  ConstRope r(c_rope_pool, f_ptr.p->m_path);
+  r.copy(f.FileName);
+
+  f.FileType = f_ptr.p->m_type;
+  f.FilegroupId = f_ptr.p->m_filegroup_id;; //group.m_id;
+  f.FileSizeHi = (f_ptr.p->m_file_size >> 32);
+  f.FileSizeLo = (f_ptr.p->m_file_size & 0xFFFFFFFF);
+  f.FileFreeExtents= free_extents;
+  f.FileId =  f_ptr.p->key;
+  f.FileVersion = f_ptr.p->m_version;
+
+  FilegroupPtr lfg_ptr;
+  ndbrequire(c_filegroup_hash.find(lfg_ptr, f.FilegroupId));
+  f.FilegroupVersion = lfg_ptr.p->m_version;
+
+  SimpleProperties::UnpackStatus s;
+  s = SimpleProperties::pack(w, 
+			     &f,
+			     DictFilegroupInfo::FileMapping, 
+			     DictFilegroupInfo::FileMappingSize, true);
+  
+  ndbrequire(s == SimpleProperties::Eof);
+}
+
 /* ---------------------------------------------------------------- */
 /* ---------------------------------------------------------------- */
 // The routines to handle responses from file system.
@@ -575,15 +869,14 @@
   
   ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
   
-  Uint32 sz = tabInfoPtr.sz + ZPAGE_HEADER_SIZE;
-
-  c_writeTableRecord.noOfPages = DIV(sz, ZSIZE_OF_PAGES_IN_WORDS);
+  Uint32 pages = WORDS2PAGES(tabInfoPtr.sz);
+  c_writeTableRecord.no_of_words = tabInfoPtr.sz;
   c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
   c_writeTableRecord.m_callback = * callback;
 
   c_writeTableRecord.pageId = 0;
-  ndbrequire(c_writeTableRecord.noOfPages < 8);
-
+  ndbrequire(pages == 1);
+  
   PageRecordPtr pageRecPtr;
   c_pageRecordArray.getPtr(pageRecPtr, c_writeTableRecord.pageId);
   copy(&pageRecPtr.p->word[ZPAGE_HEADER_SIZE], tabInfoPtr);
@@ -591,10 +884,9 @@
   memset(&pageRecPtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
   pageRecPtr.p->word[ZPOS_CHECKSUM] = 
     computeChecksum(&pageRecPtr.p->word[0], 
-		    c_writeTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS);
+		    pages * ZSIZE_OF_PAGES_IN_WORDS);
   
   startWriteTableFile(signal, tableId);
-
 }
 
 void Dbdict::startWriteTableFile(Signal* signal, Uint32 tableId)
@@ -613,9 +905,7 @@
                            Uint32 tableId,
                            bool   writeFlag) 
 {
-  TableRecordPtr tablePtr;
   FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
-  c_tableRecordPool.getPtr(tablePtr, tableId);
 
   fsOpenReq->userReference = reference();
   fsOpenReq->userPointer = fsConPtr;
@@ -630,14 +920,13 @@
     jam();
     fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
   }//if
-
   fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
   FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
   FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_TABLELIST);
   FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
   FsOpenReq::v1_setTable(fsOpenReq->fileNumber, tableId);
   FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
-  FsOpenReq::v1_setS(fsOpenReq->fileNumber, tablePtr.p->tableVersion);
+  FsOpenReq::v1_setS(fsOpenReq->fileNumber, 0);
   FsOpenReq::v1_setP(fsOpenReq->fileNumber, 255);
 /* ---------------------------------------------------------------- */
 // File name : D1/DBDICT/T0/S1.TableList
@@ -661,7 +950,7 @@
   FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 
                                 FsReadWriteReq::fsFormatArrayOfPages);
   fsRWReq->varIndex = ZBAT_TABLE_FILE;
-  fsRWReq->numberOfPages = c_writeTableRecord.noOfPages;
+  fsRWReq->numberOfPages = WORDS2PAGES(c_writeTableRecord.no_of_words);
   fsRWReq->data.arrayOfPages.varIndex = c_writeTableRecord.pageId;
   fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
@@ -738,7 +1027,7 @@
   FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 
                                 FsReadWriteReq::fsFormatArrayOfPages);
   fsRWReq->varIndex = ZBAT_TABLE_FILE;
-  fsRWReq->numberOfPages = c_readTableRecord.noOfPages;
+  fsRWReq->numberOfPages = WORDS2PAGES(c_readTableRecord.no_of_words);
   fsRWReq->data.arrayOfPages.varIndex = c_readTableRecord.pageId;
   fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
@@ -761,7 +1050,8 @@
 
   PageRecordPtr tmpPagePtr;
   c_pageRecordArray.getPtr(tmpPagePtr, c_readTableRecord.pageId);
-  Uint32 sz = c_readTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS;
+  Uint32 sz = 
+    WORDS2PAGES(c_readTableRecord.no_of_words)*ZSIZE_OF_PAGES_IN_WORDS;
   Uint32 chk = computeChecksum((const Uint32*)tmpPagePtr.p, sz);
   
   ndbrequire((chk == 0) || !crashInd);
@@ -800,10 +1090,9 @@
 /* ---------------------------------------------------------------- */
 void
 Dbdict::updateSchemaState(Signal* signal, Uint32 tableId, 
-			  SchemaFile::TableEntry* te, Callback* callback){
-
+			  SchemaFile::TableEntry* te, Callback* callback,
+                          bool savetodisk){
   jam();
-  ndbrequire(tableId < c_tableRecordPool.getSize());
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
   SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
   
@@ -820,7 +1109,7 @@
   case SchemaFile::ADD_STARTED:
     jam();
     ok = true;
-    ndbrequire(create_table_inc_schema_version(oldVersion) == newVersion);
+    ndbrequire(create_obj_inc_schema_version(oldVersion) == newVersion);
     ndbrequire(oldState == SchemaFile::INIT ||
 	       oldState == SchemaFile::DROP_TABLE_COMMITTED);
     break;
@@ -828,12 +1117,13 @@
     jam();
     ok = true;
     ndbrequire(newVersion == oldVersion);
-    ndbrequire(oldState == SchemaFile::ADD_STARTED);
+    ndbrequire(oldState == SchemaFile::ADD_STARTED ||
+	       oldState == SchemaFile::DROP_TABLE_STARTED);
     break;
   case SchemaFile::ALTER_TABLE_COMMITTED:
     jam();
     ok = true;
-    ndbrequire(alter_table_inc_schema_version(oldVersion) == newVersion);
+    ndbrequire(alter_obj_inc_schema_version(oldVersion) == newVersion);
     ndbrequire(oldState == SchemaFile::TABLE_ADD_COMMITTED ||
 	       oldState == SchemaFile::ALTER_TABLE_COMMITTED);
     break;
@@ -842,7 +1132,12 @@
   case SchemaFile::DROP_TABLE_COMMITTED:
     jam();
     ok = true;
-    ndbrequire(false);
+    break;
+  case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+    jam();
+    ndbrequire(oldState == SchemaFile::ADD_STARTED ||
+               oldState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
+    ok = true;
     break;
   case SchemaFile::INIT:
     jam();
@@ -854,16 +1149,23 @@
   * tableEntry = * te;
   computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
 
-  ndbrequire(c_writeSchemaRecord.inUse == false);
-  c_writeSchemaRecord.inUse = true;
-  
-  c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
-  c_writeSchemaRecord.newFile = false;
-  c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
-  c_writeSchemaRecord.noOfPages = 1;
-  c_writeSchemaRecord.m_callback = * callback;
-
-  startWriteSchemaFile(signal);
+  if (savetodisk)
+  {
+    ndbrequire(c_writeSchemaRecord.inUse == false);
+    c_writeSchemaRecord.inUse = true;
+    
+    c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
+    c_writeSchemaRecord.newFile = false;
+    c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
+    c_writeSchemaRecord.noOfPages = 1;
+    c_writeSchemaRecord.m_callback = * callback;
+    
+    startWriteSchemaFile(signal);
+  }
+  else
+  {
+    execute(signal, *callback, 0);
+  }
 }
 
 void Dbdict::startWriteSchemaFile(Signal* signal)
@@ -1089,7 +1391,8 @@
     ndbrequireErr(ok, NDBD_EXIT_SR_SCHEMAFILE);
     if (! ok) {
       jam();
-      ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1);
+      ndbrequireErr(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1,
+                    NDBD_EXIT_SR_SCHEMAFILE);
       readSchemaRef(signal, fsPtr);
       return;
     }
@@ -1208,30 +1511,35 @@
 /* ---------------------------------------------------------------- */
 /* **************************************************************** */
 
-Dbdict::Dbdict(const class Configuration & conf):
-  SimulatedBlock(DBDICT, conf),
-  c_tableRecordHash(c_tableRecordPool),
+Dbdict::Dbdict(Block_context& ctx):
+  SimulatedBlock(DBDICT, ctx),
   c_attributeRecordHash(c_attributeRecordPool),
-  c_triggerRecordHash(c_triggerRecordPool),
+  c_file_hash(c_file_pool),
+  c_filegroup_hash(c_filegroup_pool),
+  c_obj_hash(c_obj_pool),
   c_opCreateTable(c_opRecordPool),
   c_opDropTable(c_opRecordPool),
   c_opCreateIndex(c_opRecordPool),
   c_opDropIndex(c_opRecordPool),
   c_opAlterIndex(c_opRecordPool),
   c_opBuildIndex(c_opRecordPool),
+  c_opCreateEvent(c_opRecordPool),
+  c_opSubEvent(c_opRecordPool),
+  c_opDropEvent(c_opRecordPool),
+  c_opSignalUtil(c_opRecordPool),
   c_opCreateTrigger(c_opRecordPool),
   c_opDropTrigger(c_opRecordPool),
   c_opAlterTrigger(c_opRecordPool),
+  c_schemaOp(c_opRecordPool),
+  c_Trans(c_opRecordPool),
+  c_opCreateObj(c_schemaOp),
+  c_opDropObj(c_schemaOp),
   c_opRecordSequence(0),
   c_dictLockQueue(c_dictLockPool),
   c_dictLockPoll(false)
 {
   BLOCK_CONSTRUCTOR(Dbdict);
   
-  const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator();
-  ndbrequire(p != 0);
-
-  ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, &c_maxNoOfTriggers);
   // Transit signals
   addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD);
   addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ);
@@ -1278,6 +1586,41 @@
   addRecSignal(GSN_BUILDINDXCONF, &Dbdict::execBUILDINDXCONF);
   addRecSignal(GSN_BUILDINDXREF, &Dbdict::execBUILDINDXREF);
 
+  // Util signals
+  addRecSignal(GSN_UTIL_PREPARE_CONF, &Dbdict::execUTIL_PREPARE_CONF);
+  addRecSignal(GSN_UTIL_PREPARE_REF,  &Dbdict::execUTIL_PREPARE_REF);
+
+  addRecSignal(GSN_UTIL_EXECUTE_CONF, &Dbdict::execUTIL_EXECUTE_CONF);
+  addRecSignal(GSN_UTIL_EXECUTE_REF,  &Dbdict::execUTIL_EXECUTE_REF);
+
+  addRecSignal(GSN_UTIL_RELEASE_CONF, &Dbdict::execUTIL_RELEASE_CONF);
+  addRecSignal(GSN_UTIL_RELEASE_REF,  &Dbdict::execUTIL_RELEASE_REF);
+
+  // Event signals
+  addRecSignal(GSN_CREATE_EVNT_REQ,  &Dbdict::execCREATE_EVNT_REQ);
+  addRecSignal(GSN_CREATE_EVNT_CONF, &Dbdict::execCREATE_EVNT_CONF);
+  addRecSignal(GSN_CREATE_EVNT_REF,  &Dbdict::execCREATE_EVNT_REF);
+
+  addRecSignal(GSN_CREATE_SUBID_CONF, &Dbdict::execCREATE_SUBID_CONF);
+  addRecSignal(GSN_CREATE_SUBID_REF,  &Dbdict::execCREATE_SUBID_REF);
+
+  addRecSignal(GSN_SUB_CREATE_CONF, &Dbdict::execSUB_CREATE_CONF);
+  addRecSignal(GSN_SUB_CREATE_REF,  &Dbdict::execSUB_CREATE_REF);
+
+  addRecSignal(GSN_SUB_START_REQ,  &Dbdict::execSUB_START_REQ);
+  addRecSignal(GSN_SUB_START_CONF,  &Dbdict::execSUB_START_CONF);
+  addRecSignal(GSN_SUB_START_REF,  &Dbdict::execSUB_START_REF);
+
+  addRecSignal(GSN_SUB_STOP_REQ,  &Dbdict::execSUB_STOP_REQ);
+  addRecSignal(GSN_SUB_STOP_CONF,  &Dbdict::execSUB_STOP_CONF);
+  addRecSignal(GSN_SUB_STOP_REF,  &Dbdict::execSUB_STOP_REF);
+
+  addRecSignal(GSN_DROP_EVNT_REQ,  &Dbdict::execDROP_EVNT_REQ);
+
+  addRecSignal(GSN_SUB_REMOVE_REQ, &Dbdict::execSUB_REMOVE_REQ);
+  addRecSignal(GSN_SUB_REMOVE_CONF, &Dbdict::execSUB_REMOVE_CONF);
+  addRecSignal(GSN_SUB_REMOVE_REF,  &Dbdict::execSUB_REMOVE_REF);
+
   // Trigger signals
   addRecSignal(GSN_CREATE_TRIG_REQ, &Dbdict::execCREATE_TRIG_REQ);
   addRecSignal(GSN_CREATE_TRIG_CONF, &Dbdict::execCREATE_TRIG_CONF);
@@ -1329,8 +1672,39 @@
   addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF);
   addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF);
 
+  addRecSignal(GSN_CREATE_FILE_REQ, &Dbdict::execCREATE_FILE_REQ);
+  addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Dbdict::execCREATE_FILEGROUP_REQ);
+
+  addRecSignal(GSN_DROP_FILE_REQ, &Dbdict::execDROP_FILE_REQ);
+  addRecSignal(GSN_DROP_FILE_REF, &Dbdict::execDROP_FILE_REF);
+  addRecSignal(GSN_DROP_FILE_CONF, &Dbdict::execDROP_FILE_CONF);
+
+  addRecSignal(GSN_DROP_FILEGROUP_REQ, &Dbdict::execDROP_FILEGROUP_REQ);
+  addRecSignal(GSN_DROP_FILEGROUP_REF, &Dbdict::execDROP_FILEGROUP_REF);
+  addRecSignal(GSN_DROP_FILEGROUP_CONF, &Dbdict::execDROP_FILEGROUP_CONF);
+  
+  addRecSignal(GSN_CREATE_OBJ_REQ, &Dbdict::execCREATE_OBJ_REQ);
+  addRecSignal(GSN_CREATE_OBJ_REF, &Dbdict::execCREATE_OBJ_REF);
+  addRecSignal(GSN_CREATE_OBJ_CONF, &Dbdict::execCREATE_OBJ_CONF);
+  addRecSignal(GSN_DROP_OBJ_REQ, &Dbdict::execDROP_OBJ_REQ);
+  addRecSignal(GSN_DROP_OBJ_REF, &Dbdict::execDROP_OBJ_REF);
+  addRecSignal(GSN_DROP_OBJ_CONF, &Dbdict::execDROP_OBJ_CONF);
+
+  addRecSignal(GSN_CREATE_FILE_REF, &Dbdict::execCREATE_FILE_REF);
+  addRecSignal(GSN_CREATE_FILE_CONF, &Dbdict::execCREATE_FILE_CONF);
+  addRecSignal(GSN_CREATE_FILEGROUP_REF, &Dbdict::execCREATE_FILEGROUP_REF);
+  addRecSignal(GSN_CREATE_FILEGROUP_CONF, &Dbdict::execCREATE_FILEGROUP_CONF);
+
   addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ);
 
+  addRecSignal(GSN_DICT_COMMIT_REQ, &Dbdict::execDICT_COMMIT_REQ);
+  addRecSignal(GSN_DICT_COMMIT_REF, &Dbdict::execDICT_COMMIT_REF);
+  addRecSignal(GSN_DICT_COMMIT_CONF, &Dbdict::execDICT_COMMIT_CONF);
+
+  addRecSignal(GSN_DICT_ABORT_REQ, &Dbdict::execDICT_ABORT_REQ);
+  addRecSignal(GSN_DICT_ABORT_REF, &Dbdict::execDICT_ABORT_REF);
+  addRecSignal(GSN_DICT_ABORT_CONF, &Dbdict::execDICT_ABORT_CONF);
+
   addRecSignal(GSN_DICT_LOCK_REQ, &Dbdict::execDICT_LOCK_REQ);
   addRecSignal(GSN_DICT_UNLOCK_ORD, &Dbdict::execDICT_UNLOCK_ORD);
 }//Dbdict::Dbdict()
@@ -1390,7 +1764,7 @@
 
 void Dbdict::initReadTableRecord() 
 {
-  c_readTableRecord.noOfPages = (Uint32)-1;
+  c_readTableRecord.no_of_words= 0;
   c_readTableRecord.pageId = RNIL;
   c_readTableRecord.tableId = ZNIL;
   c_readTableRecord.inUse = false;
@@ -1398,7 +1772,7 @@
 
 void Dbdict::initWriteTableRecord() 
 {
-  c_writeTableRecord.noOfPages = (Uint32)-1;
+  c_writeTableRecord.no_of_words= 0;
   c_writeTableRecord.pageId = RNIL;
   c_writeTableRecord.noOfTableFilesHandled = 3;
   c_writeTableRecord.tableId = ZNIL;
@@ -1440,6 +1814,7 @@
 {
   c_restartRecord.gciToRestart = 0;
   c_restartRecord.activeTable = ZNIL;
+  c_restartRecord.m_pass = 0;
 }//Dbdict::initRestartRecord()
 
 void Dbdict::initNodeRecords() 
@@ -1478,23 +1853,20 @@
 
 void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr) 
 {
+  new (tablePtr.p) TableRecord();
   tablePtr.p->activePage = RNIL;
   tablePtr.p->filePtr[0] = RNIL;
   tablePtr.p->filePtr[1] = RNIL;
-  tablePtr.p->firstAttribute = RNIL;
   tablePtr.p->firstPage = RNIL;
-  tablePtr.p->lastAttribute = RNIL;
   tablePtr.p->tableId = tablePtr.i;
   tablePtr.p->tableVersion = (Uint32)-1;
   tablePtr.p->tabState = TableRecord::NOT_DEFINED;
   tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
   tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
-  memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName));
   tablePtr.p->gciTableCreated = 0;
   tablePtr.p->noOfAttributes = ZNIL;
   tablePtr.p->noOfNullAttr = 0;
-  tablePtr.p->frmLen = 0;
-  memset(tablePtr.p->frmData, 0, sizeof(tablePtr.p->frmData));
+  tablePtr.p->fragmentCount = 0;
   /*
     tablePtr.p->lh3PageIndexBits = 0;
     tablePtr.p->lh3DistrBits = 0;
@@ -1508,10 +1880,12 @@
   tablePtr.p->tupKeyLength = 1;
   tablePtr.p->maxRowsLow = 0;
   tablePtr.p->maxRowsHigh = 0;
+  tablePtr.p->defaultNoPartFlag = true;
+  tablePtr.p->linearHashFlag = true;
+  tablePtr.p->m_bits = 0;
   tablePtr.p->minRowsLow = 0;
   tablePtr.p->minRowsHigh = 0;
   tablePtr.p->singleUserMode = 0;
-  tablePtr.p->storedTable = true;
   tablePtr.p->tableType = DictTabInfo::UserTable;
   tablePtr.p->primaryTableId = RNIL;
   // volatile elements
@@ -1541,9 +1915,9 @@
 
 void Dbdict::initialiseTriggerRecord(TriggerRecordPtr triggerPtr)
 {
+  new (triggerPtr.p) TriggerRecord();
   triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
   triggerPtr.p->triggerLocal = 0;
-  memset(triggerPtr.p->triggerName, 0, sizeof(triggerPtr.p->triggerName));
   triggerPtr.p->triggerId = RNIL;
   triggerPtr.p->tableId = RNIL;
   triggerPtr.p->triggerType = (TriggerType::Value)~0;
@@ -1566,53 +1940,50 @@
   return fsPtr.i;
 }//Dbdict::getFsConnRecord()
 
+/*
+ * Search schemafile for free entry.  Its index is used as 'logical id'
+ * of new disk-stored object.
+ */
+Uint32 Dbdict::getFreeObjId(Uint32 minId)
+{
+  const XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+  Uint32 noOfPages = xsf->noOfPages;
+  Uint32 n, i;
+  for (n = 0; n < noOfPages; n++) {
+    jam();
+    const SchemaFile * sf = &xsf->schemaPage[n];
+    for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
+      const SchemaFile::TableEntry& te = sf->TableEntries[i];
+      if (te.m_tableState == (Uint32)SchemaFile::INIT ||
+          te.m_tableState == (Uint32)SchemaFile::DROP_TABLE_COMMITTED) {
+        // minId is obsolete anyway
+        if (minId <= n * NDB_SF_PAGE_ENTRIES + i)
+          return n * NDB_SF_PAGE_ENTRIES + i;
+      }
+    }
+  }
+  return RNIL;
+}
+
 Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId) 
 {
   Uint32 minId = (primaryTableId == RNIL ? 0 : primaryTableId + 1);
-  TableRecordPtr tablePtr;
-  TableRecordPtr firstTablePtr;
-  bool firstFound = false;
-  Uint32 tabSize = c_tableRecordPool.getSize();
-  for (tablePtr.i = minId; tablePtr.i < tabSize ; tablePtr.i++) {
-    jam();
-    c_tableRecordPool.getPtr(tablePtr);
-    if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
-      jam();
-      initialiseTableRecord(tablePtr);
-      tablePtr.p->tabState = TableRecord::DEFINING;
-      firstFound = true;
-      firstTablePtr.i = tablePtr.i;
-      firstTablePtr.p = tablePtr.p;
-      break;
-    }//if
-  }//for
-  if (!firstFound) {
+  Uint32 i = getFreeObjId(minId);
+  if (i == RNIL) {
     jam();
     return RNIL;
-  }//if
-#ifdef HAVE_TABLE_REORG
-  bool secondFound = false;
-  for (tablePtr.i = firstTablePtr.i + 1; tablePtr.i < tabSize ; tablePtr.i++) {
-    jam();
-    c_tableRecordPool.getPtr(tablePtr);
-    if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
-      jam();
-      initialiseTableRecord(tablePtr);
-      tablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED;
-      tablePtr.p->secondTable = firstTablePtr.i;
-      firstTablePtr.p->secondTable = tablePtr.i;
-      secondFound = true;
-      break;
-    }//if
-  }//for
-  if (!secondFound) {
+  }
+  if (i >= c_tableRecordPool.getSize()) {
     jam();
-    firstTablePtr.p->tabState = TableRecord::NOT_DEFINED;
     return RNIL;
-  }//if
-#endif
-  return firstTablePtr.i;
-}//Dbdict::getFreeTableRecord()
+  }
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, i);
+  ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
+  initialiseTableRecord(tablePtr);
+  tablePtr.p->tabState = TableRecord::DEFINING;
+  return i;
+}
 
 Uint32 Dbdict::getFreeTriggerRecord()
 {
@@ -1630,39 +2001,6 @@
   return RNIL;
 }
 
-bool
-Dbdict::getNewAttributeRecord(TableRecordPtr tablePtr, 
-			      AttributeRecordPtr & attrPtr) 
-{
-  c_attributeRecordPool.seize(attrPtr);
-  if(attrPtr.i == RNIL){
-    return false;
-  }
-  
-  memset(attrPtr.p->attributeName, 0, sizeof(attrPtr.p->attributeName));
-  attrPtr.p->attributeDescriptor = 0x00012255; //Default value
-  attrPtr.p->attributeId = ZNIL;
-  attrPtr.p->nextAttrInTable = RNIL;
-  attrPtr.p->tupleKey = 0;
-  memset(attrPtr.p->defaultValue, 0, sizeof(attrPtr.p->defaultValue));
-  
-  /* ---------------------------------------------------------------- */
-  // A free attribute record has been acquired. We will now link it
-  // to the table record.
-  /* ---------------------------------------------------------------- */
-  if (tablePtr.p->lastAttribute == RNIL) {
-    jam();
-    tablePtr.p->firstAttribute = attrPtr.i;
-  } else {
-    jam();
-    AttributeRecordPtr lastAttrPtr;
-    c_attributeRecordPool.getPtr(lastAttrPtr, tablePtr.p->lastAttribute);
-    lastAttrPtr.p->nextAttrInTable = attrPtr.i;
-  }//if
-  tablePtr.p->lastAttribute = attrPtr.i;
-  return true;
-}//Dbdict::getNewAttributeRecord()
-
 /* **************************************************************** */
 /* ---------------------------------------------------------------- */
 /* MODULE:          START/RESTART HANDLING ------------------------ */
@@ -1718,10 +2056,12 @@
   jamEntry();
  
   const ndb_mgm_configuration_iterator * p = 
-    theConfiguration.getOwnConfigIterator();
+    m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
   
   Uint32 attributesize, tablerecSize;
+  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, 
+					&c_maxNoOfTriggers));
   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_ATTRIBUTE,&attributesize));
   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &tablerecSize));
 
@@ -1732,14 +2072,29 @@
   c_pageRecordArray.setSize(ZNUMBER_OF_PAGES);
   c_schemaPageRecordArray.setSize(2 * NDB_SF_MAX_PAGES);
   c_tableRecordPool.setSize(tablerecSize);
-  c_tableRecordHash.setSize(tablerecSize);
   g_key_descriptor_pool.setSize(tablerecSize);
   c_triggerRecordPool.setSize(c_maxNoOfTriggers);
-  c_triggerRecordHash.setSize(c_maxNoOfTriggers);
+  
+  c_obj_pool.setSize(tablerecSize+c_maxNoOfTriggers);
+  c_obj_hash.setSize((tablerecSize+c_maxNoOfTriggers+1)/2);
+
+  Pool_context pc;
+  pc.m_block = this;
+
+  c_file_hash.setSize(16);
+  c_filegroup_hash.setSize(16);
+
+  c_file_pool.init(RT_DBDICT_FILE, pc);
+  c_filegroup_pool.init(RT_DBDICT_FILEGROUP, pc);
+  
   c_opRecordPool.setSize(256);   // XXX need config params
   c_opCreateTable.setSize(8);
   c_opDropTable.setSize(8);
   c_opCreateIndex.setSize(8);
+  c_opCreateEvent.setSize(2);
+  c_opSubEvent.setSize(2);
+  c_opDropEvent.setSize(2);
+  c_opSignalUtil.setSize(8);
   c_opDropIndex.setSize(8);
   c_opAlterIndex.setSize(8);
   c_opBuildIndex.setSize(8);
@@ -1757,6 +2112,33 @@
     (SchemaFile*)c_schemaPageRecordArray.getPtr(1 * NDB_SF_MAX_PAGES);
   c_schemaFile[1].noOfPages = 0;
 
+  c_schemaOp.setSize(8);
+  //c_opDropObj.setSize(8);
+  c_Trans.setSize(8);
+
+  Uint32 rps = 0;
+  rps += tablerecSize * (MAX_TAB_NAME_SIZE + MAX_FRM_DATA_SIZE);
+  rps += attributesize * (MAX_ATTR_NAME_SIZE + MAX_ATTR_DEFAULT_VALUE_SIZE);
+  rps += c_maxNoOfTriggers * MAX_TAB_NAME_SIZE;
+  rps += (10 + 10) * MAX_TAB_NAME_SIZE;
+
+  Uint32 sm = 5;
+  ndb_mgm_get_int_parameter(p, CFG_DB_STRING_MEMORY, &sm);
+  if (sm == 0)
+    sm = 5;
+  
+  Uint32 sb = 0;
+  if (sm < 100)
+  {
+    sb = (rps * sm) / 100;
+  }
+  else
+  {
+    sb = sm;
+  }
+  
+  c_rope_pool.setSize(sb/28 + 100);
+  
   // Initialize BAT for interface to file system
   NewVARIABLE* bat = allocateBat(2);
   bat[0].WA = &c_schemaPageRecordArray.getPtr(0)->word[0];
@@ -1778,6 +2160,14 @@
   conf->senderData = senderData;
   sendSignal(ref, GSN_READ_CONFIG_CONF, signal, 
 	     ReadConfigConf::SignalLength, JBB);
+
+  {
+    Ptr<DictObject> ptr;
+    SLList<DictObject> objs(c_obj_pool);
+    while(objs.seize(ptr))
+      new (ptr.p) DictObject();
+    objs.release();
+  }
 }//execSIZEALT_REP()
 
 /* ---------------------------------------------------------------- */
@@ -2024,7 +2414,7 @@
     req->setParallelism(16);
 
     // from file index state is not defined currently
-    if (indexPtr.p->storedTable) {
+    if (indexPtr.p->m_bits & TableRecord::TR_Logged) {
       // rebuild not needed
       req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
     }
@@ -2075,6 +2465,7 @@
   c_schemaRecord.m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::masterRestart_checkSchemaStatusComplete);
 
+  c_restartRecord.m_pass = 0;
   c_restartRecord.activeTable = 0;
   c_schemaRecord.schemaPage = c_schemaRecord.oldSchemaPage; // ugly
   checkSchemaStatus(signal);
@@ -2202,6 +2593,8 @@
   c_schemaRecord.m_callback.m_callbackData = 0;
   c_schemaRecord.m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::restart_checkSchemaStatusComplete);
+
+  c_restartRecord.m_pass= 0;
   c_restartRecord.activeTable = 0;
   checkSchemaStatus(signal);
 }//execSCHEMA_INFO()
@@ -2222,6 +2615,9 @@
   c_writeSchemaRecord.m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::restart_writeSchemaConf);
   
+  for(Uint32 i = 0; i<xsf->noOfPages; i++)
+    computeChecksum(xsf, i);  
+
   startWriteSchemaFile(signal);
 }
 
@@ -2264,6 +2660,75 @@
   activateIndexes(signal, 0);
 }//execSCHEMA_INFOCONF()
 
+static bool 
+checkSchemaStatus(Uint32 tableType, Uint32 pass)
+{
+  switch(tableType){
+  case DictTabInfo::UndefTableType:
+    return true;
+  case DictTabInfo::HashIndexTrigger:
+  case DictTabInfo::SubscriptionTrigger:
+  case DictTabInfo::ReadOnlyConstraint:
+  case DictTabInfo::IndexTrigger:
+    return false;
+  case DictTabInfo::LogfileGroup:
+    return pass == 0 || pass == 9 || pass == 10;
+  case DictTabInfo::Tablespace:
+    return pass == 1 || pass == 8 || pass == 11;
+  case DictTabInfo::Datafile:
+  case DictTabInfo::Undofile:
+    return pass == 2 || pass == 7 || pass == 12;
+  case DictTabInfo::SystemTable:
+  case DictTabInfo::UserTable:
+    return /* pass == 3 || pass == 6 || */ pass == 13;
+  case DictTabInfo::UniqueHashIndex:
+  case DictTabInfo::HashIndex:
+  case DictTabInfo::UniqueOrderedIndex:
+  case DictTabInfo::OrderedIndex:
+    return /* pass == 4 || pass == 5 || */ pass == 14;
+  }
+  
+  return false;
+}
+
+static const Uint32 CREATE_OLD_PASS = 4;
+static const Uint32 DROP_OLD_PASS = 9;
+static const Uint32 CREATE_NEW_PASS = 14;
+static const Uint32 LAST_PASS = 14;
+
+NdbOut&
+operator<<(NdbOut& out, const SchemaFile::TableEntry entry)
+{
+  out << "[";
+  out << " state: " << entry.m_tableState;
+  out << " version: " << hex << entry.m_tableVersion << dec;
+  out << " type: " << entry.m_tableType;
+  out << " words: " << entry.m_info_words;
+  out << " gcp: " << entry.m_gcp;
+  out << " ]";
+  return out;
+}
+
+/**
+ * Pass 0  Create old LogfileGroup
+ * Pass 1  Create old Tablespace
+ * Pass 2  Create old Datafile/Undofile
+ * Pass 3  Create old Table           // NOT DONE DUE TO DIH
+ * Pass 4  Create old Index           // NOT DONE DUE TO DIH
+ 
+ * Pass 5  Drop old Index             // NOT DONE DUE TO DIH
+ * Pass 6  Drop old Table             // NOT DONE DUE TO DIH
+ * Pass 7  Drop old Datafile/Undofile
+ * Pass 8  Drop old Tablespace
+ * Pass 9  Drop old Logfilegroup
+ 
+ * Pass 10 Create new LogfileGroup
+ * Pass 11 Create new Tablespace
+ * Pass 12 Create new Datafile/Undofile
+ * Pass 13 Create new Table
+ * Pass 14 Create new Index
+ */
+
 void Dbdict::checkSchemaStatus(Signal* signal) 
 {
   XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
@@ -2278,221 +2743,171 @@
     Uint32 tableId = c_restartRecord.activeTable;
     SchemaFile::TableEntry *newEntry = getTableEntry(newxsf, tableId);
     SchemaFile::TableEntry *oldEntry = getTableEntry(oldxsf, tableId);
-    SchemaFile::TableState schemaState = 
+    SchemaFile::TableState newSchemaState = 
       (SchemaFile::TableState)newEntry->m_tableState;
     SchemaFile::TableState oldSchemaState = 
       (SchemaFile::TableState)oldEntry->m_tableState;
 
     if (c_restartRecord.activeTable >= c_tableRecordPool.getSize()) {
       jam();
-      ndbrequire(schemaState == SchemaFile::INIT);
+      ndbrequire(newSchemaState == SchemaFile::INIT);
       ndbrequire(oldSchemaState == SchemaFile::INIT);
       continue;
     }//if
 
-    switch(schemaState){
-    case SchemaFile::INIT:{
-      jam();
-      bool ok = false;
-      switch(oldSchemaState) {
-      case SchemaFile::INIT:
-	jam();
-      case SchemaFile::DROP_TABLE_COMMITTED:
-	jam();
-	ok = true;
-        jam();
-	break;
+//#define PRINT_SCHEMA_RESTART
+#ifdef PRINT_SCHEMA_RESTART
+    char buf[100];
+    snprintf(buf, sizeof(buf), "checkSchemaStatus: pass: %d table: %d", 
+             c_restartRecord.m_pass, tableId);
+#endif
+    
+    if (c_restartRecord.m_pass <= CREATE_OLD_PASS)
+    {
+      if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
+        continue;
 
-      case SchemaFile::ADD_STARTED:
-	jam();
-      case SchemaFile::TABLE_ADD_COMMITTED:
-	jam();
-      case SchemaFile::DROP_TABLE_STARTED:
-	jam();
-      case SchemaFile::ALTER_TABLE_COMMITTED:
-	jam();
-	ok = true;
-        jam();
-	newEntry->m_tableState = SchemaFile::INIT;
-	restartDropTab(signal, tableId);
-	return;
-      }//switch
-      ndbrequire(ok);
-      break;
-    }
-    case SchemaFile::ADD_STARTED:{
-      jam();
-      bool ok = false;
-      switch(oldSchemaState) {
-      case SchemaFile::INIT:
-	jam();
-      case SchemaFile::DROP_TABLE_COMMITTED:
-	jam();
-	ok = true;
-	break;
-      case SchemaFile::ADD_STARTED: 
-	jam();
-      case SchemaFile::DROP_TABLE_STARTED:
-	jam();
-      case SchemaFile::TABLE_ADD_COMMITTED:
-	jam();
-      case SchemaFile::ALTER_TABLE_COMMITTED:
-	jam();
-	ok = true;
-	//------------------------------------------------------------------
-	// Add Table was started but not completed. Will be dropped in all
-	// nodes. Update schema information (restore table version).
-	//------------------------------------------------------------------
-	newEntry->m_tableState = SchemaFile::INIT;
-	restartDropTab(signal, tableId);
-	return;
-      }
-      ndbrequire(ok);
-      break;
-    }
-    case SchemaFile::TABLE_ADD_COMMITTED:{
-      jam();
-      bool ok = false;
-      switch(oldSchemaState) {
-      case SchemaFile::INIT:
-	jam();
-      case SchemaFile::ADD_STARTED:
-	jam();
-      case SchemaFile::DROP_TABLE_STARTED:
-	jam();
-      case SchemaFile::DROP_TABLE_COMMITTED:
+      switch(oldSchemaState){
+      case SchemaFile::INIT: jam();
+      case SchemaFile::DROP_TABLE_COMMITTED: jam();
+      case SchemaFile::ADD_STARTED: jam();
+      case SchemaFile::DROP_TABLE_STARTED: jam();
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
+	continue;
+      case SchemaFile::TABLE_ADD_COMMITTED: jam();
+      case SchemaFile::ALTER_TABLE_COMMITTED: jam();
 	jam();
-	ok = true;
-	//------------------------------------------------------------------
-	// Table was added in the master node but not in our node. We can
-	// retrieve the table definition from the master.
-	//------------------------------------------------------------------
-	restartCreateTab(signal, tableId, oldEntry, false);
+#ifdef PRINT_SCHEMA_RESTART
+        ndbout_c("%s -> restartCreateTab", buf);
+        ndbout << *newEntry << " " << *oldEntry << endl;
+#endif
+	restartCreateTab(signal, tableId, oldEntry, oldEntry, true);        
         return;
-        break;
-      case SchemaFile::TABLE_ADD_COMMITTED:
-	jam();
-      case SchemaFile::ALTER_TABLE_COMMITTED:
-        jam();
-	ok = true;
-	//------------------------------------------------------------------
-	// Table was added in both our node and the master node. We can
-	// retrieve the table definition from our own disk.
-	//------------------------------------------------------------------
-	if(* newEntry == * oldEntry){
-          jam();
-	  
-          TableRecordPtr tablePtr;
-          c_tableRecordPool.getPtr(tablePtr, tableId);
-          tablePtr.p->tableVersion = oldEntry->m_tableVersion;
-          tablePtr.p->tableType = (DictTabInfo::TableType)oldEntry->m_tableType;
-	  
-          // On NR get index from master because index state is not on file
-          const bool file = c_systemRestart || tablePtr.p->isTable();
-          restartCreateTab(signal, tableId, oldEntry, file);
-
-          return;
-        } else {
-	  //------------------------------------------------------------------
-	  // Must be a new version of the table if anything differs. Both table
-	  // version and global checkpoint must be different.
-	  // This should not happen for the master node. This can happen after
-	  // drop table followed by add table or after change table.
-	  // Not supported in this version.
-	  //------------------------------------------------------------------
-          ndbrequire(c_masterNodeId != getOwnNodeId());
-	  ndbrequire(newEntry->m_tableVersion != oldEntry->m_tableVersion);
-          jam();
-	  
-	  restartCreateTab(signal, tableId, oldEntry, false);
-          return;
-        }//if
       }
-      ndbrequire(ok);
-      break;
     }
-    case SchemaFile::DROP_TABLE_STARTED:
-      jam();
-    case SchemaFile::DROP_TABLE_COMMITTED:{
-      jam();
-      bool ok = false;
+
+    if (c_restartRecord.m_pass <= DROP_OLD_PASS)
+    {
+      if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
+        continue;
+
       switch(oldSchemaState){
-      case SchemaFile::INIT:
-	jam();
-      case SchemaFile::DROP_TABLE_COMMITTED:
-	jam();
-	ok = true;
-	break;
-      case SchemaFile::ADD_STARTED:
-	jam();
-      case SchemaFile::TABLE_ADD_COMMITTED:
-	jam();
-      case SchemaFile::DROP_TABLE_STARTED:
-	jam();
-      case SchemaFile::ALTER_TABLE_COMMITTED:
-	jam();
-	newEntry->m_tableState = SchemaFile::INIT;
-	restartDropTab(signal, tableId);
-	return;
+      case SchemaFile::INIT: jam();
+      case SchemaFile::DROP_TABLE_COMMITTED: jam();
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
+        continue;
+      case SchemaFile::ADD_STARTED: jam();
+      case SchemaFile::DROP_TABLE_STARTED: jam();
+#ifdef PRINT_SCHEMA_RESTART
+        ndbout_c("%s -> restartDropTab", buf);
+        ndbout << *newEntry << " " << *oldEntry << endl;
+#endif
+	restartDropTab(signal, tableId, oldEntry, newEntry);
+        return;
+      case SchemaFile::TABLE_ADD_COMMITTED: jam();
+      case SchemaFile::ALTER_TABLE_COMMITTED: jam();
+        if (! (* oldEntry == * newEntry))
+        {
+#ifdef PRINT_SCHEMA_RESTART
+          ndbout_c("%s -> restartDropTab", buf);
+          ndbout << *newEntry << " " << *oldEntry << endl;
+#endif
+          restartDropTab(signal, tableId, oldEntry, newEntry);
+          return;
+        }
+        continue;
       }
-      ndbrequire(ok);
-      break;
     }
-    case SchemaFile::ALTER_TABLE_COMMITTED: {
-      jam();
-      bool ok = false;
-      switch(oldSchemaState) {
-      case SchemaFile::INIT:
-	jam();
-      case SchemaFile::ADD_STARTED:
-	jam();
-      case SchemaFile::DROP_TABLE_STARTED:
-	jam();
-      case SchemaFile::DROP_TABLE_COMMITTED:
-	jam();
-      case SchemaFile::TABLE_ADD_COMMITTED:
-        jam();
-	ok = true;
-	//------------------------------------------------------------------
-	// Table was altered in the master node but not in our node. We can
-	// retrieve the altered table definition from the master.
-	//------------------------------------------------------------------
-	restartCreateTab(signal, tableId, oldEntry, false);
-        return;
-        break;
-      case SchemaFile::ALTER_TABLE_COMMITTED:
-        jam();
-	ok = true;
-	
-	//------------------------------------------------------------------
-	// Table was altered in both our node and the master node. We can
-	// retrieve the table definition from our own disk.
-	//------------------------------------------------------------------
-	TableRecordPtr tablePtr;
-	c_tableRecordPool.getPtr(tablePtr, tableId);
-	tablePtr.p->tableVersion = oldEntry->m_tableVersion;
-	tablePtr.p->tableType = (DictTabInfo::TableType)oldEntry->m_tableType;
-	
-	// On NR get index from master because index state is not on file
-	const bool file = (* newEntry == * oldEntry) &&
-	  (c_systemRestart || tablePtr.p->isTable());
-	restartCreateTab(signal, tableId, oldEntry, file);
 
-	return;
+    if (c_restartRecord.m_pass <= CREATE_NEW_PASS)
+    {
+      if (!::checkSchemaStatus(newEntry->m_tableType, c_restartRecord.m_pass))
+        continue;
+      
+      switch(newSchemaState){
+      case SchemaFile::INIT: jam();
+      case SchemaFile::DROP_TABLE_COMMITTED: jam();
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
+        * oldEntry = * newEntry;
+        continue;
+      case SchemaFile::ADD_STARTED: jam();
+      case SchemaFile::DROP_TABLE_STARTED: jam();
+        ndbrequire(DictTabInfo::isTable(newEntry->m_tableType) ||
+                   DictTabInfo::isIndex(newEntry->m_tableType));
+        newEntry->m_tableState = SchemaFile::INIT;
+        continue;
+      case SchemaFile::TABLE_ADD_COMMITTED: jam();
+      case SchemaFile::ALTER_TABLE_COMMITTED: jam();
+        if (DictTabInfo::isIndex(newEntry->m_tableType) ||
+            DictTabInfo::isTable(newEntry->m_tableType))
+        {
+          bool file = * oldEntry == *newEntry &&
+            (!DictTabInfo::isIndex(newEntry->m_tableType) || c_systemRestart);
+
+#ifdef PRINT_SCHEMA_RESTART          
+          ndbout_c("%s -> restartCreateTab (file: %d)", buf, file);
+          ndbout << *newEntry << " " << *oldEntry << endl;
+#endif
+          restartCreateTab(signal, tableId, newEntry, newEntry, file);        
+          * oldEntry = * newEntry;
+          return;
+        }
+        else if (! (* oldEntry == *newEntry))
+        {
+#ifdef PRINT_SCHEMA_RESTART
+          ndbout_c("%s -> restartCreateTab", buf);
+          ndbout << *newEntry << " " << *oldEntry << endl;
+#endif
+          restartCreateTab(signal, tableId, oldEntry, newEntry, false);        
+          * oldEntry = * newEntry;
+          return;
+        }
+        * oldEntry = * newEntry;
+        continue;
       }
-      ndbrequire(ok);
-      break;
-    }
     }
   }
   
-  execute(signal, c_schemaRecord.m_callback, 0);
+  c_restartRecord.m_pass++;
+  c_restartRecord.activeTable= 0;
+  if(c_restartRecord.m_pass <= LAST_PASS)
+  {
+    checkSchemaStatus(signal);
+  }
+  else
+  {
+    execute(signal, c_schemaRecord.m_callback, 0);
+  }
 }//checkSchemaStatus()
 
 void
 Dbdict::restartCreateTab(Signal* signal, Uint32 tableId, 
-		      const SchemaFile::TableEntry * te, bool file){
+			 const SchemaFile::TableEntry * old_entry, 
+			 const SchemaFile::TableEntry * new_entry, 
+			 bool file){
   jam();
+
+  switch(new_entry->m_tableType){
+  case DictTabInfo::UndefTableType:
+  case DictTabInfo::HashIndexTrigger:
+  case DictTabInfo::SubscriptionTrigger:
+  case DictTabInfo::ReadOnlyConstraint:
+  case DictTabInfo::IndexTrigger:
+    ndbrequire(false);
+  case DictTabInfo::SystemTable:
+  case DictTabInfo::UserTable:
+  case DictTabInfo::UniqueHashIndex:
+  case DictTabInfo::HashIndex:
+  case DictTabInfo::UniqueOrderedIndex:
+  case DictTabInfo::OrderedIndex:
+    break;
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+  case DictTabInfo::Datafile:
+  case DictTabInfo::Undofile:
+    restartCreateObj(signal, tableId, old_entry, new_entry, file);
+    return;
+  }
   
   CreateTableRecordPtr createTabPtr;  
   c_opCreateTable.seize(createTabPtr);
@@ -2512,8 +2927,7 @@
   if(file && !ERROR_INSERTED(6002)){
     jam();
     
-    c_readTableRecord.noOfPages =
-      DIV(te->m_info_words + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
+    c_readTableRecord.no_of_words = old_entry->m_info_words;
     c_readTableRecord.pageId = 0;
     c_readTableRecord.m_callback.m_callbackData = createTabPtr.p->key;
     c_readTableRecord.m_callback.m_callbackFunction = 
@@ -2557,8 +2971,8 @@
   parseRecord.requestType = DictTabInfo::GetTabInfoConf;
   parseRecord.errorCode = 0;
   
-  Uint32 sz = c_readTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS; 
-  SimplePropertiesLinearReader r(&pageRecPtr.p->word[0], sz);
+  Uint32 sz = c_readTableRecord.no_of_words;
+  SimplePropertiesLinearReader r(pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz);
   handleTabInfoInit(r, &parseRecord);
   if (parseRecord.errorCode != 0)
   {
@@ -2573,13 +2987,13 @@
 	      buf);
     ndbrequire(parseRecord.errorCode == 0);
   }
-  
+
   /* ---------------------------------------------------------------- */
   // We have read the table description from disk as part of system restart.
   // We will also write it back again to ensure that both copies are ok.
   /* ---------------------------------------------------------------- */
   ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
-  c_writeTableRecord.noOfPages = c_readTableRecord.noOfPages;
+  c_writeTableRecord.no_of_words = c_readTableRecord.no_of_words;
   c_writeTableRecord.pageId = c_readTableRecord.pageId;
   c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
   c_writeTableRecord.m_callback.m_callbackData = callbackData;
@@ -2599,9 +3013,73 @@
   
   GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
 
+  switch(conf->tableType){
+  case DictTabInfo::UndefTableType:
+  case DictTabInfo::HashIndexTrigger:
+  case DictTabInfo::SubscriptionTrigger:
+  case DictTabInfo::ReadOnlyConstraint:
+  case DictTabInfo::IndexTrigger:
+    ndbrequire(false);
+  case DictTabInfo::SystemTable:
+  case DictTabInfo::UserTable:
+  case DictTabInfo::UniqueHashIndex:
+  case DictTabInfo::HashIndex:
+  case DictTabInfo::UniqueOrderedIndex:
+  case DictTabInfo::OrderedIndex:
+    break;
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+  case DictTabInfo::Datafile:
+  case DictTabInfo::Undofile:
+    if(refToBlock(conf->senderRef) == TSMAN
+       && (refToNode(conf->senderRef) == 0
+	   || refToNode(conf->senderRef) == getOwnNodeId()))
+    {
+      jam();
+      FilePtr fg_ptr;
+      ndbrequire(c_file_hash.find(fg_ptr, conf->tableId));
+      const Uint32 free_extents= conf->freeExtents;
+      const Uint32 id= conf->tableId;
+      const Uint32 type= conf->tableType;
+      const Uint32 data= conf->senderData;
+      signal->theData[0]= ZPACK_TABLE_INTO_PAGES;
+      signal->theData[1]= id;
+      signal->theData[2]= type;
+      signal->theData[3]= data;
+      signal->theData[4]= free_extents;
+      sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
+    }
+    else if(refToBlock(conf->senderRef) == LGMAN
+	    && (refToNode(conf->senderRef) == 0
+		|| refToNode(conf->senderRef) == getOwnNodeId()))
+    {
+      jam();
+      FilegroupPtr fg_ptr;
+      ndbrequire(c_filegroup_hash.find(fg_ptr, conf->tableId));
+      const Uint32 free_hi= conf->freeWordsHi;
+      const Uint32 free_lo= conf->freeWordsLo;
+      const Uint32 id= conf->tableId;
+      const Uint32 type= conf->tableType;
+      const Uint32 data= conf->senderData;
+      signal->theData[0]= ZPACK_TABLE_INTO_PAGES;
+      signal->theData[1]= id;
+      signal->theData[2]= type;
+      signal->theData[3]= data;
+      signal->theData[4]= free_hi;
+      signal->theData[5]= free_lo;
+      sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
+    }
+    else
+    {
+      jam();
+      restartCreateObj_getTabInfoConf(signal);
+    }
+    return;
+  }
+  
   const Uint32 tableId = conf->tableId;
   const Uint32 senderData = conf->senderData;
-  
+
   SegmentedSectionPtr tabInfoPtr;
   signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
 
@@ -2620,6 +3098,13 @@
   SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
   handleTabInfoInit(r, &parseRecord);
   ndbrequire(parseRecord.errorCode == 0);
+
+  // save to disk
+
+  ndbrequire(tableId < c_tableRecordPool.getSize());
+  XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+  SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
+  tableEntry->m_info_words= tabInfoPtr.sz;
   
   Callback callback;
   callback.m_callbackData = createTabPtr.p->key;
@@ -2660,9 +3145,15 @@
   
   CreateTableRecordPtr createTabPtr;  
   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-  
-  //@todo check error
-  ndbrequire(createTabPtr.p->m_errorCode == 0);
+
+  if(createTabPtr.p->m_errorCode)
+  {
+    char buf[100];
+    BaseString::snprintf(buf, sizeof(buf), "Failed to create table during"
+                         " restart, Error: %u",
+                         createTabPtr.p->m_errorCode);
+    progError(__LINE__, NDBD_EXIT_RESOURCE_ALLOC_ERROR, buf);
+  }
 
   Callback callback;
   callback.m_callbackData = callbackData;
@@ -2685,14 +3176,54 @@
   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
   tabPtr.p->tabState = TableRecord::DEFINED;
   
-  c_opCreateTable.release(createTabPtr);
+  releaseCreateTableOp(signal,createTabPtr);
 
   c_restartRecord.activeTable++;
   checkSchemaStatus(signal);
 }
 
 void
-Dbdict::restartDropTab(Signal* signal, Uint32 tableId){
+Dbdict::releaseCreateTableOp(Signal* signal, CreateTableRecordPtr createTabPtr)
+{
+  if (createTabPtr.p->m_tabInfoPtrI != RNIL)
+  {
+    jam();
+    SegmentedSectionPtr tabInfoPtr;
+    getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
+    signal->setSection(tabInfoPtr, 0);
+    releaseSections(signal);
+  }
+  c_opCreateTable.release(createTabPtr);
+}
+
+void
+Dbdict::restartDropTab(Signal* signal, Uint32 tableId,
+                       const SchemaFile::TableEntry * old_entry, 
+                       const SchemaFile::TableEntry * new_entry)
+{
+  switch(old_entry->m_tableType){
+  case DictTabInfo::UndefTableType:
+  case DictTabInfo::HashIndexTrigger:
+  case DictTabInfo::SubscriptionTrigger:
+  case DictTabInfo::ReadOnlyConstraint:
+  case DictTabInfo::IndexTrigger:
+    ndbrequire(false);
+  case DictTabInfo::SystemTable:
+  case DictTabInfo::UserTable:
+  case DictTabInfo::UniqueHashIndex:
+  case DictTabInfo::HashIndex:
+  case DictTabInfo::UniqueOrderedIndex:
+  case DictTabInfo::OrderedIndex:
+    break;
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+  case DictTabInfo::Datafile:
+  case DictTabInfo::Undofile:
+    warningEvent("Dont drop object: %d", tableId);
+    c_restartRecord.activeTable++;
+    checkSchemaStatus(signal);
+    return;
+  }
 
   const Uint32 key = ++c_opRecordSequence;
 
@@ -2707,7 +3238,6 @@
   dropTabPtr.p->m_coordinatorRef = 0;
   dropTabPtr.p->m_requestType = DropTabReq::RestartDropTab;
   dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
-  
 
   dropTabPtr.p->m_participantData.m_block = 0;
   dropTabPtr.p->m_participantData.m_callback.m_callbackData = key;
@@ -2727,12 +3257,241 @@
   
   //@todo check error
 
+  releaseTableObject(c_restartRecord.activeTable);
   c_opDropTable.release(dropTabPtr);
 
   c_restartRecord.activeTable++;
   checkSchemaStatus(signal);
 }
 
+void
+Dbdict::restartCreateObj(Signal* signal, 
+			 Uint32 tableId, 
+			 const SchemaFile::TableEntry * old_entry,
+			 const SchemaFile::TableEntry * new_entry,
+			 bool file){
+  jam();
+  
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.seize(createObjPtr));
+  
+  const Uint32 key = ++c_opRecordSequence;
+  createObjPtr.p->key = key;
+  c_opCreateObj.add(createObjPtr);
+  createObjPtr.p->m_errorCode = 0;
+  createObjPtr.p->m_senderRef = reference();
+  createObjPtr.p->m_senderData = tableId;
+  createObjPtr.p->m_clientRef = reference();
+  createObjPtr.p->m_clientData = tableId;
+  
+  createObjPtr.p->m_obj_id = tableId;
+  createObjPtr.p->m_obj_type = new_entry->m_tableType;
+  createObjPtr.p->m_obj_version = new_entry->m_tableVersion;
+
+  createObjPtr.p->m_callback.m_callbackData = key;
+  createObjPtr.p->m_callback.m_callbackFunction= 
+    safe_cast(&Dbdict::restartCreateObj_prepare_start_done);
+  
+  createObjPtr.p->m_restart= file ? 1 : 2;
+  switch(new_entry->m_tableType){
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+    createObjPtr.p->m_vt_index = 0;
+    break;
+  case DictTabInfo::Datafile:
+  case DictTabInfo::Undofile:
+    createObjPtr.p->m_vt_index = 1;
+    break;
+  default:
+    ndbrequire(false);
+  }
+  
+  createObjPtr.p->m_obj_info_ptr_i = RNIL;
+  if(file)
+  {
+    c_readTableRecord.no_of_words = old_entry->m_info_words;
+    c_readTableRecord.pageId = 0;
+    c_readTableRecord.m_callback.m_callbackData = key;
+    c_readTableRecord.m_callback.m_callbackFunction = 
+      safe_cast(&Dbdict::restartCreateObj_readConf);
+    
+    startReadTableFile(signal, tableId);
+  }
+  else
+  {
+    /**
+     * Get from master
+     */
+    GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
+    req->senderRef = reference();
+    req->senderData = key;
+    req->requestType = GetTabInfoReq::RequestById |
+      GetTabInfoReq::LongSignalConf;
+    req->tableId = tableId;
+    sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
+	       GetTabInfoReq::SignalLength, JBB);
+  }
+}
+
+void
+Dbdict::restartCreateObj_getTabInfoConf(Signal* signal)
+{
+  jam();
+
+  GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
+
+  const Uint32 objId = conf->tableId;
+  const Uint32 senderData = conf->senderData;
+  
+  SegmentedSectionPtr objInfoPtr;
+  signal->getSection(objInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
+  
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.find(createObjPtr, senderData));
+  ndbrequire(createObjPtr.p->m_obj_id == objId);
+  
+  createObjPtr.p->m_obj_info_ptr_i= objInfoPtr.i;
+  signal->header.m_noOfSections = 0;
+  
+  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
+    (signal, createObjPtr.p);
+}
+
+void
+Dbdict::restartCreateObj_readConf(Signal* signal,
+				  Uint32 callbackData, 
+				  Uint32 returnCode)
+{
+  jam();
+  ndbrequire(returnCode == 0);
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  ndbrequire(createObjPtr.p->m_errorCode == 0);
+
+  PageRecordPtr pageRecPtr;
+  c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
+  
+  Uint32 sz = c_readTableRecord.no_of_words;
+
+  Ptr<SectionSegment> ptr;
+  ndbrequire(import(ptr, pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz));
+  createObjPtr.p->m_obj_info_ptr_i= ptr.i;  
+  
+  if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
+    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
+      (signal, createObjPtr.p);
+  else
+    execute(signal, createObjPtr.p->m_callback, 0);
+}
+
+void
+Dbdict::restartCreateObj_prepare_start_done(Signal* signal,
+					    Uint32 callbackData, 
+					    Uint32 returnCode)
+{
+  jam();
+  ndbrequire(returnCode == 0);
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  ndbrequire(createObjPtr.p->m_errorCode == 0);
+
+  Callback callback;
+  callback.m_callbackData = callbackData;
+  callback.m_callbackFunction = 
+    safe_cast(&Dbdict::restartCreateObj_write_complete);
+  
+  SegmentedSectionPtr objInfoPtr;
+  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
+
+  writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
+}
+
+void
+Dbdict::restartCreateObj_write_complete(Signal* signal,
+					Uint32 callbackData, 
+					Uint32 returnCode)
+{
+  ndbrequire(returnCode == 0);
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  ndbrequire(createObjPtr.p->m_errorCode == 0);
+  
+  SegmentedSectionPtr objInfoPtr;
+  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
+  signal->setSection(objInfoPtr, 0);
+  releaseSections(signal);
+  createObjPtr.p->m_obj_info_ptr_i = RNIL;
+  
+  createObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::restartCreateObj_prepare_complete_done);
+  
+  if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
+    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
+      (signal, createObjPtr.p);
+  else
+    execute(signal, createObjPtr.p->m_callback, 0);
+}
+
+void
+Dbdict::restartCreateObj_prepare_complete_done(Signal* signal,
+					       Uint32 callbackData, 
+					       Uint32 returnCode)
+{
+  jam();
+  ndbrequire(returnCode == 0);
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  ndbrequire(createObjPtr.p->m_errorCode == 0);
+
+  createObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::restartCreateObj_commit_start_done);
+
+  if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
+    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
+      (signal, createObjPtr.p);
+  else
+    execute(signal, createObjPtr.p->m_callback, 0);
+}
+
+void
+Dbdict::restartCreateObj_commit_start_done(Signal* signal,
+					   Uint32 callbackData, 
+					   Uint32 returnCode)
+{
+  jam();
+  ndbrequire(returnCode == 0);
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  ndbrequire(createObjPtr.p->m_errorCode == 0);
+
+  createObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::restartCreateObj_commit_complete_done);
+
+  if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
+    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
+      (signal, createObjPtr.p);
+  else
+    execute(signal, createObjPtr.p->m_callback, 0);
+}  
+
+
+void
+Dbdict::restartCreateObj_commit_complete_done(Signal* signal,
+					      Uint32 callbackData, 
+					      Uint32 returnCode)
+{
+  jam();
+  ndbrequire(returnCode == 0);
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  ndbrequire(createObjPtr.p->m_errorCode == 0);
+  
+  c_opCreateObj.release(createObjPtr);
+
+  c_restartRecord.activeTable++;
+  checkSchemaStatus(signal);
+}
+
 /* **************************************************************** */
 /* ---------------------------------------------------------------- */
 /* MODULE:          NODE FAILURE HANDLING ------------------------- */
@@ -2789,7 +3548,11 @@
   case BS_IDLE:
     jam();
     ok = true;
-    if(c_opRecordPool.getSize() != c_opRecordPool.getNoOfFree()){
+    if(c_opRecordPool.getSize() != 
+       (c_opRecordPool.getNoOfFree() + 
+	c_opSubEvent.get_count() + c_opCreateEvent.get_count() +
+	c_opDropEvent.get_count() + c_opSignalUtil.get_count()))
+    {
       jam();
       c_blockState = BS_NODE_FAILURE;
     }
@@ -2953,8 +3716,6 @@
       break;
     }
     
-    createTabPtr.p->key = ++c_opRecordSequence;
-    c_opCreateTable.add(createTabPtr);
     createTabPtr.p->m_errorCode = 0;
     createTabPtr.p->m_senderRef = senderRef;
     createTabPtr.p->m_senderData = senderData;
@@ -2963,26 +3724,58 @@
     createTabPtr.p->m_fragmentsPtrI = RNIL;
     createTabPtr.p->m_dihAddFragPtr = RNIL;
 
-    Uint32 * theData = signal->getDataPtrSend();
+    Uint32 key = c_opRecordSequence + 1;
+    Uint32 *theData = signal->getDataPtrSend();
+    Uint16 *frag_data= (Uint16*)&signal->theData[25];
     CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
     req->senderRef = reference();
-    req->senderData = createTabPtr.p->key;
+    req->senderData = key;
+    req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
+    req->noOfFragments = parseRecord.tablePtr.p->fragmentCount;
     req->fragmentationType = parseRecord.tablePtr.p->fragmentType;
-    req->noOfFragments = 0;
-    req->fragmentNode = 0;
-    req->primaryTableId = RNIL;
+    MEMCOPY_NO_WORDS(frag_data, c_fragData, c_fragDataLen);
+
     if (parseRecord.tablePtr.p->isOrderedIndex()) {
+      jam();
       // ordered index has same fragmentation as the table
-      const Uint32 primaryTableId = parseRecord.tablePtr.p->primaryTableId;
-      TableRecordPtr primaryTablePtr;
-      c_tableRecordPool.getPtr(primaryTablePtr, primaryTableId);
-      // fragmentationType must be consistent
-      req->fragmentationType = primaryTablePtr.p->fragmentType;
-      req->primaryTableId = primaryTableId;
+      req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
+      req->fragmentationType = DictTabInfo::DistrKeyOrderedIndex;
     }
-    sendSignal(DBDIH_REF, GSN_CREATE_FRAGMENTATION_REQ, signal,
-	       CreateFragmentationReq::SignalLength, JBB);
-    
+    else if (parseRecord.tablePtr.p->isHashIndex())
+    {
+      jam();
+      /*
+        Unique hash indexes has same amount of fragments as primary table
+        and distributed in the same manner but has always a normal hash
+        fragmentation.
+      */
+      req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
+      req->fragmentationType = DictTabInfo::DistrKeyUniqueHashIndex;
+    }
+    else
+    {
+      jam();
+      /*
+        Blob tables come here with primaryTableId != RNIL but we only need
+        it for creating the fragments so we set it to RNIL now that we got
+        what we wanted from it to avoid other side effects.
+      */
+      parseRecord.tablePtr.p->primaryTableId = RNIL;
+    }
+    EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
+		   CreateFragmentationReq::SignalLength);
+    jamEntry();
+    if (signal->theData[0] != 0)
+    {
+      jam();
+      parseRecord.errorCode= signal->theData[0];
+      c_opCreateTable.release(createTabPtr);
+      releaseTableObject(parseRecord.tablePtr.i, true);
+      break;
+    }
+    createTabPtr.p->key = key;
+    c_opRecordSequence++;
+    c_opCreateTable.add(createTabPtr);
     c_blockState = BS_CREATE_TAB;
     return;
   } while(0);
@@ -2990,8 +3783,8 @@
   /**
    * Something went wrong
    */
-  releaseSections(signal);
 
+  releaseSections(signal);
   CreateTableRef * ref = (CreateTableRef*)signal->getDataPtrSend();
   ref->senderData = senderData;
   ref->senderRef = reference();
@@ -3176,7 +3969,7 @@
 
   // Send prepare request to all alive nodes
   SimplePropertiesSectionWriter w(getSectionSegmentPool());
-  packTableIntoPagesImpl(w, parseRecord.tablePtr);
+  packTableIntoPages(w, parseRecord.tablePtr);
   
   SegmentedSectionPtr tabInfoPtr;
   w.getPtr(tabInfoPtr);
@@ -3246,7 +4039,7 @@
   lreq->clientData = alterTabPtr.p->m_senderData;
   lreq->changeMask = alterTabPtr.p->m_changeMask;
   lreq->tableId = tablePtr.p->tableId;
-  lreq->tableVersion = alter_table_inc_schema_version(tablePtr.p->tableVersion);
+  lreq->tableVersion = alter_obj_inc_schema_version(tablePtr.p->tableVersion);
   lreq->gci = tablePtr.p->gciTableCreated;
   lreq->requestType = AlterTabReq::AlterTablePrepare;
   
@@ -3376,7 +4169,7 @@
     }
     ndbrequire(ok);
 
-    if(alter_table_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){
+    if(alter_obj_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){
       jam();
       alterTabRef(signal, req, AlterTableRef::InvalidTableVersion);
       return;
@@ -3445,6 +4238,7 @@
     SegmentedSectionPtr tabInfoPtr;
     signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
     alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
+    bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
     
     signal->header.m_noOfSections = 0;
 
@@ -3456,7 +4250,10 @@
     SchemaFile::TableEntry tabEntry;
     tabEntry.m_tableVersion = tableVersion;
     tabEntry.m_tableType    = tablePtr.p->tableType;
-    tabEntry.m_tableState   = SchemaFile::ALTER_TABLE_COMMITTED;
+    if (savetodisk)
+      tabEntry.m_tableState   = SchemaFile::ALTER_TABLE_COMMITTED;
+    else
+      tabEntry.m_tableState   = SchemaFile::TEMPORARY_TABLE_COMMITTED;
     tabEntry.m_gcp          = gci;
     tabEntry.m_info_words   = tabInfoPtr.sz;
     memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
@@ -3466,7 +4263,7 @@
     callback.m_callbackFunction = 
       safe_cast(&Dbdict::alterTab_writeSchemaConf);
     
-    updateSchemaState(signal, tableId, &tabEntry, &callback);
+    updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
     break;
   }
   case(AlterTabReq::AlterTableRevert): {
@@ -3550,7 +4347,7 @@
       Uint32 tableVersion = tablePtr.p->tableVersion;
       Uint32 gci = tablePtr.p->gciTableCreated;
       SimplePropertiesSectionWriter w(getSectionSegmentPool());
-      packTableIntoPagesImpl(w, tablePtr);
+      packTableIntoPages(w, tablePtr);
       SegmentedSectionPtr spDataPtr;
       w.getPtr(spDataPtr);
       signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
@@ -3686,7 +4483,7 @@
 	Uint32 tableVersion = tablePtr.p->tableVersion;
 	Uint32 gci = tablePtr.p->gciTableCreated;
 	SimplePropertiesSectionWriter w(getSectionSegmentPool());
-	packTableIntoPagesImpl(w, tablePtr);
+	packTableIntoPages(w, tablePtr);
 	SegmentedSectionPtr spDataPtr;
 	w.getPtr(spDataPtr);
 	signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
@@ -3715,7 +4512,7 @@
 	TableRecordPtr tablePtr;
 	c_tableRecordPool.getPtr(tablePtr, tableId);
 	SimplePropertiesSectionWriter w(getSectionSegmentPool());
-	packTableIntoPagesImpl(w, tablePtr);
+	packTableIntoPages(w, tablePtr);
 	SegmentedSectionPtr spDataPtr;
 	w.getPtr(spDataPtr);
 	signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
@@ -3781,7 +4578,7 @@
       TableRecordPtr tabPtr;
       c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);  
       releaseTableObject(tabPtr.i, false);
-      c_opCreateTable.release(alterTabPtr);
+      releaseCreateTableOp(signal,alterTabPtr);
       c_blockState = BS_IDLE;
     }
     else {
@@ -3798,13 +4595,16 @@
 inline
 void Dbdict::printTables()
 {
-  DLHashTable<TableRecord>::Iterator iter;
-  bool moreTables = c_tableRecordHash.first(iter);
-  printf("TABLES IN DICT:\n");
+  DLHashTable<DictObject>::Iterator iter;
+  bool moreTables = c_obj_hash.first(iter);
+  printf("OBJECTS IN DICT:\n");
+  char name[MAX_TAB_NAME_SIZE];
   while (moreTables) {
-    TableRecordPtr tablePtr = iter.curr;
-    printf("%s ", tablePtr.p->tableName);
-    moreTables = c_tableRecordHash.next(iter);
+    Ptr<DictObject> tablePtr = iter.curr;
+    ConstRope r(c_rope_pool, tablePtr.p->m_name);
+    r.copy(name);
+    printf("%s ", name); 
+    moreTables = c_obj_hash.next(iter);
   }
   printf("\n");
 }
@@ -3814,31 +4614,61 @@
 			   TableRecordPtr origTablePtr,
 			   TableRecordPtr newTablePtr)
 {
+  bool supportedAlteration = false;
   Uint32 changeMask = req->changeMask;
   
   if (AlterTableReq::getNameFlag(changeMask)) {
     jam();
     // Table rename
+    supportedAlteration = true;
     // Remove from hashtable
-#ifdef VM_TRACE
-    TableRecordPtr tmp;
-    ndbrequire(c_tableRecordHash.find(tmp, *origTablePtr.p));
-#endif
-    c_tableRecordHash.remove(origTablePtr);
-    strcpy(alterTabPtrP->previousTableName, origTablePtr.p->tableName);
-    strcpy(origTablePtr.p->tableName, newTablePtr.p->tableName);
+    Ptr<DictObject> obj_ptr;
+    c_obj_pool.getPtr(obj_ptr, origTablePtr.p->m_obj_ptr_i);
+    c_obj_hash.remove(obj_ptr);
+    {
+      Rope org(c_rope_pool, origTablePtr.p->tableName);
+      org.copy(alterTabPtrP->previousTableName);
+      
+      ConstRope src(c_rope_pool, newTablePtr.p->tableName);
+      char tmp[MAX_TAB_NAME_SIZE];
+      const int len = src.size();
+      src.copy(tmp);
+      ndbrequire(org.assign(tmp, len));
+    }
+    obj_ptr.p->m_name = origTablePtr.p->tableName;
+    // Put it back
+    c_obj_hash.add(obj_ptr);
+  }
+
+  if (AlterTableReq::getFrmFlag(changeMask)) {
+    // Table definition changed (new frm)
+    supportedAlteration = true;
+    // Save old definition
+    Rope org(c_rope_pool, origTablePtr.p->frmData);
+    org.copy(alterTabPtrP->previousFrmData);
+    alterTabPtrP->previousFrmLen = org.size();
+
+    // Set new definition
+    ConstRope src(c_rope_pool, newTablePtr.p->frmData);
+    char tmp[MAX_FRM_DATA_SIZE];
+    src.copy(tmp);
+    ndbrequire(org.assign(tmp, src.size()));
+  }
+
+/*
+  TODO RONM: Lite ny kod för FragmentData och RangeOrListData
+*/
+  if (supportedAlteration)
+  {
     // Set new schema version
     origTablePtr.p->tableVersion = newTablePtr.p->tableVersion;
-    // Put it back
-#ifdef VM_TRACE
-    ndbrequire(!c_tableRecordHash.find(tmp, *origTablePtr.p));
-#endif
-    c_tableRecordHash.add(origTablePtr);	 
-    
     return 0;
   }
-  jam();
-  return -1;
+  else
+  {
+    jam();
+    return -1;
+  }
 }
 
 void Dbdict::revertAlterTable(Signal * signal, 
@@ -3846,31 +4676,51 @@
 			      Uint32 tableId,
 			      CreateTableRecord * alterTabPtrP)
 {
+  bool supportedAlteration = false;
+
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, tableId);
+  
   if (AlterTableReq::getNameFlag(changeMask)) {
     jam();
     // Table rename
+    supportedAlteration = true;
     // Restore previous name
-    TableRecordPtr tablePtr;
-    c_tableRecordPool.getPtr(tablePtr, tableId);
-    // Remove from hashtable
-#ifdef VM_TRACE
-    TableRecordPtr tmp;
-    ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p));
-#endif
-    c_tableRecordHash.remove(tablePtr);
-    // Restore name
-    strcpy(tablePtr.p->tableName, alterTabPtrP->previousTableName);
-    // Revert schema version
-    tablePtr.p->tableVersion = alter_table_dec_schema_version(tablePtr.p->tableVersion);
+
+    Ptr<DictObject> obj_ptr;
+    c_obj_pool.getPtr(obj_ptr, tablePtr.p->m_obj_ptr_i);
+    c_obj_hash.remove(obj_ptr);
+
+    {
+      // Restore name
+      Rope org(c_rope_pool, tablePtr.p->tableName);
+      ndbrequire(org.assign(alterTabPtrP->previousTableName));
+    }
+    obj_ptr.p->m_name = tablePtr.p->tableName;
     // Put it back
-#ifdef VM_TRACE
-    ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p));
-#endif
-    c_tableRecordHash.add(tablePtr);	 
+    c_obj_hash.add(obj_ptr);
+  }
 
-    return;
+  if (AlterTableReq::getFrmFlag(changeMask)) 
+  {
+    jam();
+    // Table redefinition
+    supportedAlteration = true;
+    // Restore previous frm
+    Rope org(c_rope_pool, tablePtr.p->tableName);
+    ndbrequire(org.assign(alterTabPtrP->previousFrmData, 
+			  alterTabPtrP->previousFrmLen));
+    
   }
+  
 
+  if (supportedAlteration)
+  {
+    tablePtr.p->tableVersion = 
+      alter_obj_dec_schema_version(tablePtr.p->tableVersion);
+    return;
+  }
+  
   ndbrequire(false);
 }
 
@@ -3890,13 +4740,19 @@
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::alterTab_writeTableConf);
   
-  SegmentedSectionPtr tabInfoPtr;
-  getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
-  
-  writeTableFile(signal, tableId, tabInfoPtr, &callback);
-
-  signal->setSection(tabInfoPtr, 0);
-  releaseSections(signal);
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, tableId);
+  bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
+  if (savetodisk)
+  {
+    SegmentedSectionPtr tabInfoPtr;
+    getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
+    writeTableFile(signal, tableId, tabInfoPtr, &callback);
+  }
+  else
+  {
+    execute(signal, callback, 0);
+  }
 }
 
 void
@@ -3910,8 +4766,27 @@
   Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef;
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId);
-
   // Alter table commit request handled successfully 
+  // Inform Suma so it can send events to any subscribers of the table
+  AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
+  if (coordinatorRef == reference())
+    req->senderRef = alterTabPtr.p->m_senderRef;
+  else
+    req->senderRef = 0;
+  req->senderData = callbackData;
+  req->tableId = tabPtr.p->tableId;
+  req->tableVersion = tabPtr.p->tableVersion;
+  req->gci = tabPtr.p->gciTableCreated;
+  req->requestType = AlterTabReq::AlterTableCommit;
+  req->changeMask = alterTabPtr.p->m_changeMask;
+  SegmentedSectionPtr tabInfoPtr;
+  getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
+  signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
+  EXECUTE_DIRECT(SUMA, GSN_ALTER_TAB_REQ, signal,
+                 AlterTabReq::SignalLength);
+  releaseSections(signal);
+  alterTabPtr.p->m_tabInfoPtrI = RNIL;
+  jamEntry();
   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
   conf->senderRef = reference();
   conf->senderData = callbackData;
@@ -3919,6 +4794,7 @@
   conf->tableVersion = tabPtr.p->tableVersion;
   conf->gci = tabPtr.p->gciTableCreated;
   conf->requestType = AlterTabReq::AlterTableCommit;
+  conf->changeMask = alterTabPtr.p->m_changeMask;
   sendSignal(coordinatorRef, GSN_ALTER_TAB_CONF, signal, 
 	       AlterTabConf::SignalLength, JBB);
 
@@ -3930,7 +4806,7 @@
 
     AlterTableRep* rep = (AlterTableRep*)api->theData;
     rep->tableId = tabPtr.p->tableId;
-    rep->tableVersion = alter_table_dec_schema_version(tabPtr.p->tableVersion);
+    rep->tableVersion = alter_obj_dec_schema_version(tabPtr.p->tableVersion);
     rep->changeType = AlterTableRep::CT_ALTERED;
     
     LinearSectionPtr ptr[3];
@@ -3947,7 +4823,7 @@
     // Release resources
     c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);  
     releaseTableObject(tabPtr.i, false);
-    c_opCreateTable.release(alterTabPtr);
+    releaseCreateTableOp(signal,alterTabPtr);
     c_blockState = BS_IDLE;
   }
 }
@@ -3993,20 +4869,21 @@
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
   SchemaFile::TableEntry * tabEntry = getTableEntry(xsf, tabPtr.i);
 
-  tabPtr.p->tableVersion = create_table_inc_schema_version(tabEntry->m_tableVersion);
+  tabPtr.p->tableVersion = 
+    create_obj_inc_schema_version(tabEntry->m_tableVersion);
 
   /**
    * Pack
    */
   SimplePropertiesSectionWriter w(getSectionSegmentPool());
-  packTableIntoPagesImpl(w, tabPtr);
+  packTableIntoPages(w, tabPtr);
   
   SegmentedSectionPtr spDataPtr;
   w.getPtr(spDataPtr);
   
   signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO);
   signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION);
-  
+ 
   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
   SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
   createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
@@ -4022,7 +4899,7 @@
 
   req->gci = 0;
   req->tableId = tabPtr.i;
-  req->tableVersion = create_table_inc_schema_version(tabEntry->m_tableVersion);
+  req->tableVersion = create_obj_inc_schema_version(tabEntry->m_tableVersion);
   
   sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal, 
 		       CreateTabReq::SignalLength, JBB);
@@ -4137,7 +5014,7 @@
     //@todo check api failed
     sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_REF, signal, 
 	       CreateTableRef::SignalLength, JBB);
-    c_opCreateTable.release(createTabPtr);
+    releaseCreateTableOp(signal,createTabPtr);
     c_blockState = BS_IDLE;
     return;
   }
@@ -4196,7 +5073,7 @@
   //@todo check api failed
   sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_CONF, signal, 
 	     CreateTableConf::SignalLength, JBB);
-  c_opCreateTable.release(createTabPtr);
+  releaseCreateTableOp(signal,createTabPtr);
   c_blockState = BS_IDLE;
   return;
 }
@@ -4305,7 +5182,8 @@
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::createTab_writeSchemaConf1);
   
-  updateSchemaState(signal, tableId, &tabEntry, &callback);
+  bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
+  updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
 }
 
 void getSection(SegmentedSectionPtr & ptr, Uint32 i);
@@ -4324,13 +5202,24 @@
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::createTab_writeTableConf);
   
-  SegmentedSectionPtr tabInfoPtr;
-  getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
-  writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
-
+  TableRecordPtr tabPtr;
+  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
+  bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
+  if (savetodisk)
+  {
+    SegmentedSectionPtr tabInfoPtr;
+    getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
+    writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
+  }
+  else
+  {
+    execute(signal, callback, 0);
+  }
+#if 0
   createTabPtr.p->m_tabInfoPtrI = RNIL;
   signal->setSection(tabInfoPtr, 0);
   releaseSections(signal);
+#endif
 }
 
 void
@@ -4371,11 +5260,15 @@
   req->fragType = tabPtr.p->fragmentType;
   req->kValue = tabPtr.p->kValue;
   req->noOfReplicas = 0;
-  req->storedTable = tabPtr.p->storedTable;
+  req->loggedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged);
   req->tableType = tabPtr.p->tableType;
   req->schemaVersion = tabPtr.p->tableVersion;
   req->primaryTableId = tabPtr.p->primaryTableId;
+  req->temporaryTable = !!(tabPtr.p->m_bits & TableRecord::TR_Temporary);
 
+/*
+  Behöver fiska upp fragDataPtr frĺn table object istället
+*/
   if(!fragDataPtr.isNull()){
     signal->setSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
   }
@@ -4390,34 +5283,39 @@
   new (desc) KeyDescriptor();
 
   Uint32 key = 0;
-  Uint32 tAttr = tabPtr.p->firstAttribute;
-  while (tAttr != RNIL) 
+  Ptr<AttributeRecord> attrPtr;
+  LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
+                                        tabPtr.p->m_attributes);
+  for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr))
   {
-    jam();
-    AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
-    if (aRec->tupleKey) 
+    AttributeRecord* aRec = attrPtr.p;
+    if (aRec->tupleKey)
     {
+      Uint32 attr = aRec->attributeDescriptor;
+
       desc->noOfKeyAttr ++;
-      desc->keyAttr[key].attributeDescriptor = aRec->attributeDescriptor;
-      
+      desc->keyAttr[key].attributeDescriptor = attr;
       Uint32 csNumber = (aRec->extPrecision >> 16);
-      if(csNumber)
+      if (csNumber)
       {
-	desc->keyAttr[key].charsetInfo = all_charsets[csNumber];
-	ndbrequire(all_charsets[csNumber]);
-	desc->hasCharAttr = 1;
+        desc->keyAttr[key].charsetInfo = all_charsets[csNumber];
+        ndbrequire(all_charsets[csNumber] != 0);
+        desc->hasCharAttr = 1;
       }
       else
       {
-	desc->keyAttr[key].charsetInfo = 0;	  
+        desc->keyAttr[key].charsetInfo = 0;
       }
-      if(AttributeDescriptor::getDKey(aRec->attributeDescriptor))
+      if (AttributeDescriptor::getDKey(attr))
       {
-	desc->noOfDistrKeys ++;
+        desc->noOfDistrKeys ++;
+      }
+      if (AttributeDescriptor::getArrayType(attr) != NDB_ARRAYTYPE_FIXED)
+      {
+        desc->noOfVarKeys ++;
       }
       key++;
     }
-    tAttr = aRec->nextAttrInTable;
   }
   ndbrequire(key == tabPtr.p->noOfPrimkey);
 }
@@ -4465,6 +5363,7 @@
   Uint32 fragCount = req->totalFragments;
   Uint32 requestInfo = req->requestInfo;
   Uint32 startGci = req->startGci;
+  Uint32 logPart = req->logPartId;
 
   ndbrequire(node == getOwnNodeId());
 
@@ -4520,14 +5419,15 @@
     req->nextLCP = lcpNo;
 
     req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
-    req->noOfNewAttr = 0;
     req->noOfCharsets = tabPtr.p->noOfCharsets;
     req->checksumIndicator = 1;
-    req->noOfAttributeGroups = 1;
-    req->GCPIndicator = 0;
+    req->GCPIndicator = 1;
     req->startGci = startGci;
     req->tableType = tabPtr.p->tableType;
     req->primaryTableId = tabPtr.p->primaryTableId;
+    req->tablespace_id= tabPtr.p->m_tablespace_id;
+    req->logPartId = logPart;
+    req->forceVarPartFlag = !!(tabPtr.p->m_bits& TableRecord::TR_ForceVarPart);
     sendSignal(DBLQH_REF, GSN_LQHFRAGREQ, signal, 
 	       LqhFragReq::SignalLength, JBB);
   }
@@ -4563,7 +5463,7 @@
   
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-  sendLQHADDATTRREQ(signal, createTabPtr, tabPtr.p->firstAttribute);
+  sendLQHADDATTRREQ(signal, createTabPtr, tabPtr.p->m_attributes.firstItem);
 }
 
 void
@@ -4587,7 +5487,7 @@
     entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
     if (tabPtr.p->isIndex()) {
       Uint32 primaryAttrId;
-      if (attrPtr.p->nextAttrInTable != RNIL) {
+      if (attrPtr.p->nextList != RNIL) {
         getIndexAttr(tabPtr, attributePtrI, &primaryAttrId);
       } else {
         primaryAttrId = ZNIL;
@@ -4596,7 +5496,7 @@
       }
       entry.attrId |= (primaryAttrId << 16);
     }
-    attributePtrI = attrPtr.p->nextAttrInTable;
+    attributePtrI = attrPtr.p->nextList;
   }
   req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr;
   req->senderData = createTabPtr.p->key;
@@ -4720,7 +5620,7 @@
     
     signal->theData[0] = tabPtr.i;
     signal->theData[1] = tabPtr.p->tableVersion;
-    signal->theData[2] = (Uint32)tabPtr.p->storedTable;     
+    signal->theData[2] = (Uint32)!!(tabPtr.p->m_bits & TableRecord::TR_Logged);
     signal->theData[3] = reference();
     signal->theData[4] = (Uint32)tabPtr.p->tableType;
     signal->theData[5] = createTabPtr.p->key;
@@ -4777,11 +5677,16 @@
 
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-  
+  bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
+
   SchemaFile::TableEntry tabEntry;
   tabEntry.m_tableVersion = tabPtr.p->tableVersion;
   tabEntry.m_tableType    = tabPtr.p->tableType;
-  tabEntry.m_tableState   = SchemaFile::TABLE_ADD_COMMITTED;
+  if (savetodisk)
+    tabEntry.m_tableState   = SchemaFile::TABLE_ADD_COMMITTED;
+  else
+    tabEntry.m_tableState   = SchemaFile::TEMPORARY_TABLE_COMMITTED;
+    
   tabEntry.m_gcp          = tabPtr.p->gciTableCreated;
   tabEntry.m_info_words   = tabPtr.p->packedSize;
   memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
@@ -4791,7 +5696,7 @@
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::createTab_writeSchemaConf2);
   
-  updateSchemaState(signal, tabPtr.i, &tabEntry, &callback);
+  updateSchemaState(signal, tabPtr.i, &tabEntry, &callback, savetodisk);
 }
 
 void
@@ -4828,12 +5733,28 @@
   CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
   conf->senderRef = reference();
   conf->senderData = createTabPtr.p->key;
+  {
+    CreateTabConf tmp= *conf;
+    conf->senderData = createTabPtr.p->m_tablePtrI;
+#if 0
+    signal->header.m_noOfSections = 1;
+    SegmentedSectionPtr tabInfoPtr;
+    getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
+    signal->setSection(tabInfoPtr, 0);
+#endif
+    sendSignal(SUMA_REF, GSN_CREATE_TAB_CONF, signal,
+		CreateTabConf::SignalLength, JBB);
+    *conf= tmp;
+#if 0
+    signal->header.m_noOfSections = 0;
+#endif
+  }
   sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
 	     signal, CreateTabConf::SignalLength, JBB);
 
   if(createTabPtr.p->m_coordinatorRef != reference()){
     jam();
-    c_opCreateTable.release(createTabPtr);
+    releaseCreateTableOp(signal,createTabPtr);
   }
 }
 
@@ -4867,6 +5788,13 @@
   dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createTab_dropComplete);
   dropTab_nextStep(signal, dropTabPtr);  
+
+  if (tabPtr.p->m_tablespace_id != RNIL)
+  {
+    FilegroupPtr ptr;
+    ndbrequire(c_filegroup_hash.find(ptr, tabPtr.p->m_tablespace_id));
+    decrease_ref_count(ptr.p->m_obj_ptr_i);
+  }
 }
 
 void
@@ -4901,7 +5829,7 @@
 
   if(createTabPtr.p->m_coordinatorRef != reference()){
     jam();
-    c_opCreateTable.release(createTabPtr);
+    releaseCreateTableOp(signal,createTabPtr);
   }
 
   c_opDropTable.release(dropTabPtr);
@@ -4939,6 +5867,42 @@
 
 // handleAddTableFailure(signal, __LINE__, allocatedTable);
 
+Dbdict::DictObject *
+Dbdict::get_object(const char * name, Uint32 len, Uint32 hash){
+  DictObject key;
+  key.m_key.m_name_ptr = name;
+  key.m_key.m_name_len = len;
+  key.m_key.m_pool = &c_rope_pool;
+  key.m_name.m_hash = hash;
+  Ptr<DictObject> old_ptr;
+  c_obj_hash.find(old_ptr, key);
+  return old_ptr.p;
+}
+
+void
+Dbdict::release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p){
+  Rope name(c_rope_pool, obj_ptr_p->m_name);
+  name.erase();
+
+  Ptr<DictObject> ptr = { obj_ptr_p, obj_ptr_i };
+  c_obj_hash.release(ptr);
+}
+
+void
+Dbdict::increase_ref_count(Uint32 obj_ptr_i)
+{
+  DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i);
+  ptr->m_ref_count++;  
+}
+
+void
+Dbdict::decrease_ref_count(Uint32 obj_ptr_i)
+{
+  DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i);
+  ndbrequire(ptr->m_ref_count);
+  ptr->m_ref_count--;  
+}
+
 void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
 			       ParseDictTabInfoRecord * parseP,
 			       bool checkExist) 
@@ -4952,8 +5916,8 @@
   it.first();
 
   SimpleProperties::UnpackStatus status;
-  DictTabInfo::Table tableDesc; tableDesc.init();
-  status = SimpleProperties::unpack(it, &tableDesc, 
+  c_tableDesc.init();
+  status = SimpleProperties::unpack(it, &c_tableDesc, 
 				    DictTabInfo::TableMapping, 
 				    DictTabInfo::TableMappingSize, 
 				    true, true);
@@ -4979,31 +5943,23 @@
   // Verify that table name is an allowed table name.
   // TODO
   /* ---------------------------------------------------------------- */
-  const Uint32 tableNameLength = strlen(tableDesc.TableName) + 1;
+  const Uint32 tableNameLength = strlen(c_tableDesc.TableName) + 1;
+  const Uint32 name_hash = Rope::hash(c_tableDesc.TableName, tableNameLength);
 
-  TableRecord keyRecord;
-  tabRequire(tableNameLength <= sizeof(keyRecord.tableName),
-	     CreateTableRef::TableNameTooLong);
-  strcpy(keyRecord.tableName, tableDesc.TableName);
-  
-  TableRecordPtr tablePtr;
-  c_tableRecordHash.find(tablePtr, keyRecord);
-  
-  if (checkExist){
+  if(checkExist){
     jam();
-    /* ---------------------------------------------------------------- */
-    // Check if table already existed.
-    /* ---------------------------------------------------------------- */
-    tabRequire(tablePtr.i == RNIL, CreateTableRef::TableAlreadyExist);
+    tabRequire(get_object(c_tableDesc.TableName, tableNameLength) == 0, 
+	       CreateTableRef::TableAlreadyExist);
   }
-
+  
+  TableRecordPtr tablePtr;
   switch (parseP->requestType) {
   case DictTabInfo::CreateTableFromAPI: {
     jam();
   }
   case DictTabInfo::AlterTableFromAPI:{
     jam();
-    tablePtr.i = getFreeTableRecord(tableDesc.PrimaryTableId);
+    tablePtr.i = getFreeTableRecord(c_tableDesc.PrimaryTableId);
     /* ---------------------------------------------------------------- */
     // Check if no free tables existed.
     /* ---------------------------------------------------------------- */
@@ -5019,7 +5975,7 @@
 /* ---------------------------------------------------------------- */
 // Get table id and check that table doesn't already exist
 /* ---------------------------------------------------------------- */
-    tablePtr.i = tableDesc.TableId;
+    tablePtr.i = c_tableDesc.TableId;
     
     if (parseP->requestType == DictTabInfo::ReadTableFromDiskSR) {
       ndbrequire(tablePtr.i == c_restartRecord.activeTable);
@@ -5037,25 +5993,11 @@
       jam();
       tablePtr.p->tabState = TableRecord::DEFINING;
     }//if
-#ifdef HAVE_TABLE_REORG
-/* ---------------------------------------------------------------- */
-// Get id of second table id and check that table doesn't already exist
-// and set up links between first and second table.
-/* ---------------------------------------------------------------- */
-    TableRecordPtr secondTablePtr;
-    secondTablePtr.i = tableDesc.SecondTableId;
-    c_tableRecordPool.getPtr(secondTablePtr);
-    ndbrequire(secondTablePtr.p->tabState == TableRecord::NOT_DEFINED);
-    
-    initialiseTableRecord(secondTablePtr);
-    secondTablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED;
-    secondTablePtr.p->secondTable = tablePtr.i;
-    tablePtr.p->secondTable = secondTablePtr.i;
-#endif
+
 /* ---------------------------------------------------------------- */
 // Set table version
 /* ---------------------------------------------------------------- */
-    Uint32 tableVersion = tableDesc.TableVersion;
+    Uint32 tableVersion = c_tableDesc.TableVersion;
     tablePtr.p->tableVersion = tableVersion;
     
     break;
@@ -5066,45 +6008,89 @@
   }//switch
   parseP->tablePtr = tablePtr;
   
-  strcpy(tablePtr.p->tableName, keyRecord.tableName);  
+  { 
+    Rope name(c_rope_pool, tablePtr.p->tableName);
+    tabRequire(name.assign(c_tableDesc.TableName, tableNameLength, name_hash),
+	       CreateTableRef::OutOfStringBuffer);
+  }
+
+  Ptr<DictObject> obj_ptr;
   if (parseP->requestType != DictTabInfo::AlterTableFromAPI) {
     jam();
+    ndbrequire(c_obj_hash.seize(obj_ptr));
+    obj_ptr.p->m_id = tablePtr.i;
+    obj_ptr.p->m_type = c_tableDesc.TableType;
+    obj_ptr.p->m_name = tablePtr.p->tableName;
+    obj_ptr.p->m_ref_count = 0;
+    c_obj_hash.add(obj_ptr);
+    tablePtr.p->m_obj_ptr_i = obj_ptr.i;
+
 #ifdef VM_TRACE
-    ndbout_c("Dbdict: name=%s,id=%u", tablePtr.p->tableName, tablePtr.i);
-    TableRecordPtr tmp;
-    ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p));
-#endif
-    c_tableRecordHash.add(tablePtr);
-  }
-  
-  //tablePtr.p->noOfPrimkey = tableDesc.NoOfKeyAttr;
-  //tablePtr.p->noOfNullAttr = tableDesc.NoOfNullable;
-  //tablePtr.p->tupKeyLength = tableDesc.KeyLength;
-  tablePtr.p->noOfAttributes = tableDesc.NoOfAttributes;
-  tablePtr.p->storedTable = tableDesc.TableLoggedFlag;
-  tablePtr.p->minLoadFactor = tableDesc.MinLoadFactor;
-  tablePtr.p->maxLoadFactor = tableDesc.MaxLoadFactor;
-  tablePtr.p->fragmentType = (DictTabInfo::FragmentType)tableDesc.FragmentType;
-  tablePtr.p->tableType = (DictTabInfo::TableType)tableDesc.TableType;
-  tablePtr.p->kValue = tableDesc.TableKValue;
-  tablePtr.p->fragmentCount = tableDesc.FragmentCount;
-  tablePtr.p->maxRowsLow = tableDesc.MaxRowsLow;
-  tablePtr.p->maxRowsHigh = tableDesc.MaxRowsHigh;
-  tablePtr.p->minRowsLow = tableDesc.MinRowsLow;
-  tablePtr.p->minRowsHigh = tableDesc.MinRowsHigh;
-  tablePtr.p->singleUserMode = tableDesc.SingleUserMode;
-
-  tablePtr.p->frmLen = tableDesc.FrmLen;
-  memcpy(tablePtr.p->frmData, tableDesc.FrmData, tableDesc.FrmLen);  
-
-  if(tableDesc.PrimaryTableId != RNIL) {
-    
-    tablePtr.p->primaryTableId = tableDesc.PrimaryTableId;
-    tablePtr.p->indexState = (TableRecord::IndexState)tableDesc.IndexState;
-    tablePtr.p->insertTriggerId = tableDesc.InsertTriggerId;
-    tablePtr.p->updateTriggerId = tableDesc.UpdateTriggerId;
-    tablePtr.p->deleteTriggerId = tableDesc.DeleteTriggerId;
-    tablePtr.p->customTriggerId = tableDesc.CustomTriggerId;
+    ndbout_c("Dbdict: name=%s,id=%u,obj_ptr_i=%d", 
+	     c_tableDesc.TableName, tablePtr.i, tablePtr.p->m_obj_ptr_i);
+#endif
+  }
+  
+  // Disallow logging of a temporary table.
+  tabRequire(!(c_tableDesc.TableTemporaryFlag && c_tableDesc.TableLoggedFlag),
+             CreateTableRef::NoLoggingTemporaryTable);
+
+  tablePtr.p->noOfAttributes = c_tableDesc.NoOfAttributes;
+  tablePtr.p->m_bits |= 
+    (c_tableDesc.TableLoggedFlag ? TableRecord::TR_Logged : 0);
+  tablePtr.p->m_bits |= 
+    (c_tableDesc.RowChecksumFlag ? TableRecord::TR_RowChecksum : 0);
+  tablePtr.p->m_bits |= 
+    (c_tableDesc.RowGCIFlag ? TableRecord::TR_RowGCI : 0);
+  tablePtr.p->m_bits |= 
+    (c_tableDesc.TableTemporaryFlag ? TableRecord::TR_Temporary : 0);
+  tablePtr.p->m_bits |=
+    (c_tableDesc.ForceVarPartFlag ? TableRecord::TR_ForceVarPart : 0);
+  tablePtr.p->minLoadFactor = c_tableDesc.MinLoadFactor;
+  tablePtr.p->maxLoadFactor = c_tableDesc.MaxLoadFactor;
+  tablePtr.p->fragmentType = (DictTabInfo::FragmentType)c_tableDesc.FragmentType;
+  tablePtr.p->tableType = (DictTabInfo::TableType)c_tableDesc.TableType;
+  tablePtr.p->kValue = c_tableDesc.TableKValue;
+  tablePtr.p->fragmentCount = c_tableDesc.FragmentCount;
+  tablePtr.p->m_tablespace_id = c_tableDesc.TablespaceId; 
+  tablePtr.p->maxRowsLow = c_tableDesc.MaxRowsLow; 
+  tablePtr.p->maxRowsHigh = c_tableDesc.MaxRowsHigh; 
+  tablePtr.p->minRowsLow = c_tableDesc.MinRowsLow;
+  tablePtr.p->minRowsHigh = c_tableDesc.MinRowsHigh;
+  tablePtr.p->defaultNoPartFlag = c_tableDesc.DefaultNoPartFlag; 
+  tablePtr.p->linearHashFlag = c_tableDesc.LinearHashFlag; 
+  tablePtr.p->singleUserMode = c_tableDesc.SingleUserMode;
+  
+  {
+    Rope frm(c_rope_pool, tablePtr.p->frmData);
+    tabRequire(frm.assign(c_tableDesc.FrmData, c_tableDesc.FrmLen),
+	       CreateTableRef::OutOfStringBuffer);
+    Rope range(c_rope_pool, tablePtr.p->rangeData);
+    tabRequire(range.assign(c_tableDesc.RangeListData,
+               c_tableDesc.RangeListDataLen),
+	      CreateTableRef::OutOfStringBuffer);
+    Rope fd(c_rope_pool, tablePtr.p->ngData);
+    tabRequire(fd.assign((const char*)c_tableDesc.FragmentData,
+                         c_tableDesc.FragmentDataLen),
+	       CreateTableRef::OutOfStringBuffer);
+    Rope ts(c_rope_pool, tablePtr.p->tsData);
+    tabRequire(ts.assign((const char*)c_tableDesc.TablespaceData,
+                         c_tableDesc.TablespaceDataLen),
+	       CreateTableRef::OutOfStringBuffer);
+  }
+  
+  c_fragDataLen = c_tableDesc.FragmentDataLen;
+  memcpy(c_fragData, c_tableDesc.FragmentData,
+         c_tableDesc.FragmentDataLen);
+
+  if(c_tableDesc.PrimaryTableId != RNIL) {
+    
+    tablePtr.p->primaryTableId = c_tableDesc.PrimaryTableId;
+    tablePtr.p->indexState = (TableRecord::IndexState)c_tableDesc.IndexState;
+    tablePtr.p->insertTriggerId = c_tableDesc.InsertTriggerId;
+    tablePtr.p->updateTriggerId = c_tableDesc.UpdateTriggerId;
+    tablePtr.p->deleteTriggerId = c_tableDesc.DeleteTriggerId;
+    tablePtr.p->customTriggerId = c_tableDesc.CustomTriggerId;
   } else {
     tablePtr.p->primaryTableId = RNIL;
     tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
@@ -5116,19 +6102,31 @@
   tablePtr.p->buildTriggerId = RNIL;
   tablePtr.p->indexLocal = 0;
   
-  handleTabInfo(it, parseP);
-
+  handleTabInfo(it, parseP, c_tableDesc);
+  
   if(parseP->errorCode != 0)
   {
     /**
      * Release table
      */
     releaseTableObject(tablePtr.i, checkExist);
+    return;
+  }
+
+  if (checkExist && tablePtr.p->m_tablespace_id != RNIL)
+  {
+    /**
+     * Increase ref count
+     */
+    FilegroupPtr ptr;
+    ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
+    increase_ref_count(ptr.p->m_obj_ptr_i);
   }
 }//handleTabInfoInit()
 
 void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
-			   ParseDictTabInfoRecord * parseP)
+			   ParseDictTabInfoRecord * parseP,
+			   DictTabInfo::Table &tableDesc)
 {
   TableRecordPtr tablePtr = parseP->tablePtr;
   
@@ -5144,6 +6142,11 @@
   Uint32 recordLength = 0;
   AttributeRecordPtr attrPtr;
   c_attributeRecordHash.removeAll();
+
+  LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool, 
+					tablePtr.p->m_attributes);
+
+  Uint32 counts[] = {0,0,0,0,0};
   
   for(Uint32 i = 0; i<attrCount; i++){
     /**
@@ -5154,6 +6157,7 @@
 				      DictTabInfo::AttributeMapping, 
 				      DictTabInfo::AttributeMappingSize, 
 				      true, true);
+    
     if(status != SimpleProperties::Break){
       parseP->errorCode = CreateTableRef::InvalidFormat;
       parseP->status    = status;
@@ -5165,32 +6169,51 @@
     /**
      * Check that attribute is not defined twice
      */
-    AttributeRecord tmpAttr;
+    const size_t len = strlen(attrDesc.AttributeName)+1;
+    const Uint32 name_hash = Rope::hash(attrDesc.AttributeName, len);
     {
-      strcpy(tmpAttr.attributeName, attrDesc.AttributeName); 
-      
-      AttributeRecordPtr attrPtr;
-      c_attributeRecordHash.find(attrPtr, tmpAttr);
+      AttributeRecord key;
+      key.m_key.m_name_ptr = attrDesc.AttributeName;
+      key.m_key.m_name_len = len;
+      key.attributeName.m_hash = name_hash;
+      key.m_key.m_pool = &c_rope_pool;
+      Ptr<AttributeRecord> old_ptr;
+      c_attributeRecordHash.find(old_ptr, key);
       
-      if(attrPtr.i != RNIL){
+      if(old_ptr.i != RNIL){
 	parseP->errorCode = CreateTableRef::AttributeNameTwice;
 	return;
       }
     }
     
-    if(!getNewAttributeRecord(tablePtr, attrPtr)){
+    list.seize(attrPtr);
+    if(attrPtr.i == RNIL){
       jam();
       parseP->errorCode = CreateTableRef::NoMoreAttributeRecords;
       return;
     }
     
+    new (attrPtr.p) AttributeRecord();
+    attrPtr.p->attributeDescriptor = 0x00012255; //Default value
+    attrPtr.p->tupleKey = 0;
+    
     /**
      * TmpAttrib to Attribute mapping
      */
-    strcpy(attrPtr.p->attributeName, attrDesc.AttributeName);
-    attrPtr.p->attributeId = attrDesc.AttributeId;
+    {
+      Rope name(c_rope_pool, attrPtr.p->attributeName);
+      if (!name.assign(attrDesc.AttributeName, len, name_hash))
+      {
+	jam();
+	parseP->errorCode = CreateTableRef::OutOfStringBuffer;
+	parseP->errorLine = __LINE__;
+	return;
+      }
+    }
+    attrPtr.p->attributeId = i;
+    //attrPtr.p->attributeId = attrDesc.AttributeId;
     attrPtr.p->tupleKey = (keyCount + 1) * attrDesc.AttributeKeyFlag;
-
+    
     attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision;
     attrPtr.p->extScale = attrDesc.AttributeExtScale;
     attrPtr.p->extLength = attrDesc.AttributeExtLength;
@@ -5238,20 +6261,30 @@
       return;
     }
     
+    // XXX old test option, remove
+    if(!attrDesc.AttributeKeyFlag && 
+       tablePtr.i > 1 &&
+       !tablePtr.p->isIndex())
+    {
+      //attrDesc.AttributeStorageType= NDB_STORAGETYPE_DISK;
+    }
+
     Uint32 desc = 0;
     AttributeDescriptor::setType(desc, attrDesc.AttributeExtType);
     AttributeDescriptor::setSize(desc, attrDesc.AttributeSize);
-    AttributeDescriptor::setArray(desc, attrDesc.AttributeArraySize);
+    AttributeDescriptor::setArraySize(desc, attrDesc.AttributeArraySize);
+    AttributeDescriptor::setArrayType(desc, attrDesc.AttributeArrayType);
     AttributeDescriptor::setNullable(desc, attrDesc.AttributeNullableFlag);
     AttributeDescriptor::setDKey(desc, attrDesc.AttributeDKey);
     AttributeDescriptor::setPrimaryKey(desc, attrDesc.AttributeKeyFlag);
+    AttributeDescriptor::setDiskBased(desc, attrDesc.AttributeStorageType == NDB_STORAGETYPE_DISK);
     attrPtr.p->attributeDescriptor = desc;
     attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement;
-    strcpy(attrPtr.p->defaultValue, attrDesc.AttributeDefaultValue);
-    
-    tabRequire(attrDesc.AttributeId == i, CreateTableRef::InvalidFormat);
+    {
+      Rope defaultValue(c_rope_pool, attrPtr.p->defaultValue);
+      defaultValue.assign(attrDesc.AttributeDefaultValue);
+    }
     
-    attrCount ++;
     keyCount += attrDesc.AttributeKeyFlag;
     nullCount += attrDesc.AttributeNullableFlag;
     
@@ -5289,8 +6322,21 @@
       }
     }
     
-    if (parseP->requestType != DictTabInfo::AlterTableFromAPI)
-      c_attributeRecordHash.add(attrPtr);
+    c_attributeRecordHash.add(attrPtr);
+
+    int a= AttributeDescriptor::getDiskBased(desc);
+    int b= AttributeDescriptor::getArrayType(desc);
+    Uint32 pos= 2*(a ? 1 : 0) + (b == NDB_ARRAYTYPE_FIXED ? 0 : 1);
+    counts[pos+1]++;
+
+    if(b != NDB_ARRAYTYPE_FIXED && sz == 0)
+    {
+      parseP->errorCode = CreateTableRef::VarsizeBitfieldNotSupported;
+      parseP->status    = status;
+      parseP->errorKey  = it.getKey();
+      parseP->errorLine = __LINE__;
+      return;
+    }
     
     if(!it.next())
       break;
@@ -5311,7 +6357,25 @@
 	     CreateTableRef::InvalidPrimaryKeySize);
   tabRequire(keyLength > 0, 
 	     CreateTableRef::InvalidPrimaryKeySize);
-  
+
+  if(tablePtr.p->m_tablespace_id != RNIL || counts[3] || counts[4])
+  {
+    FilegroupPtr tablespacePtr;
+    if(!c_filegroup_hash.find(tablespacePtr, tablePtr.p->m_tablespace_id))
+    {
+      tabRequire(false, CreateTableRef::InvalidTablespace);
+    }
+    
+    if(tablespacePtr.p->m_type != DictTabInfo::Tablespace)
+    {
+      tabRequire(false, CreateTableRef::NotATablespace);
+    }
+    
+    if(tablespacePtr.p->m_version != tableDesc.TablespaceVersion)
+    {
+      tabRequire(false, CreateTableRef::InvalidTablespaceVersion);
+    }
+  }
 }//handleTabInfo()
 
 
@@ -5736,7 +6800,6 @@
   conf->senderData = dropTabPtr.p->m_request.senderData;
   conf->tableId = dropTabPtr.p->m_request.tableId;
   conf->tableVersion = dropTabPtr.p->m_request.tableVersion;
-  
   Uint32 ref = dropTabPtr.p->m_request.senderRef;
   sendSignal(ref, GSN_DROP_TABLE_CONF, signal, 
 	     DropTableConf::SignalLength, JBB);
@@ -5787,21 +6850,31 @@
   SchemaFile::TableState tabState = 
     (SchemaFile::TableState)tableEntry->m_tableState;
   ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED ||
-	     tabState == SchemaFile::ALTER_TABLE_COMMITTED);
+             tabState == SchemaFile::ALTER_TABLE_COMMITTED ||
+             tabState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
   tableEntry->m_tableState   = SchemaFile::DROP_TABLE_STARTED;
   computeChecksum(xsf, tablePtr.i / NDB_SF_PAGE_ENTRIES);
-  
-  ndbrequire(c_writeSchemaRecord.inUse == false);
-  c_writeSchemaRecord.inUse = true;
-  
-  c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
-  c_writeSchemaRecord.newFile = false;
-  c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES;
-  c_writeSchemaRecord.noOfPages = 1;
-  c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
-  c_writeSchemaRecord.m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
-  startWriteSchemaFile(signal);
+
+  bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
+  Callback callback;
+  callback.m_callbackData = dropTabPtr.p->key;
+  callback.m_callbackFunction = safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
+  if (savetodisk)
+  {
+    ndbrequire(c_writeSchemaRecord.inUse == false);
+    c_writeSchemaRecord.inUse = true;
+
+    c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
+    c_writeSchemaRecord.newFile = false;
+    c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES;
+    c_writeSchemaRecord.noOfPages = 1;
+    c_writeSchemaRecord.m_callback = callback;
+    startWriteSchemaFile(signal);
+  }
+  else
+  {
+    execute(signal, callback, 0);
+  }
 }
 
 void
@@ -5853,6 +6926,13 @@
   dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::dropTab_complete);
   dropTab_nextStep(signal, dropTabPtr);  
+
+  if (tablePtr.p->m_tablespace_id != RNIL)
+  {
+    FilegroupPtr ptr;
+    ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
+    decrease_ref_count(ptr.p->m_obj_ptr_i);
+  }
 }
 
 #include <DebuggerNames.hpp>
@@ -5965,17 +7045,28 @@
   ndbrequire(tabState == SchemaFile::DROP_TABLE_STARTED);
   tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
   computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
-  
-  ndbrequire(c_writeSchemaRecord.inUse == false);
-  c_writeSchemaRecord.inUse = true;
 
-  c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
-  c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
-  c_writeSchemaRecord.noOfPages = 1;
-  c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
-  c_writeSchemaRecord.m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::dropTab_writeSchemaConf);
-  startWriteSchemaFile(signal);
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, tableId);
+  bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
+  Callback callback;
+  callback.m_callbackData = dropTabPtr.p->key;
+  callback.m_callbackFunction = safe_cast(&Dbdict::dropTab_writeSchemaConf);
+  if (savetodisk)
+  {
+    ndbrequire(c_writeSchemaRecord.inUse == false);
+    c_writeSchemaRecord.inUse = true;
+    
+    c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
+    c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
+    c_writeSchemaRecord.noOfPages = 1;
+    c_writeSchemaRecord.m_callback = callback;
+    startWriteSchemaFile(signal);
+  }
+  else
+  {
+    execute(signal, callback, 0); 
+  }
 }
 
 void
@@ -5997,7 +7088,17 @@
   conf->senderRef = reference();
   conf->senderData = dropTabPtrI;
   conf->tableId = dropTabPtr.p->m_request.tableId;
-  
+  {
+    DropTabConf tmp= *conf;
+    if (dropTabPtr.p->m_coordinatorRef == reference())
+      conf->senderRef = dropTabPtr.p->m_request.senderRef;
+    else
+      conf->senderRef = 0;
+    EXECUTE_DIRECT(SUMA, GSN_DROP_TAB_CONF, signal,
+		   DropTabConf::SignalLength);
+    jamEntry();
+    *conf= tmp;
+  }
   dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
   sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_DROP_TAB_CONF, signal, 
 	     DropTabConf::SignalLength, JBB);
@@ -6010,35 +7111,50 @@
 void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash) 
 {
   TableRecordPtr tablePtr;
-  AttributeRecordPtr attrPtr;
   c_tableRecordPool.getPtr(tablePtr, tableId);
   if (removeFromHash)
   {
-#ifdef VM_TRACE
-    TableRecordPtr tmp;
-    ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p));
-#endif
-    c_tableRecordHash.remove(tablePtr);
+    jam();
+    release_object(tablePtr.p->m_obj_ptr_i);
+  }
+  else
+  {
+    Rope tmp(c_rope_pool, tablePtr.p->tableName);
+    tmp.erase();
+  }
+  
+  {
+    Rope tmp(c_rope_pool, tablePtr.p->frmData);
+    tmp.erase();
   }
-  tablePtr.p->tabState = TableRecord::NOT_DEFINED;
 
-  Uint32 nextAttrRecord = tablePtr.p->firstAttribute;
-  while (nextAttrRecord != RNIL) {
-    jam();
-/* ---------------------------------------------------------------- */
-// Release all attribute records
-/* ---------------------------------------------------------------- */
-    c_attributeRecordPool.getPtr(attrPtr, nextAttrRecord);
-    nextAttrRecord = attrPtr.p->nextAttrInTable;
-    c_attributeRecordPool.release(attrPtr);
-  }//if
-#ifdef HAVE_TABLE_REORG
-  Uint32 secondTableId = tablePtr.p->secondTable;
-  initialiseTableRecord(tablePtr);
-  c_tableRecordPool.getPtr(tablePtr, secondTableId);
-  initialiseTableRecord(tablePtr);
-#endif
-  return; 
+  {
+    Rope tmp(c_rope_pool, tablePtr.p->tsData);
+    tmp.erase();
+  }
+
+  {
+    Rope tmp(c_rope_pool, tablePtr.p->ngData);
+    tmp.erase();
+  }
+
+  {
+    Rope tmp(c_rope_pool, tablePtr.p->rangeData);
+    tmp.erase();
+  }
+
+  tablePtr.p->tabState = TableRecord::NOT_DEFINED;
+  
+  LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool, 
+					tablePtr.p->m_attributes);
+  AttributeRecordPtr attrPtr;
+  for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)){
+    Rope name(c_rope_pool, attrPtr.p->attributeName);
+    Rope def(c_rope_pool, attrPtr.p->defaultValue);
+    name.erase();
+    def.erase();
+  }
+  list.release();
 }//releaseTableObject()
 
 /**
@@ -6102,36 +7218,29 @@
   }
 
   char tableName[MAX_TAB_NAME_SIZE];
-  TableRecord keyRecord;
   SegmentedSectionPtr ssPtr;
   signal->getSection(ssPtr,GetTableIdReq::TABLE_NAME);
   copy((Uint32*)tableName, ssPtr);
-  strcpy(keyRecord.tableName, tableName);
   releaseSections(signal);
-
-  if(len > sizeof(keyRecord.tableName)){
-    jam();
-    sendGET_TABLEID_REF((Signal*)signal, 
-			(GetTableIdReq *)req, 
-			GetTableIdRef::TableNameTooLong);
-    return;
-  }
-  
-  TableRecordPtr tablePtr;
-  if(!c_tableRecordHash.find(tablePtr, keyRecord)) {
+    
+  DictObject * obj_ptr_p = get_object(tableName, len);
+  if(obj_ptr_p == 0 || !DictTabInfo::isTable(obj_ptr_p->m_type)){
     jam();
-    sendGET_TABLEID_REF((Signal*)signal, 
+    sendGET_TABLEID_REF(signal, 
 			(GetTableIdReq *)req, 
 			GetTableIdRef::TableNotDefined);
     return;
   }
+
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, obj_ptr_p->m_id); 
+  
   GetTableIdConf * conf = (GetTableIdConf *)req;
-  conf->tableId               = tablePtr.p->tableId;
-  conf->schemaVersion         = tablePtr.p->tableVersion;
-  conf->senderData            = senderData;
+  conf->tableId = tablePtr.p->tableId;
+  conf->schemaVersion = tablePtr.p->tableVersion;
+  conf->senderData = senderData;
   sendSignal(senderRef, GSN_GET_TABLEID_CONF, signal,
 	     GetTableIdConf::SignalLength, JBB);  
-  
 }
 
 
@@ -6144,7 +7253,7 @@
    * The format of GetTabInfo Req/Ref is the same
    */
   BlockReference retRef = req->senderRef;
-  ref->err  = errorCode;
+  ref->err = errorCode;
   sendSignal(retRef, GSN_GET_TABLEID_REF, signal, 
 	     GetTableIdRef::SignalLength, JBB);
 }//sendGET_TABINFOREF()
@@ -6200,15 +7309,14 @@
 
   const bool useLongSig = (req->requestType & GetTabInfoReq::LongSignalConf);
   const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
-  
-  TableRecordPtr tablePtr;
+
+  Uint32 obj_id = RNIL;
   if(reqType == GetTabInfoReq::RequestByName){
     jam();
     ndbrequire(signal->getNoOfSections() == 1);  
     const Uint32 len = req->tableNameLen;
     
-    TableRecord keyRecord;
-    if(len > sizeof(keyRecord.tableName)){
+    if(len > MAX_TAB_NAME_SIZE){
       jam();
       releaseSections(signal);
       sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNameTooLong);
@@ -6220,51 +7328,105 @@
     signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
     SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
     r0.reset(); // undo implicit first()
-    if(r0.getWords((Uint32*)tableName, ((len + 3)/4)))
-      memcpy(keyRecord.tableName, tableName, len);
-    else {
+    if(!r0.getWords((Uint32*)tableName, (len+3)/4)){
       jam();
       releaseSections(signal);
       sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
       return;
     }
     releaseSections(signal);
-    //    memcpy(keyRecord.tableName, req->tableName, len);
-    //ntohS(&keyRecord.tableName[0], len);
-   
-    c_tableRecordHash.find(tablePtr, keyRecord);
+    
+    DictObject * old_ptr_p = old_ptr_p = get_object(tableName, len);
+    if(old_ptr_p)
+      obj_id = old_ptr_p->m_id;
   } else {
     jam();
-    c_tableRecordPool.getPtr(tablePtr, req->tableId, false);
+    obj_id = req->tableId;
   }
-  
+
+  SchemaFile::TableEntry *objEntry = 0;
+  if(obj_id != RNIL){
+    XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+    objEntry = getTableEntry(xsf, obj_id);      
+  }
+
   // The table seached for was not found
-  if(tablePtr.i == RNIL){
+  if(objEntry == 0){
     jam();
-    sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
+    sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
     return;
   }//if
-  
-  if (! (tablePtr.p->tabState == TableRecord::DEFINED ||
-	 tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)) {
+
+  // If istable/index, allow ADD_STARTED (not to ref)
+
+  if (objEntry->m_tableState != SchemaFile::TABLE_ADD_COMMITTED &&
+      objEntry->m_tableState != SchemaFile::ALTER_TABLE_COMMITTED &&
+      objEntry->m_tableState != SchemaFile::TEMPORARY_TABLE_COMMITTED){
     jam();
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
     return;
   }//if
+
+  if (DictTabInfo::isTable(objEntry->m_tableType) || 
+      DictTabInfo::isIndex(objEntry->m_tableType))
+  {
+    jam();
+    TableRecordPtr tabPtr;
+    c_tableRecordPool.getPtr(tabPtr, obj_id);
+    if (tabPtr.p->tabState != TableRecord::DEFINED &&
+	tabPtr.p->tabState != TableRecord::BACKUP_ONGOING)
+    {
+      jam();
+      sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
+      return;
+    }
+    ndbrequire(objEntry->m_tableState == SchemaFile::TEMPORARY_TABLE_COMMITTED ||
+               !(tabPtr.p->m_bits & TableRecord::TR_Temporary));
+  }
   
   c_retrieveRecord.busyState = true;
   c_retrieveRecord.blockRef = req->senderRef;
   c_retrieveRecord.m_senderData = req->senderData;
-  c_retrieveRecord.tableId = tablePtr.i;
+  c_retrieveRecord.tableId = obj_id;
   c_retrieveRecord.currentSent = 0;
   c_retrieveRecord.m_useLongSig = useLongSig;
-  
+  c_retrieveRecord.m_table_type = objEntry->m_tableType;
   c_packTable.m_state = PackTable::PTS_GET_TAB;
-  
-  signal->theData[0] = ZPACK_TABLE_INTO_PAGES;
-  signal->theData[1] = tablePtr.i;
-  signal->theData[2] = c_retrieveRecord.retrievePage;  
-  sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
+
+  if(objEntry->m_tableType==DictTabInfo::Datafile)
+  {
+    jam();
+    GetTabInfoReq *req= (GetTabInfoReq*)signal->getDataPtrSend();
+    req->senderData= c_retrieveRecord.retrievePage;
+    req->senderRef= reference();
+    req->requestType= GetTabInfoReq::RequestById;
+    req->tableId= obj_id;
+
+    sendSignal(TSMAN_REF, GSN_GET_TABINFOREQ, signal,
+	       GetTabInfoReq::SignalLength, JBB);
+  }
+  else if(objEntry->m_tableType==DictTabInfo::LogfileGroup)
+  {
+    jam();
+    GetTabInfoReq *req= (GetTabInfoReq*)signal->getDataPtrSend();
+    req->senderData= c_retrieveRecord.retrievePage;
+    req->senderRef= reference();
+    req->requestType= GetTabInfoReq::RequestById;
+    req->tableId= obj_id;
+
+    sendSignal(LGMAN_REF, GSN_GET_TABINFOREQ, signal,
+	       GetTabInfoReq::SignalLength, JBB);
+  }
+  else
+  {
+    jam();
+    signal->theData[0] = ZPACK_TABLE_INTO_PAGES;
+    signal->theData[1] = obj_id;
+    signal->theData[2] = objEntry->m_tableType;
+    signal->theData[3] = c_retrieveRecord.retrievePage;
+    sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
+  }
+  jam();
 }//execGET_TABINFOREQ()
 
 void Dbdict::sendGetTabResponse(Signal* signal) 
@@ -6286,7 +7448,8 @@
     conf->tableId = c_retrieveRecord.tableId;
     conf->senderData = c_retrieveRecord.m_senderData;
     conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
-    
+    conf->tableType = c_retrieveRecord.m_table_type;
+
     Callback c = { safe_cast(&Dbdict::initRetrieveRecord), 0 };
     LinearSectionPtr ptr[3];
     ptr[0].p = pagePointer;
@@ -6320,23 +7483,10 @@
   sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
 }//sendGET_TABINFOREF()
 
-Uint32 convertEndian(Uint32 in) {
-#ifdef WORDS_BIGENDIAN
-  Uint32 ut = 0;
-  ut += ((in >> 24) & 255);
-  ut += (((in >> 16) & 255) << 8);
-  ut += (((in >> 8) & 255) << 16);
-  ut += ((in & 255) << 24);
-  return ut;
-#else
-  return in;
-#endif
-}
 void
 Dbdict::execLIST_TABLES_REQ(Signal* signal)
 {
   jamEntry();
-  Uint32 i;
   ListTablesReq * req = (ListTablesReq*)signal->getDataPtr();
   Uint32 senderRef  = req->senderRef;
   Uint32 senderData = req->senderData;
@@ -6350,144 +7500,133 @@
   conf->senderData = senderData;
   conf->counter = 0;
   Uint32 pos = 0;
-  for (i = 0; i < c_tableRecordPool.getSize(); i++) {
-    TableRecordPtr tablePtr;
-    c_tableRecordPool.getPtr(tablePtr, i);
-    // filter
-    if (tablePtr.p->tabState == TableRecord::NOT_DEFINED ||
-        tablePtr.p->tabState == TableRecord::REORG_TABLE_PREPARED)
-      continue;
-
 
-    if ((reqTableType != (Uint32)0) && (reqTableType != (unsigned)tablePtr.p->tableType))
+  DLHashTable<DictObject>::Iterator iter;
+  bool ok = c_obj_hash.first(iter);
+  for(; ok; ok = c_obj_hash.next(iter)){
+    Uint32 type = iter.curr.p->m_type;
+    if ((reqTableType != (Uint32)0) && (reqTableType != type))
       continue;
-    if (reqListIndexes && reqTableId != tablePtr.p->primaryTableId)
+
+    if (reqListIndexes && !DictTabInfo::isIndex(type))
       continue;
-    conf->tableData[pos] = 0;
-    // id
-    conf->setTableId(pos, tablePtr.i);
-    // type
-    conf->setTableType(pos, tablePtr.p->tableType);
-    // state
-    if (tablePtr.p->isTable()) {
-      switch (tablePtr.p->tabState) {
-      case TableRecord::DEFINING:
-      case TableRecord::CHECKED:
-        conf->setTableState(pos, DictTabInfo::StateBuilding);
-        break;
-      case TableRecord::PREPARE_DROPPING:
-      case TableRecord::DROPPING:
-        conf->setTableState(pos, DictTabInfo::StateDropping);
-        break;
-      case TableRecord::DEFINED:
-        conf->setTableState(pos, DictTabInfo::StateOnline);
-        break;
-      case TableRecord::BACKUP_ONGOING:
-        conf->setTableState(pos, DictTabInfo::StateBackup);
-	break;
-      default:
-        conf->setTableState(pos, DictTabInfo::StateBroken);
-        break;
+
+    TableRecordPtr tablePtr;
+    if (DictTabInfo::isTable(type) || DictTabInfo::isIndex(type)){
+      c_tableRecordPool.getPtr(tablePtr, iter.curr.p->m_id);
+
+      if(reqListIndexes && (reqTableId != tablePtr.p->primaryTableId))
+	continue;
+      
+      conf->tableData[pos] = 0;
+      conf->setTableId(pos, tablePtr.i); // id
+      conf->setTableType(pos, type); // type
+      // state
+
+      if(DictTabInfo::isTable(type)){
+	switch (tablePtr.p->tabState) {
+	case TableRecord::DEFINING:
+	case TableRecord::CHECKED:
+	  conf->setTableState(pos, DictTabInfo::StateBuilding);
+	  break;
+	case TableRecord::PREPARE_DROPPING:
+	case TableRecord::DROPPING:
+	  conf->setTableState(pos, DictTabInfo::StateDropping);
+	  break;
+	case TableRecord::DEFINED:
+	  conf->setTableState(pos, DictTabInfo::StateOnline);
+	  break;
+	case TableRecord::BACKUP_ONGOING:
+	  conf->setTableState(pos, DictTabInfo::StateBackup);
+	  break;
+	default:
+	  conf->setTableState(pos, DictTabInfo::StateBroken);
+	  break;
+	}
       }
+      if (tablePtr.p->isIndex()) {
+	switch (tablePtr.p->indexState) {
+	case TableRecord::IS_OFFLINE:
+	  conf->setTableState(pos, DictTabInfo::StateOffline);
+	  break;
+	case TableRecord::IS_BUILDING:
+	  conf->setTableState(pos, DictTabInfo::StateBuilding);
+	  break;
+	case TableRecord::IS_DROPPING:
+	  conf->setTableState(pos, DictTabInfo::StateDropping);
+	  break;
+	case TableRecord::IS_ONLINE:
+	  conf->setTableState(pos, DictTabInfo::StateOnline);
+	  break;
+	default:
+	  conf->setTableState(pos, DictTabInfo::StateBroken);
+	  break;
+	}
+      }
+      // Logging status
+      if (! (tablePtr.p->m_bits & TableRecord::TR_Logged)) {
+	conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
+      } else {
+	conf->setTableStore(pos, DictTabInfo::StorePermanent);
+      }
+      // Temporary status
+      if (tablePtr.p->m_bits & TableRecord::TR_Temporary) {
+	conf->setTableTemp(pos, NDB_TEMP_TAB_TEMPORARY);
+      } else {
+	conf->setTableTemp(pos, NDB_TEMP_TAB_PERMANENT);
+      }
+      pos++;
     }
-    if (tablePtr.p->isIndex()) {
-      switch (tablePtr.p->indexState) {
-      case TableRecord::IS_OFFLINE:
-        conf->setTableState(pos, DictTabInfo::StateOffline);
-        break;
-      case TableRecord::IS_BUILDING:
-        conf->setTableState(pos, DictTabInfo::StateBuilding);
-        break;
-      case TableRecord::IS_DROPPING:
-        conf->setTableState(pos, DictTabInfo::StateDropping);
-        break;
-      case TableRecord::IS_ONLINE:
-        conf->setTableState(pos, DictTabInfo::StateOnline);
-        break;
+    if(DictTabInfo::isTrigger(type)){
+      TriggerRecordPtr triggerPtr;
+      c_triggerRecordPool.getPtr(triggerPtr, iter.curr.p->m_id);
+
+      conf->tableData[pos] = 0;
+      conf->setTableId(pos, triggerPtr.i);
+      conf->setTableType(pos, type);
+      switch (triggerPtr.p->triggerState) {
+      case TriggerRecord::TS_OFFLINE:
+	conf->setTableState(pos, DictTabInfo::StateOffline);
+	break;
+      case TriggerRecord::TS_ONLINE:
+	conf->setTableState(pos, DictTabInfo::StateOnline);
+	break;
       default:
-        conf->setTableState(pos, DictTabInfo::StateBroken);
-        break;
+	conf->setTableState(pos, DictTabInfo::StateBroken);
+	break;
       }
+      conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
+      pos++;
     }
-    // store
-    if (! tablePtr.p->storedTable) {
-      conf->setTableStore(pos, DictTabInfo::StoreTemporary);
-    } else {
-      conf->setTableStore(pos, DictTabInfo::StorePermanent);
-    }
-    pos++;
-    if (pos >= ListTablesConf::DataLength) {
-      sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-		 ListTablesConf::SignalLength, JBB);
-      conf->counter++;
-      pos = 0;
-    }
-    if (! reqListNames)
-      continue;
-    const Uint32 size = strlen(tablePtr.p->tableName) + 1;
-    conf->tableData[pos] = size;
-    pos++;
-    if (pos >= ListTablesConf::DataLength) {
-      sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-		 ListTablesConf::SignalLength, JBB);
-      conf->counter++;
-      pos = 0;
-    }
-    Uint32 k = 0;
-    while (k < size) {
-      char* p = (char*)&conf->tableData[pos];
-      for (Uint32 j = 0; j < 4; j++) {
-        if (k < size)
-          *p++ = tablePtr.p->tableName[k++];
-        else
-          *p++ = 0;
-      }
+    if (DictTabInfo::isFilegroup(type)){
+      jam();
+      conf->tableData[pos] = 0;
+      conf->setTableId(pos, iter.curr.p->m_id);
+      conf->setTableType(pos, type); // type
+      conf->setTableState(pos, DictTabInfo::StateOnline);  // XXX todo
       pos++;
-      if (pos >= ListTablesConf::DataLength) {
-        sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-                   ListTablesConf::SignalLength, JBB);
-        conf->counter++;
-        pos = 0;
-      }
     }
-  }
-  // XXX merge with above somehow
-  for (i = 0; i < c_triggerRecordPool.getSize(); i++) {
-    if (reqListIndexes)
-      break;
-    TriggerRecordPtr triggerPtr;
-    c_triggerRecordPool.getPtr(triggerPtr, i);
-    if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED)
-      continue;
-    // constant 10 hardcoded
-    Uint32 type = 10 + triggerPtr.p->triggerType;
-    if (reqTableType != 0 && reqTableType != type)
-      continue;
-    conf->tableData[pos] = 0;
-    conf->setTableId(pos, triggerPtr.i);
-    conf->setTableType(pos, type);
-    switch (triggerPtr.p->triggerState) {
-    case TriggerRecord::TS_OFFLINE:
-      conf->setTableState(pos, DictTabInfo::StateOffline);
-      break;
-    case TriggerRecord::TS_ONLINE:
-      conf->setTableState(pos, DictTabInfo::StateOnline);
-      break;
-    default:
-      conf->setTableState(pos, DictTabInfo::StateBroken);
-      break;
+    if (DictTabInfo::isFile(type)){
+      jam();
+      conf->tableData[pos] = 0;
+      conf->setTableId(pos, iter.curr.p->m_id);
+      conf->setTableType(pos, type); // type
+      conf->setTableState(pos, DictTabInfo::StateOnline); // XXX todo
+      pos++;
     }
-    conf->setTableStore(pos, DictTabInfo::StoreTemporary);
-    pos++;
+    
     if (pos >= ListTablesConf::DataLength) {
       sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-        ListTablesConf::SignalLength, JBB);
+		 ListTablesConf::SignalLength, JBB);
       conf->counter++;
       pos = 0;
     }
+    
     if (! reqListNames)
       continue;
-    const Uint32 size = strlen(triggerPtr.p->triggerName) + 1;
+    
+    Rope name(c_rope_pool, iter.curr.p->m_name);
+    const Uint32 size = name.size();
     conf->tableData[pos] = size;
     pos++;
     if (pos >= ListTablesConf::DataLength) {
@@ -6496,21 +7635,23 @@
       conf->counter++;
       pos = 0;
     }
-    Uint32 k = 0;
-    while (k < size) {
+    Uint32 i = 0;
+    char tmp[MAX_TAB_NAME_SIZE];
+    name.copy(tmp);
+    while (i < size) {
       char* p = (char*)&conf->tableData[pos];
       for (Uint32 j = 0; j < 4; j++) {
-        if (k < size)
-          *p++ = triggerPtr.p->triggerName[k++];
-        else
-          *p++ = 0;
+	if (i < size)
+	  *p++ = tmp[i++];
+	else
+	  *p++ = 0;
       }
       pos++;
       if (pos >= ListTablesConf::DataLength) {
-        sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-                   ListTablesConf::SignalLength, JBB);
-        conf->counter++;
-        pos = 0;
+	sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
+		   ListTablesConf::SignalLength, JBB);
+	conf->counter++;
+	pos = 0;
       }
     }
   }
@@ -6623,10 +7764,9 @@
     // save name and index table properties
     signal->getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
     SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool());
-    DictTabInfo::Table tableDesc;
-    tableDesc.init();
+    c_tableDesc.init();
     SimpleProperties::UnpackStatus status = SimpleProperties::unpack(
-        r1, &tableDesc,
+        r1, &c_tableDesc,
         DictTabInfo::TableMapping, DictTabInfo::TableMappingSize,
         true, true);
     if (status != SimpleProperties::Eof) {
@@ -6636,8 +7776,9 @@
       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
       return;
     }
-    memcpy(opPtr.p->m_indexName, tableDesc.TableName, MAX_TAB_NAME_SIZE);
-    opPtr.p->m_storedIndex = tableDesc.TableLoggedFlag;
+    memcpy(opPtr.p->m_indexName, c_tableDesc.TableName, MAX_TAB_NAME_SIZE);
+    opPtr.p->m_loggedIndex = c_tableDesc.TableLoggedFlag;
+    opPtr.p->m_temporaryIndex = c_tableDesc.TableTemporaryFlag;
     releaseSections(signal);
     // master expects to hear from all
     if (opPtr.p->m_isMaster)
@@ -6764,8 +7905,13 @@
 void
 Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
 {
-  Uint32 attrid_map[MAX_ATTRIBUTES_IN_INDEX];
+  union {
+    char tableName[MAX_TAB_NAME_SIZE];
+    char attributeName[MAX_ATTR_NAME_SIZE];
+  };
   Uint32 k;
+  Uint32 attrid_map[MAX_ATTRIBUTES_IN_INDEX];
+
   jam();
   const CreateIndxReq* const req = &opPtr.p->m_request;
   // signal data writer
@@ -6794,26 +7940,57 @@
     opPtr.p->m_errorLine = __LINE__;
     return;
   }
+
+  // Check that the temporary status of index is compatible with table.
+  if (!opPtr.p->m_temporaryIndex &&
+      tablePtr.p->m_bits & TableRecord::TR_Temporary)
+  {
+    jam();
+    opPtr.p->m_errorCode= CreateIndxRef::TableIsTemporary;
+    opPtr.p->m_errorLine= __LINE__;
+    return;
+  }
+  if (opPtr.p->m_temporaryIndex &&
+      !(tablePtr.p->m_bits & TableRecord::TR_Temporary))
+  {
+    // This could be implemented later, but mysqld does currently not detect
+    // that the index disappears after SR, and it appears not too useful.
+    jam();
+    opPtr.p->m_errorCode= CreateIndxRef::TableIsNotTemporary;
+    opPtr.p->m_errorLine= __LINE__;
+    return;
+  }
+  if (opPtr.p->m_temporaryIndex && opPtr.p->m_loggedIndex)
+  {
+    jam();
+    opPtr.p->m_errorCode= CreateIndxRef::NoLoggingTemporaryIndex;
+    opPtr.p->m_errorLine= __LINE__;
+    return;
+  }
+
   // compute index table record
   TableRecord indexRec;
   TableRecordPtr indexPtr;
   indexPtr.i = RNIL;            // invalid
   indexPtr.p = &indexRec;
   initialiseTableRecord(indexPtr);
+  indexPtr.p->m_bits = TableRecord::TR_RowChecksum;
   if (req->getIndexType() == DictTabInfo::UniqueHashIndex) {
-    indexPtr.p->storedTable = opPtr.p->m_storedIndex;
-    indexPtr.p->fragmentType = tablePtr.p->fragmentType;
+    indexPtr.p->m_bits |= (opPtr.p->m_loggedIndex ? TableRecord::TR_Logged:0);
+    indexPtr.p->m_bits |=
+      (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
+    indexPtr.p->fragmentType = DictTabInfo::DistrKeyUniqueHashIndex;
   } else if (req->getIndexType() == DictTabInfo::OrderedIndex) {
     // first version will not supported logging
-    if (opPtr.p->m_storedIndex) {
+    if (opPtr.p->m_loggedIndex) {
       jam();
       opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
       opPtr.p->m_errorLine = __LINE__;
       return;
     }
-    indexPtr.p->storedTable = false;
-    // follows table fragmentation
-    indexPtr.p->fragmentType = tablePtr.p->fragmentType;
+    indexPtr.p->m_bits |=
+      (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
+    indexPtr.p->fragmentType = DictTabInfo::DistrKeyOrderedIndex;
   } else {
     jam();
     opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
@@ -6830,6 +8007,7 @@
     opPtr.p->m_errorLine = __LINE__;
     return;
   }
+
   if (indexPtr.p->isOrderedIndex()) {
     // tree node size in words (make configurable later)
     indexPtr.p->tupKeyLength = MAX_TTREE_NODE_SIZE;
@@ -6840,13 +8018,16 @@
   for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
     jam();
     unsigned current_id= opPtr.p->m_attrList.id[k];
-    AttributeRecord* aRec= NULL;
-    Uint32 tAttr= tablePtr.p->firstAttribute;
-    for (; tAttr != RNIL; tAttr= aRec->nextAttrInTable)
+    Uint32 tAttr = tablePtr.p->m_attributes.firstItem;
+    AttributeRecord* aRec = NULL;
+    for (; tAttr != RNIL; )
     {
       aRec = c_attributeRecordPool.getPtr(tAttr);
       if (aRec->attributeId != current_id)
-        continue;
+      {
+	tAttr= aRec->nextList;
+	continue;
+      }
       jam();
       break;
     }
@@ -6863,31 +8044,42 @@
       opPtr.p->m_errorLine = __LINE__;
       return;
     }
-    mask.set(current_id);
-
     const Uint32 a = aRec->attributeDescriptor;
+
+    if (AttributeDescriptor::getDiskBased(a))
+    {
+      jam();
+      opPtr.p->m_errorCode = CreateIndxRef::IndexOnDiskAttributeError;
+      opPtr.p->m_errorLine = __LINE__;
+      return;
+    }
+    
+    mask.set(current_id);
     unsigned kk= k;
     if (indexPtr.p->isHashIndex()) {
       const Uint32 s1 = AttributeDescriptor::getSize(a);
       const Uint32 s2 = AttributeDescriptor::getArraySize(a);
       indexPtr.p->tupKeyLength += ((1 << s1) * s2 + 31) >> 5;
-      // reorder the attributes according to the tableid order
-      // for unque indexes
+
       for (; kk > 0 && current_id < attrid_map[kk-1]>>16; kk--)
 	attrid_map[kk]= attrid_map[kk-1];
     }
     attrid_map[kk]= k | (current_id << 16);
   }
+
   indexPtr.p->noOfPrimkey = indexPtr.p->noOfAttributes;
   // plus concatenated primary table key attribute
   indexPtr.p->noOfAttributes += 1;
   indexPtr.p->noOfNullAttr = 0;
   // write index table
   w.add(DictTabInfo::TableName, opPtr.p->m_indexName);
-  w.add(DictTabInfo::TableLoggedFlag, indexPtr.p->storedTable);
+  w.add(DictTabInfo::TableLoggedFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Logged));
+  w.add(DictTabInfo::TableTemporaryFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Temporary));
   w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType);
   w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType);
-  w.add(DictTabInfo::PrimaryTable, tablePtr.p->tableName);
+  Rope name(c_rope_pool, tablePtr.p->tableName);
+  name.copy(tableName);
+  w.add(DictTabInfo::PrimaryTable, tableName);
   w.add(DictTabInfo::PrimaryTableId, tablePtr.i);
   w.add(DictTabInfo::NoOfAttributes, indexPtr.p->noOfAttributes);
   w.add(DictTabInfo::NoOfKeyAttr, indexPtr.p->noOfPrimkey);
@@ -6895,8 +8087,6 @@
   w.add(DictTabInfo::KeyLength, indexPtr.p->tupKeyLength);
   w.add(DictTabInfo::SingleUserMode, (Uint32)NDB_SUM_READ_WRITE);
   // write index key attributes
-  AttributeRecordPtr aRecPtr;
-  c_attributeRecordPool.getPtr(aRecPtr, tablePtr.p->firstAttribute);
   for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
     // insert the attributes in the order decided above in attrid_map
     // k is new order, current_id is in previous order
@@ -6904,16 +8094,20 @@
     // passed up to NdbDictionary
     unsigned current_id= opPtr.p->m_attrList.id[attrid_map[k] & 0xffff];
     jam();
-    for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
+    for (Uint32 tAttr = tablePtr.p->m_attributes.firstItem; tAttr != RNIL; ) {
       AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
-      tAttr = aRec->nextAttrInTable;
+      tAttr = aRec->nextList;
       if (aRec->attributeId != current_id)
         continue;
       jam();
       const Uint32 a = aRec->attributeDescriptor;
       bool isNullable = AttributeDescriptor::getNullable(a);
+      Uint32 arrayType = AttributeDescriptor::getArrayType(a);
+      Rope attrName(c_rope_pool, aRec->attributeName);
+      attrName.copy(attributeName);
+      w.add(DictTabInfo::AttributeName, attributeName);
       Uint32 attrType = AttributeDescriptor::getType(a);
-      w.add(DictTabInfo::AttributeName, aRec->attributeName);
+      // computed
       w.add(DictTabInfo::AttributeId, k);
       if (indexPtr.p->isHashIndex()) {
         w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
@@ -6923,6 +8117,7 @@
         w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
         w.add(DictTabInfo::AttributeNullableFlag, (Uint32)isNullable);
       }
+      w.add(DictTabInfo::AttributeArrayType, arrayType);
       w.add(DictTabInfo::AttributeExtType, attrType);
       w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision);
       w.add(DictTabInfo::AttributeExtScale, aRec->extScale);
@@ -6932,13 +8127,30 @@
   }
   if (indexPtr.p->isHashIndex()) {
     jam();
-    // write concatenated primary table key attribute
+    
+    Uint32 key_type = NDB_ARRAYTYPE_FIXED;
+    AttributeRecordPtr attrPtr;
+    LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
+					   tablePtr.p->m_attributes);
+    for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)) 
+    {
+      const Uint32 desc = attrPtr.p->attributeDescriptor;
+      if (AttributeDescriptor::getPrimaryKey(desc) &&
+	  AttributeDescriptor::getArrayType(desc) != NDB_ARRAYTYPE_FIXED)
+      {
+	key_type = NDB_ARRAYTYPE_MEDIUM_VAR;
+	break;
+      }
+    }
+    
+    // write concatenated primary table key attribute i.e. keyinfo
     w.add(DictTabInfo::AttributeName, "NDB$PK");
     w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
+    w.add(DictTabInfo::AttributeArrayType, key_type);
     w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
     w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
     w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
-    w.add(DictTabInfo::AttributeExtLength, tablePtr.p->tupKeyLength);
+    w.add(DictTabInfo::AttributeExtLength, tablePtr.p->tupKeyLength+1);
     w.add(DictTabInfo::AttributeEnd, (Uint32)true);
   }
   if (indexPtr.p->isOrderedIndex()) {
@@ -6946,6 +8158,8 @@
     // write index tree node as Uint32 array attribute
     w.add(DictTabInfo::AttributeName, "NDB$TNODE");
     w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
+    // should not matter but VAR crashes in TUP
+    w.add(DictTabInfo::AttributeArrayType, (Uint32)NDB_ARRAYTYPE_FIXED);
     w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
     w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
     w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
@@ -7148,24 +8362,28 @@
       // forward initial request plus operation key to all
       Uint32 indexId= req->getIndexId();
       Uint32 indexVersion= req->getIndexVersion();
-      TableRecordPtr tmp;
-      int res = getMetaTablePtr(tmp, indexId,  indexVersion);
-      switch(res){
-      case MetaData::InvalidArgument:
+
+      if(indexId >= c_tableRecordPool.getSize())
+      {
 	err = DropIndxRef::IndexNotFound;
 	goto error;
-      case MetaData::TableNotFound:
-      case MetaData::InvalidTableVersion:
+      }
+
+      TableRecordPtr tmp;
+      c_tableRecordPool.getPtr(tmp, indexId);
+      if(tmp.p->tabState == TableRecord::NOT_DEFINED ||
+	 tmp.p->tableVersion != indexVersion)
+      {
 	err = DropIndxRef::InvalidIndexVersion;
 	goto error;
       }
-
+      
       if (! tmp.p->isIndex()) {
 	jam();
 	err = DropIndxRef::NotAnIndex;
 	goto error;
       }
-
+      
       if (tmp.p->indexState != TableRecord::IS_ONLINE)
         req->addRequestFlag(RequestFlag::RF_FORCE);
 
@@ -7174,7 +8392,7 @@
       req->setOpKey(++c_opRecordSequence);
       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
       sendSignal(rg, GSN_DROP_INDX_REQ,
-          signal, DropIndxReq::SignalLength + 1, JBB);
+		 signal, DropIndxReq::SignalLength + 1, JBB);
       return;
     }
     // seize operation record
@@ -7460,6 +8678,2246 @@
   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
 }
 
+/*****************************************************
+ *
+ * Util signalling
+ *
+ *****************************************************/
+
+int
+Dbdict::sendSignalUtilReq(Callback *pcallback,
+			  BlockReference ref, 
+			  GlobalSignalNumber gsn, 
+			  Signal* signal, 
+			  Uint32 length, 
+			  JobBufferLevel jbuf,
+			  LinearSectionPtr ptr[3],
+			  Uint32 noOfSections)
+{
+  jam();
+  EVENT_TRACE;
+  OpSignalUtilPtr utilRecPtr;
+
+  // Seize a Util Send record
+  if (!c_opSignalUtil.seize(utilRecPtr)) {
+    // Failed to allocate util record
+    return -1;
+  }
+  utilRecPtr.p->m_callback = *pcallback;
+
+  // should work for all util signal classes
+  UtilPrepareReq *req = (UtilPrepareReq*)signal->getDataPtrSend();
+  utilRecPtr.p->m_userData = req->getSenderData();
+  req->setSenderData(utilRecPtr.i);
+
+  if (ptr) {
+    jam();
+    sendSignal(ref, gsn, signal, length, jbuf, ptr, noOfSections);
+  } else {
+    jam();
+    sendSignal(ref, gsn, signal, length, jbuf);
+  }
+
+  return 0;
+}
+
+int
+Dbdict::recvSignalUtilReq(Signal* signal, Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  UtilPrepareConf * const req = (UtilPrepareConf*)signal->getDataPtr();
+  OpSignalUtilPtr utilRecPtr;
+  utilRecPtr.i = req->getSenderData();
+  if ((utilRecPtr.p = c_opSignalUtil.getPtr(utilRecPtr.i)) == NULL) {
+    jam();
+    return -1;
+  }
+
+  req->setSenderData(utilRecPtr.p->m_userData);
+  Callback c = utilRecPtr.p->m_callback;
+  c_opSignalUtil.release(utilRecPtr);
+
+  execute(signal, c, returnCode);
+  return 0;
+}
+
+void Dbdict::execUTIL_PREPARE_CONF(Signal *signal)
+{
+  jamEntry();
+  EVENT_TRACE;
+  ndbrequire(recvSignalUtilReq(signal, 0) == 0);
+}
+
+void
+Dbdict::execUTIL_PREPARE_REF(Signal *signal)
+{
+  jamEntry();
+  EVENT_TRACE;
+  ndbrequire(recvSignalUtilReq(signal, 1) == 0);
+}
+
+void Dbdict::execUTIL_EXECUTE_CONF(Signal *signal)
+{
+  jamEntry();
+  EVENT_TRACE;
+   ndbrequire(recvSignalUtilReq(signal, 0) == 0);
+}
+
+void Dbdict::execUTIL_EXECUTE_REF(Signal *signal)
+{
+  jamEntry();
+  EVENT_TRACE;
+
+#ifdef EVENT_DEBUG
+  UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend();
+
+  ndbout_c("execUTIL_EXECUTE_REF");
+  ndbout_c("senderData %u",ref->getSenderData());
+  ndbout_c("errorCode %u",ref->getErrorCode());
+  ndbout_c("TCErrorCode %u",ref->getTCErrorCode());
+#endif
+  
+  ndbrequire(recvSignalUtilReq(signal, 1) == 0);
+}
+void Dbdict::execUTIL_RELEASE_CONF(Signal *signal)
+{
+  jamEntry();
+  EVENT_TRACE;
+  ndbrequire(false);
+  ndbrequire(recvSignalUtilReq(signal, 0) == 0);
+}
+void Dbdict::execUTIL_RELEASE_REF(Signal *signal)
+{
+  jamEntry();
+  EVENT_TRACE;
+  ndbrequire(false);
+  ndbrequire(recvSignalUtilReq(signal, 1) == 0);
+}
+
+/**
+ * MODULE: Create event
+ *
+ * Create event in DICT.
+ * 
+ *
+ * Request type in CREATE_EVNT signals:
+ *
+ * Signalflow see Dbdict.txt
+ *
+ */
+
+/*****************************************************************
+ *
+ * Systable stuff
+ *
+ */
+
+const Uint32 Dbdict::sysTab_NDBEVENTS_0_szs[EVENT_SYSTEM_TABLE_LENGTH] = {
+  sizeof(((sysTab_NDBEVENTS_0*)0)->NAME),
+  sizeof(((sysTab_NDBEVENTS_0*)0)->EVENT_TYPE),
+  sizeof(((sysTab_NDBEVENTS_0*)0)->TABLEID),
+  sizeof(((sysTab_NDBEVENTS_0*)0)->TABLEVERSION),
+  sizeof(((sysTab_NDBEVENTS_0*)0)->TABLE_NAME),
+  sizeof(((sysTab_NDBEVENTS_0*)0)->ATTRIBUTE_MASK),
+  sizeof(((sysTab_NDBEVENTS_0*)0)->SUBID),
+  sizeof(((sysTab_NDBEVENTS_0*)0)->SUBKEY)
+};
+
+void
+Dbdict::prepareTransactionEventSysTable (Callback *pcallback,
+					 Signal* signal,
+					 Uint32 senderData,
+					 UtilPrepareReq::OperationTypeValue prepReq)
+{
+  // find table id for event system table
+  DictObject * opj_ptr_p = get_object(EVENT_SYSTEM_TABLE_NAME,
+				      sizeof(EVENT_SYSTEM_TABLE_NAME));
+
+  ndbrequire(opj_ptr_p != 0);
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, opj_ptr_p->m_id);
+  ndbrequire(tablePtr.i != RNIL); // system table must exist
+  
+  Uint32 tableId = tablePtr.p->tableId; /* System table */
+  Uint32 noAttr = tablePtr.p->noOfAttributes;
+  ndbrequire(noAttr == EVENT_SYSTEM_TABLE_LENGTH);
+  
+  switch (prepReq) {
+  case UtilPrepareReq::Update:
+  case UtilPrepareReq::Insert:
+  case UtilPrepareReq::Write:
+  case UtilPrepareReq::Read:
+    jam();
+    break;
+  case UtilPrepareReq::Delete:
+    jam();
+    noAttr = 1; // only involves Primary key which should be the first
+    break;
+  }
+  prepareUtilTransaction(pcallback, signal, senderData, tableId, NULL,
+		      prepReq, noAttr, NULL, NULL);
+}
+
+void
+Dbdict::prepareUtilTransaction(Callback *pcallback,
+			       Signal* signal,
+			       Uint32 senderData,
+			       Uint32 tableId,
+			       const char* tableName,
+			       UtilPrepareReq::OperationTypeValue prepReq,
+			       Uint32 noAttr,
+			       Uint32 attrIds[],
+			       const char *attrNames[])
+{
+  jam();
+  EVENT_TRACE;
+
+  UtilPrepareReq * utilPrepareReq = 
+    (UtilPrepareReq *)signal->getDataPtrSend();
+  
+  utilPrepareReq->setSenderRef(reference());
+  utilPrepareReq->setSenderData(senderData);
+
+  const Uint32 pageSizeInWords = 128;
+  Uint32 propPage[pageSizeInWords];
+  LinearWriter w(&propPage[0],128);
+  w.first();
+  w.add(UtilPrepareReq::NoOfOperations, 1);
+  w.add(UtilPrepareReq::OperationType, prepReq);
+  if (tableName) {
+    jam();
+    w.add(UtilPrepareReq::TableName, tableName);
+  } else {
+    jam();
+    w.add(UtilPrepareReq::TableId, tableId);
+  }
+  for(Uint32 i = 0; i < noAttr; i++)
+    if (tableName) {
+      jam();
+      w.add(UtilPrepareReq::AttributeName, attrNames[i]);
+    } else {
+      if (attrIds) {
+	jam();
+	w.add(UtilPrepareReq::AttributeId, attrIds[i]);
+      } else {
+	jam();
+	w.add(UtilPrepareReq::AttributeId, i);
+      }
+    }
+#ifdef EVENT_DEBUG
+  // Debugging
+  SimplePropertiesLinearReader reader(propPage, w.getWordsUsed());
+  printf("Dict::prepareInsertTransactions: Sent SimpleProperties:\n");
+  reader.printAll(ndbout);
+#endif
+
+  struct LinearSectionPtr sectionsPtr[UtilPrepareReq::NoOfSections];
+  sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].p = propPage;
+  sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].sz = w.getWordsUsed();
+
+  sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_PREPARE_REQ, signal,
+		    UtilPrepareReq::SignalLength, JBB, 
+		    sectionsPtr, UtilPrepareReq::NoOfSections);
+}
+
+/*****************************************************************
+ *
+ * CREATE_EVNT_REQ has three types RT_CREATE, RT_GET (from user)
+ * and RT_DICT_AFTER_GET send from master DICT to slaves
+ *
+ * This function just dscpaches these to
+ *
+ * createEvent_RT_USER_CREATE
+ * createEvent_RT_USER_GET
+ * createEvent_RT_DICT_AFTER_GET
+ *
+ * repectively
+ *
+ */
+
+void
+Dbdict::execCREATE_EVNT_REQ(Signal* signal)
+{
+  jamEntry();
+
+#if 0
+  {
+    SafeCounterHandle handle;
+    {
+      SafeCounter tmp(c_counterMgr, handle);
+      tmp.init<CreateEvntRef>(CMVMI, GSN_DUMP_STATE_ORD, /* senderData */ 13);
+      tmp.clearWaitingFor();
+      tmp.setWaitingFor(3);
+      ndbrequire(!tmp.done());
+      ndbout_c("Allocted");
+    }
+    ndbrequire(!handle.done());
+    {
+      SafeCounter tmp(c_counterMgr, handle);
+      tmp.clearWaitingFor(3);
+      ndbrequire(tmp.done());
+      ndbout_c("Deallocted");
+    }
+    ndbrequire(handle.done());
+  }
+  {
+    NodeBitmask nodes;
+    nodes.clear();
+
+    nodes.set(2);
+    nodes.set(3);
+    nodes.set(4);
+    nodes.set(5);
+
+    {
+      Uint32 i = 0;
+      while((i = nodes.find(i)) != NodeBitmask::NotFound){
+	ndbout_c("1 Node id = %u", i);
+	i++;
+      }
+    }
+
+    NodeReceiverGroup rg(DBDICT, nodes);
+    RequestTracker rt2;
+    ndbrequire(rt2.done());
+    ndbrequire(!rt2.hasRef());
+    ndbrequire(!rt2.hasConf());
+    rt2.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
+
+    RequestTracker rt3;
+    rt3.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
+
+    ndbrequire(!rt2.done());
+    ndbrequire(!rt3.done());
+
+    rt2.reportRef(c_counterMgr, 2);
+    rt3.reportConf(c_counterMgr, 2);
+
+    ndbrequire(!rt2.done());
+    ndbrequire(!rt3.done());
+
+    rt2.reportConf(c_counterMgr, 3);
+    rt3.reportConf(c_counterMgr, 3);
+
+    ndbrequire(!rt2.done());
+    ndbrequire(!rt3.done());
+
+    rt2.reportConf(c_counterMgr, 4);
+    rt3.reportConf(c_counterMgr, 4);
+
+    ndbrequire(!rt2.done());
+    ndbrequire(!rt3.done());
+
+    rt2.reportConf(c_counterMgr, 5);
+    rt3.reportConf(c_counterMgr, 5);
+
+    ndbrequire(rt2.done());
+    ndbrequire(rt3.done());
+  }
+#endif
+
+  if (! assembleFragments(signal)) {
+    jam();
+    return;
+  }
+
+  CreateEvntReq *req = (CreateEvntReq*)signal->getDataPtr();
+  const CreateEvntReq::RequestType requestType = req->getRequestType();
+  const Uint32                     requestFlag = req->getRequestFlag();
+
+  if (refToBlock(signal->senderBlockRef()) != DBDICT &&
+      getOwnNodeId() != c_masterNodeId)
+  {
+    jam();
+    releaseSections(signal);
+    
+    CreateEvntRef * ref = (CreateEvntRef *)signal->getDataPtrSend();
+    ref->setUserRef(reference());
+    ref->setErrorCode(CreateEvntRef::NotMaster);
+    ref->setErrorLine(__LINE__);
+    ref->setErrorNode(reference());
+    ref->setMasterNode(c_masterNodeId);
+    sendSignal(signal->senderBlockRef(), GSN_CREATE_EVNT_REF, signal,
+	       CreateEvntRef::SignalLength2, JBB);
+    return;
+  }
+
+  OpCreateEventPtr evntRecPtr;
+  // Seize a Create Event record
+  if (!c_opCreateEvent.seize(evntRecPtr)) {
+    // Failed to allocate event record
+    jam();
+    releaseSections(signal);
+
+    CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
+    ret->senderRef = reference();
+    ret->setErrorCode(747);
+    ret->setErrorLine(__LINE__);
+    ret->setErrorNode(reference());
+    sendSignal(signal->senderBlockRef(), GSN_CREATE_EVNT_REF, signal,
+	       CreateEvntRef::SignalLength, JBB);
+    return;
+  }
+
+#ifdef EVENT_DEBUG
+  ndbout_c("DBDICT::execCREATE_EVNT_REQ from %u evntRecId = (%d)", refToNode(signal->getSendersBlockRef()), evntRecPtr.i);
+#endif
+  
+  ndbrequire(req->getUserRef() == signal->getSendersBlockRef());
+
+  evntRecPtr.p->init(req,this);
+
+  if (requestFlag & (Uint32)CreateEvntReq::RT_DICT_AFTER_GET) {
+    jam();
+    EVENT_TRACE;
+    createEvent_RT_DICT_AFTER_GET(signal, evntRecPtr);
+    return;
+  }
+  if (requestType == CreateEvntReq::RT_USER_GET) {
+    jam();
+    EVENT_TRACE;
+    createEvent_RT_USER_GET(signal, evntRecPtr);
+    return;
+  }
+  if (requestType == CreateEvntReq::RT_USER_CREATE) {
+    jam();
+    EVENT_TRACE;
+    createEvent_RT_USER_CREATE(signal, evntRecPtr);
+    return;
+  }
+
+#ifdef EVENT_DEBUG
+  ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ other" << endl;
+#endif
+  jam();
+  releaseSections(signal);
+    
+  evntRecPtr.p->m_errorCode = 1;
+  evntRecPtr.p->m_errorLine = __LINE__;
+  evntRecPtr.p->m_errorNode = reference();
+  
+  createEvent_sendReply(signal, evntRecPtr);
+}
+
+/********************************************************************
+ *
+ * Event creation
+ *
+ *****************************************************************/
+
+void
+Dbdict::createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr)
+{
+  jam();
+  DBUG_ENTER("Dbdict::createEvent_RT_USER_CREATE");
+  evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
+
+#ifdef EVENT_DEBUG
+  ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ RT_USER" << endl;
+  char buf[128] = {0};
+  AttributeMask mask = evntRecPtr.p->m_request.getAttrListBitmask(); 
+  mask.getText(buf);
+  ndbout_c("mask = %s", buf);
+#endif
+
+  // Interpret the long signal
+
+  SegmentedSectionPtr ssPtr;
+  // save name and event properties
+  signal->getSection(ssPtr, CreateEvntReq::EVENT_NAME_SECTION);
+
+  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
+#ifdef EVENT_DEBUG
+  r0.printAll(ndbout);
+#endif
+    // event name
+  if ((!r0.first()) ||
+      (r0.getValueType() != SimpleProperties::StringValue) ||
+      (r0.getValueLen() <= 0)) {
+    jam();
+    releaseSections(signal);
+
+    evntRecPtr.p->m_errorCode = 1;
+    evntRecPtr.p->m_errorLine = __LINE__;
+    evntRecPtr.p->m_errorNode = reference();
+
+    createEvent_sendReply(signal, evntRecPtr);
+    DBUG_VOID_RETURN;
+  }
+  r0.getString(evntRecPtr.p->m_eventRec.NAME);
+  {
+    int len = strlen(evntRecPtr.p->m_eventRec.NAME);
+    memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
+#ifdef EVENT_DEBUG
+    printf("CreateEvntReq::RT_USER_CREATE; EventName %s, len %u\n",
+	   evntRecPtr.p->m_eventRec.NAME, len);
+    for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
+      printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
+    printf("\n");
+#endif
+  }
+  // table name
+  if ((!r0.next()) ||
+      (r0.getValueType() != SimpleProperties::StringValue) ||
+      (r0.getValueLen() <= 0)) {
+    jam();
+    releaseSections(signal);
+    
+    evntRecPtr.p->m_errorCode = 1;
+    evntRecPtr.p->m_errorLine = __LINE__;
+    evntRecPtr.p->m_errorNode = reference();
+    
+    createEvent_sendReply(signal, evntRecPtr);
+    DBUG_VOID_RETURN;
+  }
+  r0.getString(evntRecPtr.p->m_eventRec.TABLE_NAME);
+  {
+    int len = strlen(evntRecPtr.p->m_eventRec.TABLE_NAME);
+    memset(evntRecPtr.p->m_eventRec.TABLE_NAME+len, 0, MAX_TAB_NAME_SIZE-len);
+  }
+
+  releaseSections(signal);
+  
+  // Send request to SUMA
+
+  CreateSubscriptionIdReq * sumaIdReq =
+    (CreateSubscriptionIdReq *)signal->getDataPtrSend();
+  
+  // make sure we save the original sender for later
+  sumaIdReq->senderRef  = reference();
+  sumaIdReq->senderData = evntRecPtr.i;
+#ifdef EVENT_DEBUG
+  ndbout << "sumaIdReq->senderData = " << sumaIdReq->senderData << endl;
+#endif
+  sendSignal(SUMA_REF, GSN_CREATE_SUBID_REQ, signal, 
+	     CreateSubscriptionIdReq::SignalLength, JBB);
+  // we should now return in either execCREATE_SUBID_CONF
+  // or execCREATE_SUBID_REF
+  DBUG_VOID_RETURN;
+}
+
+void Dbdict::execCREATE_SUBID_REF(Signal* signal)
+{
+  jamEntry();
+  DBUG_ENTER("Dbdict::execCREATE_SUBID_REF");
+  CreateSubscriptionIdRef * const ref =
+    (CreateSubscriptionIdRef *)signal->getDataPtr();
+  OpCreateEventPtr evntRecPtr;
+
+  evntRecPtr.i = ref->senderData;
+  ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+
+  if (ref->errorCode)
+  {
+    evntRecPtr.p->m_errorCode = ref->errorCode;
+    evntRecPtr.p->m_errorLine = __LINE__;
+  }
+  else
+  {
+    evntRecPtr.p->m_errorCode = 1;
+    evntRecPtr.p->m_errorLine = __LINE__;
+  }
+  evntRecPtr.p->m_errorNode = reference();
+
+  createEvent_sendReply(signal, evntRecPtr);
+  DBUG_VOID_RETURN;
+}
+
+void Dbdict::execCREATE_SUBID_CONF(Signal* signal)
+{
+  jamEntry();
+  DBUG_ENTER("Dbdict::execCREATE_SUBID_CONF");
+
+  CreateSubscriptionIdConf const * sumaIdConf =
+    (CreateSubscriptionIdConf *)signal->getDataPtr();
+
+  Uint32 evntRecId = sumaIdConf->senderData;
+  OpCreateEvent *evntRec;
+
+  ndbrequire((evntRec = c_opCreateEvent.getPtr(evntRecId)) != NULL);
+
+  evntRec->m_request.setEventId(sumaIdConf->subscriptionId);
+  evntRec->m_request.setEventKey(sumaIdConf->subscriptionKey);
+
+  releaseSections(signal);
+
+  Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
+
+  prepareTransactionEventSysTable(&c, signal, evntRecId,
+				  UtilPrepareReq::Insert);
+  DBUG_VOID_RETURN;
+}
+
+void
+Dbdict::createEventComplete_RT_USER_CREATE(Signal* signal,
+					   OpCreateEventPtr evntRecPtr){
+  jam();
+  createEvent_sendReply(signal, evntRecPtr);
+}
+
+/*********************************************************************
+ *
+ * UTIL_PREPARE, UTIL_EXECUTE
+ *
+ * insert or read systable NDB$EVENTS_0
+ */
+
+void interpretUtilPrepareErrorCode(UtilPrepareRef::ErrorCode errorCode,
+				   Uint32& error, Uint32& line)
+{
+  DBUG_ENTER("interpretUtilPrepareErrorCode");
+  switch (errorCode) {
+  case UtilPrepareRef::NO_ERROR:
+    jam();
+    error = 1;
+    line = __LINE__;
+    DBUG_VOID_RETURN;
+  case UtilPrepareRef::PREPARE_SEIZE_ERROR:
+    jam();
+    error = 748;
+    line = __LINE__;
+    DBUG_VOID_RETURN;
+  case UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR:
+    jam();
+    error = 1;
+    line = __LINE__;
+    DBUG_VOID_RETURN;
+  case UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR:
+    jam();
+    error = 1;
+    line = __LINE__;
+    DBUG_VOID_RETURN;
+  case UtilPrepareRef::DICT_TAB_INFO_ERROR:
+    jam();
+    error = 1;
+    line = __LINE__;
+    DBUG_VOID_RETURN;
+  case UtilPrepareRef::MISSING_PROPERTIES_SECTION:
+    jam();
+    error = 1;
+    line = __LINE__;
+    DBUG_VOID_RETURN;
+  default:
+    jam();
+    error = 1;
+    line = __LINE__;
+    DBUG_VOID_RETURN;
+  }
+  DBUG_VOID_RETURN;
+}
+
+void 
+Dbdict::createEventUTIL_PREPARE(Signal* signal,
+				Uint32 callbackData,
+				Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  if (returnCode == 0) {
+    UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
+    OpCreateEventPtr evntRecPtr;
+    jam();
+    evntRecPtr.i = req->getSenderData();
+    const Uint32 prepareId = req->getPrepareId();
+    
+    ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+    
+    Callback c = { safe_cast(&Dbdict::createEventUTIL_EXECUTE), 0 };
+
+    switch (evntRecPtr.p->m_requestType) {
+    case CreateEvntReq::RT_USER_GET:
+      jam();
+      executeTransEventSysTable(&c, signal,
+				evntRecPtr.i, evntRecPtr.p->m_eventRec,
+				prepareId, UtilPrepareReq::Read);
+      break;
+    case CreateEvntReq::RT_USER_CREATE:
+      {
+	evntRecPtr.p->m_eventRec.EVENT_TYPE =
+          evntRecPtr.p->m_request.getEventType() | evntRecPtr.p->m_request.getReportFlags();
+	evntRecPtr.p->m_eventRec.TABLEID  = evntRecPtr.p->m_request.getTableId();
+	evntRecPtr.p->m_eventRec.TABLEVERSION=evntRecPtr.p->m_request.getTableVersion();
+	AttributeMask m = evntRecPtr.p->m_request.getAttrListBitmask();
+	memcpy(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK, &m,
+	       sizeof(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK));
+	evntRecPtr.p->m_eventRec.SUBID  = evntRecPtr.p->m_request.getEventId();
+	evntRecPtr.p->m_eventRec.SUBKEY = evntRecPtr.p->m_request.getEventKey();
+	DBUG_PRINT("info",
+		   ("CREATE: event name: %s table name: %s table id: %u table version: %u",
+		    evntRecPtr.p->m_eventRec.NAME,
+		    evntRecPtr.p->m_eventRec.TABLE_NAME,
+		    evntRecPtr.p->m_eventRec.TABLEID,
+		    evntRecPtr.p->m_eventRec.TABLEVERSION));
+  
+      }
+      jam();
+      executeTransEventSysTable(&c, signal,
+				evntRecPtr.i, evntRecPtr.p->m_eventRec,
+				prepareId, UtilPrepareReq::Insert);
+      break;
+    default:
+#ifdef EVENT_DEBUG
+      printf("type = %d\n", evntRecPtr.p->m_requestType);
+      printf("bet type = %d\n", CreateEvntReq::RT_USER_GET);
+      printf("create type = %d\n", CreateEvntReq::RT_USER_CREATE);
+#endif
+      ndbrequire(false);
+    }
+  } else { // returnCode != 0
+    UtilPrepareRef* const ref = (UtilPrepareRef*)signal->getDataPtr();
+
+    const UtilPrepareRef::ErrorCode errorCode =
+      (UtilPrepareRef::ErrorCode)ref->getErrorCode();
+
+    OpCreateEventPtr evntRecPtr;
+    evntRecPtr.i = ref->getSenderData();
+    ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+
+    interpretUtilPrepareErrorCode(errorCode, evntRecPtr.p->m_errorCode,
+				  evntRecPtr.p->m_errorLine);
+    evntRecPtr.p->m_errorNode = reference();
+
+    createEvent_sendReply(signal, evntRecPtr);
+  }
+}
+
+void Dbdict::executeTransEventSysTable(Callback *pcallback, Signal *signal,
+				       const Uint32 ptrI,
+				       sysTab_NDBEVENTS_0& m_eventRec,
+				       const Uint32 prepareId,
+				       UtilPrepareReq::OperationTypeValue prepReq)
+{
+  jam();
+  const Uint32 noAttr = EVENT_SYSTEM_TABLE_LENGTH;
+  Uint32 total_len = 0;
+
+  Uint32* attrHdr = signal->theData + 25;
+  Uint32* attrPtr = attrHdr;
+
+  Uint32 id=0;
+  // attribute 0 event name: Primary Key
+  {
+    AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]);
+    total_len += sysTab_NDBEVENTS_0_szs[id];
+    attrPtr++; id++;
+  }
+
+  switch (prepReq) {
+  case UtilPrepareReq::Read:
+    jam();
+    EVENT_TRACE;
+    // no more
+    while ( id < noAttr )
+      AttributeHeader::init(attrPtr++, id++, 0);
+    ndbrequire(id == (Uint32) noAttr);
+    break;
+  case UtilPrepareReq::Insert:
+    jam();
+    EVENT_TRACE;
+    while ( id < noAttr ) {
+      AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]);
+      total_len += sysTab_NDBEVENTS_0_szs[id];
+      attrPtr++; id++;
+    }
+    ndbrequire(id == (Uint32) noAttr);
+    break;
+  case UtilPrepareReq::Delete:
+    ndbrequire(id == 1);
+    break;
+  default:
+    ndbrequire(false);
+  }
+    
+  LinearSectionPtr headerPtr;
+  LinearSectionPtr dataPtr;
+    
+  headerPtr.p = attrHdr;
+  headerPtr.sz = noAttr;
+    
+  dataPtr.p = (Uint32*)&m_eventRec;
+  dataPtr.sz = total_len/4;
+
+  ndbrequire((total_len == sysTab_NDBEVENTS_0_szs[0]) ||
+	     (total_len == sizeof(sysTab_NDBEVENTS_0)));
+
+#if 0
+    printf("Header size %u\n", headerPtr.sz);
+    for(int i = 0; i < (int)headerPtr.sz; i++)
+      printf("H'%.8x ", attrHdr[i]);
+    printf("\n");
+    
+    printf("Data size %u\n", dataPtr.sz);
+    for(int i = 0; i < (int)dataPtr.sz; i++)
+      printf("H'%.8x ", dataPage[i]);
+    printf("\n");
+#endif
+
+  executeTransaction(pcallback, signal, 
+		     ptrI,
+		     prepareId,
+		     id,
+		     headerPtr,
+		     dataPtr);
+}
+
+void Dbdict::executeTransaction(Callback *pcallback,
+				Signal* signal, 
+				Uint32 senderData,
+				Uint32 prepareId,
+				Uint32 noAttr,
+				LinearSectionPtr headerPtr,
+				LinearSectionPtr dataPtr)
+{
+  jam();
+  EVENT_TRACE;
+
+  UtilExecuteReq * utilExecuteReq = 
+    (UtilExecuteReq *)signal->getDataPtrSend();
+
+  utilExecuteReq->setSenderRef(reference());
+  utilExecuteReq->setSenderData(senderData);
+  utilExecuteReq->setPrepareId(prepareId);
+  utilExecuteReq->setReleaseFlag(); // must be done after setting prepareId
+
+#if 0
+  printf("Header size %u\n", headerPtr.sz);
+  for(int i = 0; i < (int)headerPtr.sz; i++)
+    printf("H'%.8x ", headerBuffer[i]);
+  printf("\n");
+  
+  printf("Data size %u\n", dataPtr.sz);
+  for(int i = 0; i < (int)dataPtr.sz; i++)
+    printf("H'%.8x ", dataBuffer[i]);
+  printf("\n");
+#endif
+
+  struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections];
+  sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = headerPtr.p;
+  sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr;
+  sectionsPtr[UtilExecuteReq::DATA_SECTION].p = dataPtr.p;
+  sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataPtr.sz;
+
+  sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal,
+		    UtilExecuteReq::SignalLength, JBB,
+		    sectionsPtr, UtilExecuteReq::NoOfSections);
+}
+
+void Dbdict::parseReadEventSys(Signal* signal, sysTab_NDBEVENTS_0& m_eventRec)
+{
+  SegmentedSectionPtr headerPtr, dataPtr;
+  jam();
+  signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
+  SectionReader headerReader(headerPtr, getSectionSegmentPool());
+      
+  signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
+  SectionReader dataReader(dataPtr, getSectionSegmentPool());
+  
+  AttributeHeader header;
+  Uint32 *dst = (Uint32*)&m_eventRec;
+
+  for (int i = 0; i < EVENT_SYSTEM_TABLE_LENGTH; i++) {
+    headerReader.getWord((Uint32 *)&header);
+    int sz = header.getDataSize();
+    for (int i=0; i < sz; i++)
+      dataReader.getWord(dst++);
+  }
+
+  ndbrequire( ((char*)dst-(char*)&m_eventRec) == sizeof(m_eventRec) );
+
+  releaseSections(signal);
+}
+    
+void Dbdict::createEventUTIL_EXECUTE(Signal *signal, 
+				     Uint32 callbackData,
+				     Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  if (returnCode == 0) {
+    // Entry into system table all set
+    UtilExecuteConf* const conf = (UtilExecuteConf*)signal->getDataPtr();
+    jam();
+    OpCreateEventPtr evntRecPtr;
+    evntRecPtr.i = conf->getSenderData();
+    
+    ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+    OpCreateEvent *evntRec = evntRecPtr.p;
+    
+    switch (evntRec->m_requestType) {
+    case CreateEvntReq::RT_USER_GET: {
+      parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
+
+      evntRec->m_request.setEventType(evntRecPtr.p->m_eventRec.EVENT_TYPE);
+      evntRec->m_request.setReportFlags(evntRecPtr.p->m_eventRec.EVENT_TYPE);
+      evntRec->m_request.setTableId(evntRecPtr.p->m_eventRec.TABLEID);
+      evntRec->m_request.setTableVersion(evntRecPtr.p->m_eventRec.TABLEVERSION);
+      evntRec->m_request.setAttrListBitmask(*(AttributeMask*)
+					    evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK);
+      evntRec->m_request.setEventId(evntRecPtr.p->m_eventRec.SUBID);
+      evntRec->m_request.setEventKey(evntRecPtr.p->m_eventRec.SUBKEY);
+
+      DBUG_PRINT("info",
+		 ("GET: event name: %s table name: %s table id: %u table version: %u",
+		  evntRecPtr.p->m_eventRec.NAME,
+		  evntRecPtr.p->m_eventRec.TABLE_NAME,
+		  evntRecPtr.p->m_eventRec.TABLEID,
+		  evntRecPtr.p->m_eventRec.TABLEVERSION));
+      
+      // find table id for event table
+      DictObject* obj_ptr_p = get_object(evntRecPtr.p->m_eventRec.TABLE_NAME);
+      if(!obj_ptr_p){
+	jam();
+	evntRecPtr.p->m_errorCode = 723;
+	evntRecPtr.p->m_errorLine = __LINE__;
+	evntRecPtr.p->m_errorNode = reference();
+	
+	createEvent_sendReply(signal, evntRecPtr);
+	return;
+      }
+      
+      TableRecordPtr tablePtr;
+      c_tableRecordPool.getPtr(tablePtr, obj_ptr_p->m_id);
+      evntRec->m_request.setTableId(tablePtr.p->tableId);
+      evntRec->m_request.setTableVersion(tablePtr.p->tableVersion);
+      
+      createEventComplete_RT_USER_GET(signal, evntRecPtr);
+      return;
+    }
+    case CreateEvntReq::RT_USER_CREATE: {
+#ifdef EVENT_DEBUG
+      printf("create type = %d\n", CreateEvntReq::RT_USER_CREATE);
+#endif
+      jam();
+      createEventComplete_RT_USER_CREATE(signal, evntRecPtr);
+      return;
+    }
+      break;
+    default:
+      ndbrequire(false);
+    }
+  } else { // returnCode != 0
+    UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
+    OpCreateEventPtr evntRecPtr;
+    evntRecPtr.i = ref->getSenderData();
+    ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+    jam();
+    evntRecPtr.p->m_errorNode = reference();
+    evntRecPtr.p->m_errorLine = __LINE__;
+
+    switch (ref->getErrorCode()) {
+    case UtilExecuteRef::TCError:
+      switch (ref->getTCErrorCode()) {
+      case ZNOT_FOUND:
+	jam();
+	evntRecPtr.p->m_errorCode = 4710;
+	break;
+      case ZALREADYEXIST:
+	jam();
+	evntRecPtr.p->m_errorCode = 746;
+	break;
+      default:
+	jam();
+	evntRecPtr.p->m_errorCode = ref->getTCErrorCode();
+	break;
+      }
+      break;
+    default:
+      jam();
+      evntRecPtr.p->m_errorCode = ref->getErrorCode();
+      break;
+    }
+    
+    createEvent_sendReply(signal, evntRecPtr);
+  }
+}
+
+/***********************************************************************
+ *
+ * NdbEventOperation, reading systable, creating event in suma
+ *
+ */
+
+void
+Dbdict::createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
+  jam();
+  EVENT_TRACE;
+#ifdef EVENT_PH2_DEBUG
+  ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REQ::RT_USER_GET evntRecPtr.i = (%d), ref = %u", evntRecPtr.i, evntRecPtr.p->m_request.getUserRef());
+#endif
+
+  SegmentedSectionPtr ssPtr;
+
+  signal->getSection(ssPtr, 0);
+
+  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
+#ifdef EVENT_DEBUG
+  r0.printAll(ndbout);
+#endif
+  if ((!r0.first()) ||
+      (r0.getValueType() != SimpleProperties::StringValue) ||
+      (r0.getValueLen() <= 0)) {
+    jam();
+    releaseSections(signal);
+
+    evntRecPtr.p->m_errorCode = 1;
+    evntRecPtr.p->m_errorLine = __LINE__;
+    evntRecPtr.p->m_errorNode = reference();
+
+    createEvent_sendReply(signal, evntRecPtr);
+    return;
+  }
+
+  r0.getString(evntRecPtr.p->m_eventRec.NAME);
+  int len = strlen(evntRecPtr.p->m_eventRec.NAME);
+  memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
+  
+  releaseSections(signal);
+  
+  Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
+  
+  prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
+				  UtilPrepareReq::Read);
+  /* 
+   * Will read systable and fill an OpCreateEventPtr
+   * and return below
+   */
+}
+
+void
+Dbdict::createEventComplete_RT_USER_GET(Signal* signal,
+					OpCreateEventPtr evntRecPtr){
+  jam();
+
+  // Send to oneself and the other DICT's
+  CreateEvntReq * req = (CreateEvntReq *)signal->getDataPtrSend();
+      
+  *req = evntRecPtr.p->m_request;
+  req->senderRef = reference();
+  req->senderData = evntRecPtr.i;
+      
+  req->addRequestFlag(CreateEvntReq::RT_DICT_AFTER_GET);
+      
+#ifdef EVENT_PH2_DEBUG
+  ndbout_c("DBDICT(Coordinator) sending GSN_CREATE_EVNT_REQ::RT_DICT_AFTER_GET to DBDICT participants evntRecPtr.i = (%d)", evntRecPtr.i);
+#endif
+
+  NodeReceiverGroup rg(DBDICT, c_aliveNodes);
+  RequestTracker & p = evntRecPtr.p->m_reqTracker;
+  if (!p.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 
+			     evntRecPtr.i))
+  {
+    jam();
+    evntRecPtr.p->m_errorCode = 701;
+    createEvent_sendReply(signal, evntRecPtr);
+    return;
+  }
+
+  sendSignal(rg, GSN_CREATE_EVNT_REQ, signal, CreateEvntReq::SignalLength, JBB);
+}
+
+void
+Dbdict::createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI,
+				     Uint32 returnCode){
+  OpCreateEventPtr evntRecPtr;
+  c_opCreateEvent.getPtr(evntRecPtr, eventRecPtrI);
+  createEvent_sendReply(signal, evntRecPtr);
+}
+
+void Dbdict::execCREATE_EVNT_REF(Signal* signal) 
+{
+  jamEntry();      
+  EVENT_TRACE;
+  CreateEvntRef * const ref = (CreateEvntRef *)signal->getDataPtr();
+  OpCreateEventPtr evntRecPtr;
+
+  evntRecPtr.i = ref->getUserData();
+
+  ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+
+#ifdef EVENT_PH2_DEBUG
+  ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REF evntRecPtr.i = (%d)", evntRecPtr.i);
+#endif
+
+  if (ref->errorCode == CreateEvntRef::NF_FakeErrorREF){
+    jam();
+    evntRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(ref->senderRef));
+  } else {
+    jam();
+    evntRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(ref->senderRef));
+  }
+  createEvent_sendReply(signal, evntRecPtr);
+
+  return;
+}
+
+void Dbdict::execCREATE_EVNT_CONF(Signal* signal)
+{
+  jamEntry();
+  EVENT_TRACE;
+  CreateEvntConf * const conf = (CreateEvntConf *)signal->getDataPtr();
+  OpCreateEventPtr evntRecPtr;
+
+  evntRecPtr.i = conf->getUserData();
+
+  ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+
+#ifdef EVENT_PH2_DEBUG
+  ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_CONF evntRecPtr.i = (%d)", evntRecPtr.i);
+#endif
+
+  evntRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(conf->senderRef));
+
+  // we will only have a valid tablename if it the master DICT sending this
+  // but that's ok
+  LinearSectionPtr ptr[1];
+  ptr[0].p = (Uint32 *)evntRecPtr.p->m_eventRec.TABLE_NAME;
+  ptr[0].sz =
+    (strlen(evntRecPtr.p->m_eventRec.TABLE_NAME)+4)/4; // to make sure we have a null
+
+  createEvent_sendReply(signal, evntRecPtr, ptr, 1);
+    
+  return;
+}
+
+/************************************************
+ *
+ * Participant stuff
+ *
+ */
+
+void
+Dbdict::createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
+  DBUG_ENTER("Dbdict::createEvent_RT_DICT_AFTER_GET");
+  jam();
+  evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
+  
+#ifdef EVENT_PH2_DEBUG
+  ndbout_c("DBDICT(Participant) got CREATE_EVNT_REQ::RT_DICT_AFTER_GET evntRecPtr.i = (%d)", evntRecPtr.i);
+#endif
+
+  // the signal comes from the DICT block that got the first user request!
+  // This code runs on all DICT nodes, including oneself
+
+  // Seize a Create Event record, the Coordinator will now have two seized
+  // but that's ok, it's like a recursion
+
+  CRASH_INSERTION2(6009, getOwnNodeId() != c_masterNodeId);
+
+  SubCreateReq * sumaReq = (SubCreateReq *)signal->getDataPtrSend();
+  
+  sumaReq->senderRef        = reference(); // reference to DICT
+  sumaReq->senderData       = evntRecPtr.i;
+  sumaReq->subscriptionId   = evntRecPtr.p->m_request.getEventId();
+  sumaReq->subscriptionKey  = evntRecPtr.p->m_request.getEventKey();
+  sumaReq->subscriptionType = SubCreateReq::TableEvent;
+  if (evntRecPtr.p->m_request.getReportAll())
+    sumaReq->subscriptionType|= SubCreateReq::ReportAll;
+  if (evntRecPtr.p->m_request.getReportSubscribe())
+    sumaReq->subscriptionType|= SubCreateReq::ReportSubscribe;
+  sumaReq->tableId          = evntRecPtr.p->m_request.getTableId();
+    
+#ifdef EVENT_PH2_DEBUG
+  ndbout_c("sending GSN_SUB_CREATE_REQ");
+#endif
+
+  sendSignal(SUMA_REF, GSN_SUB_CREATE_REQ, signal,
+	     SubCreateReq::SignalLength, JBB);
+  DBUG_VOID_RETURN;
+}
+
+void Dbdict::execSUB_CREATE_REF(Signal* signal)
+{
+  jamEntry();
+  DBUG_ENTER("Dbdict::execSUB_CREATE_REF");
+
+  SubCreateRef * const ref = (SubCreateRef *)signal->getDataPtr();
+  OpCreateEventPtr evntRecPtr;
+
+  evntRecPtr.i = ref->senderData;
+  ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+
+  if (ref->errorCode == 1415) {
+    jam();
+    createEvent_sendReply(signal, evntRecPtr);
+    DBUG_VOID_RETURN;
+  }
+
+  if (ref->errorCode)
+  {
+    evntRecPtr.p->m_errorCode = ref->errorCode;
+    evntRecPtr.p->m_errorLine = __LINE__;
+  }
+  else
+  {
+    evntRecPtr.p->m_errorCode = 1;
+    evntRecPtr.p->m_errorLine = __LINE__;
+  }
+  evntRecPtr.p->m_errorNode = reference();
+
+  createEvent_sendReply(signal, evntRecPtr);
+  DBUG_VOID_RETURN;
+}
+
+void Dbdict::execSUB_CREATE_CONF(Signal* signal)
+{
+  jamEntry();
+  DBUG_ENTER("Dbdict::execSUB_CREATE_CONF");
+  EVENT_TRACE;
+
+  SubCreateConf * const sumaConf = (SubCreateConf *)signal->getDataPtr();
+  OpCreateEventPtr evntRecPtr;
+  evntRecPtr.i = sumaConf->senderData;
+  ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
+
+  createEvent_sendReply(signal, evntRecPtr);
+
+  DBUG_VOID_RETURN;
+}
+
+/****************************************************
+ *
+ * common create reply method
+ *
+ *******************************************************/
+
+void Dbdict::createEvent_sendReply(Signal* signal,
+				   OpCreateEventPtr evntRecPtr,
+				   LinearSectionPtr *ptr, int noLSP)
+{
+  jam();
+  EVENT_TRACE;
+
+  // check if we're ready to sent reply
+  // if we are the master dict we might be waiting for conf/ref
+
+  if (!evntRecPtr.p->m_reqTracker.done()) {
+    jam();
+    return; // there's more to come
+  }
+
+  if (evntRecPtr.p->m_reqTracker.hasRef()) {
+    ptr = NULL; // we don't want to return anything if there's an error
+    if (!evntRecPtr.p->hasError()) {
+      evntRecPtr.p->m_errorCode = 1;
+      evntRecPtr.p->m_errorLine = __LINE__;
+      evntRecPtr.p->m_errorNode = reference();
+      jam();
+    } else 
+      jam();
+  }
+
+  // reference to API if master DICT
+  // else reference to master DICT
+  Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
+  Uint32 signalLength;
+  Uint32 gsn;
+
+  if (evntRecPtr.p->hasError()) {
+    jam();
+    EVENT_TRACE;
+    CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
+    
+    ret->setEventId(evntRecPtr.p->m_request.getEventId());
+    ret->setEventKey(evntRecPtr.p->m_request.getEventKey());
+    ret->setUserData(evntRecPtr.p->m_request.getUserData());
+    ret->senderRef = reference();
+    ret->setTableId(evntRecPtr.p->m_request.getTableId());
+    ret->setTableVersion(evntRecPtr.p->m_request.getTableVersion());
+    ret->setEventType(evntRecPtr.p->m_request.getEventType());
+    ret->setRequestType(evntRecPtr.p->m_request.getRequestType());
+
+    ret->setErrorCode(evntRecPtr.p->m_errorCode);
+    ret->setErrorLine(evntRecPtr.p->m_errorLine);
+    ret->setErrorNode(evntRecPtr.p->m_errorNode);
+
+    signalLength = CreateEvntRef::SignalLength;
+#ifdef EVENT_PH2_DEBUG
+    ndbout_c("DBDICT sending GSN_CREATE_EVNT_REF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
+    ndbout_c("errorCode = %u", evntRecPtr.p->m_errorCode);
+    ndbout_c("errorLine = %u", evntRecPtr.p->m_errorLine);
+#endif
+    gsn = GSN_CREATE_EVNT_REF;
+
+  } else {
+    jam();
+    EVENT_TRACE;
+    CreateEvntConf * evntConf = (CreateEvntConf *)signal->getDataPtrSend();
+    
+    evntConf->setEventId(evntRecPtr.p->m_request.getEventId());
+    evntConf->setEventKey(evntRecPtr.p->m_request.getEventKey());
+    evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
+    evntConf->senderRef = reference();
+    evntConf->setTableId(evntRecPtr.p->m_request.getTableId());
+    evntConf->setTableVersion(evntRecPtr.p->m_request.getTableVersion());
+    evntConf->setAttrListBitmask(evntRecPtr.p->m_request.getAttrListBitmask());
+    evntConf->setEventType(evntRecPtr.p->m_request.getEventType());
+    evntConf->setRequestType(evntRecPtr.p->m_request.getRequestType());
+
+    signalLength = CreateEvntConf::SignalLength;
+#ifdef EVENT_PH2_DEBUG
+    ndbout_c("DBDICT sending GSN_CREATE_EVNT_CONF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
+#endif
+    gsn = GSN_CREATE_EVNT_CONF;
+  }
+
+  if (ptr) {
+    jam();
+    sendSignal(senderRef, gsn, signal, signalLength, JBB, ptr, noLSP);
+  } else {
+    jam();
+    sendSignal(senderRef, gsn, signal, signalLength, JBB);
+  }
+
+  c_opCreateEvent.release(evntRecPtr);
+}
+
+/*************************************************************/
+
+/********************************************************************
+ *
+ * Start event
+ *
+ *******************************************************************/
+
+void Dbdict::execSUB_START_REQ(Signal* signal)
+{
+  jamEntry();
+
+  Uint32 origSenderRef = signal->senderBlockRef();
+
+  if (refToBlock(origSenderRef) != DBDICT &&
+      getOwnNodeId() != c_masterNodeId)
+  {
+    /*
+     * Coordinator but not master
+     */
+    SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->errorCode = SubStartRef::NotMaster;
+    ref->m_masterNodeId = c_masterNodeId;
+    sendSignal(origSenderRef, GSN_SUB_START_REF, signal,
+	       SubStartRef::SignalLength2, JBB);
+    return;
+  }
+  OpSubEventPtr subbPtr;
+  Uint32 errCode = 0;
+
+  DictLockPtr loopPtr;
+  if (c_dictLockQueue.first(loopPtr) &&
+      loopPtr.p->lt->lockType == DictLockReq::NodeRestartLock)
+  {
+    jam();
+    errCode = 1405;
+    goto busy;
+  }
+
+  if (!c_opSubEvent.seize(subbPtr)) {
+    errCode = SubStartRef::Busy;
+busy:
+    jam();
+    SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
+
+    { // fix
+      Uint32 subcriberRef = ((SubStartReq*)signal->getDataPtr())->subscriberRef;
+      ref->subscriberRef = subcriberRef;
+    }
+    jam();
+    //      ret->setErrorCode(SubStartRef::SeizeError);
+    //      ret->setErrorLine(__LINE__);
+    //      ret->setErrorNode(reference());
+    ref->senderRef = reference();
+    ref->errorCode = errCode;
+
+    sendSignal(origSenderRef, GSN_SUB_START_REF, signal,
+	       SubStartRef::SignalLength2, JBB);
+    return;
+  }
+
+  {
+    const SubStartReq* req = (SubStartReq*) signal->getDataPtr();
+    subbPtr.p->m_senderRef = req->senderRef;
+    subbPtr.p->m_senderData = req->senderData;
+    subbPtr.p->m_errorCode = 0;
+  }
+  
+  if (refToBlock(origSenderRef) != DBDICT) {
+    /*
+     * Coordinator
+     */
+    jam();
+    
+    subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
+    NodeReceiverGroup rg(DBDICT, c_aliveNodes);
+    RequestTracker & p = subbPtr.p->m_reqTracker;
+    if (!p.init<SubStartRef>(c_counterMgr, rg, GSN_SUB_START_REF, subbPtr.i))
+    {
+      c_opSubEvent.release(subbPtr);
+      errCode = SubStartRef::Busy;
+      goto busy;
+    }
+    
+    SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
+    
+    req->senderRef  = reference();
+    req->senderData = subbPtr.i;
+    
+#ifdef EVENT_PH3_DEBUG
+    ndbout_c("DBDICT(Coordinator) sending GSN_SUB_START_REQ to DBDICT participants subbPtr.i = (%d)", subbPtr.i);
+#endif
+
+    sendSignal(rg, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
+    return;
+  }
+  /*
+   * Participant
+   */
+  ndbrequire(refToBlock(origSenderRef) == DBDICT);
+
+  CRASH_INSERTION(6007);
+  
+  {
+    SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
+    
+    req->senderRef = reference();
+    req->senderData = subbPtr.i;
+    
+#ifdef EVENT_PH3_DEBUG
+    ndbout_c("DBDICT(Participant) sending GSN_SUB_START_REQ to SUMA subbPtr.i = (%d)", subbPtr.i);
+#endif
+    sendSignal(SUMA_REF, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
+  }
+}
+
+void Dbdict::execSUB_START_REF(Signal* signal)
+{
+  jamEntry();
+
+  const SubStartRef* ref = (SubStartRef*) signal->getDataPtr();
+  Uint32 senderRef  = ref->senderRef;
+  Uint32 err = ref->errorCode;
+
+  OpSubEventPtr subbPtr;
+  c_opSubEvent.getPtr(subbPtr, ref->senderData);
+
+  if (refToBlock(senderRef) == SUMA) {
+    /*
+     * Participant
+     */
+    jam();
+
+#ifdef EVENT_PH3_DEBUG
+    ndbout_c("DBDICT(Participant) got GSN_SUB_START_REF = (%d)", subbPtr.i);
+#endif
+
+    jam();
+    SubStartRef* ref = (SubStartRef*) signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = subbPtr.p->m_senderData;
+    ref->errorCode = err;
+    sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
+	       signal, SubStartRef::SignalLength2, JBB);
+    c_opSubEvent.release(subbPtr);
+    return;
+  }
+  /*
+   * Coordinator
+   */
+  ndbrequire(refToBlock(senderRef) == DBDICT);
+#ifdef EVENT_PH3_DEBUG
+  ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_REF = (%d)", subbPtr.i);
+#endif
+  if (err == SubStartRef::NF_FakeErrorREF){
+    jam();
+    subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
+  } else {
+    jam();
+    if (subbPtr.p->m_errorCode == 0)
+    {
+      subbPtr.p->m_errorCode= err ? err : 1;
+    }
+    subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
+  }
+  completeSubStartReq(signal,subbPtr.i,0);
+}
+
+void Dbdict::execSUB_START_CONF(Signal* signal)
+{
+  jamEntry();
+
+  const SubStartConf* conf = (SubStartConf*) signal->getDataPtr();
+  Uint32 senderRef  = conf->senderRef;
+
+  OpSubEventPtr subbPtr;
+  c_opSubEvent.getPtr(subbPtr, conf->senderData);
+
+  if (refToBlock(senderRef) == SUMA) {
+    /*
+     * Participant
+     */
+    jam();
+    SubStartConf* conf = (SubStartConf*) signal->getDataPtrSend();
+
+#ifdef EVENT_PH3_DEBUG
+  ndbout_c("DBDICT(Participant) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
+#endif
+
+    conf->senderRef = reference();
+    conf->senderData = subbPtr.p->m_senderData;
+
+    sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
+	       signal, SubStartConf::SignalLength2, JBB);
+    c_opSubEvent.release(subbPtr);
+    return;
+  }
+  /*
+   * Coordinator
+   */
+  ndbrequire(refToBlock(senderRef) == DBDICT);
+#ifdef EVENT_PH3_DEBUG
+  ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
+#endif
+  subbPtr.p->m_sub_start_conf = *conf;
+  subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
+  completeSubStartReq(signal,subbPtr.i,0);
+}
+
+/*
+ * Coordinator
+ */
+void Dbdict::completeSubStartReq(Signal* signal,
+				 Uint32 ptrI,
+				 Uint32 returnCode){
+  jam();
+
+  OpSubEventPtr subbPtr;
+  c_opSubEvent.getPtr(subbPtr, ptrI);
+
+  if (!subbPtr.p->m_reqTracker.done()){
+    jam();
+    return;
+  }
+
+  if (subbPtr.p->m_reqTracker.hasRef()) {
+    jam();
+#ifdef EVENT_DEBUG
+    ndbout_c("SUB_START_REF");
+#endif
+    SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->errorCode = subbPtr.p->m_errorCode;
+    sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
+	       signal, SubStartRef::SignalLength, JBB);
+    if (subbPtr.p->m_reqTracker.hasConf()) {
+      //  stopStartedNodes(signal);
+    }
+    c_opSubEvent.release(subbPtr);
+    return;
+  }
+#ifdef EVENT_DEBUG
+  ndbout_c("SUB_START_CONF");
+#endif
+  
+  SubStartConf* conf = (SubStartConf*)signal->getDataPtrSend();
+  * conf = subbPtr.p->m_sub_start_conf;
+  sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
+	     signal, SubStartConf::SignalLength, JBB);
+  c_opSubEvent.release(subbPtr);
+}
+
+/********************************************************************
+ *
+ * Stop event
+ *
+ *******************************************************************/
+
+void Dbdict::execSUB_STOP_REQ(Signal* signal)
+{
+  jamEntry();
+
+  Uint32 origSenderRef = signal->senderBlockRef();
+
+  if (refToBlock(origSenderRef) != DBDICT &&
+      getOwnNodeId() != c_masterNodeId)
+  {
+    /*
+     * Coordinator but not master
+     */
+    SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->errorCode = SubStopRef::NotMaster;
+    ref->m_masterNodeId = c_masterNodeId;
+    sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal,
+	       SubStopRef::SignalLength2, JBB);
+    return;
+  }
+  OpSubEventPtr subbPtr;
+  Uint32 errCode = 0;
+  if (!c_opSubEvent.seize(subbPtr)) {
+    errCode = SubStopRef::Busy;
+busy:
+    SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
+    jam();
+    //      ret->setErrorCode(SubStartRef::SeizeError);
+    //      ret->setErrorLine(__LINE__);
+    //      ret->setErrorNode(reference());
+    ref->senderRef = reference();
+    ref->errorCode = errCode;
+
+    sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal,
+	       SubStopRef::SignalLength, JBB);
+    return;
+  }
+
+  {
+    const SubStopReq* req = (SubStopReq*) signal->getDataPtr();
+    subbPtr.p->m_senderRef = req->senderRef;
+    subbPtr.p->m_senderData = req->senderData;
+    subbPtr.p->m_errorCode = 0;
+  }
+  
+  if (refToBlock(origSenderRef) != DBDICT) {
+    /*
+     * Coordinator
+     */
+    jam();
+#ifdef EVENT_DEBUG
+    ndbout_c("SUB_STOP_REQ 1");
+#endif
+    subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
+    NodeReceiverGroup rg(DBDICT, c_aliveNodes);
+    RequestTracker & p = subbPtr.p->m_reqTracker;
+    if (!p.init<SubStopRef>(c_counterMgr, rg, GSN_SUB_STOP_REF, subbPtr.i))
+    {
+      jam();
+      c_opSubEvent.release(subbPtr);
+      errCode = SubStopRef::Busy;
+      goto busy;
+    }
+    
+    SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
+    
+    req->senderRef  = reference();
+    req->senderData = subbPtr.i;
+    
+    sendSignal(rg, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
+    return;
+  }
+  /*
+   * Participant
+   */
+#ifdef EVENT_DEBUG
+  ndbout_c("SUB_STOP_REQ 2");
+#endif
+  ndbrequire(refToBlock(origSenderRef) == DBDICT);
+
+  CRASH_INSERTION(6008);
+
+  {
+    SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
+    
+    req->senderRef = reference();
+    req->senderData = subbPtr.i;
+    
+    sendSignal(SUMA_REF, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
+  }
+}
+
+void Dbdict::execSUB_STOP_REF(Signal* signal)
+{
+  jamEntry();
+  const SubStopRef* ref = (SubStopRef*) signal->getDataPtr();
+  Uint32 senderRef  = ref->senderRef;
+  Uint32 err = ref->errorCode;
+
+  OpSubEventPtr subbPtr;
+  c_opSubEvent.getPtr(subbPtr, ref->senderData);
+
+  if (refToBlock(senderRef) == SUMA) {
+    /*
+     * Participant
+     */
+    jam();
+    SubStopRef* ref = (SubStopRef*) signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = subbPtr.p->m_senderData;
+    ref->errorCode = err;
+    sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
+	       signal, SubStopRef::SignalLength, JBB);
+    c_opSubEvent.release(subbPtr);
+    return;
+  }
+  /*
+   * Coordinator
+   */
+  ndbrequire(refToBlock(senderRef) == DBDICT);
+  if (err == SubStopRef::NF_FakeErrorREF){
+    jam();
+    subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
+  } else {
+    jam();
+    if (subbPtr.p->m_errorCode == 0)
+    {
+      subbPtr.p->m_errorCode= err ? err : 1;
+    }
+    subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
+  }
+  completeSubStopReq(signal,subbPtr.i,0);
+}
+
+void Dbdict::execSUB_STOP_CONF(Signal* signal)
+{
+  jamEntry();
+
+  const SubStopConf* conf = (SubStopConf*) signal->getDataPtr();
+  Uint32 senderRef  = conf->senderRef;
+
+  OpSubEventPtr subbPtr;
+  c_opSubEvent.getPtr(subbPtr, conf->senderData);
+
+  if (refToBlock(senderRef) == SUMA) {
+    /*
+     * Participant
+     */
+    jam();
+    SubStopConf* conf = (SubStopConf*) signal->getDataPtrSend();
+
+    conf->senderRef = reference();
+    conf->senderData = subbPtr.p->m_senderData;
+
+    sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
+	       signal, SubStopConf::SignalLength, JBB);
+    c_opSubEvent.release(subbPtr);
+    return;
+  }
+  /*
+   * Coordinator
+   */
+  ndbrequire(refToBlock(senderRef) == DBDICT);
+  subbPtr.p->m_sub_stop_conf = *conf;
+  subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
+  completeSubStopReq(signal,subbPtr.i,0);
+}
+
+/*
+ * Coordinator
+ */
+void Dbdict::completeSubStopReq(Signal* signal,
+				Uint32 ptrI,
+				Uint32 returnCode){
+  OpSubEventPtr subbPtr;
+  c_opSubEvent.getPtr(subbPtr, ptrI);
+
+  if (!subbPtr.p->m_reqTracker.done()){
+    jam();
+    return;
+  }
+
+  if (subbPtr.p->m_reqTracker.hasRef()) {
+    jam();
+#ifdef EVENT_DEBUG
+    ndbout_c("SUB_STOP_REF");
+#endif
+    SubStopRef* ref = (SubStopRef*)signal->getDataPtrSend();
+
+    ref->senderRef  = reference();
+    ref->senderData = subbPtr.p->m_senderData;
+    ref->errorCode  = subbPtr.p->m_errorCode;
+
+    sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
+	       signal, SubStopRef::SignalLength, JBB);
+    if (subbPtr.p->m_reqTracker.hasConf()) {
+      //  stopStartedNodes(signal);
+    }
+    c_opSubEvent.release(subbPtr);
+    return;
+  }
+#ifdef EVENT_DEBUG
+  ndbout_c("SUB_STOP_CONF");
+#endif
+  SubStopConf* conf = (SubStopConf*)signal->getDataPtrSend();
+  * conf = subbPtr.p->m_sub_stop_conf;
+  sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
+	     signal, SubStopConf::SignalLength, JBB);
+  c_opSubEvent.release(subbPtr);
+}
+
+/***************************************************************
+ * MODULE: Drop event.
+ *
+ * Drop event.
+ * 
+ * TODO
+ */
+
+void
+Dbdict::execDROP_EVNT_REQ(Signal* signal)
+{
+  jamEntry();
+  DBUG_ENTER("Dbdict::execDROP_EVNT_REQ");
+
+  DropEvntReq *req = (DropEvntReq*)signal->getDataPtr();
+  const Uint32 senderRef = signal->senderBlockRef();
+  OpDropEventPtr evntRecPtr;
+
+  if (refToBlock(senderRef) != DBDICT &&
+      getOwnNodeId() != c_masterNodeId)
+  {
+    jam();
+    releaseSections(signal);
+
+    DropEvntRef * ref = (DropEvntRef *)signal->getDataPtrSend();
+    ref->setUserRef(reference());
+    ref->setErrorCode(DropEvntRef::NotMaster);
+    ref->setErrorLine(__LINE__);
+    ref->setErrorNode(reference());
+    ref->setMasterNode(c_masterNodeId);
+    sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
+	       DropEvntRef::SignalLength2, JBB);
+    return;
+  }
+
+  // Seize a Create Event record
+  if (!c_opDropEvent.seize(evntRecPtr)) {
+    // Failed to allocate event record
+    jam();
+    releaseSections(signal);
+ 
+    DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
+    ret->setErrorCode(747);
+    ret->setErrorLine(__LINE__);
+    ret->setErrorNode(reference());
+    sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
+	       DropEvntRef::SignalLength, JBB);
+    DBUG_VOID_RETURN;
+  }
+
+#ifdef EVENT_DEBUG
+  ndbout_c("DBDICT::execDROP_EVNT_REQ evntRecId = (%d)", evntRecPtr.i);
+#endif
+
+  OpDropEvent* evntRec = evntRecPtr.p;
+  evntRec->init(req);
+
+  SegmentedSectionPtr ssPtr;
+
+  signal->getSection(ssPtr, 0);
+
+  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
+#ifdef EVENT_DEBUG
+  r0.printAll(ndbout);
+#endif
+  // event name
+  if ((!r0.first()) ||
+      (r0.getValueType() != SimpleProperties::StringValue) ||
+      (r0.getValueLen() <= 0)) {
+    jam();
+    releaseSections(signal);
+
+    evntRecPtr.p->m_errorCode = 1;
+    evntRecPtr.p->m_errorLine = __LINE__;
+    evntRecPtr.p->m_errorNode = reference();
+
+    dropEvent_sendReply(signal, evntRecPtr);
+    DBUG_VOID_RETURN;
+  }
+  r0.getString(evntRecPtr.p->m_eventRec.NAME);
+  {
+    int len = strlen(evntRecPtr.p->m_eventRec.NAME);
+    memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
+#ifdef EVENT_DEBUG
+    printf("DropEvntReq; EventName %s, len %u\n",
+	   evntRecPtr.p->m_eventRec.NAME, len);
+    for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
+      printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
+    printf("\n");
+#endif
+  }
+  
+  releaseSections(signal);
+
+  Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_READ), 0 };
+
+  prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
+				  UtilPrepareReq::Read);
+  DBUG_VOID_RETURN;
+}
+
+void 
+Dbdict::dropEventUTIL_PREPARE_READ(Signal* signal,
+				   Uint32 callbackData,
+				   Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  if (returnCode != 0) {
+    EVENT_TRACE;
+    dropEventUtilPrepareRef(signal, callbackData, returnCode);
+    return;
+  }
+
+  UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
+  OpDropEventPtr evntRecPtr;
+  evntRecPtr.i = req->getSenderData();
+  const Uint32 prepareId = req->getPrepareId();
+
+  ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
+
+  Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_READ), 0 };
+
+  executeTransEventSysTable(&c, signal,
+			    evntRecPtr.i, evntRecPtr.p->m_eventRec,
+			    prepareId, UtilPrepareReq::Read);
+}
+
+void 
+Dbdict::dropEventUTIL_EXECUTE_READ(Signal* signal,
+				   Uint32 callbackData,
+				   Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  if (returnCode != 0) {
+    EVENT_TRACE;
+    dropEventUtilExecuteRef(signal, callbackData, returnCode);
+    return;
+  }
+
+  OpDropEventPtr evntRecPtr;
+  UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
+  jam();
+  evntRecPtr.i = ref->getSenderData();
+  ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
+
+  parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
+
+  NodeReceiverGroup rg(DBDICT, c_aliveNodes);
+  RequestTracker & p = evntRecPtr.p->m_reqTracker;
+  if (!p.init<SubRemoveRef>(c_counterMgr, rg, GSN_SUB_REMOVE_REF,
+			    evntRecPtr.i))
+  {
+    evntRecPtr.p->m_errorCode = 701;
+    dropEvent_sendReply(signal, evntRecPtr);
+    return;
+  }
+  
+  SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
+
+  req->senderRef       = reference();
+  req->senderData      = evntRecPtr.i;
+  req->subscriptionId  = evntRecPtr.p->m_eventRec.SUBID;
+  req->subscriptionKey = evntRecPtr.p->m_eventRec.SUBKEY;
+
+  sendSignal(rg, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
+}
+
+/*
+ * Participant
+ */
+
+void
+Dbdict::execSUB_REMOVE_REQ(Signal* signal)
+{
+  jamEntry();
+  DBUG_ENTER("Dbdict::execSUB_REMOVE_REQ");
+
+  Uint32 origSenderRef = signal->senderBlockRef();
+
+  OpSubEventPtr subbPtr;
+  if (!c_opSubEvent.seize(subbPtr)) {
+    SubRemoveRef * ref = (SubRemoveRef *)signal->getDataPtrSend();
+    jam();
+    ref->senderRef = reference();
+    ref->errorCode = SubRemoveRef::Busy;
+
+    sendSignal(origSenderRef, GSN_SUB_REMOVE_REF, signal,
+	       SubRemoveRef::SignalLength, JBB);
+    DBUG_VOID_RETURN;
+  }
+
+  {
+    const SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtr();
+    subbPtr.p->m_senderRef = req->senderRef;
+    subbPtr.p->m_senderData = req->senderData;
+    subbPtr.p->m_errorCode = 0;
+  }
+
+  CRASH_INSERTION2(6010, getOwnNodeId() != c_masterNodeId);
+  
+  SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
+  req->senderRef = reference();
+  req->senderData = subbPtr.i;
+
+  sendSignal(SUMA_REF, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
+  DBUG_VOID_RETURN;
+}
+
+/*
+ * Coordintor/Participant
+ */
+
+void
+Dbdict::execSUB_REMOVE_REF(Signal* signal)
+{
+  jamEntry();
+  DBUG_ENTER("Dbdict::execSUB_REMOVE_REF");
+
+  const SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtr();
+  Uint32 senderRef = ref->senderRef;
+  Uint32 err= ref->errorCode;
+
+  if (refToBlock(senderRef) == SUMA) {
+    /*
+     * Participant
+     */
+    jam();
+    OpSubEventPtr subbPtr;
+    c_opSubEvent.getPtr(subbPtr, ref->senderData);
+    if (err == 1407) {
+      // conf this since this may occur if a nodefailure has occured
+      // earlier so that the systable was not cleared
+      SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
+      conf->senderRef  = reference();
+      conf->senderData = subbPtr.p->m_senderData;
+      sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
+		 signal, SubRemoveConf::SignalLength, JBB);
+    } else {
+      SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtrSend();
+      ref->senderRef = reference();
+      ref->senderData = subbPtr.p->m_senderData;
+      ref->errorCode = err;
+      sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_REF,
+		 signal, SubRemoveRef::SignalLength, JBB);
+    }
+    c_opSubEvent.release(subbPtr);
+    DBUG_VOID_RETURN;
+  }
+  /*
+   * Coordinator
+   */
+  ndbrequire(refToBlock(senderRef) == DBDICT);
+  OpDropEventPtr eventRecPtr;
+  c_opDropEvent.getPtr(eventRecPtr, ref->senderData);
+  if (err == SubRemoveRef::NF_FakeErrorREF){
+    jam();
+    eventRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
+  } else {
+    jam();
+    if (eventRecPtr.p->m_errorCode == 0)
+    {
+      eventRecPtr.p->m_errorCode= err ? err : 1;
+      eventRecPtr.p->m_errorLine= __LINE__;
+      eventRecPtr.p->m_errorNode= reference();
+    }
+    eventRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
+  }
+  completeSubRemoveReq(signal,eventRecPtr.i,0);
+  DBUG_VOID_RETURN;
+}
+
+void
+Dbdict::execSUB_REMOVE_CONF(Signal* signal)
+{
+  jamEntry();
+  const SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtr();
+  Uint32 senderRef = conf->senderRef;
+
+  if (refToBlock(senderRef) == SUMA) {
+    /*
+     * Participant
+     */
+    jam();
+    OpSubEventPtr subbPtr;
+    c_opSubEvent.getPtr(subbPtr, conf->senderData);
+    SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
+    conf->senderRef = reference();
+    conf->senderData = subbPtr.p->m_senderData;
+    sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
+	       signal, SubRemoveConf::SignalLength, JBB);
+    c_opSubEvent.release(subbPtr);
+    return;
+  }
+  /*
+   * Coordinator
+   */
+  ndbrequire(refToBlock(senderRef) == DBDICT);
+  OpDropEventPtr eventRecPtr;
+  c_opDropEvent.getPtr(eventRecPtr, conf->senderData);
+  eventRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
+  completeSubRemoveReq(signal,eventRecPtr.i,0);
+}
+
+void
+Dbdict::completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 xxx)
+{
+  OpDropEventPtr evntRecPtr;
+  c_opDropEvent.getPtr(evntRecPtr, ptrI);
+
+  if (!evntRecPtr.p->m_reqTracker.done()){
+    jam();
+    return;
+  }
+
+  if (evntRecPtr.p->m_reqTracker.hasRef()) {
+    jam();
+    if ( evntRecPtr.p->m_errorCode == 0 )
+    {
+      evntRecPtr.p->m_errorNode = reference();
+      evntRecPtr.p->m_errorLine = __LINE__;
+      evntRecPtr.p->m_errorCode = 1;
+    }
+    dropEvent_sendReply(signal, evntRecPtr);
+    return;
+  }
+
+  Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_DELETE), 0 };
+
+  prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
+				  UtilPrepareReq::Delete);
+}
+
+void 
+Dbdict::dropEventUTIL_PREPARE_DELETE(Signal* signal,
+				     Uint32 callbackData,
+				     Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  if (returnCode != 0) {
+    EVENT_TRACE;
+    dropEventUtilPrepareRef(signal, callbackData, returnCode);
+    return;
+  }
+
+  UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
+  OpDropEventPtr evntRecPtr;
+  jam();
+  evntRecPtr.i = req->getSenderData();
+  const Uint32 prepareId = req->getPrepareId();
+  
+  ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
+#ifdef EVENT_DEBUG
+  printf("DropEvntUTIL_PREPARE; evntRecPtr.i len %u\n",evntRecPtr.i);
+#endif    
+
+  Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_DELETE), 0 };
+
+  executeTransEventSysTable(&c, signal,
+			    evntRecPtr.i, evntRecPtr.p->m_eventRec,
+			    prepareId, UtilPrepareReq::Delete);
+}
+
+void 
+Dbdict::dropEventUTIL_EXECUTE_DELETE(Signal* signal,
+				     Uint32 callbackData,
+				     Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  if (returnCode != 0) {
+    EVENT_TRACE;
+    dropEventUtilExecuteRef(signal, callbackData, returnCode);
+    return;
+  }
+
+  OpDropEventPtr evntRecPtr;
+  UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
+  jam();
+  evntRecPtr.i = ref->getSenderData();
+  ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
+
+  dropEvent_sendReply(signal, evntRecPtr);
+}
+
+void
+Dbdict::dropEventUtilPrepareRef(Signal* signal,
+				Uint32 callbackData,
+				Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  UtilPrepareRef * const ref = (UtilPrepareRef *)signal->getDataPtr();
+  OpDropEventPtr evntRecPtr;
+  evntRecPtr.i = ref->getSenderData();
+  ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
+
+  interpretUtilPrepareErrorCode((UtilPrepareRef::ErrorCode)ref->getErrorCode(),
+				evntRecPtr.p->m_errorCode, evntRecPtr.p->m_errorLine);
+  evntRecPtr.p->m_errorNode = reference();
+
+  dropEvent_sendReply(signal, evntRecPtr);
+}
+
+void
+Dbdict::dropEventUtilExecuteRef(Signal* signal,
+				Uint32 callbackData,
+				Uint32 returnCode)
+{
+  jam();
+  EVENT_TRACE;
+  OpDropEventPtr evntRecPtr;
+  UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
+  jam();
+  evntRecPtr.i = ref->getSenderData();
+  ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
+    
+  evntRecPtr.p->m_errorNode = reference();
+  evntRecPtr.p->m_errorLine = __LINE__;
+
+  switch (ref->getErrorCode()) {
+  case UtilExecuteRef::TCError:
+    switch (ref->getTCErrorCode()) {
+    case ZNOT_FOUND:
+      jam();
+      evntRecPtr.p->m_errorCode = 4710;
+      break;
+    default:
+      jam();
+      evntRecPtr.p->m_errorCode = ref->getTCErrorCode();
+      break;
+    }
+    break;
+  default:
+    jam();
+    evntRecPtr.p->m_errorCode = ref->getErrorCode();
+    break;
+  }
+  dropEvent_sendReply(signal, evntRecPtr);
+}
+
+void Dbdict::dropEvent_sendReply(Signal* signal,
+				 OpDropEventPtr evntRecPtr)
+{
+  jam();
+  EVENT_TRACE;
+  Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
+
+  if (evntRecPtr.p->hasError()) {
+    jam();
+    DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
+    
+    ret->setUserData(evntRecPtr.p->m_request.getUserData());
+    ret->setUserRef(evntRecPtr.p->m_request.getUserRef());
+
+    ret->setErrorCode(evntRecPtr.p->m_errorCode);
+    ret->setErrorLine(evntRecPtr.p->m_errorLine);
+    ret->setErrorNode(evntRecPtr.p->m_errorNode);
+
+    sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
+	       DropEvntRef::SignalLength, JBB);
+  } else {
+    jam();
+    DropEvntConf * evntConf = (DropEvntConf *)signal->getDataPtrSend();
+    
+    evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
+    evntConf->setUserRef(evntRecPtr.p->m_request.getUserRef());
+
+    sendSignal(senderRef, GSN_DROP_EVNT_CONF, signal,
+	       DropEvntConf::SignalLength, JBB);
+  }
+
+  c_opDropEvent.release(evntRecPtr);
+}
 
 /**
  * MODULE: Alter index
@@ -7870,6 +11328,7 @@
   if (indexPtr.p->isHashIndex()) {
     req->setTriggerType(TriggerType::SECONDARY_INDEX);
     req->setMonitorReplicas(false);
+    req->setReportAllMonitoredAttributes(true);
     // insert
     if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
       req->setTriggerId(indexPtr.p->insertTriggerId);
@@ -7912,6 +11371,7 @@
     req->setTriggerType(TriggerType::ORDERED_INDEX);
     req->setTriggerActionTime(TriggerActionTime::TA_CUSTOM);
     req->setMonitorReplicas(true);
+    req->setReportAllMonitoredAttributes(true);
     // one trigger for 5 events (insert, update, delete, commit, abort)
     if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
       req->setTriggerId(indexPtr.p->customTriggerId);
@@ -8428,6 +11888,7 @@
   req->setTriggerEvent(TriggerEvent::TE_UPDATE);
   req->setMonitorReplicas(false);
   req->setMonitorAllAttributes(false);
+  req->setReportAllMonitoredAttributes(true);
   req->setOnline(true);         // alter online after create
   req->setReceiverRef(0);       // no receiver, REF-ed by TUP
   req->getAttributeMask().clear();
@@ -8739,21 +12200,14 @@
       }
     }
     releaseSections(signal);
-    {
-      // check that trigger name is unique
-      TriggerRecordPtr triggerPtr;
-      TriggerRecord keyRecord;
-      strcpy(keyRecord.triggerName, opPtr.p->m_triggerName);
-      c_triggerRecordHash.find(triggerPtr, keyRecord);
-      if (triggerPtr.i != RNIL) {
-	jam();
-	opPtr.p->m_errorCode = CreateTrigRef::TriggerExists;
-	opPtr.p->m_errorLine = __LINE__;
-	createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
-	return;
-      }
+    if(get_object(opPtr.p->m_triggerName) != 0){
+      jam();
+      opPtr.p->m_errorCode = CreateTrigRef::TriggerExists;
+      opPtr.p->m_errorLine = __LINE__;
+      createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
+      return;
     }
-
+    
     // master expects to hear from all
     if (opPtr.p->m_isMaster)
       opPtr.p->m_signalCounter = receiverNodes;
@@ -8982,7 +12436,14 @@
   c_triggerRecordPool.getPtr(triggerPtr, triggerId);
   initialiseTriggerRecord(triggerPtr);
   // fill in trigger data
-  strcpy(triggerPtr.p->triggerName, opPtr.p->m_triggerName);
+  {
+    Rope name(c_rope_pool, triggerPtr.p->triggerName);
+    if(!name.assign(opPtr.p->m_triggerName))
+    {
+      opPtr.p->m_errorCode = (CreateTrigRef::ErrorCode)CreateTableRef::OutOfStringBuffer;
+      return;
+    }
+  }
   triggerPtr.p->triggerId = triggerId;
   triggerPtr.p->tableId = req->getTableId();
   triggerPtr.p->indexId = RNIL;
@@ -8991,11 +12452,21 @@
   triggerPtr.p->triggerEvent = req->getTriggerEvent();
   triggerPtr.p->monitorReplicas = req->getMonitorReplicas();
   triggerPtr.p->monitorAllAttributes = req->getMonitorAllAttributes();
+  triggerPtr.p->reportAllMonitoredAttributes = req->getReportAllMonitoredAttributes();
   triggerPtr.p->attributeMask = req->getAttributeMask();
   triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
   // add to hash table
   //  ndbout_c("++++++++++++ Adding trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
-  c_triggerRecordHash.add(triggerPtr);
+  {
+    Ptr<DictObject> obj_ptr;
+    ndbrequire(c_obj_hash.seize(obj_ptr));
+    obj_ptr.p->m_name = triggerPtr.p->triggerName;
+    obj_ptr.p->m_id = triggerId;
+    obj_ptr.p->m_type = triggerPtr.p->triggerType;
+    obj_ptr.p->m_ref_count = 0;
+    c_obj_hash.add(obj_ptr);
+    triggerPtr.p->m_obj_ptr_i = obj_ptr.i;
+  }
   if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
       triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
     jam();
@@ -9159,7 +12630,7 @@
   if (signal->getNoOfSections() > 0) {
     ndbrequire(signal->getNoOfSections() == 1);
     jam();
-    TriggerRecord keyRecord;
+    char triggerName[MAX_TAB_NAME_SIZE];
     OpDropTrigger opTmp;
     opPtr.p=&opTmp;
 
@@ -9167,7 +12638,7 @@
     signal->getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
     SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
     if (ssReader.getKey() != DropTrigReq::TriggerNameKey ||
-	! ssReader.getString(keyRecord.triggerName)) {
+	! ssReader.getString(triggerName)) {
       jam();
       opPtr.p->m_errorCode = DropTrigRef::InvalidName;
       opPtr.p->m_errorLine = __LINE__;
@@ -9177,16 +12648,16 @@
     }
     releaseSections(signal);
 
-    TriggerRecordPtr triggerPtr;
-
-    //    ndbout_c("++++++++++++++ Looking for trigger %s", keyRecord.triggerName);
-    c_triggerRecordHash.find(triggerPtr, keyRecord);
-    if (triggerPtr.i == RNIL) {
+    //ndbout_c("++++++++++++++ Looking for trigger %s", keyRecord.triggerName);
+    DictObject * obj_ptr_p = get_object(triggerName);
+    if (obj_ptr_p == 0){
       jam();
       req->setTriggerId(RNIL);
     } else {
       jam();
-      //      ndbout_c("++++++++++ Found trigger %s", triggerPtr.p->triggerName);
+      //ndbout_c("++++++++++ Found trigger %s", triggerPtr.p->triggerName);
+      TriggerRecordPtr triggerPtr;
+      c_triggerRecordPool.getPtr(triggerPtr, obj_ptr_p->m_id);
       req->setTriggerId(triggerPtr.p->triggerId);
       req->setTableId(triggerPtr.p->tableId);
     }
@@ -9456,9 +12927,9 @@
     c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
     indexPtr.p->buildTriggerId = RNIL;
   }
-  // remove trigger
-  //  ndbout_c("++++++++++++ Removing trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
-  c_triggerRecordHash.remove(triggerPtr);
+  //remove trigger
+  //ndbout_c("++++++++++++ Removing trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
+  release_object(triggerPtr.p->m_obj_ptr_i);
   triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
 }
 
@@ -9814,6 +13285,7 @@
   req->setTriggerEvent(triggerPtr.p->triggerEvent);
   req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
   req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
+  req->setReportAllMonitoredAttributes(triggerPtr.p->reportAllMonitoredAttributes);
   req->setOnline(true);
   req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
   BlockReference blockRef = 0;
@@ -10018,17 +13490,30 @@
  * MODULE: Support routines for index and trigger.
  */
 
+/*
+  This routine is used to set-up the primary key attributes of the unique
+  hash index. Since we store fragment id as part of the primary key here
+  we insert the pseudo column for getting fragment id first in the array.
+  This routine is used as part of the building of the index.
+*/
+
 void
-Dbdict::getTableKeyList(TableRecordPtr tablePtr, AttributeList& list)
+Dbdict::getTableKeyList(TableRecordPtr tablePtr, 
+			Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list)
 {
   jam();
   list.sz = 0;
-  for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
-    AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
-    if (aRec->tupleKey)
-      list.id[list.sz++] = aRec->attributeId;
-    tAttr = aRec->nextAttrInTable;
+  list.id[list.sz++] = AttributeHeader::FRAGMENT;
+  LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
+                                         tablePtr.p->m_attributes);
+  AttributeRecordPtr attrPtr;
+  for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)) {
+    if (attrPtr.p->tupleKey) {
+      list.id[list.sz++] = attrPtr.p->attributeId;
+    }
   }
+  ndbrequire(list.sz == (uint)(tablePtr.p->noOfPrimkey + 1));
+  ndbrequire(list.sz <= MAX_ATTRIBUTES_IN_INDEX + 1);
 }
 
 // XXX should store the primary attribute id
@@ -10036,16 +13521,27 @@
 Dbdict::getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id)
 {
   jam();
+
+  Uint32 len;
+  char name[MAX_ATTR_NAME_SIZE];
   TableRecordPtr tablePtr;
+  AttributeRecordPtr attrPtr;
+
   c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
   AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
-  for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
-    AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
-    if (iaRec->equal(*aRec)) {
-      id[0] = aRec->attributeId;
+  {
+    ConstRope tmp(c_rope_pool, iaRec->attributeName);
+    tmp.copy(name);
+    len = tmp.size();
+  }
+  LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool, 
+					 tablePtr.p->m_attributes);
+  for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)){
+    ConstRope tmp(c_rope_pool, attrPtr.p->attributeName);
+    if(tmp.compare(name, len) == 0){
+      id[0] = attrPtr.p->attributeId;
       return;
     }
-    tAttr = aRec->nextAttrInTable;
   }
   ndbrequire(false);
 }
@@ -10054,34 +13550,39 @@
 Dbdict::getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list)
 {
   jam();
-  TableRecordPtr tablePtr;
-  c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
   list.sz = 0;
   memset(list.id, 0, sizeof(list.id));
   ndbrequire(indexPtr.p->noOfAttributes >= 2);
-  Uint32 itAttr = indexPtr.p->firstAttribute;
-  for (Uint32 i = 0; i < (Uint32)indexPtr.p->noOfAttributes - 1; i++) {
-    getIndexAttr(indexPtr, itAttr, &list.id[list.sz++]);
-    AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
-    itAttr = iaRec->nextAttrInTable;
+
+  LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
+                                         indexPtr.p->m_attributes);
+  AttributeRecordPtr attrPtr;
+  for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)) {
+    // skip last
+    AttributeRecordPtr tempPtr = attrPtr;
+    if (! alist.next(tempPtr))
+      break;
+    getIndexAttr(indexPtr, attrPtr.i, &list.id[list.sz++]);
   }
+  ndbrequire(indexPtr.p->noOfAttributes == list.sz + 1);
 }
 
 void
 Dbdict::getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask)
 {
   jam();
-  TableRecordPtr tablePtr;
-  c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
   mask.clear();
   ndbrequire(indexPtr.p->noOfAttributes >= 2);
-  Uint32 itAttr = indexPtr.p->firstAttribute;
-  for (Uint32 i = 0; i < (Uint32)indexPtr.p->noOfAttributes - 1; i++) {
+  
+  AttributeRecordPtr attrPtr, currPtr;
+  LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool, 
+					 indexPtr.p->m_attributes);
+  
+  
+  for (alist.first(attrPtr); currPtr = attrPtr, alist.next(attrPtr); ){
     Uint32 id;
-    getIndexAttr(indexPtr, itAttr, &id);
+    getIndexAttr(indexPtr, currPtr.i, &id);
     mask.set(id);
-    AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
-    itAttr = iaRec->nextAttrInTable;
   }
 }
 
@@ -10475,107 +13976,2511 @@
   return &sf->TableEntries[i];
 }
 
-// global metadata support
+//******************************************
+void
+Dbdict::execCREATE_FILE_REQ(Signal* signal)
+{
+  jamEntry();
+  
+  if(!assembleFragments(signal)){
+    jam();
+    return;
+  }
+  
+  CreateFileReq * req = (CreateFileReq*)signal->getDataPtr();
+  CreateFileRef * ref = (CreateFileRef*)signal->getDataPtrSend();
+  Uint32 senderRef = req->senderRef;
+  Uint32 senderData = req->senderData;
+  Uint32 type = req->objType;
+  Uint32 requestInfo = req->requestInfo;
+  
+  do {
+    if(getOwnNodeId() != c_masterNodeId){
+      jam();
+      ref->errorCode = CreateFileRef::NotMaster;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    if (c_blockState != BS_IDLE){
+      jam();
+      ref->errorCode = CreateFileRef::Busy;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
 
-int
-Dbdict::getMetaTablePtr(TableRecordPtr& tablePtr, Uint32 tableId, Uint32 tableVersion)
+    if (checkSingleUserMode(senderRef))
+    {
+      ref->errorCode = CreateFileRef::SingleUser;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    Ptr<SchemaTransaction> trans_ptr;
+    if (! c_Trans.seize(trans_ptr)){
+      jam();
+      ref->errorCode = CreateFileRef::Busy;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    jam(); 
+    const Uint32 trans_key = ++c_opRecordSequence;
+    trans_ptr.p->key = trans_key;
+    trans_ptr.p->m_senderRef = senderRef;
+    trans_ptr.p->m_senderData = senderData;
+    trans_ptr.p->m_nodes = c_aliveNodes;
+    trans_ptr.p->m_errorCode = 0;
+//    trans_ptr.p->m_nodes.clear(); 
+//    trans_ptr.p->m_nodes.set(getOwnNodeId());
+    c_Trans.add(trans_ptr);
+    
+    const Uint32 op_key = ++c_opRecordSequence;
+    trans_ptr.p->m_op.m_key = op_key;
+    trans_ptr.p->m_op.m_vt_index = 1;
+    trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
+    
+    CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
+    create_obj->op_key = op_key;
+    create_obj->senderRef = reference();
+    create_obj->senderData = trans_key;
+    create_obj->clientRef = senderRef;
+    create_obj->clientData = senderData;
+    
+    create_obj->objType = type;
+    create_obj->requestInfo = requestInfo;
+
+    {
+      Uint32 objId = getFreeObjId(0);
+      if (objId == RNIL) {
+        jam();
+        ref->errorCode = CreateFileRef::NoMoreObjectRecords;
+        ref->status    = 0;
+        ref->errorKey  = 0;
+        ref->errorLine = __LINE__;
+        break;
+      }
+      
+      create_obj->objId = objId;
+      trans_ptr.p->m_op.m_obj_id = objId;
+      create_obj->gci = 0;
+      
+      XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+      SchemaFile::TableEntry *objEntry = getTableEntry(xsf, objId);      
+      create_obj->objVersion = 
+	create_obj_inc_schema_version(objEntry->m_tableVersion);
+    }
+    
+    NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
+    SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
+    tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
+    sendSignal(rg, GSN_CREATE_OBJ_REQ, signal, 
+	       CreateObjReq::SignalLength, JBB);
+
+    c_blockState = BS_CREATE_TAB;
+    return;
+  } while(0);
+  
+  ref->senderData = senderData;
+  ref->masterNodeId = c_masterNodeId;
+  sendSignal(senderRef, GSN_CREATE_FILE_REF,signal,
+	     CreateFileRef::SignalLength, JBB);
+}
+
+void
+Dbdict::execCREATE_FILEGROUP_REQ(Signal* signal)
 {
-  if (tableId >= c_tableRecordPool.getSize()) {
-    return MetaData::InvalidArgument;
+  jamEntry();
+  
+  if(!assembleFragments(signal)){
+    jam();
+    return;
   }
-  c_tableRecordPool.getPtr(tablePtr, tableId);
-  if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
-    return MetaData::TableNotFound;
+  
+  CreateFilegroupReq * req = (CreateFilegroupReq*)signal->getDataPtr();
+  CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtrSend();
+  Uint32 senderRef = req->senderRef;
+  Uint32 senderData = req->senderData;
+  Uint32 type = req->objType;
+  
+  do {
+    if(getOwnNodeId() != c_masterNodeId){
+      jam();
+      ref->errorCode = CreateFilegroupRef::NotMaster;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    if (c_blockState != BS_IDLE){
+      jam();
+      ref->errorCode = CreateFilegroupRef::Busy;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    if (checkSingleUserMode(senderRef))
+    {
+      ref->errorCode = CreateFilegroupRef::SingleUser;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    Ptr<SchemaTransaction> trans_ptr;
+    if (! c_Trans.seize(trans_ptr)){
+      jam();
+      ref->errorCode = CreateFilegroupRef::Busy;
+      ref->status    = 0;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    jam(); 
+    const Uint32 trans_key = ++c_opRecordSequence;
+    trans_ptr.p->key = trans_key;
+    trans_ptr.p->m_senderRef = senderRef;
+    trans_ptr.p->m_senderData = senderData;
+    trans_ptr.p->m_nodes = c_aliveNodes;
+    trans_ptr.p->m_errorCode = 0;
+    c_Trans.add(trans_ptr);
+    
+    const Uint32 op_key = ++c_opRecordSequence;
+    trans_ptr.p->m_op.m_key = op_key;
+    trans_ptr.p->m_op.m_vt_index = 0;
+    trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
+    
+    CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
+    create_obj->op_key = op_key;
+    create_obj->senderRef = reference();
+    create_obj->senderData = trans_key;
+    create_obj->clientRef = senderRef;
+    create_obj->clientData = senderData;
+    
+    create_obj->objType = type;
+    
+    {
+      Uint32 objId = getFreeObjId(0);
+      if (objId == RNIL) {
+        jam();
+        ref->errorCode = CreateFilegroupRef::NoMoreObjectRecords;
+        ref->status    = 0;
+        ref->errorKey  = 0;
+        ref->errorLine = __LINE__;
+        break;
+      }
+      
+      create_obj->objId = objId;
+      trans_ptr.p->m_op.m_obj_id = objId;
+      create_obj->gci = 0;
+      
+      XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+      SchemaFile::TableEntry *objEntry = getTableEntry(xsf, objId);      
+      create_obj->objVersion = 
+	create_obj_inc_schema_version(objEntry->m_tableVersion);
+    }
+    
+    NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
+    SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
+    tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
+    sendSignal(rg, GSN_CREATE_OBJ_REQ, signal, 
+	       CreateObjReq::SignalLength, JBB);
+
+    c_blockState = BS_CREATE_TAB;
+    return;
+  } while(0);
+  
+  ref->senderData = senderData;
+  ref->masterNodeId = c_masterNodeId;
+  sendSignal(senderRef, GSN_CREATE_FILEGROUP_REF,signal,
+	     CreateFilegroupRef::SignalLength, JBB);
+}
+
+void
+Dbdict::execDROP_FILE_REQ(Signal* signal)
+{
+  jamEntry();
+  
+  if(!assembleFragments(signal)){
+    jam();
+    return;
   }
-  if (tablePtr.p->tableVersion != tableVersion) {
-    return MetaData::InvalidTableVersion;
+  
+  DropFileReq * req = (DropFileReq*)signal->getDataPtr();
+  DropFileRef * ref = (DropFileRef*)signal->getDataPtrSend();
+  Uint32 senderRef = req->senderRef;
+  Uint32 senderData = req->senderData;
+  Uint32 objId = req->file_id;
+  Uint32 version = req->file_version;
+  
+  do {
+    if(getOwnNodeId() != c_masterNodeId){
+      jam();
+      ref->errorCode = DropFileRef::NotMaster;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    if (c_blockState != BS_IDLE)
+    {
+      jam();
+      ref->errorCode = DropFileRef::Busy;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    if (checkSingleUserMode(senderRef))
+    {
+      jam();
+      ref->errorCode = DropFileRef::SingleUser;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    Ptr<File> file_ptr;
+    if (!c_file_hash.find(file_ptr, objId))
+    {
+      jam();
+      ref->errorCode = DropFileRef::NoSuchFile;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    if (file_ptr.p->m_version != version)
+    {
+      jam();
+      ref->errorCode = DropFileRef::InvalidSchemaObjectVersion;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    Ptr<SchemaTransaction> trans_ptr;
+    if (! c_Trans.seize(trans_ptr))
+    {
+      jam();
+      ref->errorCode = DropFileRef::Busy;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    jam();
+    
+    const Uint32 trans_key = ++c_opRecordSequence;
+    trans_ptr.p->key = trans_key;
+    trans_ptr.p->m_senderRef = senderRef;
+    trans_ptr.p->m_senderData = senderData;
+    trans_ptr.p->m_nodes = c_aliveNodes;
+    trans_ptr.p->m_errorCode = 0;
+    c_Trans.add(trans_ptr);
+    
+    const Uint32 op_key = ++c_opRecordSequence;
+    trans_ptr.p->m_op.m_key = op_key;
+    trans_ptr.p->m_op.m_vt_index = 2;
+    trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
+    
+    DropObjReq* drop_obj = (DropObjReq*)signal->getDataPtrSend();
+    drop_obj->op_key = op_key;
+    drop_obj->objVersion = version;
+    drop_obj->objId = objId;
+    drop_obj->objType = file_ptr.p->m_type;
+    trans_ptr.p->m_op.m_obj_id = objId;
+
+    drop_obj->senderRef = reference();
+    drop_obj->senderData = trans_key;
+    drop_obj->clientRef = senderRef;
+    drop_obj->clientData = senderData;
+
+    drop_obj->requestInfo = 0;
+    
+    NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
+    SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
+    tmp.init<CreateObjRef>(rg, GSN_DROP_OBJ_REF, trans_key);
+    sendSignal(rg, GSN_DROP_OBJ_REQ, signal, 
+	       DropObjReq::SignalLength, JBB);
+
+    c_blockState = BS_CREATE_TAB;
+    return;
+  } while(0);
+  
+  ref->senderData = senderData;
+  ref->masterNodeId = c_masterNodeId;
+  sendSignal(senderRef, GSN_DROP_FILE_REF,signal,
+	     DropFileRef::SignalLength, JBB);
+}
+
+void
+Dbdict::execDROP_FILEGROUP_REQ(Signal* signal)
+{
+  jamEntry();
+  
+  if(!assembleFragments(signal)){
+    jam();
+    return;
   }
-  // online flag is not maintained by DICT
-  tablePtr.p->online =
-    tablePtr.p->isTable() && 
-    (tablePtr.p->tabState == TableRecord::DEFINED ||
-     tablePtr.p->tabState == TableRecord::BACKUP_ONGOING) ||
-    tablePtr.p->isIndex() && tablePtr.p->indexState == TableRecord::IS_ONLINE;
-  return 0;
+  
+  DropFilegroupReq * req = (DropFilegroupReq*)signal->getDataPtr();
+  DropFilegroupRef * ref = (DropFilegroupRef*)signal->getDataPtrSend();
+  Uint32 senderRef = req->senderRef;
+  Uint32 senderData = req->senderData;
+  Uint32 objId = req->filegroup_id;
+  Uint32 version = req->filegroup_version;
+  
+  do {
+    if(getOwnNodeId() != c_masterNodeId)
+    {
+      jam();
+      ref->errorCode = DropFilegroupRef::NotMaster;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    if (c_blockState != BS_IDLE)
+    {
+      jam();
+      ref->errorCode = DropFilegroupRef::Busy;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    if (checkSingleUserMode(senderRef))
+    {
+      jam();
+      ref->errorCode = DropFilegroupRef::SingleUser;
+      ref->errorKey  = 0;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    Ptr<Filegroup> filegroup_ptr;
+    if (!c_filegroup_hash.find(filegroup_ptr, objId))
+    {
+      jam();
+      ref->errorCode = DropFilegroupRef::NoSuchFilegroup;
+      ref->errorLine = __LINE__;
+      break;
+    }
+
+    if (filegroup_ptr.p->m_version != version)
+    {
+      jam();
+      ref->errorCode = DropFilegroupRef::InvalidSchemaObjectVersion;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    Ptr<SchemaTransaction> trans_ptr;
+    if (! c_Trans.seize(trans_ptr))
+    {
+      jam();
+      ref->errorCode = DropFilegroupRef::Busy;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    jam();
+    
+    const Uint32 trans_key = ++c_opRecordSequence;
+    trans_ptr.p->key = trans_key;
+    trans_ptr.p->m_senderRef = senderRef;
+    trans_ptr.p->m_senderData = senderData;
+    trans_ptr.p->m_nodes = c_aliveNodes;
+    trans_ptr.p->m_errorCode = 0;
+    c_Trans.add(trans_ptr);
+    
+    const Uint32 op_key = ++c_opRecordSequence;
+    trans_ptr.p->m_op.m_key = op_key;
+    trans_ptr.p->m_op.m_vt_index = 3;
+    trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
+    
+    DropObjReq* drop_obj = (DropObjReq*)signal->getDataPtrSend();
+    drop_obj->op_key = op_key;
+    drop_obj->objVersion = version;
+    drop_obj->objId = objId;
+    drop_obj->objType = filegroup_ptr.p->m_type;
+    trans_ptr.p->m_op.m_obj_id = objId;
+    
+    drop_obj->senderRef = reference();
+    drop_obj->senderData = trans_key;
+    drop_obj->clientRef = senderRef;
+    drop_obj->clientData = senderData;
+    
+    drop_obj->requestInfo = 0;
+    
+    NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
+    SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
+    tmp.init<CreateObjRef>(rg, GSN_DROP_OBJ_REF, trans_key);
+    sendSignal(rg, GSN_DROP_OBJ_REQ, signal, 
+	       DropObjReq::SignalLength, JBB);
+
+    c_blockState = BS_CREATE_TAB;
+    return;
+  } while(0);
+  
+  ref->senderData = senderData;
+  ref->masterNodeId = c_masterNodeId;
+  sendSignal(senderRef, GSN_DROP_FILEGROUP_REF,signal,
+	     DropFilegroupRef::SignalLength, JBB);
 }
 
-int
-Dbdict::getMetaTable(MetaData::Table& table, Uint32 tableId, Uint32 tableVersion)
+void
+Dbdict::execCREATE_OBJ_REF(Signal* signal)
 {
-  int ret;
-  TableRecordPtr tablePtr;
-  if ((ret = getMetaTablePtr(tablePtr, tableId, tableVersion)) < 0) {
-    return ret;
+  CreateObjRef * const ref = (CreateObjRef*)signal->getDataPtr();
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
+  if(ref->errorCode != CreateObjRef::NF_FakeErrorREF){
+    jam();
+    trans_ptr.p->setErrorCode(ref->errorCode);
   }
-  new (&table) MetaData::Table(*tablePtr.p);
-  return 0;
+  Uint32 node = refToNode(ref->senderRef);
+  schemaOp_reply(signal, trans_ptr.p, node);
 }
 
-int
-Dbdict::getMetaTable(MetaData::Table& table, const char* tableName)
+void
+Dbdict::execCREATE_OBJ_CONF(Signal* signal)
 {
-  int ret;
-  TableRecordPtr tablePtr;
-  if (strlen(tableName) + 1 > MAX_TAB_NAME_SIZE) {
-    return MetaData::InvalidArgument;
+  Ptr<SchemaTransaction> trans_ptr;
+  CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
+  schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
+}
+
+void
+Dbdict::schemaOp_reply(Signal* signal, 
+		       SchemaTransaction * trans_ptr_p, 
+		       Uint32 nodeId)
+{
+  jam();
+  {
+    SafeCounter tmp(c_counterMgr, trans_ptr_p->m_counter);
+    if(!tmp.clearWaitingFor(nodeId)){
+      jam();
+      return;
+    }
+  }
+  
+  switch(trans_ptr_p->m_op.m_state){
+  case DictObjOp::Preparing:{
+    if(trans_ptr_p->m_errorCode != 0)
+    {
+      /**
+       * Failed to prepare on atleast one node -> abort on all
+       */
+      trans_ptr_p->m_op.m_state = DictObjOp::Aborting;
+      trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
+      trans_ptr_p->m_callback.m_callbackFunction= 
+	safe_cast(&Dbdict::trans_abort_start_done);
+      
+      if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
+      {
+        jam();
+	(this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
+	  (signal, trans_ptr_p);
+      }
+      else
+      {
+        jam();
+	execute(signal, trans_ptr_p->m_callback, 0);
+      }
+      return;
+    }
+    
+    trans_ptr_p->m_op.m_state = DictObjOp::Prepared;
+    trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
+    trans_ptr_p->m_callback.m_callbackFunction= 
+      safe_cast(&Dbdict::trans_commit_start_done);
+    
+    if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
+    {
+      jam();
+      (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
+	(signal, trans_ptr_p);
+    }
+    else
+    {
+      jam();
+      execute(signal, trans_ptr_p->m_callback, 0);
+    }
+    return;
   }
-  TableRecord keyRecord;
-  strcpy(keyRecord.tableName, tableName);
-  c_tableRecordHash.find(tablePtr, keyRecord);
-  if (tablePtr.i == RNIL) {
-    return MetaData::TableNotFound;
+  case DictObjOp::Committing: {
+    ndbrequire(trans_ptr_p->m_errorCode == 0);
+
+    trans_ptr_p->m_op.m_state = DictObjOp::Committed;
+    trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
+    trans_ptr_p->m_callback.m_callbackFunction= 
+      safe_cast(&Dbdict::trans_commit_complete_done);
+    
+    if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
+    {
+      jam();
+      (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
+	(signal, trans_ptr_p);
+    }
+    else
+    {
+      jam();
+      execute(signal, trans_ptr_p->m_callback, 0);
+    }
+    return;
   }
-  if ((ret = getMetaTablePtr(tablePtr, tablePtr.i, tablePtr.p->tableVersion)) < 0) {
-    return ret;
+  case DictObjOp::Aborting:{
+    trans_ptr_p->m_op.m_state = DictObjOp::Committed;
+    trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
+    trans_ptr_p->m_callback.m_callbackFunction= 
+      safe_cast(&Dbdict::trans_abort_complete_done);
+
+    if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
+    {
+      jam();
+      (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
+	(signal, trans_ptr_p);
+    }
+    else
+    {
+      jam();
+      execute(signal, trans_ptr_p->m_callback, 0);
+    }
+    return;
   }
-  new (&table) MetaData::Table(*tablePtr.p);
-  return 0;
+  case DictObjOp::Defined:
+  case DictObjOp::Prepared:
+  case DictObjOp::Committed:
+  case DictObjOp::Aborted:
+    jam();
+    break;
+  }
+  ndbrequire(false);
 }
 
-int
-Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table, Uint32 attributeId)
+void
+Dbdict::trans_commit_start_done(Signal* signal, 
+				Uint32 callbackData,
+				Uint32 retValue)
 {
-  int ret;
-  TableRecordPtr tablePtr;
-  if ((ret = getMetaTablePtr(tablePtr, table.tableId, table.tableVersion)) < 0) {
-    return ret;
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
+  ndbrequire(c_Trans.find(trans_ptr, callbackData));
+  NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
+  SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
+  tmp.init<DictCommitRef>(rg, GSN_DICT_COMMIT_REF, trans_ptr.p->key);
+  
+  DictCommitReq * const req = (DictCommitReq*)signal->getDataPtrSend();
+  req->senderRef = reference();
+  req->senderData = trans_ptr.p->key;
+  req->op_key = trans_ptr.p->m_op.m_key;
+  sendSignal(rg, GSN_DICT_COMMIT_REQ, signal, DictCommitReq::SignalLength, 
+	     JBB);
+  trans_ptr.p->m_op.m_state = DictObjOp::Committing;
+}
+
+void
+Dbdict::trans_commit_complete_done(Signal* signal, 
+				   Uint32 callbackData,
+				   Uint32 retValue)
+{
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
+  ndbrequire(c_Trans.find(trans_ptr, callbackData));
+
+  switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
+  case GSN_CREATE_FILEGROUP_REQ:{
+    FilegroupPtr fg_ptr;
+    jam();
+    ndbrequire(c_filegroup_hash.find(fg_ptr, trans_ptr.p->m_op.m_obj_id));
+    
+    CreateFilegroupConf * conf = (CreateFilegroupConf*)signal->getDataPtr();
+    conf->senderRef = reference();
+    conf->senderData = trans_ptr.p->m_senderData;
+    conf->filegroupId = fg_ptr.p->key;
+    conf->filegroupVersion = fg_ptr.p->m_version;
+    
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_CONF, signal, 
+	       CreateFilegroupConf::SignalLength, JBB);
+    break;
   }
-  AttributeRecordPtr attrPtr;
-  attrPtr.i = tablePtr.p->firstAttribute;
-  while (attrPtr.i != RNIL) {
-    c_attributeRecordPool.getPtr(attrPtr);
-    if (attrPtr.p->attributeId == attributeId)
+  case GSN_CREATE_FILE_REQ:{
+    FilePtr f_ptr;
+    jam();
+    ndbrequire(c_file_hash.find(f_ptr, trans_ptr.p->m_op.m_obj_id));
+    CreateFileConf * conf = (CreateFileConf*)signal->getDataPtr();
+    conf->senderRef = reference();
+    conf->senderData = trans_ptr.p->m_senderData;
+    conf->fileId = f_ptr.p->key;
+    conf->fileVersion = f_ptr.p->m_version;
+
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_CONF, signal, 
+	       CreateFileConf::SignalLength, JBB);
+    break;
+  }
+  case GSN_DROP_FILE_REQ:{
+    DropFileConf * conf = (DropFileConf*)signal->getDataPtr();
+    jam();
+    conf->senderRef = reference();
+    conf->senderData = trans_ptr.p->m_senderData;
+    conf->fileId = trans_ptr.p->m_op.m_obj_id;
+    
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILE_CONF, signal, 
+	       DropFileConf::SignalLength, JBB);
+    break;
+  }
+  case GSN_DROP_FILEGROUP_REQ:{
+    DropFilegroupConf * conf = (DropFilegroupConf*)signal->getDataPtr();
+    jam();
+    conf->senderRef = reference();
+    conf->senderData = trans_ptr.p->m_senderData;
+    conf->filegroupId = trans_ptr.p->m_op.m_obj_id;
+    
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILEGROUP_CONF, signal, 
+	       DropFilegroupConf::SignalLength, JBB);
+    break;
+  }
+  default:
+    ndbrequire(false);
+  }
+  
+  c_Trans.release(trans_ptr);
+  ndbrequire(c_blockState == BS_CREATE_TAB);
+  c_blockState = BS_IDLE;
+  return;
+}
+
+void
+Dbdict::trans_abort_start_done(Signal* signal, 
+			       Uint32 callbackData,
+			       Uint32 retValue)
+{
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
+  ndbrequire(c_Trans.find(trans_ptr, callbackData));
+  
+  NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
+  SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
+  ndbrequire(tmp.init<DictAbortRef>(rg, trans_ptr.p->key));
+  
+  DictAbortReq * const req = (DictAbortReq*)signal->getDataPtrSend();
+  req->senderRef = reference();
+  req->senderData = trans_ptr.p->key;
+  req->op_key = trans_ptr.p->m_op.m_key;
+  
+  sendSignal(rg, GSN_DICT_ABORT_REQ, signal, DictAbortReq::SignalLength, JBB);
+}
+
+void
+Dbdict::trans_abort_complete_done(Signal* signal, 
+				  Uint32 callbackData,
+				  Uint32 retValue)
+{
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
+  ndbrequire(c_Trans.find(trans_ptr, callbackData));
+
+  switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
+  case GSN_CREATE_FILEGROUP_REQ:
+  {
+    //
+    CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtr();
+    jam();
+    ref->senderRef = reference();
+    ref->senderData = trans_ptr.p->m_senderData;
+    ref->masterNodeId = c_masterNodeId;
+    ref->errorCode = trans_ptr.p->m_errorCode;
+    ref->errorLine = 0;
+    ref->errorKey = 0;
+    ref->status = 0;
+    
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_REF, signal, 
+	       CreateFilegroupRef::SignalLength, JBB);
+    break;
+  }
+  case GSN_CREATE_FILE_REQ:
+  {
+    CreateFileRef * ref = (CreateFileRef*)signal->getDataPtr();
+    jam();
+    ref->senderRef = reference();
+    ref->senderData = trans_ptr.p->m_senderData;
+    ref->masterNodeId = c_masterNodeId;
+    ref->errorCode = trans_ptr.p->m_errorCode;
+    ref->errorLine = 0;
+    ref->errorKey = 0;
+    ref->status = 0;
+    
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_REF, signal, 
+	       CreateFileRef::SignalLength, JBB);
+    break;
+  }
+  case GSN_DROP_FILE_REQ:
+  {
+    DropFileRef * ref = (DropFileRef*)signal->getDataPtr();
+    jam();
+    ref->senderRef = reference();
+    ref->senderData = trans_ptr.p->m_senderData;
+    ref->masterNodeId = c_masterNodeId;
+    ref->errorCode = trans_ptr.p->m_errorCode;
+    ref->errorLine = 0;
+    ref->errorKey = 0;
+    
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILE_REF, signal, 
+	       DropFileRef::SignalLength, JBB);
+    break;
+  }
+  case GSN_DROP_FILEGROUP_REQ:
+  {
+    //
+    DropFilegroupRef * ref = (DropFilegroupRef*)signal->getDataPtr();
+    jam();
+    ref->senderRef = reference();
+    ref->senderData = trans_ptr.p->m_senderData;
+    ref->masterNodeId = c_masterNodeId;
+    ref->errorCode = trans_ptr.p->m_errorCode;
+    ref->errorLine = 0;
+    ref->errorKey = 0;
+    
+    //@todo check api failed
+    sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILEGROUP_REF, signal, 
+	       DropFilegroupRef::SignalLength, JBB);
+    break;
+  }
+  default:
+    ndbrequire(false);
+  }
+  
+  c_Trans.release(trans_ptr);
+  ndbrequire(c_blockState == BS_CREATE_TAB);
+  c_blockState = BS_IDLE;
+  return;
+}
+
+void
+Dbdict::execCREATE_OBJ_REQ(Signal* signal)
+{
+  jamEntry();
+
+  if(!assembleFragments(signal)){
+    jam();
+    return;
+  }
+
+  CreateObjReq * const req = (CreateObjReq*)signal->getDataPtr();
+  const Uint32 gci = req->gci;
+  const Uint32 objId = req->objId;
+  const Uint32 objVersion = req->objVersion;
+  const Uint32 objType = req->objType;
+  const Uint32 requestInfo = req->requestInfo;
+
+  SegmentedSectionPtr objInfoPtr;
+  signal->getSection(objInfoPtr, CreateObjReq::DICT_OBJ_INFO);
+  
+  CreateObjRecordPtr createObjPtr;  
+  ndbrequire(c_opCreateObj.seize(createObjPtr));
+  
+  const Uint32 key = req->op_key;
+  createObjPtr.p->key = key;
+  c_opCreateObj.add(createObjPtr);
+  createObjPtr.p->m_errorCode = 0;
+  createObjPtr.p->m_senderRef = req->senderRef;
+  createObjPtr.p->m_senderData = req->senderData;
+  createObjPtr.p->m_clientRef = req->clientRef;
+  createObjPtr.p->m_clientData = req->clientData;
+  
+  createObjPtr.p->m_gci = gci;
+  createObjPtr.p->m_obj_id = objId;
+  createObjPtr.p->m_obj_type = objType;
+  createObjPtr.p->m_obj_version = objVersion;
+  createObjPtr.p->m_obj_info_ptr_i = objInfoPtr.i;
+  createObjPtr.p->m_obj_ptr_i = RNIL;
+
+  createObjPtr.p->m_callback.m_callbackData = key;
+  createObjPtr.p->m_callback.m_callbackFunction= 
+    safe_cast(&Dbdict::createObj_prepare_start_done);
+
+  createObjPtr.p->m_restart= 0;
+  switch(objType){
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+    jam();
+    createObjPtr.p->m_vt_index = 0;
+    break;
+  case DictTabInfo::Datafile:
+  case DictTabInfo::Undofile:
+    /**
+     * Use restart code to impl. ForceCreateFile
+     */
+    if (requestInfo & CreateFileReq::ForceCreateFile)
+    {
+      jam();
+      createObjPtr.p->m_restart= 2;
+    }
+    jam();
+    createObjPtr.p->m_vt_index = 1;
+    break;
+  default:
+    ndbrequire(false);
+  }
+  
+  signal->header.m_noOfSections = 0;
+  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
+    (signal, createObjPtr.p);
+}
+
+void
+Dbdict::execDICT_COMMIT_REQ(Signal* signal)
+{
+  DictCommitReq* req = (DictCommitReq*)signal->getDataPtr();
+  Ptr<SchemaOp> op;
+
+  jamEntry();
+  ndbrequire(c_schemaOp.find(op, req->op_key));
+  (this->*f_dict_op[op.p->m_vt_index].m_commit)(signal, op.p);
+}
+
+void
+Dbdict::execDICT_ABORT_REQ(Signal* signal)
+{
+  DictAbortReq* req = (DictAbortReq*)signal->getDataPtr();
+  Ptr<SchemaOp> op;
+
+  jamEntry();
+  ndbrequire(c_schemaOp.find(op, req->op_key));
+  (this->*f_dict_op[op.p->m_vt_index].m_abort)(signal, op.p);
+}
+
+void
+Dbdict::execDICT_COMMIT_REF(Signal* signal)
+{
+  DictCommitRef * const ref = (DictCommitRef*)signal->getDataPtr();
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
+  if(ref->errorCode != DictCommitRef::NF_FakeErrorREF){
+    jam();
+    trans_ptr.p->setErrorCode(ref->errorCode);
+  }
+  Uint32 node = refToNode(ref->senderRef);
+  schemaOp_reply(signal, trans_ptr.p, node);
+}
+
+void
+Dbdict::execDICT_COMMIT_CONF(Signal* signal)
+{
+  Ptr<SchemaTransaction> trans_ptr;
+  DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
+  schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
+}
+
+void
+Dbdict::execDICT_ABORT_REF(Signal* signal)
+{
+  DictAbortRef * const ref = (DictAbortRef*)signal->getDataPtr();
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
+  if(ref->errorCode != DictAbortRef::NF_FakeErrorREF){
+    jam();
+    trans_ptr.p->setErrorCode(ref->errorCode);
+  }
+  Uint32 node = refToNode(ref->senderRef);
+  schemaOp_reply(signal, trans_ptr.p, node);
+}
+
+void
+Dbdict::execDICT_ABORT_CONF(Signal* signal)
+{
+  DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
+  schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
+}
+
+void
+Dbdict::createObj_prepare_start_done(Signal* signal,
+				     Uint32 callbackData, 
+				     Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;  
+  SegmentedSectionPtr objInfoPtr;
+  
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  jam();
+  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
+  if(createObjPtr.p->m_errorCode != 0){
+    jam();
+    createObjPtr.p->m_obj_info_ptr_i= RNIL;
+    signal->setSection(objInfoPtr, 0);
+    releaseSections(signal);
+    createObj_prepare_complete_done(signal, callbackData, 0);
+    return;
+  }
+  
+  SchemaFile::TableEntry tabEntry;
+  bzero(&tabEntry, sizeof(tabEntry));
+  tabEntry.m_tableVersion = createObjPtr.p->m_obj_version;
+  tabEntry.m_tableType    = createObjPtr.p->m_obj_type;
+  tabEntry.m_tableState   = SchemaFile::ADD_STARTED;
+  tabEntry.m_gcp          = createObjPtr.p->m_gci;
+  tabEntry.m_info_words   = objInfoPtr.sz;
+  
+  Callback cb;
+  cb.m_callbackData = createObjPtr.p->key;
+  cb.m_callbackFunction = safe_cast(&Dbdict::createObj_writeSchemaConf1);
+  
+  updateSchemaState(signal, createObjPtr.p->m_obj_id, &tabEntry, &cb);
+}
+
+void
+Dbdict::createObj_writeSchemaConf1(Signal* signal, 
+				   Uint32 callbackData,
+				   Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;  
+  Callback callback;
+  SegmentedSectionPtr objInfoPtr;
+
+  jam();
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  
+  callback.m_callbackData = createObjPtr.p->key;
+  callback.m_callbackFunction = safe_cast(&Dbdict::createObj_writeObjConf);
+  
+  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
+  writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
+  
+  signal->setSection(objInfoPtr, 0);
+  releaseSections(signal);
+  createObjPtr.p->m_obj_info_ptr_i = RNIL;
+}
+
+void
+Dbdict::createObj_writeObjConf(Signal* signal, 
+			       Uint32 callbackData,
+			       Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
+  jam();
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  createObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::createObj_prepare_complete_done);
+  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
+    (signal, createObjPtr.p);
+}
+
+void
+Dbdict::createObj_prepare_complete_done(Signal* signal, 
+					Uint32 callbackData,
+					Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
+  jam();
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  
+  //@todo check for master failed
+  
+  if(createObjPtr.p->m_errorCode == 0){
+    jam();
+    
+    CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
+    conf->senderRef = reference();
+    conf->senderData = createObjPtr.p->m_senderData;
+    sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_CONF,
+	       signal, CreateObjConf::SignalLength, JBB);
+    return;
+  }
+  
+  CreateObjRef * const ref = (CreateObjRef*)signal->getDataPtr();
+  ref->senderRef = reference();
+  ref->senderData = createObjPtr.p->m_senderData;
+  ref->errorCode = createObjPtr.p->m_errorCode;
+  ref->errorLine = 0;
+  ref->errorKey = 0;
+  ref->errorStatus = 0;
+  
+  sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_REF,
+	     signal, CreateObjRef::SignalLength, JBB);
+}
+
+void
+Dbdict::createObj_commit(Signal * signal, SchemaOp * op)
+{
+  OpCreateObj * createObj = (OpCreateObj*)op;
+
+  createObj->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::createObj_commit_start_done);
+  if (f_dict_op[createObj->m_vt_index].m_commit_start)
+  {
+    jam();
+    (this->*f_dict_op[createObj->m_vt_index].m_commit_start)(signal, createObj);
+  }
+  else
+  {
+    jam();
+    execute(signal, createObj->m_callback, 0);
+  }
+}
+
+void
+Dbdict::createObj_commit_start_done(Signal* signal, 
+				    Uint32 callbackData,
+				    Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;  
+  
+  jam();
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  
+  Uint32 objId = createObjPtr.p->m_obj_id;
+  XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+  SchemaFile::TableEntry objEntry = * getTableEntry(xsf, objId);
+  objEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
+  
+  Callback callback;
+  callback.m_callbackData = createObjPtr.p->key;
+  callback.m_callbackFunction = 
+    safe_cast(&Dbdict::createObj_writeSchemaConf2);
+  
+  updateSchemaState(signal, createObjPtr.p->m_obj_id, &objEntry, &callback);
+
+}
+
+void
+Dbdict::createObj_writeSchemaConf2(Signal* signal, 
+				   Uint32 callbackData,
+				   Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  createObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::createObj_commit_complete_done);
+  if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
+  {
+    jam();
+    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
+      (signal, createObjPtr.p);
+  }
+  else
+  {
+    jam();
+    execute(signal, createObjPtr.p->m_callback, 0);
+  }
+  
+}
+
+void
+Dbdict::createObj_commit_complete_done(Signal* signal, 
+				       Uint32 callbackData,
+				       Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
+  jam();
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  
+  //@todo check error
+  //@todo check master failed
+  
+  DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
+  conf->senderRef = reference();
+  conf->senderData = createObjPtr.p->m_senderData;
+  sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
+	     signal, DictCommitConf::SignalLength, JBB);
+  
+  c_opCreateObj.release(createObjPtr);
+}
+
+void
+Dbdict::createObj_abort(Signal* signal, SchemaOp* op)
+{
+  OpCreateObj * createObj = (OpCreateObj*)op;
+  
+  createObj->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::createObj_abort_start_done);
+  if (f_dict_op[createObj->m_vt_index].m_abort_start)
+  {
+    jam();
+    (this->*f_dict_op[createObj->m_vt_index].m_abort_start)(signal, createObj);
+  }
+  else
+  {
+    jam();
+    execute(signal, createObj->m_callback, 0);
+  }
+}
+
+void
+Dbdict::createObj_abort_start_done(Signal* signal, 
+				   Uint32 callbackData,
+				   Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
+  jam();
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+  SchemaFile::TableEntry objEntry = * getTableEntry(xsf, 
+						    createObjPtr.p->m_obj_id);
+  objEntry.m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
+  
+  Callback callback;
+  callback.m_callbackData = createObjPtr.p->key;
+  callback.m_callbackFunction = 
+    safe_cast(&Dbdict::createObj_abort_writeSchemaConf);
+  
+  updateSchemaState(signal, createObjPtr.p->m_obj_id, &objEntry, &callback);
+}
+
+void
+Dbdict::createObj_abort_writeSchemaConf(Signal* signal, 
+					Uint32 callbackData,
+					Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+  createObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::createObj_abort_complete_done);
+  
+  if (f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
+  {
+    jam();
+    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
+      (signal, createObjPtr.p);
+  }
+  else
+  {
+    jam();
+    execute(signal, createObjPtr.p->m_callback, 0);
+  }
+}
+
+void
+Dbdict::createObj_abort_complete_done(Signal* signal, 
+				      Uint32 callbackData,
+				      Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
+  jam();
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+
+  DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
+  conf->senderRef = reference();
+  conf->senderData = createObjPtr.p->m_senderData;
+  sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
+	     signal, DictAbortConf::SignalLength, JBB);
+  
+  c_opCreateObj.release(createObjPtr);
+}
+
+void
+Dbdict::execDROP_OBJ_REQ(Signal* signal)
+{
+  jamEntry();
+
+  if(!assembleFragments(signal)){
+    jam();
+    return;
+  }
+  
+  DropObjReq * const req = (DropObjReq*)signal->getDataPtr();
+
+  const Uint32 objId = req->objId;
+  const Uint32 objVersion = req->objVersion;
+  const Uint32 objType = req->objType;
+  
+  DropObjRecordPtr dropObjPtr;  
+  ndbrequire(c_opDropObj.seize(dropObjPtr));
+  
+  const Uint32 key = req->op_key;
+  dropObjPtr.p->key = key;
+  c_opDropObj.add(dropObjPtr);
+  dropObjPtr.p->m_errorCode = 0;
+  dropObjPtr.p->m_senderRef = req->senderRef;
+  dropObjPtr.p->m_senderData = req->senderData;
+  dropObjPtr.p->m_clientRef = req->clientRef;
+  dropObjPtr.p->m_clientData = req->clientData;
+  
+  dropObjPtr.p->m_obj_id = objId;
+  dropObjPtr.p->m_obj_type = objType;
+  dropObjPtr.p->m_obj_version = objVersion;
+
+  dropObjPtr.p->m_callback.m_callbackData = key;
+  dropObjPtr.p->m_callback.m_callbackFunction= 
+    safe_cast(&Dbdict::dropObj_prepare_start_done);
+
+  switch(objType){
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+  {
+    Ptr<Filegroup> fg_ptr;
+    jam();
+    dropObjPtr.p->m_vt_index = 3;
+    ndbrequire(c_filegroup_hash.find(fg_ptr, objId));
+    dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
+    break;
+  
+  }
+  case DictTabInfo::Datafile:
+  {
+    Ptr<File> file_ptr;
+    jam();
+    dropObjPtr.p->m_vt_index = 2;
+    ndbrequire(c_file_hash.find(file_ptr, objId));
+    dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
+    break;
+  }
+  case DictTabInfo::Undofile:
+  {
+    jam();
+    dropObjPtr.p->m_vt_index = 4;
+    return;
+  }
+  default:
+    ndbrequire(false);
+  }
+  
+  signal->header.m_noOfSections = 0;
+  (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
+    (signal, dropObjPtr.p);
+}
+
+void
+Dbdict::dropObj_prepare_start_done(Signal* signal, 
+				   Uint32 callbackData,
+				   Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+  Callback cb;
+
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+
+  cb.m_callbackData = callbackData;
+  cb.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_prepare_writeSchemaConf);
+
+  if(dropObjPtr.p->m_errorCode != 0)
+  {
+    jam();
+    dropObj_prepare_complete_done(signal, callbackData, 0);
+    return;
+  }
+  jam();  
+  Uint32 objId = dropObjPtr.p->m_obj_id;
+  XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+  SchemaFile::TableEntry objEntry = *getTableEntry(xsf, objId);
+  objEntry.m_tableState = SchemaFile::DROP_TABLE_STARTED;
+  updateSchemaState(signal, objId, &objEntry, &cb);
+}
+
+void
+Dbdict::dropObj_prepare_writeSchemaConf(Signal* signal, 
+					Uint32 callbackData,
+					Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  dropObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_prepare_complete_done);
+  if(f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
+  {
+    jam();
+    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
+      (signal, dropObjPtr.p);
+  }
+  else
+  {
+    jam();
+    execute(signal, dropObjPtr.p->m_callback, 0);
+  }
+}
+
+void
+Dbdict::dropObj_prepare_complete_done(Signal* signal, 
+				      Uint32 callbackData,
+				      Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  jam();
+  
+  //@todo check for master failed
+  
+  if(dropObjPtr.p->m_errorCode == 0){
+    jam();
+    
+    DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
+    conf->senderRef = reference();
+    conf->senderData = dropObjPtr.p->m_senderData;
+    sendSignal(dropObjPtr.p->m_senderRef, GSN_DROP_OBJ_CONF,
+	       signal, DropObjConf::SignalLength, JBB);
+    return;
+  }
+  
+  DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
+  ref->senderRef = reference();
+  ref->senderData = dropObjPtr.p->m_senderData;
+  ref->errorCode = dropObjPtr.p->m_errorCode;
+  
+  sendSignal(dropObjPtr.p->m_senderRef, GSN_DROP_OBJ_REF,
+	     signal, DropObjRef::SignalLength, JBB);
+
+}
+
+void
+Dbdict::dropObj_commit(Signal * signal, SchemaOp * op)
+{
+  OpDropObj * dropObj = (OpDropObj*)op;
+
+  dropObj->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_commit_start_done);
+  if (f_dict_op[dropObj->m_vt_index].m_commit_start)
+  {
+    jam();
+    (this->*f_dict_op[dropObj->m_vt_index].m_commit_start)(signal, dropObj);
+  }
+  else
+  {
+    jam();
+    execute(signal, dropObj->m_callback, 0);
+  }
+}
+
+void
+Dbdict::dropObj_commit_start_done(Signal* signal, 
+				  Uint32 callbackData,
+				  Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+
+  jam();
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  
+  Uint32 objId = dropObjPtr.p->m_obj_id;
+  XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+  SchemaFile::TableEntry objEntry = * getTableEntry(xsf, objId);
+  objEntry.m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
+  
+  Callback callback;
+  callback.m_callbackData = dropObjPtr.p->key;
+  callback.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_commit_writeSchemaConf);
+  
+  updateSchemaState(signal, objId, &objEntry, &callback);
+}
+
+void
+Dbdict::dropObj_commit_writeSchemaConf(Signal* signal, 
+				       Uint32 callbackData,
+				       Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+
+  jam();
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  dropObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_commit_complete_done);
+  
+  if(f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
+  {
+    jam();
+    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
+      (signal, dropObjPtr.p);
+  }
+  else
+  {
+    jam();
+    execute(signal, dropObjPtr.p->m_callback, 0);
+  }
+}
+
+void
+Dbdict::dropObj_commit_complete_done(Signal* signal, 
+				     Uint32 callbackData,
+				     Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+
+  jam();
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  
+  //@todo check error
+  //@todo check master failed
+  
+  DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
+  conf->senderRef = reference();
+  conf->senderData = dropObjPtr.p->m_senderData;
+  sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
+	     signal, DictCommitConf::SignalLength, JBB);
+  c_opDropObj.release(dropObjPtr);
+}
+
+void
+Dbdict::dropObj_abort(Signal * signal, SchemaOp * op)
+{
+  OpDropObj * dropObj = (OpDropObj*)op;
+
+  dropObj->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_abort_start_done);
+  if (f_dict_op[dropObj->m_vt_index].m_abort_start)
+  {
+    jam();
+    (this->*f_dict_op[dropObj->m_vt_index].m_abort_start)(signal, dropObj);
+  }
+  else
+  {
+    jam();
+    execute(signal, dropObj->m_callback, 0);
+  }
+}
+
+void
+Dbdict::dropObj_abort_start_done(Signal* signal, 
+				 Uint32 callbackData,
+				 Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+
+  jam();
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  
+  XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+  SchemaFile::TableEntry objEntry = * getTableEntry(xsf, 
+						    dropObjPtr.p->m_obj_id);
+
+  Callback callback;
+  callback.m_callbackData = dropObjPtr.p->key;
+  callback.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_abort_writeSchemaConf);
+  
+  if (objEntry.m_tableState == SchemaFile::DROP_TABLE_STARTED)
+  {
+    jam();
+    objEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
+        
+    updateSchemaState(signal, dropObjPtr.p->m_obj_id, &objEntry, &callback);
+  }
+  else
+  {
+    jam();
+    execute(signal, callback, 0);
+  }
+}
+
+void
+Dbdict::dropObj_abort_writeSchemaConf(Signal* signal, 
+				      Uint32 callbackData,
+				      Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+
+  ndbrequire(returnCode == 0);
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  dropObjPtr.p->m_callback.m_callbackFunction = 
+    safe_cast(&Dbdict::dropObj_abort_complete_done);
+  
+  if(f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
+  {
+    jam();
+    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
+      (signal, dropObjPtr.p);
+  }
+  else
+  {
+    jam();
+    execute(signal, dropObjPtr.p->m_callback, 0);
+  }
+}
+
+void
+Dbdict::dropObj_abort_complete_done(Signal* signal, 
+				    Uint32 callbackData,
+				    Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;
+  DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
+
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  jam();
+  conf->senderRef = reference();
+  conf->senderData = dropObjPtr.p->m_senderData;
+  sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
+	     signal, DictAbortConf::SignalLength, JBB);
+  c_opDropObj.release(dropObjPtr);
+}
+
+void 
+Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op)
+{
+  /**
+   * Put data into table record
+   */
+  SegmentedSectionPtr objInfoPtr;
+  jam();
+  getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
+  SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
+
+  Ptr<DictObject> obj_ptr; obj_ptr.setNull();
+  FilegroupPtr fg_ptr; fg_ptr.setNull();
+  
+  SimpleProperties::UnpackStatus status;
+  DictFilegroupInfo::Filegroup fg; fg.init();
+  do {
+    status = SimpleProperties::unpack(it, &fg, 
+				      DictFilegroupInfo::Mapping, 
+				      DictFilegroupInfo::MappingSize, 
+				      true, true);
+    
+    if(status != SimpleProperties::Eof)
+    {
+      jam();
+      op->m_errorCode = CreateTableRef::InvalidFormat;
+      break;
+    }
+
+    if(fg.FilegroupType == DictTabInfo::Tablespace)
+    {
+      if(!fg.TS_ExtentSize)
+      {
+        jam();
+	op->m_errorCode = CreateFilegroupRef::InvalidExtentSize;
+	break;
+      }
+    } 
+    else if(fg.FilegroupType == DictTabInfo::LogfileGroup)
+    {
+      /**
+       * undo_buffer_size can't be less than 96KB in LGMAN block 
+       */
+      if(fg.LF_UndoBufferSize < 3 * File_formats::NDB_PAGE_SIZE)
+      {
+        jam();
+	op->m_errorCode = CreateFilegroupRef::InvalidUndoBufferSize;
+	break;
+      }
+    }
+    
+    Uint32 len = strlen(fg.FilegroupName) + 1;
+    Uint32 hash = Rope::hash(fg.FilegroupName, len);
+    if(get_object(fg.FilegroupName, len, hash) != 0){
+      jam();
+      op->m_errorCode = CreateTableRef::TableAlreadyExist;
+      break;
+    }
+    
+    if(!c_obj_pool.seize(obj_ptr)){
+      jam();
+      op->m_errorCode = CreateTableRef::NoMoreTableRecords;
+      break;
+    }
+    
+    if(!c_filegroup_pool.seize(fg_ptr)){
+      jam();
+      op->m_errorCode = CreateTableRef::NoMoreTableRecords;
+      break;
+    }
+  
+    new (fg_ptr.p) Filegroup();
+
+    {
+      Rope name(c_rope_pool, obj_ptr.p->m_name);
+      if(!name.assign(fg.FilegroupName, len, hash)){
+        jam();
+	op->m_errorCode = CreateTableRef::OutOfStringBuffer;
+	break;
+      }
+    }
+    
+    fg_ptr.p->key = op->m_obj_id;
+    fg_ptr.p->m_obj_ptr_i = obj_ptr.i;
+    fg_ptr.p->m_type = fg.FilegroupType;
+    fg_ptr.p->m_version = op->m_obj_version;
+    fg_ptr.p->m_name = obj_ptr.p->m_name;
+
+    switch(fg.FilegroupType){
+    case DictTabInfo::Tablespace:
+    {
+      //fg.TS_DataGrow = group.m_grow_spec;
+      fg_ptr.p->m_tablespace.m_extent_size = fg.TS_ExtentSize;
+      fg_ptr.p->m_tablespace.m_default_logfile_group_id = fg.TS_LogfileGroupId;
+
+      Ptr<Filegroup> lg_ptr;
+      if (!c_filegroup_hash.find(lg_ptr, fg.TS_LogfileGroupId))
+      {
+        jam();
+	op->m_errorCode = CreateFilegroupRef::NoSuchLogfileGroup;
+	goto error;
+      }
+
+      if (lg_ptr.p->m_version != fg.TS_LogfileGroupVersion)
+      {
+        jam();
+	op->m_errorCode = CreateFilegroupRef::InvalidFilegroupVersion;
+	goto error;
+      }
+      increase_ref_count(lg_ptr.p->m_obj_ptr_i);
+      break;
+    }
+    case DictTabInfo::LogfileGroup:
+    {
+      jam();
+      fg_ptr.p->m_logfilegroup.m_undo_buffer_size = fg.LF_UndoBufferSize;
+      fg_ptr.p->m_logfilegroup.m_files.init();
+      //fg.LF_UndoGrow = ;
+      break;
+    }
+    default:
+      ndbrequire(false);
+    }
+
+    obj_ptr.p->m_id = op->m_obj_id;
+    obj_ptr.p->m_type = fg.FilegroupType;
+    obj_ptr.p->m_ref_count = 0;
+    c_obj_hash.add(obj_ptr);
+    c_filegroup_hash.add(fg_ptr);
+    
+    op->m_obj_ptr_i = fg_ptr.i;
+  } while(0);
+
+error:
+  if (op->m_errorCode)
+  {
+    jam();
+    if (!fg_ptr.isNull())
+    {
+      jam();
+      c_filegroup_pool.release(fg_ptr);
+    }
+
+    if (!obj_ptr.isNull())
+    {
+      jam();
+      c_obj_pool.release(obj_ptr);
+    }
+  }
+  
+  execute(signal, op->m_callback, 0);
+}
+
+void
+Dbdict::create_fg_prepare_complete(Signal* signal, SchemaOp* op)
+{
+  /**
+   * CONTACT TSMAN LGMAN PGMAN 
+   */
+  CreateFilegroupImplReq* req = 
+    (CreateFilegroupImplReq*)signal->getDataPtrSend();
+  jam();
+  req->senderData = op->key;
+  req->senderRef = reference();
+  req->filegroup_id = op->m_obj_id;
+  req->filegroup_version = op->m_obj_version;
+
+  FilegroupPtr fg_ptr;
+  c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
+  
+  Uint32 ref= 0;
+  Uint32 len= 0;
+  switch(op->m_obj_type){
+  case DictTabInfo::Tablespace:
+  {
+    jam();
+    ref = TSMAN_REF;
+    len = CreateFilegroupImplReq::TablespaceLength;
+    req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
+    req->tablespace.logfile_group_id = 
+      fg_ptr.p->m_tablespace.m_default_logfile_group_id;
+    break;
+  }
+  case DictTabInfo::LogfileGroup:
+  {
+    jam();
+    ref = LGMAN_REF;
+    len = CreateFilegroupImplReq::LogfileGroupLength;
+    req->logfile_group.buffer_size = 
+      fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
+    break;
+  }
+  default:
+    ndbrequire(false);
+  }
+  
+  sendSignal(ref, GSN_CREATE_FILEGROUP_REQ, signal, len, JBB);
+}
+
+void
+Dbdict::execCREATE_FILEGROUP_REF(Signal* signal)
+{
+  CreateFilegroupImplRef * ref = (CreateFilegroupImplRef*)signal->getDataPtr();
+  CreateObjRecordPtr op_ptr;
+  jamEntry();
+  ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
+  op_ptr.p->m_errorCode = ref->errorCode;
+
+  execute(signal, op_ptr.p->m_callback, 0);  
+}  
+
+void
+Dbdict::execCREATE_FILEGROUP_CONF(Signal* signal)
+{
+  CreateFilegroupImplConf * rep = 
+    (CreateFilegroupImplConf*)signal->getDataPtr();
+  CreateObjRecordPtr op_ptr;
+  jamEntry();
+  ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
+  
+  execute(signal, op_ptr.p->m_callback, 0);  
+}
+
+void
+Dbdict::create_fg_abort_start(Signal* signal, SchemaOp* op){
+  (void) signal->getDataPtrSend();
+
+  if (op->m_obj_ptr_i != RNIL)
+  {
+    jam();
+    send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
+    return;
+  }
+  jam();  
+  execute(signal, op->m_callback, 0);  
+}
+
+void
+Dbdict::create_fg_abort_complete(Signal* signal, SchemaOp* op)
+{
+  if (op->m_obj_ptr_i != RNIL)
+  {
+    jam();
+    FilegroupPtr fg_ptr;
+    c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
+    
+    release_object(fg_ptr.p->m_obj_ptr_i);
+    c_filegroup_hash.release(fg_ptr);
+  }
+  jam();  
+  execute(signal, op->m_callback, 0);
+}
+
+void 
+Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op)
+{
+  /**
+   * Put data into table record
+   */
+  SegmentedSectionPtr objInfoPtr;
+  getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
+  SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
+  
+  Ptr<DictObject> obj_ptr; obj_ptr.setNull();
+  FilePtr filePtr; filePtr.setNull();
+
+  DictFilegroupInfo::File f; f.init();
+  SimpleProperties::UnpackStatus status;
+  status = SimpleProperties::unpack(it, &f, 
+				    DictFilegroupInfo::FileMapping, 
+				    DictFilegroupInfo::FileMappingSize, 
+				    true, true);
+  
+  do {
+    if(status != SimpleProperties::Eof){
+      jam();
+      op->m_errorCode = CreateFileRef::InvalidFormat;
+      break;
+    }
+
+    // Get Filegroup
+    FilegroupPtr fg_ptr;
+    if(!c_filegroup_hash.find(fg_ptr, f.FilegroupId)){
+      jam();
+      op->m_errorCode = CreateFileRef::NoSuchFilegroup;
+      break;
+    }
+    
+    if(fg_ptr.p->m_version != f.FilegroupVersion){
+      jam();
+      op->m_errorCode = CreateFileRef::InvalidFilegroupVersion;
+      break;
+    }
+
+    switch(f.FileType){
+    case DictTabInfo::Datafile:
+    {
+      if(fg_ptr.p->m_type != DictTabInfo::Tablespace)
+      {
+        jam();
+	op->m_errorCode = CreateFileRef::InvalidFileType;
+      }
+      jam();
+      break;
+    }
+    case DictTabInfo::Undofile:
+    {
+      if(fg_ptr.p->m_type != DictTabInfo::LogfileGroup)
+      {
+        jam();
+	op->m_errorCode = CreateFileRef::InvalidFileType;
+      }
+      jam();
+      break;
+    }
+    default:
+      jam();
+      op->m_errorCode = CreateFileRef::InvalidFileType;
+    }
+    
+    if(op->m_errorCode)
+    {
+      jam();
+      break;
+    }
+
+    Uint32 len = strlen(f.FileName) + 1;
+    Uint32 hash = Rope::hash(f.FileName, len);
+    if(get_object(f.FileName, len, hash) != 0){
+      jam();
+      op->m_errorCode = CreateFileRef::FilenameAlreadyExists;
+      break;
+    }
+    
+    {
+      Uint32 dl;
+      const ndb_mgm_configuration_iterator * p = 
+	m_ctx.m_config.getOwnConfigIterator();
+      if(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl)
+      {
+        jam();
+	op->m_errorCode = CreateFileRef::NotSupportedWhenDiskless;
+	break;
+      }
+    }
+    
+    // Loop through all filenames...
+    if(!c_obj_pool.seize(obj_ptr)){
+      jam();
+      op->m_errorCode = CreateTableRef::NoMoreTableRecords;
+      break;
+    }
+    
+    if (! c_file_pool.seize(filePtr)){
+      jam();
+      op->m_errorCode = CreateFileRef::OutOfFileRecords;
       break;
-    attrPtr.i = attrPtr.p->nextAttrInTable;
+    }
+
+    new (filePtr.p) File();
+
+    {
+      Rope name(c_rope_pool, obj_ptr.p->m_name);
+      if(!name.assign(f.FileName, len, hash)){
+        jam();
+	op->m_errorCode = CreateTableRef::OutOfStringBuffer;
+	break;
+      }
+    }
+
+    switch(fg_ptr.p->m_type){
+    case DictTabInfo::Tablespace:
+    {
+      jam();
+      increase_ref_count(fg_ptr.p->m_obj_ptr_i);
+      break;
+    }
+    case DictTabInfo::LogfileGroup:
+    {
+      jam();
+      Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
+      list.add(filePtr);
+      break;
+    }
+    default:
+      ndbrequire(false);
+    }
+    
+    /**
+     * Init file
+     */
+    filePtr.p->key = op->m_obj_id;
+    filePtr.p->m_file_size = ((Uint64)f.FileSizeHi) << 32 | f.FileSizeLo;
+    filePtr.p->m_path = obj_ptr.p->m_name;
+    filePtr.p->m_obj_ptr_i = obj_ptr.i;
+    filePtr.p->m_filegroup_id = f.FilegroupId;
+    filePtr.p->m_type = f.FileType;
+    filePtr.p->m_version = op->m_obj_version;
+    
+    obj_ptr.p->m_id = op->m_obj_id;
+    obj_ptr.p->m_type = f.FileType;
+    obj_ptr.p->m_ref_count = 0;
+    c_obj_hash.add(obj_ptr);
+    c_file_hash.add(filePtr);
+
+    op->m_obj_ptr_i = filePtr.i;
+  } while(0);
+
+  if (op->m_errorCode)
+  {
+    jam();
+    if (!filePtr.isNull())
+    {
+      jam();
+      c_file_pool.release(filePtr);
+    }
+
+    if (!obj_ptr.isNull())
+    {
+      jam();
+      c_obj_pool.release(obj_ptr);
+    }
   }
-  if (attrPtr.i == RNIL) {
-    return MetaData::AttributeNotFound;
+  execute(signal, op->m_callback, 0);
+}
+
+
+void
+Dbdict::create_file_prepare_complete(Signal* signal, SchemaOp* op)
+{
+  /**
+   * CONTACT TSMAN LGMAN PGMAN 
+   */
+  CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
+  FilePtr f_ptr;
+  FilegroupPtr fg_ptr;
+
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+  ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
+
+  req->senderData = op->key;
+  req->senderRef = reference();
+  switch(((OpCreateObj*)op)->m_restart){
+  case 0:
+  {
+    jam();
+    req->requestInfo = CreateFileImplReq::Create;
+    break;
   }
-  new (&attr) MetaData::Attribute(*attrPtr.p);
-  return 0;
+  case 1:
+  {
+    jam();
+    req->requestInfo = CreateFileImplReq::Open;
+    break;
+  }
+  case 2:
+  {
+    jam();
+    req->requestInfo = CreateFileImplReq::CreateForce;
+    break;
+  }
+  }
+	 
+  req->file_id = f_ptr.p->key;
+  req->filegroup_id = f_ptr.p->m_filegroup_id;
+  req->filegroup_version = fg_ptr.p->m_version;
+  req->file_size_hi = f_ptr.p->m_file_size >> 32;
+  req->file_size_lo = f_ptr.p->m_file_size & 0xFFFFFFFF;
+
+  Uint32 ref= 0;
+  Uint32 len= 0;
+  switch(op->m_obj_type){
+  case DictTabInfo::Datafile:
+  {
+    jam();
+    ref = TSMAN_REF;
+    len = CreateFileImplReq::DatafileLength;
+    req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
+    break;
+  }
+  case DictTabInfo::Undofile:
+  {
+    jam();
+    ref = LGMAN_REF;
+    len = CreateFileImplReq::UndofileLength;
+    break;
+  }
+  default:
+    ndbrequire(false);
+  }
+  
+  char name[MAX_TAB_NAME_SIZE];
+  ConstRope tmp(c_rope_pool, f_ptr.p->m_path);
+  tmp.copy(name);
+  LinearSectionPtr ptr[3];
+  ptr[0].p = (Uint32*)&name[0];
+  ptr[0].sz = (strlen(name)+1+3)/4;
+  sendSignal(ref, GSN_CREATE_FILE_REQ, signal, len, JBB, ptr, 1);
 }
 
-int
-Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table, const char* attributeName)
+void
+Dbdict::execCREATE_FILE_REF(Signal* signal)
 {
-  int ret;
-  TableRecordPtr tablePtr;
-  if ((ret = getMetaTablePtr(tablePtr, table.tableId, table.tableVersion)) < 0) {
-    return ret;
+  CreateFileImplRef * ref = (CreateFileImplRef*)signal->getDataPtr();
+  CreateObjRecordPtr op_ptr;
+
+  jamEntry();
+  ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
+  op_ptr.p->m_errorCode = ref->errorCode;
+  execute(signal, op_ptr.p->m_callback, 0);  
+}  
+
+void
+Dbdict::execCREATE_FILE_CONF(Signal* signal)
+{
+  CreateFileImplConf * rep = 
+    (CreateFileImplConf*)signal->getDataPtr();
+  CreateObjRecordPtr op_ptr;
+
+  jamEntry();
+  ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
+  execute(signal, op_ptr.p->m_callback, 0);  
+}
+
+void
+Dbdict::create_file_commit_start(Signal* signal, SchemaOp* op)
+{
+  /**
+   * CONTACT TSMAN LGMAN PGMAN 
+   */
+  CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
+  FilePtr f_ptr;
+  FilegroupPtr fg_ptr;
+
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+  ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
+
+  req->senderData = op->key;
+  req->senderRef = reference();
+  req->requestInfo = CreateFileImplReq::Commit;
+  
+  req->file_id = f_ptr.p->key;
+  req->filegroup_id = f_ptr.p->m_filegroup_id;
+  req->filegroup_version = fg_ptr.p->m_version;
+
+  Uint32 ref= 0;
+  switch(op->m_obj_type){
+  case DictTabInfo::Datafile:
+  {
+    jam();
+    ref = TSMAN_REF;
+    break;
   }
-  AttributeRecordPtr attrPtr;
-  attrPtr.i = tablePtr.p->firstAttribute;
-  while (attrPtr.i != RNIL) {
-    c_attributeRecordPool.getPtr(attrPtr);
-    if (strcmp(attrPtr.p->attributeName, attributeName) == 0)
+  case DictTabInfo::Undofile:
+  {
+    jam();
+    ref = LGMAN_REF;
+    break;
+  }
+  default:
+    ndbrequire(false);
+  }
+  sendSignal(ref, GSN_CREATE_FILE_REQ, signal, 
+	     CreateFileImplReq::CommitLength, JBB);
+}
+
+void
+Dbdict::create_file_abort_start(Signal* signal, SchemaOp* op)
+{
+  CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
+
+  if (op->m_obj_ptr_i != RNIL)
+  {
+    FilePtr f_ptr;
+    FilegroupPtr fg_ptr;
+
+    jam();
+    c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+    
+    ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
+    
+    req->senderData = op->key;
+    req->senderRef = reference();
+    req->requestInfo = CreateFileImplReq::Abort;
+    
+    req->file_id = f_ptr.p->key;
+    req->filegroup_id = f_ptr.p->m_filegroup_id;
+    req->filegroup_version = fg_ptr.p->m_version;
+    
+    Uint32 ref= 0;
+    switch(op->m_obj_type){
+    case DictTabInfo::Datafile:
+    {
+      jam();
+      ref = TSMAN_REF;
       break;
-    attrPtr.i = attrPtr.p->nextAttrInTable;
+    }
+    case DictTabInfo::Undofile:
+    {
+      jam();
+      ref = LGMAN_REF;
+      break;
+    }
+    default:
+      ndbrequire(false);
+    }
+    sendSignal(ref, GSN_CREATE_FILE_REQ, signal, 
+	       CreateFileImplReq::AbortLength, JBB);
+    return;
   }
-  if (attrPtr.i == RNIL) {
-    return MetaData::AttributeNotFound;
+  execute(signal, op->m_callback, 0);
+}
+
+void
+Dbdict::create_file_abort_complete(Signal* signal, SchemaOp* op)
+{
+  if (op->m_obj_ptr_i != RNIL)
+  {
+    FilePtr f_ptr;
+    FilegroupPtr fg_ptr;
+
+    jam();
+    c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+    ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
+    switch(fg_ptr.p->m_type){
+    case DictTabInfo::Tablespace:
+    {
+      jam();
+      decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
+      break;
+    }
+    case DictTabInfo::LogfileGroup:
+    {
+      jam();
+      Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
+      list.remove(f_ptr);
+      break;
+    }
+    default:
+      ndbrequire(false);
+    }
+    
+    release_object(f_ptr.p->m_obj_ptr_i);
+    c_file_hash.release(f_ptr);
   }
-  new (&attr) MetaData::Attribute(*attrPtr.p);
-  return 0;
+  execute(signal, op->m_callback, 0);
+}
+
+void
+Dbdict::drop_file_prepare_start(Signal* signal, SchemaOp* op)
+{
+  jam();
+  send_drop_file(signal, op, DropFileImplReq::Prepare);
+}
+
+void
+Dbdict::drop_undofile_prepare_start(Signal* signal, SchemaOp* op)
+{
+  jam();
+  op->m_errorCode = DropFileRef::DropUndoFileNotSupported;
+  execute(signal, op->m_callback, 0);  
+}
+
+void
+Dbdict::drop_file_commit_start(Signal* signal, SchemaOp* op)
+{
+  jam();
+  send_drop_file(signal, op, DropFileImplReq::Commit);
+}
+
+void
+Dbdict::drop_file_commit_complete(Signal* signal, SchemaOp* op)
+{
+  FilePtr f_ptr;
+  FilegroupPtr fg_ptr;
+
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+  ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
+  decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
+  release_object(f_ptr.p->m_obj_ptr_i);
+  c_file_hash.release(f_ptr);
+  execute(signal, op->m_callback, 0);
+}
+
+void
+Dbdict::drop_file_abort_start(Signal* signal, SchemaOp* op)
+{
+  jam();
+  send_drop_file(signal, op, DropFileImplReq::Abort);
+}
+
+void
+Dbdict::send_drop_file(Signal* signal, SchemaOp* op, 
+		       DropFileImplReq::RequestInfo type)
+{
+  DropFileImplReq* req = (DropFileImplReq*)signal->getDataPtrSend();
+  FilePtr f_ptr;
+  FilegroupPtr fg_ptr;
+
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+  ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
+  
+  req->senderData = op->key;
+  req->senderRef = reference();
+  req->requestInfo = type;
+  
+  req->file_id = f_ptr.p->key;
+  req->filegroup_id = f_ptr.p->m_filegroup_id;
+  req->filegroup_version = fg_ptr.p->m_version;
+  
+  Uint32 ref= 0;
+  switch(op->m_obj_type){
+  case DictTabInfo::Datafile:
+  {
+    jam();
+    ref = TSMAN_REF;
+    break;
+  }
+  case DictTabInfo::Undofile:
+  {
+    jam();
+    ref = LGMAN_REF;
+    break;
+  }
+  default:
+    ndbrequire(false);
+  }
+  sendSignal(ref, GSN_DROP_FILE_REQ, signal, 
+	     DropFileImplReq::SignalLength, JBB);
+}
+
+void
+Dbdict::execDROP_OBJ_REF(Signal* signal)
+{
+  DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
+  if(ref->errorCode != DropObjRef::NF_FakeErrorREF){
+    jam();
+    trans_ptr.p->setErrorCode(ref->errorCode);
+  }
+  Uint32 node = refToNode(ref->senderRef);
+  schemaOp_reply(signal, trans_ptr.p, node);
+}
+
+void
+Dbdict::execDROP_OBJ_CONF(Signal* signal)
+{
+  DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
+  Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
+  ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
+  schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
+}
+
+void
+Dbdict::execDROP_FILE_REF(Signal* signal)
+{
+  DropFileImplRef * ref = (DropFileImplRef*)signal->getDataPtr();
+  DropObjRecordPtr op_ptr;
+
+  jamEntry();
+  ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
+  op_ptr.p->m_errorCode = ref->errorCode;
+  execute(signal, op_ptr.p->m_callback, 0);  
+}  
+
+void
+Dbdict::execDROP_FILE_CONF(Signal* signal)
+{
+  DropFileImplConf * rep = 
+    (DropFileImplConf*)signal->getDataPtr();
+  DropObjRecordPtr op_ptr;
+
+  jamEntry();
+  ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
+  execute(signal, op_ptr.p->m_callback, 0);  
+}
+
+void
+Dbdict::execDROP_FILEGROUP_REF(Signal* signal)
+{
+  DropFilegroupImplRef * ref = (DropFilegroupImplRef*)signal->getDataPtr();
+  DropObjRecordPtr op_ptr;
+
+  jamEntry();
+  ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
+  op_ptr.p->m_errorCode = ref->errorCode;
+  execute(signal, op_ptr.p->m_callback, 0);  
+}  
+
+void
+Dbdict::execDROP_FILEGROUP_CONF(Signal* signal)
+{
+  DropFilegroupImplConf * rep = 
+    (DropFilegroupImplConf*)signal->getDataPtr();
+  DropObjRecordPtr op_ptr;
+
+  jamEntry();
+  ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
+  execute(signal, op_ptr.p->m_callback, 0);  
+}
+
+void
+Dbdict::drop_fg_prepare_start(Signal* signal, SchemaOp* op)
+{
+  FilegroupPtr fg_ptr;
+  c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
+  
+  DictObject * obj = c_obj_pool.getPtr(fg_ptr.p->m_obj_ptr_i);
+  if (obj->m_ref_count)
+  {
+    jam();
+    op->m_errorCode = DropFilegroupRef::FilegroupInUse;
+    execute(signal, op->m_callback, 0);  
+  }
+  else
+  {
+    jam();
+    send_drop_fg(signal, op, DropFilegroupImplReq::Prepare);
+  }
+}
+
+void
+Dbdict::drop_fg_commit_start(Signal* signal, SchemaOp* op)
+{
+  FilegroupPtr fg_ptr;
+  c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
+  if (op->m_obj_type == DictTabInfo::LogfileGroup)
+  {
+    jam(); 
+    /**
+     * Mark all undofiles as dropped
+     */
+    Ptr<File> filePtr;
+    Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
+    XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
+    for(list.first(filePtr); !filePtr.isNull(); list.next(filePtr))
+    {
+      jam();
+      Uint32 objId = filePtr.p->key;
+      SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, objId);
+      tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
+      computeChecksum(xsf, objId / NDB_SF_PAGE_ENTRIES);
+      release_object(filePtr.p->m_obj_ptr_i);
+      c_file_hash.remove(filePtr);
+    }
+    list.release();
+  }
+  else if(op->m_obj_type == DictTabInfo::Tablespace)
+  {
+    FilegroupPtr lg_ptr;
+    jam();
+    ndbrequire(c_filegroup_hash.
+	       find(lg_ptr, 
+		    fg_ptr.p->m_tablespace.m_default_logfile_group_id));
+    
+    decrease_ref_count(lg_ptr.p->m_obj_ptr_i);
+  }
+  jam(); 
+  send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
+}
+
+void
+Dbdict::drop_fg_commit_complete(Signal* signal, SchemaOp* op)
+{
+  FilegroupPtr fg_ptr;
+  c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
+
+  jam();
+  release_object(fg_ptr.p->m_obj_ptr_i);
+  c_filegroup_hash.release(fg_ptr);
+  execute(signal, op->m_callback, 0);
+}
+
+void
+Dbdict::drop_fg_abort_start(Signal* signal, SchemaOp* op)
+{
+  jam();
+  send_drop_fg(signal, op, DropFilegroupImplReq::Abort);
+}
+
+void
+Dbdict::send_drop_fg(Signal* signal, SchemaOp* op, 
+		     DropFilegroupImplReq::RequestInfo type)
+{
+  DropFilegroupImplReq* req = (DropFilegroupImplReq*)signal->getDataPtrSend();
+  
+  FilegroupPtr fg_ptr;
+  c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
+  
+  req->senderData = op->key;
+  req->senderRef = reference();
+  req->requestInfo = type;
+  
+  req->filegroup_id = fg_ptr.p->key;
+  req->filegroup_version = fg_ptr.p->m_version;
+  
+  Uint32 ref= 0;
+  switch(op->m_obj_type){
+  case DictTabInfo::Tablespace:
+    ref = TSMAN_REF;
+    break;
+  case DictTabInfo::LogfileGroup:
+    ref = LGMAN_REF;
+    break;
+  default:
+    ndbrequire(false);
+  }
+  
+  sendSignal(ref, GSN_DROP_FILEGROUP_REQ, signal, 
+	     DropFilegroupImplReq::SignalLength, JBB);
 }
 
 /*
@@ -10584,7 +16489,6 @@
   b) senderRef is not a db node
   c) senderRef nodeid is not the singleUserApi
 */
-
 int Dbdict::checkSingleUserMode(Uint32 senderRef)
 {
   Uint32 nodeId = refToNode(senderRef);
@@ -10594,4 +16498,3 @@
     (nodeId != getNodeState().getSingleUserApi());
 }
 
-CArray<KeyDescriptor> g_key_descriptor_pool;

--- 1.2.7.1/ndb/include/mgmapi/ndbd_exit_codes.h	2007-05-15 09:02:58 +02:00
+++ 1.17/storage/ndb/include/mgmapi/ndbd_exit_codes.h	2007-05-15 09:54:39 +02:00
@@ -95,6 +95,9 @@
 #define NDBD_EXIT_INVALID_CONFIG              2350
 #define NDBD_EXIT_OUT_OF_LONG_SIGNAL_MEMORY   2351
 
+/* Errorcodes for fatal resource errors */
+#define NDBD_EXIT_RESOURCE_ALLOC_ERROR        2500
+
 #define NDBD_EXIT_OS_SIGNAL_RECEIVED          6000
 
 /* VM 6050-> */
@@ -142,6 +145,9 @@
 #define NDBD_EXIT_AFS_NO_MORE_RESOURCES     2814
 #define NDBD_EXIT_AFS_NO_SUCH_FILE          2815
 #define NDBD_EXIT_AFS_READ_UNDERFLOW        2816
+
+#define NDBD_EXIT_INVALID_LCP_FILE          2352
+#define NDBD_EXIT_INSUFFICENT_NODES         2353
 
 const char *
 ndbd_exit_message(int faultId, ndbd_exit_classification *cl);

--- 1.1.10.1/ndb/src/kernel/error/ndbd_exit_codes.c	2007-05-15 09:02:58 +02:00
+++ 1.19/storage/ndb/src/kernel/error/ndbd_exit_codes.c	2007-05-15 09:47:50 +02:00
@@ -89,6 +89,10 @@
    /* this error message is complemented by additional info when generated */
    {NDBD_EXIT_INVALID_CONFIG, XCE,
     "Invalid configuration received from Management Server"},
+
+   {NDBD_EXIT_RESOURCE_ALLOC_ERROR, XCE,
+    "Resource allocation e