List:Commits« Previous MessageNext Message »
From:knielsen Date:August 30 2006 9:54am
Subject:bk commit into 5.1 tree (knielsen:1.2387)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of knielsen. When knielsen 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, 2006-08-30 11:54:00+02:00, knielsen@ymer.(none) +24 -0
  New feature: NDB temporary tables.
  
  Temporary tables are not written to disk by DDL operations. This makes
  DDL much faster (useful for tests), but tables are lost after system
  restart.
  
  Temporary tables are enabled by the new ndb_use_temporary_tables server
  variable.

  mysql-test/r/ndb_basic.result@stripped, 2006-08-30 11:53:52+02:00, knielsen@ymer.(none) +3 -0
    Use temporary tables in test, for increased speed.

  mysql-test/t/ndb_basic.test@stripped, 2006-08-30 11:53:52+02:00, knielsen@ymer.(none) +5 -0
    Use temporary tables in test, for increased speed.

  sql/ha_ndbcluster.cc@stripped, 2006-08-30 11:53:52+02:00, knielsen@ymer.(none) +22 -1
    Use temporary NDB tables/indexes if server variable
    ndb_use_temporary_tables is set.

  sql/ha_ndbcluster_binlog.cc@stripped, 2006-08-30 11:53:52+02:00, knielsen@ymer.(none) +15 -6
    More verbose messages.

  sql/mysqld.cc@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +8 -0
    Add server variable "ndb_use_temporary_tables".

  sql/set_var.cc@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +5 -0
    Add server variable "ndb_use_temporary_tables".

  sql/sql_class.h@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +1 -0
    Add server variable "ndb_use_temporary_tables".

  storage/ndb/include/kernel/signaldata/CreateIndx.hpp@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +4 -1
    Add new error messages for temporary tables.

  storage/ndb/include/kernel/signaldata/CreateTable.hpp@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +2 -1
    Add new error messages for temporary tables.

  storage/ndb/include/kernel/signaldata/DiAddTab.hpp@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +3 -2
    Add parameter for making table temporary.

  storage/ndb/include/kernel/signaldata/DictTabInfo.hpp@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +12 -1
    Add parameter for making table temporary.

  storage/ndb/include/kernel/signaldata/ListTables.hpp@stripped, 2006-08-30 11:53:53+02:00, knielsen@ymer.(none) +14 -2
    Add parameter for making table temporary.

  storage/ndb/include/ndbapi/NdbDictionary.hpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +17 -2
    Add parameter for making table temporary.

  storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +2 -0
    Add parameter for making table temporary.

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +242 -55
    Implement temporary tables.

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +6 -3
    Implement temporary tables.

  storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +2 -1
    Implement temporary tables.

  storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +6 -1
    Implement temporary tables.

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +27 -14
    Implement temporary tables.

  storage/ndb/src/ndbapi/NdbDictionary.cpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +10 -0
    Implement temporary tables.

  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +24 -1
    Implement temporary tables.

  storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +2 -0
    Implement temporary tables.

  storage/ndb/src/ndbapi/ndberror.c@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +4 -1
    Add new error messages for temporary tables.

  storage/ndb/tools/listTables.cpp@stripped, 2006-08-30 11:53:54+02:00, knielsen@ymer.(none) +24 -8
    Add display of table and index temporary status.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	knielsen
# Host:	ymer.(none)
# Root:	/usr/local/mysql/mysql-5.1-pbsu

--- 1.553/sql/mysqld.cc	2006-08-30 11:54:17 +02:00
+++ 1.554/sql/mysqld.cc	2006-08-30 11:54:18 +02:00
@@ -4652,6 +4652,7 @@ enum options_mysqld
   OPT_NDB_EXTRA_LOGGING,
   OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
   OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
+  OPT_NDB_USE_TEMPORARY_TABLES,
   OPT_SKIP_SAFEMALLOC,
   OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
   OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
@@ -5392,6 +5393,13 @@ Disable with --skip-ndbcluster (will sav
    (gptr*) &global_system_variables.ndb_index_stat_update_freq,
    (gptr*) &max_system_variables.ndb_index_stat_update_freq,
    0, GET_ULONG, OPT_ARG, 20, 0, ~0L, 0, 0, 0},
+  {"ndb-use-temporary-tables", OPT_NDB_USE_TEMPORARY_TABLES,
+   "Create tables in a non-durable form inside the cluster, mainly for"
+   "test purposes. Such tables are much faster to create and drop, but"
+   "are lost after a cluster system restart.",
+   (gptr*) &global_system_variables.ndb_use_temporary_tables,
+   (gptr*) &global_system_variables.ndb_use_temporary_tables,
+   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 #endif
   {"new", 'n', "Use very new possible 'unsafe' functions.",
    (gptr*) &global_system_variables.new_mode,

--- 1.293/sql/sql_class.h	2006-08-30 11:54:18 +02:00
+++ 1.294/sql/sql_class.h	2006-08-30 11:54:18 +02:00
@@ -246,6 +246,7 @@ struct system_variables
   my_bool ndb_use_exact_count;
   my_bool ndb_use_transactions;
   my_bool ndb_index_stat_enable;
+  my_bool ndb_use_temporary_tables;
   ulong ndb_autoincrement_prefetch_sz;
   ulong ndb_index_stat_cache_entries;
   ulong ndb_index_stat_update_freq;

--- 1.40/mysql-test/r/ndb_basic.result	2006-08-30 11:54:18 +02:00
+++ 1.41/mysql-test/r/ndb_basic.result	2006-08-30 11:54:18 +02:00
@@ -1,5 +1,6 @@
 DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7;
 drop database if exists mysqltest;
+SET SESSION ndb_use_temporary_tables = 1;
 CREATE TABLE t1 (
 pk1 INT NOT NULL PRIMARY KEY,
 attr1 INT NOT NULL,
@@ -619,6 +620,7 @@ create table t1
 datavalue char(40) default 'XXXX',
 primary key (counter)
 ) ENGINE=ndbcluster;
+SET SESSION ndb_use_temporary_tables = 1;
 insert into t1 (datavalue) values ('newval');
 insert into t1 (datavalue) values ('newval');
 select * from t1 order by counter;
@@ -637,6 +639,7 @@ counter	datavalue
 6	newval
 7	newval
 8	newval
+SET SESSION ndb_use_temporary_tables = 1;
 insert into t1 (datavalue) select datavalue from t1 where counter < 100;
 insert into t1 (datavalue) select datavalue from t1 where counter < 100;
 select * from t1 order by counter;

--- 1.41/mysql-test/t/ndb_basic.test	2006-08-30 11:54:18 +02:00
+++ 1.42/mysql-test/t/ndb_basic.test	2006-08-30 11:54:18 +02:00
@@ -6,6 +6,9 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t
 drop database if exists mysqltest;
 --enable_warnings
 
+# Use temporary tables for speed.
+SET SESSION ndb_use_temporary_tables = 1;
+
 # workaround for bug#16445
 # remove to reproduce bug and run tests from ndb start
 # and with ndb_autodiscover disabled. Fails on Linux 50 % of the times
@@ -607,6 +610,7 @@ create table t1
 	) ENGINE=ndbcluster;
 
 connection con1;
+SET SESSION ndb_use_temporary_tables = 1;
 insert into t1 (datavalue) values ('newval');
 insert into t1 (datavalue) values ('newval');
 select * from t1 order by counter;
@@ -614,6 +618,7 @@ insert into t1 (datavalue) select datava
 insert into t1 (datavalue) select datavalue from t1 where counter < 100;
 select * from t1 order by counter;
 connection con2;
+SET SESSION ndb_use_temporary_tables = 1;
 insert into t1 (datavalue) select datavalue from t1 where counter < 100;
 insert into t1 (datavalue) select datavalue from t1 where counter < 100;
 select * from t1 order by counter;

--- 1.8/storage/ndb/include/kernel/signaldata/CreateIndx.hpp	2006-08-30 11:54:18 +02:00
+++ 1.9/storage/ndb/include/kernel/signaldata/CreateIndx.hpp	2006-08-30 11:54:18 +02:00
@@ -207,7 +207,10 @@ public:
     NotUnique = 4251,
     AllocationError = 4252,
     CreateIndexTableFailed = 4253,
-    DuplicateAttributes = 4258
+    DuplicateAttributes = 4258,
+    TableIsTemporary = 4275,
+    TableIsNotTemporary = 4276,
+    NoLoggingTemporaryIndex = 4277,
   };
 
   CreateIndxConf m_conf;

