List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:September 19 2012 7:11am
Subject:bzr push into mysql-5.5-cluster-7.2 branch (ole.john.aske:3995 to 3996)
Bug#14103195
View as plain text  
 3996 Ole John Aske	2012-09-19 [merge]
      Merge of fix for bug#14103195 7.1 -> 7.2.
      
      Also added the testcase for this fix as SPJ testing 
      is impossible for versions prior to 7.2.

    added:
      mysql-test/suite/ndb/r/ndb_spj_dict.result
      mysql-test/suite/ndb/t/ndb_spj_dict.test
      storage/ndb/src/kernel/blocks/dbgdm/
      storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.cpp
      storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.hpp
    modified:
      sql/ha_ndbcluster.cc
      storage/ndb/include/kernel/kernel_config_parameters.h
      storage/ndb/include/kernel/signaldata/DbspjErr.hpp
      storage/ndb/include/kernel/signaldata/PrepDropTab.hpp
      storage/ndb/src/kernel/blocks/CMakeLists.txt
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
      storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjInit.cpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.cpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp
      storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.cpp
      storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp
      storage/ndb/src/kernel/vm/Configuration.cpp
      storage/ndb/src/kernel/vm/pc.hpp
      storage/ndb/src/ndbapi/ndberror.c
      storage/ndb/test/ndbapi/testSpj.cpp
 3995 Maitrayi Sabaratnam	2012-09-18 [merge]
      Merge 7.1->7.2

    added:
      mysql-test/suite/ndb/r/ndb_alter_table_dml.result
      mysql-test/suite/ndb/t/ndb_alter_table_dml.test
    modified:
      storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
      storage/ndb/src/ndbapi/ndberror.c
=== added file 'mysql-test/suite/ndb/r/ndb_spj_dict.result'
--- a/mysql-test/suite/ndb/r/ndb_spj_dict.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_spj_dict.result	2012-09-19 07:09:57 +0000
@@ -0,0 +1,189 @@
+use test;
+create table parent(a int primary key, b int not null, key(b)) engine=myisam;
+create table child(a int, b int, primary key(a,b), key(b)) engine=myisam;
+insert into parent values (1,1), (2,2), (3,3), (4,4);
+insert into parent select a+4, b+4 from parent;
+insert into parent select a+8, b+8 from parent;
+insert into parent select a+16, b+16 from parent;
+insert into parent select a+32, b+32 from parent;
+insert into parent select a+64, b+64 from parent;
+insert into parent select a+128, b+128 from parent;
+insert into parent select a+256, b+256 from parent;
+insert into parent select a+512, b+512 from parent;
+insert into parent select a+1024, b+1024 from parent;
+insert into parent select a+(2*1024), b+(2*1024) from parent;
+insert into parent select a+(4*1024), b+(4*1024) from parent;
+insert into parent select a+(8*1024), b+(8*1024) from parent;
+insert into parent select a+(16*1024), b+(16*1024) from parent;
+insert into child select * from parent;
+alter table parent engine=ndb;
+alter table child engine=ndb;
+show variables like 'server_id';
+Variable_name	Value
+server_id	1
+set ndb_join_pushdown = true;
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+explain select straight_join * 
+from parent join child
+on child.a = parent.a 
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	ref	PRIMARY	PRIMARY	4	test.parent.a	327	Child of 'parent' in pushed join@1
+explain select straight_join * 
+from parent join child
+on child.b = parent.a 
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	ref	b	b	4	test.parent.a	16	Child of 'parent' in pushed join@1
+============================================
+Early 'online' drop of REF'ed child's KEY b.
+============================================
+explain select straight_join * 
+from parent join child
+on child.b = parent.a 
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	ref	b	b	4	test.parent.a	16	Child of 'parent' in pushed join@1
+alter online table child drop key b;
+commit;
+alter table child add key(b);
+============================================
+Late 'online' drop of REF'ed child's KEY b.
+============================================
+explain select straight_join * 
+from parent join child
+on child.b = parent.a 
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	ref	b	b	4	test.parent.a	16	Child of 'parent' in pushed join@1
+alter online table child drop key b;
+commit;
+alter table child add key(b);
+============================================
+Early drop of EQ_REF'ed child's PRIMARY KEY.
+============================================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+alter table child drop primary key;
+commit;
+alter table child add primary key(a,b);
+=============================================================
+Drop of EQ_REF'ed child's PRIMARY KEY after executed a while.
+=============================================================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+alter table child drop primary key;
+commit;
+alter table child add primary key(a,b);
+===========================================================
+ONLINE ALTER: Rename table to make it go away - temporarily
+===========================================================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+alter online table child rename to child_orig;
+commit;
+alter table child_orig rename to child;
+======================================*=====================
+OFFLINE ALTER: Rename table to make it go away - temporarily
+==========================================*=================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+alter offline table child rename to child_orig;
+commit;
+alter table child_orig rename to child;
+=================================================================
+ONLINE ALTER: drop + recreate table 'child' key b in use by query
+=================================================================
+explain select straight_join * 
+from parent join child
+on child.b = parent.a 
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	ref	b	b	4	test.parent.a	16	Child of 'parent' in pushed join@1
+alter online table child drop key b;
+alter table child add key(b);
+==================================================================
+ONLINE ALTER: drop + recreate table 'parent' key b in use by query
+==================================================================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+alter online table parent drop key b;
+alter table parent add key(b);
+===============================================
+OFFLINE ALTER: add + drop column c from 'child'
+===============================================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+alter offline table child add column c int;
+alter table child drop column c;
+==========================================================
+OFFLINE ALTER: drop + recreate primary key(a,b) for 'child'
+==========================================================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a 
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	ref	PRIMARY	PRIMARY	4	test.parent.a	327	Child of 'parent' in pushed join@1
+alter offline table child drop primary key;
+alter table child add primary key(a,b);
+==================
+DROP TABLE 'child'
+==================
+explain select straight_join * 
+from parent join child
+on child.a = parent.a and child.b = parent.b
+where parent.b > 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	parent	range	PRIMARY,b	b	4	NULL	3276	Parent of 2 pushed join@1; Using where with pushed condition
+1	SIMPLE	child	eq_ref	PRIMARY,b	PRIMARY	8	test.parent.a,test.parent.b	1	Child of 'parent' in pushed join@1
+drop table child;
+===========
+Cleaning up
+===========
+drop table if exists parent;
+drop table if exists child;
+Warnings:
+Note	1051	Unknown table 'child'

=== added file 'mysql-test/suite/ndb/t/ndb_spj_dict.test'
--- a/mysql-test/suite/ndb/t/ndb_spj_dict.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_spj_dict.test	2012-09-19 07:09:57 +0000
@@ -0,0 +1,335 @@
+##############################################################
+# Purpose: To test DICTionary changes while executing 
+#          SPJ (Pushed join) operations.
+#          SPJ block should take part in the dictionary update
+#          loop controlled by DICT. Alter /dropping a table
+#          while there are ongoing SPJ operations should cause
+#          these operations to be terminated.
+#
+##############################################################
+##############################################################
+# NOTE ABOUT TESTING BELOW:
+#
+# Test cases are expected to terminate query execution on SPJ
+# when a (SPJ-) dictionary change are detected. The error codes
+# 20019-20021 are returned from SPJ, which are mapped to either
+# ER_NO_SUCH_TABLE, or ER_TABLE_DEF_CHANGED.
+#
+# To allow for possible race between DML and DDL queries, 
+# (Didn't start, or completed before the other), 'error 0'
+# is also allowed as an outcome from these tests.
+#
+##############################################################
+--source include/have_multi_ndb.inc
+connect (ddl,localhost,root,,test);
+
+connection ddl;
+
+use test;
+
+## Initially create as MyISAM to avoid 'Out of operation records'
+## ... Later alter to 'engine=ndb'
+
+create table parent(a int primary key, b int not null, key(b)) engine=myisam;
+create table child(a int, b int, primary key(a,b), key(b)) engine=myisam;
+
+insert into parent values (1,1), (2,2), (3,3), (4,4);
+insert into parent select a+4, b+4 from parent;
+insert into parent select a+8, b+8 from parent;
+insert into parent select a+16, b+16 from parent;
+insert into parent select a+32, b+32 from parent;
+insert into parent select a+64, b+64 from parent;
+insert into parent select a+128, b+128 from parent;
+insert into parent select a+256, b+256 from parent;
+insert into parent select a+512, b+512 from parent;
+insert into parent select a+1024, b+1024 from parent;
+insert into parent select a+(2*1024), b+(2*1024) from parent;
+insert into parent select a+(4*1024), b+(4*1024) from parent;
+insert into parent select a+(8*1024), b+(8*1024) from parent;
+insert into parent select a+(16*1024), b+(16*1024) from parent;
+
+insert into child select * from parent;
+
+alter table parent engine=ndb;
+alter table child engine=ndb;
+
+
+connection server1;
+show variables like 'server_id';
+
+let $query1 =
+  select straight_join * 
+  from parent join child
+  on child.a = parent.a and child.b = parent.b
+  where parent.b > 5;
+
+let $query2 =
+  select straight_join * 
+  from parent join child
+  on child.a = parent.a 
+  where parent.b > 5;
+
+let $query3 =
+  select straight_join * 
+  from parent join child
+  on child.b = parent.a 
+  where parent.b > 5;
+
+set ndb_join_pushdown = true;
+eval explain $query1;
+eval explain $query2;
+eval explain $query3;
+
+# This test provokes failure to lock metadata  
+connection server1;
+--disable_query_log
+call mtr.add_suppression("Failed to acquire metadata lock");
+call mtr.add_suppression(".*NDB_SHARE.*Moving away for safety, but possible memleak");
+--enable_query_log
+
+connection server2;
+--disable_query_log
+call mtr.add_suppression("Failed to acquire metadata lock");
+call mtr.add_suppression(".*NDB_SHARE.*Moving away for safety, but possible memleak");
+--enable_query_log
+
+
+--echo ============================================
+--echo Early 'online' drop of REF'ed child's KEY b.
+--echo ============================================
+connection server1;
+eval explain $query3;
+--disable_query_log
+send_eval $query3;
+--enable_query_log
+
+connection server2;
+alter online table child drop key b;
+commit;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table child add key(b);
+
+--echo ============================================
+--echo Late 'online' drop of REF'ed child's KEY b.
+--echo ============================================
+connection server1;
+eval explain $query3;
+--disable_query_log
+send_eval $query3;
+--enable_query_log
+
+connection server2;
+sleep 0.1;
+alter online table child drop key b;
+commit;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table child add key(b);
+
+
+--echo ============================================
+--echo Early drop of EQ_REF'ed child's PRIMARY KEY.
+--echo ============================================
+connection server1;
+eval explain $query1;
+--disable_query_log
+send_eval $query1;
+--enable_query_log
+
+connection server2;
+alter table child drop primary key;
+commit;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table child add primary key(a,b);
+
+--echo =============================================================
+--echo Drop of EQ_REF'ed child's PRIMARY KEY after executed a while.
+--echo =============================================================
+connection server1;
+eval explain $query1;
+--disable_query_log
+send_eval $query1;
+--enable_query_log
+
+connection server2;
+#Takes a short sleep to let query start executing
+sleep 0.1;
+alter table child drop primary key;
+commit;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table child add primary key(a,b);
+
+
+--echo ===========================================================
+--echo ONLINE ALTER: Rename table to make it go away - temporarily
+--echo ===========================================================
+connection server1;
+eval explain $query1;
+--disable_query_log
+send_eval $query1;
+--enable_query_log
+
+connection server2;
+sleep 0.1;
+alter online table child rename to child_orig;
+commit;
+
+connection server1;
+--disable_result_log
+--error 0,ER_TABLE_DEF_CHANGED
+reap;
+--enable_result_log
+alter table child_orig rename to child;
+
+--echo ======================================*=====================
+--echo OFFLINE ALTER: Rename table to make it go away - temporarily
+--echo ==========================================*=================
+connection server1;
+eval explain $query1;
+--disable_query_log
+send_eval $query1;
+--enable_query_log
+
+connection server2;
+sleep 0.1;
+alter offline table child rename to child_orig;
+commit;
+
+connection server1;
+--disable_result_log
+--error 0,ER_TABLE_DEF_CHANGED
+reap;
+--enable_result_log
+alter table child_orig rename to child;
+
+
+--echo =================================================================
+--echo ONLINE ALTER: drop + recreate table 'child' key b in use by query
+--echo =================================================================
+connection server1;
+eval explain $query3;
+--disable_query_log
+send_eval $query3;
+--enable_query_log
+
+connection server2;
+sleep 0.1;
+alter online table child drop key b;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table child add key(b);
+
+
+--echo ==================================================================
+--echo ONLINE ALTER: drop + recreate table 'parent' key b in use by query
+--echo ==================================================================
+connection server1;
+eval explain $query1;
+--disable_query_log
+send_eval $query1;
+--enable_query_log
+
+connection server2;
+sleep 0.1;
+alter online table parent drop key b;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table parent add key(b);
+
+
+--echo ===============================================
+--echo OFFLINE ALTER: add + drop column c from 'child'
+--echo ===============================================
+connection server1;
+eval explain $query1;
+--disable_query_log
+send_eval $query1;
+--enable_query_log
+
+connection server2;
+sleep 0.1;
+alter offline table child add column c int;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table child drop column c;
+
+
+--echo ==========================================================
+--echo OFFLINE ALTER: drop + recreate primary key(a,b) for 'child'
+--echo ==========================================================
+connection server1;
+eval explain $query2;
+--disable_query_log
+send_eval $query2;
+--enable_query_log
+
+connection server2;
+sleep 0.01;
+alter offline table child drop primary key;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+alter table child add primary key(a,b);
+
+
+--echo ==================
+--echo DROP TABLE 'child'
+--echo ==================
+connection server1;
+eval explain $query1;
+--disable_query_log
+send_eval $query1;
+--enable_query_log
+
+connection server2;
+sleep 0.01;
+drop table child;
+
+connection server1;
+--disable_result_log
+--error 0,ER_NO_SUCH_TABLE
+reap;
+--enable_result_log
+
+--echo ===========
+--echo Cleaning up
+--echo ===========
+connection ddl;
+
+drop table if exists parent;
+drop table if exists child;
+

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2012-09-17 08:08:16 +0000
+++ b/sql/ha_ndbcluster.cc	2012-09-19 07:09:57 +0000
@@ -3582,7 +3582,7 @@ int ha_ndbcluster::fetch_next_pushed()
     DBUG_PRINT("info", ("Error from 'nextResult()'"));
     table->status= STATUS_GARBAGE;
 //  DBUG_ASSERT(false);
