List:Commits« Previous MessageNext Message »
From:jonas Date:May 31 2008 6:36am
Subject:bk commit into 5.1 tree (jonas:1.2624)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of jonas.  When jonas 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, 2008-05-31 08:36:34+02:00, jonas@stripped +16 -0
  ndb -
    separate table from fragment creation in create table
    (to cater for future adding of fragments)
  
    applied from reorg-tree, but bug fixed using new test-prg
  
    (note, this is a 100% local change, i.e no distributed signals)

  storage/ndb/include/kernel/signaldata/CreateTab.hpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +26 -4
    let CREATE_TAB_REQ be sent to LQH

  storage/ndb/include/kernel/signaldata/LqhFrag.hpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +20 -24
    remove table stuff from LQHFRAG, which now is frag

  storage/ndb/include/kernel/signaldata/TupFrag.hpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +4 -15
    remove table stuff from tup-frag

  storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +5 -10
    adjust printer

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +211 -186
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +3 -2
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +17 -25
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +5 -1
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +489 -468
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +15 -7
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +2 -0
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +350 -446
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +1 -0
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +1 -0
    separate table from fragment creation in create table

  storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +197 -141
    separate table from fragment creation in create table

  storage/ndb/test/ndbapi/testDict.cpp@stripped, 2008-05-31 08:36:31+02:00, jonas@stripped +2 -2
    separate table from fragment creation in create table

diff -Nrup a/storage/ndb/include/kernel/signaldata/CreateTab.hpp b/storage/ndb/include/kernel/signaldata/CreateTab.hpp
--- a/storage/ndb/include/kernel/signaldata/CreateTab.hpp	2007-12-25 17:14:01 +01:00
+++ b/storage/ndb/include/kernel/signaldata/CreateTab.hpp	2008-05-31 08:36:31 +02:00
@@ -18,28 +18,50 @@
 
 #include "SignalData.hpp"
 
-struct CreateTabReq {
+struct CreateTabReq
+{
   STATIC_CONST( SignalLength = 6 );
-  
+  STATIC_CONST( SignalLengthLDM = 6 + 10 );
+
   enum RequestType {
   };
 
   Uint32 senderRef;
   Uint32 senderData;
-  Uint32 requestType;
   Uint32 tableId;
   Uint32 tableVersion;
+  Uint32 requestType;
   Uint32 gci;
 
+  /**
+   * Used when sending to LQH++
+   */
+  Uint32 noOfCharsets;
+  Uint32 tableType;           // DictTabInfo::TableType
+  Uint32 primaryTableId;      // table of index or RNIL
+  Uint32 tablespace_id;       // RNIL for MM table
+  Uint32 forceVarPartFlag;
+  Uint32 noOfAttributes;
+  Uint32 noOfNullAttributes;
+  Uint32 noOfKeyAttr;
+  Uint32 checksumIndicator;
+  Uint32 GCPIndicator;
+
   SECTION( DICT_TAB_INFO = 0 );
   SECTION( FRAGMENTATION = 1 );
 };
 
 struct CreateTabConf {
-  STATIC_CONST( SignalLength = 2 );
+  STATIC_CONST( SignalLength = 3 );
 
   Uint32 senderRef;
   Uint32 senderData;
+
+  union {
+    Uint32 lqhConnectPtr;
+    Uint32 tuxConnectPtr;
+    Uint32 tupConnectPtr;
+  };
 };
 
 struct CreateTabRef {
diff -Nrup a/storage/ndb/include/kernel/signaldata/LqhFrag.hpp b/storage/ndb/include/kernel/signaldata/LqhFrag.hpp
--- a/storage/ndb/include/kernel/signaldata/LqhFrag.hpp	2007-04-26 08:34:35 +02:00
+++ b/storage/ndb/include/kernel/signaldata/LqhFrag.hpp	2008-05-31 08:36:31 +02:00
@@ -105,7 +105,7 @@ class LqhFragReq {
   friend bool printLQH_FRAG_REQ(FILE *, const Uint32 *, Uint32, Uint16);
 
 public:
-  STATIC_CONST( SignalLength = 25 );
+  STATIC_CONST( SignalLength = 21 );
   
   enum RequestInfo {
     CreateInRunning = 0x8000000,
@@ -115,35 +115,31 @@ public:
 private:
   Uint32 senderData;
   Uint32 senderRef;
-  Uint32 fragmentId;
+  Uint32 tableId;
+  Uint32 tableVersion;
+
+  Uint32 nextLCP;
+  Uint32 startGci;
+  union {
+    Uint32 fragmentId;
+    Uint32 fragId;
+  };
   Uint32 requestInfo; 
+
+  Uint32 localKeyLength;
+  Uint32 lh3DistrBits;
+  Uint32 lh3PageBits;
+  Uint32 keyLength;
   Uint32 maxLoadFactor;
   Uint32 minLoadFactor;
   Uint32 kValue;
-  Uint32 schemaVersion;
-  Uint32 nextLCP;
-  Uint32 noOfCharsets;
-  Uint32 startGci;
-  Uint32 tableType;             // DictTabInfo::TableType
-  Uint32 primaryTableId;        // table of index or RNIL
-  Uint32 tablespace_id;       // RNIL for MM table
-  Uint16 tableId;
-  Uint16 localKeyLength;
-  Uint16 lh3DistrBits;
-  Uint16 lh3PageBits;
-  Uint16 noOfAttributes;
-  Uint16 noOfNullAttributes;
-  Uint16 noOfPagesToPreAllocate;
-  Uint16 keyLength;
-  Uint16 noOfKeyAttr;
-  Uint8 checksumIndicator;
-  Uint8 GCPIndicator;
+
   Uint32 logPartId;
+  Uint32 tablespace_id;       // RNIL for MM table
   Uint32 maxRowsLow;
   Uint32 maxRowsHigh;
   Uint32 minRowsLow;
   Uint32 minRowsHigh;
-  Uint32 forceVarPartFlag;
 };
 
 class LqhFragConf {
@@ -159,11 +155,12 @@ class LqhFragConf {
 
   friend bool printLQH_FRAG_CONF(FILE *, const Uint32 *, Uint32, Uint16);
 public:
-  STATIC_CONST( SignalLength = 2 );
+  STATIC_CONST( SignalLength = 3 );
 
 private:
   Uint32 senderData;
   Uint32 lqhFragPtr;
+  Uint32 fragId;
 };
 
 class LqhFragRef {
@@ -248,12 +245,11 @@ class LqhAddAttrConf {
 
   friend bool printLQH_ADD_ATTR_CONF(FILE *, const Uint32 *, Uint32, Uint16);
 public:
-  STATIC_CONST( SignalLength = 3 );
+  STATIC_CONST( SignalLength = 2 );
 
 private:
   Uint32 senderData;
   Uint32 senderAttrPtr;
-  Uint32 fragId;
 };
 
 #endif
diff -Nrup a/storage/ndb/include/kernel/signaldata/TupFrag.hpp b/storage/ndb/include/kernel/signaldata/TupFrag.hpp
--- a/storage/ndb/include/kernel/signaldata/TupFrag.hpp	2007-04-26 08:34:35 +02:00
+++ b/storage/ndb/include/kernel/signaldata/TupFrag.hpp	2008-05-31 08:36:31 +02:00
@@ -29,26 +29,18 @@ class TupFragReq {
   friend class Dblqh;
   friend class Dbtup;
 public:
-  STATIC_CONST( SignalLength = 18 );
+  STATIC_CONST( SignalLength = 10 );
 private:
   Uint32 userPtr;
   Uint32 userRef;
   Uint32 reqInfo;
   Uint32 tableId;
-  Uint32 noOfAttr;
   Uint32 fragId;
   Uint32 maxRowsLow;
   Uint32 maxRowsHigh;
   Uint32 minRowsLow;
   Uint32 minRowsHigh;
-  Uint32 noOfNullAttr;
-  Uint32 schemaVersion;
-  Uint32 noOfKeyAttr;
-  Uint32 noOfCharsets;
-  Uint32 checksumIndicator;
-  Uint32 globalCheckpointIdIndicator;
   Uint32 tablespaceid;
-  Uint32 forceVarPartFlag;
 };
 
 class TupFragConf {
@@ -79,20 +71,17 @@ class TuxFragReq {
   friend class Dblqh;
   friend class Dbtux;
 public:
-  STATIC_CONST( SignalLength = 14 );
+  STATIC_CONST( SignalLength = 9 );
 private:
   Uint32 userPtr;
   Uint32 userRef;
   Uint32 reqInfo;
   Uint32 tableId;
-  Uint32 noOfAttr;
   Uint32 fragId;
-  Uint32 fragOff;
-  Uint32 tableType;
   Uint32 primaryTableId;
   Uint32 tupIndexFragPtrI;
-  Uint32 tupTableFragPtrI[2];
-  Uint32 accTableFragPtrI[2];
+  Uint32 tupTableFragPtrI;
+  Uint32 accTableFragPtrI;
 };
 
 class TuxFragConf {
diff -Nrup a/storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp b/storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp
--- a/storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp	2006-12-23 20:20:10 +01:00
+++ b/storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp	2008-05-31 08:36:31 +02:00
@@ -22,24 +22,19 @@ printLQH_FRAG_REQ(FILE * output, const U
   
   fprintf(output, " senderData: %d senderRef: %x",
 	  sig->senderData, sig->senderRef);
-  fprintf(output, " tableId: %d fragmentId: %d tableType: %d",
-	  sig->tableId, sig->fragmentId, sig->tableType);
-  if (sig->primaryTableId == RNIL)
-    fprintf(output, " primaryTableId: RNIL\n");
-  else
-    fprintf(output, " primaryTableId: %d\n", sig->primaryTableId);
+  fprintf(output, " tableId: %d fragmentId: %d", sig->tableId, sig->fragmentId);
   fprintf(output, " localKeyLength: %d maxLoadFactor: %d minLoadFactor: %d\n",
 	  sig->localKeyLength, sig->maxLoadFactor, sig->minLoadFactor);
   fprintf(output, " kValue: %d lh3DistrBits: %d lh3PageBits: %d\n",
 	  sig->kValue, sig->lh3DistrBits, sig->lh3PageBits);
   
-  fprintf(output, " noOfAttributes: %d noOfNullAttributes: %d keyLength: %d\n",
-	  sig->noOfAttributes, sig->noOfNullAttributes, sig->keyLength);
+  fprintf(output, " keyLength: %d\n",
+	  sig->keyLength);
 
   fprintf(output, " maxRowsLow/High: %u/%u  minRowsLow/High: %u/%u\n",
 	  sig->maxRowsLow, sig->maxRowsHigh, sig->minRowsLow, sig->minRowsHigh);
-  fprintf(output, " schemaVersion: %d nextLCP: %d\n",
-	  sig->schemaVersion, sig->nextLCP);
+  fprintf(output, " nextLCP: %d\n",
+	  sig->nextLCP);
   
   return true;
 }
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-05-30 15:14:49 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-05-31 08:36:31 +02:00
@@ -5019,29 +5019,225 @@ Dbdict::createTab_writeTableConf(Signal*
   Callback callback;
   callback.m_callbackData = op_ptr.p->op_key;
   callback.m_callbackFunction =
-    safe_cast(&Dbdict::createTab_dihComplete);
+    safe_cast(&Dbdict::createTab_localComplete);
 
-  createTab_dih(signal, op_ptr, fragSec, &callback);
+  createTab_local(signal, op_ptr, fragSec, &callback);
 }
 
 void
-Dbdict::createTab_dih(Signal* signal,
-		      SchemaOpPtr op_ptr,
-		      OpSection fragSec,
-		      Callback * c)
+Dbdict::createTab_local(Signal* signal,
+                        SchemaOpPtr op_ptr,
+                        OpSection fragSec,
+                        Callback * c)
 {
   jam();
   CreateTableRecPtr createTabPtr;
   getOpRec(op_ptr, createTabPtr);
   SchemaTransPtr trans_ptr = op_ptr.p->m_trans_ptr;
 
-  D("createTab_dih" << *op_ptr.p);
-
   createTabPtr.p->m_callback = * c;
 
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
 
+  /**
+   * Start by createing table in LQH
+   */
+  CreateTabReq* req = (CreateTabReq*)signal->getDataPtrSend();
+  req->senderRef = reference();
+  req->senderData = op_ptr.p->op_key;
+  req->tableId = createTabPtr.p->m_request.tableId;
+  req->tableVersion = tabPtr.p->tableVersion;
+  req->requestType = 0;
+  req->gci = 0;
+  req->noOfCharsets = tabPtr.p->noOfCharsets;
+  req->tableType = tabPtr.p->tableType;
+  req->primaryTableId = tabPtr.p->primaryTableId;
+  req->forceVarPartFlag = !!(tabPtr.p->m_bits& TableRecord::TR_ForceVarPart);
+  req->noOfNullAttributes = tabPtr.p->noOfNullBits;
+  req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
+  req->checksumIndicator = 1;
+  req->GCPIndicator = 1;
+  req->noOfAttributes = tabPtr.p->noOfAttributes;
+  sendSignal(DBLQH_REF, GSN_CREATE_TAB_REQ, signal,
+             CreateTabReq::SignalLengthLDM, JBB);
+
+
+  /**
+   * Create KeyDescriptor
+   */
+  {
+    KeyDescriptor* desc= g_key_descriptor_pool.getPtr(tabPtr.i);
+    new (desc) KeyDescriptor();
+
+    Uint32 key = 0;
+    Ptr<AttributeRecord> attrPtr;
+    LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
+                                          tabPtr.p->m_attributes);
+    for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr))
+    {
+      AttributeRecord* aRec = attrPtr.p;
+      if (aRec->tupleKey)
+      {
+        Uint32 attr = aRec->attributeDescriptor;
+
+        desc->noOfKeyAttr ++;
+        desc->keyAttr[key].attributeDescriptor = attr;
+        Uint32 csNumber = (aRec->extPrecision >> 16);
+        if (csNumber)
+        {
+          desc->keyAttr[key].charsetInfo = all_charsets[csNumber];
+          ndbrequire(all_charsets[csNumber] != 0);
+          desc->hasCharAttr = 1;
+        }
+        else
+        {
+          desc->keyAttr[key].charsetInfo = 0;
+        }
+        if (AttributeDescriptor::getDKey(attr))
+        {
+          desc->noOfDistrKeys ++;
+        }
+        if (AttributeDescriptor::getArrayType(attr) != NDB_ARRAYTYPE_FIXED)
+        {
+          desc->noOfVarKeys ++;
+        }
+        key++;
+      }
+    }
+    ndbrequire(key == tabPtr.p->noOfPrimkey);
+  }
+}
+
+void
+Dbdict::execCREATE_TAB_REF(Signal* signal)
+{
+  // no longer received
+  ndbrequire(false);
+}
+
+void
+Dbdict::execCREATE_TAB_CONF(Signal* signal)
+{
+  jamEntry();
+
+  CreateTabConf* conf = (CreateTabConf*)signal->getDataPtr();
+
+  SchemaOpPtr op_ptr;
+  CreateTableRecPtr createTabPtr;
+  findSchemaOp(op_ptr, createTabPtr, conf->senderData);
+  ndbrequire(!op_ptr.isNull());
+
+  createTabPtr.p->m_lqhFragPtr = conf->lqhConnectPtr;
+
+  TableRecordPtr tabPtr;
+  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
+  sendLQHADDATTRREQ(signal, op_ptr, tabPtr.p->m_attributes.firstItem);
+}
+
+
+void
+Dbdict::sendLQHADDATTRREQ(Signal* signal,
+			  SchemaOpPtr op_ptr,
+			  Uint32 attributePtrI)
+{
+  jam();
+  CreateTableRecPtr createTabPtr;
+  getOpRec(op_ptr, createTabPtr);
+
+  TableRecordPtr tabPtr;
+  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
+  LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend();
+  Uint32 i = 0;
+  for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){
+    jam();
+    AttributeRecordPtr attrPtr;
+    c_attributeRecordPool.getPtr(attrPtr, attributePtrI);
+    LqhAddAttrReq::Entry& entry = req->attributes[i];
+    entry.attrId = attrPtr.p->attributeId;
+    entry.attrDescriptor = attrPtr.p->attributeDescriptor;
+    entry.extTypeInfo = 0;
+    // charset number passed to TUP, TUX in upper half
+    entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
+    if (tabPtr.p->isIndex()) {
+      Uint32 primaryAttrId;
+      if (attrPtr.p->nextList != RNIL) {
+        getIndexAttr(tabPtr, attributePtrI, &primaryAttrId);
+      } else {
+        primaryAttrId = ZNIL;
+        if (tabPtr.p->isOrderedIndex())
+          entry.attrId = 0;     // attribute goes to TUP
+      }
+      entry.attrId |= (primaryAttrId << 16);
+    }
+    attributePtrI = attrPtr.p->nextList;
+  }
+  req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr;
+  req->senderData = op_ptr.p->op_key;
+  req->senderAttrPtr = attributePtrI;
+  req->noOfAttributes = i;
+
+  sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
+	     LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
+}
+
+void
+Dbdict::execLQHADDATTCONF(Signal * signal)
+{
+  jamEntry();
+  LqhAddAttrConf * const conf = (LqhAddAttrConf*)signal->getDataPtr();
+
+  SchemaOpPtr op_ptr;
+  CreateTableRecPtr createTabPtr;
+  findSchemaOp(op_ptr, createTabPtr, conf->senderData);
+  ndbrequire(!op_ptr.isNull());
+
+  const Uint32 nextAttrPtr = conf->senderAttrPtr;
+  if(nextAttrPtr != RNIL){
+    jam();
+    sendLQHADDATTRREQ(signal, op_ptr, nextAttrPtr);
+    return;
+  }
+
+  createTab_dih(signal, op_ptr);
+}
+
+void
+Dbdict::execLQHADDATTREF(Signal * signal)
+{
+  jamEntry();
+  LqhAddAttrRef * const ref = (LqhAddAttrRef*)signal->getDataPtr();
+
+  SchemaOpPtr op_ptr;
+  CreateTableRecPtr createTabPtr;
+  findSchemaOp(op_ptr, createTabPtr, ref->senderData);
+  ndbrequire(!op_ptr.isNull());
+
+  setError(op_ptr, ref->errorCode, __LINE__);
+
+  sendTransConf(signal, op_ptr);
+}
+
+void
+Dbdict::createTab_dih(Signal* signal, SchemaOpPtr op_ptr)
+{
+  CreateTableRecPtr createTabPtr;
+  getOpRec(op_ptr, createTabPtr);
+  SchemaTransPtr trans_ptr = op_ptr.p->m_trans_ptr;
+
+  D("createTab_dih" << *op_ptr.p);
+
+  TableRecordPtr tabPtr;
+  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
+
+
+  /**
+   * NOTE: use array access here...
+   *   as during SR m_noOfSections == 0
+   *   i.e getOpSection will crash
+   */
+  const OpSection& fragSec = op_ptr.p->m_section[CreateTabReq::FRAGMENTATION];
+
   DiAddTabReq * req = (DiAddTabReq*)signal->getDataPtrSend();
   req->connectPtr = op_ptr.p->op_key;
   req->tableId = tabPtr.i;
@@ -5078,48 +5274,6 @@ Dbdict::createTab_dih(Signal* signal,
                DiAddTabReq::SignalLength, JBB,
                ptr, noOfSections);
   }
-  /**
-   * Create KeyDescriptor
-   */
-  KeyDescriptor* desc= g_key_descriptor_pool.getPtr(tabPtr.i);
-  new (desc) KeyDescriptor();
-
-  Uint32 key = 0;
-  Ptr<AttributeRecord> attrPtr;
-  LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
-                                        tabPtr.p->m_attributes);
-  for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr))
-  {
-    AttributeRecord* aRec = attrPtr.p;
-    if (aRec->tupleKey)
-    {
-      Uint32 attr = aRec->attributeDescriptor;
-
-      desc->noOfKeyAttr ++;
-      desc->keyAttr[key].attributeDescriptor = attr;
-      Uint32 csNumber = (aRec->extPrecision >> 16);
-      if (csNumber)
-      {
-        desc->keyAttr[key].charsetInfo = all_charsets[csNumber];
-        ndbrequire(all_charsets[csNumber] != 0);
-        desc->hasCharAttr = 1;
-      }
-      else
-      {
-        desc->keyAttr[key].charsetInfo = 0;
-      }
-      if (AttributeDescriptor::getDKey(attr))
-      {
-        desc->noOfDistrKeys ++;
-      }
-      if (AttributeDescriptor::getArrayType(attr) != NDB_ARRAYTYPE_FIXED)
-      {
-        desc->noOfVarKeys ++;
-      }
-      key++;
-    }
-  }
-  ndbrequire(key == tabPtr.p->noOfPrimkey);
 }
 
 static
