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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <my_sys.h>
  15. #define DBDICT_C
  16. #include "Dbdict.hpp"
  17. #include <ndb_limits.h>
  18. #include <NdbOut.hpp>
  19. #include <Properties.hpp>
  20. #include <Configuration.hpp>
  21. #include <SectionReader.hpp>
  22. #include <SimpleProperties.hpp>
  23. #include <AttributeHeader.hpp>
  24. #include <signaldata/DictSchemaInfo.hpp>
  25. #include <signaldata/DictTabInfo.hpp>
  26. #include <signaldata/DropTabFile.hpp>
  27. #include <signaldata/EventReport.hpp>
  28. #include <signaldata/FsCloseReq.hpp>
  29. #include <signaldata/FsConf.hpp>
  30. #include <signaldata/FsOpenReq.hpp>
  31. #include <signaldata/FsReadWriteReq.hpp>
  32. #include <signaldata/FsRef.hpp>
  33. #include <signaldata/GetTabInfo.hpp>
  34. #include <signaldata/GetTableId.hpp>
  35. #include <signaldata/HotSpareRep.hpp>
  36. #include <signaldata/NFCompleteRep.hpp>
  37. #include <signaldata/NodeFailRep.hpp>
  38. #include <signaldata/ReadNodesConf.hpp>
  39. #include <signaldata/RelTabMem.hpp>
  40. #include <signaldata/WaitGCP.hpp>
  41. #include <signaldata/ListTables.hpp>
  42. #include <signaldata/CreateTrig.hpp>
  43. #include <signaldata/AlterTrig.hpp>
  44. #include <signaldata/DropTrig.hpp>
  45. #include <signaldata/CreateIndx.hpp>
  46. #include <signaldata/DropIndx.hpp>
  47. #include <signaldata/BuildIndx.hpp>
  48. #include <signaldata/CreateEvnt.hpp>
  49. #include <signaldata/UtilPrepare.hpp>
  50. #include <signaldata/UtilExecute.hpp>
  51. #include <signaldata/UtilRelease.hpp>
  52. #include <signaldata/SumaImpl.hpp> 
  53. #include <GrepError.hpp>
  54. //#include <signaldata/DropEvnt.hpp>
  55. #include <signaldata/LqhFrag.hpp>
  56. #include <signaldata/DiAddTab.hpp>
  57. #include <signaldata/DihStartTab.hpp>
  58. #include <signaldata/DropTable.hpp>
  59. #include <signaldata/DropTab.hpp>
  60. #include <signaldata/PrepDropTab.hpp>
  61. #include <signaldata/CreateTable.hpp>
  62. #include <signaldata/AlterTable.hpp>
  63. #include <signaldata/AlterTab.hpp>
  64. #include <signaldata/CreateFragmentation.hpp>
  65. #include <signaldata/CreateTab.hpp>
  66. #include <NdbSleep.h>
  67. #include <signaldata/ApiBroadcast.hpp>
  68. #define ZNOT_FOUND 626
  69. #define ZALREADYEXIST 630
  70. //#define EVENT_PH2_DEBUG
  71. //#define EVENT_PH3_DEBUG
  72. //#define EVENT_DEBUG
  73. #define EVENT_TRACE 
  74. //  ndbout_c("Event debug trace: File: %s Line: %u", __FILE__, __LINE__)
  75. #define DIV(x,y) (((x)+(y)-1)/(y))
  76. #include <ndb_version.h>
  77. static
  78. Uint32
  79. alter_table_inc_schema_version(Uint32 old)
  80. {
  81.    return (old & 0x00FFFFFF) + ((old + 0x1000000) & 0xFF000000);
  82. }
  83. static
  84. Uint32
  85. alter_table_dec_schema_version(Uint32 old)
  86. {
  87.   return (old & 0x00FFFFFF) + ((old - 0x1000000) & 0xFF000000);
  88. }
  89. static
  90. Uint32
  91. create_table_inc_schema_version(Uint32 old)
  92. {
  93.   return (old + 0x00000001) & 0x00FFFFFF;
  94. }
  95. /* **************************************************************** */
  96. /* ---------------------------------------------------------------- */
  97. /* MODULE:          GENERAL MODULE -------------------------------- */
  98. /* ---------------------------------------------------------------- */
  99. /*                                                                  */
  100. /* This module contains general stuff. Mostly debug signals and     */
  101. /* general signals that go into a specific module after checking a  */
  102. /* state variable. Also general subroutines used by many.           */
  103. /* ---------------------------------------------------------------- */
  104. /* **************************************************************** */
  105. /* ---------------------------------------------------------------- */
  106. // This signal is used to dump states of various variables in the
  107. // block by command.
  108. /* ---------------------------------------------------------------- */
  109. void
  110. Dbdict::execDUMP_STATE_ORD(Signal* signal)
  111. {
  112.   jamEntry();
  113. #ifdef VM_TRACE
  114.   if(signal->theData[0] == 1222){
  115.     const Uint32 tab = signal->theData[1];
  116.     PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
  117.     req->senderRef = reference();
  118.     req->senderData = 1222;
  119.     req->tableId = tab;
  120.     sendSignal(DBLQH_REF, GSN_PREP_DROP_TAB_REQ, signal,
  121.        PrepDropTabReq::SignalLength, JBB);
  122.   }
  123.   if(signal->theData[0] == 1223){
  124.     const Uint32 tab = signal->theData[1];
  125.     PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
  126.     req->senderRef = reference();
  127.     req->senderData = 1222;
  128.     req->tableId = tab;
  129.     sendSignal(DBTC_REF, GSN_PREP_DROP_TAB_REQ, signal,
  130.        PrepDropTabReq::SignalLength, JBB);
  131.   }
  132.   if(signal->theData[0] == 1224){
  133.     const Uint32 tab = signal->theData[1];
  134.     PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
  135.     req->senderRef = reference();
  136.     req->senderData = 1222;
  137.     req->tableId = tab;
  138.     sendSignal(DBDIH_REF, GSN_PREP_DROP_TAB_REQ, signal,
  139.        PrepDropTabReq::SignalLength, JBB);
  140.   }
  141.   if(signal->theData[0] == 1225){
  142.     const Uint32 tab = signal->theData[1];
  143.     const Uint32 ver = signal->theData[2];
  144.     TableRecordPtr tabRecPtr;
  145.     c_tableRecordPool.getPtr(tabRecPtr, tab);
  146.     DropTableReq * req = (DropTableReq*)signal->getDataPtr();
  147.     req->senderData = 1225;
  148.     req->senderRef = numberToRef(1,1);
  149.     req->tableId = tab;
  150.     req->tableVersion = tabRecPtr.p->tableVersion + ver;
  151.     sendSignal(DBDICT_REF, GSN_DROP_TABLE_REQ, signal,
  152.        DropTableReq::SignalLength, JBB);
  153.   }
  154. #endif  
  155.   
  156.   return;
  157. }//Dbdict::execDUMP_STATE_ORD()
  158. /* ---------------------------------------------------------------- */
  159. /* ---------------------------------------------------------------- */
  160. // CONTINUEB is used when a real-time break is needed for long
  161. // processes.
  162. /* ---------------------------------------------------------------- */
  163. /* ---------------------------------------------------------------- */
  164. void Dbdict::execCONTINUEB(Signal* signal) 
  165. {
  166.   jamEntry();
  167.   switch (signal->theData[0]) {
  168.   case ZPACK_TABLE_INTO_PAGES :
  169.     jam();
  170.     packTableIntoPages(signal, signal->theData[1], signal->theData[2]);
  171.     break;
  172.   case ZSEND_GET_TAB_RESPONSE :
  173.     jam();
  174.     sendGetTabResponse(signal);
  175.     break;
  176.   default :
  177.     ndbrequire(false);
  178.     break;
  179.   }//switch
  180.   return;
  181. }//execCONTINUEB()
  182. /* ---------------------------------------------------------------- */
  183. /* ---------------------------------------------------------------- */
  184. // Routine to handle pack table into pages.
  185. /* ---------------------------------------------------------------- */
  186. /* ---------------------------------------------------------------- */
  187. void Dbdict::packTableIntoPages(Signal* signal, Uint32 tableId, Uint32 pageId)
  188. {
  189.   PageRecordPtr pagePtr;
  190.   TableRecordPtr tablePtr;
  191.   c_pageRecordArray.getPtr(pagePtr, pageId);
  192.   
  193.   memset(&pagePtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
  194.   c_tableRecordPool.getPtr(tablePtr, tableId);
  195.   LinearWriter w(&pagePtr.p->word[ZPAGE_HEADER_SIZE], 
  196.  8 * ZSIZE_OF_PAGES_IN_WORDS);
  197.   w.first();
  198.   packTableIntoPagesImpl(w, tablePtr);
  199.     
  200.   Uint32 wordsOfTable = w.getWordsUsed();
  201.   Uint32 pagesUsed = 
  202.     DIV(wordsOfTable + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
  203.   pagePtr.p->word[ZPOS_CHECKSUM] = 
  204.     computeChecksum(&pagePtr.p->word[0], pagesUsed * ZSIZE_OF_PAGES_IN_WORDS);
  205.   
  206.   switch (c_packTable.m_state) {
  207.   case PackTable::PTS_IDLE:
  208.   case PackTable::PTS_ADD_TABLE_MASTER:
  209.   case PackTable::PTS_ADD_TABLE_SLAVE:
  210.   case PackTable::PTS_RESTART:
  211.     ndbrequire(false);
  212.     break;
  213.   case PackTable::PTS_GET_TAB:
  214.     jam();
  215.     c_retrieveRecord.retrievedNoOfPages = pagesUsed;
  216.     c_retrieveRecord.retrievedNoOfWords = wordsOfTable;
  217.     sendGetTabResponse(signal);
  218.     return;
  219.     break;
  220.   }//switch
  221.   ndbrequire(false);
  222.   return;
  223. }//packTableIntoPages()
  224. void
  225. Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w,
  226.        TableRecordPtr tablePtr){
  227.   
  228.   w.add(DictTabInfo::TableName, tablePtr.p->tableName);
  229.   w.add(DictTabInfo::TableId, tablePtr.i);
  230. #ifdef HAVE_TABLE_REORG
  231.   w.add(DictTabInfo::SecondTableId, tablePtr.p->secondTable);
  232. #else
  233.   w.add(DictTabInfo::SecondTableId, (Uint32)0);
  234. #endif
  235.   w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion);
  236.   w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey);
  237.   w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes);
  238.   w.add(DictTabInfo::NoOfNullable, tablePtr.p->noOfNullAttr);
  239.   w.add(DictTabInfo::NoOfVariable, (Uint32)0);
  240.   w.add(DictTabInfo::KeyLength, tablePtr.p->tupKeyLength);
  241.   
  242.   w.add(DictTabInfo::TableLoggedFlag, tablePtr.p->storedTable);
  243.   w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor);
  244.   w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor);
  245.   w.add(DictTabInfo::TableKValue, tablePtr.p->kValue);
  246.   w.add(DictTabInfo::FragmentTypeVal, tablePtr.p->fragmentType);
  247.   w.add(DictTabInfo::FragmentKeyTypeVal, tablePtr.p->fragmentKeyType);
  248.   w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType);
  249.   w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount);
  250.   
  251.   if (tablePtr.p->primaryTableId != RNIL){
  252.     TableRecordPtr primTab;
  253.     c_tableRecordPool.getPtr(primTab, tablePtr.p->primaryTableId);
  254.     w.add(DictTabInfo::PrimaryTable, primTab.p->tableName);
  255.     w.add(DictTabInfo::PrimaryTableId, tablePtr.p->primaryTableId);
  256.     w.add(DictTabInfo::IndexState, tablePtr.p->indexState);
  257.     w.add(DictTabInfo::InsertTriggerId, tablePtr.p->insertTriggerId);
  258.     w.add(DictTabInfo::UpdateTriggerId, tablePtr.p->updateTriggerId);
  259.     w.add(DictTabInfo::DeleteTriggerId, tablePtr.p->deleteTriggerId);
  260.     w.add(DictTabInfo::CustomTriggerId, tablePtr.p->customTriggerId);
  261.   }
  262.   w.add(DictTabInfo::FrmLen, tablePtr.p->frmLen);
  263.   w.add(DictTabInfo::FrmData, tablePtr.p->frmData, tablePtr.p->frmLen);
  264.   
  265.   Uint32 nextAttribute = tablePtr.p->firstAttribute;
  266.   AttributeRecordPtr attrPtr;
  267.   do {
  268.     jam();
  269.     c_attributeRecordPool.getPtr(attrPtr, nextAttribute);
  270.     
  271.     w.add(DictTabInfo::AttributeName, attrPtr.p->attributeName);
  272.     w.add(DictTabInfo::AttributeId, attrPtr.p->attributeId);
  273.     w.add(DictTabInfo::AttributeKeyFlag, attrPtr.p->tupleKey > 0);
  274.     
  275.     const Uint32 desc = attrPtr.p->attributeDescriptor;
  276.     const Uint32 attrType = AttributeDescriptor::getType(desc);
  277.     const Uint32 attrSize = AttributeDescriptor::getSize(desc);
  278.     const Uint32 arraySize = AttributeDescriptor::getArraySize(desc);
  279.     const Uint32 nullable = AttributeDescriptor::getNullable(desc);
  280.     const Uint32 DGroup = AttributeDescriptor::getDGroup(desc);
  281.     const Uint32 DKey = AttributeDescriptor::getDKey(desc);
  282.     const Uint32 attrStoredInd = AttributeDescriptor::getStoredInTup(desc);
  283.     w.add(DictTabInfo::AttributeType, attrType);
  284.     w.add(DictTabInfo::AttributeSize, attrSize);
  285.     w.add(DictTabInfo::AttributeArraySize, arraySize);
  286.     w.add(DictTabInfo::AttributeNullableFlag, nullable);
  287.     w.add(DictTabInfo::AttributeDGroup, DGroup);
  288.     w.add(DictTabInfo::AttributeDKey, DKey);
  289.     w.add(DictTabInfo::AttributeStoredInd, attrStoredInd);
  290.     w.add(DictTabInfo::AttributeExtType, attrPtr.p->extType);
  291.     w.add(DictTabInfo::AttributeExtPrecision, attrPtr.p->extPrecision);
  292.     w.add(DictTabInfo::AttributeExtScale, attrPtr.p->extScale);
  293.     w.add(DictTabInfo::AttributeExtLength, attrPtr.p->extLength);
  294.     w.add(DictTabInfo::AttributeAutoIncrement, 
  295.   (Uint32)attrPtr.p->autoIncrement);
  296.     w.add(DictTabInfo::AttributeDefaultValue, attrPtr.p->defaultValue);
  297.     
  298.     w.add(DictTabInfo::AttributeEnd, 1);
  299.     nextAttribute = attrPtr.p->nextAttrInTable;
  300.   } while (nextAttribute != RNIL);
  301.   
  302.   w.add(DictTabInfo::TableEnd, 1);
  303. }
  304. /* ---------------------------------------------------------------- */
  305. /* ---------------------------------------------------------------- */
  306. // The routines to handle responses from file system.
  307. /* ---------------------------------------------------------------- */
  308. /* ---------------------------------------------------------------- */
  309. /* ---------------------------------------------------------------- */
  310. // A file was successfully closed.
  311. /* ---------------------------------------------------------------- */
  312. void Dbdict::execFSCLOSECONF(Signal* signal) 
  313. {
  314.   FsConnectRecordPtr fsPtr;
  315.   FsConf * const fsConf = (FsConf *)&signal->theData[0];
  316.   jamEntry();
  317.   c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
  318.   switch (fsPtr.p->fsState) {
  319.   case FsConnectRecord::CLOSE_WRITE_SCHEMA:
  320.     jam();
  321.     closeWriteSchemaConf(signal, fsPtr);
  322.     break;
  323.   case FsConnectRecord::CLOSE_READ_SCHEMA:
  324.     jam();
  325.     closeReadSchemaConf(signal, fsPtr);
  326.     break;
  327.   case FsConnectRecord::CLOSE_READ_TAB_FILE:
  328.     jam();
  329.     closeReadTableConf(signal, fsPtr);
  330.     break;
  331.   case FsConnectRecord::CLOSE_WRITE_TAB_FILE:
  332.     jam();
  333.     closeWriteTableConf(signal, fsPtr);
  334.     break;
  335.   case FsConnectRecord::OPEN_READ_SCHEMA2:
  336.     openSchemaFile(signal, 1, fsPtr.i, false);
  337.     break;
  338.   default:
  339.     jamLine((fsPtr.p->fsState & 0xFFF));
  340.     ndbrequire(false);
  341.     break;
  342.   }//switch
  343. }//execFSCLOSECONF()
  344. /* ---------------------------------------------------------------- */
  345. // A file was successfully opened.
  346. /* ---------------------------------------------------------------- */
  347. void Dbdict::execFSOPENCONF(Signal* signal) 
  348. {
  349.   FsConnectRecordPtr fsPtr;
  350.   jamEntry();
  351.   FsConf * const fsConf = (FsConf *)&signal->theData[0];
  352.   c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
  353.   Uint32 filePointer = fsConf->filePointer;
  354.   fsPtr.p->filePtr = filePointer;
  355.   switch (fsPtr.p->fsState) {
  356.   case FsConnectRecord::OPEN_WRITE_SCHEMA:
  357.     jam();
  358.     fsPtr.p->fsState = FsConnectRecord::WRITE_SCHEMA;
  359.     writeSchemaFile(signal, filePointer, fsPtr.i);
  360.     break;
  361.   case FsConnectRecord::OPEN_READ_SCHEMA1:
  362.     jam();
  363.     fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA1;
  364.     readSchemaFile(signal, filePointer, fsPtr.i);
  365.     break;
  366.   case FsConnectRecord::OPEN_READ_SCHEMA2:
  367.     jam();
  368.     fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA2;
  369.     readSchemaFile(signal, filePointer, fsPtr.i);
  370.     break;
  371.   case FsConnectRecord::OPEN_READ_TAB_FILE1:
  372.     jam();
  373.     fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE1;
  374.     readTableFile(signal, filePointer, fsPtr.i);
  375.     break;
  376.   case FsConnectRecord::OPEN_READ_TAB_FILE2:
  377.     jam();
  378.     fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE2;
  379.     readTableFile(signal, filePointer, fsPtr.i);
  380.     break;
  381.   case FsConnectRecord::OPEN_WRITE_TAB_FILE:
  382.     jam();
  383.     fsPtr.p->fsState = FsConnectRecord::WRITE_TAB_FILE;
  384.     writeTableFile(signal, filePointer, fsPtr.i);
  385.     break;
  386.   default:
  387.     jamLine((fsPtr.p->fsState & 0xFFF));
  388.     ndbrequire(false);
  389.     break;
  390.   }//switch
  391. }//execFSOPENCONF()
  392. /* ---------------------------------------------------------------- */
  393. // An open file was refused.
  394. /* ---------------------------------------------------------------- */
  395. void Dbdict::execFSOPENREF(Signal* signal) 
  396. {
  397.   jamEntry();
  398.   FsRef * const fsRef = (FsRef *)&signal->theData[0];
  399.   FsConnectRecordPtr fsPtr;
  400.   c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
  401.   switch (fsPtr.p->fsState) {
  402.   case FsConnectRecord::OPEN_READ_SCHEMA1:
  403.     jam();
  404.     openReadSchemaRef(signal, fsPtr);
  405.     return;
  406.   case FsConnectRecord::OPEN_READ_TAB_FILE1:
  407.     jam();
  408.     openReadTableRef(signal, fsPtr);
  409.     return;
  410.   default:
  411.     break;
  412.   }//switch
  413.   {
  414.     char msg[100];
  415.     sprintf(msg, "File system open failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
  416.     fsRefError(signal,__LINE__,msg);
  417.   }
  418. }//execFSOPENREF()
  419. /* ---------------------------------------------------------------- */
  420. // A file was successfully read.
  421. /* ---------------------------------------------------------------- */
  422. void Dbdict::execFSREADCONF(Signal* signal) 
  423. {
  424.   jamEntry();
  425.   FsConf * const fsConf = (FsConf *)&signal->theData[0];
  426.   FsConnectRecordPtr fsPtr;
  427.   c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
  428.   switch (fsPtr.p->fsState) {
  429.   case FsConnectRecord::READ_SCHEMA1:
  430.   case FsConnectRecord::READ_SCHEMA2:
  431.     readSchemaConf(signal ,fsPtr);
  432.     break;
  433.   case FsConnectRecord::READ_TAB_FILE1:
  434.   case FsConnectRecord::READ_TAB_FILE2:
  435.     jam();
  436.     readTableConf(signal ,fsPtr);
  437.     break;
  438.   default:
  439.     jamLine((fsPtr.p->fsState & 0xFFF));
  440.     ndbrequire(false);
  441.     break;
  442.   }//switch
  443. }//execFSREADCONF()
  444. /* ---------------------------------------------------------------- */
  445. // A read file was refused.
  446. /* ---------------------------------------------------------------- */
  447. void Dbdict::execFSREADREF(Signal* signal) 
  448. {
  449.   jamEntry();
  450.   FsRef * const fsRef = (FsRef *)&signal->theData[0];
  451.   FsConnectRecordPtr fsPtr;
  452.   c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
  453.   switch (fsPtr.p->fsState) {
  454.   case FsConnectRecord::READ_SCHEMA1:
  455.     jam();
  456.     readSchemaRef(signal, fsPtr);
  457.     return;
  458.   case FsConnectRecord::READ_TAB_FILE1:
  459.     jam();
  460.     readTableRef(signal, fsPtr);
  461.     return;
  462.   default:
  463.     break;
  464.   }//switch
  465.   {
  466.     char msg[100];
  467.     sprintf(msg, "File system read failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
  468.     fsRefError(signal,__LINE__,msg);
  469.   }
  470. }//execFSREADREF()
  471. /* ---------------------------------------------------------------- */
  472. // A file was successfully written.
  473. /* ---------------------------------------------------------------- */
  474. void Dbdict::execFSWRITECONF(Signal* signal) 
  475. {
  476.   FsConf * const fsConf = (FsConf *)&signal->theData[0];
  477.   FsConnectRecordPtr fsPtr;
  478.   jamEntry();
  479.   c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
  480.   switch (fsPtr.p->fsState) {
  481.   case FsConnectRecord::WRITE_TAB_FILE:
  482.     writeTableConf(signal, fsPtr);
  483.     break;
  484.   case FsConnectRecord::WRITE_SCHEMA:
  485.     jam();
  486.     writeSchemaConf(signal, fsPtr);
  487.     break;
  488.   default:
  489.     jamLine((fsPtr.p->fsState & 0xFFF));
  490.     ndbrequire(false);
  491.     break;
  492.   }//switch
  493. }//execFSWRITECONF()
  494. /* ---------------------------------------------------------------- */
  495. // Routines to handle Read/Write of Table Files
  496. /* ---------------------------------------------------------------- */
  497. void
  498. Dbdict::writeTableFile(Signal* signal, Uint32 tableId, 
  499.        SegmentedSectionPtr tabInfoPtr, Callback* callback){
  500.   
  501.   ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
  502.   
  503.   Uint32 sz = tabInfoPtr.sz + ZPAGE_HEADER_SIZE;
  504.   c_writeTableRecord.noOfPages = DIV(sz, ZSIZE_OF_PAGES_IN_WORDS);
  505.   c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
  506.   c_writeTableRecord.m_callback = * callback;
  507.   c_writeTableRecord.pageId = 0;
  508.   ndbrequire(c_writeTableRecord.noOfPages < 8);
  509.   PageRecordPtr pageRecPtr;
  510.   c_pageRecordArray.getPtr(pageRecPtr, c_writeTableRecord.pageId);
  511.   copy(&pageRecPtr.p->word[ZPAGE_HEADER_SIZE], tabInfoPtr);
  512.   
  513.   memset(&pageRecPtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
  514.   pageRecPtr.p->word[ZPOS_CHECKSUM] = 
  515.     computeChecksum(&pageRecPtr.p->word[0], 
  516.     c_writeTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS);
  517.   
  518.   startWriteTableFile(signal, tableId);
  519. }
  520. void Dbdict::startWriteTableFile(Signal* signal, Uint32 tableId)
  521. {
  522.   FsConnectRecordPtr fsPtr;
  523.   c_writeTableRecord.tableId = tableId;
  524.   c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
  525.   fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
  526.   openTableFile(signal, 0, fsPtr.i, tableId, true);
  527.   c_writeTableRecord.noOfTableFilesHandled = 0;
  528. }//Dbdict::startWriteTableFile()
  529. void Dbdict::openTableFile(Signal* signal,
  530.                            Uint32 fileNo,
  531.                            Uint32 fsConPtr,
  532.                            Uint32 tableId,
  533.                            bool   writeFlag) 
  534. {
  535.   TableRecordPtr tablePtr;
  536.   FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
  537.   c_tableRecordPool.getPtr(tablePtr, tableId);
  538.   fsOpenReq->userReference = reference();
  539.   fsOpenReq->userPointer = fsConPtr;
  540.   if (writeFlag) {
  541.     jam();
  542.     fsOpenReq->fileFlags = 
  543.       FsOpenReq::OM_WRITEONLY | 
  544.       FsOpenReq::OM_TRUNCATE | 
  545.       FsOpenReq::OM_CREATE | 
  546.       FsOpenReq::OM_SYNC;
  547.   } else {
  548.     jam();
  549.     fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
  550.   }//if
  551.   fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
  552.   FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
  553.   FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_TABLELIST);
  554.   FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
  555.   FsOpenReq::v1_setTable(fsOpenReq->fileNumber, tableId);
  556.   FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
  557.   FsOpenReq::v1_setS(fsOpenReq->fileNumber, tablePtr.p->tableVersion);
  558.   FsOpenReq::v1_setP(fsOpenReq->fileNumber, 255);
  559. /* ---------------------------------------------------------------- */
  560. // File name : D1/DBDICT/T0/S1.TableList
  561. // D1 means Disk 1 (set by fileNo + 1)
  562. // T0 means table id = 0
  563. // S1 means tableVersion 1
  564. // TableList indicates that this is a file for a table description.
  565. /* ---------------------------------------------------------------- */
  566.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
  567. }//openTableFile()
  568. void Dbdict::writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 
  569. {
  570.   FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
  571.   fsRWReq->filePointer = filePtr;
  572.   fsRWReq->userReference = reference();
  573.   fsRWReq->userPointer = fsConPtr;
  574.   fsRWReq->operationFlag = 0; // Initialise before bit changes
  575.   FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
  576.   FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 
  577.                                 FsReadWriteReq::fsFormatArrayOfPages);
  578.   fsRWReq->varIndex = ZALLOCATE;
  579.   fsRWReq->numberOfPages = c_writeTableRecord.noOfPages;
  580.   fsRWReq->data.arrayOfPages.varIndex = c_writeTableRecord.pageId;
  581.   fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
  582.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
  583. }//writeTableFile()
  584. void Dbdict::writeTableConf(Signal* signal,
  585.                                 FsConnectRecordPtr fsPtr)
  586. {
  587.   fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_TAB_FILE;
  588.   closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
  589.   return;
  590. }//Dbdict::writeTableConf()
  591. void Dbdict::closeWriteTableConf(Signal* signal,
  592.                                  FsConnectRecordPtr fsPtr)
  593. {
  594.   c_writeTableRecord.noOfTableFilesHandled++;
  595.   if (c_writeTableRecord.noOfTableFilesHandled < 2) {
  596.     jam();
  597.     fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
  598.     openTableFile(signal, 1, fsPtr.i, c_writeTableRecord.tableId, true);
  599.     return;
  600.   } 
  601.   ndbrequire(c_writeTableRecord.noOfTableFilesHandled == 2);
  602.   c_fsConnectRecordPool.release(fsPtr);
  603.   WriteTableRecord::TableWriteState state = c_writeTableRecord.tableWriteState;
  604.   c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
  605.   switch (state) {
  606.   case WriteTableRecord::IDLE:
  607.   case WriteTableRecord::WRITE_ADD_TABLE_MASTER :
  608.   case WriteTableRecord::WRITE_ADD_TABLE_SLAVE :
  609.   case WriteTableRecord::WRITE_RESTART_FROM_MASTER :
  610.   case WriteTableRecord::WRITE_RESTART_FROM_OWN :
  611.     ndbrequire(false);
  612.     break;
  613.   case WriteTableRecord::TWR_CALLBACK:
  614.     jam();
  615.     execute(signal, c_writeTableRecord.m_callback, 0);
  616.     return;
  617.   }
  618.   ndbrequire(false);
  619. }//Dbdict::closeWriteTableConf()
  620. void Dbdict::startReadTableFile(Signal* signal, Uint32 tableId)
  621. {
  622.   //globalSignalLoggers.log(number(), "startReadTableFile");
  623.   ndbrequire(!c_readTableRecord.inUse);
  624.   
  625.   FsConnectRecordPtr fsPtr;
  626.   c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
  627.   c_readTableRecord.inUse = true;
  628.   c_readTableRecord.tableId = tableId;
  629.   fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE1;
  630.   openTableFile(signal, 0, fsPtr.i, tableId, false);
  631. }//Dbdict::startReadTableFile()
  632. void Dbdict::openReadTableRef(Signal* signal,
  633.                               FsConnectRecordPtr fsPtr) 
  634. {
  635.   fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
  636.   openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
  637.   return;
  638. }//Dbdict::openReadTableConf()
  639. void Dbdict::readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 
  640. {
  641.   FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
  642.   fsRWReq->filePointer = filePtr;
  643.   fsRWReq->userReference = reference();
  644.   fsRWReq->userPointer = fsConPtr;
  645.   fsRWReq->operationFlag = 0; // Initialise before bit changes
  646.   FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
  647.   FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 
  648.                                 FsReadWriteReq::fsFormatArrayOfPages);
  649.   fsRWReq->varIndex = ZALLOCATE;
  650.   fsRWReq->numberOfPages = c_readTableRecord.noOfPages;
  651.   fsRWReq->data.arrayOfPages.varIndex = c_readTableRecord.pageId;
  652.   fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
  653.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
  654. }//readTableFile()
  655. void Dbdict::readTableConf(Signal* signal,
  656.    FsConnectRecordPtr fsPtr)
  657. {
  658.   /* ---------------------------------------------------------------- */
  659.   // Verify the data read from disk
  660.   /* ---------------------------------------------------------------- */
  661.   bool crashInd;
  662.   if (fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1) {
  663.     jam();
  664.     crashInd = false;
  665.   } else {
  666.     jam();
  667.     crashInd = true;
  668.   }//if
  669.   PageRecordPtr tmpPagePtr;
  670.   c_pageRecordArray.getPtr(tmpPagePtr, c_readTableRecord.pageId);
  671.   Uint32 sz = c_readTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS;
  672.   Uint32 chk = computeChecksum((const Uint32*)tmpPagePtr.p, sz);
  673.   
  674.   ndbrequire((chk == 0) || !crashInd);
  675.   if(chk != 0){
  676.     jam();
  677.     ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1);
  678.     readTableRef(signal, fsPtr);
  679.     return;
  680.   }//if
  681.   
  682.   fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_TAB_FILE;
  683.   closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
  684.   return;
  685. }//Dbdict::readTableConf()
  686. void Dbdict::readTableRef(Signal* signal,
  687.                           FsConnectRecordPtr fsPtr)
  688. {
  689.   fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
  690.   openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
  691.   return;
  692. }//Dbdict::readTableRef()
  693. void Dbdict::closeReadTableConf(Signal* signal,
  694.                                 FsConnectRecordPtr fsPtr)
  695. {
  696.   c_fsConnectRecordPool.release(fsPtr);
  697.   c_readTableRecord.inUse = false;
  698.   
  699.   execute(signal, c_readTableRecord.m_callback, 0);
  700.   return;
  701. }//Dbdict::closeReadTableConf()
  702. /* ---------------------------------------------------------------- */
  703. // Routines to handle Read/Write of Schema Files
  704. /* ---------------------------------------------------------------- */
  705. void
  706. Dbdict::updateSchemaState(Signal* signal, Uint32 tableId, 
  707.   SchemaFile::TableEntry* te, Callback* callback){
  708.   jam();
  709.   PageRecordPtr pagePtr;
  710.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  711.   ndbrequire(tableId < c_tableRecordPool.getSize());
  712.   SchemaFile::TableEntry * tableEntry = getTableEntry(pagePtr.p, tableId);
  713.   
  714.   SchemaFile::TableState newState = 
  715.     (SchemaFile::TableState)te->m_tableState;
  716.   SchemaFile::TableState oldState = 
  717.     (SchemaFile::TableState)tableEntry->m_tableState;
  718.   
  719.   Uint32 newVersion = te->m_tableVersion;
  720.   Uint32 oldVersion = tableEntry->m_tableVersion;
  721.   
  722.   bool ok = false;
  723.   switch(newState){
  724.   case SchemaFile::ADD_STARTED:
  725.     jam();
  726.     ok = true;
  727.     ndbrequire(create_table_inc_schema_version(oldVersion) == newVersion);
  728.     ndbrequire(oldState == SchemaFile::INIT ||
  729.        oldState == SchemaFile::DROP_TABLE_COMMITTED);
  730.     break;
  731.   case SchemaFile::TABLE_ADD_COMMITTED:
  732.     jam();
  733.     ok = true;
  734.     ndbrequire(newVersion == oldVersion);
  735.     ndbrequire(oldState == SchemaFile::ADD_STARTED);
  736.     break;
  737.   case SchemaFile::ALTER_TABLE_COMMITTED:
  738.     jam();
  739.     ok = true;
  740.     ndbrequire(alter_table_inc_schema_version(oldVersion) == newVersion);
  741.     ndbrequire(oldState == SchemaFile::TABLE_ADD_COMMITTED ||
  742.        oldState == SchemaFile::ALTER_TABLE_COMMITTED);
  743.     break;
  744.   case SchemaFile::DROP_TABLE_STARTED:
  745.     jam();
  746.   case SchemaFile::DROP_TABLE_COMMITTED:
  747.     jam();
  748.     ok = true;
  749.     ndbrequire(false);
  750.     break;
  751.   case SchemaFile::INIT:
  752.     jam();
  753.     ok = true;
  754.     ndbrequire((oldState == SchemaFile::ADD_STARTED));
  755.   }//if
  756.   ndbrequire(ok);
  757.   
  758.   * tableEntry = * te;
  759.   computeChecksum((SchemaFile*)pagePtr.p);
  760.   ndbrequire(c_writeSchemaRecord.inUse == false);
  761.   c_writeSchemaRecord.inUse = true;
  762.   
  763.   c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
  764.   c_writeSchemaRecord.m_callback = * callback;
  765.   startWriteSchemaFile(signal);
  766. }
  767. void Dbdict::startWriteSchemaFile(Signal* signal)
  768. {
  769.   FsConnectRecordPtr fsPtr;
  770.   c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
  771.   fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
  772.   openSchemaFile(signal, 0, fsPtr.i, true);
  773.   c_writeSchemaRecord.noOfSchemaFilesHandled = 0;
  774. }//Dbdict::startWriteSchemaFile()
  775. void Dbdict::openSchemaFile(Signal* signal,
  776.                             Uint32 fileNo,
  777.                             Uint32 fsConPtr,
  778.                             bool writeFlag) 
  779. {
  780.   FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
  781.   fsOpenReq->userReference = reference();
  782.   fsOpenReq->userPointer = fsConPtr;
  783.   if (writeFlag) {
  784.     jam();
  785.     fsOpenReq->fileFlags = 
  786.       FsOpenReq::OM_WRITEONLY | 
  787.       FsOpenReq::OM_TRUNCATE | 
  788.       FsOpenReq::OM_CREATE | 
  789.       FsOpenReq::OM_SYNC;
  790.   } else {
  791.     jam();
  792.     fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
  793.   }//if
  794.   fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
  795.   FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
  796.   FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_SCHEMALOG);
  797.   FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
  798.   FsOpenReq::v1_setTable(fsOpenReq->fileNumber, (Uint32)-1);
  799.   FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
  800.   FsOpenReq::v1_setS(fsOpenReq->fileNumber, (Uint32)-1);
  801.   FsOpenReq::v1_setP(fsOpenReq->fileNumber, 0);
  802. /* ---------------------------------------------------------------- */
  803. // File name : D1/DBDICT/P0.SchemaLog
  804. // D1 means Disk 1 (set by fileNo + 1). Writes to both D1 and D2
  805. // SchemaLog indicates that this is a file giving a list of current tables.
  806. /* ---------------------------------------------------------------- */
  807.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
  808. }//openSchemaFile()
  809. void Dbdict::writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 
  810. {
  811.   FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
  812.   fsRWReq->filePointer = filePtr;
  813.   fsRWReq->userReference = reference();
  814.   fsRWReq->userPointer = fsConPtr;
  815.   fsRWReq->operationFlag = 0; // Initialise before bit changes
  816.   FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
  817.   FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 
  818.                                 FsReadWriteReq::fsFormatArrayOfPages);
  819.   fsRWReq->varIndex = ZALLOCATE;
  820.   fsRWReq->numberOfPages = 1;
  821. // Write from memory page
  822.   fsRWReq->data.arrayOfPages.varIndex = c_writeSchemaRecord.pageId; 
  823.   fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
  824.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
  825. }//writeSchemaFile()
  826. void Dbdict::writeSchemaConf(Signal* signal,
  827.                                 FsConnectRecordPtr fsPtr)
  828. {
  829.   fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_SCHEMA;
  830.   closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
  831.   return;
  832. }//Dbdict::writeSchemaConf()
  833. void Dbdict::closeFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 
  834. {
  835.   FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0];
  836.   fsCloseReq->filePointer = filePtr;
  837.   fsCloseReq->userReference = reference();
  838.   fsCloseReq->userPointer = fsConPtr;
  839.   FsCloseReq::setRemoveFileFlag(fsCloseReq->fileFlag, false);
  840.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
  841.   return;
  842. }//closeFile()
  843. void Dbdict::closeWriteSchemaConf(Signal* signal,
  844.                                      FsConnectRecordPtr fsPtr)
  845. {
  846.   c_writeSchemaRecord.noOfSchemaFilesHandled++;
  847.   if (c_writeSchemaRecord.noOfSchemaFilesHandled < 2) {
  848.     jam();
  849.     fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
  850.     openSchemaFile(signal, 1, fsPtr.i, true);
  851.     return;
  852.   } 
  853.   ndbrequire(c_writeSchemaRecord.noOfSchemaFilesHandled == 2);
  854.   
  855.   c_fsConnectRecordPool.release(fsPtr);
  856.   c_writeSchemaRecord.inUse = false;
  857.   execute(signal, c_writeSchemaRecord.m_callback, 0);
  858.   return;
  859. }//Dbdict::closeWriteSchemaConf()
  860. void Dbdict::startReadSchemaFile(Signal* signal)
  861. {
  862.   //globalSignalLoggers.log(number(), "startReadSchemaFile");
  863.   FsConnectRecordPtr fsPtr;
  864.   c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
  865.   fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA1;
  866.   openSchemaFile(signal, 0, fsPtr.i, false);
  867. }//Dbdict::startReadSchemaFile()
  868. void Dbdict::openReadSchemaRef(Signal* signal,
  869.                                FsConnectRecordPtr fsPtr) 
  870. {
  871.   fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
  872.   openSchemaFile(signal, 1, fsPtr.i, false);
  873. }//Dbdict::openReadSchemaRef()
  874. void Dbdict::readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 
  875. {
  876.   FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
  877.   fsRWReq->filePointer = filePtr;
  878.   fsRWReq->userReference = reference();
  879.   fsRWReq->userPointer = fsConPtr;
  880.   fsRWReq->operationFlag = 0; // Initialise before bit changes
  881.   FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
  882.   FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 
  883.                                 FsReadWriteReq::fsFormatArrayOfPages);
  884.   fsRWReq->varIndex = ZALLOCATE;
  885.   fsRWReq->numberOfPages = 1;
  886.   fsRWReq->data.arrayOfPages.varIndex = c_readSchemaRecord.pageId; 
  887.   fsRWReq->data.arrayOfPages.fileOffset = 0; 
  888.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
  889. }//readSchemaFile()
  890. void Dbdict::readSchemaConf(Signal* signal,
  891.                             FsConnectRecordPtr fsPtr)
  892. {
  893. /* ---------------------------------------------------------------- */
  894. // Verify the data read from disk
  895. /* ---------------------------------------------------------------- */
  896.   bool crashInd;
  897.   if (fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1) {
  898.     jam();
  899.     crashInd = false;
  900.   } else {
  901.     jam();
  902.     crashInd = true;
  903.   }//if
  904.   PageRecordPtr tmpPagePtr;
  905.   c_pageRecordArray.getPtr(tmpPagePtr, c_readSchemaRecord.pageId);
  906.   Uint32 sz = ZSIZE_OF_PAGES_IN_WORDS;
  907.   Uint32 chk = computeChecksum((const Uint32*)tmpPagePtr.p, sz);
  908.   ndbrequire((chk == 0) || !crashInd);
  909.   if (chk != 0){
  910.     jam();
  911.     ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1);
  912.     readSchemaRef(signal, fsPtr);
  913.     return;
  914.   }//if
  915.   fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_SCHEMA;
  916.   closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
  917.   return;
  918. }//Dbdict::readSchemaConf()
  919. void Dbdict::readSchemaRef(Signal* signal,
  920.                            FsConnectRecordPtr fsPtr)
  921. {
  922.   /**
  923.    * First close corrupt file
  924.    */
  925.   fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
  926.   closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
  927.   return;
  928. }
  929. void Dbdict::closeReadSchemaConf(Signal* signal,
  930.                                  FsConnectRecordPtr fsPtr)
  931. {
  932.   c_fsConnectRecordPool.release(fsPtr);
  933.   ReadSchemaRecord::SchemaReadState state = c_readSchemaRecord.schemaReadState;
  934.   c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
  935.   switch(state) {
  936.   case ReadSchemaRecord::INITIAL_READ :
  937.     jam();
  938.     sendNDB_STTORRY(signal);
  939.     break;
  940.   default :
  941.     ndbrequire(false);
  942.     break;
  943.   }//switch
  944. }//Dbdict::closeReadSchemaConf()
  945. /* **************************************************************** */
  946. /* ---------------------------------------------------------------- */
  947. /* MODULE:          INITIALISATION MODULE ------------------------- */
  948. /* ---------------------------------------------------------------- */
  949. /*                                                                  */
  950. /* This module contains initialisation of data at start/restart.    */
  951. /* ---------------------------------------------------------------- */
  952. /* **************************************************************** */
  953. Dbdict::Dbdict(const class Configuration & conf):
  954.   SimulatedBlock(DBDICT, conf),
  955.   c_tableRecordHash(c_tableRecordPool),
  956.   c_attributeRecordHash(c_attributeRecordPool),
  957.   c_triggerRecordHash(c_triggerRecordPool),
  958.   c_opCreateTable(c_opRecordPool),
  959.   c_opDropTable(c_opRecordPool),
  960.   c_opCreateIndex(c_opRecordPool),
  961.   c_opDropIndex(c_opRecordPool),
  962.   c_opAlterIndex(c_opRecordPool),
  963.   c_opBuildIndex(c_opRecordPool),
  964.   c_opCreateEvent(c_opRecordPool),
  965.   c_opSubEvent(c_opRecordPool),
  966.   c_opDropEvent(c_opRecordPool),
  967.   c_opSignalUtil(c_opRecordPool),
  968.   c_opCreateTrigger(c_opRecordPool),
  969.   c_opDropTrigger(c_opRecordPool),
  970.   c_opAlterTrigger(c_opRecordPool),
  971.   c_opRecordSequence(0)
  972. {
  973.   BLOCK_CONSTRUCTOR(Dbdict);
  974.   
  975.   const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator();
  976.   ndbrequire(p != 0);
  977.   ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, &c_maxNoOfTriggers);
  978.   // Transit signals
  979.   addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD);
  980.   addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ);
  981.   addRecSignal(GSN_GET_TABLEID_REQ, &Dbdict::execGET_TABLEDID_REQ);
  982.   addRecSignal(GSN_GET_TABINFO_CONF, &Dbdict::execGET_TABINFO_CONF);
  983.   addRecSignal(GSN_CONTINUEB, &Dbdict::execCONTINUEB);
  984.   addRecSignal(GSN_CREATE_TABLE_REQ, &Dbdict::execCREATE_TABLE_REQ);
  985.   addRecSignal(GSN_CREATE_TAB_REQ, &Dbdict::execCREATE_TAB_REQ);
  986.   addRecSignal(GSN_CREATE_TAB_REF, &Dbdict::execCREATE_TAB_REF);
  987.   addRecSignal(GSN_CREATE_TAB_CONF, &Dbdict::execCREATE_TAB_CONF);
  988.   addRecSignal(GSN_CREATE_FRAGMENTATION_REF, &Dbdict::execCREATE_FRAGMENTATION_REF);
  989.   addRecSignal(GSN_CREATE_FRAGMENTATION_CONF, &Dbdict::execCREATE_FRAGMENTATION_CONF);
  990.   addRecSignal(GSN_DIADDTABCONF, &Dbdict::execDIADDTABCONF);
  991.   addRecSignal(GSN_DIADDTABREF, &Dbdict::execDIADDTABREF);
  992.   addRecSignal(GSN_ADD_FRAGREQ, &Dbdict::execADD_FRAGREQ);
  993.   addRecSignal(GSN_TAB_COMMITCONF, &Dbdict::execTAB_COMMITCONF);
  994.   addRecSignal(GSN_TAB_COMMITREF, &Dbdict::execTAB_COMMITREF);
  995.   addRecSignal(GSN_ALTER_TABLE_REQ, &Dbdict::execALTER_TABLE_REQ);
  996.   addRecSignal(GSN_ALTER_TAB_REQ, &Dbdict::execALTER_TAB_REQ);
  997.   addRecSignal(GSN_ALTER_TAB_REF, &Dbdict::execALTER_TAB_REF);
  998.   addRecSignal(GSN_ALTER_TAB_CONF, &Dbdict::execALTER_TAB_CONF);
  999.   // Index signals
  1000.   addRecSignal(GSN_CREATE_INDX_REQ, &Dbdict::execCREATE_INDX_REQ);
  1001.   addRecSignal(GSN_CREATE_INDX_CONF, &Dbdict::execCREATE_INDX_CONF);
  1002.   addRecSignal(GSN_CREATE_INDX_REF, &Dbdict::execCREATE_INDX_REF);
  1003.   addRecSignal(GSN_ALTER_INDX_REQ, &Dbdict::execALTER_INDX_REQ);
  1004.   addRecSignal(GSN_ALTER_INDX_CONF, &Dbdict::execALTER_INDX_CONF);
  1005.   addRecSignal(GSN_ALTER_INDX_REF, &Dbdict::execALTER_INDX_REF);
  1006.   addRecSignal(GSN_CREATE_TABLE_CONF, &Dbdict::execCREATE_TABLE_CONF);
  1007.   addRecSignal(GSN_CREATE_TABLE_REF, &Dbdict::execCREATE_TABLE_REF);
  1008.   addRecSignal(GSN_DROP_INDX_REQ, &Dbdict::execDROP_INDX_REQ);
  1009.   addRecSignal(GSN_DROP_INDX_CONF, &Dbdict::execDROP_INDX_CONF);
  1010.   addRecSignal(GSN_DROP_INDX_REF, &Dbdict::execDROP_INDX_REF);
  1011.   addRecSignal(GSN_DROP_TABLE_CONF, &Dbdict::execDROP_TABLE_CONF);
  1012.   addRecSignal(GSN_DROP_TABLE_REF, &Dbdict::execDROP_TABLE_REF);
  1013.   addRecSignal(GSN_BUILDINDXREQ, &Dbdict::execBUILDINDXREQ);
  1014.   addRecSignal(GSN_BUILDINDXCONF, &Dbdict::execBUILDINDXCONF);
  1015.   addRecSignal(GSN_BUILDINDXREF, &Dbdict::execBUILDINDXREF);
  1016.   // Util signals
  1017.   addRecSignal(GSN_UTIL_PREPARE_CONF, &Dbdict::execUTIL_PREPARE_CONF);
  1018.   addRecSignal(GSN_UTIL_PREPARE_REF,  &Dbdict::execUTIL_PREPARE_REF);
  1019.   addRecSignal(GSN_UTIL_EXECUTE_CONF, &Dbdict::execUTIL_EXECUTE_CONF);
  1020.   addRecSignal(GSN_UTIL_EXECUTE_REF,  &Dbdict::execUTIL_EXECUTE_REF);
  1021.   addRecSignal(GSN_UTIL_RELEASE_CONF, &Dbdict::execUTIL_RELEASE_CONF);
  1022.   addRecSignal(GSN_UTIL_RELEASE_REF,  &Dbdict::execUTIL_RELEASE_REF);
  1023.   // Event signals
  1024.   addRecSignal(GSN_CREATE_EVNT_REQ,  &Dbdict::execCREATE_EVNT_REQ);
  1025.   addRecSignal(GSN_CREATE_EVNT_CONF, &Dbdict::execCREATE_EVNT_CONF);
  1026.   addRecSignal(GSN_CREATE_EVNT_REF,  &Dbdict::execCREATE_EVNT_REF);
  1027.   addRecSignal(GSN_CREATE_SUBID_CONF, &Dbdict::execCREATE_SUBID_CONF);
  1028.   addRecSignal(GSN_CREATE_SUBID_REF,  &Dbdict::execCREATE_SUBID_REF);
  1029.   addRecSignal(GSN_SUB_CREATE_CONF, &Dbdict::execSUB_CREATE_CONF);
  1030.   addRecSignal(GSN_SUB_CREATE_REF,  &Dbdict::execSUB_CREATE_REF);
  1031.   addRecSignal(GSN_SUB_START_REQ,  &Dbdict::execSUB_START_REQ);
  1032.   addRecSignal(GSN_SUB_START_CONF,  &Dbdict::execSUB_START_CONF);
  1033.   addRecSignal(GSN_SUB_START_REF,  &Dbdict::execSUB_START_REF);
  1034.   addRecSignal(GSN_SUB_STOP_REQ,  &Dbdict::execSUB_STOP_REQ);
  1035.   addRecSignal(GSN_SUB_STOP_CONF,  &Dbdict::execSUB_STOP_CONF);
  1036.   addRecSignal(GSN_SUB_STOP_REF,  &Dbdict::execSUB_STOP_REF);
  1037.   addRecSignal(GSN_SUB_SYNC_CONF, &Dbdict::execSUB_SYNC_CONF);
  1038.   addRecSignal(GSN_SUB_SYNC_REF,  &Dbdict::execSUB_SYNC_REF);
  1039.   addRecSignal(GSN_DROP_EVNT_REQ,  &Dbdict::execDROP_EVNT_REQ);
  1040.   addRecSignal(GSN_SUB_REMOVE_REQ, &Dbdict::execSUB_REMOVE_REQ);
  1041.   addRecSignal(GSN_SUB_REMOVE_CONF, &Dbdict::execSUB_REMOVE_CONF);
  1042.   addRecSignal(GSN_SUB_REMOVE_REF,  &Dbdict::execSUB_REMOVE_REF);
  1043.   // Trigger signals
  1044.   addRecSignal(GSN_CREATE_TRIG_REQ, &Dbdict::execCREATE_TRIG_REQ);
  1045.   addRecSignal(GSN_CREATE_TRIG_CONF, &Dbdict::execCREATE_TRIG_CONF);
  1046.   addRecSignal(GSN_CREATE_TRIG_REF, &Dbdict::execCREATE_TRIG_REF);
  1047.   addRecSignal(GSN_ALTER_TRIG_REQ, &Dbdict::execALTER_TRIG_REQ);
  1048.   addRecSignal(GSN_ALTER_TRIG_CONF, &Dbdict::execALTER_TRIG_CONF);
  1049.   addRecSignal(GSN_ALTER_TRIG_REF, &Dbdict::execALTER_TRIG_REF);
  1050.   addRecSignal(GSN_DROP_TRIG_REQ, &Dbdict::execDROP_TRIG_REQ);
  1051.   addRecSignal(GSN_DROP_TRIG_CONF, &Dbdict::execDROP_TRIG_CONF);
  1052.   addRecSignal(GSN_DROP_TRIG_REF, &Dbdict::execDROP_TRIG_REF);
  1053.   // Received signals
  1054.   addRecSignal(GSN_HOT_SPAREREP, &Dbdict::execHOT_SPAREREP);
  1055.   addRecSignal(GSN_GET_SCHEMA_INFOREQ, &Dbdict::execGET_SCHEMA_INFOREQ);
  1056.   addRecSignal(GSN_SCHEMA_INFO, &Dbdict::execSCHEMA_INFO);
  1057.   addRecSignal(GSN_SCHEMA_INFOCONF, &Dbdict::execSCHEMA_INFOCONF);
  1058.   addRecSignal(GSN_DICTSTARTREQ, &Dbdict::execDICTSTARTREQ);
  1059.   addRecSignal(GSN_READ_NODESCONF, &Dbdict::execREAD_NODESCONF);
  1060.   addRecSignal(GSN_FSOPENCONF, &Dbdict::execFSOPENCONF);
  1061.   addRecSignal(GSN_FSOPENREF, &Dbdict::execFSOPENREF, true);
  1062.   addRecSignal(GSN_FSCLOSECONF, &Dbdict::execFSCLOSECONF);
  1063.   addRecSignal(GSN_FSWRITECONF, &Dbdict::execFSWRITECONF);
  1064.   addRecSignal(GSN_FSREADCONF, &Dbdict::execFSREADCONF);
  1065.   addRecSignal(GSN_FSREADREF, &Dbdict::execFSREADREF, true);
  1066.   addRecSignal(GSN_LQHFRAGCONF, &Dbdict::execLQHFRAGCONF);
  1067.   addRecSignal(GSN_LQHADDATTCONF, &Dbdict::execLQHADDATTCONF);
  1068.   addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF);
  1069.   addRecSignal(GSN_LQHFRAGREF, &Dbdict::execLQHFRAGREF);
  1070.   addRecSignal(GSN_NDB_STTOR, &Dbdict::execNDB_STTOR);
  1071.   addRecSignal(GSN_READ_CONFIG_REQ, &Dbdict::execREAD_CONFIG_REQ, true);
  1072.   addRecSignal(GSN_STTOR, &Dbdict::execSTTOR);
  1073.   addRecSignal(GSN_TC_SCHVERCONF, &Dbdict::execTC_SCHVERCONF);
  1074.   addRecSignal(GSN_NODE_FAILREP, &Dbdict::execNODE_FAILREP);
  1075.   addRecSignal(GSN_INCL_NODEREQ, &Dbdict::execINCL_NODEREQ);
  1076.   addRecSignal(GSN_API_FAILREQ, &Dbdict::execAPI_FAILREQ);
  1077.   addRecSignal(GSN_WAIT_GCP_REF, &Dbdict::execWAIT_GCP_REF);
  1078.   addRecSignal(GSN_WAIT_GCP_CONF, &Dbdict::execWAIT_GCP_CONF);
  1079.   addRecSignal(GSN_LIST_TABLES_REQ, &Dbdict::execLIST_TABLES_REQ);
  1080.   addRecSignal(GSN_DROP_TABLE_REQ, &Dbdict::execDROP_TABLE_REQ);
  1081.   
  1082.   addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbdict::execPREP_DROP_TAB_REQ);
  1083.   addRecSignal(GSN_PREP_DROP_TAB_REF, &Dbdict::execPREP_DROP_TAB_REF);
  1084.   addRecSignal(GSN_PREP_DROP_TAB_CONF, &Dbdict::execPREP_DROP_TAB_CONF);
  1085.   
  1086.   addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ);
  1087.   addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF);
  1088.   addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF);
  1089.   addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ);
  1090. }//Dbdict::Dbdict()
  1091. Dbdict::~Dbdict() 
  1092. {
  1093. }//Dbdict::~Dbdict()
  1094. BLOCK_FUNCTIONS(Dbdict)
  1095. void Dbdict::initCommonData() 
  1096. {
  1097. /* ---------------------------------------------------------------- */
  1098. // Initialise all common variables.
  1099. /* ---------------------------------------------------------------- */
  1100.   initRetrieveRecord(0, 0, 0);
  1101.   initSchemaRecord();
  1102.   initRestartRecord();
  1103.   initSendSchemaRecord();
  1104.   initReadTableRecord();
  1105.   initWriteTableRecord();
  1106.   initReadSchemaRecord();
  1107.   initWriteSchemaRecord();
  1108.   c_masterNodeId = ZNIL;
  1109.   c_numberNode = 0;
  1110.   c_noNodesFailed = 0;
  1111.   c_failureNr = 0;
  1112.   c_blockState = BS_IDLE;
  1113.   c_packTable.m_state = PackTable::PTS_IDLE;
  1114.   c_startPhase = 0;
  1115.   c_restartType = 255; //Ensure not used restartType
  1116.   c_tabinfoReceived = 0;
  1117.   c_initialStart = false;
  1118.   c_systemRestart = false;
  1119.   c_initialNodeRestart = false;
  1120.   c_nodeRestart = false;
  1121. }//Dbdict::initCommonData()
  1122. void Dbdict::initRecords() 
  1123. {
  1124.   initNodeRecords();
  1125.   initPageRecords();
  1126.   initTableRecords();
  1127.   initTriggerRecords();
  1128. }//Dbdict::initRecords()
  1129. void Dbdict::initSendSchemaRecord() 
  1130. {
  1131.   c_sendSchemaRecord.noOfWords = (Uint32)-1;
  1132.   c_sendSchemaRecord.pageId = RNIL;
  1133.   c_sendSchemaRecord.noOfWordsCurrentlySent = 0;
  1134.   c_sendSchemaRecord.noOfSignalsSentSinceDelay = 0;
  1135.   c_sendSchemaRecord.inUse = false;
  1136.   //c_sendSchemaRecord.sendSchemaState = SendSchemaRecord::IDLE;
  1137. }//initSendSchemaRecord()
  1138. void Dbdict::initReadTableRecord() 
  1139. {
  1140.   c_readTableRecord.noOfPages = (Uint32)-1;
  1141.   c_readTableRecord.pageId = RNIL;
  1142.   c_readTableRecord.tableId = ZNIL;
  1143.   c_readTableRecord.inUse = false;
  1144. }//initReadTableRecord()
  1145. void Dbdict::initWriteTableRecord() 
  1146. {
  1147.   c_writeTableRecord.noOfPages = (Uint32)-1;
  1148.   c_writeTableRecord.pageId = RNIL;
  1149.   c_writeTableRecord.noOfTableFilesHandled = 3;
  1150.   c_writeTableRecord.tableId = ZNIL;
  1151.   c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
  1152. }//initWriteTableRecord()
  1153. void Dbdict::initReadSchemaRecord() 
  1154. {
  1155.   c_readSchemaRecord.pageId = RNIL;
  1156.   c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
  1157. }//initReadSchemaRecord()
  1158. void Dbdict::initWriteSchemaRecord() 
  1159. {
  1160.   c_writeSchemaRecord.inUse = false;
  1161.   c_writeSchemaRecord.pageId = RNIL;
  1162.   c_writeSchemaRecord.noOfSchemaFilesHandled = 3;
  1163. }//initWriteSchemaRecord()
  1164. void Dbdict::initRetrieveRecord(Signal* signal, Uint32 i, Uint32 returnCode) 
  1165. {
  1166.   c_retrieveRecord.busyState = false;
  1167.   c_retrieveRecord.blockRef = 0;
  1168.   c_retrieveRecord.m_senderData = RNIL;
  1169.   c_retrieveRecord.tableId = RNIL;
  1170.   c_retrieveRecord.currentSent = 0;
  1171.   c_retrieveRecord.retrievedNoOfPages = 0;
  1172.   c_retrieveRecord.retrievedNoOfWords = 0;
  1173.   c_retrieveRecord.m_useLongSig = false;
  1174. }//initRetrieveRecord()
  1175. void Dbdict::initSchemaRecord() 
  1176. {
  1177.   c_schemaRecord.schemaPage = RNIL;
  1178. }//Dbdict::initSchemaRecord()
  1179. void Dbdict::initRestartRecord() 
  1180. {
  1181.   c_restartRecord.gciToRestart = 0;
  1182.   c_restartRecord.activeTable = ZNIL;
  1183. }//Dbdict::initRestartRecord()
  1184. void Dbdict::initNodeRecords() 
  1185. {
  1186.   jam();
  1187.   for (unsigned i = 1; i < MAX_NODES; i++) {
  1188.     NodeRecordPtr nodePtr;
  1189.     c_nodes.getPtr(nodePtr, i);
  1190.     nodePtr.p->hotSpare = false;
  1191.     nodePtr.p->nodeState = NodeRecord::API_NODE;
  1192.   }//for
  1193. }//Dbdict::initNodeRecords()
  1194. void Dbdict::initPageRecords() 
  1195. {
  1196.   c_schemaRecord.schemaPage = ZMAX_PAGES_OF_TABLE_DEFINITION;
  1197.   c_schemaRecord.oldSchemaPage = ZMAX_PAGES_OF_TABLE_DEFINITION + 1;
  1198.   c_retrieveRecord.retrievePage =  ZMAX_PAGES_OF_TABLE_DEFINITION + 2;
  1199.   ndbrequire(ZNUMBER_OF_PAGES >= (2 * ZMAX_PAGES_OF_TABLE_DEFINITION + 2));
  1200. }//Dbdict::initPageRecords()
  1201. void Dbdict::initTableRecords() 
  1202. {
  1203.   TableRecordPtr tablePtr;
  1204.   while (1) {
  1205.     jam();
  1206.     refresh_watch_dog();
  1207.     c_tableRecordPool.seize(tablePtr);
  1208.     if (tablePtr.i == RNIL) {
  1209.       jam();
  1210.       break;
  1211.     }//if
  1212.     initialiseTableRecord(tablePtr);
  1213.   }//while
  1214. }//Dbdict::initTableRecords()
  1215. void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr) 
  1216. {
  1217.   tablePtr.p->activePage = RNIL;
  1218.   tablePtr.p->filePtr[0] = RNIL;
  1219.   tablePtr.p->filePtr[1] = RNIL;
  1220.   tablePtr.p->firstAttribute = RNIL;
  1221.   tablePtr.p->firstPage = RNIL;
  1222.   tablePtr.p->lastAttribute = RNIL;
  1223.   tablePtr.p->tableId = tablePtr.i;
  1224.   tablePtr.p->tableVersion = (Uint32)-1;
  1225.   tablePtr.p->tabState = TableRecord::NOT_DEFINED;
  1226.   tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
  1227.   tablePtr.p->storageType = DictTabInfo::MainMemory;
  1228.   tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
  1229.   tablePtr.p->fragmentKeyType = DictTabInfo::PrimaryKey;
  1230.   memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName));
  1231.   tablePtr.p->gciTableCreated = 0;
  1232.   tablePtr.p->noOfAttributes = ZNIL;
  1233.   tablePtr.p->noOfNullAttr = 0;
  1234.   tablePtr.p->frmLen = 0;
  1235.   memset(tablePtr.p->frmData, 0, sizeof(tablePtr.p->frmData));
  1236.   /*
  1237.     tablePtr.p->lh3PageIndexBits = 0;
  1238.     tablePtr.p->lh3DistrBits = 0;
  1239.     tablePtr.p->lh3PageBits = 6;
  1240.   */
  1241.   tablePtr.p->kValue = 6;
  1242.   tablePtr.p->localKeyLen = 1;
  1243.   tablePtr.p->maxLoadFactor = 80;
  1244.   tablePtr.p->minLoadFactor = 70;
  1245.   tablePtr.p->noOfPrimkey = 1;
  1246.   tablePtr.p->tupKeyLength = 1;
  1247.   tablePtr.p->storedTable = true;
  1248.   tablePtr.p->tableType = DictTabInfo::UserTable;
  1249.   tablePtr.p->primaryTableId = RNIL;
  1250.   // volatile elements
  1251.   tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
  1252.   tablePtr.p->insertTriggerId = RNIL;
  1253.   tablePtr.p->updateTriggerId = RNIL;
  1254.   tablePtr.p->deleteTriggerId = RNIL;
  1255.   tablePtr.p->customTriggerId = RNIL;
  1256.   tablePtr.p->buildTriggerId = RNIL;
  1257.   tablePtr.p->indexLocal = 0;
  1258. }//Dbdict::initialiseTableRecord()
  1259. void Dbdict::initTriggerRecords()
  1260. {
  1261.   TriggerRecordPtr triggerPtr;
  1262.   while (1) {
  1263.     jam();
  1264.     refresh_watch_dog();
  1265.     c_triggerRecordPool.seize(triggerPtr);
  1266.     if (triggerPtr.i == RNIL) {
  1267.       jam();
  1268.       break;
  1269.     }//if
  1270.     initialiseTriggerRecord(triggerPtr);
  1271.   }//while
  1272. }
  1273. void Dbdict::initialiseTriggerRecord(TriggerRecordPtr triggerPtr)
  1274. {
  1275.   triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
  1276.   triggerPtr.p->triggerLocal = 0;
  1277.   memset(triggerPtr.p->triggerName, 0, sizeof(triggerPtr.p->triggerName));
  1278.   triggerPtr.p->triggerId = RNIL;
  1279.   triggerPtr.p->tableId = RNIL;
  1280.   triggerPtr.p->triggerType = (TriggerType::Value)~0;
  1281.   triggerPtr.p->triggerActionTime = (TriggerActionTime::Value)~0;
  1282.   triggerPtr.p->triggerEvent = (TriggerEvent::Value)~0;
  1283.   triggerPtr.p->monitorReplicas = false;
  1284.   triggerPtr.p->monitorAllAttributes = false;
  1285.   triggerPtr.p->attributeMask.clear();
  1286.   triggerPtr.p->indexId = RNIL;
  1287. }
  1288. Uint32 Dbdict::getFsConnRecord() 
  1289. {
  1290.   FsConnectRecordPtr fsPtr;
  1291.   c_fsConnectRecordPool.seize(fsPtr);
  1292.   ndbrequire(fsPtr.i != RNIL);
  1293.   fsPtr.p->filePtr = (Uint32)-1;
  1294.   fsPtr.p->ownerPtr = RNIL;
  1295.   fsPtr.p->fsState = FsConnectRecord::IDLE;
  1296.   return fsPtr.i;
  1297. }//Dbdict::getFsConnRecord()
  1298. Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId) 
  1299. {
  1300.   Uint32 minId = (primaryTableId == RNIL ? 0 : primaryTableId + 1);
  1301.   TableRecordPtr tablePtr;
  1302.   TableRecordPtr firstTablePtr;
  1303.   bool firstFound = false;
  1304.   Uint32 tabSize = c_tableRecordPool.getSize();
  1305.   for (tablePtr.i = minId; tablePtr.i < tabSize ; tablePtr.i++) {
  1306.     jam();
  1307.     c_tableRecordPool.getPtr(tablePtr);
  1308.     if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
  1309.       jam();
  1310.       initialiseTableRecord(tablePtr);
  1311.       tablePtr.p->tabState = TableRecord::DEFINING;
  1312.       firstFound = true;
  1313.       firstTablePtr.i = tablePtr.i;
  1314.       firstTablePtr.p = tablePtr.p;
  1315.       break;
  1316.     }//if
  1317.   }//for
  1318.   if (!firstFound) {
  1319.     jam();
  1320.     return RNIL;
  1321.   }//if
  1322. #ifdef HAVE_TABLE_REORG
  1323.   bool secondFound = false;
  1324.   for (tablePtr.i = firstTablePtr.i + 1; tablePtr.i < tabSize ; tablePtr.i++) {
  1325.     jam();
  1326.     c_tableRecordPool.getPtr(tablePtr);
  1327.     if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
  1328.       jam();
  1329.       initialiseTableRecord(tablePtr);
  1330.       tablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED;
  1331.       tablePtr.p->secondTable = firstTablePtr.i;
  1332.       firstTablePtr.p->secondTable = tablePtr.i;
  1333.       secondFound = true;
  1334.       break;
  1335.     }//if
  1336.   }//for
  1337.   if (!secondFound) {
  1338.     jam();
  1339.     firstTablePtr.p->tabState = TableRecord::NOT_DEFINED;
  1340.     return RNIL;
  1341.   }//if
  1342. #endif
  1343.   return firstTablePtr.i;
  1344. }//Dbdict::getFreeTableRecord()
  1345. Uint32 Dbdict::getFreeTriggerRecord()
  1346. {
  1347.   const Uint32 size = c_triggerRecordPool.getSize();
  1348.   TriggerRecordPtr triggerPtr;
  1349.   for (triggerPtr.i = 0; triggerPtr.i < size; triggerPtr.i++) {
  1350.     jam();
  1351.     c_triggerRecordPool.getPtr(triggerPtr);
  1352.     if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
  1353.       jam();
  1354.       initialiseTriggerRecord(triggerPtr);
  1355.       return triggerPtr.i;
  1356.     }
  1357.   }
  1358.   return RNIL;
  1359. }
  1360. bool
  1361. Dbdict::getNewAttributeRecord(TableRecordPtr tablePtr, 
  1362.       AttributeRecordPtr & attrPtr) 
  1363. {
  1364.   c_attributeRecordPool.seize(attrPtr);
  1365.   if(attrPtr.i == RNIL){
  1366.     return false;
  1367.   }
  1368.   
  1369.   memset(attrPtr.p->attributeName, 0, sizeof(attrPtr.p->attributeName));
  1370.   attrPtr.p->attributeDescriptor = 0x00012255; //Default value
  1371.   attrPtr.p->attributeId = ZNIL;
  1372.   attrPtr.p->nextAttrInTable = RNIL;
  1373.   attrPtr.p->tupleKey = 0;
  1374.   memset(attrPtr.p->defaultValue, 0, sizeof(attrPtr.p->defaultValue));
  1375.   
  1376.   /* ---------------------------------------------------------------- */
  1377.   // A free attribute record has been acquired. We will now link it
  1378.   // to the table record.
  1379.   /* ---------------------------------------------------------------- */
  1380.   if (tablePtr.p->lastAttribute == RNIL) {
  1381.     jam();
  1382.     tablePtr.p->firstAttribute = attrPtr.i;
  1383.   } else {
  1384.     jam();
  1385.     AttributeRecordPtr lastAttrPtr;
  1386.     c_attributeRecordPool.getPtr(lastAttrPtr, tablePtr.p->lastAttribute);
  1387.     lastAttrPtr.p->nextAttrInTable = attrPtr.i;
  1388.   }//if
  1389.   tablePtr.p->lastAttribute = attrPtr.i;
  1390.   return true;
  1391. }//Dbdict::getNewAttributeRecord()
  1392. /* **************************************************************** */
  1393. /* ---------------------------------------------------------------- */
  1394. /* MODULE:          START/RESTART HANDLING ------------------------ */
  1395. /* ---------------------------------------------------------------- */
  1396. /*                                                                  */
  1397. /* This module contains the code that is common for all             */
  1398. /* start/restart types.                                             */
  1399. /* ---------------------------------------------------------------- */
  1400. /* **************************************************************** */
  1401. /* ---------------------------------------------------------------- */
  1402. // This is sent as the first signal during start/restart.
  1403. /* ---------------------------------------------------------------- */
  1404. void Dbdict::execSTTOR(Signal* signal) 
  1405. {
  1406.   jamEntry();
  1407.   c_startPhase = signal->theData[1];
  1408.   switch (c_startPhase) {
  1409.   case 1:
  1410.     break;
  1411.   case 3:
  1412.     c_restartType = signal->theData[7];         /* valid if 3 */
  1413.     ndbrequire(c_restartType == NodeState::ST_INITIAL_START ||
  1414.                c_restartType == NodeState::ST_SYSTEM_RESTART ||
  1415.                c_restartType == NodeState::ST_INITIAL_NODE_RESTART ||
  1416.                c_restartType == NodeState::ST_NODE_RESTART);
  1417.     break;
  1418.   }
  1419.   sendSTTORRY(signal);
  1420. }//execSTTOR()
  1421. void Dbdict::sendSTTORRY(Signal* signal)
  1422. {
  1423.   signal->theData[0] = 0;       /* garbage SIGNAL KEY */
  1424.   signal->theData[1] = 0;       /* garbage SIGNAL VERSION NUMBER  */
  1425.   signal->theData[2] = 0;       /* garbage */
  1426.   signal->theData[3] = 1;       /* first wanted start phase */
  1427.   signal->theData[4] = 3;       /* get type of start */
  1428.   signal->theData[5] = ZNOMOREPHASES;
  1429.   sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
  1430. }
  1431. /* ---------------------------------------------------------------- */
  1432. // We receive information about sizes of records.
  1433. /* ---------------------------------------------------------------- */
  1434. void Dbdict::execREAD_CONFIG_REQ(Signal* signal) 
  1435. {
  1436.   const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
  1437.   Uint32 ref = req->senderRef;
  1438.   Uint32 senderData = req->senderData;
  1439.   ndbrequire(req->noOfParameters == 0);
  1440.   jamEntry();
  1441.  
  1442.   const ndb_mgm_configuration_iterator * p = 
  1443.     theConfiguration.getOwnConfigIterator();
  1444.   ndbrequire(p != 0);
  1445.   
  1446.   Uint32 attributesize, tablerecSize;
  1447.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_ATTRIBUTE,&attributesize));
  1448.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &tablerecSize));
  1449.   c_attributeRecordPool.setSize(attributesize);
  1450.   c_attributeRecordHash.setSize(64);
  1451.   c_fsConnectRecordPool.setSize(ZFS_CONNECT_SIZE);
  1452.   c_nodes.setSize(MAX_NODES);
  1453.   c_pageRecordArray.setSize(ZNUMBER_OF_PAGES);
  1454.   c_tableRecordPool.setSize(tablerecSize);
  1455.   c_tableRecordHash.setSize(tablerecSize);
  1456.   c_triggerRecordPool.setSize(c_maxNoOfTriggers);
  1457.   c_triggerRecordHash.setSize(c_maxNoOfTriggers);
  1458.   c_opRecordPool.setSize(256);   // XXX need config params
  1459.   c_opCreateTable.setSize(8);
  1460.   c_opDropTable.setSize(8);
  1461.   c_opCreateIndex.setSize(8);
  1462.   c_opCreateEvent.setSize(8);
  1463.   c_opSubEvent.setSize(8);
  1464.   c_opDropEvent.setSize(8);
  1465.   c_opSignalUtil.setSize(8);
  1466.   c_opDropIndex.setSize(8);
  1467.   c_opAlterIndex.setSize(8);
  1468.   c_opBuildIndex.setSize(8);
  1469.   c_opCreateTrigger.setSize(8);
  1470.   c_opDropTrigger.setSize(8);
  1471.   c_opAlterTrigger.setSize(8);
  1472.   // Initialize BAT for interface to file system
  1473.   PageRecordPtr pageRecPtr;
  1474.   c_pageRecordArray.getPtr(pageRecPtr, 0);
  1475.   NewVARIABLE* bat = allocateBat(2);
  1476.   bat[1].WA = &pageRecPtr.p->word[0];
  1477.   bat[1].nrr = ZNUMBER_OF_PAGES;
  1478.   bat[1].ClusterSize = ZSIZE_OF_PAGES_IN_WORDS * 4;
  1479.   bat[1].bits.q = ZLOG_SIZE_OF_PAGES_IN_WORDS; // 2**13 = 8192 elements
  1480.   bat[1].bits.v = 5;  // 32 bits per element
  1481.   initCommonData();
  1482.   initRecords();
  1483.   ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
  1484.   conf->senderRef = reference();
  1485.   conf->senderData = senderData;
  1486.   sendSignal(ref, GSN_READ_CONFIG_CONF, signal, 
  1487.      ReadConfigConf::SignalLength, JBB);
  1488. }//execSIZEALT_REP()
  1489. /* ---------------------------------------------------------------- */
  1490. // Start phase signals sent by CNTR. We reply with NDB_STTORRY when
  1491. // we completed this phase.
  1492. /* ---------------------------------------------------------------- */
  1493. void Dbdict::execNDB_STTOR(Signal* signal) 
  1494. {
  1495.   jamEntry();
  1496.   c_startPhase = signal->theData[2];
  1497.   const Uint32 restartType = signal->theData[3];
  1498.   if (restartType == NodeState::ST_INITIAL_START) {
  1499.     jam();
  1500.     c_initialStart = true;
  1501.   } else if (restartType == NodeState::ST_SYSTEM_RESTART) {
  1502.     jam();
  1503.     c_systemRestart = true;
  1504.   } else if (restartType == NodeState::ST_INITIAL_NODE_RESTART) {
  1505.     jam();
  1506.     c_initialNodeRestart = true;
  1507.   } else if (restartType == NodeState::ST_NODE_RESTART) {
  1508.     jam();
  1509.     c_nodeRestart = true;
  1510.   } else {
  1511.     ndbrequire(false);
  1512.   }//if
  1513.   switch (c_startPhase) {
  1514.   case 1:
  1515.     jam();
  1516.     initSchemaFile(signal);
  1517.     break;
  1518.   case 3:
  1519.     jam();
  1520.     signal->theData[0] = reference();
  1521.     sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
  1522.     break;
  1523.   case 6:
  1524.     jam();
  1525.     c_initialStart = false;
  1526.     c_systemRestart = false;
  1527.     c_initialNodeRestart = false;
  1528.     c_nodeRestart = false;
  1529.     sendNDB_STTORRY(signal);
  1530.     break;
  1531.   case 7:
  1532.     // uses c_restartType
  1533.     if(restartType == NodeState::ST_SYSTEM_RESTART &&
  1534.        c_masterNodeId == getOwnNodeId()){
  1535.       rebuildIndexes(signal, 0);
  1536.       return;
  1537.     }
  1538.     sendNDB_STTORRY(signal);
  1539.     break;
  1540.   default:
  1541.     jam();
  1542.     sendNDB_STTORRY(signal);
  1543.     break;
  1544.   }//switch
  1545. }//execNDB_STTOR()
  1546. void Dbdict::sendNDB_STTORRY(Signal* signal) 
  1547. {
  1548.   signal->theData[0] = reference();
  1549.   sendSignal(NDBCNTR_REF, GSN_NDB_STTORRY, signal, 1, JBB);
  1550.   return;
  1551. }//sendNDB_STTORRY()
  1552. /* ---------------------------------------------------------------- */
  1553. // We receive the information about which nodes that are up and down.
  1554. /* ---------------------------------------------------------------- */
  1555. void Dbdict::execREAD_NODESCONF(Signal* signal) 
  1556. {
  1557.   jamEntry();
  1558.   ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
  1559.   c_numberNode   = readNodes->noOfNodes;
  1560.   c_masterNodeId = readNodes->masterNodeId;
  1561.   c_noNodesFailed = 0;
  1562.   c_aliveNodes.clear();
  1563.   for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
  1564.     jam();
  1565.     NodeRecordPtr nodePtr;
  1566.     c_nodes.getPtr(nodePtr, i);
  1567.     if (NodeBitmask::get(readNodes->allNodes, i)) {
  1568.       jam();
  1569.       nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
  1570.       if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
  1571. jam();
  1572. /**-------------------------------------------------------------------
  1573.  *
  1574.  * THIS NODE IS DEFINED IN THE CLUSTER BUT IS NOT ALIVE CURRENTLY.
  1575.  * WE ADD THE NODE TO THE SET OF FAILED NODES AND ALSO SET THE
  1576.  * BLOCKSTATE TO BUSY TO AVOID ADDING TABLES WHILE NOT ALL NODES ARE
  1577.  * ALIVE.
  1578.  *------------------------------------------------------------------*/
  1579.         nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
  1580. c_noNodesFailed++;
  1581.       } else {
  1582. c_aliveNodes.set(i);
  1583.       }
  1584.     }//if
  1585.   }//for
  1586.   sendNDB_STTORRY(signal);
  1587. }//execREAD_NODESCONF()
  1588. /* ---------------------------------------------------------------- */
  1589. // HOT_SPAREREP informs DBDICT about which nodes that have become
  1590. // hot spare nodes.
  1591. /* ---------------------------------------------------------------- */
  1592. void Dbdict::execHOT_SPAREREP(Signal* signal) 
  1593. {
  1594.   Uint32 hotSpareNodes = 0;
  1595.   jamEntry();
  1596.   HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
  1597.   for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
  1598.     if (NodeBitmask::get(hotSpare->theHotSpareNodes, i)) {
  1599.       NodeRecordPtr nodePtr;
  1600.       c_nodes.getPtr(nodePtr, i);
  1601.       nodePtr.p->hotSpare = true;
  1602.       hotSpareNodes++;
  1603.     }//if
  1604.   }//for
  1605.   ndbrequire(hotSpareNodes == hotSpare->noHotSpareNodes);
  1606.   c_noHotSpareNodes = hotSpareNodes;
  1607.   return;
  1608. }//execHOT_SPAREREP()
  1609. void Dbdict::initSchemaFile(Signal* signal) 
  1610. {
  1611.   PageRecordPtr pagePtr;
  1612.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  1613.   SchemaFile * schemaFile = (SchemaFile *)pagePtr.p;
  1614.   initSchemaFile(schemaFile, 4 * ZSIZE_OF_PAGES_IN_WORDS);
  1615.   
  1616.   if (c_initialStart || c_initialNodeRestart) {    
  1617.     jam();
  1618.     ndbrequire(c_writeSchemaRecord.inUse == false);
  1619.     c_writeSchemaRecord.inUse = true;
  1620.     c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
  1621.     c_writeSchemaRecord.m_callback.m_callbackFunction = 
  1622.       safe_cast(&Dbdict::initSchemaFile_conf);
  1623.     
  1624.     startWriteSchemaFile(signal);
  1625.   } else if (c_systemRestart || c_nodeRestart) {
  1626.     jam();
  1627.     ndbrequire(c_readSchemaRecord.schemaReadState == ReadSchemaRecord::IDLE);
  1628.     c_readSchemaRecord.pageId = c_schemaRecord.oldSchemaPage;
  1629.     c_readSchemaRecord.schemaReadState = ReadSchemaRecord::INITIAL_READ;
  1630.     startReadSchemaFile(signal);
  1631.   } else {
  1632.     ndbrequire(false);
  1633.   }//if
  1634. }//Dbdict::initSchemaFile()
  1635. void
  1636. Dbdict::initSchemaFile_conf(Signal* signal, Uint32 callbackData, Uint32 rv){
  1637.   jam();
  1638.   sendNDB_STTORRY(signal);
  1639. }
  1640. void
  1641. Dbdict::activateIndexes(Signal* signal, Uint32 i)
  1642. {
  1643.   AlterIndxReq* req = (AlterIndxReq*)signal->getDataPtrSend();
  1644.   TableRecordPtr tablePtr;
  1645.   for (; i < c_tableRecordPool.getSize(); i++) {
  1646.     tablePtr.i = i;
  1647.     c_tableRecordPool.getPtr(tablePtr);
  1648.     if (tablePtr.p->tabState != TableRecord::DEFINED)
  1649.       continue;
  1650.     if (! tablePtr.p->isIndex())
  1651.       continue;
  1652.     jam();
  1653.     req->setUserRef(reference());
  1654.     req->setConnectionPtr(i);
  1655.     req->setTableId(tablePtr.p->primaryTableId);
  1656.     req->setIndexId(tablePtr.i);
  1657.     req->setIndexVersion(tablePtr.p->tableVersion);
  1658.     req->setOnline(true);
  1659.     if (c_restartType == NodeState::ST_SYSTEM_RESTART) {
  1660.       if (c_masterNodeId != getOwnNodeId())
  1661.         continue;
  1662.       // from file index state is not defined currently
  1663.       req->setRequestType(AlterIndxReq::RT_SYSTEMRESTART);
  1664.       req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
  1665.     }
  1666.     else if (
  1667.         c_restartType == NodeState::ST_NODE_RESTART ||
  1668.         c_restartType == NodeState::ST_INITIAL_NODE_RESTART) {
  1669.       // from master index must be online
  1670.       if (tablePtr.p->indexState != TableRecord::IS_ONLINE)
  1671.         continue;
  1672.       req->setRequestType(AlterIndxReq::RT_NODERESTART);
  1673.       // activate locally, rebuild not needed
  1674.       req->addRequestFlag((Uint32)RequestFlag::RF_LOCAL);
  1675.       req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
  1676.     } else {
  1677.       ndbrequire(false);
  1678.     }
  1679.     sendSignal(reference(), GSN_ALTER_INDX_REQ,
  1680.       signal, AlterIndxReq::SignalLength, JBB);
  1681.     return;
  1682.   }
  1683.   signal->theData[0] = reference();
  1684.   sendSignal(c_restartRecord.returnBlockRef, GSN_DICTSTARTCONF,
  1685.      signal, 1, JBB);
  1686. }
  1687. void
  1688. Dbdict::rebuildIndexes(Signal* signal, Uint32 i){
  1689.   BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
  1690.   
  1691.   TableRecordPtr indexPtr;
  1692.   for (; i < c_tableRecordPool.getSize(); i++) {
  1693.     indexPtr.i = i;
  1694.     c_tableRecordPool.getPtr(indexPtr);
  1695.     if (indexPtr.p->tabState != TableRecord::DEFINED)
  1696.       continue;
  1697.     if (! indexPtr.p->isIndex())
  1698.       continue;
  1699.     jam();
  1700.     req->setUserRef(reference());
  1701.     req->setConnectionPtr(i);
  1702.     req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART);
  1703.     req->setBuildId(0);   // not used
  1704.     req->setBuildKey(0);  // not used
  1705.     req->setIndexType(indexPtr.p->tableType);
  1706.     req->setIndexId(indexPtr.i);
  1707.     req->setTableId(indexPtr.p->primaryTableId);
  1708.     req->setParallelism(16);
  1709.     // from file index state is not defined currently
  1710.     if (indexPtr.p->storedTable) {
  1711.       // rebuild not needed
  1712.       req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
  1713.     }
  1714.     
  1715.     // send
  1716.     sendSignal(reference(), GSN_BUILDINDXREQ,
  1717.        signal, BuildIndxReq::SignalLength, JBB);
  1718.     return;
  1719.   }
  1720.   sendNDB_STTORRY(signal);
  1721. }
  1722. /* **************************************************************** */
  1723. /* ---------------------------------------------------------------- */
  1724. /* MODULE:          SYSTEM RESTART MODULE ------------------------- */
  1725. /* ---------------------------------------------------------------- */
  1726. /*                                                                  */
  1727. /* This module contains code specific for system restart            */
  1728. /* ---------------------------------------------------------------- */
  1729. /* **************************************************************** */
  1730. /* ---------------------------------------------------------------- */
  1731. // DIH asks DICT to read in table data from disk during system
  1732. // restart. DIH also asks DICT to send information about which
  1733. // tables that should be started as part of this system restart.
  1734. // DICT will also activate the tables in TC as part of this process.
  1735. /* ---------------------------------------------------------------- */
  1736. void Dbdict::execDICTSTARTREQ(Signal* signal) 
  1737. {
  1738.   jamEntry();
  1739.   c_restartRecord.gciToRestart = signal->theData[0];
  1740.   c_restartRecord.returnBlockRef = signal->theData[1];
  1741.   if (c_nodeRestart || c_initialNodeRestart) {
  1742.     jam();   
  1743.     CRASH_INSERTION(6000);
  1744.     BlockReference dictRef = calcDictBlockRef(c_masterNodeId);
  1745.     signal->theData[0] = getOwnNodeId();
  1746.     sendSignal(dictRef, GSN_GET_SCHEMA_INFOREQ, signal, 1, JBB);
  1747.     return;
  1748.   }
  1749.   ndbrequire(c_systemRestart);
  1750.   ndbrequire(c_masterNodeId == getOwnNodeId());
  1751.   c_schemaRecord.m_callback.m_callbackData = 0;
  1752.   c_schemaRecord.m_callback.m_callbackFunction = 
  1753.     safe_cast(&Dbdict::masterRestart_checkSchemaStatusComplete);
  1754.   c_restartRecord.activeTable = 0;
  1755.   c_schemaRecord.schemaPage = c_schemaRecord.oldSchemaPage;
  1756.   checkSchemaStatus(signal);
  1757. }//execDICTSTARTREQ()
  1758. void
  1759. Dbdict::masterRestart_checkSchemaStatusComplete(Signal* signal,
  1760. Uint32 callbackData,
  1761. Uint32 returnCode){
  1762.   c_schemaRecord.schemaPage = ZMAX_PAGES_OF_TABLE_DEFINITION;
  1763.   LinearSectionPtr ptr[3];
  1764.   PageRecordPtr pagePtr;
  1765.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.oldSchemaPage);
  1766.   ptr[0].p = &pagePtr.p->word[0];
  1767.   ptr[0].sz = ZSIZE_OF_PAGES_IN_WORDS;
  1768.   c_sendSchemaRecord.m_SCHEMAINFO_Counter = c_aliveNodes;
  1769.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  1770.   rg.m_nodes.clear(getOwnNodeId());
  1771.   Callback c = { 0, 0 };
  1772.   sendFragmentedSignal(rg,
  1773.        GSN_SCHEMA_INFO,
  1774.        signal, 
  1775.        1, //SchemaInfo::SignalLength,
  1776.        JBB,
  1777.        ptr,
  1778.        1,
  1779.        c);
  1780.   PageRecordPtr newPagePtr;
  1781.   c_pageRecordArray.getPtr(newPagePtr, c_schemaRecord.schemaPage);
  1782.   memcpy(&newPagePtr.p->word[0], &pagePtr.p->word[0], 
  1783.  4 *  ZSIZE_OF_PAGES_IN_WORDS);
  1784.   signal->theData[0] = getOwnNodeId();
  1785.   sendSignal(reference(), GSN_SCHEMA_INFOCONF, signal, 1, JBB);
  1786. }
  1787. void 
  1788. Dbdict::execGET_SCHEMA_INFOREQ(Signal* signal){
  1789.   const Uint32 ref = signal->getSendersBlockRef();
  1790.   //const Uint32 senderData = signal->theData[0];
  1791.   
  1792.   ndbrequire(c_sendSchemaRecord.inUse == false);
  1793.   c_sendSchemaRecord.inUse = true;
  1794.   LinearSectionPtr ptr[3];
  1795.   
  1796.   PageRecordPtr pagePtr;
  1797.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  1798.   
  1799.   ptr[0].p = &pagePtr.p->word[0];
  1800.   ptr[0].sz = ZSIZE_OF_PAGES_IN_WORDS;
  1801.   Callback c = { safe_cast(&Dbdict::sendSchemaComplete), 0 };
  1802.   sendFragmentedSignal(ref,
  1803.        GSN_SCHEMA_INFO,
  1804.        signal, 
  1805.        1, //GetSchemaInfoConf::SignalLength,
  1806.        JBB,
  1807.        ptr,
  1808.        1,
  1809.        c);
  1810. }//Dbdict::execGET_SCHEMA_INFOREQ()
  1811. void
  1812. Dbdict::sendSchemaComplete(Signal * signal, 
  1813.    Uint32 callbackData,
  1814.    Uint32 returnCode){
  1815.   ndbrequire(c_sendSchemaRecord.inUse == true);
  1816.   c_sendSchemaRecord.inUse = false;
  1817. }
  1818. /* ---------------------------------------------------------------- */
  1819. // We receive the schema info from master as part of all restarts
  1820. // except the initial start where no tables exists.
  1821. /* ---------------------------------------------------------------- */
  1822. void Dbdict::execSCHEMA_INFO(Signal* signal) 
  1823. {
  1824.   jamEntry();
  1825.   if(!assembleFragments(signal)){
  1826.     jam();
  1827.     return;
  1828.   }
  1829.   if(getNodeState().getNodeRestartInProgress()){
  1830.     CRASH_INSERTION(6001);
  1831.   }
  1832.   SegmentedSectionPtr schemaDataPtr;
  1833.   signal->getSection(schemaDataPtr, 0);
  1834.   PageRecordPtr pagePtr;
  1835.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  1836.   copy(&pagePtr.p->word[0], schemaDataPtr);
  1837.   releaseSections(signal);
  1838.     
  1839.   validateChecksum((SchemaFile*)pagePtr.p);
  1840.   ndbrequire(signal->getSendersBlockRef() != reference());
  1841.     
  1842.   /* ---------------------------------------------------------------- */
  1843.   // Synchronise our view on data with other nodes in the cluster.
  1844.   // This is an important part of restart handling where we will handle
  1845.   // cases where the table have been added but only partially, where
  1846.   // tables have been deleted but not completed the deletion yet and
  1847.   // other scenarios needing synchronisation.
  1848.   /* ---------------------------------------------------------------- */
  1849.   c_schemaRecord.m_callback.m_callbackData = 0;
  1850.   c_schemaRecord.m_callback.m_callbackFunction = 
  1851.     safe_cast(&Dbdict::restart_checkSchemaStatusComplete);
  1852.   c_restartRecord.activeTable = 0;
  1853.   checkSchemaStatus(signal);
  1854. }//execSCHEMA_INFO()
  1855. void
  1856. Dbdict::restart_checkSchemaStatusComplete(Signal * signal, 
  1857.   Uint32 callbackData,
  1858.   Uint32 returnCode){
  1859.   ndbrequire(c_writeSchemaRecord.inUse == false);
  1860.   c_writeSchemaRecord.inUse = true;
  1861.   c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
  1862.   c_writeSchemaRecord.m_callback.m_callbackData = 0;
  1863.   c_writeSchemaRecord.m_callback.m_callbackFunction = 
  1864.     safe_cast(&Dbdict::restart_writeSchemaConf);
  1865.   
  1866.   startWriteSchemaFile(signal);
  1867. }
  1868. void
  1869. Dbdict::restart_writeSchemaConf(Signal * signal, 
  1870. Uint32 callbackData,
  1871. Uint32 returnCode){
  1872.   if(c_systemRestart){
  1873.     jam();
  1874.     signal->theData[0] = getOwnNodeId();
  1875.     sendSignal(calcDictBlockRef(c_masterNodeId), GSN_SCHEMA_INFOCONF,
  1876.        signal, 1, JBB);
  1877.     return;
  1878.   }
  1879.   
  1880.   ndbrequire(c_nodeRestart || c_initialNodeRestart);
  1881.   c_blockState = BS_IDLE;
  1882.   activateIndexes(signal, 0);
  1883.   return;
  1884. }
  1885. void Dbdict::execSCHEMA_INFOCONF(Signal* signal) 
  1886. {
  1887.   jamEntry();
  1888.   ndbrequire(signal->getNoOfSections() == 0);
  1889. /* ---------------------------------------------------------------- */
  1890. // This signal is received in the master as part of system restart
  1891. // from all nodes (including the master) after they have synchronised
  1892. // their data with the master node's schema information.
  1893. /* ---------------------------------------------------------------- */
  1894.   const Uint32 nodeId = signal->theData[0];
  1895.   c_sendSchemaRecord.m_SCHEMAINFO_Counter.clearWaitingFor(nodeId);
  1896.   if (!c_sendSchemaRecord.m_SCHEMAINFO_Counter.done()){
  1897.     jam();
  1898.     return;
  1899.   }//if
  1900.   activateIndexes(signal, 0);
  1901. }//execSCHEMA_INFOCONF()
  1902. void Dbdict::checkSchemaStatus(Signal* signal) 
  1903. {
  1904.   PageRecordPtr pagePtr;
  1905.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  1906.   PageRecordPtr oldPagePtr;
  1907.   c_pageRecordArray.getPtr(oldPagePtr, c_schemaRecord.oldSchemaPage);
  1908.   for (; c_restartRecord.activeTable < MAX_TABLES; 
  1909.        c_restartRecord.activeTable++) {
  1910.     jam();
  1911.     Uint32 tableId = c_restartRecord.activeTable;
  1912.     SchemaFile::TableEntry *newEntry = getTableEntry(pagePtr.p, tableId);
  1913.     SchemaFile::TableEntry *oldEntry = getTableEntry(oldPagePtr.p, tableId, 
  1914.      true);
  1915.     SchemaFile::TableState schemaState = 
  1916.       (SchemaFile::TableState)newEntry->m_tableState;
  1917.     SchemaFile::TableState oldSchemaState = 
  1918.       (SchemaFile::TableState)oldEntry->m_tableState;
  1919.     if (c_restartRecord.activeTable >= c_tableRecordPool.getSize()) {
  1920.       jam();
  1921.       ndbrequire(schemaState == SchemaFile::INIT);
  1922.       ndbrequire(oldSchemaState == SchemaFile::INIT);
  1923.       continue;
  1924.     }//if
  1925.     switch(schemaState){
  1926.     case SchemaFile::INIT:{
  1927.       jam();
  1928.       bool ok = false;
  1929.       switch(oldSchemaState) {
  1930.       case SchemaFile::INIT:
  1931. jam();
  1932.       case SchemaFile::DROP_TABLE_COMMITTED:
  1933. jam();
  1934. ok = true;
  1935.         jam();
  1936. break;
  1937.       case SchemaFile::ADD_STARTED:
  1938. jam();
  1939.       case SchemaFile::TABLE_ADD_COMMITTED:
  1940. jam();
  1941.       case SchemaFile::DROP_TABLE_STARTED:
  1942. jam();
  1943.       case SchemaFile::ALTER_TABLE_COMMITTED:
  1944. jam();
  1945. ok = true;
  1946.         jam();
  1947. newEntry->m_tableState = SchemaFile::INIT;
  1948. restartDropTab(signal, tableId);
  1949. return;
  1950.       }//switch
  1951.       ndbrequire(ok);
  1952.       break;
  1953.     }
  1954.     case SchemaFile::ADD_STARTED:{
  1955.       jam();
  1956.       bool ok = false;
  1957.       switch(oldSchemaState) {
  1958.       case SchemaFile::INIT:
  1959. jam();
  1960.       case SchemaFile::DROP_TABLE_COMMITTED:
  1961. jam();
  1962. ok = true;
  1963. break;
  1964.       case SchemaFile::ADD_STARTED: 
  1965. jam();
  1966.       case SchemaFile::DROP_TABLE_STARTED:
  1967. jam();
  1968.       case SchemaFile::TABLE_ADD_COMMITTED:
  1969. jam();
  1970.       case SchemaFile::ALTER_TABLE_COMMITTED:
  1971. jam();
  1972. ok = true;
  1973. //------------------------------------------------------------------
  1974. // Add Table was started but not completed. Will be dropped in all
  1975. // nodes. Update schema information (restore table version).
  1976. //------------------------------------------------------------------
  1977. newEntry->m_tableState = SchemaFile::INIT;
  1978. restartDropTab(signal, tableId);
  1979. return;
  1980.       }
  1981.       ndbrequire(ok);
  1982.       break;
  1983.     }
  1984.     case SchemaFile::TABLE_ADD_COMMITTED:{
  1985.       jam();
  1986.       bool ok = false;
  1987.       switch(oldSchemaState) {
  1988.       case SchemaFile::INIT:
  1989. jam();
  1990.       case SchemaFile::ADD_STARTED:
  1991. jam();
  1992.       case SchemaFile::DROP_TABLE_STARTED:
  1993. jam();
  1994.       case SchemaFile::DROP_TABLE_COMMITTED:
  1995. jam();
  1996. ok = true;
  1997. //------------------------------------------------------------------
  1998. // Table was added in the master node but not in our node. We can
  1999. // retrieve the table definition from the master.
  2000. //------------------------------------------------------------------
  2001. restartCreateTab(signal, tableId, oldEntry, false);
  2002.         return;
  2003.         break;
  2004.       case SchemaFile::TABLE_ADD_COMMITTED:
  2005. jam();
  2006.       case SchemaFile::ALTER_TABLE_COMMITTED:
  2007.         jam();
  2008. ok = true;
  2009. //------------------------------------------------------------------
  2010. // Table was added in both our node and the master node. We can
  2011. // retrieve the table definition from our own disk.
  2012. //------------------------------------------------------------------
  2013. if(* newEntry == * oldEntry){
  2014.           jam();
  2015.   
  2016.           TableRecordPtr tablePtr;
  2017.           c_tableRecordPool.getPtr(tablePtr, tableId);
  2018.           tablePtr.p->tableVersion = oldEntry->m_tableVersion;
  2019.           tablePtr.p->tableType = (DictTabInfo::TableType)oldEntry->m_tableType;
  2020.   
  2021.           // On NR get index from master because index state is not on file
  2022.           const bool file = c_systemRestart || tablePtr.p->isTable();
  2023.           restartCreateTab(signal, tableId, oldEntry, file);
  2024.           return;
  2025.         } else {
  2026.   //------------------------------------------------------------------
  2027.   // Must be a new version of the table if anything differs. Both table
  2028.   // version and global checkpoint must be different.
  2029.   // This should not happen for the master node. This can happen after
  2030.   // drop table followed by add table or after change table.
  2031.   // Not supported in this version.
  2032.   //------------------------------------------------------------------
  2033.           ndbrequire(c_masterNodeId != getOwnNodeId());
  2034.   ndbrequire(newEntry->m_tableVersion != oldEntry->m_tableVersion);
  2035.           jam();
  2036.   
  2037.   restartCreateTab(signal, tableId, oldEntry, false);
  2038.           return;
  2039.         }//if
  2040.       }
  2041.       ndbrequire(ok); 
  2042.       break;
  2043.     }
  2044.     case SchemaFile::DROP_TABLE_STARTED:
  2045.       jam();
  2046.     case SchemaFile::DROP_TABLE_COMMITTED:{
  2047.       jam();
  2048.       bool ok = false;
  2049.       switch(oldSchemaState){
  2050.       case SchemaFile::INIT:
  2051. jam();
  2052.       case SchemaFile::DROP_TABLE_COMMITTED:
  2053. jam();
  2054. ok = true;
  2055. break;
  2056.       case SchemaFile::ADD_STARTED:
  2057. jam();
  2058.       case SchemaFile::TABLE_ADD_COMMITTED:
  2059. jam();
  2060.       case SchemaFile::DROP_TABLE_STARTED:
  2061. jam();
  2062.       case SchemaFile::ALTER_TABLE_COMMITTED:
  2063. jam();
  2064. newEntry->m_tableState = SchemaFile::INIT;
  2065. restartDropTab(signal, tableId);
  2066. return;
  2067.       }
  2068.       ndbrequire(ok);
  2069.       break;
  2070.     }
  2071.     case SchemaFile::ALTER_TABLE_COMMITTED: {
  2072.       jam();
  2073.       bool ok = false;
  2074.       switch(oldSchemaState) {
  2075.       case SchemaFile::INIT:
  2076. jam();
  2077.       case SchemaFile::ADD_STARTED:
  2078. jam();
  2079.       case SchemaFile::DROP_TABLE_STARTED:
  2080. jam();
  2081.       case SchemaFile::DROP_TABLE_COMMITTED:
  2082. jam();
  2083.       case SchemaFile::TABLE_ADD_COMMITTED:
  2084.         jam();
  2085. ok = true;
  2086. //------------------------------------------------------------------
  2087. // Table was altered in the master node but not in our node. We can
  2088. // retrieve the altered table definition from the master.
  2089. //------------------------------------------------------------------
  2090. restartCreateTab(signal, tableId, oldEntry, false);
  2091.         return;
  2092.         break;
  2093.       case SchemaFile::ALTER_TABLE_COMMITTED:
  2094.         jam();
  2095. ok = true;
  2096. //------------------------------------------------------------------
  2097. // Table was altered in both our node and the master node. We can
  2098. // retrieve the table definition from our own disk.
  2099. //------------------------------------------------------------------
  2100. TableRecordPtr tablePtr;
  2101. c_tableRecordPool.getPtr(tablePtr, tableId);
  2102. tablePtr.p->tableVersion = oldEntry->m_tableVersion;
  2103. tablePtr.p->tableType = (DictTabInfo::TableType)oldEntry->m_tableType;
  2104. // On NR get index from master because index state is not on file
  2105. const bool file = c_systemRestart || tablePtr.p->isTable();
  2106. restartCreateTab(signal, tableId, oldEntry, file);
  2107. return;
  2108.       }
  2109.       ndbrequire(ok);
  2110.       break;
  2111.     }
  2112.     }
  2113.   }
  2114.   
  2115.   execute(signal, c_schemaRecord.m_callback, 0);
  2116. }//checkSchemaStatus()
  2117. void
  2118. Dbdict::restartCreateTab(Signal* signal, Uint32 tableId, 
  2119.       const SchemaFile::TableEntry * te, bool file){
  2120.   jam();
  2121.   
  2122.   CreateTableRecordPtr createTabPtr;  
  2123.   c_opCreateTable.seize(createTabPtr);
  2124.   ndbrequire(!createTabPtr.isNull());
  2125.   createTabPtr.p->key = ++c_opRecordSequence;
  2126.   c_opCreateTable.add(createTabPtr);
  2127.   
  2128.   createTabPtr.p->m_errorCode = 0;
  2129.   createTabPtr.p->m_tablePtrI = tableId;
  2130.   createTabPtr.p->m_coordinatorRef = reference();
  2131.   createTabPtr.p->m_senderRef = 0;
  2132.   createTabPtr.p->m_senderData = RNIL;
  2133.   createTabPtr.p->m_tabInfoPtrI = RNIL;
  2134.   createTabPtr.p->m_dihAddFragPtr = RNIL;
  2135.   if(file && !ERROR_INSERTED(6002)){
  2136.     jam();
  2137.     
  2138.     c_readTableRecord.noOfPages = te->m_noOfPages;
  2139.     c_readTableRecord.pageId = 0;
  2140.     c_readTableRecord.m_callback.m_callbackData = createTabPtr.p->key;
  2141.     c_readTableRecord.m_callback.m_callbackFunction = 
  2142.       safe_cast(&Dbdict::restartCreateTab_readTableConf);
  2143.     
  2144.     startReadTableFile(signal, tableId);
  2145.     return;
  2146.   } else {
  2147.     
  2148.     ndbrequire(c_masterNodeId != getOwnNodeId());
  2149.     
  2150.     /**
  2151.      * Get from master
  2152.      */
  2153.     GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
  2154.     req->senderRef = reference();
  2155.     req->senderData = createTabPtr.p->key;
  2156.     req->requestType = GetTabInfoReq::RequestById |
  2157.       GetTabInfoReq::LongSignalConf;
  2158.     req->tableId = tableId;
  2159.     sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
  2160.        GetTabInfoReq::SignalLength, JBB);
  2161.     if(ERROR_INSERTED(6002)){
  2162.       NdbSleep_MilliSleep(10);
  2163.       CRASH_INSERTION(6002);
  2164.     }
  2165.   }
  2166. }
  2167. void
  2168. Dbdict::restartCreateTab_readTableConf(Signal* signal, 
  2169.        Uint32 callbackData,
  2170.        Uint32 returnCode){
  2171.   jam();
  2172.   
  2173.   PageRecordPtr pageRecPtr;
  2174.   c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
  2175.   ParseDictTabInfoRecord parseRecord;
  2176.   parseRecord.requestType = DictTabInfo::GetTabInfoConf;
  2177.   parseRecord.errorCode = 0;
  2178.   
  2179.   Uint32 sz = c_readTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS; 
  2180.   SimplePropertiesLinearReader r(&pageRecPtr.p->word[0], sz);
  2181.   handleTabInfoInit(r, &parseRecord);
  2182.   ndbrequire(parseRecord.errorCode == 0);
  2183.   
  2184.   /* ---------------------------------------------------------------- */
  2185.   // We have read the table description from disk as part of system restart.
  2186.   // We will also write it back again to ensure that both copies are ok.
  2187.   /* ---------------------------------------------------------------- */
  2188.   ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
  2189.   c_writeTableRecord.noOfPages = c_readTableRecord.noOfPages;
  2190.   c_writeTableRecord.pageId = c_readTableRecord.pageId;
  2191.   c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
  2192.   c_writeTableRecord.m_callback.m_callbackData = callbackData;
  2193.   c_writeTableRecord.m_callback.m_callbackFunction = 
  2194.     safe_cast(&Dbdict::restartCreateTab_writeTableConf);
  2195.   startWriteTableFile(signal, c_readTableRecord.tableId);
  2196. }
  2197. void
  2198. Dbdict::execGET_TABINFO_CONF(Signal* signal){
  2199.   jamEntry();
  2200.   if(!assembleFragments(signal)){
  2201.     jam();
  2202.     return;
  2203.   }
  2204.   
  2205.   GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
  2206.   const Uint32 tableId = conf->tableId;
  2207.   const Uint32 senderData = conf->senderData;
  2208.   
  2209.   SegmentedSectionPtr tabInfoPtr;
  2210.   signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
  2211.   CreateTableRecordPtr createTabPtr;  
  2212.   ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
  2213.   ndbrequire(!createTabPtr.isNull());
  2214.   ndbrequire(createTabPtr.p->m_tablePtrI == tableId);
  2215.   /**
  2216.    * Put data into table record
  2217.    */
  2218.   ParseDictTabInfoRecord parseRecord;
  2219.   parseRecord.requestType = DictTabInfo::GetTabInfoConf;
  2220.   parseRecord.errorCode = 0;
  2221.   
  2222.   SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
  2223.   handleTabInfoInit(r, &parseRecord);
  2224.   ndbrequire(parseRecord.errorCode == 0);
  2225.   
  2226.   Callback callback;
  2227.   callback.m_callbackData = createTabPtr.p->key;
  2228.   callback.m_callbackFunction = 
  2229.     safe_cast(&Dbdict::restartCreateTab_writeTableConf);
  2230.   
  2231.   signal->header.m_noOfSections = 0;
  2232.   writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
  2233.   signal->setSection(tabInfoPtr, 0);
  2234.   releaseSections(signal);
  2235. }
  2236. void
  2237. Dbdict::restartCreateTab_writeTableConf(Signal* signal, 
  2238. Uint32 callbackData,
  2239. Uint32 returnCode){
  2240.   jam();
  2241.   CreateTableRecordPtr createTabPtr;  
  2242.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  2243.   Callback callback;
  2244.   callback.m_callbackData = callbackData;
  2245.   callback.m_callbackFunction = 
  2246.     safe_cast(&Dbdict::restartCreateTab_dihComplete);
  2247.   
  2248.   SegmentedSectionPtr fragDataPtr; 
  2249.   fragDataPtr.sz = 0;
  2250.   fragDataPtr.setNull();
  2251.   createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
  2252. }
  2253. void
  2254. Dbdict::restartCreateTab_dihComplete(Signal* signal, 
  2255.      Uint32 callbackData,
  2256.      Uint32 returnCode){
  2257.   jam();
  2258.   
  2259.   CreateTableRecordPtr createTabPtr;  
  2260.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  2261.   
  2262.   //@todo check error
  2263.   ndbrequire(createTabPtr.p->m_errorCode == 0);
  2264.   Callback callback;
  2265.   callback.m_callbackData = callbackData;
  2266.   callback.m_callbackFunction = 
  2267.     safe_cast(&Dbdict::restartCreateTab_activateComplete);
  2268.   
  2269.   alterTab_activate(signal, createTabPtr, &callback);
  2270. }
  2271. void
  2272. Dbdict::restartCreateTab_activateComplete(Signal* signal, 
  2273.   Uint32 callbackData,
  2274.   Uint32 returnCode){
  2275.   jam();
  2276.   
  2277.   CreateTableRecordPtr createTabPtr;  
  2278.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  2279.   TableRecordPtr tabPtr;
  2280.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  2281.   tabPtr.p->tabState = TableRecord::DEFINED;
  2282.   
  2283.   c_opCreateTable.release(createTabPtr);
  2284.   c_restartRecord.activeTable++;
  2285.   checkSchemaStatus(signal);
  2286. }
  2287. void
  2288. Dbdict::restartDropTab(Signal* signal, Uint32 tableId){
  2289.   const Uint32 key = ++c_opRecordSequence;
  2290.   DropTableRecordPtr dropTabPtr;  
  2291.   ndbrequire(c_opDropTable.seize(dropTabPtr));
  2292.   
  2293.   dropTabPtr.p->key = key;
  2294.   c_opDropTable.add(dropTabPtr);
  2295.   
  2296.   dropTabPtr.p->m_errorCode = 0;
  2297.   dropTabPtr.p->m_request.tableId = tableId;
  2298.   dropTabPtr.p->m_coordinatorRef = 0;
  2299.   dropTabPtr.p->m_requestType = DropTabReq::RestartDropTab;
  2300.   dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
  2301.   
  2302.   dropTabPtr.p->m_participantData.m_block = 0;
  2303.   dropTabPtr.p->m_participantData.m_callback.m_callbackData = key;
  2304.   dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 
  2305.     safe_cast(&Dbdict::restartDropTab_complete);
  2306.   dropTab_nextStep(signal, dropTabPtr);  
  2307. }
  2308. void
  2309. Dbdict::restartDropTab_complete(Signal* signal, 
  2310. Uint32 callbackData,
  2311. Uint32 returnCode){
  2312.   jam();
  2313.   DropTableRecordPtr dropTabPtr;
  2314.   ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
  2315.   
  2316.   //@todo check error
  2317.   c_opDropTable.release(dropTabPtr);
  2318.   c_restartRecord.activeTable++;
  2319.   checkSchemaStatus(signal);
  2320. }
  2321. /* **************************************************************** */
  2322. /* ---------------------------------------------------------------- */
  2323. /* MODULE:          NODE FAILURE HANDLING ------------------------- */
  2324. /* ---------------------------------------------------------------- */
  2325. /*                                                                  */
  2326. /* This module contains the code that is used when nodes            */
  2327. /* (kernel/api) fails.                                              */
  2328. /* ---------------------------------------------------------------- */
  2329. /* **************************************************************** */
  2330. /* ---------------------------------------------------------------- */
  2331. // We receive a report of an API that failed.
  2332. /* ---------------------------------------------------------------- */
  2333. void Dbdict::execAPI_FAILREQ(Signal* signal) 
  2334. {
  2335.   jamEntry();
  2336.   Uint32 failedApiNode = signal->theData[0];
  2337.   BlockReference retRef = signal->theData[1];
  2338. #if 0
  2339.   Uint32 userNode = refToNode(c_connRecord.userBlockRef);
  2340.   if (userNode == failedApiNode) {
  2341.     jam();
  2342.     c_connRecord.userBlockRef = (Uint32)-1;
  2343.   }//if
  2344. #endif
  2345.   signal->theData[0] = failedApiNode;
  2346.   signal->theData[1] = reference();
  2347.   sendSignal(retRef, GSN_API_FAILCONF, signal, 2, JBB);
  2348. }//execAPI_FAILREQ()
  2349. /* ---------------------------------------------------------------- */
  2350. // We receive a report of one or more node failures of kernel nodes.
  2351. /* ---------------------------------------------------------------- */
  2352. void Dbdict::execNODE_FAILREP(Signal* signal) 
  2353. {
  2354.   jamEntry();
  2355.   NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
  2356.   c_failureNr    = nodeFail->failNo;
  2357.   const Uint32 numberOfFailedNodes  = nodeFail->noOfNodes;
  2358.   const bool masterFailed = (c_masterNodeId != nodeFail->masterNodeId);
  2359.   c_masterNodeId = nodeFail->masterNodeId;
  2360.   c_noNodesFailed += numberOfFailedNodes;
  2361.   Uint32 theFailedNodes[NodeBitmask::Size];
  2362.   memcpy(theFailedNodes, nodeFail->theNodes, sizeof(theFailedNodes));
  2363.   c_counterMgr.execNODE_FAILREP(signal);
  2364.   
  2365.   bool ok = false;
  2366.   switch(c_blockState){
  2367.   case BS_IDLE:
  2368.     jam();
  2369.     ok = true;
  2370.     if(c_opRecordPool.getSize() != c_opRecordPool.getNoOfFree()){
  2371.       jam();
  2372.       c_blockState = BS_NODE_FAILURE;
  2373.     }
  2374.     break;
  2375.   case BS_CREATE_TAB:
  2376.     jam();
  2377.     ok = true;
  2378.     if(!masterFailed)
  2379.       break;
  2380.     // fall through
  2381.   case BS_BUSY:
  2382.   case BS_NODE_FAILURE:
  2383.     jam();
  2384.     c_blockState = BS_NODE_FAILURE;
  2385.     ok = true;
  2386.     break;
  2387.   }
  2388.   ndbrequire(ok);
  2389.   
  2390.   for(unsigned i = 1; i < MAX_NDB_NODES; i++) {
  2391.     jam();
  2392.     if(NodeBitmask::get(theFailedNodes, i)) {
  2393.       jam();
  2394.       NodeRecordPtr nodePtr;
  2395.       c_nodes.getPtr(nodePtr, i);
  2396.       nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
  2397.       NFCompleteRep * const nfCompRep = (NFCompleteRep *)&signal->theData[0];
  2398.       nfCompRep->blockNo      = DBDICT;
  2399.       nfCompRep->nodeId       = getOwnNodeId();
  2400.       nfCompRep->failedNodeId = nodePtr.i;
  2401.       sendSignal(DBDIH_REF, GSN_NF_COMPLETEREP, signal, 
  2402.  NFCompleteRep::SignalLength, JBB);
  2403.       
  2404.       c_aliveNodes.clear(i);
  2405.     }//if
  2406.   }//for
  2407. }//execNODE_FAILREP()
  2408. /* **************************************************************** */
  2409. /* ---------------------------------------------------------------- */
  2410. /* MODULE:          NODE START HANDLING --------------------------- */
  2411. /* ---------------------------------------------------------------- */
  2412. /*                                                                  */
  2413. /* This module contains the code that is used when kernel nodes     */
  2414. /* starts.                                                          */
  2415. /* ---------------------------------------------------------------- */
  2416. /* **************************************************************** */
  2417. /* ---------------------------------------------------------------- */
  2418. // Include a starting node in list of nodes to be part of adding
  2419. // and dropping tables.
  2420. /* ---------------------------------------------------------------- */
  2421. void Dbdict::execINCL_NODEREQ(Signal* signal) 
  2422. {
  2423.   jamEntry();
  2424.   NodeRecordPtr nodePtr;
  2425.   BlockReference retRef = signal->theData[0];
  2426.   nodePtr.i = signal->theData[1];
  2427.   ndbrequire(c_noNodesFailed > 0);
  2428.   c_noNodesFailed--;
  2429.   c_nodes.getPtr(nodePtr);
  2430.   ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD);
  2431.   nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
  2432.   signal->theData[0] = reference();
  2433.   sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB);
  2434.   c_aliveNodes.set(nodePtr.i);
  2435. }//execINCL_NODEREQ()
  2436. /* **************************************************************** */
  2437. /* ---------------------------------------------------------------- */
  2438. /* MODULE:          ADD TABLE HANDLING ---------------------------- */
  2439. /* ---------------------------------------------------------------- */
  2440. /*                                                                  */
  2441. /* This module contains the code that is used when adding a table.  */
  2442. /* ---------------------------------------------------------------- */
  2443. /* **************************************************************** */
  2444. /* ---------------------------------------------------------------- */
  2445. // This signal receives information about a table from either:
  2446. // API, Ndbcntr or from other DICT.
  2447. /* ---------------------------------------------------------------- */
  2448. void
  2449. Dbdict::execCREATE_TABLE_REQ(Signal* signal){
  2450.   jamEntry();
  2451.   if(!assembleFragments(signal)){
  2452.     return;
  2453.   }
  2454.   
  2455.   CreateTableReq* const req = (CreateTableReq*)signal->getDataPtr();
  2456.   const Uint32 senderRef = req->senderRef;
  2457.   const Uint32 senderData = req->senderData;
  2458.   
  2459.   ParseDictTabInfoRecord parseRecord;
  2460.   do {
  2461.     if(getOwnNodeId() != c_masterNodeId){
  2462.       jam();
  2463.       parseRecord.errorCode = CreateTableRef::NotMaster;
  2464.       break;
  2465.     }
  2466.     
  2467.     if (c_blockState != BS_IDLE){
  2468.       jam();
  2469.       parseRecord.errorCode = CreateTableRef::Busy;
  2470.       break;
  2471.     }
  2472.     CreateTableRecordPtr createTabPtr;
  2473.     c_opCreateTable.seize(createTabPtr);
  2474.     
  2475.     if(createTabPtr.isNull()){
  2476.       jam();
  2477.       parseRecord.errorCode = CreateTableRef::Busy;
  2478.       break;
  2479.     }
  2480.     
  2481.     parseRecord.requestType = DictTabInfo::CreateTableFromAPI;
  2482.     parseRecord.errorCode = 0;
  2483.     
  2484.     SegmentedSectionPtr ptr;
  2485.     signal->getSection(ptr, CreateTableReq::DICT_TAB_INFO);
  2486.     SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
  2487.     
  2488.     handleTabInfoInit(r, &parseRecord);
  2489.     releaseSections(signal);
  2490.     
  2491.     if(parseRecord.errorCode != 0){
  2492.       jam();
  2493.       c_opCreateTable.release(createTabPtr);
  2494.       break;
  2495.     }
  2496.     
  2497.     createTabPtr.p->key = ++c_opRecordSequence;
  2498.     c_opCreateTable.add(createTabPtr);
  2499.     createTabPtr.p->m_errorCode = 0;
  2500.     createTabPtr.p->m_senderRef = senderRef;
  2501.     createTabPtr.p->m_senderData = senderData;
  2502.     createTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
  2503.     createTabPtr.p->m_coordinatorRef = reference();
  2504.     createTabPtr.p->m_fragmentsPtrI = RNIL;
  2505.     createTabPtr.p->m_dihAddFragPtr = RNIL;
  2506.     Uint32 * theData = signal->getDataPtrSend();
  2507.     CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
  2508.     req->senderRef = reference();
  2509.     req->senderData = createTabPtr.p->key;
  2510.     req->fragmentationType = parseRecord.tablePtr.p->fragmentType;
  2511.     req->noOfFragments = 0;
  2512.     req->fragmentNode = 0;
  2513.     req->primaryTableId = RNIL;
  2514.     if (parseRecord.tablePtr.p->isOrderedIndex()) {
  2515.       // ordered index has same fragmentation as the table
  2516.       const Uint32 primaryTableId = parseRecord.tablePtr.p->primaryTableId;
  2517.       TableRecordPtr primaryTablePtr;
  2518.       c_tableRecordPool.getPtr(primaryTablePtr, primaryTableId);
  2519.       // fragmentationType must be consistent
  2520.       req->fragmentationType = primaryTablePtr.p->fragmentType;
  2521.       req->primaryTableId = primaryTableId;
  2522.     }
  2523.     sendSignal(DBDIH_REF, GSN_CREATE_FRAGMENTATION_REQ, signal,
  2524.        CreateFragmentationReq::SignalLength, JBB);
  2525.     
  2526.     c_blockState = BS_CREATE_TAB;
  2527.     return;
  2528.   } while(0);
  2529.   
  2530.   /**
  2531.    * Something went wrong
  2532.    */
  2533.   releaseSections(signal);
  2534.   CreateTableRef * ref = (CreateTableRef*)signal->getDataPtrSend();
  2535.   ref->senderData = senderData;
  2536.   ref->senderRef = reference();
  2537.   ref->masterNodeId = c_masterNodeId;
  2538.   ref->errorCode = parseRecord.errorCode;
  2539.   ref->errorLine = parseRecord.errorLine;
  2540.   ref->errorKey = parseRecord.errorKey;
  2541.   ref->status = parseRecord.status;
  2542.   sendSignal(senderRef, GSN_CREATE_TABLE_REF, signal, 
  2543.      CreateTableRef::SignalLength, JBB);
  2544. }
  2545. void
  2546. Dbdict::execBACKUP_FRAGMENT_REQ(Signal* signal)
  2547. {
  2548.   jamEntry();
  2549.   Uint32 tableId = signal->theData[0];
  2550.   Uint32 lock = signal->theData[1];
  2551.   TableRecordPtr tablePtr;
  2552.   c_tableRecordPool.getPtr(tablePtr, tableId, true);
  2553.   if(lock)
  2554.   {
  2555.     ndbrequire(tablePtr.p->tabState == TableRecord::DEFINED);
  2556.     tablePtr.p->tabState = TableRecord::BACKUP_ONGOING;
  2557.   }
  2558.   else if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
  2559.   {
  2560.     tablePtr.p->tabState = TableRecord::DEFINED;
  2561.   }
  2562. }
  2563. bool
  2564. Dbdict::check_ndb_versions() const
  2565. {
  2566.   Uint32 node = 0;
  2567.   Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
  2568.   while((node = c_aliveNodes.find(node + 1)) != BitmaskImpl::NotFound)
  2569.   {
  2570.     if(getNodeInfo(node).m_version != version)
  2571.     {
  2572.       return false;
  2573.     }
  2574.   }
  2575.   return true;
  2576. }
  2577. void
  2578. Dbdict::execALTER_TABLE_REQ(Signal* signal)
  2579. {
  2580.   // Received by master
  2581.   jamEntry();
  2582.   if(!assembleFragments(signal)){
  2583.     return;
  2584.   }
  2585.   AlterTableReq* const req = (AlterTableReq*)signal->getDataPtr();
  2586.   const Uint32 senderRef = req->senderRef;
  2587.   const Uint32 senderData = req->senderData;
  2588.   const Uint32 changeMask = req->changeMask;
  2589.   const Uint32 tableId = req->tableId;
  2590.   const Uint32 tableVersion = req->tableVersion;
  2591.   ParseDictTabInfoRecord* aParseRecord;
  2592.   
  2593.   // Get table definition
  2594.   TableRecordPtr tablePtr;
  2595.   c_tableRecordPool.getPtr(tablePtr, tableId, false);
  2596.   if(tablePtr.isNull()){
  2597.     jam();
  2598.     alterTableRef(signal, req, AlterTableRef::NoSuchTable);
  2599.     return;
  2600.   }
  2601.   
  2602.   if(getOwnNodeId() != c_masterNodeId){
  2603.     jam();
  2604.     alterTableRef(signal, req, AlterTableRef::NotMaster);
  2605.     return;
  2606.   }
  2607.   
  2608.   if(c_blockState != BS_IDLE){
  2609.     jam();
  2610.     alterTableRef(signal, req, AlterTableRef::Busy);
  2611.     return;
  2612.   }
  2613.   if (!check_ndb_versions())
  2614.   {
  2615.     jam();
  2616.     alterTableRef(signal, req, AlterTableRef::IncompatibleVersions);
  2617.     return;
  2618.   }
  2619.   
  2620.   const TableRecord::TabState tabState = tablePtr.p->tabState;
  2621.   bool ok = false;
  2622.   switch(tabState){
  2623.   case TableRecord::NOT_DEFINED:
  2624.   case TableRecord::REORG_TABLE_PREPARED:
  2625.   case TableRecord::DEFINING:
  2626.   case TableRecord::CHECKED:
  2627.     jam();
  2628.     alterTableRef(signal, req, AlterTableRef::NoSuchTable);
  2629.     return;
  2630.   case TableRecord::DEFINED:
  2631.     ok = true;
  2632.     jam();
  2633.     break;
  2634.   case TableRecord::BACKUP_ONGOING:
  2635.     jam();
  2636.     alterTableRef(signal, req, AlterTableRef::BackupInProgress);
  2637.     return;
  2638.   case TableRecord::PREPARE_DROPPING:
  2639.   case TableRecord::DROPPING:
  2640.     jam();
  2641.     alterTableRef(signal, req, AlterTableRef::DropInProgress);
  2642.     return;
  2643.   }
  2644.   ndbrequire(ok);
  2645.   if(tablePtr.p->tableVersion != tableVersion){
  2646.     jam();
  2647.     alterTableRef(signal, req, AlterTableRef::InvalidTableVersion);
  2648.     return;
  2649.   }
  2650.   // Parse new table defintion
  2651.   ParseDictTabInfoRecord parseRecord;
  2652.   aParseRecord = &parseRecord;
  2653.     
  2654.   CreateTableRecordPtr alterTabPtr; // Reuse create table records
  2655.   c_opCreateTable.seize(alterTabPtr);
  2656.   
  2657.   if(alterTabPtr.isNull()){
  2658.     jam();
  2659.     alterTableRef(signal, req, AlterTableRef::Busy);
  2660.     return;
  2661.   }
  2662.   alterTabPtr.p->m_changeMask = changeMask;
  2663.   parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
  2664.   parseRecord.errorCode = 0;
  2665.   
  2666.   SegmentedSectionPtr ptr;
  2667.   signal->getSection(ptr, AlterTableReq::DICT_TAB_INFO);
  2668.   SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
  2669.   handleTabInfoInit(r, &parseRecord, false); // Will not save info
  2670.   
  2671.   if(parseRecord.errorCode != 0){
  2672.     jam();
  2673.     c_opCreateTable.release(alterTabPtr);
  2674.     alterTableRef(signal, req, 
  2675.   (AlterTableRef::ErrorCode) parseRecord.errorCode, 
  2676.   aParseRecord);
  2677.     return;
  2678.   }
  2679.   
  2680.   releaseSections(signal);
  2681.   alterTabPtr.p->key = ++c_opRecordSequence;
  2682.   c_opCreateTable.add(alterTabPtr);
  2683.   ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
  2684.   alterTabPtr.p->m_errorCode = 0;
  2685.   alterTabPtr.p->m_senderRef = senderRef;
  2686.   alterTabPtr.p->m_senderData = senderData;
  2687.   alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
  2688.   alterTabPtr.p->m_alterTableFailed = false;
  2689.   alterTabPtr.p->m_coordinatorRef = reference();
  2690.   alterTabPtr.p->m_fragmentsPtrI = RNIL;
  2691.   alterTabPtr.p->m_dihAddFragPtr = RNIL;
  2692.   alterTabPtr.p->m_alterTableId = tablePtr.p->tableId;
  2693.   // Send prepare request to all alive nodes
  2694.   SimplePropertiesSectionWriter w(getSectionSegmentPool());
  2695.   packTableIntoPagesImpl(w, parseRecord.tablePtr);
  2696.   
  2697.   SegmentedSectionPtr tabInfoPtr;
  2698.   w.getPtr(tabInfoPtr);
  2699.   
  2700.   alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
  2701.   // Alter table on all nodes
  2702.   c_blockState = BS_BUSY;
  2703.   Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
  2704.   Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked),
  2705.  alterTabPtr.p->key };
  2706.   
  2707.   ndbrequire(mutex.lock(c));
  2708. }
  2709. void
  2710. Dbdict::alterTable_backup_mutex_locked(Signal* signal,
  2711.        Uint32 callbackData,
  2712.        Uint32 retValue)
  2713. {
  2714.   jamEntry();
  2715.   
  2716.   ndbrequire(retValue == 0);
  2717.   
  2718.   CreateTableRecordPtr alterTabPtr;
  2719.   ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
  2720.   TableRecordPtr tablePtr;
  2721.   c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId, true);
  2722.   Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
  2723.   mutex.unlock(); // ignore response
  2724.   SegmentedSectionPtr tabInfoPtr;
  2725.   getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
  2726.   signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
  2727.   
  2728.   alterTabPtr.p->m_tabInfoPtrI = RNIL;
  2729.   
  2730.   if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
  2731.   {
  2732.     jam();
  2733.     AlterTableReq* req = (AlterTableReq*)signal->getDataPtr();
  2734.     req->senderData = alterTabPtr.p->m_senderData;
  2735.     req->senderRef = alterTabPtr.p->m_senderRef;
  2736.     alterTableRef(signal, req, AlterTableRef::BackupInProgress);
  2737.     c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_tablePtrI);  
  2738.     releaseTableObject(tablePtr.i, false);
  2739.     c_opCreateTable.release(alterTabPtr);
  2740.     c_blockState = BS_IDLE;
  2741.     return;
  2742.   }
  2743.   
  2744.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2745.   alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
  2746.   SafeCounter safeCounter(c_counterMgr, 
  2747.   alterTabPtr.p->m_coordinatorData.m_counter);
  2748.   safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
  2749.   AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
  2750.   lreq->senderRef = reference();
  2751.   lreq->senderData = alterTabPtr.p->key;
  2752.   lreq->clientRef = alterTabPtr.p->m_senderRef;
  2753.   lreq->clientData = alterTabPtr.p->m_senderData;
  2754.   lreq->changeMask = alterTabPtr.p->m_changeMask;
  2755.   lreq->tableId = tablePtr.p->tableId;
  2756.   lreq->tableVersion = alter_table_inc_schema_version(tablePtr.p->tableVersion);
  2757.   lreq->gci = tablePtr.p->gciTableCreated;
  2758.   lreq->requestType = AlterTabReq::AlterTablePrepare;
  2759.   
  2760.   sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 
  2761.        AlterTabReq::SignalLength, JBB);
  2762. }
  2763. void Dbdict::alterTableRef(Signal * signal, 
  2764.    AlterTableReq * req, 
  2765.    AlterTableRef::ErrorCode errCode,
  2766.    ParseDictTabInfoRecord* parseRecord)
  2767. {
  2768.   jam();
  2769.   releaseSections(signal);
  2770.   AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend();
  2771.   Uint32 senderRef = req->senderRef;
  2772.   ref->senderData = req->senderData;
  2773.   ref->senderRef = reference();
  2774.   ref->masterNodeId = c_masterNodeId;
  2775.   if (parseRecord) {
  2776.     ref->errorCode = parseRecord->errorCode;
  2777.     ref->errorLine = parseRecord->errorLine;
  2778.     ref->errorKey = parseRecord->errorKey;
  2779.     ref->status = parseRecord->status;
  2780.   }
  2781.   else {
  2782.     ref->errorCode = errCode;
  2783.     ref->errorLine = 0;
  2784.     ref->errorKey = 0;
  2785.     ref->status = 0;
  2786.   }
  2787.   sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal, 
  2788.      AlterTableRef::SignalLength, JBB);
  2789. }
  2790. void
  2791. Dbdict::execALTER_TAB_REQ(Signal * signal) 
  2792. {
  2793.   // Received in all nodes to handle change locally
  2794.   jamEntry();
  2795.   if(!assembleFragments(signal)){
  2796.     return;
  2797.   }
  2798.   AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
  2799.   const Uint32 senderRef = req->senderRef;
  2800.   const Uint32 senderData = req->senderData;
  2801.   const Uint32 changeMask = req->changeMask;
  2802.   const Uint32 tableId = req->tableId;
  2803.   const Uint32 tableVersion = req->tableVersion;
  2804.   const Uint32 gci = req->gci;
  2805.   AlterTabReq::RequestType requestType = 
  2806.     (AlterTabReq::RequestType) req->requestType;
  2807.   SegmentedSectionPtr tabInfoPtr;
  2808.   signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
  2809.   CreateTableRecordPtr alterTabPtr; // Reuse create table records
  2810.   if (senderRef != reference()) {
  2811.     jam();
  2812.     c_blockState = BS_BUSY;
  2813.   }
  2814.   if ((requestType == AlterTabReq::AlterTablePrepare)
  2815.       && (senderRef != reference())) {
  2816.     jam();
  2817.     c_opCreateTable.seize(alterTabPtr);
  2818.     if(!alterTabPtr.isNull())
  2819.       alterTabPtr.p->m_changeMask = changeMask;
  2820.   }
  2821.   else {
  2822.     jam();
  2823.     ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
  2824.   }
  2825.   if(alterTabPtr.isNull()){
  2826.     jam();
  2827.     alterTabRef(signal, req, AlterTableRef::Busy);
  2828.     return;
  2829.   }
  2830.   if (!check_ndb_versions())
  2831.   {
  2832.     jam();
  2833.     alterTabRef(signal, req, AlterTableRef::IncompatibleVersions);
  2834.     return;
  2835.   }
  2836.   alterTabPtr.p->m_alterTableId = tableId;
  2837.   alterTabPtr.p->m_coordinatorRef = senderRef;
  2838.   
  2839.   // Get table definition
  2840.   TableRecordPtr tablePtr;
  2841.   c_tableRecordPool.getPtr(tablePtr, tableId, false);
  2842.   if(tablePtr.isNull()){
  2843.     jam();
  2844.     alterTabRef(signal, req, AlterTableRef::NoSuchTable);
  2845.     return;
  2846.   }
  2847.     
  2848.   switch(requestType) {
  2849.   case(AlterTabReq::AlterTablePrepare): {
  2850.     ParseDictTabInfoRecord* aParseRecord;
  2851.   
  2852.     const TableRecord::TabState tabState = tablePtr.p->tabState;
  2853.     bool ok = false;
  2854.     switch(tabState){
  2855.     case TableRecord::NOT_DEFINED:
  2856.     case TableRecord::REORG_TABLE_PREPARED:
  2857.     case TableRecord::DEFINING:
  2858.     case TableRecord::CHECKED:
  2859.       jam();
  2860.       alterTabRef(signal, req, AlterTableRef::NoSuchTable);
  2861.       return;
  2862.     case TableRecord::DEFINED:
  2863.       ok = true;
  2864.       jam();
  2865.       break;
  2866.     case TableRecord::PREPARE_DROPPING:
  2867.     case TableRecord::DROPPING:
  2868.       jam();
  2869.       alterTabRef(signal, req, AlterTableRef::DropInProgress);
  2870.       return;
  2871.     case TableRecord::BACKUP_ONGOING:
  2872.       jam();
  2873.       alterTabRef(signal, req, AlterTableRef::BackupInProgress);
  2874.       return;
  2875.     }
  2876.     ndbrequire(ok);
  2877.     if(alter_table_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){
  2878.       jam();
  2879.       alterTabRef(signal, req, AlterTableRef::InvalidTableVersion);
  2880.       return;
  2881.     }
  2882.     TableRecordPtr newTablePtr;
  2883.     if (senderRef  != reference()) {
  2884.       jam();
  2885.       // Parse altered table defintion
  2886.       ParseDictTabInfoRecord parseRecord;
  2887.       aParseRecord = &parseRecord;
  2888.       
  2889.       parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
  2890.       parseRecord.errorCode = 0;
  2891.       
  2892.       SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
  2893.       
  2894.       handleTabInfoInit(r, &parseRecord, false); // Will not save info
  2895.       
  2896.       if(parseRecord.errorCode != 0){
  2897. jam();
  2898. c_opCreateTable.release(alterTabPtr);
  2899. alterTabRef(signal, req, 
  2900.     (AlterTableRef::ErrorCode) parseRecord.errorCode, 
  2901.     aParseRecord);
  2902. return;
  2903.       }
  2904.       alterTabPtr.p->key = senderData;
  2905.       c_opCreateTable.add(alterTabPtr);
  2906.       alterTabPtr.p->m_errorCode = 0;
  2907.       alterTabPtr.p->m_senderRef = senderRef;
  2908.       alterTabPtr.p->m_senderData = senderData;
  2909.       alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
  2910.       alterTabPtr.p->m_fragmentsPtrI = RNIL;
  2911.       alterTabPtr.p->m_dihAddFragPtr = RNIL;
  2912.       newTablePtr = parseRecord.tablePtr;
  2913.       newTablePtr.p->tableVersion = tableVersion;
  2914.     }
  2915.     else { // (req->senderRef  == reference())
  2916.       jam();
  2917.       c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
  2918.       newTablePtr.p->tableVersion = tableVersion;
  2919.     }
  2920.     if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) {
  2921.       jam();
  2922.       c_opCreateTable.release(alterTabPtr);
  2923.       alterTabRef(signal, req, AlterTableRef::UnsupportedChange);
  2924.       return;
  2925.     }
  2926.     releaseSections(signal);
  2927.     // Propagate alter table to other local blocks
  2928.     AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
  2929.     req->senderRef = reference();
  2930.     req->senderData = senderData;
  2931.     req->changeMask = changeMask;
  2932.     req->tableId = tableId;
  2933.     req->tableVersion = tableVersion;
  2934.     req->gci = gci;
  2935.     req->requestType = requestType;
  2936.     sendSignal(DBLQH_REF, GSN_ALTER_TAB_REQ, signal, 
  2937.        AlterTabReq::SignalLength, JBB);
  2938.     return;
  2939.   }
  2940.   case(AlterTabReq::AlterTableCommit): {
  2941.     jam();
  2942.     // Write schema for altered table to disk
  2943.     SegmentedSectionPtr tabInfoPtr;
  2944.     signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
  2945.     alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
  2946.     
  2947.     signal->header.m_noOfSections = 0;
  2948.     // Update table record
  2949.     tablePtr.p->packedSize = tabInfoPtr.sz;
  2950.     tablePtr.p->tableVersion = tableVersion;
  2951.     tablePtr.p->gciTableCreated = gci;
  2952.     SchemaFile::TableEntry tabEntry;
  2953.     tabEntry.m_tableVersion = tableVersion;
  2954.     tabEntry.m_tableType    = tablePtr.p->tableType;
  2955.     tabEntry.m_tableState   = SchemaFile::ALTER_TABLE_COMMITTED;
  2956.     tabEntry.m_gcp          = gci;
  2957.     tabEntry.m_noOfPages    = 
  2958.       DIV(tabInfoPtr.sz + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
  2959.     
  2960.     Callback callback;
  2961.     callback.m_callbackData = senderData;
  2962.     callback.m_callbackFunction = 
  2963.       safe_cast(&Dbdict::alterTab_writeSchemaConf);
  2964.     
  2965.     updateSchemaState(signal, tableId, &tabEntry, &callback);
  2966.     break;
  2967.   }
  2968.   case(AlterTabReq::AlterTableRevert): {
  2969.     jam();
  2970.     // Revert failed alter table
  2971.     revertAlterTable(signal, changeMask, tableId, alterTabPtr.p);
  2972.     // Acknowledge the reverted alter table
  2973.     AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
  2974.     conf->senderRef = reference();
  2975.     conf->senderData = senderData;
  2976.     conf->changeMask = changeMask;
  2977.     conf->tableId = tableId;
  2978.     conf->tableVersion = tableVersion;
  2979.     conf->gci = gci;
  2980.     conf->requestType = requestType;
  2981.     sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal, 
  2982.        AlterTabConf::SignalLength, JBB);
  2983.     break;
  2984.   }
  2985.   default: ndbrequire(false);
  2986.   }
  2987. }
  2988. void Dbdict::alterTabRef(Signal * signal, 
  2989.  AlterTabReq * req, 
  2990.  AlterTableRef::ErrorCode errCode,
  2991.  ParseDictTabInfoRecord* parseRecord)
  2992. {
  2993.   jam();
  2994.   releaseSections(signal);
  2995.   AlterTabRef * ref = (AlterTabRef*)signal->getDataPtrSend();
  2996.   Uint32 senderRef = req->senderRef;
  2997.   ref->senderData = req->senderData;
  2998.   ref->senderRef = reference();
  2999.   if (parseRecord) {
  3000.     jam();
  3001.     ref->errorCode = parseRecord->errorCode;
  3002.     ref->errorLine = parseRecord->errorLine;
  3003.     ref->errorKey = parseRecord->errorKey;
  3004.     ref->errorStatus = parseRecord->status;
  3005.   }
  3006.   else {
  3007.     jam();
  3008.     ref->errorCode = errCode;
  3009.     ref->errorLine = 0;
  3010.     ref->errorKey = 0;
  3011.     ref->errorStatus = 0;
  3012.   }
  3013.   sendSignal(senderRef, GSN_ALTER_TAB_REF, signal, 
  3014.      AlterTabRef::SignalLength, JBB);
  3015.   
  3016.   c_blockState = BS_IDLE;
  3017. }
  3018. void Dbdict::execALTER_TAB_REF(Signal * signal){
  3019.   jamEntry();
  3020.   AlterTabRef * ref = (AlterTabRef*)signal->getDataPtr();
  3021.   Uint32 senderRef = ref->senderRef;
  3022.   Uint32 senderData = ref->senderData;
  3023.   Uint32 errorCode = ref->errorCode;
  3024.   Uint32 errorLine = ref->errorLine;
  3025.   Uint32 errorKey = ref->errorKey;
  3026.   Uint32 errorStatus = ref->errorStatus;
  3027.   AlterTabReq::RequestType requestType = 
  3028.     (AlterTabReq::RequestType) ref->requestType;
  3029.   CreateTableRecordPtr alterTabPtr;  
  3030.   ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
  3031.   Uint32 changeMask = alterTabPtr.p->m_changeMask;
  3032.   SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
  3033.   safeCounter.clearWaitingFor(refToNode(senderRef));
  3034.   switch (requestType) {
  3035.   case(AlterTabReq::AlterTablePrepare): {
  3036.     if (safeCounter.done()) {
  3037.       jam();
  3038.       // Send revert request to all alive nodes
  3039.       TableRecordPtr tablePtr;
  3040.       c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
  3041.       Uint32 tableId = tablePtr.p->tableId;
  3042.       Uint32 tableVersion = tablePtr.p->tableVersion;
  3043.       Uint32 gci = tablePtr.p->gciTableCreated;
  3044.       SimplePropertiesSectionWriter w(getSectionSegmentPool());
  3045.       packTableIntoPagesImpl(w, tablePtr);
  3046.       SegmentedSectionPtr spDataPtr;
  3047.       w.getPtr(spDataPtr);
  3048.       signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
  3049.       
  3050.       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  3051.       alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
  3052.       safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
  3053.   
  3054.       AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
  3055.       lreq->senderRef = reference();
  3056.       lreq->senderData = alterTabPtr.p->key;
  3057.       lreq->clientRef = alterTabPtr.p->m_senderRef;
  3058.       lreq->clientData = alterTabPtr.p->m_senderData;
  3059.       lreq->changeMask = changeMask;
  3060.       lreq->tableId = tableId;
  3061.       lreq->tableVersion = tableVersion;
  3062.       lreq->gci = gci;
  3063.       lreq->requestType = AlterTabReq::AlterTableRevert;
  3064.       
  3065.       sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 
  3066.  AlterTabReq::SignalLength, JBB);
  3067.     }
  3068.     else {
  3069.       jam();
  3070.       alterTabPtr.p->m_alterTableFailed = true;
  3071.     }
  3072.     break;
  3073.   }
  3074.   case(AlterTabReq::AlterTableCommit):
  3075.     jam();
  3076.   case(AlterTabReq::AlterTableRevert): {
  3077.     AlterTableRef * apiRef = (AlterTableRef*)signal->getDataPtrSend();
  3078.     
  3079.     apiRef->senderData = senderData;
  3080.     apiRef->senderRef = reference();
  3081.     apiRef->masterNodeId = c_masterNodeId;
  3082.     apiRef->errorCode = errorCode;
  3083.     apiRef->errorLine = errorLine;
  3084.     apiRef->errorKey = errorKey;
  3085.     apiRef->status = errorStatus;
  3086.     if (safeCounter.done()) {
  3087.       jam();
  3088.       sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal, 
  3089.  AlterTableRef::SignalLength, JBB);
  3090.       c_blockState = BS_IDLE;
  3091.     }
  3092.     else {
  3093.       jam();
  3094.       alterTabPtr.p->m_alterTableFailed = true;
  3095.       alterTabPtr.p->m_alterTableRef = *apiRef;
  3096.     }
  3097.     break;
  3098.   } 
  3099.   default: ndbrequire(false);
  3100.   }
  3101. }
  3102. void
  3103. Dbdict::execALTER_TAB_CONF(Signal * signal){
  3104.   jamEntry();
  3105.   AlterTabConf * const conf = (AlterTabConf*)signal->getDataPtr();
  3106.   Uint32 senderRef = conf->senderRef;
  3107.   Uint32 senderData = conf->senderData;
  3108.   Uint32 changeMask = conf->changeMask;
  3109.   Uint32 tableId = conf->tableId;
  3110.   Uint32 tableVersion = conf->tableVersion;
  3111.   Uint32 gci = conf->gci;
  3112.   AlterTabReq::RequestType requestType = 
  3113.     (AlterTabReq::RequestType) conf->requestType;
  3114.   CreateTableRecordPtr alterTabPtr;  
  3115.   ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
  3116.   switch (requestType) {
  3117.   case(AlterTabReq::AlterTablePrepare): {
  3118.     switch(refToBlock(signal->getSendersBlockRef())) {
  3119.     case DBLQH: {
  3120.       jam();
  3121.       AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
  3122.       req->senderRef = reference();
  3123.       req->senderData = senderData;
  3124.       req->changeMask = changeMask;
  3125.       req->tableId = tableId;
  3126.       req->tableVersion = tableVersion;
  3127.       req->gci = gci;
  3128.       req->requestType = requestType;
  3129.       sendSignal(DBDIH_REF, GSN_ALTER_TAB_REQ, signal, 
  3130.  AlterTabReq::SignalLength, JBB);
  3131.       return;
  3132.     }
  3133.     case DBDIH: {
  3134.       jam();
  3135.       AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
  3136.       req->senderRef = reference();
  3137.       req->senderData = senderData;
  3138.       req->changeMask = changeMask;
  3139.       req->tableId = tableId;
  3140.       req->tableVersion = tableVersion;
  3141.       req->gci = gci;
  3142.       req->requestType = requestType;
  3143.       sendSignal(DBTC_REF, GSN_ALTER_TAB_REQ, signal, 
  3144.  AlterTabReq::SignalLength, JBB);
  3145.       return;
  3146.     }
  3147.     case DBTC: {
  3148.       jam();
  3149.       // Participant is done with prepare phase, send conf to coordinator
  3150.       AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
  3151.       conf->senderRef = reference();
  3152.       conf->senderData = senderData;
  3153.       conf->changeMask = changeMask;
  3154.       conf->tableId = tableId;
  3155.       conf->tableVersion = tableVersion;
  3156.       conf->gci = gci;
  3157.       conf->requestType = requestType;
  3158.       sendSignal(alterTabPtr.p->m_coordinatorRef, GSN_ALTER_TAB_CONF, signal, 
  3159.  AlterTabConf::SignalLength, JBB);
  3160.       return;
  3161.     }
  3162.     default :break;
  3163.     }
  3164.     // Coordinator only
  3165.     SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
  3166.     safeCounter.clearWaitingFor(refToNode(senderRef));
  3167.     if (safeCounter.done()) {
  3168.       jam();
  3169.       // We have received all local confirmations
  3170.       if (alterTabPtr.p->m_alterTableFailed) {
  3171. jam();
  3172. // Send revert request to all alive nodes
  3173. TableRecordPtr tablePtr;
  3174. c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
  3175. Uint32 tableId = tablePtr.p->tableId;
  3176. Uint32 tableVersion = tablePtr.p->tableVersion;
  3177. Uint32 gci = tablePtr.p->gciTableCreated;
  3178. SimplePropertiesSectionWriter w(getSectionSegmentPool());
  3179. packTableIntoPagesImpl(w, tablePtr);
  3180. SegmentedSectionPtr spDataPtr;
  3181. w.getPtr(spDataPtr);
  3182. signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
  3183. NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  3184. alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
  3185. safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
  3186. AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
  3187. lreq->senderRef = reference();
  3188. lreq->senderData = alterTabPtr.p->key;
  3189. lreq->clientRef = alterTabPtr.p->m_senderRef;
  3190. lreq->clientData = alterTabPtr.p->m_senderData;
  3191. lreq->changeMask = changeMask;
  3192. lreq->tableId = tableId;
  3193. lreq->tableVersion = tableVersion;
  3194. lreq->gci = gci;
  3195. lreq->requestType = AlterTabReq::AlterTableRevert;
  3196. sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 
  3197.    AlterTabReq::SignalLength, JBB);
  3198.       }
  3199.       else {
  3200. jam();
  3201. // Send commit request to all alive nodes
  3202. TableRecordPtr tablePtr;
  3203. c_tableRecordPool.getPtr(tablePtr, tableId);
  3204. SimplePropertiesSectionWriter w(getSectionSegmentPool());
  3205. packTableIntoPagesImpl(w, tablePtr);
  3206. SegmentedSectionPtr spDataPtr;
  3207. w.getPtr(spDataPtr);
  3208. signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
  3209. NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  3210. alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
  3211. safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
  3212.   
  3213. AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
  3214. lreq->senderRef = reference();
  3215. lreq->senderData = alterTabPtr.p->key;
  3216. lreq->clientRef = alterTabPtr.p->m_senderRef;
  3217. lreq->clientData = alterTabPtr.p->m_senderData;
  3218. lreq->changeMask = changeMask;
  3219. lreq->tableId = tableId;
  3220. lreq->tableVersion = tableVersion;
  3221. lreq->gci = gci;
  3222. lreq->requestType = AlterTabReq::AlterTableCommit;
  3223. sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 
  3224.      AlterTabReq::SignalLength, JBB);
  3225.       }
  3226.     }
  3227.     else {
  3228.       // (!safeCounter.done())
  3229.       jam();
  3230.     }
  3231.     break;
  3232.   }
  3233.   case(AlterTabReq::AlterTableRevert):
  3234.     jam();
  3235.   case(AlterTabReq::AlterTableCommit): {
  3236.     SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
  3237.     safeCounter.clearWaitingFor(refToNode(senderRef));
  3238.     if (safeCounter.done()) {
  3239.       jam();
  3240.       // We have received all local confirmations
  3241.       releaseSections(signal);
  3242.       if (alterTabPtr.p->m_alterTableFailed) {
  3243. jam();
  3244. AlterTableRef * apiRef = 
  3245.   (AlterTableRef*)signal->getDataPtrSend();
  3246. *apiRef = alterTabPtr.p->m_alterTableRef;
  3247. sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal, 
  3248.    AlterTableRef::SignalLength, JBB);
  3249.       }
  3250.       else {
  3251. jam();
  3252. // Alter table completed, inform API
  3253. AlterTableConf * const apiConf = 
  3254.   (AlterTableConf*)signal->getDataPtrSend();
  3255. apiConf->senderRef = reference();
  3256. apiConf->senderData = alterTabPtr.p->m_senderData;
  3257. apiConf->tableId = tableId;
  3258. apiConf->tableVersion = tableVersion;
  3259. //@todo check api failed
  3260. sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_CONF, signal,
  3261.    AlterTableConf::SignalLength, JBB);
  3262.       }
  3263.       
  3264.       // Release resources
  3265.       TableRecordPtr tabPtr;
  3266.       c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);  
  3267.       releaseTableObject(tabPtr.i, false);
  3268.       c_opCreateTable.release(alterTabPtr);
  3269.       c_blockState = BS_IDLE;
  3270.     }
  3271.     else {
  3272.       // (!safeCounter.done())
  3273.       jam();
  3274.     }
  3275.     break;
  3276.   }
  3277.   default: ndbrequire(false);
  3278.   }
  3279. }
  3280. // For debugging
  3281. inline
  3282. void Dbdict::printTables()
  3283. {
  3284.   DLHashTable<TableRecord>::Iterator iter;
  3285.   bool moreTables = c_tableRecordHash.first(iter);
  3286.   printf("TABLES IN DICT:n");
  3287.   while (moreTables) {
  3288.     TableRecordPtr tablePtr = iter.curr;
  3289.     printf("%s ", tablePtr.p->tableName);
  3290.     moreTables = c_tableRecordHash.next(iter);
  3291.   }
  3292.   printf("n");
  3293. }
  3294. int Dbdict::handleAlterTab(AlterTabReq * req,
  3295.    CreateTableRecord * alterTabPtrP,
  3296.    TableRecordPtr origTablePtr,
  3297.    TableRecordPtr newTablePtr)
  3298. {
  3299.   Uint32 changeMask = req->changeMask;
  3300.   
  3301.   if (AlterTableReq::getNameFlag(changeMask)) {
  3302.     jam();
  3303.     // Table rename
  3304.     // Remove from hashtable
  3305. #ifdef VM_TRACE
  3306.     TableRecordPtr tmp;
  3307.     ndbrequire(c_tableRecordHash.find(tmp, *origTablePtr.p));
  3308. #endif
  3309.     c_tableRecordHash.remove(origTablePtr);
  3310.     strcpy(alterTabPtrP->previousTableName, origTablePtr.p->tableName);
  3311.     strcpy(origTablePtr.p->tableName, newTablePtr.p->tableName);
  3312.     // Set new schema version
  3313.     origTablePtr.p->tableVersion = newTablePtr.p->tableVersion;
  3314.     // Put it back
  3315. #ifdef VM_TRACE
  3316.     ndbrequire(!c_tableRecordHash.find(tmp, *origTablePtr.p));
  3317. #endif
  3318.     c_tableRecordHash.add(origTablePtr);  
  3319.     
  3320.     return 0;
  3321.   }
  3322.   jam();
  3323.   return -1;
  3324. }
  3325. void Dbdict::revertAlterTable(Signal * signal, 
  3326.       Uint32 changeMask, 
  3327.       Uint32 tableId,
  3328.       CreateTableRecord * alterTabPtrP)
  3329. {
  3330.   if (AlterTableReq::getNameFlag(changeMask)) {
  3331.     jam();
  3332.     // Table rename
  3333.     // Restore previous name
  3334.     TableRecordPtr tablePtr;
  3335.     c_tableRecordPool.getPtr(tablePtr, tableId);
  3336.     // Remove from hashtable
  3337. #ifdef VM_TRACE
  3338.     TableRecordPtr tmp;
  3339.     ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p));
  3340. #endif
  3341.     c_tableRecordHash.remove(tablePtr);
  3342.     // Restore name
  3343.     strcpy(tablePtr.p->tableName, alterTabPtrP->previousTableName);
  3344.     // Revert schema version
  3345.     tablePtr.p->tableVersion = alter_table_dec_schema_version(tablePtr.p->tableVersion);
  3346.     // Put it back
  3347. #ifdef VM_TRACE
  3348.     ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p));
  3349. #endif
  3350.     c_tableRecordHash.add(tablePtr);  
  3351.     return;
  3352.   }
  3353.   ndbrequire(false);
  3354. }
  3355. void
  3356. Dbdict::alterTab_writeSchemaConf(Signal* signal, 
  3357.  Uint32 callbackData,
  3358.  Uint32 returnCode)
  3359. {
  3360.   jam();
  3361.   Uint32 key = callbackData;
  3362.   CreateTableRecordPtr alterTabPtr;  
  3363.   ndbrequire(c_opCreateTable.find(alterTabPtr, key));
  3364.   Uint32 tableId = alterTabPtr.p->m_alterTableId;
  3365.   Callback callback;
  3366.   callback.m_callbackData = alterTabPtr.p->key;
  3367.   callback.m_callbackFunction = 
  3368.     safe_cast(&Dbdict::alterTab_writeTableConf);
  3369.   
  3370.   SegmentedSectionPtr tabInfoPtr;
  3371.   getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
  3372.   
  3373.   writeTableFile(signal, tableId, tabInfoPtr, &callback);
  3374.   signal->setSection(tabInfoPtr, 0);
  3375.   releaseSections(signal);
  3376. }
  3377. void
  3378. Dbdict::alterTab_writeTableConf(Signal* signal, 
  3379. Uint32 callbackData,
  3380. Uint32 returnCode)
  3381. {
  3382.   jam();
  3383.   CreateTableRecordPtr alterTabPtr;  
  3384.   ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
  3385.   Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef;
  3386.   TableRecordPtr tabPtr;
  3387.   c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId);
  3388.   // Alter table commit request handled successfully 
  3389.   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
  3390.   conf->senderRef = reference();
  3391.   conf->senderData = callbackData;
  3392.   conf->tableId = tabPtr.p->tableId;
  3393.   conf->tableVersion = tabPtr.p->tableVersion;
  3394.   conf->gci = tabPtr.p->gciTableCreated;
  3395.   conf->requestType = AlterTabReq::AlterTableCommit;
  3396.   sendSignal(coordinatorRef, GSN_ALTER_TAB_CONF, signal, 
  3397.        AlterTabConf::SignalLength, JBB);
  3398.   {
  3399.     ApiBroadcastRep* api= (ApiBroadcastRep*)signal->getDataPtrSend();
  3400.     api->gsn = GSN_ALTER_TABLE_REP;
  3401.     api->minVersion = MAKE_VERSION(4,1,15);
  3402.     AlterTableRep* rep = (AlterTableRep*)api->theData;
  3403.     rep->tableId = tabPtr.p->tableId;
  3404.     rep->tableVersion = alter_table_dec_schema_version(tabPtr.p->tableVersion);
  3405.     rep->changeType = AlterTableRep::CT_ALTERED;
  3406.     
  3407.     LinearSectionPtr ptr[3];
  3408.     ptr[0].p = (Uint32*)alterTabPtr.p->previousTableName;
  3409.     ptr[0].sz = (sizeof(alterTabPtr.p->previousTableName) + 3) >> 2;
  3410.     
  3411.     sendSignal(QMGR_REF, GSN_API_BROADCAST_REP, signal, 
  3412.        ApiBroadcastRep::SignalLength + AlterTableRep::SignalLength,
  3413.        JBB, ptr,1);
  3414.   }
  3415.   if(coordinatorRef != reference()) {
  3416.     jam();
  3417.     // Release resources
  3418.     c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);  
  3419.     releaseTableObject(tabPtr.i, false);
  3420.     c_opCreateTable.release(alterTabPtr);
  3421.     c_blockState = BS_IDLE;
  3422.   }
  3423. }
  3424. void
  3425. Dbdict::execCREATE_FRAGMENTATION_REF(Signal * signal){
  3426.   jamEntry();
  3427.   const Uint32 * theData = signal->getDataPtr();
  3428.   CreateFragmentationRef * const ref = (CreateFragmentationRef*)theData;
  3429.   (void)ref;
  3430.   ndbrequire(false);
  3431. }
  3432. void
  3433. Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){
  3434.   jamEntry();
  3435.   const Uint32 * theData = signal->getDataPtr();
  3436.   CreateFragmentationConf * const conf = (CreateFragmentationConf*)theData;
  3437.   CreateTableRecordPtr createTabPtr;
  3438.   ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
  3439.   ndbrequire(signal->getNoOfSections() == 1);
  3440.   SegmentedSectionPtr fragDataPtr;
  3441.   signal->getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS);
  3442.   signal->header.m_noOfSections = 0;
  3443.   /**
  3444.    * Get table
  3445.    */
  3446.   TableRecordPtr tabPtr;
  3447.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  3448.   /**
  3449.    * Save fragment count
  3450.    */
  3451.   tabPtr.p->fragmentCount = conf->noOfFragments;
  3452.   /**
  3453.    * Update table version
  3454.    */
  3455.   PageRecordPtr pagePtr;
  3456.   c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage);
  3457.   SchemaFile::TableEntry * tabEntry = getTableEntry(pagePtr.p, tabPtr.i);
  3458.   tabPtr.p->tableVersion = create_table_inc_schema_version(tabEntry->m_tableVersion);
  3459.   /**
  3460.    * Pack
  3461.    */
  3462.   SimplePropertiesSectionWriter w(getSectionSegmentPool());
  3463.   packTableIntoPagesImpl(w, tabPtr);
  3464.   
  3465.   SegmentedSectionPtr spDataPtr;
  3466.   w.getPtr(spDataPtr);
  3467.   
  3468.   signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO);
  3469.   signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION);
  3470.   
  3471.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  3472.   SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
  3473.   createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
  3474.   createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTablePrepare;
  3475.   tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
  3476.   
  3477.   CreateTabReq * const req = (CreateTabReq*)theData;
  3478.   req->senderRef = reference();
  3479.   req->senderData = createTabPtr.p->key;
  3480.   req->clientRef = createTabPtr.p->m_senderRef;
  3481.   req->clientData = createTabPtr.p->m_senderData;
  3482.   req->requestType = CreateTabReq::CreateTablePrepare;
  3483.   req->gci = 0;
  3484.   req->tableId = tabPtr.i;
  3485.   req->tableVersion = create_table_inc_schema_version(tabEntry->m_tableVersion);
  3486.   
  3487.   sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal, 
  3488.        CreateTabReq::SignalLength, JBB);
  3489.   return;
  3490. }
  3491. void
  3492. Dbdict::execCREATE_TAB_REF(Signal* signal){
  3493.   jamEntry();
  3494.   CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
  3495.   
  3496.   CreateTableRecordPtr createTabPtr;
  3497.   ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
  3498.   
  3499.   ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
  3500.   ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
  3501.   if(ref->errorCode != CreateTabRef::NF_FakeErrorREF){
  3502.     createTabPtr.p->setErrorCode(ref->errorCode);
  3503.   }
  3504.   createTab_reply(signal, createTabPtr, refToNode(ref->senderRef));
  3505. }
  3506. void
  3507. Dbdict::execCREATE_TAB_CONF(Signal* signal){
  3508.   jamEntry();
  3509.   ndbrequire(signal->getNoOfSections() == 0);
  3510.   CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
  3511.   
  3512.   CreateTableRecordPtr createTabPtr;
  3513.   ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
  3514.   
  3515.   ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
  3516.   ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
  3517.   createTab_reply(signal, createTabPtr, refToNode(conf->senderRef));
  3518. }
  3519. void
  3520. Dbdict::createTab_reply(Signal* signal, 
  3521. CreateTableRecordPtr createTabPtr, 
  3522. Uint32 nodeId)
  3523. {
  3524.   SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
  3525.   if(!tmp.clearWaitingFor(nodeId)){
  3526.     jam();
  3527.     return;
  3528.   }
  3529.   
  3530.   switch(createTabPtr.p->m_coordinatorData.m_requestType){
  3531.   case CreateTabReq::CreateTablePrepare:{
  3532.     if(createTabPtr.p->m_errorCode != 0){
  3533.       jam();
  3534.       /**
  3535.        * Failed to prepare on atleast one node -> abort on all
  3536.        */
  3537.       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  3538.       createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
  3539.       createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableDrop;
  3540.       ndbrequire(tmp.init<CreateTabRef>(rg, createTabPtr.p->key));
  3541.       
  3542.       CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
  3543.       req->senderRef = reference();
  3544.       req->senderData = createTabPtr.p->key;
  3545.       req->requestType = CreateTabReq::CreateTableDrop;
  3546.       
  3547.       sendSignal(rg, GSN_CREATE_TAB_REQ, signal, 
  3548.  CreateTabReq::SignalLength, JBB);
  3549.       return;
  3550.     }
  3551.     
  3552.     /**
  3553.      * Lock mutex before commiting table
  3554.      */
  3555.     Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
  3556.     Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_locked),
  3557.    createTabPtr.p->key};
  3558.     ndbrequire(mutex.lock(c));
  3559.     return;
  3560.   }
  3561.   case CreateTabReq::CreateTableCommit:{
  3562.     jam();
  3563.     ndbrequire(createTabPtr.p->m_errorCode == 0);
  3564.     
  3565.     /**
  3566.      * Unlock mutex before commiting table
  3567.      */
  3568.     Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
  3569.     Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_unlocked),
  3570.    createTabPtr.p->key};
  3571.     mutex.unlock(c);
  3572.     return;
  3573.   }
  3574.   case CreateTabReq::CreateTableDrop:{
  3575.     jam();
  3576.     CreateTableRef * const ref = (CreateTableRef*)signal->getDataPtr();
  3577.     ref->senderRef = reference();
  3578.     ref->senderData = createTabPtr.p->m_senderData;
  3579.     ref->errorCode = createTabPtr.p->m_errorCode;
  3580.     ref->masterNodeId = c_masterNodeId;
  3581.     ref->status = 0;
  3582.     ref->errorKey = 0;
  3583.     ref->errorLine = 0;
  3584.     
  3585.     //@todo check api failed
  3586.     sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_REF, signal, 
  3587.        CreateTableRef::SignalLength, JBB);
  3588.     c_opCreateTable.release(createTabPtr);
  3589.     c_blockState = BS_IDLE;
  3590.     return;
  3591.   }
  3592.   }
  3593.   ndbrequire(false);
  3594. }
  3595. void
  3596. Dbdict::createTab_startLcpMutex_locked(Signal* signal, 
  3597.        Uint32 callbackData,
  3598.        Uint32 retValue){
  3599.   jamEntry();
  3600.   ndbrequire(retValue == 0);
  3601.   
  3602.   CreateTableRecordPtr createTabPtr;  
  3603.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  3604.   
  3605.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  3606.   createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
  3607.   createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableCommit;
  3608.   SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
  3609.   tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
  3610.   
  3611.   CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
  3612.   req->senderRef = reference();
  3613.   req->senderData = createTabPtr.p->key;
  3614.   req->requestType = CreateTabReq::CreateTableCommit;
  3615.   
  3616.   sendSignal(rg, GSN_CREATE_TAB_REQ, signal, 
  3617.      CreateTabReq::SignalLength, JBB);
  3618. }
  3619. void
  3620. Dbdict::createTab_startLcpMutex_unlocked(Signal* signal, 
  3621.  Uint32 callbackData,
  3622.  Uint32 retValue){
  3623.   jamEntry();
  3624.   
  3625.   ndbrequire(retValue == 0);
  3626.   
  3627.   CreateTableRecordPtr createTabPtr;  
  3628.   ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
  3629.   createTabPtr.p->m_startLcpMutex.release(c_mutexMgr);
  3630.   
  3631.   TableRecordPtr tabPtr;
  3632.   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
  3633.   
  3634.   CreateTableConf * const conf = (CreateTableConf*)signal->getDataPtr();
  3635.   conf->senderRef = reference();
  3636.   conf->senderData = createTabPtr.p->m_senderData;
  3637.   conf->tableId = createTabPtr.p->m_tablePtrI;
  3638.   conf->tableVersion = tabPtr.p->tableVersion;
  3639.   
  3640.   //@todo check api failed
  3641.   sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_CONF, signal, 
  3642.      CreateTableConf::SignalLength, JBB);
  3643.   c_opCreateTable.release(createTabPtr);
  3644.   c_blockState = BS_IDLE;
  3645.   return;
  3646. }
  3647. /***********************************************************
  3648.  * CreateTable participant code
  3649.  **********************************************************/
  3650. void
  3651. Dbdict::execCREATE_TAB_REQ(Signal* signal){
  3652.   jamEntry();
  3653.   if(!assembleFragments(signal)){
  3654.     jam();
  3655.     return;
  3656.   }
  3657.   CreateTabReq * const req = (CreateTabReq*)signal->getDataPtr();
  3658.   CreateTabReq::RequestType rt = (CreateTabReq::RequestType)req->requestType;
  3659.   switch(rt){
  3660.   case CreateTabReq::CreateTablePrepare:
  3661.     CRASH_INSERTION2(6003, getOwnNodeId() != c_masterNodeId);
  3662.     createTab_prepare(signal, req);
  3663.     return;
  3664.   case CreateTabReq::CreateTableCommit:
  3665.     CRASH_INSERTION2(6004, getOwnNodeId() != c_masterNodeId);
  3666.     createTab_commit(signal, req);
  3667.     return;
  3668.   case CreateTabReq::CreateTableDrop:
  3669.     CRASH_INSERTION2(6005, getOwnNodeId() != c_masterNodeId);
  3670.     createTab_drop(signal, req);
  3671.     return;
  3672.   }
  3673.   ndbrequire(false);
  3674. }