-//  DBUG_RETURN(ndb_err(m_thd_ndb->trans));
+    DBUG_RETURN(ndb_err(m_thd_ndb->trans));
   }
   DBUG_RETURN(result);
 }

=== modified file 'storage/ndb/include/kernel/kernel_config_parameters.h'
--- a/storage/ndb/include/kernel/kernel_config_parameters.h	2012-03-13 15:18:24 +0000
+++ b/storage/ndb/include/kernel/kernel_config_parameters.h	2012-09-19 07:09:57 +0000
@@ -62,4 +62,6 @@
 #define CFG_TUX_ATTRIBUTE     (PRIVATE_BASE + 42)
 #define CFG_TUX_SCAN_OP       (PRIVATE_BASE + 43)
 
+#define CFG_SPJ_TABLE         (PRIVATE_BASE + 44)
+
 #endif

=== modified file 'storage/ndb/include/kernel/signaldata/DbspjErr.hpp'
--- a/storage/ndb/include/kernel/signaldata/DbspjErr.hpp	2012-08-24 11:53:18 +0000
+++ b/storage/ndb/include/kernel/signaldata/DbspjErr.hpp	2012-09-19 07:09:57 +0000
@@ -41,6 +41,9 @@ struct DbspjErr
     ,NodeFailure = 20016
     ,InvalidTreeNodeCount = 20017
     ,IndexFragNotFound = 20018
+    ,NoSuchTable = 20019
+    ,DropTableInProgress = 20020
+    ,WrongSchemaVersion = 20021
   };
 };
 