@@ -5211,28 +5365,18 @@ Dbdict::execADD_FRAGREQ(Signal* signal)
     req->kValue = tabPtr.p->kValue;
     req->lh3DistrBits = 0; //lhDistrBits;
     req->lh3PageBits = 0; //lhPageBits;
-    req->noOfAttributes = tabPtr.p->noOfAttributes;
-    req->noOfNullAttributes = tabPtr.p->noOfNullBits;
     req->maxRowsLow = maxRows & 0xFFFFFFFF;
     req->maxRowsHigh = maxRows >> 32;
     req->minRowsLow = minRows & 0xFFFFFFFF;
     req->minRowsHigh = minRows >> 32;
-    req->schemaVersion = tabPtr.p->tableVersion;
     Uint32 keyLen = tabPtr.p->tupKeyLength;
     req->keyLength = keyLen; // wl-2066 no more "long keys"
     req->nextLCP = lcpNo;
 
-    req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
-    req->noOfCharsets = tabPtr.p->noOfCharsets;
-    req->checksumIndicator = 1;
-    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->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);
   }
@@ -5250,96 +5394,7 @@ Dbdict::execLQHFRAGCONF(Signal * signal)
   ndbrequire(!op_ptr.isNull());
 
   createTabPtr.p->m_lqhFragPtr = conf->lqhFragPtr;
-
-  TableRecordPtr tabPtr;
-  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
-  sendLQHADDATTRREQ(signal, op_ptr, tabPtr.p->m_attributes.firstItem);
-}
-
-void
-Dbdict::execLQHFRAGREF(Signal * signal)
-{
-  jamEntry();
-  LqhFragRef * const ref = (LqhFragRef*)signal->getDataPtr();
-
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;
-  findSchemaOp(op_ptr, createTabPtr, ref->senderData);
-  ndbrequire(!op_ptr.isNull());
-
-  setError(op_ptr, ref->errorCode, __LINE__);
-
-  {
-    AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
-    ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
-    sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal,
-	       AddFragRef::SignalLength, JBB);
-  }
-}
-
-void
-Dbdict::sendLQHADDATTRREQ(Signal* signal,
-			  SchemaOpPtr op_ptr,
-			  Uint32 attributePtrI)
-{
-  jam();
-  CreateTableRecPtr createTabPtr;
-  getOpRec(op_ptr, createTabPtr);
-
-  TableRecordPtr tabPtr;
-  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
-  LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend();
-  Uint32 i = 0;
-  for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){
-    jam();
-    AttributeRecordPtr attrPtr;
-    c_attributeRecordPool.getPtr(attrPtr, attributePtrI);
-    LqhAddAttrReq::Entry& entry = req->attributes[i];
-    entry.attrId = attrPtr.p->attributeId;
-    entry.attrDescriptor = attrPtr.p->attributeDescriptor;
-    entry.extTypeInfo = 0;
-    // charset number passed to TUP, TUX in upper half
-    entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
-    if (tabPtr.p->isIndex()) {
-      Uint32 primaryAttrId;
-      if (attrPtr.p->nextList != RNIL) {
-        getIndexAttr(tabPtr, attributePtrI, &primaryAttrId);
-      } else {
-        primaryAttrId = ZNIL;
-        if (tabPtr.p->isOrderedIndex())
-          entry.attrId = 0;     // attribute goes to TUP
-      }
-      entry.attrId |= (primaryAttrId << 16);
-    }
-    attributePtrI = attrPtr.p->nextList;
-  }
-  req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr;
-  req->senderData = op_ptr.p->op_key;
-  req->senderAttrPtr = attributePtrI;
-  req->noOfAttributes = i;
-
-  sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
-	     LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
-}
-
-void
-Dbdict::execLQHADDATTCONF(Signal * signal)
-{
-  jamEntry();
-  LqhAddAttrConf * const conf = (LqhAddAttrConf*)signal->getDataPtr();
-
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;
-  findSchemaOp(op_ptr, createTabPtr, conf->senderData);
-  ndbrequire(!op_ptr.isNull());
-
-  const Uint32 fragId = conf->fragId;
-  const Uint32 nextAttrPtr = conf->senderAttrPtr;
-  if(nextAttrPtr != RNIL){
-    jam();
-    sendLQHADDATTRREQ(signal, op_ptr, nextAttrPtr);
-    return;
-  }
+  Uint32 fragId = conf->fragId;
 
   {
     AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
@@ -5351,10 +5406,10 @@ Dbdict::execLQHADDATTCONF(Signal * signa
 }
 
 void
-Dbdict::execLQHADDATTREF(Signal * signal)
+Dbdict::execLQHFRAGREF(Signal * signal)
 {
   jamEntry();
-  LqhAddAttrRef * const ref = (LqhAddAttrRef*)signal->getDataPtr();
+  LqhFragRef * const ref = (LqhFragRef*)signal->getDataPtr();
 
   SchemaOpPtr op_ptr;
   CreateTableRecPtr createTabPtr;
@@ -5387,22 +5442,7 @@ Dbdict::execDIADDTABCONF(Signal* signal)
   signal->theData[1] = reference();
   signal->theData[2] = createTabPtr.p->m_request.tableId;
 
-  if(createTabPtr.p->m_dihAddFragPtr != RNIL){
-    jam();
-
-    /**
-     * We did perform at least one LQHFRAGREQ
-     */
-    sendSignal(DBLQH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
-    return;
-  } else {
-    /**
-     * No local fragment (i.e. no LQHFRAGREQ)
-     */
-    execute(signal, createTabPtr.p->m_callback, 0);
-    return;
-    //sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
-  }
+  sendSignal(DBLQH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
 }
 
 void
@@ -5479,12 +5519,11 @@ Dbdict::execTAB_COMMITREF(Signal* signal
 }//execTAB_COMMITREF()
 
 void
-Dbdict::createTab_dihComplete(Signal* signal,
-			      Uint32 op_key,
-			      Uint32 ret)
+Dbdict::createTab_localComplete(Signal* signal,
+                                Uint32 op_key,
+                                Uint32 ret)
 {
   jam();
-  D("createTab_dihComplete");
 
   SchemaOpPtr op_ptr;
   CreateTableRecPtr createTabPtr;
@@ -5746,20 +5785,6 @@ void
 Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal)
 {
   // currently not received
-  ndbrequire(false);
-}
-
-void
-Dbdict::execCREATE_TAB_REF(Signal* signal)
-{
-  // no longer received
-  ndbrequire(false);
-}
-
-void
-Dbdict::execCREATE_TAB_CONF(Signal* signal)
-{
-  // no longer received
   ndbrequire(false);
 }
 
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2008-05-30 14:21:23 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2008-05-31 08:36:31 +02:00
@@ -2052,8 +2052,9 @@ private:
 
   // prepare
   void createTab_writeTableConf(Signal*, Uint32 op_key, Uint32 ret);
-  void createTab_dih(Signal*, SchemaOpPtr, OpSection fragSec, Callback*);
-  void createTab_dihComplete(Signal*, Uint32 op_key, Uint32 ret);
+  void createTab_local(Signal*, SchemaOpPtr, OpSection fragSec, Callback*);
+  void createTab_dih(Signal*, SchemaOpPtr);
+  void createTab_localComplete(Signal*, Uint32 op_key, Uint32 ret);
 
   // commit
   void createTab_activate(Signal*, SchemaOpPtr, Callback*);
diff -Nrup a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2008-05-30 08:36:53 +02:00
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2008-05-31 08:36:31 +02:00
@@ -27,6 +27,7 @@
 #include <NodeBitmask.hpp>
 #include <signaldata/LCP.hpp>
 #include <signaldata/LqhTransConf.hpp>
+#include <signaldata/CreateTab.hpp>
 #include <signaldata/LqhFrag.hpp>
 #include <signaldata/FsOpenReq.hpp>
 
@@ -423,39 +424,22 @@ public:
       TUP_ATTR_WAIT = 7,
       TUX_ATTR_WAIT = 9
     };
-    LqhAddAttrReq::Entry attributes[LqhAddAttrReq::MAX_ATTRIBUTES];
-    UintR accConnectptr;
     AddFragStatus addfragStatus;
-    UintR dictConnectptr;
     UintR fragmentPtr;
     UintR nextAddfragrec;
-    UintR schemaVer;
+    UintR accConnectptr;
     UintR tupConnectptr;
     UintR tuxConnectptr;
-    UintR checksumIndicator;
-    UintR GCPIndicator;
-    BlockReference dictBlockref;
-    Uint32 m_senderAttrPtr;
+
+    CreateTabReq m_createTabReq;
+    LqhFragReq m_lqhFragReq;
+    LqhAddAttrReq m_addAttrReq;
+
     Uint16 addfragErrorCode;
     Uint16 attrSentToTup;
     Uint16 attrReceived;
-    Uint16 addFragid;
-    Uint16 noOfAttr;
-    Uint16 noOfNull;
-    Uint16 tabId;
     Uint16 totalAttrReceived;
     Uint16 fragCopyCreation;
-    Uint16 noOfKeyAttr;
-    Uint16 noOfCharsets;
-    Uint16 lh3DistrBits;
-    Uint16 tableType;
-    Uint16 primaryTableId;
-    Uint32 tablespace_id;
-    Uint32 maxRowsLow;
-    Uint32 maxRowsHigh;
-    Uint32 minRowsLow;
-    Uint32 minRowsHigh;
-    Uint32 forceVarPartFlag;
   };
   typedef Ptr<AddFragRecord> AddFragRecordPtr;
   
@@ -2098,14 +2082,20 @@ private:
   void execSEND_PACKED(Signal* signal);
   void execTUP_ATTRINFO(Signal* signal);
   void execREAD_CONFIG_REQ(Signal* signal);
-  void execLQHFRAGREQ(Signal* signal);
+
+  void execCREATE_TAB_REQ(Signal* signal);
+  void execCREATE_TAB_REF(Signal* signal);
+  void execCREATE_TAB_CONF(Signal* signal);
   void execLQHADDATTREQ(Signal* signal);
   void execTUP_ADD_ATTCONF(Signal* signal);
   void execTUP_ADD_ATTRREF(Signal* signal);
+
+  void execLQHFRAGREQ(Signal* signal);
   void execACCFRAGCONF(Signal* signal);
   void execACCFRAGREF(Signal* signal);
   void execTUPFRAGCONF(Signal* signal);
   void execTUPFRAGREF(Signal* signal);
+
   void execTAB_COMMITREQ(Signal* signal);
   void execACCSEIZECONF(Signal* signal);
   void execACCSEIZEREF(Signal* signal);
@@ -2523,8 +2513,9 @@ private:
   void closeExecSrCompletedLab(Signal* signal);
   void readSrFrontpageLab(Signal* signal);
   
-  void sendAddFragReq(Signal* signal);
+  void sendCreateTabReq(Signal*, AddFragRecordPtr);
   void sendAddAttrReq(Signal* signal);
+  void sendAddFragReq(Signal* signal);
   void checkDropTab(Signal*);
   Uint32 checkDropTabState(Tablerec::TableStatus, Uint32) const;
 
@@ -2626,6 +2617,7 @@ private:
   AddFragRecordPtr addfragptr;
   UintR cfirstfreeAddfragrec;
   UintR caddfragrecFileSize;
+  Uint32 c_active_add_frag_ptr_i;
 
 #define ZATTRINBUF_FILE_SIZE 12288  // 1.5 MByte
 #define ZINBUF_DATA_LEN 24            /* POSITION OF 'DATA LENGHT'-VARIABLE. */
diff -Nrup a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp	2008-02-06 21:00:08 +01:00
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp	2008-05-31 08:36:31 +02:00
@@ -64,6 +64,7 @@ void Dblqh::initData() 
   m_backup_ptr = RNIL;
   clogFileSize = 16;
   cmaxLogFilesInPageZero = 40;
+  c_active_add_frag_ptr_i = RNIL;
 }//Dblqh::initData()
 
 void Dblqh::initRecords() 
@@ -278,7 +279,10 @@ Dblqh::Dblqh(Block_context& ctx):
   addRecSignal(GSN_FSSYNCCONF,  &Dblqh::execFSSYNCCONF);
   addRecSignal(GSN_REMOVE_MARKER_ORD, &Dblqh::execREMOVE_MARKER_ORD);
 
-  //addRecSignal(GSN_DROP_TAB_REQ, &Dblqh::execDROP_TAB_REQ);
+  addRecSignal(GSN_CREATE_TAB_REQ, &Dblqh::execCREATE_TAB_REQ);
+  addRecSignal(GSN_CREATE_TAB_REF, &Dblqh::execCREATE_TAB_REF);
+  addRecSignal(GSN_CREATE_TAB_CONF, &Dblqh::execCREATE_TAB_CONF);
+
   addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dblqh::execPREP_DROP_TAB_REQ);
   addRecSignal(GSN_DROP_TAB_REQ, &Dblqh::execDROP_TAB_REQ);
 
diff -Nrup a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-05-30 08:36:54 +02:00
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-05-31 08:36:31 +02:00
@@ -48,6 +48,8 @@
 #include <signaldata/DumpStateOrd.hpp>
 #include <signaldata/PackedSignal.hpp>
 
+#include <signaldata/CreateTab.hpp>
+#include <signaldata/CreateTable.hpp>
 #include <signaldata/PrepDropTab.hpp>
 #include <signaldata/DropTab.hpp>
 
