Dbdict.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:368k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. void
  2. Dbdict::createTab_prepare(Signal* signal, CreateTabReq * req){
  3.   const Uint32 gci = req->gci;
  4.   const Uint32 tableId = req->tableId;
  5.   const Uint32 tableVersion = req->tableVersion;
  6.   SegmentedSectionPtr tabInfoPtr;
  7.   signal->getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO);
  8.   
  9.   CreateTableRecordPtr createTabPtr;  
  10.   if(req->senderRef == reference()){
  11.     jam();
  12.     ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
  13.   } else {
  14.     jam();
  15.     c_opCreateTable.seize(createTabPtr);
  16.     
  17.     ndbrequire(!createTabPtr.isNull());
  18.     
  19.     createTabPtr.p->key = req->senderData;
  20.     c_opCreateTable.add(createTabPtr);
  21.     createTabPtr.p->m_errorCode = 0;
  22.     createTabPtr.p->m_tablePtrI = tableId;
  23.     createTabPtr.p->m_coordinatorRef = req->senderRef;
  24.     createTabPtr.p->m_senderRef = req->clientRef;
  25.     createTabPtr.p->m_senderData = req->clientData;
  26.     createTabPtr.p->m_dihAddFragPtr = RNIL;
  27.     
  28.     /**
  29.      * Put data into table record
  30.      */
  31.     ParseDictTabInfoRecord parseRecord;
  32.     parseRecord.requestType = DictTabInfo::AddTableFromDict;
  33.     parseRecord.errorCode = 0;
  34.     
  35.     SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
  36.     
  37.     handleTabInfoInit(r, &parseRecord);
  38.     ndbrequire(parseRecord.errorCode == 0);
  39.   }
  40.   
  41.   ndbrequire(!createTabPtr.isNull());
  42.   SegmentedSectionPtr fragPtr;
  43.   signal->getSection(fragPtr, CreateTabReq::FRAGMENTATION);
  44.   createTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
  45.   createTabPtr.p->m_fragmentsPtrI = fragPtr.i;
  46.   
  47.   signal->header.m_noOfSections = 0;
  48.   
  49.   TableRecordPtr tabPtr;
  50.   c_tableRecordPool.getPtr(tabPtr, tableId);
  51.   tabPtr.p->packedSize = tabInfoPtr.sz;
  52.   tabPtr.p->tableVersion = tableVersion;
  53.   tabPtr.p->gciTableCreated = gci;
  54.   SchemaFile::TableEntry tabEntry;
  55.   tabEntry.m_tableVersion = tableVersion;
  56.   tabEntry.m_tableType    = tabPtr.p->tableType;
  57.   tabEntry.m_tableState   = SchemaFile::ADD_STARTED;
  58.   tabEntry.m_gcp          = gci;
  59.   tabEntry.m_noOfPages    = 
  60.     DIV(tabInfoPtr.sz + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
  61.   
  62.   Callback callback;
  63.   callback.m_callbackData = createTabPtr.p->key;
  64.   callback.m_callbackFunction = 
  65.     safe_cast(&Dbdict::createTab_writeSchemaConf1);
  66.   
  67.   updateSchemaState(signal, tableId, &tabEntry, &callback);
  68. }
  69. void getSection(SegmentedSectionPtr & ptr, Uint32 i);
  70. void
  71. Dbdict::createTab_writeSchemaConf1(Signal* signal, 
  72.    Uint32 callbackData,
  73.    Uint32 returnCode){
  74.   jam();
  75.   CreateTableRecordPtr createTabPtr;  
  76.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  77.   Callback callback;
  78.   callback.m_callbackData = createTabPtr.p->key;
  79.   callback.m_callbackFunction = 
  80.     safe_cast(&Dbdict::createTab_writeTableConf);
  81.   
  82.   SegmentedSectionPtr tabInfoPtr;
  83.   getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
  84.   writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
  85.   createTabPtr.p->m_tabInfoPtrI = RNIL;
  86.   signal->setSection(tabInfoPtr, 0);
  87.   releaseSections(signal);
  88. }
  89. void
  90. Dbdict::createTab_writeTableConf(Signal* signal, 
  91.  Uint32 callbackData,
  92.  Uint32 returnCode){
  93.   jam();
  94.   CreateTableRecordPtr createTabPtr;  
  95.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  96.   SegmentedSectionPtr fragDataPtr;
  97.   getSection(fragDataPtr, createTabPtr.p->m_fragmentsPtrI);
  98.   
  99.   Callback callback;
  100.   callback.m_callbackData = callbackData;
  101.   callback.m_callbackFunction = 
  102.     safe_cast(&Dbdict::createTab_dihComplete);
  103.   
  104.   createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
  105. }
  106. void
  107. Dbdict::createTab_dih(Signal* signal, 
  108.       CreateTableRecordPtr createTabPtr, 
  109.       SegmentedSectionPtr fragDataPtr,
  110.       Callback * c){
  111.   jam();
  112.   
  113.   createTabPtr.p->m_callback = * c;
  114.   TableRecordPtr tabPtr;
  115.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  116.   
  117.   DiAddTabReq * req = (DiAddTabReq*)signal->getDataPtrSend();
  118.   req->connectPtr = createTabPtr.p->key;
  119.   req->tableId = tabPtr.i;
  120.   req->fragType = tabPtr.p->fragmentType;
  121.   req->kValue = tabPtr.p->kValue;
  122.   req->noOfReplicas = 0;
  123.   req->storedTable = tabPtr.p->storedTable;
  124.   req->tableType = tabPtr.p->tableType;
  125.   req->schemaVersion = tabPtr.p->tableVersion;
  126.   req->primaryTableId = tabPtr.p->primaryTableId;
  127.   if(!fragDataPtr.isNull()){
  128.     signal->setSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
  129.   }
  130.   sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal, 
  131.      DiAddTabReq::SignalLength, JBB);
  132. }
  133. static
  134. void
  135. calcLHbits(Uint32 * lhPageBits, Uint32 * lhDistrBits, 
  136.    Uint32 fid, Uint32 totalFragments) 
  137. {
  138.   Uint32 distrBits = 0;
  139.   Uint32 pageBits = 0;
  140.   
  141.   Uint32 tmp = 1;
  142.   while (tmp < totalFragments) {
  143.     jam();
  144.     tmp <<= 1;
  145.     distrBits++;
  146.   }//while
  147. #ifdef ndb_classical_lhdistrbits
  148.   if (tmp != totalFragments) {
  149.     tmp >>= 1;
  150.     if ((fid >= (totalFragments - tmp)) && (fid < (tmp - 1))) {
  151.       distrBits--;
  152.     }//if
  153.   }//if
  154. #endif
  155.   * lhPageBits = pageBits;
  156.   * lhDistrBits = distrBits;
  157. }//calcLHbits()
  158. void 
  159. Dbdict::execADD_FRAGREQ(Signal* signal) {
  160.   jamEntry();
  161.   AddFragReq * const req = (AddFragReq*)signal->getDataPtr();
  162.   
  163.   Uint32 dihPtr = req->dihPtr;
  164.   Uint32 senderData = req->senderData;
  165.   Uint32 tableId = req->tableId;
  166.   Uint32 fragId = req->fragmentId;
  167.   Uint32 node = req->nodeId;
  168.   Uint32 lcpNo = req->nextLCP;
  169.   Uint32 fragCount = req->totalFragments;
  170.   Uint32 requestInfo = req->requestInfo;
  171.   Uint32 startGci = req->startGci;
  172.   ndbrequire(node == getOwnNodeId());
  173.   CreateTableRecordPtr createTabPtr;  
  174.   ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
  175.   
  176.   createTabPtr.p->m_dihAddFragPtr = dihPtr;
  177.   
  178.   TableRecordPtr tabPtr;
  179.   c_tableRecordPool.getPtr(tabPtr, tableId);
  180. #if 0
  181.   tabPtr.p->gciTableCreated = (startGci > tabPtr.p->gciTableCreated ? startGci:
  182.        startGci > tabPtr.p->gciTableCreated);
  183. #endif
  184.   
  185.   /**
  186.    * Calc lh3PageBits
  187.    */
  188.   Uint32 lhDistrBits = 0;
  189.   Uint32 lhPageBits = 0;
  190.   ::calcLHbits(&lhPageBits, &lhDistrBits, fragId, fragCount);
  191.   {  
  192.     LqhFragReq* req = (LqhFragReq*)signal->getDataPtrSend();
  193.     req->senderData = senderData;
  194.     req->senderRef = reference();
  195.     req->fragmentId = fragId;
  196.     req->requestInfo = requestInfo;
  197.     req->tableId = tableId;
  198.     req->localKeyLength = tabPtr.p->localKeyLen;
  199.     req->maxLoadFactor = tabPtr.p->maxLoadFactor;
  200.     req->minLoadFactor = tabPtr.p->minLoadFactor;
  201.     req->kValue = tabPtr.p->kValue;
  202.     req->lh3DistrBits = lhDistrBits;
  203.     req->lh3PageBits = lhPageBits;
  204.     req->noOfAttributes = tabPtr.p->noOfAttributes;
  205.     req->noOfNullAttributes = tabPtr.p->noOfNullAttr;
  206.     req->noOfPagesToPreAllocate = 0;
  207.     req->schemaVersion = tabPtr.p->tableVersion;
  208.     Uint32 keyLen = tabPtr.p->tupKeyLength;
  209.     req->keyLength = keyLen > 8 ? 0 : keyLen; // Put this into ACC instead
  210.     req->nextLCP = lcpNo;
  211.     req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
  212.     req->noOfNewAttr = 0;
  213.     // noOfCharsets passed to TUP in upper half
  214.     req->noOfNewAttr |= (tabPtr.p->noOfCharsets << 16);
  215.     req->checksumIndicator = 1;
  216.     req->noOfAttributeGroups = 1;
  217.     req->GCPIndicator = 0;
  218.     req->startGci = startGci;
  219.     req->tableType = tabPtr.p->tableType;
  220.     req->primaryTableId = tabPtr.p->primaryTableId;
  221.     sendSignal(DBLQH_REF, GSN_LQHFRAGREQ, signal, 
  222.        LqhFragReq::SignalLength, JBB);
  223.   }
  224. }
  225. void
  226. Dbdict::execLQHFRAGREF(Signal * signal){
  227.   jamEntry();
  228.   LqhFragRef * const ref = (LqhFragRef*)signal->getDataPtr();
  229.  
  230.   CreateTableRecordPtr createTabPtr;  
  231.   ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
  232.   
  233.   createTabPtr.p->setErrorCode(ref->errorCode);
  234.   
  235.   {
  236.     AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
  237.     ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
  238.     sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal, 
  239.        AddFragRef::SignalLength, JBB);
  240.   }
  241. }
  242. void
  243. Dbdict::execLQHFRAGCONF(Signal * signal){
  244.   jamEntry();
  245.   LqhFragConf * const conf = (LqhFragConf*)signal->getDataPtr();
  246.   CreateTableRecordPtr createTabPtr;  
  247.   ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
  248.   
  249.   createTabPtr.p->m_lqhFragPtr = conf->lqhFragPtr;
  250.   
  251.   TableRecordPtr tabPtr;
  252.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  253.   sendLQHADDATTRREQ(signal, createTabPtr, tabPtr.p->firstAttribute);
  254. }
  255. void
  256. Dbdict::sendLQHADDATTRREQ(Signal* signal,
  257.   CreateTableRecordPtr createTabPtr,
  258.   Uint32 attributePtrI){
  259.   jam();
  260.   TableRecordPtr tabPtr;
  261.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  262.   LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend();
  263.   Uint32 i = 0;
  264.   for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){
  265.     jam();
  266.     AttributeRecordPtr attrPtr;
  267.     c_attributeRecordPool.getPtr(attrPtr, attributePtrI);
  268.     LqhAddAttrReq::Entry& entry = req->attributes[i];
  269.     entry.attrId = attrPtr.p->attributeId;
  270.     entry.attrDescriptor = attrPtr.p->attributeDescriptor;
  271.     entry.extTypeInfo = attrPtr.p->extType;
  272.     // charset number passed to TUP, TUX in upper half
  273.     entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
  274.     if (tabPtr.p->isIndex()) {
  275.       Uint32 primaryAttrId;
  276.       if (attrPtr.p->nextAttrInTable != RNIL) {
  277.         getIndexAttr(tabPtr, attributePtrI, &primaryAttrId);
  278.       } else {
  279.         primaryAttrId = ZNIL;
  280.         if (tabPtr.p->isOrderedIndex())
  281.           entry.attrId = 0;     // attribute goes to TUP
  282.       }
  283.       entry.attrId |= (primaryAttrId << 16);
  284.     }
  285.     attributePtrI = attrPtr.p->nextAttrInTable;
  286.   }
  287.   req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr;
  288.   req->senderData = createTabPtr.p->key;
  289.   req->senderAttrPtr = attributePtrI;
  290.   req->noOfAttributes = i;
  291.   
  292.   sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal, 
  293.      LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
  294. }
  295. void
  296. Dbdict::execLQHADDATTREF(Signal * signal){
  297.   jamEntry();
  298.   LqhAddAttrRef * const ref = (LqhAddAttrRef*)signal->getDataPtr();
  299.   CreateTableRecordPtr createTabPtr;  
  300.   ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
  301.   
  302.   createTabPtr.p->setErrorCode(ref->errorCode);
  303.   
  304.   {
  305.     AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
  306.     ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
  307.     sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal, 
  308.        AddFragRef::SignalLength, JBB);
  309.   }
  310.   
  311. }
  312. void
  313. Dbdict::execLQHADDATTCONF(Signal * signal){
  314.   jamEntry();
  315.   LqhAddAttrConf * const conf = (LqhAddAttrConf*)signal->getDataPtr();
  316.   CreateTableRecordPtr createTabPtr;
  317.   ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
  318.   
  319.   const Uint32 fragId = conf->fragId;
  320.   const Uint32 nextAttrPtr = conf->senderAttrPtr;
  321.   if(nextAttrPtr != RNIL){
  322.     jam();
  323.     sendLQHADDATTRREQ(signal, createTabPtr, nextAttrPtr);
  324.     return;
  325.   }
  326.   {
  327.     AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
  328.     conf->dihPtr = createTabPtr.p->m_dihAddFragPtr;
  329.     conf->fragId = fragId;
  330.     sendSignal(DBDIH_REF, GSN_ADD_FRAGCONF, signal, 
  331.        AddFragConf::SignalLength, JBB);
  332.   }
  333. }
  334. void
  335. Dbdict::execDIADDTABREF(Signal* signal){
  336.   jam();
  337.   
  338.   DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
  339.   
  340.   CreateTableRecordPtr createTabPtr;  
  341.   ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
  342.   
  343.   createTabPtr.p->setErrorCode(ref->errorCode);  
  344.   execute(signal, createTabPtr.p->m_callback, 0);
  345. }
  346. void
  347. Dbdict::execDIADDTABCONF(Signal* signal){
  348.   jam();
  349.   
  350.   DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
  351.   
  352.   CreateTableRecordPtr createTabPtr;  
  353.   ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
  354.   signal->theData[0] = createTabPtr.p->key;
  355.   signal->theData[1] = reference();
  356.   signal->theData[2] = createTabPtr.p->m_tablePtrI;
  357.   if(createTabPtr.p->m_dihAddFragPtr != RNIL){
  358.     jam();
  359.     /**
  360.      * We did perform at least one LQHFRAGREQ
  361.      */
  362.     sendSignal(DBLQH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
  363.     return;
  364.   } else {
  365.     /**
  366.      * No local fragment (i.e. no LQHFRAGREQ)
  367.      */
  368.     execute(signal, createTabPtr.p->m_callback, 0);
  369.     return;
  370.     //sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
  371.   }
  372. }
  373. void 
  374. Dbdict::execTAB_COMMITREF(Signal* signal) {
  375.   jamEntry();
  376.   ndbrequire(false);
  377. }//execTAB_COMMITREF()
  378. void
  379. Dbdict::execTAB_COMMITCONF(Signal* signal){
  380.   jamEntry();
  381.   CreateTableRecordPtr createTabPtr;  
  382.   ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[0]));
  383.   
  384.   if(refToBlock(signal->getSendersBlockRef()) == DBLQH){
  385.     execute(signal, createTabPtr.p->m_callback, 0);
  386.     return;
  387.   }
  388.   if(refToBlock(signal->getSendersBlockRef()) == DBDIH){
  389.     TableRecordPtr tabPtr;
  390.     c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  391.     
  392.     signal->theData[0] = tabPtr.i;
  393.     signal->theData[1] = tabPtr.p->tableVersion;
  394.     signal->theData[2] = (Uint32)tabPtr.p->storedTable;     
  395.     signal->theData[3] = reference();
  396.     signal->theData[4] = (Uint32)tabPtr.p->tableType;
  397.     signal->theData[5] = createTabPtr.p->key;
  398.     sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 6, JBB);
  399.     return;
  400.   }
  401.   ndbrequire(false);
  402. }
  403. void
  404. Dbdict::createTab_dihComplete(Signal* signal, 
  405.       Uint32 callbackData,
  406.       Uint32 returnCode){
  407.   jam();
  408.   CreateTableRecordPtr createTabPtr;  
  409.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  410.   //@todo check for master failed
  411.   
  412.   if(createTabPtr.p->m_errorCode == 0){
  413.     jam();
  414.     CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
  415.     conf->senderRef = reference();
  416.     conf->senderData = createTabPtr.p->key;
  417.     sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
  418.        signal, CreateTabConf::SignalLength, JBB);
  419.     return;
  420.   }
  421.   CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
  422.   ref->senderRef = reference();
  423.   ref->senderData = createTabPtr.p->key;
  424.   ref->errorCode = createTabPtr.p->m_errorCode;
  425.   ref->errorLine = 0;
  426.   ref->errorKey = 0;
  427.   ref->errorStatus = 0;
  428.   sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_REF,
  429.      signal, CreateTabRef::SignalLength, JBB);
  430. }
  431. void
  432. Dbdict::createTab_commit(Signal * signal, CreateTabReq * req){
  433.   jam();
  434.   
  435.   CreateTableRecordPtr createTabPtr;  
  436.   ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
  437.   TableRecordPtr tabPtr;
  438.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  439.   
  440.   SchemaFile::TableEntry tabEntry;
  441.   tabEntry.m_tableVersion = tabPtr.p->tableVersion;
  442.   tabEntry.m_tableType    = tabPtr.p->tableType;
  443.   tabEntry.m_tableState   = SchemaFile::TABLE_ADD_COMMITTED;
  444.   tabEntry.m_gcp          = tabPtr.p->gciTableCreated;
  445.   tabEntry.m_noOfPages    = 
  446.     DIV(tabPtr.p->packedSize + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
  447.   
  448.   Callback callback;
  449.   callback.m_callbackData = createTabPtr.p->key;
  450.   callback.m_callbackFunction = 
  451.     safe_cast(&Dbdict::createTab_writeSchemaConf2);
  452.   
  453.   updateSchemaState(signal, tabPtr.i, &tabEntry, &callback);
  454. }
  455. void
  456. Dbdict::createTab_writeSchemaConf2(Signal* signal, 
  457.    Uint32 callbackData,
  458.    Uint32 returnCode){
  459.   jam();
  460.   
  461.   CreateTableRecordPtr createTabPtr;  
  462.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  463.   
  464.   Callback c;
  465.   c.m_callbackData = callbackData;
  466.   c.m_callbackFunction = safe_cast(&Dbdict::createTab_alterComplete);
  467.   alterTab_activate(signal, createTabPtr, &c);
  468. }
  469. void
  470. Dbdict::createTab_alterComplete(Signal* signal, 
  471. Uint32 callbackData,
  472. Uint32 returnCode){
  473.   jam();
  474.   CreateTableRecordPtr createTabPtr;  
  475.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  476.   
  477.   TableRecordPtr tabPtr;
  478.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  479.   tabPtr.p->tabState = TableRecord::DEFINED;
  480.   
  481.   //@todo check error
  482.   //@todo check master failed
  483.   
  484.   CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
  485.   conf->senderRef = reference();
  486.   conf->senderData = createTabPtr.p->key;
  487.   sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
  488.      signal, CreateTabConf::SignalLength, JBB);
  489.   if(createTabPtr.p->m_coordinatorRef != reference()){
  490.     jam();
  491.     c_opCreateTable.release(createTabPtr);
  492.   }
  493. }
  494. void
  495. Dbdict::createTab_drop(Signal* signal, CreateTabReq * req){
  496.   jam();
  497.   const Uint32 key = req->senderData;
  498.   CreateTableRecordPtr createTabPtr;  
  499.   ndbrequire(c_opCreateTable.find(createTabPtr, key));
  500.   
  501.   TableRecordPtr tabPtr;
  502.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  503.   tabPtr.p->tabState = TableRecord::DROPPING;
  504.   DropTableRecordPtr dropTabPtr;  
  505.   ndbrequire(c_opDropTable.seize(dropTabPtr));
  506.   
  507.   dropTabPtr.p->key = key;
  508.   c_opDropTable.add(dropTabPtr);
  509.   
  510.   dropTabPtr.p->m_errorCode = 0;
  511.   dropTabPtr.p->m_request.tableId = createTabPtr.p->m_tablePtrI;
  512.   dropTabPtr.p->m_requestType = DropTabReq::CreateTabDrop;
  513.   dropTabPtr.p->m_coordinatorRef = createTabPtr.p->m_coordinatorRef;
  514.   dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
  515.   
  516.   dropTabPtr.p->m_participantData.m_block = 0;
  517.   dropTabPtr.p->m_participantData.m_callback.m_callbackData = req->senderData;
  518.   dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 
  519.     safe_cast(&Dbdict::createTab_dropComplete);
  520.   dropTab_nextStep(signal, dropTabPtr);  
  521. }
  522. void
  523. Dbdict::createTab_dropComplete(Signal* signal, 
  524.        Uint32 callbackData,
  525.        Uint32 returnCode){
  526.   jam();
  527.   CreateTableRecordPtr createTabPtr;  
  528.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  529.   
  530.   DropTableRecordPtr dropTabPtr;
  531.   ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
  532.   TableRecordPtr tabPtr;
  533.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  534.   
  535.   releaseTableObject(tabPtr.i);
  536.   PageRecordPtr pagePtr;
  537.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  538.   SchemaFile::TableEntry * tableEntry = getTableEntry(pagePtr.p, tabPtr.i);
  539.   tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
  540.   
  541.   //@todo check error
  542.   //@todo check master failed
  543.   
  544.   CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
  545.   conf->senderRef = reference();
  546.   conf->senderData = createTabPtr.p->key;
  547.   sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
  548.      signal, CreateTabConf::SignalLength, JBB);
  549.   if(createTabPtr.p->m_coordinatorRef != reference()){
  550.     jam();
  551.     c_opCreateTable.release(createTabPtr);
  552.   }
  553.   c_opDropTable.release(dropTabPtr);
  554. }
  555. void
  556. Dbdict::alterTab_activate(Signal* signal, CreateTableRecordPtr createTabPtr,
  557.   Callback * c){
  558.   createTabPtr.p->m_callback = * c;
  559.   
  560.   signal->theData[0] = createTabPtr.p->key;
  561.   signal->theData[1] = reference();
  562.   signal->theData[2] = createTabPtr.p->m_tablePtrI;
  563.   sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
  564. }
  565. void
  566. Dbdict::execTC_SCHVERCONF(Signal* signal){
  567.   jamEntry();
  568.   CreateTableRecordPtr createTabPtr;  
  569.   ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[1]));
  570.   execute(signal, createTabPtr.p->m_callback, 0);
  571. }
  572. #define tabRequire(cond, error) 
  573.   if (!(cond)) { 
  574.     jam();    
  575.     parseP->errorCode = error; parseP->errorLine = __LINE__; 
  576.     parseP->errorKey = it.getKey(); 
  577.     return;   
  578.   }//if
  579. // handleAddTableFailure(signal, __LINE__, allocatedTable);
  580. void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
  581.        ParseDictTabInfoRecord * parseP,
  582.        bool checkExist) 
  583. {
  584. /* ---------------------------------------------------------------- */
  585. // We always start by handling table name since this must be the first
  586. // item in the list. Through the table name we can derive if it is a
  587. // correct name, a new name or an already existing table.
  588. /* ---------------------------------------------------------------- */
  589.   it.first();
  590.   SimpleProperties::UnpackStatus status;
  591.   DictTabInfo::Table tableDesc; tableDesc.init();
  592.   status = SimpleProperties::unpack(it, &tableDesc, 
  593.     DictTabInfo::TableMapping, 
  594.     DictTabInfo::TableMappingSize, 
  595.     true, true);
  596.   
  597.   if(status != SimpleProperties::Break){
  598.     parseP->errorCode = CreateTableRef::InvalidFormat;
  599.     parseP->status    = status;
  600.     parseP->errorKey  = it.getKey();
  601.     parseP->errorLine = __LINE__;
  602.     return;
  603.   }
  604.   if(parseP->requestType == DictTabInfo::AlterTableFromAPI)
  605.   {  
  606.     ndbrequire(!checkExist);
  607.   }
  608.   if(!checkExist)
  609.   {
  610.     ndbrequire(parseP->requestType == DictTabInfo::AlterTableFromAPI);
  611.   }
  612.   
  613.   /* ---------------------------------------------------------------- */
  614.   // Verify that table name is an allowed table name.
  615.   // TODO
  616.   /* ---------------------------------------------------------------- */
  617.   const Uint32 tableNameLength = strlen(tableDesc.TableName) + 1;
  618.   TableRecord keyRecord;
  619.   tabRequire(tableNameLength <= sizeof(keyRecord.tableName),
  620.      CreateTableRef::TableNameTooLong);
  621.   strcpy(keyRecord.tableName, tableDesc.TableName);
  622.   
  623.   TableRecordPtr tablePtr;
  624.   c_tableRecordHash.find(tablePtr, keyRecord);
  625.   
  626.   if (checkExist){
  627.     jam();
  628.     /* ---------------------------------------------------------------- */
  629.     // Check if table already existed.
  630.     /* ---------------------------------------------------------------- */
  631.     tabRequire(tablePtr.i == RNIL, CreateTableRef::TableAlreadyExist);
  632.   }
  633.   switch (parseP->requestType) {
  634.   case DictTabInfo::CreateTableFromAPI: {
  635.     jam();
  636.   }
  637.   case DictTabInfo::AlterTableFromAPI:{
  638.     jam();
  639.     tablePtr.i = getFreeTableRecord(tableDesc.PrimaryTableId);
  640.     /* ---------------------------------------------------------------- */
  641.     // Check if no free tables existed.
  642.     /* ---------------------------------------------------------------- */
  643.     tabRequire(tablePtr.i != RNIL, CreateTableRef::NoMoreTableRecords);
  644.     
  645.     c_tableRecordPool.getPtr(tablePtr);
  646.     break;
  647.   }
  648.   case DictTabInfo::AddTableFromDict:
  649.   case DictTabInfo::ReadTableFromDiskSR:
  650.   case DictTabInfo::GetTabInfoConf:
  651.   {
  652. /* ---------------------------------------------------------------- */
  653. // Get table id and check that table doesn't already exist
  654. /* ---------------------------------------------------------------- */
  655.     tablePtr.i = tableDesc.TableId;
  656.     
  657.     if (parseP->requestType == DictTabInfo::ReadTableFromDiskSR) {
  658.       ndbrequire(tablePtr.i == c_restartRecord.activeTable);
  659.     }//if
  660.     if (parseP->requestType == DictTabInfo::GetTabInfoConf) {
  661.       ndbrequire(tablePtr.i == c_restartRecord.activeTable);
  662.     }//if
  663.     
  664.     c_tableRecordPool.getPtr(tablePtr);
  665.     ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
  666.     
  667.     //Uint32 oldTableVersion = tablePtr.p->tableVersion;
  668.     initialiseTableRecord(tablePtr);
  669.     if (parseP->requestType == DictTabInfo::AddTableFromDict) {
  670.       jam();
  671.       tablePtr.p->tabState = TableRecord::DEFINING;
  672.     }//if
  673. #ifdef HAVE_TABLE_REORG
  674. /* ---------------------------------------------------------------- */
  675. // Get id of second table id and check that table doesn't already exist
  676. // and set up links between first and second table.
  677. /* ---------------------------------------------------------------- */
  678.     TableRecordPtr secondTablePtr;
  679.     secondTablePtr.i = tableDesc.SecondTableId;
  680.     c_tableRecordPool.getPtr(secondTablePtr);
  681.     ndbrequire(secondTablePtr.p->tabState == TableRecord::NOT_DEFINED);
  682.     
  683.     initialiseTableRecord(secondTablePtr);
  684.     secondTablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED;
  685.     secondTablePtr.p->secondTable = tablePtr.i;
  686.     tablePtr.p->secondTable = secondTablePtr.i;
  687. #endif
  688. /* ---------------------------------------------------------------- */
  689. // Set table version
  690. /* ---------------------------------------------------------------- */
  691.     Uint32 tableVersion = tableDesc.TableVersion;
  692.     tablePtr.p->tableVersion = tableVersion;
  693.     
  694.     break;
  695.   }
  696.   default:
  697.     ndbrequire(false);
  698.     break;
  699.   }//switch
  700.   parseP->tablePtr = tablePtr;
  701.   
  702.   strcpy(tablePtr.p->tableName, keyRecord.tableName);  
  703.   if (parseP->requestType != DictTabInfo::AlterTableFromAPI) {
  704.     jam();
  705. #ifdef VM_TRACE
  706.     ndbout_c("Dbdict: name=%s,id=%u", tablePtr.p->tableName, tablePtr.i);
  707.     TableRecordPtr tmp;
  708.     ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p));
  709. #endif
  710.     c_tableRecordHash.add(tablePtr);
  711.   }
  712.   
  713.   //tablePtr.p->noOfPrimkey = tableDesc.NoOfKeyAttr;
  714.   //tablePtr.p->noOfNullAttr = tableDesc.NoOfNullable;
  715.   //tablePtr.p->tupKeyLength = tableDesc.KeyLength;
  716.   tablePtr.p->noOfAttributes = tableDesc.NoOfAttributes;
  717.   tablePtr.p->storedTable = tableDesc.TableLoggedFlag;
  718.   tablePtr.p->minLoadFactor = tableDesc.MinLoadFactor;
  719.   tablePtr.p->maxLoadFactor = tableDesc.MaxLoadFactor;
  720.   tablePtr.p->fragmentType = (DictTabInfo::FragmentType)tableDesc.FragmentType;
  721.   tablePtr.p->fragmentKeyType = (DictTabInfo::FragmentKeyType)tableDesc.FragmentKeyType;
  722.   tablePtr.p->tableType = (DictTabInfo::TableType)tableDesc.TableType;
  723.   tablePtr.p->kValue = tableDesc.TableKValue;
  724.   tablePtr.p->fragmentCount = tableDesc.FragmentCount;
  725.   tablePtr.p->frmLen = tableDesc.FrmLen;
  726.   memcpy(tablePtr.p->frmData, tableDesc.FrmData, tableDesc.FrmLen);  
  727.   if(tableDesc.PrimaryTableId != RNIL) {
  728.     
  729.     tablePtr.p->primaryTableId = tableDesc.PrimaryTableId;
  730.     tablePtr.p->indexState = (TableRecord::IndexState)tableDesc.IndexState;
  731.     tablePtr.p->insertTriggerId = tableDesc.InsertTriggerId;
  732.     tablePtr.p->updateTriggerId = tableDesc.UpdateTriggerId;
  733.     tablePtr.p->deleteTriggerId = tableDesc.DeleteTriggerId;
  734.     tablePtr.p->customTriggerId = tableDesc.CustomTriggerId;
  735.   } else {
  736.     tablePtr.p->primaryTableId = RNIL;
  737.     tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
  738.     tablePtr.p->insertTriggerId = RNIL;
  739.     tablePtr.p->updateTriggerId = RNIL;
  740.     tablePtr.p->deleteTriggerId = RNIL;
  741.     tablePtr.p->customTriggerId = RNIL;
  742.   }
  743.   tablePtr.p->buildTriggerId = RNIL;
  744.   tablePtr.p->indexLocal = 0;
  745.   
  746.   handleTabInfo(it, parseP);
  747.   if(parseP->errorCode != 0)
  748.   {
  749.     /**
  750.      * Release table
  751.      */
  752.     releaseTableObject(tablePtr.i, checkExist);
  753.   }
  754. }//handleTabInfoInit()
  755. void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
  756.    ParseDictTabInfoRecord * parseP)
  757. {
  758.   TableRecordPtr tablePtr = parseP->tablePtr;
  759.   
  760.   SimpleProperties::UnpackStatus status;
  761.   
  762.   Uint32 keyCount = 0;
  763.   Uint32 keyLength = 0;
  764.   Uint32 attrCount = tablePtr.p->noOfAttributes;
  765.   Uint32 nullCount = 0;
  766.   Uint32 noOfCharsets = 0;
  767.   Uint16 charsets[128];
  768.   Uint32 recordLength = 0;
  769.   AttributeRecordPtr attrPtr;
  770.   c_attributeRecordHash.removeAll();
  771.   
  772.   for(Uint32 i = 0; i<attrCount; i++){
  773.     /**
  774.      * Attribute Name
  775.      */
  776.     DictTabInfo::Attribute attrDesc; attrDesc.init();
  777.     status = SimpleProperties::unpack(it, &attrDesc, 
  778.       DictTabInfo::AttributeMapping, 
  779.       DictTabInfo::AttributeMappingSize, 
  780.       true, true);
  781.     if(status != SimpleProperties::Break){
  782.       parseP->errorCode = CreateTableRef::InvalidFormat;
  783.       parseP->status    = status;
  784.       parseP->errorKey  = it.getKey();
  785.       parseP->errorLine = __LINE__;
  786.       return;
  787.     }
  788.     /**
  789.      * Check that attribute is not defined twice
  790.      */
  791.     AttributeRecord tmpAttr;
  792.     {
  793.       strcpy(tmpAttr.attributeName, attrDesc.AttributeName); 
  794.       
  795.       AttributeRecordPtr attrPtr;
  796.       c_attributeRecordHash.find(attrPtr, tmpAttr);
  797.       
  798.       if(attrPtr.i != RNIL){
  799. parseP->errorCode = CreateTableRef::AttributeNameTwice;
  800. return;
  801.       }
  802.     }
  803.     
  804.     if(!getNewAttributeRecord(tablePtr, attrPtr)){
  805.       jam();
  806.       parseP->errorCode = CreateTableRef::NoMoreAttributeRecords;
  807.       return;
  808.     }
  809.     
  810.     /**
  811.      * TmpAttrib to Attribute mapping
  812.      */
  813.     strcpy(attrPtr.p->attributeName, attrDesc.AttributeName);
  814.     attrPtr.p->attributeId = attrDesc.AttributeId;
  815.     attrPtr.p->tupleKey = (keyCount + 1) * attrDesc.AttributeKeyFlag;
  816.     attrPtr.p->extType = attrDesc.AttributeExtType;
  817.     attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision;
  818.     attrPtr.p->extScale = attrDesc.AttributeExtScale;
  819.     attrPtr.p->extLength = attrDesc.AttributeExtLength;
  820.     // charset in upper half of precision
  821.     unsigned csNumber = (attrPtr.p->extPrecision >> 16);
  822.     if (csNumber != 0) {
  823.       CHARSET_INFO* cs = get_charset(csNumber, MYF(0));
  824.       if (cs == NULL) {
  825.         parseP->errorCode = CreateTableRef::InvalidCharset;
  826.         parseP->errorLine = __LINE__;
  827.         return;
  828.       }
  829.       unsigned i = 0;
  830.       while (i < noOfCharsets) {
  831.         if (charsets[i] == csNumber)
  832.           break;
  833.         i++;
  834.       }
  835.       if (i == noOfCharsets) {
  836.         noOfCharsets++;
  837.         if (noOfCharsets > sizeof(charsets)/sizeof(charsets[0])) {
  838.           parseP->errorCode = CreateTableRef::InvalidFormat;
  839.           parseP->errorLine = __LINE__;
  840.           return;
  841.         }
  842.         charsets[i] = csNumber;
  843.       }
  844.     }
  845.     /**
  846.      * Ignore incoming old-style type and recompute it.
  847.      */
  848.     bool translateOk = attrDesc.translateExtType();
  849.     tabRequire(translateOk, CreateTableRef::Inconsistency);
  850.     if(attrDesc.AttributeArraySize > 65535){
  851.       parseP->errorCode = CreateTableRef::ArraySizeTooBig;
  852.       parseP->status    = status;
  853.       parseP->errorKey  = it.getKey();
  854.       parseP->errorLine = __LINE__;
  855.       return;
  856.     }
  857.     
  858.     Uint32 desc = 0;
  859.     AttributeDescriptor::setType(desc, attrDesc.AttributeType);
  860.     AttributeDescriptor::setSize(desc, attrDesc.AttributeSize);
  861.     AttributeDescriptor::setArray(desc, attrDesc.AttributeArraySize);
  862.     AttributeDescriptor::setNullable(desc, attrDesc.AttributeNullableFlag);
  863.     AttributeDescriptor::setDGroup(desc, attrDesc.AttributeDGroup);
  864.     AttributeDescriptor::setDKey(desc, attrDesc.AttributeDKey);
  865.     AttributeDescriptor::setPrimaryKey(desc, attrDesc.AttributeKeyFlag);
  866.     AttributeDescriptor::setStoredInTup(desc, attrDesc.AttributeStoredInd); 
  867.     attrPtr.p->attributeDescriptor = desc;
  868.     attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement;
  869.     strcpy(attrPtr.p->defaultValue, attrDesc.AttributeDefaultValue);
  870.     
  871.     tabRequire(attrDesc.AttributeId == i, CreateTableRef::InvalidFormat);
  872.     
  873.     attrCount ++;
  874.     keyCount += attrDesc.AttributeKeyFlag;
  875.     nullCount += attrDesc.AttributeNullableFlag;
  876.     
  877.     const Uint32 aSz = (1 << attrDesc.AttributeSize);
  878.     const Uint32 sz = ((aSz * attrDesc.AttributeArraySize) + 31) >> 5;
  879.     
  880.     recordLength += sz;
  881.     if(attrDesc.AttributeKeyFlag){
  882.       keyLength += sz;
  883.       if(attrDesc.AttributeNullableFlag){
  884. parseP->errorCode = CreateTableRef::NullablePrimaryKey;
  885. parseP->status    = status;
  886. parseP->errorKey  = it.getKey();
  887. parseP->errorLine = __LINE__;
  888. return;
  889.       }
  890.     }
  891.     
  892.     if (parseP->requestType != DictTabInfo::AlterTableFromAPI)
  893.       c_attributeRecordHash.add(attrPtr);
  894.     
  895.     if(!it.next())
  896.       break;
  897.     
  898.     if(it.getKey() != DictTabInfo::AttributeName)
  899.       break;
  900.   }//while
  901.   
  902.   tablePtr.p->noOfPrimkey = keyCount;
  903.   tablePtr.p->noOfNullAttr = nullCount;
  904.   tablePtr.p->noOfCharsets = noOfCharsets;
  905.   tablePtr.p->tupKeyLength = keyLength;
  906.   tabRequire(recordLength<= MAX_TUPLE_SIZE_IN_WORDS, 
  907.      CreateTableRef::RecordTooBig);
  908.   tabRequire(keyLength <= MAX_KEY_SIZE_IN_WORDS, 
  909.      CreateTableRef::InvalidPrimaryKeySize);
  910.   tabRequire(keyLength > 0, 
  911.      CreateTableRef::InvalidPrimaryKeySize);
  912.   
  913. }//handleTabInfo()
  914. /* ---------------------------------------------------------------- */
  915. // DICTTABCONF is sent when participants have received all DICTTABINFO
  916. // and successfully handled it.
  917. // Also sent to self (DICT master) when index table creation ready.
  918. /* ---------------------------------------------------------------- */
  919. void Dbdict::execCREATE_TABLE_CONF(Signal* signal) 
  920. {
  921.   jamEntry();
  922.   ndbrequire(signal->getNoOfSections() == 0);
  923.   CreateTableConf * const conf = (CreateTableConf *)signal->getDataPtr();
  924.   // assume part of create index operation
  925.   OpCreateIndexPtr opPtr;
  926.   c_opCreateIndex.find(opPtr, conf->senderData);
  927.   ndbrequire(! opPtr.isNull());
  928.   opPtr.p->m_request.setIndexId(conf->tableId);
  929.   opPtr.p->m_request.setIndexVersion(conf->tableVersion);
  930.   createIndex_fromCreateTable(signal, opPtr);
  931. }//execCREATE_TABLE_CONF()
  932. void Dbdict::execCREATE_TABLE_REF(Signal* signal) 
  933. {
  934.   jamEntry();
  935.   CreateTableRef * const ref = (CreateTableRef *)signal->getDataPtr();
  936.   // assume part of create index operation
  937.   OpCreateIndexPtr opPtr;
  938.   c_opCreateIndex.find(opPtr, ref->senderData);
  939.   ndbrequire(! opPtr.isNull());
  940.   opPtr.p->setError(ref);
  941.   createIndex_fromCreateTable(signal, opPtr);
  942. }//execCREATE_TABLE_REF()
  943. /* ---------------------------------------------------------------- */
  944. // New global checkpoint created.
  945. /* ---------------------------------------------------------------- */
  946. void Dbdict::execWAIT_GCP_CONF(Signal* signal) 
  947. {
  948. #if 0
  949.   TableRecordPtr tablePtr;
  950.   jamEntry();
  951.   WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
  952.   c_tableRecordPool.getPtr(tablePtr, c_connRecord.connTableId);
  953.   tablePtr.p->gciTableCreated = conf->gcp;
  954.   sendUpdateSchemaState(signal,
  955.                         tablePtr.i,
  956.                         SchemaFile::TABLE_ADD_COMMITTED,
  957.                         c_connRecord.noOfPagesForTable,
  958.                         conf->gcp);
  959. #endif
  960. }//execWAIT_GCP_CONF()
  961. /* ---------------------------------------------------------------- */
  962. // Refused new global checkpoint.
  963. /* ---------------------------------------------------------------- */
  964. void Dbdict::execWAIT_GCP_REF(Signal* signal) 
  965. {
  966.   jamEntry();
  967.   WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
  968. /* ---------------------------------------------------------------- */
  969. // Error Handling code needed
  970. /* ---------------------------------------------------------------- */
  971.   progError(ref->errorCode, 0);
  972. }//execWAIT_GCP_REF()
  973. /* **************************************************************** */
  974. /* ---------------------------------------------------------------- */
  975. /* MODULE:          DROP TABLE                 -------------------- */
  976. /* ---------------------------------------------------------------- */
  977. /*                                                                  */
  978. /* This module contains the code used to drop a table.              */
  979. /* ---------------------------------------------------------------- */
  980. /* **************************************************************** */
  981. void
  982. Dbdict::execDROP_TABLE_REQ(Signal* signal){
  983.   jamEntry();
  984.   DropTableReq* req = (DropTableReq*)signal->getDataPtr();
  985.   TableRecordPtr tablePtr;
  986.   c_tableRecordPool.getPtr(tablePtr, req->tableId, false);
  987.   if(tablePtr.isNull()){
  988.     jam();
  989.     dropTableRef(signal, req, DropTableRef::NoSuchTable);
  990.     return;
  991.   }
  992.   if(getOwnNodeId() != c_masterNodeId){
  993.     jam();
  994.     dropTableRef(signal, req, DropTableRef::NotMaster);
  995.     return;
  996.   }
  997.   if(c_blockState != BS_IDLE){
  998.     jam();
  999.     dropTableRef(signal, req, DropTableRef::Busy);
  1000.     return;
  1001.   }
  1002.   
  1003.   const TableRecord::TabState tabState = tablePtr.p->tabState;
  1004.   bool ok = false;
  1005.   switch(tabState){
  1006.   case TableRecord::NOT_DEFINED:
  1007.   case TableRecord::REORG_TABLE_PREPARED:
  1008.   case TableRecord::DEFINING:
  1009.   case TableRecord::CHECKED:
  1010.     jam();
  1011.     dropTableRef(signal, req, DropTableRef::NoSuchTable);
  1012.     return;
  1013.   case TableRecord::DEFINED:
  1014.     ok = true;
  1015.     jam();
  1016.     break;
  1017.   case TableRecord::PREPARE_DROPPING:
  1018.   case TableRecord::DROPPING:
  1019.     jam();
  1020.     dropTableRef(signal, req, DropTableRef::DropInProgress);
  1021.     return;
  1022.   case TableRecord::BACKUP_ONGOING:
  1023.     jam();
  1024.     dropTableRef(signal, req, DropTableRef::BackupInProgress);
  1025.     return;
  1026.   }
  1027.   ndbrequire(ok);
  1028.   if(tablePtr.p->tableVersion != req->tableVersion){
  1029.     jam();
  1030.     dropTableRef(signal, req, DropTableRef::InvalidTableVersion);
  1031.     return;
  1032.   }
  1033.   /**
  1034.    * Seems ok
  1035.    */
  1036.   DropTableRecordPtr dropTabPtr;
  1037.   c_opDropTable.seize(dropTabPtr);
  1038.   
  1039.   if(dropTabPtr.isNull()){
  1040.     jam();
  1041.     dropTableRef(signal, req, DropTableRef::NoDropTableRecordAvailable);
  1042.     return;
  1043.   }
  1044.   c_blockState = BS_BUSY;
  1045.   
  1046.   dropTabPtr.p->key = ++c_opRecordSequence;
  1047.   c_opDropTable.add(dropTabPtr);
  1048.   dropTabPtr.p->m_request = * req;
  1049.   dropTabPtr.p->m_errorCode = 0;
  1050.   dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab;
  1051.   dropTabPtr.p->m_coordinatorRef = reference();
  1052.   dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ;
  1053.   dropTabPtr.p->m_coordinatorData.m_block = 0;
  1054.   
  1055.   Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
  1056.   Callback c = { safe_cast(&Dbdict::dropTable_backup_mutex_locked),
  1057.  dropTabPtr.p->key};
  1058.   
  1059.   ndbrequire(mutex.lock(c));
  1060. }
  1061. void
  1062. Dbdict::dropTable_backup_mutex_locked(Signal* signal, 
  1063.       Uint32 callbackData,
  1064.       Uint32 retValue){
  1065.   jamEntry();
  1066.   
  1067.   ndbrequire(retValue == 0);
  1068.   
  1069.   DropTableRecordPtr dropTabPtr;
  1070.   ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
  1071.   
  1072.   TableRecordPtr tablePtr;
  1073.   c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId, true);
  1074.   
  1075.   Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
  1076.   mutex.unlock(); // ignore response
  1077.   
  1078.   if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
  1079.   {
  1080.     jam();
  1081.     dropTableRef(signal, &dropTabPtr.p->m_request,
  1082.  DropTableRef::BackupInProgress);
  1083.     
  1084.     c_blockState = BS_IDLE;
  1085.     c_opDropTable.release(dropTabPtr);
  1086.   }
  1087.   else
  1088.   {
  1089.     jam();
  1090.     tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
  1091.     prepDropTab_nextStep(signal, dropTabPtr);
  1092.   }
  1093. }
  1094. void
  1095. Dbdict::dropTableRef(Signal * signal, 
  1096.      DropTableReq * req, DropTableRef::ErrorCode errCode){
  1097.   Uint32 tableId = req->tableId;
  1098.   Uint32 tabVersion = req->tableVersion;
  1099.   Uint32 senderData = req->senderData;
  1100.   Uint32 senderRef = req->senderRef;
  1101.   
  1102.   DropTableRef * ref = (DropTableRef*)signal->getDataPtrSend();
  1103.   ref->tableId = tableId;
  1104.   ref->tableVersion = tabVersion;
  1105.   ref->senderData = senderData;
  1106.   ref->senderRef = reference();
  1107.   ref->errorCode = errCode;
  1108.   ref->masterNodeId = c_masterNodeId;
  1109.   sendSignal(senderRef, GSN_DROP_TABLE_REF, signal, 
  1110.      DropTableRef::SignalLength, JBB);
  1111. }
  1112. void
  1113. Dbdict::prepDropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
  1114.   
  1115.   /**
  1116.    * No errors currently allowed
  1117.    */
  1118.   ndbrequire(dropTabPtr.p->m_errorCode == 0);
  1119.   Uint32 block = 0;
  1120.   switch(dropTabPtr.p->m_coordinatorData.m_block){
  1121.   case 0:
  1122.     jam();
  1123.     block = dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
  1124.     break;
  1125.   case DBDICT:
  1126.     jam();
  1127.     block = dropTabPtr.p->m_coordinatorData.m_block = DBLQH;
  1128.     break;
  1129.   case DBLQH:
  1130.     jam();
  1131.     block = dropTabPtr.p->m_coordinatorData.m_block = DBTC;
  1132.     break;
  1133.   case DBTC:
  1134.     jam();
  1135.     block = dropTabPtr.p->m_coordinatorData.m_block = DBDIH;
  1136.     break;
  1137.   case DBDIH:
  1138.     jam();
  1139.     prepDropTab_complete(signal, dropTabPtr);
  1140.     return;
  1141.   default:
  1142.     ndbrequire(false);
  1143.   }
  1144.   PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
  1145.   prep->senderRef = reference();
  1146.   prep->senderData = dropTabPtr.p->key;
  1147.   prep->tableId = dropTabPtr.p->m_request.tableId;
  1148.   prep->requestType = dropTabPtr.p->m_requestType;
  1149.   
  1150.   dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
  1151.   NodeReceiverGroup rg(block, c_aliveNodes);
  1152.   sendSignal(rg, GSN_PREP_DROP_TAB_REQ, signal, 
  1153.      PrepDropTabReq::SignalLength, JBB);
  1154.   
  1155. #if 0  
  1156.   for (Uint32 i = 1; i < MAX_NDB_NODES; i++){
  1157.     if(c_aliveNodes.get(i)){
  1158.       jam();
  1159.       BlockReference ref = numberToRef(block, i);
  1160.       
  1161.       dropTabPtr.p->m_coordinatorData.m_signalCounter.setWaitingFor(i);
  1162.     }
  1163.   }
  1164. #endif
  1165. }
  1166. void
  1167. Dbdict::execPREP_DROP_TAB_CONF(Signal * signal){
  1168.   jamEntry();
  1169.   PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();
  1170.   DropTableRecordPtr dropTabPtr;  
  1171.   ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
  1172.   
  1173.   ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
  1174.   ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
  1175.   ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
  1176.   
  1177.   Uint32 nodeId = refToNode(prep->senderRef);
  1178.   dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
  1179.   
  1180.   if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
  1181.     jam();
  1182.     return;
  1183.   }
  1184.   prepDropTab_nextStep(signal, dropTabPtr);
  1185. }
  1186. void
  1187. Dbdict::execPREP_DROP_TAB_REF(Signal* signal){
  1188.   jamEntry();
  1189.   PrepDropTabRef * prep = (PrepDropTabRef*)signal->getDataPtr();
  1190.   DropTableRecordPtr dropTabPtr;  
  1191.   ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
  1192.   
  1193.   ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
  1194.   ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
  1195.   ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
  1196.   
  1197.   Uint32 nodeId = refToNode(prep->senderRef);
  1198.   dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
  1199.   
  1200.   Uint32 block = refToBlock(prep->senderRef);
  1201.   if((prep->errorCode == PrepDropTabRef::NoSuchTable && block == DBLQH) ||
  1202.      (prep->errorCode == PrepDropTabRef::NF_FakeErrorREF)){
  1203.     jam();
  1204.     /**
  1205.      * Ignore errors:
  1206.      * 1) no such table and LQH, it might not exists in different LQH's
  1207.      * 2) node failure...
  1208.      */
  1209.   } else {
  1210.     dropTabPtr.p->setErrorCode((Uint32)prep->errorCode);
  1211.   }
  1212.   
  1213.   if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
  1214.     jam();
  1215.     return;
  1216.   }
  1217.   prepDropTab_nextStep(signal, dropTabPtr);
  1218. }
  1219. void
  1220. Dbdict::prepDropTab_complete(Signal* signal, DropTableRecordPtr dropTabPtr){
  1221.   jam();
  1222.   dropTabPtr.p->m_coordinatorData.m_gsn = GSN_DROP_TAB_REQ;
  1223.   dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
  1224.   
  1225.   DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
  1226.   req->senderRef = reference();
  1227.   req->senderData = dropTabPtr.p->key;
  1228.   req->tableId = dropTabPtr.p->m_request.tableId;
  1229.   req->requestType = dropTabPtr.p->m_requestType;
  1230.   dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
  1231.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  1232.   sendSignal(rg, GSN_DROP_TAB_REQ, signal, 
  1233.      DropTabReq::SignalLength, JBB);
  1234. }
  1235. void
  1236. Dbdict::execDROP_TAB_REF(Signal* signal){
  1237.   jamEntry();
  1238.   DropTabRef * const req = (DropTabRef*)signal->getDataPtr();
  1239.   Uint32 block = refToBlock(req->senderRef);
  1240.   ndbrequire(req->errorCode == DropTabRef::NF_FakeErrorREF ||
  1241.      (req->errorCode == DropTabRef::NoSuchTable &&
  1242.       (block == DBTUP || block == DBACC || block == DBLQH)));
  1243.   
  1244.   if(block != DBDICT){
  1245.     jam();
  1246.     ndbrequire(refToNode(req->senderRef) == getOwnNodeId());
  1247.     dropTab_localDROP_TAB_CONF(signal);
  1248.     return;
  1249.   }
  1250.   ndbrequire(false);
  1251. }
  1252. void
  1253. Dbdict::execDROP_TAB_CONF(Signal* signal){
  1254.   jamEntry();
  1255.   DropTabConf * const req = (DropTabConf*)signal->getDataPtr();
  1256.   if(refToBlock(req->senderRef) != DBDICT){
  1257.     jam();
  1258.     ndbrequire(refToNode(req->senderRef) == getOwnNodeId());
  1259.     dropTab_localDROP_TAB_CONF(signal);
  1260.     return;
  1261.   }
  1262.   DropTableRecordPtr dropTabPtr;  
  1263.   ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
  1264.   
  1265.   ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
  1266.   ndbrequire(dropTabPtr.p->m_request.tableId == req->tableId);
  1267.   ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_DROP_TAB_REQ);
  1268.   Uint32 nodeId = refToNode(req->senderRef);
  1269.   dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
  1270.   
  1271.   if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
  1272.     jam();
  1273.     return;
  1274.   }
  1275.   
  1276.   DropTableConf* conf = (DropTableConf*)signal->getDataPtrSend();
  1277.   conf->senderRef = reference();
  1278.   conf->senderData = dropTabPtr.p->m_request.senderData;
  1279.   conf->tableId = dropTabPtr.p->m_request.tableId;
  1280.   conf->tableVersion = dropTabPtr.p->m_request.tableVersion;
  1281.   
  1282.   Uint32 ref = dropTabPtr.p->m_request.senderRef;
  1283.   sendSignal(ref, GSN_DROP_TABLE_CONF, signal, 
  1284.      DropTableConf::SignalLength, JBB);
  1285.   c_opDropTable.release(dropTabPtr);
  1286.   c_blockState = BS_IDLE;
  1287. }
  1288. /**
  1289.  * DROP TABLE PARTICIPANT CODE
  1290.  */
  1291. void
  1292. Dbdict::execPREP_DROP_TAB_REQ(Signal* signal){
  1293.   jamEntry();
  1294.   PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();  
  1295.   DropTableRecordPtr dropTabPtr;  
  1296.   if(prep->senderRef == reference()){
  1297.     jam();
  1298.     ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
  1299.     ndbrequire(dropTabPtr.p->m_requestType == prep->requestType);
  1300.   } else {
  1301.     jam();
  1302.     c_opDropTable.seize(dropTabPtr);
  1303.     if(!dropTabPtr.isNull()){
  1304.       dropTabPtr.p->key = prep->senderData;
  1305.       c_opDropTable.add(dropTabPtr);
  1306.     }
  1307.   }
  1308.   
  1309.   ndbrequire(!dropTabPtr.isNull());
  1310.   dropTabPtr.p->m_errorCode = 0;
  1311.   dropTabPtr.p->m_request.tableId = prep->tableId;
  1312.   dropTabPtr.p->m_requestType = prep->requestType;
  1313.   dropTabPtr.p->m_coordinatorRef = prep->senderRef;
  1314.   dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_REQ;
  1315.   TableRecordPtr tablePtr;
  1316.   c_tableRecordPool.getPtr(tablePtr, prep->tableId);
  1317.   tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
  1318.   
  1319.   /**
  1320.    * Modify schema
  1321.    */
  1322.   PageRecordPtr pagePtr;
  1323.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  1324.   
  1325.   SchemaFile::TableEntry * tableEntry = getTableEntry(pagePtr.p, tablePtr.i);
  1326.   SchemaFile::TableState tabState = 
  1327.     (SchemaFile::TableState)tableEntry->m_tableState;
  1328.   ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED ||
  1329.      tabState == SchemaFile::ALTER_TABLE_COMMITTED);
  1330.   tableEntry->m_tableState   = SchemaFile::DROP_TABLE_STARTED;
  1331.   computeChecksum((SchemaFile*)pagePtr.p);
  1332.   
  1333.   ndbrequire(c_writeSchemaRecord.inUse == false);
  1334.   c_writeSchemaRecord.inUse = true;
  1335.   
  1336.   c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
  1337.   c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
  1338.   c_writeSchemaRecord.m_callback.m_callbackFunction = 
  1339.     safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
  1340.   startWriteSchemaFile(signal);
  1341. }
  1342. void
  1343. Dbdict::prepDropTab_writeSchemaConf(Signal* signal, 
  1344.     Uint32 dropTabPtrI,
  1345.     Uint32 returnCode){
  1346.   jam();
  1347.   DropTableRecordPtr dropTabPtr;  
  1348.   ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
  1349.   ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_REQ);
  1350.   
  1351.   /**
  1352.    * There probably should be node fail handlign here
  1353.    *
  1354.    * To check that coordinator hasn't died
  1355.    */
  1356.   
  1357.   PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();  
  1358.   prep->senderRef = reference();
  1359.   prep->senderData = dropTabPtrI;
  1360.   prep->tableId = dropTabPtr.p->m_request.tableId;
  1361.   
  1362.   dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_CONF;
  1363.   sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_PREP_DROP_TAB_CONF, signal, 
  1364.      PrepDropTabConf::SignalLength, JBB);
  1365. }
  1366. void
  1367. Dbdict::execDROP_TAB_REQ(Signal* signal){
  1368.   jamEntry();
  1369.   DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();  
  1370.   DropTableRecordPtr dropTabPtr;  
  1371.   ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
  1372.   ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_CONF);
  1373.   dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
  1374.   ndbrequire(dropTabPtr.p->m_requestType == req->requestType);
  1375.   TableRecordPtr tablePtr;
  1376.   c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
  1377.   tablePtr.p->tabState = TableRecord::DROPPING;
  1378.   dropTabPtr.p->m_participantData.m_block = 0;
  1379.   dropTabPtr.p->m_participantData.m_callback.m_callbackData = dropTabPtr.p->key;
  1380.   dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 
  1381.     safe_cast(&Dbdict::dropTab_complete);
  1382.   dropTab_nextStep(signal, dropTabPtr);  
  1383. }
  1384. #include <DebuggerNames.hpp>
  1385. void
  1386. Dbdict::dropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
  1387.   /**
  1388.    * No errors currently allowed
  1389.    */
  1390.   ndbrequire(dropTabPtr.p->m_errorCode == 0);
  1391.   TableRecordPtr tablePtr;
  1392.   c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
  1393.   Uint32 block = 0;
  1394.   switch(dropTabPtr.p->m_participantData.m_block){
  1395.   case 0:
  1396.     jam();
  1397.     block = DBTC;
  1398.     break;
  1399.   case DBTC:
  1400.     jam();
  1401.     if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
  1402.       block = DBACC;
  1403.     if (tablePtr.p->isOrderedIndex())
  1404.       block = DBTUP;
  1405.     break;
  1406.   case DBACC:
  1407.     jam();
  1408.     block = DBTUP;
  1409.     break;
  1410.   case DBTUP:
  1411.     jam();
  1412.     if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
  1413.       block = DBLQH;
  1414.     if (tablePtr.p->isOrderedIndex())
  1415.       block = DBTUX;
  1416.     break;
  1417.   case DBTUX:
  1418.     jam();
  1419.     block = DBLQH;
  1420.     break;
  1421.   case DBLQH:
  1422.     jam();
  1423.     block = DBDIH;
  1424.     break;
  1425.   case DBDIH:
  1426.     jam();
  1427.     execute(signal, dropTabPtr.p->m_participantData.m_callback, 0);
  1428.     return;
  1429.   }
  1430.   ndbrequire(block != 0);
  1431.   dropTabPtr.p->m_participantData.m_block = block;
  1432.   DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
  1433.   req->senderRef = reference();
  1434.   req->senderData = dropTabPtr.p->key;
  1435.   req->tableId = dropTabPtr.p->m_request.tableId;
  1436.   req->requestType = dropTabPtr.p->m_requestType;
  1437.   
  1438.   const Uint32 nodeId = getOwnNodeId();
  1439.   dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor();
  1440.   dropTabPtr.p->m_participantData.m_signalCounter.setWaitingFor(nodeId);
  1441.   BlockReference ref = numberToRef(block, 0);
  1442.   sendSignal(ref, GSN_DROP_TAB_REQ, signal, DropTabReq::SignalLength, JBB);
  1443. }
  1444. void
  1445. Dbdict::dropTab_localDROP_TAB_CONF(Signal* signal){
  1446.   jamEntry();
  1447.   
  1448.   DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
  1449.   DropTableRecordPtr dropTabPtr;  
  1450.   ndbrequire(c_opDropTable.find(dropTabPtr, conf->senderData));
  1451.   
  1452.   ndbrequire(dropTabPtr.p->m_request.tableId == conf->tableId);
  1453.   ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
  1454.   
  1455.   Uint32 nodeId = refToNode(conf->senderRef);
  1456.   dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor(nodeId);
  1457.   
  1458.   if(!dropTabPtr.p->m_participantData.m_signalCounter.done()){
  1459.     jam();
  1460.     ndbrequire(false);
  1461.     return;
  1462.   }
  1463.   dropTab_nextStep(signal, dropTabPtr);
  1464. }
  1465. void
  1466. Dbdict::dropTab_complete(Signal* signal, 
  1467.  Uint32 dropTabPtrI,
  1468.  Uint32 returnCode){
  1469.   jam();
  1470.   DropTableRecordPtr dropTabPtr;  
  1471.   ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
  1472.   
  1473.   Uint32 tableId = dropTabPtr.p->m_request.tableId;
  1474.   
  1475.   /**
  1476.    * Write to schema file
  1477.    */
  1478.   PageRecordPtr pagePtr;
  1479.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  1480.   
  1481.   SchemaFile::TableEntry * tableEntry = getTableEntry(pagePtr.p, tableId);
  1482.   SchemaFile::TableState tabState = 
  1483.     (SchemaFile::TableState)tableEntry->m_tableState;
  1484.   ndbrequire(tabState == SchemaFile::DROP_TABLE_STARTED);
  1485.   tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
  1486.   computeChecksum((SchemaFile*)pagePtr.p);
  1487.   
  1488.   ndbrequire(c_writeSchemaRecord.inUse == false);
  1489.   c_writeSchemaRecord.inUse = true;
  1490.   c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
  1491.   c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
  1492.   c_writeSchemaRecord.m_callback.m_callbackFunction = 
  1493.     safe_cast(&Dbdict::dropTab_writeSchemaConf);
  1494.   startWriteSchemaFile(signal);
  1495. }
  1496. void
  1497. Dbdict::dropTab_writeSchemaConf(Signal* signal, 
  1498. Uint32 dropTabPtrI,
  1499. Uint32 returnCode){
  1500.   jam();
  1501.   DropTableRecordPtr dropTabPtr;  
  1502.   ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
  1503.   ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
  1504.   dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
  1505.   releaseTableObject(dropTabPtr.p->m_request.tableId);
  1506.   DropTabConf * conf = (DropTabConf*)signal->getDataPtr();  
  1507.   conf->senderRef = reference();
  1508.   conf->senderData = dropTabPtrI;
  1509.   conf->tableId = dropTabPtr.p->m_request.tableId;
  1510.   
  1511.   dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
  1512.   sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_DROP_TAB_CONF, signal, 
  1513.      DropTabConf::SignalLength, JBB);
  1514.   
  1515.   if(dropTabPtr.p->m_coordinatorRef != reference()){
  1516.     c_opDropTable.release(dropTabPtr);
  1517.   }
  1518. }
  1519. void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash) 
  1520. {
  1521.   TableRecordPtr tablePtr;
  1522.   AttributeRecordPtr attrPtr;
  1523.   c_tableRecordPool.getPtr(tablePtr, tableId);
  1524.   if (removeFromHash)
  1525.   {
  1526. #ifdef VM_TRACE
  1527.     TableRecordPtr tmp;
  1528.     ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p));
  1529. #endif
  1530.     c_tableRecordHash.remove(tablePtr);
  1531.   }
  1532.   tablePtr.p->tabState = TableRecord::NOT_DEFINED;
  1533.   Uint32 nextAttrRecord = tablePtr.p->firstAttribute;
  1534.   while (nextAttrRecord != RNIL) {
  1535.     jam();
  1536. /* ---------------------------------------------------------------- */
  1537. // Release all attribute records
  1538. /* ---------------------------------------------------------------- */
  1539.     c_attributeRecordPool.getPtr(attrPtr, nextAttrRecord);
  1540.     nextAttrRecord = attrPtr.p->nextAttrInTable;
  1541.     c_attributeRecordPool.release(attrPtr);
  1542.   }//if
  1543. #ifdef HAVE_TABLE_REORG
  1544.   Uint32 secondTableId = tablePtr.p->secondTable;
  1545.   initialiseTableRecord(tablePtr);
  1546.   c_tableRecordPool.getPtr(tablePtr, secondTableId);
  1547.   initialiseTableRecord(tablePtr);
  1548. #endif
  1549.   return; 
  1550. }//releaseTableObject()
  1551. /**
  1552.  * DICT receives these on index create and drop.
  1553.  */
  1554. void Dbdict::execDROP_TABLE_CONF(Signal* signal) 
  1555. {
  1556.   jamEntry();
  1557.   ndbrequire(signal->getNoOfSections() == 0);
  1558.   DropTableConf * const conf = (DropTableConf *)signal->getDataPtr();
  1559.   // assume part of drop index operation
  1560.   OpDropIndexPtr opPtr;
  1561.   c_opDropIndex.find(opPtr, conf->senderData);
  1562.   ndbrequire(! opPtr.isNull());
  1563.   ndbrequire(opPtr.p->m_request.getIndexId() == conf->tableId);
  1564.   ndbrequire(opPtr.p->m_request.getIndexVersion() == conf->tableVersion);
  1565.   dropIndex_fromDropTable(signal, opPtr);
  1566. }
  1567. void Dbdict::execDROP_TABLE_REF(Signal* signal) 
  1568. {
  1569.   jamEntry();
  1570.   DropTableRef * const ref = (DropTableRef *)signal->getDataPtr();
  1571.   // assume part of drop index operation
  1572.   OpDropIndexPtr opPtr;
  1573.   c_opDropIndex.find(opPtr, ref->senderData);
  1574.   ndbrequire(! opPtr.isNull());
  1575.   opPtr.p->setError(ref);
  1576.   opPtr.p->m_errorLine = __LINE__;
  1577.   dropIndex_fromDropTable(signal, opPtr);
  1578. }
  1579. /* **************************************************************** */
  1580. /* ---------------------------------------------------------------- */
  1581. /* MODULE:          EXTERNAL INTERFACE TO DATA -------------------- */
  1582. /* ---------------------------------------------------------------- */
  1583. /*                                                                  */
  1584. /* This module contains the code that is used by other modules to.  */
  1585. /* access the data within DBDICT.                                   */
  1586. /* ---------------------------------------------------------------- */
  1587. /* **************************************************************** */
  1588. void Dbdict::execGET_TABLEDID_REQ(Signal * signal) 
  1589. {
  1590.   jamEntry();
  1591.   ndbrequire(signal->getNoOfSections() == 1);  
  1592.   GetTableIdReq const * req = (GetTableIdReq *)signal->getDataPtr();
  1593.   Uint32 senderData = req->senderData;
  1594.   Uint32 senderRef = req->senderRef;
  1595.   Uint32 len = req->len;
  1596.   if(len>MAX_TAB_NAME_SIZE)
  1597.   {
  1598.     jam();
  1599.     sendGET_TABLEID_REF((Signal*)signal, 
  1600. (GetTableIdReq *)req, 
  1601. GetTableIdRef::TableNameTooLong);
  1602.     return;
  1603.   }
  1604.   char tableName[MAX_TAB_NAME_SIZE];
  1605.   TableRecord keyRecord;
  1606.   SegmentedSectionPtr ssPtr;
  1607.   signal->getSection(ssPtr,GetTableIdReq::TABLE_NAME);
  1608.   copy((Uint32*)tableName, ssPtr);
  1609.   strcpy(keyRecord.tableName, tableName);
  1610.   releaseSections(signal);
  1611.   if(len > sizeof(keyRecord.tableName)){
  1612.     jam();
  1613.     sendGET_TABLEID_REF((Signal*)signal, 
  1614. (GetTableIdReq *)req, 
  1615. GetTableIdRef::TableNameTooLong);
  1616.     return;
  1617.   }
  1618.   
  1619.   TableRecordPtr tablePtr;
  1620.   if(!c_tableRecordHash.find(tablePtr, keyRecord)) {
  1621.     jam();
  1622.     sendGET_TABLEID_REF((Signal*)signal, 
  1623. (GetTableIdReq *)req, 
  1624. GetTableIdRef::TableNotDefined);
  1625.     return;
  1626.   }
  1627.   GetTableIdConf * conf = (GetTableIdConf *)req;
  1628.   conf->tableId               = tablePtr.p->tableId;
  1629.   conf->schemaVersion         = tablePtr.p->tableVersion;
  1630.   conf->senderData            = senderData;
  1631.   sendSignal(senderRef, GSN_GET_TABLEID_CONF, signal,
  1632.      GetTableIdConf::SignalLength, JBB);  
  1633.   
  1634. }
  1635. void Dbdict::sendGET_TABLEID_REF(Signal* signal, 
  1636.  GetTableIdReq * req,
  1637.  GetTableIdRef::ErrorCode errorCode) 
  1638. {
  1639.   GetTableIdRef * const ref = (GetTableIdRef *)req;
  1640.   /**
  1641.    * The format of GetTabInfo Req/Ref is the same
  1642.    */
  1643.   BlockReference retRef = req->senderRef;
  1644.   ref->err  = errorCode;
  1645.   sendSignal(retRef, GSN_GET_TABLEID_REF, signal, 
  1646.      GetTableIdRef::SignalLength, JBB);
  1647. }//sendGET_TABINFOREF()
  1648. /* ---------------------------------------------------------------- */
  1649. // Get a full table description.
  1650. /* ---------------------------------------------------------------- */
  1651. void Dbdict::execGET_TABINFOREQ(Signal* signal) 
  1652. {
  1653.   jamEntry();
  1654.   if(!assembleFragments(signal)) { return; }  
  1655.   GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
  1656.   /**
  1657.    * If I get a GET_TABINFO_REQ from myself
  1658.    * it's is a one from the time queue
  1659.    */
  1660.   bool fromTimeQueue = (signal->senderBlockRef() == reference());
  1661.   
  1662.   if (c_retrieveRecord.busyState && fromTimeQueue == true) {
  1663.     jam();
  1664.     
  1665.     sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30, 
  1666. signal->length());
  1667.     return;
  1668.   }//if
  1669.   const Uint32 MAX_WAITERS = 5;
  1670.   
  1671.   if(c_retrieveRecord.busyState && fromTimeQueue == false){
  1672.     jam();
  1673.     if(c_retrieveRecord.noOfWaiters < MAX_WAITERS){
  1674.       jam();
  1675.       c_retrieveRecord.noOfWaiters++;
  1676.       
  1677.       sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30, 
  1678.   signal->length());
  1679.       return;
  1680.     }
  1681.     
  1682.     sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy);
  1683.     return;
  1684.   }
  1685.   
  1686.   if(fromTimeQueue){
  1687.     jam();
  1688.     c_retrieveRecord.noOfWaiters--;
  1689.   } 
  1690.   const bool useLongSig = (req->requestType & GetTabInfoReq::LongSignalConf);
  1691.   const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
  1692.   
  1693.   TableRecordPtr tablePtr;
  1694.   if(reqType == GetTabInfoReq::RequestByName){
  1695.     jam();
  1696.     ndbrequire(signal->getNoOfSections() == 1);  
  1697.     const Uint32 len = req->tableNameLen;
  1698.     
  1699.     TableRecord keyRecord;
  1700.     if(len > sizeof(keyRecord.tableName)){
  1701.       jam();
  1702.       releaseSections(signal);
  1703.       sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNameTooLong);
  1704.       return;
  1705.     }
  1706.     char tableName[MAX_TAB_NAME_SIZE];
  1707.     SegmentedSectionPtr ssPtr;
  1708.     signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
  1709.     SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
  1710.     r0.reset(); // undo implicit first()
  1711.     if(r0.getWords((Uint32*)tableName, ((len + 3)/4)))
  1712.       memcpy(keyRecord.tableName, tableName, len);
  1713.     else {
  1714.       jam();
  1715.       releaseSections(signal);
  1716.       sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
  1717.       return;
  1718.     }
  1719.     releaseSections(signal);
  1720.     //    memcpy(keyRecord.tableName, req->tableName, len);
  1721.     //ntohS(&keyRecord.tableName[0], len);
  1722.    
  1723.     c_tableRecordHash.find(tablePtr, keyRecord);
  1724.   } else {
  1725.     jam();
  1726.     c_tableRecordPool.getPtr(tablePtr, req->tableId, false);
  1727.   }
  1728.   
  1729.   // The table seached for was not found
  1730.   if(tablePtr.i == RNIL){
  1731.     jam();
  1732.     sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
  1733.     return;
  1734.   }//if
  1735.   
  1736.   if (! (tablePtr.p->tabState == TableRecord::DEFINED ||
  1737.  tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)) {
  1738.     jam();
  1739.     sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
  1740.     return;
  1741.   }//if
  1742.   
  1743.   c_retrieveRecord.busyState = true;
  1744.   c_retrieveRecord.blockRef = req->senderRef;
  1745.   c_retrieveRecord.m_senderData = req->senderData;
  1746.   c_retrieveRecord.tableId = tablePtr.i;
  1747.   c_retrieveRecord.currentSent = 0;
  1748.   c_retrieveRecord.m_useLongSig = useLongSig;
  1749.   
  1750.   c_packTable.m_state = PackTable::PTS_GET_TAB;
  1751.   
  1752.   signal->theData[0] = ZPACK_TABLE_INTO_PAGES;
  1753.   signal->theData[1] = tablePtr.i;
  1754.   signal->theData[2] = c_retrieveRecord.retrievePage;  
  1755.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1756. }//execGET_TABINFOREQ()
  1757. void Dbdict::sendGetTabResponse(Signal* signal) 
  1758. {
  1759.   PageRecordPtr pagePtr;
  1760.   DictTabInfo * const conf = (DictTabInfo *)&signal->theData[0];
  1761.   conf->senderRef   = reference();
  1762.   conf->senderData  = c_retrieveRecord.m_senderData;
  1763.   conf->requestType = DictTabInfo::GetTabInfoConf;
  1764.   conf->totalLen    = c_retrieveRecord.retrievedNoOfWords;
  1765.   c_pageRecordArray.getPtr(pagePtr, c_retrieveRecord.retrievePage);
  1766.   Uint32* pagePointer = (Uint32*)&pagePtr.p->word[0] + ZPAGE_HEADER_SIZE;
  1767.   
  1768.   if(c_retrieveRecord.m_useLongSig){
  1769.     jam();
  1770.     GetTabInfoConf* conf = (GetTabInfoConf*)signal->getDataPtr();
  1771.     conf->gci = 0;
  1772.     conf->tableId = c_retrieveRecord.tableId;
  1773.     conf->senderData = c_retrieveRecord.m_senderData;
  1774.     conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
  1775.     
  1776.     Callback c = { safe_cast(&Dbdict::initRetrieveRecord), 0 };
  1777.     LinearSectionPtr ptr[3];
  1778.     ptr[0].p = pagePointer;
  1779.     ptr[0].sz = c_retrieveRecord.retrievedNoOfWords;
  1780.     sendFragmentedSignal(c_retrieveRecord.blockRef,
  1781.  GSN_GET_TABINFO_CONF,
  1782.  signal, 
  1783.  GetTabInfoConf::SignalLength,
  1784.  JBB,
  1785.  ptr,
  1786.  1,
  1787.  c);
  1788.     return;
  1789.   }
  1790.   ndbrequire(false);
  1791. }//sendGetTabResponse()
  1792. void Dbdict::sendGET_TABINFOREF(Signal* signal, 
  1793. GetTabInfoReq * req,
  1794. GetTabInfoRef::ErrorCode errorCode) 
  1795. {
  1796.   jamEntry();
  1797.   GetTabInfoRef * const ref = (GetTabInfoRef *)&signal->theData[0];
  1798.   /**
  1799.    * The format of GetTabInfo Req/Ref is the same
  1800.    */
  1801.   BlockReference retRef = req->senderRef;
  1802.   ref->errorCode = errorCode;
  1803.   
  1804.   sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
  1805. }//sendGET_TABINFOREF()
  1806. Uint32 convertEndian(Uint32 in) {
  1807. #ifdef WORDS_BIGENDIAN
  1808.   Uint32 ut = 0;
  1809.   ut += ((in >> 24) & 255);
  1810.   ut += (((in >> 16) & 255) << 8);
  1811.   ut += (((in >> 8) & 255) << 16);
  1812.   ut += ((in & 255) << 24);
  1813.   return ut;
  1814. #else
  1815.   return in;
  1816. #endif
  1817. }
  1818. void
  1819. Dbdict::execLIST_TABLES_REQ(Signal* signal)
  1820. {
  1821.   jamEntry();
  1822.   Uint32 i;
  1823.   ListTablesReq * req = (ListTablesReq*)signal->getDataPtr();
  1824.   Uint32 senderRef  = req->senderRef;
  1825.   Uint32 senderData = req->senderData;
  1826.   // save req flags
  1827.   const Uint32 reqTableId = req->getTableId();
  1828.   const Uint32 reqTableType = req->getTableType();
  1829.   const bool reqListNames = req->getListNames();
  1830.   const bool reqListIndexes = req->getListIndexes();
  1831.   // init the confs
  1832.   ListTablesConf * conf = (ListTablesConf *)signal->getDataPtrSend();
  1833.   conf->senderData = senderData;
  1834.   conf->counter = 0;
  1835.   Uint32 pos = 0;
  1836.   for (i = 0; i < c_tableRecordPool.getSize(); i++) {
  1837.     TableRecordPtr tablePtr;
  1838.     c_tableRecordPool.getPtr(tablePtr, i);
  1839.     // filter
  1840.     if (tablePtr.p->tabState == TableRecord::NOT_DEFINED ||
  1841.         tablePtr.p->tabState == TableRecord::REORG_TABLE_PREPARED)
  1842.       continue;
  1843.     if ((reqTableType != (Uint32)0) && (reqTableType != (unsigned)tablePtr.p->tableType))
  1844.       continue;
  1845.     if (reqListIndexes && reqTableId != tablePtr.p->primaryTableId)
  1846.       continue;
  1847.     conf->tableData[pos] = 0;
  1848.     // id
  1849.     conf->setTableId(pos, tablePtr.i);
  1850.     // type
  1851.     conf->setTableType(pos, tablePtr.p->tableType);
  1852.     // state
  1853.     if (tablePtr.p->isTable()) {
  1854.       switch (tablePtr.p->tabState) {
  1855.       case TableRecord::DEFINING:
  1856.       case TableRecord::CHECKED:
  1857.         conf->setTableState(pos, DictTabInfo::StateBuilding);
  1858.         break;
  1859.       case TableRecord::PREPARE_DROPPING:
  1860.       case TableRecord::DROPPING:
  1861.         conf->setTableState(pos, DictTabInfo::StateDropping);
  1862.         break;
  1863.       case TableRecord::DEFINED:
  1864.         conf->setTableState(pos, DictTabInfo::StateOnline);
  1865.         break;
  1866.       case TableRecord::BACKUP_ONGOING:
  1867.         conf->setTableState(pos, DictTabInfo::StateBackup);
  1868. break;
  1869.       default:
  1870.         conf->setTableState(pos, DictTabInfo::StateBroken);
  1871.         break;
  1872.       }
  1873.     }
  1874.     if (tablePtr.p->isIndex()) {
  1875.       switch (tablePtr.p->indexState) {
  1876.       case TableRecord::IS_OFFLINE:
  1877.         conf->setTableState(pos, DictTabInfo::StateOffline);
  1878.         break;
  1879.       case TableRecord::IS_BUILDING:
  1880.         conf->setTableState(pos, DictTabInfo::StateBuilding);
  1881.         break;
  1882.       case TableRecord::IS_DROPPING:
  1883.         conf->setTableState(pos, DictTabInfo::StateDropping);
  1884.         break;
  1885.       case TableRecord::IS_ONLINE:
  1886.         conf->setTableState(pos, DictTabInfo::StateOnline);
  1887.         break;
  1888.       default:
  1889.         conf->setTableState(pos, DictTabInfo::StateBroken);
  1890.         break;
  1891.       }
  1892.     }
  1893.     // store
  1894.     if (! tablePtr.p->storedTable) {
  1895.       conf->setTableStore(pos, DictTabInfo::StoreTemporary);
  1896.     } else {
  1897.       conf->setTableStore(pos, DictTabInfo::StorePermanent);
  1898.     }
  1899.     pos++;
  1900.     if (pos >= ListTablesConf::DataLength) {
  1901.       sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
  1902.  ListTablesConf::SignalLength, JBB);
  1903.       conf->counter++;
  1904.       pos = 0;
  1905.     }
  1906.     if (! reqListNames)
  1907.       continue;
  1908.     const Uint32 size = strlen(tablePtr.p->tableName) + 1;
  1909.     conf->tableData[pos] = size;
  1910.     pos++;
  1911.     if (pos >= ListTablesConf::DataLength) {
  1912.       sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
  1913.  ListTablesConf::SignalLength, JBB);
  1914.       conf->counter++;
  1915.       pos = 0;
  1916.     }
  1917.     Uint32 k = 0;
  1918.     while (k < size) {
  1919.       char* p = (char*)&conf->tableData[pos];
  1920.       for (Uint32 j = 0; j < 4; j++) {
  1921.         if (k < size)
  1922.           *p++ = tablePtr.p->tableName[k++];
  1923.         else
  1924.           *p++ = 0;
  1925.       }
  1926.       pos++;
  1927.       if (pos >= ListTablesConf::DataLength) {
  1928.         sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
  1929.                    ListTablesConf::SignalLength, JBB);
  1930.         conf->counter++;
  1931.         pos = 0;
  1932.       }
  1933.     }
  1934.   }
  1935.   // XXX merge with above somehow
  1936.   for (i = 0; i < c_triggerRecordPool.getSize(); i++) {
  1937.     if (reqListIndexes)
  1938.       break;
  1939.     TriggerRecordPtr triggerPtr;
  1940.     c_triggerRecordPool.getPtr(triggerPtr, i);
  1941.     if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED)
  1942.       continue;
  1943.     // constant 10 hardcoded
  1944.     Uint32 type = 10 + triggerPtr.p->triggerType;
  1945.     if (reqTableType != 0 && reqTableType != type)
  1946.       continue;
  1947.     conf->tableData[pos] = 0;
  1948.     conf->setTableId(pos, triggerPtr.i);
  1949.     conf->setTableType(pos, type);
  1950.     switch (triggerPtr.p->triggerState) {
  1951.     case TriggerRecord::TS_OFFLINE:
  1952.       conf->setTableState(pos, DictTabInfo::StateOffline);
  1953.       break;
  1954.     case TriggerRecord::TS_ONLINE:
  1955.       conf->setTableState(pos, DictTabInfo::StateOnline);
  1956.       break;
  1957.     default:
  1958.       conf->setTableState(pos, DictTabInfo::StateBroken);
  1959.       break;
  1960.     }
  1961.     conf->setTableStore(pos, DictTabInfo::StoreTemporary);
  1962.     pos++;
  1963.     if (pos >= ListTablesConf::DataLength) {
  1964.       sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
  1965.         ListTablesConf::SignalLength, JBB);
  1966.       conf->counter++;
  1967.       pos = 0;
  1968.     }
  1969.     if (! reqListNames)
  1970.       continue;
  1971.     const Uint32 size = strlen(triggerPtr.p->triggerName) + 1;
  1972.     conf->tableData[pos] = size;
  1973.     pos++;
  1974.     if (pos >= ListTablesConf::DataLength) {
  1975.       sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
  1976.  ListTablesConf::SignalLength, JBB);
  1977.       conf->counter++;
  1978.       pos = 0;
  1979.     }
  1980.     Uint32 k = 0;
  1981.     while (k < size) {
  1982.       char* p = (char*)&conf->tableData[pos];
  1983.       for (Uint32 j = 0; j < 4; j++) {
  1984.         if (k < size)
  1985.           *p++ = triggerPtr.p->triggerName[k++];
  1986.         else
  1987.           *p++ = 0;
  1988.       }
  1989.       pos++;
  1990.       if (pos >= ListTablesConf::DataLength) {
  1991.         sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
  1992.                    ListTablesConf::SignalLength, JBB);
  1993.         conf->counter++;
  1994.         pos = 0;
  1995.       }
  1996.     }
  1997.   }
  1998.   // last signal must have less than max length
  1999.   sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
  2000.      ListTablesConf::HeaderLength + pos, JBB);
  2001. }
  2002. /**
  2003.  * MODULE: Create index
  2004.  *
  2005.  * Create index in DICT via create table operation.  Then invoke alter
  2006.  * index opearation to online the index.
  2007.  *
  2008.  * Request type in CREATE_INDX signals:
  2009.  *
  2010.  * RT_USER - from API to DICT master
  2011.  * RT_DICT_PREPARE - prepare participants
  2012.  * RT_DICT_COMMIT - commit participants
  2013.  * RT_TC - create index in TC (part of alter index operation)
  2014.  */
  2015. void
  2016. Dbdict::execCREATE_INDX_REQ(Signal* signal)
  2017. {
  2018.   jamEntry();
  2019.   CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
  2020.   OpCreateIndexPtr opPtr;
  2021.   const Uint32 senderRef = signal->senderBlockRef();
  2022.   const CreateIndxReq::RequestType requestType = req->getRequestType();
  2023.   if (requestType == CreateIndxReq::RT_USER) {
  2024.     jam();
  2025.     if (! assembleFragments(signal)) {
  2026.       jam();
  2027.       return;
  2028.     }
  2029.     if (signal->getLength() == CreateIndxReq::SignalLength) {
  2030.       jam();
  2031.       if (getOwnNodeId() != c_masterNodeId) {
  2032.         jam();
  2033. releaseSections(signal);
  2034. OpCreateIndex opBusy;
  2035. opPtr.p = &opBusy;
  2036. opPtr.p->save(req);
  2037. opPtr.p->m_isMaster = (senderRef == reference());
  2038. opPtr.p->key = 0;
  2039. opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
  2040. opPtr.p->m_errorCode = CreateIndxRef::NotMaster;
  2041. opPtr.p->m_errorLine = __LINE__;
  2042. opPtr.p->m_errorNode = c_masterNodeId;
  2043. createIndex_sendReply(signal, opPtr, true);
  2044. return;
  2045.       }
  2046.       
  2047.       // forward initial request plus operation key to all
  2048.       req->setOpKey(++c_opRecordSequence);
  2049.       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2050.       sendSignal(rg, GSN_CREATE_INDX_REQ,
  2051.           signal, CreateIndxReq::SignalLength + 1, JBB);
  2052.       return;
  2053.     }
  2054.     // seize operation record
  2055.     ndbrequire(signal->getLength() == CreateIndxReq::SignalLength + 1);
  2056.     const Uint32 opKey = req->getOpKey();
  2057.     OpCreateIndex opBusy;
  2058.     if (! c_opCreateIndex.seize(opPtr))
  2059.       opPtr.p = &opBusy;
  2060.     opPtr.p->save(req);
  2061.     opPtr.p->m_coordinatorRef = senderRef;
  2062.     opPtr.p->m_isMaster = (senderRef == reference());
  2063.     opPtr.p->key = opKey;
  2064.     opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
  2065.     if (opPtr.p == &opBusy) {
  2066.       jam();
  2067.       opPtr.p->m_errorCode = CreateIndxRef::Busy;
  2068.       opPtr.p->m_errorLine = __LINE__;
  2069.       releaseSections(signal);
  2070.       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2071.       return;
  2072.     }
  2073.     c_opCreateIndex.add(opPtr);
  2074.     // save attribute list
  2075.     SegmentedSectionPtr ssPtr;
  2076.     signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
  2077.     SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
  2078.     r0.reset(); // undo implicit first()
  2079.     if (! r0.getWord(&opPtr.p->m_attrList.sz) ||
  2080.         ! r0.getWords(opPtr.p->m_attrList.id, opPtr.p->m_attrList.sz)) {
  2081.       jam();
  2082.       opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
  2083.       opPtr.p->m_errorLine = __LINE__;
  2084.       releaseSections(signal);
  2085.       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2086.       return;
  2087.     }
  2088.     // save name and index table properties
  2089.     signal->getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
  2090.     SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool());
  2091.     DictTabInfo::Table tableDesc;
  2092.     tableDesc.init();
  2093.     SimpleProperties::UnpackStatus status = SimpleProperties::unpack(
  2094.         r1, &tableDesc,
  2095.         DictTabInfo::TableMapping, DictTabInfo::TableMappingSize,
  2096.         true, true);
  2097.     if (status != SimpleProperties::Eof) {
  2098.       opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
  2099.       opPtr.p->m_errorLine = __LINE__;
  2100.       releaseSections(signal);
  2101.       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2102.       return;
  2103.     }
  2104.     memcpy(opPtr.p->m_indexName, tableDesc.TableName, MAX_TAB_NAME_SIZE);
  2105.     opPtr.p->m_storedIndex = tableDesc.TableLoggedFlag;
  2106.     releaseSections(signal);
  2107.     // master expects to hear from all
  2108.     if (opPtr.p->m_isMaster)
  2109.       opPtr.p->m_signalCounter = c_aliveNodes;
  2110.     createIndex_slavePrepare(signal, opPtr);
  2111.     createIndex_sendReply(signal, opPtr, false);
  2112.     return;
  2113.   }
  2114.   c_opCreateIndex.find(opPtr, req->getConnectionPtr());
  2115.   if (! opPtr.isNull()) {
  2116.     opPtr.p->m_requestType = requestType;
  2117.     if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
  2118.         requestType == CreateIndxReq::RT_DICT_ABORT) {
  2119.       jam();
  2120.       if (requestType == CreateIndxReq::RT_DICT_COMMIT) {
  2121.         opPtr.p->m_request.setIndexId(req->getIndexId());
  2122.         opPtr.p->m_request.setIndexVersion(req->getIndexVersion());
  2123.         createIndex_slaveCommit(signal, opPtr);
  2124.       } else {
  2125.         createIndex_slaveAbort(signal, opPtr);
  2126.       }
  2127.       createIndex_sendReply(signal, opPtr, false);
  2128.       // done in slave
  2129.       if (! opPtr.p->m_isMaster)
  2130.         c_opCreateIndex.release(opPtr);
  2131.       return;
  2132.     }
  2133.   }
  2134.   jam();
  2135.   // return to sender
  2136.   releaseSections(signal);
  2137.   OpCreateIndex opBad;
  2138.   opPtr.p = &opBad;
  2139.   opPtr.p->save(req);
  2140.   opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
  2141.   opPtr.p->m_errorLine = __LINE__;
  2142.   createIndex_sendReply(signal, opPtr, true);
  2143. }
  2144. void
  2145. Dbdict::execCREATE_INDX_CONF(Signal* signal)
  2146. {
  2147.   jamEntry();
  2148.   ndbrequire(signal->getNoOfSections() == 0);
  2149.   CreateIndxConf* conf = (CreateIndxConf*)signal->getDataPtrSend();
  2150.   createIndex_recvReply(signal, conf, 0);
  2151. }
  2152. void
  2153. Dbdict::execCREATE_INDX_REF(Signal* signal) 
  2154. {
  2155.   jamEntry();      
  2156.   CreateIndxRef* ref = (CreateIndxRef*)signal->getDataPtrSend();
  2157.   createIndex_recvReply(signal, ref->getConf(), ref);
  2158. }
  2159. void
  2160. Dbdict::createIndex_recvReply(Signal* signal, const CreateIndxConf* conf,
  2161.     const CreateIndxRef* ref)
  2162. {
  2163.   jam();
  2164.   const Uint32 senderRef = signal->senderBlockRef();
  2165.   const CreateIndxReq::RequestType requestType = conf->getRequestType();
  2166.   const Uint32 key = conf->getConnectionPtr();
  2167.   if (requestType == CreateIndxReq::RT_TC) {
  2168.     jam();
  2169.     // part of alter index operation
  2170.     OpAlterIndexPtr opPtr;
  2171.     c_opAlterIndex.find(opPtr, key);
  2172.     ndbrequire(! opPtr.isNull());
  2173.     opPtr.p->setError(ref);
  2174.     alterIndex_fromCreateTc(signal, opPtr);
  2175.     return;
  2176.   }
  2177.   OpCreateIndexPtr opPtr;
  2178.   c_opCreateIndex.find(opPtr, key);
  2179.   ndbrequire(! opPtr.isNull());
  2180.   ndbrequire(opPtr.p->m_isMaster);
  2181.   ndbrequire(opPtr.p->m_requestType == requestType);
  2182.   opPtr.p->setError(ref);
  2183.   opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
  2184.   if (! opPtr.p->m_signalCounter.done()) {
  2185.     jam();
  2186.     return;
  2187.   }
  2188.   if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
  2189.       requestType == CreateIndxReq::RT_DICT_ABORT) {
  2190.     jam();
  2191.     // send reply to user
  2192.     createIndex_sendReply(signal, opPtr, true);
  2193.     c_opCreateIndex.release(opPtr);
  2194.     return;
  2195.   }
  2196.   if (opPtr.p->hasError()) {
  2197.     jam();
  2198.     opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
  2199.     createIndex_sendSlaveReq(signal, opPtr);
  2200.     return;
  2201.   }
  2202.   if (requestType == CreateIndxReq::RT_DICT_PREPARE) {
  2203.     jam();
  2204.     // start index table create
  2205.     createIndex_toCreateTable(signal, opPtr);
  2206.     if (opPtr.p->hasError()) {
  2207.       jam();
  2208.       opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
  2209.       createIndex_sendSlaveReq(signal, opPtr);
  2210.       return;
  2211.     }
  2212.     return;
  2213.   }
  2214.   ndbrequire(false);
  2215. }
  2216. void
  2217. Dbdict::createIndex_slavePrepare(Signal* signal, OpCreateIndexPtr opPtr)
  2218. {
  2219.   jam();
  2220. }
  2221. void
  2222. Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
  2223. {
  2224.   Uint32 k;
  2225.   jam();
  2226.   const CreateIndxReq* const req = &opPtr.p->m_request;
  2227.   // signal data writer
  2228.   Uint32* wbuffer = &c_indexPage.word[0];
  2229.   LinearWriter w(wbuffer, sizeof(c_indexPage) >> 2);
  2230.   w.first();
  2231.   // get table being indexed
  2232.   if (! (req->getTableId() < c_tableRecordPool.getSize())) {
  2233.     jam();
  2234.     opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
  2235.     opPtr.p->m_errorLine = __LINE__;
  2236.     return;
  2237.   }
  2238.   TableRecordPtr tablePtr;
  2239.   c_tableRecordPool.getPtr(tablePtr, req->getTableId());
  2240.   if (tablePtr.p->tabState != TableRecord::DEFINED &&
  2241.       tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
  2242.     jam();
  2243.     opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
  2244.     opPtr.p->m_errorLine = __LINE__;
  2245.     return;
  2246.   }
  2247.   if (! tablePtr.p->isTable()) {
  2248.     jam();
  2249.     opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
  2250.     opPtr.p->m_errorLine = __LINE__;
  2251.     return;
  2252.   }
  2253.   // compute index table record
  2254.   TableRecord indexRec;
  2255.   TableRecordPtr indexPtr;
  2256.   indexPtr.i = RNIL;            // invalid
  2257.   indexPtr.p = &indexRec;
  2258.   initialiseTableRecord(indexPtr);
  2259.   if (req->getIndexType() == DictTabInfo::UniqueHashIndex) {
  2260.     indexPtr.p->storedTable = opPtr.p->m_storedIndex;
  2261.     indexPtr.p->fragmentType = tablePtr.p->fragmentType;
  2262.   } else if (req->getIndexType() == DictTabInfo::OrderedIndex) {
  2263.     // first version will not supported logging
  2264.     if (opPtr.p->m_storedIndex) {
  2265.       jam();
  2266.       opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
  2267.       opPtr.p->m_errorLine = __LINE__;
  2268.       return;
  2269.     }
  2270.     indexPtr.p->storedTable = false;
  2271.     // follows table fragmentation
  2272.     indexPtr.p->fragmentType = tablePtr.p->fragmentType;
  2273.   } else {
  2274.     jam();
  2275.     opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
  2276.     opPtr.p->m_errorLine = __LINE__;
  2277.     return;
  2278.   }
  2279.   indexPtr.p->tableType = (DictTabInfo::TableType)req->getIndexType();
  2280.   indexPtr.p->primaryTableId = req->getTableId();
  2281.   indexPtr.p->noOfAttributes = opPtr.p->m_attrList.sz;
  2282.   indexPtr.p->tupKeyLength = 0;
  2283.   if (indexPtr.p->noOfAttributes == 0) {
  2284.     jam();
  2285.     opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
  2286.     opPtr.p->m_errorLine = __LINE__;
  2287.     return;
  2288.   }
  2289.   if (indexPtr.p->isOrderedIndex()) {
  2290.     // tree node size in words (make configurable later)
  2291.     indexPtr.p->tupKeyLength = MAX_TTREE_NODE_SIZE;
  2292.   }
  2293.   // hash index attributes must currently be in table order
  2294.   Uint32 prevAttrId = RNIL;
  2295.   for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
  2296.     jam();
  2297.     bool found = false;
  2298.     for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
  2299.       AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
  2300.       tAttr = aRec->nextAttrInTable;
  2301.       if (aRec->attributeId != opPtr.p->m_attrList.id[k])
  2302.         continue;
  2303.       jam();
  2304.       found = true;
  2305.       const Uint32 a = aRec->attributeDescriptor;
  2306.       if (indexPtr.p->isHashIndex()) {
  2307.         const Uint32 s1 = AttributeDescriptor::getSize(a);
  2308.         const Uint32 s2 = AttributeDescriptor::getArraySize(a);
  2309.         indexPtr.p->tupKeyLength += ((1 << s1) * s2 + 31) >> 5;
  2310.       }
  2311.     }
  2312.     if (! found) {
  2313.       jam();
  2314.       opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
  2315.       opPtr.p->m_errorLine = __LINE__;
  2316.       return;
  2317.     }
  2318.     if (indexPtr.p->isHashIndex() && 
  2319.         k > 0 && prevAttrId >= opPtr.p->m_attrList.id[k]) {
  2320.       jam();
  2321.       opPtr.p->m_errorCode = CreateIndxRef::InvalidAttributeOrder;
  2322.       opPtr.p->m_errorLine = __LINE__;
  2323.       return;
  2324.     }
  2325.     prevAttrId = opPtr.p->m_attrList.id[k];
  2326.   }
  2327.   indexPtr.p->noOfPrimkey = indexPtr.p->noOfAttributes;
  2328.   // plus concatenated primary table key attribute
  2329.   indexPtr.p->noOfAttributes += 1;
  2330.   indexPtr.p->noOfNullAttr = 0;
  2331.   // write index table
  2332.   w.add(DictTabInfo::TableName, opPtr.p->m_indexName);
  2333.   w.add(DictTabInfo::TableLoggedFlag, indexPtr.p->storedTable);
  2334.   w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType);
  2335.   w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType);
  2336.   w.add(DictTabInfo::PrimaryTable, tablePtr.p->tableName);
  2337.   w.add(DictTabInfo::PrimaryTableId, tablePtr.i);
  2338.   w.add(DictTabInfo::NoOfAttributes, indexPtr.p->noOfAttributes);
  2339.   w.add(DictTabInfo::NoOfKeyAttr, indexPtr.p->noOfPrimkey);
  2340.   w.add(DictTabInfo::NoOfNullable, indexPtr.p->noOfNullAttr);
  2341.   w.add(DictTabInfo::KeyLength, indexPtr.p->tupKeyLength);
  2342.   // write index key attributes
  2343.   AttributeRecordPtr aRecPtr;
  2344.   c_attributeRecordPool.getPtr(aRecPtr, tablePtr.p->firstAttribute);
  2345.   for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
  2346.     jam();
  2347.     for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
  2348.       AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
  2349.       tAttr = aRec->nextAttrInTable;
  2350.       if (aRec->attributeId != opPtr.p->m_attrList.id[k])
  2351.         continue;
  2352.       jam();
  2353.       const Uint32 a = aRec->attributeDescriptor;
  2354.       bool isNullable = AttributeDescriptor::getNullable(a);
  2355.       w.add(DictTabInfo::AttributeName, aRec->attributeName);
  2356.       w.add(DictTabInfo::AttributeId, k);
  2357.       if (indexPtr.p->isHashIndex()) {
  2358.         w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
  2359.         w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
  2360.       }
  2361.       if (indexPtr.p->isOrderedIndex()) {
  2362.         w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
  2363.         w.add(DictTabInfo::AttributeNullableFlag, (Uint32)isNullable);
  2364.       }
  2365.       w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored);
  2366.       // ext type overrides
  2367.       w.add(DictTabInfo::AttributeExtType, aRec->extType);
  2368.       w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision);
  2369.       w.add(DictTabInfo::AttributeExtScale, aRec->extScale);
  2370.       w.add(DictTabInfo::AttributeExtLength, aRec->extLength);
  2371.       w.add(DictTabInfo::AttributeEnd, (Uint32)true);
  2372.     }
  2373.   }
  2374.   if (indexPtr.p->isHashIndex()) {
  2375.     jam();
  2376.     // write concatenated primary table key attribute
  2377.     w.add(DictTabInfo::AttributeName, "NDB$PK");
  2378.     w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
  2379.     w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
  2380.     w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored);
  2381.     w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
  2382.     // ext type overrides
  2383.     w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
  2384.     w.add(DictTabInfo::AttributeExtLength, tablePtr.p->tupKeyLength);
  2385.     w.add(DictTabInfo::AttributeEnd, (Uint32)true);
  2386.   }
  2387.   if (indexPtr.p->isOrderedIndex()) {
  2388.     jam();
  2389.     // write index tree node as Uint32 array attribute
  2390.     w.add(DictTabInfo::AttributeName, "NDB$TNODE");
  2391.     w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
  2392.     w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
  2393.     w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored);
  2394.     w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
  2395.     // ext type overrides
  2396.     w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
  2397.     w.add(DictTabInfo::AttributeExtLength, indexPtr.p->tupKeyLength);
  2398.     w.add(DictTabInfo::AttributeEnd, (Uint32)true);
  2399.   }
  2400.   // finish
  2401.   w.add(DictTabInfo::TableEnd, (Uint32)true);
  2402.   // remember to...
  2403.   releaseSections(signal);
  2404.   // send create index table request
  2405.   CreateTableReq * const cre = (CreateTableReq*)signal->getDataPtrSend();
  2406.   cre->senderRef = reference();
  2407.   cre->senderData = opPtr.p->key;
  2408.   LinearSectionPtr lsPtr[3];
  2409.   lsPtr[0].p = wbuffer;
  2410.   lsPtr[0].sz = w.getWordsUsed();
  2411.   sendSignal(DBDICT_REF, GSN_CREATE_TABLE_REQ,
  2412.       signal, CreateTableReq::SignalLength, JBB, lsPtr, 1);
  2413. }
  2414. void
  2415. Dbdict::createIndex_fromCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
  2416. {
  2417.   jam();
  2418.   if (opPtr.p->hasError()) {
  2419.     jam();
  2420.     opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
  2421.     createIndex_sendSlaveReq(signal, opPtr);
  2422.     return;
  2423.   }
  2424.   if (! opPtr.p->m_request.getOnline()) {
  2425.     jam();
  2426.     opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
  2427.     createIndex_sendSlaveReq(signal, opPtr);
  2428.     return;
  2429.   }
  2430.   createIndex_toAlterIndex(signal, opPtr);
  2431. }
  2432. void
  2433. Dbdict::createIndex_toAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
  2434. {
  2435.   jam();
  2436.   AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
  2437.   req->setUserRef(reference());
  2438.   req->setConnectionPtr(opPtr.p->key);
  2439.   req->setRequestType(AlterIndxReq::RT_CREATE_INDEX);
  2440.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2441.   req->setTableId(opPtr.p->m_request.getTableId());
  2442.   req->setIndexId(opPtr.p->m_request.getIndexId());
  2443.   req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
  2444.   req->setOnline(true);
  2445.   sendSignal(reference(), GSN_ALTER_INDX_REQ,
  2446.       signal, AlterIndxReq::SignalLength, JBB);
  2447. }
  2448. void
  2449. Dbdict::createIndex_fromAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
  2450. {
  2451.   jam();
  2452.   if (opPtr.p->hasError()) {
  2453.     jam();
  2454.     opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
  2455.     createIndex_sendSlaveReq(signal, opPtr);
  2456.     return;
  2457.   }
  2458.   opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
  2459.   createIndex_sendSlaveReq(signal, opPtr);
  2460. }
  2461. void
  2462. Dbdict::createIndex_slaveCommit(Signal* signal, OpCreateIndexPtr opPtr)
  2463. {
  2464.   jam();
  2465.   const Uint32 indexId = opPtr.p->m_request.getIndexId();
  2466.   TableRecordPtr indexPtr;
  2467.   c_tableRecordPool.getPtr(indexPtr, indexId);
  2468.   if (! opPtr.p->m_request.getOnline()) {
  2469.     ndbrequire(indexPtr.p->indexState == TableRecord::IS_UNDEFINED);
  2470.     indexPtr.p->indexState = TableRecord::IS_OFFLINE;
  2471.   } else {
  2472.     ndbrequire(indexPtr.p->indexState == TableRecord::IS_ONLINE);
  2473.   }
  2474. }
  2475. void
  2476. Dbdict::createIndex_slaveAbort(Signal* signal, OpCreateIndexPtr opPtr)
  2477. {
  2478.   jam();
  2479.   CreateIndxReq* const req = &opPtr.p->m_request;
  2480.   const Uint32 indexId = req->getIndexId();
  2481.   if (indexId >= c_tableRecordPool.getSize()) {
  2482.     jam();
  2483.     return;
  2484.   }
  2485.   TableRecordPtr indexPtr;
  2486.   c_tableRecordPool.getPtr(indexPtr, indexId);
  2487.   if (! indexPtr.p->isIndex()) {
  2488.     jam();
  2489.     return;
  2490.   }
  2491.   indexPtr.p->indexState = TableRecord::IS_BROKEN;
  2492. }
  2493. void
  2494. Dbdict::createIndex_sendSlaveReq(Signal* signal, OpCreateIndexPtr opPtr)
  2495. {
  2496.   jam();
  2497.   CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
  2498.   *req = opPtr.p->m_request;
  2499.   req->setUserRef(opPtr.p->m_coordinatorRef);
  2500.   req->setConnectionPtr(opPtr.p->key);
  2501.   req->setRequestType(opPtr.p->m_requestType);
  2502.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2503.   opPtr.p->m_signalCounter = c_aliveNodes;
  2504.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2505.   sendSignal(rg, GSN_CREATE_INDX_REQ,
  2506.       signal, CreateIndxReq::SignalLength, JBB);
  2507. }
  2508. void
  2509. Dbdict::createIndex_sendReply(Signal* signal, OpCreateIndexPtr opPtr,
  2510.     bool toUser)
  2511. {
  2512.   CreateIndxRef* rep = (CreateIndxRef*)signal->getDataPtrSend();
  2513.   Uint32 gsn = GSN_CREATE_INDX_CONF;
  2514.   Uint32 length = CreateIndxConf::InternalLength;
  2515.   bool sendRef;
  2516.   if (! toUser) {
  2517.     sendRef = opPtr.p->hasLastError();
  2518.     rep->setUserRef(opPtr.p->m_coordinatorRef);
  2519.     rep->setConnectionPtr(opPtr.p->key);
  2520.     rep->setRequestType(opPtr.p->m_requestType);
  2521.     if (opPtr.p->m_requestType == CreateIndxReq::RT_DICT_ABORT)
  2522.       sendRef = false;
  2523.   } else {
  2524.     sendRef = opPtr.p->hasError();
  2525.     rep->setUserRef(opPtr.p->m_request.getUserRef());
  2526.     rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
  2527.     rep->setRequestType(opPtr.p->m_request.getRequestType());
  2528.     length = CreateIndxConf::SignalLength;
  2529.   }
  2530.   rep->setTableId(opPtr.p->m_request.getTableId());
  2531.   rep->setIndexId(opPtr.p->m_request.getIndexId());
  2532.   rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
  2533.   if (sendRef) {
  2534.     if (opPtr.p->m_errorNode == 0)
  2535.       opPtr.p->m_errorNode = getOwnNodeId();
  2536.     rep->setErrorCode(opPtr.p->m_errorCode);
  2537.     rep->setErrorLine(opPtr.p->m_errorLine);
  2538.     rep->setErrorNode(opPtr.p->m_errorNode);
  2539.     gsn = GSN_CREATE_INDX_REF;
  2540.     length = CreateIndxRef::SignalLength;
  2541.   }
  2542.   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
  2543. }
  2544. /**
  2545.  * MODULE: Drop index.
  2546.  *
  2547.  * Drop index.  First alters the index offline (i.e.  drops metadata in
  2548.  * other blocks) and then drops the index table.
  2549.  */
  2550. void
  2551. Dbdict::execDROP_INDX_REQ(Signal* signal)
  2552. {
  2553.   jamEntry();
  2554.   DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
  2555.   OpDropIndexPtr opPtr;
  2556.   int err = DropIndxRef::BadRequestType;
  2557.   const Uint32 senderRef = signal->senderBlockRef();
  2558.   const DropIndxReq::RequestType requestType = req->getRequestType();
  2559.   if (requestType == DropIndxReq::RT_USER) {
  2560.     jam();
  2561.     if (signal->getLength() == DropIndxReq::SignalLength) {
  2562.       jam();
  2563.       if (getOwnNodeId() != c_masterNodeId) {
  2564.         jam();
  2565. err = DropIndxRef::NotMaster;
  2566. goto error;
  2567.       }
  2568.       // forward initial request plus operation key to all
  2569.       Uint32 indexId= req->getIndexId();
  2570.       Uint32 indexVersion= req->getIndexVersion();
  2571.       TableRecordPtr tmp;
  2572.       int res = getMetaTablePtr(tmp, indexId,  indexVersion);
  2573.       switch(res){
  2574.       case MetaData::InvalidArgument:
  2575. err = DropIndxRef::IndexNotFound;
  2576. goto error;
  2577.       case MetaData::TableNotFound:
  2578.       case MetaData::InvalidTableVersion:
  2579. err = DropIndxRef::InvalidIndexVersion;
  2580. goto error;
  2581.       }
  2582.       if (! tmp.p->isIndex()) {
  2583. jam();
  2584. err = DropIndxRef::NotAnIndex;
  2585. goto error;
  2586.       }
  2587.       if (tmp.p->indexState != TableRecord::IS_ONLINE)
  2588.         req->addRequestFlag(RequestFlag::RF_FORCE);
  2589.       tmp.p->indexState = TableRecord::IS_DROPPING;
  2590.       req->setOpKey(++c_opRecordSequence);
  2591.       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2592.       sendSignal(rg, GSN_DROP_INDX_REQ,
  2593.           signal, DropIndxReq::SignalLength + 1, JBB);
  2594.       return;
  2595.     }
  2596.     // seize operation record
  2597.     ndbrequire(signal->getLength() == DropIndxReq::SignalLength + 1);
  2598.     const Uint32 opKey = req->getOpKey();
  2599.     OpDropIndex opBusy;
  2600.     if (! c_opDropIndex.seize(opPtr))
  2601.       opPtr.p = &opBusy;
  2602.     opPtr.p->save(req);
  2603.     opPtr.p->m_coordinatorRef = senderRef;
  2604.     opPtr.p->m_isMaster = (senderRef == reference());
  2605.     opPtr.p->key = opKey;
  2606.     opPtr.p->m_requestType = DropIndxReq::RT_DICT_PREPARE;
  2607.     if (opPtr.p == &opBusy) {
  2608.       jam();
  2609.       opPtr.p->m_errorCode = DropIndxRef::Busy;
  2610.       opPtr.p->m_errorLine = __LINE__;
  2611.       dropIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2612.       return;
  2613.     }
  2614.     c_opDropIndex.add(opPtr);
  2615.     // master expects to hear from all
  2616.     if (opPtr.p->m_isMaster)
  2617.       opPtr.p->m_signalCounter = c_aliveNodes;
  2618.     dropIndex_slavePrepare(signal, opPtr);
  2619.     dropIndex_sendReply(signal, opPtr, false);
  2620.     return;
  2621.   }
  2622.   c_opDropIndex.find(opPtr, req->getConnectionPtr());
  2623.   if (! opPtr.isNull()) {
  2624.     opPtr.p->m_requestType = requestType;
  2625.     if (requestType == DropIndxReq::RT_DICT_COMMIT ||
  2626.         requestType == DropIndxReq::RT_DICT_ABORT) {
  2627.       jam();
  2628.       if (requestType == DropIndxReq::RT_DICT_COMMIT)
  2629.         dropIndex_slaveCommit(signal, opPtr);
  2630.       else
  2631.         dropIndex_slaveAbort(signal, opPtr);
  2632.       dropIndex_sendReply(signal, opPtr, false);
  2633.       // done in slave
  2634.       if (! opPtr.p->m_isMaster)
  2635.         c_opDropIndex.release(opPtr);
  2636.       return;
  2637.     }
  2638.   }
  2639. error:
  2640.   jam();
  2641.   // return to sender
  2642.   OpDropIndex opBad;
  2643.   opPtr.p = &opBad;
  2644.   opPtr.p->save(req);
  2645.   opPtr.p->m_errorCode = (DropIndxRef::ErrorCode)err;
  2646.   opPtr.p->m_errorLine = __LINE__;
  2647.   opPtr.p->m_errorNode = c_masterNodeId;
  2648.   dropIndex_sendReply(signal, opPtr, true);
  2649. }
  2650. void
  2651. Dbdict::execDROP_INDX_CONF(Signal* signal)
  2652. {
  2653.   jamEntry();
  2654.   DropIndxConf* conf = (DropIndxConf*)signal->getDataPtrSend();
  2655.   dropIndex_recvReply(signal, conf, 0);
  2656. }
  2657. void
  2658. Dbdict::execDROP_INDX_REF(Signal* signal) 
  2659. {
  2660.   jamEntry();
  2661.   DropIndxRef* ref = (DropIndxRef*)signal->getDataPtrSend();
  2662.   dropIndex_recvReply(signal, ref->getConf(), ref);
  2663. }
  2664. void
  2665. Dbdict::dropIndex_recvReply(Signal* signal, const DropIndxConf* conf,
  2666.     const DropIndxRef* ref)
  2667. {
  2668.   jam();
  2669.   const Uint32 senderRef = signal->senderBlockRef();
  2670.   const DropIndxReq::RequestType requestType = conf->getRequestType();
  2671.   const Uint32 key = conf->getConnectionPtr();
  2672.   if (requestType == DropIndxReq::RT_TC) {
  2673.     jam();
  2674.     // part of alter index operation
  2675.     OpAlterIndexPtr opPtr;
  2676.     c_opAlterIndex.find(opPtr, key);
  2677.     ndbrequire(! opPtr.isNull());
  2678.     opPtr.p->setError(ref);
  2679.     alterIndex_fromDropTc(signal, opPtr);
  2680.     return;
  2681.   }
  2682.   OpDropIndexPtr opPtr;
  2683.   c_opDropIndex.find(opPtr, key);
  2684.   ndbrequire(! opPtr.isNull());
  2685.   ndbrequire(opPtr.p->m_isMaster);
  2686.   ndbrequire(opPtr.p->m_requestType == requestType);
  2687.   opPtr.p->setError(ref);
  2688.   opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
  2689.   if (! opPtr.p->m_signalCounter.done()) {
  2690.     jam();
  2691.     return;
  2692.   }
  2693.   if (requestType == DropIndxReq::RT_DICT_COMMIT ||
  2694.       requestType == DropIndxReq::RT_DICT_ABORT) {
  2695.     jam();
  2696.     // send reply to user
  2697.     dropIndex_sendReply(signal, opPtr, true);
  2698.     c_opDropIndex.release(opPtr);
  2699.     return;
  2700.   }
  2701.   if (opPtr.p->hasError()) {
  2702.     jam();
  2703.     opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
  2704.     dropIndex_sendSlaveReq(signal, opPtr);
  2705.     return;
  2706.   }
  2707.   if (requestType == DropIndxReq::RT_DICT_PREPARE) {
  2708.     jam();
  2709.     // start alter offline
  2710.     dropIndex_toAlterIndex(signal, opPtr);
  2711.     return;
  2712.   }
  2713.   ndbrequire(false);
  2714. }
  2715. void
  2716. Dbdict::dropIndex_slavePrepare(Signal* signal, OpDropIndexPtr opPtr)
  2717. {
  2718.   jam();
  2719.   DropIndxReq* const req = &opPtr.p->m_request;
  2720.   // check index exists
  2721.   TableRecordPtr indexPtr;
  2722.   if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
  2723.     jam();
  2724.     opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
  2725.     opPtr.p->m_errorLine = __LINE__;
  2726.     return;
  2727.   }
  2728.   c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
  2729.   if (indexPtr.p->tabState != TableRecord::DEFINED) {
  2730.     jam();
  2731.     opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
  2732.     opPtr.p->m_errorLine = __LINE__;
  2733.     return;
  2734.   }
  2735.   if (! indexPtr.p->isIndex()) {
  2736.     jam();
  2737.     opPtr.p->m_errorCode = DropIndxRef::NotAnIndex;
  2738.     opPtr.p->m_errorLine = __LINE__;
  2739.     return;
  2740.   }
  2741.   // ignore incoming primary table id
  2742.   req->setTableId(indexPtr.p->primaryTableId);
  2743. }
  2744. void
  2745. Dbdict::dropIndex_toAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
  2746. {
  2747.   jam();
  2748.   AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
  2749.   req->setUserRef(reference());
  2750.   req->setConnectionPtr(opPtr.p->key);
  2751.   req->setRequestType(AlterIndxReq::RT_DROP_INDEX);
  2752.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2753.   req->setTableId(opPtr.p->m_request.getTableId());
  2754.   req->setIndexId(opPtr.p->m_request.getIndexId());
  2755.   req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
  2756.   req->setOnline(false);
  2757.   sendSignal(reference(), GSN_ALTER_INDX_REQ,
  2758.       signal, AlterIndxReq::SignalLength, JBB);
  2759. }
  2760. void
  2761. Dbdict::dropIndex_fromAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
  2762. {
  2763.   jam();
  2764.   if (opPtr.p->hasError()) {
  2765.     jam();
  2766.     opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
  2767.     dropIndex_sendSlaveReq(signal, opPtr);
  2768.     return;
  2769.   }
  2770.   dropIndex_toDropTable(signal, opPtr);
  2771. }
  2772. void
  2773. Dbdict::dropIndex_toDropTable(Signal* signal, OpDropIndexPtr opPtr)
  2774. {
  2775.   jam();
  2776.   DropTableReq* const req = (DropTableReq*)signal->getDataPtrSend();
  2777.   req->senderRef = reference();
  2778.   req->senderData = opPtr.p->key;
  2779.   req->tableId = opPtr.p->m_request.getIndexId();
  2780.   req->tableVersion = opPtr.p->m_request.getIndexVersion();
  2781.   sendSignal(reference(), GSN_DROP_TABLE_REQ,
  2782.       signal,DropTableReq::SignalLength, JBB);
  2783. }
  2784. void
  2785. Dbdict::dropIndex_fromDropTable(Signal* signal, OpDropIndexPtr opPtr)
  2786. {
  2787.   jam();
  2788.   if (opPtr.p->hasError()) {
  2789.     jam();
  2790.     opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
  2791.     dropIndex_sendSlaveReq(signal, opPtr);
  2792.     return;
  2793.   }
  2794.   opPtr.p->m_requestType = DropIndxReq::RT_DICT_COMMIT;
  2795.   dropIndex_sendSlaveReq(signal, opPtr);
  2796. }
  2797. void
  2798. Dbdict::dropIndex_slaveCommit(Signal* signal, OpDropIndexPtr opPtr)
  2799. {
  2800.   jam();
  2801. }
  2802. void
  2803. Dbdict::dropIndex_slaveAbort(Signal* signal, OpDropIndexPtr opPtr)
  2804. {
  2805.   jam();
  2806.   DropIndxReq* const req = &opPtr.p->m_request;
  2807.   const Uint32 indexId = req->getIndexId();
  2808.   if (indexId >= c_tableRecordPool.getSize()) {
  2809.     jam();
  2810.     return;
  2811.   }
  2812.   TableRecordPtr indexPtr;
  2813.   c_tableRecordPool.getPtr(indexPtr, indexId);
  2814.   indexPtr.p->indexState = TableRecord::IS_BROKEN;
  2815. }
  2816. void
  2817. Dbdict::dropIndex_sendSlaveReq(Signal* signal, OpDropIndexPtr opPtr)
  2818. {
  2819.   DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
  2820.   *req = opPtr.p->m_request;
  2821.   req->setUserRef(opPtr.p->m_coordinatorRef);
  2822.   req->setConnectionPtr(opPtr.p->key);
  2823.   req->setRequestType(opPtr.p->m_requestType);
  2824.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2825.   opPtr.p->m_signalCounter = c_aliveNodes;
  2826.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2827.   sendSignal(rg, GSN_DROP_INDX_REQ,
  2828.       signal, DropIndxReq::SignalLength, JBB);
  2829. }
  2830. void
  2831. Dbdict::dropIndex_sendReply(Signal* signal, OpDropIndexPtr opPtr,
  2832.     bool toUser)
  2833. {
  2834.   DropIndxRef* rep = (DropIndxRef*)signal->getDataPtrSend();
  2835.   Uint32 gsn = GSN_DROP_INDX_CONF;
  2836.   Uint32 length = DropIndxConf::InternalLength;
  2837.   bool sendRef;
  2838.   if (! toUser) {
  2839.     sendRef = opPtr.p->hasLastError();
  2840.     rep->setUserRef(opPtr.p->m_coordinatorRef);
  2841.     rep->setConnectionPtr(opPtr.p->key);
  2842.     rep->setRequestType(opPtr.p->m_requestType);
  2843.     if (opPtr.p->m_requestType == DropIndxReq::RT_DICT_ABORT)
  2844.       sendRef = false;
  2845.   } else {
  2846.     sendRef = opPtr.p->hasError();
  2847.     rep->setUserRef(opPtr.p->m_request.getUserRef());
  2848.     rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
  2849.     rep->setRequestType(opPtr.p->m_request.getRequestType());
  2850.     length = DropIndxConf::SignalLength;
  2851.   }
  2852.   rep->setTableId(opPtr.p->m_request.getTableId());
  2853.   rep->setIndexId(opPtr.p->m_request.getIndexId());
  2854.   rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
  2855.   if (sendRef) {
  2856.     if (opPtr.p->m_errorNode == 0)
  2857.       opPtr.p->m_errorNode = getOwnNodeId();
  2858.     rep->setErrorCode(opPtr.p->m_errorCode);
  2859.     rep->setErrorLine(opPtr.p->m_errorLine);
  2860.     rep->setErrorNode(opPtr.p->m_errorNode);
  2861.     gsn = GSN_DROP_INDX_REF;
  2862.     length = DropIndxRef::SignalLength;
  2863.   }
  2864.   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
  2865. }
  2866. /*****************************************************
  2867.  *
  2868.  * Util signalling
  2869.  *
  2870.  *****************************************************/
  2871. int
  2872. Dbdict::sendSignalUtilReq(Callback *pcallback,
  2873.   BlockReference ref, 
  2874.   GlobalSignalNumber gsn, 
  2875.   Signal* signal, 
  2876.   Uint32 length, 
  2877.   JobBufferLevel jbuf,
  2878.   LinearSectionPtr ptr[3],
  2879.   Uint32 noOfSections)
  2880. {
  2881.   jam();
  2882.   EVENT_TRACE;
  2883.   OpSignalUtilPtr utilRecPtr;
  2884.   // Seize a Util Send record
  2885.   if (!c_opSignalUtil.seize(utilRecPtr)) {
  2886.     // Failed to allocate util record
  2887.     return -1;
  2888.   }
  2889.   utilRecPtr.p->m_callback = *pcallback;
  2890.   // should work for all util signal classes
  2891.   UtilPrepareReq *req = (UtilPrepareReq*)signal->getDataPtrSend();
  2892.   utilRecPtr.p->m_userData = req->getSenderData();
  2893.   req->setSenderData(utilRecPtr.i);
  2894.   if (ptr) {
  2895.     jam();
  2896.     sendSignal(ref, gsn, signal, length, jbuf, ptr, noOfSections);
  2897.   } else {
  2898.     jam();
  2899.     sendSignal(ref, gsn, signal, length, jbuf);
  2900.   }
  2901.   return 0;
  2902. }
  2903. int
  2904. Dbdict::recvSignalUtilReq(Signal* signal, Uint32 returnCode)
  2905. {
  2906.   jam();
  2907.   EVENT_TRACE;
  2908.   UtilPrepareConf * const req = (UtilPrepareConf*)signal->getDataPtr();
  2909.   OpSignalUtilPtr utilRecPtr;
  2910.   utilRecPtr.i = req->getSenderData();
  2911.   if ((utilRecPtr.p = c_opSignalUtil.getPtr(utilRecPtr.i)) == NULL) {
  2912.     jam();
  2913.     return -1;
  2914.   }
  2915.   req->setSenderData(utilRecPtr.p->m_userData);
  2916.   Callback c = utilRecPtr.p->m_callback;
  2917.   c_opSignalUtil.release(utilRecPtr);
  2918.   execute(signal, c, returnCode);
  2919.   return 0;
  2920. }
  2921. void Dbdict::execUTIL_PREPARE_CONF(Signal *signal)
  2922. {
  2923.   jamEntry();
  2924.   EVENT_TRACE;
  2925.   ndbrequire(recvSignalUtilReq(signal, 0) == 0);
  2926. }
  2927. void
  2928. Dbdict::execUTIL_PREPARE_REF(Signal *signal)
  2929. {
  2930.   jamEntry();
  2931.   EVENT_TRACE;
  2932.   ndbrequire(recvSignalUtilReq(signal, 1) == 0);
  2933. }
  2934. void Dbdict::execUTIL_EXECUTE_CONF(Signal *signal)
  2935. {
  2936.   jamEntry();
  2937.   EVENT_TRACE;
  2938.    ndbrequire(recvSignalUtilReq(signal, 0) == 0);
  2939. }
  2940. void Dbdict::execUTIL_EXECUTE_REF(Signal *signal)
  2941. {
  2942.   jamEntry();
  2943.   EVENT_TRACE;
  2944. #ifdef EVENT_DEBUG
  2945.   UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend();
  2946.   ndbout_c("execUTIL_EXECUTE_REF");
  2947.   ndbout_c("senderData %u",ref->getSenderData());
  2948.   ndbout_c("errorCode %u",ref->getErrorCode());
  2949.   ndbout_c("TCErrorCode %u",ref->getTCErrorCode());
  2950. #endif
  2951.   
  2952.   ndbrequire(recvSignalUtilReq(signal, 1) == 0);
  2953. }
  2954. void Dbdict::execUTIL_RELEASE_CONF(Signal *signal)
  2955. {
  2956.   jamEntry();
  2957.   EVENT_TRACE;
  2958.   ndbrequire(false);
  2959.   ndbrequire(recvSignalUtilReq(signal, 0) == 0);
  2960. }
  2961. void Dbdict::execUTIL_RELEASE_REF(Signal *signal)
  2962. {
  2963.   jamEntry();
  2964.   EVENT_TRACE;
  2965.   ndbrequire(false);
  2966.   ndbrequire(recvSignalUtilReq(signal, 1) == 0);
  2967. }
  2968. /**
  2969.  * MODULE: Create event
  2970.  *
  2971.  * Create event in DICT.
  2972.  * 
  2973.  *
  2974.  * Request type in CREATE_EVNT signals:
  2975.  *
  2976.  * Signalflow see Dbdict.txt
  2977.  *
  2978.  */
  2979. /*****************************************************************
  2980.  *
  2981.  * Systable stuff
  2982.  *
  2983.  */
  2984. const Uint32 Dbdict::sysTab_NDBEVENTS_0_szs[EVENT_SYSTEM_TABLE_LENGTH] = {
  2985.   sizeof(((sysTab_NDBEVENTS_0*)0)->NAME),
  2986.   sizeof(((sysTab_NDBEVENTS_0*)0)->EVENT_TYPE),
  2987.   sizeof(((sysTab_NDBEVENTS_0*)0)->TABLE_NAME),
  2988.   sizeof(((sysTab_NDBEVENTS_0*)0)->ATTRIBUTE_MASK),
  2989.   sizeof(((sysTab_NDBEVENTS_0*)0)->SUBID),
  2990.   sizeof(((sysTab_NDBEVENTS_0*)0)->SUBKEY)
  2991. };
  2992. void
  2993. Dbdict::prepareTransactionEventSysTable (Callback *pcallback,
  2994.  Signal* signal,
  2995.  Uint32 senderData,
  2996.  UtilPrepareReq::OperationTypeValue prepReq)
  2997. {
  2998.   // find table id for event system table
  2999.   TableRecord keyRecord;
  3000.   strcpy(keyRecord.tableName, EVENT_SYSTEM_TABLE_NAME);
  3001.   TableRecordPtr tablePtr;
  3002.   c_tableRecordHash.find(tablePtr, keyRecord);
  3003.   
  3004.   ndbrequire(tablePtr.i != RNIL); // system table must exist
  3005.   Uint32 tableId = tablePtr.p->tableId; /* System table */
  3006.   Uint32 noAttr = tablePtr.p->noOfAttributes;
  3007.   ndbrequire(noAttr == EVENT_SYSTEM_TABLE_LENGTH);
  3008.   switch (prepReq) {
  3009.   case UtilPrepareReq::Update:
  3010.   case UtilPrepareReq::Insert:
  3011.   case UtilPrepareReq::Write:
  3012.   case UtilPrepareReq::Read:
  3013.     jam();
  3014.     break;
  3015.   case UtilPrepareReq::Delete:
  3016.     jam();
  3017.     noAttr = 1; // only involves Primary key which should be the first
  3018.     break;
  3019.   }
  3020.   prepareUtilTransaction(pcallback, signal, senderData, tableId, NULL,
  3021.       prepReq, noAttr, NULL, NULL);
  3022. }
  3023. void
  3024. Dbdict::prepareUtilTransaction(Callback *pcallback,
  3025.        Signal* signal,
  3026.        Uint32 senderData,
  3027.        Uint32 tableId,
  3028.        const char* tableName,
  3029.        UtilPrepareReq::OperationTypeValue prepReq,
  3030.        Uint32 noAttr,
  3031.        Uint32 attrIds[],
  3032.        const char *attrNames[])
  3033. {
  3034.   jam();
  3035.   EVENT_TRACE;
  3036.   UtilPrepareReq * utilPrepareReq = 
  3037.     (UtilPrepareReq *)signal->getDataPtrSend();
  3038.   
  3039.   utilPrepareReq->setSenderRef(reference());
  3040.   utilPrepareReq->setSenderData(senderData);
  3041.   const Uint32 pageSizeInWords = 128;
  3042.   Uint32 propPage[pageSizeInWords];
  3043.   LinearWriter w(&propPage[0],128);
  3044.   w.first();
  3045.   w.add(UtilPrepareReq::NoOfOperations, 1);
  3046.   w.add(UtilPrepareReq::OperationType, prepReq);
  3047.   if (tableName) {
  3048.     jam();
  3049.     w.add(UtilPrepareReq::TableName, tableName);
  3050.   } else {
  3051.     jam();
  3052.     w.add(UtilPrepareReq::TableId, tableId);
  3053.   }
  3054.   for(Uint32 i = 0; i < noAttr; i++)
  3055.     if (tableName) {
  3056.       jam();
  3057.       w.add(UtilPrepareReq::AttributeName, attrNames[i]);
  3058.     } else {
  3059.       if (attrIds) {
  3060. jam();
  3061. w.add(UtilPrepareReq::AttributeId, attrIds[i]);
  3062.       } else {
  3063. jam();
  3064. w.add(UtilPrepareReq::AttributeId, i);
  3065.       }
  3066.     }
  3067. #ifdef EVENT_DEBUG
  3068.   // Debugging
  3069.   SimplePropertiesLinearReader reader(propPage, w.getWordsUsed());
  3070.   printf("Dict::prepareInsertTransactions: Sent SimpleProperties:n");
  3071.   reader.printAll(ndbout);
  3072. #endif
  3073.   struct LinearSectionPtr sectionsPtr[UtilPrepareReq::NoOfSections];
  3074.   sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].p = propPage;
  3075.   sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].sz = w.getWordsUsed();
  3076.   sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_PREPARE_REQ, signal,
  3077.     UtilPrepareReq::SignalLength, JBB, 
  3078.     sectionsPtr, UtilPrepareReq::NoOfSections);
  3079. }
  3080. /*****************************************************************
  3081.  *
  3082.  * CREATE_EVNT_REQ has three types RT_CREATE, RT_GET (from user)
  3083.  * and RT_DICT_AFTER_GET send from master DICT to slaves
  3084.  *
  3085.  * This function just dscpaches these to
  3086.  *
  3087.  * createEvent_RT_USER_CREATE
  3088.  * createEvent_RT_USER_GET
  3089.  * createEvent_RT_DICT_AFTER_GET
  3090.  *
  3091.  * repectively
  3092.  *
  3093.  */
  3094. void
  3095. Dbdict::execCREATE_EVNT_REQ(Signal* signal)
  3096. {
  3097.   jamEntry();
  3098. #if 0
  3099.   {
  3100.     SafeCounterHandle handle;
  3101.     {
  3102.       SafeCounter tmp(c_counterMgr, handle);
  3103.       tmp.init<CreateEvntRef>(CMVMI, GSN_DUMP_STATE_ORD, /* senderData */ 13);
  3104.       tmp.clearWaitingFor();
  3105.       tmp.setWaitingFor(3);
  3106.       ndbrequire(!tmp.done());
  3107.       ndbout_c("Allocted");
  3108.     }
  3109.     ndbrequire(!handle.done());
  3110.     {
  3111.       SafeCounter tmp(c_counterMgr, handle);
  3112.       tmp.clearWaitingFor(3);
  3113.       ndbrequire(tmp.done());
  3114.       ndbout_c("Deallocted");
  3115.     }
  3116.     ndbrequire(handle.done());
  3117.   }
  3118.   {
  3119.     NodeBitmask nodes;
  3120.     nodes.clear();
  3121.     nodes.set(2);
  3122.     nodes.set(3);
  3123.     nodes.set(4);
  3124.     nodes.set(5);
  3125.     {
  3126.       Uint32 i = 0;
  3127.       while((i = nodes.find(i)) != NodeBitmask::NotFound){
  3128. ndbout_c("1 Node id = %u", i);
  3129. i++;
  3130.       }
  3131.     }
  3132.     NodeReceiverGroup rg(DBDICT, nodes);
  3133.     RequestTracker rt2;
  3134.     ndbrequire(rt2.done());
  3135.     ndbrequire(!rt2.hasRef());
  3136.     ndbrequire(!rt2.hasConf());
  3137.     rt2.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
  3138.     RequestTracker rt3;
  3139.     rt3.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
  3140.     ndbrequire(!rt2.done());
  3141.     ndbrequire(!rt3.done());
  3142.     rt2.reportRef(c_counterMgr, 2);
  3143.     rt3.reportConf(c_counterMgr, 2);
  3144.     ndbrequire(!rt2.done());
  3145.     ndbrequire(!rt3.done());
  3146.     rt2.reportConf(c_counterMgr, 3);
  3147.     rt3.reportConf(c_counterMgr, 3);
  3148.     ndbrequire(!rt2.done());
  3149.     ndbrequire(!rt3.done());
  3150.     rt2.reportConf(c_counterMgr, 4);
  3151.     rt3.reportConf(c_counterMgr, 4);
  3152.     ndbrequire(!rt2.done());
  3153.     ndbrequire(!rt3.done());
  3154.     rt2.reportConf(c_counterMgr, 5);
  3155.     rt3.reportConf(c_counterMgr, 5);
  3156.     ndbrequire(rt2.done());
  3157.     ndbrequire(rt3.done());
  3158.   }
  3159. #endif
  3160.   if (! assembleFragments(signal)) {
  3161.     jam();
  3162.     return;
  3163.   }
  3164.   CreateEvntReq *req = (CreateEvntReq*)signal->getDataPtr();
  3165.   const CreateEvntReq::RequestType requestType = req->getRequestType();
  3166.   const Uint32                     requestFlag = req->getRequestFlag();
  3167.   OpCreateEventPtr evntRecPtr;
  3168.   // Seize a Create Event record
  3169.   if (!c_opCreateEvent.seize(evntRecPtr)) {
  3170.     // Failed to allocate event record
  3171.     jam();
  3172.     releaseSections(signal);
  3173.     CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
  3174.     ret->senderRef = reference();
  3175.     ret->setErrorCode(CreateEvntRef::SeizeError);
  3176.     ret->setErrorLine(__LINE__);
  3177.     ret->setErrorNode(reference());
  3178.     sendSignal(signal->senderBlockRef(), GSN_CREATE_EVNT_REF, signal,
  3179.        CreateEvntRef::SignalLength, JBB);
  3180.     return;
  3181.   }
  3182. #ifdef EVENT_DEBUG
  3183.   ndbout_c("DBDICT::execCREATE_EVNT_REQ from %u evntRecId = (%d)", refToNode(signal->getSendersBlockRef()), evntRecPtr.i);
  3184. #endif
  3185.   
  3186.   ndbrequire(req->getUserRef() == signal->getSendersBlockRef());
  3187.   evntRecPtr.p->init(req,this);
  3188.   if (requestFlag & (Uint32)CreateEvntReq::RT_DICT_AFTER_GET) {
  3189.     jam();
  3190.     EVENT_TRACE;
  3191.     createEvent_RT_DICT_AFTER_GET(signal, evntRecPtr);
  3192.     return;
  3193.   }
  3194.   if (requestType == CreateEvntReq::RT_USER_GET) {
  3195.     jam();
  3196.     EVENT_TRACE;
  3197.     createEvent_RT_USER_GET(signal, evntRecPtr);
  3198.     return;
  3199.   }
  3200.   if (requestType == CreateEvntReq::RT_USER_CREATE) {
  3201.     jam();
  3202.     EVENT_TRACE;
  3203.     createEvent_RT_USER_CREATE(signal, evntRecPtr);
  3204.     return;
  3205.   }
  3206. #ifdef EVENT_DEBUG
  3207.   ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ other" << endl;
  3208. #endif
  3209.   jam();
  3210.   releaseSections(signal);
  3211.     
  3212.   evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  3213.   evntRecPtr.p->m_errorLine = __LINE__;
  3214.   evntRecPtr.p->m_errorNode = reference();
  3215.   
  3216.   createEvent_sendReply(signal, evntRecPtr);
  3217. }
  3218. /********************************************************************
  3219.  *
  3220.  * Event creation
  3221.  *
  3222.  *****************************************************************/
  3223. void
  3224. Dbdict::createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr){
  3225.   jam();
  3226.   evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
  3227. #ifdef EVENT_DEBUG
  3228.   ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ RT_USER" << endl;
  3229.   char buf[128] = {0};
  3230.   AttributeMask mask = evntRecPtr.p->m_request.getAttrListBitmask(); 
  3231.   mask.getText(buf);
  3232.   ndbout_c("mask = %s", buf);
  3233. #endif
  3234.   // Interpret the long signal
  3235.   SegmentedSectionPtr ssPtr;
  3236.   // save name and event properties
  3237.   signal->getSection(ssPtr, CreateEvntReq::EVENT_NAME_SECTION);
  3238.   SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
  3239. #ifdef EVENT_DEBUG
  3240.   r0.printAll(ndbout);
  3241. #endif
  3242.     // event name
  3243.   if ((!r0.first()) ||
  3244.       (r0.getValueType() != SimpleProperties::StringValue) ||
  3245.       (r0.getValueLen() <= 0)) {
  3246.     jam();
  3247.     releaseSections(signal);
  3248.     evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  3249.     evntRecPtr.p->m_errorLine = __LINE__;
  3250.     evntRecPtr.p->m_errorNode = reference();
  3251.     createEvent_sendReply(signal, evntRecPtr);
  3252.     return;
  3253.   }
  3254.   r0.getString(evntRecPtr.p->m_eventRec.NAME);
  3255.   {
  3256.     int len = strlen(evntRecPtr.p->m_eventRec.NAME);
  3257.     memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
  3258. #ifdef EVENT_DEBUG
  3259.     printf("CreateEvntReq::RT_USER_CREATE; EventName %s, len %un",
  3260.    evntRecPtr.p->m_eventRec.NAME, len);
  3261.     for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
  3262.       printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
  3263.     printf("n");
  3264. #endif
  3265.   }
  3266.   // table name
  3267.   if ((!r0.next()) ||
  3268.       (r0.getValueType() != SimpleProperties::StringValue) ||
  3269.       (r0.getValueLen() <= 0)) {
  3270.     jam();
  3271.     releaseSections(signal);
  3272.     
  3273.     evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  3274.     evntRecPtr.p->m_errorLine = __LINE__;
  3275.     evntRecPtr.p->m_errorNode = reference();
  3276.     
  3277.     createEvent_sendReply(signal, evntRecPtr);
  3278.     return;
  3279.   }
  3280.   r0.getString(evntRecPtr.p->m_eventRec.TABLE_NAME);
  3281.   {
  3282.     int len = strlen(evntRecPtr.p->m_eventRec.TABLE_NAME);
  3283.     memset(evntRecPtr.p->m_eventRec.TABLE_NAME+len, 0, MAX_TAB_NAME_SIZE-len);
  3284.   }
  3285.   
  3286. #ifdef EVENT_DEBUG
  3287.   ndbout_c("event name: %s",evntRecPtr.p->m_eventRec.NAME);
  3288.   ndbout_c("table name: %s",evntRecPtr.p->m_eventRec.TABLE_NAME);
  3289. #endif
  3290.   
  3291.   releaseSections(signal);
  3292.   
  3293.   // Send request to SUMA
  3294.   CreateSubscriptionIdReq * sumaIdReq =
  3295.     (CreateSubscriptionIdReq *)signal->getDataPtrSend();
  3296.   
  3297.   // make sure we save the original sender for later
  3298.   sumaIdReq->senderData = evntRecPtr.i;
  3299. #ifdef EVENT_DEBUG
  3300.   ndbout << "sumaIdReq->senderData = " << sumaIdReq->senderData << endl;
  3301. #endif
  3302.   sendSignal(SUMA_REF, GSN_CREATE_SUBID_REQ, signal, 
  3303.      CreateSubscriptionIdReq::SignalLength, JBB);
  3304.   // we should now return in either execCREATE_SUBID_CONF
  3305.   // or execCREATE_SUBID_REF
  3306. }
  3307. void Dbdict::execCREATE_SUBID_REF(Signal* signal)
  3308. {
  3309.   jamEntry();      
  3310.   EVENT_TRACE;
  3311.   CreateSubscriptionIdRef * const ref =
  3312.     (CreateSubscriptionIdRef *)signal->getDataPtr();
  3313.   OpCreateEventPtr evntRecPtr;
  3314.   evntRecPtr.i = ref->senderData;
  3315.   ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  3316.   evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  3317.   evntRecPtr.p->m_errorLine = __LINE__;
  3318.   evntRecPtr.p->m_errorNode = reference();
  3319.   createEvent_sendReply(signal, evntRecPtr);
  3320. }
  3321. void Dbdict::execCREATE_SUBID_CONF(Signal* signal)
  3322. {
  3323.   jamEntry();
  3324.   EVENT_TRACE;
  3325.   CreateSubscriptionIdConf const * sumaIdConf =
  3326.     (CreateSubscriptionIdConf *)signal->getDataPtr();
  3327.   Uint32 evntRecId = sumaIdConf->senderData;
  3328.   OpCreateEvent *evntRec;
  3329.   ndbrequire((evntRec = c_opCreateEvent.getPtr(evntRecId)) != NULL);
  3330.   evntRec->m_request.setEventId(sumaIdConf->subscriptionId);
  3331.   evntRec->m_request.setEventKey(sumaIdConf->subscriptionKey);
  3332.   releaseSections(signal);
  3333.   Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
  3334.   prepareTransactionEventSysTable(&c, signal, evntRecId,
  3335.   UtilPrepareReq::Insert);
  3336. }
  3337. void
  3338. Dbdict::createEventComplete_RT_USER_CREATE(Signal* signal,
  3339.    OpCreateEventPtr evntRecPtr){
  3340.   jam();
  3341.   createEvent_sendReply(signal, evntRecPtr);
  3342. }
  3343. /*********************************************************************
  3344.  *
  3345.  * UTIL_PREPARE, UTIL_EXECUTE
  3346.  *
  3347.  * insert or read systable NDB$EVENTS_0
  3348.  */
  3349. void interpretUtilPrepareErrorCode(UtilPrepareRef::ErrorCode errorCode,
  3350.    bool& temporary, Uint32& line)
  3351. {
  3352.   switch (errorCode) {
  3353.   case UtilPrepareRef::NO_ERROR:
  3354.     jam();
  3355.     line = __LINE__;
  3356.     EVENT_TRACE;
  3357.     break;
  3358.   case UtilPrepareRef::PREPARE_SEIZE_ERROR:
  3359.     jam();
  3360.     temporary = true;
  3361.     line = __LINE__;
  3362.     EVENT_TRACE;
  3363.     break;
  3364.   case UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR:
  3365.     jam();
  3366.     line = __LINE__;
  3367.     EVENT_TRACE;
  3368.     break;
  3369.   case UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR:
  3370.     jam();
  3371.     line = __LINE__;
  3372.     EVENT_TRACE;
  3373.     break;
  3374.   case UtilPrepareRef::DICT_TAB_INFO_ERROR:
  3375.     jam();
  3376.     line = __LINE__;
  3377.     EVENT_TRACE;
  3378.     break;
  3379.   case UtilPrepareRef::MISSING_PROPERTIES_SECTION:
  3380.     jam();
  3381.     line = __LINE__;
  3382.     EVENT_TRACE;
  3383.     break;
  3384.   default:
  3385.     jam();
  3386.     line = __LINE__;
  3387.     EVENT_TRACE;
  3388.     break;
  3389.   }
  3390. }
  3391. void 
  3392. Dbdict::createEventUTIL_PREPARE(Signal* signal,
  3393. Uint32 callbackData,
  3394. Uint32 returnCode)
  3395. {
  3396.   jam();
  3397.   EVENT_TRACE;
  3398.   if (returnCode == 0) {
  3399.     UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
  3400.     OpCreateEventPtr evntRecPtr;
  3401.     jam();
  3402.     evntRecPtr.i = req->getSenderData();
  3403.     const Uint32 prepareId = req->getPrepareId();
  3404.     
  3405.     ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  3406.     
  3407.     Callback c = { safe_cast(&Dbdict::createEventUTIL_EXECUTE), 0 };
  3408.     switch (evntRecPtr.p->m_requestType) {
  3409.     case CreateEvntReq::RT_USER_GET:
  3410. #ifdef EVENT_DEBUG
  3411.       printf("get type = %dn", CreateEvntReq::RT_USER_GET);
  3412. #endif
  3413.       jam();
  3414.       executeTransEventSysTable(&c, signal,
  3415. evntRecPtr.i, evntRecPtr.p->m_eventRec,
  3416. prepareId, UtilPrepareReq::Read);
  3417.       break;
  3418.     case CreateEvntReq::RT_USER_CREATE:
  3419. #ifdef EVENT_DEBUG
  3420.       printf("create type = %dn", CreateEvntReq::RT_USER_CREATE);
  3421. #endif
  3422.       {
  3423. evntRecPtr.p->m_eventRec.EVENT_TYPE = evntRecPtr.p->m_request.getEventType();
  3424. AttributeMask m = evntRecPtr.p->m_request.getAttrListBitmask();
  3425. memcpy(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK, &m,
  3426.        sizeof(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK));
  3427. evntRecPtr.p->m_eventRec.SUBID  = evntRecPtr.p->m_request.getEventId();
  3428. evntRecPtr.p->m_eventRec.SUBKEY = evntRecPtr.p->m_request.getEventKey();
  3429.       }
  3430.       jam();
  3431.       executeTransEventSysTable(&c, signal,
  3432. evntRecPtr.i, evntRecPtr.p->m_eventRec,
  3433. prepareId, UtilPrepareReq::Insert);
  3434.       break;
  3435.     default:
  3436. #ifdef EVENT_DEBUG
  3437.       printf("type = %dn", evntRecPtr.p->m_requestType);
  3438.       printf("bet type = %dn", CreateEvntReq::RT_USER_GET);
  3439.       printf("create type = %dn", CreateEvntReq::RT_USER_CREATE);
  3440. #endif
  3441.       ndbrequire(false);
  3442.     }
  3443.   } else { // returnCode != 0
  3444.     UtilPrepareRef* const ref = (UtilPrepareRef*)signal->getDataPtr();
  3445.     const UtilPrepareRef::ErrorCode errorCode =
  3446.       (UtilPrepareRef::ErrorCode)ref->getErrorCode();
  3447.     OpCreateEventPtr evntRecPtr;
  3448.     evntRecPtr.i = ref->getSenderData();
  3449.     ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  3450.     bool temporary = false;
  3451.     interpretUtilPrepareErrorCode(errorCode,
  3452.   temporary, evntRecPtr.p->m_errorLine);
  3453.     if (temporary) {
  3454.       evntRecPtr.p->m_errorCode =
  3455. CreateEvntRef::makeTemporary(CreateEvntRef::Undefined);
  3456.     }
  3457.     if (evntRecPtr.p->m_errorCode == 0) {
  3458.       evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  3459.     }
  3460.     evntRecPtr.p->m_errorNode = reference();
  3461.     createEvent_sendReply(signal, evntRecPtr);
  3462.   }
  3463. }
  3464. void Dbdict::executeTransEventSysTable(Callback *pcallback, Signal *signal,
  3465.        const Uint32 ptrI,
  3466.        sysTab_NDBEVENTS_0& m_eventRec,
  3467.        const Uint32 prepareId,
  3468.        UtilPrepareReq::OperationTypeValue prepReq)
  3469. {
  3470.   jam();
  3471.   const Uint32 noAttr = EVENT_SYSTEM_TABLE_LENGTH;
  3472.   Uint32 total_len = 0;
  3473.   Uint32* attrHdr = signal->theData + 25;
  3474.   Uint32* attrPtr = attrHdr;
  3475.   Uint32 id=0;
  3476.   // attribute 0 event name: Primary Key
  3477.   {
  3478.     AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]/4);
  3479.     total_len += sysTab_NDBEVENTS_0_szs[id];
  3480.     attrPtr++; id++;
  3481.   }
  3482.   switch (prepReq) {
  3483.   case UtilPrepareReq::Read:
  3484.     jam();
  3485.     EVENT_TRACE;
  3486.     // no more
  3487.     while ( id < noAttr )
  3488.       AttributeHeader::init(attrPtr++, id++, 0);
  3489.     ndbrequire(id == (Uint32) noAttr);
  3490.     break;
  3491.   case UtilPrepareReq::Insert:
  3492.     jam();
  3493.     EVENT_TRACE;
  3494.     while ( id < noAttr ) {
  3495.       AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]/4);
  3496.       total_len += sysTab_NDBEVENTS_0_szs[id];
  3497.       attrPtr++; id++;
  3498.     }
  3499.     ndbrequire(id == (Uint32) noAttr);
  3500.     break;
  3501.   case UtilPrepareReq::Delete:
  3502.     ndbrequire(id == 1);
  3503.     break;
  3504.   default:
  3505.     ndbrequire(false);
  3506.   }
  3507.     
  3508.   LinearSectionPtr headerPtr;
  3509.   LinearSectionPtr dataPtr;
  3510.     
  3511.   headerPtr.p = attrHdr;
  3512.   headerPtr.sz = noAttr;
  3513.     
  3514.   dataPtr.p = (Uint32*)&m_eventRec;
  3515.   dataPtr.sz = total_len/4;
  3516.   ndbrequire((total_len == sysTab_NDBEVENTS_0_szs[0]) ||
  3517.      (total_len == sizeof(sysTab_NDBEVENTS_0)));
  3518. #if 0
  3519.     printf("Header size %un", headerPtr.sz);
  3520.     for(int i = 0; i < (int)headerPtr.sz; i++)
  3521.       printf("H'%.8x ", attrHdr[i]);
  3522.     printf("n");
  3523.     
  3524.     printf("Data size %un", dataPtr.sz);
  3525.     for(int i = 0; i < (int)dataPtr.sz; i++)
  3526.       printf("H'%.8x ", dataPage[i]);
  3527.     printf("n");
  3528. #endif
  3529.   executeTransaction(pcallback, signal, 
  3530.      ptrI,
  3531.      prepareId,
  3532.      id,
  3533.      headerPtr,
  3534.      dataPtr);
  3535. }
  3536. void Dbdict::executeTransaction(Callback *pcallback,
  3537. Signal* signal, 
  3538. Uint32 senderData,
  3539. Uint32 prepareId,
  3540. Uint32 noAttr,
  3541. LinearSectionPtr headerPtr,
  3542. LinearSectionPtr dataPtr)
  3543. {
  3544.   jam();
  3545.   EVENT_TRACE;
  3546.   UtilExecuteReq * utilExecuteReq = 
  3547.     (UtilExecuteReq *)signal->getDataPtrSend();
  3548.   utilExecuteReq->setSenderRef(reference());
  3549.   utilExecuteReq->setSenderData(senderData);
  3550.   utilExecuteReq->setPrepareId(prepareId);
  3551.   utilExecuteReq->setReleaseFlag(); // must be done after setting prepareId
  3552. #if 0
  3553.   printf("Header size %un", headerPtr.sz);
  3554.   for(int i = 0; i < (int)headerPtr.sz; i++)
  3555.     printf("H'%.8x ", headerBuffer[i]);
  3556.   printf("n");
  3557.   
  3558.   printf("Data size %un", dataPtr.sz);
  3559.   for(int i = 0; i < (int)dataPtr.sz; i++)
  3560.     printf("H'%.8x ", dataBuffer[i]);
  3561.   printf("n");
  3562. #endif
  3563.   struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections];
  3564.   sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = headerPtr.p;
  3565.   sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr;
  3566.   sectionsPtr[UtilExecuteReq::DATA_SECTION].p = dataPtr.p;
  3567.   sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataPtr.sz;
  3568.   sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal,
  3569.     UtilExecuteReq::SignalLength, JBB,
  3570.     sectionsPtr, UtilExecuteReq::NoOfSections);
  3571. }
  3572. void Dbdict::parseReadEventSys(Signal* signal, sysTab_NDBEVENTS_0& m_eventRec)
  3573. {
  3574.   SegmentedSectionPtr headerPtr, dataPtr;
  3575.   jam();
  3576.   signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
  3577.   SectionReader headerReader(headerPtr, getSectionSegmentPool());
  3578.       
  3579.   signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
  3580.   SectionReader dataReader(dataPtr, getSectionSegmentPool());
  3581.   
  3582.   AttributeHeader header;
  3583.   Uint32 *dst = (Uint32*)&m_eventRec;
  3584.   for (int i = 0; i < EVENT_SYSTEM_TABLE_LENGTH; i++) {
  3585.     headerReader.getWord((Uint32 *)&header);
  3586.     int sz = header.getDataSize();
  3587.     for (int i=0; i < sz; i++)
  3588.       dataReader.getWord(dst++);
  3589.   }
  3590.   ndbrequire( ((char*)dst-(char*)&m_eventRec) == sizeof(m_eventRec) );
  3591.   releaseSections(signal);
  3592. }
  3593.     
  3594. void Dbdict::createEventUTIL_EXECUTE(Signal *signal, 
  3595.      Uint32 callbackData,
  3596.      Uint32 returnCode)
  3597. {
  3598.   jam();
  3599.   EVENT_TRACE;
  3600.   if (returnCode == 0) {
  3601.     // Entry into system table all set
  3602.     UtilExecuteConf* const conf = (UtilExecuteConf*)signal->getDataPtr();
  3603.     jam();
  3604.     OpCreateEventPtr evntRecPtr;
  3605.     evntRecPtr.i = conf->getSenderData();
  3606.     
  3607.     ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  3608.     OpCreateEvent *evntRec = evntRecPtr.p;
  3609.     
  3610.     switch (evntRec->m_requestType) {
  3611.     case CreateEvntReq::RT_USER_GET: {
  3612. #ifdef EVENT_DEBUG
  3613.       printf("get type = %dn", CreateEvntReq::RT_USER_GET);
  3614. #endif
  3615.       parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
  3616.       evntRec->m_request.setEventType(evntRecPtr.p->m_eventRec.EVENT_TYPE);
  3617.       evntRec->m_request.setAttrListBitmask(*(AttributeMask*)evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK);
  3618.       evntRec->m_request.setEventId(evntRecPtr.p->m_eventRec.SUBID);
  3619.       evntRec->m_request.setEventKey(evntRecPtr.p->m_eventRec.SUBKEY);
  3620. #ifdef EVENT_DEBUG
  3621.       printf("EventName: %sn", evntRec->m_eventRec.NAME);
  3622.       printf("TableName: %sn", evntRec->m_eventRec.TABLE_NAME);
  3623. #endif
  3624.       
  3625.       // find table id for event table
  3626.       TableRecord keyRecord;
  3627.       strcpy(keyRecord.tableName, evntRecPtr.p->m_eventRec.TABLE_NAME);
  3628.       
  3629.       TableRecordPtr tablePtr;
  3630.       c_tableRecordHash.find(tablePtr, keyRecord);
  3631.       
  3632.       if (tablePtr.i == RNIL) {
  3633. jam();
  3634. evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  3635. evntRecPtr.p->m_errorLine = __LINE__;
  3636. evntRecPtr.p->m_errorNode = reference();
  3637. createEvent_sendReply(signal, evntRecPtr);
  3638. return;
  3639.       }
  3640.       
  3641.       evntRec->m_request.setTableId(tablePtr.p->tableId);
  3642.       
  3643.       createEventComplete_RT_USER_GET(signal, evntRecPtr);
  3644.       return;
  3645.     }
  3646.     case CreateEvntReq::RT_USER_CREATE: {
  3647. #ifdef EVENT_DEBUG
  3648.       printf("create type = %dn", CreateEvntReq::RT_USER_CREATE);
  3649. #endif
  3650.       jam();
  3651.       createEventComplete_RT_USER_CREATE(signal, evntRecPtr);
  3652.       return;
  3653.     }
  3654.       break;
  3655.     default:
  3656.       ndbrequire(false);
  3657.     }
  3658.   } else { // returnCode != 0
  3659.     UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
  3660.     OpCreateEventPtr evntRecPtr;
  3661.     evntRecPtr.i = ref->getSenderData();
  3662.     ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  3663.     jam();
  3664.     evntRecPtr.p->m_errorNode = reference();
  3665.     evntRecPtr.p->m_errorLine = __LINE__;
  3666.     switch (ref->getErrorCode()) {
  3667.     case UtilExecuteRef::TCError:
  3668.       switch (ref->getTCErrorCode()) {
  3669.       case ZNOT_FOUND:
  3670. jam();
  3671. evntRecPtr.p->m_errorCode = CreateEvntRef::EventNotFound;
  3672. break;
  3673.       case ZALREADYEXIST:
  3674. jam();
  3675. evntRecPtr.p->m_errorCode = CreateEvntRef::EventExists;
  3676. break;
  3677.       default:
  3678. jam();
  3679. evntRecPtr.p->m_errorCode = CreateEvntRef::UndefinedTCError;
  3680. break;
  3681.       }
  3682.       break;
  3683.     default:
  3684.       jam();
  3685.       evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  3686.       break;
  3687.     }
  3688.     
  3689.     createEvent_sendReply(signal, evntRecPtr);
  3690.   }
  3691. }
  3692. /***********************************************************************