=== modified file 'storage/ndb/include/kernel/signaldata/PrepDropTab.hpp'
--- a/storage/ndb/include/kernel/signaldata/PrepDropTab.hpp	2011-07-05 12:46:07 +0000
+++ b/storage/ndb/include/kernel/signaldata/PrepDropTab.hpp	2012-09-19 07:09:57 +0000
@@ -30,11 +30,12 @@ class PrepDropTabReq {
   /**
    * Receiver(s)
    */
+  friend class Dbspj;
   friend class Dbtc;
   friend class Dblqh;
   friend class DblqhProxy;
   friend class Dbdih;
-  friend class DbtcProxy;
+  friend class DbgdmProxy;
 
   friend bool printPREP_DROP_TAB_REQ(FILE *, const Uint32 *, Uint32, Uint16);
 public:
@@ -51,11 +52,12 @@ class PrepDropTabConf {
   /**
    * Sender(s)
    */
+  friend class Dbspj;
   friend class Dbtc;
   friend class Dblqh;
   friend class DblqhProxy;
   friend class Dbdih;
-  friend class DbtcProxy;
+  friend class DbgdmProxy;
 
   /**
    * Receiver(s)
@@ -76,11 +78,12 @@ class PrepDropTabRef {
   /**
    * Sender(s)
    */
+  friend class Dbspj;
   friend class Dbtc;
   friend class Dblqh;
   friend class DblqhProxy;
   friend class Dbdih;
-  friend class DbtcProxy;
+  friend class DbgdmProxy;
 
   /**
    * Receiver(s)

=== modified file 'storage/ndb/src/kernel/blocks/CMakeLists.txt'
--- a/storage/ndb/src/kernel/blocks/CMakeLists.txt	2012-02-23 15:41:31 +0000
+++ b/storage/ndb/src/kernel/blocks/CMakeLists.txt	2012-09-19 07:09:57 +0000
@@ -35,6 +35,7 @@ ADD_CONVENIENCE_LIBRARY(ndbblocks
     dbdih/DbdihInit.cpp dbdih/DbdihMain.cpp
     dblqh/DblqhInit.cpp dblqh/DblqhMain.cpp
     dbtc/DbtcInit.cpp dbtc/DbtcMain.cpp
+    dbgdm/DbgdmProxy.cpp
     dbspj/DbspjInit.cpp dbspj/DbspjMain.cpp dbspj/DbspjProxy.cpp
     dbtup/DbtupExecQuery.cpp dbtup/DbtupBuffer.cpp
     dbtup/DbtupRoutines.cpp dbtup/DbtupCommit.cpp

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2012-08-22 11:15:43 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2012-09-19 07:09:57 +0000
@@ -6777,9 +6777,10 @@ Dbdict::execTAB_COMMITCONF(Signal* signa
   bool ok = find_object(tabPtr, createTabPtr.p->m_request.tableId);
   ndbrequire(ok);
 
-  if (refToBlock(signal->getSendersBlockRef()) == DBLQH) {
+  if (refToBlock(signal->getSendersBlockRef()) == DBLQH)
+  {
     jam();
-    // prepare table in DBTC
+    // prepare table in DBSPJ
     TcSchVerReq * req = (TcSchVerReq*)signal->getDataPtr();
     req->tableId = createTabPtr.p->m_request.tableId;
     req->tableVersion = tabPtr.p->tableVersion;
@@ -6800,23 +6801,35 @@ Dbdict::execTAB_COMMITCONF(Signal* signa
       req->userDefinedPartition = (basePtr.p->fragmentType == DictTabInfo::UserDefined);
     }
 
-    sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal,
+    sendSignal(DBSPJ_REF, GSN_TC_SCHVERREQ, signal,
                TcSchVerReq::SignalLength, JBB);
     return;
   }
 
-  if (refToBlock(signal->getSendersBlockRef()) == DBDIH) {
+  if (refToBlock(signal->getSendersBlockRef()) == DBDIH)
+  {
     jam();
-    // commit table in DBTC
+    // commit table in DBSPJ
     signal->theData[0] = op_ptr.p->op_key;
     signal->theData[1] = reference();
     signal->theData[2] = createTabPtr.p->m_request.tableId;
+    sendSignal(DBSPJ_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
+    return;
+  }
 
+  if (refToBlock(signal->getSendersBlockRef()) == DBSPJ)
+  {
+    jam();
+    // commit table in DBTC
+    signal->theData[0] = op_ptr.p->op_key;
+    signal->theData[1] = reference();
+    signal->theData[2] = createTabPtr.p->m_request.tableId;
     sendSignal(DBTC_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
     return;
   }
 
-  if (refToBlock(signal->getSendersBlockRef()) == DBTC) {
+  if (refToBlock(signal->getSendersBlockRef()) == DBTC)
+  {
     jam();
     execute(signal, createTabPtr.p->m_callback, 0);
     return;
@@ -6920,6 +6933,39 @@ Dbdict::execTC_SCHVERCONF(Signal* signal
   findSchemaOp(op_ptr, createTabPtr, signal->theData[1]);
   ndbrequire(!op_ptr.isNull());
 
+  if (refToBlock(signal->getSendersBlockRef()) == DBSPJ)
+  {
+    jam();
+    // prepare table in DBTC
+    TableRecordPtr tabPtr;
+    bool ok = find_object(tabPtr, createTabPtr.p->m_request.tableId);
+    ndbrequire(ok);
+
+    TcSchVerReq * req = (TcSchVerReq*)signal->getDataPtr();
+    req->tableId = createTabPtr.p->m_request.tableId;
+    req->tableVersion = tabPtr.p->tableVersion;
+    req->tableLogged = (Uint32)!!(tabPtr.p->m_bits & TableRecord::TR_Logged);
+    req->senderRef = reference();
+    req->tableType = (Uint32)tabPtr.p->tableType;
+    req->senderData = op_ptr.p->op_key;
+    req->noOfPrimaryKeys = (Uint32)tabPtr.p->noOfPrimkey;
+    req->singleUserMode = (Uint32)tabPtr.p->singleUserMode;
+    req->userDefinedPartition = (tabPtr.p->fragmentType == DictTabInfo::UserDefined);
+
+    if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType))
+    {
+      jam();
+      TableRecordPtr basePtr;
+      bool ok = find_object(basePtr, tabPtr.p->primaryTableId);
+      ndbrequire(ok);
+      req->userDefinedPartition = (basePtr.p->fragmentType == DictTabInfo::UserDefined);
+    }
+
+    sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal,
+               TcSchVerReq::SignalLength, JBB);
+    return;
+  }
+  ndbrequire(refToBlock(signal->getSendersBlockRef()) == DBTC);
   execute(signal, createTabPtr.p->m_callback, 0);
 }
 
@@ -7052,10 +7098,11 @@ Dbdict::createTable_abortPrepare(Signal*
 
   dropTabPtr.p->m_block = 0;
   dropTabPtr.p->m_blockNo[0] = DBTC;
-  dropTabPtr.p->m_blockNo[1] = DBLQH; // wait usage + LCP
-  dropTabPtr.p->m_blockNo[2] = DBDIH; //
-  dropTabPtr.p->m_blockNo[3] = DBLQH; // release
-  dropTabPtr.p->m_blockNo[4] = 0;
+  dropTabPtr.p->m_blockNo[1] = DBSPJ;
+  dropTabPtr.p->m_blockNo[2] = DBLQH; // wait usage + LCP
+  dropTabPtr.p->m_blockNo[3] = DBDIH; //
+  dropTabPtr.p->m_blockNo[4] = DBLQH; // release
+  dropTabPtr.p->m_blockNo[5] = 0;
 
   dropTabPtr.p->m_callback.m_callbackData =
     oplnk_ptr.p->op_key;
@@ -7556,9 +7603,10 @@ Dbdict::dropTable_commit(Signal* signal,
   }
   dropTabPtr.p->m_block = 0;
   dropTabPtr.p->m_blockNo[0] = DBLQH;
-  dropTabPtr.p->m_blockNo[1] = DBTC;
-  dropTabPtr.p->m_blockNo[2] = DBDIH;
-  dropTabPtr.p->m_blockNo[3] = 0;
+  dropTabPtr.p->m_blockNo[1] = DBSPJ;
+  dropTabPtr.p->m_blockNo[2] = DBTC;
+  dropTabPtr.p->m_blockNo[3] = DBDIH;
+  dropTabPtr.p->m_blockNo[4] = 0;
   dropTable_commit_nextStep(signal, op_ptr);
 }
 
@@ -7699,10 +7747,11 @@ Dbdict::dropTable_complete(Signal* signa
 
   dropTabPtr.p->m_block = 0;
   dropTabPtr.p->m_blockNo[0] = DBTC;
-  dropTabPtr.p->m_blockNo[1] = DBLQH; // wait usage + LCP
-  dropTabPtr.p->m_blockNo[2] = DBDIH; //
-  dropTabPtr.p->m_blockNo[3] = DBLQH; // release
-  dropTabPtr.p->m_blockNo[4] = 0;
+  dropTabPtr.p->m_blockNo[1] = DBSPJ;
+  dropTabPtr.p->m_blockNo[2] = DBLQH; // wait usage + LCP
+  dropTabPtr.p->m_blockNo[3] = DBDIH; //
+  dropTabPtr.p->m_blockNo[4] = DBLQH; // release
+  dropTabPtr.p->m_blockNo[5] = 0;
   dropTabPtr.p->m_callback.m_callbackData =
     op_ptr.p->op_key;
   dropTabPtr.p->m_callback.m_callbackFunction =
@@ -9364,7 +9413,8 @@ Dbdict::alterTable_commit(Signal* signal
   alterTabPtr.p->m_blockIndex = 0;
   alterTabPtr.p->m_blockNo[0] = DBLQH;
   alterTabPtr.p->m_blockNo[1] = DBDIH;
-  alterTabPtr.p->m_blockNo[2] = DBTC;
+  alterTabPtr.p->m_blockNo[2] = DBSPJ;
+  alterTabPtr.p->m_blockNo[3] = DBTC;
 
   if (AlterTableReq::getReorgFragFlag(impl_req->changeMask))
   {
@@ -9386,6 +9436,7 @@ Dbdict::alterTable_commit(Signal* signal
      */
     alterTabPtr.p->m_blockNo[0] = RNIL;
     alterTabPtr.p->m_blockNo[2] = RNIL;
+    alterTabPtr.p->m_blockNo[3] = RNIL;
   }
   else if (AlterTableReq::getReorgCompleteFlag(impl_req->changeMask) ||
            AlterTableReq::getReorgSumaEnableFlag(impl_req->changeMask) ||
@@ -9609,6 +9660,7 @@ Dbdict::alterTable_complete(Signal* sign
   alterTabPtr.p->m_blockNo[0] = RNIL;
   alterTabPtr.p->m_blockNo[1] = RNIL;
   alterTabPtr.p->m_blockNo[2] = RNIL;
+  alterTabPtr.p->m_blockNo[3] = RNIL;
 
   if (AlterTableReq::getReorgCommitFlag(impl_req->changeMask))
   {

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2012-08-22 11:15:43 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2012-09-19 07:09:57 +0000
@@ -2468,7 +2468,7 @@ private:
     MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
 
     Uint32 m_block;
-    enum { BlockCount = 5 };
+    enum { BlockCount = 6 };
     Uint32 m_blockNo[BlockCount];
     Callback m_callback;
 
@@ -2549,7 +2549,7 @@ private:
     Uint32 m_lqhFragPtr;
 
     // local blocks to process
-    enum { BlockCount = 3 };
+    enum { BlockCount = 4 };
     Uint32 m_blockNo[BlockCount];
     Uint32 m_blockIndex;
 
@@ -2571,7 +2571,8 @@ private:
       m_lqhFragPtr = RNIL;
       m_blockNo[0] = DBLQH;
       m_blockNo[1] = DBDIH;
-      m_blockNo[2] = DBTC;
+      m_blockNo[2] = DBSPJ;
+      m_blockNo[3] = DBTC;
       m_blockIndex = 0;
       m_sub_add_frag_index_ptr = RNIL;
       m_sub_add_frag = false;

=== added directory 'storage/ndb/src/kernel/blocks/dbgdm'
=== added file 'storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.cpp	2012-09-19 06:37:24 +0000
@@ -0,0 +1,419 @@
+/*
+  Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "DbgdmProxy.hpp"
+
+#include <signaldata/CreateTab.hpp>
+#include <signaldata/TabCommit.hpp>
+#include <signaldata/PrepDropTab.hpp>
+#include <signaldata/DropTab.hpp>
+#include <signaldata/AlterTab.hpp>
+
+DbgdmProxy::DbgdmProxy(BlockNumber blockNumber, Block_context& ctx)
+ : LocalProxy(blockNumber, ctx)
+{
+  // GSN_TC_SCHVERREQ
+  addRecSignal(GSN_TC_SCHVERREQ, &DbgdmProxy::execTC_SCHVERREQ);
+  addRecSignal(GSN_TC_SCHVERCONF, &DbgdmProxy::execTC_SCHVERCONF);
+
+  // GSN_TAB_COMMITREQ
+  addRecSignal(GSN_TAB_COMMITREQ, &DbgdmProxy::execTAB_COMMITREQ);
+  addRecSignal(GSN_TAB_COMMITCONF, &DbgdmProxy::execTAB_COMMITCONF);
+  addRecSignal(GSN_TAB_COMMITREF, &DbgdmProxy::execTAB_COMMITREF);
+
+  // GSN_PREP_DROP_TAB_REQ
+  addRecSignal(GSN_PREP_DROP_TAB_REQ, &DbgdmProxy::execPREP_DROP_TAB_REQ);
+  addRecSignal(GSN_PREP_DROP_TAB_CONF, &DbgdmProxy::execPREP_DROP_TAB_CONF);
+  addRecSignal(GSN_PREP_DROP_TAB_REF, &DbgdmProxy::execPREP_DROP_TAB_REF);
+
+  // GSN_DROP_TAB_REQ
+  addRecSignal(GSN_DROP_TAB_REQ, &DbgdmProxy::execDROP_TAB_REQ);
+  addRecSignal(GSN_DROP_TAB_CONF, &DbgdmProxy::execDROP_TAB_CONF);
+  addRecSignal(GSN_DROP_TAB_REF, &DbgdmProxy::execDROP_TAB_REF);
+
+  // GSN_ALTER_TAB_REQ
+  addRecSignal(GSN_ALTER_TAB_REQ, &DbgdmProxy::execALTER_TAB_REQ);
+  addRecSignal(GSN_ALTER_TAB_CONF, &DbgdmProxy::execALTER_TAB_CONF);
+  addRecSignal(GSN_ALTER_TAB_REF, &DbgdmProxy::execALTER_TAB_REF);
+}
+
+DbgdmProxy::~DbgdmProxy()
+{
+}
+
+// GSN_TC_SCHVERREQ
+
+void
+DbgdmProxy::execTC_SCHVERREQ(Signal* signal)
+{
+  Ss_TC_SCHVERREQ& ss = ssSeize<Ss_TC_SCHVERREQ>(1);
+
+  const TcSchVerReq* req = (const TcSchVerReq*)signal->getDataPtr();
+  ss.m_req = *req;
+
+  sendREQ(signal, ss);
+}
+
+void
+DbgdmProxy::sendTC_SCHVERREQ(Signal* signal, Uint32 ssId, SectionHandle*)
+{
+  Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
+
+  TcSchVerReq* req = (TcSchVerReq*)signal->getDataPtrSend();
+  *req = ss.m_req;
+  req->senderRef = reference();
+  req->senderData = ssId;
+  sendSignal(workerRef(ss.m_worker), GSN_TC_SCHVERREQ,
+             signal, TcSchVerReq::SignalLength, JBB);
+}
+
+void
+DbgdmProxy::execTC_SCHVERCONF(Signal* signal)
+{
+  const TcSchVerConf* conf = (const TcSchVerConf*)signal->getDataPtr();
+  Uint32 ssId = conf->senderData;
+  Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
+  recvCONF(signal, ss);
+}
+
+void
+DbgdmProxy::sendTC_SCHVERCONF(Signal* signal, Uint32 ssId)
+{
+  Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
+  BlockReference dictRef = ss.m_req.senderRef;
+
+  if (!lastReply(ss))
+    return;
+
+  TcSchVerConf* conf = (TcSchVerConf*)signal->getDataPtrSend();
+  conf->senderRef = reference();
+  conf->senderData = ss.m_req.senderData;
+  sendSignal(dictRef, GSN_TC_SCHVERCONF,
+             signal, TcSchVerConf::SignalLength, JBB);
+
+  ssRelease<Ss_TC_SCHVERREQ>(ssId);
+}
+
+// GSN_TAB_COMMITREQ [ sub-op ]
+
+void
+DbgdmProxy::execTAB_COMMITREQ(Signal* signal)
+{
+  Ss_TAB_COMMITREQ& ss = ssSeize<Ss_TAB_COMMITREQ>(1);
+
+  const TabCommitReq* req = (const TabCommitReq*)signal->getDataPtr();
+  ss.m_req = *req;
+  sendREQ(signal, ss);
+}
+
+void
+DbgdmProxy::sendTAB_COMMITREQ(Signal* signal, Uint32 ssId, SectionHandle*)
+{
+  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
+
+  TabCommitReq* req = (TabCommitReq*)signal->getDataPtrSend();
+  req->senderRef = reference();
+  req->senderData = ssId;
+  req->tableId = ss.m_req.tableId;
+  sendSignal(workerRef(ss.m_worker), GSN_TAB_COMMITREQ,
+             signal, TabCommitReq::SignalLength, JBB);
+}
+
+void
+DbgdmProxy::execTAB_COMMITCONF(Signal* signal)
+{
+  const TabCommitConf* conf = (TabCommitConf*)signal->getDataPtr();
+  Uint32 ssId = conf->senderData;
+  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
+  recvCONF(signal, ss);
+}
+
+void
+DbgdmProxy::execTAB_COMMITREF(Signal* signal)
+{
+  const TabCommitRef* ref = (TabCommitRef*)signal->getDataPtr();
+  Uint32 ssId = ref->senderData;
+  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
+
+  recvREF(signal, ss, ref->errorCode);
+}
+
+void
+DbgdmProxy::sendTAB_COMMITCONF(Signal* signal, Uint32 ssId)
+{
+  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
+  BlockReference dictRef = ss.m_req.senderRef;
+
+  if (!lastReply(ss))
+    return;
+
+  if (ss.m_error == 0) {
+    jam();
+    TabCommitConf* conf = (TabCommitConf*)signal->getDataPtrSend();
+    conf->senderData = ss.m_req.senderData;
+    conf->nodeId = getOwnNodeId();
+    conf->tableId = ss.m_req.tableId;
+    sendSignal(dictRef, GSN_TAB_COMMITCONF,
+               signal, TabCommitConf::SignalLength, JBB);
+  } else {
+    jam();
+    TabCommitRef* ref = (TabCommitRef*)signal->getDataPtrSend();
+    ref->senderData = ss.m_req.senderData;
+    ref->nodeId = getOwnNodeId();
+    ref->tableId = ss.m_req.tableId;
+    sendSignal(dictRef, GSN_TAB_COMMITREF,
+               signal, TabCommitRef::SignalLength, JBB);
+    return;
+  }
+
+  ssRelease<Ss_TAB_COMMITREQ>(ssId);
+}
+
+// GSN_PREP_DROP_TAB_REQ
+
+void
+DbgdmProxy::execPREP_DROP_TAB_REQ(Signal* signal)
+{
+  const PrepDropTabReq* req = (const PrepDropTabReq*)signal->getDataPtr();
+  Uint32 ssId = getSsId(req);
+  Ss_PREP_DROP_TAB_REQ& ss = ssSeize<Ss_PREP_DROP_TAB_REQ>(ssId);
+  ss.m_req = *req;
+  ndbrequire(signal->getLength() == PrepDropTabReq::SignalLength);
+  sendREQ(signal, ss);
+}
+
+void
+DbgdmProxy::sendPREP_DROP_TAB_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
+{
+  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
+
+  PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtrSend();
+  *req = ss.m_req;
+  req->senderRef = reference();
+  req->senderData = ssId; // redundant since tableId is used
+  sendSignal(workerRef(ss.m_worker), GSN_PREP_DROP_TAB_REQ,
+             signal, PrepDropTabReq::SignalLength, JBB);
+}
+
+void
+DbgdmProxy::execPREP_DROP_TAB_CONF(Signal* signal)
+{
+  const PrepDropTabConf* conf = (const PrepDropTabConf*)signal->getDataPtr();
+  Uint32 ssId = getSsId(conf);
+  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
+  recvCONF(signal, ss);
+}
+
+void
+DbgdmProxy::execPREP_DROP_TAB_REF(Signal* signal)
+{
+  const PrepDropTabRef* ref = (const PrepDropTabRef*)signal->getDataPtr();
+  Uint32 ssId = getSsId(ref);
+  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
+  recvREF(signal, ss, ref->errorCode);
+}
+
+void
+DbgdmProxy::sendPREP_DROP_TAB_CONF(Signal* signal, Uint32 ssId)
+{
+  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
+  BlockReference dictRef = ss.m_req.senderRef;
+
+  if (!lastReply(ss))
+    return;
+
+  if (ss.m_error == 0) {
+    jam();
+    PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
+    conf->senderRef = reference();
+    conf->senderData = ss.m_req.senderData;
+    conf->tableId = ss.m_req.tableId;
+    sendSignal(dictRef, GSN_PREP_DROP_TAB_CONF,
+               signal, PrepDropTabConf::SignalLength, JBB);
+  } else {
+    jam();
+    PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = ss.m_req.senderData;
+    ref->tableId = ss.m_req.tableId;
+    ref->errorCode = ss.m_error;
+    sendSignal(dictRef, GSN_PREP_DROP_TAB_REF,
+               signal, PrepDropTabRef::SignalLength, JBB);
+  }
+
+  ssRelease<Ss_PREP_DROP_TAB_REQ>(ssId);
+}
+
+// GSN_DROP_TAB_REQ
+
+void
+DbgdmProxy::execDROP_TAB_REQ(Signal* signal)
+{
+  const DropTabReq* req = (const DropTabReq*)signal->getDataPtr();
+  Uint32 ssId = getSsId(req);
+  Ss_DROP_TAB_REQ& ss = ssSeize<Ss_DROP_TAB_REQ>(ssId);
+  ss.m_req = *req;
+  ndbrequire(signal->getLength() == DropTabReq::SignalLength);
+  sendREQ(signal, ss);
+}
+
+void
+DbgdmProxy::sendDROP_TAB_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
+{
+  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
+
+  DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
+  *req = ss.m_req;
+  req->senderRef = reference();
+  req->senderData = ssId; // redundant since tableId is used
+  sendSignal(workerRef(ss.m_worker), GSN_DROP_TAB_REQ,
+             signal, DropTabReq::SignalLength, JBB);
+}
+
+void
+DbgdmProxy::execDROP_TAB_CONF(Signal* signal)
+{
+  const DropTabConf* conf = (const DropTabConf*)signal->getDataPtr();
+  Uint32 ssId = getSsId(conf);
+  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
+  recvCONF(signal, ss);
+}
+
+void
+DbgdmProxy::execDROP_TAB_REF(Signal* signal)
+{
+  const DropTabRef* ref = (const DropTabRef*)signal->getDataPtr();
+  Uint32 ssId = getSsId(ref);
+  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
+  recvREF(signal, ss, ref->errorCode);
+}
+
+void
+DbgdmProxy::sendDROP_TAB_CONF(Signal* signal, Uint32 ssId)
+{
+  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
+  BlockReference dictRef = ss.m_req.senderRef;
+
+  if (!lastReply(ss))
+    return;
+
+  if (ss.m_error == 0) {
+    jam();
+    DropTabConf* conf = (DropTabConf*)signal->getDataPtrSend();
+    conf->senderRef = reference();
+    conf->senderData = ss.m_req.senderData;
+    conf->tableId = ss.m_req.tableId;
+    sendSignal(dictRef, GSN_DROP_TAB_CONF,
+               signal, DropTabConf::SignalLength, JBB);
+  } else {
+    jam();
+    DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = ss.m_req.senderData;
+    ref->tableId = ss.m_req.tableId;
+    ref->errorCode = ss.m_error;
+    sendSignal(dictRef, GSN_DROP_TAB_REF,
+               signal, DropTabConf::SignalLength, JBB);
+  }
+
+  ssRelease<Ss_DROP_TAB_REQ>(ssId);
+}
+
+// GSN_ALTER_TAB_REQ
+
+void
+DbgdmProxy::execALTER_TAB_REQ(Signal* signal)
+{
+  if (!assembleFragments(signal))
+  {
+    jam();
+    return;
+  }
+
+  const AlterTabReq* req = (const AlterTabReq*)signal->getDataPtr();
+  Uint32 ssId = getSsId(req);
+  Ss_ALTER_TAB_REQ& ss = ssSeize<Ss_ALTER_TAB_REQ>(ssId);
+  ss.m_req = *req;
+
+  SectionHandle handle(this, signal);
+  saveSections(ss, handle);
+
+  sendREQ(signal, ss);
+}
+
+void
+DbgdmProxy::sendALTER_TAB_REQ(Signal* signal, Uint32 ssId,
+                             SectionHandle* handle)
+{
+  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
+
+  AlterTabReq* req = (AlterTabReq*)signal->getDataPtrSend();
+  *req = ss.m_req;
+  req->senderRef = reference();
+  req->senderData = ssId;
+  sendSignalNoRelease(workerRef(ss.m_worker), GSN_ALTER_TAB_REQ,
+                      signal, AlterTabReq::SignalLength, JBB, handle);
+}
+
+void
+DbgdmProxy::execALTER_TAB_CONF(Signal* signal)
+{
+  const AlterTabConf* conf = (const AlterTabConf*)signal->getDataPtr();
+  Uint32 ssId = getSsId(conf);
+  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
+  recvCONF(signal, ss);
+}
+
+void
+DbgdmProxy::execALTER_TAB_REF(Signal* signal)
+{
+  const AlterTabRef* ref = (const AlterTabRef*)signal->getDataPtr();
+  Uint32 ssId = getSsId(ref);
+  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
+  recvREF(signal, ss, ref->errorCode);
+}
+
+void
+DbgdmProxy::sendALTER_TAB_CONF(Signal* signal, Uint32 ssId)
+{
+  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
+  BlockReference dictRef = ss.m_req.senderRef;
+
+  if (!lastReply(ss))
+    return;
+
+  if (ss.m_error == 0) {
+    jam();
+    AlterTabConf* conf = (AlterTabConf*)signal->getDataPtrSend();
+    conf->senderRef = reference();
+    conf->senderData = ss.m_req.senderData;
+    sendSignal(dictRef, GSN_ALTER_TAB_CONF,
+               signal, AlterTabConf::SignalLength, JBB);
+  } else {
+    jam();
+    AlterTabRef* ref = (AlterTabRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = ss.m_req.senderData;
+    ref->errorCode = ss.m_error;
+    sendSignal(dictRef, GSN_ALTER_TAB_REF,
+               signal, AlterTabConf::SignalLength, JBB);
+  }
+
+  ssRelease<Ss_ALTER_TAB_REQ>(ssId);
+}
+
+BLOCK_FUNCTIONS(DbgdmProxy)

=== added file 'storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/blocks/dbgdm/DbgdmProxy.hpp	2012-09-19 06:37:24 +0000
@@ -0,0 +1,168 @@
+/*
+  Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef NDB_DBGDM_PROXY_HPP
+#define NDB_DBGDM_PROXY_HPP
+
+#include <LocalProxy.hpp>
+#include <signaldata/CreateTab.hpp>
+#include <signaldata/TabCommit.hpp>
+#include <signaldata/PrepDropTab.hpp>
+#include <signaldata/DropTab.hpp>
+#include <signaldata/AlterTab.hpp>
+
+/**
+ * The Global Dictionary Manager (GDB):
+ *
+ * Intended as a shared base class for the TC and SPJ
+ * table dictionary which share lots of common
+ * components in this area.
+ */
+
+class DbgdmProxy : public LocalProxy {
+public:
+  DbgdmProxy(BlockNumber blockNumber, Block_context& ctx);
+  virtual ~DbgdmProxy();
+  BLOCK_DEFINES(DbgdmProxy);
+
+protected:
+  virtual SimulatedBlock* newWorker(Uint32 instanceNo) = 0;
+
+  // GSN_TC_SCHVERREQ
+  struct Ss_TC_SCHVERREQ : SsParallel {
+    TcSchVerReq m_req;
+    Ss_TC_SCHVERREQ() {
+      m_sendREQ = (SsFUNCREQ)&DbgdmProxy::sendTC_SCHVERREQ;
+      m_sendCONF = (SsFUNCREP)&DbgdmProxy::sendTC_SCHVERCONF;
+    }
+    enum { poolSize = 1 };
+    static SsPool<Ss_TC_SCHVERREQ>& pool(LocalProxy* proxy) {
+      return ((DbgdmProxy*)proxy)->c_ss_TC_SCHVERREQ;
+    }
+  };
+  SsPool<Ss_TC_SCHVERREQ> c_ss_TC_SCHVERREQ;
+  void execTC_SCHVERREQ(Signal*);
+  void sendTC_SCHVERREQ(Signal*, Uint32 ssId, SectionHandle*);
+  void execTC_SCHVERCONF(Signal*);
+  void sendTC_SCHVERCONF(Signal*, Uint32 ssId);
+
+  // GSN_TAB_COMMITREQ [ sub-op ]
+  struct Ss_TAB_COMMITREQ : SsParallel {
+    TabCommitReq m_req;
+    Ss_TAB_COMMITREQ() {
+      m_sendREQ = (SsFUNCREQ)&DbgdmProxy::sendTAB_COMMITREQ;
+      m_sendCONF = (SsFUNCREP)&DbgdmProxy::sendTAB_COMMITCONF;
+    }
+    enum { poolSize = 1 };
+    static SsPool<Ss_TAB_COMMITREQ>& pool(LocalProxy* proxy) {
+      return ((DbgdmProxy*)proxy)->c_ss_TAB_COMMITREQ;
+    }
+  };
+  SsPool<Ss_TAB_COMMITREQ> c_ss_TAB_COMMITREQ;
+  void execTAB_COMMITREQ(Signal*);
+  void sendTAB_COMMITREQ(Signal*, Uint32 ssId, SectionHandle*);
+  void execTAB_COMMITCONF(Signal*);
+  void execTAB_COMMITREF(Signal*);
+  void sendTAB_COMMITCONF(Signal*, Uint32 ssId);
+
+  // GSN_PREP_DROP_TAB_REQ
+  struct Ss_PREP_DROP_TAB_REQ : SsParallel {
+    PrepDropTabReq m_req;
+    Ss_PREP_DROP_TAB_REQ() {
+      m_sendREQ = (SsFUNCREQ)&DbgdmProxy::sendPREP_DROP_TAB_REQ;
+      m_sendCONF = (SsFUNCREP)&DbgdmProxy::sendPREP_DROP_TAB_CONF;
+    }
+    enum { poolSize = 1 };
+    static SsPool<Ss_PREP_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
+      return ((DbgdmProxy*)proxy)->c_ss_PREP_DROP_TAB_REQ;
+    }
+  };
+
+  SsPool<Ss_PREP_DROP_TAB_REQ> c_ss_PREP_DROP_TAB_REQ;
+  Uint32 getSsId(const PrepDropTabReq* req) {
+    return SsIdBase | req->tableId;
+  }
+  Uint32 getSsId(const PrepDropTabConf* conf) {
+    return SsIdBase | conf->tableId;
+  }
+  Uint32 getSsId(const PrepDropTabRef* ref) {
+    return SsIdBase | ref->tableId;
+  }
+  void execPREP_DROP_TAB_REQ(Signal*);
+  void sendPREP_DROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
+  void execPREP_DROP_TAB_CONF(Signal*);
+  void execPREP_DROP_TAB_REF(Signal*);
+  void sendPREP_DROP_TAB_CONF(Signal*, Uint32 ssId);
+
+  // GSN_DROP_TAB_REQ
+  struct Ss_DROP_TAB_REQ : SsParallel {
+    DropTabReq m_req;
+    Ss_DROP_TAB_REQ() {
+      m_sendREQ = (SsFUNCREQ)&DbgdmProxy::sendDROP_TAB_REQ;
+      m_sendCONF = (SsFUNCREP)&DbgdmProxy::sendDROP_TAB_CONF;
+    }
+    enum { poolSize = 1 };
+    static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
+      return ((DbgdmProxy*)proxy)->c_ss_DROP_TAB_REQ;
+    }
+  };
+  SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ;
+  Uint32 getSsId(const DropTabReq* req) {
+    return SsIdBase | req->tableId;
+  }
+  Uint32 getSsId(const DropTabConf* conf) {
+    return SsIdBase | conf->tableId;
+  }
+  Uint32 getSsId(const DropTabRef* ref) {
+    return SsIdBase | ref->tableId;
+  }
+  void execDROP_TAB_REQ(Signal*);
+  void sendDROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
+  void execDROP_TAB_CONF(Signal*);
+  void execDROP_TAB_REF(Signal*);
+  void sendDROP_TAB_CONF(Signal*, Uint32 ssId);
+
+  // GSN_ALTER_TAB_REQ
+  struct Ss_ALTER_TAB_REQ : SsParallel {
+    AlterTabReq m_req;
+    Ss_ALTER_TAB_REQ() {
+      m_sendREQ = (SsFUNCREQ)&DbgdmProxy::sendALTER_TAB_REQ;
+      m_sendCONF = (SsFUNCREP)&DbgdmProxy::sendALTER_TAB_CONF;
+    }
+    enum { poolSize = 1 };
+    static SsPool<Ss_ALTER_TAB_REQ>& pool(LocalProxy* proxy) {
+      return ((DbgdmProxy*)proxy)->c_ss_ALTER_TAB_REQ;
+    }
+  };
+  SsPool<Ss_ALTER_TAB_REQ> c_ss_ALTER_TAB_REQ;
+  Uint32 getSsId(const AlterTabReq* req) {
+    return SsIdBase | req->tableId;
+  }
+  Uint32 getSsId(const AlterTabConf* conf) {
+    return conf->senderData;
+  }
+  Uint32 getSsId(const AlterTabRef* ref) {
+    return ref->senderData;
+  }
+  void execALTER_TAB_REQ(Signal*);
+  void sendALTER_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
+  void execALTER_TAB_CONF(Signal*);
+  void execALTER_TAB_REF(Signal*);
+  void sendALTER_TAB_CONF(Signal*, Uint32 ssId);
+};
+
+#endif // NDB_DBGDM_PROXY_HPP

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp	2012-08-24 12:07:17 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp	2012-09-19 07:09:57 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -12,7 +12,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #ifndef DBSPJ_H
@@ -58,6 +58,15 @@ private:
   BLOCK_DEFINES(Dbspj);
 
   /**
+   * Signals from DICT
+   */
+  void execTC_SCHVERREQ(Signal* signal);
+  void execTAB_COMMITREQ(Signal* signal);
+  void execPREP_DROP_TAB_REQ(Signal* signal);
+  void execDROP_TAB_REQ(Signal* signal);
+  void execALTER_TAB_REQ(Signal* signal);
+
+  /**
    * Signals from TC
    */
   void execLQHKEYREQ(Signal* signal);
@@ -109,6 +118,40 @@ public:
   typedef LocalDataBuffer2<14, LocalArenaPoolImpl> Local_pattern_store;
   typedef Bitmask<(NDB_SPJ_MAX_TREE_NODES+31)/32> TreeNodeBitMask;
 
+  /* *********** TABLE RECORD ********************************************* */
+
+  /********************************************************/
+  /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF   */
+  /* ALL TABLES IN THE SYSTEM.                            */
+  /********************************************************/
+  struct TableRecord {
+    TableRecord() 
+    : m_currentSchemaVersion(0), m_flags(0)
+    {};
+
+    TableRecord(Uint32 schemaVersion)
+    : m_currentSchemaVersion(schemaVersion), m_flags(TR_PREPARED)
+    {};
+
+    Uint32 m_currentSchemaVersion;
+    Uint16 m_flags;
+
+    enum {
+      TR_ENABLED      = 1 << 0,
+      TR_DROPPING     = 1 << 1,
+      TR_PREPARED     = 1 << 2
+    };
+    Uint8 get_enabled()     const { return (m_flags & TR_ENABLED)      != 0; }
+    Uint8 get_dropping()    const { return (m_flags & TR_DROPPING)     != 0; }
+    Uint8 get_prepared()    const { return (m_flags & TR_PREPARED)     != 0; }
+    void set_enabled(Uint8 f)     { f ? m_flags |= (Uint16)TR_ENABLED      : m_flags &= ~(Uint16)TR_ENABLED; }
+    void set_dropping(Uint8 f)    { f ? m_flags |= (Uint16)TR_DROPPING     : m_flags &= ~(Uint16)TR_DROPPING; }
+    void set_prepared(Uint8 f)    { f ? m_flags |= (Uint16)TR_PREPARED : m_flags &= ~(Uint16)TR_PREPARED; }
+
+    Uint32 checkTableError(Uint32 schemaVersion) const;
+  };
+  typedef Ptr<TableRecord> TableRecordPtr;
+
   struct RowRef
   {
     Uint32 m_page_id;
@@ -633,7 +676,7 @@ public:
 
     TreeNode()
     : m_magic(MAGIC), m_state(TN_END),
-      m_parentPtrI(RNIL), m_requestPtrI(0),
+      m_parentPtrI(RNIL), m_requestPtrI(RNIL),
       m_ancestors()
     {
     }
@@ -776,6 +819,13 @@ public:
 
     bool isLeaf() const { return (m_bits & T_LEAF) != 0;}
 
+    // table or index this TreeNode operates on, and its schemaVersion
+    Uint32 m_tableOrIndexId;
+    Uint32 m_schemaVersion;
+
+    // TableId if 'm_tableOrIndexId' is an index, else equal 
+    Uint32 m_primaryTableId; 
+
     Uint32 m_bits;
     Uint32 m_state;
     Uint32 m_node_no;
@@ -1044,6 +1094,9 @@ private:
   TreeNode_pool m_treenode_pool;
   ScanFragHandle_pool m_scanfraghandle_pool;
 
+  TableRecord *m_tableRecord;
+  UintR c_tabrecFilesize;
+
   NdbNodeBitmask c_alive_nodes;
 
   void do_init(Request*, const LqhKeyReq*, Uint32 senderRef);
@@ -1171,6 +1224,9 @@ private:
 
   Uint32 getResultRef(Ptr<Request> requestPtr);
 
+  Uint32 checkTableError(Ptr<TreeNode> treeNodePtr) const;
+  Uint32 getNodes(Signal*, BuildKeyReq&, Uint32 tableId);
+
   /**
    * Lookup
    */
@@ -1197,7 +1253,6 @@ private:
 
   Uint32 computeHash(Signal*, BuildKeyReq&, Uint32 table, Uint32 keyInfoPtrI);
   Uint32 computePartitionHash(Signal*, BuildKeyReq&, Uint32 table, Uint32 keyInfoPtrI);
-  Uint32 getNodes(Signal*, BuildKeyReq&, Uint32 tableId);
 
   /**
    * ScanFrag

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjInit.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjInit.cpp	2011-02-23 19:28:26 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjInit.cpp	2012-09-19 06:37:24 +0000
@@ -26,7 +26,8 @@
 Dbspj::Dbspj(Block_context& ctx, Uint32 instanceNumber):
   SimulatedBlock(DBSPJ, ctx, instanceNumber),
   m_scan_request_hash(m_request_pool),
-  m_lookup_request_hash(m_request_pool)
+  m_lookup_request_hash(m_request_pool),
+  m_tableRecord(NULL), c_tabrecFilesize(0)
 {
   BLOCK_CONSTRUCTOR(Dbspj);
 
@@ -41,6 +42,15 @@ Dbspj::Dbspj(Block_context& ctx, Uint32 
   addRecSignal(GSN_API_FAILREQ, &Dbspj::execAPI_FAILREQ);
 
   /**
+   * Signals from DICT
+   */
+  addRecSignal(GSN_TC_SCHVERREQ, &Dbspj::execTC_SCHVERREQ);
+  addRecSignal(GSN_TAB_COMMITREQ, &Dbspj::execTAB_COMMITREQ);
+  addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbspj::execPREP_DROP_TAB_REQ);
+  addRecSignal(GSN_DROP_TAB_REQ, &Dbspj::execDROP_TAB_REQ);
+  addRecSignal(GSN_ALTER_TAB_REQ, &Dbspj::execALTER_TAB_REQ);
+
+  /**
    * Signals from DIH
    */
   addRecSignal(GSN_DIH_SCAN_TAB_REF, &Dbspj::execDIH_SCAN_TAB_REF);
@@ -71,6 +81,11 @@ Dbspj::Dbspj(Block_context& ctx, Uint32 
 Dbspj::~Dbspj()
 {
   m_page_pool.clear();
+
+  deallocRecord((void**)&m_tableRecord,
+		"TableRecord",
+		sizeof(TableRecord), 
+		c_tabrecFilesize);
 }//Dbspj::~Dbspj()
 
 

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp	2012-09-07 15:52:18 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp	2012-09-19 07:09:57 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+  Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -12,7 +12,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #define DBSPJ_C
@@ -28,6 +28,11 @@
 #include <signaldata/DiGetNodes.hpp>
 #include <signaldata/DihScanTab.hpp>
 #include <signaldata/AttrInfo.hpp>
+#include <signaldata/CreateTab.hpp>
+#include <signaldata/PrepDropTab.hpp>
+#include <signaldata/DropTab.hpp>
+#include <signaldata/AlterTab.hpp>
+#include <signaldata/DbspjErr.hpp>
 #include <Interpreter.hpp>
 #include <AttributeHeader.hpp>
 #include <AttributeDescriptor.hpp>
@@ -45,12 +50,14 @@
 #ifdef VM_TRACE
 
 #define DEBUG(x) ndbout << "DBSPJ: "<< x << endl;
+#define DEBUG_DICT(x) ndbout << "DBSPJ: "<< x << endl;
 #define DEBUG_LQHKEYREQ
 #define DEBUG_SCAN_FRAGREQ
 
 #else
 
 #define DEBUG(x)
+#define DEBUG_DICT(x)
 
 #endif
 
@@ -59,6 +66,8 @@
 #if 1
 #undef DEBUG
 #define DEBUG(x)
+#undef DEBUG_DICT
+#define DEBUG_DICT(x)
 #undef DEBUG_LQHKEYREQ
 #undef DEBUG_SCAN_FRAGREQ
 #endif
@@ -110,6 +119,259 @@ void Dbspj::execSIGNAL_DROPPED_REP(Signa
   return;
 }
 
+inline
+Uint32 
+Dbspj::TableRecord::checkTableError(Uint32 schemaVersion) const
+{
+  DEBUG_DICT("Dbspj::TableRecord::checkTableError"
+            << ", m_flags: " << m_flags
+            << ", m_currentSchemaVersion: " << m_currentSchemaVersion
+            << ", check schemaVersion: " << schemaVersion);
+
+  if (!get_enabled())
+    return DbspjErr::NoSuchTable;
+  if (get_dropping())
+    return DbspjErr::DropTableInProgress;
+  if (table_version_major(schemaVersion) != table_version_major(m_currentSchemaVersion))
+    return DbspjErr::WrongSchemaVersion;
+
+  return 0;
+}
+
+// create table prepare
+void Dbspj::execTC_SCHVERREQ(Signal* signal) 
+{
+  jamEntry();
+  if (! assembleFragments(signal)) {
+    jam();
+    return;
+  }
+  const TcSchVerReq* req = CAST_CONSTPTR(TcSchVerReq, signal->getDataPtr());
+  const Uint32 tableId = req->tableId;
+  const Uint32 senderRef = req->senderRef;
+  const Uint32 senderData = req->senderData;
+
+  DEBUG_DICT("Dbspj::execTC_SCHVERREQ"
+     << ", tableId: " << tableId
+     << ", version: " << req->tableVersion
+  );
+
+  TableRecordPtr tablePtr;
+  tablePtr.i = tableId;
+  ptrCheckGuard(tablePtr, c_tabrecFilesize, m_tableRecord);
+
+  ndbrequire(tablePtr.p->get_prepared() == false);
+  ndbrequire(tablePtr.p->get_enabled() == false);
+  new (tablePtr.p) TableRecord(req->tableVersion);
+
+  /**
+   * NOTE: Even if there are more information, like 
+   * 'tableType', 'noOfPrimaryKeys'etc available from
+   * TcSchVerReq, we do *not* store that in TableRecord.
+   * Instead this information is retrieved on demand from
+   * g_key_descriptor_pool where it is readily available.
+   * The 'contract' for consistency of this information is 
+   * such that:
+   * 1) g_key_descriptor[ENTRY] will be populated *before* 
+   *    any blocks receiving CREATE_TAB_REQ (or equivalent).
+   * 2) g_key_descriptor[ENTRY] will be invalidated *after*
+   *    all blocks sent DROP_TAB_CONF (commit)
+   * Thus, this info is consistent whenever required by SPJ.
+   */
+  TcSchVerConf * conf = (TcSchVerConf*)signal->getDataPtr();
+  conf->senderRef = reference();
+  conf->senderData = senderData;
+  sendSignal(senderRef, GSN_TC_SCHVERCONF, signal,
+             TcSchVerConf::SignalLength, JBB);
+}//Dbspj::execTC_SCHVERREQ()
+
+// create table commit
+void Dbspj::execTAB_COMMITREQ(Signal* signal)
+{
+  jamEntry();
+  const Uint32 senderData = signal->theData[0];
+  const Uint32 senderRef = signal->theData[1];
+  const Uint32 tableId = signal->theData[2];
+
+  DEBUG_DICT("Dbspj::execTAB_COMMITREQ"
+     << ", tableId: " << tableId
+  );
+
+  TableRecordPtr tablePtr;
+  tablePtr.i = tableId;
+  ptrCheckGuard(tablePtr, c_tabrecFilesize, m_tableRecord);
+
+  ndbrequire(tablePtr.p->get_prepared() == true);
+  ndbrequire(tablePtr.p->get_enabled() == false);
+  tablePtr.p->set_enabled(true);
+  tablePtr.p->set_prepared(false);
+  tablePtr.p->set_dropping(false);
+
+  signal->theData[0] = senderData;
+  signal->theData[1] = reference();
+  signal->theData[2] = tableId;
+  sendSignal(senderRef, GSN_TAB_COMMITCONF, signal, 3, JBB);
+}//Dbspj::execTAB_COMMITREQ
+
+void
+Dbspj::execPREP_DROP_TAB_REQ(Signal* signal)
+{
+  jamEntry();
+  
+  PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
+  const Uint32 tableId = req->tableId;
+  const Uint32 senderRef = req->senderRef;
+  const Uint32 senderData = req->senderData;
+
+  DEBUG_DICT("Dbspj::execPREP_DROP_TAB_REQ"
+     << ", tableId: " << tableId
+  );
+
+  TableRecordPtr tablePtr;
+  tablePtr.i = tableId;
+  ptrCheckGuard(tablePtr, c_tabrecFilesize, m_tableRecord);
+
+  if (!tablePtr.p->get_enabled())
+  {
+    jam();
+    PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = senderData;
+    ref->tableId = tableId;
+    ref->errorCode = PrepDropTabRef::NoSuchTable;
+    sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
+	       PrepDropTabRef::SignalLength, JBB);
+    return;
+  }
+
+  if (tablePtr.p->get_dropping())
+  {
+    jam();
+    PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = senderData;
+    ref->tableId = tableId;
+    ref->errorCode = PrepDropTabRef::DropInProgress;
+    sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
+	       PrepDropTabRef::SignalLength, JBB);
+    return;
+  }
+  
+  tablePtr.p->set_dropping(true);
+  tablePtr.p->set_prepared(false);
+
+  PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
+  conf->tableId = tableId;
+  conf->senderRef = reference();
+  conf->senderData = senderData;
+  sendSignal(senderRef, GSN_PREP_DROP_TAB_CONF, signal,
+             PrepDropTabConf::SignalLength, JBB);
+}//Dbspj::execPREP_DROP_TAB_REQ
+
+void
+Dbspj::execDROP_TAB_REQ(Signal* signal)
+{
+  jamEntry();
+
+  const DropTabReq* req = (DropTabReq*)signal->getDataPtr();
+  const Uint32 tableId = req->tableId;
+  const Uint32 senderRef = req->senderRef;
+  const Uint32 senderData = req->senderData;
+  DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
+
+  DEBUG_DICT("Dbspj::execDROP_TAB_REQ"
+     << ", tableId: " << tableId
+  );
+
+  TableRecordPtr tablePtr;
+  tablePtr.i = tableId;
+  ptrCheckGuard(tablePtr, c_tabrecFilesize, m_tableRecord);
+
+  if (rt == DropTabReq::OnlineDropTab){
+    if (!tablePtr.p->get_enabled()){
+      jam();
+      DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
+      ref->senderRef = reference();
+      ref->senderData = senderData;
+      ref->tableId = tableId;
+      ref->errorCode = DropTabRef::NoSuchTable;
+      sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
+	         DropTabRef::SignalLength, JBB);
+      return;
+    }
+    if (!tablePtr.p->get_dropping()){
+      jam();
+      DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
+      ref->senderRef = reference();
+      ref->senderData = senderData;
+      ref->tableId = tableId;
+      ref->errorCode = DropTabRef::DropWoPrep;
+      sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
+	         DropTabRef::SignalLength, JBB);
+      return;
+    }
+  }
+  
+  tablePtr.p->set_enabled(false);
+  tablePtr.p->set_prepared(false);
+  tablePtr.p->set_dropping(false);
+
+  DropTabConf * conf = (DropTabConf*)signal->getDataPtrSend();
+  conf->tableId = tableId;
+  conf->senderRef = reference();
+  conf->senderData = senderData;
+  sendSignal(senderRef, GSN_DROP_TAB_CONF, signal,
+	     PrepDropTabConf::SignalLength, JBB);
+}//Dbspj::execDROP_TAB_REQ
+
+void
+Dbspj::execALTER_TAB_REQ(Signal* signal)
+{
+  jamEntry();
+
+  const AlterTabReq* req = (const AlterTabReq*)signal->getDataPtr();
+  const Uint32 tableId = req->tableId;
+  const Uint32 senderRef = req->senderRef;
+  const Uint32 senderData = req->senderData;
+  const Uint32 tableVersion = req->tableVersion;
+  const Uint32 newTableVersion = req->newTableVersion;
+  AlterTabReq::RequestType requestType = 
+    (AlterTabReq::RequestType) req->requestType;
+
+  DEBUG_DICT("Dbspj::execALTER_TAB_REQ"
+     << ", tableId: " << tableId
+     << ", version: " << tableVersion << " --> " << newTableVersion
+  );
+
+  TableRecordPtr tablePtr;
+  tablePtr.i = tableId;
+  ptrCheckGuard(tablePtr, c_tabrecFilesize, m_tableRecord);
+
+  switch (requestType) {
+  case AlterTabReq::AlterTablePrepare:
+    jam();
+    break;
+  case AlterTabReq::AlterTableRevert:
+    jam();
+    tablePtr.p->m_currentSchemaVersion = tableVersion;
+    break;
+  case AlterTabReq::AlterTableCommit:
+    jam();
+    tablePtr.p->m_currentSchemaVersion = newTableVersion;
+    break;
+  default:
+    ndbrequire(false);
+    break;
+  }
+
+  AlterTabConf* conf = (AlterTabConf*)signal->getDataPtrSend();
+  conf->senderRef = reference();
+  conf->senderData = senderData;
+  conf->connectPtr = RNIL;
+  sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal, 
+	     AlterTabConf::SignalLength, JBB);
+}//Dbspj::execALTER_TAB_REQ
+
 /** A noop for now.*/
 void Dbspj::execREAD_CONFIG_REQ(Signal* signal)
 {
@@ -137,6 +399,23 @@ void Dbspj::execREAD_CONFIG_REQ(Signal* 
   Dependency_map::createRecordInfo(ri, RT_SPJ_DATABUFFER);
   m_dependency_map_pool.init(&m_arenaAllocator, ri, pc);
 
+  {
+    const ndb_mgm_configuration_iterator * p = 
+      m_ctx.m_config.getOwnConfigIterator();
+    ndbrequire(p != 0);
+
+    ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_SPJ_TABLE, &c_tabrecFilesize));
+  }
+  m_tableRecord = (TableRecord*)allocRecord("TableRecord",
+                                            sizeof(TableRecord),
+                                            c_tabrecFilesize);
+
+  TableRecordPtr tablePtr;
+  for (tablePtr.i = 0; tablePtr.i < c_tabrecFilesize; tablePtr.i++) {
+    ptrAss(tablePtr, m_tableRecord);
+    new (tablePtr.p) TableRecord;
+  }//for
+
   ReadConfigConf* const conf =
     reinterpret_cast<ReadConfigConf*>(signal->getDataPtrSend());
   conf->senderRef = reference();
