List:Commits« Previous MessageNext Message »
From:jonas Date:May 16 2008 3:08pm
Subject:bk commit into 5.1 tree (jonas:1.2595)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of jonas.  When jonas does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-05-16 15:08:36+02:00, jonas@stripped +15 -0
  ndb -
    change LIST_TABLE_CONF
    1) use 32-bit id's for table id
    2) use long (maybe) fragmented response

  mysql-test/suite/ndb/r/ndb_restore_compat.result@stripped, 2008-05-16 15:08:31+02:00,
jonas@stripped +2 -2
    sort results

  mysql-test/suite/ndb/r/ndb_restore_different_endian_data.result@stripped, 2008-05-16
15:08:31+02:00, jonas@stripped +4 -4
    sort results

  mysql-test/suite/ndb/t/ndb_restore_compat.test@stripped, 2008-05-16 15:08:31+02:00,
jonas@stripped +1 -0
    sort results

  mysql-test/suite/ndb/t/ndb_restore_different_endian_data.test@stripped, 2008-05-16
15:08:31+02:00, jonas@stripped +1 -0
    sort results

  storage/ndb/include/kernel/signaldata/ListTables.hpp@stripped, 2008-05-16 15:08:31+02:00,
jonas@stripped +117 -21
    new ListTablesData

  storage/ndb/include/ndb_version.h.in@stripped, 2008-05-16 15:08:31+02:00,
jonas@stripped +23 -0
    add upgrade handling

  storage/ndb/include/util/SimpleProperties.hpp@stripped, 2008-05-16 15:08:31+02:00,
jonas@stripped +4 -1
    add destructor to SimplePropertiesSectionWriter

  storage/ndb/src/kernel/blocks/backup/Backup.cpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +57 -43
    addopt to new list_tables_conf

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +312 -10
    addopt to new list_tables_conf

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +4 -0
    addopt to new list_tables_conf

  storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +60 -11
    destructor

  storage/ndb/src/ndbapi/NdbApiSignal.hpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +1 -0
    new checked

  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +258 -18
    new list_tables_conf

  storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +15 -2
    new list_tables_conf

  storage/ndb/src/ndbapi/TransporterFacade.hpp@stripped, 2008-05-16 15:08:32+02:00,
jonas@stripped +2 -1
    friend

diff -Nrup a/mysql-test/suite/ndb/r/ndb_restore_compat.result
b/mysql-test/suite/ndb/r/ndb_restore_compat.result
--- a/mysql-test/suite/ndb/r/ndb_restore_compat.result	2007-12-21 15:19:31 +01:00
+++ b/mysql-test/suite/ndb/r/ndb_restore_compat.result	2008-05-16 15:08:31 +02:00
@@ -4,10 +4,10 @@ USE BANK;
 SHOW TABLES;
 Tables_in_BANK
 ACCOUNT
-GL
 ACCOUNT_TYPE
-TRANSACTION
+GL
 SYSTEM_VALUES
+TRANSACTION
 SELECT * FROM GL            ORDER BY TIME,ACCOUNT_TYPE;
 TIME	ACCOUNT_TYPE	BALANCE	DEPOSIT_COUNT	DEPOSIT_SUM	WITHDRAWAL_COUNT	WITHDRAWAL_SUM	PURGED
 0	0	10000000	0	0	0	0	1
diff -Nrup a/mysql-test/suite/ndb/r/ndb_restore_different_endian_data.result
b/mysql-test/suite/ndb/r/ndb_restore_different_endian_data.result
--- a/mysql-test/suite/ndb/r/ndb_restore_different_endian_data.result	2007-09-05 15:01:20
+02:00
+++ b/mysql-test/suite/ndb/r/ndb_restore_different_endian_data.result	2008-05-16 15:08:31
+02:00
@@ -2,10 +2,10 @@ USE test;
 DROP TABLE IF EXISTS t_num,t_datetime,t_string_1,t_string_2,t_gis;
 SHOW TABLES;
 Tables_in_test
-t_gis
-t_string_1
 t_datetime
+t_gis
 t_num
+t_string_1
 t_string_2
 SHOW CREATE TABLE t_num;
 Table	Create Table
@@ -102,10 +102,10 @@ DROP TABLE t_num,t_datetime,t_string_1,t
 SHOW TABLES;
 Tables_in_test
 t_gis
-t_string_1
+t_string_2
 t_datetime
+t_string_1
 t_num