--- 1.6/storage/ndb/include/kernel/signaldata/CreateTable.hpp	2006-08-30 11:54:18 +02:00
+++ 1.7/storage/ndb/include/kernel/signaldata/CreateTable.hpp	2006-08-30 11:54:18 +02:00
@@ -96,7 +96,8 @@ public:
     VarsizeBitfieldNotSupported = 757,
     NotATablespace = 758,
     InvalidTablespaceVersion = 759,
-    OutOfStringBuffer = 773
+    OutOfStringBuffer = 773,
+    NoLoggingTemporaryTable = 4277,
   };
 
 private:

--- 1.3/storage/ndb/include/kernel/signaldata/DiAddTab.hpp	2006-08-30 11:54:18 +02:00
+++ 1.4/storage/ndb/include/kernel/signaldata/DiAddTab.hpp	2006-08-30 11:54:18 +02:00
@@ -30,7 +30,7 @@ class DiAddTabReq {
    */
   friend class Dbdih;
 public:
-  STATIC_CONST( SignalLength = 9 );
+  STATIC_CONST( SignalLength = 10 );
   SECTION( FRAGMENTATION = 0 );
   SECTION( TS_RANGE = 0 );
   
@@ -40,10 +40,11 @@ private:
   Uint32 fragType;
   Uint32 kValue;
   Uint32 noOfReplicas; //Currently not used
-  Uint32 storedTable;
+  Uint32 loggedTable;
   Uint32 tableType;
   Uint32 schemaVersion;
   Uint32 primaryTableId;
+  Uint32 temporaryTable;
 };
 
 class DiAddTabRef {

--- 1.28/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2006-08-30 11:54:18 +02:00
+++ 1.29/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2006-08-30 11:54:18 +02:00
@@ -117,6 +117,9 @@ public:
     CustomTriggerId    = 25,
     FrmLen             = 26,
     FrmData            = 27,
+
+    TableTemporaryFlag = 28,  //Default not Temporary
+
     FragmentCount      = 128, // No of fragments in table (!fragment replicas)
     FragmentDataLen    = 129,
     FragmentData       = 130, // CREATE_FRAGMENTATION reply
@@ -275,10 +278,17 @@ public:
   // Object store for translating from/to API
   enum ObjectStore {
     StoreUndefined = 0,
-    StoreTemporary = 1,
+    StoreNotLogged = 1,
     StorePermanent = 2
   };
   
+  // Object temporary status for translating from/to API
+  enum ObjectTemp {
+    TempUndefined = 0,
+    TempIsTemporary = 1,
+    TempIsPermanent = 2
+  };
+  
   // AttributeSize constants
   STATIC_CONST( aBit = 0 );
   STATIC_CONST( an8Bit = 3 );
@@ -294,6 +304,7 @@ public:
     char   PrimaryTable[MAX_TAB_NAME_SIZE]; // Only used when "index"
     Uint32 PrimaryTableId;
     Uint32 TableLoggedFlag;
+    Uint32 TableTemporaryFlag;
     Uint32 NoOfKeyAttr;
     Uint32 NoOfAttributes;
     Uint32 NoOfNullable;

--- 1.2/storage/ndb/include/kernel/signaldata/ListTables.hpp	2006-08-30 11:54:18 +02:00
+++ 1.3/storage/ndb/include/kernel/signaldata/ListTables.hpp	2006-08-30 11:54:18 +02:00
@@ -42,10 +42,16 @@ public:
     return BitmaskImpl::getField(1, &data, 20, 4);
   }
   static void setTableStore(Uint32& data, Uint32 val) {
-    BitmaskImpl::setField(1, &data, 20, 4, val);
+    BitmaskImpl::setField(1, &data, 20, 2, val);
   }
   static Uint32 getTableState(Uint32 data) {
-    return BitmaskImpl::getField(1, &data, 24, 4);
+    return BitmaskImpl::getField(1, &data, 24, 2);
+  }
+  static Uint32 getTableTemp(Uint32 data) {
+    return BitmaskImpl::getField(1, &data, 26, 2);
+  }
+  static void setTableTemp(Uint32& data, Uint32 val) {
+    BitmaskImpl::setField(1, &data, 26, 2, val);
   }
   static void setTableState(Uint32& data, Uint32 val) {
     BitmaskImpl::setField(1, &data, 24, 4, val);
@@ -160,6 +166,12 @@ public:  
   }
   void setTableState(unsigned pos, Uint32 val) {
     ListTablesData::setTableState(tableData[pos], val);
+  }
+  static Uint32 getTableTemp(Uint32 data) {
+    return ListTablesData::getTableTemp(data);
+  }
+  void setTableTemp(unsigned pos, Uint32 val) {
+    ListTablesData::setTableTemp(tableData[pos], val);
   }
 };
 

--- 1.74/storage/ndb/include/ndbapi/NdbDictionary.hpp	2006-08-30 11:54:18 +02:00
+++ 1.75/storage/ndb/include/ndbapi/NdbDictionary.hpp	2006-08-30 11:54:18 +02:00
@@ -136,11 +136,20 @@ public:
      */
     enum Store {
       StoreUndefined = 0,     ///< Undefined
-      StoreTemporary = 1,     ///< Object or data deleted on system restart
+      StoreNotLogged = 1,     ///< Object or data deleted on system restart
       StorePermanent = 2      ///< Permanent. logged to disk
     };
 
     /**
+     * Object store
+     */
+    enum Temp {
+      TempUndefined   = 0,    ///< Undefined
+      TempIsTemporary = 1,    ///< Object or data deleted on system restart
+      TempIsPermanent = 2     ///< Permanent. logged to disk
+    };
+
+    /**
      * Type of fragmentation.
      *
      * This parameter specifies how data in the table or index will
@@ -884,6 +893,8 @@ public:
     int createTableInDb(Ndb*, bool existingEqualIsOk = true) const ;
 
     int getReplicaCount() const ;
+
+    void setTemporary(bool); 
 #endif
 
   private:
@@ -1071,6 +1082,8 @@ public:
 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
     void setStoredIndex(bool x) { setLogging(x); }
     bool getStoredIndex() const { return getLogging(); }
+
+    void setTemporary(bool); 
 #endif
     
     /** @} *******************************************************************/
@@ -1530,7 +1543,8 @@ public:
 	unsigned id;            ///< Id of object
         Object::Type type;      ///< Type of object
         Object::State state;    ///< State of object
-        Object::Store store;    ///< How object is stored
+        Object::Store store;    ///< How object is logged
+        Object::Temp temp;      ///< Temporary status of object
 	char * database;        ///< In what database the object resides 
 	char * schema;          ///< What schema the object is defined in
 	char * name;            ///< Name of object
@@ -1539,6 +1553,7 @@ public:
           type(Object::TypeUndefined),
           state(Object::StateUndefined),
           store(Object::StoreUndefined),