@@ -1099,404 +1101,180 @@ void Dblqh::execREAD_CONFIG_REQ(Signal* 
 
 // this unbelievable mess could be replaced by one signal to LQH
 // and execute direct to local DICT to get everything at once
-
-void Dblqh::execLQHFRAGREQ(Signal* signal) 
+void
+Dblqh::execCREATE_TAB_REQ(Signal* signal)
 {
-  jamEntry();
-  LqhFragReq * req = (LqhFragReq*)signal->getDataPtr();
-  
-  Uint32 retPtr = req->senderData;
-  BlockReference retRef = req->senderRef;
-  Uint32 fragId = req->fragmentId;
-  Uint32 reqinfo = req->requestInfo;
+  CreateTabReq* req = (CreateTabReq*)signal->getDataPtr();
   tabptr.i = req->tableId;
-  Uint16 tlocalKeylen = req->localKeyLength;
-  Uint32 tmaxLoadFactor = req->maxLoadFactor;
-  Uint32 tminLoadFactor = req->minLoadFactor;
-  Uint8 tk = req->kValue;
-  Uint8 tlhstar = req->lh3DistrBits;
-  Uint8 tlh = req->lh3PageBits;
-  Uint32 tnoOfAttr = req->noOfAttributes;
-  Uint32 tnoOfNull = req->noOfNullAttributes;
-  Uint32 maxRowsLow = req->maxRowsLow;
-  Uint32 maxRowsHigh = req->maxRowsHigh;
-  Uint32 minRowsLow = req->minRowsLow;
-  Uint32 minRowsHigh = req->minRowsHigh;
-  Uint32 tschemaVersion = req->schemaVersion;
-  Uint32 ttupKeyLength = req->keyLength;
-  Uint32 noOfKeyAttr = req->noOfKeyAttr;
-  Uint32 noOfCharsets = req->noOfCharsets;
-  Uint32 checksumIndicator = req->checksumIndicator;
-  Uint32 gcpIndicator = req->GCPIndicator;
-  Uint32 startGci = req->startGci;
-  Uint32 tableType = req->tableType;
-  Uint32 primaryTableId = req->primaryTableId;
-  Uint32 tablespace= req->tablespace_id;
-  Uint32 logPart = req->logPartId;
-  Uint32 forceVarPartFlag = req->forceVarPartFlag;
-
-  if (signal->getLength() < 20)
-  {
-    logPart = (fragId & 1) + 2 * (tabptr.i & 1);
-  }
-  logPart &= 3;
-
   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
-  bool tempTable = ((reqinfo & LqhFragReq::TemporaryTable) != 0);
 
-  /* Temporary tables set to defined in system restart */
-  if (tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
-    tabptr.p->tableStatus = Tablerec::ADD_TABLE_ONGOING;
-    tabptr.p->tableType = tableType;
-    tabptr.p->primaryTableId = 
-      (primaryTableId == RNIL ? tabptr.i : primaryTableId);
-    tabptr.p->schemaVersion = tschemaVersion;
-    tabptr.p->m_disk_table= 0;
-  }//if
-  
-  if (tabptr.p->tableStatus != Tablerec::ADD_TABLE_ONGOING){
-    jam();
-    fragrefLab(signal, retRef, retPtr, ZTAB_STATE_ERROR);
-    return;
-  }//if
-  //--------------------------------------------------------------------
-  // We could arrive here if we create the fragment as part of a take
-  // over by a hot spare node. The table is then is already created
-  // and bit 31 is set, thus indicating that we are creating a fragment
-  // by copy creation. Also since the node has already been started we
-  // know that it is not a node restart ongoing.
-  //--------------------------------------------------------------------
+  Uint32 senderRef = req->senderRef;
+  Uint32 senderData = req->senderData;
 
-  if (getFragmentrec(signal, fragId)) {
-    jam();
-    fragrefLab(signal, retRef, retPtr, terrorCode);
-    return;
-  }//if
-  if (!insertFragrec(signal, fragId)) {
+  if (tabptr.p->tableStatus != Tablerec::NOT_DEFINED)
+  {
     jam();
-    fragrefLab(signal, retRef, retPtr, terrorCode);
+    CreateTabRef* ref = (CreateTabRef*)signal->getDataPtrSend();
+    ref->senderData = senderData;
+    ref->senderRef = reference();
+    ref->errorCode = CreateTableRef::TableAlreadyExist;
+    sendSignal(senderRef, GSN_CREATE_TAB_REF, signal,
+               CreateTabRef::SignalLength, JBB);
     return;
-  }//if
-  Uint32 copyType = reqinfo & 3;
-  initFragrec(signal, tabptr.i, fragId, copyType);
-  fragptr.p->startGci = startGci;
-  fragptr.p->newestGci = startGci;
-  fragptr.p->tableType = tableType;
-  fragptr.p->m_log_part_ptr_i = logPart; // assumes array
-  
-  if (DictTabInfo::isOrderedIndex(tableType)) {
-    jam();
-    // find corresponding primary table fragment
-    TablerecPtr tTablePtr;
-    tTablePtr.i = primaryTableId;
-    ptrCheckGuard(tTablePtr, ctabrecFileSize, tablerec);
-    FragrecordPtr tFragPtr;
-    tFragPtr.i = RNIL;
-    for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
-      if (tTablePtr.p->fragid[i] == fragptr.p->fragId) {
-        jam();
-        tFragPtr.i = tTablePtr.p->fragrec[i];
-        break;
-      }
-    }
-    ndbrequire(tFragPtr.i != RNIL);
-    // store it
-    fragptr.p->tableFragptr = tFragPtr.i;
-  } else {
-    fragptr.p->tableFragptr = fragptr.i;
   }
 
-  if (tempTable) {
-//--------------------------------------------
-// reqinfo bit 3-4 = 2 means temporary table
-// without logging or checkpointing.
-//--------------------------------------------
-    jam();
-    fragptr.p->logFlag = Fragrecord::STATE_FALSE;
-    fragptr.p->lcpFlag = Fragrecord::LCP_STATE_FALSE;
-  }//if
-  
-//----------------------------------------------
-// For node restarts it is not necessarily zero 
-//----------------------------------------------
-  if (cfirstfreeAddfragrec == RNIL) {
-    jam();
-    deleteFragrec(fragId);
-    fragrefLab(signal, retRef, retPtr, ZNO_ADD_FRAGREC);
-    return;
-  }//if
   seizeAddfragrec(signal);
-  addfragptr.p->addFragid = fragId;
-  addfragptr.p->fragmentPtr = fragptr.i;
-  addfragptr.p->dictBlockref = retRef;
-  addfragptr.p->dictConnectptr = retPtr;
-  addfragptr.p->m_senderAttrPtr = RNIL;
-  addfragptr.p->noOfAttr = tnoOfAttr;
-  addfragptr.p->noOfNull = tnoOfNull;
-  addfragptr.p->maxRowsLow = maxRowsLow;
-  addfragptr.p->maxRowsHigh = maxRowsHigh;
-  addfragptr.p->minRowsLow = minRowsLow;
-  addfragptr.p->minRowsHigh = minRowsHigh;
-  addfragptr.p->tabId = tabptr.i;
-  addfragptr.p->totalAttrReceived = 0;
-  addfragptr.p->attrSentToTup = ZNIL;/* TO FIND PROGRAMMING ERRORS QUICKLY */
-  addfragptr.p->schemaVer = tschemaVersion;
-  Uint32 tmp = (reqinfo & LqhFragReq::CreateInRunning);
-  addfragptr.p->fragCopyCreation = (tmp == 0 ? 0 : 1);
-  addfragptr.p->addfragErrorCode = 0;
-  addfragptr.p->noOfKeyAttr = noOfKeyAttr;
-  addfragptr.p->noOfCharsets = noOfCharsets;
-  addfragptr.p->checksumIndicator = checksumIndicator;
-  addfragptr.p->GCPIndicator = gcpIndicator;
-  addfragptr.p->lh3DistrBits = tlhstar;
-  addfragptr.p->tableType = tableType;
-  addfragptr.p->primaryTableId = primaryTableId;
-  addfragptr.p->tablespace_id= tablespace;
-  addfragptr.p->forceVarPartFlag = forceVarPartFlag;
-  //
-  addfragptr.p->tupConnectptr = RNIL;
-  addfragptr.p->tuxConnectptr = RNIL;
+  addfragptr.p->m_createTabReq = *req;
+  req = &addfragptr.p->m_createTabReq;
 
-  if (DictTabInfo::isTable(tableType) ||
-      DictTabInfo::isHashIndex(tableType)) {
-    jam();
-    AccFragReq* const accreq = (AccFragReq*)signal->getDataPtrSend();
-    accreq->userPtr = addfragptr.i;
-    accreq->userRef = cownref;
-    accreq->tableId = tabptr.i;
-    accreq->reqInfo = copyType << 4;
-    accreq->fragId = fragId;
-    accreq->localKeyLen = tlocalKeylen;
-    accreq->maxLoadFactor = tmaxLoadFactor;
-    accreq->minLoadFactor = tminLoadFactor;
-    accreq->kValue = tk;
-    accreq->lhFragBits = tlhstar;
-    accreq->lhDirBits = tlh;
-    accreq->keyLength = ttupKeyLength;
-    /* --------------------------------------------------------------------- */
-    /* Send ACCFRAGREQ, when confirmation is received send 2 * TUPFRAGREQ to */
-    /* create 2 tuple fragments on this node.                                */
-    /* --------------------------------------------------------------------- */
-    addfragptr.p->addfragStatus = AddFragRecord::ACC_ADDFRAG;
-    sendSignal(fragptr.p->accBlockref, GSN_ACCFRAGREQ,
-	       signal, AccFragReq::SignalLength, JBB);
-    return;
-  }
-  if (DictTabInfo::isOrderedIndex(tableType)) {
+  tabptr.p->tableStatus = Tablerec::ADD_TABLE_ONGOING;
+  tabptr.p->tableType = req->tableType;
+  tabptr.p->primaryTableId = (req->primaryTableId == RNIL ? tabptr.i :
+                              req->primaryTableId);
+  tabptr.p->schemaVersion = req->tableVersion;
+  tabptr.p->m_disk_table= 0;
+
+  addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
+  sendCreateTabReq(signal, addfragptr);
+}
+
+void
+Dblqh::sendCreateTabReq(Signal* signal, AddFragRecordPtr addfragptr)
+{
+  TablerecPtr tabPtr;
+  tabPtr.i = addfragptr.p->m_createTabReq.tableId;
+  ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
+
+  CreateTabReq* req = (CreateTabReq*)signal->getDataPtrSend();
+  * req = addfragptr.p->m_createTabReq;
+
+  req->senderRef = reference();
+  req->senderData = addfragptr.i;
+
+  Uint32 ref = DBTUP_REF;
+  switch(addfragptr.p->addfragStatus){
+  case AddFragRecord::WAIT_TUP:
+    if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType))
+    {
+      jam();
+      req->noOfAttributes = 1;
+      req->noOfKeyAttr = 1;
+      req->noOfNullAttributes = 0;
+    }
+    break;
+  case AddFragRecord::WAIT_TUX:
     jam();
-    addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
-    sendAddFragReq(signal);
-    return;
+    ndbrequire(req->noOfAttributes >= 2);
+    req->noOfAttributes--;
+    ref = DBTUX_REF;
+    break;
+  default:
+    jamLine(addfragptr.p->addfragStatus);
+    ndbrequire(false);
   }
-  ndbrequire(false);
-}//Dblqh::execLQHFRAGREQ()
 
-/* *************** */
-/*  ACCFRAGCONF  > */
-/* *************** */
-void Dblqh::execACCFRAGCONF(Signal* signal) 
+  sendSignal(ref, GSN_CREATE_TAB_REQ, signal,
+             CreateTabReq::SignalLengthLDM, JBB);
+}
+
+void
+Dblqh::execCREATE_TAB_REF(Signal* signal)
 {
   jamEntry();
-  addfragptr.i = signal->theData[0];
-  Uint32 taccConnectptr = signal->theData[1];
-  //Uint32 fragId1 = signal->theData[2];
-  Uint32 accFragPtr1 = signal->theData[4];
+
+  CreateTabRef * ref = (CreateTabRef*)signal->getDataPtr();
+  addfragptr.i = ref->senderData;
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
-  ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
 
-  addfragptr.p->accConnectptr = taccConnectptr;
-  fragptr.i = addfragptr.p->fragmentPtr;
-  c_fragment_pool.getPtr(fragptr);
-  fragptr.p->accFragptr = accFragPtr1;
+  abortAddFragOps(signal);
 
-  addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
-  sendAddFragReq(signal);
-}//Dblqh::execACCFRAGCONF()
+  ref->senderRef = reference();
+  ref->senderData = addfragptr.p->m_createTabReq.senderData;
+  sendSignal(addfragptr.p->m_createTabReq.senderRef,
+             GSN_CREATE_TAB_REF, signal, CreateTabConf::SignalLength, JBB);
 
-/* *************** */
-/*  TUPFRAGCONF  > */
-/* *************** */
-void Dblqh::execTUPFRAGCONF(Signal* signal) 
+  releaseAddfragrec(signal);
+}
+
+void
+Dblqh::execCREATE_TAB_CONF(Signal* signal)
 {
   jamEntry();
-  addfragptr.i = signal->theData[0];
-  Uint32 tupConnectptr = signal->theData[1];
-  Uint32 tupFragPtr = signal->theData[2];  /* TUP FRAGMENT POINTER */
-  //Uint32 localFragId = signal->theData[3];  /* LOCAL FRAGMENT ID    */
+  CreateTabConf* conf = (CreateTabConf*)signal->getDataPtr();
+  addfragptr.i = conf->senderData;
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
-  fragptr.i = addfragptr.p->fragmentPtr;
-  c_fragment_pool.getPtr(fragptr);
-  fragptr.p->tupFragptr = tupFragPtr;
-  switch (addfragptr.p->addfragStatus) {
+
+  TablerecPtr tabPtr;
+  tabPtr.i = addfragptr.p->m_createTabReq.tableId;
+  ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
+
+  switch(addfragptr.p->addfragStatus){
   case AddFragRecord::WAIT_TUP:
     jam();
-    fragptr.p->tupFragptr = tupFragPtr;
-    addfragptr.p->tupConnectptr = tupConnectptr;
-    if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
+    addfragptr.p->tupConnectptr = conf->tupConnectPtr;
+    if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType))
+    {
+      jam();
       addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUX;
-      sendAddFragReq(signal);
-      break;
+      sendCreateTabReq(signal, addfragptr);
+      return;
     }
-    goto done_with_frag;
     break;
   case AddFragRecord::WAIT_TUX:
     jam();
-    fragptr.p->tuxFragptr = tupFragPtr;
-    addfragptr.p->tuxConnectptr = tupConnectptr;
-    goto done_with_frag;
-    break;
-  done_with_frag:
-    /* ---------------------------------------------------------------- */
-    /* Finished create of fragments. Now ready for creating attributes. */
-    /* ---------------------------------------------------------------- */
-    addfragptr.p->addfragStatus = AddFragRecord::WAIT_ADD_ATTR;
-    {
-      LqhFragConf* conf = (LqhFragConf*)signal->getDataPtrSend();
-      conf->senderData = addfragptr.p->dictConnectptr;
-      conf->lqhFragPtr = addfragptr.i;
-      sendSignal(addfragptr.p->dictBlockref, GSN_LQHFRAGCONF,
-		 signal, LqhFragConf::SignalLength, JBB);
-    }
+    addfragptr.p->tuxConnectptr = conf->tuxConnectPtr;
     break;
   default:
+    jamLine(addfragptr.p->addfragStatus);
     ndbrequire(false);
-    break;
   }
-}//Dblqh::execTUPFRAGCONF()
 
-/* *************** */
-/*  TUXFRAGCONF  > */
-/* *************** */
-void Dblqh::execTUXFRAGCONF(Signal* signal) 
-{
-  jamEntry();
-  execTUPFRAGCONF(signal);
-}//Dblqh::execTUXFRAGCONF
+  addfragptr.p->addfragStatus = AddFragRecord::WAIT_ADD_ATTR;
 
-/*
- * Add fragment in TUP or TUX.  Called up to 4 times.
- */
-void
-Dblqh::sendAddFragReq(Signal* signal)
-{
-  fragptr.i = addfragptr.p->fragmentPtr;
-  c_fragment_pool.getPtr(fragptr);
-  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUP){
-    TupFragReq* const tupFragReq = (TupFragReq*)signal->getDataPtrSend();
-    if (DictTabInfo::isTable(addfragptr.p->tableType) ||
-        DictTabInfo::isHashIndex(addfragptr.p->tableType)) {
-      jam();
-      tupFragReq->userPtr = addfragptr.i;
-      tupFragReq->userRef = cownref;
-      tupFragReq->reqInfo = 0; /* ADD TABLE */
-      tupFragReq->tableId = addfragptr.p->tabId;
-      tupFragReq->noOfAttr = addfragptr.p->noOfAttr;
-      tupFragReq->fragId = addfragptr.p->addFragid;
-      tupFragReq->maxRowsLow = addfragptr.p->maxRowsLow;
-      tupFragReq->maxRowsHigh = addfragptr.p->maxRowsHigh;
-      tupFragReq->minRowsLow = addfragptr.p->minRowsLow;
-      tupFragReq->minRowsHigh = addfragptr.p->minRowsHigh;
-      tupFragReq->noOfNullAttr = addfragptr.p->noOfNull;
-      tupFragReq->schemaVersion = addfragptr.p->schemaVer;
-      tupFragReq->noOfKeyAttr = addfragptr.p->noOfKeyAttr;
-      tupFragReq->noOfCharsets = addfragptr.p->noOfCharsets;
-      tupFragReq->checksumIndicator = addfragptr.p->checksumIndicator;
-      tupFragReq->globalCheckpointIdIndicator = addfragptr.p->GCPIndicator;
-      tupFragReq->tablespaceid = addfragptr.p->tablespace_id;
-      tupFragReq->forceVarPartFlag = addfragptr.p->forceVarPartFlag;
-      sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
-		 signal, TupFragReq::SignalLength, JBB);
-      return;
-    }
-    if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
-      jam();
-      tupFragReq->userPtr = addfragptr.i;
-      tupFragReq->userRef = cownref;
-      tupFragReq->reqInfo = 0; /* ADD TABLE */
-      tupFragReq->tableId = addfragptr.p->tabId;
-      tupFragReq->noOfAttr = 1; /* ordered index: one array attr */
-      tupFragReq->fragId = addfragptr.p->addFragid;
-      tupFragReq->maxRowsLow = addfragptr.p->maxRowsLow;
-      tupFragReq->maxRowsHigh = addfragptr.p->maxRowsHigh;
-      tupFragReq->minRowsLow = addfragptr.p->minRowsLow;
-      tupFragReq->minRowsHigh = addfragptr.p->minRowsHigh;
-      tupFragReq->noOfNullAttr = 0; /* ordered index: no nullable */
-      tupFragReq->schemaVersion = addfragptr.p->schemaVer;
-      tupFragReq->noOfKeyAttr = 1; /* ordered index: one key */
-      tupFragReq->noOfCharsets = addfragptr.p->noOfCharsets;
-      tupFragReq->checksumIndicator = addfragptr.p->checksumIndicator;
-      tupFragReq->globalCheckpointIdIndicator = addfragptr.p->GCPIndicator;
-      tupFragReq->forceVarPartFlag = addfragptr.p->forceVarPartFlag;      
-      sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
-		 signal, TupFragReq::SignalLength, JBB);
-      return;
-    }
-  }
-  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUX) {
-    if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
-      jam();
-      TuxFragReq* const tuxreq = (TuxFragReq*)signal->getDataPtrSend();
-      tuxreq->userPtr = addfragptr.i;
-      tuxreq->userRef = cownref;
-      tuxreq->reqInfo = 0; /* ADD TABLE */
-      tuxreq->tableId = addfragptr.p->tabId;
-      ndbrequire(addfragptr.p->noOfAttr >= 2);
-      tuxreq->noOfAttr = addfragptr.p->noOfAttr - 1; /* skip NDB$TNODE */
-      tuxreq->fragId = addfragptr.p->addFragid;
-      tuxreq->fragOff = addfragptr.p->lh3DistrBits;
-      tuxreq->tableType = addfragptr.p->tableType;
-      tuxreq->primaryTableId = addfragptr.p->primaryTableId;
-      // pointer to index fragment in TUP
-      tuxreq->tupIndexFragPtrI = fragptr.p->tupFragptr;
-      // pointers to table fragments in TUP and ACC
-      FragrecordPtr tFragPtr;
-      tFragPtr.i = fragptr.p->tableFragptr;
-      c_fragment_pool.getPtr(tFragPtr);
-      tuxreq->tupTableFragPtrI[0] = tFragPtr.p->tupFragptr;
-      tuxreq->tupTableFragPtrI[1] = RNIL;
-      tuxreq->accTableFragPtrI[0] = tFragPtr.p->accFragptr;
-      tuxreq->accTableFragPtrI[1] = RNIL;
-      sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ,
-		 signal, TuxFragReq::SignalLength, JBB);
-      return;
-    }
-  }
-  ndbrequire(false);
-}//Dblqh::sendAddFragReq
+  conf->senderRef = reference();
+  conf->senderData = addfragptr.p->m_createTabReq.senderData;
+  conf->lqhConnectPtr = addfragptr.i;
+  sendSignal(addfragptr.p->m_createTabReq.senderRef,
+             GSN_CREATE_TAB_CONF, signal, CreateTabConf::SignalLength, JBB);
+}
 
 /* ************************************************************************> */
 /*  LQHADDATTRREQ: Request from DICT to create attributes for the new table. */
 /* ************************************************************************> */