-t_string_2
 SHOW CREATE TABLE t_num;
 Table	Create Table
 t_num	CREATE TABLE `t_num` (
diff -Nrup a/mysql-test/suite/ndb/t/ndb_restore_compat.test
b/mysql-test/suite/ndb/t/ndb_restore_compat.test
--- a/mysql-test/suite/ndb/t/ndb_restore_compat.test	2007-09-12 14:04:58 +02:00
+++ b/mysql-test/suite/ndb/t/ndb_restore_compat.test	2008-05-16 15:08:31 +02:00
@@ -16,6 +16,7 @@ CREATE DATABASE BANK default charset=lat
 --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -p 1 -m -r
$MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
 --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -e -b 1 -n 2 -p 1 -r
$MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
 USE BANK;
+--sorted_result
 SHOW TABLES;
 SELECT * FROM GL            ORDER BY TIME,ACCOUNT_TYPE;
 SELECT * FROM ACCOUNT       ORDER BY ACCOUNT_ID;
diff -Nrup a/mysql-test/suite/ndb/t/ndb_restore_different_endian_data.test
b/mysql-test/suite/ndb/t/ndb_restore_different_endian_data.test
--- a/mysql-test/suite/ndb/t/ndb_restore_different_endian_data.test	2007-09-05 15:01:20
+02:00
+++ b/mysql-test/suite/ndb/t/ndb_restore_different_endian_data.test	2008-05-16 15:08:31
+02:00
@@ -147,6 +147,7 @@ DROP TABLE IF EXISTS t_num,t_datetime,t_
 --enable_warnings
 --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -m -r
$MYSQL_TEST_DIR/std_data/ndb_backup51_data_le >> $NDB_TOOLS_OUTPUT
 --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -r
$MYSQL_TEST_DIR/std_data/ndb_backup51_data_le >> $NDB_TOOLS_OUTPUT
+--sorted_result
 SHOW TABLES;
 SHOW CREATE TABLE t_num;
 SHOW CREATE TABLE t_datetime;
diff -Nrup a/storage/ndb/include/kernel/signaldata/ListTables.hpp
b/storage/ndb/include/kernel/signaldata/ListTables.hpp
--- a/storage/ndb/include/kernel/signaldata/ListTables.hpp	2006-12-23 20:20:05 +01:00
+++ b/storage/ndb/include/kernel/signaldata/ListTables.hpp	2008-05-16 15:08:31 +02:00
@@ -19,11 +19,63 @@
 #include <Bitmask.hpp>
 #include "SignalData.hpp"
 
+class ListTablesData {
+public:
+  Uint32 getTableId() {
+    return tableId;
+  }
+  void setTableId(Uint32 val) {
+    tableId = val;
+  }
+  Uint32 getTableType() {
+    return tableType;
+  }
+  void setTableType(Uint32 val) {
+    tableType = val;
+  }
+  Uint32 getTableStore() {
+    return BitmaskImpl::getField(1, &requestData, 20, 3);
+  }
+  void setTableStore(Uint32 val) {
+    BitmaskImpl::setField(1, &requestData, 20, 3, val);
+  }
+  Uint32 getTableTemp() {
+    return BitmaskImpl::getField(1, &requestData, 23, 1);
+  }
+  void setTableTemp(Uint32 val) {
+    BitmaskImpl::setField(1, &requestData, 23, 1, val);
+  }
+  Uint32 getTableState() {
+    return BitmaskImpl::getField(1, &requestData, 24, 4);
+  }
+  void setTableState(Uint32 val) {
+    BitmaskImpl::setField(1, &requestData, 24, 4, val);
+  }
+  Uint32 getListNames() {
+    return BitmaskImpl::getField(1, &requestData, 28, 1);
+  }
+  void setListNames(Uint32 val) {
+    BitmaskImpl::setField(1, &requestData, 28, 1, val);
+  }
+  Uint32 getListIndexes() {
+    return BitmaskImpl::getField(1, &requestData, 29, 1);
+  }
+  void setListIndexes(Uint32 val) {
+    BitmaskImpl::setField(1, &requestData, 29, 1, val);
+  }
+public:
+  Uint32 requestData;
+  Uint32 tableId;
+  Uint32 tableType;
+};
+
 /**
+ * DEPRICATED
  * It is convenient to pack request/response data per table in one
  * 32-bit word...
+ *
  */
-class ListTablesData {
+class OldListTablesData {
 public:
   static Uint32 getTableId(Uint32 data) {
     return BitmaskImpl::getField(1, &data, 0, 12);
@@ -83,36 +135,58 @@ class ListTablesReq {
   friend class Dbdict;
 
 public:
-  STATIC_CONST( SignalLength = 3 );
+  STATIC_CONST( oldSignalLength = 3 );
+  STATIC_CONST( SignalLength = 5 );
 
 public:  
   Uint32 senderData;
   Uint32 senderRef;
   Uint32 requestData;
+  Uint32 tableId;
+  Uint32 tableType;
 
   Uint32 getTableId() {
-    return ListTablesData::getTableId(requestData);
+    return tableId;
   }
   void setTableId(Uint32 val) {
-    ListTablesData::setTableId(requestData, val);
+    tableId = val;
   }
   Uint32 getTableType() const {
-    return ListTablesData::getTableType(requestData);
+    return tableType;
   }
   void setTableType(Uint32 val) {
-    ListTablesData::setTableType(requestData, val);
+    tableType = val;
   }
   Uint32 getListNames() const {
-    return ListTablesData::getListNames(requestData);
+    ListTablesData* ltd = (ListTablesData *) &requestData;
+    return ltd->getListNames();
   }
   void setListNames(Uint32 val) {
-    ListTablesData::setListNames(requestData, val);
+    ListTablesData* ltd = (ListTablesData *) &requestData;
+    ltd->setListNames(val);
   }
   Uint32 getListIndexes() const {
-    return ListTablesData::getListIndexes(requestData);
+    ListTablesData* ltd = (ListTablesData *) &requestData;
+    return ltd->getListIndexes();
   }
   void setListIndexes(Uint32 val) {
-    ListTablesData::setListIndexes(requestData, val);
+    ListTablesData* ltd = (ListTablesData *) &requestData;
+    ltd->setListIndexes(val);
+  }
+
+
+  /* For backwards compatility */
+  Uint32 oldGetTableId() {
+    return OldListTablesData::getTableId(requestData);
+  }
+  void oldSetTableId(Uint32 val) {
+    OldListTablesData::setTableId(requestData, val);
+  }
+  Uint32 oldGetTableType() const {
+    return OldListTablesData::getTableType(requestData);
+  }
+  void oldSetTableType(Uint32 val) {
+    OldListTablesData::setTableType(requestData, val);
   }
 };
 
@@ -127,7 +201,29 @@ class ListTablesConf {
    */
   friend class Backup;
   friend class Table;
-  friend class Suma;
+
+public:
+  STATIC_CONST( SignalLength = 2 );
+
+public:
+  Uint32 senderData;
+  Uint32 noOfTables;
+
+  SECTION( TABLE_DATA = 0 );
+  SECTION( TABLE_NAMES = 1 );
+};
+
+class OldListTablesConf {
+  /**
+   * Sender(s)
+   */
+  friend class Dbdict;
+
+  /**
+   * Reciver(s)
+   */
+  friend class Backup;
+  friend class Table;
 
 public:
   /**
@@ -143,34 +239,34 @@ public:  
   Uint32 tableData[DataLength];
 
   static Uint32 getTableId(Uint32 data) {
-    return ListTablesData::getTableId(data);
+    return OldListTablesData::getTableId(data);
   }
   void setTableId(unsigned pos, Uint32 val) {
-    ListTablesData::setTableId(tableData[pos], val);
+    OldListTablesData::setTableId(tableData[pos], val);
   }
   static Uint32 getTableType(Uint32 data) {
-    return ListTablesData::getTableType(data);
+    return OldListTablesData::getTableType(data);
   }
   void setTableType(unsigned pos, Uint32 val) {
-    ListTablesData::setTableType(tableData[pos], val);
+    OldListTablesData::setTableType(tableData[pos], val);
   }
   static Uint32 getTableStore(Uint32 data) {
-    return ListTablesData::getTableStore(data);
+    return OldListTablesData::getTableStore(data);
   }
   void setTableStore(unsigned pos, Uint32 val) {
-    ListTablesData::setTableStore(tableData[pos], val);
+    OldListTablesData::setTableStore(tableData[pos], val);
   }
   static Uint32 getTableState(Uint32 data) {
-    return ListTablesData::getTableState(data);
+    return OldListTablesData::getTableState(data);
   }
   void setTableState(unsigned pos, Uint32 val) {
-    ListTablesData::setTableState(tableData[pos], val);
+    OldListTablesData::setTableState(tableData[pos], val);
   }
   static Uint32 getTableTemp(Uint32 data) {
-    return ListTablesData::getTableTemp(data);
+    return OldListTablesData::getTableTemp(data);
   }
   void setTableTemp(unsigned pos, Uint32 val) {
-    ListTablesData::setTableTemp(tableData[pos], val);
+    OldListTablesData::setTableTemp(tableData[pos], val);
   }
 };
 
diff -Nrup a/storage/ndb/include/ndb_version.h.in b/storage/ndb/include/ndb_version.h.in
--- a/storage/ndb/include/ndb_version.h.in	2008-04-08 10:29:09 +02:00
+++ b/storage/ndb/include/ndb_version.h.in	2008-05-16 15:08:31 +02:00
@@ -184,4 +184,27 @@ ndbd_suma_dictlock(Uint32 x)
   return x >= NDBD_SUMA_DICT_LOCK_63;
 }
 
+#define NDBD_LONG_LIST_TABLES_CONF_62 NDB_MAKE_VERSION(6,2,16)
+#define NDBD_LONG_LIST_TABLES_CONF_63 NDB_MAKE_VERSION(6,3,15)
+
+static
+inline
+int
+ndbd_LIST_TABLES_CONF_long_signal(Uint32 x)
+{
+  if (x >= NDB_VERSION_D)
+    return 1;
+
+  const Uint32 major = (x >> 16) & 0xFF;
+  const Uint32 minor = (x >>  8) & 0xFF;
+
+  if (major >= 6)
+  {
+    if (minor == 2)
+      return x >= NDBD_LONG_LIST_TABLES_CONF_62;
+  }
+
+  return x >= NDBD_LONG_LIST_TABLES_CONF_63;
+}
+
 #endif
diff -Nrup a/storage/ndb/include/util/SimpleProperties.hpp
b/storage/ndb/include/util/SimpleProperties.hpp
--- a/storage/ndb/include/util/SimpleProperties.hpp	2007-01-29 00:47:32 +01:00
+++ b/storage/ndb/include/util/SimpleProperties.hpp	2008-05-16 15:08:31 +02:00
@@ -277,11 +277,12 @@ Uint32 SimplePropertiesSectionReader::ge
 class SimplePropertiesSectionWriter : public SimpleProperties::Writer {
 public:
   SimplePropertiesSectionWriter(class SectionSegmentPool &);
-  virtual ~SimplePropertiesSectionWriter() {}
+  virtual ~SimplePropertiesSectionWriter();
 
   virtual bool reset();
   virtual bool putWord(Uint32 val);
   virtual bool putWords(const Uint32 * src, Uint32 len);
+  Uint32 getWordsUsed() const;
 
   /**
    * This "unlinks" the writer from the memory
@@ -289,6 +290,8 @@ public:
   void getPtr(struct SegmentedSectionPtr & dst);
   
 private:
+  void release();
+
   Int32 m_pos;
   Uint32 m_sz;
   class SectionSegmentPool & m_pool;
diff -Nrup a/storage/ndb/src/kernel/blocks/backup/Backup.cpp
b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp	2008-03-25 16:46:09 +01:00
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp	2008-05-16 15:08:32 +02:00
@@ -2813,6 +2813,8 @@ Backup::backupAllData(Signal* signal, Ba
   req->senderRef = reference();
   req->senderData = ptr.i;
   req->requestData = 0;
+  req->tableId = 0;
+  req->tableType = 0;
   sendSignal(DBDICT_REF, GSN_LIST_TABLES_REQ, signal, 
 	     ListTablesReq::SignalLength, JBB);
 }
@@ -2821,56 +2823,68 @@ void
 Backup::execLIST_TABLES_CONF(Signal* signal)
 {
   jamEntry();
-  
+  Uint32 fragInfo = signal->header.m_fragmentInfo;
   ListTablesConf* conf = (ListTablesConf*)signal->getDataPtr();
+  Uint32 noOfTables = conf->noOfTables;
 
   BackupRecordPtr ptr LINT_SET_PTR;
   c_backupPool.getPtr(ptr, conf->senderData);
-  
-  const Uint32 len = signal->length() - ListTablesConf::HeaderLength;
-  for(unsigned int i = 0; i<len; i++) {
-    jam();
-    Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]);
-    Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]);
-    Uint32 state= ListTablesConf::getTableState(conf->tableData[i]);
-
-    if (! (DictTabInfo::isTable(tableType) ||
-	   DictTabInfo::isIndex(tableType) ||
-	   DictTabInfo::isFilegroup(tableType) ||
-	   DictTabInfo::isFile(tableType)))
-    {
-      jam();
-      continue;
-    }
-    
-    if (state != DictTabInfo::StateOnline)
-    {
-      jam();
-      continue;
-    }
-    
-    TablePtr tabPtr;
-    ptr.p->tables.seize(tabPtr);
-    if(tabPtr.i == RNIL) {
+
+  if (noOfTables > 0)
+  {
+    ndbassert(signal->getNoOfSections() > 0);
+    ListTablesData ltd;
+    const Uint32 listTablesDataSizeInWords = (sizeof(ListTablesData) + 3) / 4;
+    SegmentedSectionPtr tableDataPtr;
+    signal->getSection(tableDataPtr, ListTablesConf::TABLE_DATA);
+    SimplePropertiesSectionReader
+      tableDataReader(tableDataPtr, getSectionSegmentPool());
+
+    tableDataReader.reset();
+    for(unsigned int i = 0; i<noOfTables; i++) {
       jam();
-      defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateTables);
-      return;
-    }//if
-    tabPtr.p->tableId = tableId;
-    tabPtr.p->tableType = tableType;
-  }//for
-  
-  if(len == ListTablesConf::DataLength) {
-    jam();
-    /**
-     * Not finished...
-     */
-    return;
-  }//if
+      tableDataReader.getWords((Uint32 *)&ltd, listTablesDataSizeInWords);
+      Uint32 tableId = ltd.getTableId();
+      Uint32 tableType = ltd.getTableType();
+      Uint32 state= ltd.getTableState();
 
-  /**
-   * All tables fetched
+      if (! (DictTabInfo::isTable(tableType) ||
+             DictTabInfo::isIndex(tableType) ||
+             DictTabInfo::isFilegroup(tableType) ||
+             DictTabInfo::isFile(tableType)))
+      {
+        jam();
+        continue;
+      }
+
+      if (state != DictTabInfo::StateOnline)
+      {
+        jam();
+        continue;
+      }
+
+      TablePtr tabPtr;
+      ptr.p->tables.seize(tabPtr);
+      if(tabPtr.i == RNIL) {
+        jam();
+        defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateTables);
+        releaseSections(signal);
+        return;
+      }//if
+      tabPtr.p->tableId = tableId;
+      tabPtr.p->tableType = tableType;
+    }//for
+    releaseSections(signal);
+  }
+
+  /*
+    If first or not last signal
+    then keep accumulating table data
    */
+  if ((fragInfo == 1) || (fragInfo == 2))
+  {
+    return;
+  }
   openFiles(signal, ptr);
 }
 
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-04-22 21:36:00 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-05-16 15:08:32 +02:00
@@ -2022,6 +2022,10 @@ Uint32 Dbdict::getFreeObjId(Uint32 minId
 Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId) 
 {
   Uint32 minId = (primaryTableId == RNIL ? 0 : primaryTableId + 1);
+  if (ERROR_INSERTED(6012) && minId < 4096){
+    minId = 4096;
+    CLEAR_ERROR_INSERT_VALUE;
+  }
   Uint32 i = getFreeObjId(minId);
   if (i == RNIL) {
     jam();
@@ -7894,15 +7898,28 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
 {
   jamEntry();
   ListTablesReq * req = (ListTablesReq*)signal->getDataPtr();
+
+  Uint32 senderRef  = req->senderRef;
+  Uint32 receiverVersion = getNodeInfo(refToNode(senderRef)).m_version;
+
+  if (ndbd_LIST_TABLES_CONF_long_signal(receiverVersion))
+    sendLIST_TABLES_CONF(signal, req);
+  else
+    sendOLD_LIST_TABLES_CONF(signal, req);
+}
+
+void Dbdict::sendOLD_LIST_TABLES_CONF(Signal* signal, ListTablesReq* req)
+{
   Uint32 senderRef  = req->senderRef;
   Uint32 senderData = req->senderData;
   // save req flags
-  const Uint32 reqTableId = req->getTableId();
-  const Uint32 reqTableType = req->getTableType();
+  const Uint32 reqTableId = req->oldGetTableId();
+  const Uint32 reqTableType = req->oldGetTableType();
   const bool reqListNames = req->getListNames();
   const bool reqListIndexes = req->getListIndexes();
+
   // init the confs
-  ListTablesConf * conf = (ListTablesConf *)signal->getDataPtrSend();
+  OldListTablesConf * conf = (OldListTablesConf *)signal->getDataPtrSend();
   conf->senderData = senderData;
   conf->counter = 0;
   Uint32 pos = 0;
@@ -8020,9 +8037,9 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
       pos++;
     }
     
-    if (pos >= ListTablesConf::DataLength) {
+    if (pos >= OldListTablesConf::DataLength) {
       sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-		 ListTablesConf::SignalLength, JBB);
+		 OldListTablesConf::SignalLength, JBB);
       conf->counter++;
       pos = 0;
     }
@@ -8034,9 +8051,9 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
     const Uint32 size = name.size();
     conf->tableData[pos] = size;
     pos++;
-    if (pos >= ListTablesConf::DataLength) {
+    if (pos >= OldListTablesConf::DataLength) {
       sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-		 ListTablesConf::SignalLength, JBB);
+		 OldListTablesConf::SignalLength, JBB);
       conf->counter++;
       pos = 0;
     }
@@ -8052,9 +8069,9 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
 	  *p++ = 0;
       }
       pos++;
-      if (pos >= ListTablesConf::DataLength) {
+      if (pos >= OldListTablesConf::DataLength) {
 	sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-		   ListTablesConf::SignalLength, JBB);
+		   OldListTablesConf::SignalLength, JBB);
 	conf->counter++;
 	pos = 0;
       }
@@ -8062,7 +8079,292 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
   }
   // last signal must have less than max length
   sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
