List:Internals« Previous MessageNext Message »
From:Martin Skold Date:October 18 2005 9:49am
Subject:bk commit into 5.1 tree (mskold:1.2040)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of marty. When marty 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
  1.2040 05/10/18 11:48:48 mskold@stripped +6 -0
  Merge mskold@stripped:/home/bk/mysql-5.1-wl2604
  into  mysql.com:/usr/local/home/marty/MySQL/mysql-5.1-wl2604

  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
    1.112 05/10/18 11:48:40 mskold@stripped +0 -0
    Auto merged

  storage/ndb/src/ndbapi/NdbDictionary.cpp
    1.59 05/10/18 11:48:40 mskold@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
    1.47 05/10/18 11:48:40 mskold@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
    1.110 05/10/18 11:48:39 mskold@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.h
    1.87 05/10/18 11:48:39 mskold@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.cc
    1.166 05/10/18 11:48:39 mskold@stripped +0 -0
    Auto merged

# 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:	mskold
# Host:	blowfish.ndb.mysql.com
# Root:	/usr/local/home/marty/MySQL/mysql-5.1-wl2604/RESYNC

--- 1.109/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-10-12 13:15:56 +02:00
+++ 1.110/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-10-18 11:48:39 +02:00
@@ -104,6 +104,7 @@
 
 static
 struct {
+  Uint32 m_gsn_user_req;
   Uint32 m_gsn_req;
   Uint32 m_gsn_ref;
   Uint32 m_gsn_conf;
@@ -114,20 +115,25 @@
 
   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::create_fg_commit_start, &Dbdict::create_fg_commit_complete,
+    &Dbdict::createObj_commit,
+    0, 0,
+    &Dbdict::createObj_abort,
     &Dbdict::create_fg_abort_start, &Dbdict::create_fg_abort_complete,
   }
 
@@ -135,12 +141,56 @@
    * 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::create_file_commit_start, &Dbdict::create_file_commit_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
+  }
 };
 
 Uint32
@@ -356,7 +406,6 @@
   union {
     char tableName[MAX_TAB_NAME_SIZE];
     char frmData[MAX_FRM_DATA_SIZE];
-    char tsNameData[16*MAX_NDB_PARTITIONS];
     char rangeData[16*MAX_NDB_PARTITIONS];
     char ngData[2*MAX_NDB_PARTITIONS];
     char tsData[2*2*MAX_NDB_PARTITIONS];
@@ -440,11 +489,6 @@
   */
   {
     jam();
-    ConstRope ts_name(c_rope_pool, tablePtr.p->tsNameData);
-    ts_name.copy(tsNameData);
-    w.add(DictTabInfo::TsNameLen, ts_name.size());
-    w.add(DictTabInfo::TsNameData, tsNameData, ts_name.size());
-
     ConstRope ts(c_rope_pool, tablePtr.p->tsData);
     ts.copy(tsData);
     w.add(DictTabInfo::TablespaceDataLen, ts.size());
@@ -1044,7 +1088,8 @@
     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();
@@ -1432,10 +1477,12 @@
   c_opCreateTrigger(c_opRecordPool),
   c_opDropTrigger(c_opRecordPool),
   c_opAlterTrigger(c_opRecordPool),
-  //c_opDropObj(c_opRecordPool),
-  c_opCreateObj(c_opRecordPool),
+  c_schemaOp(c_opRecordPool),
   c_Trans(c_opRecordPool),
+  c_opCreateObj(c_schemaOp),
+  c_opDropObj(c_schemaOp),
   c_opRecordSequence(0)
+
 {
   BLOCK_CONSTRUCTOR(Dbdict);
   
@@ -1579,14 +1626,19 @@
   addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Dbdict::execCREATE_FILEGROUP_REQ);
 
   addRecSignal(GSN_DROP_FILE_REQ, &Dbdict::execDROP_FILE_REQ);
-  addRecSignal(GSN_DROP_FILEGROUP_REQ, &Dbdict::execDROP_FILEGROUP_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_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);
@@ -1594,6 +1646,15 @@
   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);
+
 }//Dbdict::Dbdict()
 
 Dbdict::~Dbdict() 
@@ -1984,7 +2045,7 @@
     (SchemaFile*)c_schemaPageRecordArray.getPtr(1 * NDB_SF_MAX_PAGES);
   c_schemaFile[1].noOfPages = 0;
 
-  c_opCreateObj.setSize(8);
+  c_schemaOp.setSize(8);
   //c_opDropObj.setSize(8);
   c_Trans.setSize(8);
   c_rope_pool.setSize(100000/28);
@@ -3223,8 +3284,11 @@
   ndbrequire(import(ptr, pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz));
   createObjPtr.p->m_obj_info_ptr_i= ptr.i;  
   
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
-    (signal, createObjPtr.p);
+  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
@@ -3268,8 +3332,11 @@
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::restartCreateObj_prepare_complete_done);
   
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
-    (signal, createObjPtr.p);
+  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
@@ -3285,8 +3352,12 @@
 
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::restartCreateObj_commit_start_done);
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
-    (signal, createObjPtr.p);
+
+  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
@@ -3302,8 +3373,12 @@
 
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::restartCreateObj_commit_complete_done);
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
-    (signal, createObjPtr.p);
+
+  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);
 }  
 
 
@@ -3832,8 +3907,8 @@
   lreq->gci = tablePtr.p->gciTableCreated;
   lreq->requestType = AlterTabReq::AlterTablePrepare;
   
-  sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 
-	     AlterTabReq::SignalLength, JBB);
+  sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 
+		       AlterTabReq::SignalLength, JBB);
 }
 
 void Dbdict::alterTableRef(Signal * signal, 
@@ -4317,8 +4392,8 @@
 	lreq->gci = gci;
 	lreq->requestType = AlterTabReq::AlterTableCommit;
 	
-	sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 
-		   AlterTabReq::SignalLength, JBB);
+	sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 
+			     AlterTabReq::SignalLength, JBB);
       }
     }
     else {
@@ -4955,6 +5030,13 @@
     safe_cast(&Dbdict::createTab_writeSchemaConf1);
   
   updateSchemaState(signal, tableId, &tabEntry, &callback);
+
+  if (tabPtr.p->m_tablespace_id != RNIL)
+  {
+    FilegroupPtr ptr;
+    ndbrequire(c_filegroup_hash.find(ptr, tabPtr.p->m_tablespace_id));
+    increase_ref_count(ptr.p->m_obj_ptr_i);
+  }
 }
 
 void getSection(SegmentedSectionPtr & ptr, Uint32 i);
@@ -5532,6 +5614,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
@@ -5625,6 +5714,21 @@
   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) 
@@ -5742,6 +5846,7 @@
     obj_ptr.p->m_id = tablePtr.i;
     obj_ptr.p->m_type = 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;
 
@@ -5767,8 +5872,6 @@
     Rope range(c_rope_pool, tablePtr.p->rangeData);
     ndbrequire(range.assign(tableDesc.RangeListData,
                tableDesc.RangeListDataLen));
-    Rope ts_name(c_rope_pool, tablePtr.p->tsNameData);
-    ndbrequire(ts_name.assign(tableDesc.TsNameData, tableDesc.TsNameLen));
     Rope fd(c_rope_pool, tablePtr.p->ngData);
     ndbrequire(fd.assign((const char*)tableDesc.FragmentData,
                          tableDesc.FragmentDataLen));
@@ -6122,7 +6225,10 @@
 /* ---------------------------------------------------------------- */
 // Error Handling code needed
 /* ---------------------------------------------------------------- */
-  progError(ref->errorCode, 0);
+  char buf[32];
+  BaseString::snprintf(buf, sizeof(buf), "WAIT_GCP_REF ErrorCode=%d",
+		       ref->errorCode);
+  progError(__LINE__, NDBD_EXIT_NDBREQUIRE, buf);
 }//execWAIT_GCP_REF()
 
 
@@ -6581,6 +6687,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>
@@ -11836,6 +11949,7 @@
     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;
   }
@@ -12869,7 +12983,8 @@
 */
 
 void
-Dbdict::getTableKeyList(TableRecordPtr tablePtr, AttributeList& list)
+Dbdict::getTableKeyList(TableRecordPtr tablePtr, 
+			Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list)
 {
   jam();
   list.sz = 0;
@@ -12883,6 +12998,7 @@
     }
   }
   ndbrequire(list.sz == (uint)(tablePtr.p->noOfPrimkey + 1));
+  ndbrequire(list.sz <= MAX_ATTRIBUTES_IN_INDEX + 1);
 }
 
 // XXX should store the primary attribute id
@@ -13095,7 +13211,7 @@
     
     const Uint32 op_key = ++c_opRecordSequence;
     trans_ptr.p->m_op.m_key = op_key;
-    trans_ptr.p->m_op.m_gsn = GSN_CREATE_FILE_REQ;
+    trans_ptr.p->m_op.m_vt_index = 1;
     trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
     
     CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
@@ -13106,7 +13222,6 @@
     create_obj->clientData = senderData;
     
     create_obj->objType = type;