-void Dblqh::execLQHADDATTREQ(Signal* signal) 
+void Dblqh::execLQHADDATTREQ(Signal* signal)
 {
   jamEntry();
-  LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtr();
-  
+  LqhAddAttrReq * req = (LqhAddAttrReq*)signal->getDataPtr();
+
   addfragptr.i = req->lqhFragPtr;
+  ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
+
+  addfragptr.p->m_addAttrReq = * req;
+
   const Uint32 tnoOfAttr = req->noOfAttributes;
-  const Uint32 senderData = req->senderData;
-  const Uint32 senderAttrPtr = req->senderAttrPtr;
 
-  ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::WAIT_ADD_ATTR);
   ndbrequire((tnoOfAttr != 0) && (tnoOfAttr <= LqhAddAttrReq::MAX_ATTRIBUTES));
   addfragptr.p->totalAttrReceived += tnoOfAttr;
-  ndbrequire(addfragptr.p->totalAttrReceived <= addfragptr.p->noOfAttr);
+  ndbrequire(addfragptr.p->totalAttrReceived <=
+             addfragptr.p->m_createTabReq.noOfAttributes);
 
   addfragptr.p->attrReceived = tnoOfAttr;
-  for (Uint32 i = 0; i < tnoOfAttr; i++) {
-    addfragptr.p->attributes[i] = req->attributes[i];
+
+  TablerecPtr tabPtr;
+  tabPtr.i = addfragptr.p->m_createTabReq.tableId;
+  ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
+
+  for (Uint32 i = 0; i < tnoOfAttr; i++)
+  {
     if(AttributeDescriptor::getDiskBased(req->attributes[i].attrDescriptor))
     {
-      TablerecPtr tabPtr;
-      tabPtr.i = addfragptr.p->tabId;
-      ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
+      jam();
       tabPtr.p->m_disk_table = 1;
     }
   }//for
+
   addfragptr.p->attrSentToTup = 0;
-  ndbrequire(addfragptr.p->dictConnectptr == senderData);
-  addfragptr.p->m_senderAttrPtr = senderAttrPtr;
   addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT;
   sendAddAttrReq(signal);
 }//Dblqh::execLQHADDATTREQ()