-	     ListTablesConf::HeaderLength + pos, JBB);
+	     OldListTablesConf::HeaderLength + pos, JBB);
+}
+
+void Dbdict::sendLIST_TABLES_CONF(Signal* signal, ListTablesReq* req)
+{
+  Uint32 senderRef  = req->senderRef;
+  Uint32 senderData = req->senderData;
+  // save req flags
+  const Uint32 reqTableId = req->getTableId();
+  const Uint32 reqTableType = req->getTableType();
+  const bool reqListNames = req->getListNames();
+  const bool reqListIndexes = req->getListIndexes();
+
+  NodeReceiverGroup rg(senderRef);
+
+  DLHashTable<DictObject>::Iterator iter;
+  bool done = !c_obj_hash.first(iter);
+
+  if (done)
+  {
+    /*
+     * Empty hashtable, send empty signal
+     */
+    jam();
+    ListTablesConf * const conf = (ListTablesConf*)signal->getDataPtrSend();
+    conf->senderData = senderData;
+    conf->noOfTables = 0;
+    sendSignal(rg, GSN_LIST_TABLES_CONF, signal,
+               ListTablesConf::SignalLength, JBB);
+    return;
+  }
+
+  /*
+    Pack table data and table names (if requested) in
+    two signal segments and send it in one long fragmented
+    signal
+   */
+  ListTablesData ltd;
+  const Uint32 listTablesDataSizeInWords = (sizeof(ListTablesData) + 3) / 4;
+  char tname[MAX_TAB_NAME_SIZE];
+  SimplePropertiesSectionWriter tableDataWriter(getSectionSegmentPool());
+  SimplePropertiesSectionWriter tableNamesWriter(getSectionSegmentPool());
+
+  Uint32 count = 0;
+  Uint32 fragId = rand();
+  Uint32 fragInfo = 0;
+  const Uint32 fragSize = 240;
+
+  tableDataWriter.first();
+  tableNamesWriter.first();
+  while(true)
+  {
+    Uint32 type = iter.curr.p->m_type;
+
+    if ((reqTableType != (Uint32)0) && (reqTableType != type))
+      goto flush;
+
+    if (reqListIndexes && !DictTabInfo::isIndex(type))
+      goto flush;
+
+    TableRecordPtr tablePtr;
+    if (DictTabInfo::isTable(type) || DictTabInfo::isIndex(type)){
+      c_tableRecordPool.getPtr(tablePtr, iter.curr.p->m_id);
+
+      if(reqListIndexes && (reqTableId != tablePtr.p->primaryTableId))
+	goto flush;
+
+      ltd.requestData = 0; // clear
+      ltd.setTableId(tablePtr.i); // id
+      ltd.setTableType(type); // type
+      // state
+
+      if(DictTabInfo::isTable(type)){
+	switch (tablePtr.p->tabState) {
+	case TableRecord::DEFINING:
+	  ltd.setTableState(DictTabInfo::StateBuilding);
+	  break;
+	case TableRecord::PREPARE_DROPPING:
+	case TableRecord::DROPPING:
+	  ltd.setTableState(DictTabInfo::StateDropping);
+	  break;
+	case TableRecord::DEFINED:
+	  ltd.setTableState(DictTabInfo::StateOnline);
+	  break;
+	case TableRecord::BACKUP_ONGOING:
+	  ltd.setTableState(DictTabInfo::StateBackup);
+	  break;
+	default:
+	  ltd.setTableState(DictTabInfo::StateBroken);
+	  break;
+	}
+      }
+      if (tablePtr.p->isIndex()) {
+	switch (tablePtr.p->indexState) {
+	case TableRecord::IS_OFFLINE:
+	  ltd.setTableState(DictTabInfo::StateOffline);
+	  break;
+	case TableRecord::IS_BUILDING:
+	  ltd.setTableState(DictTabInfo::StateBuilding);
+	  break;
+	case TableRecord::IS_DROPPING:
+	  ltd.setTableState(DictTabInfo::StateDropping);
+	  break;
+	case TableRecord::IS_ONLINE:
+	  ltd.setTableState(DictTabInfo::StateOnline);
+	  break;
+	default:
+	  ltd.setTableState(DictTabInfo::StateBroken);
+	  break;
+	}
+      }
+      // Logging status
+      if (! (tablePtr.p->m_bits & TableRecord::TR_Logged)) {
+	ltd.setTableStore(DictTabInfo::StoreNotLogged);
+      } else {
+	ltd.setTableStore(DictTabInfo::StorePermanent);
+      }
+      // Temporary status
+      if (tablePtr.p->m_bits & TableRecord::TR_Temporary) {
+	ltd.setTableTemp(NDB_TEMP_TAB_TEMPORARY);
+      } else {
+	ltd.setTableTemp(NDB_TEMP_TAB_PERMANENT);
+      }
+    }
+    if(DictTabInfo::isTrigger(type)){
+      TriggerRecordPtr triggerPtr;
+      c_triggerRecordPool.getPtr(triggerPtr, iter.curr.p->m_id);
+
+      ltd.requestData = 0;
+      ltd.setTableId(triggerPtr.i);
+      ltd.setTableType(type);
+      switch (triggerPtr.p->triggerState) {
+      case TriggerRecord::TS_OFFLINE:
+	ltd.setTableState(DictTabInfo::StateOffline);
+	break;
+      case TriggerRecord::TS_ONLINE:
+	ltd.setTableState(DictTabInfo::StateOnline);
+	break;
+      default:
+	ltd.setTableState(DictTabInfo::StateBroken);
+	break;
+      }
+      ltd.setTableStore(DictTabInfo::StoreNotLogged);
+    }
+    if (DictTabInfo::isFilegroup(type)){
+      jam();
+      ltd.requestData = 0;
+      ltd.setTableId(iter.curr.p->m_id);
+      ltd.setTableType(type); // type
+      ltd.setTableState(DictTabInfo::StateOnline);  // XXX todo
+    }
+    if (DictTabInfo::isFile(type)){
+      jam();
+      ltd.requestData = 0;
+      ltd.setTableId(iter.curr.p->m_id);
+      ltd.setTableType(type); // type
+      ltd.setTableState(DictTabInfo::StateOnline); // XXX todo
+    }
+    tableDataWriter.putWords((Uint32 *) &ltd, listTablesDataSizeInWords);
+    count++;
+
+    if (reqListNames)
+    {
+      jam();
+      Rope name(c_rope_pool, iter.curr.p->m_name);
+      const Uint32 size = name.size(); // String length including \0
+      const Uint32 wsize = (size + 3) / 4;
+      tableNamesWriter.putWord(size);
+      name.copy(tname);
+      tableNamesWriter.putWords((Uint32 *) tname, wsize);
+    }
+
+flush:
+    Uint32 tableDataWords = tableDataWriter.getWordsUsed();
+    Uint32 tableNameWords = tableNamesWriter.getWordsUsed();
+
+    done = !c_obj_hash.next(iter);
+    if ((tableDataWords + tableNameWords) > fragSize || done)
+    {
+      jam();
+
+      /*
+       * Flush signal fragment to keep memory usage down
+       */
+      Uint32 sigLen = ListTablesConf::SignalLength;
+      Uint32 secs = 0;
+      if (tableDataWords != 0)
+      {
+        jam();
+        secs++;
+      }
+      if (tableNameWords != 0)
+      {
+        jam();
+        secs++;
+      }
+      Uint32 * secNos = &signal->theData[sigLen];
+      signal->theData[sigLen + secs] = fragId;
+      switch (secs) {
+      case(0):
+        jam();
+        sigLen++; // + fragId;
+        break;
+      case(1):
+      {
+        jam();
+        SegmentedSectionPtr segSecPtr;
+        sigLen += 2; // 1 sections + fragid
+        if (tableNameWords == 0)
+        {
+          tableDataWriter.getPtr(segSecPtr);
+          secNos[0] = ListTablesConf::TABLE_DATA;;
+        }
+        else
+        {
+          tableNamesWriter.getPtr(segSecPtr);
+          secNos[0] = ListTablesConf::TABLE_NAMES;
+        }
+        signal->setSection(segSecPtr, 0);
+        break;
+      }
+      case(2):
+      {
+        jam();
+        sigLen += 3; // 2 sections + fragid
+        SegmentedSectionPtr tableDataPtr;
+        tableDataWriter.getPtr(tableDataPtr);
+        signal->setSection(tableDataPtr, ListTablesConf::TABLE_DATA);
+        SegmentedSectionPtr tableNamesPtr;
+        tableNamesWriter.getPtr(tableNamesPtr);
+        signal->setSection(tableNamesPtr, ListTablesConf::TABLE_NAMES);
+        secNos[0] = ListTablesConf::TABLE_DATA;
+        secNos[1] = ListTablesConf::TABLE_NAMES;
+        break;
+      }
+      }
+
+      if (done)
+      {
+        jam();
+        if (fragInfo)
+        {
+          jam();
+          fragInfo = 3;
+        }
+      }
+      else
+      {
+        jam();
+        if (fragInfo == 0)
+        {
+          jam();
+          fragInfo = 1;
+        }
+        else
+        {
+          jam();
+          fragInfo = 2;
+        }
+      }
+      signal->header.m_fragmentInfo = fragInfo;
+
+      ListTablesConf * const conf = (ListTablesConf*)signal->getDataPtrSend();
+      conf->senderData = senderData;
+      conf->noOfTables = count;
+      sendSignal(rg, GSN_LIST_TABLES_CONF, signal,
+                 sigLen, JBB);
+
+      signal->header.m_noOfSections = 0;
+      signal->header.m_fragmentInfo = 0;
+
+      if (done)
+      {
+        jam();
+        return;
+      }
+
+      /**
+       * Reset counter for next signal
+       * Reset buffers
+       */
+      count = 0;
+      tableDataWriter.first();
+      tableNamesWriter.first();
+    }
+  }
 }
 
 /**
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2008-02-20 10:04:24 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2008-05-16 15:08:32 +02:00
@@ -41,6 +41,7 @@
 #include <signaldata/DropTable.hpp>
 #include <signaldata/AlterTable.hpp>
 #include <signaldata/AlterTab.hpp>
+#include <signaldata/ListTables.hpp>
 #include <signaldata/CreateIndx.hpp>
 #include <signaldata/DropIndx.hpp>
 #include <signaldata/AlterIndx.hpp>
@@ -2672,6 +2673,9 @@ public:
   void drop_undofile_commit_complete(Signal* signal, SchemaOp*);
   
   int checkSingleUserMode(Uint32 senderRef);
+
+  void sendOLD_LIST_TABLES_CONF(Signal *signal, ListTablesReq*);
+  void sendLIST_TABLES_CONF(Signal *signal, ListTablesReq*);
 
   Uint32 c_outstanding_sub_startstop;
   NdbNodeBitmask c_sub_startstop_lock;
diff -Nrup a/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp
b/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp
--- a/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp	2006-12-23 20:20:20 +01:00
+++ b/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp	2008-05-16 15:08:32 +02:00
@@ -121,6 +121,55 @@ SimplePropertiesSectionReader::getWords(
 SimplePropertiesSectionWriter::SimplePropertiesSectionWriter(class SectionSegmentPool
& pool)
   : m_pool(pool)
 {
+  m_pos = -1;
+  m_head = 0;
+  m_currentSegment = 0;
+  m_prevPtrI = RNIL;
+  reset();
+}
+
+extern void release(SegmentedSectionPtr & ptr);
+
+SimplePropertiesSectionWriter::~SimplePropertiesSectionWriter()
+{
+  release();
+}
+
+void
+SimplePropertiesSectionWriter::release()
+{
+  if (m_head)
+  {
+    if (m_sz)
+    {
+      SegmentedSectionPtr ptr;
+      ptr.p = m_head;
+      ptr.i = m_head->m_lastSegment;
+      ptr.sz = m_sz;
+      m_head->m_sz = m_sz;
+      m_head->m_lastSegment = m_currentSegment->m_lastSegment;
+
+      if((m_pos % SectionSegment::DataLength) == 0){
+        m_pool.release(m_currentSegment->m_lastSegment);
+        m_head->m_lastSegment = m_prevPtrI;
+      }
+      ::release(ptr);
+    }
+    else
+    {
+      m_pool.release(m_head->m_lastSegment);
+    }
+  }
+  m_pos = -1;
+  m_head = 0;
+  m_currentSegment = 0;
+  m_prevPtrI = RNIL;
+}
+
+bool
+SimplePropertiesSectionWriter::reset()
+{
+  release();
   Ptr<SectionSegment> first;
   if(m_pool.seize(first)){
     ;
@@ -129,7 +178,7 @@ SimplePropertiesSectionWriter::SimplePro
     m_head = 0;
     m_currentSegment = 0;
     m_prevPtrI = RNIL;
-    return;
+    return false;
   }
   m_sz = 0;
   m_pos = 0;
@@ -137,14 +186,6 @@ SimplePropertiesSectionWriter::SimplePro
   m_head->m_lastSegment = first.i;
   m_currentSegment = first.p;
   m_prevPtrI = RNIL;
-}
-  
-bool
-SimplePropertiesSectionWriter::reset(){
-  if(m_pos >= 0){
-    m_pos = 0;
-    return true;
-  }
   return false;
 }
 
@@ -188,6 +229,11 @@ SimplePropertiesSectionWriter::putWords(
   return true;
 }
 
+Uint32 SimplePropertiesSectionWriter::getWordsUsed() const
+{
+  return m_sz;
+}
+
 void
 SimplePropertiesSectionWriter::getPtr(struct SegmentedSectionPtr & dst){
   // Set last ptr and size
@@ -213,8 +259,11 @@ SimplePropertiesSectionWriter::getPtr(st
   dst.sz = 0;
   dst.i = RNIL;
 
-  m_pool.release(m_head->m_lastSegment);
-  
+  if (m_head)
+  {
+    m_pool.release(m_head->m_lastSegment);
+  }
+
   m_sz = 0;
   m_pos = -1;
   m_head = m_currentSegment = 0;
diff -Nrup a/storage/ndb/src/ndbapi/NdbApiSignal.hpp
b/storage/ndb/src/ndbapi/NdbApiSignal.hpp
--- a/storage/ndb/src/ndbapi/NdbApiSignal.hpp	2006-12-23 20:20:22 +01:00
+++ b/storage/ndb/src/ndbapi/NdbApiSignal.hpp	2008-05-16 15:08:32 +02:00
@@ -76,6 +76,7 @@ public:  
   /**
    * Fragmentation
    */