-    create_obj->requestType = DictObjOp::Prepare;
     create_obj->requestInfo = requestInfo;
 
     {
@@ -13140,7 +13255,7 @@
   ref->senderData = senderData;
   ref->masterNodeId = c_masterNodeId;
   sendSignal(senderRef, GSN_CREATE_FILE_REF,signal,
-	     CreateFilegroupRef::SignalLength, JBB);
+	     CreateFileRef::SignalLength, JBB);
 }
 
 void
@@ -13196,7 +13311,7 @@
     
     const Uint32 op_key = ++c_opRecordSequence;
     trans_ptr.p->m_op.m_key = op_key;
-    trans_ptr.p->m_op.m_gsn = GSN_CREATE_FILEGROUP_REQ;
+    trans_ptr.p->m_op.m_vt_index = 0;
     trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
     
     CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
@@ -13207,7 +13322,6 @@
     create_obj->clientData = senderData;
     
     create_obj->objType = type;
-    create_obj->requestType = DictObjOp::Prepare;
     
     {
       Uint32 objId = getFreeObjId(0);
@@ -13244,12 +13358,153 @@
 }
 
 void
-Dbdict::execDROP_FILE_REQ(Signal* signal){
+Dbdict::execDROP_FILE_REQ(Signal* signal)
+{
+  jamEntry();
+  
+  if(!assembleFragments(signal)){
+    jam();
+    return;
+  }
+  
+  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 {
+    Ptr<File> file_ptr;
+    if (!c_file_hash.find(file_ptr, objId))
+    {
+      ref->errorCode = DropFileRef::NoSuchFile;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    Ptr<SchemaTransaction> trans_ptr;
+    if (! c_Trans.seize(trans_ptr))
+    {
+      ref->errorCode = CreateFileRef::Busy;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    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);
+    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){
 
+void
+Dbdict::execDROP_FILEGROUP_REQ(Signal* signal)
+{
+  jamEntry();
+  
+  if(!assembleFragments(signal)){
+    jam();
+    return;
+  }
+  
+  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 {
+    Ptr<Filegroup> filegroup_ptr;
+    if (!c_filegroup_hash.find(filegroup_ptr, objId))
+    {
+      ref->errorCode = DropFilegroupRef::NoSuchFilegroup;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    Ptr<SchemaTransaction> trans_ptr;
+    if (! c_Trans.seize(trans_ptr))
+    {
+      ref->errorCode = CreateFilegroupRef::Busy;
+      ref->errorLine = __LINE__;
+      break;
+    }
+    
+    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);
+    return;
+  } while(0);
+  
+  ref->senderData = senderData;
+  ref->masterNodeId = c_masterNodeId;
+  sendSignal(senderRef, GSN_DROP_FILEGROUP_REF,signal,
+	     DropFilegroupRef::SignalLength, JBB);
 }
 
 void
@@ -13265,7 +13520,7 @@
     trans_ptr.p->setErrorCode(ref->errorCode);
   }
   Uint32 node = refToNode(ref->senderRef);
-  createObj_reply(signal, trans_ptr.p, node);
+  schemaOp_reply(signal, trans_ptr.p, node);
 }
 
 void
@@ -13276,13 +13531,13 @@
   
   Ptr<SchemaTransaction> trans_ptr;
   ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
-  createObj_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
+  schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
 }
 
 void
-Dbdict::createObj_reply(Signal* signal, 
-			SchemaTransaction * trans_ptr_p, 
-			Uint32 nodeId)
+Dbdict::schemaOp_reply(Signal* signal, 
+		       SchemaTransaction * trans_ptr_p, 
+		       Uint32 nodeId)
 {
   {
     SafeCounter tmp(c_counterMgr, trans_ptr_p->m_counter);
@@ -13294,7 +13549,7 @@
   
   switch(trans_ptr_p->m_op.m_state){
   case DictObjOp::Preparing:{
-
+    
     if(trans_ptr_p->m_errorCode != 0)
     {
       jam();
@@ -13306,8 +13561,9 @@
       trans_ptr_p->m_callback.m_callbackFunction= 
 	safe_cast(&Dbdict::trans_abort_start_done);
       
-      if(f_dict_op[0].m_trans_abort_start)
-	(this->*f_dict_op[0].m_trans_abort_start)(signal, trans_ptr_p);
+      if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
+	(this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
+	  (signal, trans_ptr_p);
       else
 	execute(signal, trans_ptr_p->m_callback, 0);
       return;
@@ -13318,8 +13574,9 @@
     trans_ptr_p->m_callback.m_callbackFunction= 
       safe_cast(&Dbdict::trans_commit_start_done);
     
-    if(f_dict_op[0].m_trans_commit_start)
-      (this->*f_dict_op[0].m_trans_commit_start)(signal, trans_ptr_p);
+    if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
+      (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
+	(signal, trans_ptr_p);
     else
       execute(signal, trans_ptr_p->m_callback, 0);
     return;
@@ -13333,8 +13590,9 @@
     trans_ptr_p->m_callback.m_callbackFunction= 
       safe_cast(&Dbdict::trans_commit_complete_done);
     
-    if(f_dict_op[0].m_trans_commit_complete)
-      (this->*f_dict_op[0].m_trans_commit_complete)(signal, trans_ptr_p);
+    if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
+      (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
+	(signal, trans_ptr_p);
     else
       execute(signal, trans_ptr_p->m_callback, 0);      
     return;
@@ -13347,8 +13605,9 @@
     trans_ptr_p->m_callback.m_callbackFunction= 
       safe_cast(&Dbdict::trans_abort_complete_done);
 
-    if(f_dict_op[0].m_trans_abort_complete)
-      (this->*f_dict_op[0].m_trans_abort_complete)(signal, trans_ptr_p);
+    if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
+      (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
+	(signal, trans_ptr_p);
     else
       execute(signal, trans_ptr_p->m_callback, 0);      
     return;
@@ -13375,14 +13634,14 @@
   
   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_ptr.p->key);
+  tmp.init<DictCommitRef>(rg, GSN_DICT_COMMIT_REF, trans_ptr.p->key);
   
-  CreateObjReq * const req = (CreateObjReq*)signal->getDataPtrSend();
+  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;
-  req->requestType = DictObjOp::Commit;
-  sendSignal(rg, GSN_CREATE_OBJ_REQ, signal, 4, JBB);
+  sendSignal(rg, GSN_DICT_COMMIT_REQ, signal, DictCommitReq::SignalLength, 
+	     JBB);
   
   trans_ptr.p->m_op.m_state = DictObjOp::Committing;
 }
@@ -13398,7 +13657,7 @@
   Ptr<SchemaTransaction> trans_ptr;
   ndbrequire(c_Trans.find(trans_ptr, callbackData));
 
-  switch(trans_ptr.p->m_op.m_gsn){
+  switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
   case GSN_CREATE_FILEGROUP_REQ:{
     FilegroupPtr fg_ptr;
     ndbrequire(c_filegroup_hash.find(fg_ptr, trans_ptr.p->m_op.m_obj_id));
@@ -13425,10 +13684,32 @@
     
     //@todo check api failed
     sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_CONF, signal, 
-	       CreateFilegroupConf::SignalLength, JBB);
+	       CreateFileConf::SignalLength, JBB);
     
     break;
   }
+  case GSN_DROP_FILE_REQ:{
+    DropFileConf * conf = (DropFileConf*)signal->getDataPtr();
+    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();
+    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);
   }
@@ -13451,15 +13732,14 @@
   
   NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
   SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
-  ndbrequire(tmp.init<CreateObjRef>(rg, trans_ptr.p->key));
+  ndbrequire(tmp.init<DictAbortRef>(rg, trans_ptr.p->key));
   
-  CreateObjReq * const req = (CreateObjReq*)signal->getDataPtrSend();
+  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;
-  req->requestType = DictObjOp::Abort;
   
-  sendSignal(rg, GSN_CREATE_OBJ_REQ, signal, 4, JBB);
+  sendSignal(rg, GSN_DICT_ABORT_REQ, signal, DictAbortReq::SignalLength, JBB);
 }
 
 void
@@ -13473,7 +13753,7 @@
   Ptr<SchemaTransaction> trans_ptr;
   ndbrequire(c_Trans.find(trans_ptr, callbackData));
 
-  switch(trans_ptr.p->m_op.m_gsn){
+  switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
   case GSN_CREATE_FILEGROUP_REQ:
   {
     //
@@ -13509,6 +13789,39 @@
     
     break;
   }
+  case GSN_DROP_FILE_REQ:
+  {
+    DropFileRef * ref = (DropFileRef*)signal->getDataPtr();
+    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();
+    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);
   }
@@ -13528,26 +13841,6 @@
   }
 
   CreateObjReq * const req = (CreateObjReq*)signal->getDataPtr();
-
-  DictObjOp::RequestType rt = (DictObjOp::RequestType)req->requestType;
-  switch(rt){
-  case DictObjOp::Prepare:
-    createObj_prepare(signal, req);
-    return;
-  case DictObjOp::Commit:
-    createObj_commit(signal, req);
-    return;
-  case DictObjOp::Abort:
-    createObj_abort(signal, req);
-    return;
-  }
-  ndbrequire(false);
-}
-
-void
-Dbdict::createObj_prepare(Signal* signal, CreateObjReq* req){
-
-  jam();
   const Uint32 gci = req->gci;
   const Uint32 objId = req->objId;
   const Uint32 objVersion = req->objVersion;
@@ -13569,6 +13862,7 @@
   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;
@@ -13603,6 +13897,84 @@
 }
 
 void
+Dbdict::execDICT_COMMIT_REQ(Signal* signal)
+{
+  DictCommitReq* req = (DictCommitReq*)signal->getDataPtr();
+
+  Ptr<SchemaOp> op;
+  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;
+  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){
+  jamEntry();
+  
+  DictCommitRef * const ref = (DictCommitRef*)signal->getDataPtr();
+  
+  Ptr<SchemaTransaction> trans_ptr;
+  ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
+  
+  if(ref->errorCode != DictCommitRef::NF_FakeErrorREF){
+    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){
+  jamEntry();
+  
+  DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
+  
+  Ptr<SchemaTransaction> trans_ptr;
+  ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
+  schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
+}
+
+void
+Dbdict::execDICT_ABORT_REF(Signal* signal){
+  jamEntry();
+  
+  DictAbortRef * const ref = (DictAbortRef*)signal->getDataPtr();
+  
+  Ptr<SchemaTransaction> trans_ptr;
+  ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
+  
+  if(ref->errorCode != DictAbortRef::NF_FakeErrorREF){
+    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){
+  jamEntry();
+  
+  DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
+  
+  Ptr<SchemaTransaction> trans_ptr;
+  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){
@@ -13625,6 +13997,7 @@
   }
   
   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;
@@ -13716,16 +14089,16 @@
 }
 
 void
-Dbdict::createObj_commit(Signal * signal, CreateObjReq * req){
+Dbdict::createObj_commit(Signal * signal, SchemaOp * op){
   jam();
   
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, req->op_key));
-  
-  createObjPtr.p->m_callback.m_callbackFunction = 
+  OpCreateObj * createObj = (OpCreateObj*)op;
+  createObj->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_commit_start_done);
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
-    (signal, createObjPtr.p);
+  if (f_dict_op[createObj->m_vt_index].m_commit_start)
+    (this->*f_dict_op[createObj->m_vt_index].m_commit_start)(signal, createObj);
+  else
+    execute(signal, createObj->m_callback, 0);
 }
 
 void
@@ -13765,8 +14138,11 @@
 
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_commit_complete_done);
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
-    (signal, createObjPtr.p);
+  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);
   
 }
 
