1 /*
2 Copyright (c) 2003, 2021, Oracle and/or its affiliates.
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, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef DBDICT_H
26 #define DBDICT_H
27
28 /**
29 * Dict : Dictionary Block
30 */
31 #include <ndb_limits.h>
32 #include <trigger_definitions.h>
33 #include <pc.hpp>
34 #include <ArenaPool.hpp>
35 #include <DataBuffer2.hpp>
36 #include <DLHashTable.hpp>
37 #include <IntrusiveList.hpp>
38 #include <CArray.hpp>
39 #include <KeyTable.hpp>
40 #include <KeyTable2.hpp>
41 #include <KeyTable2Ref.hpp>
42 #include <SimulatedBlock.hpp>
43 #include <SimpleProperties.hpp>
44 #include <SignalCounter.hpp>
45 #include <Bitmask.hpp>
46 #include <AttributeList.hpp>
47 #include <signaldata/GetTableId.hpp>
48 #include <signaldata/GetTabInfo.hpp>
49 #include <signaldata/DictTabInfo.hpp>
50 #include <signaldata/CreateTable.hpp>
51 #include <signaldata/CreateTab.hpp>
52 #include <signaldata/DropTable.hpp>
53 #include <signaldata/DropTab.hpp>
54 #include <signaldata/AlterTable.hpp>
55 #include <signaldata/AlterTab.hpp>
56 #include <signaldata/ListTables.hpp>
57 #include <signaldata/CreateIndx.hpp>
58 #include <signaldata/CreateIndxImpl.hpp>
59 #include <signaldata/DropIndx.hpp>
60 #include <signaldata/DropIndxImpl.hpp>
61 #include <signaldata/AlterIndx.hpp>
62 #include <signaldata/AlterIndxImpl.hpp>
63 #include <signaldata/BuildIndx.hpp>
64 #include <signaldata/BuildIndxImpl.hpp>
65 #include <signaldata/IndexStatSignal.hpp>
66 #include <signaldata/UtilPrepare.hpp>
67 #include <signaldata/CreateEvnt.hpp>
68 #include <signaldata/CreateTrig.hpp>
69 #include <signaldata/CreateTrigImpl.hpp>
70 #include <signaldata/DropTrig.hpp>
71 #include <signaldata/DropTrigImpl.hpp>
72 #include <signaldata/DictLock.hpp>
73 #include <signaldata/DictTakeover.hpp>
74 #include <signaldata/SumaImpl.hpp>
75 #include <signaldata/CreateHashMap.hpp>
76 #include <signaldata/HashMapImpl.hpp>
77 #include "SchemaFile.hpp"
78 #include <blocks/mutexes.hpp>
79 #include <SafeCounter.hpp>
80 #include <RequestTracker.hpp>
81 #include <Rope.hpp>
82 #include <signaldata/CreateFilegroupImpl.hpp>
83 #include <signaldata/DropFilegroupImpl.hpp>
84 #include <signaldata/DictSignal.hpp>
85 #include <signaldata/SchemaTransImpl.hpp>
86 #include <LockQueue.hpp>
87 #include <signaldata/CopyData.hpp>
88 #include <signaldata/NodeFailRep.hpp>
89 #include <signaldata/CreateNodegroup.hpp>
90 #include <signaldata/DropNodegroup.hpp>
91 #include <signaldata/CreateNodegroupImpl.hpp>
92 #include <signaldata/DropNodegroupImpl.hpp>
93 #include <Mutex.hpp>
94 #include <SegmentList.hpp>
95
96 #include <signaldata/CreateFK.hpp>
97 #include <signaldata/CreateFKImpl.hpp>
98 #include <signaldata/BuildFK.hpp>
99 #include <signaldata/BuildFKImpl.hpp>
100 #include <signaldata/DropFK.hpp>
101 #include <signaldata/DropFKImpl.hpp>
102
103 #define JAM_FILE_ID 464
104
105 #ifdef DBDICT_C
106
107 /*--------------------------------------------------------------*/
108 // Constants for CONTINUEB
109 /*--------------------------------------------------------------*/
110 #define ZPACK_TABLE_INTO_PAGES 0
111 #define ZSEND_GET_TAB_RESPONSE 3
112 #define ZWAIT_SUBSTARTSTOP 4
113 #define ZDICT_TAKEOVER_REQ 5
114
115 #define ZCOMMIT_WAIT_GCI 6
116 #define ZINDEX_STAT_BG_PROCESS 7
117 #define ZGET_TABINFO_RETRY 8
118 #define ZNEXT_GET_TAB_REQ 9
119
120 /*--------------------------------------------------------------*/
121 // Other constants in alphabetical order
122 /*--------------------------------------------------------------*/
123 #define ZNOMOREPHASES 255
124
125 /*--------------------------------------------------------------*/
126 // Schema file defines
127 /*--------------------------------------------------------------*/
128 #define ZSCHEMA_WORDS 4
129
130 /*--------------------------------------------------------------*/
131 // Page constants
132 /*--------------------------------------------------------------*/
133 #define ZBAT_SCHEMA_FILE 0 //Variable number of page for NDBFS
134 #define ZBAT_TABLE_FILE 1 //Variable number of page for NDBFS
135 #define ZPAGE_HEADER_SIZE 32
136 #define ZPOS_PAGE_SIZE 16
137 #define ZPOS_CHECKSUM 17
138 #define ZPOS_VERSION 18
139 #define ZPOS_PAGE_HEADER_SIZE 19
140
141 /*--------------------------------------------------------------*/
142 // Size constants
143 /*--------------------------------------------------------------*/
144 #define ZFS_CONNECT_SIZE 4
145 #define ZSIZE_OF_PAGES_IN_WORDS 8192
146 #define ZLOG_SIZE_OF_PAGES_IN_WORDS 13
147 #define ZMAX_PAGES_OF_TABLE_DEFINITION \
148 ((ZPAGE_HEADER_SIZE + MAX_WORDS_META_FILE + ZSIZE_OF_PAGES_IN_WORDS - 1) / \
149 ZSIZE_OF_PAGES_IN_WORDS)
150
151 /**
152 * - one for retreive
153 * - one for read or write
154 */
155 #define ZNUMBER_OF_PAGES (2 * ZMAX_PAGES_OF_TABLE_DEFINITION)
156 #endif
157
158 /**
159 * Systable NDB$EVENTS_0
160 */
161 #define EVENT_SYSTEM_TABLE_LENGTH 9
162 #define EVENT_SYSTEM_TABLE_ATTRIBUTE_MASK2_ID 8
163
164 struct sysTab_NDBEVENTS_0 {
165 char NAME[MAX_TAB_NAME_SIZE];
166 Uint32 EVENT_TYPE;
167 Uint32 TABLEID;
168 Uint32 TABLEVERSION;
169 char TABLE_NAME[MAX_TAB_NAME_SIZE];
170 Uint32 ATTRIBUTE_MASK[MAXNROFATTRIBUTESINWORDS_OLD];
171 Uint32 SUBID;
172 Uint32 SUBKEY;
173
174 // +1 to allow var size header to be received
175 Uint32 ATTRIBUTE_MASK2[(MAX_ATTRIBUTES_IN_TABLE / 32) + 1];
176 };
177
178 /**
179 * DICT - This blocks handles all metadata
180 */
181 class Dbdict: public SimulatedBlock {
182 public:
183
184 /*
185 * 2.3 RECORD AND FILESIZES
186 */
187
188 /**
189 * Table attributes. Permanent data.
190 *
191 * Indexes have an attribute list which duplicates primary table
192 * attributes. This is wrong but convenient.
193 */
194 struct AttributeRecord {
AttributeRecordDbdict::AttributeRecord195 AttributeRecord(){}
196
197 /* attribute id */
198 Uint16 attributeId;
199
200 /* Attribute number within tuple key (counted from 1) */
201 Uint16 tupleKey;
202
203 /* Attribute name (unique within table) */
204 RopeHandle attributeName;
205
206 /* Attribute description (old-style packed descriptor) */
207 Uint32 attributeDescriptor;
208
209 /* Extended attributes */
210 Uint32 extType;
211 Uint32 extPrecision;
212 Uint32 extScale;
213 Uint32 extLength;
214
215 /* Autoincrement flag, only for ODBC/SQL */
216 bool autoIncrement;
217
218 /* Default value as null-terminated string, only for ODBC/SQL */
219 RopeHandle defaultValue;
220
221 struct {
222 Uint32 m_name_len;
223 const char * m_name_ptr;
224 RopePool * m_pool;
225 } m_key;
226
227 union {
228 Uint32 nextPool;
229 Uint32 nextList;
230 };
231 Uint32 prevList;
232 Uint32 nextHash;
233 Uint32 prevHash;
234
hashValueDbdict::AttributeRecord235 Uint32 hashValue() const { return attributeName.hashValue();}
equalDbdict::AttributeRecord236 bool equal(const AttributeRecord& obj) const {
237 if(obj.hashValue() == hashValue()){
238 ConstRope r(* m_key.m_pool, obj.attributeName);
239 return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0;
240 }
241 return false;
242 }
243 };
244 typedef Ptr<AttributeRecord> AttributeRecordPtr;
245 typedef ArrayPool<AttributeRecord> AttributeRecord_pool;
246 typedef DLMHashTable<AttributeRecord_pool, AttributeRecord> AttributeRecord_hash;
247 typedef DLFifoListImpl<AttributeRecord_pool, AttributeRecord, AttributeRecord> AttributeRecord_list;
248 typedef LocalDLFifoListImpl<AttributeRecord_pool, AttributeRecord, AttributeRecord> LocalAttributeRecord_list;
249
250 AttributeRecord_pool c_attributeRecordPool;
251 AttributeRecord_hash c_attributeRecordHash;
252 RSS_AP_SNAPSHOT(c_attributeRecordPool);
253
254 /**
255 * Shared table / index record. Most of this is permanent data stored
256 * on disk. Index trigger ids are volatile.
257 */
258 struct TableRecord;
259 typedef Ptr<TableRecord> TableRecordPtr;
260 typedef ArrayPool<TableRecord> TableRecord_pool;
261 typedef DLFifoListImpl<TableRecord_pool, TableRecord, TableRecord> TableRecord_list;
262 typedef LocalDLFifoListImpl<TableRecord_pool, TableRecord, TableRecord> LocalTableRecord_list;
263
264 struct TableRecord {
TableRecordDbdict::TableRecord265 TableRecord(){ m_upgrade_trigger_handling.m_upgrade = false;}
isCompatibleDbdict::TableRecord266 static bool isCompatible(Uint32 type) { return DictTabInfo::isTable(type) || DictTabInfo::isIndex(type); }
267
268 Uint32 maxRowsLow;
269 Uint32 maxRowsHigh;
270 Uint32 minRowsLow;
271 Uint32 minRowsHigh;
272 /* Table id (array index in DICT and other blocks) */
273 Uint32 tableId;
274 Uint32 m_obj_ptr_i;
275
276 /* Table version (incremented when tableId is re-used) */
277 Uint32 tableVersion;
278
279 /* */
280 Uint32 hashMapObjectId;
281 Uint32 hashMapVersion;
282
283 /* Table name (may not be unique under "alter table") */
284 RopeHandle tableName;
285
286 /* Type of table or index */
287 DictTabInfo::TableType tableType;
288
289 /* Is table or index online (this flag is not used in DICT) */
290 bool online;
291
292 /* Primary table of index otherwise RNIL */
293 Uint32 primaryTableId;
294
295 /* Type of fragmentation (small/medium/large) */
296 DictTabInfo::FragmentType fragmentType;
297
298 /* Global checkpoint identity when table created */
299 Uint32 gciTableCreated;
300
301 /* Is the table logged (i.e. data survives system restart) */
302 enum Bits
303 {
304 TR_Logged = 0x1,
305 TR_RowGCI = 0x2,
306 TR_RowChecksum = 0x4,
307 TR_Temporary = 0x8,
308 TR_ForceVarPart = 0x10
309 };
310 Uint8 m_extra_row_gci_bits;
311 Uint8 m_extra_row_author_bits;
312 Uint16 m_bits;
313
314 /* Number of attibutes in table */
315 Uint16 noOfAttributes;
316
317 /* Number of null attributes in table (should be computed) */
318 Uint16 noOfNullAttr;
319
320 /* Number of primary key attributes (should be computed) */
321 Uint16 noOfPrimkey;
322
323 /* Length of primary key in words (should be computed) */
324 /* For ordered index this is tree node size in words */
325 Uint16 tupKeyLength;
326
327 /** */
328 Uint16 noOfCharsets;
329
330 /* K value for LH**3 algorithm (only 6 allowed currently) */
331 Uint8 kValue;
332
333 /* Local key length in words (currently 1) */
334 Uint8 localKeyLen;
335
336 /*
337 * Parameter for hash algorithm that specifies the load factor in
338 * percentage of fill level in buckets. A high value means we are
339 * splitting early and that buckets are only lightly used. A high
340 * value means that we have fill the buckets more and get more
341 * likelihood of overflow buckets.
342 */
343 Uint8 maxLoadFactor;
344
345 /*
346 Flag to indicate default number of partitions
347 */
348 bool defaultNoPartFlag;
349
350 /*
351 Flag to indicate using linear hash function
352 */
353 bool linearHashFlag;
354
355 /*
356 * Used when shrinking to decide when to merge buckets. Hysteresis
357 * is thus possible. Should be smaller but not much smaller than
358 * maxLoadFactor
359 */
360 Uint8 minLoadFactor;
361
362 /**
363 * Table default storage method
364 */
365 Uint8 storageType; // NDB_STORAGETYPE_
366
367 /* Convenience routines */
368 bool isTable() const;
369 bool isIndex() const;
370 bool isUniqueIndex() const;
371 bool isNonUniqueIndex() const;
372 bool isHashIndex() const;
373 bool isOrderedIndex() const;
374
375 /****************************************************
376 * Support variables for table handling
377 ****************************************************/
378
379 /** File pointer received from disk */
380 Uint32 filePtr[2];
381
382 /** Pointer to first attribute in table */
383 AttributeRecord_list::Head m_attributes;
384
385 Uint32 nextPool;
386
387 Uint32 m_read_locked; // BACKUP_ONGOING
388
389 /** Number of words */
390 Uint32 packedSize;
391
392 /** Index state (volatile data) TODO remove */
393 enum IndexState {
394 IS_UNDEFINED = 0, // initial
395 IS_OFFLINE = 1, // index table created
396 IS_BUILDING = 2, // building (local state)
397 IS_DROPPING = 3, // dropping (local state)
398 IS_ONLINE = 4, // online
399 IS_BROKEN = 9 // build or drop aborted
400 };
401 IndexState indexState;
402
403 /** Trigger ids of index (volatile data) */
404 Uint32 triggerId; // ordered index (1)
405 Uint32 buildTriggerId; // temp during build
406
407 struct UpgradeTriggerHandling
408 {
409 /**
410 * In 6.3 (and prior) 3 triggers was created for each unique index
411 * in 6.4 these has been merged to 1
412 * but...we need to maintain these during an upgrade situation
413 * puh
414 */
415 bool m_upgrade;
416 Uint32 insertTriggerId;
417 Uint32 updateTriggerId;
418 Uint32 deleteTriggerId;
419 } m_upgrade_trigger_handling;
420
421 Uint32 noOfNullBits;
422
423 /** frm data for this table */
424 RopeHandle frmData;
425 RopeHandle ngData;
426 RopeHandle rangeData;
427
428 Uint32 fragmentCount;
429 Uint32 m_tablespace_id;
430
431 /** List of indexes attached to table */
432 TableRecord_list::Head m_indexes;
433 Uint32 nextList, prevList;
434
435 /*
436 * Access rights to table during single user mode
437 */
438 Uint8 singleUserMode;
439
440 /*
441 * Fragment and node to use for index statistics. Not part of
442 * DICTTABINFO. Computed locally by each DICT. If the node is
443 * down, no automatic stats update takes place. This is not
444 * critical and is not worth fixing.
445 */
446 Uint16 indexStatFragId;
447 Uint16 indexStatNodes[MAX_REPLICAS];
448
449 // pending background request (IndexStatRep::RequestType)
450 Uint32 indexStatBgRequest;
451 };
452
453 TableRecord_pool c_tableRecordPool_;
454 RSS_AP_SNAPSHOT(c_tableRecordPool_);
get_pool(TableRecordPtr)455 TableRecord_pool& get_pool(TableRecordPtr) { return c_tableRecordPool_; }
456
457 /** Node Group and Tablespace id+version + range or list data.
458 * This is only stored temporarily in DBDICT during an ongoing
459 * change.
460 * TODO RONM: Look into improvements of this
461 */
462 Uint32 c_fragDataLen;
463 union {
464 Uint16 c_fragData[MAX_NDB_PARTITIONS];
465 Uint32 c_fragData_align32[1];
466 };
467 Uint32 c_tsIdData[2*MAX_NDB_PARTITIONS];
468
469 /**
470 * Triggers. This is volatile data not saved on disk. Setting a
471 * trigger online creates the trigger in TC (if index) and LQH-TUP.
472 */
473 struct TriggerRecord {
TriggerRecordDbdict::TriggerRecord474 TriggerRecord() {}
isCompatibleDbdict::TriggerRecord475 static bool isCompatible(Uint32 type) { return DictTabInfo::isTrigger(type); }
476
477 /** Trigger state */
478 enum TriggerState {
479 TS_NOT_DEFINED = 0,
480 TS_DEFINING = 1,
481 TS_OFFLINE = 2, // created globally in DICT
482 //TS_BUILDING = 3,
483 //TS_DROPPING = 4,
484 TS_ONLINE = 5, // created in other blocks
485 TS_FAKE_UPGRADE = 6
486 };
487 TriggerState triggerState;
488
489 /** Trigger name, used by DICT to identify the trigger */
490 RopeHandle triggerName;
491
492 /** Trigger id, used by TRIX, TC, LQH, and TUP to identify the trigger */
493 Uint32 triggerId;
494 Uint32 m_obj_ptr_i;
495
496 /** Table id, the table the trigger is defined on */
497 Uint32 tableId;
498
499 /** TriggerInfo (packed) */
500 Uint32 triggerInfo;
501
502 /**
503 * Attribute mask, defines what attributes are to be monitored.
504 * Can be seen as a compact representation of SQL column name list.
505 */
506 AttributeMask attributeMask;
507
508 /** Receiver. Not used from index triggers */
509 BlockReference receiverRef;
510
511 /** Index id, only used by secondary_index triggers */
512 Uint32 indexId;
513
514 /** Pointer to the next attribute used by ArrayPool */
515 Uint32 nextPool;
516 };
517
518 typedef Ptr<TriggerRecord> TriggerRecordPtr;
519 typedef ArrayPool<TriggerRecord> TriggerRecord_pool;
520
521 Uint32 c_maxNoOfTriggers;
522 TriggerRecord_pool c_triggerRecordPool_;
get_pool(TriggerRecordPtr)523 TriggerRecord_pool& get_pool(TriggerRecordPtr) { return c_triggerRecordPool_;}
524 RSS_AP_SNAPSHOT(c_triggerRecordPool_);
525
526 /**
527 * Information for each FS connection.
528 ***************************************************************************/
529 struct FsConnectRecord {
530 enum FsState {
531 IDLE = 0,
532 OPEN_WRITE_SCHEMA = 1,
533 WRITE_SCHEMA = 2,
534 CLOSE_WRITE_SCHEMA = 3,
535 OPEN_READ_SCHEMA1 = 4,
536 OPEN_READ_SCHEMA2 = 5,
537 READ_SCHEMA1 = 6,
538 READ_SCHEMA2 = 7,
539 CLOSE_READ_SCHEMA = 8,
540 OPEN_READ_TAB_FILE1 = 9,
541 OPEN_READ_TAB_FILE2 = 10,
542 READ_TAB_FILE1 = 11,
543 READ_TAB_FILE2 = 12,
544 CLOSE_READ_TAB_FILE = 13,
545 OPEN_WRITE_TAB_FILE = 14,
546 WRITE_TAB_FILE = 15,
547 CLOSE_WRITE_TAB_FILE = 16
548 };
549 /** File Pointer for this file system connection */
550 Uint32 filePtr;
551
552 /** Reference of owner record */
553 Uint32 ownerPtr;
554
555 /** State of file system connection */
556 FsState fsState;
557
558 /** Used by Array Pool for free list handling */
559 Uint32 nextPool;
560 };
561
562 typedef Ptr<FsConnectRecord> FsConnectRecordPtr;
563 typedef ArrayPool<FsConnectRecord> FsConnectRecord_pool;
564 FsConnectRecord_pool c_fsConnectRecordPool;
565
566 /**
567 * This record stores all the information about a node and all its attributes
568 ***************************************************************************/
569 struct NodeRecord {
570 enum NodeState {
571 API_NODE = 0,
572 NDB_NODE_ALIVE = 1,
573 NDB_NODE_DEAD = 2,
574 NDB_MASTER_TAKEOVER = 3
575 };
576 bool hotSpare;
577 NodeState nodeState;
578
579 // Schema transaction data
580 enum RecoveryState {
581 RS_NORMAL = 0, // Node is up to date with master
582 RS_PARTIAL_ROLLBACK = 1, // Node has rolled back some operations
583 RS_PARTIAL_ROLLFORWARD = 2 // Node has committed some operations
584 };
585 RecoveryState recoveryState;
586 NodeFailRep nodeFailRep;
587 NdbNodeBitmask m_nodes; // Nodes sent DICT_TAKEOVER_REQ during takeover
588 SafeCounterHandle m_counter; // Outstanding DICT_TAKEOVER_REQ's
589 //TODO Accumulate in buffer when DictTakeoverConf becomes long signal
590 DictTakeoverConf takeOverConf; // Accumulated replies
591
592 // TODO: these should be moved to SchemaTransPtr
593 // Starting operation for partial rollback/rollforward
594 Uint32 start_op;
595 // Starting state of operation for partial rollback/rollforward
596 Uint32 start_op_state;
597 };
598
599 typedef Ptr<NodeRecord> NodeRecordPtr;
600 CArray<NodeRecord> c_nodes;
601 NdbNodeBitmask c_aliveNodes;
602
603 struct PageRecord {
604 Uint32 word[8192];
605 };
606
607 typedef Ptr<PageRecord> PageRecordPtr;
608 CArray<PageRecord> c_pageRecordArray;
609
610 struct SchemaPageRecord {
611 Uint32 word[NDB_SF_PAGE_SIZE_IN_WORDS];
612 };
613
614 CArray<SchemaPageRecord> c_schemaPageRecordArray;
615
616 unsigned g_trace;
617 DictTabInfo::Table c_tableDesc;
618
619 /**
620 * A page for create index table signal.
621 */
622 PageRecord c_indexPage;
623
624 struct File {
FileDbdict::File625 File() {}
isCompatibleDbdict::File626 static bool isCompatible(Uint32 type) { return DictTabInfo::isFile(type); }
627
628 Uint32 key;
629 Uint32 m_magic;
630 Uint32 m_version;
631 Uint32 m_obj_ptr_i;
632 Uint32 m_filegroup_id;
633 Uint32 m_type;
634 Uint64 m_file_size;
635 Uint64 m_file_free;
636 RopeHandle m_path;
637
638 Uint32 nextList;
639 union {
640 Uint32 prevList;
641 Uint32 nextPool;
642 };
643 };
644 typedef Ptr<File> FilePtr;
645 typedef RecordPool<File, RWPool> File_pool;
646 typedef DLListImpl<File_pool, File> File_list;
647 typedef LocalDLListImpl<File_pool, File> Local_file_list;
648
649 struct Filegroup {
FilegroupDbdict::Filegroup650 Filegroup(){}
isCompatibleDbdict::Filegroup651 static bool isCompatible(Uint32 type) { return DictTabInfo::isFilegroup(type); }
652
653 Uint32 key;
654 Uint32 m_obj_ptr_i;
655 Uint32 m_magic;
656
657 Uint32 m_type;
658 Uint32 m_version;
659 RopeHandle m_name;
660
661 union {
662 struct {
663 Uint32 m_extent_size;
664 Uint32 m_default_logfile_group_id;
665 } m_tablespace;
666
667 struct {
668 Uint32 m_undo_buffer_size;
669 File_list::HeadPOD m_files;
670 } m_logfilegroup;
671 };
672
673 union {
674 Uint32 nextPool;
675 Uint32 nextList;
676 };
677 };
678 typedef Ptr<Filegroup> FilegroupPtr;
679 typedef RecordPool<Filegroup, RWPool> Filegroup_pool;
680
681 File_pool c_file_pool;
682 Filegroup_pool c_filegroup_pool;
683
get_pool(FilePtr)684 File_pool& get_pool(FilePtr) { return c_file_pool; }
get_pool(FilegroupPtr)685 Filegroup_pool& get_pool(FilegroupPtr) { return c_filegroup_pool; }
686
687 RopePool c_rope_pool;
688 RSS_AP_SNAPSHOT(c_rope_pool);
689
690 template <typename T, typename U = T> struct HashedById {
nextHashDbdict::HashedById691 static Uint32& nextHash(U& t) { return t.nextHash_by_id; }
prevHashDbdict::HashedById692 static Uint32& prevHash(U& t) { return t.prevHash_by_id; }
hashValueDbdict::HashedById693 static Uint32 hashValue(T const& t) { return t.hashValue_by_id(); }
equalDbdict::HashedById694 static bool equal(T const& lhs, T const& rhs) { return lhs.equal_by_id(rhs); }
695 };
696
697 template <typename T, typename U = T> struct HashedByName {
nextHashDbdict::HashedByName698 static Uint32& nextHash(U& t) { return t.nextHash_by_name; }
prevHashDbdict::HashedByName699 static Uint32& prevHash(U& t) { return t.prevHash_by_name; }
hashValueDbdict::HashedByName700 static Uint32 hashValue(T const& t) { return t.hashValue_by_name(); }
equalDbdict::HashedByName701 static bool equal(T const& lhs, T const& rhs) { return lhs.equal_by_name(rhs); }
702 };
703
704 struct DictObject {
DictObjectDbdict::DictObject705 DictObject() {
706 m_trans_key = 0;
707 m_op_ref_count = 0;
708 };
709 Uint32 m_id;
710 Uint32 m_type;
711 Uint32 m_object_ptr_i;
712 Uint32 m_ref_count;
713 RopeHandle m_name;
714 union {
715 struct {
716 Uint32 m_name_len;
717 const char * m_name_ptr;
718 RopePool * m_pool;
719 } m_key;
720 Uint32 nextPool;
721 Uint32 nextList;
722 };
723
724 // SchemaOp -> DictObject -> SchemaTrans
725 Uint32 m_trans_key;
726 Uint32 m_op_ref_count;
727
728 // HashedById
729 Uint32 nextHash_by_id;
730 Uint32 prevHash_by_id;
hashValue_by_idDbdict::DictObject731 Uint32 hashValue_by_id() const { return m_id; }
equal_by_idDbdict::DictObject732 bool equal_by_id(DictObject const& obj) const {
733 bool isTrigger = DictTabInfo::isTrigger(m_type);
734 bool objIsTrigger = DictTabInfo::isTrigger(obj.m_type);
735 return (isTrigger == objIsTrigger) &&
736 (obj.m_id == m_id);
737 }
738
739 // HashedByName
740 Uint32 nextHash_by_name;
741 Uint32 prevHash_by_name;
hashValue_by_nameDbdict::DictObject742 Uint32 hashValue_by_name() const { return m_name.hashValue(); }
equal_by_nameDbdict::DictObject743 bool equal_by_name(DictObject const& obj) const {
744 if(obj.hashValue_by_name() == hashValue_by_name()){
745 ConstRope r(* m_key.m_pool, obj.m_name);
746 return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0;
747 }
748 return false;
749 }
750
751 #ifdef VM_TRACE
752 void print(NdbOut&) const;
753 #endif
754 };
755
756 typedef Ptr<DictObject> DictObjectPtr;
757 typedef ArrayPool<DictObject> DictObject_pool;
758 typedef DLMHashTable<DictObject_pool, DictObject, HashedByName<DictObject> > DictObjectName_hash;
759 typedef DLMHashTable<DictObject_pool, DictObject, HashedById<DictObject> > DictObjectId_hash;
760 typedef SLList<DictObject> DictObject_list;
761
762 DictObjectName_hash c_obj_name_hash; // Name (not temporary TableRecords)
763 DictObjectId_hash c_obj_id_hash; // Schema file id / Trigger id
764 DictObject_pool c_obj_pool;
765 RSS_AP_SNAPSHOT(c_obj_pool);
766
find_object(DictObjectPtr & obj,Ptr<T> & object,Uint32 id)767 template<typename T> bool find_object(DictObjectPtr& obj, Ptr<T>& object, Uint32 id)
768 {
769 if (!find_object(obj, id))
770 {
771 object.setNull();
772 return false;
773 }
774 if (!T::isCompatible(obj.p->m_type))
775 {
776 object.setNull();
777 return false;
778 }
779 get_pool(object).getPtr(object, obj.p->m_object_ptr_i);
780 return !object.isNull();
781 }
782
find_object(Ptr<T> & object,Uint32 id)783 template<typename T> bool find_object(Ptr<T>& object, Uint32 id)
784 {
785 DictObjectPtr obj;
786 return find_object(obj, object, id);
787 }
788
find_object(DictObjectPtr & obj,Ptr<TriggerRecord> & object,Uint32 id)789 bool find_object(DictObjectPtr& obj, Ptr<TriggerRecord>& object, Uint32 id)
790 {
791 if (!find_trigger_object(obj, id))
792 {
793 object.setNull();
794 return false;
795 }
796 get_pool(object).getPtr(object, obj.p->m_object_ptr_i);
797 return !object.isNull();
798 }
799
find_object(DictObjectPtr & object,Uint32 id)800 bool find_object(DictObjectPtr& object, Uint32 id)
801 {
802 DictObject key;
803 key.m_id = id;
804 key.m_type = 0; // Not a trigger atleast
805 bool ok = c_obj_id_hash.find(object, key);
806 return ok;
807 }
808
find_trigger_object(DictObjectPtr & object,Uint32 id)809 bool find_trigger_object(DictObjectPtr& object, Uint32 id)
810 {
811 DictObject key;
812 key.m_id = id;
813 key.m_type = DictTabInfo::HashIndexTrigger; // A trigger type
814 bool ok = c_obj_id_hash.find(object, key);
815 return ok;
816 }
817
link_object(DictObjectPtr obj,Ptr<T> object)818 template<typename T> bool link_object(DictObjectPtr obj, Ptr<T> object)
819 {
820 if (!T::isCompatible(obj.p->m_type))
821 {
822 return false;
823 }
824 obj.p->m_object_ptr_i = object.i;
825 object.p->m_obj_ptr_i = obj.i;
826 return true;
827 }
828
829 // 1
get_object(const char * name)830 DictObject * get_object(const char * name){
831 return get_object(name, Uint32(strlen(name) + 1));
832 }
833
get_object(const char * name,Uint32 len)834 DictObject * get_object(const char * name, Uint32 len){
835 return get_object(name, len, LocalRope::hash(name, len));
836 }
837
838 DictObject * get_object(const char * name, Uint32 len, Uint32 hash);
839
840 //2
get_object(DictObjectPtr & obj_ptr,const char * name)841 bool get_object(DictObjectPtr& obj_ptr, const char * name){
842 return get_object(obj_ptr, name, Uint32(strlen(name) + 1));
843 }
844
get_object(DictObjectPtr & obj_ptr,const char * name,Uint32 len)845 bool get_object(DictObjectPtr& obj_ptr, const char * name, Uint32 len){
846 return get_object(obj_ptr, name, len, LocalRope::hash(name, len));
847 }
848
849 bool get_object(DictObjectPtr&, const char* name, Uint32 len, Uint32 hash);
850
release_object(Uint32 obj_ptr_i)851 void release_object(Uint32 obj_ptr_i){
852 release_object(obj_ptr_i, c_obj_pool.getPtr(obj_ptr_i));
853 }
854
855 void release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p);
856
857 void increase_ref_count(Uint32 obj_ptr_i);
858 void decrease_ref_count(Uint32 obj_ptr_i);
859
860 public:
861 Dbdict(Block_context& ctx);
862 virtual ~Dbdict();
863
864 private:
865 BLOCK_DEFINES(Dbdict);
866
867 // Signal receivers
868 void execDICTSTARTREQ(Signal* signal);
869
870 void execGET_TABINFOREQ(Signal* signal);
871 void execGET_TABLEDID_REQ(Signal* signal);
872 void execGET_TABINFOREF(Signal* signal);
873 void execGET_TABINFO_CONF(Signal* signal);
874 void execCONTINUEB(Signal* signal);
875
876 void execDUMP_STATE_ORD(Signal* signal);
877 void execDBINFO_SCANREQ(Signal* signal);
878 void execHOT_SPAREREP(Signal* signal);
879 void execDIADDTABCONF(Signal* signal);
880 void execDIADDTABREF(Signal* signal);
881 void execTAB_COMMITCONF(Signal* signal);
882 void execTAB_COMMITREF(Signal* signal);
883 void execGET_SCHEMA_INFOREQ(Signal* signal);
884 void execSCHEMA_INFO(Signal* signal);
885 void execSCHEMA_INFOCONF(Signal* signal);
886 void execREAD_NODESCONF(Signal* signal);
887 void execFSCLOSECONF(Signal* signal);
888 void execFSOPENCONF(Signal* signal);
889 void execFSOPENREF(Signal* signal);
890 void execFSREADCONF(Signal* signal);
891 void execFSREADREF(Signal* signal);
892 void execFSWRITECONF(Signal* signal);
893 void execNDB_STTOR(Signal* signal);
894 void execREAD_CONFIG_REQ(Signal* signal);
895 void execSTTOR(Signal* signal);
896 void execTC_SCHVERCONF(Signal* signal);
897 void execNODE_FAILREP(Signal* signal);
898
899 void send_nf_complete_rep(Signal* signal, const NodeFailRep*);
900
901 void execINCL_NODEREQ(Signal* signal);
902 void execAPI_FAILREQ(Signal* signal);
903
904 void execWAIT_GCP_REF(Signal* signal);
905 void execWAIT_GCP_CONF(Signal* signal);
906
907 void execLIST_TABLES_REQ(Signal* signal);
908
909 // Index signals
910 void execCREATE_INDX_REQ(Signal* signal);
911 void execCREATE_INDX_IMPL_CONF(Signal* signal);
912 void execCREATE_INDX_IMPL_REF(Signal* signal);
913
914 void execALTER_INDX_REQ(Signal* signal);
915 void execALTER_INDX_CONF(Signal* signal);
916 void execALTER_INDX_REF(Signal* signal);
917 void execALTER_INDX_IMPL_CONF(Signal* signal);
918 void execALTER_INDX_IMPL_REF(Signal* signal);
919
920 void execCREATE_TABLE_CONF(Signal* signal);
921 void execCREATE_TABLE_REF(Signal* signal);
922
923 void execDROP_INDX_REQ(Signal* signal);
924 void execDROP_INDX_IMPL_CONF(Signal* signal);
925 void execDROP_INDX_IMPL_REF(Signal* signal);
926
927 void execDROP_TABLE_CONF(Signal* signal);
928 void execDROP_TABLE_REF(Signal* signal);
929
930 void execBUILDINDXREQ(Signal* signal);
931 void execBUILDINDXCONF(Signal* signal);
932 void execBUILDINDXREF(Signal* signal);
933 void execBUILD_INDX_IMPL_CONF(Signal* signal);
934 void execBUILD_INDX_IMPL_REF(Signal* signal);
935
936 void execBACKUP_LOCK_TAB_REQ(Signal*);
937
938 // Util signals used by Event code
939 void execUTIL_PREPARE_CONF(Signal* signal);
940 void execUTIL_PREPARE_REF (Signal* signal);
941 void execUTIL_EXECUTE_CONF(Signal* signal);
942 void execUTIL_EXECUTE_REF (Signal* signal);
943 void execUTIL_RELEASE_CONF(Signal* signal);
944 void execUTIL_RELEASE_REF (Signal* signal);
945
946
947 // Event signals from API
948 void execCREATE_EVNT_REQ (Signal* signal);
949 void execCREATE_EVNT_CONF(Signal* signal);
950 void execCREATE_EVNT_REF (Signal* signal);
951
952 void execDROP_EVNT_REQ (Signal* signal);
953
954 void execSUB_START_REQ (Signal* signal);
955 void execSUB_START_CONF (Signal* signal);
956 void execSUB_START_REF (Signal* signal);
957
958 void execSUB_STOP_REQ (Signal* signal);
959 void execSUB_STOP_CONF (Signal* signal);
960 void execSUB_STOP_REF (Signal* signal);
961
962 // Event signals from SUMA
963
964 void execCREATE_SUBID_CONF(Signal* signal);
965 void execCREATE_SUBID_REF (Signal* signal);
966
967 void execSUB_CREATE_CONF(Signal* signal);
968 void execSUB_CREATE_REF (Signal* signal);
969
970 void execSUB_REMOVE_REQ(Signal* signal);
971 void execSUB_REMOVE_CONF(Signal* signal);
972 void execSUB_REMOVE_REF(Signal* signal);
973
974 // Trigger signals
975 void execCREATE_TRIG_REQ(Signal* signal);
976 void execCREATE_TRIG_CONF(Signal* signal);
977 void execCREATE_TRIG_REF(Signal* signal);
978 void execALTER_TRIG_REQ(Signal* signal);
979 void execALTER_TRIG_CONF(Signal* signal);
980 void execALTER_TRIG_REF(Signal* signal);
981 void execDROP_TRIG_REQ(Signal* signal);
982 void execDROP_TRIG_CONF(Signal* signal);
983 void execDROP_TRIG_REF(Signal* signal);
984 // from other blocks
985 void execCREATE_TRIG_IMPL_CONF(Signal* signal);
986 void execCREATE_TRIG_IMPL_REF(Signal* signal);
987 void execDROP_TRIG_IMPL_CONF(Signal* signal);
988 void execDROP_TRIG_IMPL_REF(Signal* signal);
989
990 void execDROP_TABLE_REQ(Signal* signal);
991
992 void execPREP_DROP_TAB_REQ(Signal* signal);
993 void execPREP_DROP_TAB_REF(Signal* signal);
994 void execPREP_DROP_TAB_CONF(Signal* signal);
995
996 void execDROP_TAB_REF(Signal* signal);
997 void execDROP_TAB_CONF(Signal* signal);
998
999 void execCREATE_TABLE_REQ(Signal* signal);
1000 void execALTER_TABLE_REQ(Signal* signal);
1001
1002 Uint32 get_fragmentation(Signal*, Uint32 tableId);
1003 Uint32 create_fragmentation(Signal* signal, TableRecordPtr,
1004 const Uint16*, Uint32 cnt,
1005 Uint32 flags = 0);
1006 void execCREATE_FRAGMENTATION_REQ(Signal*);
1007 void execCREATE_FRAGMENTATION_REF(Signal*);
1008 void execCREATE_FRAGMENTATION_CONF(Signal*);
1009 void execCREATE_TAB_REQ(Signal* signal);
1010 void execADD_FRAGREQ(Signal* signal);
1011 void execLQHFRAGREF(Signal* signal);
1012 void execLQHFRAGCONF(Signal* signal);
1013 void execLQHADDATTREF(Signal* signal);
1014 void execLQHADDATTCONF(Signal* signal);
1015 void execCREATE_TAB_REF(Signal* signal);
1016 void execCREATE_TAB_CONF(Signal* signal);
1017 void execALTER_TAB_REF(Signal* signal);
1018 void execALTER_TAB_CONF(Signal* signal);
1019 void execALTER_TABLE_REF(Signal* signal);
1020 void execALTER_TABLE_CONF(Signal* signal);
1021 bool check_ndb_versions() const;
1022 int check_sender_version(const Signal* signal, Uint32 version) const;
1023
1024
1025 void execCREATE_FILE_REQ(Signal* signal);
1026 void execCREATE_FILEGROUP_REQ(Signal* signal);
1027 void execDROP_FILE_REQ(Signal* signal);
1028 void execDROP_FILEGROUP_REQ(Signal* signal);
1029
1030 // Internal
1031 void execCREATE_FILE_IMPL_REF(Signal* signal);
1032 void execCREATE_FILE_IMPL_CONF(Signal* signal);
1033 void execCREATE_FILEGROUP_IMPL_REF(Signal* signal);
1034 void execCREATE_FILEGROUP_IMPL_CONF(Signal* signal);
1035 void execDROP_FILE_IMPL_REF(Signal* signal);
1036 void execDROP_FILE_IMPL_CONF(Signal* signal);
1037 void execDROP_FILEGROUP_IMPL_REF(Signal* signal);
1038 void execDROP_FILEGROUP_IMPL_CONF(Signal* signal);
1039
1040 void execSCHEMA_TRANS_BEGIN_REQ(Signal* signal);
1041 void execSCHEMA_TRANS_BEGIN_CONF(Signal* signal);
1042 void execSCHEMA_TRANS_BEGIN_REF(Signal* signal);
1043 void execSCHEMA_TRANS_END_REQ(Signal* signal);
1044 void execSCHEMA_TRANS_END_CONF(Signal* signal);
1045 void execSCHEMA_TRANS_END_REF(Signal* signal);
1046 void execSCHEMA_TRANS_END_REP(Signal* signal);
1047 void execSCHEMA_TRANS_IMPL_REQ(Signal* signal);
1048 void execSCHEMA_TRANS_IMPL_CONF(Signal* signal);
1049 void execSCHEMA_TRANS_IMPL_REF(Signal* signal);
1050
1051 void execDICT_LOCK_REQ(Signal* signal);
1052 void execDICT_UNLOCK_ORD(Signal* signal);
1053
1054 void execDICT_TAKEOVER_REQ(Signal* signal);
1055 void execDICT_TAKEOVER_REF(Signal* signal);
1056 void execDICT_TAKEOVER_CONF(Signal* signal);
1057
1058 // ordered index statistics
1059 void execINDEX_STAT_REQ(Signal* signal);
1060 void execINDEX_STAT_CONF(Signal* signal);
1061 void execINDEX_STAT_REF(Signal* signal);
1062 void execINDEX_STAT_IMPL_CONF(Signal* signal);
1063 void execINDEX_STAT_IMPL_REF(Signal* signal);
1064 void execINDEX_STAT_REP(Signal* signal);
1065
1066 /*
1067 * 2.4 COMMON STORED VARIABLES
1068 */
1069
1070 /**
1071 * This record stores all the state needed
1072 * when the schema page is being sent to other nodes
1073 ***************************************************************************/
1074 struct SendSchemaRecord {
1075 /** Number of words of schema data */
1076 Uint32 noOfWords;
1077 /** Page Id of schema data */
1078 Uint32 pageId;
1079
1080 Uint32 nodeId;
1081 SignalCounter m_SCHEMAINFO_Counter;
1082
1083 Uint32 noOfWordsCurrentlySent;
1084 Uint32 noOfSignalsSentSinceDelay;
1085
1086 bool inUse;
1087 };
1088 SendSchemaRecord c_sendSchemaRecord;
1089
1090 /**
1091 * This record stores all the state needed
1092 * when a table file is being read from disk
1093 ****************************************************************************/
1094 struct ReadTableRecord {
1095 /** Number of Pages */
1096 Uint32 no_of_words;
1097 /** Page Id*/
1098 Uint32 pageId;
1099 /** Table Id of read table */
1100 Uint32 tableId;
1101
1102 bool inUse;
1103 Callback m_callback;
1104 };
1105 ReadTableRecord c_readTableRecord;
1106
1107 /**
1108 * This record stores all the state needed
1109 * when a table file is being written to disk
1110 ****************************************************************************/
1111 struct WriteTableRecord {
1112 /** Number of Pages */
1113 Uint32 no_of_words;
1114 /** Page Id*/
1115 Uint32 pageId;
1116 /** Table Files Handled, local state variable */
1117 Uint32 noOfTableFilesHandled;
1118 /** Table Id of written table */
1119 Uint32 tableId;
1120 /** State, indicates from where it was called */
1121 enum TableWriteState {
1122 IDLE = 0,
1123 WRITE_ADD_TABLE_MASTER = 1,
1124 WRITE_ADD_TABLE_SLAVE = 2,
1125 WRITE_RESTART_FROM_MASTER = 3,
1126 WRITE_RESTART_FROM_OWN = 4,
1127 TWR_CALLBACK = 5
1128 };
1129 TableWriteState tableWriteState;
1130 Callback m_callback;
1131 };
1132 WriteTableRecord c_writeTableRecord;
1133
1134 /**
1135 * This record stores all the state needed
1136 * when a schema file is being read from disk
1137 ****************************************************************************/
1138 struct ReadSchemaRecord {
1139 /** Page Id of schema page */
1140 Uint32 pageId;
1141 /** First page to read */
1142 Uint32 firstPage;
1143 /** Number of pages to read */
1144 Uint32 noOfPages;
1145 /** State, indicates from where it was called */
1146 enum SchemaReadState {
1147 IDLE = 0,
1148 INITIAL_READ_HEAD = 1,
1149 INITIAL_READ = 2
1150 };
1151 SchemaReadState schemaReadState;
1152 };
1153 ReadSchemaRecord c_readSchemaRecord;
1154
1155 /**
1156 * This record stores all the state needed
1157 * when a schema file is being written to disk
1158 ****************************************************************************/
1159 struct WriteSchemaRecord {
1160 /** Page Id of schema page */
1161 Uint32 pageId;
1162 /** Rewrite entire file */
1163 Uint32 newFile;
1164 /** First page to write */
1165 Uint32 firstPage;
1166 /** Number of pages to write */
1167 Uint32 noOfPages;
1168 /** Schema Files Handled, local state variable */
1169 Uint32 noOfSchemaFilesHandled;
1170
1171 bool inUse;
1172 Callback m_callback;
1173 };
1174 WriteSchemaRecord c_writeSchemaRecord;
1175
1176 /**
1177 * This record stores all the information needed
1178 * when a file is being read from disk
1179 ****************************************************************************/
1180 struct RestartRecord {
1181 /** Global check point identity */
1182 Uint32 gciToRestart;
1183
1184 /** The active table at restart process */
1185 Uint32 activeTable;
1186
1187 /** The active table at restart process */
1188 BlockReference returnBlockRef;
1189 Uint32 m_senderData;
1190
1191 Uint32 m_pass; // 0 tablespaces/logfilegroups, 1 tables, 2 indexes
1192 Uint32 m_end_pass; //
1193 const char * m_start_banner;
1194 const char * m_end_banner;
1195
1196 Uint32 m_tx_ptr_i;
1197 Uint32 m_op_cnt;
1198 SchemaFile::TableEntry m_entry;
1199 };
1200 RestartRecord c_restartRecord;
1201
1202 /**
1203 * This record stores all the information needed
1204 * when a file is being read from disk
1205 ****************************************************************************/
1206 struct RetrieveRecord {
RetrieveRecordDbdict::RetrieveRecord1207 RetrieveRecord():
1208 busyState(false) {};
1209
1210 /** Only one retrieve table definition at a time */
1211 bool busyState;
1212
1213 /** Block Reference of retriever */
1214 BlockReference blockRef;
1215
1216 /** Id of retriever */
1217 Uint32 m_senderData;
1218
1219 /** Table id of retrieved table */
1220 Uint32 tableId;
1221
1222 Uint32 m_table_type;
1223
1224 /** Starting page to retrieve data from */
1225 Uint32 retrievePage;
1226
1227 /** Number of pages retrieved */
1228 Uint32 retrievedNoOfPages;
1229
1230 /** Number of words retrieved */
1231 Uint32 retrievedNoOfWords;
1232
1233 /** Number of words sent currently */
1234 Uint32 currentSent;
1235
1236 /**
1237 * Long signal stuff
1238 */
1239 bool m_useLongSig;
1240
1241 Uint32 schemaTransId;
1242 Uint32 requestType;
1243 };
1244 RetrieveRecord c_retrieveRecord;
1245
1246 class GetTabInfoReqQueue
1247 {
1248 public:
1249 /**
1250 * GetTabInfoReqQueue
1251 *
1252 * This is a queue of GetTabInfoReq signals
1253 * It queues signals from internal (other data nodes)
1254 * and external (NdbApi clients) sources.
1255 * It gives preference to internal requests, but avoids
1256 * starvation.
1257 * Signals are queued using SegmentLists - using
1258 * SegmentedSections to implement a FIFO queue.
1259 * There is an internal requests list and an
1260 * external requests lists.
1261 * To ensure that internal requests can proceed
1262 * during overload, the internal segment list uses
1263 * Segments from a reserved sub pool.
1264 * The external requests use segments from the
1265 * global pool, which may not be able to provide
1266 * segments when the system is overloaded.
1267 * For this reason, an external request can fail
1268 * to be enqueued, resulting in a BUSY response,
1269 * whereas an internal request should never encounter
1270 * this.
1271 * Internal requests are fully catered for as they have
1272 * bounded concurrency, and probably higher priority.
1273 * External requests currently have almost unbounded
1274 * concurrency.
1275 */
GetTabInfoReqQueue(SegmentUtils & pool)1276 explicit GetTabInfoReqQueue(SegmentUtils& pool):
1277 m_internalSegmentPool(pool),
1278 m_internalQueue(m_internalQueueHead,
1279 m_internalSegmentPool),
1280 m_consecutiveInternalReqCount(0),
1281 m_externalSegmentPool(pool),
1282 m_externalQueue(m_externalQueueHead,
1283 m_externalSegmentPool),
1284 m_jamBuffer(0)
1285 {};
1286
init(EmulatedJamBuffer * jamBuff)1287 bool init(EmulatedJamBuffer* jamBuff)
1288 {
1289 m_jamBuffer = jamBuff;
1290 return m_internalSegmentPool.init(InternalSegmentPoolSize,
1291 InternalSegmentPoolSize);
1292 }
1293
1294 /**
1295 * isEmpty
1296 *
1297 * Are both queues empty
1298 */
isEmpty() const1299 bool isEmpty() const
1300 {
1301 return (m_internalQueue.isEmpty() &&
1302 m_externalQueue.isEmpty());
1303 };
1304
1305 /**
1306 * tryEnqReq
1307 *
1308 * Try to enqueue a request on the indicated queue
1309 * Returns false if this was not possible
1310 */
tryEnqReq(bool internal,Signal * signal)1311 bool tryEnqReq(bool internal,
1312 Signal* signal)
1313 {
1314 thrjam(m_jamBuffer);
1315 /* Put data inline in signal buffer for atomic enq */
1316 signal->theData[GetTabInfoReq::SignalLength] =
1317 signal->header.m_noOfSections;
1318
1319 memcpy(&signal->theData[GetTabInfoReq::SignalLength+1],
1320 signal->m_sectionPtrI,
1321 3 * sizeof(Uint32));
1322
1323 LocalSegmentList& reqQueue = internal?
1324 m_internalQueue:
1325 m_externalQueue;
1326
1327 /* Check that we are allowed to queue another req */
1328 Uint32 maxReqs = 0;
1329
1330 if (internal)
1331 maxReqs = MaxInternalReqs;
1332 else
1333 maxReqs = MaxExternalReqs;
1334
1335 if (getNumReqs(reqQueue) >= maxReqs)
1336 {
1337 thrjam(m_jamBuffer);
1338 return false;
1339 }
1340
1341 assert(ElementLen == 9); /* Just in case someone adds words...*/
1342
1343 if (reqQueue.enqWords(signal->theData,
1344 ElementLen))
1345 {
1346 thrjam(m_jamBuffer);
1347 /* Detach section(s) */
1348 signal->header.m_noOfSections = 0;
1349 return true;
1350 }
1351
1352 /* Enqueue failed */
1353 return false;
1354 }
1355
1356 /**
1357 * deqReq
1358 *
1359 * Dequeue the next request to work on, setting up the Signal
1360 * object with signal data (and sections if appropriate)
1361 * Assumes that there is some next request to be processed.
1362 */
deqReq(Signal * signal)1363 bool deqReq(Signal* signal)
1364 {
1365 assert(signal->header.m_noOfSections == 0);
1366 assert(!isEmpty());
1367
1368 LocalSegmentList& reqQueue = isInternalQueueNext()?
1369 m_internalQueue :
1370 m_externalQueue;
1371
1372 assert(getNumReqs(reqQueue) > 0);
1373
1374 Uint32 noOfSections;
1375
1376 /* Restore signal context from queue...*/
1377 if (reqQueue.deqWords(signal->theData, GetTabInfoReq::SignalLength) &&
1378 reqQueue.deqWords(&noOfSections, 1) &&
1379 reqQueue.deqWords(signal->m_sectionPtrI, 3))
1380 {
1381 signal->header.m_noOfSections = (Uint8) noOfSections;
1382 return true;
1383 }
1384 return false;
1385 }
1386
1387 private:
1388 /**
1389 * isInternalQueueNext
1390 *
1391 * Which queue should provide the next request
1392 * to work on
1393 */
isInternalQueueNext()1394 bool isInternalQueueNext()
1395 {
1396 thrjam(m_jamBuffer);
1397 /**
1398 * Prefer the internal request queue, unless we've already
1399 * had a number of those requests consecutively and an
1400 * external request is waiting.
1401 */
1402 if (!m_internalQueue.isEmpty())
1403 {
1404 thrjam(m_jamBuffer);
1405 if (m_externalQueue.isEmpty() ||
1406 m_consecutiveInternalReqCount <= MaxInternalPerExternal)
1407 {
1408 thrjam(m_jamBuffer);
1409 m_consecutiveInternalReqCount++;
1410 return true; /* Use internal */
1411 }
1412 }
1413 m_consecutiveInternalReqCount = 0;
1414 return false; /* Use external */
1415 }
1416
1417 /**
1418 * getNumReqs
1419 *
1420 * Get the number of requests in the given queue
1421 */
getNumReqs(const LocalSegmentList & queue) const1422 Uint32 getNumReqs(const LocalSegmentList& queue) const
1423 {
1424 Uint32 qWordLen = queue.getLen();
1425 assert((qWordLen % ElementLen) == 0);
1426 return qWordLen / ElementLen;
1427 };
1428
1429 /* Length of GetTabInfoReq queue elements */
1430 static const Uint32 ElementLen = GetTabInfoReq::SignalLength + 1 + 3;
1431
1432 /**
1433 * Pessimistic estimate of worst-case internally sourced
1434 * GET_TABINFOREQ concurrency.
1435 * Needs updated if more concurrency or use cases are added
1436 */
1437 static const uint MaxInternalReqs =
1438 MAX_NDB_NODES + /* restartCreateObj() forward to Master */
1439 1 + /* SUMA SUB_CREATE_REQ */
1440 (2 * MAX_NDBMT_LQH_THREADS) + /* Backup - 1 LCP + 1 Backup per LDM instance */
1441 1; /* Trix Index stat */
1442
1443 /**
1444 * InternalSegmentPoolSize
1445 * Enough segments to take MaxInternalReqs,
1446 * + 1 to handle max offset within the first segment
1447 */
1448 static const Uint32 InternalSegmentPoolSize =
1449 (((MaxInternalReqs * ElementLen) + SectionSegment::DataLength - 1)/
1450 SectionSegment::DataLength ) + 1;
1451
1452 /**
1453 * Internal waiters queue
1454 * Uses a reserved segment sub pool.
1455 * We keep a LocalSegmentList around permanently
1456 */
1457 SegmentSubPool m_internalSegmentPool;
1458 SegmentListHead m_internalQueueHead;
1459 LocalSegmentList m_internalQueue;
1460
1461 /**
1462 * Avoid external request starvation
1463 */
1464 static const Uint32 MaxInternalPerExternal = 10;
1465 Uint32 m_consecutiveInternalReqCount;
1466
1467 /**
1468 * External waiters queue
1469 * Uses global segment pool.
1470 *
1471 * Max of 1 req per node on average, can be
1472 * less in overload.
1473 */
1474 static const Uint32 MaxExternalReqs = MAX_NODES;
1475 SegmentUtils& m_externalSegmentPool;
1476 SegmentListHead m_externalQueueHead;
1477 LocalSegmentList m_externalQueue;
1478
1479
1480 EmulatedJamBuffer* m_jamBuffer;
1481 };
1482
1483 GetTabInfoReqQueue c_gettabinforeq_q;
1484
1485 /**
1486 * This record stores all the information needed
1487 * when a file is being read from disk
1488 *
1489 * This is the info stored in one entry of the schema
1490 * page. Each table has 4 words of info.
1491 * Word 1: Schema version (upper 16 bits)
1492 * Table State (lower 16 bits)
1493 * Word 2: Number of pages of table description
1494 * Word 3: Global checkpoint id table was created
1495 * Word 4: Currently zero
1496 ****************************************************************************/
1497 struct SchemaRecord {
1498 enum
1499 {
1500 NEW_SCHEMA_FILE = 0, // Index in c_schemaFile
1501 OLD_SCHEMA_FILE = 1
1502 };
1503
1504 /** Schema file first page (0) */
1505 Uint32 schemaPage;
1506
1507 /** Old Schema file first page (used at node restart) */
1508 Uint32 oldSchemaPage;
1509
1510 Callback m_callback;
1511 };
1512 SchemaRecord c_schemaRecord;
1513
1514 /*
1515 * Schema file, list of schema pages. Use an array until a pool
1516 * exists and NDBFS interface can use it.
1517 */
1518 struct XSchemaFile {
1519 SchemaFile* schemaPage;
1520 Uint32 noOfPages;
1521 };
1522 // 0-normal 1-old
1523 XSchemaFile c_schemaFile[2];
1524
1525 void initSchemaFile(XSchemaFile *, Uint32 firstPage, Uint32 lastPage,
1526 bool initEntries);
1527 void resizeSchemaFile(XSchemaFile * xsf, Uint32 noOfPages);
1528 void modifySchemaFileAtRestart(XSchemaFile * xsf);
1529 void computeChecksum(XSchemaFile *, Uint32 pageNo);
1530 bool validateChecksum(const XSchemaFile *);
1531 SchemaFile::TableEntry * getTableEntry(Uint32 tableId);
1532 SchemaFile::TableEntry * getTableEntry(XSchemaFile *, Uint32 tableId);
1533 const SchemaFile::TableEntry * getTableEntry(const XSchemaFile*, Uint32);
1534
1535 Uint32 computeChecksum(const Uint32 * src, Uint32 len);
1536
1537 void doGET_TABINFOREQ(Signal* signal);
1538
1539
1540 /* ----------------------------------------------------------------------- */
1541 // Node References
1542 /* ----------------------------------------------------------------------- */
1543 Uint16 c_masterNodeId;
1544
1545 /* ----------------------------------------------------------------------- */
1546 // Various current system properties
1547 /* ----------------------------------------------------------------------- */
1548 Uint16 c_numberNode;
1549 Uint16 c_noHotSpareNodes;
1550 Uint16 c_noNodesFailed;
1551 Uint32 c_failureNr;
1552
1553 /* ----------------------------------------------------------------------- */
1554 // State variables
1555 /* ----------------------------------------------------------------------- */
1556
1557 struct PackTable {
1558
1559 enum PackTableState {
1560 PTS_IDLE = 0,
1561 PTS_GET_TAB = 3
1562 } m_state;
1563
1564 } c_packTable;
1565
1566 Uint32 c_startPhase;
1567 Uint32 c_restartType;
1568 bool c_initialStart;
1569 bool c_systemRestart;
1570 bool c_nodeRestart;
1571 bool c_initialNodeRestart;
1572 Uint32 c_tabinfoReceived;
1573 /**
1574 * This flag indicates that a dict takeover is in progress, specifically
1575 * that the new master has outstanding DICT_TAKEOVER_REQ messages. The flag
1576 * is used to prevent client from starting (or ending) transactions during
1577 * takeover.
1578 */
1579 bool c_takeOverInProgress;
1580
1581 /**
1582 * Temporary structure used when parsing table info
1583 */
1584 struct ParseDictTabInfoRecord {
ParseDictTabInfoRecordDbdict::ParseDictTabInfoRecord1585 ParseDictTabInfoRecord() { tablePtr.setNull();}
1586 DictTabInfo::RequestType requestType;
1587 Uint32 errorCode;
1588 Uint32 errorLine;
1589
1590 SimpleProperties::UnpackStatus status;
1591 Uint32 errorKey;
1592 TableRecordPtr tablePtr;
1593 };
1594
1595 // Misc helpers
1596
1597 template <Uint32 sz>
1598 inline bool
copyRope(RopeHandle & rh_dst,const RopeHandle & rh_src)1599 copyRope(RopeHandle& rh_dst, const RopeHandle& rh_src)
1600 {
1601 char buf[sz];
1602 LocalRope r_dst(c_rope_pool, rh_dst);
1603 ConstRope r_src(c_rope_pool, rh_src);
1604 ndbrequire(r_src.size() <= sz);
1605 r_src.copy(buf);
1606 bool ok = r_dst.assign(buf, r_src.size());
1607 return ok;
1608 }
1609
1610 #ifdef VM_TRACE
1611 template <Uint32 sz>
1612 inline const char*
copyRope(const RopeHandle & rh)1613 copyRope(const RopeHandle& rh)
1614 {
1615 static char buf[2][sz];
1616 static int i = 0;
1617 ConstRope r(c_rope_pool, rh);
1618 char* str = buf[i++ % 2];
1619 r.copy(str);
1620 return str;
1621 }
1622 #endif
1623
1624 // Operation records
1625
1626 /**
1627 * Common part of operation records. Uses KeyTable2. Note that each
1628 * seize/release invokes ctor/dtor automatically.
1629 */
1630 struct OpRecordCommon {
OpRecordCommonDbdict::OpRecordCommon1631 OpRecordCommon() {}
1632 Uint32 key; // key shared between master and slaves
1633 Uint32 nextHash;
1634 Uint32 prevHash;
hashValueDbdict::OpRecordCommon1635 Uint32 hashValue() const {
1636 return key;
1637 }
equalDbdict::OpRecordCommon1638 bool equal(const OpRecordCommon& rec) const {
1639 return key == rec.key;
1640 }
1641 };
1642
1643 // MODULE: SchemaTrans
1644
1645 struct SchemaOp;
1646 struct SchemaTrans;
1647 struct TxHandle;
1648 typedef Ptr<SchemaOp> SchemaOpPtr;
1649 typedef Ptr<SchemaTrans> SchemaTransPtr;
1650 typedef Ptr<TxHandle> TxHandlePtr;
1651
1652 // ErrorInfo
1653
1654 struct ErrorInfo {
1655 Uint32 errorCode;
1656 Uint32 errorLine;
1657 Uint32 errorNodeId;
1658 Uint32 errorCount;
1659 // for CreateTable
1660 Uint32 errorStatus;
1661 Uint32 errorKey;
1662 char errorObjectName[MAX_TAB_NAME_SIZE];
ErrorInfoDbdict::ErrorInfo1663 ErrorInfo() {
1664 errorCode = 0;
1665 errorLine = 0;
1666 errorNodeId = 0;
1667 errorCount = 0;
1668 errorStatus = 0;
1669 errorKey = 0;
1670 errorObjectName[0] = 0;
1671 }
1672 void print(NdbOut&) const;
1673 private:
1674 ErrorInfo& operator=(const ErrorInfo&);
1675 };
1676
1677 void setError(ErrorInfo&,
1678 Uint32 code,
1679 Uint32 line,
1680 Uint32 nodeId = 0,
1681 Uint32 status = 0,
1682 Uint32 key = 0,
1683 const char * name = 0);
1684
1685 void setError(ErrorInfo&,
1686 Uint32 code,
1687 Uint32 line,
1688 const char * name);
1689
1690 void setError(ErrorInfo&, const ErrorInfo&);
1691 void setError(ErrorInfo&, const ParseDictTabInfoRecord&);
1692
1693 void setError(SchemaOpPtr, Uint32 code, Uint32 line, Uint32 nodeId = 0);
1694 void setError(SchemaOpPtr, const ErrorInfo&);
1695
1696 void setError(SchemaTransPtr, Uint32 code, Uint32 line, Uint32 nodeId = 0);
1697 void setError(SchemaTransPtr, const ErrorInfo&);
1698
1699 void setError(TxHandlePtr, Uint32 code, Uint32 line, Uint32 nodeId = 0);
1700 void setError(TxHandlePtr, const ErrorInfo&);
1701
1702 template <class Ref>
1703 inline void
setError(ErrorInfo & e,const Ref * ref)1704 setError(ErrorInfo& e, const Ref* ref) {
1705 setError(e, ref->errorCode, ref->errorLine, ref->errorNodeId);
1706 }
1707
1708 template <class Ref>
1709 inline void
getError(const ErrorInfo & e,Ref * ref)1710 getError(const ErrorInfo& e, Ref* ref) {
1711 ref->errorCode = e.errorCode;
1712 ref->errorLine = e.errorLine;
1713 ref->errorNodeId = e.errorNodeId;
1714 ref->masterNodeId = c_masterNodeId;
1715 }
1716
1717 bool hasError(const ErrorInfo&);
1718
1719 void resetError(ErrorInfo&);
1720 void resetError(SchemaOpPtr);
1721 void resetError(SchemaTransPtr);
1722 void resetError(TxHandlePtr);
1723
1724 // OpInfo
1725
1726 struct OpInfo {
1727 const char m_opType[4]; // e.g. CTa for CreateTable. TODO: remove. use only m_magic?
1728 Uint32 m_magic;
1729 Uint32 m_impl_req_gsn;
1730 Uint32 m_impl_req_length;
1731
1732 // seize / release type-specific Data record
1733 bool (Dbdict::*m_seize)(SchemaOpPtr);
1734 void (Dbdict::*m_release)(SchemaOpPtr);
1735
1736 // parse phase
1737 void (Dbdict::*m_parse)(Signal*, bool master,
1738 SchemaOpPtr, SectionHandle&, ErrorInfo&);
1739 bool (Dbdict::*m_subOps)(Signal*, SchemaOpPtr);
1740 void (Dbdict::*m_reply)(Signal*, SchemaOpPtr, ErrorInfo);
1741
1742 // run phases
1743 void (Dbdict::*m_prepare)(Signal*, SchemaOpPtr);
1744 void (Dbdict::*m_commit)(Signal*, SchemaOpPtr);
1745 void (Dbdict::*m_complete)(Signal*, SchemaOpPtr);
1746 // abort mode
1747 void (Dbdict::*m_abortParse)(Signal*, SchemaOpPtr);
1748 void (Dbdict::*m_abortPrepare)(Signal*, SchemaOpPtr);
1749 };
1750
1751 // all OpInfo records
1752 static const OpInfo* g_opInfoList[];
1753 const OpInfo* findOpInfo(Uint32 gsn);
1754
1755 // OpRec
1756
1757 struct OpRec
1758 {
1759 char m_opType[4]; // TODO: remove. only use m_magic
1760
1761 Uint32 nextPool;
1762
1763 Uint32 m_magic;
1764
1765 // reference to the static member in subclass
1766 const OpInfo& m_opInfo;
1767
1768 // pointer to internal signal in subclass instance
1769 Uint32* const m_impl_req_data;
1770
1771 // DictObject operated on
1772 Uint32 m_obj_ptr_i;
1773
OpRecDbdict::OpRec1774 OpRec(const OpInfo& info, Uint32* impl_req_data) :
1775 m_magic(info.m_magic),
1776 m_opInfo(info),
1777 m_impl_req_data(impl_req_data) {
1778 m_obj_ptr_i = RNIL;
1779 memcpy(m_opType, m_opInfo.m_opType, 4);
1780 }
1781 };
1782 typedef Ptr<OpRec> OpRecPtr;
1783
1784 /*
1785 * OpSection
1786 *
1787 * Signal sections are released in parse phase. If necessary
1788 * they are first saved under schema op record.
1789 */
1790
1791 enum { OpSectionSegmentSize = 127 };
1792 typedef
1793 LocalDataBuffer2<OpSectionSegmentSize, LocalArenaPoolImpl>
1794 OpSectionBuffer;
1795 typedef
1796 DataBuffer2<OpSectionSegmentSize, LocalArenaPoolImpl>::Head
1797 OpSectionBufferHead;
1798 typedef
1799 OpSectionBuffer::DataBufferPool
1800 OpSectionBufferPool;
1801 typedef
1802 DataBuffer2<OpSectionSegmentSize, LocalArenaPoolImpl>::ConstDataBufferIterator
1803 OpSectionBufferConstIterator;
1804
1805 ArenaPool c_opSectionBufferPool;
1806
1807 struct OpSection {
1808 OpSectionBufferHead m_head;
getSizeDbdict::OpSection1809 Uint32 getSize() const {
1810 return m_head.getSize();
1811 }
1812 };
1813
1814 bool copyIn(OpSectionBufferPool&, OpSection&, const SegmentedSectionPtr&);
1815 bool copyIn(OpSectionBufferPool&, OpSection&, const Uint32* src, Uint32 srcSize);
1816 bool copyOut(OpSectionBufferPool&, const OpSection&, SegmentedSectionPtr&);
1817 bool copyOut(OpSectionBufferPool&, const OpSection&, Uint32* dst, Uint32 dstSize);
1818 bool copyOut(OpSectionBuffer & buffer, OpSectionBufferConstIterator & iter,
1819 Uint32 * dst, Uint32 len);
1820 void release(OpSectionBufferPool&, OpSection&);
1821
1822 // SchemaOp
1823
1824 struct SchemaOp {
1825 Uint32 nextPool;
1826
1827 enum OpState
1828 {
1829 OS_INITIAL = 0,
1830 OS_PARSE_MASTER = 1,
1831 OS_PARSING = 2,
1832 OS_PARSED = 3,
1833 OS_PREPARING = 4,
1834 OS_PREPARED = 5,
1835 OS_ABORTING_PREPARE = 6,
1836 OS_ABORTED_PREPARE = 7,
1837 OS_ABORTING_PARSE = 8,
1838 //OS_ABORTED_PARSE = 9, // Not used, op released
1839 OS_COMMITTING = 10,
1840 OS_COMMITTED = 11,
1841 OS_COMPLETING = 12,
1842 OS_COMPLETED = 13
1843 };
1844
1845 Uint32 m_state;
1846 /*
1847 Return the "weight" of an operation state, used to determine
1848 the absolute order of operations.
1849 */
weightDbdict::SchemaOp1850 static Uint32 weight(Uint32 state) {
1851 switch ((OpState) state) {
1852 case OS_INITIAL:
1853 return 0;
1854 case OS_PARSE_MASTER:
1855 return 1;
1856 case OS_PARSING:
1857 return 2;
1858 case OS_PARSED:
1859 return 5;
1860 case OS_PREPARING:
1861 return 6;
1862 case OS_PREPARED:
1863 return 9;
1864 case OS_ABORTING_PREPARE:
1865 return 8;
1866 case OS_ABORTED_PREPARE:
1867 return 7;
1868 case OS_ABORTING_PARSE:
1869 return 4;
1870 //case OS_ABORTED_PARSE = 9, // Not used, op released
1871 //return 3:
1872 case OS_COMMITTING:
1873 return 10;
1874 case OS_COMMITTED:
1875 return 11;
1876 case OS_COMPLETING:
1877 return 12;
1878 case OS_COMPLETED:
1879 return 13;
1880 }
1881 assert(false);
1882 return -1;
1883 }
1884 Uint32 m_restart;
1885 Uint32 op_key;
1886 Uint32 m_base_op_ptr_i;
1887 Uint32 nextHash;
1888 Uint32 prevHash;
hashValueDbdict::SchemaOp1889 Uint32 hashValue() const {
1890 return op_key;
1891 }
equalDbdict::SchemaOp1892 bool equal(const SchemaOp& rec) const {
1893 return op_key == rec.op_key;
1894 }
1895
1896 Uint32 nextList;
1897 Uint32 prevList;
1898
1899 // tx client or DICT master for recursive ops
1900 Uint32 m_clientRef;
1901 Uint32 m_clientData;
1902
1903 // requestExtra and requestFlags from REQ and trans level
1904 Uint32 m_requestInfo;
1905
1906 // the op belongs to this trans
1907 SchemaTransPtr m_trans_ptr;
1908
1909 // type specific record (the other half of schema op)
1910 OpRecPtr m_oprec_ptr;
1911
1912 // saved signal sections or other variable data
1913 OpSection m_section[3];
1914 Uint32 m_sections;
1915
1916 // callback for use with sub-operations
1917 Callback m_callback;
1918
1919 // link to an extra "helper" op and link back from it
1920 SchemaOpPtr m_oplnk_ptr;
1921 SchemaOpPtr m_opbck_ptr;
1922
1923 // error always propagates to trans level
1924 ErrorInfo m_error;
1925
1926 // Copy of original and current schema file entry
1927 Uint32 m_orig_entry_id;
1928 SchemaFile::TableEntry m_orig_entry;
1929
1930 // magic is on when record is seized
1931 enum { DICT_MAGIC = ~RT_DBDICT_SCHEMA_OPERATION };
1932 Uint32 m_magic;
1933
SchemaOpDbdict::SchemaOp1934 SchemaOp() {
1935 m_restart = 0;
1936 m_clientRef = 0;
1937 m_clientData = 0;
1938 m_requestInfo = 0;
1939 m_trans_ptr.setNull();
1940 m_oprec_ptr.setNull();
1941 m_sections = 0;
1942 m_callback.m_callbackFunction = 0;
1943 m_callback.m_callbackData = 0;
1944 m_oplnk_ptr.setNull();
1945 m_opbck_ptr.setNull();
1946 m_magic = DICT_MAGIC;
1947 m_base_op_ptr_i = RNIL;
1948
1949 m_orig_entry_id = RNIL;
1950 m_orig_entry.init();
1951 }
1952
SchemaOpDbdict::SchemaOp1953 SchemaOp(Uint32 the_op_key) {
1954 op_key = the_op_key;
1955 }
1956
1957 #ifdef VM_TRACE
1958 void print(NdbOut&) const;
1959 #endif
1960 };
1961
1962 typedef RecordPool<SchemaOp,ArenaPool> SchemaOp_pool;
1963 typedef DLMHashTable<SchemaOp_pool, SchemaOp> SchemaOp_hash;
1964 typedef DLFifoListImpl<SchemaOp_pool, SchemaOp, SchemaOp>::Head SchemaOp_head;
1965 typedef LocalDLFifoListImpl<SchemaOp_pool, SchemaOp, SchemaOp> LocalSchemaOp_list;
1966
1967 SchemaOp_pool c_schemaOpPool;
1968 SchemaOp_hash c_schemaOpHash;
1969
1970 const OpInfo& getOpInfo(SchemaOpPtr op_ptr);
1971
1972 // set or get the type specific record cast to the specific type
1973
1974 template <class T>
1975 inline void
setOpRec(SchemaOpPtr op_ptr,const Ptr<T> t_ptr)1976 setOpRec(SchemaOpPtr op_ptr, const Ptr<T> t_ptr) {
1977 OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
1978 ndbrequire(!t_ptr.isNull());
1979 oprec_ptr.i = t_ptr.i;
1980 oprec_ptr.p = static_cast<OpRec*>(t_ptr.p);
1981 ndbrequire(memcmp(t_ptr.p->m_opType, T::g_opInfo.m_opType, 4) == 0);
1982 }
1983
1984 template <class T>
1985 inline void
getOpRec(SchemaOpPtr op_ptr,Ptr<T> & t_ptr)1986 getOpRec(SchemaOpPtr op_ptr, Ptr<T>& t_ptr) {
1987 OpRecPtr oprec_ptr = op_ptr.p->m_oprec_ptr;
1988 ndbrequire(!oprec_ptr.isNull());
1989 t_ptr.i = oprec_ptr.i;
1990 t_ptr.p = static_cast<T*>(oprec_ptr.p);
1991 ndbrequire(memcmp(t_ptr.p->m_opType, T::g_opInfo.m_opType, 4) == 0);
1992 }
1993
1994 // OpInfo m_seize, m_release
1995
1996 template <class T>
1997 inline bool
seizeOpRec(SchemaOpPtr op_ptr)1998 seizeOpRec(SchemaOpPtr op_ptr) {
1999 OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
2000 RecordPool<T,ArenaPool>& pool = T::getPool(this);
2001 Ptr<T> t_ptr;
2002 if (pool.seize(op_ptr.p->m_trans_ptr.p->m_arena, t_ptr)) {
2003 new (t_ptr.p) T();
2004 setOpRec<T>(op_ptr, t_ptr);
2005 return true;
2006 }
2007 oprec_ptr.setNull();
2008 return false;
2009 }
2010
2011 template <class T>
2012 inline void
releaseOpRec(SchemaOpPtr op_ptr)2013 releaseOpRec(SchemaOpPtr op_ptr) {
2014 OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
2015 RecordPool<T,ArenaPool>& pool = T::getPool(this);
2016 Ptr<T> t_ptr;
2017 getOpRec<T>(op_ptr, t_ptr);
2018 pool.release(t_ptr);
2019 oprec_ptr.setNull();
2020 }
2021
2022 // seize / find / release, atomic on op rec + data rec
2023
2024 bool seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Uint32 op_key, const OpInfo& info, bool linked=false);
2025
2026 template <class T>
2027 inline bool
seizeSchemaOp(SchemaTransPtr trans_ptr,SchemaOpPtr & op_ptr,Uint32 op_key,bool linked)2028 seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Uint32 op_key, bool linked) {
2029 return seizeSchemaOp(trans_ptr, op_ptr, op_key, T::g_opInfo, linked);
2030 }
2031
2032 template <class T>
2033 inline bool
seizeSchemaOp(SchemaTransPtr trans_ptr,SchemaOpPtr & op_ptr,Ptr<T> & t_ptr,Uint32 op_key)2034 seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, Uint32 op_key) {
2035 if (seizeSchemaOp<T>(trans_ptr, op_ptr, op_key)) {
2036 getOpRec<T>(op_ptr, t_ptr);
2037 return true;
2038 }
2039 return false;
2040 }
2041
2042 template <class T>
2043 inline bool
seizeSchemaOp(SchemaTransPtr trans_ptr,SchemaOpPtr & op_ptr,bool linked)2044 seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, bool linked) {
2045 /*
2046 Store node id in high 8 bits to make op_key globally unique
2047 */
2048 Uint32 op_key =
2049 (getOwnNodeId() << 24) +
2050 ((c_opRecordSequence + 1) & 0x00FFFFFF);
2051 if (seizeSchemaOp<T>(trans_ptr, op_ptr, op_key, linked)) {
2052 c_opRecordSequence++;
2053 return true;
2054 }
2055 return false;
2056 }
2057
2058 template <class T>
2059 inline bool
seizeSchemaOp(SchemaTransPtr trans_ptr,SchemaOpPtr & op_ptr,Ptr<T> & t_ptr,bool linked=false)2060 seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, bool linked=false) {
2061 if (seizeSchemaOp<T>(trans_ptr, op_ptr, linked)) {
2062 getOpRec<T>(op_ptr, t_ptr);
2063 return true;
2064 }
2065 return false;
2066 }
2067
2068 template <class T>
2069 inline bool
seizeLinkedSchemaOp(SchemaOpPtr op_ptr,SchemaOpPtr & oplnk_ptr,Ptr<T> & t_ptr)2070 seizeLinkedSchemaOp(SchemaOpPtr op_ptr, SchemaOpPtr& oplnk_ptr, Ptr<T>& t_ptr) {
2071 ndbrequire(op_ptr.p->m_oplnk_ptr.isNull());
2072 if (seizeSchemaOp<T>(op_ptr.p->m_trans_ptr, oplnk_ptr, true)) {
2073 op_ptr.p->m_oplnk_ptr = oplnk_ptr;
2074 oplnk_ptr.p->m_opbck_ptr = op_ptr;
2075 getOpRec<T>(oplnk_ptr, t_ptr);
2076 return true;
2077 }
2078 oplnk_ptr.setNull();
2079 return false;
2080 }
2081
2082 bool findSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key);
2083
2084 template <class T>
2085 inline bool
findSchemaOp(SchemaOpPtr & op_ptr,Ptr<T> & t_ptr,Uint32 op_key)2086 findSchemaOp(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, Uint32 op_key) {
2087 if (findSchemaOp(op_ptr, op_key)) {
2088 getOpRec(op_ptr, t_ptr);
2089 return true;
2090 }
2091 return false;
2092 }
2093
2094 void releaseSchemaOp(SchemaOpPtr& op_ptr);
2095
2096 // copy signal sections to schema op sections
2097 const OpSection& getOpSection(SchemaOpPtr, Uint32 ss_no);
2098 bool saveOpSection(SchemaOpPtr, SectionHandle&, Uint32 ss_no);
2099 bool saveOpSection(SchemaOpPtr, SegmentedSectionPtr ss_ptr, Uint32 ss_no);
2100 void releaseOpSection(SchemaOpPtr, Uint32 ss_no);
2101
2102 // add operation to transaction OpList
2103 void addSchemaOp(SchemaOpPtr);
2104
2105 void updateSchemaOpStep(SchemaTransPtr, SchemaOpPtr);
2106
2107 // the link between SdhemaOp and DictObject (1-way now)
2108
2109 bool hasDictObject(SchemaOpPtr);
2110 void getDictObject(SchemaOpPtr, DictObjectPtr&);
2111 void linkDictObject(SchemaOpPtr op_ptr, DictObjectPtr obj_ptr);
2112 void unlinkDictObject(SchemaOpPtr op_ptr);
2113 void seizeDictObject(SchemaOpPtr, DictObjectPtr&, const RopeHandle& name);
2114 bool findDictObject(SchemaOpPtr, DictObjectPtr&, const char* name);
2115 bool findDictObject(SchemaOpPtr, DictObjectPtr&, Uint32 obj_ptr_i);
2116 void releaseDictObject(SchemaOpPtr);
2117 void findDictObjectOp(SchemaOpPtr&, DictObjectPtr);
2118
2119 /*
2120 * Trans client is the API client (not us, for recursive ops).
2121 * Its state is shared by SchemaTrans / TxHandle (for takeover).
2122 */
2123 struct TransClient {
2124 enum State {
2125 StateUndef = 0,
2126 BeginReq = 1, // begin trans received
2127 BeginReply = 2, // reply sent / waited for
2128 ParseReq = 3,
2129 ParseReply = 4,
2130 EndReq = 5,
2131 EndReply = 6
2132 };
2133 enum Flag {
2134 ApiFail = 1,
2135 Background = 2,
2136 TakeOver = 4,
2137 Commit = 8
2138 };
2139 };
2140
2141 // SchemaTrans
2142
2143 struct SchemaTrans {
2144 // ArrayPool
2145 Uint32 nextPool;
2146
2147 enum TransState
2148 {
2149 TS_INITIAL = 0,
2150 TS_STARTING = 1, // Starting at participants
2151 TS_STARTED = 2, // Started (potentially with parsed ops)
2152 TS_PARSING = 3, // Parsing at participants
2153 TS_SUBOP = 4, // Creating subop
2154 TS_ROLLBACK_SP = 5, // Rolling back to SP (supported before prepare)
2155 TS_FLUSH_PREPARE = 6,
2156 TS_PREPARING = 7, // Preparing operations
2157 TS_ABORTING_PREPARE = 8, // Aborting prepared operations
2158 TS_ABORTING_PARSE = 9, // Aborting parsed operations
2159 TS_FLUSH_COMMIT = 10,
2160 TS_COMMITTING = 11,// Committing
2161 TS_FLUSH_COMPLETE = 12,// Committed
2162 TS_COMPLETING = 13,// Completing
2163 TS_ENDING = 14
2164 };
2165
2166 Uint32 m_state;
weightDbdict::SchemaTrans2167 static Uint32 weight(Uint32 state) {
2168 /*
2169 Return the "weight" of a transaction state, used to determine
2170 the absolute order of beleived transaction states at master
2171 takeover.
2172 */
2173 switch ((TransState) state) {
2174 case TS_INITIAL:
2175 return 0;
2176 case TS_STARTING:
2177 return 1;
2178 case TS_STARTED:
2179 return 2;
2180 case TS_PARSING:
2181 return 3;
2182 case TS_SUBOP:
2183 return 6;
2184 case TS_ROLLBACK_SP:
2185 return 5;
2186 case TS_FLUSH_PREPARE:
2187 return 7;
2188 case TS_PREPARING:
2189 return 8;
2190 case TS_ABORTING_PREPARE:
2191 return 9;
2192 case TS_ABORTING_PARSE:
2193 return 4;
2194 case TS_FLUSH_COMMIT:
2195 return 10;
2196 case TS_COMMITTING:
2197 return 11;
2198 case TS_FLUSH_COMPLETE:
2199 return 12;
2200 case TS_COMPLETING:
2201 return 13;
2202 case TS_ENDING:
2203 return 14;
2204 }
2205 assert(false);
2206 return -1;
2207 }
2208 // DLMHashTable
2209 Uint32 trans_key;
2210 Uint32 nextHash;
2211 Uint32 prevHash;
hashValueDbdict::SchemaTrans2212 Uint32 hashValue() const {
2213 return trans_key;
2214 }
equalDbdict::SchemaTrans2215 bool equal(const SchemaTrans& rec) const {
2216 return trans_key == rec.trans_key;
2217 }
2218
2219 // DLFifoList where new ones are added at end
2220 Uint32 nextList;
2221 Uint32 prevList;
2222
2223 bool m_isMaster;
2224 BlockReference m_masterRef;
2225
2226 // requestFlags from begin/end trans
2227 Uint32 m_requestInfo;
2228
2229 BlockReference m_clientRef;
2230 Uint32 m_obj_id;
2231 Uint32 m_transId;
2232 TransClient::State m_clientState;
2233 Uint32 m_clientFlags;
2234 Uint32 m_takeOverTxKey;
2235
2236 NdbNodeBitmask m_nodes; // Nodes part of transaction
2237 NdbNodeBitmask m_ref_nodes; // Nodes replying REF to req
2238 SafeCounterHandle m_counter; // Outstanding REQ's
2239
2240 ArenaHead m_arena;
2241 Uint32 m_curr_op_ptr_i;
2242 SchemaOp_head m_op_list;
2243
2244 // Master takeover
2245 enum TakeoverRecoveryState
2246 {
2247 TRS_INITIAL = 0,
2248 TRS_ROLLFORWARD = 1,
2249 TRS_ROLLBACK = 2
2250 };
2251 Uint32 m_master_recovery_state;
2252 // These are common states all nodes must achieve
2253 // to be able to be involved in total rollforward/rollbackward
2254 Uint32 m_rollforward_op;
2255 Uint32 m_rollforward_op_state;
2256 Uint32 m_rollback_op;
2257 Uint32 m_rollback_op_state;
2258 Uint32 m_lowest_trans_state;
2259 Uint32 m_highest_trans_state;
2260 // Flag for signalling partial rollforward check during master takeover
2261 bool check_partial_rollforward;
2262 // Flag for signalling that already completed operation is recreated
2263 bool ressurected_op;
2264
2265 // request for lock/unlock
2266 DictLockReq m_lockReq;
2267
2268 // callback (not yet used)
2269 Callback m_callback;
2270
2271 // error is reset after each req/reply
2272 ErrorInfo m_error;
2273
2274 /**
2275 * Mutex handling
2276 */
2277 MutexHandle2<DIH_START_LCP_MUTEX> m_commit_mutex;
2278
2279 bool m_flush_prepare;
2280 bool m_flush_commit;
2281 bool m_flush_complete;
2282 bool m_flush_end;
2283 bool m_wait_gcp_on_commit;
2284 bool m_abort_on_node_fail;
2285
2286 // magic is on when record is seized
2287 enum { DICT_MAGIC = ~RT_DBDICT_SCHEMA_TRANSACTION };
2288 Uint32 m_magic;
2289
SchemaTransDbdict::SchemaTrans2290 SchemaTrans() {
2291 m_state = TS_INITIAL;
2292 m_isMaster = false;
2293 m_masterRef = 0;
2294 m_requestInfo = 0;
2295 m_clientRef = 0;
2296 m_transId = 0;
2297 m_clientState = TransClient::StateUndef;
2298 m_clientFlags = 0;
2299 m_takeOverTxKey = 0;
2300 bzero(&m_lockReq, sizeof(m_lockReq));
2301 m_callback.m_callbackFunction = 0;
2302 m_callback.m_callbackData = 0;
2303 m_magic = DICT_MAGIC;
2304 m_obj_id = RNIL;
2305 m_flush_prepare = false;
2306 m_flush_commit = false;
2307 m_flush_complete = false;
2308 m_flush_end = false;
2309 m_wait_gcp_on_commit = true;
2310 m_abort_on_node_fail = false;
2311 }
2312
SchemaTransDbdict::SchemaTrans2313 SchemaTrans(Uint32 the_trans_key) {
2314 trans_key = the_trans_key;
2315 }
2316
2317 #ifdef VM_TRACE
2318 void print(NdbOut&) const;
2319 #endif
2320 };
2321
2322 Uint32 check_read_obj(Uint32 objId, Uint32 transId = 0);
2323 Uint32 check_read_obj(SchemaFile::TableEntry*, Uint32 transId = 0);
2324 Uint32 check_write_obj(Uint32 objId, Uint32 transId = 0,
2325 SchemaFile::EntryState = SchemaFile::SF_UNUSED);
2326 Uint32 check_write_obj(Uint32, Uint32, SchemaFile::EntryState, ErrorInfo&);
2327
2328 typedef RecordPool<SchemaTrans,ArenaPool> SchemaTrans_pool;
2329 typedef DLMHashTable<SchemaTrans_pool, SchemaTrans> SchemaTrans_hash;
2330 typedef DLFifoListImpl<SchemaTrans_pool, SchemaTrans, SchemaTrans> SchemaTrans_list;
2331
2332 SchemaTrans_pool c_schemaTransPool;
2333 SchemaTrans_hash c_schemaTransHash;
2334 SchemaTrans_list c_schemaTransList;
2335 Uint32 c_schemaTransCount;
2336
2337 bool seizeSchemaTrans(SchemaTransPtr&, Uint32 trans_key);
2338 bool seizeSchemaTrans(SchemaTransPtr&);
2339 bool findSchemaTrans(SchemaTransPtr&, Uint32 trans_key);
2340 void releaseSchemaTrans(SchemaTransPtr&);
2341
2342 // coordinator
2343 void createSubOps(Signal*, SchemaOpPtr, bool first = false);
2344 void abortSubOps(Signal*, SchemaOpPtr, ErrorInfo);
2345
2346 void trans_recv_reply(Signal*, SchemaTransPtr);
2347 void trans_start_recv_reply(Signal*, SchemaTransPtr);
2348 void trans_parse_recv_reply(Signal*, SchemaTransPtr);
2349
2350 void trans_prepare_start(Signal*, SchemaTransPtr);
2351 void trans_prepare_first(Signal*, SchemaTransPtr);
2352 void trans_prepare_recv_reply(Signal*, SchemaTransPtr);
2353 void trans_prepare_next(Signal*, SchemaTransPtr, SchemaOpPtr);
2354 void trans_prepare_done(Signal*, SchemaTransPtr);
2355
2356 void trans_abort_prepare_start(Signal*, SchemaTransPtr);
2357 void trans_abort_prepare_recv_reply(Signal*, SchemaTransPtr);
2358 void trans_abort_prepare_next(Signal*, SchemaTransPtr, SchemaOpPtr);
2359 void trans_abort_prepare_done(Signal*, SchemaTransPtr);
2360
2361 void trans_abort_parse_start(Signal*, SchemaTransPtr);
2362 void trans_abort_parse_recv_reply(Signal*, SchemaTransPtr);
2363 void trans_abort_parse_next(Signal*, SchemaTransPtr, SchemaOpPtr);
2364 void trans_abort_parse_done(Signal*, SchemaTransPtr);
2365
2366 void trans_rollback_sp_start(Signal* signal, SchemaTransPtr);
2367 void trans_rollback_sp_recv_reply(Signal* signal, SchemaTransPtr);
2368 void trans_rollback_sp_next(Signal* signal, SchemaTransPtr, SchemaOpPtr);
2369 void trans_rollback_sp_done(Signal* signal, SchemaTransPtr, SchemaOpPtr);
2370
2371 void trans_commit_start(Signal*, SchemaTransPtr);
2372 void trans_commit_wait_gci(Signal*);
2373 void trans_commit_mutex_locked(Signal*, Uint32, Uint32);
2374 void trans_commit_first(Signal*, SchemaTransPtr);
2375 void trans_commit_recv_reply(Signal*, SchemaTransPtr);
2376 void trans_commit_next(Signal*, SchemaTransPtr, SchemaOpPtr);
2377 void trans_commit_done(Signal* signal, SchemaTransPtr);
2378 void trans_commit_mutex_unlocked(Signal*, Uint32, Uint32);
2379
2380 void trans_complete_start(Signal* signal, SchemaTransPtr);
2381 void trans_complete_first(Signal* signal, SchemaTransPtr);
2382 void trans_complete_next(Signal*, SchemaTransPtr, SchemaOpPtr);
2383 void trans_complete_recv_reply(Signal*, SchemaTransPtr);
2384 void trans_complete_done(Signal*, SchemaTransPtr);
2385
2386 void trans_end_start(Signal* signal, SchemaTransPtr);
2387 void trans_end_recv_reply(Signal*, SchemaTransPtr);
2388
2389 void trans_log(SchemaTransPtr);
2390 Uint32 trans_log_schema_op(SchemaOpPtr,
2391 Uint32 objectId,
2392 const SchemaFile::TableEntry*);
2393
2394 void trans_log_schema_op_abort(SchemaOpPtr);
2395 void trans_log_schema_op_complete(SchemaOpPtr);
2396
2397 void handle_master_takeover(Signal*);
2398 void check_takeover_replies(Signal*);
2399 void trans_recover(Signal*, SchemaTransPtr);
2400 void check_partial_trans_abort_prepare_next(SchemaTransPtr,
2401 NdbNodeBitmask &,
2402 SchemaOpPtr);
2403 void check_partial_trans_abort_parse_next(SchemaTransPtr,
2404 NdbNodeBitmask &,
2405 SchemaOpPtr);
2406 void check_partial_trans_complete_start(SchemaTransPtr, NdbNodeBitmask &);
2407 void check_partial_trans_commit_start(SchemaTransPtr, NdbNodeBitmask &);
2408 void check_partial_trans_commit_next(SchemaTransPtr,
2409 NdbNodeBitmask &,
2410 SchemaOpPtr);
2411
2412 // participant
2413 void recvTransReq(Signal*);
2414 void recvTransParseReq(Signal*, SchemaTransPtr,
2415 Uint32 op_key, const OpInfo& info,
2416 Uint32 requestInfo);
2417 void runTransSlave(Signal*, SchemaTransPtr);
2418 void update_op_state(SchemaOpPtr);
2419 void sendTransConf(Signal*, SchemaOpPtr);
2420 void sendTransConf(Signal*, SchemaTransPtr);
2421 void sendTransConfRelease(Signal*, SchemaTransPtr);
2422 void sendTransRef(Signal*, SchemaOpPtr);
2423 void sendTransRef(Signal*, SchemaTransPtr);
2424
2425 void slave_run_start(Signal*, const SchemaTransImplReq*);
2426 void slave_run_parse(Signal*, SchemaTransPtr, const SchemaTransImplReq*);
2427 void slave_run_flush(Signal*, SchemaTransPtr, const SchemaTransImplReq*);
2428 void slave_writeSchema_conf(Signal*, Uint32, Uint32);
2429 void slave_commit_mutex_locked(Signal*, Uint32, Uint32);
2430 void slave_commit_mutex_unlocked(Signal*, Uint32, Uint32);
2431
2432 // reply to trans client for begin/end trans
2433 void sendTransClientReply(Signal*, SchemaTransPtr);
2434
2435 // on DB slave node failure exclude the node from transactions
2436 void handleTransSlaveFail(Signal*, Uint32 failedNode);
2437
2438 // common code for different op types
2439
2440 /*
2441 * Client REQ starts with find trans and add op record.
2442 * Sets request info in op and default request type in impl_req.
2443 */
2444 template <class T, class Req, class ImplReq>
2445 inline void
startClientReq(SchemaOpPtr & op_ptr,Ptr<T> & t_ptr,const Req * req,ImplReq * & impl_req,ErrorInfo & error)2446 startClientReq(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr,
2447 const Req* req, ImplReq*& impl_req, ErrorInfo& error)
2448 {
2449 SchemaTransPtr trans_ptr;
2450
2451 const Uint32 requestInfo = req->requestInfo;
2452 const Uint32 requestType = DictSignal::getRequestType(requestInfo);
2453 const Uint32 requestExtra = DictSignal::getRequestExtra(requestInfo);
2454 const bool localTrans = (requestInfo & DictSignal::RF_LOCAL_TRANS);
2455
2456 if (getOwnNodeId() != c_masterNodeId && !localTrans) {
2457 jam();
2458 setError(error, SchemaTransImplRef::NotMaster, __LINE__);
2459 return;
2460 }
2461
2462 if (!findSchemaTrans(trans_ptr, req->transKey)) {
2463 jam();
2464 setError(error, SchemaTransImplRef::InvalidTransKey, __LINE__);
2465 return;
2466 }
2467
2468 if (trans_ptr.p->m_transId != req->transId) {
2469 jam();
2470 setError(error, SchemaTransImplRef::InvalidTransId, __LINE__);
2471 return;
2472 }
2473
2474 if (!localTrans)
2475 {
2476 ndbassert(getOwnNodeId() == c_masterNodeId);
2477 NodeRecordPtr masterNodePtr;
2478 c_nodes.getPtr(masterNodePtr, c_masterNodeId);
2479
2480 if (masterNodePtr.p->nodeState == NodeRecord::NDB_MASTER_TAKEOVER)
2481 {
2482 jam();
2483 /**
2484 * There is a dict takeover in progress, and the transaction may thus
2485 * be in an inconsistent state where its fate has not been decided yet.
2486 * If transaction is in error we return that error,
2487 * else we return 'Busy' which will cause a later retry.
2488 */
2489 if (hasError(trans_ptr.p->m_error))
2490 {
2491 jam();
2492 setError(error, trans_ptr.p->m_error);
2493 }
2494 else
2495 {
2496 jam();
2497 setError(error, SchemaTransImplRef::Busy, __LINE__);
2498 }
2499 return;
2500 }
2501 }
2502
2503 // Assert that we are not in an inconsistent/incomplete state
2504 ndbassert(!hasError(trans_ptr.p->m_error));
2505 ndbassert(!c_takeOverInProgress);
2506 ndbassert(trans_ptr.p->m_counter.done());
2507
2508 if (!seizeSchemaOp(trans_ptr, op_ptr, t_ptr)) {
2509 jam();
2510 setError(error, SchemaTransImplRef::TooManySchemaOps, __LINE__);
2511 return;
2512 }
2513
2514 trans_ptr.p->m_clientState = TransClient::ParseReq;
2515
2516 DictSignal::setRequestExtra(op_ptr.p->m_requestInfo, requestExtra);
2517 DictSignal::addRequestFlags(op_ptr.p->m_requestInfo, requestInfo);
2518
2519 // impl_req was passed via reference
2520 impl_req = &t_ptr.p->m_request;
2521
2522 impl_req->senderRef = reference();
2523 impl_req->senderData = op_ptr.p->op_key;
2524 impl_req->requestType = requestType;
2525
2526 // client of this REQ (trans client or us, recursively)
2527 op_ptr.p->m_clientRef = req->clientRef;
2528 op_ptr.p->m_clientData = req->clientData;
2529 }
2530
2531 /*
2532 * The other half of client REQ processing. On error starts
2533 * rollback of current client op and its sub-ops.
2534 */
2535 void handleClientReq(Signal*, SchemaOpPtr, SectionHandle&);
2536
2537 // DICT receives recursive or internal CONF or REF
2538
2539 template <class Conf>
2540 inline void
handleDictConf(Signal * signal,const Conf * conf)2541 handleDictConf(Signal* signal, const Conf* conf) {
2542 D("handleDictConf" << V(conf->senderData));
2543 ndbrequire(signal->getNoOfSections() == 0);
2544
2545 Callback callback;
2546 bool ok = findCallback(callback, conf->senderData);
2547 ndbrequire(ok);
2548 execute(signal, callback, 0);
2549 }
2550
2551 template <class Ref>
2552 inline void
handleDictRef(Signal * signal,const Ref * ref)2553 handleDictRef(Signal* signal, const Ref* ref) {
2554 D("handleDictRef" << V(ref->senderData) << V(ref->errorCode));
2555 ndbrequire(signal->getNoOfSections() == 0);
2556
2557 Callback callback;
2558 bool ok = findCallback(callback, ref->senderData);
2559 ndbrequire(ok);
2560 ndbrequire(ref->errorCode != 0);
2561 execute(signal, callback, ref->errorCode);
2562 }
2563
2564 /*
2565 * TxHandle
2566 *
2567 * DICT as schema trans client. TxHandle is the client-side record.
2568 * It has same role as NdbDictInterface::Tx in NDB API. It is used
2569 * for following:
2570 *
2571 * - create or drop table at NR/SR [not yet]
2572 * - build or activate indexes at NR/SR
2573 * - take over client trans if client requests this
2574 * - take over client trans when client API has failed
2575 */
2576
2577 struct TxHandle {
2578 // ArrayPool
2579 Uint32 nextPool;
2580
2581 // DLMHashTable
2582 Uint32 tx_key;
2583 Uint32 nextHash;
2584 Uint32 prevHash;
hashValueDbdict::TxHandle2585 Uint32 hashValue() const {
2586 return tx_key;
2587 }
equalDbdict::TxHandle2588 bool equal(const TxHandle& rec) const {
2589 return tx_key == rec.tx_key;
2590 }
2591
2592 Uint32 m_requestInfo; // global flags are passed to schema trans
2593 Uint32 m_transId;
2594 Uint32 m_transKey;
2595 Uint32 m_userData;
2596
2597 // when take over for background or for failed API
2598 TransClient::State m_clientState;
2599 Uint32 m_clientFlags;
2600 BlockReference m_takeOverRef;
2601 Uint32 m_takeOverTransId;
2602
2603 Callback m_callback;
2604 ErrorInfo m_error;
2605
2606 // magic is on when record is seized
2607 enum { DICT_MAGIC = 0xd1c70003 };
2608 Uint32 m_magic;
2609
TxHandleDbdict::TxHandle2610 TxHandle() {
2611 m_requestInfo = 0;
2612 m_transId = 0;
2613 m_transKey = 0;
2614 m_userData = 0;
2615 m_clientState = TransClient::StateUndef;
2616 m_clientFlags = 0;
2617 m_takeOverRef = 0;
2618 m_takeOverTransId = 0;
2619 m_callback.m_callbackFunction = 0;
2620 m_callback.m_callbackData = 0;
2621 m_magic = 0;
2622 }
2623
TxHandleDbdict::TxHandle2624 TxHandle(Uint32 the_tx_key) {
2625 tx_key = the_tx_key;
2626 }
2627 #ifdef VM_TRACE
2628 void print(NdbOut&) const;
2629 #endif
2630 };
2631
2632 typedef ArrayPool<TxHandle> TxHandle_pool;
2633 typedef DLMHashTable<TxHandle_pool, TxHandle> TxHandle_hash;
2634
2635 TxHandle_pool c_txHandlePool;
2636 TxHandle_hash c_txHandleHash;
2637
2638 bool seizeTxHandle(TxHandlePtr&);
2639 bool findTxHandle(TxHandlePtr&, Uint32 tx_key);
2640 void releaseTxHandle(TxHandlePtr&);
2641
2642 void beginSchemaTrans(Signal*, TxHandlePtr);
2643 void endSchemaTrans(Signal*, TxHandlePtr, Uint32 flags = 0);
2644
2645 void handleApiFail(Signal*, Uint32 failedApiNode);
2646 void takeOverTransClient(Signal*, SchemaTransPtr);
2647 void runTransClientTakeOver(Signal*, Uint32 tx_key, Uint32 ret);
2648 void finishApiFail(Signal*, TxHandlePtr tx_ptr);
2649 void apiFailBlockHandling(Signal*, Uint32 failedApiNode);
2650
2651 /*
2652 * Callback key is for different record types in some cases.
2653 * For example a CONF can be for SchemaOp or for TxHandle.
2654 * This looks for match for one of op_key/trans_key/tx_key.
2655 */
2656 bool findCallback(Callback& callback, Uint32 any_key);
2657
2658 // MODULE: CreateTable
2659
2660 struct CreateTableRec;
2661 typedef RecordPool<CreateTableRec,ArenaPool> CreateTableRec_pool;
2662
2663 struct CreateTableRec : public OpRec {
2664 static const OpInfo g_opInfo;
2665
2666 static CreateTableRec_pool&
getPoolDbdict::CreateTableRec2667 getPool(Dbdict* dict) {
2668 return dict->c_createTableRecPool;
2669 }
2670
2671 CreateTabReq m_request;
2672
2673 // wl3600_todo check mutex name and number later
2674 MutexHandle2<DIH_START_LCP_MUTEX> m_startLcpMutex;
2675
2676 // long signal memory for temp use
2677 Uint32 m_tabInfoPtrI;
2678 Uint32 m_fragmentsPtrI;
2679
2680 // connect pointers towards DIH and LQH
2681 Uint32 m_dihAddFragPtr;
2682 Uint32 m_lqhFragPtr;
2683
2684 // who is using local create tab
2685 Callback m_callback;
2686
2687 // flag if this op has been aborted in RT_PREPARE phase
2688 bool m_abortPrepareDone;
2689
CreateTableRecDbdict::CreateTableRec2690 CreateTableRec() :
2691 OpRec(g_opInfo, (Uint32*)&m_request) {
2692 memset(&m_request, 0, sizeof(m_request));
2693 m_tabInfoPtrI = RNIL;
2694 m_fragmentsPtrI = RNIL;
2695 m_dihAddFragPtr = RNIL;
2696 m_lqhFragPtr = RNIL;
2697 m_abortPrepareDone = false;
2698 }
2699
2700 #ifdef VM_TRACE
2701 void print(NdbOut&) const;
2702 #endif
2703 };
2704
2705 typedef Ptr<CreateTableRec> CreateTableRecPtr;
2706 CreateTableRec_pool c_createTableRecPool;
2707
2708 // OpInfo
2709 bool createTable_seize(SchemaOpPtr);
2710 void createTable_release(SchemaOpPtr);
2711 //
2712 void createTable_parse(Signal*, bool master,
2713 SchemaOpPtr, SectionHandle&, ErrorInfo&);
2714 bool createTable_subOps(Signal*, SchemaOpPtr);
2715 void createTable_reply(Signal*, SchemaOpPtr, ErrorInfo);
2716 //
2717 void createTable_prepare(Signal*, SchemaOpPtr);
2718 void createTable_commit(Signal*, SchemaOpPtr);
2719 void createTable_complete(Signal*, SchemaOpPtr);
2720 //
2721 void createTable_abortParse(Signal*, SchemaOpPtr);
2722 void createTable_abortPrepare(Signal*, SchemaOpPtr);
2723
2724 // prepare
2725 void createTab_writeTableConf(Signal*, Uint32 op_key, Uint32 ret);
2726 void createTab_local(Signal*, SchemaOpPtr, OpSection fragSec, Callback*);
2727 void createTab_dih(Signal*, SchemaOpPtr);
2728 void createTab_localComplete(Signal*, Uint32 op_key, Uint32 ret);
2729
2730 // commit
2731 void createTab_activate(Signal*, SchemaOpPtr, Callback*);
2732 void createTab_alterComplete(Signal*, Uint32 op_key, Uint32 ret);
2733
2734 // abort prepare
2735 void createTable_abortLocalConf(Signal*, Uint32 aux_op_key, Uint32 ret);
2736
2737 // MODULE: DropTable
2738
2739 struct DropTableRec;
2740 typedef RecordPool<DropTableRec,ArenaPool> DropTableRec_pool;
2741
2742 struct DropTableRec : public OpRec {
2743 static const OpInfo g_opInfo;
2744
2745 static DropTableRec_pool&
getPoolDbdict::DropTableRec2746 getPool(Dbdict* dict) {
2747 return dict->c_dropTableRecPool;
2748 }
2749
2750 DropTabReq m_request;
2751
2752 // wl3600_todo check mutex name and number later
2753 MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
2754
2755 Uint32 m_block;
2756 enum { BlockCount = 6 };
2757 Uint32 m_blockNo[BlockCount];
2758 Callback m_callback;
2759
DropTableRecDbdict::DropTableRec2760 DropTableRec() :
2761 OpRec(g_opInfo, (Uint32*)&m_request) {
2762 memset(&m_request, 0, sizeof(m_request));
2763 m_block = 0;
2764 }
2765
2766 #ifdef VM_TRACE
2767 void print(NdbOut&) const;
2768 #endif
2769 };
2770
2771 typedef Ptr<DropTableRec> DropTableRecPtr;
2772 DropTableRec_pool c_dropTableRecPool;
2773
2774 // OpInfo
2775 bool dropTable_seize(SchemaOpPtr);
2776 void dropTable_release(SchemaOpPtr);
2777 //
2778 void dropTable_parse(Signal*, bool master,
2779 SchemaOpPtr, SectionHandle&, ErrorInfo&);
2780 bool dropTable_subOps(Signal*, SchemaOpPtr);
2781 void dropTable_reply(Signal*, SchemaOpPtr, ErrorInfo);
2782 //
2783 void dropTable_prepare(Signal*, SchemaOpPtr);
2784 void dropTable_commit(Signal*, SchemaOpPtr);
2785 void dropTable_complete(Signal*, SchemaOpPtr);
2786 //
2787 void dropTable_abortParse(Signal*, SchemaOpPtr);
2788 void dropTable_abortPrepare(Signal*, SchemaOpPtr);
2789
2790 // prepare
2791 void dropTable_backup_mutex_locked(Signal*, Uint32 op_key, Uint32 ret);
2792
2793 // commit
2794 void dropTable_commit_nextStep(Signal*, SchemaOpPtr);
2795 void dropTable_commit_fromLocal(Signal*, Uint32 op_key, Uint32 errorCode);
2796 void dropTable_commit_done(Signal*, SchemaOpPtr);
2797
2798 // complete
2799 void dropTable_complete_nextStep(Signal*, SchemaOpPtr);
2800 void dropTable_complete_fromLocal(Signal*, Uint32 op_key);
2801 void dropTable_complete_done(Signal*, Uint32 op_key, Uint32 ret);
2802
2803 // MODULE: AlterTable
2804
2805 struct AlterTableRec;
2806 typedef RecordPool<AlterTableRec,ArenaPool> AlterTableRec_pool;
2807
2808 struct AlterTableRec : public OpRec {
2809 static const OpInfo g_opInfo;
2810
2811 static AlterTableRec_pool&
getPoolDbdict::AlterTableRec2812 getPool(Dbdict* dict) {
2813 return dict->c_alterTableRecPool;
2814 }
2815
2816 AlterTabReq m_request;
2817
2818 // added attributes
2819 OpSection m_newAttrData;
2820
2821 // wl3600_todo check mutex name and number later
2822 MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
2823
2824 // current and new temporary work table
2825 TableRecordPtr::I m_newTablePtrI;
2826 Uint32 m_newTable_realObjectId;
2827
2828 // before image
2829 RopeHandle m_oldTableName;
2830 RopeHandle m_oldFrmData;
2831
2832 // connect ptr towards TUP, DIH, LQH
2833 Uint32 m_dihAddFragPtr;
2834 Uint32 m_lqhFragPtr;
2835
2836 // local blocks to process
2837 enum { BlockCount = 4 };
2838 Uint32 m_blockNo[BlockCount];
2839 Uint32 m_blockIndex;
2840
2841 // used for creating subops for add partitions, wrt ordered index
2842 bool m_sub_reorg_commit;
2843 bool m_sub_reorg_complete;
2844 bool m_sub_add_frag;
2845 Uint32 m_sub_add_frag_index_ptr;
2846 bool m_sub_trigger;
2847 bool m_sub_copy_data;
2848 bool m_sub_suma_enable;
2849 bool m_sub_suma_filter;
2850
AlterTableRecDbdict::AlterTableRec2851 AlterTableRec() :
2852 OpRec(g_opInfo, (Uint32*)&m_request) {
2853 memset(&m_request, 0, sizeof(m_request));
2854 m_newTablePtrI = RNIL;
2855 m_dihAddFragPtr = RNIL;
2856 m_lqhFragPtr = RNIL;
2857 m_blockNo[0] = DBLQH;
2858 m_blockNo[1] = DBDIH;
2859 m_blockNo[2] = DBSPJ;
2860 m_blockNo[3] = DBTC;
2861 m_blockIndex = 0;
2862 m_sub_add_frag_index_ptr = RNIL;
2863 m_sub_add_frag = false;
2864 m_sub_reorg_commit = false;
2865 m_sub_reorg_complete = false;
2866 m_sub_trigger = false;
2867 m_sub_copy_data = false;
2868 m_sub_suma_enable = false;
2869 m_sub_suma_filter = false;
2870 }
2871 #ifdef VM_TRACE
2872 void print(NdbOut&) const;
2873 #endif
2874 };
2875
2876 typedef Ptr<AlterTableRec> AlterTableRecPtr;
2877 AlterTableRec_pool c_alterTableRecPool;
2878
2879 // OpInfo
2880 bool alterTable_seize(SchemaOpPtr);
2881 void alterTable_release(SchemaOpPtr);
2882 //
2883 void alterTable_parse(Signal*, bool master,
2884 SchemaOpPtr, SectionHandle&, ErrorInfo&);
2885 bool alterTable_subOps(Signal*, SchemaOpPtr);
2886 void alterTable_reply(Signal*, SchemaOpPtr, ErrorInfo);
2887 //
2888 void alterTable_prepare(Signal*, SchemaOpPtr);
2889 void alterTable_commit(Signal*, SchemaOpPtr);
2890 void alterTable_complete(Signal*, SchemaOpPtr);
2891 //
2892 void alterTable_abortParse(Signal*, SchemaOpPtr);
2893 void alterTable_abortPrepare(Signal*, SchemaOpPtr);
2894
2895 void alterTable_toCopyData(Signal* signal, SchemaOpPtr op_ptr);
2896 void alterTable_fromCopyData(Signal*, Uint32 op_key, Uint32 ret);
2897
2898 // prepare phase
2899 void alterTable_backup_mutex_locked(Signal*, Uint32 op_key, Uint32 ret);
2900 void alterTable_toLocal(Signal*, SchemaOpPtr);
2901 void alterTable_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
2902
2903 void alterTable_toAlterIndex(Signal*, SchemaOpPtr);
2904 void alterTable_fromAlterIndex(Signal*, Uint32 op_key, Uint32 ret);
2905
2906 void alterTable_toReorgTable(Signal*, SchemaOpPtr, Uint32 step);
2907 void alterTable_fromReorgTable(Signal*, Uint32 op_key, Uint32 ret);
2908
2909 void alterTable_toCreateTrigger(Signal* signal, SchemaOpPtr op_ptr);
2910 void alterTable_fromCreateTrigger(Signal*, Uint32 op_key, Uint32 ret);
2911
2912 void alterTable_toSumaSync(Signal* signal, SchemaOpPtr op_ptr, Uint32);
2913
2914 // commit phase
2915 void alterTable_toCommitComplete(Signal*, SchemaOpPtr, Uint32 = ~Uint32(0));
2916 void alterTable_fromCommitComplete(Signal*, Uint32 op_key, Uint32 ret);
2917 void alterTab_writeTableConf(Signal*, Uint32 op_key, Uint32 ret);
2918
2919 // abort
2920 void alterTable_abortToLocal(Signal*, SchemaOpPtr);
2921 void alterTable_abortFromLocal(Signal*, Uint32 op_key, Uint32 ret);
2922
2923 Uint32 check_supported_add_fragment(Uint16*, const Uint16*);
2924 Uint32 check_supported_reorg(Uint32, Uint32);
2925
2926 // MODULE: CreateIndex
2927
2928 typedef struct {
2929 Uint32 old_index;
2930 Uint32 attr_id;
2931 Uint32 attr_ptr_i;
2932 } AttributeMap[MAX_ATTRIBUTES_IN_INDEX];
2933
2934 struct CreateIndexRec;
2935 typedef RecordPool<CreateIndexRec,ArenaPool> CreateIndexRec_pool;
2936
2937 struct CreateIndexRec : public OpRec {
2938 CreateIndxImplReq m_request;
2939 char m_indexName[MAX_TAB_NAME_SIZE];
2940 IndexAttributeList m_attrList;
2941 AttributeMask m_attrMask;
2942 AttributeMap m_attrMap;
2943 Uint32 m_bits;
2944 Uint32 m_fragmentType;
2945 Uint32 m_indexKeyLength;
2946
2947 // reflection
2948 static const OpInfo g_opInfo;
2949
2950 static CreateIndexRec_pool&
getPoolDbdict::CreateIndexRec2951 getPool(Dbdict* dict) {
2952 return dict->c_createIndexRecPool;
2953 }
2954
2955 // sub-operation counters
2956 bool m_sub_create_table;
2957 bool m_sub_alter_index;
2958
CreateIndexRecDbdict::CreateIndexRec2959 CreateIndexRec() :
2960 OpRec(g_opInfo, (Uint32*)&m_request) {
2961 memset(&m_request, 0, sizeof(m_request));
2962 memset(m_indexName, 0, sizeof(m_indexName));
2963 memset(&m_attrList, 0, sizeof(m_attrList));
2964 m_attrMask.clear();
2965 memset(m_attrMap, 0, sizeof(m_attrMap));
2966 m_bits = 0;
2967 m_fragmentType = 0;
2968 m_indexKeyLength = 0;
2969 m_sub_create_table = false;
2970 m_sub_alter_index = false;
2971 }
2972 #ifdef VM_TRACE
2973 void print(NdbOut&) const;
2974 #endif
2975 };
2976
2977 typedef Ptr<CreateIndexRec> CreateIndexRecPtr;
2978 CreateIndexRec_pool c_createIndexRecPool;
2979
2980 // OpInfo
2981 bool createIndex_seize(SchemaOpPtr);
2982 void createIndex_release(SchemaOpPtr);
2983 //
2984 void createIndex_parse(Signal*, bool master,
2985 SchemaOpPtr, SectionHandle&, ErrorInfo&);
2986 bool createIndex_subOps(Signal*, SchemaOpPtr);
2987 void createIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
2988 //
2989 void createIndex_prepare(Signal*, SchemaOpPtr);
2990 void createIndex_commit(Signal*, SchemaOpPtr);
2991 void createIndex_complete(Signal*, SchemaOpPtr);
2992 //
2993 void createIndex_abortParse(Signal*, SchemaOpPtr);
2994 void createIndex_abortPrepare(Signal*, SchemaOpPtr);
2995
2996 // sub-ops
2997 void createIndex_toCreateTable(Signal*, SchemaOpPtr);
2998 void createIndex_fromCreateTable(Signal*, Uint32 op_key, Uint32 ret);
2999 void createIndex_toAlterIndex(Signal*, SchemaOpPtr);
3000 void createIndex_fromAlterIndex(Signal*, Uint32 op_key, Uint32 ret);
3001
3002 // MODULE: DropIndex
3003
3004 struct DropIndexRec;
3005 typedef RecordPool<DropIndexRec,ArenaPool> DropIndexRec_pool;
3006
3007 struct DropIndexRec : public OpRec {
3008 DropIndxImplReq m_request;
3009
3010 // reflection
3011 static const OpInfo g_opInfo;
3012
3013 static DropIndexRec_pool&
getPoolDbdict::DropIndexRec3014 getPool(Dbdict* dict) {
3015 return dict->c_dropIndexRecPool;
3016 }
3017
3018 // sub-operation counters
3019 bool m_sub_alter_index;
3020 bool m_sub_drop_table;
3021
DropIndexRecDbdict::DropIndexRec3022 DropIndexRec() :
3023 OpRec(g_opInfo, (Uint32*)&m_request) {
3024 memset(&m_request, 0, sizeof(m_request));
3025 m_sub_alter_index = false;
3026 m_sub_drop_table = false;
3027 }
3028 #ifdef VM_TRACE
3029 void print(NdbOut&) const;
3030 #endif
3031 };
3032
3033 typedef Ptr<DropIndexRec> DropIndexRecPtr;
3034 DropIndexRec_pool c_dropIndexRecPool;
3035
3036 // OpInfo
3037 bool dropIndex_seize(SchemaOpPtr);
3038 void dropIndex_release(SchemaOpPtr);
3039 //
3040 void dropIndex_parse(Signal*, bool master,
3041 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3042 bool dropIndex_subOps(Signal*, SchemaOpPtr);
3043 void dropIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
3044 //
3045 void dropIndex_prepare(Signal*, SchemaOpPtr);
3046 void dropIndex_commit(Signal*, SchemaOpPtr);
3047 void dropIndex_complete(Signal*, SchemaOpPtr);
3048 //
3049 void dropIndex_abortParse(Signal*, SchemaOpPtr);
3050 void dropIndex_abortPrepare(Signal*, SchemaOpPtr);
3051
3052 // sub-ops
3053 void dropIndex_toDropTable(Signal*, SchemaOpPtr);
3054 void dropIndex_fromDropTable(Signal*, Uint32 op_key, Uint32 ret);
3055 void dropIndex_toAlterIndex(Signal*, SchemaOpPtr);
3056 void dropIndex_fromAlterIndex(Signal*, Uint32 op_key, Uint32 ret);
3057
3058 // MODULE: AlterIndex
3059
3060 struct TriggerTmpl {
3061 const char* nameFormat; // contains one %u for index id
3062 TriggerInfo triggerInfo;
3063 };
3064
3065 static const TriggerTmpl g_hashIndexTriggerTmpl[1];
3066 static const TriggerTmpl g_orderedIndexTriggerTmpl[1];
3067 static const TriggerTmpl g_buildIndexConstraintTmpl[1];
3068 static const TriggerTmpl g_reorgTriggerTmpl[1];
3069 static const TriggerTmpl g_fkTriggerTmpl[2];
3070
3071 struct AlterIndexRec;
3072 typedef RecordPool<AlterIndexRec,ArenaPool> AlterIndexRec_pool;
3073
3074 struct AlterIndexRec : public OpRec {
3075 AlterIndxImplReq m_request;
3076 IndexAttributeList m_attrList;
3077 AttributeMask m_attrMask;
3078
3079 // reflection
3080 static const OpInfo g_opInfo;
3081
3082 static AlterIndexRec_pool&
getPoolDbdict::AlterIndexRec3083 getPool(Dbdict* dict) {
3084 return dict->c_alterIndexRecPool;
3085 }
3086
3087 // sub-operation counters (true = done or skip)
3088 const TriggerTmpl* m_triggerTmpl;
3089 bool m_sub_trigger;
3090 bool m_sub_build_index;
3091 bool m_sub_index_stat_dml;
3092 bool m_sub_index_stat_mon;
3093
3094 // prepare phase
3095 bool m_tc_index_done;
3096
3097 // connect pointers towards DIH and LQH
3098 Uint32 m_dihAddFragPtr;
3099 Uint32 m_lqhFragPtr;
3100
AlterIndexRecDbdict::AlterIndexRec3101 AlterIndexRec() :
3102 OpRec(g_opInfo, (Uint32*)&m_request) {
3103 memset(&m_request, 0, sizeof(m_request));
3104 memset(&m_attrList, 0, sizeof(m_attrList));
3105 m_attrMask.clear();
3106 m_triggerTmpl = 0;
3107 m_sub_trigger = false;
3108 m_sub_build_index = false;
3109 m_sub_index_stat_dml = false;
3110 m_sub_index_stat_mon = false;
3111 m_tc_index_done = false;
3112 }
3113
3114 #ifdef VM_TRACE
3115 void print(NdbOut&) const;
3116 #endif
3117 };
3118
3119 typedef Ptr<AlterIndexRec> AlterIndexRecPtr;
3120 AlterIndexRec_pool c_alterIndexRecPool;
3121
3122 // OpInfo
3123 bool alterIndex_seize(SchemaOpPtr);
3124 void alterIndex_release(SchemaOpPtr);
3125 //
3126 void alterIndex_parse(Signal*, bool master,
3127 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3128 bool alterIndex_subOps(Signal*, SchemaOpPtr);
3129 void alterIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
3130 //
3131 void alterIndex_prepare(Signal*, SchemaOpPtr);
3132 void alterIndex_commit(Signal*, SchemaOpPtr);
3133 void alterIndex_complete(Signal*, SchemaOpPtr);
3134 //
3135 void alterIndex_abortParse(Signal*, SchemaOpPtr);
3136 void alterIndex_abortPrepare(Signal*, SchemaOpPtr);
3137
3138 // parse phase sub-routine
3139 void set_index_stat_frag(Signal*, TableRecordPtr indexPtr);
3140
3141 // sub-ops
3142 void alterIndex_toCreateTrigger(Signal*, SchemaOpPtr);
3143 void alterIndex_atCreateTrigger(Signal*, SchemaOpPtr);
3144 void alterIndex_fromCreateTrigger(Signal*, Uint32 op_key, Uint32 ret);
3145 void alterIndex_toDropTrigger(Signal*, SchemaOpPtr);
3146 void alterIndex_atDropTrigger(Signal*, SchemaOpPtr);
3147 void alterIndex_fromDropTrigger(Signal*, Uint32 op_key, Uint32 ret);
3148 void alterIndex_toBuildIndex(Signal*, SchemaOpPtr);
3149 void alterIndex_fromBuildIndex(Signal*, Uint32 op_key, Uint32 ret);
3150 void alterIndex_toIndexStat(Signal*, SchemaOpPtr);
3151 void alterIndex_fromIndexStat(Signal*, Uint32 op_key, Uint32 ret);
3152
3153 // prepare phase
3154 void alterIndex_toCreateLocal(Signal*, SchemaOpPtr);
3155 void alterIndex_toDropLocal(Signal*, SchemaOpPtr);
3156 void alterIndex_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3157
3158 void alterIndex_toAddPartitions(Signal*, SchemaOpPtr);
3159 void alterIndex_fromAddPartitions(Signal*, Uint32 op_key, Uint32 ret);
3160
3161 // abort
3162 void alterIndex_abortFromLocal(Signal*, Uint32 op_key, Uint32 ret);
3163
3164 // MODULE: BuildIndex
3165
3166 // this prepends 1 column used for FRAGMENT in hash index table key
3167 typedef Id_array<1 + MAX_ATTRIBUTES_IN_INDEX> FragAttributeList;
3168
3169 struct BuildIndexRec;
3170 typedef RecordPool<BuildIndexRec,ArenaPool> BuildIndexRec_pool;
3171
3172 struct BuildIndexRec : public OpRec {
3173 static const OpInfo g_opInfo;
3174
3175 static BuildIndexRec_pool&
getPoolDbdict::BuildIndexRec3176 getPool(Dbdict* dict) {
3177 return dict->c_buildIndexRecPool;
3178 }
3179
3180 BuildIndxImplReq m_request;
3181
3182 IndexAttributeList m_indexKeyList;
3183 FragAttributeList m_tableKeyList;
3184 AttributeMask m_attrMask;
3185
3186 // sub-operation counters (CTr BIn DTr)
3187 const TriggerTmpl* m_triggerTmpl;
3188 Uint32 m_subOpCount; // 3 or 0
3189 Uint32 m_subOpIndex;
3190
3191 // do the actual build (i.e. not done in a sub-op BIn)
3192 bool m_doBuild;
3193
BuildIndexRecDbdict::BuildIndexRec3194 BuildIndexRec() :
3195 OpRec(g_opInfo, (Uint32*)&m_request) {
3196 memset(&m_request, 0, sizeof(m_request));
3197 memset(&m_indexKeyList, 0, sizeof(m_indexKeyList));
3198 memset(&m_tableKeyList, 0, sizeof(m_tableKeyList));
3199 m_attrMask.clear();
3200 m_triggerTmpl = 0;
3201 m_subOpCount = 0;
3202 m_subOpIndex = 0;
3203 m_doBuild = false;
3204 }
3205 };
3206
3207 typedef Ptr<BuildIndexRec> BuildIndexRecPtr;
3208 BuildIndexRec_pool c_buildIndexRecPool;
3209
3210 // OpInfo
3211 bool buildIndex_seize(SchemaOpPtr);
3212 void buildIndex_release(SchemaOpPtr);
3213 //
3214 void buildIndex_parse(Signal*, bool master,
3215 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3216 bool buildIndex_subOps(Signal*, SchemaOpPtr);
3217 void buildIndex_reply(Signal*, SchemaOpPtr, ErrorInfo);
3218 //
3219 void buildIndex_prepare(Signal*, SchemaOpPtr);
3220 void buildIndex_commit(Signal*, SchemaOpPtr);
3221 void buildIndex_complete(Signal*, SchemaOpPtr);
3222 //
3223 void buildIndex_abortParse(Signal*, SchemaOpPtr);
3224 void buildIndex_abortPrepare(Signal*, SchemaOpPtr);
3225
3226 // parse phase
3227 void buildIndex_toCreateConstraint(Signal*, SchemaOpPtr);
3228 void buildIndex_atCreateConstraint(Signal*, SchemaOpPtr);
3229 void buildIndex_fromCreateConstraint(Signal*, Uint32 op_key, Uint32 ret);
3230 //
3231 void buildIndex_toBuildIndex(Signal*, SchemaOpPtr);
3232 void buildIndex_fromBuildIndex(Signal*, Uint32 op_key, Uint32 ret);
3233 //
3234 void buildIndex_toDropConstraint(Signal*, SchemaOpPtr);
3235 void buildIndex_atDropConstraint(Signal*, SchemaOpPtr);
3236 void buildIndex_fromDropConstraint(Signal*, Uint32 op_key, Uint32 ret);
3237
3238 // prepare phase
3239 void buildIndex_toLocalBuild(Signal*, SchemaOpPtr);
3240 void buildIndex_fromLocalBuild(Signal*, Uint32 op_key, Uint32 ret);
3241
3242 // commit phase
3243 void buildIndex_toLocalOnline(Signal*, SchemaOpPtr);
3244 void buildIndex_fromLocalOnline(Signal*, Uint32 op_key, Uint32 ret);
3245
3246 // MODULE: IndexStat
3247
3248 struct IndexStatRec;
3249 typedef RecordPool<IndexStatRec,ArenaPool> IndexStatRec_pool;
3250
3251 struct IndexStatRec : public OpRec {
3252 static const OpInfo g_opInfo;
3253
3254 static IndexStatRec_pool&
getPoolDbdict::IndexStatRec3255 getPool(Dbdict* dict) {
3256 return dict->c_indexStatRecPool;
3257 }
3258
3259 IndexStatImplReq m_request;
3260
3261 // sub-operation counters
3262 const TriggerTmpl* m_triggerTmpl;
3263 Uint32 m_subOpCount;
3264 Uint32 m_subOpIndex;
3265
IndexStatRecDbdict::IndexStatRec3266 IndexStatRec() :
3267 OpRec(g_opInfo, (Uint32*)&m_request) {
3268 memset(&m_request, 0, sizeof(m_request));
3269 m_subOpCount = 0;
3270 m_subOpIndex = 0;
3271 }
3272 };
3273
3274 typedef Ptr<IndexStatRec> IndexStatRecPtr;
3275 IndexStatRec_pool c_indexStatRecPool;
3276
3277 Uint32 c_indexStatAutoCreate;
3278 Uint32 c_indexStatAutoUpdate;
3279 Uint32 c_indexStatBgId;
3280
3281 // OpInfo
3282 bool indexStat_seize(SchemaOpPtr);
3283 void indexStat_release(SchemaOpPtr);
3284 //
3285 void indexStat_parse(Signal*, bool master,
3286 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3287 bool indexStat_subOps(Signal*, SchemaOpPtr);
3288 void indexStat_reply(Signal*, SchemaOpPtr, ErrorInfo);
3289 //
3290 void indexStat_prepare(Signal*, SchemaOpPtr);
3291 void indexStat_commit(Signal*, SchemaOpPtr);
3292 void indexStat_complete(Signal*, SchemaOpPtr);
3293 //
3294 void indexStat_abortParse(Signal*, SchemaOpPtr);
3295 void indexStat_abortPrepare(Signal*, SchemaOpPtr);
3296
3297 // parse phase
3298 void indexStat_toIndexStat(Signal*, SchemaOpPtr, Uint32 requestType);
3299 void indexStat_fromIndexStat(Signal*, Uint32 op_key, Uint32 ret);
3300
3301 // prepare phase
3302 void indexStat_toLocalStat(Signal*, SchemaOpPtr);
3303 void indexStat_fromLocalStat(Signal*, Uint32 op_key, Uint32 ret);
3304
3305 // background processing of stat requests
3306 void indexStatBg_process(Signal*);
3307 void indexStatBg_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
3308 void indexStatBg_fromIndexStat(Signal*, Uint32 tx_key, Uint32 ret);
3309 void indexStatBg_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
3310 void indexStatBg_sendContinueB(Signal*);
3311
3312 // MODULE: CreateHashMap
3313
3314 struct HashMapRecord {
HashMapRecordDbdict::HashMapRecord3315 HashMapRecord(){}
isCompatibleDbdict::HashMapRecord3316 static bool isCompatible(Uint32 type) { return DictTabInfo::isHashMap(type); }
3317
3318 /* Table id (array index in DICT and other blocks) */
3319 union {
3320 Uint32 m_object_id;
3321 Uint32 key;
3322 };
3323 Uint32 m_obj_ptr_i; // in HashMap_pool
3324 Uint32 m_object_version;
3325
3326 RopeHandle m_name;
3327
3328 /**
3329 * ptr.i, in g_hash_map
3330 */
3331 Uint32 m_map_ptr_i;
3332 Uint32 nextPool;
3333 };
3334 typedef Ptr<HashMapRecord> HashMapRecordPtr;
3335 typedef ArrayPool<HashMapRecord> HashMapRecord_pool;
3336
3337 HashMapRecord_pool c_hash_map_pool;
3338 RSS_AP_SNAPSHOT(c_hash_map_pool);
3339 RSS_AP_SNAPSHOT(g_hash_map);
get_pool(HashMapRecordPtr)3340 HashMapRecord_pool& get_pool(HashMapRecordPtr) { return c_hash_map_pool; }
3341
3342 struct CreateHashMapRec;
3343 typedef RecordPool<CreateHashMapRec,ArenaPool> CreateHashMapRec_pool;
3344
3345 struct CreateHashMapRec : public OpRec {
3346 static const OpInfo g_opInfo;
3347
3348 static CreateHashMapRec_pool&
getPoolDbdict::CreateHashMapRec3349 getPool(Dbdict* dict) {
3350 return dict->c_createHashMapRecPool;
3351 }
3352
3353 CreateHashMapImplReq m_request;
3354
CreateHashMapRecDbdict::CreateHashMapRec3355 CreateHashMapRec() :
3356 OpRec(g_opInfo, (Uint32*)&m_request) {
3357 memset(&m_request, 0, sizeof(m_request));
3358 }
3359 };
3360
3361 typedef Ptr<CreateHashMapRec> CreateHashMapRecPtr;
3362 CreateHashMapRec_pool c_createHashMapRecPool;
3363 void execCREATE_HASH_MAP_REQ(Signal* signal);
3364
3365 // OpInfo
3366 bool createHashMap_seize(SchemaOpPtr);
3367 void createHashMap_release(SchemaOpPtr);
3368 //
3369 void createHashMap_parse(Signal*, bool master,
3370 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3371 bool createHashMap_subOps(Signal*, SchemaOpPtr);
3372 void createHashMap_reply(Signal*, SchemaOpPtr, ErrorInfo);
3373 //
3374 void createHashMap_prepare(Signal*, SchemaOpPtr);
3375 void createHashMap_writeObjConf(Signal* signal, Uint32, Uint32);
3376 void createHashMap_commit(Signal*, SchemaOpPtr);
3377 void createHashMap_complete(Signal*, SchemaOpPtr);
3378 //
3379 void createHashMap_abortParse(Signal*, SchemaOpPtr);
3380 void createHashMap_abortPrepare(Signal*, SchemaOpPtr);
3381
3382 void packHashMapIntoPages(SimpleProperties::Writer&, Ptr<HashMapRecord>);
3383
3384 // MODULE: CopyData
3385
3386 struct CopyDataRec;
3387 typedef RecordPool<CopyDataRec,ArenaPool> CopyDataRec_pool;
3388
3389 struct CopyDataRec : public OpRec {
3390 static const OpInfo g_opInfo;
3391
3392 static CopyDataRec_pool&
getPoolDbdict::CopyDataRec3393 getPool(Dbdict* dict) {
3394 return dict->c_copyDataRecPool;
3395 }
3396
3397 CopyDataImplReq m_request;
3398
CopyDataRecDbdict::CopyDataRec3399 CopyDataRec() :
3400 OpRec(g_opInfo, (Uint32*)&m_request) {
3401 memset(&m_request, 0, sizeof(m_request));
3402 }
3403 };
3404
3405 typedef Ptr<CopyDataRec> CopyDataRecPtr;
3406 CopyDataRec_pool c_copyDataRecPool;
3407 void execCOPY_DATA_REQ(Signal* signal);
3408 void execCOPY_DATA_REF(Signal* signal);
3409 void execCOPY_DATA_CONF(Signal* signal);
3410 void execCOPY_DATA_IMPL_REF(Signal* signal);
3411 void execCOPY_DATA_IMPL_CONF(Signal* signal);
3412
3413 // OpInfo
3414 bool copyData_seize(SchemaOpPtr);
3415 void copyData_release(SchemaOpPtr);
3416 //
3417 void copyData_parse(Signal*, bool master,
3418 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3419 bool copyData_subOps(Signal*, SchemaOpPtr);
3420 void copyData_reply(Signal*, SchemaOpPtr, ErrorInfo);
3421 //
3422 void copyData_prepare(Signal*, SchemaOpPtr);
3423 void copyData_fromLocal(Signal*, Uint32, Uint32);
3424 void copyData_commit(Signal*, SchemaOpPtr);
3425 void copyData_complete(Signal*, SchemaOpPtr);
3426 //
3427 void copyData_abortParse(Signal*, SchemaOpPtr);
3428 void copyData_abortPrepare(Signal*, SchemaOpPtr);
3429
3430 /**
3431 * Operation record for Util Signals.
3432 */
3433 struct OpSignalUtil : OpRecordCommon{
3434 Callback m_callback;
3435 Uint32 m_userData;
3436 };
3437 typedef Ptr<OpSignalUtil> OpSignalUtilPtr;
3438
3439 /**
3440 * Operation record for subscribe-start-stop
3441 */
3442 struct OpSubEvent : OpRecordCommon {
3443 Uint32 m_senderRef;
3444 Uint32 m_senderData;
3445 Uint32 m_errorCode;
3446
3447 Uint32 m_gsn;
3448 Uint32 m_subscriptionId;
3449 Uint32 m_subscriptionKey;
3450 Uint32 m_subscriberRef;
3451 Uint32 m_subscriberData;
3452 Uint8 m_buckets_per_ng[256]; // For SUB_START_REQ
3453 union {
3454 SubStartConf m_sub_start_conf;
3455 SubStopConf m_sub_stop_conf;
3456 };
3457 RequestTracker m_reqTracker;
3458 };
3459 typedef Ptr<OpSubEvent> OpSubEventPtr;
3460
3461 /**
3462 * Operation record for create event.
3463 */
3464 struct OpCreateEvent : OpRecordCommon {
3465 // original request (event id will be added)
3466 CreateEvntReq m_request;
3467 //AttributeMask m_attrListBitmask;
3468 // AttributeList m_attrList;
3469 sysTab_NDBEVENTS_0 m_eventRec;
3470 // char m_eventName[MAX_TAB_NAME_SIZE];
3471 // char m_tableName[MAX_TAB_NAME_SIZE];
3472
3473 // coordinator DICT
3474 RequestTracker m_reqTracker;
3475 // state info
3476 CreateEvntReq::RequestType m_requestType;
3477 // error info
3478 Uint32 m_errorCode;
3479 Uint32 m_errorLine;
3480 Uint32 m_errorNode; /* also used to store master node id
3481 in case of NotMaster */
3482 // ctor
OpCreateEventDbdict::OpCreateEvent3483 OpCreateEvent() {
3484 memset(&m_request, 0, sizeof(m_request));
3485 m_requestType = CreateEvntReq::RT_UNDEFINED;
3486 m_errorCode = CreateEvntRef::NoError;
3487 m_errorLine = 0;
3488 m_errorNode = 0;
3489 }
initDbdict::OpCreateEvent3490 void init(const CreateEvntReq* req, Dbdict* dp) {
3491 m_request = *req;
3492 m_errorCode = CreateEvntRef::NoError;
3493 m_errorLine = 0;
3494 m_errorNode = 0;
3495 m_requestType = req->getRequestType();
3496 }
hasErrorDbdict::OpCreateEvent3497 bool hasError() {
3498 return m_errorCode != CreateEvntRef::NoError;
3499 }
setErrorDbdict::OpCreateEvent3500 void setError(const CreateEvntRef* ref) {
3501 if (ref != 0 && ! hasError()) {
3502 m_errorCode = ref->getErrorCode();
3503 m_errorLine = ref->getErrorLine();
3504 m_errorNode = ref->getErrorNode();
3505 }
3506 }
3507
3508 };
3509 typedef Ptr<OpCreateEvent> OpCreateEventPtr;
3510
3511 /**
3512 * Operation record for drop event.
3513 */
3514 struct OpDropEvent : OpRecordCommon {
3515 // original request
3516 DropEvntReq m_request;
3517 // char m_eventName[MAX_TAB_NAME_SIZE];
3518 sysTab_NDBEVENTS_0 m_eventRec;
3519 RequestTracker m_reqTracker;
3520 // error info
3521 Uint32 m_errorCode;
3522 Uint32 m_errorLine;
3523 Uint32 m_errorNode;
3524 // ctor
OpDropEventDbdict::OpDropEvent3525 OpDropEvent() {
3526 memset(&m_request, 0, sizeof(m_request));
3527 m_errorCode = 0;
3528 m_errorLine = 0;
3529 m_errorNode = 0;
3530 }
initDbdict::OpDropEvent3531 void init(const DropEvntReq* req) {
3532 m_request = *req;
3533 m_errorCode = 0;
3534 m_errorLine = 0;
3535 m_errorNode = 0;
3536 }
hasErrorDbdict::OpDropEvent3537 bool hasError() {
3538 return m_errorCode != 0;
3539 }
setErrorDbdict::OpDropEvent3540 void setError(const DropEvntRef* ref) {
3541 if (ref != 0 && ! hasError()) {
3542 m_errorCode = ref->getErrorCode();
3543 m_errorLine = ref->getErrorLine();
3544 m_errorNode = ref->getErrorNode();
3545 }
3546 }
3547 };
3548 typedef Ptr<OpDropEvent> OpDropEventPtr;
3549
3550 // MODULE: CreateTrigger
3551
3552 struct CreateTriggerRec;
3553 typedef RecordPool<CreateTriggerRec,ArenaPool> CreateTriggerRec_pool;
3554
3555 struct CreateTriggerRec : public OpRec {
3556 static const OpInfo g_opInfo;
3557
3558 static CreateTriggerRec_pool&
getPoolDbdict::CreateTriggerRec3559 getPool(Dbdict* dict) {
3560 return dict->c_createTriggerRecPool;
3561 }
3562
3563 CreateTrigImplReq m_request;
3564
3565 char m_triggerName[MAX_TAB_NAME_SIZE];
3566 // sub-operation counters
3567 bool m_created;
3568 bool m_main_op;
3569 bool m_sub_dst; // Create trigger destination
3570 bool m_sub_src; // Create trigger source
3571 Uint32 m_block_list[1]; // Only 1 block...
3572
CreateTriggerRecDbdict::CreateTriggerRec3573 CreateTriggerRec() :
3574 OpRec(g_opInfo, (Uint32*)&m_request) {
3575 memset(&m_request, 0, sizeof(m_request));
3576 memset(m_triggerName, 0, sizeof(m_triggerName));
3577 m_main_op = true;
3578 m_sub_src = false;
3579 m_sub_dst = false;
3580 m_created = false;
3581 }
3582 };
3583
3584 typedef Ptr<CreateTriggerRec> CreateTriggerRecPtr;
3585 CreateTriggerRec_pool c_createTriggerRecPool;
3586
3587 // OpInfo
3588 bool createTrigger_seize(SchemaOpPtr);
3589 void createTrigger_release(SchemaOpPtr);
3590 //
3591 void createTrigger_parse(Signal*, bool master,
3592 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3593 void createTrigger_parse_endpoint(Signal*, SchemaOpPtr op_ptr, ErrorInfo&);
3594 bool createTrigger_subOps(Signal*, SchemaOpPtr);
3595 void createTrigger_toCreateEndpoint(Signal*, SchemaOpPtr,
3596 CreateTrigReq::EndpointFlag);
3597 void createTrigger_fromCreateEndpoint(Signal*, Uint32, Uint32);
3598 void createTrigger_create_drop_trigger_operation(Signal*,SchemaOpPtr,
3599 ErrorInfo& error);
3600
3601 void createTrigger_reply(Signal*, SchemaOpPtr, ErrorInfo);
3602 //
3603 void createTrigger_prepare(Signal*, SchemaOpPtr);
3604 void createTrigger_prepare_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3605 void createTrigger_commit(Signal*, SchemaOpPtr);
3606 void createTrigger_commit_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3607 void createTrigger_complete(Signal*, SchemaOpPtr);
3608 //
3609 void createTrigger_abortParse(Signal*, SchemaOpPtr);
3610 void createTrigger_abortPrepare(Signal*, SchemaOpPtr);
3611 void createTrigger_abortPrepare_fromLocal(Signal*, Uint32, Uint32);
3612 void send_create_trig_req(Signal*, SchemaOpPtr);
3613
3614 // MODULE: DropTrigger
3615
3616 struct DropTriggerRec;
3617 typedef RecordPool<DropTriggerRec,ArenaPool> DropTriggerRec_pool;
3618
3619 struct DropTriggerRec : public OpRec {
3620 static const OpInfo g_opInfo;
3621
3622 static DropTriggerRec_pool&
getPoolDbdict::DropTriggerRec3623 getPool(Dbdict* dict) {
3624 return dict->c_dropTriggerRecPool;
3625 }
3626
3627 DropTrigImplReq m_request;
3628
3629 char m_triggerName[MAX_TAB_NAME_SIZE];
3630 // sub-operation counters
3631 bool m_main_op;
3632 bool m_sub_dst; // Create trigger destination
3633 bool m_sub_src; // Create trigger source
3634 Uint32 m_block_list[1]; // Only 1 block...
3635
DropTriggerRecDbdict::DropTriggerRec3636 DropTriggerRec() :
3637 OpRec(g_opInfo, (Uint32*)&m_request) {
3638 memset(&m_request, 0, sizeof(m_request));
3639 memset(m_triggerName, 0, sizeof(m_triggerName));
3640 m_main_op = true;
3641 m_sub_src = false;
3642 m_sub_dst = false;
3643 }
3644 };
3645
3646 typedef Ptr<DropTriggerRec> DropTriggerRecPtr;
3647 DropTriggerRec_pool c_dropTriggerRecPool;
3648
3649 // OpInfo
3650 bool dropTrigger_seize(SchemaOpPtr);
3651 void dropTrigger_release(SchemaOpPtr);
3652 //
3653 void dropTrigger_parse(Signal*, bool master,
3654 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3655 void dropTrigger_parse_endpoint(Signal*, SchemaOpPtr op_ptr, ErrorInfo&);
3656 bool dropTrigger_subOps(Signal*, SchemaOpPtr);
3657 void dropTrigger_toDropEndpoint(Signal*, SchemaOpPtr,
3658 DropTrigReq::EndpointFlag);
3659 void dropTrigger_fromDropEndpoint(Signal*, Uint32, Uint32);
3660 void dropTrigger_reply(Signal*, SchemaOpPtr, ErrorInfo);
3661 //
3662 void dropTrigger_prepare(Signal*, SchemaOpPtr);
3663 void dropTrigger_commit(Signal*, SchemaOpPtr);
3664 void dropTrigger_commit_fromLocal(Signal*, Uint32, Uint32);
3665 void dropTrigger_complete(Signal*, SchemaOpPtr);
3666 //
3667 void dropTrigger_abortParse(Signal*, SchemaOpPtr);
3668 void dropTrigger_abortPrepare(Signal*, SchemaOpPtr);
3669
3670 void send_drop_trig_req(Signal*, SchemaOpPtr);
3671
3672
3673 // MODULE: CreateFilegroup
3674
3675 struct CreateFilegroupRec;
3676 typedef RecordPool<CreateFilegroupRec,ArenaPool> CreateFilegroupRec_pool;
3677
3678 struct CreateFilegroupRec : public OpRec {
3679 bool m_parsed, m_prepared;
3680 CreateFilegroupImplReq m_request;
3681 Uint32 m_warningFlags;
3682
3683 // reflection
3684 static const OpInfo g_opInfo;
3685
3686 static CreateFilegroupRec_pool&
getPoolDbdict::CreateFilegroupRec3687 getPool(Dbdict* dict) {
3688 return dict->c_createFilegroupRecPool;
3689 }
3690
CreateFilegroupRecDbdict::CreateFilegroupRec3691 CreateFilegroupRec() :
3692 OpRec(g_opInfo, (Uint32*)&m_request) {
3693 memset(&m_request, 0, sizeof(m_request));
3694 m_parsed = m_prepared = false;
3695 m_warningFlags = 0;
3696 }
3697 };
3698
3699 typedef Ptr<CreateFilegroupRec> CreateFilegroupRecPtr;
3700 CreateFilegroupRec_pool c_createFilegroupRecPool;
3701
3702 // OpInfo
3703 bool createFilegroup_seize(SchemaOpPtr);
3704 void createFilegroup_release(SchemaOpPtr);
3705 //
3706 void createFilegroup_parse(Signal*, bool master,
3707 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3708 bool createFilegroup_subOps(Signal*, SchemaOpPtr);
3709 void createFilegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3710 //
3711 void createFilegroup_prepare(Signal*, SchemaOpPtr);
3712 void createFilegroup_commit(Signal*, SchemaOpPtr);
3713 void createFilegroup_complete(Signal*, SchemaOpPtr);
3714 //
3715 void createFilegroup_abortParse(Signal*, SchemaOpPtr);
3716 void createFilegroup_abortPrepare(Signal*, SchemaOpPtr);
3717
3718 void createFilegroup_fromLocal(Signal*, Uint32, Uint32);
3719 void createFilegroup_fromWriteObjInfo(Signal*, Uint32, Uint32);
3720
3721 // MODULE: CreateFile
3722
3723 struct CreateFileRec;
3724 typedef RecordPool<CreateFileRec,ArenaPool> CreateFileRec_pool;
3725
3726 struct CreateFileRec : public OpRec {
3727 bool m_parsed, m_prepared;
3728 CreateFileImplReq m_request;
3729 Uint32 m_warningFlags;
3730
3731 // reflection
3732 static const OpInfo g_opInfo;
3733
3734 static CreateFileRec_pool&
getPoolDbdict::CreateFileRec3735 getPool(Dbdict* dict) {
3736 return dict->c_createFileRecPool;
3737 }
3738
CreateFileRecDbdict::CreateFileRec3739 CreateFileRec() :
3740 OpRec(g_opInfo, (Uint32*)&m_request) {
3741 memset(&m_request, 0, sizeof(m_request));
3742 m_parsed = m_prepared = false;
3743 m_warningFlags = 0;
3744 }
3745 };
3746
3747 typedef Ptr<CreateFileRec> CreateFileRecPtr;
3748 CreateFileRec_pool c_createFileRecPool;
3749
3750 // OpInfo
3751 bool createFile_seize(SchemaOpPtr);
3752 void createFile_release(SchemaOpPtr);
3753 //
3754 void createFile_parse(Signal*, bool master,
3755 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3756 bool createFile_subOps(Signal*, SchemaOpPtr);
3757 void createFile_reply(Signal*, SchemaOpPtr, ErrorInfo);
3758 //
3759 void createFile_prepare(Signal*, SchemaOpPtr);
3760 void createFile_commit(Signal*, SchemaOpPtr);
3761 void createFile_complete(Signal*, SchemaOpPtr);
3762 //
3763 void createFile_abortParse(Signal*, SchemaOpPtr);
3764 void createFile_abortPrepare(Signal*, SchemaOpPtr);
3765
3766 void createFile_fromLocal(Signal*, Uint32, Uint32);
3767 void createFile_fromWriteObjInfo(Signal*, Uint32, Uint32);
3768
3769 // MODULE: DropFilegroup
3770
3771 struct DropFilegroupRec;
3772 typedef RecordPool<DropFilegroupRec,ArenaPool> DropFilegroupRec_pool;
3773
3774 struct DropFilegroupRec : public OpRec {
3775 bool m_parsed, m_prepared;
3776 DropFilegroupImplReq m_request;
3777
3778 // reflection
3779 static const OpInfo g_opInfo;
3780
3781 static DropFilegroupRec_pool&
getPoolDbdict::DropFilegroupRec3782 getPool(Dbdict* dict) {
3783 return dict->c_dropFilegroupRecPool;
3784 }
3785
DropFilegroupRecDbdict::DropFilegroupRec3786 DropFilegroupRec() :
3787 OpRec(g_opInfo, (Uint32*)&m_request) {
3788 memset(&m_request, 0, sizeof(m_request));
3789 m_parsed = m_prepared = false;
3790 }
3791 };
3792
3793 typedef Ptr<DropFilegroupRec> DropFilegroupRecPtr;
3794 DropFilegroupRec_pool c_dropFilegroupRecPool;
3795
3796 // OpInfo
3797 bool dropFilegroup_seize(SchemaOpPtr);
3798 void dropFilegroup_release(SchemaOpPtr);
3799 //
3800 void dropFilegroup_parse(Signal*, bool master,
3801 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3802 bool dropFilegroup_subOps(Signal*, SchemaOpPtr);
3803 void dropFilegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3804 //
3805 void dropFilegroup_prepare(Signal*, SchemaOpPtr);
3806 void dropFilegroup_commit(Signal*, SchemaOpPtr);
3807 void dropFilegroup_complete(Signal*, SchemaOpPtr);
3808 //
3809 void dropFilegroup_abortParse(Signal*, SchemaOpPtr);
3810 void dropFilegroup_abortPrepare(Signal*, SchemaOpPtr);
3811
3812 void dropFilegroup_fromLocal(Signal*, Uint32, Uint32);
3813
3814 // MODULE: DropFile
3815
3816 struct DropFileRec;
3817 typedef RecordPool<DropFileRec,ArenaPool> DropFileRec_pool;
3818
3819 struct DropFileRec : public OpRec {
3820 bool m_parsed, m_prepared;
3821 DropFileImplReq m_request;
3822
3823 // reflection
3824 static const OpInfo g_opInfo;
3825
3826 static DropFileRec_pool&
getPoolDbdict::DropFileRec3827 getPool(Dbdict* dict) {
3828 return dict->c_dropFileRecPool;
3829 }
3830
DropFileRecDbdict::DropFileRec3831 DropFileRec() :
3832 OpRec(g_opInfo, (Uint32*)&m_request) {
3833 memset(&m_request, 0, sizeof(m_request));
3834 m_parsed = m_prepared = false;
3835 }
3836 };
3837
3838 typedef Ptr<DropFileRec> DropFileRecPtr;
3839 DropFileRec_pool c_dropFileRecPool;
3840
3841 // OpInfo
3842 bool dropFile_seize(SchemaOpPtr);
3843 void dropFile_release(SchemaOpPtr);
3844 //
3845 void dropFile_parse(Signal*, bool master,
3846 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3847 bool dropFile_subOps(Signal*, SchemaOpPtr);
3848 void dropFile_reply(Signal*, SchemaOpPtr, ErrorInfo);
3849 //
3850 void dropFile_prepare(Signal*, SchemaOpPtr);
3851 void dropFile_commit(Signal*, SchemaOpPtr);
3852 void dropFile_complete(Signal*, SchemaOpPtr);
3853 //
3854 void dropFile_abortParse(Signal*, SchemaOpPtr);
3855 void dropFile_abortPrepare(Signal*, SchemaOpPtr);
3856
3857 void dropFile_fromLocal(Signal*, Uint32, Uint32);
3858
3859 // MODULE: CreateNodegroup
3860
3861 struct CreateNodegroupRec;
3862 typedef RecordPool<CreateNodegroupRec,ArenaPool> CreateNodegroupRec_pool;
3863
3864 struct CreateNodegroupRec : public OpRec {
3865 bool m_map_created;
3866 CreateNodegroupImplReq m_request;
3867
3868 // reflection
3869 static const OpInfo g_opInfo;
3870
3871 static CreateNodegroupRec_pool&
getPoolDbdict::CreateNodegroupRec3872 getPool(Dbdict* dict) {
3873 return dict->c_createNodegroupRecPool;
3874 }
3875
CreateNodegroupRecDbdict::CreateNodegroupRec3876 CreateNodegroupRec() :
3877 OpRec(g_opInfo, (Uint32*)&m_request) {
3878 memset(&m_request, 0, sizeof(m_request));
3879 m_map_created = false;
3880 m_blockIndex = RNIL;
3881 m_blockCnt = RNIL;
3882 m_cnt_waitGCP = RNIL;
3883 m_wait_gcp_type = RNIL;
3884 m_substartstop_blocked = false;
3885 m_gcp_blocked = false;
3886 }
3887
3888 enum { BlockCount = 3 };
3889 Uint32 m_blockNo[BlockCount];
3890 Uint32 m_blockIndex;
3891 Uint32 m_blockCnt;
3892 Uint32 m_cnt_waitGCP;
3893 Uint32 m_wait_gcp_type;
3894 bool m_gcp_blocked;
3895 bool m_substartstop_blocked;
3896 };
3897
3898 typedef Ptr<CreateNodegroupRec> CreateNodegroupRecPtr;
3899 CreateNodegroupRec_pool c_createNodegroupRecPool;
3900
3901 // OpInfo
3902 void execCREATE_NODEGROUP_REQ(Signal*);
3903 void execCREATE_NODEGROUP_IMPL_REF(Signal*);
3904 void execCREATE_NODEGROUP_IMPL_CONF(Signal*);
3905
3906 bool createNodegroup_seize(SchemaOpPtr);
3907 void createNodegroup_release(SchemaOpPtr);
3908 //
3909 void createNodegroup_parse(Signal*, bool master,
3910 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3911 bool createNodegroup_subOps(Signal*, SchemaOpPtr);
3912 void createNodegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3913 //
3914 void createNodegroup_prepare(Signal*, SchemaOpPtr);
3915 void createNodegroup_commit(Signal*, SchemaOpPtr);
3916 void createNodegroup_complete(Signal*, SchemaOpPtr);
3917 //
3918 void createNodegroup_abortParse(Signal*, SchemaOpPtr);
3919 void createNodegroup_abortPrepare(Signal*, SchemaOpPtr);
3920
3921 void createNodegroup_toLocal(Signal*, SchemaOpPtr);
3922 void createNodegroup_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3923 void createNodegroup_fromCreateHashMap(Signal*, Uint32 op_key, Uint32 ret);
3924 void createNodegroup_fromWaitGCP(Signal*, Uint32 op_key, Uint32 ret);
3925 void createNodegroup_fromBlockSubStartStop(Signal*, Uint32 op_key, Uint32);
3926
3927 void execCREATE_HASH_MAP_REF(Signal* signal);
3928 void execCREATE_HASH_MAP_CONF(Signal* signal);
3929
3930 // MODULE: DropNodegroup
3931
3932 struct DropNodegroupRec;
3933 typedef RecordPool<DropNodegroupRec,ArenaPool> DropNodegroupRec_pool;
3934
3935 struct DropNodegroupRec : public OpRec {
3936 DropNodegroupImplReq m_request;
3937
3938 // reflection
3939 static const OpInfo g_opInfo;
3940
3941 static DropNodegroupRec_pool&
getPoolDbdict::DropNodegroupRec3942 getPool(Dbdict* dict) {
3943 return dict->c_dropNodegroupRecPool;
3944 }
3945
DropNodegroupRecDbdict::DropNodegroupRec3946 DropNodegroupRec() :
3947 OpRec(g_opInfo, (Uint32*)&m_request) {
3948 memset(&m_request, 0, sizeof(m_request));
3949 m_blockIndex = RNIL;
3950 m_blockCnt = RNIL;
3951 m_cnt_waitGCP = RNIL;
3952 m_wait_gcp_type = RNIL;
3953 m_gcp_blocked = false;
3954 m_substartstop_blocked = false;
3955 }
3956
3957 enum { BlockCount = 3 };
3958 Uint32 m_blockNo[BlockCount];
3959 Uint32 m_blockIndex;
3960 Uint32 m_blockCnt;
3961 Uint32 m_cnt_waitGCP;
3962 Uint32 m_wait_gcp_type;
3963 bool m_gcp_blocked;
3964 bool m_substartstop_blocked;
3965 };
3966
3967 typedef Ptr<DropNodegroupRec> DropNodegroupRecPtr;
3968 DropNodegroupRec_pool c_dropNodegroupRecPool;
3969
3970 // OpInfo
3971 void execDROP_NODEGROUP_REQ(Signal*);
3972 void execDROP_NODEGROUP_IMPL_REF(Signal*);
3973 void execDROP_NODEGROUP_IMPL_CONF(Signal*);
3974
3975 bool dropNodegroup_seize(SchemaOpPtr);
3976 void dropNodegroup_release(SchemaOpPtr);
3977 //
3978 void dropNodegroup_parse(Signal*, bool master,
3979 SchemaOpPtr, SectionHandle&, ErrorInfo&);
3980 bool dropNodegroup_subOps(Signal*, SchemaOpPtr);
3981 void dropNodegroup_reply(Signal*, SchemaOpPtr, ErrorInfo);
3982 //
3983 void dropNodegroup_prepare(Signal*, SchemaOpPtr);
3984 void dropNodegroup_commit(Signal*, SchemaOpPtr);
3985 void dropNodegroup_complete(Signal*, SchemaOpPtr);
3986 //
3987 void dropNodegroup_abortParse(Signal*, SchemaOpPtr);
3988 void dropNodegroup_abortPrepare(Signal*, SchemaOpPtr);
3989
3990 void dropNodegroup_toLocal(Signal*, SchemaOpPtr);
3991 void dropNodegroup_fromLocal(Signal*, Uint32 op_key, Uint32 ret);
3992 void dropNodegroup_fromWaitGCP(Signal*, Uint32 op_key, Uint32 ret);
3993 void dropNodegroup_fromBlockSubStartStop(Signal*, Uint32 op_key, Uint32);
3994
3995 // MODULE: CreateFK
3996 struct CreateFKRec;
3997 typedef RecordPool<CreateFKRec,ArenaPool> CreateFKRec_pool;
3998
3999 struct CreateFKRec : public OpRec {
4000 bool m_parsed;
4001 bool m_prepared;
4002 Uint32 m_sub_create_trigger;
4003 bool m_sub_build_fk;
4004 CreateFKImplReq m_request;
4005
4006 // reflection
4007 static const OpInfo g_opInfo;
4008
4009 static CreateFKRec_pool&
getPoolDbdict::CreateFKRec4010 getPool(Dbdict* dict) {
4011 return dict->c_createFKRecPool;
4012 }
4013
CreateFKRecDbdict::CreateFKRec4014 CreateFKRec() :
4015 OpRec(g_opInfo, (Uint32*)&m_request) {
4016 memset(&m_request, 0, sizeof(m_request));
4017 m_parsed = m_prepared = false;
4018 m_sub_create_trigger = 0;
4019 m_sub_build_fk = false;
4020 }
4021 };
4022
4023 typedef Ptr<CreateFKRec> CreateFKRecPtr;
4024 CreateFKRec_pool c_createFKRecPool;
4025
4026 // OpInfo
4027 bool createFK_seize(SchemaOpPtr);
4028 void createFK_release(SchemaOpPtr);
4029 //
4030 void createFK_parse(Signal*, bool master,
4031 SchemaOpPtr, SectionHandle&, ErrorInfo&);
4032 bool createFK_subOps(Signal*, SchemaOpPtr);
4033 void createFK_reply(Signal*, SchemaOpPtr, ErrorInfo);
4034
4035 void createFK_toCreateTrigger(Signal* signal, SchemaOpPtr);
4036 void createFK_fromCreateTrigger(Signal* signal, Uint32 op_key, Uint32 ret);
4037 void createFK_fromBuildFK(Signal* signal, Uint32 op_key, Uint32 ret);
4038 //
4039 void createFK_prepare(Signal*, SchemaOpPtr);
4040 void createFK_writeTableConf(Signal* signal, Uint32 op_key, Uint32 ret);
4041 void createFK_prepareFromLocal(Signal* signal, Uint32 op_key, Uint32 ret);
4042
4043 void createFK_commit(Signal*, SchemaOpPtr);
4044 void createFK_complete(Signal*, SchemaOpPtr);
4045 //
4046 void createFK_abortParse(Signal*, SchemaOpPtr);
4047 void createFK_abortPrepare(Signal*, SchemaOpPtr);
4048 void createFK_abortPrepareFromLocal(Signal*, Uint32 op_key, Uint32 ret);
4049
4050 void createFK_fromLocal(Signal*, Uint32, Uint32);
4051 void createFK_fromWriteObjInfo(Signal*, Uint32, Uint32);
4052
4053 void execCREATE_FK_REQ(Signal*);
4054 void execCREATE_FK_IMPL_REF(Signal*);
4055 void execCREATE_FK_IMPL_CONF(Signal*);
4056 void execCREATE_FK_REF(Signal*);
4057 void execCREATE_FK_CONF(Signal*);
4058
4059 // MODULE: BuildFK
4060 struct BuildFKRec;
4061 typedef RecordPool<BuildFKRec,ArenaPool> BuildFKRec_pool;
4062
4063 struct BuildFKRec : public OpRec {
4064 bool m_parsed, m_prepared;
4065 BuildFKImplReq m_request;
4066
4067 // reflection
4068 static const OpInfo g_opInfo;
4069
4070 static BuildFKRec_pool&
getPoolDbdict::BuildFKRec4071 getPool(Dbdict* dict) {
4072 return dict->c_buildFKRecPool;
4073 }
4074
BuildFKRecDbdict::BuildFKRec4075 BuildFKRec() :
4076 OpRec(g_opInfo, (Uint32*)&m_request) {
4077 memset(&m_request, 0, sizeof(m_request));
4078 m_parsed = m_prepared = false;
4079 }
4080 };
4081
4082 typedef Ptr<BuildFKRec> BuildFKRecPtr;
4083 BuildFKRec_pool c_buildFKRecPool;
4084
4085 // OpInfo
4086 bool buildFK_seize(SchemaOpPtr);
4087 void buildFK_release(SchemaOpPtr);
4088 //
4089 void buildFK_parse(Signal*, bool master,
4090 SchemaOpPtr, SectionHandle&, ErrorInfo&);
4091 bool buildFK_subOps(Signal*, SchemaOpPtr);
4092 void buildFK_reply(Signal*, SchemaOpPtr, ErrorInfo);
4093 //
4094 void buildFK_prepare(Signal*, SchemaOpPtr);
4095 void buildFK_commit(Signal*, SchemaOpPtr);
4096 void buildFK_complete(Signal*, SchemaOpPtr);
4097 //
4098 void buildFK_abortParse(Signal*, SchemaOpPtr);
4099 void buildFK_abortPrepare(Signal*, SchemaOpPtr);
4100
4101 void buildFK_fromLocal(Signal*, Uint32, Uint32);
4102
4103 void execBUILD_FK_REQ(Signal*);
4104 void execBUILD_FK_REF(Signal*);
4105 void execBUILD_FK_CONF(Signal*);
4106 void execBUILD_FK_IMPL_REF(Signal*);
4107 void execBUILD_FK_IMPL_CONF(Signal*);
4108
4109 // MODULE: DropFK
4110 struct DropFKRec;
4111 typedef RecordPool<DropFKRec,ArenaPool> DropFKRec_pool;
4112
4113 struct DropFKRec : public OpRec {
4114 bool m_parsed;
4115 bool m_prepared;
4116 Uint32 m_sub_drop_trigger;
4117 DropFKImplReq m_request;
4118
4119 // reflection
4120 static const OpInfo g_opInfo;
4121
4122 static DropFKRec_pool&
getPoolDbdict::DropFKRec4123 getPool(Dbdict* dict) {
4124 return dict->c_dropFKRecPool;
4125 }
4126
DropFKRecDbdict::DropFKRec4127 DropFKRec() :
4128 OpRec(g_opInfo, (Uint32*)&m_request) {
4129 memset(&m_request, 0, sizeof(m_request));
4130 m_parsed = m_prepared = false;
4131 m_sub_drop_trigger = 0;
4132 }
4133 };
4134
4135 typedef Ptr<DropFKRec> DropFKRecPtr;
4136 DropFKRec_pool c_dropFKRecPool;
4137
4138 // OpInfo
4139 bool dropFK_seize(SchemaOpPtr);
4140 void dropFK_release(SchemaOpPtr);
4141 //
4142 void dropFK_parse(Signal*, bool master,
4143 SchemaOpPtr, SectionHandle&, ErrorInfo&);
4144 bool dropFK_subOps(Signal*, SchemaOpPtr);
4145 void dropFK_reply(Signal*, SchemaOpPtr, ErrorInfo);
4146 //
4147 void dropFK_toDropTrigger(Signal* signal, SchemaOpPtr, Uint32);
4148 void dropFK_fromDropTrigger(Signal* signal, Uint32 op_key, Uint32 ret);
4149
4150 //
4151 void dropFK_prepare(Signal*, SchemaOpPtr);
4152 void dropFK_commit(Signal*, SchemaOpPtr);
4153 void dropFK_complete(Signal*, SchemaOpPtr);
4154 //
4155 void dropFK_abortParse(Signal*, SchemaOpPtr);
4156 void dropFK_abortPrepare(Signal*, SchemaOpPtr);
4157
4158 void send_drop_fk_req(Signal*, SchemaOpPtr);
4159 void dropFK_fromLocal(Signal*, Uint32, Uint32);
4160 void dropFK_fromWriteObjInfo(Signal*, Uint32, Uint32);
4161
4162 void execDROP_FK_REQ(Signal*);
4163 void execDROP_FK_IMPL_REF(Signal*);
4164 void execDROP_FK_IMPL_CONF(Signal*);
4165
4166 /**
4167 * Foreign Key representation
4168 */
4169 struct ForeignKeyRec
4170 {
ForeignKeyRecDbdict::ForeignKeyRec4171 ForeignKeyRec() { }
4172
isCompatibleDbdict::ForeignKeyRec4173 static bool isCompatible(Uint32 type) {
4174 return DictTabInfo::isForeignKey(type);
4175 }
4176
4177 Uint32 m_magic;
4178 union {
4179 Uint32 key;
4180 Uint32 m_fk_id;
4181 };
4182
4183 Uint32 m_obj_ptr_i;
4184 Uint32 m_version;
4185 RopeHandle m_name;
4186 Uint32 m_parentTableId;
4187 Uint32 m_childTableId;
4188 Uint32 m_parentIndexId;
4189 Uint32 m_childIndexId;
4190 Uint32 m_bits; // CreateFKImplReq::Bits
4191
4192 Uint32 m_parentTriggerId;
4193 Uint32 m_childTriggerId;
4194
4195 Uint32 m_columnCount;
4196 Uint32 m_parentColumns[MAX_ATTRIBUTES_IN_INDEX];
4197 Uint32 m_childColumns[MAX_ATTRIBUTES_IN_INDEX];
4198
4199 Uint32 nextPool;
4200 Uint32 nextHash;
4201 Uint32 prevHash;
4202
hashValueDbdict::ForeignKeyRec4203 Uint32 hashValue() const {
4204 return key;
4205 }
4206
equalDbdict::ForeignKeyRec4207 Uint32 equal(const ForeignKeyRec& obj) const {
4208 return key == obj.key;
4209 }
4210 };
4211
4212 typedef Ptr<ForeignKeyRec> ForeignKeyRecPtr;
4213 typedef RecordPool<ForeignKeyRec, RWPool> ForeignKeyRec_pool;
4214
4215 ForeignKeyRec_pool c_fk_pool;
4216
get_pool(ForeignKeyRecPtr)4217 ForeignKeyRec_pool& get_pool(ForeignKeyRecPtr) { return c_fk_pool; }
4218 void packFKIntoPages(SimpleProperties::Writer &, Ptr<ForeignKeyRec>);
4219
4220 /**
4221 * Only used at coordinator/master
4222 */
4223 // Common operation record pool
4224 public:
4225 STATIC_CONST( opCreateEventSize = sizeof(OpCreateEvent) );
4226 STATIC_CONST( opSubEventSize = sizeof(OpSubEvent) );
4227 STATIC_CONST( opDropEventSize = sizeof(OpDropEvent) );
4228 STATIC_CONST( opSignalUtilSize = sizeof(OpSignalUtil) );
4229 private:
4230 #define PTR_ALIGN(n) ((((n)+sizeof(void*)-1)>>2)&~((sizeof(void*)-1)>>2))
4231 union OpRecordUnion {
4232 Uint32 u_opCreateEvent [PTR_ALIGN(opCreateEventSize)];
4233 Uint32 u_opSubEvent [PTR_ALIGN(opSubEventSize)];
4234 Uint32 u_opDropEvent [PTR_ALIGN(opDropEventSize)];
4235 Uint32 u_opSignalUtil [PTR_ALIGN(opSignalUtilSize)];
4236 Uint32 nextPool;
4237 };
4238 typedef ArrayPool<OpRecordUnion> OpRecordUnion_pool;
4239 OpRecordUnion_pool c_opRecordPool;
4240
4241 // Operation records
4242 typedef KeyTable2C<OpCreateEvent, OpRecordUnion> OpCreateEvent_pool;
4243 typedef KeyTable2C<OpSubEvent, OpRecordUnion> OpSubEvent_pool;
4244 typedef KeyTable2C<OpDropEvent, OpRecordUnion> OpDropEvent_pool;
4245 typedef KeyTable2C<OpSignalUtil, OpRecordUnion> OpSignalUtil_pool;
4246 OpCreateEvent_pool c_opCreateEvent;
4247 OpSubEvent_pool c_opSubEvent;
4248 OpDropEvent_pool c_opDropEvent;
4249 OpSignalUtil_pool c_opSignalUtil;
4250
4251 // Unique key for operation XXX move to some system table
4252 Uint32 c_opRecordSequence;
4253
4254 void handleNdbdFailureCallback(Signal* signal,
4255 Uint32 failedNodeId,
4256 Uint32 ignoredRc);
4257 void handleApiFailureCallback(Signal* signal,
4258 Uint32 failedNodeId,
4259 Uint32 ignoredRc);
4260 // Statement blocks
4261
4262 /* ------------------------------------------------------------ */
4263 // Start/Restart Handling
4264 /* ------------------------------------------------------------ */
4265 void sendSTTORRY(Signal* signal);
4266 void sendNDB_STTORRY(Signal* signal);
4267 void initSchemaFile(Signal* signal);
4268
4269 /* ------------------------------------------------------------ */
4270 // Drop Table Handling
4271 /* ------------------------------------------------------------ */
4272 void releaseTableObject(Uint32 table_ptr_i, bool removeFromHash = true);
4273
4274 /* ------------------------------------------------------------ */
4275 // General Stuff
4276 /* ------------------------------------------------------------ */
4277 Uint32 getFreeObjId(bool both = false);
4278 Uint32 getFreeTableRecord();
4279 bool seizeTableRecord(TableRecordPtr& tableRecord, Uint32& schemaFileId);
4280 Uint32 getFreeTriggerRecord();
4281 bool seizeTriggerRecord(TriggerRecordPtr& tableRecord, Uint32 triggerId);
4282 void releaseTriggerObject(Uint32 trigger_ptr_i);
4283 bool getNewAttributeRecord(TableRecordPtr tablePtr,
4284 AttributeRecordPtr & attrPtr);
4285 void packTableIntoPages(Signal* signal);
4286 void packTableIntoPages(SimpleProperties::Writer &, TableRecordPtr, Signal* =0);
4287 void packFilegroupIntoPages(SimpleProperties::Writer &,
4288 FilegroupPtr,
4289 const Uint32 undo_free_hi,
4290 const Uint32 undo_free_lo);
4291 void packFileIntoPages(SimpleProperties::Writer &, FilePtr, const Uint32);
4292
4293 void sendGET_TABINFOREQ(Signal* signal,
4294 Uint32 tableId);
4295 void sendTC_SCHVERREQ(Signal* signal,
4296 Uint32 tableId,
4297 BlockReference tcRef);
4298
4299 /* ------------------------------------------------------------ */
4300 // System Restart Handling
4301 /* ------------------------------------------------------------ */
4302 void initSendSchemaData(Signal* signal);
4303 void sendSchemaData(Signal* signal);
4304 Uint32 sendSCHEMA_INFO(Signal* signal, Uint32 nodeId, Uint32* pagePointer);
4305 void sendDIHSTARTTAB_REQ(Signal* signal);
4306
4307 /* ------------------------------------------------------------ */
4308 // Receive Table Handling
4309 /* ------------------------------------------------------------ */
4310 void handleTabInfoInit(Signal*, SchemaTransPtr&,
4311 SimpleProperties::Reader &,
4312 ParseDictTabInfoRecord *,
4313 bool checkExist = true);
4314 void handleTabInfo(SimpleProperties::Reader & it, ParseDictTabInfoRecord *,
4315 DictTabInfo::Table & tableDesc);
4316
4317 void handleAddTableFailure(Signal* signal,
4318 Uint32 failureLine,
4319 Uint32 tableId);
4320 bool verifyTableCorrect(Signal* signal, Uint32 tableId);
4321
4322 /* ------------------------------------------------------------ */
4323 // Add Fragment Handling
4324 /* ------------------------------------------------------------ */
4325 void sendLQHADDATTRREQ(Signal*, SchemaOpPtr, Uint32 attributePtrI);
4326
4327 /* ------------------------------------------------------------ */
4328 // Read/Write Schema and Table files
4329 /* ------------------------------------------------------------ */
4330 void updateSchemaState(Signal* signal, Uint32 tableId,
4331 SchemaFile::TableEntry*, Callback*,
4332 bool savetodisk = 1, bool dicttrans = 0);
4333 void startWriteSchemaFile(Signal* signal);
4334 void openSchemaFile(Signal* signal,
4335 Uint32 fileNo,
4336 Uint32 fsPtr,
4337 bool writeFlag,
4338 bool newFile);
4339 void writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
4340 void writeSchemaConf(Signal* signal,
4341 FsConnectRecordPtr fsPtr);
4342 void closeFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
4343 void closeWriteSchemaConf(Signal* signal,
4344 FsConnectRecordPtr fsPtr);
4345 void initSchemaFile_conf(Signal* signal, Uint32 i, Uint32 returnCode);
4346
4347 void writeTableFile(Signal* signal, Uint32 tableId,
4348 SegmentedSectionPtr tabInfo, Callback*);
4349 void writeTableFile(Signal* signal, SchemaOpPtr op_ptr, Uint32 tableId,
4350 OpSection opSection, Callback*);
4351 void startWriteTableFile(Signal* signal, Uint32 tableId);
4352 void openTableFile(Signal* signal,
4353 Uint32 fileNo,
4354 Uint32 fsPtr,
4355 Uint32 tableId,
4356 bool writeFlag);
4357 void writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
4358 void writeTableConf(Signal* signal,
4359 FsConnectRecordPtr fsPtr);
4360 void closeWriteTableConf(Signal* signal,
4361 FsConnectRecordPtr fsPtr);
4362
4363 void startReadTableFile(Signal* signal, Uint32 tableId);
4364 void openReadTableRef(Signal* signal,
4365 FsConnectRecordPtr fsPtr);
4366 void readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
4367 void readTableConf(Signal* signal,
4368 FsConnectRecordPtr fsPtr);
4369 void readTableRef(Signal* signal,
4370 FsConnectRecordPtr fsPtr);
4371 void closeReadTableConf(Signal* signal,
4372 FsConnectRecordPtr fsPtr);
4373
4374 void startReadSchemaFile(Signal* signal);
4375 void openReadSchemaRef(Signal* signal,
4376 FsConnectRecordPtr fsPtr);
4377 void readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
4378 void readSchemaConf(Signal* signal, FsConnectRecordPtr fsPtr);
4379 void readSchemaRef(Signal* signal, FsConnectRecordPtr fsPtr);
4380 void closeReadSchemaConf(Signal* signal,
4381 FsConnectRecordPtr fsPtr);
4382 bool convertSchemaFileTo_5_0_6(XSchemaFile*);
4383 bool convertSchemaFileTo_6_4(XSchemaFile*);
4384
4385 /* ------------------------------------------------------------ */
4386 // Get table definitions
4387 /* ------------------------------------------------------------ */
4388 void sendGET_TABINFOREF(Signal* signal,
4389 GetTabInfoReq*,
4390 GetTabInfoRef::ErrorCode errorCode,
4391 Uint32 errorLine);
4392
4393 void sendGET_TABLEID_REF(Signal* signal,
4394 GetTableIdReq * req,
4395 GetTableIdRef::ErrorCode errorCode);
4396
4397 void sendGetTabResponse(Signal* signal);
4398
4399 /* ------------------------------------------------------------ */
4400 // Indexes and triggers
4401 /* ------------------------------------------------------------ */
4402
4403 // reactivate and rebuild indexes on start up
4404 void activateIndexes(Signal* signal, Uint32 i);
4405 void activateIndex_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
4406 void activateIndex_fromAlterIndex(Signal*, Uint32 tx_key, Uint32 ret);
4407 void activateIndex_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
4408 void rebuildIndexes(Signal* signal, Uint32 i);
4409 void rebuildIndex_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
4410 void rebuildIndex_fromBuildIndex(Signal*, Uint32 tx_key, Uint32 ret);
4411 void rebuildIndex_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
4412 // FK re-enable (create triggers) on start up
4413 void enableFKs(Signal* signal, Uint32 i);
4414 void enableFK_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
4415 void enableFK_fromCreateFK(Signal*, Uint32 tx_key, Uint32 ret);
4416 void enableFK_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
4417 bool c_restart_enable_fks;
4418 Uint32 c_at_restart_skip_indexes;
4419 Uint32 c_at_restart_skip_fks;
4420
4421 // Events
4422 void
4423 createEventUTIL_PREPARE(Signal* signal,
4424 Uint32 callbackData,
4425 Uint32 returnCode);
4426 void
4427 createEventUTIL_EXECUTE(Signal *signal,
4428 Uint32 callbackData,
4429 Uint32 returnCode);
4430 void
4431 dropEventUTIL_PREPARE_READ(Signal* signal,
4432 Uint32 callbackData,
4433 Uint32 returnCode);
4434 void
4435 dropEventUTIL_EXECUTE_READ(Signal* signal,
4436 Uint32 callbackData,
4437 Uint32 returnCode);
4438 void
4439 dropEventUTIL_PREPARE_DELETE(Signal* signal,
4440 Uint32 callbackData,
4441 Uint32 returnCode);
4442 void
4443 dropEventUTIL_EXECUTE_DELETE(Signal *signal,
4444 Uint32 callbackData,
4445 Uint32 returnCode);
4446 void
4447 dropEventUtilPrepareRef(Signal* signal,
4448 Uint32 callbackData,
4449 Uint32 returnCode);
4450 void
4451 dropEventUtilExecuteRef(Signal* signal,
4452 Uint32 callbackData,
4453 Uint32 returnCode);
4454 int
4455 sendSignalUtilReq(Callback *c,
4456 BlockReference ref,
4457 GlobalSignalNumber gsn,
4458 Signal* signal,
4459 Uint32 length,
4460 JobBufferLevel jbuf,
4461 LinearSectionPtr ptr[3],
4462 Uint32 noOfSections);
4463 int
4464 recvSignalUtilReq(Signal* signal, Uint32 returnCode);
4465
4466 void completeSubStartReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
4467 void completeSubStopReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
4468 void completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
4469
4470 void dropEvent_sendReply(Signal* signal,
4471 OpDropEventPtr evntRecPtr);
4472
4473 void createEvent_RT_USER_CREATE(Signal* signal,
4474 OpCreateEventPtr evntRecPtr,
4475 SectionHandle& handle);
4476 void createEventComplete_RT_USER_CREATE(Signal* signal,
4477 OpCreateEventPtr evntRecPtr);
4478 void createEvent_RT_USER_GET(Signal*, OpCreateEventPtr, SectionHandle&);
4479 void createEventComplete_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
4480
4481 void createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
4482
4483 void createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI,
4484 Uint32 returnCode);
4485 void createEvent_sendReply(Signal* signal, OpCreateEventPtr evntRecPtr,
4486 LinearSectionPtr *ptr = NULL, int noLSP = 0);
4487
4488 void prepareTransactionEventSysTable (Callback *c,
4489 Signal* signal,
4490 Uint32 senderData,
4491 UtilPrepareReq::OperationTypeValue prepReq);
4492 void prepareUtilTransaction(Callback *c,
4493 Signal* signal,
4494 Uint32 senderData,
4495 Uint32 tableId,
4496 const char *tableName,
4497 UtilPrepareReq::OperationTypeValue prepReq,
4498 Uint32 noAttr,
4499 Uint32 attrIds[],
4500 const char *attrNames[]);
4501
4502 void executeTransEventSysTable(Callback *c,
4503 Signal *signal,
4504 const Uint32 ptrI,
4505 sysTab_NDBEVENTS_0& m_eventRec,
4506 const Uint32 prepareId,
4507 UtilPrepareReq::OperationTypeValue prepReq);
4508 void executeTransaction(Callback *c,
4509 Signal* signal,
4510 Uint32 senderData,
4511 Uint32 prepareId,
4512 Uint32 noAttr,
4513 LinearSectionPtr headerPtr,
4514 LinearSectionPtr dataPtr);
4515
4516 void parseReadEventSys(Signal *signal, sysTab_NDBEVENTS_0& m_eventRec);
4517 bool upgrade_suma_NotStarted(Uint32 err, Uint32 ref) const;
4518
4519 // support
4520 void getTableKeyList(TableRecordPtr,
4521 Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list);
4522 void getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id);
4523 void getIndexAttrList(TableRecordPtr indexPtr, IndexAttributeList& list);
4524 void getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask);
4525
4526 /* ------------------------------------------------------------ */
4527 // Initialisation
4528 /* ------------------------------------------------------------ */
4529 void initCommonData();
4530 void initRecords();
4531 void initConnectRecord();
4532 void initRetrieveRecord(Signal*, Uint32, Uint32 returnCode);
4533 void initSchemaRecord();
4534 void initRestartRecord(Uint32 sp = 0, Uint32 lp = 0,
4535 const char * sb = 0, const char * eb = 0);
4536 void initSendSchemaRecord();
4537 void initReadTableRecord();
4538 void initWriteTableRecord();
4539 void initReadSchemaRecord();
4540 void initWriteSchemaRecord();
4541
4542 void initNodeRecords();
4543 void initialiseTableRecord(TableRecordPtr tablePtr, Uint32 tableId);
4544 void initialiseTriggerRecord(TriggerRecordPtr triggerPtr, Uint32 triggerId);
4545 void initPageRecords();
4546
4547 Uint32 getFsConnRecord();
4548
4549 bool getIsFailed(Uint32 nodeId) const;
4550
4551 void printTables(); // For debugging only
4552
4553 void startRestoreSchema(Signal*, Callback);
4554 void restartNextPass(Signal*);
4555 void restart_fromBeginTrans(Signal*, Uint32 tx_key, Uint32 ret);
4556 void restart_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
4557 void restartEndPass_fromEndTrans(Signal*, Uint32 tx_key, Uint32 ret);
4558 void restart_fromWriteSchemaFile(Signal*, Uint32, Uint32);
4559 void restart_nextOp(Signal*, bool commit = false);
4560
4561 void checkSchemaStatus(Signal* signal);
4562 void checkPendingSchemaTrans(XSchemaFile* xsf);
4563
4564 void restartCreateObj(Signal*, Uint32, const SchemaFile::TableEntry *, bool);
4565 void restartCreateObj_readConf(Signal*, Uint32, Uint32);
4566 void restartCreateObj_getTabInfoConf(Signal*);
4567 void restartCreateObj_parse(Signal*, SegmentedSectionPtr, bool);
4568 void restartDropObj(Signal*, Uint32, const SchemaFile::TableEntry *);
4569
4570 void restart_checkSchemaStatusComplete(Signal*, Uint32 callback, Uint32);
4571 void masterRestart_checkSchemaStatusComplete(Signal*, Uint32, Uint32);
4572
4573 void sendSchemaComplete(Signal*, Uint32 callbackData, Uint32);
4574
4575 public:
4576 void send_drop_file(Signal*, Uint32, Uint32, DropFileImplReq::RequestInfo);
4577 void send_drop_fg(Signal*, Uint32, Uint32, DropFilegroupImplReq::RequestInfo);
4578
4579 int checkSingleUserMode(Uint32 senderRef);
4580
4581 friend NdbOut& operator<<(NdbOut& out, const ErrorInfo&);
4582 #ifdef VM_TRACE
4583 friend NdbOut& operator<<(NdbOut& out, const DictObject&);
4584 friend NdbOut& operator<<(NdbOut& out, const SchemaOp&);
4585 friend NdbOut& operator<<(NdbOut& out, const SchemaTrans&);
4586 friend NdbOut& operator<<(NdbOut& out, const TxHandle&);
4587 void check_consistency();
4588 void check_consistency_entry(TableRecordPtr tablePtr);
4589 void check_consistency_table(TableRecordPtr tablePtr);
4590 void check_consistency_index(TableRecordPtr indexPtr);
4591 void check_consistency_trigger(TriggerRecordPtr triggerPtr);
4592 void check_consistency_object(DictObjectPtr obj_ptr);
4593 #endif
4594
4595 /**
4596 * Dict lock queue does currently uniformly handle
4597 *
4598 * - starting node
4599 * - schema op
4600 *
4601 * The impl. is based on DbUtil lock's (LockQueue)
4602 *
4603 * It would be very nice to use this *fully*
4604 * But instead of introducing extra break in schema-op
4605 * a lock queue in instantiated in Dict, for easy trylock-handling
4606 */
4607 struct DictLockType;
4608 friend struct DictLockType;
4609
4610 struct DictLockType {
4611 DictLockReq::LockType lockType;
4612 const char* text;
4613 };
4614 static const DictLockType* getDictLockType(Uint32 lockType);
4615 void sendDictLockInfoEvent(Signal*, const UtilLockReq*, const char* text);
4616 void debugLockInfo(Signal* signal,
4617 const char* text,
4618 Uint32 rc);
4619 void removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes);
4620
4621
4622 Uint32 dict_lock_trylock(const DictLockReq* req);
4623 Uint32 dict_lock_unlock(Signal* signal, const DictLockReq* req,
4624 DictLockReq::LockType* type=0);
4625
4626 LockQueue::Pool m_dict_lock_pool;
4627 LockQueue m_dict_lock;
4628
4629 /**
4630 Make a ListTablesData representation of a DictObject.
4631 @rapam dictObject The input object.
4632 @param parentTableId If not RNIL, leave 'ltd' unchanged and return false if
4633 'dictObject' does not depend on parentTableId. Foreign keys depend on
4634 each of the indexes and tables they refer, triggers depend on the
4635 table on which they are defined, and indexes depend on their base tables.
4636 All other objects are considered to be independent, such that false
4637 will be returned if parentTableId!=RNIL.
4638 @param ltd Result value.
4639 @return false if parentTableId!=RNIL and 'dictObject' did not depend on it,
4640 otherwise true.
4641 **/
4642 bool buildListTablesData(const DictObject& dictObject,
4643 Uint32 parentTableId,
4644 ListTablesData& ltd,
4645 Uint32& objectVersion,
4646 Uint32& parentObjectType,
4647 Uint32& parentObjectId);
4648
4649 void sendOLD_LIST_TABLES_CONF(Signal *signal, ListTablesReq*);
4650 void sendLIST_TABLES_CONF(Signal *signal, ListTablesReq*);
4651
4652 Uint32 c_outstanding_sub_startstop;
4653 NdbNodeBitmask c_sub_startstop_lock;
4654
4655 Uint32 get_default_fragments(Signal*, Uint32 extra_nodegroups = 0);
4656 void wait_gcp(Signal* signal, SchemaOpPtr op_ptr, Uint32 flags);
4657
4658 void block_substartstop(Signal* signal, SchemaOpPtr op_ptr);
4659 void unblock_substartstop();
4660 void wait_substartstop(Signal* signal, Uint32 opPtrI);
4661
4662 void upgrade_seizeTrigger(Ptr<TableRecord> tabPtr, Uint32, Uint32, Uint32);
4663
4664 void send_event(Signal*, SchemaTransPtr&,
4665 Uint32 ev,
4666 Uint32 id,
4667 Uint32 version,
4668 Uint32 type);
4669
4670 void startNextGetTabInfoReq(Signal*);
4671
4672 protected:
4673 virtual bool getParam(const char * param, Uint32 * retVal);
4674 private:
4675 ArenaAllocator c_arenaAllocator;
4676 Uint32 c_noOfMetaTables;
4677 Uint32 c_default_hashmap_size;
4678 };
4679
4680 inline bool
isTable() const4681 Dbdict::TableRecord::isTable() const
4682 {
4683 return DictTabInfo::isTable(tableType);
4684 }
4685
4686 inline bool
isIndex() const4687 Dbdict::TableRecord::isIndex() const
4688 {
4689 return DictTabInfo::isIndex(tableType);
4690 }
4691
4692 inline bool
isUniqueIndex() const4693 Dbdict::TableRecord::isUniqueIndex() const
4694 {
4695 return DictTabInfo::isUniqueIndex(tableType);
4696 }
4697
4698 inline bool
isNonUniqueIndex() const4699 Dbdict::TableRecord::isNonUniqueIndex() const
4700 {
4701 return DictTabInfo::isNonUniqueIndex(tableType);
4702 }
4703
4704 inline bool
isHashIndex() const4705 Dbdict::TableRecord::isHashIndex() const
4706 {
4707 return DictTabInfo::isHashIndex(tableType);
4708 }
4709
4710 inline bool
isOrderedIndex() const4711 Dbdict::TableRecord::isOrderedIndex() const
4712 {
4713 return DictTabInfo::isOrderedIndex(tableType);
4714 }
4715
4716 // quilt keeper
4717
4718 #undef JAM_FILE_ID
4719
4720 #endif
4721