@@ -1504,16 +1282,23 @@ void Dblqh::execLQHADDATTREQ(Signal* sig
 /* *********************>> */
 /*  TUP_ADD_ATTCONF      > */
 /* *********************>> */
-void Dblqh::execTUP_ADD_ATTCONF(Signal* signal) 
+void Dblqh::execTUP_ADD_ATTCONF(Signal* signal)
 {
   jamEntry();
   addfragptr.i = signal->theData[0];
   // implies that operation was released on the other side
   const bool lastAttr = signal->theData[1];
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
+
+  tabptr.i = addfragptr.p->m_createTabReq.tableId;
+  ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+
+  Uint32 noOfAttr = addfragptr.p->m_createTabReq.noOfAttributes;
+
   switch (addfragptr.p->addfragStatus) {
   case AddFragRecord::TUP_ATTR_WAIT:
-    if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
+    if (DictTabInfo::isOrderedIndex(tabptr.p->tableType))
+    {
       addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT;
       sendAddAttrReq(signal);
       break;
@@ -1529,56 +1314,33 @@ void Dblqh::execTUP_ADD_ATTCONF(Signal* 
   done_with_attr:
     addfragptr.p->attrSentToTup = addfragptr.p->attrSentToTup + 1;
     ndbrequire(addfragptr.p->attrSentToTup <= addfragptr.p->attrReceived);
-    ndbrequire(addfragptr.p->totalAttrReceived <= addfragptr.p->noOfAttr);
-    if (addfragptr.p->attrSentToTup < addfragptr.p->attrReceived) {
+    ndbrequire(addfragptr.p->totalAttrReceived <= noOfAttr);
+    if (addfragptr.p->attrSentToTup < addfragptr.p->attrReceived)
+    {
       // more in this batch
       jam();
       addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT;
       sendAddAttrReq(signal);
-    } else if (addfragptr.p->totalAttrReceived < addfragptr.p->noOfAttr) {
-      // more batches to receive
+      return;
+    }
+
+    { // Reply
+      LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
+      conf->senderData = addfragptr.p->m_addAttrReq.senderData;
+      conf->senderAttrPtr = addfragptr.p->m_addAttrReq.senderAttrPtr;
+      sendSignal(addfragptr.p->m_createTabReq.senderRef,
+                 GSN_LQHADDATTCONF, signal, LqhAddAttrConf::SignalLength, JBB);
+    }
+    if (addfragptr.p->totalAttrReceived < noOfAttr)
+    {
       jam();
       addfragptr.p->addfragStatus = AddFragRecord::WAIT_ADD_ATTR;
-      LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
-      conf->senderData = addfragptr.p->dictConnectptr;
-      conf->senderAttrPtr = addfragptr.p->m_senderAttrPtr;
-      conf->fragId = addfragptr.p->addFragid;
-      sendSignal(addfragptr.p->dictBlockref, GSN_LQHADDATTCONF,
-		 signal, LqhAddAttrConf::SignalLength, JBB);
-    } else {
-      fragptr.i = addfragptr.p->fragmentPtr;
-      c_fragment_pool.getPtr(fragptr);
-      /* ------------------------------------------------------------------ 
-       * WE HAVE NOW COMPLETED ADDING THIS FRAGMENT. WE NOW NEED TO SET THE 
-       * PROPER STATE IN FRAG_STATUS DEPENDENT ON IF WE ARE CREATING A NEW 
-       * REPLICA OR IF WE ARE CREATING A TABLE. FOR FRAGMENTS IN COPY
-       * PROCESS WE DO NOT WANT LOGGING ACTIVATED.      
-       * ----------------------------------------------------------------- */
-      if (addfragptr.p->fragCopyCreation == 1) {
-        jam();
-        if (! DictTabInfo::isOrderedIndex(addfragptr.p->tableType))
-	{
-	  fragptr.p->m_copy_started_state = Fragrecord::AC_IGNORED;
-	  //fragptr.p->m_copy_started_state = Fragrecord::AC_NR_COPY;
-          fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION;
-	}
-        else
-	{
-          fragptr.p->fragStatus = Fragrecord::FSACTIVE;
-	}
-        fragptr.p->logFlag = Fragrecord::STATE_FALSE;
-      } else {
-        jam();
-        fragptr.p->fragStatus = Fragrecord::FSACTIVE;
-      }//if
-      LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
-      conf->senderData = addfragptr.p->dictConnectptr;
-      conf->senderAttrPtr = addfragptr.p->m_senderAttrPtr;
-      conf->fragId = addfragptr.p->addFragid;
-      sendSignal(addfragptr.p->dictBlockref, GSN_LQHADDATTCONF, signal, 
-                 LqhAddAttrConf::SignalLength, JBB);
+    }
+    else
+    {
+      jam();
       releaseAddfragrec(signal);
-    }//if
+    }
     break;
   default:
     ndbrequire(false);
@@ -1589,12 +1351,58 @@ void Dblqh::execTUP_ADD_ATTCONF(Signal* 
 /* **********************>> */
 /*  TUX_ADD_ATTRCONF      > */
 /* **********************>> */
-void Dblqh::execTUX_ADD_ATTRCONF(Signal* signal) 
+void Dblqh::execTUX_ADD_ATTRCONF(Signal* signal)
 {
   jamEntry();
   execTUP_ADD_ATTCONF(signal);
 }//Dblqh::execTUX_ADD_ATTRCONF
 
+/* *********************> */
+/*  TUP_ADD_ATTREF      > */
+/* *********************> */
+void Dblqh::execTUP_ADD_ATTRREF(Signal* signal)
+{
+  jamEntry();
+  addfragptr.i = signal->theData[0];
+  ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
+  Uint32 errorCode = terrorCode = signal->theData[1];
+
+  abortAddFragOps(signal);
+
+  // operation was released on the other side
+  switch (addfragptr.p->addfragStatus) {
+  case AddFragRecord::TUP_ATTR_WAIT:
+    jam();
+    break;
+  case AddFragRecord::TUX_ATTR_WAIT:
+    jam();
+    break;
+  default:
+    ndbrequire(false);
+    break;
+  }
+
+  const Uint32 Ref = addfragptr.p->m_createTabReq.senderRef;
+  const Uint32 senderData = addfragptr.p->m_addAttrReq.senderData;
+
+  releaseAddfragrec(signal);
+
+  LqhAddAttrRef *const ref = (LqhAddAttrRef*)signal->getDataPtrSend();
+  ref->senderData = senderData;
+  ref->errorCode = errorCode;
+  sendSignal(Ref, GSN_LQHADDATTREF, signal,
+	     LqhAddAttrRef::SignalLength, JBB);
+}//Dblqh::execTUP_ADD_ATTRREF()
+
+/* **********************> */
+/*  TUX_ADD_ATTRREF      > */
+/* **********************> */
+void Dblqh::execTUX_ADD_ATTRREF(Signal* signal)
+{
+  jamEntry();
+  execTUP_ADD_ATTRREF(signal);
+}//Dblqh::execTUX_ADD_ATTRREF
+
 /*
  * Add attribute in TUP or TUX.  Called up to 4 times.
  */
@@ -1603,15 +1411,19 @@ Dblqh::sendAddAttrReq(Signal* signal)
 {
   arrGuard(addfragptr.p->attrSentToTup, LqhAddAttrReq::MAX_ATTRIBUTES);
   LqhAddAttrReq::Entry& entry =
-    addfragptr.p->attributes[addfragptr.p->attrSentToTup];
+    addfragptr.p->m_addAttrReq.attributes[addfragptr.p->attrSentToTup];
+
   const Uint32 attrId = entry.attrId & 0xffff;
   const Uint32 primaryAttrId = entry.attrId >> 16;
-  fragptr.i = addfragptr.p->fragmentPtr;
-  c_fragment_pool.getPtr(fragptr);
-  if (addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT) {
-    if (DictTabInfo::isTable(addfragptr.p->tableType) ||
-        DictTabInfo::isHashIndex(addfragptr.p->tableType) ||
-        (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
+
+  tabptr.i = addfragptr.p->m_createTabReq.tableId;
+  ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+
+  if (addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT)
+  {
+    if (DictTabInfo::isTable(tabptr.p->tableType) ||
+        DictTabInfo::isHashIndex(tabptr.p->tableType) ||
+        (DictTabInfo::isOrderedIndex(tabptr.p->tableType) &&
          primaryAttrId == ZNIL)) {
       jam();
       TupAddAttrReq* const tupreq = (TupAddAttrReq*)signal->getDataPtrSend();
@@ -1620,11 +1432,11 @@ Dblqh::sendAddAttrReq(Signal* signal)
       tupreq->attrId = attrId;
       tupreq->attrDescriptor = entry.attrDescriptor;
       tupreq->extTypeInfo = entry.extTypeInfo;
-      sendSignal(fragptr.p->tupBlockref, GSN_TUP_ADD_ATTRREQ,
-          signal, TupAddAttrReq::SignalLength, JBB);
+      sendSignal(DBTUP_REF, GSN_TUP_ADD_ATTRREQ,
+                 signal, TupAddAttrReq::SignalLength, JBB);
       return;
     }
-    if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
+    if (DictTabInfo::isOrderedIndex(tabptr.p->tableType) &&
         primaryAttrId != ZNIL) {
       // this attribute is not for TUP
       jam();
@@ -1636,9 +1448,11 @@ Dblqh::sendAddAttrReq(Signal* signal)
       return;
     }
   }
-  if (addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT) {
+
+  if (addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT)
+  {
     jam();
-    if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
+    if (DictTabInfo::isOrderedIndex(tabptr.p->tableType) &&
         primaryAttrId != ZNIL) {
       jam();
       TuxAddAttrReq* const tuxreq = (TuxAddAttrReq*)signal->getDataPtrSend();
@@ -1648,11 +1462,11 @@ Dblqh::sendAddAttrReq(Signal* signal)
       tuxreq->attrDescriptor = entry.attrDescriptor;
       tuxreq->extTypeInfo = entry.extTypeInfo;
       tuxreq->primaryAttrId = primaryAttrId;
-      sendSignal(fragptr.p->tuxBlockref, GSN_TUX_ADD_ATTRREQ,
+      sendSignal(DBTUX_REF, GSN_TUX_ADD_ATTRREQ,
 		 signal, TuxAddAttrReq::SignalLength, JBB);
       return;
     }
-    if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
+    if (DictTabInfo::isOrderedIndex(tabptr.p->tableType) &&
         primaryAttrId == ZNIL) {
       // this attribute is not for TUX
       jam();
@@ -1667,6 +1481,258 @@ Dblqh::sendAddAttrReq(Signal* signal)
   ndbrequire(false);
 }//Dblqh::sendAddAttrReq
 
+void Dblqh::execLQHFRAGREQ(Signal* signal)
+{
+  jamEntry();
+  LqhFragReq copy = *(LqhFragReq*)signal->getDataPtr();
+  LqhFragReq * req = &copy;
+
+  tabptr.i = req->tableId;
+  ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+
+  if (tabptr.p->tableStatus != Tablerec::ADD_TABLE_ONGOING)
+  {
+    jam();
+    fragrefLab(signal, req->senderRef, req->senderData, ZTAB_STATE_ERROR);
+    return;
+  }//if
+
+  if (getFragmentrec(signal, req->fragId))
+  {
+    jam();
+    fragrefLab(signal, req->senderRef, req->senderData, terrorCode);
+    return;
+  }//if
+
+  if (!insertFragrec(signal, req->fragId))
+  {
+    jam();
+    fragrefLab(signal, req->senderRef, req->senderData, terrorCode);
+    return;
+  }//if
+  
+  Uint32 copyType = req->requestInfo & 3;
+  bool tempTable = ((req->requestInfo & LqhFragReq::TemporaryTable) != 0);
+  initFragrec(signal, tabptr.i, req->fragId, copyType);
+  fragptr.p->startGci = req->startGci;
+  fragptr.p->newestGci = req->startGci;
+  fragptr.p->tableType = tabptr.p->tableType;
+  fragptr.p->m_log_part_ptr_i = (req->logPartId & 3); // assumes array
+
+  if (DictTabInfo::isOrderedIndex(tabptr.p->tableType)) {
+    jam();
+    // find corresponding primary table fragment
+    TablerecPtr tTablePtr;
+    tTablePtr.i = tabptr.p->primaryTableId;
+    ptrCheckGuard(tTablePtr, ctabrecFileSize, tablerec);
+    FragrecordPtr tFragPtr;
+    tFragPtr.i = RNIL;
+    for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
+      if (tTablePtr.p->fragid[i] == fragptr.p->fragId) {
+        jam();
+        tFragPtr.i = tTablePtr.p->fragrec[i];
+        break;
+      }
+    }
+    ndbrequire(tFragPtr.i != RNIL);
+    // store it
+    fragptr.p->tableFragptr = tFragPtr.i;
+  }
+  else
+  {
+    jam();
+    fragptr.p->tableFragptr = fragptr.i;
+  }
+
+  if (tempTable)
+  {
+//--------------------------------------------
+// reqinfo bit 3-4 = 2 means temporary table
+// without logging or checkpointing.
+//--------------------------------------------
+    jam();
+    fragptr.p->logFlag = Fragrecord::STATE_FALSE;
+    fragptr.p->lcpFlag = Fragrecord::LCP_STATE_FALSE;
+  }//if
+
+  seizeAddfragrec(signal);
+  addfragptr.p->m_lqhFragReq = * req;
+  addfragptr.p->fragmentPtr = fragptr.i;
+
+  if (DictTabInfo::isTable(tabptr.p->tableType) ||
+      DictTabInfo::isHashIndex(tabptr.p->tableType)) {
+    jam();
+    AccFragReq* const accreq = (AccFragReq*)signal->getDataPtrSend();
+    accreq->userPtr = addfragptr.i;
+    accreq->userRef = cownref;
+    accreq->tableId = tabptr.i;
+    accreq->reqInfo = 0;
+    accreq->fragId = req->fragId;
+    accreq->localKeyLen = addfragptr.p->m_lqhFragReq.localKeyLength;
+    accreq->maxLoadFactor = addfragptr.p->m_lqhFragReq.maxLoadFactor;
+    accreq->minLoadFactor = addfragptr.p->m_lqhFragReq.minLoadFactor;
+    accreq->kValue = addfragptr.p->m_lqhFragReq.kValue;
+    accreq->lhFragBits = addfragptr.p->m_lqhFragReq.lh3DistrBits;
+    accreq->lhDirBits = addfragptr.p->m_lqhFragReq.lh3PageBits;
+    accreq->keyLength = addfragptr.p->m_lqhFragReq.keyLength;
+    /* --------------------------------------------------------------------- */
+    /* Send ACCFRAGREQ, when confirmation is received send 2 * TUPFRAGREQ to */
+    /* create 2 tuple fragments on this node.                                */
+    /* --------------------------------------------------------------------- */
+    addfragptr.p->addfragStatus = AddFragRecord::ACC_ADDFRAG;
+    sendSignal(fragptr.p->accBlockref, GSN_ACCFRAGREQ,
+	       signal, AccFragReq::SignalLength, JBB);
+    return;
+  }
+  if (DictTabInfo::isOrderedIndex(tabptr.p->tableType)) {
+    jam();
+    addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
+    sendAddFragReq(signal);
+    return;
+  }
+  ndbrequire(false);
+}//Dblqh::execLQHFRAGREQ()
+
+/* *************** */
+/*  ACCFRAGCONF  > */
+/* *************** */
+void Dblqh::execACCFRAGCONF(Signal* signal) 
+{
+  jamEntry();
+  addfragptr.i = signal->theData[0];
+  Uint32 taccConnectptr = signal->theData[1];
+  //Uint32 fragId1 = signal->theData[2];
+  Uint32 accFragPtr1 = signal->theData[4];
+  ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
+  ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
+
+  addfragptr.p->accConnectptr = taccConnectptr;
+  fragptr.i = addfragptr.p->fragmentPtr;
+  c_fragment_pool.getPtr(fragptr);
+  fragptr.p->accFragptr = accFragPtr1;
+
+  addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
+  sendAddFragReq(signal);
+}//Dblqh::execACCFRAGCONF()
+
+/* *************** */
+/*  TUPFRAGCONF  > */
+/* *************** */
+void Dblqh::execTUPFRAGCONF(Signal* signal) 
+{
+  jamEntry();
+  addfragptr.i = signal->theData[0];
+  Uint32 tupConnectptr = signal->theData[1];
+  Uint32 tupFragPtr = signal->theData[2];  /* TUP FRAGMENT POINTER */
+  //Uint32 localFragId = signal->theData[3];  /* LOCAL FRAGMENT ID    */
+  ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
+  fragptr.i = addfragptr.p->fragmentPtr;
+  c_fragment_pool.getPtr(fragptr);
+  tabptr.i = fragptr.p->tabRef;
+  ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+  fragptr.p->tupFragptr = tupFragPtr;
+  switch (addfragptr.p->addfragStatus) {
+  case AddFragRecord::WAIT_TUP:
+    jam();
+    fragptr.p->tupFragptr = tupFragPtr;
+    addfragptr.p->tupConnectptr = tupConnectptr;
+    if (DictTabInfo::isOrderedIndex(tabptr.p->tableType))
+    {
+      addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUX;
+      sendAddFragReq(signal);
+      break;
+    }
+    goto done_with_frag;
+    break;
+  case AddFragRecord::WAIT_TUX:
+    jam();
+    fragptr.p->tuxFragptr = tupFragPtr;
+    addfragptr.p->tuxConnectptr = tupConnectptr;
+    goto done_with_frag;
+    break;
+  done_with_frag:
+    /* ---------------------------------------------------------------- */
+    /* Finished create of fragments. Now ready for creating attributes. */
+    /* ---------------------------------------------------------------- */
+    fragptr.p->fragStatus = Fragrecord::FSACTIVE;
+    {
+      LqhFragConf* conf = (LqhFragConf*)signal->getDataPtrSend();
+      conf->senderData = addfragptr.p->m_lqhFragReq.senderData;
+      conf->lqhFragPtr = RNIL;
+      conf->fragId = fragptr.p->fragId;
+      sendSignal(addfragptr.p->m_lqhFragReq.senderRef, GSN_LQHFRAGCONF,
+		 signal, LqhFragConf::SignalLength, JBB);
+    }
+    releaseAddfragrec(signal);
+    break;
+  default:
+    ndbrequire(false);
+    break;
+  }
+}//Dblqh::execTUPFRAGCONF()
+
+/* *************** */
+/*  TUXFRAGCONF  > */
+/* *************** */
+void Dblqh::execTUXFRAGCONF(Signal* signal) 
+{
+  jamEntry();
+  execTUPFRAGCONF(signal);
+}//Dblqh::execTUXFRAGCONF
+
+/*
+ * Add fragment in TUP or TUX.  Called up to 4 times.
+ */
+void
+Dblqh::sendAddFragReq(Signal* signal)
+{
+  fragptr.i = addfragptr.p->fragmentPtr;
+  c_fragment_pool.getPtr(fragptr);
+  tabptr.i = fragptr.p->tabRef;
+  ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
+  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUP)
+  {
+    TupFragReq* const tupFragReq = (TupFragReq*)signal->getDataPtrSend();
+    tupFragReq->userPtr = addfragptr.i;
+    tupFragReq->userRef = cownref;
+    tupFragReq->reqInfo = 0; /* ADD TABLE */
+    tupFragReq->tableId = tabptr.i;
+    tupFragReq->fragId = addfragptr.p->m_lqhFragReq.fragId;
+    tupFragReq->tablespaceid = addfragptr.p->m_lqhFragReq.tablespace_id;
+    tupFragReq->maxRowsHigh = addfragptr.p->m_lqhFragReq.maxRowsHigh;
+    tupFragReq->maxRowsLow = addfragptr.p->m_lqhFragReq.maxRowsLow;
+    tupFragReq->minRowsHigh = addfragptr.p->m_lqhFragReq.minRowsHigh;
+    tupFragReq->minRowsLow = addfragptr.p->m_lqhFragReq.minRowsLow;
+    sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
+               signal, TupFragReq::SignalLength, JBB);
+    return;
+  }
+  if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUX)
+  {
+    jam();
+    ndbrequire(DictTabInfo::isOrderedIndex(tabptr.p->tableType));
+    TuxFragReq* const tuxreq = (TuxFragReq*)signal->getDataPtrSend();
+    tuxreq->userPtr = addfragptr.i;
+    tuxreq->userRef = cownref;
+    tuxreq->reqInfo = 0; /* ADD TABLE */
+    tuxreq->tableId = tabptr.i;
+    tuxreq->fragId = addfragptr.p->m_lqhFragReq.fragId;
+    tuxreq->primaryTableId = tabptr.p->primaryTableId;
+    // pointer to index fragment in TUP
+    tuxreq->tupIndexFragPtrI = fragptr.p->tupFragptr;
+    // pointers to table fragments in TUP and ACC
+    FragrecordPtr tFragPtr;
+    tFragPtr.i = fragptr.p->tableFragptr;
+    c_fragment_pool.getPtr(tFragPtr);
+    tuxreq->tupTableFragPtrI = tFragPtr.p->tupFragptr;
+    tuxreq->accTableFragPtrI = tFragPtr.p->accFragptr;
+    sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ,
+               signal, TuxFragReq::SignalLength, JBB);
+    return;
+  }
+}//Dblqh::sendAddFragReq
+
+
 /* ************************************************************************>> */
 /*  TAB_COMMITREQ: Commit the new table for use in transactions. Sender DICT. */
 /* ************************************************************************>> */
@@ -1706,6 +1772,7 @@ void Dblqh::execTAB_COMMITREQ(Signal* si
   signal->theData[1] = cownNodeid;
   signal->theData[2] = tabptr.i;
   sendSignal(dihBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
+
   return;
 }//Dblqh::execTAB_COMMITREQ()
 
@@ -1728,14 +1795,12 @@ void Dblqh::fragrefLab(Signal* signal,
  */
 void Dblqh::abortAddFragOps(Signal* signal)
 {
-  fragptr.i = addfragptr.p->fragmentPtr;
-  c_fragment_pool.getPtr(fragptr);
   if (addfragptr.p->tupConnectptr != RNIL) {
     jam();
     TupFragReq* const tupFragReq = (TupFragReq*)signal->getDataPtrSend();
     tupFragReq->userPtr = (Uint32)-1;
     tupFragReq->userRef = addfragptr.p->tupConnectptr;
-    sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
+    sendSignal(ctupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
     addfragptr.p->tupConnectptr = RNIL;
   }
   if (addfragptr.p->tuxConnectptr != RNIL) {
@@ -1743,7 +1808,7 @@ void Dblqh::abortAddFragOps(Signal* sign
     TuxFragReq* const tuxFragReq = (TuxFragReq*)signal->getDataPtrSend();
     tuxFragReq->userPtr = (Uint32)-1;
     tuxFragReq->userRef = addfragptr.p->tuxConnectptr;
-    sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
+    sendSignal(ctuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
     addfragptr.p->tuxConnectptr = RNIL;
   }
 }
@@ -1756,14 +1821,13 @@ void Dblqh::execACCFRAGREF(Signal* signa
   jamEntry();
   addfragptr.i = signal->theData[0];
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
-  terrorCode = signal->theData[1];
+  Uint32 errorCode = terrorCode = signal->theData[1];
   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
-  addfragptr.p->addfragErrorCode = terrorCode;
 
-  const Uint32 ref = addfragptr.p->dictBlockref;
-  const Uint32 senderData = addfragptr.p->dictConnectptr;
-  const Uint32 errorCode = addfragptr.p->addfragErrorCode;
+  const Uint32 ref = addfragptr.p->m_lqhFragReq.senderRef;
+  const Uint32 senderData = addfragptr.p->m_lqhFragReq.senderData;
   releaseAddfragrec(signal);
+
   fragrefLab(signal, ref, senderData, errorCode);
 
   return;
@@ -1777,10 +1841,9 @@ void Dblqh::execTUPFRAGREF(Signal* signa
   jamEntry();
   addfragptr.i = signal->theData[0];
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
-  terrorCode = signal->theData[1];
+  Uint32 errorCode = terrorCode = signal->theData[1];
   fragptr.i = addfragptr.p->fragmentPtr;
   c_fragment_pool.getPtr(fragptr);
-  addfragptr.p->addfragErrorCode = terrorCode;
 
   // no operation to release, just add some jams
   switch (addfragptr.p->addfragStatus) {
@@ -1794,11 +1857,9 @@ void Dblqh::execTUPFRAGREF(Signal* signa
     ndbrequire(false);
     break;
   }
-  abortAddFragOps(signal);
 
-  const Uint32 ref = addfragptr.p->dictBlockref;
-  const Uint32 senderData = addfragptr.p->dictConnectptr;
-  const Uint32 errorCode = addfragptr.p->addfragErrorCode;
+  const Uint32 ref = addfragptr.p->m_lqhFragReq.senderRef;
+  const Uint32 senderData = addfragptr.p->m_lqhFragReq.senderData;
   releaseAddfragrec(signal);
   fragrefLab(signal, ref, senderData, errorCode);
 
@@ -1813,57 +1874,6 @@ void Dblqh::execTUXFRAGREF(Signal* signa
   execTUPFRAGREF(signal);
 }//Dblqh::execTUXFRAGREF
 
-/* *********************> */
-/*  TUP_ADD_ATTREF      > */
-/* *********************> */
-void Dblqh::execTUP_ADD_ATTRREF(Signal* signal) 
-{
-  jamEntry();
-  addfragptr.i = signal->theData[0];
-  ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
-  terrorCode = signal->theData[1];
-  addfragptr.p->addfragErrorCode = terrorCode;
-
-  // operation was released on the other side
-  switch (addfragptr.p->addfragStatus) {
-  case AddFragRecord::TUP_ATTR_WAIT:
-    jam();
-    ndbrequire(addfragptr.p->tupConnectptr != RNIL);
-    addfragptr.p->tupConnectptr = RNIL;
-    break;
-  case AddFragRecord::TUX_ATTR_WAIT:
-    jam();
-    ndbrequire(addfragptr.p->tuxConnectptr != RNIL);
-    addfragptr.p->tuxConnectptr = RNIL;
-    break;
-  default:
-    ndbrequire(false);
-    break;
-  }
-  abortAddFragOps(signal);
-  
-  const Uint32 Ref = addfragptr.p->dictBlockref;
-  const Uint32 senderData = addfragptr.p->dictConnectptr;
-  const Uint32 errorCode = addfragptr.p->addfragErrorCode;
-  releaseAddfragrec(signal);
-  
-  LqhAddAttrRef *const ref = (LqhAddAttrRef*)signal->getDataPtrSend();
-  ref->senderData = senderData;
-  ref->errorCode = errorCode;
-  sendSignal(Ref, GSN_LQHADDATTREF, signal, 
-	     LqhAddAttrRef::SignalLength, JBB);
-  
-}//Dblqh::execTUP_ADD_ATTRREF()
-
-/* **********************> */
-/*  TUX_ADD_ATTRREF      > */
-/* **********************> */
-void Dblqh::execTUX_ADD_ATTRREF(Signal* signal) 
-{
-  jamEntry();
-  execTUP_ADD_ATTRREF(signal);
-}//Dblqh::execTUX_ADD_ATTRREF
-
 void
 Dblqh::execPREP_DROP_TAB_REQ(Signal* signal){
   jamEntry();
@@ -18392,6 +18402,17 @@ void Dblqh::seizeAddfragrec(Signal* sign
   addfragptr.i = cfirstfreeAddfragrec;
   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
   cfirstfreeAddfragrec = addfragptr.p->nextAddfragrec;
+
+  addfragptr.p->accConnectptr = RNIL;
+  addfragptr.p->tupConnectptr = RNIL;
+  addfragptr.p->tuxConnectptr = RNIL;
+  bzero(&addfragptr.p->m_createTabReq, sizeof(addfragptr.p->m_createTabReq));
+  bzero(&addfragptr.p->m_lqhFragReq, sizeof(addfragptr.p->m_lqhFragReq));
+  bzero(&addfragptr.p->m_addAttrReq, sizeof(addfragptr.p->m_addAttrReq));
+  addfragptr.p->addfragErrorCode = 0;
+  addfragptr.p->attrSentToTup = 0;
+  addfragptr.p->attrReceived = 0;
+  addfragptr.p->totalAttrReceived = 0;
 }//Dblqh::seizeAddfragrec()
 
 /* --------------------------------------------------------------------------
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2008-05-29 18:16:47 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2008-05-31 08:36:31 +02:00
@@ -1098,12 +1098,18 @@ ArrayPool<TupTriggerData> c_triggerPool;
     Uint32 fragid[MAX_FRAG_PER_NODE];
     Uint32 fragrec[MAX_FRAG_PER_NODE];
 
-    struct {
-      Uint32 tabUserPtr;
-      Uint32 tabUserRef;
-      Uint32 m_lcpno;
-      Uint32 m_fragPtrI;
-    } m_dropTable;
+    union {
+      struct {
+        Uint32 tabUserPtr;
+        Uint32 tabUserRef;
+        Uint32 m_lcpno;
+        Uint32 m_fragPtrI;
+      } m_dropTable;
+      struct {
+        Uint32 m_fragOpPtrI;
+      } m_createTable;
+    };
+
     State tableStatus;
   };  
 
@@ -1714,8 +1720,10 @@ private:
   void execTUPSEIZEREQ(Signal* signal);
   void execTUPRELEASEREQ(Signal* signal);
   void execSTORED_PROCREQ(Signal* signal);
-  void execTUPFRAGREQ(Signal* signal);
+
+  void execCREATE_TAB_REQ(Signal*);
   void execTUP_ADD_ATTRREQ(Signal* signal);
+  void execTUPFRAGREQ(Signal* signal);
   void execTUP_COMMITREQ(Signal* signal);
   void execTUP_ABORTREQ(Signal* signal);
   void execNDB_STTOR(Signal* signal);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2008-05-29 18:16:47 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2008-05-31 08:36:31 +02:00
@@ -73,6 +73,8 @@ Dbtup::Dbtup(Block_context& ctx, Pgman* 
   addRecSignal(GSN_TUPSEIZEREQ, &Dbtup::execTUPSEIZEREQ);
   addRecSignal(GSN_TUPRELEASEREQ, &Dbtup::execTUPRELEASEREQ);
   addRecSignal(GSN_STORED_PROCREQ, &Dbtup::execSTORED_PROCREQ);
+
+  addRecSignal(GSN_CREATE_TAB_REQ, &Dbtup::execCREATE_TAB_REQ);
   addRecSignal(GSN_TUPFRAGREQ, &Dbtup::execTUPFRAGREQ);
   addRecSignal(GSN_TUP_ADD_ATTRREQ, &Dbtup::execTUP_ADD_ATTRREQ);
   addRecSignal(GSN_ALTER_TAB_REQ, &Dbtup::execALTER_TAB_REQ);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2008-05-29 18:16:47 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2008-05-31 08:36:31 +02:00
@@ -20,6 +20,9 @@
 #include <RefConvert.hpp>
 #include <ndb_limits.h>
 #include <pc.hpp>
+// Error codes
+#include <signaldata/CreateTable.hpp>
+#include <signaldata/CreateTab.hpp>
 #include <signaldata/TupFrag.hpp>
 #include <signaldata/FsRef.hpp>
 #include <signaldata/FsConf.hpp>
@@ -32,270 +35,121 @@
 #include "AttributeOffset.hpp"
 #include <my_sys.h>
 
-void Dbtup::execTUPFRAGREQ(Signal* signal)
+void
+Dbtup::execCREATE_TAB_REQ(Signal* signal)
 {
   jamEntry();
 
-  TupFragReq* tupFragReq = (TupFragReq*)signal->getDataPtr();
-  if (tupFragReq->userPtr == (Uint32)-1) {
-    jam();
-    abortAddFragOp(signal);
-    return;
-  }
+  CreateTabReq reqCopy = *(CreateTabReq*)signal->getDataPtr();
+  CreateTabReq* req = &reqCopy;
 
-  FragoperrecPtr fragOperPtr;
-  FragrecordPtr regFragPtr;
   TablerecPtr regTabPtr;
+  regTabPtr.i = req->tableId;
+  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
 
-  Uint32 userptr        = tupFragReq->userPtr;
-  Uint32 userblockref   = tupFragReq->userRef;
-  Uint32 reqinfo        = tupFragReq->reqInfo;
-  regTabPtr.i           = tupFragReq->tableId;
-  Uint32 noOfAttributes = tupFragReq->noOfAttr;
-  Uint32 fragId         = tupFragReq->fragId;
-  /*  Uint32 schemaVersion = tupFragReq->schemaVersion;*/
-  Uint32 noOfKeyAttr = tupFragReq->noOfKeyAttr;
-  Uint32 noOfCharsets = tupFragReq->noOfCharsets;
-
-  Uint32 checksumIndicator = tupFragReq->checksumIndicator;
-  Uint32 gcpIndicator = tupFragReq->globalCheckpointIdIndicator;
-  Uint32 tablespace_id= tupFragReq->tablespaceid;
-  Uint32 forceVarPart = tupFragReq->forceVarPartFlag;
-
-  Uint64 maxRows =
-    (((Uint64)tupFragReq->maxRowsHigh) << 32) + tupFragReq->maxRowsLow;
-  Uint64 minRows =
-    (((Uint64)tupFragReq->minRowsHigh) << 32) + tupFragReq->minRowsLow;
-
-#ifndef VM_TRACE
-  // config mismatch - do not crash if release compiled
-  if (regTabPtr.i >= cnoOfTablerec) {
+  if (regTabPtr.p->tableStatus != NOT_DEFINED)
+  {
     jam();
-    tupFragReq->userPtr = userptr;
-    tupFragReq->userRef = 800;
-    sendSignal(userblockref, GSN_TUPFRAGREF, signal, 2, JBB);
-    return;
+    ndbout_c("regTabPtr.p->tableStatus : %u", regTabPtr.p->tableStatus);
+    terrorCode = CreateTableRef::TableAlreadyExist;
+    goto sendref;
   }
-#endif
 
-  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
-  if (cfirstfreeFragopr == RNIL) {
+  if (cfirstfreeFragopr == RNIL)
+  {
     jam();
-    tupFragReq->userPtr = userptr;
-    tupFragReq->userRef = ZNOFREE_FRAGOP_ERROR;
-    sendSignal(userblockref, GSN_TUPFRAGREF, signal, 2, JBB);
-    return;
+    terrorCode = ZNOFREE_FRAGOP_ERROR;
+    goto sendref;
   }
-  seizeFragoperrec(fragOperPtr);
 
-  fragOperPtr.p->nextFragoprec = RNIL;
-  fragOperPtr.p->lqhBlockrefFrag = userblockref;
-  fragOperPtr.p->lqhPtrFrag = userptr;
-  fragOperPtr.p->fragidFrag = fragId;
+  FragoperrecPtr fragOperPtr;
+  seizeFragoperrec(fragOperPtr);
   fragOperPtr.p->tableidFrag = regTabPtr.i;
-  fragOperPtr.p->attributeCount = noOfAttributes;
-  
+  fragOperPtr.p->attributeCount = req->noOfAttributes;
   memset(fragOperPtr.p->m_null_bits, 0, sizeof(fragOperPtr.p->m_null_bits));
-
   fragOperPtr.p->charsetIndex = 0;
-  fragOperPtr.p->minRows = minRows;
-  fragOperPtr.p->maxRows = maxRows;
+  fragOperPtr.p->lqhBlockrefFrag = req->senderRef;
 
-  ndbrequire(reqinfo == ZADDFRAG);
+  regTabPtr.p->m_createTable.m_fragOpPtrI = fragOperPtr.i;
+  regTabPtr.p->tableStatus= DEFINING;
+  regTabPtr.p->m_bits = 0;
+  regTabPtr.p->m_bits |= (req->checksumIndicator ? Tablerec::TR_Checksum : 0);
+  regTabPtr.p->m_bits |= (req->GCPIndicator ? Tablerec::TR_RowGCI : 0);
+  regTabPtr.p->m_bits |= (req->forceVarPartFlag? Tablerec::TR_ForceVarPart : 0);
+
+  regTabPtr.p->m_offsets[MM].m_disk_ref_offset= 0;
+  regTabPtr.p->m_offsets[MM].m_null_words= 0;
+  regTabPtr.p->m_offsets[MM].m_fix_header_size= 0;
+  regTabPtr.p->m_offsets[MM].m_max_var_offset= 0;
+  regTabPtr.p->m_offsets[MM].m_max_dyn_offset= 0;
+  regTabPtr.p->m_offsets[MM].m_dyn_null_words= 0;
+
+  regTabPtr.p->m_offsets[DD].m_disk_ref_offset= 0;
+  regTabPtr.p->m_offsets[DD].m_null_words= 0;
+  regTabPtr.p->m_offsets[DD].m_fix_header_size= 0;
+  regTabPtr.p->m_offsets[DD].m_max_var_offset= 0;
+  regTabPtr.p->m_offsets[DD].m_max_dyn_offset= 0;
+  regTabPtr.p->m_offsets[DD].m_dyn_null_words= 0;
+
+  regTabPtr.p->m_attributes[MM].m_no_of_fixsize= 0;
+  regTabPtr.p->m_attributes[MM].m_no_of_varsize= 0;
+  regTabPtr.p->m_attributes[MM].m_no_of_dynamic= 0;
+  regTabPtr.p->m_attributes[MM].m_no_of_dyn_fix= 0;
+  regTabPtr.p->m_attributes[MM].m_no_of_dyn_var= 0;
+  regTabPtr.p->m_attributes[DD].m_no_of_fixsize= 0;
+  regTabPtr.p->m_attributes[DD].m_no_of_varsize= 0;
+  regTabPtr.p->m_attributes[DD].m_no_of_dynamic= 0;
+  regTabPtr.p->m_attributes[DD].m_no_of_dyn_fix= 0;
+  regTabPtr.p->m_attributes[DD].m_no_of_dyn_var= 0;
+
+  // Reserve space for bitmap length
+  regTabPtr.p->m_dyn_null_bits= DYN_BM_LEN_BITS;
+  regTabPtr.p->noOfKeyAttr= req->noOfKeyAttr;
+  regTabPtr.p->noOfCharsets= req->noOfCharsets;
+  regTabPtr.p->m_no_of_attributes= req->noOfAttributes;
+  regTabPtr.p->dynTabDescriptor= RNIL;
 
-  getFragmentrec(regFragPtr, fragId, regTabPtr.p);
-  if (regFragPtr.i != RNIL) {
-    jam();
-    terrorCode= ZEXIST_FRAG_ERROR;
-    fragrefuse1Lab(signal, fragOperPtr);
-    return;
-  }
-  if (cfirstfreefrag != RNIL) {
-    jam();
-    seizeFragrecord(regFragPtr);
-  } else {
-    jam();
-    terrorCode= ZFULL_FRAGRECORD_ERROR;
-    fragrefuse1Lab(signal, fragOperPtr);
-    return;
-  }
-  if (!addfragtotab(regTabPtr.p, fragId, regFragPtr.i)) {
-    jam();
-    terrorCode= ZNO_FREE_TAB_ENTRY_ERROR;
-    fragrefuse2Lab(signal, fragOperPtr, regFragPtr);
-    return;
-  }
-
-  regFragPtr.p->fragTableId= regTabPtr.i;
-  regFragPtr.p->fragmentId= fragId;
-  regFragPtr.p->m_tablespace_id= tablespace_id;
-  regFragPtr.p->m_undo_complete= false;
-  regFragPtr.p->m_lcp_scan_op = RNIL; 
-  regFragPtr.p->m_lcp_keep_list = RNIL;
-  regFragPtr.p->noOfPages = 0;
-  regFragPtr.p->noOfVarPages = 0;
-  regFragPtr.p->m_max_page_no = 0;
-  regFragPtr.p->m_free_page_id_list = FREE_PAGE_RNIL;
-  ndbrequire(regFragPtr.p->m_page_map.isEmpty());
-  regFragPtr.p->m_restore_lcp_id = RNIL;
-  for (Uint32 i = 0; i<MAX_FREE_LIST+1; i++)
-    ndbrequire(regFragPtr.p->free_var_page_array[i].isEmpty());
-
-  if (ERROR_INSERTED(4007) && regTabPtr.p->fragid[0] == fragId ||
-      ERROR_INSERTED(4008) && regTabPtr.p->fragid[1] == fragId) {
-    jam();
-    terrorCode = 1;
-    fragrefuse4Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId);
-    CLEAR_ERROR_INSERT_VALUE;
-    return;
-  }
-
-  if (regTabPtr.p->tableStatus == NOT_DEFINED) {
-    jam();
-//-----------------------------------------------------------------------------
-// We are setting up references to the header of the tuple.
-// Active operation  This word contains a reference to the operation active
-//                   on the tuple at the moment. RNIL means no one active at
-//                   all.  Not optional.
-// Tuple version     Uses only low 16 bits.  Not optional.
-// Checksum          The third header word is optional and contains a checksum
-//                   of the tuple header.
-// Null-bits         A number of words to contain null bits for all
-//                   non-dynamic attributes. Each word contains upto 32 null
-//                   bits. Each time a new word is needed we allocate the
-//                   complete word. Zero nullable attributes means that there
-//                   is no word at all
-//                   Note that the null-bits are also used for storing the
-//                   data for (non-dynamic) bit types.
-//-----------------------------------------------------------------------------
-    fragOperPtr.p->definingFragment= true;
-    regTabPtr.p->tableStatus= DEFINING;
-    regTabPtr.p->m_bits = 0;
-    regTabPtr.p->m_bits |= (checksumIndicator ? Tablerec::TR_Checksum : 0);
-    regTabPtr.p->m_bits |= (gcpIndicator ? Tablerec::TR_RowGCI : 0);
-    regTabPtr.p->m_bits |= (forceVarPart ? Tablerec::TR_ForceVarPart : 0);
-    
-    regTabPtr.p->m_offsets[MM].m_disk_ref_offset= 0;
-    regTabPtr.p->m_offsets[MM].m_null_words= 0;
-    regTabPtr.p->m_offsets[MM].m_fix_header_size= 0;
-    regTabPtr.p->m_offsets[MM].m_max_var_offset= 0;
-    regTabPtr.p->m_offsets[MM].m_max_dyn_offset= 0;
-    regTabPtr.p->m_offsets[MM].m_dyn_null_words= 0;
-
-    regTabPtr.p->m_offsets[DD].m_disk_ref_offset= 0;
-    regTabPtr.p->m_offsets[DD].m_null_words= 0;
-    regTabPtr.p->m_offsets[DD].m_fix_header_size= 0;
-    regTabPtr.p->m_offsets[DD].m_max_var_offset= 0;
-    regTabPtr.p->m_offsets[DD].m_max_dyn_offset= 0;
-    regTabPtr.p->m_offsets[DD].m_dyn_null_words= 0;
-
-    regTabPtr.p->m_attributes[MM].m_no_of_fixsize= 0;
-    regTabPtr.p->m_attributes[MM].m_no_of_varsize= 0;
-    regTabPtr.p->m_attributes[MM].m_no_of_dynamic= 0;
-    regTabPtr.p->m_attributes[MM].m_no_of_dyn_fix= 0;
-    regTabPtr.p->m_attributes[MM].m_no_of_dyn_var= 0;
-    regTabPtr.p->m_attributes[DD].m_no_of_fixsize= 0;
-    regTabPtr.p->m_attributes[DD].m_no_of_varsize= 0;
-    regTabPtr.p->m_attributes[DD].m_no_of_dynamic= 0;
-    regTabPtr.p->m_attributes[DD].m_no_of_dyn_fix= 0;
-    regTabPtr.p->m_attributes[DD].m_no_of_dyn_var= 0;
-
-    // Reserve space for bitmap length
-    regTabPtr.p->m_dyn_null_bits= DYN_BM_LEN_BITS; 
-    regTabPtr.p->noOfKeyAttr= noOfKeyAttr;
-    regTabPtr.p->noOfCharsets= noOfCharsets;
-    regTabPtr.p->m_no_of_attributes= noOfAttributes;
-    
-    regTabPtr.p->dynTabDescriptor= RNIL;
-    
+  {
     Uint32 offset[10];
-    Uint32 allocSize= getTabDescrOffsets(noOfAttributes, noOfCharsets,
-                                         noOfKeyAttr, offset);
+    Uint32 allocSize= getTabDescrOffsets(req->noOfAttributes,
+                                         req->noOfCharsets,
+                                         req->noOfKeyAttr,
+                                         offset);
     Uint32 tableDescriptorRef= allocTabDescr(allocSize);
-    if (tableDescriptorRef == RNIL) {
+    if (tableDescriptorRef == RNIL)
+    {
       jam();
-      fragrefuse4Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId);
-      return;
+      goto error;
     }
     setUpDescriptorReferences(tableDescriptorRef, regTabPtr.p, offset);
-  } else {
-    jam();
-    fragOperPtr.p->definingFragment= false;
   }
-  signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
-  signal->theData[1]= fragOperPtr.i;
-  signal->theData[2]= regFragPtr.i;
-  signal->theData[3]= fragId;
-  sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUPFRAGCONF, signal, 4, JBB);
-  return;
-}
 
-bool Dbtup::addfragtotab(Tablerec* const regTabPtr,
-                         Uint32 fragId,
-                         Uint32 fragIndex) 
-{
-  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
-    jam();
-    if (regTabPtr->fragid[i] == RNIL) {
-      jam();
-      regTabPtr->fragid[i]= fragId;
-      regTabPtr->fragrec[i]= fragIndex;
-      return true;
-    }
+  {
+    CreateTabConf* conf = (CreateTabConf*)signal->getDataPtrSend();
+    conf->senderData = req->senderData;
+    conf->senderRef = reference();
+    conf->tupConnectPtr = fragOperPtr.i;
+    sendSignal(req->senderRef, GSN_CREATE_TAB_CONF, signal,
+               CreateTabConf::SignalLength, JBB);
   }
-  return false;
-}
 
-void Dbtup::getFragmentrec(FragrecordPtr& regFragPtr,
-                           Uint32 fragId,
-                           Tablerec* const regTabPtr) 
-{
-  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
-    jam();
-    if (regTabPtr->fragid[i] == fragId) {
-      jam();
-      regFragPtr.i= regTabPtr->fragrec[i];
-      ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
-      return;
-    }
-  }
-  regFragPtr.i= RNIL;
-  ptrNull(regFragPtr);
-}
-
-void Dbtup::seizeFragrecord(FragrecordPtr& regFragPtr) 
-{
-  regFragPtr.i= cfirstfreefrag;
-  ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
-  cfirstfreefrag= regFragPtr.p->nextfreefrag;
-  regFragPtr.p->nextfreefrag= RNIL;
-  RSS_OP_ALLOC(cnoOfFreeFragrec);
-}
+  return;
 
-void Dbtup::seizeFragoperrec(FragoperrecPtr& fragOperPtr) 
-{
-  fragOperPtr.i= cfirstfreeFragopr;
-  ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
-  cfirstfreeFragopr = fragOperPtr.p->nextFragoprec;
-  fragOperPtr.p->nextFragoprec = RNIL;
-  fragOperPtr.p->inUse = true;
-  RSS_OP_ALLOC(cnoOfFreeFragoprec);
-}//Dbtup::seizeFragoperrec()
+error:
+  regTabPtr.p->tableStatus = NOT_DEFINED;
+  releaseFragoperrec(fragOperPtr);
 
-void Dbtup::seizeAlterTabOperation(AlterTabOperationPtr& alterTabOpPtr)
-{
-  alterTabOpPtr.i= cfirstfreeAlterTabOp;
-  ptrCheckGuard(alterTabOpPtr, cnoOfAlterTabOps, alterTabOperRec);
-  cfirstfreeAlterTabOp= alterTabOpPtr.p->nextAlterTabOp;
-  alterTabOpPtr.p->nextAlterTabOp= RNIL;
+sendref:
+  CreateTabRef* ref = (CreateTabRef*)signal->getDataPtrSend();
+  ref->senderData = req->senderData;
+  ref->senderRef = reference();
+  ref->errorCode = terrorCode;
+  sendSignal(req->senderRef, GSN_CREATE_TAB_REF, signal,
+             CreateTabRef::SignalLength, JBB);
 }
 
-/* **************************************************************** */
-/* **************          TUP_ADD_ATTRREQ       ****************** */
-/* **************************************************************** */
 void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
 {
-  FragrecordPtr regFragPtr;
   FragoperrecPtr fragOperPtr;
   TablerecPtr regTabPtr;
 
@@ -310,60 +164,10 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
   regTabPtr.i= fragOperPtr.p->tableidFrag;
   ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
 
-  Uint32 fragId= fragOperPtr.p->fragidFrag;
-
-  getFragmentrec(regFragPtr, fragId, regTabPtr.p);
-  ndbrequire(regFragPtr.i != RNIL);
-
   ndbrequire(fragOperPtr.p->attributeCount > 0);
   fragOperPtr.p->attributeCount--;
   const bool lastAttr = (fragOperPtr.p->attributeCount == 0);
 
-  if (ERROR_INSERTED(4009) && regTabPtr.p->fragid[0] == fragId && attrId == 0||
-      ERROR_INSERTED(4010) && regTabPtr.p->fragid[0] == fragId && lastAttr ||
-      ERROR_INSERTED(4011) && regTabPtr.p->fragid[1] == fragId && attrId == 0||
-      ERROR_INSERTED(4012) && regTabPtr.p->fragid[1] == fragId && lastAttr) {
-    jam();
-    terrorCode = 1;
-    addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
-    CLEAR_ERROR_INSERT_VALUE;
-    return;
-  }
-
-  if (regTabPtr.p->tableStatus != DEFINING)
-  {
-    ndbrequire(regTabPtr.p->tableStatus == DEFINED);
-    signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
-    signal->theData[1] = lastAttr;
-    sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF, 
-	       signal, 2, JBB);
-    
-    if(lastAttr)
-    {
-      jam();
-      /**
-       * Init Disk_alloc_info
-       */
-      CreateFilegroupImplReq rep;
-      if(regTabPtr.p->m_no_of_disk_attributes)
-      {
-	Tablespace_client tsman(0, c_tsman, 0, 0, 
-				regFragPtr.p->m_tablespace_id);
-	ndbrequire(tsman.get_tablespace_info(&rep) == 0);
-	regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id;
-      }
-      else
-      {
-	jam();
-	regFragPtr.p->m_logfile_group_id = RNIL;
-      }
-      new (&regFragPtr.p->m_disk_alloc_info)
-	Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size);
-      releaseFragoperrec(fragOperPtr);      
-    }
-    return;
-  }
-    
   Uint32 firstTabDesIndex= regTabPtr.p->tabDescriptor + (attrId * ZAD_SIZE);
   setTabDescrWord(firstTabDesIndex, attrDescriptor);
   Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
@@ -408,12 +212,12 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
     ndbrequire(ind==MM);
     regTabPtr.p->m_attributes[ind].m_no_of_dynamic++;
     /*
-       The dynamic attribute format always require a 'null' bit. So
-       storing NOT NULL attributes as dynamic is not all that useful
-       (but not harmful in any way either).
-       Later we might implement NOT NULL DEFAULT xxx by storing the value
-       xxx internally as 'null'.
-    */
+     * The dynamic attribute format always require a 'null' bit. So
+     * storing NOT NULL attributes as dynamic is not all that useful
+     * (but not harmful in any way either).
+     * Later we might implement NOT NULL DEFAULT xxx by storing the value
+     * xxx internally as 'null'.
+     */
 
     Uint32 null_pos= regTabPtr.p->m_dyn_null_bits;
 
@@ -423,16 +227,16 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
       jam();
       if (AttributeDescriptor::getSize(attrDescriptor)==0)
       {
-        /*
-          Bit type. These are stored directly in the bitmap.
-          This means that we will still use some space for a dynamic NULL
-          bittype if a following dynamic attribute is non-NULL.
-        */
+        /**
+         * Bit type. These are stored directly in the bitmap.
+         * This means that we will still use some space for a dynamic NULL
+         * bittype if a following dynamic attribute is non-NULL.
+         */
         Uint32 bits= AttributeDescriptor::getArraySize(attrDescriptor);
-        /*
-          The NULL bit is stored after the data bits, so that we automatically
-          ensure that the full size bitmap is stored when non-NULL.
-        */
+        /**
+         * The NULL bit is stored after the data bits, so that we automatically
+         * ensure that the full size bitmap is stored when non-NULL.
+         */
         null_pos+= bits;
         regTabPtr.p->m_dyn_null_bits+= bits+1;
       }
@@ -440,10 +244,10 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
       {
         jam();
         /*
-          We use one NULL bit per 4 bytes of dynamic fixed-size attribute. So
-          for dynamic fixsize longer than 64 bytes (16 null bits), it is more
-          efficient to store them as dynamic varsize internally.
-        */
+         * We use one NULL bit per 4 bytes of dynamic fixed-size attribute. So
+         * for dynamic fixsize longer than 64 bytes (16 null bits), it is more
+         * efficient to store them as dynamic varsize internally.
+         */
         if(words > InternalMaxDynFix)
           goto treat_as_varsize;
 
@@ -455,7 +259,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
     else
     {
       /* A variable-sized dynamic attribute. */
-    treat_as_varsize:
+  treat_as_varsize:
       jam();
       regTabPtr.p->m_attributes[ind].m_no_of_dyn_var++;
       regTabPtr.p->m_dyn_null_bits++;
@@ -471,10 +275,17 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
                    fragOperPtr.p->charsetIndex, attrDes2);
   setTabDescrWord(firstTabDesIndex + 1, attrDes2);
 
-/* **************************************************************** */
-/* **************          TUP_ADD_ATTCONF       ****************** */
-/* **************************************************************** */
-  if (! lastAttr) {
+  if (ERROR_INSERTED(4009) && attrId == 0 ||
+      ERROR_INSERTED(4010) && lastAttr)
+  {
+    jam();
+    CLEAR_ERROR_INSERT_VALUE;
+    terrorCode = 1;
+    goto error;
+  }
+
+  if (! lastAttr)
+  {
     jam();
     signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
     signal->theData[1] = lastAttr;
@@ -483,26 +294,24 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
     return;
   }
   
-  ndbrequire(regTabPtr.p->tableStatus == DEFINING);
-  regTabPtr.p->tableStatus= DEFINED;
-  regFragPtr.p->fragStatus= ACTIVE;
-  
 #define BTW(x) ((x+31) >> 5)
   regTabPtr.p->m_offsets[MM].m_null_words= BTW(fragOperPtr.p->m_null_bits[MM]);
   regTabPtr.p->m_offsets[DD].m_null_words= BTW(fragOperPtr.p->m_null_bits[DD]);
 #undef BTW
 
-  /* Allocate  dynamic descriptor. */
-  Uint32 offset[3];
-  Uint32 allocSize= getDynTabDescrOffsets((regTabPtr.p->m_dyn_null_bits+31)>>5,
-                                          offset);
-  Uint32 dynTableDescriptorRef= allocTabDescr(allocSize);
-  if (dynTableDescriptorRef == RNIL) {
-    jam();
-    addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
-    return;
+  {
+    /* Allocate  dynamic descriptor. */
+    Uint32 offset[3];
+    Uint32 allocSize= getDynTabDescrOffsets((regTabPtr.p->m_dyn_null_bits+31)>>5,
+                                            offset);
+    Uint32 dynTableDescriptorRef= allocTabDescr(allocSize);
+    if (dynTableDescriptorRef == RNIL)
+    {
+      jam();
+      goto error;
+    }
+    setupDynDescriptorReferences(dynTableDescriptorRef, regTabPtr.p, offset);
   }
-  setupDynDescriptorReferences(dynTableDescriptorRef, regTabPtr.p, offset);
 
   /* Compute table aggregate metadata. */
   computeTableMetaData(regTabPtr.p);
@@ -519,47 +328,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
   }
 #endif
   
-  {
-#ifdef MIN_ROWS_NOT_SUPPORTED
-    Uint32 fix_tupheader = regTabPtr.p->m_offsets[MM].m_fix_header_size;
-    ndbassert(fix_tupheader > 0);
-    Uint32 noRowsPerPage = ZWORDS_ON_PAGE / fix_tupheader;
-    Uint32 noAllocatedPages =
-      (fragOperPtr.p->minRows + noRowsPerPage - 1 )/ noRowsPerPage;
-    if (fragOperPtr.p->minRows == 0)
-      noAllocatedPages = 2;
-    else if (noAllocatedPages == 0)
-      noAllocatedPages = 2;
-#endif
-    
-    Uint32 noAllocatedPages = 1; //allocFragPage(regFragPtr.p);
-    
-    if (noAllocatedPages == 0) {
-      jam();
-      terrorCode = ZNO_PAGES_ALLOCATED_ERROR;
-      addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
-      return;
-    }//if
-  }
-
-  CreateFilegroupImplReq rep;
-  if(regTabPtr.p->m_no_of_disk_attributes)
-  {
-    jam();
-    Tablespace_client tsman(0, c_tsman, 0, 0, 
-			    regFragPtr.p->m_tablespace_id);
-    ndbrequire(tsman.get_tablespace_info(&rep) == 0);
-    regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id;
-  }
-  else
-  {
-    jam();
-    regFragPtr.p->m_logfile_group_id = RNIL;
-  }
-
-  new (&regFragPtr.p->m_disk_alloc_info)
-    Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size); 
-  
+#if SYNC_TABLE
   if (regTabPtr.p->m_no_of_disk_attributes)
   {
     jam();
@@ -596,15 +365,234 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
       return;
     }
   }
-  
+#endif
+
+  ndbrequire(regTabPtr.p->tableStatus == DEFINING);
+  regTabPtr.p->tableStatus= DEFINED;
+
   signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
   signal->theData[1] = lastAttr;
   sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF, 
 	     signal, 2, JBB);
 
   releaseFragoperrec(fragOperPtr);
+  return;
+error:
+  signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
+  signal->theData[1]= terrorCode;
+  sendSignal(fragOperPtr.p->lqhBlockrefFrag,
+             GSN_TUP_ADD_ATTRREF, signal, 2, JBB);
+  
+  return;
+}
+
+void Dbtup::execTUPFRAGREQ(Signal* signal)
+{
+  jamEntry();
+
+  TupFragReq copy = *(TupFragReq*)signal->getDataPtr();
+  TupFragReq* req = &copy;
+
+  FragrecordPtr regFragPtr;
+
+  Uint32 tableId        = req->tableId;
+  Uint32 userptr        = req->userPtr;
+  Uint32 userRef        = req->userRef;
+  Uint32 reqinfo        = req->reqInfo;
+  Uint32 fragId         = req->fragId;
+  Uint32 tablespace_id  = req->tablespaceid;
+
+  Uint64 maxRows =
+    (((Uint64)req->maxRowsHigh) << 32) + req->maxRowsLow;
+  Uint64 minRows =
+    (((Uint64)req->minRowsHigh) << 32) + req->minRowsLow;
+
+  if (req->userPtr == (Uint32)-1) 
+  {
+    jam();
+    abortAddFragOp(signal);
+    return;
+  }
+  
+#ifndef VM_TRACE
+  // config mismatch - do not crash if release compiled
+  if (tableId >= cnoOfTablerec)
+  {
+    jam();
+    req->userPtr = userptr;
+    req->userRef = 800;
+    sendSignal(userblockref, GSN_TUPFRAGREF, signal, 2, JBB);
+    return;
+  }
+#endif
+
+  TablerecPtr regTabPtr;
+  regTabPtr.i = tableId;
+  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
+
+  getFragmentrec(regFragPtr, fragId, regTabPtr.p);
+  if (regFragPtr.i != RNIL)
+  {
+    jam();
+    terrorCode= ZEXIST_FRAG_ERROR;
+    goto sendref;
+  }
+
+  if (cfirstfreefrag != RNIL)
+  {
+    jam();
+    seizeFragrecord(regFragPtr);
+  }
+  else
+  {
+    jam();
+    terrorCode= ZFULL_FRAGRECORD_ERROR;
+    goto sendref;
+  }
+
+  {
+#ifdef MIN_ROWS_NOT_SUPPORTED
+    Uint32 fix_tupheader = regTabPtr.p->m_offsets[MM].m_fix_header_size;
+    ndbassert(fix_tupheader > 0);
+    Uint32 noRowsPerPage = ZWORDS_ON_PAGE / fix_tupheader;
+    Uint32 noAllocatedPages = (minRows + noRowsPerPage - 1 )/ noRowsPerPage;
+    if (minRows == 0)
+      noAllocatedPages = 2;
+    else if (noAllocatedPages == 0)
+      noAllocatedPages = 2;
+#endif
+
+    Uint32 noAllocatedPages = 1; //allocFragPage(regFragPtr.p);
+
+    if (noAllocatedPages == 0)
+    {
+      jam();
+      releaseFragrec(regFragPtr);
+      terrorCode = ZNO_PAGES_ALLOCATED_ERROR;
+      goto sendref;
+    }
+  }
+
+  if (!addfragtotab(regTabPtr.p, fragId, regFragPtr.i))
+  {
+    jam();
+    releaseFragrec(regFragPtr);
+    terrorCode= ZNO_FREE_TAB_ENTRY_ERROR;
+    goto sendref;
+  }
+
+  if (ERROR_INSERTED(4007) && regTabPtr.p->fragid[0] == fragId ||
+      ERROR_INSERTED(4008) && regTabPtr.p->fragid[1] == fragId)
+  {
+    jam();
+    CLEAR_ERROR_INSERT_VALUE;
+    terrorCode = 1;
+    goto sendref;
+  }
+
+  regFragPtr.p->fragTableId= regTabPtr.i;
+  regFragPtr.p->fragmentId= fragId;
+  regFragPtr.p->m_tablespace_id= tablespace_id;
+  regFragPtr.p->m_undo_complete= false;
+  regFragPtr.p->m_lcp_scan_op = RNIL;
+  regFragPtr.p->m_lcp_keep_list = RNIL;
+  regFragPtr.p->noOfPages = 0;
+  regFragPtr.p->noOfVarPages = 0;
+  regFragPtr.p->m_max_page_no = 0;
+  regFragPtr.p->m_free_page_id_list = FREE_PAGE_RNIL;
+  ndbrequire(regFragPtr.p->m_page_map.isEmpty());
+  regFragPtr.p->m_restore_lcp_id = RNIL;
+  for (Uint32 i = 0; i<MAX_FREE_LIST+1; i++)
+    ndbrequire(regFragPtr.p->free_var_page_array[i].isEmpty());
+
+  CreateFilegroupImplReq rep;
+  if(regTabPtr.p->m_no_of_disk_attributes)
+  {
+    Tablespace_client tsman(0, c_tsman, 0, 0,
+                            regFragPtr.p->m_tablespace_id);
+    ndbrequire(tsman.get_tablespace_info(&rep) == 0);
+    regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id;
+  }
+  else
+  {
+    jam();
+    regFragPtr.p->m_logfile_group_id = RNIL;
+  }
+  new (&regFragPtr.p->m_disk_alloc_info)
+    Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size);
+
+  signal->theData[0]= userptr;
+  signal->theData[1]= fragId;
+  signal->theData[2]= regFragPtr.i;
+  sendSignal(userRef, GSN_TUPFRAGCONF, signal, 3, JBB);
 
   return;
+
+sendref:
+
+  signal->theData[0]= userptr;
+  signal->theData[1]= terrorCode;
+  sendSignal(userRef, GSN_TUPFRAGREF, signal, 2, JBB);
+}
+
+bool Dbtup::addfragtotab(Tablerec* const regTabPtr,
+                         Uint32 fragId,
+                         Uint32 fragIndex)
+{
+  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
+    jam();
+    if (regTabPtr->fragid[i] == RNIL) {
+      jam();
+      regTabPtr->fragid[i]= fragId;
+      regTabPtr->fragrec[i]= fragIndex;
+      return true;
+    }
+  }
+  return false;
+}
+
+void Dbtup::getFragmentrec(FragrecordPtr& regFragPtr,
+                           Uint32 fragId,
+                           Tablerec* const regTabPtr)
+{
+  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
+    jam();
+    if (regTabPtr->fragid[i] == fragId) {
+      jam();
+      regFragPtr.i= regTabPtr->fragrec[i];
+      ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
+      return;
+    }
+  }
+  regFragPtr.i= RNIL;
+  ptrNull(regFragPtr);
+}
+
+void Dbtup::seizeFragrecord(FragrecordPtr& regFragPtr)
+{
+  regFragPtr.i= cfirstfreefrag;
+  ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
+  cfirstfreefrag= regFragPtr.p->nextfreefrag;
+  regFragPtr.p->nextfreefrag= RNIL;
+  RSS_OP_ALLOC(cnoOfFreeFragrec);
+}
+
+void Dbtup::seizeFragoperrec(FragoperrecPtr& fragOperPtr)
+{
+  fragOperPtr.i= cfirstfreeFragopr;
+  ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
+  cfirstfreeFragopr = fragOperPtr.p->nextFragoprec;
+  fragOperPtr.p->nextFragoprec = RNIL;
+  fragOperPtr.p->inUse = true;
+  RSS_OP_ALLOC(cnoOfFreeFragoprec);
+}//Dbtup::seizeFragoperrec()
+
+void Dbtup::seizeAlterTabOperation(AlterTabOperationPtr& alterTabOpPtr)
+{
+  alterTabOpPtr.i= cfirstfreeAlterTabOp;
+  ptrCheckGuard(alterTabOpPtr, cnoOfAlterTabOps, alterTabOperRec);
+  cfirstfreeAlterTabOp= alterTabOpPtr.p->nextAlterTabOp;
+  alterTabOpPtr.p->nextAlterTabOp= RNIL;
 }
 
 void
@@ -1343,77 +1331,6 @@ void Dbtup::setUpKeyArray(Tablerec* cons
   ndbrequire(cnt == regTabPtr->m_no_of_attributes);
 }
 
-void Dbtup::addattrrefuseLab(Signal* signal,
-                             FragrecordPtr regFragPtr,
-                             FragoperrecPtr fragOperPtr,
-                             Tablerec* const regTabPtr,
-                             Uint32 fragId) 
-{
-  deleteFragTab(regTabPtr, fragId);
-  releaseFragrec(regFragPtr);
-  releaseTabDescr(regTabPtr);
-
-  signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
-  signal->theData[1]= terrorCode;
-  sendSignal(fragOperPtr.p->lqhBlockrefFrag,
-              GSN_TUP_ADD_ATTRREF, signal, 2, JBB);
-  releaseFragoperrec(fragOperPtr);
-}
-
-void Dbtup::fragrefuse4Lab(Signal* signal,
-                           FragoperrecPtr fragOperPtr,
-                           FragrecordPtr regFragPtr,
-                           Tablerec* const regTabPtr,
-                           Uint32 fragId)
-{
-  bool found = false;
-  for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) 
-  {
-    jam();
-    if (regTabPtr->fragid[i] == fragId) 
-    {
-      jam();
-      ndbrequire(regTabPtr->fragrec[i] == regFragPtr.i);
-      regTabPtr->fragid[i] = RNIL;
-      regTabPtr->fragrec[i] = RNIL;
-      found = true;
-      break;
-    }
-  }
-  ndbrequire(found);
-  fragrefuse3Lab(signal, fragOperPtr, regFragPtr, regTabPtr, fragId);
-}
-
-void Dbtup::fragrefuse3Lab(Signal* signal,
-                           FragoperrecPtr fragOperPtr,
-                           FragrecordPtr regFragPtr,
-                           Tablerec* const regTabPtr,
-                           Uint32 fragId) 
-{
-  fragrefuse2Lab(signal, fragOperPtr, regFragPtr);
-}
-
-void Dbtup::fragrefuse2Lab(Signal* signal,
-                           FragoperrecPtr fragOperPtr,
-                           FragrecordPtr regFragPtr) 
-{
-  fragrefuse1Lab(signal, fragOperPtr);
-  releaseFragrec(regFragPtr);
-}
-
-void Dbtup::fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr) 
-{
-  fragrefuseLab(signal, fragOperPtr);
-  releaseFragoperrec(fragOperPtr);
-}
-
-void Dbtup::fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr) 
-{
-  signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
-  signal->theData[1]= terrorCode;
-  sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUPFRAGREF, signal, 2, JBB);
-}
-
 void Dbtup::releaseFragoperrec(FragoperrecPtr fragOperPtr) 
 {
   fragOperPtr.p->inUse = false;
@@ -1473,19 +1390,6 @@ Dbtup::execDROP_TAB_REQ(Signal* signal)
   
   tabPtr.p->m_dropTable.tabUserRef = req->senderRef;
   tabPtr.p->m_dropTable.tabUserPtr = req->senderData;
-
-  if (tabPtr.p->tableStatus == NOT_DEFINED) 
-  {
-    jam();
-    DropTabConf * const dropConf= (DropTabConf *)signal->getDataPtrSend();
-    dropConf->senderRef= reference();
-    dropConf->senderData= tabPtr.p->m_dropTable.tabUserPtr;
-    dropConf->tableId= tabPtr.i;
-    sendSignal(tabPtr.p->m_dropTable.tabUserRef, GSN_DROP_TAB_CONF,
-               signal, DropTabConf::SignalLength, JBB);
-    return;
-  }
-
   tabPtr.p->tableStatus = DROPPING;
 
   signal->theData[0]= ZREL_FRAG;
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
--- a/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp	2008-05-30 08:36:54 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp	2008-05-31 08:36:31 +02:00
@@ -562,6 +562,7 @@ private:
   /*
    * DbtuxMeta.cpp
    */
+  void execCREATE_TAB_REQ(Signal*);
   void execTUXFRAGREQ(Signal* signal);
   void execTUX_ADD_ATTRREQ(Signal* signal);
   void execALTER_INDX_IMPL_REQ(Signal* signal);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp	2007-12-25 17:34:13 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp	2008-05-31 08:36:31 +02:00
@@ -48,6 +48,7 @@ Dbtux::Dbtux(Block_context& ctx) :
   /*
    * DbtuxMeta.cpp
    */
+  addRecSignal(GSN_CREATE_TAB_REQ, &Dbtux::execCREATE_TAB_REQ);
   addRecSignal(GSN_TUXFRAGREQ, &Dbtux::execTUXFRAGREQ);
   addRecSignal(GSN_TUX_ADD_ATTRREQ, &Dbtux::execTUX_ADD_ATTRREQ);
   addRecSignal(GSN_ALTER_INDX_IMPL_REQ, &Dbtux::execALTER_INDX_IMPL_REQ);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp	2007-12-25 17:34:14 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp	2008-05-31 08:36:31 +02:00
@@ -23,24 +23,31 @@
  * For historical reasons it looks like we are adding random fragments
  * and attributes to existing index.  In fact all fragments must be
  * created at one time and they have identical attributes.
+ *
+ * But history changes?
+ * Now index will be created using the sequence
+ *   CREATE_TAB_REQ
+ *     TUP_ADD_ATTR_REQ +
+ *
+ * Followed by 0-N
+ *   TUXFRAGREQ
  */
 
+#include <signaldata/CreateTab.hpp>
+
 void
-Dbtux::execTUXFRAGREQ(Signal* signal)
+Dbtux::execCREATE_TAB_REQ(Signal* signal)
 {
   jamEntry();
-  if (signal->theData[0] == (Uint32)-1) {
-    jam();
-    abortAddFragOp(signal);
-    return;
-  }
-  const TuxFragReq reqCopy = *(const TuxFragReq*)signal->getDataPtr();
-  const TuxFragReq* const req = &reqCopy;
+  CreateTabReq copy = *(CreateTabReq*)signal->getDataPtr();
+  CreateTabReq* req = &copy;
+
   IndexPtr indexPtr;
   indexPtr.i = RNIL;
   FragOpPtr fragOpPtr;
   fragOpPtr.i = RNIL;
-  TuxFragRef::ErrorCode errorCode = TuxFragRef::NoError;
+  Uint32 errorCode = 0;
+
   do {
     // get the index record
     if (req->tableId >= c_indexPool.getSize()) {
@@ -49,22 +56,23 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
       break;
     }
     c_indexPool.getPtr(indexPtr, req->tableId);
-    if (indexPtr.p->m_state != Index::NotDefined &&
-        indexPtr.p->m_state != Index::Defining) {
+    if (indexPtr.p->m_state != Index::NotDefined)
+    {
       jam();
       errorCode = TuxFragRef::InvalidRequest;
       indexPtr.i = RNIL;        // leave alone
       break;
     }
+
     // get new operation record
     c_fragOpPool.seize(fragOpPtr);
     ndbrequire(fragOpPtr.i != RNIL);
     new (fragOpPtr.p) FragOp();
-    fragOpPtr.p->m_userPtr = req->userPtr;
-    fragOpPtr.p->m_userRef = req->userRef;
+    fragOpPtr.p->m_userPtr = req->senderData;
+    fragOpPtr.p->m_userRef = req->senderRef;
     fragOpPtr.p->m_indexId = req->tableId;
-    fragOpPtr.p->m_fragId = req->fragId;
-    fragOpPtr.p->m_fragNo = indexPtr.p->m_numFrags;
+    fragOpPtr.p->m_fragId = RNIL;
+    fragOpPtr.p->m_fragNo = RNIL;
     fragOpPtr.p->m_numAttrsRecvd = 0;
 #ifdef VM_TRACE
     if (debugFlags & DebugMeta) {
@@ -72,68 +80,24 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
     }
 #endif
     // check if index has place for more fragments
-    ndbrequire(indexPtr.p->m_numFrags < MaxIndexFragments);
-    // seize new fragment record
-    FragPtr fragPtr;
-    c_fragPool.seize(fragPtr);
-    if (fragPtr.i == RNIL) {
+    ndbrequire(indexPtr.p->m_state == Index::NotDefined &&
+               DictTabInfo::isOrderedIndex(req->tableType) &&
+               req->noOfAttributes > 0 &&
+               req->noOfAttributes <= MaxIndexAttributes &&
+               indexPtr.p->m_descPage == RNIL);
+
+    indexPtr.p->m_state = Index::Defining;
+    indexPtr.p->m_tableType = (DictTabInfo::TableType)req->tableType;
+    indexPtr.p->m_tableId = req->primaryTableId;
+    indexPtr.p->m_numAttrs = req->noOfAttributes;
+    indexPtr.p->m_storeNullKey = true;  // not yet configurable
+    // allocate attribute descriptors
+    if (! allocDescEnt(indexPtr)) {
       jam();
-      errorCode = TuxFragRef::NoFreeFragment;
+      errorCode = TuxFragRef::NoFreeAttributes;
       break;
     }
-    new (fragPtr.p) Frag(c_scanOpPool);
-    fragPtr.p->m_tableId = req->primaryTableId;
-    fragPtr.p->m_indexId = req->tableId;
-    fragPtr.p->m_fragId = req->fragId;
-    fragPtr.p->m_numAttrs = req->noOfAttr;
-    fragPtr.p->m_storeNullKey = true;  // not yet configurable
-    fragPtr.p->m_tupIndexFragPtrI = req->tupIndexFragPtrI;
-    fragPtr.p->m_tupTableFragPtrI = req->tupTableFragPtrI[0];
-    fragPtr.p->m_accTableFragPtrI = req->accTableFragPtrI[0];
-    // add the fragment to the index
-    indexPtr.p->m_fragId[indexPtr.p->m_numFrags] = req->fragId;
-    indexPtr.p->m_fragPtrI[indexPtr.p->m_numFrags] = fragPtr.i;
-    indexPtr.p->m_numFrags++;
-    // save under operation
-    fragOpPtr.p->m_fragPtrI = fragPtr.i;
-    // prepare to receive attributes
-    if (fragOpPtr.p->m_fragNo == 0) {
-      jam();
-      // receiving first fragment
-      ndbrequire(
-          indexPtr.p->m_state == Index::NotDefined &&
-          DictTabInfo::isOrderedIndex(req->tableType) &&
-          req->noOfAttr > 0 &&
-          req->noOfAttr <= MaxIndexAttributes &&
-          indexPtr.p->m_descPage == RNIL);
-      indexPtr.p->m_state = Index::Defining;
-      indexPtr.p->m_tableType = (DictTabInfo::TableType)req->tableType;
-      indexPtr.p->m_tableId = req->primaryTableId;
-      indexPtr.p->m_numAttrs = req->noOfAttr;
-      indexPtr.p->m_storeNullKey = true;  // not yet configurable
-      // allocate attribute descriptors
-      if (! allocDescEnt(indexPtr)) {
-        jam();
-        errorCode = TuxFragRef::NoFreeAttributes;
-        break;
-      }
-    } else {
-      // receiving subsequent fragment
-      jam();
-      ndbrequire(
-          indexPtr.p->m_state == Index::Defining &&
-          indexPtr.p->m_tableType == (DictTabInfo::TableType)req->tableType &&
-          indexPtr.p->m_tableId == req->primaryTableId &&
-          indexPtr.p->m_numAttrs == req->noOfAttr);
-    }
-    // copy metadata address to each fragment
-    fragPtr.p->m_descPage = indexPtr.p->m_descPage;
-    fragPtr.p->m_descOff = indexPtr.p->m_descOff;
-#ifdef VM_TRACE
-    if (debugFlags & DebugMeta) {
-      debugOut << "Add frag " << fragPtr.i << " " << *fragPtr.p << endl;
-    }
-#endif
+
     // error inserts
     if (ERROR_INSERTED(12001) && fragOpPtr.p->m_fragNo == 0 ||
         ERROR_INSERTED(12002) && fragOpPtr.p->m_fragNo == 1) {
@@ -143,33 +107,32 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
       break;
     }
     // success
-    TuxFragConf* const conf = (TuxFragConf*)signal->getDataPtrSend();
-    conf->userPtr = req->userPtr;
+    CreateTabConf* conf = (CreateTabConf*)signal->getDataPtrSend();
+    conf->senderRef = reference();
+    conf->senderData = req->senderData;
     conf->tuxConnectPtr = fragOpPtr.i;
-    conf->fragPtr = fragPtr.i;
-    conf->fragId = fragPtr.p->m_fragId;
-    sendSignal(req->userRef, GSN_TUXFRAGCONF,
-        signal, TuxFragConf::SignalLength, JBB);
+    sendSignal(req->senderRef, GSN_CREATE_TAB_CONF,
+               signal, CreateTabConf::SignalLength, JBB);
     return;
   } while (0);
   // error
-  TuxFragRef* const ref = (TuxFragRef*)signal->getDataPtrSend();
-  ref->userPtr = req->userPtr;
+
+  CreateTabRef* const ref = (CreateTabRef*)signal->getDataPtrSend();
+  ref->senderData = req->senderData;
   ref->errorCode = errorCode;
-  sendSignal(req->userRef, GSN_TUXFRAGREF,
-      signal, TuxFragRef::SignalLength, JBB);
-  if (fragOpPtr.i != RNIL) {
-#ifdef VM_TRACE
-    if (debugFlags & DebugMeta) {
-      debugOut << "Release on frag error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
-    }
-#endif
-    c_fragOpPool.release(fragOpPtr);
-  }
+  sendSignal(req->senderRef, GSN_CREATE_TAB_REF,
+             signal, CreateTabRef::SignalLength, JBB);
+
   if (indexPtr.i != RNIL) {
     jam();
     // let DICT drop the unfinished index
   }
+
+  if (fragOpPtr.i != RNIL)
+  {
+    jam();
+    c_fragOpPool.release(fragOpPtr);
+  }
 }
 
 void
@@ -181,10 +144,8 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signa
   // get the records
   FragOpPtr fragOpPtr;
   IndexPtr indexPtr;
-  FragPtr fragPtr;
   c_fragOpPool.getPtr(fragOpPtr, req->tuxConnectPtr);
   c_indexPool.getPtr(indexPtr, fragOpPtr.p->m_indexId);
-  c_fragPool.getPtr(fragPtr, fragOpPtr.p->m_fragPtrI);
   TuxAddAttrRef::ErrorCode errorCode = TuxAddAttrRef::NoError;
   do {
     // expected attribute id
@@ -202,7 +163,7 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signa
     descAttr.m_charset = (req->extTypeInfo >> 16);
 #ifdef VM_TRACE
     if (debugFlags & DebugMeta) {
-      debugOut << "Add frag " << fragPtr.i << " attr " << attrId << " " << descAttr << endl;
+      debugOut << "attr " << attrId << " " << descAttr << endl;
     }
 #endif
     // check that type is valid and has a binary comparison method
@@ -224,56 +185,14 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signa
       }
     }
     const bool lastAttr = (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd);
-    if (ERROR_INSERTED(12003) && fragOpPtr.p->m_fragNo == 0 && attrId == 0 ||
-        ERROR_INSERTED(12004) && fragOpPtr.p->m_fragNo == 0 && lastAttr ||
-        ERROR_INSERTED(12005) && fragOpPtr.p->m_fragNo == 1 && attrId == 0 ||
-        ERROR_INSERTED(12006) && fragOpPtr.p->m_fragNo == 1 && lastAttr) {
+    if (ERROR_INSERTED(12003) && attrId == 0 ||
+        ERROR_INSERTED(12004) && lastAttr)
+    {
       errorCode = (TuxAddAttrRef::ErrorCode)1;
       CLEAR_ERROR_INSERT_VALUE;
       break;
     }
     if (lastAttr) {
-      jam();
-      // initialize tree header
-      TreeHead& tree = fragPtr.p->m_tree;
-      new (&tree) TreeHead();
-      // make these configurable later
-      tree.m_nodeSize = MAX_TTREE_NODE_SIZE;
-      tree.m_prefSize = MAX_TTREE_PREF_SIZE;
-      const unsigned maxSlack = MAX_TTREE_NODE_SLACK;
-      // size up to and including first 2 entries
-      const unsigned pref = tree.getSize(AccPref);
-      if (! (pref <= tree.m_nodeSize)) {
-        jam();
-        errorCode = TuxAddAttrRef::InvalidNodeSize;
-        break;
-      }
-      const unsigned slots = (tree.m_nodeSize - pref) / TreeEntSize;
-      // leave out work space entry
-      tree.m_maxOccup = 2 + slots - 1;
-      // min occupancy of interior node must be at least 2
-      if (! (2 + maxSlack <= tree.m_maxOccup)) {
-        jam();
-        errorCode = TuxAddAttrRef::InvalidNodeSize;
-        break;
-      }
-      tree.m_minOccup = tree.m_maxOccup - maxSlack;
-      // root node does not exist (also set by ctor)
-      tree.m_root = NullTupLoc;
-#ifdef VM_TRACE
-      if (debugFlags & DebugMeta) {
-        if (fragOpPtr.p->m_fragNo == 0) {
-          debugOut << "Index id=" << indexPtr.i;
-          debugOut << " nodeSize=" << tree.m_nodeSize;
-          debugOut << " headSize=" << NodeHeadSize;
-          debugOut << " prefSize=" << tree.m_prefSize;
-          debugOut << " entrySize=" << TreeEntSize;
-          debugOut << " minOccup=" << tree.m_minOccup;
-          debugOut << " maxOccup=" << tree.m_maxOccup;
-          debugOut << endl;
-        }
-      }
-#endif
       // fragment is defined
 #ifdef VM_TRACE
       if (debugFlags & DebugMeta) {
@@ -301,8 +220,145 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signa
       debugOut << "Release on attr error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
     }
 #endif
-  c_fragOpPool.release(fragOpPtr);
   // let DICT drop the unfinished index
+}
+
+void
+Dbtux::execTUXFRAGREQ(Signal* signal)
+{
+  jamEntry();
+
+  if (signal->theData[0] == (Uint32)-1) {
+    jam();
+    abortAddFragOp(signal);
+    return;
+  }
+
+  const TuxFragReq reqCopy = *(const TuxFragReq*)signal->getDataPtr();
+  const TuxFragReq* const req = &reqCopy;
+  IndexPtr indexPtr;
+  indexPtr.i = RNIL;
+  TuxFragRef::ErrorCode errorCode = TuxFragRef::NoError;
+  do {
+    // get the index record
+    if (req->tableId >= c_indexPool.getSize()) {
+      jam();
+      errorCode = TuxFragRef::InvalidRequest;
+      break;
+    }
+    c_indexPool.getPtr(indexPtr, req->tableId);
+    if (false && indexPtr.p->m_state != Index::Defining) {
+      jam();
+      errorCode = TuxFragRef::InvalidRequest;
+      indexPtr.i = RNIL;        // leave alone
+      break;
+    }
+
+    // check if index has place for more fragments
+    ndbrequire(indexPtr.p->m_numFrags < MaxIndexFragments);
+    // seize new fragment record
+    FragPtr fragPtr;
+    c_fragPool.seize(fragPtr);
+    if (fragPtr.i == RNIL) {
+      jam();
+      errorCode = TuxFragRef::NoFreeFragment;
+      break;
+    }
+    new (fragPtr.p) Frag(c_scanOpPool);
+    fragPtr.p->m_tableId = req->primaryTableId;
+    fragPtr.p->m_indexId = req->tableId;
+    fragPtr.p->m_fragId = req->fragId;
+    fragPtr.p->m_numAttrs = indexPtr.p->m_numAttrs;
+    fragPtr.p->m_storeNullKey = true;  // not yet configurable
+    fragPtr.p->m_tupIndexFragPtrI = req->tupIndexFragPtrI;
+    fragPtr.p->m_tupTableFragPtrI = req->tupTableFragPtrI;
+    fragPtr.p->m_accTableFragPtrI = req->accTableFragPtrI;
+    // add the fragment to the index
+    Uint32 fragNo = indexPtr.p->m_numFrags;
+    indexPtr.p->m_fragId[indexPtr.p->m_numFrags] = req->fragId;
+    indexPtr.p->m_fragPtrI[indexPtr.p->m_numFrags] = fragPtr.i;
+    indexPtr.p->m_numFrags++;
+
+    // copy metadata address to each fragment
+    fragPtr.p->m_descPage = indexPtr.p->m_descPage;
+    fragPtr.p->m_descOff = indexPtr.p->m_descOff;
+#ifdef VM_TRACE
+    if (debugFlags & DebugMeta) {
+      debugOut << "Add frag " << fragPtr.i << " " << *fragPtr.p << endl;
+    }
+#endif
+    // error inserts
+    if (ERROR_INSERTED(12001) && fragNo == 0 ||
+        ERROR_INSERTED(12002) && fragNo == 1) {
+      jam();
+      errorCode = (TuxFragRef::ErrorCode)1;
+      CLEAR_ERROR_INSERT_VALUE;
+      break;
+    }
+
+    // initialize tree header
+    TreeHead& tree = fragPtr.p->m_tree;
+    new (&tree) TreeHead();
+    // make these configurable later
+    tree.m_nodeSize = MAX_TTREE_NODE_SIZE;
+    tree.m_prefSize = MAX_TTREE_PREF_SIZE;
+    const unsigned maxSlack = MAX_TTREE_NODE_SLACK;
+    // size up to and including first 2 entries
+    const unsigned pref = tree.getSize(AccPref);
+    if (! (pref <= tree.m_nodeSize)) {
+      jam();
+      errorCode = (TuxFragRef::ErrorCode)TuxAddAttrRef::InvalidNodeSize;
+      break;
+    }
+    const unsigned slots = (tree.m_nodeSize - pref) / TreeEntSize;
+    // leave out work space entry
+    tree.m_maxOccup = 2 + slots - 1;
+    // min occupancy of interior node must be at least 2
+    if (! (2 + maxSlack <= tree.m_maxOccup)) {
+      jam();
+        errorCode = (TuxFragRef::ErrorCode)TuxAddAttrRef::InvalidNodeSize;
+        break;
+    }
+    tree.m_minOccup = tree.m_maxOccup - maxSlack;
+    // root node does not exist (also set by ctor)
+    tree.m_root = NullTupLoc;
+#ifdef VM_TRACE
+    if (debugFlags & DebugMeta) {
+      if (fragNo == 0) {
+        debugOut << "Index id=" << indexPtr.i;
+        debugOut << " nodeSize=" << tree.m_nodeSize;
+        debugOut << " headSize=" << NodeHeadSize;
+        debugOut << " prefSize=" << tree.m_prefSize;
+        debugOut << " entrySize=" << TreeEntSize;
+        debugOut << " minOccup=" << tree.m_minOccup;
+        debugOut << " maxOccup=" << tree.m_maxOccup;
+        debugOut << endl;
+      }
+    }
+#endif
+
+    // success
+    TuxFragConf* const conf = (TuxFragConf*)signal->getDataPtrSend();
+    conf->userPtr = req->userPtr;
+    conf->tuxConnectPtr = RNIL;
+    conf->fragPtr = fragPtr.i;
+    conf->fragId = fragPtr.p->m_fragId;
+    sendSignal(req->userRef, GSN_TUXFRAGCONF,
+        signal, TuxFragConf::SignalLength, JBB);
+    return;
+  } while (0);
+
+  // error
+  TuxFragRef* const ref = (TuxFragRef*)signal->getDataPtrSend();
+  ref->userPtr = req->userPtr;
+  ref->errorCode = errorCode;
+  sendSignal(req->userRef, GSN_TUXFRAGREF,
+      signal, TuxFragRef::SignalLength, JBB);
+
+  if (indexPtr.i != RNIL) {
+    jam();
+    // let DICT drop the unfinished index
+  }
 }
 
 /*
diff -Nrup a/storage/ndb/test/ndbapi/testDict.cpp b/storage/ndb/test/ndbapi/testDict.cpp
--- a/storage/ndb/test/ndbapi/testDict.cpp	2008-05-30 14:21:23 +02:00
+++ b/storage/ndb/test/ndbapi/testDict.cpp	2008-05-31 08:36:31 +02:00
@@ -1974,8 +1974,8 @@ runCreateDiskTable(NDBT_Context* ctx, ND
 
 int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
   static int acclst[] = { 3001, 6200, 6202 };
-  static int tuplst[] = { 4007, 4008, 4009, 4010, 4011, 4012 };
-  static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006, 
+  static int tuplst[] = { 4007, 4008, 4009, 4010 };
+  static int tuxlst[] = { 12001, 12002, 12003, 12004, 
                           6201, 6203 };
   static unsigned acccnt = sizeof(acclst)/sizeof(acclst[0]);
   static unsigned tupcnt = sizeof(tuplst)/sizeof(tuplst[0]);
Thread
bk commit into 5.1 tree (jonas:1.2624)jonas31 May