@@ -13782,26 +14158,28 @@
   //@todo check error
   //@todo check master failed
   
-  CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
+  DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
   conf->senderRef = reference();
   conf->senderData = createObjPtr.p->m_senderData;
-  sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_CONF,
-	     signal, CreateObjConf::SignalLength, JBB);
+  sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
+	     signal, DictCommitConf::SignalLength, JBB);
   
   c_opCreateObj.release(createObjPtr);
 }
 
 void
-Dbdict::createObj_abort(Signal* signal, CreateObjReq * req){
+Dbdict::createObj_abort(Signal* signal, SchemaOp* op)
+{
   jam();
   
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, req->op_key));
-
-  createObjPtr.p->m_callback.m_callbackFunction = 
+  OpCreateObj * createObj = (OpCreateObj*)op;
+  
+  createObj->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_abort_start_done);
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_abort_start)
-    (signal, createObjPtr.p);
+  if (f_dict_op[createObj->m_vt_index].m_abort_start)
+    (this->*f_dict_op[createObj->m_vt_index].m_abort_start)(signal, createObj);
+  else
+    execute(signal, createObj->m_callback, 0);
 }
 
 void
@@ -13838,8 +14216,12 @@
 
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_abort_complete_done);
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
-    (signal, createObjPtr.p);
+  
+  if (f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
+    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
+      (signal, createObjPtr.p);
+  else
+    execute(signal, createObjPtr.p->m_callback, 0);
 }
 
 void
@@ -13852,11 +14234,11 @@
   CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
 
-  CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
+  DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
   conf->senderRef = reference();
   conf->senderData = createObjPtr.p->m_senderData;
-  sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_CONF,
-	     signal, CreateObjConf::SignalLength, JBB);
+  sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
+	     signal, DictAbortConf::SignalLength, JBB);
   
   c_opCreateObj.release(createObjPtr);
 }
@@ -13869,66 +14251,309 @@
     jam();
     return;
   }
-
+  
   DropObjReq * const req = (DropObjReq*)signal->getDataPtr();
 
-  DictObjOp::RequestType rt = (DictObjOp::RequestType)req->requestType;
-  switch(rt){
-  case DictObjOp::Prepare:
-    dropObj_prepare(signal, req);
-    return;
-  case DictObjOp::Commit:
-    dropObj_commit(signal, req);
+  const Uint32 objId = req->objId;
+  const Uint32 objVersion = req->objVersion;
+  const Uint32 objType = req->objType;
+  const Uint32 requestInfo = req->requestInfo;
+  
+  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:
+  {
+    dropObjPtr.p->m_vt_index = 3;
+    Ptr<Filegroup> fg_ptr;
+    ndbrequire(c_filegroup_hash.find(fg_ptr, objId));
+    dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
+    break;
+  
+  }
+  case DictTabInfo::Datafile:
+  {
+    dropObjPtr.p->m_vt_index = 2;
+    Ptr<File> file_ptr;
+    ndbrequire(c_file_hash.find(file_ptr, objId));
+    dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
+    break;
+  }
+  case DictTabInfo::Undofile:
+    dropObjPtr.p->m_vt_index = 4;
     return;
-  case DictObjOp::Abort:
-    dropObj_abort(signal, req);
+  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)
+{
+  ndbrequire(returnCode == 0);
+
+  DropObjRecordPtr dropObjPtr;  
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+
+  Callback cb;
+  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;
   }
-  ndbrequire(false);
+  
+  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(Signal* signal, DropObjReq* req){
+Dbdict::dropObj_prepare_writeSchemaConf(Signal* signal, 
+					Uint32 callbackData,
+					Uint32 returnCode)
+{
+  ndbrequire(returnCode == 0);
+
+  DropObjRecordPtr dropObjPtr;  
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
   
-  ndbrequire(false);
+  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)
+    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
+      (signal, dropObjPtr.p);
+  else
+    execute(signal, dropObjPtr.p->m_callback, 0);
 }
 
 void
-Dbdict::dropObj_prepareComplete(Signal* signal, 
-				Uint32 callbackData,
-				Uint32 returnCode){
-  ndbrequire(false);  
+Dbdict::dropObj_prepare_complete_done(Signal* signal, 
+				      Uint32 callbackData,
+				      Uint32 returnCode)
+{
+  ndbrequire(returnCode == 0);
+  
+  DropObjRecordPtr dropObjPtr;  
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  
+  //@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, DropObjReq * req){
+Dbdict::dropObj_commit(Signal * signal, SchemaOp * op){
   jam();
-  ndbrequire(false);  
+  
+  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)
+    (this->*f_dict_op[dropObj->m_vt_index].m_commit_start)(signal, dropObj);
+  else
+    execute(signal, dropObj->m_callback, 0);
 }
 
 void
-Dbdict::dropObj_commitComplete(Signal* signal, 
-				 Uint32 callbackData,
-				 Uint32 returnCode){
+Dbdict::dropObj_commit_start_done(Signal* signal, 
+				  Uint32 callbackData,
+				  Uint32 returnCode)
+{
+  jam();
+  ndbrequire(returnCode == 0);
+
+  DropObjRecordPtr dropObjPtr;  
+  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)
+{
   jam();
-  ndbrequire(false);  
+  ndbrequire(returnCode == 0);
+  
+  DropObjRecordPtr dropObjPtr;  
+  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)
+    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
+      (signal, dropObjPtr.p);
+  else
+    execute(signal, dropObjPtr.p->m_callback, 0);
 }
 
 void
-Dbdict::dropObj_abort(Signal* signal, DropObjReq * req){
+Dbdict::dropObj_commit_complete_done(Signal* signal, 
+				     Uint32 callbackData,
+				     Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;  
+  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){
   jam();
-  ndbrequire(false);  
+  
+  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)
+    (this->*f_dict_op[dropObj->m_vt_index].m_abort_start)(signal, dropObj);
+  else
+    execute(signal, dropObj->m_callback, 0);
 }
 
 void
-Dbdict::dropObj_abortComplete(Signal* signal, 
-			      Uint32 callbackData,
-			      Uint32 returnCode){
+Dbdict::dropObj_abort_start_done(Signal* signal, 
+				 Uint32 callbackData,
+				 Uint32 returnCode)
+{
+  jam();
+  ndbrequire(returnCode == 0);
+
+  DropObjRecordPtr dropObjPtr;  
+  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
+  {
+    execute(signal, callback, 0);
+  }
+}
+
+void
+Dbdict::dropObj_abort_writeSchemaConf(Signal* signal, 
+				      Uint32 callbackData,
+				      Uint32 returnCode)
+{
   jam();
-  ndbrequire(false);  
+  ndbrequire(returnCode == 0);
+  
+  DropObjRecordPtr dropObjPtr;  
+  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)
+    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
+      (signal, dropObjPtr.p);
+  else
+    execute(signal, dropObjPtr.p->m_callback, 0);
 }
 
+void
+Dbdict::dropObj_abort_complete_done(Signal* signal, 
+				    Uint32 callbackData,
+				    Uint32 returnCode)
+{
+  DropObjRecordPtr dropObjPtr;  
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+
+  DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
+  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){
@@ -13949,7 +14574,6 @@
     
     if(status != SimpleProperties::Eof)
     {
-      ndbrequire(false);
       op->m_errorCode = CreateTableRef::InvalidFormat;
       break;
     }
@@ -14013,10 +14637,23 @@
       fg_ptr.p->m_tablespace.m_extent_size = fg.TS_ExtentSize;
       fg_ptr.p->m_tablespace.m_default_logfile_group_id = fg.TS_LogfileGroupId;
 
-      // Todo validate logfile group version
+      Ptr<Filegroup> lg_ptr;
+      if (!c_filegroup_hash.find(lg_ptr, fg.TS_LogfileGroupId))
+      {
+	op->m_errorCode = CreateFilegroupRef::NoSuchLogfileGroup;
+	goto error;
+      }
+
+      if (lg_ptr.p->m_version != fg.TS_LogfileGroupVersion)
+      {
+	op->m_errorCode = CreateFilegroupRef::InvalidFilegroupVersion;
+	goto error;
+      }
+      increase_ref_count(lg_ptr.p->m_obj_ptr_i);
       break;
     case DictTabInfo::LogfileGroup:
       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:
@@ -14025,12 +14662,14 @@
 
     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:
   execute(signal, op->m_callback, 0);
 }
 
@@ -14100,16 +14739,6 @@
 }
 
 void
