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

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 "NdbDictionaryImpl.hpp"
  14. #include "API.hpp"
  15. #include <NdbOut.hpp>
  16. #include "NdbApiSignal.hpp"
  17. #include "TransporterFacade.hpp"
  18. #include <signaldata/GetTabInfo.hpp>
  19. #include <signaldata/DictTabInfo.hpp>
  20. #include <signaldata/CreateTable.hpp>
  21. #include <signaldata/CreateIndx.hpp>
  22. #include <signaldata/CreateEvnt.hpp>
  23. #include <signaldata/SumaImpl.hpp>
  24. #include <signaldata/DropTable.hpp>
  25. #include <signaldata/AlterTable.hpp>
  26. #include <signaldata/DropIndx.hpp>
  27. #include <signaldata/ListTables.hpp>
  28. #include <SimpleProperties.hpp>
  29. #include <Bitmask.hpp>
  30. #include <AttributeList.hpp>
  31. #include <NdbEventOperation.hpp>
  32. #include "NdbEventOperationImpl.hpp"
  33. #include <NdbBlob.hpp>
  34. #include "NdbBlobImpl.hpp"
  35. #include <AttributeHeader.hpp>
  36. #include <my_sys.h>
  37. #define DEBUG_PRINT 0
  38. #define INCOMPATIBLE_VERSION -2
  39. //#define EVENT_DEBUG
  40. /**
  41.  * Column
  42.  */
  43. NdbColumnImpl::NdbColumnImpl()
  44.   : NdbDictionary::Column(* this), m_attrId(-1), m_facade(this)
  45. {
  46.   init();
  47. }
  48. NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f)
  49.   : NdbDictionary::Column(* this), m_attrId(-1), m_facade(&f)
  50. {
  51.   init();
  52. }
  53. NdbColumnImpl&
  54. NdbColumnImpl::operator=(const NdbColumnImpl& col)
  55. {
  56.   m_attrId = col.m_attrId;
  57.   m_name = col.m_name;
  58.   m_type = col.m_type;
  59.   m_precision = col.m_precision;
  60.   m_cs = col.m_cs;
  61.   m_scale = col.m_scale;
  62.   m_length = col.m_length;
  63.   m_pk = col.m_pk;
  64.   m_tupleKey = col.m_tupleKey;
  65.   m_distributionKey = col.m_distributionKey;
  66.   m_distributionGroup = col.m_distributionGroup;
  67.   m_distributionGroupBits = col.m_distributionGroupBits;
  68.   m_nullable = col.m_nullable;
  69.   m_indexOnly = col.m_indexOnly;
  70.   m_autoIncrement = col.m_autoIncrement;
  71.   m_autoIncrementInitialValue = col.m_autoIncrementInitialValue;
  72.   m_defaultValue = col.m_defaultValue;
  73.   m_attrType = col.m_attrType; 
  74.   m_attrSize = col.m_attrSize; 
  75.   m_arraySize = col.m_arraySize;
  76.   m_keyInfoPos = col.m_keyInfoPos;
  77.   m_blobTable = col.m_blobTable;
  78.   // Do not copy m_facade !!
  79.   return *this;
  80. }
  81. void
  82. NdbColumnImpl::init(Type t)
  83. {
  84.   // do not use default_charset_info as it may not be initialized yet
  85.   // use binary collation until NDB tests can handle charsets
  86.   CHARSET_INFO* default_cs = &my_charset_bin;
  87.   m_type = t;
  88.   switch (m_type) {
  89.   case Tinyint:
  90.   case Tinyunsigned:
  91.   case Smallint:
  92.   case Smallunsigned:
  93.   case Mediumint:
  94.   case Mediumunsigned:
  95.   case Int:
  96.   case Unsigned:
  97.   case Bigint:
  98.   case Bigunsigned:
  99.   case Float:
  100.   case Double:
  101.     m_precision = 0;
  102.     m_scale = 0;
  103.     m_length = 1;
  104.     m_cs = NULL;
  105.     break;
  106.   case Olddecimal:
  107.   case Olddecimalunsigned:
  108.     m_precision = 10;
  109.     m_scale = 0;
  110.     m_length = 1;
  111.     m_cs = NULL;
  112.     break;
  113.   case Char:
  114.   case Varchar:
  115.     m_precision = 0;
  116.     m_scale = 0;
  117.     m_length = 1;
  118.     m_cs = default_cs;
  119.     break;
  120.   case Binary:
  121.   case Varbinary:
  122.   case Datetime:
  123.   case Date:
  124.     m_precision = 0;
  125.     m_scale = 0;
  126.     m_length = 1;
  127.     m_cs = NULL;
  128.     break;
  129.   case Blob:
  130.     m_precision = 256;
  131.     m_scale = 8000;
  132.     m_length = 4;
  133.     m_cs = NULL;
  134.     break;
  135.   case Text:
  136.     m_precision = 256;
  137.     m_scale = 8000;
  138.     m_length = 4;
  139.     m_cs = default_cs;
  140.     break;
  141.   case Time:
  142.   case Year:
  143.   case Timestamp:
  144.     m_precision = 0;
  145.     m_scale = 0;
  146.     m_length = 1;
  147.     m_cs = NULL;
  148.     break;
  149.   case Undefined:
  150.     assert(false);
  151.     break;
  152.   }
  153.   m_pk = false;
  154.   m_nullable = false;
  155.   m_tupleKey = false;
  156.   m_indexOnly = false;
  157.   m_distributionKey = false;
  158.   m_distributionGroup = false;
  159.   m_distributionGroupBits = 8;
  160.   m_keyInfoPos = 0;
  161.   // next 2 are set at run time
  162.   m_attrSize = 0;
  163.   m_arraySize = 0;
  164.   m_autoIncrement = false;
  165.   m_autoIncrementInitialValue = 1;
  166.   m_blobTable = NULL;
  167. }
  168. NdbColumnImpl::~NdbColumnImpl()
  169. {
  170. }
  171. bool
  172. NdbColumnImpl::equal(const NdbColumnImpl& col) const 
  173. {
  174.   if(strcmp(m_name.c_str(), col.m_name.c_str()) != 0){
  175.     return false;
  176.   }
  177.   if(m_type != col.m_type){
  178.     return false;
  179.   }
  180.   if(m_pk != col.m_pk){
  181.     return false;
  182.   }
  183.   if(m_nullable != col.m_nullable){
  184.     return false;
  185.   }
  186.   if(m_pk){
  187.     if(m_tupleKey != col.m_tupleKey){
  188.       return false;
  189.     }
  190.     if(m_indexOnly != col.m_indexOnly){
  191.       return false;
  192.     }
  193.     if(m_distributionKey != col.m_distributionKey){
  194.       return false;
  195.     }
  196.     if(m_distributionGroup != col.m_distributionGroup){
  197.       return false;
  198.     }
  199.     if(m_distributionGroup && 
  200.        (m_distributionGroupBits != col.m_distributionGroupBits)){
  201.       return false;
  202.     }
  203.   }
  204.   if (m_precision != col.m_precision ||
  205.       m_scale != col.m_scale ||
  206.       m_length != col.m_length ||
  207.       m_cs != col.m_cs) {
  208.     return false;
  209.   }
  210.   if (m_autoIncrement != col.m_autoIncrement){
  211.     return false;
  212.   }
  213.   if(strcmp(m_defaultValue.c_str(), col.m_defaultValue.c_str()) != 0){
  214.     return false;
  215.   }
  216.   return true;
  217. }
  218. NdbDictionary::Column *
  219. NdbColumnImpl::create_psuedo(const char * name){
  220.   NdbDictionary::Column * col = new NdbDictionary::Column();
  221.   col->setName(name);
  222.   if(!strcmp(name, "NDB$FRAGMENT")){
  223.     col->setType(NdbDictionary::Column::Unsigned);
  224.     col->m_impl.m_attrId = AttributeHeader::FRAGMENT;
  225.     col->m_impl.m_attrSize = 4;
  226.     col->m_impl.m_arraySize = 1;
  227.   } else if(!strcmp(name, "NDB$ROW_COUNT")){
  228.     col->setType(NdbDictionary::Column::Bigunsigned);
  229.     col->m_impl.m_attrId = AttributeHeader::ROW_COUNT;
  230.     col->m_impl.m_attrSize = 8;
  231.     col->m_impl.m_arraySize = 1;
  232.   } else if(!strcmp(name, "NDB$COMMIT_COUNT")){
  233.     col->setType(NdbDictionary::Column::Bigunsigned);
  234.     col->m_impl.m_attrId = AttributeHeader::COMMIT_COUNT;
  235.     col->m_impl.m_attrSize = 8;
  236.     col->m_impl.m_arraySize = 1;
  237.   } else {
  238.     abort();
  239.   }
  240.   return col;
  241. }
  242. /**
  243.  * NdbTableImpl
  244.  */
  245. NdbTableImpl::NdbTableImpl()
  246.   : NdbDictionary::Table(* this), m_facade(this)
  247. {
  248.   init();
  249. }
  250. NdbTableImpl::NdbTableImpl(NdbDictionary::Table & f)
  251.   : NdbDictionary::Table(* this), m_facade(&f)
  252. {
  253.   init();
  254. }
  255. NdbTableImpl::~NdbTableImpl()
  256. {
  257.   if (m_index != 0) {
  258.     delete m_index;
  259.     m_index = 0;
  260.   }
  261.   for (unsigned i = 0; i < m_columns.size(); i++)
  262.     delete m_columns[i];  
  263. }
  264. void
  265. NdbTableImpl::init(){
  266.   clearNewProperties();
  267.   m_frm.clear();
  268.   m_fragmentType = NdbDictionary::Object::FragAllSmall;
  269.   m_logging = true;
  270.   m_kvalue = 6;
  271.   m_minLoadFactor = 78;
  272.   m_maxLoadFactor = 80;
  273.   m_index = 0;
  274.   m_indexType = NdbDictionary::Index::Undefined;
  275.   
  276.   m_noOfKeys = 0;
  277.   m_fragmentCount = 0;
  278.   m_sizeOfKeysInWords = 0;
  279.   m_noOfBlobs = 0;
  280. }
  281. bool
  282. NdbTableImpl::equal(const NdbTableImpl& obj) const 
  283. {
  284.   if ((m_internalName.c_str() == NULL) || 
  285.       (strcmp(m_internalName.c_str(), "") == 0) ||
  286.       (obj.m_internalName.c_str() == NULL) || 
  287.       (strcmp(obj.m_internalName.c_str(), "") == 0)) {
  288.     // Shallow equal
  289.     if(strcmp(getName(), obj.getName()) != 0){
  290.       return false;    
  291.     }
  292.   } else 
  293.     // Deep equal
  294.     if(strcmp(m_internalName.c_str(), obj.m_internalName.c_str()) != 0){
  295.       return false;
  296.   }
  297.   if(m_fragmentType != obj.m_fragmentType){
  298.     return false;
  299.   }
  300.   if(m_columns.size() != obj.m_columns.size()){
  301.     return false;
  302.   }
  303.   for(unsigned i = 0; i<obj.m_columns.size(); i++){
  304.     if(!m_columns[i]->equal(* obj.m_columns[i])){
  305.       return false;
  306.     }
  307.   }
  308.   
  309.   if(m_logging != obj.m_logging){
  310.     return false;
  311.   }
  312.   if(m_kvalue != obj.m_kvalue){
  313.     return false;
  314.   }
  315.   if(m_minLoadFactor != obj.m_minLoadFactor){
  316.     return false;
  317.   }
  318.   if(m_maxLoadFactor != obj.m_maxLoadFactor){
  319.     return false;
  320.   }
  321.   
  322.   return true;
  323. }
  324. void
  325. NdbTableImpl::assign(const NdbTableImpl& org)
  326. {
  327.   m_tableId = org.m_tableId;
  328.   m_internalName.assign(org.m_internalName);
  329.   m_externalName.assign(org.m_externalName);
  330.   m_newExternalName.assign(org.m_newExternalName);
  331.   m_frm.assign(org.m_frm.get_data(), org.m_frm.length());
  332.   m_fragmentType = org.m_fragmentType;
  333.   m_fragmentCount = org.m_fragmentCount;
  334.   for(unsigned i = 0; i<org.m_columns.size(); i++){
  335.     NdbColumnImpl * col = new NdbColumnImpl();
  336.     const NdbColumnImpl * iorg = org.m_columns[i];
  337.     (* col) = (* iorg);
  338.     m_columns.push_back(col);
  339.   }
  340.   m_logging = org.m_logging;
  341.   m_kvalue = org.m_kvalue;
  342.   m_minLoadFactor = org.m_minLoadFactor;
  343.   m_maxLoadFactor = org.m_maxLoadFactor;
  344.   
  345.   if (m_index != 0)
  346.     delete m_index;
  347.   m_index = org.m_index;
  348.   
  349.   m_noOfKeys = org.m_noOfKeys;
  350.   m_sizeOfKeysInWords = org.m_sizeOfKeysInWords;
  351.   m_noOfBlobs = org.m_noOfBlobs;
  352.   m_version = org.m_version;
  353.   m_status = org.m_status;
  354. }
  355. void NdbTableImpl::setName(const char * name)
  356. {
  357.   m_newExternalName.assign(name);
  358. }
  359. const char * 
  360. NdbTableImpl::getName() const
  361. {
  362.   if (m_newExternalName.empty())
  363.     return m_externalName.c_str();
  364.   else
  365.     return m_newExternalName.c_str();
  366. }
  367. void NdbTableImpl::clearNewProperties()
  368. {
  369.   m_newExternalName.assign("");
  370.   m_changeMask = 0;
  371. }
  372. void NdbTableImpl::copyNewProperties()
  373. {
  374.   if (!m_newExternalName.empty()) {
  375.     m_externalName.assign(m_newExternalName);
  376.     AlterTableReq::setNameFlag(m_changeMask, true);
  377.   }
  378. }
  379. void
  380. NdbTableImpl::buildColumnHash(){
  381.   const Uint32 size = m_columns.size();
  382.   int i;
  383.   for(i = 31; i >= 0; i--){
  384.     if(((1 << i) & size) != 0){
  385.       m_columnHashMask = (1 << (i + 1)) - 1;
  386.       break;
  387.     }
  388.   }
  389.   Vector<Uint32> hashValues;
  390.   Vector<Vector<Uint32> > chains; chains.fill(size, hashValues);
  391.   for(i = 0; i< (int) size; i++){
  392.     Uint32 hv = Hash(m_columns[i]->getName()) & 0xFFFE;
  393.     Uint32 bucket = hv & m_columnHashMask;
  394.     bucket = (bucket < size ? bucket : bucket - size);
  395.     assert(bucket < size);
  396.     hashValues.push_back(hv);
  397.     chains[bucket].push_back(i);
  398.   }
  399.   m_columnHash.clear();
  400.   Uint32 tmp = 1; 
  401.   m_columnHash.fill((unsigned)size-1, tmp);   // Default no chaining
  402.   Uint32 pos = 0; // In overflow vector
  403.   for(i = 0; i< (int) size; i++){
  404.     Uint32 sz = chains[i].size();
  405.     if(sz == 1){
  406.       Uint32 col = chains[i][0];
  407.       Uint32 hv = hashValues[col];
  408.       Uint32 bucket = hv & m_columnHashMask;
  409.       bucket = (bucket < size ? bucket : bucket - size);
  410.       m_columnHash[bucket] = (col << 16) | hv | 1;
  411.     } else if(sz > 1){
  412.       Uint32 col = chains[i][0];
  413.       Uint32 hv = hashValues[col];
  414.       Uint32 bucket = hv & m_columnHashMask;
  415.       bucket = (bucket < size ? bucket : bucket - size);
  416.       m_columnHash[bucket] = (sz << 16) | (((size - bucket) + pos) << 1);
  417.       for(size_t j = 0; j<sz; j++, pos++){
  418. Uint32 col = chains[i][j];
  419. Uint32 hv = hashValues[col];
  420. m_columnHash.push_back((col << 16) | hv);
  421.       }
  422.     }
  423.   }
  424.   m_columnHash.push_back(0); // Overflow when looping in end of array
  425. #if 0
  426.   for(size_t i = 0; i<m_columnHash.size(); i++){
  427.     Uint32 tmp = m_columnHash[i];
  428.     int col = -1;
  429.     if(i < size && (tmp & 1) == 1){
  430.       col = (tmp >> 16);
  431.     } else if(i >= size){
  432.       col = (tmp >> 16);
  433.     }
  434.     ndbout_c("m_columnHash[%d] %s = %x", 
  435.      i, col > 0 ? m_columns[col]->getName() : "" , m_columnHash[i]);
  436.   }
  437. #endif
  438. }
  439.   
  440. /**
  441.  * NdbIndexImpl
  442.  */
  443. NdbIndexImpl::NdbIndexImpl() : 
  444.   NdbDictionary::Index(* this), 
  445.   m_facade(this)
  446. {
  447.   m_logging = true;
  448. }
  449. NdbIndexImpl::NdbIndexImpl(NdbDictionary::Index & f) : 
  450.   NdbDictionary::Index(* this), 
  451.   m_facade(&f)
  452. {
  453.   m_logging = true;
  454. }
  455. NdbIndexImpl::~NdbIndexImpl(){
  456.   for (unsigned i = 0; i < m_columns.size(); i++)
  457.     delete m_columns[i];  
  458. }
  459. void NdbIndexImpl::setName(const char * name)
  460. {
  461.   m_externalName.assign(name);
  462. }
  463. const char * 
  464. NdbIndexImpl::getName() const
  465. {
  466.   return m_externalName.c_str();
  467. }
  468.  
  469. void 
  470. NdbIndexImpl::setTable(const char * table)
  471. {
  472.   m_tableName.assign(table);
  473. }
  474.  
  475. const char * 
  476. NdbIndexImpl::getTable() const
  477. {
  478.   return m_tableName.c_str();
  479. }
  480. const NdbTableImpl *
  481. NdbIndexImpl::getIndexTable() const
  482. {
  483.   return m_table;
  484. }
  485. /**
  486.  * NdbEventImpl
  487.  */
  488. NdbEventImpl::NdbEventImpl() : 
  489.   NdbDictionary::Event(* this),
  490.   m_facade(this)
  491. {
  492.   mi_type = 0;
  493.   m_dur = NdbDictionary::Event::ED_UNDEFINED;
  494.   eventOp = NULL;
  495.   m_tableImpl = NULL;
  496. }
  497. NdbEventImpl::NdbEventImpl(NdbDictionary::Event & f) : 
  498.   NdbDictionary::Event(* this),
  499.   m_facade(&f)
  500. {
  501.   mi_type = 0;
  502.   m_dur = NdbDictionary::Event::ED_UNDEFINED;
  503.   eventOp = NULL;
  504.   m_tableImpl = NULL;
  505. }
  506. NdbEventImpl::~NdbEventImpl()
  507. {
  508.   for (unsigned i = 0; i < m_columns.size(); i++)
  509.     delete  m_columns[i];
  510. }
  511. void NdbEventImpl::setName(const char * name)
  512. {
  513.   m_externalName.assign(name);
  514. }
  515. void 
  516. NdbEventImpl::setTable(const char * table)
  517. {
  518.   m_tableName.assign(table);
  519. }
  520. const char * 
  521. NdbEventImpl::getTable() const
  522. {
  523.   return m_tableName.c_str();
  524. }
  525. const char * 
  526. NdbEventImpl::getName() const
  527. {
  528.   return m_externalName.c_str();
  529. void
  530. NdbEventImpl::addTableEvent(const NdbDictionary::Event::TableEvent t =  NdbDictionary::Event::TE_ALL)
  531. {
  532.   switch (t) {
  533.   case NdbDictionary::Event::TE_INSERT : mi_type |= 1; break;
  534.   case NdbDictionary::Event::TE_DELETE : mi_type |= 2; break;
  535.   case NdbDictionary::Event::TE_UPDATE : mi_type |= 4; break;
  536.   default: mi_type = 4 | 2 | 1; // all types
  537.   }
  538. }
  539. void
  540. NdbEventImpl::setDurability(const NdbDictionary::Event::EventDurability d)
  541. {
  542.   m_dur = d;
  543. }
  544. /**
  545.  * NdbDictionaryImpl
  546.  */
  547. NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb)
  548.   : NdbDictionary::Dictionary(* this), 
  549.     m_facade(this), 
  550.     m_receiver(m_error),
  551.     m_ndb(ndb)
  552. {
  553.   m_globalHash = 0;
  554.   m_local_table_data_size= 0;
  555. }
  556. NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb,
  557.      NdbDictionary::Dictionary & f)
  558.   : NdbDictionary::Dictionary(* this), 
  559.     m_facade(&f), 
  560.     m_receiver(m_error),
  561.     m_ndb(ndb)
  562. {
  563.   m_globalHash = 0;
  564.   m_local_table_data_size= 0;
  565. }
  566. static int f_dictionary_count = 0;
  567. NdbDictionaryImpl::~NdbDictionaryImpl()
  568. {
  569.   NdbElement_t<Ndb_local_table_info> * curr = m_localHash.m_tableHash.getNext(0);
  570.   if(m_globalHash){
  571.     while(curr != 0){
  572.       m_globalHash->lock();
  573.       m_globalHash->release(curr->theData->m_table_impl);
  574.       Ndb_local_table_info::destroy(curr->theData);
  575.       m_globalHash->unlock();
  576.       
  577.       curr = m_localHash.m_tableHash.getNext(curr);
  578.     }
  579.     
  580.     m_globalHash->lock();
  581.     if(--f_dictionary_count == 0){
  582.       delete NdbDictionary::Column::FRAGMENT; 
  583.       delete NdbDictionary::Column::ROW_COUNT;
  584.       delete NdbDictionary::Column::COMMIT_COUNT;
  585.       NdbDictionary::Column::FRAGMENT= 0;
  586.       NdbDictionary::Column::ROW_COUNT= 0;
  587.       NdbDictionary::Column::COMMIT_COUNT= 0;
  588.     }
  589.     m_globalHash->unlock();
  590.   } else {
  591.     assert(curr == 0);
  592.   }
  593. }
  594. Ndb_local_table_info *
  595. NdbDictionaryImpl::fetchGlobalTableImpl(const char * internalTableName)
  596. {
  597.   NdbTableImpl *impl;
  598.   m_globalHash->lock();
  599.   impl = m_globalHash->get(internalTableName);
  600.   m_globalHash->unlock();
  601.   if (impl == 0){
  602.     impl = m_receiver.getTable(internalTableName,
  603.        m_ndb.usingFullyQualifiedNames());
  604.     m_globalHash->lock();
  605.     m_globalHash->put(internalTableName, impl);
  606.     m_globalHash->unlock();
  607.     
  608.     if(impl == 0){
  609.       return 0;
  610.     }
  611.   }
  612.   Ndb_local_table_info *info=
  613.     Ndb_local_table_info::create(impl, m_local_table_data_size);
  614.   m_localHash.put(internalTableName, info);
  615.   m_ndb.theFirstTupleId[impl->getTableId()] = ~0;
  616.   m_ndb.theLastTupleId[impl->getTableId()]  = ~0;
  617.   
  618.   return info;
  619. }
  620. #if 0
  621. bool
  622. NdbDictionaryImpl::setTransporter(class TransporterFacade * tf)
  623. {
  624.   if(tf != 0){
  625.     m_globalHash = &tf->m_globalDictCache;
  626.     return m_receiver.setTransporter(tf);
  627.   }
  628.   
  629.   return false;
  630. }
  631. #endif
  632. bool
  633. NdbDictionaryImpl::setTransporter(class Ndb* ndb, 
  634.   class TransporterFacade * tf)
  635. {
  636.   m_globalHash = &tf->m_globalDictCache;
  637.   if(m_receiver.setTransporter(ndb, tf)){
  638.     m_globalHash->lock();
  639.     if(f_dictionary_count++ == 0){
  640.       NdbDictionary::Column::FRAGMENT= 
  641. NdbColumnImpl::create_psuedo("NDB$FRAGMENT");
  642.       NdbDictionary::Column::ROW_COUNT= 
  643. NdbColumnImpl::create_psuedo("NDB$ROW_COUNT");
  644.       NdbDictionary::Column::COMMIT_COUNT= 
  645. NdbColumnImpl::create_psuedo("NDB$COMMIT_COUNT");
  646.     }
  647.     m_globalHash->unlock();
  648.     return true;
  649.   }
  650.   return false;
  651. }
  652. NdbTableImpl * 
  653. NdbDictionaryImpl::getIndexTable(NdbIndexImpl * index, 
  654.  NdbTableImpl * table)
  655. {
  656.   const char * internalName = 
  657.     m_ndb.internalizeIndexName(table, index->getName());
  658.   
  659.   return getTable(m_ndb.externalizeTableName(internalName));
  660. }
  661. #if 0
  662. bool
  663. NdbDictInterface::setTransporter(class TransporterFacade * tf)
  664. {
  665.   if(tf == 0)
  666.     return false;
  667.   
  668.   Guard g(tf->theMutexPtr);
  669.   
  670.   m_blockNumber = tf->open(this,
  671.    execSignal,
  672.    execNodeStatus);
  673.   
  674.   if ( m_blockNumber == -1 ) {
  675.     m_error.code = 4105;
  676.     return false; // no more free blocknumbers
  677.   }//if
  678.   Uint32 theNode = tf->ownId();
  679.   m_reference = numberToRef(m_blockNumber, theNode);
  680.   m_transporter = tf;
  681.   m_waiter.m_mutex = tf->theMutexPtr;
  682.   return true;
  683. }
  684. #endif
  685. bool
  686. NdbDictInterface::setTransporter(class Ndb* ndb, class TransporterFacade * tf)
  687. {
  688.   m_reference = ndb->getReference();
  689.   m_transporter = tf;
  690.   m_waiter.m_mutex = tf->theMutexPtr;
  691.   
  692.   return true;
  693. }
  694. NdbDictInterface::~NdbDictInterface()
  695. {
  696. }
  697. void 
  698. NdbDictInterface::execSignal(void* dictImpl, 
  699.      class NdbApiSignal* signal, 
  700.      class LinearSectionPtr ptr[3])
  701. {
  702.   NdbDictInterface * tmp = (NdbDictInterface*)dictImpl;
  703.   
  704.   const Uint32 gsn = signal->readSignalNumber();
  705.   switch(gsn){
  706.   case GSN_GET_TABINFOREF:
  707.     tmp->execGET_TABINFO_REF(signal, ptr);
  708.     break;
  709.   case GSN_GET_TABINFO_CONF:
  710.     tmp->execGET_TABINFO_CONF(signal, ptr);
  711.     break;
  712.   case GSN_CREATE_TABLE_REF:
  713.     tmp->execCREATE_TABLE_REF(signal, ptr);
  714.     break;
  715.   case GSN_CREATE_TABLE_CONF:
  716.     tmp->execCREATE_TABLE_CONF(signal, ptr);
  717.     break;
  718.   case GSN_DROP_TABLE_REF:
  719.     tmp->execDROP_TABLE_REF(signal, ptr);
  720.     break;
  721.   case GSN_DROP_TABLE_CONF:
  722.     tmp->execDROP_TABLE_CONF(signal, ptr);
  723.     break;
  724.   case GSN_ALTER_TABLE_REF:
  725.     tmp->execALTER_TABLE_REF(signal, ptr);
  726.     break;
  727.   case GSN_ALTER_TABLE_CONF:
  728.     tmp->execALTER_TABLE_CONF(signal, ptr);
  729.     break;
  730.   case GSN_CREATE_INDX_REF:
  731.     tmp->execCREATE_INDX_REF(signal, ptr);
  732.     break;
  733.   case GSN_CREATE_INDX_CONF:
  734.     tmp->execCREATE_INDX_CONF(signal, ptr);
  735.     break;
  736.   case GSN_DROP_INDX_REF:
  737.     tmp->execDROP_INDX_REF(signal, ptr);
  738.     break;
  739.   case GSN_DROP_INDX_CONF:
  740.     tmp->execDROP_INDX_CONF(signal, ptr);
  741.     break;
  742.   case GSN_CREATE_EVNT_REF:
  743.     tmp->execCREATE_EVNT_REF(signal, ptr);
  744.     break;
  745.   case GSN_CREATE_EVNT_CONF:
  746.     tmp->execCREATE_EVNT_CONF(signal, ptr);
  747.     break;
  748.   case GSN_SUB_START_CONF:
  749.     tmp->execSUB_START_CONF(signal, ptr);
  750.     break;
  751.   case GSN_SUB_START_REF:
  752.     tmp->execSUB_START_REF(signal, ptr);
  753.     break;
  754.   case GSN_SUB_TABLE_DATA:
  755.     tmp->execSUB_TABLE_DATA(signal, ptr);
  756.     break;
  757.   case GSN_SUB_GCP_COMPLETE_REP:
  758.     tmp->execSUB_GCP_COMPLETE_REP(signal, ptr);
  759.     break;
  760.   case GSN_SUB_STOP_CONF:
  761.     tmp->execSUB_STOP_CONF(signal, ptr);
  762.     break;
  763.   case GSN_SUB_STOP_REF:
  764.     tmp->execSUB_STOP_REF(signal, ptr);
  765.     break;
  766.   case GSN_DROP_EVNT_REF:
  767.     tmp->execDROP_EVNT_REF(signal, ptr);
  768.     break;
  769.   case GSN_DROP_EVNT_CONF:
  770.     tmp->execDROP_EVNT_CONF(signal, ptr);
  771.     break;
  772.   case GSN_LIST_TABLES_CONF:
  773.     tmp->execLIST_TABLES_CONF(signal, ptr);
  774.     break;
  775.   default:
  776.     abort();
  777.   }
  778. }
  779. void
  780. NdbDictInterface::execNodeStatus(void* dictImpl, Uint32 aNode,
  781.  bool alive, bool nfCompleted)
  782. {
  783.   NdbDictInterface * tmp = (NdbDictInterface*)dictImpl;
  784.   
  785.   if(!alive && !nfCompleted){
  786.     return;
  787.   }
  788.   
  789.   if (!alive && nfCompleted){
  790.     tmp->m_waiter.nodeFail(aNode);
  791.   }
  792. }
  793. int
  794. NdbDictInterface::dictSignal(NdbApiSignal* signal, 
  795.      LinearSectionPtr ptr[3],int noLSP,
  796.      const int useMasterNodeId,
  797.      const Uint32 RETRIES,
  798.      const WaitSignalType wst,
  799.      const int theWait,
  800.      const int *errcodes,
  801.      const int noerrcodes,
  802.      const int temporaryMask)
  803. {
  804.   DBUG_ENTER("NdbDictInterface::dictSignal");
  805.   DBUG_PRINT("enter", ("useMasterNodeId: %d", useMasterNodeId));
  806.   for(Uint32 i = 0; i<RETRIES; i++){
  807.     //if (useMasterNodeId == 0)
  808.     m_buffer.clear();
  809.     // Protected area
  810.     m_transporter->lock_mutex();
  811.     Uint32 aNodeId;
  812.     if (useMasterNodeId) {
  813.       if ((m_masterNodeId == 0) ||
  814.   (!m_transporter->get_node_alive(m_masterNodeId))) {
  815. m_masterNodeId = m_transporter->get_an_alive_node();
  816.       }//if
  817.       aNodeId = m_masterNodeId;
  818.     } else {
  819.       aNodeId = m_transporter->get_an_alive_node();
  820.     }
  821.     if(aNodeId == 0){
  822.       m_error.code = 4009;
  823.       m_transporter->unlock_mutex();
  824.       DBUG_RETURN(-1);
  825.     }
  826.     {
  827.       int r;
  828.       if (ptr) {
  829. #ifdef EVENT_DEBUG
  830. printf("Long signal %d ptr", noLSP);
  831. for (int q=0;q<noLSP;q++) {
  832.   printf(" sz %d", ptr[q].sz);
  833. }
  834. printf("n");
  835. #endif
  836. r = m_transporter->sendFragmentedSignal(signal, aNodeId, ptr, noLSP);
  837.       } else {
  838. #ifdef EVENT_DEBUG
  839. printf("Short signaln");
  840. #endif
  841. r = m_transporter->sendSignal(signal, aNodeId);
  842.       }
  843.       if(r != 0){
  844. m_transporter->unlock_mutex();
  845. continue;
  846.       }
  847.     }
  848.     
  849.     m_error.code = 0;
  850.     
  851.     m_waiter.m_node = aNodeId;
  852.     m_waiter.m_state = wst;
  853.     m_waiter.wait(theWait);
  854.     m_transporter->unlock_mutex();    
  855.     // End of Protected area  
  856.     
  857.     if(m_waiter.m_state == NO_WAIT && m_error.code == 0){
  858.       // Normal return
  859.       DBUG_RETURN(0);
  860.     }
  861.     
  862.     /**
  863.      * Handle error codes
  864.      */
  865.     if(m_waiter.m_state == WAIT_NODE_FAILURE)
  866.       continue;
  867.     if(m_waiter.m_state == WST_WAIT_TIMEOUT)
  868.     {
  869.       m_error.code = 4008;
  870.       DBUG_RETURN(-1);
  871.     }
  872.     
  873.     if ( (temporaryMask & m_error.code) != 0 ) {
  874.       continue;
  875.     }
  876.     if (errcodes) {
  877.       int doContinue = 0;
  878.       for (int j=0; j < noerrcodes; j++)
  879. if(m_error.code == errcodes[j]) {
  880.   doContinue = 1;
  881.   continue;
  882. }
  883.       if (doContinue)
  884. continue;
  885.     }
  886.     DBUG_RETURN(-1);
  887.   }
  888.   DBUG_RETURN(-1);
  889. }
  890. /*****************************************************************
  891.  * get tab info
  892.  */
  893. NdbTableImpl * 
  894. NdbDictInterface::getTable(int tableId, bool fullyQualifiedNames)
  895. {
  896.   NdbApiSignal tSignal(m_reference);
  897.   GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
  898.   
  899.   req->senderRef = m_reference;
  900.   req->senderData = 0;
  901.   req->requestType = 
  902.     GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
  903.   req->tableId = tableId;
  904.   tSignal.theReceiversBlockNumber = DBDICT;
  905.   tSignal.theVerId_signalNumber   = GSN_GET_TABINFOREQ;
  906.   tSignal.theLength = GetTabInfoReq::SignalLength;
  907.   
  908.   return getTable(&tSignal, 0, 0, fullyQualifiedNames);
  909. }
  910. NdbTableImpl * 
  911. NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames)
  912. {
  913.   NdbApiSignal tSignal(m_reference);
  914.   GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
  915.   
  916.   const Uint32 strLen = strlen(name) + 1; // NULL Terminated
  917.   if(strLen > MAX_TAB_NAME_SIZE) {//sizeof(req->tableName)){
  918.     m_error.code = 4307;
  919.     return 0;
  920.   }
  921.   // avoid alignment problem and memory overrun
  922.   Uint32 name_buf[(MAX_TAB_NAME_SIZE + 3) / 4];
  923.   strncpy((char*)name_buf, name, sizeof(name_buf)); // strncpy null-pads
  924.   name = (char*)name_buf;
  925.   req->senderRef = m_reference;
  926.   req->senderData = 0;
  927.   req->requestType = 
  928.     GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
  929.   req->tableNameLen = strLen;
  930.   tSignal.theReceiversBlockNumber = DBDICT;
  931.   tSignal.theVerId_signalNumber   = GSN_GET_TABINFOREQ;
  932.   //  tSignal.theLength = GetTabInfoReq::HeaderLength + ((strLen + 3) / 4);
  933.   tSignal.theLength = GetTabInfoReq::SignalLength;
  934.   LinearSectionPtr ptr[1];
  935.   ptr[0].p  = (Uint32*)name;
  936.   ptr[0].sz = (strLen + 3) / 4;
  937.   
  938.   return getTable(&tSignal, ptr, 1, fullyQualifiedNames);
  939. }
  940. NdbTableImpl *
  941. NdbDictInterface::getTable(class NdbApiSignal * signal, 
  942.    LinearSectionPtr ptr[3],
  943.    Uint32 noOfSections, bool fullyQualifiedNames)
  944. {
  945.   //GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, signal->getDataPtrSend());
  946.   int r = dictSignal(signal,ptr,noOfSections,
  947.      0/*do not use masternode id*/,
  948.      100,
  949.      WAIT_GET_TAB_INFO_REQ,
  950.      WAITFOR_RESPONSE_TIMEOUT,
  951.      NULL,0);
  952.   if (r) return 0;
  953.   NdbTableImpl * rt = 0;
  954.   m_error.code = parseTableInfo(&rt, 
  955.    (Uint32*)m_buffer.get_data(), 
  956.    m_buffer.length() / 4, fullyQualifiedNames);
  957.   rt->buildColumnHash();
  958.   return rt;
  959. }
  960. void
  961. NdbDictInterface::execGET_TABINFO_CONF(NdbApiSignal * signal, 
  962.        LinearSectionPtr ptr[3])
  963. {
  964.   const GetTabInfoConf* conf = CAST_CONSTPTR(GetTabInfoConf, signal->getDataPtr());
  965.   if(signal->isFirstFragment()){
  966.     m_fragmentId = signal->getFragmentId();
  967.     m_buffer.grow(4 * conf->totalLen);
  968.   } else {
  969.     if(m_fragmentId != signal->getFragmentId()){
  970.       abort();
  971.     }
  972.   }
  973.   
  974.   const Uint32 i = GetTabInfoConf::DICT_TAB_INFO;
  975.   m_buffer.append(ptr[i].p, 4 * ptr[i].sz);
  976.   if(!signal->isLastFragment()){
  977.     return;
  978.   }  
  979.   
  980.   m_waiter.signal(NO_WAIT);
  981. }
  982. void
  983. NdbDictInterface::execGET_TABINFO_REF(NdbApiSignal * signal,
  984.       LinearSectionPtr ptr[3])
  985. {
  986.   const GetTabInfoRef* ref = CAST_CONSTPTR(GetTabInfoRef, signal->getDataPtr());
  987.   m_error.code = ref->errorCode;
  988.   m_waiter.signal(NO_WAIT);
  989. }
  990. /*****************************************************************
  991.  * Pack/Unpack tables
  992.  */
  993. struct ApiKernelMapping {
  994.   Int32 kernelConstant;
  995.   Int32 apiConstant;
  996. };
  997. Uint32
  998. getApiConstant(Int32 kernelConstant, const ApiKernelMapping map[], Uint32 def)
  999. {
  1000.   int i = 0;
  1001.   while(map[i].kernelConstant != kernelConstant){
  1002.     if(map[i].kernelConstant == -1 &&
  1003.        map[i].apiConstant == -1){
  1004.       return def;
  1005.     }
  1006.     i++;
  1007.   }
  1008.   return map[i].apiConstant;
  1009. }
  1010. Uint32
  1011. getKernelConstant(Int32 apiConstant, const ApiKernelMapping map[], Uint32 def)
  1012. {
  1013.   int i = 0;
  1014.   while(map[i].apiConstant != apiConstant){
  1015.     if(map[i].kernelConstant == -1 &&
  1016.        map[i].apiConstant == -1){
  1017.       return def;
  1018.     }
  1019.     i++;
  1020.   }
  1021.   return map[i].kernelConstant;
  1022. }
  1023. static const
  1024. ApiKernelMapping 
  1025. fragmentTypeMapping[] = {
  1026.   { DictTabInfo::AllNodesSmallTable,  NdbDictionary::Object::FragAllSmall },
  1027.   { DictTabInfo::AllNodesMediumTable, NdbDictionary::Object::FragAllMedium },
  1028.   { DictTabInfo::AllNodesLargeTable,  NdbDictionary::Object::FragAllLarge },
  1029.   { DictTabInfo::SingleFragment,      NdbDictionary::Object::FragSingle },
  1030.   { -1, -1 }
  1031. };
  1032. static const
  1033. ApiKernelMapping
  1034. objectTypeMapping[] = {
  1035.   { DictTabInfo::SystemTable,        NdbDictionary::Object::SystemTable },
  1036.   { DictTabInfo::UserTable,          NdbDictionary::Object::UserTable },
  1037.   { DictTabInfo::UniqueHashIndex,    NdbDictionary::Object::UniqueHashIndex },
  1038.   { DictTabInfo::HashIndex,          NdbDictionary::Object::HashIndex }, 
  1039.   { DictTabInfo::UniqueOrderedIndex, NdbDictionary::Object::UniqueOrderedIndex },
  1040.   { DictTabInfo::OrderedIndex,       NdbDictionary::Object::OrderedIndex },
  1041.   { DictTabInfo::HashIndexTrigger,   NdbDictionary::Object::HashIndexTrigger },
  1042.   { DictTabInfo::IndexTrigger,       NdbDictionary::Object::IndexTrigger },
  1043.   { DictTabInfo::SubscriptionTrigger,NdbDictionary::Object::SubscriptionTrigger },
  1044.   { DictTabInfo::ReadOnlyConstraint ,NdbDictionary::Object::ReadOnlyConstraint },
  1045.   { -1, -1 }
  1046. };
  1047. static const
  1048. ApiKernelMapping
  1049. objectStateMapping[] = {
  1050.   { DictTabInfo::StateOffline,       NdbDictionary::Object::StateOffline },
  1051.   { DictTabInfo::StateBuilding,      NdbDictionary::Object::StateBuilding },
  1052.   { DictTabInfo::StateDropping,      NdbDictionary::Object::StateDropping },
  1053.   { DictTabInfo::StateOnline,        NdbDictionary::Object::StateOnline },
  1054.   { DictTabInfo::StateBackup,        NdbDictionary::Object::StateBackup },
  1055.   { DictTabInfo::StateBroken,        NdbDictionary::Object::StateBroken }, 
  1056.   { -1, -1 }
  1057. };
  1058. static const
  1059. ApiKernelMapping
  1060. objectStoreMapping[] = {
  1061.   { DictTabInfo::StoreTemporary,     NdbDictionary::Object::StoreTemporary },
  1062.   { DictTabInfo::StorePermanent,     NdbDictionary::Object::StorePermanent },
  1063.   { -1, -1 }
  1064. };
  1065. static const
  1066. ApiKernelMapping
  1067. indexTypeMapping[] = {
  1068.   { DictTabInfo::UniqueHashIndex,    NdbDictionary::Index::UniqueHashIndex },  
  1069.   { DictTabInfo::HashIndex,          NdbDictionary::Index::HashIndex },  
  1070.   { DictTabInfo::UniqueOrderedIndex, NdbDictionary::Index::UniqueOrderedIndex},
  1071.   { DictTabInfo::OrderedIndex,       NdbDictionary::Index::OrderedIndex },
  1072.   { -1, -1 }
  1073. };
  1074. // TODO: remove, api-kernel type codes must match now
  1075. static const
  1076. ApiKernelMapping
  1077. columnTypeMapping[] = {
  1078.   { DictTabInfo::ExtTinyint,         NdbDictionary::Column::Tinyint },
  1079.   { DictTabInfo::ExtTinyunsigned,    NdbDictionary::Column::Tinyunsigned },
  1080.   { DictTabInfo::ExtSmallint,        NdbDictionary::Column::Smallint },
  1081.   { DictTabInfo::ExtSmallunsigned,   NdbDictionary::Column::Smallunsigned },
  1082.   { DictTabInfo::ExtMediumint,       NdbDictionary::Column::Mediumint },
  1083.   { DictTabInfo::ExtMediumunsigned,  NdbDictionary::Column::Mediumunsigned },
  1084.   { DictTabInfo::ExtInt,             NdbDictionary::Column::Int },
  1085.   { DictTabInfo::ExtUnsigned,        NdbDictionary::Column::Unsigned },
  1086.   { DictTabInfo::ExtBigint,          NdbDictionary::Column::Bigint },
  1087.   { DictTabInfo::ExtBigunsigned,     NdbDictionary::Column::Bigunsigned },
  1088.   { DictTabInfo::ExtFloat,           NdbDictionary::Column::Float },
  1089.   { DictTabInfo::ExtDouble,          NdbDictionary::Column::Double },
  1090.   { DictTabInfo::ExtOlddecimal,      NdbDictionary::Column::Olddecimal },
  1091.   { DictTabInfo::ExtOlddecimalunsigned, NdbDictionary::Column::Olddecimalunsigned },
  1092.   { DictTabInfo::ExtChar,            NdbDictionary::Column::Char },
  1093.   { DictTabInfo::ExtVarchar,         NdbDictionary::Column::Varchar },
  1094.   { DictTabInfo::ExtBinary,          NdbDictionary::Column::Binary },
  1095.   { DictTabInfo::ExtVarbinary,       NdbDictionary::Column::Varbinary },
  1096.   { DictTabInfo::ExtDatetime,        NdbDictionary::Column::Datetime },
  1097.   { DictTabInfo::ExtDate,            NdbDictionary::Column::Date },
  1098.   { DictTabInfo::ExtBlob,            NdbDictionary::Column::Blob },
  1099.   { DictTabInfo::ExtText,            NdbDictionary::Column::Text },
  1100.   { DictTabInfo::ExtTime,            NdbDictionary::Column::Time },
  1101.   { DictTabInfo::ExtYear,            NdbDictionary::Column::Year },
  1102.   { DictTabInfo::ExtTimestamp,       NdbDictionary::Column::Timestamp },
  1103.   { -1, -1 }
  1104. };
  1105. int
  1106. NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
  1107.  const Uint32 * data, Uint32 len,
  1108.  bool fullyQualifiedNames)
  1109. {
  1110.   SimplePropertiesLinearReader it(data, len);
  1111.   DictTabInfo::Table tableDesc; tableDesc.init();
  1112.   SimpleProperties::UnpackStatus s;
  1113.   s = SimpleProperties::unpack(it, &tableDesc, 
  1114.        DictTabInfo::TableMapping, 
  1115.        DictTabInfo::TableMappingSize, 
  1116.        true, true);
  1117.   
  1118.   if(s != SimpleProperties::Break){
  1119.     return 703;
  1120.   }
  1121.   const char * internalName = tableDesc.TableName;
  1122.   const char * externalName = Ndb::externalizeTableName(internalName, fullyQualifiedNames);
  1123.   NdbTableImpl * impl = new NdbTableImpl();
  1124.   impl->m_tableId = tableDesc.TableId;
  1125.   impl->m_version = tableDesc.TableVersion;
  1126.   impl->m_status = NdbDictionary::Object::Retrieved;
  1127.   impl->m_internalName.assign(internalName);
  1128.   impl->m_externalName.assign(externalName);
  1129.   impl->m_frm.assign(tableDesc.FrmData, tableDesc.FrmLen);
  1130.   
  1131.   impl->m_fragmentType = (NdbDictionary::Object::FragmentType)
  1132.     getApiConstant(tableDesc.FragmentType, 
  1133.    fragmentTypeMapping, 
  1134.    (Uint32)NdbDictionary::Object::FragUndefined);
  1135.   
  1136.   impl->m_logging = tableDesc.TableLoggedFlag;
  1137.   impl->m_kvalue = tableDesc.TableKValue;
  1138.   impl->m_minLoadFactor = tableDesc.MinLoadFactor;
  1139.   impl->m_maxLoadFactor = tableDesc.MaxLoadFactor;
  1140.   impl->m_fragmentCount = tableDesc.FragmentCount;
  1141.   impl->m_indexType = (NdbDictionary::Index::Type)
  1142.     getApiConstant(tableDesc.TableType,
  1143.    indexTypeMapping,
  1144.    NdbDictionary::Index::Undefined);
  1145.   
  1146.   if(impl->m_indexType == NdbDictionary::Index::Undefined){
  1147.   } else {
  1148.     const char * externalPrimary = 
  1149.       Ndb::externalizeTableName(tableDesc.PrimaryTable, fullyQualifiedNames);
  1150.     impl->m_primaryTable.assign(externalPrimary);
  1151.   }
  1152.   
  1153.   Uint32 keyInfoPos = 0;
  1154.   Uint32 keyCount = 0;
  1155.   Uint32 blobCount = 0;
  1156.   
  1157.   for(Uint32 i = 0; i < tableDesc.NoOfAttributes; i++) {
  1158.     DictTabInfo::Attribute attrDesc; attrDesc.init();
  1159.     s = SimpleProperties::unpack(it, 
  1160.  &attrDesc, 
  1161.  DictTabInfo::AttributeMapping, 
  1162.  DictTabInfo::AttributeMappingSize, 
  1163.  true, true);
  1164.     if(s != SimpleProperties::Break){
  1165.       delete impl;
  1166.       return 703;
  1167.     }
  1168.     
  1169.     NdbColumnImpl * col = new NdbColumnImpl();
  1170.     col->m_attrId = attrDesc.AttributeId;
  1171.     col->setName(attrDesc.AttributeName);
  1172.     col->m_type = (NdbDictionary::Column::Type)
  1173.       getApiConstant(attrDesc.AttributeExtType,
  1174.                      columnTypeMapping,
  1175.                      NdbDictionary::Column::Undefined);
  1176.     if (col->m_type == NdbDictionary::Column::Undefined) {
  1177.       delete impl;
  1178.       return 703;
  1179.     }
  1180.     col->m_extType = attrDesc.AttributeExtType;
  1181.     col->m_precision = (attrDesc.AttributeExtPrecision & 0xFFFF);
  1182.     col->m_scale = attrDesc.AttributeExtScale;
  1183.     col->m_length = attrDesc.AttributeExtLength;
  1184.     // charset in upper half of precision
  1185.     unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16);
  1186.     // charset is defined exactly for char types
  1187.     if (col->getCharType() != (cs_number != 0)) {
  1188.       delete impl;
  1189.       return 703;
  1190.     }
  1191.     if (col->getCharType()) {
  1192.       col->m_cs = get_charset(cs_number, MYF(0));
  1193.       if (col->m_cs == NULL) {
  1194.         delete impl;
  1195.         return 743;
  1196.       }
  1197.     }
  1198.     // translate to old kernel types and sizes
  1199.     if (! attrDesc.translateExtType()) {
  1200.       delete impl;
  1201.       return 703;
  1202.     }
  1203.     col->m_attrType =attrDesc.AttributeType;
  1204.     col->m_attrSize = (1 << attrDesc.AttributeSize) / 8;
  1205.     col->m_arraySize = attrDesc.AttributeArraySize;
  1206.     
  1207.     col->m_pk = attrDesc.AttributeKeyFlag;
  1208.     col->m_tupleKey = 0;
  1209.     col->m_distributionKey = attrDesc.AttributeDKey;
  1210.     col->m_distributionGroup = attrDesc.AttributeDGroup;
  1211.     col->m_distributionGroupBits = 16;
  1212.     col->m_nullable = attrDesc.AttributeNullableFlag;
  1213.     col->m_indexOnly = (attrDesc.AttributeStoredInd ? false : true);
  1214.     col->m_autoIncrement = (attrDesc.AttributeAutoIncrement ? true : false);
  1215.     col->m_autoIncrementInitialValue = ~0;
  1216.     col->m_defaultValue.assign(attrDesc.AttributeDefaultValue);
  1217.     if(attrDesc.AttributeKeyFlag){
  1218.       col->m_keyInfoPos = keyInfoPos + 1;
  1219.       keyInfoPos += ((col->m_attrSize * col->m_arraySize + 3) / 4);
  1220.       keyCount++;
  1221.     } else {
  1222.       col->m_keyInfoPos = 0;
  1223.     }
  1224.     if (col->getBlobType())
  1225.       blobCount++;
  1226.     NdbColumnImpl * null = 0;
  1227.     impl->m_columns.fill(attrDesc.AttributeId, null);
  1228.     if(impl->m_columns[attrDesc.AttributeId] != 0){
  1229.       delete col;
  1230.       delete impl;
  1231.       return 703;
  1232.     }
  1233.     impl->m_columns[attrDesc.AttributeId] = col;
  1234.     it.next();
  1235.   }
  1236.   impl->m_noOfKeys = keyCount;
  1237.   impl->m_keyLenInWords = keyInfoPos;
  1238.   impl->m_sizeOfKeysInWords = keyInfoPos;
  1239.   impl->m_noOfBlobs = blobCount;
  1240.   * ret = impl;
  1241.   return 0;
  1242. }
  1243. /*****************************************************************
  1244.  * Create table and alter table
  1245.  */
  1246. int
  1247. NdbDictionaryImpl::createTable(NdbTableImpl &t)
  1248.   if (m_receiver.createTable(m_ndb, t) != 0)
  1249.     return -1;
  1250.   if (t.m_noOfBlobs == 0)
  1251.     return 0;
  1252.   // update table def from DICT
  1253.   Ndb_local_table_info *info=
  1254.     get_local_table_info(t.m_internalName.c_str(),false);
  1255.   if (info == NULL) {
  1256.     m_error.code = 709;
  1257.     return -1;
  1258.   }
  1259.   if (createBlobTables(*(info->m_table_impl)) != 0) {
  1260.     int save_code = m_error.code;
  1261.     (void)dropTable(t);
  1262.     m_error.code = save_code;
  1263.     return -1;
  1264.   }
  1265.   return 0;
  1266. }
  1267. int
  1268. NdbDictionaryImpl::createBlobTables(NdbTableImpl &t)
  1269. {
  1270.   for (unsigned i = 0; i < t.m_columns.size(); i++) {
  1271.     NdbColumnImpl & c = *t.m_columns[i];
  1272.     if (! c.getBlobType() || c.getPartSize() == 0)
  1273.       continue;
  1274.     NdbTableImpl bt;
  1275.     NdbBlob::getBlobTable(bt, &t, &c);
  1276.     if (createTable(bt) != 0)
  1277.       return -1;
  1278.     // Save BLOB table handle
  1279.     Ndb_local_table_info *info=
  1280.       get_local_table_info(bt.m_internalName.c_str(),false);
  1281.     if (info == 0) {
  1282.       return -1;
  1283.     }
  1284.     c.m_blobTable = info->m_table_impl;
  1285.   }
  1286.   
  1287.   return 0;
  1288. }
  1289. int
  1290. NdbDictionaryImpl::addBlobTables(NdbTableImpl &t)
  1291. {
  1292.   unsigned n= t.m_noOfBlobs;
  1293.   // optimized for blob column being the last one
  1294.   // and not looking for more than one if not neccessary
  1295.   for (unsigned i = t.m_columns.size(); i > 0 && n > 0;) {
  1296.     i--;
  1297.     NdbColumnImpl & c = *t.m_columns[i];
  1298.     if (! c.getBlobType() || c.getPartSize() == 0)
  1299.       continue;
  1300.     n--;
  1301.     char btname[NdbBlobImpl::BlobTableNameSize];
  1302.     NdbBlob::getBlobTableName(btname, &t, &c);
  1303.     // Save BLOB table handle
  1304.     NdbTableImpl * cachedBlobTable = getTable(btname);
  1305.     if (cachedBlobTable == 0) {
  1306.       return -1;
  1307.     }
  1308.     c.m_blobTable = cachedBlobTable;
  1309.   }
  1310.   
  1311.   return 0;
  1312. }
  1313. int 
  1314. NdbDictInterface::createTable(Ndb & ndb,
  1315.       NdbTableImpl & impl)
  1316. {
  1317.   return createOrAlterTable(ndb, impl, false);
  1318. }
  1319. int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
  1320. {
  1321.   BaseString internalName = impl.m_internalName;
  1322.   const char * originalInternalName = internalName.c_str();
  1323.   BaseString externalName = impl.m_externalName;
  1324.   const char * originalExternalName = externalName.c_str();
  1325.   DBUG_ENTER("NdbDictionaryImpl::alterTable");
  1326.   Ndb_local_table_info * local = 0;
  1327.   if((local= get_local_table_info(originalInternalName, false)) == 0)
  1328.   {
  1329.     m_error.code = 709;
  1330.     DBUG_RETURN(-1);
  1331.   }
  1332.   // Alter the table
  1333.   int ret = m_receiver.alterTable(m_ndb, impl);
  1334.   if(ret == 0){
  1335.     // Remove cached information and let it be refreshed at next access
  1336.     m_globalHash->lock();
  1337.     local->m_table_impl->m_status = NdbDictionary::Object::Invalid;
  1338.     m_globalHash->drop(local->m_table_impl);
  1339.     m_globalHash->unlock();
  1340.     m_localHash.drop(originalInternalName);
  1341.   }
  1342.   DBUG_RETURN(ret);
  1343. }
  1344. int 
  1345. NdbDictInterface::alterTable(Ndb & ndb,
  1346.       NdbTableImpl & impl)
  1347. {
  1348.   return createOrAlterTable(ndb, impl, true);
  1349. }
  1350. int 
  1351. NdbDictInterface::createOrAlterTable(Ndb & ndb,
  1352.      NdbTableImpl & impl,
  1353.      bool alter)
  1354. {
  1355.   DBUG_ENTER("NdbDictInterface::createOrAlterTable");
  1356.   unsigned i;
  1357.   if((unsigned)impl.getNoOfPrimaryKeys() > NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY){
  1358.     m_error.code = 4317;
  1359.     DBUG_RETURN(-1);
  1360.   }
  1361.   unsigned sz = impl.m_columns.size();
  1362.   if (sz > NDB_MAX_ATTRIBUTES_IN_TABLE){
  1363.     m_error.code = 4318;
  1364.     DBUG_RETURN(-1);
  1365.   }
  1366.   impl.copyNewProperties();
  1367.   //validate();
  1368.   //aggregate();
  1369.   const char * internalName = 
  1370.     ndb.internalizeTableName(impl.m_externalName.c_str());
  1371.   impl.m_internalName.assign(internalName);
  1372.   UtilBufferWriter w(m_buffer);
  1373.   DictTabInfo::Table tmpTab; tmpTab.init();
  1374.   BaseString::snprintf(tmpTab.TableName, 
  1375.    sizeof(tmpTab.TableName), 
  1376.    internalName);
  1377.   bool haveAutoIncrement = false;
  1378.   Uint64 autoIncrementValue = 0;
  1379.   for(i = 0; i<sz; i++){
  1380.     const NdbColumnImpl * col = impl.m_columns[i];
  1381.     if(col == 0)
  1382.       continue;
  1383.     if (col->m_autoIncrement) {
  1384.       if (haveAutoIncrement) {
  1385.         m_error.code = 4335;
  1386.         DBUG_RETURN(-1);
  1387.       }
  1388.       haveAutoIncrement = true;
  1389.       autoIncrementValue = col->m_autoIncrementInitialValue;
  1390.      }
  1391.   }
  1392.   // Check max length of frm data
  1393.   if (impl.m_frm.length() > MAX_FRM_DATA_SIZE){
  1394.     m_error.code = 1229;
  1395.     DBUG_RETURN(-1);
  1396.   }
  1397.   tmpTab.FrmLen = impl.m_frm.length();
  1398.   memcpy(tmpTab.FrmData, impl.m_frm.get_data(), impl.m_frm.length());
  1399.   tmpTab.TableLoggedFlag = impl.m_logging;
  1400.   tmpTab.TableKValue = impl.m_kvalue;
  1401.   tmpTab.MinLoadFactor = impl.m_minLoadFactor;
  1402.   tmpTab.MaxLoadFactor = impl.m_maxLoadFactor;
  1403.   tmpTab.TableType = DictTabInfo::UserTable;
  1404.   tmpTab.NoOfAttributes = sz;
  1405.   
  1406.   tmpTab.FragmentType = getKernelConstant(impl.m_fragmentType,
  1407.   fragmentTypeMapping,
  1408.   DictTabInfo::AllNodesSmallTable);
  1409.   tmpTab.TableVersion = rand();
  1410.   SimpleProperties::UnpackStatus s;
  1411.   s = SimpleProperties::pack(w, 
  1412.      &tmpTab,
  1413.      DictTabInfo::TableMapping, 
  1414.      DictTabInfo::TableMappingSize, true);
  1415.   
  1416.   if(s != SimpleProperties::Eof){
  1417.     abort();
  1418.   }
  1419.   
  1420.   for(i = 0; i<sz; i++){
  1421.     const NdbColumnImpl * col = impl.m_columns[i];
  1422.     if(col == 0)
  1423.       continue;
  1424.     
  1425.     DictTabInfo::Attribute tmpAttr; tmpAttr.init();
  1426.     BaseString::snprintf(tmpAttr.AttributeName, sizeof(tmpAttr.AttributeName), 
  1427.      col->m_name.c_str());
  1428.     tmpAttr.AttributeId = i;
  1429.     tmpAttr.AttributeKeyFlag = col->m_pk || col->m_tupleKey;
  1430.     tmpAttr.AttributeNullableFlag = col->m_nullable;
  1431.     tmpAttr.AttributeStoredInd = (col->m_indexOnly ? 0 : 1);
  1432.     tmpAttr.AttributeDKey = col->m_distributionKey;
  1433.     tmpAttr.AttributeDGroup = col->m_distributionGroup;
  1434.     tmpAttr.AttributeExtType =
  1435.       getKernelConstant(col->m_type,
  1436.                         columnTypeMapping,
  1437.                         DictTabInfo::ExtUndefined);
  1438.     tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF);
  1439.     tmpAttr.AttributeExtScale = col->m_scale;
  1440.     tmpAttr.AttributeExtLength = col->m_length;
  1441.     // charset is defined exactly for char types
  1442.     if (col->getCharType() != (col->m_cs != NULL)) {
  1443.       m_error.code = 703;
  1444.       DBUG_RETURN(-1);
  1445.     }
  1446.     // primary key type check
  1447.     if (col->m_pk && ! NdbSqlUtil::usable_in_pk(col->m_type, col->m_cs)) {
  1448.       m_error.code = 743;
  1449.       DBUG_RETURN(-1);
  1450.     }
  1451.     // charset in upper half of precision
  1452.     if (col->getCharType()) {
  1453.       tmpAttr.AttributeExtPrecision |= (col->m_cs->number << 16);
  1454.     }
  1455.     // DICT will ignore and recompute this
  1456.     (void)tmpAttr.translateExtType();
  1457.     tmpAttr.AttributeAutoIncrement = col->m_autoIncrement;
  1458.     BaseString::snprintf(tmpAttr.AttributeDefaultValue, 
  1459.      sizeof(tmpAttr.AttributeDefaultValue),
  1460.      col->m_defaultValue.c_str());
  1461.     s = SimpleProperties::pack(w, 
  1462.        &tmpAttr,
  1463.        DictTabInfo::AttributeMapping, 
  1464.        DictTabInfo::AttributeMappingSize, true);
  1465.     w.add(DictTabInfo::AttributeEnd, 1);
  1466.   }
  1467.   NdbApiSignal tSignal(m_reference);
  1468.   tSignal.theReceiversBlockNumber = DBDICT;
  1469.   
  1470.   LinearSectionPtr ptr[3];
  1471.   ptr[0].p = (Uint32*)m_buffer.get_data();
  1472.   ptr[0].sz = m_buffer.length() / 4;
  1473.   int ret;
  1474.   if (alter)
  1475.   {
  1476.     AlterTableReq * const req = 
  1477.       CAST_PTR(AlterTableReq, tSignal.getDataPtrSend());
  1478.     
  1479.     req->senderRef = m_reference;
  1480.     req->senderData = 0;
  1481.     req->changeMask = impl.m_changeMask;
  1482.     req->tableId = impl.m_tableId;
  1483.     req->tableVersion = impl.m_version;;
  1484.     tSignal.theVerId_signalNumber   = GSN_ALTER_TABLE_REQ;
  1485.     tSignal.theLength = AlterTableReq::SignalLength;
  1486.     ret= alterTable(&tSignal, ptr);
  1487.   }
  1488.   else
  1489.   {
  1490.     CreateTableReq * const req = 
  1491.       CAST_PTR(CreateTableReq, tSignal.getDataPtrSend());
  1492.     
  1493.     req->senderRef = m_reference;
  1494.     req->senderData = 0;
  1495.     tSignal.theVerId_signalNumber   = GSN_CREATE_TABLE_REQ;
  1496.     tSignal.theLength = CreateTableReq::SignalLength;
  1497.     ret= createTable(&tSignal, ptr);
  1498.     if (ret)
  1499.       DBUG_RETURN(ret);
  1500.     if (haveAutoIncrement) {
  1501.       if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(),
  1502.      autoIncrementValue)) {
  1503. if (ndb.theError.code == 0) {
  1504.   m_error.code = 4336;
  1505.   ndb.theError = m_error;
  1506. } else
  1507.   m_error= ndb.theError;
  1508. ret = -1; // errorcode set in initialize_autoincrement
  1509.       }
  1510.     }
  1511.   }
  1512.   DBUG_RETURN(ret);
  1513. }
  1514. int
  1515. NdbDictInterface::createTable(NdbApiSignal* signal, LinearSectionPtr ptr[3])
  1516. {
  1517. #if DEBUG_PRINT
  1518.   ndbout_c("BufferLen = %d", ptr[0].sz);
  1519.   SimplePropertiesLinearReader r(ptr[0].p, ptr[0].sz);
  1520.   r.printAll(ndbout);
  1521. #endif
  1522.   const int noErrCodes = 2;
  1523.   int errCodes[noErrCodes] = 
  1524.      {CreateTableRef::Busy,
  1525.       CreateTableRef::NotMaster};
  1526.   return dictSignal(signal,ptr,1,
  1527.     1/*use masternode id*/,
  1528.     100,
  1529.     WAIT_CREATE_INDX_REQ,
  1530.     WAITFOR_RESPONSE_TIMEOUT,
  1531.     errCodes,noErrCodes);
  1532. }
  1533. void
  1534. NdbDictInterface::execCREATE_TABLE_CONF(NdbApiSignal * signal,
  1535. LinearSectionPtr ptr[3])
  1536. {
  1537.   const CreateTableConf* const conf=
  1538.     CAST_CONSTPTR(CreateTableConf, signal->getDataPtr());
  1539.   Uint32 tableId= conf->tableId;
  1540.   Uint32 tableVersion= conf->tableVersion;
  1541.   
  1542.   m_waiter.signal(NO_WAIT);  
  1543. }
  1544. void
  1545. NdbDictInterface::execCREATE_TABLE_REF(NdbApiSignal * signal,
  1546.        LinearSectionPtr ptr[3])
  1547. {
  1548.   const CreateTableRef* const ref=
  1549.     CAST_CONSTPTR(CreateTableRef, signal->getDataPtr());
  1550.   m_error.code = ref->errorCode;
  1551.   m_masterNodeId = ref->masterNodeId;
  1552.   m_waiter.signal(NO_WAIT);  
  1553. }
  1554. int
  1555. NdbDictInterface::alterTable(NdbApiSignal* signal, LinearSectionPtr ptr[3])
  1556. {
  1557. #if DEBUG_PRINT
  1558.   ndbout_c("BufferLen = %d", ptr[0].sz);
  1559.   SimplePropertiesLinearReader r(ptr[0].p, ptr[0].sz);
  1560.   r.printAll(ndbout);
  1561. #endif
  1562.   const int noErrCodes = 2;
  1563.   int errCodes[noErrCodes] =
  1564.     {AlterTableRef::NotMaster,
  1565.      AlterTableRef::Busy};
  1566.   int r = dictSignal(signal,ptr,1,
  1567.      1/*use masternode id*/,
  1568.      100,WAIT_ALTER_TAB_REQ,
  1569.      WAITFOR_RESPONSE_TIMEOUT,
  1570.      errCodes, noErrCodes);
  1571.   if(m_error.code == AlterTableRef::InvalidTableVersion) {
  1572.     // Clear caches and try again
  1573.     return INCOMPATIBLE_VERSION;
  1574.   }
  1575.   return r;
  1576. }
  1577. void
  1578. NdbDictInterface::execALTER_TABLE_CONF(NdbApiSignal * signal,
  1579.                                        LinearSectionPtr ptr[3])
  1580. {
  1581.   //AlterTableConf* const conf = CAST_CONSTPTR(AlterTableConf, signal->getDataPtr());
  1582.   m_waiter.signal(NO_WAIT);
  1583. }
  1584. void
  1585. NdbDictInterface::execALTER_TABLE_REF(NdbApiSignal * signal,
  1586.       LinearSectionPtr ptr[3])
  1587. {
  1588.   const AlterTableRef * const ref = 
  1589.     CAST_CONSTPTR(AlterTableRef, signal->getDataPtr());
  1590.   m_error.code = ref->errorCode;
  1591.   m_masterNodeId = ref->masterNodeId;
  1592.   m_waiter.signal(NO_WAIT);
  1593. }
  1594. /*****************************************************************
  1595.  * Drop table
  1596.  */
  1597. int
  1598. NdbDictionaryImpl::dropTable(const char * name)
  1599. {
  1600.   DBUG_ENTER("NdbDictionaryImpl::dropTable");
  1601.   DBUG_PRINT("enter",("name: %s", name));
  1602.   NdbTableImpl * tab = getTable(name);
  1603.   if(tab == 0){
  1604.     return -1;
  1605.   }
  1606.   int ret = dropTable(* tab);
  1607.   // If table stored in cache is incompatible with the one in the kernel
  1608.   // we must clear the cache and try again
  1609.   if (ret == INCOMPATIBLE_VERSION) {
  1610.     const char * internalTableName = m_ndb.internalizeTableName(name);
  1611.     DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName));
  1612.     m_localHash.drop(internalTableName);
  1613.     m_globalHash->lock();
  1614.     tab->m_status = NdbDictionary::Object::Invalid;
  1615.     m_globalHash->drop(tab);
  1616.     m_globalHash->unlock();   
  1617.     DBUG_RETURN(dropTable(name));
  1618.   }
  1619.   DBUG_RETURN(ret);
  1620. }
  1621. int
  1622. NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
  1623. {
  1624.   int res;
  1625.   const char * name = impl.getName();
  1626.   if(impl.m_status == NdbDictionary::Object::New){
  1627.     return dropTable(name);
  1628.   }
  1629.   if (impl.m_indexType != NdbDictionary::Index::Undefined) {
  1630.     m_receiver.m_error.code = 1228;
  1631.     return -1;
  1632.   }
  1633.   List list;
  1634.   if ((res = listIndexes(list, impl.m_tableId)) == -1){
  1635.     return -1;
  1636.   }
  1637.   for (unsigned i = 0; i < list.count; i++) {
  1638.     const List::Element& element = list.elements[i];
  1639.     if ((res = dropIndex(element.name, name)) == -1)
  1640.     {
  1641.       return -1;
  1642.     }
  1643.   }
  1644.   
  1645.   if (impl.m_noOfBlobs != 0) {
  1646.     if (dropBlobTables(impl) != 0){
  1647.       return -1;
  1648.     }
  1649.   }
  1650.   
  1651.   int ret = m_receiver.dropTable(impl);  
  1652.   if(ret == 0 || m_error.code == 709){
  1653.     const char * internalTableName = impl.m_internalName.c_str();
  1654.     
  1655.     m_localHash.drop(internalTableName);
  1656.     m_globalHash->lock();
  1657.     impl.m_status = NdbDictionary::Object::Invalid;
  1658.     m_globalHash->drop(&impl);
  1659.     m_globalHash->unlock();
  1660.     return 0;
  1661.   }
  1662.   
  1663.   return ret;
  1664. }
  1665. int
  1666. NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
  1667. {
  1668.   DBUG_ENTER("NdbDictionaryImpl::dropBlobTables");
  1669.   for (unsigned i = 0; i < t.m_columns.size(); i++) {
  1670.     NdbColumnImpl & c = *t.m_columns[i];
  1671.     if (! c.getBlobType() || c.getPartSize() == 0)
  1672.       continue;
  1673.     char btname[NdbBlobImpl::BlobTableNameSize];
  1674.     NdbBlob::getBlobTableName(btname, &t, &c);
  1675.     if (dropTable(btname) != 0) {
  1676.       if (m_error.code != 709){
  1677. DBUG_PRINT("exit",("error %u - exiting",m_error.code));
  1678.         DBUG_RETURN(-1);
  1679.       }
  1680.       DBUG_PRINT("info",("error %u - continuing",m_error.code));
  1681.     }
  1682.   }
  1683.   DBUG_RETURN(0);
  1684. }
  1685. int
  1686. NdbDictInterface::dropTable(const NdbTableImpl & impl)
  1687. {
  1688.   NdbApiSignal tSignal(m_reference);
  1689.   tSignal.theReceiversBlockNumber = DBDICT;
  1690.   tSignal.theVerId_signalNumber   = GSN_DROP_TABLE_REQ;
  1691.   tSignal.theLength = DropTableReq::SignalLength;
  1692.   
  1693.   DropTableReq * const req = CAST_PTR(DropTableReq, tSignal.getDataPtrSend());
  1694.   req->senderRef = m_reference;
  1695.   req->senderData = 0;
  1696.   req->tableId = impl.m_tableId;
  1697.   req->tableVersion = impl.m_version;
  1698.   return dropTable(&tSignal, 0);
  1699. }
  1700. int
  1701. NdbDictInterface::dropTable(NdbApiSignal* signal, LinearSectionPtr ptr[3])
  1702. {
  1703.   const int noErrCodes = 3;
  1704.   int errCodes[noErrCodes] =
  1705.          {DropTableRef::NoDropTableRecordAvailable,
  1706.           DropTableRef::NotMaster,
  1707.           DropTableRef::Busy};
  1708.   int r = dictSignal(signal,NULL,0,
  1709.      1/*use masternode id*/,
  1710.      100,WAIT_DROP_TAB_REQ,
  1711.      WAITFOR_RESPONSE_TIMEOUT,
  1712.      errCodes, noErrCodes);
  1713.   if(m_error.code == DropTableRef::InvalidTableVersion) {
  1714.     // Clear caches and try again
  1715.     return INCOMPATIBLE_VERSION;
  1716.   }
  1717.   return r;
  1718. }
  1719. void
  1720. NdbDictInterface::execDROP_TABLE_CONF(NdbApiSignal * signal,
  1721.        LinearSectionPtr ptr[3])
  1722. {
  1723.   //DropTableConf* const conf = CAST_CONSTPTR(DropTableConf, signal->getDataPtr());
  1724.   m_waiter.signal(NO_WAIT);  
  1725. }
  1726. void
  1727. NdbDictInterface::execDROP_TABLE_REF(NdbApiSignal * signal,
  1728.       LinearSectionPtr ptr[3])
  1729. {
  1730.   const DropTableRef* const ref = CAST_CONSTPTR(DropTableRef, signal->getDataPtr());
  1731.   m_error.code = ref->errorCode;
  1732.   m_masterNodeId = ref->masterNodeId;
  1733.   m_waiter.signal(NO_WAIT);  
  1734. }
  1735. int
  1736. NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
  1737. {
  1738.   const char * internalTableName = impl.m_internalName.c_str();
  1739.   m_localHash.drop(internalTableName);  
  1740.   m_globalHash->lock();
  1741.   impl.m_status = NdbDictionary::Object::Invalid;
  1742.   m_globalHash->drop(&impl);
  1743.   m_globalHash->unlock();
  1744.   return 0;
  1745. }
  1746. int
  1747. NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl)
  1748. {
  1749.   const char * internalTableName = impl.m_internalName.c_str();
  1750.   m_localHash.drop(internalTableName);  
  1751.   m_globalHash->lock();
  1752.   m_globalHash->release(&impl);
  1753.   m_globalHash->unlock();
  1754.   return 0;
  1755. }
  1756. /*****************************************************************
  1757.  * Get index info
  1758.  */
  1759. NdbIndexImpl*
  1760. NdbDictionaryImpl::getIndexImpl(const char * externalName, 
  1761. const char * internalName)
  1762. {
  1763.   Ndb_local_table_info * info = get_local_table_info(internalName,
  1764.      false);
  1765.   if(info == 0){
  1766.     m_error.code = 4243;
  1767.     return 0;
  1768.   }
  1769.   NdbTableImpl * tab = info->m_table_impl;
  1770.   if(tab->m_indexType == NdbDictionary::Index::Undefined){
  1771.     // Not an index
  1772.     m_error.code = 4243;
  1773.     return 0;
  1774.   }
  1775.   NdbTableImpl* prim = getTable(tab->m_primaryTable.c_str());
  1776.   if(prim == 0){
  1777.     m_error.code = 4243;
  1778.     return 0;
  1779.   }
  1780.   
  1781.   /**
  1782.    * Create index impl
  1783.    */
  1784.   NdbIndexImpl* idx;
  1785.   if(NdbDictInterface::create_index_obj_from_table(&idx, tab, prim) == 0){
  1786.     idx->m_table = tab;
  1787.     idx->m_externalName.assign(externalName);
  1788.     idx->m_internalName.assign(internalName);
  1789.     // TODO Assign idx to tab->m_index
  1790.     // Don't do it right now since assign can't asign a table with index
  1791.     // tab->m_index = idx;
  1792.     return idx;
  1793.   }
  1794.   return 0;
  1795. }
  1796. int
  1797. NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
  1798.       const NdbTableImpl* tab,
  1799.       const NdbTableImpl* prim){
  1800.   NdbIndexImpl *idx = new NdbIndexImpl();
  1801.   idx->m_version = tab->m_version;
  1802.   idx->m_status = tab->m_status;
  1803.   idx->m_indexId = tab->m_tableId;
  1804.   idx->m_externalName.assign(tab->getName());
  1805.   idx->m_tableName.assign(prim->m_externalName);
  1806.   idx->m_type = tab->m_indexType;
  1807.   idx->m_logging = tab->m_logging;
  1808.   // skip last attribute (NDB$PK or NDB$TNODE)
  1809.   for(unsigned i = 0; i+1<tab->m_columns.size(); i++){
  1810.     NdbColumnImpl* col = new NdbColumnImpl;
  1811.     // Copy column definition
  1812.     *col = *tab->m_columns[i];
  1813.     idx->m_columns.push_back(col);
  1814.     /**
  1815.      * reverse map
  1816.      */
  1817.     int key_id = prim->getColumn(col->getName())->getColumnNo();
  1818.     int fill = -1;
  1819.     idx->m_key_ids.fill(key_id, fill);
  1820.     idx->m_key_ids[key_id] = i;
  1821.     col->m_keyInfoPos = key_id;
  1822.   }
  1823.   * dst = idx;
  1824.   return 0;
  1825. }
  1826. /*****************************************************************
  1827.  * Create index
  1828.  */
  1829. int
  1830. NdbDictionaryImpl::createIndex(NdbIndexImpl &ix)
  1831. {
  1832.   NdbTableImpl* tab = getTable(ix.getTable());
  1833.   if(tab == 0){
  1834.     m_error.code = 4249;
  1835.     return -1;
  1836.   }
  1837.   
  1838.   return m_receiver.createIndex(m_ndb, ix, * tab);
  1839. }
  1840. int 
  1841. NdbDictInterface::createIndex(Ndb & ndb,
  1842.       NdbIndexImpl & impl, 
  1843.       const NdbTableImpl & table)
  1844. {
  1845.   //validate();
  1846.   //aggregate();
  1847.   unsigned i;
  1848.   UtilBufferWriter w(m_buffer);
  1849.   const size_t len = strlen(impl.m_externalName.c_str()) + 1;
  1850.   if(len > MAX_TAB_NAME_SIZE) {
  1851.     m_error.code = 4241;
  1852.     return -1;
  1853.   }
  1854.   const char * internalName = 
  1855.     ndb.internalizeIndexName(&table, impl.getName());
  1856.   
  1857.   impl.m_internalName.assign(internalName);
  1858.   w.add(DictTabInfo::TableName, internalName);
  1859.   w.add(DictTabInfo::TableLoggedFlag, impl.m_logging);
  1860.   NdbApiSignal tSignal(m_reference);
  1861.   tSignal.theReceiversBlockNumber = DBDICT;
  1862.   tSignal.theVerId_signalNumber   = GSN_CREATE_INDX_REQ;
  1863.   tSignal.theLength = CreateIndxReq::SignalLength;
  1864.   
  1865.   CreateIndxReq * const req = CAST_PTR(CreateIndxReq, tSignal.getDataPtrSend());
  1866.   
  1867.   req->setUserRef(m_reference);
  1868.   req->setConnectionPtr(0);
  1869.   req->setRequestType(CreateIndxReq::RT_USER);
  1870.   
  1871.   Uint32 it = getKernelConstant(impl.m_type,
  1872. indexTypeMapping,
  1873. DictTabInfo::UndefTableType);
  1874.   
  1875.   if(it == DictTabInfo::UndefTableType){
  1876.     m_error.code = 4250;
  1877.     return -1;
  1878.   }
  1879.   req->setIndexType((DictTabInfo::TableType) it);
  1880.   
  1881.   req->setTableId(table.m_tableId);
  1882.   req->setOnline(true);
  1883.   AttributeList attributeList;
  1884.   attributeList.sz = impl.m_columns.size();
  1885.   for(i = 0; i<attributeList.sz; i++){
  1886.     const NdbColumnImpl* col = 
  1887.       table.getColumn(impl.m_columns[i]->m_name.c_str());
  1888.     if(col == 0){
  1889.       m_error.code = 4247;
  1890.       return -1;
  1891.     }
  1892.     // Copy column definition
  1893.     *impl.m_columns[i] = *col;
  1894.     if(col->m_pk && col->m_indexOnly){
  1895.       m_error.code = 4245;
  1896.       return -1;
  1897.     }
  1898.     // index key type check
  1899.     if (it == DictTabInfo::UniqueHashIndex &&
  1900.         ! NdbSqlUtil::usable_in_hash_index(col->m_type, col->m_cs) ||
  1901.         it == DictTabInfo::OrderedIndex &&
  1902.         ! NdbSqlUtil::usable_in_ordered_index(col->m_type, col->m_cs)) {
  1903.       m_error.code = 743;
  1904.       return -1;
  1905.     }
  1906.     attributeList.id[i] = col->m_attrId;
  1907.   }
  1908.   if (it == DictTabInfo::UniqueHashIndex) {
  1909.     // Sort index attributes according to primary table (using insertion sort)
  1910.     for(i = 1; i < attributeList.sz; i++) {
  1911.       unsigned int temp = attributeList.id[i];
  1912.       unsigned int j = i;
  1913.       while((j > 0) && (attributeList.id[j - 1] > temp)) {
  1914. attributeList.id[j] = attributeList.id[j - 1];
  1915. j--;
  1916.       }
  1917.       attributeList.id[j] = temp;
  1918.     }
  1919.     // Check for illegal duplicate attributes
  1920.     for(i = 0; i<attributeList.sz; i++) {
  1921.       if ((i != (attributeList.sz - 1)) && 
  1922.   (attributeList.id[i] == attributeList.id[i+1])) {
  1923. m_error.code = 4258;
  1924. return -1;
  1925.       }
  1926.     }
  1927.   }
  1928.   LinearSectionPtr ptr[3];
  1929.   ptr[0].p = (Uint32*)&attributeList;
  1930.   ptr[0].sz = 1 + attributeList.sz;
  1931.   ptr[1].p = (Uint32*)m_buffer.get_data();
  1932.   ptr[1].sz = m_buffer.length() >> 2;                //BUG?
  1933.   return createIndex(&tSignal, ptr);
  1934. }
  1935. int
  1936. NdbDictInterface::createIndex(NdbApiSignal* signal, 
  1937.       LinearSectionPtr ptr[3])
  1938. {
  1939.   const int noErrCodes = 2;
  1940.   int errCodes[noErrCodes] = {CreateIndxRef::Busy, CreateIndxRef::NotMaster};
  1941.   return dictSignal(signal,ptr,2,
  1942.     1 /*use masternode id*/,
  1943.     100,
  1944.     WAIT_CREATE_INDX_REQ,
  1945.     -1,
  1946.     errCodes,noErrCodes);
  1947. }
  1948. void
  1949. NdbDictInterface::execCREATE_INDX_CONF(NdbApiSignal * signal,
  1950.        LinearSectionPtr ptr[3])
  1951. {
  1952.   //CreateTableConf* const conf = CAST_CONSTPTR(CreateTableConf, signal->getDataPtr());
  1953.   
  1954.   m_waiter.signal(NO_WAIT);  
  1955. }
  1956. void
  1957. NdbDictInterface::execCREATE_INDX_REF(NdbApiSignal * signal,
  1958.       LinearSectionPtr ptr[3])
  1959. {
  1960.   const CreateIndxRef* const ref = CAST_CONSTPTR(CreateIndxRef, signal->getDataPtr());
  1961.   m_error.code = ref->getErrorCode();
  1962.   if(m_error.code == ref->NotMaster)
  1963.     m_masterNodeId= ref->masterNodeId;
  1964.   m_waiter.signal(NO_WAIT);  
  1965. }
  1966. /*****************************************************************
  1967.  * Drop index
  1968.  */
  1969. int
  1970. NdbDictionaryImpl::dropIndex(const char * indexName, 
  1971.      const char * tableName)
  1972. {
  1973.   NdbIndexImpl * idx = getIndex(indexName, tableName);
  1974.   if (idx == 0) {
  1975.     m_error.code = 4243;
  1976.     return -1;
  1977.   }
  1978.   int ret = dropIndex(*idx, tableName);
  1979.   // If index stored in cache is incompatible with the one in the kernel
  1980.   // we must clear the cache and try again
  1981.   if (ret == INCOMPATIBLE_VERSION) {
  1982.     const char * internalIndexName = (tableName)
  1983.       ?
  1984.       m_ndb.internalizeIndexName(getTable(tableName), indexName)
  1985.       :
  1986.       m_ndb.internalizeTableName(indexName); // Index is also a table
  1987.     
  1988.     m_localHash.drop(internalIndexName);
  1989.     m_globalHash->lock();
  1990.     idx->m_table->m_status = NdbDictionary::Object::Invalid;
  1991.     m_globalHash->drop(idx->m_table);
  1992.     m_globalHash->unlock();   
  1993.     return dropIndex(indexName, tableName);
  1994.   }
  1995.   
  1996.   return ret;
  1997. }
  1998. int
  1999. NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
  2000. {
  2001.   const char * indexName = impl.getName();
  2002.   if (tableName || m_ndb.usingFullyQualifiedNames()) {
  2003.     NdbTableImpl * timpl = impl.m_table;
  2004.     
  2005.     if (timpl == 0) {
  2006.       m_error.code = 709;
  2007.       return -1;
  2008.     }
  2009.     const char * internalIndexName = (tableName)
  2010.       ?
  2011.       m_ndb.internalizeIndexName(getTable(tableName), indexName)
  2012.       :
  2013.       m_ndb.internalizeTableName(indexName); // Index is also a table
  2014.     if(impl.m_status == NdbDictionary::Object::New){
  2015.       return dropIndex(indexName, tableName);
  2016.     }
  2017.     
  2018.     int ret = m_receiver.dropIndex(impl, *timpl);
  2019.     if(ret == 0){
  2020.       m_localHash.drop(internalIndexName);
  2021.       m_globalHash->lock();
  2022.       impl.m_table->m_status = NdbDictionary::Object::Invalid;
  2023.       m_globalHash->drop(impl.m_table);
  2024.       m_globalHash->unlock();
  2025.     }
  2026.     return ret;
  2027.   }
  2028.   m_error.code = 4243;
  2029.   return -1;
  2030. }
  2031. int
  2032. NdbDictInterface::dropIndex(const NdbIndexImpl & impl, 
  2033.     const NdbTableImpl & timpl)
  2034. {
  2035.   NdbApiSignal tSignal(m_reference);
  2036.   tSignal.theReceiversBlockNumber = DBDICT;
  2037.   tSignal.theVerId_signalNumber   = GSN_DROP_INDX_REQ;
  2038.   tSignal.theLength = DropIndxReq::SignalLength;
  2039.   DropIndxReq * const req = CAST_PTR(DropIndxReq, tSignal.getDataPtrSend());
  2040.   req->setUserRef(m_reference);
  2041.   req->setConnectionPtr(0);
  2042.   req->setRequestType(DropIndxReq::RT_USER);
  2043.   req->setTableId(~0);  // DICT overwrites
  2044.   req->setIndexId(timpl.m_tableId);
  2045.   req->setIndexVersion(timpl.m_version);
  2046.   return dropIndex(&tSignal, 0);
  2047. }
  2048. int
  2049. NdbDictInterface::dropIndex(NdbApiSignal* signal, LinearSectionPtr ptr[3])
  2050. {
  2051.   const int noErrCodes = 2;
  2052.   int errCodes[noErrCodes] = {DropIndxRef::Busy, DropIndxRef::NotMaster};
  2053.   int r = dictSignal(signal,NULL,0,
  2054.      1/*Use masternode id*/,
  2055.      100,
  2056.      WAIT_DROP_INDX_REQ,
  2057.      WAITFOR_RESPONSE_TIMEOUT,
  2058.      errCodes,noErrCodes);
  2059.   if(m_error.code == DropIndxRef::InvalidIndexVersion) {
  2060.     // Clear caches and try again
  2061.     return INCOMPATIBLE_VERSION;
  2062.   }
  2063.   return r;
  2064. }
  2065. void
  2066. NdbDictInterface::execDROP_INDX_CONF(NdbApiSignal * signal,
  2067.        LinearSectionPtr ptr[3])
  2068. {
  2069.   m_waiter.signal(NO_WAIT);  
  2070. }
  2071. void
  2072. NdbDictInterface::execDROP_INDX_REF(NdbApiSignal * signal,
  2073.       LinearSectionPtr ptr[3])
  2074. {
  2075.   const DropIndxRef* const ref = CAST_CONSTPTR(DropIndxRef, signal->getDataPtr());
  2076.   m_error.code = ref->getErrorCode();
  2077.   if(m_error.code == ref->NotMaster)
  2078.     m_masterNodeId= ref->masterNodeId;
  2079.   m_waiter.signal(NO_WAIT);  
  2080. }
  2081. /*****************************************************************
  2082.  * Create event
  2083.  */
  2084. int
  2085. NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
  2086. {
  2087.   int i;
  2088.   NdbTableImpl* tab = getTable(evnt.getTable());
  2089.   if(tab == 0){
  2090.     //    m_error.code = 3249;
  2091.     ndbout_c(":createEvent: table %s not found", evnt.getTable());
  2092. #ifdef EVENT_DEBUG
  2093.     ndbout_c("NdbDictionaryImpl::createEvent: table not found: %s", evnt.getTable());
  2094. #endif
  2095.     return -1;
  2096.   }
  2097.   evnt.m_tableId = tab->m_tableId;
  2098.   evnt.m_tableImpl = tab;
  2099. #ifdef EVENT_DEBUG
  2100.   ndbout_c("Event on tableId=%d", evnt.m_tableId);
  2101. #endif
  2102.   NdbTableImpl &table = *evnt.m_tableImpl;
  2103.   int attributeList_sz = evnt.m_attrIds.size();
  2104.   for (i = 0; i < attributeList_sz; i++) {
  2105.     NdbColumnImpl *col_impl = table.getColumn(evnt.m_attrIds[i]);
  2106.     if (col_impl) {
  2107.       evnt.m_facade->addColumn(*(col_impl->m_facade));
  2108.     } else {
  2109.       ndbout_c("Attr id %u in table %s not found", evnt.m_attrIds[i],
  2110.        evnt.getTable());
  2111.       return -1;
  2112.     }
  2113.   }
  2114.   evnt.m_attrIds.clear();
  2115.   attributeList_sz = evnt.m_columns.size();
  2116. #ifdef EVENT_DEBUG
  2117.   ndbout_c("creating event %s", evnt.m_externalName.c_str());
  2118.   ndbout_c("no of columns %d", evnt.m_columns.size());
  2119. #endif
  2120.   int pk_count = 0;
  2121.   evnt.m_attrListBitmask.clear();
  2122.   for(i = 0; i<attributeList_sz; i++){
  2123.     const NdbColumnImpl* col = 
  2124.       table.getColumn(evnt.m_columns[i]->m_name.c_str());
  2125.     if(col == 0){
  2126.       m_error.code = 4247;
  2127.       return -1;
  2128.     }
  2129.     // Copy column definition
  2130.     *evnt.m_columns[i] = *col;
  2131.     
  2132.     if(col->m_pk){
  2133.       pk_count++;
  2134.     }
  2135.     
  2136.     evnt.m_attrListBitmask.set(col->m_attrId);
  2137.   }
  2138.   
  2139.   // Sort index attributes according to primary table (using insertion sort)
  2140.   for(i = 1; i < attributeList_sz; i++) {
  2141.     NdbColumnImpl* temp = evnt.m_columns[i];
  2142.     unsigned int j = i;
  2143.     while((j > 0) && (evnt.m_columns[j - 1]->m_attrId > temp->m_attrId)) {
  2144.       evnt.m_columns[j] = evnt.m_columns[j - 1];
  2145.       j--;
  2146.     }
  2147.     evnt.m_columns[j] = temp;
  2148.   }
  2149.   // Check for illegal duplicate attributes
  2150.   for(i = 1; i<attributeList_sz; i++) {
  2151.     if (evnt.m_columns[i-1]->m_attrId == evnt.m_columns[i]->m_attrId) {
  2152.       m_error.code = 4258;
  2153.       return -1;
  2154.     }
  2155.   }
  2156.   
  2157. #ifdef EVENT_DEBUG
  2158.   char buf[128] = {0};
  2159.   evnt.m_attrListBitmask.getText(buf);
  2160.   ndbout_c("createEvent: mask = %s", buf);
  2161. #endif
  2162.   // NdbDictInterface m_receiver;
  2163.   return m_receiver.createEvent(m_ndb, evnt, 0 /* getFlag unset */);
  2164. }
  2165. int
  2166. NdbDictInterface::createEvent(class Ndb & ndb,
  2167.       NdbEventImpl & evnt,
  2168.       int getFlag)
  2169. {
  2170.   NdbApiSignal tSignal(m_reference);
  2171.   tSignal.theReceiversBlockNumber = DBDICT;
  2172.   tSignal.theVerId_signalNumber   = GSN_CREATE_EVNT_REQ;
  2173.   if (getFlag)
  2174.     tSignal.theLength = CreateEvntReq::SignalLengthGet;
  2175.   else
  2176.     tSignal.theLength = CreateEvntReq::SignalLengthCreate;
  2177.   CreateEvntReq * const req = CAST_PTR(CreateEvntReq, tSignal.getDataPtrSend());
  2178.   
  2179.   req->setUserRef(m_reference);
  2180.   req->setUserData(0);
  2181.   if (getFlag) {
  2182.     // getting event from Dictionary
  2183.     req->setRequestType(CreateEvntReq::RT_USER_GET);
  2184.   } else {
  2185.     // creating event in Dictionary
  2186.     req->setRequestType(CreateEvntReq::RT_USER_CREATE);
  2187.     req->setTableId(evnt.m_tableId);
  2188.     req->setAttrListBitmask(evnt.m_attrListBitmask);
  2189.     req->setEventType(evnt.mi_type);
  2190.   }
  2191.   UtilBufferWriter w(m_buffer);
  2192.   const size_t len = strlen(evnt.m_externalName.c_str()) + 1;
  2193.   if(len > MAX_TAB_NAME_SIZE) {
  2194.     m_error.code = 4241;
  2195.     return -1;
  2196.   }
  2197.   w.add(SimpleProperties::StringValue, evnt.m_externalName.c_str());
  2198.   if (getFlag == 0)
  2199.     w.add(SimpleProperties::StringValue,
  2200.   ndb.internalizeTableName(evnt.m_tableName.c_str()));
  2201.   LinearSectionPtr ptr[3];
  2202.   ptr[0].p = (Uint32*)m_buffer.get_data();
  2203.   ptr[0].sz = (m_buffer.length()+3) >> 2;
  2204.   int ret = createEvent(&tSignal, ptr, 1);
  2205.   if (ret) {
  2206.     return ret;
  2207.   }
  2208.   char *dataPtr = (char *)m_buffer.get_data();
  2209.   unsigned int lenCreateEvntConf = *((unsigned int *)dataPtr);
  2210.   dataPtr += sizeof(lenCreateEvntConf);
  2211.   CreateEvntConf const * evntConf = (CreateEvntConf *)dataPtr;
  2212.   dataPtr += lenCreateEvntConf;
  2213.   
  2214.   //  NdbEventImpl *evntImpl = (NdbEventImpl *)evntConf->getUserData();
  2215.   if (getFlag) {
  2216.     evnt.m_tableId         = evntConf->getTableId();
  2217.     evnt.m_attrListBitmask = evntConf->getAttrListBitmask();
  2218.     evnt.mi_type           = evntConf->getEventType();
  2219.     evnt.setTable(dataPtr);
  2220.   } else {
  2221.     if (evnt.m_tableId         != evntConf->getTableId() ||
  2222. //evnt.m_attrListBitmask != evntConf->getAttrListBitmask() ||
  2223. evnt.mi_type           != evntConf->getEventType()) {
  2224.       ndbout_c("ERROR*************");
  2225.       return 1;
  2226.     }
  2227.   }
  2228.   evnt.m_eventId         = evntConf->getEventId();
  2229.   evnt.m_eventKey        = evntConf->getEventKey();
  2230.   return ret;
  2231. }
  2232. int
  2233. NdbDictInterface::createEvent(NdbApiSignal* signal,
  2234.       LinearSectionPtr ptr[3], int noLSP)
  2235. {
  2236.   const int noErrCodes = 1;
  2237.   int errCodes[noErrCodes] = {CreateEvntRef::Busy};
  2238.   return dictSignal(signal,ptr,noLSP,
  2239.     1 /*use masternode id*/,
  2240.     100,
  2241.     WAIT_CREATE_INDX_REQ /*WAIT_CREATE_EVNT_REQ*/,
  2242.     -1,
  2243.     errCodes,noErrCodes, CreateEvntRef::Temporary);
  2244. }
  2245. int
  2246. NdbDictionaryImpl::executeSubscribeEvent(NdbEventImpl & ev)
  2247. {
  2248.   // NdbDictInterface m_receiver;
  2249.   return m_receiver.executeSubscribeEvent(m_ndb, ev);
  2250. }
  2251. int
  2252. NdbDictInterface::executeSubscribeEvent(class Ndb & ndb,
  2253.  NdbEventImpl & evnt)
  2254. {
  2255.   NdbApiSignal tSignal(m_reference);
  2256.   //  tSignal.theReceiversBlockNumber = SUMA;
  2257.   tSignal.theReceiversBlockNumber = DBDICT;
  2258.   tSignal.theVerId_signalNumber   = GSN_SUB_START_REQ;
  2259.   tSignal.theLength = SubStartReq::SignalLength2;
  2260.   
  2261.   SubStartReq * sumaStart = CAST_PTR(SubStartReq, tSignal.getDataPtrSend());
  2262.   sumaStart->subscriptionId   = evnt.m_eventId;
  2263.   sumaStart->subscriptionKey  = evnt.m_eventKey;
  2264.   sumaStart->part             = SubscriptionData::TableData;
  2265.   sumaStart->subscriberData   = evnt.m_bufferId & 0xFF;
  2266.   sumaStart->subscriberRef    = m_reference;
  2267.   return executeSubscribeEvent(&tSignal, NULL);
  2268. }
  2269. int
  2270. NdbDictInterface::executeSubscribeEvent(NdbApiSignal* signal,
  2271. LinearSectionPtr ptr[3])
  2272. {
  2273.   return dictSignal(signal,NULL,0,
  2274.     1 /*use masternode id*/,
  2275.     100,
  2276.     WAIT_CREATE_INDX_REQ /*WAIT_CREATE_EVNT_REQ*/,
  2277.     -1,
  2278.     NULL,0);
  2279. }
  2280. int
  2281. NdbDictionaryImpl::stopSubscribeEvent(NdbEventImpl & ev)
  2282. {
  2283.   // NdbDictInterface m_receiver;
  2284.   return m_receiver.stopSubscribeEvent(m_ndb, ev);
  2285. }
  2286. int
  2287. NdbDictInterface::stopSubscribeEvent(class Ndb & ndb,
  2288.      NdbEventImpl & evnt)
  2289. {
  2290. #ifdef EVENT_DEBUG
  2291.   ndbout_c("SUB_STOP_REQ");
  2292. #endif
  2293.   NdbApiSignal tSignal(m_reference);
  2294.   //  tSignal.theReceiversBlockNumber = SUMA;
  2295.   tSignal.theReceiversBlockNumber = DBDICT;
  2296.   tSignal.theVerId_signalNumber   = GSN_SUB_STOP_REQ;
  2297.   tSignal.theLength = SubStopReq::SignalLength;
  2298.   
  2299.   SubStopReq * sumaStop = CAST_PTR(SubStopReq, tSignal.getDataPtrSend());
  2300.   sumaStop->subscriptionId  = evnt.m_eventId;
  2301.   sumaStop->subscriptionKey = evnt.m_eventKey;
  2302.   sumaStop->subscriberData  = evnt.m_bufferId & 0xFF;
  2303.   sumaStop->part            = (Uint32) SubscriptionData::TableData;
  2304.   sumaStop->subscriberRef   = m_reference;
  2305.   return stopSubscribeEvent(&tSignal, NULL);
  2306. }
  2307. int
  2308. NdbDictInterface::stopSubscribeEvent(NdbApiSignal* signal,
  2309.      LinearSectionPtr ptr[3])
  2310. {
  2311.   return dictSignal(signal,NULL,0,
  2312.     1 /*use masternode id*/,
  2313.     100,
  2314.     WAIT_CREATE_INDX_REQ /*WAIT_SUB_STOP__REQ*/,
  2315.     -1,
  2316.     NULL,0);
  2317. }
  2318. NdbEventImpl * 
  2319. NdbDictionaryImpl::getEvent(const char * eventName)
  2320. {
  2321.   NdbEventImpl *ev =  new NdbEventImpl();
  2322.   if (ev == NULL) {
  2323.     return NULL;
  2324.   }
  2325.   ev->setName(eventName);
  2326.   int ret = m_receiver.createEvent(m_ndb, *ev, 1 /* getFlag set */);
  2327.   if (ret) {
  2328.     delete ev;
  2329.     return NULL;
  2330.   }
  2331.   // We only have the table name with internal name
  2332.   ev->setTable(m_ndb.externalizeTableName(ev->getTable()));
  2333.   ev->m_tableImpl = getTable(ev->getTable());
  2334.   // get the columns from the attrListBitmask
  2335.   NdbTableImpl &table = *ev->m_tableImpl;
  2336.   AttributeMask & mask = ev->m_attrListBitmask;
  2337.   int attributeList_sz = mask.count();
  2338.   int id = -1;
  2339. #ifdef EVENT_DEBUG
  2340.   ndbout_c("NdbDictionaryImpl::getEvent attributeList_sz = %d",
  2341.    attributeList_sz);
  2342.   char buf[128] = {0};
  2343.   mask.getText(buf);
  2344.   ndbout_c("mask = %s", buf);
  2345. #endif
  2346.   for(int i = 0; i < attributeList_sz; i++) {
  2347.     id++; while (!mask.get(id)) id++;
  2348.     const NdbColumnImpl* col = table.getColumn(id);
  2349.     if(col == 0) {
  2350. #ifdef EVENT_DEBUG
  2351.       ndbout_c("NdbDictionaryImpl::getEvent could not find column id %d", id);
  2352. #endif
  2353.       m_error.code = 4247;
  2354.       delete ev;
  2355.       return NULL;
  2356.     }
  2357.     NdbColumnImpl* new_col = new NdbColumnImpl;
  2358.     // Copy column definition
  2359.     *new_col = *col;
  2360.     ev->m_columns.push_back(new_col);
  2361.   }
  2362.   return ev;
  2363. }
  2364. void
  2365. NdbDictInterface::execCREATE_EVNT_CONF(NdbApiSignal * signal,
  2366.        LinearSectionPtr ptr[3])
  2367. {
  2368. #ifdef EVENT_DEBUG
  2369.   ndbout << "NdbDictionaryImpl.cpp: execCREATE_EVNT_CONF" << endl;
  2370. #endif
  2371.   m_buffer.clear();
  2372.   unsigned int len = signal->getLength() << 2;
  2373.   m_buffer.append((char *)&len, sizeof(len));
  2374.   m_buffer.append(signal->getDataPtr(), len);
  2375.   if (signal->m_noOfSections > 0) {
  2376.     m_buffer.append((char *)ptr[0].p, strlen((char *)ptr[0].p)+1);
  2377.   }
  2378.   m_waiter.signal(NO_WAIT);
  2379. }
  2380. void
  2381. NdbDictInterface::execCREATE_EVNT_REF(NdbApiSignal * signal,
  2382.       LinearSectionPtr ptr[3])
  2383. {
  2384. #ifdef EVENT_DEBUG
  2385.   ndbout << "NdbDictionaryImpl.cpp: execCREATE_EVNT_REF" << endl;
  2386.   ndbout << "Exiting" << endl;
  2387.   exit(-1);
  2388. #endif
  2389.   const CreateEvntRef* const ref = CAST_CONSTPTR(CreateEvntRef, signal->getDataPtr());
  2390.   m_error.code = ref->getErrorCode();
  2391. #ifdef EVENT_DEBUG
  2392.   ndbout_c("execCREATE_EVNT_REF");
  2393.   ndbout_c("ErrorCode %u", ref->getErrorCode());
  2394.   ndbout_c("Errorline %u", ref->getErrorLine());
  2395.   ndbout_c("ErrorNode %u", ref->getErrorNode());
  2396. #endif
  2397.   m_waiter.signal(NO_WAIT);  
  2398. }
  2399. void
  2400. NdbDictInterface::execSUB_STOP_CONF(NdbApiSignal * signal,
  2401.       LinearSectionPtr ptr[3])
  2402. {
  2403. #ifdef EVENT_DEBUG
  2404.   ndbout << "Got GSN_SUB_STOP_CONF" << endl;
  2405. #endif
  2406.   //  SubRemoveConf * const sumaRemoveConf = CAST_CONSTPTR(SubRemoveConf, signal->getDataPtr());
  2407.   //  Uint32 subscriptionId = sumaRemoveConf->subscriptionId;
  2408.   //  Uint32 subscriptionKey = sumaRemoveConf->subscriptionKey;
  2409.   //  Uint32 senderData = sumaRemoveConf->senderData;
  2410.   m_waiter.signal(NO_WAIT);
  2411. }
  2412. void
  2413. NdbDictInterface::execSUB_STOP_REF(NdbApiSignal * signal,
  2414.      LinearSectionPtr ptr[3])
  2415. {
  2416. #ifdef EVENT_DEBUG
  2417.   ndbout << "Got GSN_SUB_STOP_REF" << endl;
  2418. #endif
  2419.   //  SubRemoveConf * const sumaRemoveRef = CAST_CONSTPTR(SubRemoveRef, signal->getDataPtr());
  2420.   //  Uint32 subscriptionId = sumaRemoveRef->subscriptionId;
  2421.   //  Uint32 subscriptionKey = sumaRemoveRef->subscriptionKey;
  2422.   //  Uint32 senderData = sumaRemoveRef->senderData;
  2423.   m_error.code = 1;
  2424.   m_waiter.signal(NO_WAIT);
  2425. }
  2426. void
  2427. NdbDictInterface::execSUB_START_CONF(NdbApiSignal * signal,
  2428.      LinearSectionPtr ptr[3])
  2429. {
  2430. #ifdef EVENT_DEBUG
  2431.   ndbout << "Got GSN_SUB_START_CONF" << endl;
  2432. #endif
  2433.   const SubStartConf * const sumaStartConf = CAST_CONSTPTR(SubStartConf, signal->getDataPtr());
  2434.   //  Uint32 subscriptionId = sumaStartConf->subscriptionId;
  2435.   //  Uint32 subscriptionKey = sumaStartConf->subscriptionKey;
  2436.   SubscriptionData::Part part = 
  2437.   (SubscriptionData::Part)sumaStartConf->part;
  2438.   //  Uint32 subscriberData = sumaStartConf->subscriberData;
  2439.   switch(part) {
  2440.   case SubscriptionData::MetaData: {
  2441. #ifdef EVENT_DEBUG
  2442.     ndbout << "SubscriptionData::MetaData" << endl;
  2443. #endif
  2444.     m_error.code = 1;
  2445.     break;
  2446.   }
  2447.   case SubscriptionData::TableData: {
  2448. #ifdef EVENT_DEBUG
  2449.     ndbout << "SubscriptionData::TableData" << endl;
  2450. #endif
  2451.     break;
  2452.   }
  2453.   default: {
  2454. #ifdef EVENT_DEBUG
  2455.     ndbout_c("NdbDictInterface::execSUB_START_CONF wrong data");
  2456. #endif
  2457.     m_error.code = 1;
  2458.     break;
  2459.   }
  2460.   }
  2461.   m_waiter.signal(NO_WAIT);
  2462. }
  2463. void
  2464. NdbDictInterface::execSUB_START_REF(NdbApiSignal * signal,
  2465.     LinearSectionPtr ptr[3])
  2466. {
  2467. #ifdef EVENT_DEBUG
  2468.     ndbout << "Got GSN_SUB_START_REF" << endl;
  2469. #endif
  2470.   m_error.code = 1;
  2471.   m_waiter.signal(NO_WAIT);  
  2472. }
  2473. void
  2474. NdbDictInterface::execSUB_GCP_COMPLETE_REP(NdbApiSignal * signal,
  2475.    LinearSectionPtr ptr[3])
  2476. {
  2477.   const SubGcpCompleteRep * const rep = CAST_CONSTPTR(SubGcpCompleteRep, signal->getDataPtr());
  2478.   const Uint32 gci            = rep->gci;
  2479.   //  const Uint32 senderRef      = rep->senderRef;
  2480.   const Uint32 subscriberData = rep->subscriberData;
  2481.   const Uint32 bufferId = subscriberData;
  2482.   const Uint32 ref = signal->theSendersBlockRef;
  2483.   NdbApiSignal tSignal(m_reference);
  2484.   SubGcpCompleteAcc * acc = CAST_PTR(SubGcpCompleteAcc, tSignal.getDataPtrSend());
  2485.   acc->rep = *rep;
  2486.   tSignal.theReceiversBlockNumber = refToBlock(ref);
  2487.   tSignal.theVerId_signalNumber   = GSN_SUB_GCP_COMPLETE_ACC;
  2488.   tSignal.theLength = SubGcpCompleteAcc::SignalLength;
  2489.   Uint32 aNodeId = refToNode(ref);
  2490.   //  m_transporter->lock_mutex();
  2491.   int r;
  2492.   r = m_transporter->sendSignal(&tSignal, aNodeId);
  2493.   //  m_transporter->unlock_mutex();
  2494.   NdbGlobalEventBufferHandle::latestGCI(bufferId, gci);
  2495. }
  2496. void
  2497. NdbDictInterface::execSUB_TABLE_DATA(NdbApiSignal * signal,
  2498.      LinearSectionPtr ptr[3])
  2499. {
  2500. #ifdef EVENT_DEBUG
  2501.   const char * FNAME = "NdbDictInterface::execSUB_TABLE_DATA";
  2502. #endif
  2503.   //TODO
  2504.   const SubTableData * const sdata = CAST_CONSTPTR(SubTableData, signal->getDataPtr());
  2505.   //  const Uint32 gci            = sdata->gci;
  2506.   //  const Uint32 operation      = sdata->operation;
  2507.   //  const Uint32 tableId        = sdata->tableId;
  2508.   //  const Uint32 noOfAttrs      = sdata->noOfAttributes;
  2509.   //  const Uint32 dataLen        = sdata->dataSize;
  2510.   const Uint32 subscriberData = sdata->subscriberData;
  2511.   //  const Uint32 logType        = sdata->logType;
  2512.   for (int i=signal->m_noOfSections;i < 3; i++) {
  2513.     ptr[i].p = NULL;
  2514.     ptr[i].sz = 0;
  2515.   }
  2516. #ifdef EVENT_DEBUG
  2517.   ndbout_c("%s: senderData %d, gci %d, operation %d, tableId %d, noOfAttrs %d, dataLen %d",
  2518.    FNAME, subscriberData, gci, operation, tableId, noOfAttrs, dataLen);
  2519.   ndbout_c("ptr[0] %u %u ptr[1] %u %u ptr[2] %u %un",
  2520.    ptr[0].p,ptr[0].sz,ptr[1].p,ptr[1].sz,ptr[2].p,ptr[2].sz);
  2521. #endif
  2522.   const Uint32 bufferId = subscriberData;
  2523.   NdbGlobalEventBufferHandle::insertDataL(bufferId,
  2524.   sdata, ptr);
  2525. }
  2526. /*****************************************************************
  2527.  * Drop event
  2528.  */
  2529. int 
  2530. NdbDictionaryImpl::dropEvent(const char * eventName)
  2531. {
  2532.   NdbEventImpl *ev =  new NdbEventImpl();
  2533.   ev->setName(eventName);
  2534.   int ret = m_receiver.dropEvent(*ev);
  2535.   delete ev;  
  2536.   //  printf("__________________RET %un", ret);
  2537.   return ret;
  2538. }
  2539. int
  2540. NdbDictInterface::dropEvent(const NdbEventImpl &evnt)
  2541. {
  2542.   NdbApiSignal tSignal(m_reference);
  2543.   tSignal.theReceiversBlockNumber = DBDICT;
  2544.   tSignal.theVerId_signalNumber   = GSN_DROP_EVNT_REQ;
  2545.   tSignal.theLength = DropEvntReq::SignalLength;
  2546.   
  2547.   DropEvntReq * const req = CAST_PTR(DropEvntReq, tSignal.getDataPtrSend());
  2548.   req->setUserRef(m_reference);
  2549.   req->setUserData(0);
  2550.   UtilBufferWriter w(m_buffer);
  2551.   w.add(SimpleProperties::StringValue, evnt.m_externalName.c_str());
  2552.   LinearSectionPtr ptr[1];
  2553.   ptr[0].p = (Uint32*)m_buffer.get_data();
  2554.   ptr[0].sz = (m_buffer.length()+3) >> 2;
  2555.   return dropEvent(&tSignal, ptr, 1);
  2556. }
  2557. int
  2558. NdbDictInterface::dropEvent(NdbApiSignal* signal,
  2559.     LinearSectionPtr ptr[3], int noLSP)
  2560. {
  2561.   //TODO
  2562.   const int noErrCodes = 1;
  2563.   int errCodes[noErrCodes] = {DropEvntRef::Busy};
  2564.   return dictSignal(signal,ptr,noLSP,
  2565.     1 /*use masternode id*/,
  2566.     100,
  2567.     WAIT_CREATE_INDX_REQ /*WAIT_CREATE_EVNT_REQ*/,
  2568.     -1,
  2569.     errCodes,noErrCodes, DropEvntRef::Temporary);
  2570. }
  2571. void
  2572. NdbDictInterface::execDROP_EVNT_CONF(NdbApiSignal * signal,
  2573.      LinearSectionPtr ptr[3])
  2574. {
  2575. #ifdef EVENT_DEBUG
  2576.   ndbout << "NdbDictionaryImpl.cpp: execDROP_EVNT_CONF" << endl;
  2577. #endif
  2578.   m_waiter.signal(NO_WAIT);  
  2579. }
  2580. void
  2581. NdbDictInterface::execDROP_EVNT_REF(NdbApiSignal * signal,
  2582.     LinearSectionPtr ptr[3])
  2583. {
  2584. #ifdef EVENT_DEBUG
  2585.   ndbout << "NdbDictionaryImpl.cpp: execDROP_EVNT_REF" << endl;
  2586. #endif
  2587.   const DropEvntRef* const ref = CAST_CONSTPTR(DropEvntRef, signal->getDataPtr());
  2588.   m_error.code = ref->getErrorCode();
  2589. #if 0
  2590.   ndbout_c("execDROP_EVNT_REF");
  2591.   ndbout_c("ErrorCode %u", ref->getErrorCode());
  2592.   ndbout_c("Errorline %u", ref->getErrorLine());
  2593.   ndbout_c("ErrorNode %u", ref->getErrorNode());
  2594. #endif
  2595.   m_waiter.signal(NO_WAIT);  
  2596. }
  2597. /*****************************************************************
  2598.  * List objects or indexes
  2599.  */
  2600. int
  2601. NdbDictionaryImpl::listObjects(List& list, NdbDictionary::Object::Type type)
  2602. {
  2603.   ListTablesReq req;
  2604.   req.requestData = 0;
  2605.   req.setTableType(getKernelConstant(type, objectTypeMapping, 0));
  2606.   req.setListNames(true);
  2607.   return m_receiver.listObjects(list, req.requestData, m_ndb.usingFullyQualifiedNames());
  2608. }
  2609. int
  2610. NdbDictionaryImpl::listIndexes(List& list, Uint32 indexId)
  2611. {
  2612.   ListTablesReq req;
  2613.   req.requestData = 0;
  2614.   req.setTableId(indexId);
  2615.   req.setListNames(true);
  2616.   req.setListIndexes(true);
  2617.   return m_receiver.listObjects(list, req.requestData, m_ndb.usingFullyQualifiedNames());
  2618. }
  2619. int
  2620. NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list,
  2621.       Uint32 requestData, bool fullyQualifiedNames)
  2622. {
  2623.   NdbApiSignal tSignal(m_reference);
  2624.   ListTablesReq* const req = CAST_PTR(ListTablesReq, tSignal.getDataPtrSend());
  2625.   req->senderRef = m_reference;
  2626.   req->senderData = 0;
  2627.   req->requestData = requestData;
  2628.   tSignal.theReceiversBlockNumber = DBDICT;
  2629.   tSignal.theVerId_signalNumber = GSN_LIST_TABLES_REQ;
  2630.   tSignal.theLength = ListTablesReq::SignalLength;
  2631.   if (listObjects(&tSignal) != 0)
  2632.     return -1;
  2633.   // count
  2634.   const Uint32* data = (const Uint32*)m_buffer.get_data();
  2635.   const unsigned length = m_buffer.length() / 4;
  2636.   list.count = 0;
  2637.   bool ok = true;
  2638.   unsigned pos, count;
  2639.   pos = count = 0;
  2640.   while (pos < length) {
  2641.     // table id - name length - name
  2642.     pos++;
  2643.     if (pos >= length) {
  2644.       ok = false;
  2645.       break;
  2646.     }
  2647.     Uint32 n = (data[pos++] + 3) >> 2;
  2648.     pos += n;
  2649.     if (pos > length) {
  2650.       ok = false;
  2651.       break;
  2652.     }
  2653.     count++;
  2654.   }
  2655.   if (! ok) {
  2656.     // bad signal data
  2657.     m_error.code = 4213;
  2658.     return -1;
  2659.   }
  2660.   list.count = count;
  2661.   list.elements = new NdbDictionary::Dictionary::List::Element[count];
  2662.   pos = count = 0;
  2663.   while (pos < length) {
  2664.     NdbDictionary::Dictionary::List::Element& element = list.elements[count];
  2665.     Uint32 d = data[pos++];
  2666.     element.id = ListTablesConf::getTableId(d);
  2667.     element.type = (NdbDictionary::Object::Type)
  2668.       getApiConstant(ListTablesConf::getTableType(d), objectTypeMapping, 0);
  2669.     element.state = (NdbDictionary::Object::State)
  2670.       getApiConstant(ListTablesConf::getTableState(d), objectStateMapping, 0);
  2671.     element.store = (NdbDictionary::Object::Store)
  2672.       getApiConstant(ListTablesConf::getTableStore(d), objectStoreMapping, 0);
  2673.     // table or index name
  2674.     Uint32 n = (data[pos++] + 3) >> 2;
  2675.     BaseString databaseName;
  2676.     BaseString schemaName;
  2677.     BaseString objectName;
  2678.     if ((element.type == NdbDictionary::Object::UniqueHashIndex) ||
  2679. (element.type == NdbDictionary::Object::HashIndex) ||
  2680. (element.type == NdbDictionary::Object::UniqueOrderedIndex) ||
  2681. (element.type == NdbDictionary::Object::OrderedIndex)) {
  2682.       char * indexName = new char[n << 2];
  2683.       memcpy(indexName, &data[pos], n << 2);
  2684.       databaseName = Ndb::getDatabaseFromInternalName(indexName);
  2685.       schemaName = Ndb::getSchemaFromInternalName(indexName);
  2686.       objectName = BaseString(Ndb::externalizeIndexName(indexName, fullyQualifiedNames));
  2687.       delete [] indexName;
  2688.     } else if ((element.type == NdbDictionary::Object::SystemTable) || 
  2689.        (element.type == NdbDictionary::Object::UserTable)) {
  2690.       char * tableName = new char[n << 2];
  2691.       memcpy(tableName, &data[pos], n << 2);
  2692.       databaseName = Ndb::getDatabaseFromInternalName(tableName);
  2693.       schemaName = Ndb::getSchemaFromInternalName(tableName);
  2694.       objectName = BaseString(Ndb::externalizeTableName(tableName, fullyQualifiedNames));
  2695.       delete [] tableName;
  2696.     }
  2697.     else {
  2698.       char * otherName = new char[n << 2];
  2699.       memcpy(otherName, &data[pos], n << 2);
  2700.       objectName = BaseString(otherName);
  2701.       delete [] otherName;
  2702.     }
  2703.     element.database = new char[databaseName.length() + 1]; 
  2704.     strcpy(element.database, databaseName.c_str());
  2705.     element.schema = new char[schemaName.length() + 1]; 
  2706.     strcpy(element.schema, schemaName.c_str());
  2707.     element.name = new char[objectName.length() + 1]; 
  2708.     strcpy(element.name, objectName.c_str());
  2709.     pos += n;
  2710.     count++;
  2711.   }
  2712.   return 0;
  2713. }
  2714. int
  2715. NdbDictInterface::listObjects(NdbApiSignal* signal)
  2716. {
  2717.   const Uint32 RETRIES = 100;
  2718.   for (Uint32 i = 0; i < RETRIES; i++) {
  2719.     m_buffer.clear();
  2720.     // begin protected
  2721.     m_transporter->lock_mutex();
  2722.     Uint16 aNodeId = m_transporter->get_an_alive_node();
  2723.     if (aNodeId == 0) {
  2724.       m_error.code = 4009;
  2725.       m_transporter->unlock_mutex();
  2726.       return -1;
  2727.     }
  2728.     if (m_transporter->sendSignal(signal, aNodeId) != 0) {
  2729.       m_transporter->unlock_mutex();
  2730.       continue;
  2731.     }
  2732.     m_error.code = 0;
  2733.     m_waiter.m_node = aNodeId;
  2734.     m_waiter.m_state = WAIT_LIST_TABLES_CONF;
  2735.     m_waiter.wait(WAITFOR_RESPONSE_TIMEOUT);
  2736.     m_transporter->unlock_mutex();    
  2737.     // end protected
  2738.     if (m_waiter.m_state == NO_WAIT && m_error.code == 0)
  2739.       return 0;
  2740.     if (m_waiter.m_state == WAIT_NODE_FAILURE)
  2741.       continue;
  2742.     return -1;
  2743.   }
  2744.   return -1;
  2745. }
  2746. void
  2747. NdbDictInterface::execLIST_TABLES_CONF(NdbApiSignal* signal,
  2748.        LinearSectionPtr ptr[3])
  2749. {
  2750.   const unsigned off = ListTablesConf::HeaderLength;
  2751.   const unsigned len = (signal->getLength() - off);
  2752.   m_buffer.append(signal->getDataPtr() + off, len << 2);
  2753.   if (signal->getLength() < ListTablesConf::SignalLength) {
  2754.     // last signal has less than full length
  2755.     m_waiter.signal(NO_WAIT);
  2756.   }
  2757. }
  2758. template class Vector<int>;
  2759. template class Vector<Uint32>;
  2760. template class Vector<Vector<Uint32> >;
  2761. template class Vector<NdbTableImpl*>;
  2762. template class Vector<NdbColumnImpl*>;