+          temp(Object::TempUndefined),
 	  database(0),
 	  schema(0),
           name(0) {

--- 1.16/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp	2006-08-30 11:54:18 +02:00
+++ 1.17/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp	2006-08-30 11:54:18 +02:00
@@ -26,6 +26,7 @@ DictTabInfo::TableMapping[] = {
   DTIMAPS(Table, PrimaryTable, PrimaryTable, 0, MAX_TAB_NAME_SIZE),
   DTIMAP(Table, PrimaryTableId, PrimaryTableId),
   DTIMAP2(Table, TableLoggedFlag, TableLoggedFlag, 0, 1),
+  DTIMAP2(Table, TableTemporaryFlag, TableTemporaryFlag, 0, 1),
   DTIMAP2(Table, TableKValue, TableKValue,         6, 6),
   DTIMAP2(Table, MinLoadFactor, MinLoadFactor,     0, 90),
   DTIMAP2(Table, MaxLoadFactor, MaxLoadFactor,    25, 110),
@@ -118,6 +119,7 @@ DictTabInfo::Table::init(){
   memset(PrimaryTable, 0, sizeof(PrimaryTable));//PrimaryTable[0] = 0; // Only used when "index"
   PrimaryTableId = RNIL;
   TableLoggedFlag = 1;
+  TableTemporaryFlag = 0;
   NoOfKeyAttr = 0;
   NoOfAttributes = 0;
   NoOfNullable = 0;

--- 1.87/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2006-08-30 11:54:18 +02:00
+++ 1.88/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2006-08-30 11:54:18 +02:00
@@ -443,6 +443,8 @@ Dbdict::packTableIntoPages(SimplePropert
 	!!(tablePtr.p->m_bits & TableRecord::TR_RowGCI));
   w.add(DictTabInfo::RowChecksumFlag, 
 	!!(tablePtr.p->m_bits & TableRecord::TR_RowChecksum));
+  w.add(DictTabInfo::TableTemporaryFlag, 
+	!!(tablePtr.p->m_bits & TableRecord::TR_Temporary));
   
   w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor);
   w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor);
@@ -1079,8 +1081,8 @@ void Dbdict::closeReadTableConf(Signal* 
 /* ---------------------------------------------------------------- */
 void
 Dbdict::updateSchemaState(Signal* signal, Uint32 tableId, 
-			  SchemaFile::TableEntry* te, Callback* callback){
-
+			  SchemaFile::TableEntry* te, Callback* callback,
+                          bool savetodisk){
   jam();
   ndbrequire(tableId < c_tableRecordPool.getSize());
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
@@ -1123,6 +1125,12 @@ Dbdict::updateSchemaState(Signal* signal
     jam();
     ok = true;
     break;
+  case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+    jam();
+    ndbrequire(oldState == SchemaFile::ADD_STARTED ||
+               oldState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
+    ok = true;
+    break;
   case SchemaFile::INIT:
     jam();
     ok = true;
@@ -1133,16 +1141,23 @@ Dbdict::updateSchemaState(Signal* signal
   * tableEntry = * te;
   computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
 
-  ndbrequire(c_writeSchemaRecord.inUse == false);
-  c_writeSchemaRecord.inUse = true;
-  
-  c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
-  c_writeSchemaRecord.newFile = false;
-  c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
-  c_writeSchemaRecord.noOfPages = 1;
-  c_writeSchemaRecord.m_callback = * callback;
-
-  startWriteSchemaFile(signal);
+  if (savetodisk)
+  {
+    ndbrequire(c_writeSchemaRecord.inUse == false);
+    c_writeSchemaRecord.inUse = true;
+    
+    c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
+    c_writeSchemaRecord.newFile = false;
+    c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
+    c_writeSchemaRecord.noOfPages = 1;
+    c_writeSchemaRecord.m_callback = * callback;
+    
+    startWriteSchemaFile(signal);
+  }
+  else
+  {
+    execute(signal, *callback, 0);
+  }
 }
 
 void Dbdict::startWriteSchemaFile(Signal* signal)
@@ -2707,6 +2722,13 @@ void Dbdict::checkSchemaStatus(Signal* s
 	newEntry->m_tableState = SchemaFile::INIT;
 	restartDropTab(signal, tableId);
 	return;
+
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+        // Temporary table is never written to disk, so just set to INIT.
+        jam();
+	ok = true;
+	newEntry->m_tableState = SchemaFile::INIT;
+        break;
       }//switch
       ndbrequire(ok);
       break;
@@ -2737,6 +2759,11 @@ void Dbdict::checkSchemaStatus(Signal* s
 	newEntry->m_tableState = SchemaFile::INIT;
 	restartDropTab(signal, tableId);
 	return;
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+        jam();
+	ok = true;
+	newEntry->m_tableState = SchemaFile::INIT;
+        break;
       }
       ndbrequire(ok);
       break;
@@ -2797,6 +2824,17 @@ void Dbdict::checkSchemaStatus(Signal* s
 	  restartCreateTab(signal, tableId, oldEntry, newEntry, false);
           return;
         }//if
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+        jam();
+        ok = true;
+        // For NR, we must re-create the table.
+        // For SR, we do nothing as the table was never saved to disk.
+        if(!c_systemRestart)
+        {
+          restartCreateTab(signal, tableId, oldEntry, newEntry, false);
+          return;
+        }
+        break;
       }
       ndbrequire(ok);
       break;
@@ -2824,6 +2862,11 @@ void Dbdict::checkSchemaStatus(Signal* s
 	newEntry->m_tableState = SchemaFile::INIT;
 	restartDropTab(signal, tableId);
 	return;
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+        jam();
+        ok = true;
+	newEntry->m_tableState = SchemaFile::INIT;
+        break;
       }
       ndbrequire(ok);
       break;
@@ -2840,6 +2883,15 @@ void Dbdict::checkSchemaStatus(Signal* s
 	jam();
       case SchemaFile::DROP_TABLE_COMMITTED:
 	jam();
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+        jam();
+        ok = true;
+        if(!c_systemRestart)
+        {
+          restartCreateTab(signal, tableId, oldEntry, newEntry, false);
+          return;
+        }
+        break;
       case SchemaFile::TABLE_ADD_COMMITTED:
         jam();
 	ok = true;
@@ -2870,6 +2922,37 @@ void Dbdict::checkSchemaStatus(Signal* s
       ndbrequire(ok);
       break;
     }
+    case SchemaFile::TEMPORARY_TABLE_COMMITTED: {
+      jam();
+      bool ok = false;
+      switch(oldSchemaState){
+      case SchemaFile::INIT:
+	jam();
+      case SchemaFile::DROP_TABLE_COMMITTED:
+	jam();
+      case SchemaFile::ADD_STARTED:
+	jam();
+      case SchemaFile::TABLE_ADD_COMMITTED:
+	jam();
+      case SchemaFile::DROP_TABLE_STARTED:
+	jam();
+      case SchemaFile::ALTER_TABLE_COMMITTED:
+	jam();
+      case SchemaFile::TEMPORARY_TABLE_COMMITTED:
+        jam();
+	ok = true;
+        if(!c_systemRestart)
+        {
+          restartCreateTab(signal, tableId, oldEntry, newEntry, false);
+          return;
+        } else {
+          newEntry->m_tableState = SchemaFile::INIT;
+        }          
+	break;
+      }
+      ndbrequire(ok);
+      break;
+    }
     }
   }
   
@@ -3104,6 +3187,8 @@ Dbdict::execGET_TABINFO_CONF(Signal* sig
   handleTabInfoInit(r, &parseRecord);
   ndbrequire(parseRecord.errorCode == 0);
 
+  // save to disk
+
   ndbrequire(tableId < c_tableRecordPool.getSize());
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
   SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
@@ -4165,6 +4250,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signa
     SegmentedSectionPtr tabInfoPtr;
     signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
     alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
+    bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
     
     signal->header.m_noOfSections = 0;
 
@@ -4176,7 +4262,10 @@ Dbdict::execALTER_TAB_REQ(Signal * signa
     SchemaFile::TableEntry tabEntry;
     tabEntry.m_tableVersion = tableVersion;
     tabEntry.m_tableType    = tablePtr.p->tableType;
-    tabEntry.m_tableState   = SchemaFile::ALTER_TABLE_COMMITTED;
+    if (savetodisk)
+      tabEntry.m_tableState   = SchemaFile::ALTER_TABLE_COMMITTED;
+    else
+      tabEntry.m_tableState   = SchemaFile::TEMPORARY_TABLE_COMMITTED;
     tabEntry.m_gcp          = gci;
     tabEntry.m_info_words   = tabInfoPtr.sz;
     memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
@@ -4186,7 +4275,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signa
     callback.m_callbackFunction = 
       safe_cast(&Dbdict::alterTab_writeSchemaConf);
     
-    updateSchemaState(signal, tableId, &tabEntry, &callback);
+    updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
     break;
   }
   case(AlterTabReq::AlterTableRevert): {
@@ -4663,9 +4752,19 @@ Dbdict::alterTab_writeSchemaConf(Signal*
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::alterTab_writeTableConf);
   
-  SegmentedSectionPtr tabInfoPtr;
-  getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
-  writeTableFile(signal, tableId, tabInfoPtr, &callback);
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, tableId);
+  bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
+  if (savetodisk)
+  {
+    SegmentedSectionPtr tabInfoPtr;
+    getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
+    writeTableFile(signal, tableId, tabInfoPtr, &callback);
+  }
+  else
+  {
+    execute(signal, callback, 0);
+  }
 }
 
 void
@@ -5101,7 +5200,8 @@ Dbdict::createTab_prepare(Signal* signal
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::createTab_writeSchemaConf1);
   
-  updateSchemaState(signal, tableId, &tabEntry, &callback);
+  bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
+  updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
 }
 
 void getSection(SegmentedSectionPtr & ptr, Uint32 i);
@@ -5120,9 +5220,19 @@ Dbdict::createTab_writeSchemaConf1(Signa
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::createTab_writeTableConf);
   
-  SegmentedSectionPtr tabInfoPtr;
-  getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
-  writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
+  TableRecordPtr tabPtr;
+  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
+  bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
+  if (savetodisk)
+  {
+    SegmentedSectionPtr tabInfoPtr;
+    getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
+    writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
+  }
+  else
+  {
+    execute(signal, callback, 0);
+  }
 #if 0
   createTabPtr.p->m_tabInfoPtrI = RNIL;
   signal->setSection(tabInfoPtr, 0);
@@ -5168,10 +5278,11 @@ Dbdict::createTab_dih(Signal* signal, 
   req->fragType = tabPtr.p->fragmentType;
   req->kValue = tabPtr.p->kValue;
   req->noOfReplicas = 0;
-  req->storedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged);
+  req->loggedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged);
   req->tableType = tabPtr.p->tableType;
   req->schemaVersion = tabPtr.p->tableVersion;
   req->primaryTableId = tabPtr.p->primaryTableId;
+  req->temporaryTable = !!(tabPtr.p->m_bits & TableRecord::TR_Temporary);
 
 /*
@@ -5575,11 +5686,16 @@ Dbdict::createTab_commit(Signal * signal
 
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-  
+  bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
+
   SchemaFile::TableEntry tabEntry;
   tabEntry.m_tableVersion = tabPtr.p->tableVersion;
   tabEntry.m_tableType    = tabPtr.p->tableType;
-  tabEntry.m_tableState   = SchemaFile::TABLE_ADD_COMMITTED;
+  if (savetodisk)
+    tabEntry.m_tableState   = SchemaFile::TABLE_ADD_COMMITTED;
+  else
+    tabEntry.m_tableState   = SchemaFile::TEMPORARY_TABLE_COMMITTED;
+    
   tabEntry.m_gcp          = tabPtr.p->gciTableCreated;
   tabEntry.m_info_words   = tabPtr.p->packedSize;
   memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
@@ -5589,7 +5705,7 @@ Dbdict::createTab_commit(Signal * signal
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::createTab_writeSchemaConf2);
   
-  updateSchemaState(signal, tabPtr.i, &tabEntry, &callback);
+  updateSchemaState(signal, tabPtr.i, &tabEntry, &callback, savetodisk);
 }
 
 void
@@ -5924,6 +6040,10 @@ void Dbdict::handleTabInfoInit(SimplePro
 #endif
   }
   
+  // Disallow logging of a temporary table.
+  tabRequire(!(c_tableDesc.TableTemporaryFlag && c_tableDesc.TableLoggedFlag),
+             CreateTableRef::NoLoggingTemporaryTable);
+
   tablePtr.p->noOfAttributes = c_tableDesc.NoOfAttributes;
   tablePtr.p->m_bits |= 
     (c_tableDesc.TableLoggedFlag ? TableRecord::TR_Logged : 0);
@@ -5931,6 +6051,8 @@ void Dbdict::handleTabInfoInit(SimplePro
     (c_tableDesc.RowChecksumFlag ? TableRecord::TR_RowChecksum : 0);
   tablePtr.p->m_bits |= 
     (c_tableDesc.RowGCIFlag ? TableRecord::TR_RowGCI : 0);
+  tablePtr.p->m_bits |= 
+    (c_tableDesc.TableTemporaryFlag ? TableRecord::TR_Temporary : 0);
   tablePtr.p->minLoadFactor = c_tableDesc.MinLoadFactor;
   tablePtr.p->maxLoadFactor = c_tableDesc.MaxLoadFactor;
   tablePtr.p->fragmentType = (DictTabInfo::FragmentType)c_tableDesc.FragmentType;
@@ -6719,21 +6841,31 @@ Dbdict::execPREP_DROP_TAB_REQ(Signal* si
   SchemaFile::TableState tabState = 
     (SchemaFile::TableState)tableEntry->m_tableState;
   ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED ||
-	     tabState == SchemaFile::ALTER_TABLE_COMMITTED);
+             tabState == SchemaFile::ALTER_TABLE_COMMITTED ||
+             tabState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
   tableEntry->m_tableState   = SchemaFile::DROP_TABLE_STARTED;
   computeChecksum(xsf, tablePtr.i / NDB_SF_PAGE_ENTRIES);
-  
-  ndbrequire(c_writeSchemaRecord.inUse == false);
-  c_writeSchemaRecord.inUse = true;
-  
-  c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
-  c_writeSchemaRecord.newFile = false;
-  c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES;
-  c_writeSchemaRecord.noOfPages = 1;
-  c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
-  c_writeSchemaRecord.m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
-  startWriteSchemaFile(signal);
+
+  bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
+  Callback callback;
+  callback.m_callbackData = dropTabPtr.p->key;
+  callback.m_callbackFunction = safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
+  if (savetodisk)
+  {
+    ndbrequire(c_writeSchemaRecord.inUse == false);
+    c_writeSchemaRecord.inUse = true;
+
+    c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
+    c_writeSchemaRecord.newFile = false;
+    c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES;
+    c_writeSchemaRecord.noOfPages = 1;
+    c_writeSchemaRecord.m_callback = callback;
+    startWriteSchemaFile(signal);
+  }
+  else
+  {
+    execute(signal, callback, 0);
+  }
 }
 
 void
@@ -6904,17 +7036,28 @@ Dbdict::dropTab_complete(Signal* signal,
   ndbrequire(tabState == SchemaFile::DROP_TABLE_STARTED);
   tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
   computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
-  
-  ndbrequire(c_writeSchemaRecord.inUse == false);
-  c_writeSchemaRecord.inUse = true;
 
-  c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
-  c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
-  c_writeSchemaRecord.noOfPages = 1;
-  c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
-  c_writeSchemaRecord.m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::dropTab_writeSchemaConf);
-  startWriteSchemaFile(signal);
+  TableRecordPtr tablePtr;
+  c_tableRecordPool.getPtr(tablePtr, tableId);
+  bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
+  Callback callback;
+  callback.m_callbackData = dropTabPtr.p->key;
+  callback.m_callbackFunction = safe_cast(&Dbdict::dropTab_writeSchemaConf);
+  if (savetodisk)
+  {
+    ndbrequire(c_writeSchemaRecord.inUse == false);
+    c_writeSchemaRecord.inUse = true;
+    
+    c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
+    c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
+    c_writeSchemaRecord.noOfPages = 1;
+    c_writeSchemaRecord.m_callback = callback;
+    startWriteSchemaFile(signal);
+  }
+  else
+  {
+    execute(signal, callback, 0); 
+  }
 }
 
 void
@@ -7180,9 +7323,12 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
     return;
   }//if
-  
+
+  // If istable/index, allow ADD_STARTED (not to ref)
+
   if (objEntry->m_tableState != SchemaFile::TABLE_ADD_COMMITTED &&
-      objEntry->m_tableState != SchemaFile::ALTER_TABLE_COMMITTED){
+      objEntry->m_tableState != SchemaFile::ALTER_TABLE_COMMITTED &&
+      objEntry->m_tableState != SchemaFile::TEMPORARY_TABLE_COMMITTED){
     jam();
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
     return;
@@ -7201,6 +7347,8 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
       sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
       return;
     }
+    ndbrequire(objEntry->m_tableState == SchemaFile::TEMPORARY_TABLE_COMMITTED ||
+               !(tabPtr.p->m_bits & TableRecord::TR_Temporary));
   }
   
   c_retrieveRecord.busyState = true;
@@ -7385,10 +7533,15 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
       }
       // store
       if (! (tablePtr.p->m_bits & TableRecord::TR_Logged)) {
-	conf->setTableStore(pos, DictTabInfo::StoreTemporary);
+	conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
       } else {
 	conf->setTableStore(pos, DictTabInfo::StorePermanent);
       }
+      if (tablePtr.p->m_bits & TableRecord::TR_Temporary) {
+	conf->setTableTemp(pos, DictTabInfo::TempIsTemporary);
+      } else {
+	conf->setTableTemp(pos, DictTabInfo::TempIsPermanent);
+      }
       pos++;
     }
     if(DictTabInfo::isTrigger(type)){
@@ -7409,7 +7562,7 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
 	conf->setTableState(pos, DictTabInfo::StateBroken);
 	break;
       }
-      conf->setTableStore(pos, DictTabInfo::StoreTemporary);
+      conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
       pos++;
     }
     if (DictTabInfo::isFilegroup(type)){
@@ -7578,7 +7731,8 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
       return;
     }
     memcpy(opPtr.p->m_indexName, c_tableDesc.TableName, MAX_TAB_NAME_SIZE);
-    opPtr.p->m_storedIndex = c_tableDesc.TableLoggedFlag;
+    opPtr.p->m_loggedIndex = c_tableDesc.TableLoggedFlag;
+    opPtr.p->m_temporaryIndex = c_tableDesc.TableTemporaryFlag;
     releaseSections(signal);
     // master expects to hear from all
     if (opPtr.p->m_isMaster)
@@ -7740,6 +7894,34 @@ Dbdict::createIndex_toCreateTable(Signal
     opPtr.p->m_errorLine = __LINE__;
     return;
   }
+
+  // Check that the temporary status of index is compatible with table.
+  if (!opPtr.p->m_temporaryIndex &&
+      tablePtr.p->m_bits & TableRecord::TR_Temporary)
+  {
+    jam();
+    opPtr.p->m_errorCode= CreateIndxRef::TableIsTemporary;
+    opPtr.p->m_errorLine= __LINE__;
+    return;
+  }
+  if (opPtr.p->m_temporaryIndex &&
+      !(tablePtr.p->m_bits & TableRecord::TR_Temporary))
+  {
+    // This could be implemented later, but mysqld does currently not detect
+    // that the index disappears after SR, and it appears not too useful.
+    jam();
+    opPtr.p->m_errorCode= CreateIndxRef::TableIsNotTemporary;
+    opPtr.p->m_errorLine= __LINE__;
+    return;
+  }
+  if (opPtr.p->m_temporaryIndex && opPtr.p->m_loggedIndex)
+  {
+    jam();
+    opPtr.p->m_errorCode= CreateIndxRef::NoLoggingTemporaryIndex;
+    opPtr.p->m_errorLine= __LINE__;
+    return;
+  }
+
   // compute index table record
   TableRecord indexRec;
   TableRecordPtr indexPtr;
@@ -7748,16 +7930,20 @@ Dbdict::createIndex_toCreateTable(Signal
   initialiseTableRecord(indexPtr);
   indexPtr.p->m_bits = TableRecord::TR_RowChecksum;
   if (req->getIndexType() == DictTabInfo::UniqueHashIndex) {
-    indexPtr.p->m_bits |= (opPtr.p->m_storedIndex ? TableRecord::TR_Logged:0);
+    indexPtr.p->m_bits |= (opPtr.p->m_loggedIndex ? TableRecord::TR_Logged:0);
+    indexPtr.p->m_bits |=
+      (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
     indexPtr.p->fragmentType = DictTabInfo::DistrKeyUniqueHashIndex;
   } else if (req->getIndexType() == DictTabInfo::OrderedIndex) {
     // first version will not supported logging
-    if (opPtr.p->m_storedIndex) {
+    if (opPtr.p->m_loggedIndex) {
       jam();
       opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
       opPtr.p->m_errorLine = __LINE__;
       return;
     }
+    indexPtr.p->m_bits |=
+      (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
     indexPtr.p->fragmentType = DictTabInfo::DistrKeyOrderedIndex;
   } else {
     jam();
@@ -7842,6 +8028,7 @@ Dbdict::createIndex_toCreateTable(Signal
   // write index table
   w.add(DictTabInfo::TableName, opPtr.p->m_indexName);
   w.add(DictTabInfo::TableLoggedFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Logged));
+  w.add(DictTabInfo::TableTemporaryFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Temporary));
   w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType);
   w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType);
   Rope name(c_rope_pool, tablePtr.p->tableName);

--- 1.31/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2006-08-30 11:54:18 +02:00
+++ 1.32/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2006-08-30 11:54:18 +02:00
@@ -234,7 +234,8 @@ public:
     {
       TR_Logged = 0x1,
       TR_RowGCI = 0x2,
-      TR_RowChecksum = 0x4
+      TR_RowChecksum = 0x4,
+      TR_Temporary = 0x8
     };
     Uint16 m_bits;
 
@@ -1199,7 +1200,8 @@ private:
     CreateIndxReq m_request;
     AttributeList m_attrList;
     char m_indexName[MAX_TAB_NAME_SIZE];
-    bool m_storedIndex;
+    bool m_loggedIndex;
+    bool m_temporaryIndex;
     // coordinator DICT
     Uint32 m_coordinatorRef;
     bool m_isMaster;
@@ -2088,7 +2090,8 @@ private:
   // Read/Write Schema and Table files
   /* ------------------------------------------------------------ */
   void updateSchemaState(Signal* signal, Uint32 tableId, 
-			 SchemaFile::TableEntry*, Callback*);
+			 SchemaFile::TableEntry*, Callback*,
+                         bool savetodisk = 1);
   void startWriteSchemaFile(Signal* signal);
   void openSchemaFile(Signal* signal,
                       Uint32 fileNo,

--- 1.4/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp	2006-08-30 11:54:18 +02:00
+++ 1.5/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp	2006-08-30 11:54:18 +02:00
@@ -54,7 +54,8 @@ struct SchemaFile {
     TABLE_ADD_COMMITTED = 2,
     DROP_TABLE_STARTED = 3,
     DROP_TABLE_COMMITTED = 4,
-    ALTER_TABLE_COMMITTED = 5
+    ALTER_TABLE_COMMITTED = 5,
+    TEMPORARY_TABLE_COMMITTED = 6
   };
 
   // entry size 32 bytes

--- 1.17/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2006-08-30 11:54:18 +02:00
+++ 1.18/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp	2006-08-30 11:54:18 +02:00
@@ -469,11 +469,17 @@ public:
       NORMAL_HASH = 2,
       USER_DEFINED = 3
     };