-Dbdict::create_fg_commit_start(Signal* signal, SchemaOp* op){
-  execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::create_fg_commit_complete(Signal* signal, SchemaOp* op){
-  execute(signal, op->m_callback, 0);
-}
-
-void
 Dbdict::create_fg_abort_start(Signal* signal, SchemaOp* op){
   execute(signal, op->m_callback, 0);
   abort();
@@ -14147,7 +14776,6 @@
     FilegroupPtr fg_ptr;
     if(!c_filegroup_hash.find(fg_ptr, f.FilegroupId)){
       op->m_errorCode = CreateFileRef::NoSuchFilegroup;
-      ndbrequire(false);
       break;
     }
     
@@ -14187,8 +14815,7 @@
     }
     
     FilePtr filePtr;
-    LocalDLList<File> list(c_file_pool, fg_ptr.p->m_files);
-    if (! list.seize(filePtr)){
+    if (! c_file_pool.seize(filePtr)){
       op->m_errorCode = CreateFileRef::OutOfFileRecords;
       c_obj_pool.release(obj_ptr);
       break;
@@ -14199,10 +14826,24 @@
       if(!name.assign(f.FileName, len, hash)){
 	op->m_errorCode = CreateTableRef::TableNameTooLong;
 	c_obj_pool.release(obj_ptr);
-	list.release(filePtr);
+	c_file_pool.release(filePtr);
 	break;
       }
     }
+
+    switch(fg_ptr.p->m_type){
+    case DictTabInfo::Tablespace:
+      increase_ref_count(fg_ptr.p->m_obj_ptr_i);
+      break;
+    case DictTabInfo::LogfileGroup:
+    {
+      LocalDLList<File> list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
+      list.add(filePtr);
+      break;
+    }
+    default:
+      ndbrequire(false);
+    }
     
     /**
      * Init file
@@ -14216,6 +14857,7 @@
     
     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);
 
@@ -14350,11 +14992,6 @@
 }
 
 void
-Dbdict::create_file_commit_complete(Signal* signal, SchemaOp* op){
-  execute(signal, op->m_callback, 0);
-}
-
-void
 Dbdict::create_file_abort_start(Signal* signal, SchemaOp* op)
 {
   CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
@@ -14398,12 +15035,283 @@
   FilegroupPtr fg_ptr;
   ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
   
+  switch(fg_ptr.p->m_type){
+  case DictTabInfo::Tablespace:
+    decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
+    break;
+  case DictTabInfo::LogfileGroup:
+  {
+    LocalDLList<File> 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);
   
-  LocalDLList<File> list(c_file_pool, fg_ptr.p->m_files);
-  list.release(f_ptr);
-
   execute(signal, op->m_callback, 0);
 }
 
 CArray<KeyDescriptor> g_key_descriptor_pool;
+
+void
+Dbdict::drop_file_prepare_start(Signal* signal, SchemaOp* op)
+{
+  send_drop_file(signal, op, DropFileImplReq::Prepare);
+}
+
+void
+Dbdict::drop_undofile_prepare_start(Signal* signal, SchemaOp* op)
+{
+  op->m_errorCode = DropFileRef::DropUndoFileNotSupported;
+  execute(signal, op->m_callback, 0);  
+}
+
+void
+Dbdict::drop_file_commit_start(Signal* signal, SchemaOp* op)
+{
+  send_drop_file(signal, op, DropFileImplReq::Commit);
+}
+
+void
+Dbdict::drop_file_commit_complete(Signal* signal, SchemaOp* op)
+{
+  FilePtr f_ptr;
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+  
+  FilegroupPtr fg_ptr;
+  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);
+  
+  execute(signal, op->m_callback, 0);
+}
+
+void
+Dbdict::drop_file_abort_start(Signal* signal, SchemaOp* op)
+{
+  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;
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+  
+  FilegroupPtr fg_ptr;
+  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:
+    ref = TSMAN_REF;
+    break;
+  case DictTabInfo::Undofile:
+    ref = LGMAN_REF;
+    break;
+  default:
+    ndbrequire(false);
+  }
+  
+  sendSignal(ref, GSN_DROP_FILE_REQ, signal, 
+	     DropFileImplReq::SignalLength, JBB);
+}
+
+void
+Dbdict::execDROP_OBJ_REF(Signal* signal){
+  jamEntry();
+
+  DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
+  
+  Ptr<SchemaTransaction> trans_ptr;
+  ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
+  
+  if(ref->errorCode != DropObjRef::NF_FakeErrorREF){
+    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){
+  jamEntry();
+
+  DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
+  
+  Ptr<SchemaTransaction> trans_ptr;
+  ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
+  schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
+}
+
+void
+Dbdict::execDROP_FILE_REF(Signal* signal){
+  jamEntry();
+
+  DropFileImplRef * ref = (DropFileImplRef*)signal->getDataPtr();
+  
+  DropObjRecordPtr op_ptr;
+  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){  
+  jamEntry();
+
+  DropFileImplConf * rep = 
+    (DropFileImplConf*)signal->getDataPtr();
+  
+  DropObjRecordPtr op_ptr;
+  ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
+  
+  execute(signal, op_ptr.p->m_callback, 0);  
+}
+
+void
+Dbdict::execDROP_FILEGROUP_REF(Signal* signal){
+  jamEntry();
+
+  DropFilegroupImplRef * ref = (DropFilegroupImplRef*)signal->getDataPtr();
+  
+  DropObjRecordPtr op_ptr;
+  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){  
+  jamEntry();
+
+  DropFilegroupImplConf * rep = 
+    (DropFilegroupImplConf*)signal->getDataPtr();
+  
+  DropObjRecordPtr op_ptr;
+  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)
+  {
+    op->m_errorCode = DropFilegroupRef::FilegroupInUse;
+    execute(signal, op->m_callback, 0);  
+  }
+  else
+  {
+    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)
+  {
+    
+    /**
+     * Mark all undofiles as dropped
+     */
+    Ptr<File> filePtr;
+    LocalDLList<File> 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))
+    {
+      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);
+    }
+    list.release();
+  }
+  else if(op->m_obj_type == DictTabInfo::Tablespace)
+  {
+    FilegroupPtr lg_ptr;
+    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);
+  }
+  
+  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);
+  
+  release_object(fg_ptr.p->m_obj_ptr_i);
+  
+  execute(signal, op->m_callback, 0);
+}
+
+void
+Dbdict::drop_fg_abort_start(Signal* signal, SchemaOp* op)
+{
+  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);
+}
+

--- 1.46/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2005-10-12 13:15:56 +02:00
+++ 1.47/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2005-10-18 11:48:40 +02:00
@@ -29,6 +29,7 @@
 #include <CArray.hpp>
 #include <KeyTable.hpp>
 #include <KeyTable2.hpp>
+#include <KeyTable2Ref.hpp>
 #include <SimulatedBlock.hpp>
 #include <SimpleProperties.hpp>
 #include <SignalCounter.hpp>
@@ -57,6 +58,8 @@
 #include <RequestTracker.hpp>
 #include <Rope.hpp>
 #include <signaldata/DictObjOp.hpp>
+#include <signaldata/DropFilegroupImpl.hpp>
+#include <SLList.hpp>
 
 #ifdef DBDICT_C
 // Debug Macros