@@ -1093,6 +1372,7 @@ void
 Dbspj::start(Signal* signal,
              Ptr<Request> requestPtr)
 {
+  Uint32 err = 0;
   if (requestPtr.p->m_bits & Request::RT_NEED_PREPARE)
   {
     jam();
@@ -1104,6 +1384,15 @@ Dbspj::start(Signal* signal,
     for (list.first(nodePtr); !nodePtr.isNull(); list.next(nodePtr))
     {
       jam();
+      /**
+       * Verify existence of all involved tables.
+       */
+      err = checkTableError(nodePtr);
+      if (unlikely(err))
+      {
+        jam();
+        break;
+      }
       ndbrequire(nodePtr.p->m_info != 0);
       if (nodePtr.p->m_info->m_prepare != 0)
       {
@@ -1116,7 +1405,13 @@ Dbspj::start(Signal* signal,
      * preferably RT_NEED_PREPARE should only be set if blocking
      * calls are used, in which case m_outstanding should have been increased
      */
-    ndbassert(requestPtr.p->m_outstanding);
+    ndbassert(err || requestPtr.p->m_outstanding);
+  }
+  if (unlikely(err))
+  {
+    jam();
+    abort(signal, requestPtr, err);
+    return;
   }
 
   checkPrepareComplete(signal, requestPtr, 0);
@@ -1140,12 +1435,20 @@ Dbspj::checkPrepareComplete(Signal * sig
       return;
     }
 
-    requestPtr.p->m_state = Request::RS_RUNNING;
     Ptr<TreeNode> nodePtr;
     {
       Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes);
       ndbrequire(list.first(nodePtr));
     }
+    Uint32 err = checkTableError(nodePtr);
+    if (unlikely(err != 0))
+    {
+      jam();
+      abort(signal, requestPtr, err);
+      return;
+    }
+
+    requestPtr.p->m_state = Request::RS_RUNNING;
     ndbrequire(nodePtr.p->m_info != 0 && nodePtr.p->m_info->m_start != 0);
     (this->*(nodePtr.p->m_info->m_start))(signal, requestPtr, nodePtr);
   }
@@ -2198,7 +2501,13 @@ Dbspj::execSCAN_NEXTREQ(Signal* signal)
                                                                   requestPtr,
                                                                   treeNodePtr);
       }
-    }
+      if (unlikely((requestPtr.p->m_state & Request::RS_ABORTING) != 0))
+      {
+        jam();
+        break;
+      }
+    }// for all treeNodes in 'm_cursor_nodes'
+
     /* Expected only a single ACTIVE TreeNode among the cursors */
     ndbrequire(cnt_active == 1 ||
                !(requestPtr.p->m_bits & Request::RT_REPEAT_SCAN_RESULT));