+    enum Storage {
+      ST_NOLOGGING = 0,         // Table is not logged, but survives SR
+      ST_NORMAL = 1,            // Normal table, logged and durable
+      ST_TEMPORARY = 2          // Table is lost after SR, not logged
+    };
     CopyStatus tabCopyStatus;
     UpdateState tabUpdateState;
     TabLcpStatus tabLcpStatus;
     TabStatus tabStatus;
     Method method;
+    Storage tabStorage;
 
     Uint32 pageRef[8];
 //-----------------------------------------------------------------------------
@@ -506,7 +512,6 @@ public:
     Uint8 kvalue;
     Uint8 noOfBackups;
     Uint8 noPages;
-    Uint8 storedTable;              /* 0 IF THE TABLE IS A TEMPORARY TABLE */
     Uint16 tableType;
     Uint16 primaryTableId;
   };

--- 1.61/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2006-08-30 11:54:18 +02:00
+++ 1.62/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2006-08-30 11:54:18 +02:00
@@ -5435,7 +5435,7 @@ void Dbdih::removeNodeFromTable(Signal* 
 
   //const Uint32 lcpId = SYSFILE->latestLCP_ID;
   const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
-  const bool temporary = !tabPtr.p->storedTable;
+  const bool unlogged = (tabPtr.p->tabStorage != TabRecord::ST_NORMAL);
   
   FragmentstorePtr fragPtr;
   for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
@@ -5456,7 +5456,7 @@ void Dbdih::removeNodeFromTable(Signal* 
         jam();
 	found = true;
 	noOfRemovedReplicas++;
-	removeNodeFromStored(nodeId, fragPtr, replicaPtr, temporary);
+	removeNodeFromStored(nodeId, fragPtr, replicaPtr, unlogged);
 	if(replicaPtr.p->lcpOngoingFlag){
 	  jam();
 	  /**
@@ -6716,7 +6716,12 @@ void Dbdih::execDIADDTABREQ(Signal* sign
   /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/
   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
   tabPtr.p->tabStatus = TabRecord::TS_CREATING;
-  tabPtr.p->storedTable = req->storedTable;
+  if(req->loggedTable)
+    tabPtr.p->tabStorage= TabRecord::ST_NORMAL;
+  else if(req->temporaryTable)
+    tabPtr.p->tabStorage= TabRecord::ST_TEMPORARY;
+  else
+    tabPtr.p->tabStorage= TabRecord::ST_NOLOGGING;
   tabPtr.p->kvalue = req->kValue;
 
   switch ((DictTabInfo::FragmentType)fragType)
@@ -6881,7 +6886,7 @@ Dbdih::sendAddFragreq(Signal* signal, Co
     ndbrequire(replicaPtr.p->procNode == getOwnNodeId());
 
     Uint32 requestInfo = 0;
-    if(!tabPtr.p->storedTable){
+    if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
       requestInfo |= LqhFragReq::TemporaryTable;
     }
     
@@ -8293,9 +8298,9 @@ void Dbdih::initLcpLab(Signal* signal, U
       continue;
     }
 
-    if (tabPtr.p->storedTable == 0) {
+    if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
       /**
-       * Temporary table
+       * Table is not logged
        */
       jam();
       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
@@ -8772,10 +8777,10 @@ void Dbdih::readPagesIntoTableLab(Signal
   rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
   rf.rwfTabPtr.p->mask = readPageWord(&rf);
   rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf);
-  /* ---------------------------------- */
-  /* Type of table, 2 = temporary table */
-  /* ---------------------------------- */
-  rf.rwfTabPtr.p->storedTable = readPageWord(&rf); 
+  /* ------------- */
+  /* Type of table */
+  /* ------------- */
+  rf.rwfTabPtr.p->tabStorage = (TabRecord::Storage)(readPageWord(&rf)); 
 
   Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments;
   ndbrequire(noOfFrags > 0);
@@ -8866,7 +8871,7 @@ void Dbdih::packTableIntoPagesLab(Signal
   writePageWord(&wf, tabPtr.p->kvalue);
   writePageWord(&wf, tabPtr.p->mask);
   writePageWord(&wf, tabPtr.p->method);
-  writePageWord(&wf, tabPtr.p->storedTable);
+  writePageWord(&wf, tabPtr.p->tabStorage);
 
   signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
   signal->theData[1] = tabPtr.i;
@@ -9071,7 +9076,7 @@ void Dbdih::startFragment(Signal* signal
       continue;
     }
     
-    if(tabPtr.p->storedTable == 0){
+    if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
       jam();
       TloopCount++;
       tableId++;
@@ -9696,7 +9701,7 @@ void Dbdih::calculateKeepGciLab(Signal* 
     }//if
     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE || 
-	tabPtr.p->storedTable == 0) {
+	tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
       if (TloopCount > 100) {
         jam();
         signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
@@ -10614,6 +10619,14 @@ void Dbdih::allNodesLcpCompletedLab(Sign
 /* ------------------------------------------------------------------------- */
 void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) {
   FileRecordPtr filePtr;
+  if(tabPtr.p->tabStorage == TabRecord::ST_TEMPORARY) {
+    // For temporary tables we do not write to disk. Mark both copies 0 and 1
+    // as done, and go straight to the after-close code.
+    filePtr.i = tabPtr.p->tabFile[1];
+    ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
+    tableCloseLab(signal, filePtr);
+    return;
+  }
   filePtr.i = tabPtr.p->tabFile[0];
   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
   createFileRw(signal, filePtr);
@@ -11645,7 +11658,7 @@ void Dbdih::initTable(TabRecordPtr tabPt
   tabPtr.p->kvalue = 0;
   tabPtr.p->hashpointer = (Uint32)-1;
   tabPtr.p->mask = 0;
-  tabPtr.p->storedTable = 1;
+  tabPtr.p->tabStorage = TabRecord::ST_NORMAL;
   tabPtr.p->tabErrorCode = 0;
   tabPtr.p->schemaVersion = (Uint32)-1;
   tabPtr.p->tabRemoveNode = RNIL;

--- 1.56/storage/ndb/src/ndbapi/NdbDictionary.cpp	2006-08-30 11:54:18 +02:00
+++ 1.57/storage/ndb/src/ndbapi/NdbDictionary.cpp	2006-08-30 11:54:18 +02:00
@@ -594,6 +594,11 @@ NdbDictionary::Table::getReplicaCount() 
   return m_impl.m_replicaCount;
 }
 
+void
+NdbDictionary::Table::setTemporary(bool val) {
+  m_impl.m_temporary = val;
+}
+
 int
 NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const {  
   const NdbDictionary::Table * pTab = 
@@ -768,6 +773,11 @@ NdbDictionary::Index::getType() const {
 void
 NdbDictionary::Index::setLogging(bool val){
   m_impl.m_logging = val;
+}
+
+void
+NdbDictionary::Index::setTemporary(bool val){
+  m_impl.m_temporary = val;
 }
 
 bool 

--- 1.129/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2006-08-30 11:54:18 +02:00
+++ 1.130/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2006-08-30 11:54:18 +02:00
@@ -427,6 +427,7 @@ NdbTableImpl::init(){
   m_max_rows = 0;
   m_default_no_part_flag = 1;
   m_logging= true;
+  m_temporary = false;
   m_row_gci = true;
   m_row_checksum = true;
   m_kvalue= 6;
@@ -544,6 +545,12 @@ NdbTableImpl::equal(const NdbTableImpl& 
     DBUG_RETURN(false);
   }
 
+  if(m_temporary != obj.m_temporary)
+  {
+    DBUG_PRINT("info",("m_temporary %d != %d",m_temporary,obj.m_temporary));
+    DBUG_RETURN(false);
+  }
+
   if(m_row_gci != obj.m_row_gci)
   {
     DBUG_PRINT("info",("m_row_gci %d != %d",m_row_gci,obj.m_row_gci));
@@ -675,6 +682,7 @@ NdbTableImpl::assign(const NdbTableImpl&
   m_max_rows = org.m_max_rows;
   m_default_no_part_flag = org.m_default_no_part_flag;
   m_logging = org.m_logging;
+  m_temporary = org.m_temporary;
   m_row_gci = org.m_row_gci;
   m_row_checksum = org.m_row_checksum;
   m_kvalue = org.m_kvalue;
@@ -1040,6 +1048,7 @@ void NdbIndexImpl::init()
   m_id= RNIL;
   m_type= NdbDictionary::Object::TypeUndefined;
   m_logging= true;
+  m_temporary= false;
   m_table= NULL;
 }
 
@@ -1941,13 +1950,21 @@ objectStateMapping[] = {
 static const
 ApiKernelMapping
 objectStoreMapping[] = {
-  { DictTabInfo::StoreTemporary,     NdbDictionary::Object::StoreTemporary },
+  { DictTabInfo::StoreNotLogged,     NdbDictionary::Object::StoreNotLogged },
   { DictTabInfo::StorePermanent,     NdbDictionary::Object::StorePermanent },
   { -1, -1 }
 };
 
 static const
 ApiKernelMapping
+objectTempMapping[] = {
+  { DictTabInfo::TempIsTemporary,    NdbDictionary::Object::TempIsTemporary },
+  { DictTabInfo::TempIsPermanent,    NdbDictionary::Object::TempIsPermanent },
+  { -1, -1 }
+};
+
+static const
+ApiKernelMapping
 indexTypeMapping[] = {
   { DictTabInfo::UniqueHashIndex,    NdbDictionary::Index::UniqueHashIndex },  
   { DictTabInfo::OrderedIndex,       NdbDictionary::Index::OrderedIndex },
@@ -2017,6 +2034,7 @@ NdbDictInterface::parseTableInfo(NdbTabl
   impl->m_default_no_part_flag = tableDesc->DefaultNoPartFlag;
   impl->m_linear_flag = tableDesc->LinearHashFlag;
   impl->m_logging = tableDesc->TableLoggedFlag;
+  impl->m_temporary = tableDesc->TableTemporaryFlag;
   impl->m_row_gci = tableDesc->RowGCIFlag;
   impl->m_row_checksum = tableDesc->RowChecksumFlag;
   impl->m_kvalue = tableDesc->TableKValue;
@@ -2459,6 +2477,7 @@ NdbDictInterface::createOrAlterTable(Ndb
 
   tmpTab->FragmentCount= impl.m_fragmentCount;
   tmpTab->TableLoggedFlag = impl.m_logging;
+  tmpTab->TableTemporaryFlag = impl.m_temporary;
   tmpTab->RowGCIFlag = impl.m_row_gci;
   tmpTab->RowChecksumFlag = impl.m_row_checksum;
   tmpTab->TableKValue = impl.m_kvalue;
@@ -3029,6 +3048,7 @@ NdbDictInterface::create_index_obj_from_
   idx->m_tableName.assign(prim->m_externalName);
   NdbDictionary::Object::Type type = idx->m_type = tab->m_indexType;
   idx->m_logging = tab->m_logging;
+  idx->m_temporary = tab->m_temporary;
   // skip last attribute (NDB$PK or NDB$TNODE)
 
   const Uint32 distKeys = prim->m_noOfDistributionKeys;
@@ -3117,6 +3137,7 @@ NdbDictInterface::createIndex(Ndb & ndb,
     ndb.internalize_index_name(&table, impl.getName()));
   w.add(DictTabInfo::TableName, internalName.c_str());
   w.add(DictTabInfo::TableLoggedFlag, impl.m_logging);
+  w.add(DictTabInfo::TableTemporaryFlag, impl.m_temporary);
 
   NdbApiSignal tSignal(m_reference);
   tSignal.theReceiversBlockNumber = DBDICT;
@@ -4096,6 +4117,8 @@ NdbDictInterface::listObjects(NdbDiction
       getApiConstant(ListTablesConf::getTableState(d), objectStateMapping, 0);
     element.store = (NdbDictionary::Object::Store)
       getApiConstant(ListTablesConf::getTableStore(d), objectStoreMapping, 0);
+    element.temp = (NdbDictionary::Object::Temp)
+      getApiConstant(ListTablesConf::getTableTemp(d), objectTempMapping, 0);
     // table or index name
     Uint32 n = (data[pos++] + 3) >> 2;
     BaseString databaseName;

--- 1.57/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2006-08-30 11:54:18 +02:00
+++ 1.58/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2006-08-30 11:54:18 +02:00
@@ -187,6 +187,7 @@ public:
   Uint32 m_default_no_part_flag;
   bool m_linear_flag;
   bool m_logging;
+  bool m_temporary;
   bool m_row_gci;
   bool m_row_checksum;
   int m_kvalue;
@@ -262,6 +263,7 @@ public:
   Vector<int> m_key_ids;
 
   bool m_logging;
+  bool m_temporary;
   
   NdbTableImpl * m_table;
   

--- 1.26/storage/ndb/tools/listTables.cpp	2006-08-30 11:54:18 +02:00
+++ 1.27/storage/ndb/tools/listTables.cpp	2006-08-30 11:54:18 +02:00
@@ -80,9 +80,9 @@ list(const char * tabname, 
     if (!_parsable)
     {
       if (ndb->usingFullyQualifiedNames())
-        ndbout_c("%-5s %-20s %-8s %-7s %-12s %-8s %s", "id", "type", "state", "logging", "database", "schema", "name");
+        ndbout_c("%-5s %-20s %-8s %-7s %-4s %-12s %-8s %s", "id", "type", "state", "logging", "temp", "database", "schema", "name");
       else
-        ndbout_c("%-5s %-20s %-8s %-7s %s", "id", "type", "state", "logging", "name");
+        ndbout_c("%-5s %-20s %-8s %-7s %-4s %s", "id", "type", "state", "logging", "temp", "name");
     }
     for (unsigned i = 0; i < list.count; i++) {
 	NdbDictionary::Dictionary::List::Element& elt = list.elements[i];
@@ -162,30 +162,46 @@ list(const char * tabname, 
 	    strcpy(store, "-");
 	else {
 	    switch (elt.store) {
-	    case NdbDictionary::Object::StoreTemporary:
+	    case NdbDictionary::Object::StoreNotLogged:
 		strcpy(store, "No");
 		break;
 	    case NdbDictionary::Object::StorePermanent:
 		strcpy(store, "Yes");
 		break;
 	    default:
-		sprintf(state, "%d", (int)elt.store);
+		sprintf(store, "%d", (int)elt.store);
+		break;
+	    }
+	}
+        char temp[100];
+	if (! isTable)
+	    strcpy(temp, "-");
+	else {
+	    switch (elt.temp) {
+	    case NdbDictionary::Object::TempIsPermanent:
+		strcpy(temp, "No");
+		break;
+	    case NdbDictionary::Object::TempIsTemporary:
+		strcpy(temp, "Yes");
+		break;
+	    default:
+		sprintf(temp, "%d", (int)elt.temp);
 		break;
 	    }
 	}
 	if (ndb->usingFullyQualifiedNames())
         {
           if (_parsable)
-            ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name);
+            ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, temp, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name);
           else
-            ndbout_c("%-5d %-20s %-8s %-7s %-12s %-8s %s", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name);
+            ndbout_c("%-5d %-20s %-8s %-7s %-4s %-12s %-8s %s", elt.id, type, state, store, temp, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name);
         }
         else
         {
           if (_parsable)
-            ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, elt.name);
+            ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, temp, elt.name);
           else
-            ndbout_c("%-5d %-20s %-8s %-7s %s", elt.id, type, state, store, elt.name);
+            ndbout_c("%-5d %-20s %-8s %-7s %-4s %s", elt.id, type, state, store, temp, elt.name);
         }
     }
     if (_parsable)

--- 1.303/sql/ha_ndbcluster.cc	2006-08-30 11:54:18 +02:00
+++ 1.304/sql/ha_ndbcluster.cc	2006-08-30 11:54:18 +02:00
@@ -4425,7 +4425,23 @@ int ha_ndbcluster::create(const char *na
 
   DBUG_PRINT("table", ("name: %s", m_tabname));  
   tab.setName(m_tabname);
-  tab.setLogging(!(info->options & HA_LEX_CREATE_TMP_TABLE));    
+  // the schema and apply_status tables are never created as temporary.
+  if( (strcmp(m_dbname, NDB_REP_DB) == 0 &&
+       strcmp(m_tabname, NDB_SCHEMA_TABLE) == 0) ||
+      (strcmp(m_dbname, NDB_REP_DB) == 0 &&
+       strcmp(m_tabname, NDB_APPLY_TABLE) == 0) )
+  {
+    tab.setLogging(1);
+  }
+  else if(current_thd->variables.ndb_use_temporary_tables)
+  {
+    tab.setLogging(0);
+    tab.setTemporary(1);
+  }
+  else
+  {
+    tab.setLogging(!(info->options & HA_LEX_CREATE_TMP_TABLE));    
+  }
    
   // Save frm data for this table
   if (readfrm(name, &data, &length))
@@ -4793,6 +4809,11 @@ int ha_ndbcluster::create_ndb_index(cons
     ndb_index.setType(NdbDictionary::Index::OrderedIndex);
     // TODO Only temporary ordered indexes supported
     ndb_index.setLogging(FALSE); 
+  }
+  if(current_thd->variables.ndb_use_temporary_tables)
+  {
+    ndb_index.setLogging(0);
+    ndb_index.setTemporary(1);
   }
   ndb_index.setTable(m_tabname);
 

--- 1.185/sql/set_var.cc	2006-08-30 11:54:18 +02:00
+++ 1.186/sql/set_var.cc	2006-08-30 11:54:18 +02:00
@@ -526,6 +526,9 @@ sys_ndb_index_stat_update_freq("ndb_inde
                                &SV::ndb_index_stat_update_freq);
 sys_var_long_ptr
 sys_ndb_extra_logging("ndb_extra_logging", &ndb_extra_logging);
+sys_var_thd_bool
+sys_ndb_use_temporary_tables("ndb_use_temporary_tables",
+                             &SV::ndb_use_temporary_tables);
 
 /* Time/date/datetime formats */
 
@@ -896,6 +899,8 @@ SHOW_VAR init_vars[]= {
 #endif
   {sys_ndb_use_exact_count.name,(char*) &sys_ndb_use_exact_count,   SHOW_SYS},
   {sys_ndb_use_transactions.name,(char*) &sys_ndb_use_transactions, SHOW_SYS},
+  {sys_ndb_use_temporary_tables.name,
+   (char*) &sys_ndb_use_temporary_tables,                           SHOW_SYS},
   {sys_net_buffer_length.name,(char*) &sys_net_buffer_length,       SHOW_SYS},
   {sys_net_read_timeout.name, (char*) &sys_net_read_timeout,        SHOW_SYS},
   {sys_net_retry_count.name,  (char*) &sys_net_retry_count,	    SHOW_SYS},

--- 1.58/storage/ndb/src/ndbapi/ndberror.c	2006-08-30 11:54:18 +02:00
+++ 1.59/storage/ndb/src/ndbapi/ndberror.c	2006-08-30 11:54:18 +02:00
@@ -604,7 +604,10 @@ ErrorBundle ErrorCodes[] = {
   { 4271, DMEC, AE, "Invalid index object, not retrieved via getIndex()" },
   { 4272, DMEC, AE, "Table definition has undefined column" },
   { 4273, DMEC, IE, "No blob table in dict cache" },
-  { 4274, DMEC, IE, "Corrupted main table PK in blob operation" }
+  { 4274, DMEC, IE, "Corrupted main table PK in blob operation" },
+  { 4275, DMEC, AE, "Index created on temporary table must itself be temporary" },
+  { 4276, DMEC, AE, "Cannot create a temporary index on a non-temporary table" },
+  { 4277, DMEC, AE, "A temporary table or index must be specified as not logging" },
 };
 
 static

--- 1.51/sql/ha_ndbcluster_binlog.cc	2006-08-30 11:54:18 +02:00
+++ 1.52/sql/ha_ndbcluster_binlog.cc	2006-08-30 11:54:18 +02:00
@@ -1689,10 +1689,15 @@ ndb_binlog_thread_handle_schema_event(TH
           pthread_mutex_lock(&LOCK_open);
           if (ndb_create_table_from_engine(thd, schema->db, schema->name))
           {
-            sql_print_error("Could not discover table '%s.%s' from "
-                            "binlog schema event '%s' from node %d",
+            sql_print_error("NDB binlog: Could not discover table '%s.%s' from "
+                            "binlog schema event '%s' from node %d. "
+                            "my_errno: %d",
                             schema->db, schema->name, schema->query,
-                            schema->node_id);
+                            schema->node_id, my_errno);
+            List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+            MYSQL_ERROR *err;
+            while ((err= it++))
+              sql_print_warning("NDB binlog: (%d)%s", err->code, err->msg);
           }
           pthread_mutex_unlock(&LOCK_open);
           log_query= 1;
@@ -1930,10 +1935,14 @@ ndb_binlog_thread_handle_schema_event_po
           pthread_mutex_lock(&LOCK_open);
           if (ndb_create_table_from_engine(thd, schema->db, schema->name))
           {
-            sql_print_error("Could not discover table '%s.%s' from "
-                            "binlog schema event '%s' from node %d",
+            sql_print_error("NDB binlog: Could not discover table '%s.%s' from "
+                            "binlog schema event '%s' from node %d. my_errno: %d",
                             schema->db, schema->name, schema->query,
-                            schema->node_id);
+                            schema->node_id, my_errno);
+            List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+            MYSQL_ERROR *err;
+            while ((err= it++))
+              sql_print_warning("NDB binlog: (%d)%s", err->code, err->msg);
           }
           pthread_mutex_unlock(&LOCK_open);
         }
Thread
bk commit into 5.1 tree (knielsen:1.2387)knielsen30 Aug