@@ -344,7 +347,6 @@
     
     /**  frm data for this table */
     RopeHandle frmData;
-    RopeHandle tsNameData;
     RopeHandle tsData;
     RopeHandle ngData;
     RopeHandle rangeData;
@@ -527,7 +529,6 @@
     bool equal(const File& obj) const { return key == obj.key;}
   };
   typedef Ptr<File> FilePtr;
-  typedef LocalDLList<File> FileList;
 
   struct Filegroup {
     Filegroup(){}
@@ -538,7 +539,6 @@
     Uint32 m_type;
     Uint32 m_version;
     RopeHandle m_name;
-    DLList<File>::Head m_files;
 
     union {
       struct {
@@ -548,6 +548,7 @@
       
       struct {
 	Uint32 m_undo_buffer_size;
+	DLList<File>::HeadPOD m_files;
       } m_logfilegroup;
     };
     
@@ -574,13 +575,14 @@
     DictObject() {}
     Uint32 m_id;
     Uint32 m_type;
+    Uint32 m_ref_count;
     RopeHandle m_name;  
-    struct {
-      Uint32 m_name_len;
-      const char * m_name_ptr;
-      RopePool * m_pool;
-    } m_key;
     union {
+      struct {
+	Uint32 m_name_len;
+	const char * m_name_ptr;
+	RopePool * m_pool;
+      } m_key;
       Uint32 nextPool;
       Uint32 nextList;
     };
@@ -616,6 +618,9 @@
   
   void release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p);
 
+  void increase_ref_count(Uint32 obj_ptr_i);
+  void decrease_ref_count(Uint32 obj_ptr_i);
+
 public:
   Dbdict(const class Configuration &);
   virtual ~Dbdict();
@@ -770,6 +775,10 @@
   void execCREATE_FILE_CONF(Signal* signal);
   void execCREATE_FILEGROUP_REF(Signal* signal);
   void execCREATE_FILEGROUP_CONF(Signal* signal);
+  void execDROP_FILE_REF(Signal* signal);
+  void execDROP_FILE_CONF(Signal* signal);
+  void execDROP_FILEGROUP_REF(Signal* signal);
+  void execDROP_FILEGROUP_CONF(Signal* signal);
 
   /*
    *  2.4 COMMON STORED VARIABLES
@@ -1450,7 +1459,7 @@
     // original request plus buffer for attribute lists
     BuildIndxReq m_request;
     AttributeList m_attrList;
-    AttributeList m_tableKeyList;
+    Id_array<MAX_ATTRIBUTES_IN_INDEX+1> m_tableKeyList;
     // coordinator DICT
     Uint32 m_coordinatorRef;
     bool m_isMaster;
@@ -1874,6 +1883,7 @@
     Uint32 m_obj_type;
     Uint32 m_obj_version;
     Uint32 m_obj_ptr_i;
+    Uint32 m_vt_index;
     Callback m_callback;
   };
   typedef Ptr<SchemaOp> SchemaOpPtr;
@@ -1893,8 +1903,8 @@
      * This should contain "lists" with operations
      */
     struct {
-      Uint32 m_key;   // Operation key
-      Uint32 m_gsn;   // Operation type
+      Uint32 m_key;      // Operation key
+      Uint32 m_vt_index; // Operation type
       Uint32 m_obj_id;
       DictObjOp::State m_state;
     } m_op;
@@ -1904,15 +1914,14 @@
   struct OpCreateObj : public SchemaOp {
     Uint32 m_gci;
     Uint32 m_obj_info_ptr_i;
-    Uint32 m_vt_index;
     Uint32 m_restart;
   };
   typedef Ptr<OpCreateObj> CreateObjRecordPtr;
   
-  struct OpCreateFilegroup : public OpCreateObj {
+  struct OpDropObj : public SchemaOp 
+  {
   };
-  
-  typedef Ptr<OpCreateFilegroup> OpCreateFilegroupPtr;
+  typedef Ptr<OpDropObj> DropObjRecordPtr;
   
   /**
    * Only used at coordinator/master
@@ -1932,7 +1941,7 @@
   STATIC_CONST( opCreateTriggerSize = sizeof(OpCreateTrigger) );
   STATIC_CONST( opDropTriggerSize = sizeof(OpDropTrigger) );
   STATIC_CONST( opAlterTriggerSize = sizeof(OpAlterTrigger) );
-  STATIC_CONST( opCreateFilegroupSize = sizeof(OpCreateFilegroup) );
+  STATIC_CONST( opCreateObjSize = sizeof(OpCreateObj) );
 private:
 #define PTR_ALIGN(n) ((((n)+sizeof(void*)-1)>>2)&~((sizeof(void*)-1)>>2))
   union OpRecordUnion {
@@ -1949,7 +1958,7 @@
     Uint32 u_opCreateTrigger[PTR_ALIGN(opCreateTriggerSize)];
     Uint32 u_opDropTrigger  [PTR_ALIGN(opDropTriggerSize)];
     Uint32 u_opAlterTrigger [PTR_ALIGN(opAlterTriggerSize)];
-    Uint32 u_opCreateFG     [PTR_ALIGN(opCreateFilegroupSize)];
+    Uint32 u_opCreateObj    [PTR_ALIGN(opCreateObjSize)];
     Uint32 nextPool;
   };
   ArrayPool<OpRecordUnion> c_opRecordPool;
@@ -1968,9 +1977,11 @@
   KeyTable2<OpCreateTrigger, OpRecordUnion> c_opCreateTrigger;
   KeyTable2<OpDropTrigger, OpRecordUnion> c_opDropTrigger;
   KeyTable2<OpAlterTrigger, OpRecordUnion> c_opAlterTrigger;
-  KeyTable2<OpCreateObj, OpRecordUnion> c_opCreateObj; 
+  KeyTable2<SchemaOp, OpRecordUnion> c_schemaOp; 
   KeyTable2<SchemaTransaction, OpRecordUnion> c_Trans;
-  
+  KeyTable2Ref<OpCreateObj, SchemaOp, OpRecordUnion> c_opCreateObj;
+  KeyTable2Ref<OpDropObj, SchemaOp, OpRecordUnion> c_opDropObj;
+
   // Unique key for operation  XXX move to some system table
   Uint32 c_opRecordSequence;
 
@@ -2300,7 +2311,8 @@
   void alterTrigger_sendSlaveReq(Signal* signal, OpAlterTriggerPtr opPtr);
   void alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr, bool);
   // support
-  void getTableKeyList(TableRecordPtr tablePtr, AttributeList& list);
+  void getTableKeyList(TableRecordPtr, 
+		       Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list);
   void getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id);
   void getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list);
   void getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask);
@@ -2406,12 +2418,10 @@
   void execCREATE_OBJ_REF(Signal* signal);  
   void execCREATE_OBJ_CONF(Signal* signal);
 
-  void createObj_prepare(Signal*, struct CreateObjReq*);
   void createObj_prepare_start_done(Signal* signal, Uint32 callback, Uint32);
   void createObj_writeSchemaConf1(Signal* signal, Uint32 callback, Uint32);
   void createObj_writeObjConf(Signal* signal, Uint32 callbackData, Uint32);
   void createObj_prepare_complete_done(Signal*, Uint32 callbackData, Uint32);
-  void createObj_commit(Signal*, struct CreateObjReq*);
   void createObj_commit_start_done(Signal* signal, Uint32 callback, Uint32);
   void createObj_writeSchemaConf2(Signal* signal, Uint32 callbackData, Uint32);
   void createObj_commit_complete_done(Signal*, Uint32 callbackData, Uint32);
@@ -2420,7 +2430,7 @@
   void createObj_abort_writeSchemaConf(Signal*, Uint32 callbackData, Uint32);
   void createObj_abort_complete_done(Signal*, Uint32 callbackData, Uint32);  
 
-  void createObj_reply(Signal* signal, SchemaTransaction *, Uint32);
+  void schemaOp_reply(Signal* signal, SchemaTransaction *, Uint32);
   void trans_commit_start_done(Signal*, Uint32 callbackData, Uint32);
   void trans_commit_complete_done(Signal*, Uint32 callbackData, Uint32);
   void trans_abort_start_done(Signal*, Uint32 callbackData, Uint32);
@@ -2430,13 +2440,16 @@
   void execDROP_OBJ_REF(Signal* signal);  
   void execDROP_OBJ_CONF(Signal* signal);
 
-  void dropObj_prepare(Signal*, struct DropObjReq*);
-  void dropObj_prepareComplete(Signal*, Uint32 callbackData, Uint32);
-  void dropObj_commit(Signal*, struct DropObjReq*);
-  void dropObj_commitComplete(Signal*, Uint32 callbackData, Uint32);
-  void dropObj_abort(Signal*, struct DropObjReq*);
-  void dropObj_abortComplete(Signal*, Uint32 callbackData, Uint32);
-
+  void dropObj_prepare_start_done(Signal* signal, Uint32 callback, Uint32);
+  void dropObj_prepare_writeSchemaConf(Signal*, Uint32 callback, Uint32);
+  void dropObj_prepare_complete_done(Signal*, Uint32 callbackData, Uint32);
+  void dropObj_commit_start_done(Signal*, Uint32 callbackData, Uint32);
+  void dropObj_commit_writeSchemaConf(Signal*, Uint32 callback, Uint32);
+  void dropObj_commit_complete_done(Signal*, Uint32 callbackData, Uint32);
+  void dropObj_abort_start_done(Signal*, Uint32 callbackData, Uint32);
+  void dropObj_abort_writeSchemaConf(Signal*, Uint32 callback, Uint32);
+  void dropObj_abort_complete_done(Signal*, Uint32 callbackData, Uint32);
+  
   void restartCreateObj(Signal*, Uint32, 
 			const SchemaFile::TableEntry *,
 			const SchemaFile::TableEntry *, bool);
@@ -2448,20 +2461,44 @@
   void restartCreateObj_commit_start_done(Signal*, Uint32, Uint32);
   void restartCreateObj_commit_complete_done(Signal*, Uint32, Uint32);
 
+  void execDICT_COMMIT_REQ(Signal*);
+  void execDICT_COMMIT_REF(Signal*);
+  void execDICT_COMMIT_CONF(Signal*);
+
+  void execDICT_ABORT_REQ(Signal*);
+  void execDICT_ABORT_REF(Signal*);
+  void execDICT_ABORT_CONF(Signal*);
+
 public:
+  void createObj_commit(Signal*, struct SchemaOp*);
+  void createObj_abort(Signal*, struct SchemaOp*);
+
   void create_fg_prepare_start(Signal* signal, SchemaOp*);
   void create_fg_prepare_complete(Signal* signal, SchemaOp*);
-  void create_fg_commit_start(Signal* signal, SchemaOp*);
-  void create_fg_commit_complete(Signal* signal, SchemaOp*);
   void create_fg_abort_start(Signal* signal, SchemaOp*);
   void create_fg_abort_complete(Signal* signal, SchemaOp*);
 
   void create_file_prepare_start(Signal* signal, SchemaOp*);
   void create_file_prepare_complete(Signal* signal, SchemaOp*);
   void create_file_commit_start(Signal* signal, SchemaOp*);
-  void create_file_commit_complete(Signal* signal, SchemaOp*);
   void create_file_abort_start(Signal* signal, SchemaOp*);
   void create_file_abort_complete(Signal* signal, SchemaOp*);
+
+  void dropObj_commit(Signal*, struct SchemaOp*);
+  void dropObj_abort(Signal*, struct SchemaOp*);
+  void drop_file_prepare_start(Signal* signal, SchemaOp*);
+  void drop_file_commit_start(Signal* signal, SchemaOp*);
+  void drop_file_commit_complete(Signal* signal, SchemaOp*);
+  void drop_file_abort_start(Signal* signal, SchemaOp*);
+  void send_drop_file(Signal*, SchemaOp*, DropFileImplReq::RequestInfo);
+
+  void drop_fg_prepare_start(Signal* signal, SchemaOp*);
+  void drop_fg_commit_start(Signal* signal, SchemaOp*);
+  void drop_fg_commit_complete(Signal* signal, SchemaOp*);
+  void drop_fg_abort_start(Signal* signal, SchemaOp*);
+  void send_drop_fg(Signal*, SchemaOp*, DropFilegroupImplReq::RequestInfo);
+
+  void drop_undofile_prepare_start(Signal* signal, SchemaOp*);
 };
 
 inline bool

--- 1.58/storage/ndb/src/ndbapi/NdbDictionary.cpp	2005-10-12 13:15:56 +02:00
+++ 1.59/storage/ndb/src/ndbapi/NdbDictionary.cpp	2005-10-18 11:48:40 +02:00
@@ -460,7 +460,7 @@
 }
 
 Uint32
-NdbDictionary::Table::getFragmentCount()
+NdbDictionary::Table::getFragmentCount() const
 {
   return m_impl.getFragmentCount();
 }

--- 1.111/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2005-10-12 13:26:45 +02:00
+++ 1.112/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2005-10-18 11:48:40 +02:00
@@ -1639,7 +1639,6 @@
   impl->m_externalName.assign(externalName);
 
   impl->m_frm.assign(tableDesc.FrmData, tableDesc.FrmLen);
-  impl->m_ts_name.assign(tableDesc.TsNameData, tableDesc.TsNameLen);
   impl->m_fd.assign(tableDesc.FragmentData, tableDesc.FragmentDataLen);
   impl->m_range.assign(tableDesc.RangeListData, tableDesc.RangeListDataLen);
   impl->m_fragmentCount = tableDesc.FragmentCount;
@@ -1910,7 +1909,7 @@
 				     bool alter)
 {
   unsigned i;
-  char *name_ptr;
+  char *ts_names[MAX_NDB_PARTITIONS];
   DBUG_ENTER("NdbDictInterface::createOrAlterTable");
 
   impl.computeAggregates();
@@ -2056,8 +2055,7 @@
   memcpy(tmpTab.RangeListData, impl.m_range.get_data(),
          impl.m_range.length());
 
-  tmpTab.TsNameLen = impl.m_ts_name.length();
-  memcpy(tmpTab.TsNameData, impl.m_ts_name.get_data(),
+  memcpy(ts_names, impl.m_ts_name.get_data(),
          impl.m_ts_name.length());
 
   tmpTab.FragmentCount= impl.m_fragmentCount;
@@ -2069,30 +2067,36 @@
   tmpTab.PrimaryTableId = impl.m_primaryTableId;
   tmpTab.NoOfAttributes = sz;
 
-#if 0
-  if (tmpTab.TsNameLen)
+  if (impl.m_ts_name.length())
   {
+    char **ts_name_ptr= (char**)ts_names;
     i= 0;
-    name_ptr= tmpTab.TsNameData;
     do
     {
       NdbTablespaceImpl tmp;
-      char *ts_name;
-      uint len= strlen(name_ptr);
-      if(get_filegroup(tmp, NdbDictionary::Object::Tablespace, 
-                       (const char*)ts_name) == 0)
+      if (*ts_name_ptr)
       {
-        tmpTab.TablespaceData[2*i] = tmp.m_id;
-        tmpTab.TablespaceData[2*i + 1] = tmp.m_version;
+        if(get_filegroup(tmp, NdbDictionary::Object::Tablespace, 
+                         (const char*)*ts_name_ptr) == 0)
+        {
+          tmpTab.TablespaceData[2*i] = tmp.m_id;
+          tmpTab.TablespaceData[2*i + 1] = tmp.m_version;
+        }
+        else
+          return -1;
       }
       else
-        return -1;
-      name_ptr+= len + 1;
+      {
+        /*
+          No tablespace used, set tablespace id to NULL
+        */
+        tmpTab.TablespaceData[2*i] = RNIL;
+        tmpTab.TablespaceData[2*i + 1] = 0;
+      }
+      ts_name_ptr++;
     } while (++i < tmpTab.FragmentCount);
     tmpTab.TablespaceDataLen= 4*i;