@@ -2824,6 +3133,39 @@ Dbspj::releaseGlobal(Signal * signal)
   sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, delay, 1);
 }
 
+Uint32
+Dbspj::checkTableError(Ptr<TreeNode> treeNodePtr) const
+{
+  jam();
+  if (treeNodePtr.p->m_tableOrIndexId >= c_tabrecFilesize)
+  {
+    jam();
+    ndbassert(c_tabrecFilesize > 0);
+    return DbspjErr::NoSuchTable;
+  }
+  
+  TableRecordPtr tablePtr;
+  tablePtr.i = treeNodePtr.p->m_tableOrIndexId;
+  ptrAss(tablePtr, m_tableRecord);
+  Uint32 err = tablePtr.p->checkTableError(treeNodePtr.p->m_schemaVersion);
+  if (unlikely(err))
+  {
+    DEBUG_DICT("Dbsp::checkTableError"
+              << ", m_node_no: " << treeNodePtr.p->m_node_no
+              << ", tableOrIndexId: " << treeNodePtr.p->m_tableOrIndexId
+              << ", error: " << err);
+  }
+  if (ERROR_INSERTED_CLEAR(17520) ||
+      ERROR_INSERTED(17521) && (rand() % 7) == 0)
+  {
+    jam();
+    ndbout_c("::checkTableError, injecting NoSuchTable error at line %d file %s",
+              __LINE__,  __FILE__);
+    return DbspjErr::NoSuchTable;
+  }
+  return err;
+}
+
 /**
  * END - MODULE GENERIC
  */
