MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Dbdict.hpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef DBDICT_H
19 #define DBDICT_H
20 
24 #include <ndb_limits.h>
25 #include <trigger_definitions.h>
26 #include <pc.hpp>
27 #include <DLHashTable.hpp>
28 #include <DLFifoList.hpp>
29 #include <CArray.hpp>
30 #include <KeyTable.hpp>
31 #include <KeyTable2.hpp>
32 #include <KeyTable2Ref.hpp>
33 #include <SimulatedBlock.hpp>
34 #include <SimpleProperties.hpp>
35 #include <SignalCounter.hpp>
36 #include <Bitmask.hpp>
37 #include <AttributeList.hpp>
38 #include <signaldata/GetTableId.hpp>
39 #include <signaldata/GetTabInfo.hpp>
40 #include <signaldata/DictTabInfo.hpp>
41 #include <signaldata/CreateTable.hpp>
42 #include <signaldata/CreateTab.hpp>
43 #include <signaldata/DropTable.hpp>
44 #include <signaldata/DropTab.hpp>
45 #include <signaldata/AlterTable.hpp>
46 #include <signaldata/AlterTab.hpp>
47 #include <signaldata/ListTables.hpp>
48 #include <signaldata/CreateIndx.hpp>
49 #include <signaldata/CreateIndxImpl.hpp>
50 #include <signaldata/DropIndx.hpp>
51 #include <signaldata/DropIndxImpl.hpp>
52 #include <signaldata/AlterIndx.hpp>
53 #include <signaldata/AlterIndxImpl.hpp>
54 #include <signaldata/BuildIndx.hpp>
55 #include <signaldata/BuildIndxImpl.hpp>
56 #include <signaldata/IndexStatSignal.hpp>
57 #include <signaldata/UtilPrepare.hpp>
58 #include <signaldata/CreateEvnt.hpp>
59 #include <signaldata/CreateTrig.hpp>
60 #include <signaldata/CreateTrigImpl.hpp>
61 #include <signaldata/DropTrig.hpp>
62 #include <signaldata/DropTrigImpl.hpp>
63 #include <signaldata/DictLock.hpp>
64 #include <signaldata/DictTakeover.hpp>
65 #include <signaldata/SumaImpl.hpp>
66 #include <signaldata/CreateHashMap.hpp>
67 #include <signaldata/HashMapImpl.hpp>
68 #include "SchemaFile.hpp"
69 #include <blocks/mutexes.hpp>
70 #include <SafeCounter.hpp>
71 #include <RequestTracker.hpp>
72 #include <Rope.hpp>
73 #include <signaldata/CreateFilegroupImpl.hpp>
74 #include <signaldata/DropFilegroupImpl.hpp>
75 #include <SLList.hpp>
76 #include <signaldata/DictSignal.hpp>
77 #include <signaldata/SchemaTransImpl.hpp>
78 #include <LockQueue.hpp>
79 #include <signaldata/CopyData.hpp>
80 #include <signaldata/NodeFailRep.hpp>
81 #include <signaldata/CreateNodegroup.hpp>
82 #include <signaldata/DropNodegroup.hpp>
83 #include <signaldata/CreateNodegroupImpl.hpp>
84 #include <signaldata/DropNodegroupImpl.hpp>
85 
86 
87 #ifdef DBDICT_C
88 
89 /*--------------------------------------------------------------*/
90 // Constants for CONTINUEB
91 /*--------------------------------------------------------------*/
92 #define ZPACK_TABLE_INTO_PAGES 0
93 #define ZSEND_GET_TAB_RESPONSE 3
94 #define ZWAIT_SUBSTARTSTOP 4
95 #define ZDICT_TAKEOVER_REQ 5
96 
97 #define ZCOMMIT_WAIT_GCI 6
98 #define ZINDEX_STAT_BG_PROCESS 7
99 
100 /*--------------------------------------------------------------*/
101 // Other constants in alphabetical order
102 /*--------------------------------------------------------------*/
103 #define ZNOMOREPHASES 255
104 
105 /*--------------------------------------------------------------*/
106 // Schema file defines
107 /*--------------------------------------------------------------*/
108 #define ZSCHEMA_WORDS 4
109 
110 /*--------------------------------------------------------------*/
111 // Page constants
112 /*--------------------------------------------------------------*/
113 #define ZBAT_SCHEMA_FILE 0 //Variable number of page for NDBFS
114 #define ZBAT_TABLE_FILE 1 //Variable number of page for NDBFS
115 #define ZPAGE_HEADER_SIZE 32
116 #define ZPOS_PAGE_SIZE 16
117 #define ZPOS_CHECKSUM 17
118 #define ZPOS_VERSION 18
119 #define ZPOS_PAGE_HEADER_SIZE 19
120 
121 /*--------------------------------------------------------------*/
122 // Size constants
123 /*--------------------------------------------------------------*/
124 #define ZFS_CONNECT_SIZE 4
125 #define ZSIZE_OF_PAGES_IN_WORDS 8192
126 #define ZLOG_SIZE_OF_PAGES_IN_WORDS 13
127 #define ZMAX_PAGES_OF_TABLE_DEFINITION \
128  ((ZPAGE_HEADER_SIZE + MAX_WORDS_META_FILE + ZSIZE_OF_PAGES_IN_WORDS - 1) / \
129  ZSIZE_OF_PAGES_IN_WORDS)
130 
135 #define ZNUMBER_OF_PAGES (2 * ZMAX_PAGES_OF_TABLE_DEFINITION)
136 
137 /*--------------------------------------------------------------*/
138 // Error codes
139 /*--------------------------------------------------------------*/
140 #define ZNODE_FAILURE_ERROR 704
141 #endif
142 
146 #define EVENT_SYSTEM_TABLE_LENGTH 9
147 #define EVENT_SYSTEM_TABLE_ATTRIBUTE_MASK2_ID 8
148 
150  char NAME[MAX_TAB_NAME_SIZE];
151  Uint32 EVENT_TYPE;
152  Uint32 TABLEID;
153  Uint32 TABLEVERSION;
154  char TABLE_NAME[MAX_TAB_NAME_SIZE];
155  Uint32 ATTRIBUTE_MASK[MAXNROFATTRIBUTESINWORDS_OLD];
156  Uint32 SUBID;
157  Uint32 SUBKEY;
158 
159  // +1 to allow var size header to be received
160  Uint32 ATTRIBUTE_MASK2[(MAX_ATTRIBUTES_IN_TABLE / 32) + 1];
161 };
162 
166 class Dbdict: public SimulatedBlock {
167 public:
168  /*
169  * 2.3 RECORD AND FILESIZES
170  */
171 
179  AttributeRecord(){}
180 
181  /* attribute id */
182  Uint16 attributeId;
183 
184  /* Attribute number within tuple key (counted from 1) */
185  Uint16 tupleKey;
186 
187  /* Attribute name (unique within table) */
188  RopeHandle attributeName;
189 
190  /* Attribute description (old-style packed descriptor) */
191  Uint32 attributeDescriptor;
192 
193  /* Extended attributes */
194  Uint32 extType;
195  Uint32 extPrecision;
196  Uint32 extScale;
197  Uint32 extLength;
198 
199  /* Autoincrement flag, only for ODBC/SQL */
200  bool autoIncrement;
201 
202  /* Default value as null-terminated string, only for ODBC/SQL */
203  RopeHandle defaultValue;
204 
205  struct {
206  Uint32 m_name_len;
207  const char * m_name_ptr;
208  RopePool * m_pool;
209  } m_key;
210 
211  union {
212  Uint32 nextPool;
213  Uint32 nextList;
214  };
215  Uint32 prevList;
216  Uint32 nextHash;
217  Uint32 prevHash;
218 
219  Uint32 hashValue() const { return attributeName.hashValue();}
220  bool equal(const AttributeRecord& obj) const {
221  if(obj.hashValue() == hashValue()){
222  ConstRope r(* m_key.m_pool, obj.attributeName);
223  return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0;
224  }
225  return false;
226  }
227  };
229  ArrayPool<AttributeRecord> c_attributeRecordPool;
230  DLHashTable<AttributeRecord> c_attributeRecordHash;
231  RSS_AP_SNAPSHOT(c_attributeRecordPool);
232 
237  struct TableRecord {
238  TableRecord(){ m_upgrade_trigger_handling.m_upgrade = false;}
239  Uint32 maxRowsLow;
240  Uint32 maxRowsHigh;
241  Uint32 minRowsLow;
242  Uint32 minRowsHigh;
243  /* Table id (array index in DICT and other blocks) */
244  Uint32 tableId;
245  Uint32 m_obj_ptr_i;
246 
247  /* Table version (incremented when tableId is re-used) */
248  Uint32 tableVersion;
249 
250  /* */
251  Uint32 hashMapObjectId;
252  Uint32 hashMapVersion;
253 
254  /* Table name (may not be unique under "alter table") */
255  RopeHandle tableName;
256 
257  /* Type of table or index */
258  DictTabInfo::TableType tableType;
259 
260  /* Is table or index online (this flag is not used in DICT) */
261  bool online;
262 
263  /* Primary table of index otherwise RNIL */
264  Uint32 primaryTableId;
265 
266  /* Type of fragmentation (small/medium/large) */
267  DictTabInfo::FragmentType fragmentType;
268 
269  /* Global checkpoint identity when table created */
270  Uint32 gciTableCreated;
271 
272  /* Is the table logged (i.e. data survives system restart) */
273  enum Bits
274  {
275  TR_Logged = 0x1,
276  TR_RowGCI = 0x2,
277  TR_RowChecksum = 0x4,
278  TR_Temporary = 0x8,
279  TR_ForceVarPart = 0x10
280  };
281  Uint8 m_extra_row_gci_bits;
282  Uint8 m_extra_row_author_bits;
283  Uint16 m_bits;
284 
285  /* Number of attibutes in table */
286  Uint16 noOfAttributes;
287 
288  /* Number of null attributes in table (should be computed) */
289  Uint16 noOfNullAttr;
290 
291  /* Number of primary key attributes (should be computed) */
292  Uint16 noOfPrimkey;
293 
294  /* Length of primary key in words (should be computed) */
295  /* For ordered index this is tree node size in words */
296  Uint16 tupKeyLength;
297 
299  Uint16 noOfCharsets;
300 
301  /* K value for LH**3 algorithm (only 6 allowed currently) */
302  Uint8 kValue;
303 
304  /* Local key length in words (currently 1) */
305  Uint8 localKeyLen;
306 
307  /*
308  * Parameter for hash algorithm that specifies the load factor in
309  * percentage of fill level in buckets. A high value means we are
310  * splitting early and that buckets are only lightly used. A high
311  * value means that we have fill the buckets more and get more
312  * likelihood of overflow buckets.
313  */
314  Uint8 maxLoadFactor;
315 
316  /*
317  Flag to indicate default number of partitions
318  */
319  bool defaultNoPartFlag;
320 
321  /*
322  Flag to indicate using linear hash function
323  */
324  bool linearHashFlag;
325 
326  /*
327  * Used when shrinking to decide when to merge buckets. Hysteresis
328  * is thus possible. Should be smaller but not much smaller than
329  * maxLoadFactor
330  */
331  Uint8 minLoadFactor;
332 
336  Uint8 storageType; // NDB_STORAGETYPE_
337 
338  /* Convenience routines */
339  bool isTable() const;
340  bool isIndex() const;
341  bool isUniqueIndex() const;
342  bool isNonUniqueIndex() const;
343  bool isHashIndex() const;
344  bool isOrderedIndex() const;
345 
346  /****************************************************
347  * Support variables for table handling
348  ****************************************************/
349 
351  Uint32 filePtr[2];
352 
355 
356  Uint32 nextPool;
357 
358  Uint32 m_read_locked; // BACKUP_ONGOING
359 
361  Uint32 packedSize;
362 
364  enum IndexState {
365  IS_UNDEFINED = 0, // initial
366  IS_OFFLINE = 1, // index table created
367  IS_BUILDING = 2, // building (local state)
368  IS_DROPPING = 3, // dropping (local state)
369  IS_ONLINE = 4, // online
370  IS_BROKEN = 9 // build or drop aborted
371  };
372  IndexState indexState;
373 
375  Uint32 triggerId; // ordered index (1)
376  Uint32 buildTriggerId; // temp during build
377 
379  {
386  bool m_upgrade;
387  Uint32 insertTriggerId;
388  Uint32 updateTriggerId;
389  Uint32 deleteTriggerId;
390  } m_upgrade_trigger_handling;
391 
392  Uint32 noOfNullBits;
393 
396  RopeHandle ngData;
397  RopeHandle rangeData;
398 
399  Uint32 fragmentCount;
400  Uint32 m_tablespace_id;
401 
404  Uint32 nextList, prevList;
405 
406  /*
407  * Access rights to table during single user mode
408  */
409  Uint8 singleUserMode;
410 
411  /*
412  * Fragment and node to use for index statistics. Not part of
413  * DICTTABINFO. Computed locally by each DICT. If the node is
414  * down, no automatic stats update takes place. This is not
415  * critical and is not worth fixing.
416  */
417  Uint16 indexStatFragId;
418  Uint16 indexStatNodeId;
419 
420  // pending background request (IndexStatRep::RequestType)
421  Uint32 indexStatBgRequest;
422  };
423 
425  ArrayPool<TableRecord> c_tableRecordPool;
426  RSS_AP_SNAPSHOT(c_tableRecordPool);
427 
434  union {
435  Uint16 c_fragData[MAX_NDB_PARTITIONS];
436  Uint32 c_fragData_align32[1];
437  };
438  Uint32 c_tsIdData[2*MAX_NDB_PARTITIONS];
439 
444  struct TriggerRecord {
445  TriggerRecord() {}
446 
448  enum TriggerState {
449  TS_NOT_DEFINED = 0,
450  TS_DEFINING = 1,
451  TS_OFFLINE = 2, // created globally in DICT
452  //TS_BUILDING = 3,
453  //TS_DROPPING = 4,
454  TS_ONLINE = 5, // created in other blocks
455  TS_FAKE_UPGRADE = 6
456  };
457  TriggerState triggerState;
458 
461 
463  Uint32 triggerId;
464  Uint32 m_obj_ptr_i;
465 
467  Uint32 tableId;
468 
470  Uint32 triggerInfo;
471 
477 
479  BlockReference receiverRef;
480 
482  Uint32 indexId;
483 
485  Uint32 nextPool;
486  };
487 
488  Uint32 c_maxNoOfTriggers;
490  ArrayPool<TriggerRecord> c_triggerRecordPool;
491  RSS_AP_SNAPSHOT(c_triggerRecordPool);
492 
497  enum FsState {
498  IDLE = 0,
499  OPEN_WRITE_SCHEMA = 1,
500  WRITE_SCHEMA = 2,
501  CLOSE_WRITE_SCHEMA = 3,
502  OPEN_READ_SCHEMA1 = 4,
503  OPEN_READ_SCHEMA2 = 5,
504  READ_SCHEMA1 = 6,
505  READ_SCHEMA2 = 7,
506  CLOSE_READ_SCHEMA = 8,
507  OPEN_READ_TAB_FILE1 = 9,
508  OPEN_READ_TAB_FILE2 = 10,
509  READ_TAB_FILE1 = 11,
510  READ_TAB_FILE2 = 12,
511  CLOSE_READ_TAB_FILE = 13,
512  OPEN_WRITE_TAB_FILE = 14,
513  WRITE_TAB_FILE = 15,
514  CLOSE_WRITE_TAB_FILE = 16
515  };
517  Uint32 filePtr;
518 
520  Uint32 ownerPtr;
521 
523  FsState fsState;
524 
526  Uint32 nextPool;
527  };
528 
530  ArrayPool<FsConnectRecord> c_fsConnectRecordPool;
531 
535  struct NodeRecord {
536  enum NodeState {
537  API_NODE = 0,
538  NDB_NODE_ALIVE = 1,
539  NDB_NODE_DEAD = 2,
540  NDB_MASTER_TAKEOVER = 3
541  };
542  bool hotSpare;
543  NodeState nodeState;
544 
545  // Schema transaction data
546  enum RecoveryState {
547  RS_NORMAL = 0, // Node is up to date with master
548  RS_PARTIAL_ROLLBACK = 1, // Node has rolled back some operations
549  RS_PARTIAL_ROLLFORWARD = 2 // Node has committed some operations
550  };
551  RecoveryState recoveryState;
552  NodeFailRep nodeFailRep;
553  NdbNodeBitmask m_nodes; // Nodes sent DICT_TAKEOVER_REQ during takeover
554  SafeCounterHandle m_counter; // Outstanding DICT_TAKEOVER_REQ's
555  //TODO Accumulate in buffer when DictTakeoverConf becomes long signal
556  DictTakeoverConf takeOverConf; // Accumulated replies
557 
558  // TODO: these should be moved to SchemaTransPtr
559  // Starting operation for partial rollback/rollforward
560  Uint32 start_op;
561  // Starting state of operation for partial rollback/rollforward
562  Uint32 start_op_state;
563  };
564 
566  CArray<NodeRecord> c_nodes;
567  NdbNodeBitmask c_aliveNodes;
568 
569  struct PageRecord {
570  Uint32 word[8192];
571  };
572 
574  CArray<PageRecord> c_pageRecordArray;
575 
577  Uint32 word[NDB_SF_PAGE_SIZE_IN_WORDS];
578  };
579 
580  CArray<SchemaPageRecord> c_schemaPageRecordArray;
581 
582  unsigned g_trace;
583  DictTabInfo::Table c_tableDesc;
584 
589 
590  struct File {
591  File() {}
592 
593  Uint32 key;
594  Uint32 m_magic;
595  Uint32 m_version;
596  Uint32 m_obj_ptr_i;
597  Uint32 m_filegroup_id;
598  Uint32 m_type;
599  Uint64 m_file_size;
600  Uint64 m_file_free;
601  RopeHandle m_path;
602 
603  Uint32 nextList;
604  union {
605  Uint32 prevList;
606  Uint32 nextPool;
607  };
608  Uint32 nextHash, prevHash;
609 
610  Uint32 hashValue() const { return key;}
611  bool equal(const File& obj) const { return key == obj.key;}
612  };
613  typedef Ptr<File> FilePtr;
618 
619  struct Filegroup {
620  Filegroup(){}
621 
622  Uint32 key;
623  Uint32 m_obj_ptr_i;
624  Uint32 m_magic;
625 
626  Uint32 m_type;
627  Uint32 m_version;
628  RopeHandle m_name;
629 
630  union {
631  struct {
632  Uint32 m_extent_size;
633  Uint32 m_default_logfile_group_id;
634  } m_tablespace;
635 
636  struct {
637  Uint32 m_undo_buffer_size;
638  File_list::HeadPOD m_files;
639  } m_logfilegroup;
640  };
641 
642  union {
643  Uint32 nextPool;
644  Uint32 nextList;
645  Uint32 nextHash;
646  };
647  Uint32 prevHash;
648 
649  Uint32 hashValue() const { return key;}
650  bool equal(const Filegroup& obj) const { return key == obj.key;}
651  };
655 
656  File_pool c_file_pool;
657  Filegroup_pool c_filegroup_pool;
658  File_hash c_file_hash;
659  Filegroup_hash c_filegroup_hash;
660 
661  RopePool c_rope_pool;
662  RSS_AP_SNAPSHOT(c_rope_pool);
663 
664  struct DictObject {
665  DictObject() {
666  m_trans_key = 0;
667  m_op_ref_count = 0;
668  };
669  Uint32 m_id;
670  Uint32 m_type;
671  Uint32 m_ref_count;
672  RopeHandle m_name;
673  union {
674  struct {
675  Uint32 m_name_len;
676  const char * m_name_ptr;
677  RopePool * m_pool;
678  } m_key;
679  Uint32 nextPool;
680  Uint32 nextList;
681  };
682  Uint32 nextHash;
683  Uint32 prevHash;
684 
685  Uint32 hashValue() const { return m_name.hashValue();}
686  bool equal(const DictObject& obj) const {
687  if(obj.hashValue() == hashValue()){
688  ConstRope r(* m_key.m_pool, obj.m_name);
689  return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0;
690  }
691  return false;
692  }
693 
694  // SchemaOp -> DictObject -> SchemaTrans
695  Uint32 m_trans_key;
696  Uint32 m_op_ref_count;
697 #ifdef VM_TRACE
698  void print(NdbOut&) const;
699 #endif
700  };
701 
703 
704  DLHashTable<DictObject> c_obj_hash; // Name
705  ArrayPool<DictObject> c_obj_pool;
706  RSS_AP_SNAPSHOT(c_obj_pool);
707 
708  // 1
709  DictObject * get_object(const char * name){
710  return get_object(name, Uint32(strlen(name) + 1));
711  }
712 
713  DictObject * get_object(const char * name, Uint32 len){
714  return get_object(name, len, Rope::hash(name, len));
715  }
716 
717  DictObject * get_object(const char * name, Uint32 len, Uint32 hash);
718 
719  //2
720  bool get_object(DictObjectPtr& obj_ptr, const char * name){
721  return get_object(obj_ptr, name, Uint32(strlen(name) + 1));
722  }
723 
724  bool get_object(DictObjectPtr& obj_ptr, const char * name, Uint32 len){
725  return get_object(obj_ptr, name, len, Rope::hash(name, len));
726  }
727 
728  bool get_object(DictObjectPtr&, const char* name, Uint32 len, Uint32 hash);
729 
730  void release_object(Uint32 obj_ptr_i){
731  release_object(obj_ptr_i, c_obj_pool.getPtr(obj_ptr_i));
732  }
733 
734  void release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p);
735 
736  void increase_ref_count(Uint32 obj_ptr_i);
737  void decrease_ref_count(Uint32 obj_ptr_i);
738 
739 public:
740  Dbdict(Block_context& ctx);
741  virtual ~Dbdict();
742 
743 private:
744  BLOCK_DEFINES(Dbdict);
745 
746  // Signal receivers
747  void execDICTSTARTREQ(Signal* signal);
748 
749  void execGET_TABINFOREQ(Signal* signal);
750  void execGET_TABLEDID_REQ(Signal* signal);
751  void execGET_TABINFO_REF(Signal* signal);
752  void execGET_TABINFO_CONF(Signal* signal);
753  void execCONTINUEB(Signal* signal);
754 
755  void execDUMP_STATE_ORD(Signal* signal);
756  void execDBINFO_SCANREQ(Signal* signal);
757  void execHOT_SPAREREP(Signal* signal);
758  void execDIADDTABCONF(Signal* signal);
759  void execDIADDTABREF(Signal* signal);
760  void execTAB_COMMITCONF(Signal* signal);
761  void execTAB_COMMITREF(Signal* signal);
762  void execGET_SCHEMA_INFOREQ(Signal* signal);
763  void execSCHEMA_INFO(Signal* signal);
764  void execSCHEMA_INFOCONF(Signal* signal);
765  void execREAD_NODESCONF(Signal* signal);
766  void execFSCLOSECONF(Signal* signal);
767  void execFSOPENCONF(Signal* signal);
768  void execFSOPENREF(Signal* signal);
769  void execFSREADCONF(Signal* signal);
770  void execFSREADREF(Signal* signal);
771  void execFSWRITECONF(Signal* signal);
772  void execNDB_STTOR(Signal* signal);
773  void execREAD_CONFIG_REQ(Signal* signal);
774  void execSTTOR(Signal* signal);
775  void execTC_SCHVERCONF(Signal* signal);
776  void execNODE_FAILREP(Signal* signal);
777 
778  void send_nf_complete_rep(Signal* signal, const NodeFailRep*);
779 
780  void execINCL_NODEREQ(Signal* signal);
781  void execAPI_FAILREQ(Signal* signal);
782 
783  void execWAIT_GCP_REF(Signal* signal);
784  void execWAIT_GCP_CONF(Signal* signal);
785 
786  void execLIST_TABLES_REQ(Signal* signal);
787 
788  // Index signals
789  void execCREATE_INDX_REQ(Signal* signal);
790  void execCREATE_INDX_IMPL_CONF(Signal* signal);
791  void execCREATE_INDX_IMPL_REF(Signal* signal);
792 
793  void execALTER_INDX_REQ(Signal* signal);
794  void execALTER_INDX_CONF(Signal* signal);
795  void execALTER_INDX_REF(Signal* signal);
796  void execALTER_INDX_IMPL_CONF(Signal* signal);
797  void execALTER_INDX_IMPL_REF(Signal* signal);
798 
799  void execCREATE_TABLE_CONF(Signal* signal);
800  void execCREATE_TABLE_REF(Signal* signal);
801 
802  void execDROP_INDX_REQ(Signal* signal);
803  void execDROP_INDX_IMPL_CONF(Signal* signal);
804  void execDROP_INDX_IMPL_REF(Signal* signal);
805 
806  void execDROP_TABLE_CONF(Signal* signal);
807  void execDROP_TABLE_REF(Signal* signal);
808 
809  void execBUILDINDXREQ(Signal* signal);
810  void execBUILDINDXCONF(Signal* signal);
811  void execBUILDINDXREF(Signal* signal);
812  void execBUILD_INDX_IMPL_CONF(Signal* signal);
813  void execBUILD_INDX_IMPL_REF(Signal* signal);
814 
815  void execBACKUP_LOCK_TAB_REQ(Signal*);
816 
817  // Util signals used by Event code
818  void execUTIL_PREPARE_CONF(Signal* signal);
819  void execUTIL_PREPARE_REF (Signal* signal);
820  void execUTIL_EXECUTE_CONF(Signal* signal);
821  void execUTIL_EXECUTE_REF (Signal* signal);
822  void execUTIL_RELEASE_CONF(Signal* signal);
823  void execUTIL_RELEASE_REF (Signal* signal);
824 
825 
826  // Event signals from API
827  void execCREATE_EVNT_REQ (Signal* signal);
828  void execCREATE_EVNT_CONF(Signal* signal);
829  void execCREATE_EVNT_REF (Signal* signal);
830 
831  void execDROP_EVNT_REQ (Signal* signal);
832 
833  void execSUB_START_REQ (Signal* signal);
834  void execSUB_START_CONF (Signal* signal);
835  void execSUB_START_REF (Signal* signal);
836 
837  void execSUB_STOP_REQ (Signal* signal);
838  void execSUB_STOP_CONF (Signal* signal);
839  void execSUB_STOP_REF (Signal* signal);
840 
841  // Event signals from SUMA
842 
843  void execCREATE_SUBID_CONF(Signal* signal);
844  void execCREATE_SUBID_REF (Signal* signal);
845 
846  void execSUB_CREATE_CONF(Signal* signal);
847  void execSUB_CREATE_REF (Signal* signal);
848 
849  void execSUB_REMOVE_REQ(Signal* signal);
850  void execSUB_REMOVE_CONF(Signal* signal);
851  void execSUB_REMOVE_REF(Signal* signal);
852 
853  // Trigger signals
854  void execCREATE_TRIG_REQ(Signal* signal);
855  void execCREATE_TRIG_CONF(Signal* signal);
856  void execCREATE_TRIG_REF(Signal* signal);
857  void execALTER_TRIG_REQ(Signal* signal);
858  void execALTER_TRIG_CONF(Signal* signal);
859  void execALTER_TRIG_REF(Signal* signal);
860  void execDROP_TRIG_REQ(Signal* signal);
861  void execDROP_TRIG_CONF(Signal* signal);
862  void execDROP_TRIG_REF(Signal* signal);
863  // from other blocks
864  void execCREATE_TRIG_IMPL_CONF(Signal* signal);
865  void execCREATE_TRIG_IMPL_REF(Signal* signal);
866  void execDROP_TRIG_IMPL_CONF(Signal* signal);
867  void execDROP_TRIG_IMPL_REF(Signal* signal);
868 
869  void execDROP_TABLE_REQ(Signal* signal);
870 
871  void execPREP_DROP_TAB_REQ(Signal* signal);
872  void execPREP_DROP_TAB_REF(Signal* signal);
873  void execPREP_DROP_TAB_CONF(Signal* signal);
874 
875  void execDROP_TAB_REF(Signal* signal);
876  void execDROP_TAB_CONF(Signal* signal);
877 
878  void execCREATE_TABLE_REQ(Signal* signal);
879  void execALTER_TABLE_REQ(Signal* signal);
880 
881  Uint32 get_fragmentation(Signal*, Uint32 tableId);
882  Uint32 create_fragmentation(Signal* signal, TableRecordPtr,
883  const Uint16*, Uint32 cnt,
884  Uint32 flags = 0);
885  void execCREATE_FRAGMENTATION_REQ(Signal*);
886  void execCREATE_FRAGMENTATION_REF(Signal*);
887  void execCREATE_FRAGMENTATION_CONF(Signal*);
888  void execCREATE_TAB_REQ(Signal* signal);
889  void execADD_FRAGREQ(Signal* signal);
890  void execLQHFRAGREF(Signal* signal);
891  void execLQHFRAGCONF(Signal* signal);
892  void execLQHADDATTREF(Signal* signal);
893  void execLQHADDATTCONF(Signal* signal);
894  void execCREATE_TAB_REF(Signal* signal);
895  void execCREATE_TAB_CONF(Signal* signal);
896  void execALTER_TAB_REF(Signal* signal);
897  void execALTER_TAB_CONF(Signal* signal);
898  void execALTER_TABLE_REF(Signal* signal);
899  void execALTER_TABLE_CONF(Signal* signal);
900  bool check_ndb_versions() const;
901  int check_sender_version(const Signal* signal, Uint32 version) const;
902 
903 
904  void execCREATE_FILE_REQ(Signal* signal);
905  void execCREATE_FILEGROUP_REQ(Signal* signal);
906  void execDROP_FILE_REQ(Signal* signal);
907  void execDROP_FILEGROUP_REQ(Signal* signal);
908 
909  // Internal
910  void execCREATE_FILE_IMPL_REF(Signal* signal);
911  void execCREATE_FILE_IMPL_CONF(Signal* signal);
912  void execCREATE_FILEGROUP_IMPL_REF(Signal* signal);
913  void execCREATE_FILEGROUP_IMPL_CONF(Signal* signal);
914  void execDROP_FILE_IMPL_REF(Signal* signal);
915  void execDROP_FILE_IMPL_CONF(Signal* signal);
916  void execDROP_FILEGROUP_IMPL_REF(Signal* signal);
917  void execDROP_FILEGROUP_IMPL_CONF(Signal* signal);
918 
919  void execSCHEMA_TRANS_BEGIN_REQ(Signal* signal);
920  void execSCHEMA_TRANS_BEGIN_CONF(Signal* signal);
921  void execSCHEMA_TRANS_BEGIN_REF(Signal* signal);
922  void execSCHEMA_TRANS_END_REQ(Signal* signal);
923  void execSCHEMA_TRANS_END_CONF(Signal* signal);
924  void execSCHEMA_TRANS_END_REF(Signal* signal);
925  void execSCHEMA_TRANS_END_REP(Signal* signal);
926  void execSCHEMA_TRANS_IMPL_REQ(Signal* signal);
927  void execSCHEMA_TRANS_IMPL_CONF(Signal* signal);
928  void execSCHEMA_TRANS_IMPL_REF(Signal* signal);
929 
930  void execDICT_LOCK_REQ(Signal* signal);
931  void execDICT_UNLOCK_ORD(Signal* signal);
932 
933  void execDICT_TAKEOVER_REQ(Signal* signal);
934  void execDICT_TAKEOVER_REF(Signal* signal);
935  void execDICT_TAKEOVER_CONF(Signal* signal);
936 
937  // ordered index statistics
938  void execINDEX_STAT_REQ(Signal* signal);
939  void execINDEX_STAT_CONF(Signal* signal);
940  void execINDEX_STAT_REF(Signal* signal);
941  void execINDEX_STAT_IMPL_CONF(Signal* signal);
942  void execINDEX_STAT_IMPL_REF(Signal* signal);
943  void execINDEX_STAT_REP(Signal* signal);
944 
945  /*
946  * 2.4 COMMON STORED VARIABLES
947  */
948 
953  struct SendSchemaRecord {
955  Uint32 noOfWords;
957  Uint32 pageId;
958 
959  Uint32 nodeId;
960  SignalCounter m_SCHEMAINFO_Counter;
961 
962  Uint32 noOfWordsCurrentlySent;
963  Uint32 noOfSignalsSentSinceDelay;
964 
965  bool inUse;
966  };
967  SendSchemaRecord c_sendSchemaRecord;
968 
973  struct ReadTableRecord {
975  Uint32 no_of_words;
977  Uint32 pageId;
979  Uint32 tableId;
980 
981  bool inUse;
982  Callback m_callback;
983  };
984  ReadTableRecord c_readTableRecord;
985 
990  struct WriteTableRecord {
992  Uint32 no_of_words;
994  Uint32 pageId;
996  Uint32 noOfTableFilesHandled;
998  Uint32 tableId;
1000  enum TableWriteState {
1001  IDLE = 0,
1002  WRITE_ADD_TABLE_MASTER = 1,
1003  WRITE_ADD_TABLE_SLAVE = 2,
1004  WRITE_RESTART_FROM_MASTER = 3,
1005  WRITE_RESTART_FROM_OWN = 4,
1006  TWR_CALLBACK = 5
1007  };
1008  TableWriteState tableWriteState;
1009  Callback m_callback;
1010  };
1011  WriteTableRecord c_writeTableRecord;
1012 
1017  struct ReadSchemaRecord {
1019  Uint32 pageId;
1021  Uint32 firstPage;
1023  Uint32 noOfPages;
1025  enum SchemaReadState {
1026  IDLE = 0,
1027  INITIAL_READ_HEAD = 1,
1028  INITIAL_READ = 2
1029  };
1030  SchemaReadState schemaReadState;
1031  };
1032  ReadSchemaRecord c_readSchemaRecord;
1033 
1038  struct WriteSchemaRecord {
1040  Uint32 pageId;
1042  Uint32 newFile;
1044  Uint32 firstPage;
1046  Uint32 noOfPages;
1048  Uint32 noOfSchemaFilesHandled;
1049 
1050  bool inUse;
1051  Callback m_callback;
1052  };
1053  WriteSchemaRecord c_writeSchemaRecord;
1054 
1059  struct RestartRecord {
1061  Uint32 gciToRestart;
1062 
1064  Uint32 activeTable;
1065 
1067  BlockReference returnBlockRef;
1068  Uint32 m_senderData;
1069 
1070  Uint32 m_pass; // 0 tablespaces/logfilegroups, 1 tables, 2 indexes
1071  Uint32 m_end_pass; //
1072  const char * m_start_banner;
1073  const char * m_end_banner;
1074 
1075  Uint32 m_tx_ptr_i;
1076  Uint32 m_op_cnt;
1077  SchemaFile::TableEntry m_entry;
1078  };
1079  RestartRecord c_restartRecord;
1080 
1085  struct RetrieveRecord {
1086  RetrieveRecord(){ noOfWaiters = 0;}
1087 
1089  bool busyState;
1090 
1094  Uint32 noOfWaiters;
1095 
1097  BlockReference blockRef;
1098 
1100  Uint32 m_senderData;
1101 
1103  Uint32 tableId;
1104 
1105  Uint32 m_table_type;
1106 
1108  Uint32 retrievePage;
1109 
1111  Uint32 retrievedNoOfPages;
1112 
1114  Uint32 retrievedNoOfWords;
1115 
1117  Uint32 currentSent;
1118 
1122  bool m_useLongSig;
1123 
1124  Uint32 schemaTransId;
1125  Uint32 requestType;
1126  };
1127  RetrieveRecord c_retrieveRecord;
1128 
1141  struct SchemaRecord {
1142  enum
1143  {
1144  NEW_SCHEMA_FILE = 0, // Index in c_schemaFile
1145  OLD_SCHEMA_FILE = 1
1146  };
1147 
1149  Uint32 schemaPage;
1150 
1152  Uint32 oldSchemaPage;
1153 
1154  Callback m_callback;
1155  };
1156  SchemaRecord c_schemaRecord;
1157 
1158  /*
1159  * Schema file, list of schema pages. Use an array until a pool
1160  * exists and NDBFS interface can use it.
1161  */
1162  struct XSchemaFile {
1163  SchemaFile* schemaPage;
1164  Uint32 noOfPages;
1165  };
1166  // 0-normal 1-old
1167  XSchemaFile c_schemaFile[2];
1168 
1169  void initSchemaFile(XSchemaFile *, Uint32 firstPage, Uint32 lastPage,
1170  bool initEntries);
1171  void resizeSchemaFile(XSchemaFile * xsf, Uint32 noOfPages);
1172  void computeChecksum(XSchemaFile *, Uint32 pageNo);
1173  bool validateChecksum(const XSchemaFile *);
1174  SchemaFile::TableEntry * getTableEntry(Uint32 tableId);
1175  SchemaFile::TableEntry * getTableEntry(XSchemaFile *, Uint32 tableId);
1176  const SchemaFile::TableEntry * getTableEntry(const XSchemaFile*, Uint32);
1177 
1178  Uint32 computeChecksum(const Uint32 * src, Uint32 len);
1179 
1180 
1181  /* ----------------------------------------------------------------------- */
1182  // Node References
1183  /* ----------------------------------------------------------------------- */
1184  Uint16 c_masterNodeId;
1185 
1186  /* ----------------------------------------------------------------------- */
1187  // Various current system properties
1188  /* ----------------------------------------------------------------------- */
1189  Uint16 c_numberNode;
1190  Uint16 c_noHotSpareNodes;
1191  Uint16 c_noNodesFailed;
1192  Uint32 c_failureNr;
1193 
1194  /* ----------------------------------------------------------------------- */
1195  // State variables
1196  /* ----------------------------------------------------------------------- */
1197 
1198  struct PackTable {
1199 
1200  enum PackTableState {
1201  PTS_IDLE = 0,
1202  PTS_GET_TAB = 3
1203  } m_state;
1204 
1205  } c_packTable;
1206 
1207  Uint32 c_startPhase;
1208  Uint32 c_restartType;
1209  bool c_initialStart;
1210  bool c_systemRestart;
1211  bool c_nodeRestart;
1212  bool c_initialNodeRestart;
1213  Uint32 c_tabinfoReceived;
1214 
1218  struct ParseDictTabInfoRecord {
1219  ParseDictTabInfoRecord() { tablePtr.setNull();}
1220  DictTabInfo::RequestType requestType;
1221  Uint32 errorCode;
1222  Uint32 errorLine;
1223 
1225  Uint32 errorKey;
1226  TableRecordPtr tablePtr;
1227  };
1228 
1229  // Misc helpers
1230 
1231  template <Uint32 sz>
1232  inline bool
1233  copyRope(RopeHandle& rh_dst, const RopeHandle& rh_src)
1234  {
1235  char buf[sz];
1236  Rope r_dst(c_rope_pool, rh_dst);
1237  ConstRope r_src(c_rope_pool, rh_src);
1238  ndbrequire(r_src.size() <= sz);
1239  r_src.copy(buf);
1240  bool ok = r_dst.assign(buf, r_src.size());
1241  return ok;
1242  }
1243 
1244 #ifdef VM_TRACE
1245  template <Uint32 sz>
1246  inline const char*
1247  copyRope(const RopeHandle& rh)
1248  {
1249  static char buf[2][sz];
1250  static int i = 0;
1251  ConstRope r(c_rope_pool, rh);
1252  char* str = buf[i++ % 2];
1253  r.copy(str);
1254  return str;
1255  }
1256 #endif
1257 
1258  // Operation records
1259 
1264  struct OpRecordCommon {
1265  OpRecordCommon() {}
1266  Uint32 key; // key shared between master and slaves
1267  Uint32 nextHash;
1268  Uint32 prevHash;
1269  Uint32 hashValue() const {
1270  return key;
1271  }
1272  bool equal(const OpRecordCommon& rec) const {
1273  return key == rec.key;
1274  }
1275  };
1276 
1277  // MODULE: SchemaTrans
1278 
1279  struct SchemaOp;
1280  struct SchemaTrans;
1281  struct TxHandle;
1282  typedef Ptr<SchemaOp> SchemaOpPtr;
1283  typedef Ptr<SchemaTrans> SchemaTransPtr;
1284  typedef Ptr<TxHandle> TxHandlePtr;
1285 
1286  // ErrorInfo
1287 
1288  struct ErrorInfo {
1289  Uint32 errorCode;
1290  Uint32 errorLine;
1291  Uint32 errorNodeId;
1292  Uint32 errorCount;
1293  // for CreateTable
1294  Uint32 errorStatus;
1295  Uint32 errorKey;
1296  char errorObjectName[MAX_TAB_NAME_SIZE];
1297  ErrorInfo() {
1298  errorCode = 0;
1299  errorLine = 0;
1300  errorNodeId = 0;
1301  errorCount = 0;
1302  errorStatus = 0;
1303  errorKey = 0;
1304  errorObjectName[0] = 0;
1305  }
1306  void print(NdbOut&) const;
1307  private:
1308  ErrorInfo& operator=(const ErrorInfo&);
1309  };
1310 
1311  void setError(ErrorInfo&,
1312  Uint32 code,
1313  Uint32 line,
1314  Uint32 nodeId = 0,
1315  Uint32 status = 0,
1316  Uint32 key = 0,
1317  const char * name = 0);
1318 
1319  void setError(ErrorInfo&,
1320  Uint32 code,
1321  Uint32 line,
1322  const char * name);
1323 
1324  void setError(ErrorInfo&, const ErrorInfo&);
1325  void setError(ErrorInfo&, const ParseDictTabInfoRecord&);
1326 
1327  void setError(SchemaOpPtr, Uint32 code, Uint32 line, Uint32 nodeId = 0);
1328  void setError(SchemaOpPtr, const ErrorInfo&);
1329 
1330  void setError(SchemaTransPtr, Uint32 code, Uint32 line, Uint32 nodeId = 0);
1331  void setError(SchemaTransPtr, const ErrorInfo&);
1332 
1333  void setError(TxHandlePtr, Uint32 code, Uint32 line, Uint32 nodeId = 0);
1334  void setError(TxHandlePtr, const ErrorInfo&);
1335 
1336  template <class Ref>
1337  inline void
1338  setError(ErrorInfo& e, const Ref* ref) {
1339  setError(e, ref->errorCode, ref->errorLine, ref->errorNodeId);
1340  }
1341 
1342  template <class Ref>
1343  inline void
1344  getError(const ErrorInfo& e, Ref* ref) {
1345  ref->errorCode = e.errorCode;
1346  ref->errorLine = e.errorLine;
1347  ref->errorNodeId = e.errorNodeId;
1348  ref->masterNodeId = c_masterNodeId;
1349  }
1350 
1351  bool hasError(const ErrorInfo&);
1352 
1353  void resetError(ErrorInfo&);
1354  void resetError(SchemaOpPtr);
1355  void resetError(SchemaTransPtr);
1356  void resetError(TxHandlePtr);
1357 
1358  // OpInfo
1359 
1360  struct OpInfo {
1361  const char m_opType[4]; // e.g. CTa for CreateTable
1362  Uint32 m_impl_req_gsn;
1363  Uint32 m_impl_req_length;
1364 
1365  // seize / release type-specific Data record
1366  bool (Dbdict::*m_seize)(SchemaOpPtr);
1367  void (Dbdict::*m_release)(SchemaOpPtr);
1368 
1369  // parse phase
1370  void (Dbdict::*m_parse)(Signal*, bool master,
1371  SchemaOpPtr, SectionHandle&, ErrorInfo&);
1372  bool (Dbdict::*m_subOps)(Signal*, SchemaOpPtr);
1373  void (Dbdict::*m_reply)(Signal*, SchemaOpPtr, ErrorInfo);
1374 
1375  // run phases
1376  void (Dbdict::*m_prepare)(Signal*, SchemaOpPtr);
1377  void (Dbdict::*m_commit)(Signal*, SchemaOpPtr);
1378  void (Dbdict::*m_complete)(Signal*, SchemaOpPtr);
1379  // abort mode
1380  void (Dbdict::*m_abortParse)(Signal*, SchemaOpPtr);
1381  void (Dbdict::*m_abortPrepare)(Signal*, SchemaOpPtr);
1382  };
1383 
1384  // all OpInfo records
1385  static const OpInfo* g_opInfoList[];
1386  const OpInfo* findOpInfo(Uint32 gsn);
1387 
1388  // OpRec
1389 
1390  struct OpRec
1391  {
1392  char m_opType[4];
1393 
1394  Uint32 nextPool;
1395 
1396  // reference to the static member in subclass
1397  const OpInfo& m_opInfo;
1398 
1399  // pointer to internal signal in subclass instance
1400  Uint32* const m_impl_req_data;
1401 
1402  // DictObject operated on
1403  Uint32 m_obj_ptr_i;
1404 
1405  OpRec(const OpInfo& info, Uint32* impl_req_data) :
1406  m_opInfo(info),
1407  m_impl_req_data(impl_req_data) {
1408  m_obj_ptr_i = RNIL;
1409  memcpy(m_opType, m_opInfo.m_opType, 4);
1410  }
1411  };
1412  typedef Ptr<OpRec> OpRecPtr;
1413 
1414  /*
1415  * OpSection
1416  *
1417  * Signal sections are released in parse phase. If necessary
1418  * they are first saved under schema op record.
1419  */
1420 
1421  enum { OpSectionSegmentSize = 127 };
1422  typedef
1424  OpSectionBuffer;
1425  typedef
1426  OpSectionBuffer::Head
1427  OpSectionBufferHead;
1428  typedef
1429  OpSectionBuffer::DataBufferPool
1430  OpSectionBufferPool;
1431  typedef
1433  OpSectionBufferConstIterator;
1434 
1435  OpSectionBufferPool c_opSectionBufferPool;
1436 
1437  struct OpSection {
1438  OpSectionBufferHead m_head;
1439  Uint32 getSize() const {
1440  return m_head.getSize();
1441  }
1442  };
1443 
1444  bool copyIn(OpSection&, const SegmentedSectionPtr&);
1445  bool copyIn(OpSection&, const Uint32* src, Uint32 srcSize);
1446  bool copyOut(const OpSection&, SegmentedSectionPtr&);
1447  bool copyOut(const OpSection&, Uint32* dst, Uint32 dstSize);
1448  bool copyOut(OpSectionBuffer & buffer, OpSectionBufferConstIterator & iter,
1449  Uint32 * dst, Uint32 len);
1450  void release(OpSection&);
1451 
1452  // SchemaOp
1453 
1454  struct SchemaOp {
1455  Uint32 nextPool;
1456 
1457  enum OpState
1458  {
1459  OS_INITIAL = 0,
1460  OS_PARSE_MASTER = 1,
1461  OS_PARSING = 2,
1462  OS_PARSED = 3,
1463  OS_PREPARING = 4,
1464  OS_PREPARED = 5,
1465  OS_ABORTING_PREPARE = 6,
1466  OS_ABORTED_PREPARE = 7,
1467  OS_ABORTING_PARSE = 8,
1468  //OS_ABORTED_PARSE = 9, // Not used, op released
1469  OS_COMMITTING = 10,
1470  OS_COMMITTED = 11,
1471  OS_COMPLETING = 12,
1472  OS_COMPLETED = 13
1473  };
1474 
1475  Uint32 m_state;
1476  /*
1477  Return the "weight" of an operation state, used to determine
1478  the absolute order of operations.
1479  */
1480  static Uint32 weight(Uint32 state) {
1481  switch ((OpState) state) {
1482  case OS_INITIAL:
1483  return 0;
1484  case OS_PARSE_MASTER:
1485  return 1;
1486  case OS_PARSING:
1487  return 2;
1488  case OS_PARSED:
1489  return 5;
1490  case OS_PREPARING:
1491  return 6;
1492  case OS_PREPARED:
1493  return 9;
1494  case OS_ABORTING_PREPARE:
1495  return 8;
1496  case OS_ABORTED_PREPARE:
1497  return 7;
1498  case OS_ABORTING_PARSE:
1499  return 4;
1500  //case OS_ABORTED_PARSE = 9, // Not used, op released
1501  //return 3:
1502  case OS_COMMITTING:
1503  return 10;
1504  case OS_COMMITTED:
1505  return 11;
1506  case OS_COMPLETING:
1507  return 12;
1508  case OS_COMPLETED:
1509  return 13;
1510  }
1511  assert(false);
1512  return -1;
1513  }
1514  Uint32 m_restart;
1515  Uint32 op_key;
1516  Uint32 m_base_op_ptr_i;
1517  Uint32 nextHash;
1518  Uint32 prevHash;
1519  Uint32 hashValue() const {
1520  return op_key;
1521  }
1522  bool equal(const SchemaOp& rec) const {
1523  return op_key == rec.op_key;
1524  }
1525 
1526  Uint32 nextList;
1527  Uint32 prevList;
1528 
1529  // tx client or DICT master for recursive ops
1530  Uint32 m_clientRef;
1531  Uint32 m_clientData;
1532 
1533  // requestExtra and requestFlags from REQ and trans level
1534  Uint32 m_requestInfo;
1535 
1536  // the op belongs to this trans
1537  SchemaTransPtr m_trans_ptr;
1538 
1539  // type specific record (the other half of schema op)
1540  OpRecPtr m_oprec_ptr;
1541 
1542  // saved signal sections or other variable data
1543  OpSection m_section[3];
1544  Uint32 m_sections;
1545 
1546  // callback for use with sub-operations
1547  Callback m_callback;
1548 
1549  // link to an extra "helper" op and link back from it
1550  SchemaOpPtr m_oplnk_ptr;
1551  SchemaOpPtr m_opbck_ptr;
1552 
1553  // error always propagates to trans level
1554  ErrorInfo m_error;
1555 
1556  // Copy of original and current schema file entry
1557  Uint32 m_orig_entry_id;
1558  SchemaFile::TableEntry m_orig_entry;
1559 
1560  // magic is on when record is seized
1561  enum { DICT_MAGIC = 0xd1c70001 };
1562  Uint32 m_magic;
1563 
1564  SchemaOp() {
1565  m_restart = 0;
1566  m_clientRef = 0;
1567  m_clientData = 0;
1568  m_requestInfo = 0;
1569  m_trans_ptr.setNull();
1570  m_oprec_ptr.setNull();
1571  m_sections = 0;
1572  m_callback.m_callbackFunction = 0;
1573  m_callback.m_callbackData = 0;
1574  m_oplnk_ptr.setNull();
1575  m_opbck_ptr.setNull();
1576  m_magic = 0;
1577  m_base_op_ptr_i = RNIL;
1578 
1579  m_orig_entry_id = RNIL;
1580  m_orig_entry.init();
1581  }
1582 
1583  SchemaOp(Uint32 the_op_key) {
1584  op_key = the_op_key;
1585  }
1586 
1587 #ifdef VM_TRACE
1588  void print(NdbOut&) const;
1589 #endif
1590  };
1591 
1592  ArrayPool<SchemaOp> c_schemaOpPool;
1593  DLHashTable<SchemaOp> c_schemaOpHash;
1594 
1595  const OpInfo& getOpInfo(SchemaOpPtr op_ptr);
1596 
1597  // set or get the type specific record cast to the specific type
1598 
1599  template <class T>
1600  inline void
1601  setOpRec(SchemaOpPtr op_ptr, const Ptr<T> t_ptr) {
1602  OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
1603  ndbrequire(!t_ptr.isNull());
1604  oprec_ptr.i = t_ptr.i;
1605  oprec_ptr.p = static_cast<OpRec*>(t_ptr.p);
1606  ndbrequire(memcmp(t_ptr.p->m_opType, T::g_opInfo.m_opType, 4) == 0);
1607  }
1608 
1609  template <class T>
1610  inline void
1611  getOpRec(SchemaOpPtr op_ptr, Ptr<T>& t_ptr) {
1612  OpRecPtr oprec_ptr = op_ptr.p->m_oprec_ptr;
1613  ndbrequire(!oprec_ptr.isNull());
1614  t_ptr.i = oprec_ptr.i;
1615  t_ptr.p = static_cast<T*>(oprec_ptr.p);
1616  ndbrequire(memcmp(t_ptr.p->m_opType, T::g_opInfo.m_opType, 4) == 0);
1617  }
1618 
1619  // OpInfo m_seize, m_release
1620 
1621  template <class T>
1622  inline bool
1623  seizeOpRec(SchemaOpPtr op_ptr) {
1624  OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
1625  ArrayPool<T>& pool = T::getPool(this);
1626  Ptr<T> t_ptr;
1627  if (pool.seize(t_ptr)) {
1628  new (t_ptr.p) T();
1629  setOpRec<T>(op_ptr, t_ptr);
1630  return true;
1631  }
1632  oprec_ptr.setNull();
1633  return false;
1634  }
1635 
1636  template <class T>
1637  inline void
1638  releaseOpRec(SchemaOpPtr op_ptr) {
1639  OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
1640  ArrayPool<T>& pool = T::getPool(this);
1641  Ptr<T> t_ptr;
1642  getOpRec<T>(op_ptr, t_ptr);
1643  pool.release(t_ptr);
1644  oprec_ptr.setNull();
1645  }
1646 
1647  // seize / find / release, atomic on op rec + data rec
1648 
1649  bool seizeSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key, const OpInfo& info);
1650 
1651  template <class T>
1652  inline bool
1653  seizeSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key) {
1654  return seizeSchemaOp(op_ptr, op_key, T::g_opInfo);
1655  }
1656 
1657  template <class T>
1658  inline bool
1659  seizeSchemaOp(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, Uint32 op_key) {
1660  if (seizeSchemaOp<T>(op_ptr, op_key)) {
1661  getOpRec<T>(op_ptr, t_ptr);
1662  return true;
1663  }
1664  return false;
1665  }
1666 
1667  template <class T>
1668  inline bool
1669  seizeSchemaOp(SchemaOpPtr& op_ptr) {
1670  /*
1671  Store node id in high 8 bits to make op_key globally unique
1672  */
1673  Uint32 op_key =
1674  (getOwnNodeId() << 24) +
1675  ((c_opRecordSequence + 1) & 0x00FFFFFF);
1676  if (seizeSchemaOp<T>(op_ptr, op_key)) {
1677  c_opRecordSequence++;
1678  return true;
1679  }
1680  return false;
1681  }
1682 
1683  template <class T>
1684  inline bool
1685  seizeSchemaOp(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr) {
1686  if (seizeSchemaOp<T>(op_ptr)) {
1687  getOpRec<T>(op_ptr, t_ptr);
1688  return true;
1689  }
1690  return false;
1691  }
1692 
1693  bool findSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key);
1694 
1695  template <class T>
1696  inline bool
1697  findSchemaOp(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, Uint32 op_key) {
1698  if (findSchemaOp(op_ptr, op_key)) {
1699  getOpRec(op_ptr, t_ptr);
1700  return true;
1701  }
1702  return false;
1703  }
1704 
1705  void releaseSchemaOp(SchemaOpPtr& op_ptr);
1706 
1707  // copy signal sections to schema op sections
1708  const OpSection& getOpSection(SchemaOpPtr, Uint32 ss_no);
1709  bool saveOpSection(SchemaOpPtr, SectionHandle&, Uint32 ss_no);
1710  bool saveOpSection(SchemaOpPtr, SegmentedSectionPtr ss_ptr, Uint32 ss_no);
1711  void releaseOpSection(SchemaOpPtr, Uint32 ss_no);
1712 
1713  // add operation to transaction OpList
1714  void addSchemaOp(SchemaTransPtr, SchemaOpPtr&);
1715 
1716  void updateSchemaOpStep(SchemaTransPtr, SchemaOpPtr);
1717 
1718  // the link between SdhemaOp and DictObject (1-way now)
1719 
1720  bool hasDictObject(SchemaOpPtr);
1721  void getDictObject(SchemaOpPtr, DictObjectPtr&);
1722  void linkDictObject(SchemaOpPtr op_ptr, DictObjectPtr obj_ptr);
1723  void unlinkDictObject(SchemaOpPtr op_ptr);
1724  void seizeDictObject(SchemaOpPtr, DictObjectPtr&, const RopeHandle& name);
1725  bool findDictObject(SchemaOpPtr, DictObjectPtr&, const char* name);
1726  bool findDictObject(SchemaOpPtr, DictObjectPtr&, Uint32 obj_ptr_i);
1727  void releaseDictObject(SchemaOpPtr);
1728  void findDictObjectOp(SchemaOpPtr&, DictObjectPtr);
1729 
1730  /*
1731  * Trans client is the API client (not us, for recursive ops).
1732  * Its state is shared by SchemaTrans / TxHandle (for takeover).
1733  */
1734  struct TransClient {
1735  enum State {
1736  StateUndef = 0,
1737  BeginReq = 1, // begin trans received
1738  BeginReply = 2, // reply sent / waited for
1739  ParseReq = 3,
1740  ParseReply = 4,
1741  EndReq = 5,
1742  EndReply = 6
1743  };
1744  enum Flag {
1745  ApiFail = 1,
1746  Background = 2,
1747  TakeOver = 4,
1748  Commit = 8
1749  };
1750  };
1751 
1752  // SchemaTrans
1753 
1754  struct SchemaTrans {
1755  // ArrayPool
1756  Uint32 nextPool;
1757 
1758  enum TransState
1759  {
1760  TS_INITIAL = 0,
1761  TS_STARTING = 1, // Starting at participants
1762  TS_STARTED = 2, // Started (potentially with parsed ops)
1763  TS_PARSING = 3, // Parsing at participants
1764  TS_SUBOP = 4, // Creating subop
1765  TS_ROLLBACK_SP = 5, // Rolling back to SP (supported before prepare)
1766  TS_FLUSH_PREPARE = 6,
1767  TS_PREPARING = 7, // Preparing operations
1768  TS_ABORTING_PREPARE = 8, // Aborting prepared operations
1769  TS_ABORTING_PARSE = 9, // Aborting parsed operations
1770  TS_FLUSH_COMMIT = 10,
1771  TS_COMMITTING = 11,// Committing
1772  TS_FLUSH_COMPLETE = 12,// Committed
1773  TS_COMPLETING = 13,// Completing
1774  TS_ENDING = 14
1775  };
1776 
1777  Uint32 m_state;
1778  static Uint32 weight(Uint32 state) {
1779  /*
1780  Return the "weight" of a transaction state, used to determine
1781  the absolute order of beleived transaction states at master
1782  takeover.
1783  */
1784  switch ((TransState) state) {
1785  case TS_INITIAL:
1786  return 0;
1787  case TS_STARTING:
1788  return 1;
1789  case TS_STARTED:
1790  return 2;
1791  case TS_PARSING:
1792  return 3;
1793  case TS_SUBOP:
1794  return 6;
1795  case TS_ROLLBACK_SP:
1796  return 5;
1797  case TS_FLUSH_PREPARE:
1798  return 7;
1799  case TS_PREPARING:
1800  return 8;
1801  case TS_ABORTING_PREPARE:
1802  return 9;
1803  case TS_ABORTING_PARSE:
1804  return 4;
1805  case TS_FLUSH_COMMIT:
1806  return 10;
1807  case TS_COMMITTING:
1808  return 11;
1809  case TS_FLUSH_COMPLETE:
1810  return 12;
1811  case TS_COMPLETING:
1812  return 13;
1813  case TS_ENDING:
1814  return 14;
1815  }
1816  assert(false);
1817  return -1;
1818  }
1819  // DLHashTable
1820  Uint32 trans_key;
1821  Uint32 nextHash;
1822  Uint32 prevHash;
1823  Uint32 hashValue() const {
1824  return trans_key;
1825  }
1826  bool equal(const SchemaTrans& rec) const {
1827  return trans_key == rec.trans_key;
1828  }
1829 
1830  // DLFifoList where new ones are added at end
1831  Uint32 nextList;
1832  Uint32 prevList;
1833 
1834  bool m_isMaster;
1835  BlockReference m_masterRef;
1836 
1837  // requestFlags from begin/end trans
1838  Uint32 m_requestInfo;
1839 
1840  BlockReference m_clientRef;
1841  Uint32 m_obj_id;
1842  Uint32 m_transId;
1843  TransClient::State m_clientState;
1844  Uint32 m_clientFlags;
1845  Uint32 m_takeOverTxKey;
1846 
1847  NdbNodeBitmask m_nodes; // Nodes part of transaction
1848  NdbNodeBitmask m_ref_nodes; // Nodes replying REF to req
1849  SafeCounterHandle m_counter; // Outstanding REQ's
1850 
1851  Uint32 m_curr_op_ptr_i;
1852  DLFifoList<SchemaOp>::Head m_op_list;
1853 
1854  // Master takeover
1855  enum TakeoverRecoveryState
1856  {
1857  TRS_INITIAL = 0,
1858  TRS_ROLLFORWARD = 1,
1859  TRS_ROLLBACK = 2
1860  };
1861  Uint32 m_master_recovery_state;
1862  // These are common states all nodes must achieve
1863  // to be able to be involved in total rollforward/rollbackward
1864  Uint32 m_rollforward_op;
1865  Uint32 m_rollforward_op_state;
1866  Uint32 m_rollback_op;
1867  Uint32 m_rollback_op_state;
1868  Uint32 m_lowest_trans_state;
1869  Uint32 m_highest_trans_state;
1870  // Flag for signalling partial rollforward check during master takeover
1871  bool check_partial_rollforward;
1872  // Flag for signalling that already completed operation is recreated
1873  bool ressurected_op;
1874 
1875  // request for lock/unlock
1876  DictLockReq m_lockReq;
1877 
1878  // callback (not yet used)
1879  Callback m_callback;
1880 
1881  // error is reset after each req/reply
1882  ErrorInfo m_error;
1883 
1887  MutexHandle2<DIH_START_LCP_MUTEX> m_commit_mutex;
1888 
1889  bool m_flush_prepare;
1890  bool m_flush_commit;
1891  bool m_flush_complete;
1892  bool m_flush_end;
1893  bool m_wait_gcp_on_commit;
1894 
1895  // magic is on when record is seized
1896  enum { DICT_MAGIC = 0xd1c70002 };
1897  Uint32 m_magic;
1898 
1899  SchemaTrans() {
1900  m_state = TS_INITIAL;
1901  m_isMaster = false;
1902  m_masterRef = 0;
1903  m_requestInfo = 0;
1904  m_clientRef = 0;
1905  m_transId = 0;
1906  m_clientState = TransClient::StateUndef;
1907  m_clientFlags = 0;
1908  m_takeOverTxKey = 0;
1909  bzero(&m_lockReq, sizeof(m_lockReq));
1910  m_callback.m_callbackFunction = 0;
1911  m_callback.m_callbackData = 0;
1912  m_magic = 0;
1913  m_obj_id = RNIL;
1914  m_flush_prepare = false;
1915  m_flush_commit = false;
1916  m_flush_complete = false;
1917  m_flush_end = false;
1918  m_wait_gcp_on_commit = true;
1919  }
1920 
1921  SchemaTrans(Uint32 the_trans_key) {
1922  trans_key = the_trans_key;
1923  }
1924 
1925 #ifdef VM_TRACE
1926  void print(NdbOut&) const;
1927 #endif
1928  };
1929 
1930  Uint32 check_read_obj(Uint32 objId, Uint32 transId = 0);
1931  Uint32 check_read_obj(SchemaFile::TableEntry*, Uint32 transId = 0);
1932  Uint32 check_write_obj(Uint32 objId, Uint32 transId = 0);
1933  Uint32 check_write_obj(Uint32, Uint32, SchemaFile::EntryState, ErrorInfo&);
1934 
1935  ArrayPool<SchemaTrans> c_schemaTransPool;
1936  DLHashTable<SchemaTrans> c_schemaTransHash;
1937  DLFifoList<SchemaTrans> c_schemaTransList;
1938  Uint32 c_schemaTransCount;
1939 
1940  bool seizeSchemaTrans(SchemaTransPtr&, Uint32 trans_key);
1941  bool seizeSchemaTrans(SchemaTransPtr&);
1942  bool findSchemaTrans(SchemaTransPtr&, Uint32 trans_key);
1943  void releaseSchemaTrans(SchemaTransPtr&);
1944 
1945  // coordinator
1946  void createSubOps(Signal*, SchemaOpPtr, bool first = false);
1947  void abortSubOps(Signal*, SchemaOpPtr, ErrorInfo);
1948 
1949  void trans_recv_reply(Signal*, SchemaTransPtr);
1950  void trans_start_recv_reply(Signal*, SchemaTransPtr);
1951  void trans_parse_recv_reply(Signal*, SchemaTransPtr);
1952 
1953  void trans_prepare_start(Signal*, SchemaTransPtr);
1954  void trans_prepare_first(Signal*, SchemaTransPtr);
1955  void trans_prepare_recv_reply(Signal*, SchemaTransPtr);
1956  void trans_prepare_next(Signal*, SchemaTransPtr, SchemaOpPtr);
1957  void trans_prepare_done(Signal*, SchemaTransPtr);
1958 
1959  void trans_abort_prepare_start(Signal*, SchemaTransPtr);
1960  void trans_abort_prepare_recv_reply(Signal*, SchemaTransPtr);
1961  void trans_abort_prepare_next(Signal*, SchemaTransPtr, SchemaOpPtr);
1962  void trans_abort_prepare_done(Signal*, SchemaTransPtr);
1963 
1964  void trans_abort_parse_start(Signal*, SchemaTransPtr);
1965  void trans_abort_parse_recv_reply(Signal*, SchemaTransPtr);
1966  void trans_abort_parse_next(Signal*, SchemaTransPtr, SchemaOpPtr);
1967  void trans_abort_parse_done(Signal*, SchemaTransPtr);
1968 
1969  void trans_rollback_sp_start(Signal* signal, SchemaTransPtr);
1970  void trans_rollback_sp_recv_reply(Signal* signal, SchemaTransPtr);
1971  void trans_rollback_sp_next(Signal* signal, SchemaTransPtr, SchemaOpPtr);
1972  void trans_rollback_sp_done(Signal* signal, SchemaTransPtr, SchemaOpPtr);
1973 
1974  void trans_commit_start(Signal*, SchemaTransPtr);
1975  void trans_commit_wait_gci(Signal*);
1976  void trans_commit_mutex_locked(Signal*, Uint32, Uint32);
1977  void trans_commit_first(Signal*, SchemaTransPtr);
1978  void trans_commit_recv_reply(Signal*, SchemaTransPtr);
1979  void trans_commit_next(Signal*, SchemaTransPtr, SchemaOpPtr);
1980  void trans_commit_done(Signal* signal, SchemaTransPtr);
1981  void trans_commit_mutex_unlocked(Signal*, Uint32, Uint32);
1982 
1983  void trans_complete_start(Signal* signal, SchemaTransPtr);
1984  void trans_complete_first(Signal* signal, SchemaTransPtr);
1985  void trans_complete_next(Signal*, SchemaTransPtr, SchemaOpPtr);
1986  void trans_complete_recv_reply(Signal*, SchemaTransPtr);
1987  void trans_complete_done(Signal*, SchemaTransPtr);
1988 
1989  void trans_end_start(Signal* signal, SchemaTransPtr);
1990  void trans_end_recv_reply(Signal*, SchemaTransPtr);
1991 
1992  void trans_log(SchemaTransPtr);
1993  Uint32 trans_log_schema_op(SchemaOpPtr,
1994  Uint32 objectId,
1995  const SchemaFile::TableEntry*);
1996 
1997  void trans_log_schema_op_abort(SchemaOpPtr);
1998  void trans_log_schema_op_complete(SchemaOpPtr);
1999 
2000  void handle_master_takeover(Signal*);
2001  void check_takeover_replies(Signal*);
2002  void trans_recover(Signal*, SchemaTransPtr);
2003  void check_partial_trans_abort_prepare_next(SchemaTransPtr,
2004  NdbNodeBitmask &,
2005  SchemaOpPtr);
2006  void check_partial_trans_abort_parse_next(SchemaTransPtr,
2007  NdbNodeBitmask &,
2008  SchemaOpPtr);
2009  void check_partial_trans_complete_start(SchemaTransPtr, NdbNodeBitmask &);
2010  void check_partial_trans_commit_start(SchemaTransPtr, NdbNodeBitmask &);
2011  void check_partial_trans_commit_next(SchemaTransPtr,
2012  NdbNodeBitmask &,
2013  SchemaOpPtr);
2014  void check_partial_trans_end_recv_reply(SchemaTransPtr);
2015 
2016  // participant
2017  void recvTransReq(Signal*);
2018  void recvTransParseReq(Signal*, SchemaTransPtr,
2019  Uint32 op_key, const OpInfo& info,
2020  Uint32 requestInfo);
2021  void runTransSlave(Signal*, SchemaTransPtr);
2022  void update_op_state(SchemaOpPtr);
2023  void sendTransConf(Signal*, SchemaOpPtr);
2024  void sendTransConf(Signal*, SchemaTransPtr);
2025  void sendTransConfRelease(Signal*, SchemaTransPtr);
2026  void sendTransRef(Signal*, SchemaOpPtr);
2027  void sendTransRef(Signal*, SchemaTransPtr);
2028 
2029  void slave_run_start(Signal*, const SchemaTransImplReq*);
2030  void slave_run_parse(Signal*, SchemaTransPtr, const SchemaTransImplReq*);
2031  void slave_run_flush(Signal*, SchemaTransPtr, const SchemaTransImplReq*);
2032  void slave_writeSchema_conf(Signal*, Uint32, Uint32);
2033  void slave_commit_mutex_locked(Signal*, Uint32, Uint32);
2034  void slave_commit_mutex_unlocked(Signal*, Uint32, Uint32);
2035 
2036  // reply to trans client for begin/end trans
2037  void sendTransClientReply(Signal*, SchemaTransPtr);
2038 
2039  // on DB slave node failure exclude the node from transactions
2040  void handleTransSlaveFail(Signal*, Uint32 failedNode);
2041 
2042  // common code for different op types
2043 
2044  /*
2045  * Client REQ starts with find trans and add op record.
2046  * Sets request info in op and default request type in impl_req.
2047  */
2048  template <class T, class Req, class ImplReq>
2049  inline void
2050  startClientReq(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr,
2051  const Req* req, ImplReq*& impl_req, ErrorInfo& error)
2052  {
2053  SchemaTransPtr trans_ptr;
2054 
2055  const Uint32 requestInfo = req->requestInfo;
2056  const Uint32 requestType = DictSignal::getRequestType(requestInfo);
2057  const Uint32 requestExtra = DictSignal::getRequestExtra(requestInfo);
2058  const bool localTrans = (requestInfo & DictSignal::RF_LOCAL_TRANS);
2059 
2060  if (getOwnNodeId() != c_masterNodeId && !localTrans) {
2061  jam();
2062  setError(error, SchemaTransImplRef::NotMaster, __LINE__);
2063  return;
2064  }
2065 
2066  if (!findSchemaTrans(trans_ptr, req->transKey)) {
2067  jam();
2068  setError(error, SchemaTransImplRef::InvalidTransKey, __LINE__);
2069  return;
2070  }
2071 
2072  if (trans_ptr.p->m_transId != req->transId) {
2073  jam();
2074  setError(error, SchemaTransImplRef::InvalidTransId, __LINE__);
2075  return;
2076  }
2077 
2078  if (!seizeSchemaOp(op_ptr, t_ptr)) {
2079  jam();
2080  setError(error, SchemaTransImplRef::TooManySchemaOps, __LINE__);
2081  return;
2082  }
2083 
2084  trans_ptr.p->m_clientState = TransClient::ParseReq;
2085 
2086  DictSignal::setRequestExtra(op_ptr.p->m_requestInfo, requestExtra);
2087  DictSignal::addRequestFlags(op_ptr.p->m_requestInfo, requestInfo);
2088 
2089  // add op and global flags from trans level
2090  addSchemaOp(trans_ptr, op_ptr);
2091 
2092  // impl_req was passed via reference
2093  impl_req = &t_ptr.p->m_request;
2094 
2095  impl_req->senderRef = reference();
2096  impl_req->senderData = op_ptr.p->op_key;
2097  impl_req->requestType = requestType;
2098 
2099  // client of this REQ (trans client or us, recursively)
2100  op_ptr.p->m_clientRef = req->clientRef;
2101  op_ptr.p->m_clientData = req->clientData;
2102  }
2103 
2104  /*
2105  * The other half of client REQ processing. On error starts
2106  * rollback of current client op and its sub-ops.
2107  */
2108  void handleClientReq(Signal*, SchemaOpPtr, SectionHandle&);
2109 
2110  // DICT receives recursive or internal CONF or REF
2111 
2112  template <class Conf>
2113  inline void
2114  handleDictConf(Signal* signal, const Conf* conf) {
2115  D("handleDictConf" << V(conf->senderData));
2116  ndbrequire(signal->getNoOfSections() == 0);
2117 
2118  Callback callback;
2119  bool ok = findCallback(callback, conf->senderData);
2120  ndbrequire(ok);
2121  execute(signal, callback, 0);
2122  }
2123 
2124  template <class Ref>
2125  inline void
2126  handleDictRef(Signal* signal, const Ref* ref) {
2127  D("handleDictRef" << V(ref->senderData) << V(ref->errorCode));
2128  ndbrequire(signal->getNoOfSections() == 0);
2129 
2130  Callback callback;
2131  bool ok = findCallback(callback, ref->senderData);
2132  ndbrequire(ok);
2133  ndbrequire(ref->errorCode != 0);
2134  execute(signal, callback, ref->errorCode);
2135  }
2136 
2137  /*
2138  * TxHandle
2139  *
2140  * DICT as schema trans client. TxHandle is the client-side record.
2141  * It has same role as NdbDictInterface::Tx in NDB API. It is used
2142  * for following:
2143  *
2144  * - create or drop table at NR/SR [not yet]
2145  * - build or activate indexes at NR/SR
2146  * - take over client trans if client requests this
2147  * - take over client trans when client API has failed
2148  */
2149 
2150  struct TxHandle {
2151  // ArrayPool
2152  Uint32 nextPool;
2153 
2154  // DLHashTable
2155  Uint32 tx_key;
2156  Uint32 nextHash;
2157  Uint32 prevHash;
2158  Uint32 hashValue() const {
2159  return tx_key;
2160  }
2161  bool equal(const TxHandle& rec) const {
2162  return tx_key == rec.tx_key;
2163  }
2164 
2165  Uint32 m_requestInfo; // global flags are passed to schema trans
2166  Uint32 m_transId;
2167  Uint32 m_transKey;
2168  Uint32 m_userData;
2169 
2170  // when take over for background or for failed API
2171  TransClient::State m_clientState;
2172  Uint32 m_clientFlags;
2173  BlockReference m_takeOverRef;
2174  Uint32 m_takeOverTransId;
2175 
2176  Callback m_callback;
2177  ErrorInfo m_error;
2178 
2179  // magic is on when record is seized
2180  enum { DICT_MAGIC = 0xd1c70003 };
2181  Uint32 m_magic;
2182 
2183  TxHandle() {
2184  m_requestInfo = 0;
2185  m_transId = 0;
2186  m_transKey = 0;
2187  m_userData = 0;
2188  m_clientState = TransClient::StateUndef;
2189  m_clientFlags = 0;
2190  m_takeOverRef = 0;
2191  m_takeOverTransId = 0;
2192  m_callback.m_callbackFunction = 0;
2193  m_callback.m_callbackData = 0;
2194  m_magic = 0;
2195  }
2196 
2197  TxHandle(Uint32 the_tx_key) {
2198  tx_key = the_tx_key;
2199  }
2200 #ifdef VM_TRACE
2201  void print(NdbOut&) const;
2202 #endif
2203  };
2204 
2205  ArrayPool<TxHandle> c_txHandlePool;
2206  DLHashTable<TxHandle> c_txHandleHash;
2207 
2208  bool seizeTxHandle(TxHandlePtr&);
2209  bool findTxHandle(TxHandlePtr&, Uint32 tx_key);
2210  void releaseTxHandle(TxHandlePtr&);
2211 
2212  void beginSchemaTrans(Signal*, TxHandlePtr);
2213  void endSchemaTrans(Signal*, TxHandlePtr, Uint32 flags = 0);
2214 
2215  void handleApiFail(Signal*, Uint32 failedApiNode);
2216  void takeOverTransClient(Signal*, SchemaTransPtr);
2217  void runTransClientTakeOver(Signal*, Uint32 tx_key, Uint32 ret);
2218  void finishApiFail(Signal*, TxHandlePtr tx_ptr);
2219  void apiFailBlockHandling(Signal*, Uint32 failedApiNode);
2220 
2221  /*
2222  * Callback key is for different record types in some cases.
2223  * For example a CONF can be for SchemaOp or for TxHandle.
2224  * This looks for match for one of op_key/trans_key/tx_key.
2225  */
2226  bool findCallback(Callback& callback, Uint32 any_key);
2227 
2228  // MODULE: CreateTable
2229 
2230  struct CreateTableRec : public OpRec {
2231  static const OpInfo g_opInfo;
2232 
2234  getPool(Dbdict* dict) {
2235  return dict->c_createTableRecPool;
2236  }
2237 
2238  CreateTabReq m_request;
2239 
2240  // wl3600_todo check mutex name and number later
2241  MutexHandle2<DIH_START_LCP_MUTEX> m_startLcpMutex;
2242 
2243  // long signal memory for temp use
2244  Uint32 m_tabInfoPtrI;
2245  Uint32 m_fragmentsPtrI;
2246 
2247  // connect pointers towards DIH and LQH
2248  Uint32 m_dihAddFragPtr;
2249  Uint32 m_lqhFragPtr;
2250 
2251  // who is using local create tab
2252  Callback m_callback;
2253 
2254  // flag if this op has been aborted in RT_PREPARE phase
2255  bool m_abortPrepareDone;
2256 
2257  CreateTableRec() :
2258  OpRec(g_opInfo, (Uint32*)&m_request) {
2259  memset(&m_request, 0, sizeof(m_request));
2260  m_tabInfoPtrI = RNIL;
2261  m_fragmentsPtrI = RNIL;
2262  m_dihAddFragPtr = RNIL;
2263  m_lqhFragPtr = RNIL;
2264  m_abortPrepareDone = false;
2265  }
2266 
2267 #ifdef VM_TRACE
2268  void print(NdbOut&) const;
2269 #endif
2270  };
2271 
2272  typedef Ptr<CreateTableRec> CreateTableRecPtr;
2273  ArrayPool<CreateTableRec> c_createTableRecPool;
2274 
2275  // OpInfo
2276  bool createTable_seize(SchemaOpPtr);
2277  void createTable_release(SchemaOpPtr);
2278  //
2279  void createTable_parse(Signal*, bool master,
2280  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2281  bool createTable_subOps(Signal*, SchemaOpPtr);
2282  void createTable_reply(Signal*, SchemaOpPtr, ErrorInfo);
2283  //
2284  void createTable_prepare(Signal*, SchemaOpPtr);
2285  void createTable_commit(Signal*, SchemaOpPtr);
2286  void createTable_complete(Signal*, SchemaOpPtr);
2287  //
2288  void createTable_abortParse(Signal*, SchemaOpPtr);
2289  void createTable_abortPrepare(Signal*, SchemaOpPtr);
2290 
2291  // prepare
2292  void createTab_writeTableConf(Signal*, Uint32 op_key, Uint32 ret);
2293  void createTab_local(Signal*, SchemaOpPtr, OpSection fragSec, Callback*);
2294  void createTab_dih(Signal*, SchemaOpPtr);
2295  void createTab_localComplete(Signal*, Uint32 op_key, Uint32 ret);
2296 
2297  // commit
2298  void createTab_activate(Signal*, SchemaOpPtr, Callback*);
2299  void createTab_alterComplete(Signal*, Uint32 op_key, Uint32 ret);
2300 
2301  // abort prepare
2302  void createTable_abortLocalConf(Signal*, Uint32 aux_op_key, Uint32 ret);
2303 
2304  // MODULE: DropTable
2305 
2306  struct DropTableRec : public OpRec {
2307  static const OpInfo g_opInfo;
2308 
2310  getPool(Dbdict* dict) {
2311  return dict->c_dropTableRecPool;
2312  }
2313 
2314  DropTabReq m_request;
2315 
2316  // wl3600_todo check mutex name and number later
2317  MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
2318 
2319  Uint32 m_block;
2320  enum { BlockCount = 5 };
2321  Uint32 m_blockNo[BlockCount];
2322  Callback m_callback;
2323 
2324  DropTableRec() :
2325  OpRec(g_opInfo, (Uint32*)&m_request) {
2326  memset(&m_request, 0, sizeof(m_request));
2327  m_block = 0;
2328  }
2329 
2330 #ifdef VM_TRACE
2331  void print(NdbOut&) const;
2332 #endif
2333  };
2334 
2335  typedef Ptr<DropTableRec> DropTableRecPtr;
2336  ArrayPool<DropTableRec> c_dropTableRecPool;
2337 
2338  // OpInfo
2339  bool dropTable_seize(SchemaOpPtr);
2340  void dropTable_release(SchemaOpPtr);
2341  //
2342  void dropTable_parse(Signal*, bool master,
2343  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2344  bool dropTable_subOps(Signal*, SchemaOpPtr);
2345  void dropTable_reply(Signal*, SchemaOpPtr, ErrorInfo);
2346  //
2347  void dropTable_prepare(Signal*, SchemaOpPtr);
2348  void dropTable_commit(Signal*, SchemaOpPtr);
2349  void dropTable_complete(Signal*, SchemaOpPtr);
2350  //
2351  void dropTable_abortParse(Signal*, SchemaOpPtr);
2352  void dropTable_abortPrepare(Signal*, SchemaOpPtr);
2353 
2354  // prepare
2355  void dropTable_backup_mutex_locked(Signal*, Uint32 op_key, Uint32 ret);
2356 
2357  // commit
2358  void dropTable_commit_nextStep(Signal*, SchemaOpPtr);
2359  void dropTable_commit_fromLocal(Signal*, Uint32 op_key, Uint32 errorCode);
2360  void dropTable_commit_done(Signal*, SchemaOpPtr);
2361 
2362  // complete
2363  void dropTable_complete_nextStep(Signal*, SchemaOpPtr);
2364  void dropTable_complete_fromLocal(Signal*, Uint32 op_key);
2365  void dropTable_complete_done(Signal*, Uint32 op_key, Uint32 ret);
2366 
2367  // MODULE: AlterTable
2368 
2369  struct AlterTableRec : public OpRec {
2370  static const OpInfo g_opInfo;
2371 
2373  getPool(Dbdict* dict) {
2374  return dict->c_alterTableRecPool;
2375  }
2376 
2377  AlterTabReq m_request;
2378 
2379  // added attributes
2380  Uint32 m_newAttrData[2 * MAX_ATTRIBUTES_IN_TABLE];
2381 
2382  // wl3600_todo check mutex name and number later
2383  MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
2384 
2385  // current and new temporary work table
2386  TableRecordPtr m_tablePtr;
2387  TableRecordPtr m_newTablePtr;
2388  Uint32 m_newTable_realObjectId;
2389 
2390  // before image
2391  RopeHandle m_oldTableName;
2392  RopeHandle m_oldFrmData;
2393 
2394  // connect ptr towards TUP, DIH, LQH
2395  Uint32 m_dihAddFragPtr;
2396  Uint32 m_lqhFragPtr;
2397 
2398  // local blocks to process
2399  enum { BlockCount = 3 };
2400  Uint32 m_blockNo[BlockCount];
2401  Uint32 m_blockIndex;
2402 
2403  // used for creating subops for add partitions, wrt ordered index
2404  bool m_sub_reorg_commit;
2405  bool m_sub_reorg_complete;
2406  bool m_sub_add_frag;
2407  Uint32 m_sub_add_frag_index_ptr;
2408  bool m_sub_trigger;
2409  bool m_sub_copy_data;
2410  bool m_sub_suma_enable;
2411  bool m_sub_suma_filter;
2412 
2413  AlterTableRec() :
2414  OpRec(g_opInfo, (Uint32*)&m_request) {
2415  memset(&m_request, 0, sizeof(m_request));
2416  memset(&m_newAttrData, 0, sizeof(m_newAttrData));
2417  m_tablePtr.setNull();
2418  m_newTablePtr.setNull();
2419  m_dihAddFragPtr = RNIL;
2420  m_lqhFragPtr = RNIL;
2421  m_blockNo[0] = DBLQH;
2422  m_blockNo[1] = DBDIH;
2423  m_blockNo[2] = DBTC;
2424  m_blockIndex = 0;
2425  m_sub_add_frag_index_ptr = RNIL;
2426  m_sub_add_frag = false;
2427  m_sub_reorg_commit = false;
2428  m_sub_reorg_complete = false;
2429  m_sub_trigger = false;
2430  m_sub_copy_data = false;
2431  m_sub_suma_enable = false;
2432  m_sub_suma_filter = false;
2433  }
2434 #ifdef VM_TRACE
2435  void print(NdbOut&) const;
2436 #endif
2437  };
2438 
2439  typedef Ptr<AlterTableRec> AlterTableRecPtr;
2440  ArrayPool<AlterTableRec> c_alterTableRecPool;
2441 
2442  // OpInfo
2443  bool alterTable_seize(SchemaOpPtr);
2444  void alterTable_release(SchemaOpPtr);
2445  //
2446  void alterTable_parse(Signal*, bool master,
2447  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2448  bool alterTable_subOps(Signal*, SchemaOpPtr);
2449  void alterTable_reply(Signal*, SchemaOpPtr, ErrorInfo);
2450  //
2451  void alterTable_prepare(Signal*, SchemaOpPtr);
2452  void alterTable_commit(Signal*, SchemaOpPtr);
2453  void alterTable_complete(Signal*, SchemaOpPtr);
2454  //
2455  void alterTable_abortParse(Signal*, SchemaOpPtr);
2456  void alterTable_abortPrepare(Signal*, SchemaOpPtr);
2457 
2458  void alterTable_toCopyData(Signal* signal, SchemaOpPtr op_ptr);
2459  void alterTable_fromCopyData(Signal*, Uint32 op_key, Uint32 ret);
2460 
2461  // prepare phase
2462  void alterTable_backup_mutex_locked(Signal*, Uint32 op_key, Uint32 ret);
2463  void alterTable_toLocal(Signal*, SchemaOpPtr);
2464  void alterTable_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
2465 
2466  void alterTable_toAlterIndex(Signal*, SchemaOpPtr);
2467  void alterTable_fromAlterIndex(Signal*, Uint32 op_key, Uint32 ret);
2468 
2469  void alterTable_toReorgTable(Signal*, SchemaOpPtr, Uint32 step);
2470  void alterTable_fromReorgTable(Signal*, Uint32 op_key, Uint32 ret);
2471 
2472  void alterTable_toCreateTrigger(Signal* signal, SchemaOpPtr op_ptr);
2473  void alterTable_fromCreateTrigger(Signal*, Uint32 op_key, Uint32 ret);
2474 
2475  void alterTable_toSumaSync(Signal* signal, SchemaOpPtr op_ptr, Uint32);
2476 
2477  // commit phase
2478  void alterTable_toCommitComplete(Signal*, SchemaOpPtr, Uint32 = ~Uint32(0));
2479  void alterTable_fromCommitComplete(Signal*, Uint32 op_key, Uint32 ret);
2480  void alterTab_writeTableConf(Signal*, Uint32 op_key, Uint32 ret);
2481 
2482  // abort
2483  void alterTable_abortToLocal(Signal*, SchemaOpPtr);
2484  void alterTable_abortFromLocal(Signal*, Uint32 op_key, Uint32 ret);
2485 
2486  Uint32 check_supported_add_fragment(Uint16*, const Uint16*);
2487  Uint32 check_supported_reorg(Uint32, Uint32);
2488 
2489  // MODULE: CreateIndex
2490 
2491  typedef struct {
2492  Uint32 old_index;
2493  Uint32 attr_id;
2494  Uint32 attr_ptr_i;
2495  } AttributeMap[MAX_ATTRIBUTES_IN_INDEX];
2496 
2497  struct CreateIndexRec : public OpRec {
2498  CreateIndxImplReq m_request;
2499  char m_indexName[MAX_TAB_NAME_SIZE];
2500  IndexAttributeList m_attrList;
2501  AttributeMask m_attrMask;
2502  AttributeMap m_attrMap;
2503  Uint32 m_bits;
2504  Uint32 m_fragmentType;
2505  Uint32 m_indexKeyLength;
2506 
2507  // reflection
2508  static const OpInfo g_opInfo;
2509 
2511  getPool(Dbdict* dict) {
2512  return dict->c_createIndexRecPool;
2513  }
2514 
2515  // sub-operation counters
2516  bool m_sub_create_table;
2517  bool m_sub_alter_index;
2518 
2519  CreateIndexRec() :
2520  OpRec(g_opInfo, (Uint32*)&m_request) {
2521  memset(&m_request, 0, sizeof(m_request));
2522  memset(m_indexName, 0, sizeof(m_indexName));
2523  memset(&m_attrList, 0, sizeof(m_attrList));
2524  m_attrMask.clear();
2525  memset(m_attrMap, 0, sizeof(m_attrMap));
2526  m_bits = 0;
2527  m_fragmentType = 0;
2528  m_indexKeyLength = 0;
2529  m_sub_create_table = false;
2530  m_sub_alter_index = false;
2531  }
2532 #ifdef VM_TRACE
2533  void print(NdbOut&) const;
2534 #endif
2535  };
2536 
2537  typedef Ptr<CreateIndexRec> CreateIndexRecPtr;
2538  ArrayPool<CreateIndexRec> c_createIndexRecPool;
2539 
2540  // OpInfo
2541  bool createIndex_seize(SchemaOpPtr);
2542  void createIndex_release(SchemaOpPtr);
2543  //
2544  void createIndex_parse(Signal*, bool master,
2545  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2546  bool createIndex_subOps(Signal*, SchemaOpPtr);
2547  void createIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
2548  //
2549  void createIndex_prepare(Signal*, SchemaOpPtr);
2550  void createIndex_commit(Signal*, SchemaOpPtr);
2551  void createIndex_complete(Signal*, SchemaOpPtr);
2552  //
2553  void createIndex_abortParse(Signal*, SchemaOpPtr);
2554  void createIndex_abortPrepare(Signal*, SchemaOpPtr);
2555 
2556  // sub-ops
2557  void createIndex_toCreateTable(Signal*, SchemaOpPtr);
2558  void createIndex_fromCreateTable(Signal*, Uint32 op_key, Uint32 ret);
2559  void createIndex_toAlterIndex(Signal*, SchemaOpPtr);
2560  void createIndex_fromAlterIndex(Signal*, Uint32 op_key, Uint32 ret);
2561 
2562  // MODULE: DropIndex
2563 
2564  struct DropIndexRec : public OpRec {
2565  DropIndxImplReq m_request;
2566 
2567  // reflection
2568  static const OpInfo g_opInfo;
2569 
2571  getPool(Dbdict* dict) {
2572  return dict->c_dropIndexRecPool;
2573  }
2574 
2575  // sub-operation counters
2576  bool m_sub_alter_index;
2577  bool m_sub_drop_table;
2578 
2579  DropIndexRec() :
2580  OpRec(g_opInfo, (Uint32*)&m_request) {
2581  memset(&m_request, 0, sizeof(m_request));
2582  m_sub_alter_index = false;
2583  m_sub_drop_table = false;
2584  }
2585 #ifdef VM_TRACE
2586  void print(NdbOut&) const;
2587 #endif
2588  };
2589 
2590  typedef Ptr<DropIndexRec> DropIndexRecPtr;
2591  ArrayPool<DropIndexRec> c_dropIndexRecPool;
2592 
2593  // OpInfo
2594  bool dropIndex_seize(SchemaOpPtr);
2595  void dropIndex_release(SchemaOpPtr);
2596  //
2597  void dropIndex_parse(Signal*, bool master,
2598  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2599  bool dropIndex_subOps(Signal*, SchemaOpPtr);
2600  void dropIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
2601  //
2602  void dropIndex_prepare(Signal*, SchemaOpPtr);
2603  void dropIndex_commit(Signal*, SchemaOpPtr);
2604  void dropIndex_complete(Signal*, SchemaOpPtr);
2605  //
2606  void dropIndex_abortParse(Signal*, SchemaOpPtr);
2607  void dropIndex_abortPrepare(Signal*, SchemaOpPtr);
2608 
2609  // sub-ops
2610  void dropIndex_toDropTable(Signal*, SchemaOpPtr);
2611  void dropIndex_fromDropTable(Signal*, Uint32 op_key, Uint32 ret);
2612  void dropIndex_toAlterIndex(Signal*, SchemaOpPtr);
2613  void dropIndex_fromAlterIndex(Signal*, Uint32 op_key, Uint32 ret);
2614 
2615  // MODULE: AlterIndex
2616 
2617  struct TriggerTmpl {
2618  const char* nameFormat; // contains one %u for index id
2619  const TriggerInfo triggerInfo;
2620  };
2621 
2622  static const TriggerTmpl g_hashIndexTriggerTmpl[1];
2623  static const TriggerTmpl g_orderedIndexTriggerTmpl[1];
2624  static const TriggerTmpl g_buildIndexConstraintTmpl[1];
2625  static const TriggerTmpl g_reorgTriggerTmpl[1];
2626 
2627  struct AlterIndexRec : public OpRec {
2628  AlterIndxImplReq m_request;
2629  IndexAttributeList m_attrList;
2630  AttributeMask m_attrMask;
2631 
2632  // reflection
2633  static const OpInfo g_opInfo;
2634 
2636  getPool(Dbdict* dict) {
2637  return dict->c_alterIndexRecPool;
2638  }
2639 
2640  // sub-operation counters (true = done or skip)
2641  const TriggerTmpl* m_triggerTmpl;
2642  bool m_sub_trigger;
2643  bool m_sub_build_index;
2644  bool m_sub_index_stat_dml;
2645  bool m_sub_index_stat_mon;
2646 
2647  // prepare phase
2648  bool m_tc_index_done;
2649 
2650  // connect pointers towards DIH and LQH
2651  Uint32 m_dihAddFragPtr;
2652  Uint32 m_lqhFragPtr;
2653 
2654  AlterIndexRec() :
2655  OpRec(g_opInfo, (Uint32*)&m_request) {
2656  memset(&m_request, 0, sizeof(m_request));
2657  memset(&m_attrList, 0, sizeof(m_attrList));
2658  m_attrMask.clear();
2659  m_triggerTmpl = 0;
2660  m_sub_trigger = false;
2661  m_sub_build_index = false;
2662  m_sub_index_stat_dml = false;
2663  m_sub_index_stat_mon = false;
2664  m_tc_index_done = false;
2665  }
2666 
2667 #ifdef VM_TRACE
2668  void print(NdbOut&) const;
2669 #endif
2670  };
2671 
2672  typedef Ptr<AlterIndexRec> AlterIndexRecPtr;
2673  ArrayPool<AlterIndexRec> c_alterIndexRecPool;
2674 
2675  // OpInfo
2676  bool alterIndex_seize(SchemaOpPtr);
2677  void alterIndex_release(SchemaOpPtr);
2678  //
2679  void alterIndex_parse(Signal*, bool master,
2680  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2681  bool alterIndex_subOps(Signal*, SchemaOpPtr);
2682  void alterIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
2683  //
2684  void alterIndex_prepare(Signal*, SchemaOpPtr);
2685  void alterIndex_commit(Signal*, SchemaOpPtr);
2686  void alterIndex_complete(Signal*, SchemaOpPtr);
2687  //
2688  void alterIndex_abortParse(Signal*, SchemaOpPtr);
2689  void alterIndex_abortPrepare(Signal*, SchemaOpPtr);
2690 
2691  // parse phase sub-routine
2692  void set_index_stat_frag(Signal*, TableRecordPtr indexPtr);
2693 
2694  // sub-ops
2695  void alterIndex_toCreateTrigger(Signal*, SchemaOpPtr);
2696  void alterIndex_atCreateTrigger(Signal*, SchemaOpPtr);
2697  void alterIndex_fromCreateTrigger(Signal*, Uint32 op_key, Uint32 ret);
2698  void alterIndex_toDropTrigger(Signal*, SchemaOpPtr);
2699  void alterIndex_atDropTrigger(Signal*, SchemaOpPtr);
2700  void alterIndex_fromDropTrigger(Signal*, Uint32 op_key, Uint32 ret);
2701  void alterIndex_toBuildIndex(Signal*, SchemaOpPtr);
2702  void alterIndex_fromBuildIndex(Signal*, Uint32 op_key, Uint32 ret);
2703  void alterIndex_toIndexStat(Signal*, SchemaOpPtr);
2704  void alterIndex_fromIndexStat(Signal*, Uint32 op_key, Uint32 ret);
2705 
2706  // prepare phase
2707  void alterIndex_toCreateLocal(Signal*, SchemaOpPtr);
2708  void alterIndex_toDropLocal(Signal*, SchemaOpPtr);
2709  void alterIndex_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
2710 
2711  void alterIndex_toAddPartitions(Signal*, SchemaOpPtr);
2712  void alterIndex_fromAddPartitions(Signal*, Uint32 op_key, Uint32 ret);
2713 
2714  // abort
2715  void alterIndex_abortFromLocal(Signal*, Uint32 op_key, Uint32 ret);
2716 
2717  // MODULE: BuildIndex
2718 
2719  // this prepends 1 column used for FRAGMENT in hash index table key
2720  typedef Id_array<1 + MAX_ATTRIBUTES_IN_INDEX> FragAttributeList;
2721 
2722  struct BuildIndexRec : public OpRec {
2723  static const OpInfo g_opInfo;
2724 
2726  getPool(Dbdict* dict) {
2727  return dict->c_buildIndexRecPool;
2728  }
2729 
2730  BuildIndxImplReq m_request;
2731 
2732  IndexAttributeList m_indexKeyList;
2733  FragAttributeList m_tableKeyList;
2734  AttributeMask m_attrMask;
2735 
2736  // sub-operation counters (CTr BIn DTr)
2737  const TriggerTmpl* m_triggerTmpl;
2738  Uint32 m_subOpCount; // 3 or 0
2739  Uint32 m_subOpIndex;
2740 
2741  // do the actual build (i.e. not done in a sub-op BIn)
2742  bool m_doBuild;
2743 
2744  BuildIndexRec() :
2745  OpRec(g_opInfo, (Uint32*)&m_request) {
2746  memset(&m_request, 0, sizeof(m_request));
2747  memset(&m_indexKeyList, 0, sizeof(m_indexKeyList));
2748  memset(&m_tableKeyList, 0, sizeof(m_tableKeyList));
2749  m_attrMask.clear();
2750  m_triggerTmpl = 0;
2751  m_subOpCount = 0;
2752  m_subOpIndex = 0;
2753  m_doBuild = false;
2754  }
2755  };
2756 
2757  typedef Ptr<BuildIndexRec> BuildIndexRecPtr;
2758  ArrayPool<BuildIndexRec> c_buildIndexRecPool;
2759 
2760  // OpInfo
2761  bool buildIndex_seize(SchemaOpPtr);
2762  void buildIndex_release(SchemaOpPtr);
2763  //
2764  void buildIndex_parse(Signal*, bool master,
2765  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2766  bool buildIndex_subOps(Signal*, SchemaOpPtr);
2767  void buildIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
2768  //
2769  void buildIndex_prepare(Signal*, SchemaOpPtr);
2770  void buildIndex_commit(Signal*, SchemaOpPtr);
2771  void buildIndex_complete(Signal*, SchemaOpPtr);
2772  //
2773  void buildIndex_abortParse(Signal*, SchemaOpPtr);
2774  void buildIndex_abortPrepare(Signal*, SchemaOpPtr);
2775 
2776  // parse phase
2777  void buildIndex_toCreateConstraint(Signal*, SchemaOpPtr);
2778  void buildIndex_atCreateConstraint(Signal*, SchemaOpPtr);
2779  void buildIndex_fromCreateConstraint(Signal*, Uint32 op_key, Uint32 ret);
2780  //
2781  void buildIndex_toBuildIndex(Signal*, SchemaOpPtr);
2782  void buildIndex_fromBuildIndex(Signal*, Uint32 op_key, Uint32 ret);
2783  //
2784  void buildIndex_toDropConstraint(Signal*, SchemaOpPtr);
2785  void buildIndex_atDropConstraint(Signal*, SchemaOpPtr);
2786  void buildIndex_fromDropConstraint(Signal*, Uint32 op_key, Uint32 ret);
2787 
2788  // prepare phase
2789  void buildIndex_toLocalBuild(Signal*, SchemaOpPtr);
2790  void buildIndex_fromLocalBuild(Signal*, Uint32 op_key, Uint32 ret);
2791 
2792  // commit phase
2793  void buildIndex_toLocalOnline(Signal*, SchemaOpPtr);
2794  void buildIndex_fromLocalOnline(Signal*, Uint32 op_key, Uint32 ret);
2795 
2796  // MODULE: IndexStat
2797 
2798  struct IndexStatRec : public OpRec {
2799  static const OpInfo g_opInfo;
2800 
2802  getPool(Dbdict* dict) {
2803  return dict->c_indexStatRecPool;
2804  }
2805 
2806  IndexStatImplReq m_request;
2807 
2808  // sub-operation counters
2809  const TriggerTmpl* m_triggerTmpl;
2810  Uint32 m_subOpCount;
2811  Uint32 m_subOpIndex;
2812 
2813  IndexStatRec() :
2814  OpRec(g_opInfo, (Uint32*)&m_request) {
2815  memset(&m_request, 0, sizeof(m_request));
2816  m_subOpCount = 0;
2817  m_subOpIndex = 0;
2818  }
2819  };
2820 
2821  typedef Ptr<IndexStatRec> IndexStatRecPtr;
2822  ArrayPool<IndexStatRec> c_indexStatRecPool;
2823 
2824  Uint32 c_indexStatAutoCreate;
2825  Uint32 c_indexStatAutoUpdate;
2826  Uint32 c_indexStatBgId;
2827 
2828  // OpInfo
2829  bool indexStat_seize(SchemaOpPtr);
2830  void indexStat_release(SchemaOpPtr);
2831  //
2832  void indexStat_parse(Signal*, bool master,
2833  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2834  bool indexStat_subOps(Signal*, SchemaOpPtr);
2835  void indexStat_reply(Signal*, SchemaOpPtr, ErrorInfo);
2836  //
2837  void indexStat_prepare(Signal*, SchemaOpPtr);
2838  void indexStat_commit(Signal*, SchemaOpPtr);
2839  void indexStat_complete(Signal*, SchemaOpPtr);
2840  //
2841  void indexStat_abortParse(Signal*, SchemaOpPtr);
2842  void indexStat_abortPrepare(Signal*, SchemaOpPtr);
2843 
2844  // parse phase
2845  void indexStat_toIndexStat(Signal*, SchemaOpPtr, Uint32 requestType);
2846  void indexStat_fromIndexStat(Signal*, Uint32 op_key, Uint32 ret);
2847 
2848  // prepare phase
2849  void indexStat_toLocalStat(Signal*, SchemaOpPtr);
2850  void indexStat_fromLocalStat(Signal*, Uint32 op_key, Uint32 ret);
2851 
2852  // background processing of stat requests
2853  void indexStatBg_process(Signal*);
2854  void indexStatBg_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
2855  void indexStatBg_fromIndexStat(Signal*, Uint32 tx_key, Uint32 ret);
2856  void indexStatBg_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
2857  void indexStatBg_sendContinueB(Signal*);
2858 
2859  // MODULE: CreateHashMap
2860 
2861  struct HashMapRecord {
2862  HashMapRecord(){}
2863 
2864  /* Table id (array index in DICT and other blocks) */
2865  union {
2866  Uint32 m_object_id;
2867  Uint32 key;
2868  };
2869  Uint32 m_obj_ptr_i; // in HashMap_pool
2870  Uint32 m_object_version;
2871 
2872  RopeHandle m_name;
2873 
2877  Uint32 m_map_ptr_i;
2878  union {
2879  Uint32 nextPool;
2880  Uint32 nextHash;
2881  };
2882  Uint32 prevHash;
2883 
2884  Uint32 hashValue() const { return key;}
2885  bool equal(const HashMapRecord& obj) const { return key == obj.key;}
2886 
2887  };
2888  typedef Ptr<HashMapRecord> HashMapPtr;
2889  typedef ArrayPool<HashMapRecord> HashMap_pool;
2890  typedef KeyTableImpl<HashMap_pool, HashMapRecord> HashMap_hash;
2891 
2892  HashMap_pool c_hash_map_pool;
2893  HashMap_hash c_hash_map_hash;
2894  RSS_AP_SNAPSHOT(c_hash_map_pool);
2895  RSS_AP_SNAPSHOT(g_hash_map);
2896 
2897  struct CreateHashMapRec : public OpRec {
2898  static const OpInfo g_opInfo;
2899 
2901  getPool(Dbdict* dict) {
2902  return dict->c_createHashMapRecPool;
2903  }
2904 
2905  CreateHashMapImplReq m_request;
2906 
2907  CreateHashMapRec() :
2908  OpRec(g_opInfo, (Uint32*)&m_request) {
2909  memset(&m_request, 0, sizeof(m_request));
2910  }
2911  };
2912 
2913  typedef Ptr<CreateHashMapRec> CreateHashMapRecPtr;
2914  ArrayPool<CreateHashMapRec> c_createHashMapRecPool;
2915  void execCREATE_HASH_MAP_REQ(Signal* signal);
2916 
2917  // OpInfo
2918  bool createHashMap_seize(SchemaOpPtr);
2919  void createHashMap_release(SchemaOpPtr);
2920  //
2921  void createHashMap_parse(Signal*, bool master,
2922  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2923  bool createHashMap_subOps(Signal*, SchemaOpPtr);
2924  void createHashMap_reply(Signal*, SchemaOpPtr, ErrorInfo);
2925  //
2926  void createHashMap_prepare(Signal*, SchemaOpPtr);
2927  void createHashMap_writeObjConf(Signal* signal, Uint32, Uint32);
2928  void createHashMap_commit(Signal*, SchemaOpPtr);
2929  void createHashMap_complete(Signal*, SchemaOpPtr);
2930  //
2931  void createHashMap_abortParse(Signal*, SchemaOpPtr);
2932  void createHashMap_abortPrepare(Signal*, SchemaOpPtr);
2933 
2934  void packHashMapIntoPages(SimpleProperties::Writer&, Ptr<HashMapRecord>);
2935 
2936  // MODULE: CopyData
2937 
2938  struct CopyDataRec : public OpRec {
2939  static const OpInfo g_opInfo;
2940 
2942  getPool(Dbdict* dict) {
2943  return dict->c_copyDataRecPool;
2944  }
2945 
2946  CopyDataImplReq m_request;
2947 
2948  CopyDataRec() :
2949  OpRec(g_opInfo, (Uint32*)&m_request) {
2950  memset(&m_request, 0, sizeof(m_request));
2951  }
2952  };
2953 
2954  typedef Ptr<CopyDataRec> CopyDataRecPtr;
2955  ArrayPool<CopyDataRec> c_copyDataRecPool;
2956  void execCOPY_DATA_REQ(Signal* signal);
2957  void execCOPY_DATA_REF(Signal* signal);
2958  void execCOPY_DATA_CONF(Signal* signal);
2959  void execCOPY_DATA_IMPL_REF(Signal* signal);
2960  void execCOPY_DATA_IMPL_CONF(Signal* signal);
2961 
2962  // OpInfo
2963  bool copyData_seize(SchemaOpPtr);
2964  void copyData_release(SchemaOpPtr);
2965  //
2966  void copyData_parse(Signal*, bool master,
2967  SchemaOpPtr, SectionHandle&, ErrorInfo&);
2968  bool copyData_subOps(Signal*, SchemaOpPtr);
2969  void copyData_reply(Signal*, SchemaOpPtr, ErrorInfo);
2970  //
2971  void copyData_prepare(Signal*, SchemaOpPtr);
2972  void copyData_fromLocal(Signal*, Uint32, Uint32);
2973  void copyData_commit(Signal*, SchemaOpPtr);
2974  void copyData_complete(Signal*, SchemaOpPtr);
2975  //
2976  void copyData_abortParse(Signal*, SchemaOpPtr);
2977  void copyData_abortPrepare(Signal*, SchemaOpPtr);
2978 
2982  struct OpSignalUtil : OpRecordCommon{
2983  Callback m_callback;
2984  Uint32 m_userData;
2985  };
2986  typedef Ptr<OpSignalUtil> OpSignalUtilPtr;
2987 
2991  struct OpSubEvent : OpRecordCommon {
2992  Uint32 m_senderRef;
2993  Uint32 m_senderData;
2994  Uint32 m_errorCode;
2995 
2996  Uint32 m_gsn;
2997  Uint32 m_subscriptionId;
2998  Uint32 m_subscriptionKey;
2999  Uint32 m_subscriberRef;
3000  Uint32 m_subscriberData;
3001  Uint8 m_buckets_per_ng[256]; // For SUB_START_REQ
3002  union {
3003  SubStartConf m_sub_start_conf;
3004  SubStopConf m_sub_stop_conf;
3005  };
3006  RequestTracker m_reqTracker;
3007  };
3008  typedef Ptr<OpSubEvent> OpSubEventPtr;
3009 
3013  struct OpCreateEvent : OpRecordCommon {
3014  // original request (event id will be added)
3015  CreateEvntReq m_request;
3016  //AttributeMask m_attrListBitmask;
3017  // AttributeList m_attrList;
3018  sysTab_NDBEVENTS_0 m_eventRec;
3019  // char m_eventName[MAX_TAB_NAME_SIZE];
3020  // char m_tableName[MAX_TAB_NAME_SIZE];
3021 
3022  // coordinator DICT
3023  RequestTracker m_reqTracker;
3024  // state info
3025  CreateEvntReq::RequestType m_requestType;
3026  // error info
3027  Uint32 m_errorCode;
3028  Uint32 m_errorLine;
3029  Uint32 m_errorNode; /* also used to store master node id
3030  in case of NotMaster */
3031  // ctor
3032  OpCreateEvent() {
3033  memset(&m_request, 0, sizeof(m_request));
3034  m_requestType = CreateEvntReq::RT_UNDEFINED;
3035  m_errorCode = CreateEvntRef::NoError;
3036  m_errorLine = 0;
3037  m_errorNode = 0;
3038  }
3039  void init(const CreateEvntReq* req, Dbdict* dp) {
3040  m_request = *req;
3041  m_errorCode = CreateEvntRef::NoError;
3042  m_errorLine = 0;
3043  m_errorNode = 0;
3044  m_requestType = req->getRequestType();
3045  }
3046  bool hasError() {
3047  return m_errorCode != CreateEvntRef::NoError;
3048  }
3049  void setError(const CreateEvntRef* ref) {
3050  if (ref != 0 && ! hasError()) {
3051  m_errorCode = ref->getErrorCode();
3052  m_errorLine = ref->getErrorLine();
3053  m_errorNode = ref->getErrorNode();
3054  }
3055  }
3056 
3057  };
3058  typedef Ptr<OpCreateEvent> OpCreateEventPtr;
3059 
3063  struct OpDropEvent : OpRecordCommon {
3064  // original request
3065  DropEvntReq m_request;
3066  // char m_eventName[MAX_TAB_NAME_SIZE];
3067  sysTab_NDBEVENTS_0 m_eventRec;
3068  RequestTracker m_reqTracker;
3069  // error info
3070  Uint32 m_errorCode;
3071  Uint32 m_errorLine;
3072  Uint32 m_errorNode;
3073  // ctor
3074  OpDropEvent() {
3075  memset(&m_request, 0, sizeof(m_request));
3076  m_errorCode = 0;
3077  m_errorLine = 0;
3078  m_errorNode = 0;
3079  }
3080  void init(const DropEvntReq* req) {
3081  m_request = *req;
3082  m_errorCode = 0;
3083  m_errorLine = 0;
3084  m_errorNode = 0;
3085  }
3086  bool hasError() {
3087  return m_errorCode != 0;
3088  }
3089  void setError(const DropEvntRef* ref) {
3090  if (ref != 0 && ! hasError()) {
3091  m_errorCode = ref->getErrorCode();
3092  m_errorLine = ref->getErrorLine();
3093  m_errorNode = ref->getErrorNode();
3094  }
3095  }
3096  };
3097  typedef Ptr<OpDropEvent> OpDropEventPtr;
3098 
3099  // MODULE: CreateTrigger
3100  struct CreateTriggerRec : public OpRec {
3101  static const OpInfo g_opInfo;
3102 
3104  getPool(Dbdict* dict) {
3105  return dict->c_createTriggerRecPool;
3106  }
3107 
3108  CreateTrigImplReq m_request;
3109 
3110  char m_triggerName[MAX_TAB_NAME_SIZE];
3111  // sub-operation counters
3112  bool m_created;
3113  bool m_main_op;
3114  bool m_sub_dst; // Create trigger destination
3115  bool m_sub_src; // Create trigger source
3116  Uint32 m_block_list[1]; // Only 1 block...
3117 
3118  CreateTriggerRec() :
3119  OpRec(g_opInfo, (Uint32*)&m_request) {
3120  memset(&m_request, 0, sizeof(m_request));
3121  memset(m_triggerName, 0, sizeof(m_triggerName));
3122  m_main_op = true;
3123  m_sub_src = false;
3124  m_sub_dst = false;
3125  m_created = false;
3126  }
3127  };
3128 
3129  typedef Ptr<CreateTriggerRec> CreateTriggerRecPtr;
3130  ArrayPool<CreateTriggerRec> c_createTriggerRecPool;
3131 
3132  // OpInfo
3133  bool createTrigger_seize(SchemaOpPtr);
3134  void createTrigger_release(SchemaOpPtr);
3135  //
3136  void createTrigger_parse(Signal*, bool master,
3137  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3138  void createTrigger_parse_endpoint(Signal*, SchemaOpPtr op_ptr, ErrorInfo&);
3139  bool createTrigger_subOps(Signal*, SchemaOpPtr);
3140  void createTrigger_toCreateEndpoint(Signal*, SchemaOpPtr,
3141  CreateTrigReq::EndpointFlag);
3142  void createTrigger_fromCreateEndpoint(Signal*, Uint32, Uint32);
3143  void createTrigger_create_drop_trigger_operation(Signal*,SchemaOpPtr,
3144  ErrorInfo& error);
3145 
3146  void createTrigger_reply(Signal*, SchemaOpPtr, ErrorInfo);
3147  //
3148  void createTrigger_prepare(Signal*, SchemaOpPtr);
3149  void createTrigger_prepare_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3150  void createTrigger_commit(Signal*, SchemaOpPtr);
3151  void createTrigger_commit_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3152  void createTrigger_complete(Signal*, SchemaOpPtr);
3153  //
3154  void createTrigger_abortParse(Signal*, SchemaOpPtr);
3155  void createTrigger_abortPrepare(Signal*, SchemaOpPtr);
3156  void createTrigger_abortPrepare_fromLocal(Signal*, Uint32, Uint32);
3157  void send_create_trig_req(Signal*, SchemaOpPtr);
3158 
3159  // MODULE: DropTrigger
3160 
3161  struct DropTriggerRec : public OpRec {
3162  static const OpInfo g_opInfo;
3163 
3165  getPool(Dbdict* dict) {
3166  return dict->c_dropTriggerRecPool;
3167  }
3168 
3169  DropTrigImplReq m_request;
3170 
3171  char m_triggerName[MAX_TAB_NAME_SIZE];
3172  // sub-operation counters
3173  bool m_main_op;
3174  bool m_sub_dst; // Create trigger destination
3175  bool m_sub_src; // Create trigger source
3176  Uint32 m_block_list[1]; // Only 1 block...
3177 
3178  DropTriggerRec() :
3179  OpRec(g_opInfo, (Uint32*)&m_request) {
3180  memset(&m_request, 0, sizeof(m_request));
3181  memset(m_triggerName, 0, sizeof(m_triggerName));
3182  m_main_op = true;
3183  m_sub_src = false;
3184  m_sub_dst = false;
3185  }
3186  };
3187 
3188  typedef Ptr<DropTriggerRec> DropTriggerRecPtr;
3189  ArrayPool<DropTriggerRec> c_dropTriggerRecPool;
3190 
3191  // OpInfo
3192  bool dropTrigger_seize(SchemaOpPtr);
3193  void dropTrigger_release(SchemaOpPtr);
3194  //
3195  void dropTrigger_parse(Signal*, bool master,
3196  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3197  void dropTrigger_parse_endpoint(Signal*, SchemaOpPtr op_ptr, ErrorInfo&);
3198  bool dropTrigger_subOps(Signal*, SchemaOpPtr);
3199  void dropTrigger_toDropEndpoint(Signal*, SchemaOpPtr,
3200  DropTrigReq::EndpointFlag);
3201  void dropTrigger_fromDropEndpoint(Signal*, Uint32, Uint32);
3202  void dropTrigger_reply(Signal*, SchemaOpPtr, ErrorInfo);
3203  //
3204  void dropTrigger_prepare(Signal*, SchemaOpPtr);
3205  void dropTrigger_commit(Signal*, SchemaOpPtr);
3206  void dropTrigger_commit_fromLocal(Signal*, Uint32, Uint32);
3207  void dropTrigger_complete(Signal*, SchemaOpPtr);
3208  //
3209  void dropTrigger_abortParse(Signal*, SchemaOpPtr);
3210  void dropTrigger_abortPrepare(Signal*, SchemaOpPtr);
3211 
3212  void send_drop_trig_req(Signal*, SchemaOpPtr);
3213 
3214 
3215  // MODULE: CreateFilegroup
3216 
3217  struct CreateFilegroupRec : public OpRec {
3218  bool m_parsed, m_prepared;
3219  CreateFilegroupImplReq m_request;
3220  Uint32 m_warningFlags;
3221 
3222  // reflection
3223  static const OpInfo g_opInfo;
3224 
3226  getPool(Dbdict* dict) {
3227  return dict->c_createFilegroupRecPool;
3228  }
3229 
3230  CreateFilegroupRec() :
3231  OpRec(g_opInfo, (Uint32*)&m_request) {
3232  memset(&m_request, 0, sizeof(m_request));
3233  m_parsed = m_prepared = false;
3234  m_warningFlags = 0;
3235  }
3236  };
3237 
3238  typedef Ptr<CreateFilegroupRec> CreateFilegroupRecPtr;
3239  ArrayPool<CreateFilegroupRec> c_createFilegroupRecPool;
3240 
3241  // OpInfo
3242  bool createFilegroup_seize(SchemaOpPtr);
3243  void createFilegroup_release(SchemaOpPtr);
3244  //
3245  void createFilegroup_parse(Signal*, bool master,
3246  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3247  bool createFilegroup_subOps(Signal*, SchemaOpPtr);
3248  void createFilegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3249  //
3250  void createFilegroup_prepare(Signal*, SchemaOpPtr);
3251  void createFilegroup_commit(Signal*, SchemaOpPtr);
3252  void createFilegroup_complete(Signal*, SchemaOpPtr);
3253  //
3254  void createFilegroup_abortParse(Signal*, SchemaOpPtr);
3255  void createFilegroup_abortPrepare(Signal*, SchemaOpPtr);
3256 
3257  void createFilegroup_fromLocal(Signal*, Uint32, Uint32);
3258  void createFilegroup_fromWriteObjInfo(Signal*, Uint32, Uint32);
3259 
3260  // MODULE: CreateFile
3261 
3262  struct CreateFileRec : public OpRec {
3263  bool m_parsed, m_prepared;
3264  CreateFileImplReq m_request;
3265  Uint32 m_warningFlags;
3266 
3267  // reflection
3268  static const OpInfo g_opInfo;
3269 
3271  getPool(Dbdict* dict) {
3272  return dict->c_createFileRecPool;
3273  }
3274 
3275  CreateFileRec() :
3276  OpRec(g_opInfo, (Uint32*)&m_request) {
3277  memset(&m_request, 0, sizeof(m_request));
3278  m_parsed = m_prepared = false;
3279  m_warningFlags = 0;
3280  }
3281  };
3282 
3283  typedef Ptr<CreateFileRec> CreateFileRecPtr;
3284  ArrayPool<CreateFileRec> c_createFileRecPool;
3285 
3286  // OpInfo
3287  bool createFile_seize(SchemaOpPtr);
3288  void createFile_release(SchemaOpPtr);
3289  //
3290  void createFile_parse(Signal*, bool master,
3291  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3292  bool createFile_subOps(Signal*, SchemaOpPtr);
3293  void createFile_reply(Signal*, SchemaOpPtr, ErrorInfo);
3294  //
3295  void createFile_prepare(Signal*, SchemaOpPtr);
3296  void createFile_commit(Signal*, SchemaOpPtr);
3297  void createFile_complete(Signal*, SchemaOpPtr);
3298  //
3299  void createFile_abortParse(Signal*, SchemaOpPtr);
3300  void createFile_abortPrepare(Signal*, SchemaOpPtr);
3301 
3302  void createFile_fromLocal(Signal*, Uint32, Uint32);
3303  void createFile_fromWriteObjInfo(Signal*, Uint32, Uint32);
3304 
3305  // MODULE: DropFilegroup
3306 
3307  struct DropFilegroupRec : public OpRec {
3308  bool m_parsed, m_prepared;
3309  DropFilegroupImplReq m_request;
3310 
3311  // reflection
3312  static const OpInfo g_opInfo;
3313 
3315  getPool(Dbdict* dict) {
3316  return dict->c_dropFilegroupRecPool;
3317  }
3318 
3319  DropFilegroupRec() :
3320  OpRec(g_opInfo, (Uint32*)&m_request) {
3321  memset(&m_request, 0, sizeof(m_request));
3322  m_parsed = m_prepared = false;
3323  }
3324  };
3325 
3326  typedef Ptr<DropFilegroupRec> DropFilegroupRecPtr;
3327  ArrayPool<DropFilegroupRec> c_dropFilegroupRecPool;
3328 
3329  // OpInfo
3330  bool dropFilegroup_seize(SchemaOpPtr);
3331  void dropFilegroup_release(SchemaOpPtr);
3332  //
3333  void dropFilegroup_parse(Signal*, bool master,
3334  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3335  bool dropFilegroup_subOps(Signal*, SchemaOpPtr);
3336  void dropFilegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3337  //
3338  void dropFilegroup_prepare(Signal*, SchemaOpPtr);
3339  void dropFilegroup_commit(Signal*, SchemaOpPtr);
3340  void dropFilegroup_complete(Signal*, SchemaOpPtr);
3341  //
3342  void dropFilegroup_abortParse(Signal*, SchemaOpPtr);
3343  void dropFilegroup_abortPrepare(Signal*, SchemaOpPtr);
3344 
3345  void dropFilegroup_fromLocal(Signal*, Uint32, Uint32);
3346 
3347  // MODULE: DropFile
3348 
3349  struct DropFileRec : public OpRec {
3350  bool m_parsed, m_prepared;
3351  DropFileImplReq m_request;
3352 
3353  // reflection
3354  static const OpInfo g_opInfo;
3355 
3357  getPool(Dbdict* dict) {
3358  return dict->c_dropFileRecPool;
3359  }
3360 
3361  DropFileRec() :
3362  OpRec(g_opInfo, (Uint32*)&m_request) {
3363  memset(&m_request, 0, sizeof(m_request));
3364  m_parsed = m_prepared = false;
3365  }
3366  };
3367 
3368  typedef Ptr<DropFileRec> DropFileRecPtr;
3369  ArrayPool<DropFileRec> c_dropFileRecPool;
3370 
3371  // OpInfo
3372  bool dropFile_seize(SchemaOpPtr);
3373  void dropFile_release(SchemaOpPtr);
3374  //
3375  void dropFile_parse(Signal*, bool master,
3376  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3377  bool dropFile_subOps(Signal*, SchemaOpPtr);
3378  void dropFile_reply(Signal*, SchemaOpPtr, ErrorInfo);
3379  //
3380  void dropFile_prepare(Signal*, SchemaOpPtr);
3381  void dropFile_commit(Signal*, SchemaOpPtr);
3382  void dropFile_complete(Signal*, SchemaOpPtr);
3383  //
3384  void dropFile_abortParse(Signal*, SchemaOpPtr);
3385  void dropFile_abortPrepare(Signal*, SchemaOpPtr);
3386 
3387  void dropFile_fromLocal(Signal*, Uint32, Uint32);
3388 
3389  // MODULE: CreateNodegroup
3390 
3391  struct CreateNodegroupRec : public OpRec {
3392  bool m_map_created;
3393  CreateNodegroupImplReq m_request;
3394 
3395  // reflection
3396  static const OpInfo g_opInfo;
3397 
3399  getPool(Dbdict* dict) {
3400  return dict->c_createNodegroupRecPool;
3401  }
3402 
3403  CreateNodegroupRec() :
3404  OpRec(g_opInfo, (Uint32*)&m_request) {
3405  memset(&m_request, 0, sizeof(m_request));
3406  m_map_created = false;
3407  m_blockIndex = RNIL;
3408  m_blockCnt = RNIL;
3409  m_cnt_waitGCP = RNIL;
3410  m_wait_gcp_type = RNIL;
3411  m_substartstop_blocked = false;
3412  m_gcp_blocked = false;
3413  }
3414 
3415  enum { BlockCount = 3 };
3416  Uint32 m_blockNo[BlockCount];
3417  Uint32 m_blockIndex;
3418  Uint32 m_blockCnt;
3419  Uint32 m_cnt_waitGCP;
3420  Uint32 m_wait_gcp_type;
3421  bool m_gcp_blocked;
3422  bool m_substartstop_blocked;
3423  };
3424 
3425  typedef Ptr<CreateNodegroupRec> CreateNodegroupRecPtr;
3426  ArrayPool<CreateNodegroupRec> c_createNodegroupRecPool;
3427 
3428  // OpInfo
3429  void execCREATE_NODEGROUP_REQ(Signal*);
3430  void execCREATE_NODEGROUP_IMPL_REF(Signal*);
3431  void execCREATE_NODEGROUP_IMPL_CONF(Signal*);
3432 
3433  bool createNodegroup_seize(SchemaOpPtr);
3434  void createNodegroup_release(SchemaOpPtr);
3435  //
3436  void createNodegroup_parse(Signal*, bool master,
3437  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3438  bool createNodegroup_subOps(Signal*, SchemaOpPtr);
3439  void createNodegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3440  //
3441  void createNodegroup_prepare(Signal*, SchemaOpPtr);
3442  void createNodegroup_commit(Signal*, SchemaOpPtr);
3443  void createNodegroup_complete(Signal*, SchemaOpPtr);
3444  //
3445  void createNodegroup_abortParse(Signal*, SchemaOpPtr);
3446  void createNodegroup_abortPrepare(Signal*, SchemaOpPtr);
3447 
3448  void createNodegroup_toLocal(Signal*, SchemaOpPtr);
3449  void createNodegroup_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3450  void createNodegroup_fromCreateHashMap(Signal*, Uint32 op_key, Uint32 ret);
3451  void createNodegroup_fromWaitGCP(Signal*, Uint32 op_key, Uint32 ret);
3452  void createNodegroup_fromBlockSubStartStop(Signal*, Uint32 op_key, Uint32);
3453 
3454  void execCREATE_HASH_MAP_REF(Signal* signal);
3455  void execCREATE_HASH_MAP_CONF(Signal* signal);
3456 
3457  // MODULE: DropNodegroup
3458 
3459  struct DropNodegroupRec : public OpRec {
3460  DropNodegroupImplReq m_request;
3461 
3462  // reflection
3463  static const OpInfo g_opInfo;
3464 
3466  getPool(Dbdict* dict) {
3467  return dict->c_dropNodegroupRecPool;
3468  }
3469 
3470  DropNodegroupRec() :
3471  OpRec(g_opInfo, (Uint32*)&m_request) {
3472  memset(&m_request, 0, sizeof(m_request));
3473  m_blockIndex = RNIL;
3474  m_blockCnt = RNIL;
3475  m_cnt_waitGCP = RNIL;
3476  m_wait_gcp_type = RNIL;
3477  m_gcp_blocked = false;
3478  m_substartstop_blocked = false;
3479  }
3480 
3481  enum { BlockCount = 3 };
3482  Uint32 m_blockNo[BlockCount];
3483  Uint32 m_blockIndex;
3484  Uint32 m_blockCnt;
3485  Uint32 m_cnt_waitGCP;
3486  Uint32 m_wait_gcp_type;
3487  bool m_gcp_blocked;
3488  bool m_substartstop_blocked;
3489  };
3490 
3491  typedef Ptr<DropNodegroupRec> DropNodegroupRecPtr;
3492  ArrayPool<DropNodegroupRec> c_dropNodegroupRecPool;
3493 
3494  // OpInfo
3495  void execDROP_NODEGROUP_REQ(Signal*);
3496  void execDROP_NODEGROUP_IMPL_REF(Signal*);
3497  void execDROP_NODEGROUP_IMPL_CONF(Signal*);
3498 
3499  bool dropNodegroup_seize(SchemaOpPtr);
3500  void dropNodegroup_release(SchemaOpPtr);
3501  //
3502  void dropNodegroup_parse(Signal*, bool master,
3503  SchemaOpPtr, SectionHandle&, ErrorInfo&);
3504  bool dropNodegroup_subOps(Signal*, SchemaOpPtr);
3505  void dropNodegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3506  //
3507  void dropNodegroup_prepare(Signal*, SchemaOpPtr);
3508  void dropNodegroup_commit(Signal*, SchemaOpPtr);
3509  void dropNodegroup_complete(Signal*, SchemaOpPtr);
3510  //
3511  void dropNodegroup_abortParse(Signal*, SchemaOpPtr);
3512  void dropNodegroup_abortPrepare(Signal*, SchemaOpPtr);
3513 
3514  void dropNodegroup_toLocal(Signal*, SchemaOpPtr);
3515  void dropNodegroup_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3516  void dropNodegroup_fromWaitGCP(Signal*, Uint32 op_key, Uint32 ret);
3517  void dropNodegroup_fromBlockSubStartStop(Signal*, Uint32 op_key, Uint32);
3518 
3522  // Common operation record pool
3523 public:
3524  STATIC_CONST( opCreateEventSize = sizeof(OpCreateEvent) );
3525  STATIC_CONST( opSubEventSize = sizeof(OpSubEvent) );
3526  STATIC_CONST( opDropEventSize = sizeof(OpDropEvent) );
3527  STATIC_CONST( opSignalUtilSize = sizeof(OpSignalUtil) );
3528 private:
3529 #define PTR_ALIGN(n) ((((n)+sizeof(void*)-1)>>2)&~((sizeof(void*)-1)>>2))
3530  union OpRecordUnion {
3531  Uint32 u_opCreateEvent [PTR_ALIGN(opCreateEventSize)];
3532  Uint32 u_opSubEvent [PTR_ALIGN(opSubEventSize)];
3533  Uint32 u_opDropEvent [PTR_ALIGN(opDropEventSize)];
3534  Uint32 u_opSignalUtil [PTR_ALIGN(opSignalUtilSize)];
3535  Uint32 nextPool;
3536  };
3537  ArrayPool<OpRecordUnion> c_opRecordPool;
3538 
3539  // Operation records
3544 
3545  // Unique key for operation XXX move to some system table
3546  Uint32 c_opRecordSequence;
3547 
3548  void handleNdbdFailureCallback(Signal* signal,
3549  Uint32 failedNodeId,
3550  Uint32 ignoredRc);
3551  void handleApiFailureCallback(Signal* signal,
3552  Uint32 failedNodeId,
3553  Uint32 ignoredRc);
3554  // Statement blocks
3555 
3556  /* ------------------------------------------------------------ */
3557  // Start/Restart Handling
3558  /* ------------------------------------------------------------ */
3559  void sendSTTORRY(Signal* signal);
3560  void sendNDB_STTORRY(Signal* signal);
3561  void initSchemaFile(Signal* signal);
3562 
3563  /* ------------------------------------------------------------ */
3564  // Drop Table Handling
3565  /* ------------------------------------------------------------ */
3566  void releaseTableObject(Uint32 tableId, bool removeFromHash = true);
3567 
3568  /* ------------------------------------------------------------ */
3569  // General Stuff
3570  /* ------------------------------------------------------------ */
3571  Uint32 getFreeObjId(Uint32 minId, bool both = false);
3572  Uint32 getFreeTableRecord(Uint32 primaryTableId);
3573  Uint32 getFreeTriggerRecord();
3574  bool getNewAttributeRecord(TableRecordPtr tablePtr,
3575  AttributeRecordPtr & attrPtr);
3576  void packTableIntoPages(Signal* signal);
3577  void packTableIntoPages(SimpleProperties::Writer &, TableRecordPtr, Signal* =0);
3578  void packFilegroupIntoPages(SimpleProperties::Writer &,
3579  FilegroupPtr,
3580  const Uint32 undo_free_hi,
3581  const Uint32 undo_free_lo);
3582  void packFileIntoPages(SimpleProperties::Writer &, FilePtr, const Uint32);
3583 
3584  void sendGET_TABINFOREQ(Signal* signal,
3585  Uint32 tableId);
3586  void sendTC_SCHVERREQ(Signal* signal,
3587  Uint32 tableId,
3588  BlockReference tcRef);
3589 
3590  /* ------------------------------------------------------------ */
3591  // System Restart Handling
3592  /* ------------------------------------------------------------ */
3593  void initSendSchemaData(Signal* signal);
3594  void sendSchemaData(Signal* signal);
3595  Uint32 sendSCHEMA_INFO(Signal* signal, Uint32 nodeId, Uint32* pagePointer);
3596  void sendDIHSTARTTAB_REQ(Signal* signal);
3597 
3598  /* ------------------------------------------------------------ */
3599  // Receive Table Handling
3600  /* ------------------------------------------------------------ */
3601  void handleTabInfoInit(Signal*, SchemaTransPtr&,
3603  ParseDictTabInfoRecord *,
3604  bool checkExist = true);
3605  void handleTabInfo(SimpleProperties::Reader & it, ParseDictTabInfoRecord *,
3606  DictTabInfo::Table & tableDesc);
3607 
3608  void handleAddTableFailure(Signal* signal,
3609  Uint32 failureLine,
3610  Uint32 tableId);
3611  bool verifyTableCorrect(Signal* signal, Uint32 tableId);
3612 
3613  /* ------------------------------------------------------------ */
3614  // Add Fragment Handling
3615  /* ------------------------------------------------------------ */
3616  void sendLQHADDATTRREQ(Signal*, SchemaOpPtr, Uint32 attributePtrI);
3617 
3618  /* ------------------------------------------------------------ */
3619  // Read/Write Schema and Table files
3620  /* ------------------------------------------------------------ */
3621  void updateSchemaState(Signal* signal, Uint32 tableId,
3622  SchemaFile::TableEntry*, Callback*,
3623  bool savetodisk = 1, bool dicttrans = 0);
3624  void startWriteSchemaFile(Signal* signal);
3625  void openSchemaFile(Signal* signal,
3626  Uint32 fileNo,
3627  Uint32 fsPtr,
3628  bool writeFlag,
3629  bool newFile);
3630  void writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
3631  void writeSchemaConf(Signal* signal,
3632  FsConnectRecordPtr fsPtr);
3633  void closeFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
3634  void closeWriteSchemaConf(Signal* signal,
3635  FsConnectRecordPtr fsPtr);
3636  void initSchemaFile_conf(Signal* signal, Uint32 i, Uint32 returnCode);
3637 
3638  void writeTableFile(Signal* signal, Uint32 tableId,
3639  SegmentedSectionPtr tabInfo, Callback*);
3640  void writeTableFile(Signal* signal, Uint32 tableId,
3641  OpSection opSection, Callback*);
3642  void startWriteTableFile(Signal* signal, Uint32 tableId);
3643  void openTableFile(Signal* signal,
3644  Uint32 fileNo,
3645  Uint32 fsPtr,
3646  Uint32 tableId,
3647  bool writeFlag);
3648  void writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
3649  void writeTableConf(Signal* signal,
3650  FsConnectRecordPtr fsPtr);
3651  void closeWriteTableConf(Signal* signal,
3652  FsConnectRecordPtr fsPtr);
3653 
3654  void startReadTableFile(Signal* signal, Uint32 tableId);
3655  void openReadTableRef(Signal* signal,
3656  FsConnectRecordPtr fsPtr);
3657  void readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
3658  void readTableConf(Signal* signal,
3659  FsConnectRecordPtr fsPtr);
3660  void readTableRef(Signal* signal,
3661  FsConnectRecordPtr fsPtr);
3662  void closeReadTableConf(Signal* signal,
3663  FsConnectRecordPtr fsPtr);
3664 
3665  void startReadSchemaFile(Signal* signal);
3666  void openReadSchemaRef(Signal* signal,
3667  FsConnectRecordPtr fsPtr);
3668  void readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
3669  void readSchemaConf(Signal* signal, FsConnectRecordPtr fsPtr);
3670  void readSchemaRef(Signal* signal, FsConnectRecordPtr fsPtr);
3671  void closeReadSchemaConf(Signal* signal,
3672  FsConnectRecordPtr fsPtr);
3673  bool convertSchemaFileTo_5_0_6(XSchemaFile*);
3674  bool convertSchemaFileTo_6_4(XSchemaFile*);
3675 
3676  /* ------------------------------------------------------------ */
3677  // Get table definitions
3678  /* ------------------------------------------------------------ */
3679  void sendGET_TABINFOREF(Signal* signal,
3680  GetTabInfoReq*,
3681  GetTabInfoRef::ErrorCode errorCode,
3682  Uint32 errorLine);
3683 
3684  void sendGET_TABLEID_REF(Signal* signal,
3685  GetTableIdReq * req,
3686  GetTableIdRef::ErrorCode errorCode);
3687 
3688  void sendGetTabResponse(Signal* signal);
3689 
3690  /* ------------------------------------------------------------ */
3691  // Indexes and triggers
3692  /* ------------------------------------------------------------ */
3693 
3694  // reactivate and rebuild indexes on start up
3695  void activateIndexes(Signal* signal, Uint32 i);
3696  void activateIndex_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
3697  void activateIndex_fromAlterIndex(Signal*, Uint32 tx_key, Uint32 ret);
3698  void activateIndex_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
3699  void rebuildIndexes(Signal* signal, Uint32 i);
3700  void rebuildIndex_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
3701  void rebuildIndex_fromBuildIndex(Signal*, Uint32 tx_key, Uint32 ret);
3702  void rebuildIndex_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
3703 
3704  // Events
3705  void
3706  createEventUTIL_PREPARE(Signal* signal,
3707  Uint32 callbackData,
3708  Uint32 returnCode);
3709  void
3710  createEventUTIL_EXECUTE(Signal *signal,
3711  Uint32 callbackData,
3712  Uint32 returnCode);
3713  void
3714  dropEventUTIL_PREPARE_READ(Signal* signal,
3715  Uint32 callbackData,
3716  Uint32 returnCode);
3717  void
3718  dropEventUTIL_EXECUTE_READ(Signal* signal,
3719  Uint32 callbackData,
3720  Uint32 returnCode);
3721  void
3722  dropEventUTIL_PREPARE_DELETE(Signal* signal,
3723  Uint32 callbackData,
3724  Uint32 returnCode);
3725  void
3726  dropEventUTIL_EXECUTE_DELETE(Signal *signal,
3727  Uint32 callbackData,
3728  Uint32 returnCode);
3729  void
3730  dropEventUtilPrepareRef(Signal* signal,
3731  Uint32 callbackData,
3732  Uint32 returnCode);
3733  void
3734  dropEventUtilExecuteRef(Signal* signal,
3735  Uint32 callbackData,
3736  Uint32 returnCode);
3737  int
3738  sendSignalUtilReq(Callback *c,
3739  BlockReference ref,
3740  GlobalSignalNumber gsn,
3741  Signal* signal,
3742  Uint32 length,
3743  JobBufferLevel jbuf,
3744  LinearSectionPtr ptr[3],
3745  Uint32 noOfSections);
3746  int
3747  recvSignalUtilReq(Signal* signal, Uint32 returnCode);
3748 
3749  void completeSubStartReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
3750  void completeSubStopReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
3751  void completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
3752 
3753  void dropEvent_sendReply(Signal* signal,
3754  OpDropEventPtr evntRecPtr);
3755 
3756  void createEvent_RT_USER_CREATE(Signal* signal,
3757  OpCreateEventPtr evntRecPtr,
3758  SectionHandle& handle);
3759  void createEventComplete_RT_USER_CREATE(Signal* signal,
3760  OpCreateEventPtr evntRecPtr);
3761  void createEvent_RT_USER_GET(Signal*, OpCreateEventPtr, SectionHandle&);
3762  void createEventComplete_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
3763 
3764  void createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
3765 
3766  void createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI,
3767  Uint32 returnCode);
3768  void createEvent_sendReply(Signal* signal, OpCreateEventPtr evntRecPtr,
3769  LinearSectionPtr *ptr = NULL, int noLSP = 0);
3770 
3771  void prepareTransactionEventSysTable (Callback *c,
3772  Signal* signal,
3773  Uint32 senderData,
3774  UtilPrepareReq::OperationTypeValue prepReq);
3775  void prepareUtilTransaction(Callback *c,
3776  Signal* signal,
3777  Uint32 senderData,
3778  Uint32 tableId,
3779  const char *tableName,
3780  UtilPrepareReq::OperationTypeValue prepReq,
3781  Uint32 noAttr,
3782  Uint32 attrIds[],
3783  const char *attrNames[]);
3784 
3785  void executeTransEventSysTable(Callback *c,
3786  Signal *signal,
3787  const Uint32 ptrI,
3788  sysTab_NDBEVENTS_0& m_eventRec,
3789  const Uint32 prepareId,
3790  UtilPrepareReq::OperationTypeValue prepReq);
3791  void executeTransaction(Callback *c,
3792  Signal* signal,
3793  Uint32 senderData,
3794  Uint32 prepareId,
3795  Uint32 noAttr,
3796  LinearSectionPtr headerPtr,
3797  LinearSectionPtr dataPtr);
3798 
3799  void parseReadEventSys(Signal *signal, sysTab_NDBEVENTS_0& m_eventRec);
3800  bool upgrade_suma_NotStarted(Uint32 err, Uint32 ref) const;
3801 
3802  // support
3803  void getTableKeyList(TableRecordPtr,
3805  void getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id);
3806  void getIndexAttrList(TableRecordPtr indexPtr, IndexAttributeList& list);
3807  void getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask);
3808 
3809  /* ------------------------------------------------------------ */
3810  // Initialisation
3811  /* ------------------------------------------------------------ */
3812  void initCommonData();
3813  void initRecords();
3814  void initConnectRecord();
3815  void initRetrieveRecord(Signal*, Uint32, Uint32 returnCode);
3816  void initSchemaRecord();
3817  void initRestartRecord(Uint32 sp = 0, Uint32 lp = 0,
3818  const char * sb = 0, const char * eb = 0);
3819  void initSendSchemaRecord();
3820  void initReadTableRecord();
3821  void initWriteTableRecord();
3822  void initReadSchemaRecord();
3823  void initWriteSchemaRecord();
3824 
3825  void initNodeRecords();
3826  void initTableRecords();
3827  void initialiseTableRecord(TableRecordPtr tablePtr);
3828  void initTriggerRecords();
3829  void initialiseTriggerRecord(TriggerRecordPtr triggerPtr);
3830  void initPageRecords();
3831 
3832  Uint32 getFsConnRecord();
3833 
3834  bool getIsFailed(Uint32 nodeId) const;
3835 
3836  void printTables(); // For debugging only
3837 
3838  void startRestoreSchema(Signal*, Callback);
3839  void restartNextPass(Signal*);
3840  void restart_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
3841  void restart_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
3842  void restartEndPass_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
3843  void restart_fromWriteSchemaFile(Signal*, Uint32, Uint32);
3844  void restart_nextOp(Signal*, bool commit = false);
3845 
3846  void checkSchemaStatus(Signal* signal);
3847  void checkPendingSchemaTrans(XSchemaFile* xsf);
3848 
3849  void restartCreateObj(Signal*, Uint32, const SchemaFile::TableEntry *, bool);
3850  void restartCreateObj_readConf(Signal*, Uint32, Uint32);
3851  void restartCreateObj_getTabInfoConf(Signal*);
3852  void restartCreateObj_parse(Signal*, SegmentedSectionPtr, bool);
3853  void restartDropObj(Signal*, Uint32, const SchemaFile::TableEntry *);
3854 
3855  void restart_checkSchemaStatusComplete(Signal*, Uint32 callback, Uint32);
3856  void masterRestart_checkSchemaStatusComplete(Signal*, Uint32, Uint32);
3857 
3858  void sendSchemaComplete(Signal*, Uint32 callbackData, Uint32);
3859 
3860 public:
3861  void send_drop_file(Signal*, Uint32, Uint32, DropFileImplReq::RequestInfo);
3862  void send_drop_fg(Signal*, Uint32, Uint32, DropFilegroupImplReq::RequestInfo);
3863 
3864  int checkSingleUserMode(Uint32 senderRef);
3865 
3866  friend NdbOut& operator<<(NdbOut& out, const ErrorInfo&);
3867 #ifdef VM_TRACE
3868  friend NdbOut& operator<<(NdbOut& out, const DictObject&);
3869  friend NdbOut& operator<<(NdbOut& out, const SchemaOp&);
3870  friend NdbOut& operator<<(NdbOut& out, const SchemaTrans&);
3871  friend NdbOut& operator<<(NdbOut& out, const TxHandle&);
3872  void check_consistency();
3873  void check_consistency_entry(TableRecordPtr tablePtr);
3874  void check_consistency_table(TableRecordPtr tablePtr);
3875  void check_consistency_index(TableRecordPtr indexPtr);
3876  void check_consistency_trigger(TriggerRecordPtr triggerPtr);
3877  void check_consistency_object(DictObjectPtr obj_ptr);
3878 #endif
3879 
3892  struct DictLockType;
3893  friend struct DictLockType;
3894 
3895  struct DictLockType {
3896  DictLockReq::LockType lockType;
3897  const char* text;
3898  };
3899  static const DictLockType* getDictLockType(Uint32 lockType);
3900  void sendDictLockInfoEvent(Signal*, const UtilLockReq*, const char* text);
3901  void removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes);
3902 
3903 
3904  Uint32 dict_lock_trylock(const DictLockReq* req);
3905  Uint32 dict_lock_unlock(Signal* signal, const DictLockReq* req);
3906 
3907  LockQueue::Pool m_dict_lock_pool;
3908  LockQueue m_dict_lock;
3909 
3910  void sendOLD_LIST_TABLES_CONF(Signal *signal, ListTablesReq*);
3911  void sendLIST_TABLES_CONF(Signal *signal, ListTablesReq*);
3912 
3913  Uint32 c_outstanding_sub_startstop;
3914  NdbNodeBitmask c_sub_startstop_lock;
3915 
3916  Uint32 get_default_fragments(Signal*, Uint32 extra_nodegroups = 0);
3917  void wait_gcp(Signal* signal, SchemaOpPtr op_ptr, Uint32 flags);
3918 
3919  void block_substartstop(Signal* signal, SchemaOpPtr op_ptr);
3920  void unblock_substartstop();
3921  void wait_substartstop(Signal* signal, Uint32 opPtrI);
3922 
3923  void upgrade_seizeTrigger(Ptr<TableRecord> tabPtr, Uint32, Uint32, Uint32);
3924 
3925  void send_event(Signal*, SchemaTransPtr&,
3926  Uint32 ev,
3927  Uint32 id,
3928  Uint32 version,
3929  Uint32 type);
3930 
3931 protected:
3932  virtual bool getParam(const char * param, Uint32 * retVal);
3933 };
3934 
3935 inline bool
3936 Dbdict::TableRecord::isTable() const
3937 {
3938  return DictTabInfo::isTable(tableType);
3939 }
3940 
3941 inline bool
3942 Dbdict::TableRecord::isIndex() const
3943 {
3944  return DictTabInfo::isIndex(tableType);
3945 }
3946 
3947 inline bool
3948 Dbdict::TableRecord::isUniqueIndex() const
3949 {
3950  return DictTabInfo::isUniqueIndex(tableType);
3951 }
3952 
3953 inline bool
3954 Dbdict::TableRecord::isNonUniqueIndex() const
3955 {
3956  return DictTabInfo::isNonUniqueIndex(tableType);
3957 }
3958 
3959 inline bool
3960 Dbdict::TableRecord::isHashIndex() const
3961 {
3962  return DictTabInfo::isHashIndex(tableType);
3963 }
3964 
3965 inline bool
3966 Dbdict::TableRecord::isOrderedIndex() const
3967 {
3968  return DictTabInfo::isOrderedIndex(tableType);
3969 }
3970 
3971 // quilt keeper
3972 #endif