-    DBUG_ASSERT((uint)(name_ptr - tmpTab.TsNameData) == tmpTab.TsNameLen);
   }
-#endif
 
   tmpTab.FragmentType = getKernelConstant(impl.m_fragmentType,
 					  fragmentTypeMapping,
@@ -3855,7 +3859,7 @@
   req->senderData = 0;
   req->file_id = file.m_id;
   req->file_version = file.m_version;
-  
+
   int err[] = { DropFileRef::Busy, 0};
   DBUG_RETURN(dictSignal(&tSignal, 0, 0,
 	                 0, // master
@@ -3988,8 +3992,8 @@
   DropFilegroupReq* req = CAST_PTR(DropFilegroupReq, tSignal.getDataPtrSend());
   req->senderRef = m_reference;
   req->senderData = 0;
-  req->file_group_id = group.m_id;
-  req->file_group_version = group.m_version;
+  req->filegroup_id = group.m_id;
+  req->filegroup_version = group.m_version;
   
   int err[] = { DropFilegroupRef::Busy, DropFilegroupRef::NotMaster, 0};
   DBUG_RETURN(dictSignal(&tSignal, 0, 0,

--- 1.165/sql/ha_ndbcluster.cc	2005-10-12 13:26:44 +02:00
+++ 1.166/sql/ha_ndbcluster.cc	2005-10-18 11:48:39 +02:00
@@ -53,8 +53,12 @@
 static int ndbcluster_commit(THD *thd, bool all);
 static int ndbcluster_rollback(THD *thd, bool all);
 
-static handlerton ndbcluster_hton = {
+handlerton ndbcluster_hton = {
   "ndbcluster",
+  SHOW_OPTION_YES,
+  "Clustered, fault-tolerant, memory-based tables", 
+  DB_TYPE_NDBCLUSTER,
+  ndbcluster_init,
   0, /* slot */
   0, /* savepoint size */
   ndbcluster_close_connection,
@@ -126,7 +130,7 @@
 static pthread_t ndb_util_thread;
 pthread_mutex_t LOCK_ndb_util_thread;
 pthread_cond_t COND_ndb_util_thread;
-extern "C" pthread_handler_decl(ndb_util_thread_func, arg);
+pthread_handler_t ndb_util_thread_func(void *arg);
 ulong ndb_cache_check_time;
 
 /*
@@ -1273,7 +1277,8 @@
   DBUG_ENTER("ha_ndbcluster::index_flags");
   DBUG_PRINT("info", ("idx_no: %d", idx_no));
   DBUG_ASSERT(get_index_type_from_table(idx_no) < index_flags_size);
-  DBUG_RETURN(index_type_flags[get_index_type_from_table(idx_no)]);
+  DBUG_RETURN(index_type_flags[get_index_type_from_table(idx_no)] | 
+              HA_KEY_SCAN_NOT_ROR);
 }
 
 static void shrink_varchar(Field* field, const byte* & ptr, char* buf)
@@ -3424,7 +3429,7 @@
   startTransaction for each transaction/statement.
 */
 
-int ha_ndbcluster::start_stmt(THD *thd)
+int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
 {
   int error=0;
   DBUG_ENTER("start_stmt");
@@ -4861,11 +4866,14 @@
   return 0;
 }
 
-handlerton *
-ndbcluster_init()
+bool ndbcluster_init()
 {
   int res;
   DBUG_ENTER("ndbcluster_init");
+
+  if (have_ndbcluster != SHOW_OPTION_YES)
+    goto ndbcluster_init_error;
+
   // Set connectstring if specified
   if (opt_ndbcluster_connectstring != 0)
     DBUG_PRINT("connectstring", ("%s", opt_ndbcluster_connectstring));     
@@ -4946,16 +4954,17 @@
   }
   
   ndbcluster_inited= 1;
-  DBUG_RETURN(&ndbcluster_hton);
+  DBUG_RETURN(FALSE);
 
- ndbcluster_init_error:
+ndbcluster_init_error:
   if (g_ndb)
     delete g_ndb;
   g_ndb= NULL;
   if (g_ndb_cluster_connection)
     delete g_ndb_cluster_connection;
   g_ndb_cluster_connection= NULL;
-  DBUG_RETURN(NULL);
+  have_ndbcluster= SHOW_OPTION_DISABLED;	// If we couldn't use handler
+  DBUG_RETURN(TRUE);
 }
 
 
@@ -6059,8 +6068,7 @@
 
 
 // Utility thread main loop
-extern "C" pthread_handler_decl(ndb_util_thread_func,
-                                arg __attribute__((unused)))
+pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
 {
   THD *thd; /* needs to be first for thread_stack */
   Ndb* ndb;
@@ -7795,141 +7803,213 @@
   }
   ndb= get_ndb();
   dict= ndb->getDictionary();
-  switch (info->ts_cmd_type)
+  switch (info->ts_cmd_type){
+  case (CREATE_TABLESPACE):
+  {
+    NdbDictionary::Tablespace ndb_ts;
+    NdbDictionary::Datafile ndb_df;
+    if (set_up_tablespace(info, &ndb_ts))
+    {
+      DBUG_RETURN(1);
+    }
+    if (set_up_datafile(info, &ndb_df))
+    {
+      DBUG_RETURN(1);
+    }
+    if (error= dict->createTablespace(ndb_ts))
+    {
+      DBUG_PRINT("error", ("createTablespace returned %d", error));
+      my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "TABLESPACE");
+      DBUG_RETURN(1);
+    }
+    DBUG_PRINT("info", ("Successfully created Tablespace"));
+    if (error= dict->createDatafile(ndb_df))
+    {
+      DBUG_PRINT("error", ("createDatafile returned %d", error));
+      my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "DATAFILE");
+      DBUG_RETURN(1);
+    }
+    break;
+  }
+  case (ALTER_TABLESPACE):
   {
-    case (CREATE_TABLESPACE):
+    if (info->ts_alter_tablespace_type == ALTER_TABLESPACE_ADD_FILE)
     {
-      NdbDictionary::Tablespace ndb_ts;
       NdbDictionary::Datafile ndb_df;
-      if (set_up_tablespace(info, &ndb_ts))
-      {
-        DBUG_RETURN(1);
-      }
       if (set_up_datafile(info, &ndb_df))
       {
-        DBUG_RETURN(1);
+	DBUG_RETURN(1);
       }
-      if ((error= dict->createTablespace(ndb_ts)))
+      if ((error= dict->createDatafile(ndb_df)))
       {
-        DBUG_PRINT("error", ("createTablespace returned %d", error));
-        my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "TABLESPACE");
-        DBUG_RETURN(1);
+	DBUG_PRINT("error", ("createDatafile returned %d", error));
+	my_error(ER_ALTER_TABLESPACE_FAILED, MYF(0), "CREATE DATAFILE");
+	DBUG_RETURN(1);
+      }
+    }
+    else if(info->ts_alter_tablespace_type == ALTER_TABLESPACE_DROP_FILE)
+    {
+      NdbDictionary::Datafile df = dict->getDatafile(0, 
+						     info->data_file_name);
+      if (strcmp(df.getPath(), info->data_file_name) == 0)
+      {
+	if (error= dict->dropDatafile(df))
+	{
+	  DBUG_PRINT("error", ("createDatafile returned %d", error));
+	  my_error(ER_ALTER_TABLESPACE_FAILED, MYF(0), " DROP DATAFILE");
+	  DBUG_RETURN(1);
+	}
       }
-      DBUG_PRINT("info", ("Successfully created Tablespace"));
-      if ((error= dict->createDatafile(ndb_df)))
+      else
       {
-        DBUG_PRINT("error", ("createDatafile returned %d", error));
-        my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "DATAFILE");
-        DBUG_RETURN(1);
+	DBUG_PRINT("error", ("No such datafile"));
+	my_error(ER_ALTER_TABLESPACE_FAILED, MYF(0), " NO SUCH FILE");
+	DBUG_RETURN(1);
       }
-      break;
     }
-    case (ALTER_TABLESPACE):
+    else
     {
-      NdbDictionary::Datafile ndb_df;
-      if (set_up_datafile(info, &ndb_df))
-      {
-        DBUG_RETURN(1);
-      }
-      if ((error= dict->createDatafile(ndb_df)))
-      {
-        DBUG_PRINT("error", ("createDatafile returned %d", error));
-        my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "DATAFILE");
-        DBUG_RETURN(1);
-      }
-      break;
+      DBUG_PRINT("error", ("Unsupported alter tablespace: %d", 
+			   info->ts_alter_tablespace_type));
+      DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
     }
-    case (CREATE_LOGFILE_GROUP):
+    break;
+  }
+  case (CREATE_LOGFILE_GROUP):
+  {
+    NdbDictionary::LogfileGroup ndb_lg;
+    NdbDictionary::Undofile ndb_uf;
+    if (info->undo_file_name == NULL)
     {
-      NdbDictionary::LogfileGroup ndb_lg;
-      NdbDictionary::Undofile ndb_uf;
-      if (info->undo_file_name == NULL)
-      {
-        /*
-          REDO files in LOGFILE GROUP not supported yet
-        */
-        DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
-      }
-      if (set_up_logfile_group(info, &ndb_lg))
-      {
-        DBUG_RETURN(1);
-      }
-      if ((error= dict->createLogfileGroup(ndb_lg)))
-      {
-        DBUG_PRINT("error", ("createLogfileGroup returned %d", error));
-        my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "LOGFILE GROUP");
-        DBUG_RETURN(1);
-      }
-      DBUG_PRINT("info", ("Successfully created Logfile Group"));
-      if (set_up_undofile(info, &ndb_uf))
-      {
-        DBUG_RETURN(1);
-      }
-      if ((error= dict->createUndofile(ndb_uf)))
-      {
-        DBUG_PRINT("error", ("createUndofile returned %d", error));
-        my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "UNDOFILE");
-        DBUG_RETURN(1);
-      }
-      break;
+      /*
+	REDO files in LOGFILE GROUP not supported yet
+      */
+      DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
     }
-    case (ALTER_LOGFILE_GROUP):
+    if (set_up_logfile_group(info, &ndb_lg))
     {
-      NdbDictionary::Undofile ndb_uf;
-      if (info->undo_file_name == NULL)
-      {
-        /*
-          REDO files in LOGFILE GROUP not supported yet
-        */
-        DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
-      }
-      if (set_up_undofile(info, &ndb_uf))
-      {
-        DBUG_RETURN(1);
-      }
-      if ((error= dict->createUndofile(ndb_uf)))
-      {
-        DBUG_PRINT("error", ("createUndofile returned %d", error));
-        my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "UNDOFILE");
-        DBUG_RETURN(1);
-      }
-      break;
+      DBUG_RETURN(1);
     }