+  bool isFragmented() const { return m_fragmentInfo != 0;}
   bool isFirstFragment() const { return m_fragmentInfo <= 1;}
   bool isLastFragment() const { 
     return m_fragmentInfo == 0 || m_fragmentInfo == 3; 
diff -Nrup a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2008-04-01 19:09:22 +02:00
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2008-05-16 15:08:32 +02:00
@@ -4542,13 +4542,12 @@ NdbDictionaryImpl::listObjects(List& lis
 
   ListTablesReq req;
   req.requestData = 0;
+  req.tableId = 0;
   req.setTableType(getKernelConstant(type, objectTypeMapping, 0));
   req.setListNames(true);
   if (!list2.count)
-    return m_receiver.listObjects(list, req.requestData,
-                                  m_ndb.usingFullyQualifiedNames());
-  ret = m_receiver.listObjects(list1, req.requestData,
-                               m_ndb.usingFullyQualifiedNames());
+    return m_receiver.listObjects(list, req, m_ndb.usingFullyQualifiedNames());
+  ret = m_receiver.listObjects(list1, req, m_ndb.usingFullyQualifiedNames());
   if (ret)
     return ret;
   list.count = list1.count + list2.count;
@@ -4576,25 +4575,168 @@ NdbDictionaryImpl::listIndexes(List& lis
   ListTablesReq req;
   req.requestData = 0;
   req.setTableId(indexId);
+  req.tableType = 0;
   req.setListNames(true);
   req.setListIndexes(true);
-  return m_receiver.listObjects(list, req.requestData, m_ndb.usingFullyQualifiedNames());
+  return m_receiver.listObjects(list, req, m_ndb.usingFullyQualifiedNames());
 }
 
 int
 NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list,
-			      Uint32 requestData, bool fullyQualifiedNames)
+                              ListTablesReq& ltreq, bool fullyQualifiedNames)
 {
+  bool listTablesLongSignal = false;
   NdbApiSignal tSignal(m_reference);
   ListTablesReq* const req = CAST_PTR(ListTablesReq, tSignal.getDataPtrSend());
   req->senderRef = m_reference;
   req->senderData = 0;
-  req->requestData = requestData;
+  req->requestData = ltreq.requestData;
+  req->setTableId(ltreq.getTableId());
+  req->setTableType(ltreq.getTableType());
+  if (ltreq.getTableId() > 4096)
+  {
+    /*
+      Enforce new long signal format,
+      if this is not supported by the
+      called node the request will fail
+     */
+    listTablesLongSignal = true;
+  }
+
+  /*
+    Set table id and type according to old format
+    in case sent to old nodes (during upgrade).
+  */
+  req->oldSetTableId(ltreq.getTableId());
+  req->oldSetTableType(ltreq.getTableType());
+
   tSignal.theReceiversBlockNumber = DBDICT;
   tSignal.theVerId_signalNumber = GSN_LIST_TABLES_REQ;
   tSignal.theLength = ListTablesReq::SignalLength;
-  if (listObjects(&tSignal) != 0)
+  if (listObjects(&tSignal, listTablesLongSignal) != 0)
     return -1;
+
+  if (listTablesLongSignal)
+  {
+    return unpackListTables(list, fullyQualifiedNames);
+  }
+  else
+  {
+    return unpackOldListTables(list, fullyQualifiedNames);
+  }
+}
+
+int
+NdbDictInterface::unpackListTables(NdbDictionary::Dictionary::List& list,
+                                   bool fullyQualifiedNames)
+{
+  Uint32 count = 0;
+  Uint32* tableData = (Uint32*)m_tableData.get_data();
+  Uint32* tableNames = (Uint32*)m_tableNames.get_data();
+  const Uint32 listTablesDataSizeInWords = (sizeof(ListTablesData) + 3) / 4;
+  list.count = m_noOfTables;
+  list.elements = new NdbDictionary::Dictionary::List::Element[m_noOfTables];
+
+  while (count < m_noOfTables)
+  {
+    NdbDictionary::Dictionary::List::Element& element = list.elements[count];
+    ListTablesData* ltd = (ListTablesData *) tableData;
+    tableData += listTablesDataSizeInWords;
+    element.id = ltd->getTableId();
+    element.type = (NdbDictionary::Object::Type)
+      getApiConstant(ltd->getTableType(), objectTypeMapping, 0);
+    element.state = (NdbDictionary::Object::State)
+      getApiConstant(ltd->getTableState(), objectStateMapping, 0);
+    element.store = (NdbDictionary::Object::Store)
+      getApiConstant(ltd->getTableStore(), objectStoreMapping, 0);
+    element.temp = ltd->getTableTemp();
+    // table or index name
+    BaseString databaseName;
+    BaseString schemaName;
+    BaseString objectName;
+    if (!databaseName || !schemaName || !objectName)
+    {
+      m_error.code= 4000;
+      return -1;
+    }
+    Uint32 size = tableNames[0];
+    Uint32 wsize = (size + 3) / 4;
+    tableNames++;
+    if ((element.type == NdbDictionary::Object::UniqueHashIndex) ||
+	(element.type == NdbDictionary::Object::OrderedIndex)) {
+      char * indexName = new char[size];
+      if (indexName == NULL)
+      {
+        m_error.code= 4000;
+        return -1;
+      }
+      memcpy(indexName, (char *) tableNames, size);
+      if (!(databaseName = Ndb::getDatabaseFromInternalName(indexName)) ||
+          !(schemaName = Ndb::getSchemaFromInternalName(indexName)))
+      {
+        delete [] indexName;
+        m_error.code= 4000;
+        return -1;
+      }
+      objectName = BaseString(Ndb::externalizeIndexName(indexName,
+                                                        fullyQualifiedNames));
+      delete [] indexName;
+    } else if ((element.type == NdbDictionary::Object::SystemTable) ||
+	       (element.type == NdbDictionary::Object::UserTable)) {
+      char * tableName = new char[size];
+      if (tableName == NULL)
+      {
+        m_error.code= 4000;
+        return -1;
+      }
+      memcpy(tableName, (char *) tableNames, size);
+      if (!(databaseName = Ndb::getDatabaseFromInternalName(tableName)) ||
+          !(schemaName = Ndb::getSchemaFromInternalName(tableName)))
+      {
+        delete [] tableName;
+        m_error.code= 4000;
+        return -1;
+      }
+      objectName = BaseString(Ndb::externalizeTableName(tableName,
+                                                        fullyQualifiedNames));
+      delete [] tableName;
+    }
+    else {
+      char * otherName = new char[size];
+      if (otherName == NULL)
+      {
+        m_error.code= 4000;
+        return -1;
+      }
+      memcpy(otherName, (char *) tableNames, size);
+      if (!(objectName = BaseString(otherName)))
+      {
+        m_error.code= 4000;
+        return -1;
+      }
+      delete [] otherName;
+    }
+    if (!(element.database = new char[databaseName.length() + 1]) ||
+        !(element.schema = new char[schemaName.length() + 1]) ||
+        !(element.name = new char[objectName.length() + 1]))
+    {
+      m_error.code= 4000;
+      return -1;
+    }
+    strcpy(element.database, databaseName.c_str());
+    strcpy(element.schema, schemaName.c_str());
+    strcpy(element.name, objectName.c_str());
+    count++;
+    tableNames += wsize;
+  }
+
+  return 0;
+}
+
+int
+NdbDictInterface::unpackOldListTables(NdbDictionary::Dictionary::List& list,
+                                      bool fullyQualifiedNames)
+{
   // count
   const Uint32* data = (const Uint32*)m_buffer.get_data();
   const unsigned length = m_buffer.length() / 4;
@@ -4628,14 +4770,14 @@ NdbDictInterface::listObjects(NdbDiction
   while (pos < length) {
     NdbDictionary::Dictionary::List::Element& element = list.elements[count];
     Uint32 d = data[pos++];
-    element.id = ListTablesConf::getTableId(d);
+    element.id = OldListTablesConf::getTableId(d);
     element.type = (NdbDictionary::Object::Type)
-      getApiConstant(ListTablesConf::getTableType(d), objectTypeMapping, 0);
+      getApiConstant(OldListTablesConf::getTableType(d), objectTypeMapping, 0);
     element.state = (NdbDictionary::Object::State)
-      getApiConstant(ListTablesConf::getTableState(d), objectStateMapping, 0);
+      getApiConstant(OldListTablesConf::getTableState(d), objectStateMapping, 0);
     element.store = (NdbDictionary::Object::Store)
-      getApiConstant(ListTablesConf::getTableStore(d), objectStoreMapping, 0);
-    element.temp = ListTablesConf::getTableTemp(d);
+      getApiConstant(OldListTablesConf::getTableStore(d), objectStoreMapping, 0);
+    element.temp = OldListTablesConf::getTableTemp(d);
     // table or index name
     Uint32 n = (data[pos++] + 3) >> 2;
     BaseString databaseName;
@@ -4715,7 +4857,8 @@ NdbDictInterface::listObjects(NdbDiction
 }
 
 int
-NdbDictInterface::listObjects(NdbApiSignal* signal)
+NdbDictInterface::listObjects(NdbApiSignal* signal,
+                              bool& listTablesLongSignal)
 {
   const Uint32 RETRIES = 100;
   for (Uint32 i = 0; i < RETRIES; i++) {
@@ -4733,6 +4876,24 @@ NdbDictInterface::listObjects(NdbApiSign
       m_error.code= 4009;
       return -1;
     }
+    NodeInfo info = m_transporter->theClusterMgr->getNodeInfo(aNodeId).m_info;
+    if (ndbd_LIST_TABLES_CONF_long_signal(info.m_version))
+    {
+      /*
+        Called node will return a long signal
+       */
+      listTablesLongSignal = true;
+    }
+    else if (listTablesLongSignal)
+    {
+      /*
+        We are requesting info from a table with table id > 4096
+        and older versions don't support that, bug#36044
+      */
+      m_error.code= 4105;
+      return -1;
+    }
+
     if (m_transporter->sendSignal(signal, aNodeId) != 0) {
       continue;
     }
@@ -4751,15 +4912,94 @@ NdbDictInterface::listObjects(NdbApiSign
 
 void
 NdbDictInterface::execLIST_TABLES_CONF(NdbApiSignal* signal,
-				       LinearSectionPtr ptr[3])
+                                       LinearSectionPtr ptr[3])
 {
-  const unsigned off = ListTablesConf::HeaderLength;
+  Uint16 nodeId = refToNode(signal->theSendersBlockRef);
+  NodeInfo info = m_transporter->theClusterMgr->getNodeInfo(nodeId).m_info;
+  if (!ndbd_LIST_TABLES_CONF_long_signal(info.m_version))
+  {
+    /*
+      Sender doesn't support new signal format
+     */
+    NdbDictInterface::execOLD_LIST_TABLES_CONF(signal, ptr);
+    return;
+  }
+
+  if (signal->isFirstFragment())
+  {
+    m_fragmentId = signal->getFragmentId();
+    m_noOfTables = 0;
+    m_tableData.clear();
+    m_tableNames.clear();
+  }
+  else
+  {
+    Uint32 fid = signal->getFragmentId();
+    if (m_fragmentId != signal->getFragmentId())
+    {
+      abort();
+    }
+  }
+
+  /*
+    Save the count
+   */
+  const ListTablesConf* const conf=
+    CAST_CONSTPTR(ListTablesConf, signal->getDataPtr());
+  m_noOfTables+= conf->noOfTables;
+
+  bool fragmented = signal->isFragmented();
+  Uint32 sigLen = signal->getLength() - 1;
+  const Uint32 secs = signal->m_noOfSections;
+  const Uint32 directMap[3] = {0,1,2};
+  const Uint32 * const secNos =
+    (fragmented) ?
+    &signal->getDataPtr()[sigLen - secs]
+    : (const Uint32 *) &directMap;
+
+  for(Uint32 i = 0; i<secs; i++)
+  {
+    Uint32 sectionNo = secNos[i];
+    switch (sectionNo) {
+    case(ListTablesConf::TABLE_DATA):
+      if (m_tableData.append(ptr[i].p, 4 * ptr[i].sz))
+      {
+        m_error.code= 4000;
+        goto end;
+      }
+      break;
+    case(ListTablesConf::TABLE_NAMES):
+      if (m_tableNames.append(ptr[i].p, 4 * ptr[i].sz))
+      {
+        m_error.code= 4000;
+        goto end;
+      }
+      break;
+    default:
+      abort();
+    }
+  }
+
+ end:
+  if(!signal->isLastFragment()){
+    return;
+  }
+
+  m_waiter.signal(NO_WAIT);
+}
+
+
+void
+NdbDictInterface::execOLD_LIST_TABLES_CONF(NdbApiSignal* signal,
+                                           LinearSectionPtr ptr[3])
+{
+  const unsigned off = OldListTablesConf::HeaderLength;
   const unsigned len = (signal->getLength() - off);
   if (m_buffer.append(signal->getDataPtr() + off, len << 2))
   {
     m_error.code= 4000;
   }
-  if (signal->getLength() < ListTablesConf::SignalLength) {
+  if (signal->getLength() < OldListTablesConf::SignalLength) {
     // last signal has less than full length
     m_waiter.signal(NO_WAIT);
   }
@@ -4816,7 +5056,7 @@ NdbDictInterface::execWAIT_GCP_CONF(NdbA
 
 void
 NdbDictInterface::execWAIT_GCP_REF(NdbApiSignal* signal,
-				    LinearSectionPtr ptr[3])
+                                   LinearSectionPtr ptr[3])
 {
   m_waiter.signal(NO_WAIT);
 }
diff -Nrup a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2008-04-01 17:36:49 +02:00
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2008-05-16 15:08:32 +02:00
@@ -31,6 +31,8 @@
 #include "NdbWaiter.hpp"
 #include "DictCache.hpp"
 
+class ListTablesReq;
+
 bool
 is_ndb_blob_table(const char* name, Uint32* ptab_id = 0, Uint32* pcol_no = 0);
 bool
@@ -506,8 +508,14 @@ public:
   int executeSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &);
   int stopSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &);
   
-  int listObjects(NdbDictionary::Dictionary::List& list, Uint32 requestData, bool
fullyQualifiedNames);
-  int listObjects(NdbApiSignal* signal);
+  int listObjects(NdbDictionary::Dictionary::List& list,
+                  ListTablesReq& ltreq, bool fullyQualifiedNames);
+  int listObjects(NdbApiSignal* signal, bool& listTablesLongSignal);
+
+  int unpackListTables(NdbDictionary::Dictionary::List& list,
+                       bool fullyQualifiedNames);
+  int unpackOldListTables(NdbDictionary::Dictionary::List& list,
+                          bool fullyQualifiedNames);
   
   NdbTableImpl * getTable(int tableId, bool fullyQualifiedNames);
   NdbTableImpl * getTable(const BaseString& name, bool fullyQualifiedNames);
@@ -584,6 +592,7 @@ private:
 
   void execDROP_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
   void execDROP_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+  void execOLD_LIST_TABLES_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
   void execLIST_TABLES_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
 
   void execCREATE_FILE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
@@ -603,6 +612,10 @@ private:
 
   Uint32 m_fragmentId;
   UtilBuffer m_buffer;
+
+  Uint32 m_noOfTables;
+  UtilBuffer m_tableData;
+  UtilBuffer m_tableNames;
 };
 
 class NdbDictionaryImpl;
diff -Nrup a/storage/ndb/src/ndbapi/TransporterFacade.hpp
b/storage/ndb/src/ndbapi/TransporterFacade.hpp
--- a/storage/ndb/src/ndbapi/TransporterFacade.hpp	2007-04-02 21:37:47 +02:00
+++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp	2008-05-16 15:08:32 +02:00
@@ -176,7 +176,8 @@ private:
   friend class Ndb;
   friend class Ndb_cluster_connection_impl;
   friend class NdbTransaction;
-  
+  friend class NdbDictInterface;
+
   int sendSignalUnCond(NdbApiSignal *, NodeId nodeId);
 
   bool isConnected(NodeId aNodeId);
Thread
bk commit into 5.1 tree (jonas:1.2595)jonas16 May