@@ -2887,6 +3229,9 @@ Dbspj::lookup_build(Build_context& ctx,
       break;
     }
 
+    treeNodePtr.p->m_tableOrIndexId = node->tableId;
+    treeNodePtr.p->m_primaryTableId = node->tableId;
+    treeNodePtr.p->m_schemaVersion = node->tableVersion;
     treeNodePtr.p->m_info = &g_LookupOpInfo;
     Uint32 transId1 = requestPtr.p->m_transId[0];
     Uint32 transId2 = requestPtr.p->m_transId[1];
@@ -3060,6 +3405,11 @@ Dbspj::lookup_send(Signal* signal,
                    Ptr<TreeNode> treeNodePtr)
 {
   jam();
+  if (!ERROR_INSERTED(17521)) // Avoid emulated rnd errors
+  {
+    // ::checkTableError() should be handled before we reach this far
+    ndbassert(checkTableError(treeNodePtr) == 0);
+  }
 
   Uint32 cnt = 2;
   if (treeNodePtr.p->isLeaf())
@@ -3512,6 +3862,8 @@ Dbspj::lookup_parent_row(Signal* signal,
                          Ptr<TreeNode> treeNodePtr,
                          const RowPtr & rowRef)
 {
+  jam();
+
   /**
    * Here we need to...
    *   1) construct a key
@@ -3519,8 +3871,7 @@ Dbspj::lookup_parent_row(Signal* signal,
    *   3) get node for row (normally TC)
    */
   Uint32 err = 0;
-  const LqhKeyReq* src = (LqhKeyReq*)treeNodePtr.p->m_lookup_data.m_lqhKeyReq;
-  const Uint32 tableId = LqhKeyReq::getTableId(src->tableSchemaVersion);
+  const Uint32 tableId = treeNodePtr.p->m_tableOrIndexId;
   const Uint32 corrVal = rowRef.m_src_correlation;
 
   DEBUG("::lookup_parent_row"
@@ -3528,6 +3879,13 @@ Dbspj::lookup_parent_row(Signal* signal,
 
   do
   {
+    err = checkTableError(treeNodePtr);
+    if (unlikely(err != 0))
+    {
+      jam();
+      break;
+    }
+
     /**
      * Test execution terminated due to 'OutOfQueryMemory' which
      * may happen multiple places below:
@@ -4099,6 +4457,9 @@ Dbspj::scanFrag_build(Build_context& ctx
     }
 
     treeNodePtr.p->m_info = &g_ScanFragOpInfo;
+    treeNodePtr.p->m_tableOrIndexId = node->tableId;
+    treeNodePtr.p->m_primaryTableId = node->tableId;
+    treeNodePtr.p->m_schemaVersion = node->tableVersion;
     treeNodePtr.p->m_scanfrag_data.m_scanFragHandlePtrI = RNIL;
     Ptr<ScanFragHandle> scanFragHandlePtr;
     if (ERROR_INSERTED_CLEAR(17004))
@@ -4277,6 +4638,11 @@ Dbspj::scanFrag_send(Signal* signal,
                      Ptr<TreeNode> treeNodePtr)
 {
   jam();
+  if (!ERROR_INSERTED(17521)) // Avoid emulated rnd errors
+  {
+    // ::checkTableError() should be handled before we reach this far
+    ndbassert(checkTableError(treeNodePtr) == 0);
+  }
 
   Ptr<ScanFragHandle> scanFragHandlePtr;
   m_scanfraghandle_pool.getPtr(scanFragHandlePtr, treeNodePtr.p->
@@ -4504,7 +4870,14 @@ Dbspj::scanFrag_execSCAN_NEXTREQ(Signal*
                                  Ptr<Request> requestPtr,
                                  Ptr<TreeNode> treeNodePtr)
 {
-  jamEntry();
+  jam();
+  Uint32 err = checkTableError(treeNodePtr);
+  if (unlikely(err))
+  {
+    jam();
+    abort(signal, requestPtr, err);
+    return;
+  }
 
   Ptr<ScanFragHandle> scanFragHandlePtr;
   m_scanfraghandle_pool.getPtr(scanFragHandlePtr, treeNodePtr.p->
@@ -4548,12 +4921,12 @@ Dbspj::scanFrag_abort(Signal* signal,
 {
   jam();
 
-  Ptr<ScanFragHandle> scanFragHandlePtr;
-  m_scanfraghandle_pool.getPtr(scanFragHandlePtr, treeNodePtr.p->
-                               m_scanfrag_data.m_scanFragHandlePtrI);
   if (treeNodePtr.p->m_state == TreeNode::TN_ACTIVE)
   {
     jam();
+    Ptr<ScanFragHandle> scanFragHandlePtr;
+    m_scanfraghandle_pool.getPtr(scanFragHandlePtr, treeNodePtr.p->
+                                 m_scanfrag_data.m_scanFragHandlePtrI);
 
     switch(scanFragHandlePtr.p->m_state){
     case ScanFragHandle::SFH_NOT_STARTED:
@@ -4679,7 +5052,14 @@ Dbspj::scanIndex_build(Build_context& ct
     requestPtr.p->m_bits |= Request::RT_SCAN;
     requestPtr.p->m_bits |= Request::RT_NEED_PREPARE;
     requestPtr.p->m_bits |= Request::RT_NEED_COMPLETE;
+
+    Uint32 indexId = node->tableId;
+    Uint32 tableId = g_key_descriptor_pool.getPtr(indexId)->primaryTableId;
+
     treeNodePtr.p->m_info = &g_ScanIndexOpInfo;
+    treeNodePtr.p->m_tableOrIndexId = indexId;
+    treeNodePtr.p->m_primaryTableId = tableId;
+    treeNodePtr.p->m_schemaVersion = node->tableVersion;
     treeNodePtr.p->m_bits |= TreeNode::T_ATTR_INTERPRETED;
     treeNodePtr.p->m_bits |= TreeNode::T_NEED_REPORT_BATCH_COMPLETED;
     treeNodePtr.p->m_batch_size = 
@@ -4901,13 +5281,17 @@ Dbspj::scanIndex_prepare(Signal * signal
 {
   jam();
 
+  if (!ERROR_INSERTED(17521)) // Avoid emulated rnd errors
+  {
+    // ::checkTableError() should be handled before we reach this far
+    ndbassert(checkTableError(treeNodePtr) == 0); //Handled in Dbspj::start
+  }
   treeNodePtr.p->m_state = TreeNode::TN_PREPARING;
-  ScanFragReq*dst=(ScanFragReq*)treeNodePtr.p->m_scanindex_data.m_scanFragReq;
 
   DihScanTabReq * req = (DihScanTabReq*)signal->getDataPtrSend();
   req->senderRef = reference();
   req->senderData = treeNodePtr.i;
-  req->tableId = dst->tableId;
+  req->tableId = treeNodePtr.p->m_tableOrIndexId;
   req->schemaTransId = 0;
   sendSignal(DBDIH_REF, GSN_DIH_SCAN_TAB_REQ, signal,
              DihScanTabReq::SignalLength, JBB);
@@ -4936,11 +5320,11 @@ Dbspj::execDIH_SCAN_TAB_CONF(Signal* sig
 
   Uint32 cookie = conf->scanCookie;
   Uint32 fragCount = conf->fragmentCount;
-  ScanFragReq * dst = (ScanFragReq*)data.m_scanFragReq;
 
   if (conf->reorgFlag)
   {
     jam();
+    ScanFragReq * dst = (ScanFragReq*)data.m_scanFragReq;
     ScanFragReq::setReorgFlag(dst->requestInfo, 1);
   }
   if (treeNodePtr.p->m_bits & TreeNode::T_CONST_PRUNE)
@@ -4971,6 +5355,12 @@ Dbspj::execDIH_SCAN_TAB_CONF(Signal* sig
     {
       Local_ScanFragHandle_list list(m_scanfraghandle_pool, data.m_fragments);
 
+      err = checkTableError(treeNodePtr);
+      if (unlikely(err != 0))
+      {
+        jam();
+        break;
+      }
       for (Uint32 i = 0; i<fragCount; i++)
       {
         jam();
@@ -5004,8 +5394,7 @@ Dbspj::execDIH_SCAN_TAB_CONF(Signal* sig
       // but only parts in distribution key
 
       BuildKeyReq tmp;
-      Uint32 indexId = dst->tableId;
-      Uint32 tableId = g_key_descriptor_pool.getPtr(indexId)->primaryTableId;
+      Uint32 tableId = treeNodePtr.p->m_primaryTableId;
       err = computePartitionHash(signal, tmp, tableId, data.m_constPrunePtrI);
       if (unlikely(err != 0))
       {
@@ -5123,7 +5512,7 @@ Dbspj::scanindex_sendDihGetNodesReq(Sign
   if (fragCnt > 0)
   {
     jam();
-    Uint32 tableId = ((ScanFragReq*)data.m_scanFragReq)->tableId;
+    Uint32 tableId = treeNodePtr.p->m_tableOrIndexId;
     req->senderRef = reference();
     req->tableId = tableId;
     req->scanCookie = data.m_scanCookie;
@@ -5326,6 +5715,14 @@ Dbspj::scanIndex_parent_row(Signal* sign
     Ptr<ScanFragHandle> fragPtr;
     Local_ScanFragHandle_list list(m_scanfraghandle_pool, data.m_fragments);
     LocalArenaPoolImpl pool(requestPtr.p->m_arena, m_dependency_map_pool);
+
+    err = checkTableError(treeNodePtr);
+    if (unlikely(err != 0))
+    {
+      jam();
+      break;
+    }
+
     if (treeNodePtr.p->m_bits & TreeNode::T_PRUNE_PATTERN)
     {
       jam();
@@ -5357,9 +5754,7 @@ Dbspj::scanIndex_parent_row(Signal* sign
       }
 
       BuildKeyReq tmp;
-      ScanFragReq * dst = (ScanFragReq*)data.m_scanFragReq;
-      Uint32 indexId = dst->tableId;
-      Uint32 tableId = g_key_descriptor_pool.getPtr(indexId)->primaryTableId;
+      Uint32 tableId = treeNodePtr.p->m_primaryTableId;
       err = computePartitionHash(signal, tmp, tableId, pruneKeyPtrI);
       releaseSection(pruneKeyPtrI);
       if (unlikely(err != 0))
@@ -5757,8 +6152,9 @@ Dbspj::scanIndex_send(Signal* signal,
   req->batch_size_bytes = bs_bytes;
   req->batch_size_rows = bs_rows;
 
-  Uint32 err = 0;
   Uint32 requestsSent = 0;
+  Uint32 err = checkTableError(treeNodePtr);
+  if (likely(err == 0))
   {
     Local_ScanFragHandle_list list(m_scanfraghandle_pool, data.m_fragments);
     Ptr<ScanFragHandle> fragPtr;
@@ -6244,6 +6640,13 @@ Dbspj::scanIndex_execSCAN_NEXTREQ(Signal
                                   Ptr<TreeNode> treeNodePtr)
 {
   jam();
+  Uint32 err = checkTableError(treeNodePtr);
+  if (unlikely(err))
+  {
+    jam();
+    abort(signal, requestPtr, err);
+    return;
+  }
 
   ScanIndexData& data = treeNodePtr.p->m_scanindex_data;
   const ScanFragReq * org = (const ScanFragReq*)data.m_scanFragReq;
@@ -6414,12 +6817,11 @@ Dbspj::scanIndex_complete(Signal* signal
 {
   jam();
   ScanIndexData& data = treeNodePtr.p->m_scanindex_data;
-  ScanFragReq*dst=(ScanFragReq*)treeNodePtr.p->m_scanindex_data.m_scanFragReq;
   if (!data.m_fragments.isEmpty())
   {
     jam();
     DihScanTabCompleteRep* rep=(DihScanTabCompleteRep*)signal->getDataPtrSend();
-    rep->tableId = dst->tableId;
+    rep->tableId = treeNodePtr.p->m_tableOrIndexId;
     rep->scanCookie = data.m_scanCookie;
     sendSignal(DBDIH_REF, GSN_DIH_SCAN_TAB_COMPLETE_REP,
                signal, DihScanTabCompleteRep::SignalLength, JBB);

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.cpp	2011-02-23 19:28:26 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.cpp	2012-09-19 06:37:24 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+  Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -12,16 +12,15 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #include "DbspjProxy.hpp"
 #include "Dbspj.hpp"
 
 DbspjProxy::DbspjProxy(Block_context& ctx) :
-  LocalProxy(DBSPJ, ctx)
-{
-}
+  DbgdmProxy(DBSPJ, ctx)
+{}
 
 DbspjProxy::~DbspjProxy()
 {

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp	2012-08-24 11:53:18 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp	2012-09-19 07:09:57 +0000
@@ -11,14 +11,15 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
 
 #ifndef NDB_DBSPJ_PROXY_HPP
 #define NDB_DBSPJ_PROXY_HPP
 
-#include <LocalProxy.hpp>
+#include "../dbgdm/DbgdmProxy.hpp"
 
-class DbspjProxy : public LocalProxy {
+class DbspjProxy : public DbgdmProxy {
 public:
   DbspjProxy(Block_context& ctx);
   virtual ~DbspjProxy();

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.cpp	2011-09-15 20:21:59 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.cpp	2012-09-19 06:37:24 +0000
@@ -19,17 +19,8 @@
 #include "Dbtc.hpp"
 
 DbtcProxy::DbtcProxy(Block_context& ctx) :
-  LocalProxy(DBTC, ctx)
+  DbgdmProxy(DBTC, ctx)
 {
-  // GSN_TC_SCHVERREQ
-  addRecSignal(GSN_TC_SCHVERREQ, &DbtcProxy::execTC_SCHVERREQ);
-  addRecSignal(GSN_TC_SCHVERCONF, &DbtcProxy::execTC_SCHVERCONF);
-
-  // GSN_TAB_COMMITREQ
-  addRecSignal(GSN_TAB_COMMITREQ, &DbtcProxy::execTAB_COMMITREQ);
-  addRecSignal(GSN_TAB_COMMITCONF, &DbtcProxy::execTAB_COMMITCONF);
-  addRecSignal(GSN_TAB_COMMITREF, &DbtcProxy::execTAB_COMMITREF);
-
   // GSN_TCSEIZEREQ
   addRecSignal(GSN_TCSEIZEREQ, &DbtcProxy::execTCSEIZEREQ);
 
@@ -45,21 +36,6 @@ DbtcProxy::DbtcProxy(Block_context& ctx)
   addRecSignal(GSN_GCP_NOMORETRANS, &DbtcProxy::execGCP_NOMORETRANS);
   addRecSignal(GSN_GCP_TCFINISHED, &DbtcProxy::execGCP_TCFINISHED);
 
-  // GSN_PREP_DROP_TAB_REQ
-  addRecSignal(GSN_PREP_DROP_TAB_REQ, &DbtcProxy::execPREP_DROP_TAB_REQ);
-  addRecSignal(GSN_PREP_DROP_TAB_CONF, &DbtcProxy::execPREP_DROP_TAB_CONF);
-  addRecSignal(GSN_PREP_DROP_TAB_REF, &DbtcProxy::execPREP_DROP_TAB_REF);
-
-  // GSN_DROP_TAB_REQ
-  addRecSignal(GSN_DROP_TAB_REQ, &DbtcProxy::execDROP_TAB_REQ);
-  addRecSignal(GSN_DROP_TAB_CONF, &DbtcProxy::execDROP_TAB_CONF);
-  addRecSignal(GSN_DROP_TAB_REF, &DbtcProxy::execDROP_TAB_REF);
-
-  // GSN_ALTER_TAB_REQ
-  addRecSignal(GSN_ALTER_TAB_REQ, &DbtcProxy::execALTER_TAB_REQ);
-  addRecSignal(GSN_ALTER_TAB_CONF, &DbtcProxy::execALTER_TAB_CONF);
-  addRecSignal(GSN_ALTER_TAB_REF, &DbtcProxy::execALTER_TAB_REF);
-
   // GSN_CREATE_INDX_IMPL_REQ
   addRecSignal(GSN_CREATE_INDX_IMPL_REQ, &DbtcProxy::execCREATE_INDX_IMPL_REQ);
   addRecSignal(GSN_CREATE_INDX_IMPL_CONF,&DbtcProxy::execCREATE_INDX_IMPL_CONF);
@@ -116,367 +92,6 @@ DbtcProxy::callNDB_STTOR(Signal* signal)
   }
 }
 
-// GSN_TC_SCHVERREQ
-
-void
-DbtcProxy::execTC_SCHVERREQ(Signal* signal)
-{
-  Ss_TC_SCHVERREQ& ss = ssSeize<Ss_TC_SCHVERREQ>(1);
-
-  const TcSchVerReq* req = (const TcSchVerReq*)signal->getDataPtr();
-  ss.m_req = *req;
-
-  sendREQ(signal, ss);
-}
-
-void
-DbtcProxy::sendTC_SCHVERREQ(Signal* signal, Uint32 ssId, SectionHandle*)
-{
-  Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
-
-  TcSchVerReq* req = (TcSchVerReq*)signal->getDataPtrSend();
-  *req = ss.m_req;
-  req->senderRef = reference();
-  req->senderData = ssId;
-  sendSignal(workerRef(ss.m_worker), GSN_TC_SCHVERREQ,
-             signal, TcSchVerReq::SignalLength, JBB);
-}
-
-void
-DbtcProxy::execTC_SCHVERCONF(Signal* signal)
-{
-  const TcSchVerConf* conf = (const TcSchVerConf*)signal->getDataPtr();
-  Uint32 ssId = conf->senderData;
-  Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbtcProxy::sendTC_SCHVERCONF(Signal* signal, Uint32 ssId)
-{
-  Ss_TC_SCHVERREQ& ss = ssFind<Ss_TC_SCHVERREQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  TcSchVerConf* conf = (TcSchVerConf*)signal->getDataPtrSend();
-  conf->senderRef = reference();
-  conf->senderData = ss.m_req.senderData;
-  sendSignal(dictRef, GSN_TC_SCHVERCONF,
-             signal, TcSchVerConf::SignalLength, JBB);
-
-  ssRelease<Ss_TC_SCHVERREQ>(ssId);
-}
-
-// GSN_TAB_COMMITREQ [ sub-op ]
-
-void
-DbtcProxy::execTAB_COMMITREQ(Signal* signal)
-{
-  Ss_TAB_COMMITREQ& ss = ssSeize<Ss_TAB_COMMITREQ>(1); // lost connection
-
-  const TabCommitReq* req = (const TabCommitReq*)signal->getDataPtr();
-  ss.m_req = *req;
-  sendREQ(signal, ss);
-}
-
-void
-DbtcProxy::sendTAB_COMMITREQ(Signal* signal, Uint32 ssId, SectionHandle*)
-{
-  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
-
-  TabCommitReq* req = (TabCommitReq*)signal->getDataPtrSend();
-  req->senderRef = reference();
-  req->senderData = ssId;
-  req->tableId = ss.m_req.tableId;
-  sendSignal(workerRef(ss.m_worker), GSN_TAB_COMMITREQ,
-             signal, TabCommitReq::SignalLength, JBB);
-}
-
-void
-DbtcProxy::execTAB_COMMITCONF(Signal* signal)
-{
-  const TabCommitConf* conf = (TabCommitConf*)signal->getDataPtr();
-  Uint32 ssId = conf->senderData;
-  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbtcProxy::execTAB_COMMITREF(Signal* signal)
-{
-  const TabCommitRef* ref = (TabCommitRef*)signal->getDataPtr();
-  Uint32 ssId = ref->senderData;
-  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
-
-  recvREF(signal, ss, ref->errorCode);
-}
-
-void
-DbtcProxy::sendTAB_COMMITCONF(Signal* signal, Uint32 ssId)
-{
-  Ss_TAB_COMMITREQ& ss = ssFind<Ss_TAB_COMMITREQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  if (ss.m_error == 0) {
-    jam();
-    TabCommitConf* conf = (TabCommitConf*)signal->getDataPtrSend();
-    conf->senderData = ss.m_req.senderData;
-    conf->nodeId = getOwnNodeId();
-    conf->tableId = ss.m_req.tableId;
-    sendSignal(dictRef, GSN_TAB_COMMITCONF,
-               signal, TabCommitConf::SignalLength, JBB);
-  } else {
-    jam();
-    TabCommitRef* ref = (TabCommitRef*)signal->getDataPtrSend();
-    ref->senderData = ss.m_req.senderData;
-    ref->nodeId = getOwnNodeId();
-    ref->tableId = ss.m_req.tableId;
-    sendSignal(dictRef, GSN_TAB_COMMITREF,
-               signal, TabCommitRef::SignalLength, JBB);
-    return;
-  }
-
-  ssRelease<Ss_TAB_COMMITREQ>(ssId);
-}
-
-// GSN_PREP_DROP_TAB_REQ
-
-void
-DbtcProxy::execPREP_DROP_TAB_REQ(Signal* signal)
-{
-  const PrepDropTabReq* req = (const PrepDropTabReq*)signal->getDataPtr();
-  Uint32 ssId = getSsId(req);
-  Ss_PREP_DROP_TAB_REQ& ss = ssSeize<Ss_PREP_DROP_TAB_REQ>(ssId);
-  ss.m_req = *req;
-  ndbrequire(signal->getLength() == PrepDropTabReq::SignalLength);
-  sendREQ(signal, ss);
-}
-
-void
-DbtcProxy::sendPREP_DROP_TAB_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
-{
-  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
-
-  PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtrSend();
-  *req = ss.m_req;
-  req->senderRef = reference();
-  req->senderData = ssId; // redundant since tableId is used
-  sendSignal(workerRef(ss.m_worker), GSN_PREP_DROP_TAB_REQ,
-             signal, PrepDropTabReq::SignalLength, JBB);
-}
-
-void
-DbtcProxy::execPREP_DROP_TAB_CONF(Signal* signal)
-{
-  const PrepDropTabConf* conf = (const PrepDropTabConf*)signal->getDataPtr();
-  Uint32 ssId = getSsId(conf);
-  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbtcProxy::execPREP_DROP_TAB_REF(Signal* signal)
-{
-  const PrepDropTabRef* ref = (const PrepDropTabRef*)signal->getDataPtr();
-  Uint32 ssId = getSsId(ref);
-  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
-  recvREF(signal, ss, ref->errorCode);
-}
-
-void
-DbtcProxy::sendPREP_DROP_TAB_CONF(Signal* signal, Uint32 ssId)
-{
-  Ss_PREP_DROP_TAB_REQ& ss = ssFind<Ss_PREP_DROP_TAB_REQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  if (ss.m_error == 0) {
-    jam();
-    PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
-    conf->senderRef = reference();
-    conf->senderData = ss.m_req.senderData;
-    conf->tableId = ss.m_req.tableId;
-    sendSignal(dictRef, GSN_PREP_DROP_TAB_CONF,
-               signal, PrepDropTabConf::SignalLength, JBB);
-  } else {
-    jam();
-    PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
-    ref->senderRef = reference();
-    ref->senderData = ss.m_req.senderData;
-    ref->tableId = ss.m_req.tableId;
-    ref->errorCode = ss.m_error;
-    sendSignal(dictRef, GSN_PREP_DROP_TAB_REF,
-               signal, PrepDropTabRef::SignalLength, JBB);
-  }
-
-  ssRelease<Ss_PREP_DROP_TAB_REQ>(ssId);
-}
-
-// GSN_DROP_TAB_REQ
-
-void
-DbtcProxy::execDROP_TAB_REQ(Signal* signal)
-{
-  const DropTabReq* req = (const DropTabReq*)signal->getDataPtr();
-  Uint32 ssId = getSsId(req);
-  Ss_DROP_TAB_REQ& ss = ssSeize<Ss_DROP_TAB_REQ>(ssId);
-  ss.m_req = *req;
-  ndbrequire(signal->getLength() == DropTabReq::SignalLength);
-  sendREQ(signal, ss);
-}
-
-void
-DbtcProxy::sendDROP_TAB_REQ(Signal* signal, Uint32 ssId, SectionHandle*)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-
-  DropTabReq* req = (DropTabReq*)signal->getDataPtrSend();
-  *req = ss.m_req;
-  req->senderRef = reference();
-  req->senderData = ssId; // redundant since tableId is used
-  sendSignal(workerRef(ss.m_worker), GSN_DROP_TAB_REQ,
-             signal, DropTabReq::SignalLength, JBB);
-}
-
-void
-DbtcProxy::execDROP_TAB_CONF(Signal* signal)
-{
-  const DropTabConf* conf = (const DropTabConf*)signal->getDataPtr();
-  Uint32 ssId = getSsId(conf);
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbtcProxy::execDROP_TAB_REF(Signal* signal)
-{
-  const DropTabRef* ref = (const DropTabRef*)signal->getDataPtr();
-  Uint32 ssId = getSsId(ref);
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  recvREF(signal, ss, ref->errorCode);
-}
-
-void
-DbtcProxy::sendDROP_TAB_CONF(Signal* signal, Uint32 ssId)
-{
-  Ss_DROP_TAB_REQ& ss = ssFind<Ss_DROP_TAB_REQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  if (ss.m_error == 0) {
-    jam();
-    DropTabConf* conf = (DropTabConf*)signal->getDataPtrSend();
-    conf->senderRef = reference();
-    conf->senderData = ss.m_req.senderData;
-    conf->tableId = ss.m_req.tableId;
-    sendSignal(dictRef, GSN_DROP_TAB_CONF,
-               signal, DropTabConf::SignalLength, JBB);
-  } else {
-    jam();
-    DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
-    ref->senderRef = reference();
-    ref->senderData = ss.m_req.senderData;
-    ref->tableId = ss.m_req.tableId;
-    ref->errorCode = ss.m_error;
-    sendSignal(dictRef, GSN_DROP_TAB_REF,
-               signal, DropTabConf::SignalLength, JBB);
-  }
-
-  ssRelease<Ss_DROP_TAB_REQ>(ssId);
-}
-
-// GSN_ALTER_TAB_REQ
-
-void
-DbtcProxy::execALTER_TAB_REQ(Signal* signal)
-{
-  if (!assembleFragments(signal))
-  {
-    jam();
-    return;
-  }
-
-  const AlterTabReq* req = (const AlterTabReq*)signal->getDataPtr();
-  Uint32 ssId = getSsId(req);
-  Ss_ALTER_TAB_REQ& ss = ssSeize<Ss_ALTER_TAB_REQ>(ssId);
-  ss.m_req = *req;
-
-  SectionHandle handle(this, signal);
-  saveSections(ss, handle);
-
-  sendREQ(signal, ss);
-}
-
-void
-DbtcProxy::sendALTER_TAB_REQ(Signal* signal, Uint32 ssId,
-                             SectionHandle* handle)
-{
-  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
-
-  AlterTabReq* req = (AlterTabReq*)signal->getDataPtrSend();
-  *req = ss.m_req;
-  req->senderRef = reference();
-  req->senderData = ssId;
-  sendSignalNoRelease(workerRef(ss.m_worker), GSN_ALTER_TAB_REQ,
-                      signal, AlterTabReq::SignalLength, JBB, handle);
-}
-
-void
-DbtcProxy::execALTER_TAB_CONF(Signal* signal)
-{
-  const AlterTabConf* conf = (const AlterTabConf*)signal->getDataPtr();
-  Uint32 ssId = getSsId(conf);
-  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
-  recvCONF(signal, ss);
-}
-
-void
-DbtcProxy::execALTER_TAB_REF(Signal* signal)
-{
-  const AlterTabRef* ref = (const AlterTabRef*)signal->getDataPtr();
-  Uint32 ssId = getSsId(ref);
-  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
-  recvREF(signal, ss, ref->errorCode);
-}
-
-void
-DbtcProxy::sendALTER_TAB_CONF(Signal* signal, Uint32 ssId)
-{
-  Ss_ALTER_TAB_REQ& ss = ssFind<Ss_ALTER_TAB_REQ>(ssId);
-  BlockReference dictRef = ss.m_req.senderRef;
-
-  if (!lastReply(ss))
-    return;
-
-  if (ss.m_error == 0) {
-    jam();
-    AlterTabConf* conf = (AlterTabConf*)signal->getDataPtrSend();
-    conf->senderRef = reference();
-    conf->senderData = ss.m_req.senderData;
-    sendSignal(dictRef, GSN_ALTER_TAB_CONF,
-               signal, AlterTabConf::SignalLength, JBB);
-  } else {
-    jam();
-    AlterTabRef* ref = (AlterTabRef*)signal->getDataPtrSend();
-    ref->senderRef = reference();
-    ref->senderData = ss.m_req.senderData;
-    ref->errorCode = ss.m_error;
-    sendSignal(dictRef, GSN_ALTER_TAB_REF,
-               signal, AlterTabConf::SignalLength, JBB);
-  }
-
-  ssRelease<Ss_ALTER_TAB_REQ>(ssId);
-}
-
 void
 DbtcProxy::execTCSEIZEREQ(Signal* signal)
 {

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp	2011-10-07 08:07:21 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp	2012-09-19 06:37:24 +0000
@@ -18,12 +18,8 @@
 #ifndef NDB_DBTC_PROXY_HPP
 #define NDB_DBTC_PROXY_HPP
 
-#include <LocalProxy.hpp>
-#include <signaldata/CreateTab.hpp>
-#include <signaldata/TabCommit.hpp>
-#include <signaldata/PrepDropTab.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/AlterTab.hpp>
+#include "../dbgdm/DbgdmProxy.hpp"
+
 #include <signaldata/GCP.hpp>
 
 #include <signaldata/CreateIndxImpl.hpp>
@@ -31,7 +27,8 @@
 #include <signaldata/DropIndxImpl.hpp>
 #include <signaldata/AbortAll.hpp>
 
-class DbtcProxy : public LocalProxy {
+
+class DbtcProxy : public DbgdmProxy {
 public:
   DbtcProxy(Block_context& ctx);
   virtual ~DbtcProxy();
@@ -43,128 +40,6 @@ protected:
   // GSN_NDB_STTOR
   virtual void callNDB_STTOR(Signal*);
 
-  // GSN_TC_SCHVERREQ
-  struct Ss_TC_SCHVERREQ : SsParallel {
-    TcSchVerReq m_req;
-    Ss_TC_SCHVERREQ() {
-      m_sendREQ = (SsFUNCREQ)&DbtcProxy::sendTC_SCHVERREQ;
-      m_sendCONF = (SsFUNCREP)&DbtcProxy::sendTC_SCHVERCONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_TC_SCHVERREQ>& pool(LocalProxy* proxy) {
-      return ((DbtcProxy*)proxy)->c_ss_TC_SCHVERREQ;
-    }
-  };
-  SsPool<Ss_TC_SCHVERREQ> c_ss_TC_SCHVERREQ;
-  void execTC_SCHVERREQ(Signal*);
-  void sendTC_SCHVERREQ(Signal*, Uint32 ssId, SectionHandle*);
-  void execTC_SCHVERCONF(Signal*);
-  void sendTC_SCHVERCONF(Signal*, Uint32 ssId);
-
-  // GSN_TAB_COMMITREQ [ sub-op ]
-  struct Ss_TAB_COMMITREQ : SsParallel {
-    TabCommitReq m_req;
-    Ss_TAB_COMMITREQ() {
-      m_sendREQ = (SsFUNCREQ)&DbtcProxy::sendTAB_COMMITREQ;
-      m_sendCONF = (SsFUNCREP)&DbtcProxy::sendTAB_COMMITCONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_TAB_COMMITREQ>& pool(LocalProxy* proxy) {
-      return ((DbtcProxy*)proxy)->c_ss_TAB_COMMITREQ;
-    }
-  };
-  SsPool<Ss_TAB_COMMITREQ> c_ss_TAB_COMMITREQ;
-  void execTAB_COMMITREQ(Signal*);
-  void sendTAB_COMMITREQ(Signal*, Uint32 ssId, SectionHandle*);
-  void execTAB_COMMITCONF(Signal*);
-  void execTAB_COMMITREF(Signal*);
-  void sendTAB_COMMITCONF(Signal*, Uint32 ssId);
-
-  // GSN_PREP_DROP_TAB_REQ
-  struct Ss_PREP_DROP_TAB_REQ : SsParallel {
-    PrepDropTabReq m_req;
-    Ss_PREP_DROP_TAB_REQ() {
-      m_sendREQ = (SsFUNCREQ)&DbtcProxy::sendPREP_DROP_TAB_REQ;
-      m_sendCONF = (SsFUNCREP)&DbtcProxy::sendPREP_DROP_TAB_CONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_PREP_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
-      return ((DbtcProxy*)proxy)->c_ss_PREP_DROP_TAB_REQ;
-    }
-  };
-
-  SsPool<Ss_PREP_DROP_TAB_REQ> c_ss_PREP_DROP_TAB_REQ;
-  Uint32 getSsId(const PrepDropTabReq* req) {
-    return SsIdBase | req->tableId;
-  }
-  Uint32 getSsId(const PrepDropTabConf* conf) {
-    return SsIdBase | conf->tableId;
-  }
-  Uint32 getSsId(const PrepDropTabRef* ref) {
-    return SsIdBase | ref->tableId;
-  }
-  void execPREP_DROP_TAB_REQ(Signal*);
-  void sendPREP_DROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
-  void execPREP_DROP_TAB_CONF(Signal*);
-  void execPREP_DROP_TAB_REF(Signal*);
-  void sendPREP_DROP_TAB_CONF(Signal*, Uint32 ssId);
-
-  // GSN_DROP_TAB_REQ
-  struct Ss_DROP_TAB_REQ : SsParallel {
-    DropTabReq m_req;
-    Ss_DROP_TAB_REQ() {
-      m_sendREQ = (SsFUNCREQ)&DbtcProxy::sendDROP_TAB_REQ;
-      m_sendCONF = (SsFUNCREP)&DbtcProxy::sendDROP_TAB_CONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
-      return ((DbtcProxy*)proxy)->c_ss_DROP_TAB_REQ;
-    }
-  };
-  SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ;
-  Uint32 getSsId(const DropTabReq* req) {
-    return SsIdBase | req->tableId;
-  }
-  Uint32 getSsId(const DropTabConf* conf) {
-    return SsIdBase | conf->tableId;
-  }
-  Uint32 getSsId(const DropTabRef* ref) {
-    return SsIdBase | ref->tableId;
-  }
-  void execDROP_TAB_REQ(Signal*);
-  void sendDROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
-  void execDROP_TAB_CONF(Signal*);
-  void execDROP_TAB_REF(Signal*);
-  void sendDROP_TAB_CONF(Signal*, Uint32 ssId);
-
-  // GSN_ALTER_TAB_REQ
-  struct Ss_ALTER_TAB_REQ : SsParallel {
-    AlterTabReq m_req;
-    Ss_ALTER_TAB_REQ() {
-      m_sendREQ = (SsFUNCREQ)&DbtcProxy::sendALTER_TAB_REQ;
-      m_sendCONF = (SsFUNCREP)&DbtcProxy::sendALTER_TAB_CONF;
-    }
-    enum { poolSize = 1 };
-    static SsPool<Ss_ALTER_TAB_REQ>& pool(LocalProxy* proxy) {
-      return ((DbtcProxy*)proxy)->c_ss_ALTER_TAB_REQ;
-    }
-  };
-  SsPool<Ss_ALTER_TAB_REQ> c_ss_ALTER_TAB_REQ;
-  Uint32 getSsId(const AlterTabReq* req) {
-    return SsIdBase | req->tableId;
-  }
-  Uint32 getSsId(const AlterTabConf* conf) {
-    return conf->senderData;
-  }
-  Uint32 getSsId(const AlterTabRef* ref) {
-    return ref->senderData;
-  }
-  void execALTER_TAB_REQ(Signal*);
-  void sendALTER_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
-  void execALTER_TAB_CONF(Signal*);
-  void execALTER_TAB_REF(Signal*);
-  void sendALTER_TAB_CONF(Signal*, Uint32 ssId);
-
   /**
    * TCSEIZEREQ
    */

=== modified file 'storage/ndb/src/kernel/vm/Configuration.cpp'
--- a/storage/ndb/src/kernel/vm/Configuration.cpp	2012-03-13 15:18:24 +0000
+++ b/storage/ndb/src/kernel/vm/Configuration.cpp	2012-09-19 07:09:57 +0000
@@ -909,6 +909,14 @@ Configuration::calcSizeAlt(ConfigValues 
   
   {
     /**
+     * Spj Size Alt values
+     */
+    cfg.put(CFG_SPJ_TABLE, 
+	    noOfMetaTables);
+  }
+  
+  {
+    /**
      * Tc Size Alt values
      */
     cfg.put(CFG_TC_API_CONNECT, 

=== modified file 'storage/ndb/src/kernel/vm/pc.hpp'
--- a/storage/ndb/src/kernel/vm/pc.hpp	2011-11-16 05:47:02 +0000
+++ b/storage/ndb/src/kernel/vm/pc.hpp	2012-09-19 07:09:57 +0000
@@ -127,7 +127,7 @@
 
 // -------- ERROR INSERT MACROS -------
 #ifdef ERROR_INSERT
-#define ERROR_INSERT_VARIABLE UintR cerrorInsert, c_error_insert_extra
+#define ERROR_INSERT_VARIABLE mutable UintR cerrorInsert, c_error_insert_extra
 #define ERROR_INSERTED(x) (cerrorInsert == (x))
 #define ERROR_INSERTED_CLEAR(x) (cerrorInsert == (x) ? (cerrorInsert = 0, true) : false)
 #define ERROR_INSERT_VALUE cerrorInsert

=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c	2012-09-18 14:36:25 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c	2012-09-19 07:09:57 +0000
@@ -165,7 +165,10 @@ ErrorBundle ErrorCodes[] = {
   { 20016, DMEC, NR, "Query aborted due to node failure" },
   { 20017, DMEC, IE, "Query aborted due to invalid node count" },
   { 20018, DMEC, IE, "Query aborted due to index fragment not found" },
-  
+  { 20019, HA_ERR_NO_SUCH_TABLE, SE, "Query table not defined" },
+  { 20020, HA_ERR_NO_SUCH_TABLE, SE, "Query table is being dropped" },
+  { 20021, HA_ERR_TABLE_DEF_CHANGED, SE, "Query table definition has changed" },
+
   /**
    * Node shutdown
    */

=== modified file 'storage/ndb/test/ndbapi/testSpj.cpp'
--- a/storage/ndb/test/ndbapi/testSpj.cpp	2012-09-13 08:36:35 +0000
+++ b/storage/ndb/test/ndbapi/testSpj.cpp	2012-09-19 07:09:57 +0000
@@ -32,7 +32,7 @@ static int faultToInject = 0;
 
 enum faultsToInject {
   FI_START = 17001,
-  FI_END = 17510
+  FI_END = 17521
 };
 
 int
@@ -131,7 +131,8 @@ runLookupJoinError(NDBT_Context* ctx, ND
       17120, 17121, // execTRANSID_AI -> OutOfRowMemory
       17130,        // sendSignal(DIH_SCAN_GET_NODES_REQ)  -> import() failed
       7234,         // sendSignal(DIH_SCAN_GET_NODES_CONF) -> import() failed (DIH)
-      17510 // random failure when allocating seection memory
+      17510,        // random failure when allocating section memory
+      17520, 17521  // failure (+random) from ::checkTableError()
   }; 
   loops =  faultToInject ? 1 : sizeof(lookupFaults)/sizeof(int);
 
@@ -226,7 +227,8 @@ runScanJoinError(NDBT_Context* ctx, NDBT
       17100, // scanFrag_sends invalid schema version, to get a SCAN_FRAGREF
       17110, 17111, 17112, // scanIndex_sends invalid schema version, to get a SCAN_FRAGREF
       17120, 17121, // execTRANSID_AI -> OutOfRowMemory
-      17510 // random failure when allocating seection memory
+      17510,        // random failure when allocating section memory
+      17520, 17521  // failure (+random) from TableRecord::checkTableError()
   }; 
   loops =  faultToInject ? 1 : sizeof(scanFaults)/sizeof(int);
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5-cluster-7.2 branch (ole.john.aske:3995 to 3996)Bug#14103195Ole John Aske19 Sep