-    case (DROP_TABLESPACE):
+    if (error= dict->createLogfileGroup(ndb_lg))
     {
-      if ((error= dict->dropTablespace(
-            dict->getTablespace(info->tablespace_name))))
-      {
-        DBUG_PRINT("error", ("dropTablespace returned %d", error));
-        my_error(ER_DROP_TABLESPACE_FAILED, MYF(0), "TABLESPACE");
-        DBUG_RETURN(1);
-      }
-      break;
+      DBUG_PRINT("error", ("createLogfileGroup returned %d", error));
+      my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "LOGFILE GROUP");
+      DBUG_RETURN(1);
     }
-    case (DROP_LOGFILE_GROUP):
+    DBUG_PRINT("info", ("Successfully created Logfile Group"));
+    if (set_up_undofile(info, &ndb_uf))
     {
-      if ((error= dict->dropLogfileGroup(
-            dict->getLogfileGroup(info->tablespace_name))))
-      {
-        DBUG_PRINT("error", ("dropLogfileGroup returned %d", error));
-        my_error(ER_DROP_TABLESPACE_FAILED, MYF(0), "LOGFILE GROUP");
-        DBUG_RETURN(1);
-      }
-      break;
+      DBUG_RETURN(1);
     }
-    case (CHANGE_FILE_TABLESPACE):
+    if (error= dict->createUndofile(ndb_uf))
     {
-      DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+      DBUG_PRINT("error", ("createUndofile returned %d", error));
+      my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "UNDOFILE");
+      DBUG_RETURN(1);
     }
-    case (ALTER_ACCESS_MODE_TABLESPACE):
+    break;
+  }
+  case (ALTER_LOGFILE_GROUP):
+  {
+    if (info->undo_file_name == NULL)
     {
+      /*
+	REDO files in LOGFILE GROUP not supported yet
+      */
       DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
     }
-    default:
+    NdbDictionary::Undofile ndb_uf;
+    if (set_up_undofile(info, &ndb_uf))
     {
-      DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+      DBUG_RETURN(1);
+    }
+    if (error= dict->createUndofile(ndb_uf))
+    {
+      DBUG_PRINT("error", ("createUndofile returned %d", error));
+      my_error(ER_ALTER_TABLESPACE_FAILED, MYF(0), "CREATE UNDOFILE");
+      DBUG_RETURN(1);
+    }
+    break;
+  }
+  case (DROP_TABLESPACE):
+  {
+    if (error= dict->dropTablespace(
+				    dict->getTablespace(info->tablespace_name)))
+    {
+      DBUG_PRINT("error", ("dropTablespace returned %d", error));
+      my_error(ER_DROP_TABLESPACE_FAILED, MYF(0), "TABLESPACE");
+      DBUG_RETURN(1);
+    }
+    break;
+  }
+  case (DROP_LOGFILE_GROUP):
+  {
+    if (error= dict->dropLogfileGroup(dict->getLogfileGroup(info->logfile_group_name)))
+    {
+      DBUG_PRINT("error", ("dropLogfileGroup returned %d", error));
+      my_error(ER_DROP_TABLESPACE_FAILED, MYF(0), "LOGFILE GROUP");
+      DBUG_RETURN(1);
+    }
+    break;
+  }
+  case (CHANGE_FILE_TABLESPACE):
+  {
+    DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+  }
+  case (ALTER_ACCESS_MODE_TABLESPACE):
+  {
+    DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+  }
+  default:
+  {
+    DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+  }
+  }
+  DBUG_RETURN(FALSE);
+}
+
+int
+ndbcluster_show_status(THD* thd)
+{
+  Protocol *protocol= thd->protocol;
+  
+  DBUG_ENTER("ndbcluster_show_status");
+  
+  if (have_ndbcluster != SHOW_OPTION_YES) 
+  {
+    my_message(ER_NOT_SUPPORTED_YET,
+	       "Cannot call SHOW NDBCLUSTER STATUS because skip-ndbcluster is defined",
+	       MYF(0));
+    DBUG_RETURN(TRUE);
+  }
+  
+  List<Item> field_list;
+  field_list.push_back(new Item_empty_string("free_list", 255));
+  field_list.push_back(new Item_return_int("created", 10,MYSQL_TYPE_LONG));
+  field_list.push_back(new Item_return_int("free", 10,MYSQL_TYPE_LONG));
+  field_list.push_back(new Item_return_int("sizeof", 10,MYSQL_TYPE_LONG));
+
+  if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+    DBUG_RETURN(TRUE);
+  
+  if (get_thd_ndb(thd) && get_thd_ndb(thd)->ndb)
+  {
+    Ndb* ndb= (get_thd_ndb(thd))->ndb;
+    Ndb::Free_list_usage tmp; tmp.m_name= 0;
+    while (ndb->get_free_list_usage(&tmp))
+    {
+      protocol->prepare_for_resend();
+      
+      protocol->store(tmp.m_name, &my_charset_bin);
+      protocol->store((uint)tmp.m_created);
+      protocol->store((uint)tmp.m_free);
+      protocol->store((uint)tmp.m_sizeof);
+      if (protocol->write())
+	DBUG_RETURN(TRUE);
     }
   }
+  send_eof(thd);
+  
   DBUG_RETURN(FALSE);
 }
 
@@ -8096,8 +8176,8 @@
                                           void *tab_par)
 {
   ushort frag_data[MAX_PARTITIONS];
+  char *ts_names[MAX_PARTITIONS];
   ulong ts_index= 0, fd_index= 0, i, j;
-  char *ts_names;
   NDBTAB *tab= (NDBTAB*)tab_par;
   NDBTAB::FragmentType ftype= NDBTAB::UserDefined;
   partition_element *part_elem;
@@ -8151,13 +8231,8 @@
       ng= part_elem->nodegroup_id;
       if (first && ng == UNDEF_NODEGROUP)
         ng= 0;
+      ts_names[fd_index]= part_elem->tablespace_name;
       frag_data[fd_index++]= ng;
-#if 0
-      if (part_elem->tablespace_name)
-        tot_ts_name_len+= strlen(part_elem->tablespace_name) + 1;
-      else
-        tot_ts_name_len+= strlen(default_ts) + 1;
-#endif
     }
     else
     {
@@ -8169,50 +8244,13 @@
         ng= part_elem->nodegroup_id;
         if (first && ng == UNDEF_NODEGROUP)
           ng= 0;
+        ts_names[fd_index]= part_elem->tablespace_name;
         frag_data[fd_index++]= ng;
-#if 0
-        if (part_elem->tablespace_name)
-          tot_ts_name_len+= strlen(part_elem->tablespace_name) + 1;
-        else
-          tot_ts_name_len+= strlen(default_ts) + 1;
-#endif
       } while (++j < part_info->no_subparts);
     }
     first= FALSE;
   } while (++i < part_info->no_parts);
-#if 0
-  if (!(ts_names= sql_alloc(tot_ts_name_len)))
-  {
-    mem_alloc_error();
-    DBUG_RETURN(1);
-  }
-  name_ptr= ts_names;
-  i= 0;
-  part_it.rewind();
-  do
-  {
-    part_elem= part_it++;
-    if (!is_sub_partitioned(part_info))
-      if (part_elem->tablespace_name)
-        name_ptr= (strmov(name_ptr, part_elem->tablespace_name)) + 1;
-      else
-        name_ptr= (strmov(name_ptr, default_ts)) + 1;
-    else
-    {
-      List_iterator<partition_element> sub_it(part_elem->subpartitions);
-      j= 0;
-      do
-      {
-        part_elem= sub_it++;
-        if (part_elem->tablespace_name)
-          name_ptr= (strmov(name_ptr, part_elem->tablespace_name)) + 1;
-        else
-          name_ptr= (strmov(name_ptr, default_ts)) + 1;
-      } while (++j < part_info->no_subparts);
-    }
-  } while (++i < part_info->no_parts);
-  tab->setTablespaceNames(ts_names, tot_ts_name_len);
-#endif
+  tab->setTablespaceNames(ts_names, fd_index*sizeof(char*));
   tab->setFragmentCount(fd_index);
   tab->setFragmentData(&frag_data, fd_index*2);
   {
@@ -8404,7 +8442,7 @@
 {
   Ndb *ndb;
   NDBDICT *dict;
-  NDBTAB *tab;
+  const NDBTAB *tab;
   int err;
   DBUG_ENTER("ha_ndbcluster::get_no_parts");
 

--- 1.86/sql/ha_ndbcluster.h	2005-10-12 13:26:44 +02:00
+++ 1.87/sql/ha_ndbcluster.h	2005-10-18 11:48:39 +02:00
@@ -520,7 +520,7 @@
   int extra(enum ha_extra_function operation);
   int extra_opt(enum ha_extra_function operation, ulong cache_size);
   int external_lock(THD *thd, int lock_type);
-  int start_stmt(THD *thd);
+  int start_stmt(THD *thd, thr_lock_type lock_type);
   const char * table_type() const;
   const char ** bas_ext() const;
   ulong table_flags(void) const;
@@ -789,7 +789,7 @@
 
 extern struct show_var_st ndb_status_variables[];
 
-handlerton *ndbcluster_init(void);
+bool ndbcluster_init(void);
 bool ndbcluster_end(void);
 
 int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
@@ -801,3 +801,5 @@
 int ndbcluster_drop_database(const char* path);
 
 void ndbcluster_print_error(int error, const NdbOperation *error_op);
+
+int ndbcluster_show_status(THD*);
Thread
bk commit into 5.1 tree (mskold:1.2040)Martin Skold18 Oct