/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DBDICT_H #define DBDICT_H /** * Dict : Dictionary Block */ #include <ndb_limits.h> #include <trigger_definitions.h> #include <pc.hpp> #include <DLHashTable.hpp> #include <DLFifoList.hpp> #include <CArray.hpp> #include <KeyTable.hpp> #include <KeyTable2.hpp> #include <KeyTable2Ref.hpp> #include <SimulatedBlock.hpp> #include <SimpleProperties.hpp> #include <SignalCounter.hpp> #include <Bitmask.hpp> #include <AttributeList.hpp> #include <signaldata/GetTableId.hpp> #include <signaldata/GetTabInfo.hpp> #include <signaldata/DictTabInfo.hpp> #include <signaldata/CreateTable.hpp> #include <signaldata/CreateTab.hpp> #include <signaldata/DropTable.hpp> #include <signaldata/AlterTable.hpp> #include <signaldata/AlterTab.hpp> #include <signaldata/CreateIndx.hpp> #include <signaldata/DropIndx.hpp> #include <signaldata/AlterIndx.hpp> #include <signaldata/BuildIndx.hpp> #include <signaldata/UtilPrepare.hpp> #include <signaldata/CreateEvnt.hpp> #include <signaldata/CreateTrig.hpp> #include <signaldata/DropTrig.hpp> #include <signaldata/AlterTrig.hpp> #include <signaldata/DictLock.hpp> #include "SchemaFile.hpp" #include <blocks/mutexes.hpp> #include <SafeCounter.hpp> #include <RequestTracker.hpp> #include <Rope.hpp> #include <signaldata/DictObjOp.hpp> #include <signaldata/DropFilegroupImpl.hpp> #include <SLList.hpp> #ifdef DBDICT_C // Debug Macros /*--------------------------------------------------------------*/ // Constants for CONTINUEB /*--------------------------------------------------------------*/ #define ZPACK_TABLE_INTO_PAGES 0 #define ZSEND_GET_TAB_RESPONSE 3 #define ZDICT_LOCK_POLL 4 /*--------------------------------------------------------------*/ // Other constants in alphabetical order /*--------------------------------------------------------------*/ #define ZNOMOREPHASES 255 /*--------------------------------------------------------------*/ // Schema file defines /*--------------------------------------------------------------*/ #define ZSCHEMA_WORDS 4 /*--------------------------------------------------------------*/ // Page constants /*--------------------------------------------------------------*/ #define ZBAT_SCHEMA_FILE 0 //Variable number of page for NDBFS #define ZBAT_TABLE_FILE 1 //Variable number of page for NDBFS #define ZPAGE_HEADER_SIZE 32 #define ZPOS_PAGE_SIZE 16 #define ZPOS_CHECKSUM 17 #define ZPOS_VERSION 18 #define ZPOS_PAGE_HEADER_SIZE 19 /*--------------------------------------------------------------*/ // Size constants /*--------------------------------------------------------------*/ #define ZFS_CONNECT_SIZE 4 #define ZSIZE_OF_PAGES_IN_WORDS 8192 #define ZLOG_SIZE_OF_PAGES_IN_WORDS 13 #define ZMAX_PAGES_OF_TABLE_DEFINITION 8 #define ZNUMBER_OF_PAGES (ZMAX_PAGES_OF_TABLE_DEFINITION + 1) #define ZNO_OF_FRAGRECORD 5 /*--------------------------------------------------------------*/ // Error codes /*--------------------------------------------------------------*/ #define ZNODE_FAILURE_ERROR 704 #endif /** * Systable NDB$EVENTS_0 */ #define EVENT_SYSTEM_TABLE_LENGTH 8 struct sysTab_NDBEVENTS_0 { char NAME[MAX_TAB_NAME_SIZE]; Uint32 EVENT_TYPE; Uint32 TABLEID; Uint32 TABLEVERSION; char TABLE_NAME[MAX_TAB_NAME_SIZE]; Uint32 ATTRIBUTE_MASK[MAXNROFATTRIBUTESINWORDS]; Uint32 SUBID; Uint32 SUBKEY; }; /** * DICT - This blocks handles all metadata */ class Dbdict: public SimulatedBlock { public: /* * 2.3 RECORD AND FILESIZES */ /** * Table attributes. Permanent data. * * Indexes have an attribute list which duplicates primary table * attributes. This is wrong but convenient. */ struct AttributeRecord { AttributeRecord(){} /* attribute id */ Uint16 attributeId; /* Attribute number within tuple key (counted from 1) */ Uint16 tupleKey; /* Attribute name (unique within table) */ RopeHandle attributeName; /* Attribute description (old-style packed descriptor) */ Uint32 attributeDescriptor; /* Extended attributes */ Uint32 extType; Uint32 extPrecision; Uint32 extScale; Uint32 extLength; /* Autoincrement flag, only for ODBC/SQL */ bool autoIncrement; /* Default value as null-terminated string, only for ODBC/SQL */ RopeHandle defaultValue; struct { Uint32 m_name_len; const char * m_name_ptr; RopePool * m_pool; } m_key; union { Uint32 nextPool; Uint32 nextList; }; Uint32 prevList; Uint32 nextHash; Uint32 prevHash; Uint32 hashValue() const { return attributeName.hashValue();} bool equal(const AttributeRecord& obj) const { if(obj.hashValue() == hashValue()){ ConstRope r(* m_key.m_pool, obj.attributeName); return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0; } return false; } /** Singly linked in internal (attributeId) order */ // TODO use DL template when possible to have more than 1 Uint32 nextAttributeIdPtrI; }; typedef Ptr<AttributeRecord> AttributeRecordPtr; ArrayPool<AttributeRecord> c_attributeRecordPool; DLHashTable<AttributeRecord> c_attributeRecordHash; /** * Shared table / index record. Most of this is permanent data stored * on disk. Index trigger ids are volatile. */ struct TableRecord { TableRecord(){} Uint32 maxRowsLow; Uint32 maxRowsHigh; /* Table id (array index in DICT and other blocks) */ Uint32 tableId; Uint32 m_obj_ptr_i; /* Table version (incremented when tableId is re-used) */ Uint32 tableVersion; /* Table name (may not be unique under "alter table") */ RopeHandle tableName; /* Type of table or index */ DictTabInfo::TableType tableType; /* Is table or index online (this flag is not used in DICT) */ bool online; /* Primary table of index otherwise RNIL */ Uint32 primaryTableId; /* Type of fragmentation (small/medium/large) */ DictTabInfo::FragmentType fragmentType; /* Global checkpoint identity when table created */ Uint32 gciTableCreated; /* Is the table logged (i.e. data survives system restart) */ enum Bits { TR_Logged = 0x1, TR_RowGCI = 0x2, TR_RowChecksum = 0x4 }; Uint16 m_bits; /* Number of attibutes in table */ Uint16 noOfAttributes; /* Number of null attributes in table (should be computed) */ Uint16 noOfNullAttr; /* Number of primary key attributes (should be computed) */ Uint16 noOfPrimkey; /* Length of primary key in words (should be computed) */ /* For ordered index this is tree node size in words */ Uint16 tupKeyLength; /** */ Uint16 noOfCharsets; /* K value for LH**3 algorithm (only 6 allowed currently) */ Uint8 kValue; /* Local key length in words (currently 1) */ Uint8 localKeyLen; /* * Parameter for hash algorithm that specifies the load factor in * percentage of fill level in buckets. A high value means we are * splitting early and that buckets are only lightly used. A high * value means that we have fill the buckets more and get more * likelihood of overflow buckets. */ Uint8 maxLoadFactor; /* Flag to indicate default number of partitions */ bool defaultNoPartFlag; /* Flag to indicate using linear hash function */ bool linearHashFlag; /* * Used when shrinking to decide when to merge buckets. Hysteresis * is thus possible. Should be smaller but not much smaller than * maxLoadFactor */ Uint8 minLoadFactor; /* Convenience routines */ bool isTable() const; bool isIndex() const; bool isUniqueIndex() const; bool isNonUniqueIndex() const; bool isHashIndex() const; bool isOrderedIndex() const; /**************************************************** * Support variables for table handling ****************************************************/ /* Active page which is sent to disk */ Uint32 activePage; /** File pointer received from disk */ Uint32 filePtr[2]; /** Pointer to first attribute in table */ DLFifoList<AttributeRecord>::Head m_attributes; /* Pointer to first page of table description */ Uint32 firstPage; Uint32 nextPool; enum TabState { NOT_DEFINED = 0, REORG_TABLE_PREPARED = 1, DEFINING = 2, CHECKED = 3, DEFINED = 4, PREPARE_DROPPING = 5, DROPPING = 6, BACKUP_ONGOING = 7 }; TabState tabState; /* State when returning from TC_SCHVERREQ */ enum TabReturnState { TRS_IDLE = 0, ADD_TABLE = 1, SLAVE_SYSTEM_RESTART = 2, MASTER_SYSTEM_RESTART = 3 }; TabReturnState tabReturnState; /** Number of words */ Uint32 packedSize; /** Index state (volatile data) */ enum IndexState { IS_UNDEFINED = 0, // initial IS_OFFLINE = 1, // index table created IS_BUILDING = 2, // building (local state) IS_DROPPING = 3, // dropping (local state) IS_ONLINE = 4, // online IS_BROKEN = 9 // build or drop aborted }; IndexState indexState; /** Trigger ids of index (volatile data) */ Uint32 insertTriggerId; Uint32 updateTriggerId; Uint32 deleteTriggerId; Uint32 customTriggerId; // ordered index Uint32 buildTriggerId; // temp during build /** Index state in other blocks on this node */ enum IndexLocal { IL_CREATED_TC = 1 << 0 // created in TC }; Uint32 indexLocal; Uint32 noOfNullBits; /** frm data for this table */ RopeHandle frmData; RopeHandle tsData; RopeHandle ngData; RopeHandle rangeData; Uint32 fragmentCount; Uint32 m_tablespace_id; }; typedef Ptr<TableRecord> TableRecordPtr; ArrayPool<TableRecord> c_tableRecordPool; /** Node Group and Tablespace id+version + range or list data. * This is only stored temporarily in DBDICT during an ongoing * change. * TODO RONM: Look into improvements of this */ Uint32 c_fragDataLen; Uint16 c_fragData[MAX_NDB_PARTITIONS]; Uint32 c_tsIdData[2*MAX_NDB_PARTITIONS]; /** * Triggers. This is volatile data not saved on disk. Setting a * trigger online creates the trigger in TC (if index) and LQH-TUP. */ struct TriggerRecord { TriggerRecord() {} /** Trigger state */ enum TriggerState { TS_NOT_DEFINED = 0, TS_DEFINING = 1, TS_OFFLINE = 2, // created globally in DICT TS_BUILDING = 3, TS_DROPPING = 4, TS_ONLINE = 5 // activated globally }; TriggerState triggerState; /** Trigger state in other blocks on this node */ enum IndexLocal { TL_CREATED_TC = 1 << 0, // created in TC TL_CREATED_LQH = 1 << 1 // created in LQH-TUP }; Uint32 triggerLocal; /** Trigger name, used by DICT to identify the trigger */ RopeHandle triggerName; /** Trigger id, used by TRIX, TC, LQH, and TUP to identify the trigger */ Uint32 triggerId; Uint32 m_obj_ptr_i; /** Table id, the table the trigger is defined on */ Uint32 tableId; /** Trigger type, defines what the trigger is used for */ TriggerType::Value triggerType; /** Trigger action time, defines when the trigger should fire */ TriggerActionTime::Value triggerActionTime; /** Trigger event, defines what events the trigger should monitor */ TriggerEvent::Value triggerEvent; /** Monitor all replicas */ bool monitorReplicas; /** Monitor all, the trigger monitors changes of all attributes in table */ bool monitorAllAttributes; /** Monitor all, the trigger monitors changes of all attributes in table */ bool reportAllMonitoredAttributes; /** * Attribute mask, defines what attributes are to be monitored. * Can be seen as a compact representation of SQL column name list. */ AttributeMask attributeMask; /** Index id, only used by secondary_index triggers */ Uint32 indexId; /** Pointer to the next attribute used by ArrayPool */ Uint32 nextPool; }; Uint32 c_maxNoOfTriggers; typedef Ptr<TriggerRecord> TriggerRecordPtr; ArrayPool<TriggerRecord> c_triggerRecordPool; /** * Information for each FS connection. ***************************************************************************/ struct FsConnectRecord { enum FsState { IDLE = 0, OPEN_WRITE_SCHEMA = 1, WRITE_SCHEMA = 2, CLOSE_WRITE_SCHEMA = 3, OPEN_READ_SCHEMA1 = 4, OPEN_READ_SCHEMA2 = 5, READ_SCHEMA1 = 6, READ_SCHEMA2 = 7, CLOSE_READ_SCHEMA = 8, OPEN_READ_TAB_FILE1 = 9, OPEN_READ_TAB_FILE2 = 10, READ_TAB_FILE1 = 11, READ_TAB_FILE2 = 12, CLOSE_READ_TAB_FILE = 13, OPEN_WRITE_TAB_FILE = 14, WRITE_TAB_FILE = 15, CLOSE_WRITE_TAB_FILE = 16 }; /** File Pointer for this file system connection */ Uint32 filePtr; /** Reference of owner record */ Uint32 ownerPtr; /** State of file system connection */ FsState fsState; /** Used by Array Pool for free list handling */ Uint32 nextPool; }; typedef Ptr<FsConnectRecord> FsConnectRecordPtr; ArrayPool<FsConnectRecord> c_fsConnectRecordPool; /** * This record stores all the information about a node and all its attributes ***************************************************************************/ struct NodeRecord { enum NodeState { API_NODE = 0, NDB_NODE_ALIVE = 1, NDB_NODE_DEAD = 2 }; bool hotSpare; NodeState nodeState; }; typedef Ptr<NodeRecord> NodeRecordPtr; CArray<NodeRecord> c_nodes; NdbNodeBitmask c_aliveNodes; struct PageRecord { Uint32 word[8192]; }; typedef Ptr<PageRecord> PageRecordPtr; CArray<PageRecord> c_pageRecordArray; struct SchemaPageRecord { Uint32 word[NDB_SF_PAGE_SIZE_IN_WORDS]; }; CArray<SchemaPageRecord> c_schemaPageRecordArray; DictTabInfo::Table c_tableDesc; /** * A page for create index table signal. */ PageRecord c_indexPage; struct File { File() {} Uint32 key; Uint32 m_magic; Uint32 m_version; Uint32 m_obj_ptr_i; Uint32 m_filegroup_id; Uint32 m_type; Uint64 m_file_size; Uint64 m_file_free; RopeHandle m_path; Uint32 nextList; union { Uint32 prevList; Uint32 nextPool; }; Uint32 nextHash, prevHash; Uint32 hashValue() const { return key;} bool equal(const File& obj) const { return key == obj.key;} }; typedef Ptr<File> FilePtr; typedef RecordPool<File, RWPool> File_pool; typedef DLListImpl<File_pool, File> File_list; typedef LocalDLListImpl<File_pool, File> Local_file_list; typedef KeyTableImpl<File_pool, File> File_hash; struct Filegroup { Filegroup(){} Uint32 key; Uint32 m_obj_ptr_i; Uint32 m_magic; Uint32 m_type; Uint32 m_version; RopeHandle m_name; union { struct { Uint32 m_extent_size; Uint32 m_default_logfile_group_id; } m_tablespace; struct { Uint32 m_undo_buffer_size; File_list::HeadPOD m_files; } m_logfilegroup; }; union { Uint32 nextPool; Uint32 nextList; Uint32 nextHash; }; Uint32 prevHash; Uint32 hashValue() const { return key;} bool equal(const Filegroup& obj) const { return key == obj.key;} }; typedef Ptr<Filegroup> FilegroupPtr; typedef RecordPool<Filegroup, RWPool> Filegroup_pool; typedef KeyTableImpl<Filegroup_pool, Filegroup> Filegroup_hash; File_pool c_file_pool; Filegroup_pool c_filegroup_pool; File_hash c_file_hash; Filegroup_hash c_filegroup_hash; RopePool c_rope_pool; struct DictObject { DictObject() {} Uint32 m_id; Uint32 m_type; Uint32 m_ref_count; RopeHandle m_name; union { struct { Uint32 m_name_len; const char * m_name_ptr; RopePool * m_pool; } m_key; Uint32 nextPool; Uint32 nextList; }; Uint32 nextHash; Uint32 prevHash; Uint32 hashValue() const { return m_name.hashValue();} bool equal(const DictObject& obj) const { if(obj.hashValue() == hashValue()){ ConstRope r(* m_key.m_pool, obj.m_name); return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0; } return false; } }; DLHashTable<DictObject> c_obj_hash; // Name ArrayPool<DictObject> c_obj_pool; DictObject * get_object(const char * name){ return get_object(name, strlen(name) + 1); } DictObject * get_object(const char * name, Uint32 len){ return get_object(name, len, Rope::hash(name, len)); } DictObject * get_object(const char * name, Uint32 len, Uint32 hash); void release_object(Uint32 obj_ptr_i){ release_object(obj_ptr_i, c_obj_pool.getPtr(obj_ptr_i)); } void release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p); void increase_ref_count(Uint32 obj_ptr_i); void decrease_ref_count(Uint32 obj_ptr_i); public: Dbdict(Block_context& ctx); virtual ~Dbdict(); private: BLOCK_DEFINES(Dbdict); // Signal receivers void execDICTSTARTREQ(Signal* signal); void execGET_TABINFOREQ(Signal* signal); void execGET_TABLEDID_REQ(Signal* signal); void execGET_TABINFO_REF(Signal* signal); void execGET_TABINFO_CONF(Signal* signal); void execCONTINUEB(Signal* signal); void execDUMP_STATE_ORD(Signal* signal); void execHOT_SPAREREP(Signal* signal); void execDIADDTABCONF(Signal* signal); void execDIADDTABREF(Signal* signal); void execTAB_COMMITCONF(Signal* signal); void execTAB_COMMITREF(Signal* signal); void execGET_SCHEMA_INFOREQ(Signal* signal); void execSCHEMA_INFO(Signal* signal); void execSCHEMA_INFOCONF(Signal* signal); void execREAD_NODESCONF(Signal* signal); void execFSCLOSECONF(Signal* signal); void execFSOPENCONF(Signal* signal); void execFSOPENREF(Signal* signal); void execFSREADCONF(Signal* signal); void execFSREADREF(Signal* signal); void execFSWRITECONF(Signal* signal); void execNDB_STTOR(Signal* signal); void execREAD_CONFIG_REQ(Signal* signal); void execSTTOR(Signal* signal); void execTC_SCHVERCONF(Signal* signal); void execNODE_FAILREP(Signal* signal); void execINCL_NODEREQ(Signal* signal); void execAPI_FAILREQ(Signal* signal); void execWAIT_GCP_REF(Signal* signal); void execWAIT_GCP_CONF(Signal* signal); void execLIST_TABLES_REQ(Signal* signal); // Index signals void execCREATE_INDX_REQ(Signal* signal); void execCREATE_INDX_CONF(Signal* signal); void execCREATE_INDX_REF(Signal* signal); void execALTER_INDX_REQ(Signal* signal); void execALTER_INDX_CONF(Signal* signal); void execALTER_INDX_REF(Signal* signal); void execCREATE_TABLE_CONF(Signal* signal); void execCREATE_TABLE_REF(Signal* signal); void execDROP_INDX_REQ(Signal* signal); void execDROP_INDX_CONF(Signal* signal); void execDROP_INDX_REF(Signal* signal); void execDROP_TABLE_CONF(Signal* signal); void execDROP_TABLE_REF(Signal* signal); void execBUILDINDXREQ(Signal* signal); void execBUILDINDXCONF(Signal* signal); void execBUILDINDXREF(Signal* signal); void execBACKUP_FRAGMENT_REQ(Signal*); // Util signals used by Event code void execUTIL_PREPARE_CONF(Signal* signal); void execUTIL_PREPARE_REF (Signal* signal); void execUTIL_EXECUTE_CONF(Signal* signal); void execUTIL_EXECUTE_REF (Signal* signal); void execUTIL_RELEASE_CONF(Signal* signal); void execUTIL_RELEASE_REF (Signal* signal); // Event signals from API void execCREATE_EVNT_REQ (Signal* signal); void execCREATE_EVNT_CONF(Signal* signal); void execCREATE_EVNT_REF (Signal* signal); void execDROP_EVNT_REQ (Signal* signal); void execSUB_START_REQ (Signal* signal); void execSUB_START_CONF (Signal* signal); void execSUB_START_REF (Signal* signal); void execSUB_STOP_REQ (Signal* signal); void execSUB_STOP_CONF (Signal* signal); void execSUB_STOP_REF (Signal* signal); // Event signals from SUMA void execCREATE_SUBID_CONF(Signal* signal); void execCREATE_SUBID_REF (Signal* signal); void execSUB_CREATE_CONF(Signal* signal); void execSUB_CREATE_REF (Signal* signal); void execSUB_REMOVE_REQ(Signal* signal); void execSUB_REMOVE_CONF(Signal* signal); void execSUB_REMOVE_REF(Signal* signal); // Trigger signals void execCREATE_TRIG_REQ(Signal* signal); void execCREATE_TRIG_CONF(Signal* signal); void execCREATE_TRIG_REF(Signal* signal); void execALTER_TRIG_REQ(Signal* signal); void execALTER_TRIG_CONF(Signal* signal); void execALTER_TRIG_REF(Signal* signal); void execDROP_TRIG_REQ(Signal* signal); void execDROP_TRIG_CONF(Signal* signal); void execDROP_TRIG_REF(Signal* signal); void execDROP_TABLE_REQ(Signal* signal); void execPREP_DROP_TAB_REQ(Signal* signal); void execPREP_DROP_TAB_REF(Signal* signal); void execPREP_DROP_TAB_CONF(Signal* signal); void execDROP_TAB_REQ(Signal* signal); void execDROP_TAB_REF(Signal* signal); void execDROP_TAB_CONF(Signal* signal); void execCREATE_TABLE_REQ(Signal* signal); void execALTER_TABLE_REQ(Signal* signal); void execCREATE_FRAGMENTATION_REF(Signal*); void execCREATE_FRAGMENTATION_CONF(Signal*); void execCREATE_TAB_REQ(Signal* signal); void execADD_FRAGREQ(Signal* signal); void execLQHFRAGREF(Signal* signal); void execLQHFRAGCONF(Signal* signal); void execLQHADDATTREF(Signal* signal); void execLQHADDATTCONF(Signal* signal); void execCREATE_TAB_REF(Signal* signal); void execCREATE_TAB_CONF(Signal* signal); void execALTER_TAB_REQ(Signal* signal); void execALTER_TAB_REF(Signal* signal); void execALTER_TAB_CONF(Signal* signal); bool check_ndb_versions() const; void execCREATE_FILE_REQ(Signal* signal); void execCREATE_FILEGROUP_REQ(Signal* signal); void execDROP_FILE_REQ(Signal* signal); void execDROP_FILEGROUP_REQ(Signal* signal); // Internal void execCREATE_FILE_REF(Signal* signal); void execCREATE_FILE_CONF(Signal* signal); void execCREATE_FILEGROUP_REF(Signal* signal); void execCREATE_FILEGROUP_CONF(Signal* signal); void execDROP_FILE_REF(Signal* signal); void execDROP_FILE_CONF(Signal* signal); void execDROP_FILEGROUP_REF(Signal* signal); void execDROP_FILEGROUP_CONF(Signal* signal); void execDICT_LOCK_REQ(Signal* signal); void execDICT_UNLOCK_ORD(Signal* signal); /* * 2.4 COMMON STORED VARIABLES */ /** * This record stores all the state needed * when the schema page is being sent to other nodes ***************************************************************************/ struct SendSchemaRecord { /** Number of words of schema data */ Uint32 noOfWords; /** Page Id of schema data */ Uint32 pageId; Uint32 nodeId; SignalCounter m_SCHEMAINFO_Counter; Uint32 noOfWordsCurrentlySent; Uint32 noOfSignalsSentSinceDelay; bool inUse; }; SendSchemaRecord c_sendSchemaRecord; /** * This record stores all the state needed * when a table file is being read from disk ****************************************************************************/ struct ReadTableRecord { /** Number of Pages */ Uint32 no_of_words; /** Page Id*/ Uint32 pageId; /** Table Id of read table */ Uint32 tableId; bool inUse; Callback m_callback; }; ReadTableRecord c_readTableRecord; /** * This record stores all the state needed * when a table file is being written to disk ****************************************************************************/ struct WriteTableRecord { /** Number of Pages */ Uint32 no_of_words; /** Page Id*/ Uint32 pageId; /** Table Files Handled, local state variable */ Uint32 noOfTableFilesHandled; /** Table Id of written table */ Uint32 tableId; /** State, indicates from where it was called */ enum TableWriteState { IDLE = 0, WRITE_ADD_TABLE_MASTER = 1, WRITE_ADD_TABLE_SLAVE = 2, WRITE_RESTART_FROM_MASTER = 3, WRITE_RESTART_FROM_OWN = 4, TWR_CALLBACK = 5 }; TableWriteState tableWriteState; Callback m_callback; }; WriteTableRecord c_writeTableRecord; /** * This record stores all the state needed * when a schema file is being read from disk ****************************************************************************/ struct ReadSchemaRecord { /** Page Id of schema page */ Uint32 pageId; /** First page to read */ Uint32 firstPage; /** Number of pages to read */ Uint32 noOfPages; /** State, indicates from where it was called */ enum SchemaReadState { IDLE = 0, INITIAL_READ_HEAD = 1, INITIAL_READ = 2 }; SchemaReadState schemaReadState; }; ReadSchemaRecord c_readSchemaRecord; /** * This record stores all the state needed * when a schema file is being written to disk ****************************************************************************/ struct WriteSchemaRecord { /** Page Id of schema page */ Uint32 pageId; /** Rewrite entire file */ Uint32 newFile; /** First page to write */ Uint32 firstPage; /** Number of pages to write */ Uint32 noOfPages; /** Schema Files Handled, local state variable */ Uint32 noOfSchemaFilesHandled; bool inUse; Callback m_callback; }; WriteSchemaRecord c_writeSchemaRecord; /** * This record stores all the information needed * when a file is being read from disk ****************************************************************************/ struct RestartRecord { /** Global check point identity */ Uint32 gciToRestart; /** The active table at restart process */ Uint32 activeTable; /** The active table at restart process */ BlockReference returnBlockRef; Uint32 m_pass; // 0 tablespaces/logfilegroups, 1 tables, 2 indexes }; RestartRecord c_restartRecord; /** * This record stores all the information needed * when a file is being read from disk ****************************************************************************/ struct RetrieveRecord { RetrieveRecord(){ noOfWaiters = 0;} /** Only one retrieve table definition at a time */ bool busyState; /** * No of waiting in time queue */ Uint32 noOfWaiters; /** Block Reference of retriever */ BlockReference blockRef; /** Id of retriever */ Uint32 m_senderData; /** Table id of retrieved table */ Uint32 tableId; Uint32 m_table_type; /** Starting page to retrieve data from */ Uint32 retrievePage; /** Number of pages retrieved */ Uint32 retrievedNoOfPages; /** Number of words retrieved */ Uint32 retrievedNoOfWords; /** Number of words sent currently */ Uint32 currentSent; /** * Long signal stuff */ bool m_useLongSig; }; RetrieveRecord c_retrieveRecord; /** * This record stores all the information needed * when a file is being read from disk * * This is the info stored in one entry of the schema * page. Each table has 4 words of info. * Word 1: Schema version (upper 16 bits) * Table State (lower 16 bits) * Word 2: Number of pages of table description * Word 3: Global checkpoint id table was created * Word 4: Currently zero ****************************************************************************/ struct SchemaRecord { /** Schema file first page (0) */ Uint32 schemaPage; /** Old Schema file first page (used at node restart) */ Uint32 oldSchemaPage; Callback m_callback; }; SchemaRecord c_schemaRecord; /* * Schema file, list of schema pages. Use an array until a pool * exists and NDBFS interface can use it. */ struct XSchemaFile { SchemaFile* schemaPage; Uint32 noOfPages; }; // 0-normal 1-old XSchemaFile c_schemaFile[2]; void initSchemaFile(XSchemaFile *, Uint32 firstPage, Uint32 lastPage, bool initEntries); void resizeSchemaFile(XSchemaFile * xsf, Uint32 noOfPages); void computeChecksum(XSchemaFile *, Uint32 pageNo); bool validateChecksum(const XSchemaFile *); SchemaFile::TableEntry * getTableEntry(XSchemaFile *, Uint32 tableId); Uint32 computeChecksum(const Uint32 * src, Uint32 len); /* ----------------------------------------------------------------------- */ // Node References /* ----------------------------------------------------------------------- */ Uint16 c_masterNodeId; /* ----------------------------------------------------------------------- */ // Various current system properties /* ----------------------------------------------------------------------- */ Uint16 c_numberNode; Uint16 c_noHotSpareNodes; Uint16 c_noNodesFailed; Uint32 c_failureNr; /* ----------------------------------------------------------------------- */ // State variables /* ----------------------------------------------------------------------- */ #ifndef ndb_dbdict_log_block_state enum BlockState { BS_IDLE = 0, BS_CREATE_TAB = 1, BS_BUSY = 2, BS_NODE_FAILURE = 3, BS_NODE_RESTART = 4 }; #else // quick hack to log changes enum { BS_IDLE = 0, BS_CREATE_TAB = 1, BS_BUSY = 2, BS_NODE_FAILURE = 3, BS_NODE_RESTART = 4 }; struct BlockState; friend struct BlockState; struct BlockState { BlockState() : m_value(BS_IDLE) { } BlockState(int value) : m_value(value) { } operator int() const { return m_value; } BlockState& operator=(const BlockState& bs) { Dbdict* dict = (Dbdict*)globalData.getBlock(DBDICT); dict->infoEvent("DICT: bs %d->%d", m_value, bs.m_value); globalSignalLoggers.log(DBDICT, "bs %d->%d", m_value, bs.m_value); m_value = bs.m_value; return *this; } int m_value; }; #endif BlockState c_blockState; struct PackTable { enum PackTableState { PTS_IDLE = 0, PTS_GET_TAB = 3 } m_state; } c_packTable; Uint32 c_startPhase; Uint32 c_restartType; bool c_initialStart; bool c_systemRestart; bool c_nodeRestart; bool c_initialNodeRestart; Uint32 c_tabinfoReceived; /** * Temporary structure used when parsing table info */ struct ParseDictTabInfoRecord { DictTabInfo::RequestType requestType; Uint32 errorCode; Uint32 errorLine; SimpleProperties::UnpackStatus status; Uint32 errorKey; TableRecordPtr tablePtr; }; // Operation records /** * Common part of operation records. Uses KeyTable2. Note that each * seize/release invokes ctor/dtor automatically. */ struct OpRecordCommon { Uint32 key; // key shared between master and slaves Uint32 nextHash; Uint32 prevHash; Uint32 hashValue() const { return key; } bool equal(const OpRecordCommon& rec) const { return key == rec.key; } }; /** * Create table record */ struct CreateTableRecord : OpRecordCommon { Uint32 m_senderRef; Uint32 m_senderData; Uint32 m_coordinatorRef; Uint32 m_errorCode; void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;} // For alter table Uint32 m_changeMask; bool m_alterTableFailed; AlterTableRef m_alterTableRef; Uint32 m_alterTableId; /* Previous table name (used for reverting failed table rename) */ char previousTableName[MAX_TAB_NAME_SIZE]; /* Previous table definition, frm (used for reverting) */ /** TODO Could preferrably be made dynamic size */ Uint32 previousFrmLen; char previousFrmData[MAX_FRM_DATA_SIZE]; Uint32 m_tablePtrI; Uint32 m_tabInfoPtrI; Uint32 m_fragmentsPtrI; Uint32 m_dihAddFragPtr; // Connect ptr towards DIH Uint32 m_lqhFragPtr; // Connect ptr towards LQH Callback m_callback; // Who's using local create tab MutexHandle2<DIH_START_LCP_MUTEX> m_startLcpMutex; struct CoordinatorData { Uint32 m_gsn; SafeCounterHandle m_counter; CreateTabReq::RequestType m_requestType; } m_coordinatorData; }; typedef Ptr<CreateTableRecord> CreateTableRecordPtr; /** * Drop table record */ struct DropTableRecord : OpRecordCommon { DropTableReq m_request; Uint32 m_requestType; Uint32 m_coordinatorRef; Uint32 m_errorCode; void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;} MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex; /** * When sending stuff around */ struct CoordinatorData { Uint32 m_gsn; Uint32 m_block; SignalCounter m_signalCounter; } m_coordinatorData; struct ParticipantData { Uint32 m_gsn; Uint32 m_block; SignalCounter m_signalCounter; Callback m_callback; } m_participantData; }; typedef Ptr<DropTableRecord> DropTableRecordPtr; /** * Request flags passed in signals along with request type and * propagated across operations. */ struct RequestFlag { enum { RF_LOCAL = 1 << 0, // create on local node only RF_NOBUILD = 1 << 1, // no need to build index RF_NOTCTRIGGER = 1 << 2, // alter trigger: no trigger in TC RF_FORCE = 1 << 4 // force drop }; }; /** * Operation record for create index. */ struct OpCreateIndex : OpRecordCommon { // original request (index id will be added) CreateIndxReq m_request; AttributeList m_attrList; char m_indexName[MAX_TAB_NAME_SIZE]; bool m_storedIndex; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; // state info CreateIndxReq::RequestType m_requestType; Uint32 m_requestFlag; // error info CreateIndxRef::ErrorCode m_lastError; CreateIndxRef::ErrorCode m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // counters SignalCounter m_signalCounter; // ctor OpCreateIndex() { memset(&m_request, 0, sizeof(m_request)); m_coordinatorRef = 0; m_requestType = CreateIndxReq::RT_UNDEFINED; m_requestFlag = 0; m_lastError = CreateIndxRef::NoError; m_errorCode = CreateIndxRef::NoError; m_errorLine = 0; m_errorNode = 0; } void save(const CreateIndxReq* req) { m_request = *req; m_requestType = req->getRequestType(); m_requestFlag = req->getRequestFlag(); } bool hasLastError() { return m_lastError != CreateIndxRef::NoError; } bool hasError() { return m_errorCode != CreateIndxRef::NoError; } void setError(const CreateIndxRef* ref) { m_lastError = CreateIndxRef::NoError; if (ref != 0) { m_lastError = ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const CreateTableRef* ref) { m_lastError = CreateIndxRef::NoError; if (ref != 0) { switch (ref->getErrorCode()) { case CreateTableRef::TableAlreadyExist: m_lastError = CreateIndxRef::IndexExists; break; default: m_lastError = (CreateIndxRef::ErrorCode)ref->getErrorCode(); break; } if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); } } } void setError(const AlterIndxRef* ref) { m_lastError = CreateIndxRef::NoError; if (ref != 0) { m_lastError = (CreateIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } }; typedef Ptr<OpCreateIndex> OpCreateIndexPtr; /** * Operation record for drop index. */ struct OpDropIndex : OpRecordCommon { // original request DropIndxReq m_request; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; // state info DropIndxReq::RequestType m_requestType; Uint32 m_requestFlag; // error info DropIndxRef::ErrorCode m_lastError; DropIndxRef::ErrorCode m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // counters SignalCounter m_signalCounter; // ctor OpDropIndex() { memset(&m_request, 0, sizeof(m_request)); m_coordinatorRef = 0; m_requestType = DropIndxReq::RT_UNDEFINED; m_requestFlag = 0; m_lastError = DropIndxRef::NoError; m_errorCode = DropIndxRef::NoError; m_errorLine = 0; m_errorNode = 0; } void save(const DropIndxReq* req) { m_request = *req; m_requestType = req->getRequestType(); m_requestFlag = req->getRequestFlag(); } bool hasLastError() { return m_lastError != DropIndxRef::NoError; } bool hasError() { return m_errorCode != DropIndxRef::NoError; } void setError(const DropIndxRef* ref) { m_lastError = DropIndxRef::NoError; if (ref != 0) { m_lastError = ref->getErrorCode(); if (! hasError()) { m_errorCode = ref->getErrorCode(); m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const AlterIndxRef* ref) { m_lastError = DropIndxRef::NoError; if (ref != 0) { m_lastError = (DropIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const DropTableRef* ref) { m_lastError = DropIndxRef::NoError; if (ref != 0) { switch (ref->errorCode) { case DropTableRef::Busy: m_lastError = DropIndxRef::Busy; break; case DropTableRef::NoSuchTable: m_lastError = DropIndxRef::IndexNotFound; break; case DropTableRef::DropInProgress: m_lastError = DropIndxRef::Busy; break; case DropTableRef::NoDropTableRecordAvailable: m_lastError = DropIndxRef::Busy; break; default: m_lastError = (DropIndxRef::ErrorCode)ref->errorCode; break; } if (! hasError()) { m_errorCode = m_lastError; m_errorLine = 0; m_errorNode = 0; } } } }; typedef Ptr<OpDropIndex> OpDropIndexPtr; /** * Operation record for alter index. */ struct OpAlterIndex : OpRecordCommon { // original request plus buffer for attribute lists AlterIndxReq m_request; AttributeList m_attrList; AttributeList m_tableKeyList; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; // state info AlterIndxReq::RequestType m_requestType; Uint32 m_requestFlag; // error info AlterIndxRef::ErrorCode m_lastError; AlterIndxRef::ErrorCode m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // counters SignalCounter m_signalCounter; Uint32 m_triggerCounter; // ctor OpAlterIndex() { memset(&m_request, 0, sizeof(m_request)); m_coordinatorRef = 0; m_requestType = AlterIndxReq::RT_UNDEFINED; m_requestFlag = 0; m_lastError = AlterIndxRef::NoError; m_errorCode = AlterIndxRef::NoError; m_errorLine = 0; m_errorNode = 0; m_triggerCounter = 0; } void save(const AlterIndxReq* req) { m_request = *req; m_requestType = req->getRequestType(); m_requestFlag = req->getRequestFlag(); } bool hasLastError() { return m_lastError != AlterIndxRef::NoError; } bool hasError() { return m_errorCode != AlterIndxRef::NoError; } void setError(const AlterIndxRef* ref) { m_lastError = AlterIndxRef::NoError; if (ref != 0) { m_lastError = ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const CreateIndxRef* ref) { m_lastError = AlterIndxRef::NoError; if (ref != 0) { m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const DropIndxRef* ref) { m_lastError = AlterIndxRef::NoError; if (ref != 0) { m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const BuildIndxRef* ref) { m_lastError = AlterIndxRef::NoError; if (ref != 0) { m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = 0; m_errorNode = 0; } } } void setError(const CreateTrigRef* ref) { m_lastError = AlterIndxRef::NoError; if (ref != 0) { m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const DropTrigRef* ref) { m_lastError = AlterIndxRef::NoError; if (ref != 0) { m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } }; typedef Ptr<OpAlterIndex> OpAlterIndexPtr; /** * Operation record for build index. */ struct OpBuildIndex : OpRecordCommon { // original request plus buffer for attribute lists BuildIndxReq m_request; AttributeList m_attrList; Id_array<MAX_ATTRIBUTES_IN_INDEX+1> m_tableKeyList; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; // state info BuildIndxReq::RequestType m_requestType; Uint32 m_requestFlag; Uint32 m_constrTriggerId; // error info BuildIndxRef::ErrorCode m_lastError; BuildIndxRef::ErrorCode m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // counters SignalCounter m_signalCounter; // ctor OpBuildIndex() { memset(&m_request, 0, sizeof(m_request)); m_coordinatorRef = 0; m_requestType = BuildIndxReq::RT_UNDEFINED; m_requestFlag = 0; m_lastError = BuildIndxRef::NoError; m_errorCode = BuildIndxRef::NoError; m_errorLine = 0; m_errorNode = 0; } void save(const BuildIndxReq* req) { m_request = *req; m_requestType = req->getRequestType(); m_requestFlag = req->getRequestFlag(); } bool hasLastError() { return m_lastError != BuildIndxRef::NoError; } bool hasError() { return m_errorCode != BuildIndxRef::NoError; } void setError(const BuildIndxRef* ref) { m_lastError = BuildIndxRef::NoError; if (ref != 0) { m_lastError = ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = 0; m_errorNode = 0; } } } void setError(const AlterIndxRef* ref) { m_lastError = BuildIndxRef::NoError; if (ref != 0) { m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const CreateTrigRef* ref) { m_lastError = BuildIndxRef::NoError; if (ref != 0) { m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const DropTrigRef* ref) { m_lastError = BuildIndxRef::NoError; if (ref != 0) { m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } }; typedef Ptr<OpBuildIndex> OpBuildIndexPtr; /** * Operation record for Util Signals. */ struct OpSignalUtil : OpRecordCommon{ Callback m_callback; Uint32 m_userData; }; typedef Ptr<OpSignalUtil> OpSignalUtilPtr; /** * Operation record for subscribe-start-stop */ struct OpSubEvent : OpRecordCommon { Uint32 m_senderRef; Uint32 m_senderData; Uint32 m_errorCode; RequestTracker m_reqTracker; }; typedef Ptr<OpSubEvent> OpSubEventPtr; static const Uint32 sysTab_NDBEVENTS_0_szs[]; /** * Operation record for create event. */ struct OpCreateEvent : OpRecordCommon { // original request (event id will be added) CreateEvntReq m_request; //AttributeMask m_attrListBitmask; // AttributeList m_attrList; sysTab_NDBEVENTS_0 m_eventRec; // char m_eventName[MAX_TAB_NAME_SIZE]; // char m_tableName[MAX_TAB_NAME_SIZE]; // coordinator DICT RequestTracker m_reqTracker; // state info CreateEvntReq::RequestType m_requestType; // error info Uint32 m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; /* also used to store master node id in case of NotMaster */ // ctor OpCreateEvent() { memset(&m_request, 0, sizeof(m_request)); m_requestType = CreateEvntReq::RT_UNDEFINED; m_errorCode = CreateEvntRef::NoError; m_errorLine = 0; m_errorNode = 0; } void init(const CreateEvntReq* req, Dbdict* dp) { m_request = *req; m_errorCode = CreateEvntRef::NoError; m_errorLine = 0; m_errorNode = 0; m_requestType = req->getRequestType(); } bool hasError() { return m_errorCode != CreateEvntRef::NoError; } void setError(const CreateEvntRef* ref) { if (ref != 0 && ! hasError()) { m_errorCode = ref->getErrorCode(); m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } }; typedef Ptr<OpCreateEvent> OpCreateEventPtr; /** * Operation record for drop event. */ struct OpDropEvent : OpRecordCommon { // original request DropEvntReq m_request; // char m_eventName[MAX_TAB_NAME_SIZE]; sysTab_NDBEVENTS_0 m_eventRec; RequestTracker m_reqTracker; // error info Uint32 m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // ctor OpDropEvent() { memset(&m_request, 0, sizeof(m_request)); m_errorCode = 0; m_errorLine = 0; m_errorNode = 0; } void init(const DropEvntReq* req) { m_request = *req; m_errorCode = 0; m_errorLine = 0; m_errorNode = 0; } bool hasError() { return m_errorCode != 0; } void setError(const DropEvntRef* ref) { if (ref != 0 && ! hasError()) { m_errorCode = ref->getErrorCode(); m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } }; typedef Ptr<OpDropEvent> OpDropEventPtr; /** * Operation record for create trigger. */ struct OpCreateTrigger : OpRecordCommon { // original request (trigger id will be added) CreateTrigReq m_request; char m_triggerName[MAX_TAB_NAME_SIZE]; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; // state info CreateTrigReq::RequestType m_requestType; Uint32 m_requestFlag; // error info CreateTrigRef::ErrorCode m_lastError; CreateTrigRef::ErrorCode m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // counters SignalCounter m_signalCounter; // ctor OpCreateTrigger() { memset(&m_request, 0, sizeof(m_request)); m_coordinatorRef = 0; m_requestType = CreateTrigReq::RT_UNDEFINED; m_requestFlag = 0; m_lastError = CreateTrigRef::NoError; m_errorCode = CreateTrigRef::NoError; m_errorLine = 0; m_errorNode = 0; } void save(const CreateTrigReq* req) { m_request = *req; m_requestType = req->getRequestType(); m_requestFlag = req->getRequestFlag(); } bool hasLastError() { return m_lastError != CreateTrigRef::NoError; } bool hasError() { return m_errorCode != CreateTrigRef::NoError; } void setError(const CreateTrigRef* ref) { m_lastError = CreateTrigRef::NoError; if (ref != 0) { m_lastError = ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const AlterTrigRef* ref) { m_lastError = CreateTrigRef::NoError; if (ref != 0) { m_lastError = (CreateTrigRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } }; typedef Ptr<OpCreateTrigger> OpCreateTriggerPtr; /** * Operation record for drop trigger. */ struct OpDropTrigger : OpRecordCommon { // original request DropTrigReq m_request; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; // state info DropTrigReq::RequestType m_requestType; Uint32 m_requestFlag; // error info DropTrigRef::ErrorCode m_lastError; DropTrigRef::ErrorCode m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // counters SignalCounter m_signalCounter; // ctor OpDropTrigger() { memset(&m_request, 0, sizeof(m_request)); m_coordinatorRef = 0; m_requestType = DropTrigReq::RT_UNDEFINED; m_requestFlag = 0; m_lastError = DropTrigRef::NoError; m_errorCode = DropTrigRef::NoError; m_errorLine = 0; m_errorNode = 0; } void save(const DropTrigReq* req) { m_request = *req; m_requestType = req->getRequestType(); m_requestFlag = req->getRequestFlag(); } bool hasLastError() { return m_lastError != DropTrigRef::NoError; } bool hasError() { return m_errorCode != DropTrigRef::NoError; } void setError(const DropTrigRef* ref) { m_lastError = DropTrigRef::NoError; if (ref != 0) { m_lastError = ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const AlterTrigRef* ref) { m_lastError = DropTrigRef::NoError; if (ref != 0) { m_lastError = (DropTrigRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } }; typedef Ptr<OpDropTrigger> OpDropTriggerPtr; /** * Operation record for alter trigger. */ struct OpAlterTrigger : OpRecordCommon { // original request AlterTrigReq m_request; // nodes participating in operation NdbNodeBitmask m_nodes; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; // state info AlterTrigReq::RequestType m_requestType; Uint32 m_requestFlag; // error info AlterTrigRef::ErrorCode m_lastError; AlterTrigRef::ErrorCode m_errorCode; Uint32 m_errorLine; Uint32 m_errorNode; // counters SignalCounter m_signalCounter; // ctor OpAlterTrigger() { memset(&m_request, 0, sizeof(m_request)); m_coordinatorRef = 0; m_requestType = AlterTrigReq::RT_UNDEFINED; m_requestFlag = 0; m_lastError = AlterTrigRef::NoError; m_errorCode = AlterTrigRef::NoError; m_errorLine = 0; m_errorNode = 0; } void save(const AlterTrigReq* req) { m_request = *req; m_requestType = req->getRequestType(); m_requestFlag = req->getRequestFlag(); } bool hasLastError() { return m_lastError != AlterTrigRef::NoError; } bool hasError() { return m_errorCode != AlterTrigRef::NoError; } void setError(const AlterTrigRef* ref) { m_lastError = AlterTrigRef::NoError; if (ref != 0) { m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const CreateTrigRef* ref) { m_lastError = AlterTrigRef::NoError; if (ref != 0) { m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } void setError(const DropTrigRef* ref) { m_lastError = AlterTrigRef::NoError; if (ref != 0) { m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode(); if (! hasError()) { m_errorCode = m_lastError; m_errorLine = ref->getErrorLine(); m_errorNode = ref->getErrorNode(); } } } }; typedef Ptr<OpAlterTrigger> OpAlterTriggerPtr; public: struct SchemaOp : OpRecordCommon { Uint32 m_clientRef; // API (for take-over) Uint32 m_clientData;// API Uint32 m_senderRef; // Uint32 m_senderData;// transaction key value Uint32 m_errorCode; Uint32 m_obj_id; Uint32 m_obj_type; Uint32 m_obj_version; Uint32 m_obj_ptr_i; Uint32 m_vt_index; Callback m_callback; }; typedef Ptr<SchemaOp> SchemaOpPtr; struct SchemaTransaction : OpRecordCommon { Uint32 m_senderRef; // API Uint32 m_senderData;// API Callback m_callback; SafeCounterHandle m_counter; NodeBitmask m_nodes; Uint32 m_errorCode; void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;} /** * This should contain "lists" with operations */ struct { Uint32 m_key; // Operation key Uint32 m_vt_index; // Operation type Uint32 m_obj_id; DictObjOp::State m_state; } m_op; }; private: struct OpCreateObj : public SchemaOp { Uint32 m_gci; Uint32 m_obj_info_ptr_i; Uint32 m_restart; }; typedef Ptr<OpCreateObj> CreateObjRecordPtr; struct OpDropObj : public SchemaOp { }; typedef Ptr<OpDropObj> DropObjRecordPtr; /** * Only used at coordinator/master */ // Common operation record pool public: STATIC_CONST( opCreateTableSize = sizeof(CreateTableRecord) ); STATIC_CONST( opDropTableSize = sizeof(DropTableRecord) ); STATIC_CONST( opCreateIndexSize = sizeof(OpCreateIndex) ); STATIC_CONST( opDropIndexSize = sizeof(OpDropIndex) ); STATIC_CONST( opAlterIndexSize = sizeof(OpAlterIndex) ); STATIC_CONST( opBuildIndexSize = sizeof(OpBuildIndex) ); STATIC_CONST( opCreateEventSize = sizeof(OpCreateEvent) ); STATIC_CONST( opSubEventSize = sizeof(OpSubEvent) ); STATIC_CONST( opDropEventSize = sizeof(OpDropEvent) ); STATIC_CONST( opSignalUtilSize = sizeof(OpSignalUtil) ); STATIC_CONST( opCreateTriggerSize = sizeof(OpCreateTrigger) ); STATIC_CONST( opDropTriggerSize = sizeof(OpDropTrigger) ); STATIC_CONST( opAlterTriggerSize = sizeof(OpAlterTrigger) ); STATIC_CONST( opCreateObjSize = sizeof(OpCreateObj) ); private: #define PTR_ALIGN(n) ((((n)+sizeof(void*)-1)>>2)&~((sizeof(void*)-1)>>2)) union OpRecordUnion { Uint32 u_opCreateTable [PTR_ALIGN(opCreateTableSize)]; Uint32 u_opDropTable [PTR_ALIGN(opDropTableSize)]; Uint32 u_opCreateIndex [PTR_ALIGN(opCreateIndexSize)]; Uint32 u_opDropIndex [PTR_ALIGN(opDropIndexSize)]; Uint32 u_opCreateEvent [PTR_ALIGN(opCreateEventSize)]; Uint32 u_opSubEvent [PTR_ALIGN(opSubEventSize)]; Uint32 u_opDropEvent [PTR_ALIGN(opDropEventSize)]; Uint32 u_opSignalUtil [PTR_ALIGN(opSignalUtilSize)]; Uint32 u_opAlterIndex [PTR_ALIGN(opAlterIndexSize)]; Uint32 u_opBuildIndex [PTR_ALIGN(opBuildIndexSize)]; Uint32 u_opCreateTrigger[PTR_ALIGN(opCreateTriggerSize)]; Uint32 u_opDropTrigger [PTR_ALIGN(opDropTriggerSize)]; Uint32 u_opAlterTrigger [PTR_ALIGN(opAlterTriggerSize)]; Uint32 u_opCreateObj [PTR_ALIGN(opCreateObjSize)]; Uint32 nextPool; }; ArrayPool<OpRecordUnion> c_opRecordPool; // Operation records KeyTable2<CreateTableRecord, OpRecordUnion> c_opCreateTable; KeyTable2<DropTableRecord, OpRecordUnion> c_opDropTable; KeyTable2<OpCreateIndex, OpRecordUnion> c_opCreateIndex; KeyTable2<OpDropIndex, OpRecordUnion> c_opDropIndex; KeyTable2<OpAlterIndex, OpRecordUnion> c_opAlterIndex; KeyTable2<OpBuildIndex, OpRecordUnion> c_opBuildIndex; KeyTable2<OpCreateEvent, OpRecordUnion> c_opCreateEvent; KeyTable2<OpSubEvent, OpRecordUnion> c_opSubEvent; KeyTable2<OpDropEvent, OpRecordUnion> c_opDropEvent; KeyTable2<OpSignalUtil, OpRecordUnion> c_opSignalUtil; KeyTable2<OpCreateTrigger, OpRecordUnion> c_opCreateTrigger; KeyTable2<OpDropTrigger, OpRecordUnion> c_opDropTrigger; KeyTable2<OpAlterTrigger, OpRecordUnion> c_opAlterTrigger; KeyTable2<SchemaOp, OpRecordUnion> c_schemaOp; KeyTable2<SchemaTransaction, OpRecordUnion> c_Trans; KeyTable2Ref<OpCreateObj, SchemaOp, OpRecordUnion> c_opCreateObj; KeyTable2Ref<OpDropObj, SchemaOp, OpRecordUnion> c_opDropObj; // Unique key for operation XXX move to some system table Uint32 c_opRecordSequence; /* * Master DICT can be locked in 2 mutually exclusive ways: * * 1) for schema ops, via operation records * 2) against schema ops, via a lock queue * * Current use of 2) is by a starting node, to prevent schema ops * until started. The ops are refused (BlockState != BS_IDLE), * not queued. * * Master failure is not handled, in node start case the starting * node will crash too anyway. Use lock table in future.. * * The lock queue is "serial" but other behaviour is possible * by checking lock types e.g. to allow parallel node starts. * * Checking release of last op record is not convenient with * current structure (5.0). Instead we poll via continueB. * * XXX only table ops check BlockState */ struct DictLockType { DictLockReq::LockType lockType; BlockState blockState; const char* text; }; struct DictLockRecord { DictLockReq req; const DictLockType* lt; bool locked; union { Uint32 nextPool; Uint32 nextList; }; Uint32 prevList; }; typedef Ptr<DictLockRecord> DictLockPtr; ArrayPool<DictLockRecord> c_dictLockPool; DLFifoList<DictLockRecord> c_dictLockQueue; bool c_dictLockPoll; static const DictLockType* getDictLockType(Uint32 lockType); void sendDictLockInfoEvent(Uint32 pollCount); void sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text); void checkDictLockQueue(Signal* signal, bool poll); void sendDictLockConf(Signal* signal, DictLockPtr lockPtr); void sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode); // control polling i.e. continueB loop void setDictLockPoll(Signal* signal, bool on, Uint32 pollCount); // NF handling void removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes); // Statement blocks /* ------------------------------------------------------------ */ // Start/Restart Handling /* ------------------------------------------------------------ */ void sendSTTORRY(Signal* signal); void sendNDB_STTORRY(Signal* signal); void initSchemaFile(Signal* signal); /* ------------------------------------------------------------ */ // Drop Table Handling /* ------------------------------------------------------------ */ void releaseTableObject(Uint32 tableId, bool removeFromHash = true); /* ------------------------------------------------------------ */ // General Stuff /* ------------------------------------------------------------ */ Uint32 getFreeObjId(Uint32 minId); Uint32 getFreeTableRecord(Uint32 primaryTableId); Uint32 getFreeTriggerRecord(); bool getNewAttributeRecord(TableRecordPtr tablePtr, AttributeRecordPtr & attrPtr); void packTableIntoPages(Signal* signal); void packTableIntoPages(SimpleProperties::Writer &, TableRecordPtr, Signal* =0); void packFilegroupIntoPages(SimpleProperties::Writer &, FilegroupPtr, const Uint32 undo_free_hi, const Uint32 undo_free_lo); void packFileIntoPages(SimpleProperties::Writer &, FilePtr, const Uint32); void sendGET_TABINFOREQ(Signal* signal, Uint32 tableId); void sendTC_SCHVERREQ(Signal* signal, Uint32 tableId, BlockReference tcRef); /* ------------------------------------------------------------ */ // System Restart Handling /* ------------------------------------------------------------ */ void initSendSchemaData(Signal* signal); void sendSchemaData(Signal* signal); Uint32 sendSCHEMA_INFO(Signal* signal, Uint32 nodeId, Uint32* pagePointer); void checkSchemaStatus(Signal* signal); void sendDIHSTARTTAB_REQ(Signal* signal); /* ------------------------------------------------------------ */ // Receive Table Handling /* ------------------------------------------------------------ */ void handleTabInfoInit(SimpleProperties::Reader &, ParseDictTabInfoRecord *, bool checkExist = true); void handleTabInfo(SimpleProperties::Reader & it, ParseDictTabInfoRecord *, DictTabInfo::Table & tableDesc); void handleAddTableFailure(Signal* signal, Uint32 failureLine, Uint32 tableId); bool verifyTableCorrect(Signal* signal, Uint32 tableId); /* ------------------------------------------------------------ */ // Add Table Handling /* ------------------------------------------------------------ */ void releaseCreateTableOp(Signal* signal, CreateTableRecordPtr createTabPtr); /* ------------------------------------------------------------ */ // Add Fragment Handling /* ------------------------------------------------------------ */ void sendLQHADDATTRREQ(Signal*, CreateTableRecordPtr, Uint32 attributePtrI); /* ------------------------------------------------------------ */ // Read/Write Schema and Table files /* ------------------------------------------------------------ */ void updateSchemaState(Signal* signal, Uint32 tableId, SchemaFile::TableEntry*, Callback*); void startWriteSchemaFile(Signal* signal); void openSchemaFile(Signal* signal, Uint32 fileNo, Uint32 fsPtr, bool writeFlag, bool newFile); void writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr); void writeSchemaConf(Signal* signal, FsConnectRecordPtr fsPtr); void closeFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr); void closeWriteSchemaConf(Signal* signal, FsConnectRecordPtr fsPtr); void initSchemaFile_conf(Signal* signal, Uint32 i, Uint32 returnCode); void writeTableFile(Signal* signal, Uint32 tableId, SegmentedSectionPtr tabInfo, Callback*); void startWriteTableFile(Signal* signal, Uint32 tableId); void openTableFile(Signal* signal, Uint32 fileNo, Uint32 fsPtr, Uint32 tableId, bool writeFlag); void writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr); void writeTableConf(Signal* signal, FsConnectRecordPtr fsPtr); void closeWriteTableConf(Signal* signal, FsConnectRecordPtr fsPtr); void startReadTableFile(Signal* signal, Uint32 tableId); void openReadTableRef(Signal* signal, FsConnectRecordPtr fsPtr); void readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr); void readTableConf(Signal* signal, FsConnectRecordPtr fsPtr); void readTableRef(Signal* signal, FsConnectRecordPtr fsPtr); void closeReadTableConf(Signal* signal, FsConnectRecordPtr fsPtr); void startReadSchemaFile(Signal* signal); void openReadSchemaRef(Signal* signal, FsConnectRecordPtr fsPtr); void readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr); void readSchemaConf(Signal* signal, FsConnectRecordPtr fsPtr); void readSchemaRef(Signal* signal, FsConnectRecordPtr fsPtr); void closeReadSchemaConf(Signal* signal, FsConnectRecordPtr fsPtr); bool convertSchemaFileTo_5_0_6(XSchemaFile*); /* ------------------------------------------------------------ */ // Get table definitions /* ------------------------------------------------------------ */ void sendGET_TABINFOREF(Signal* signal, GetTabInfoReq*, GetTabInfoRef::ErrorCode errorCode); void sendGET_TABLEID_REF(Signal* signal, GetTableIdReq * req, GetTableIdRef::ErrorCode errorCode); void sendGetTabResponse(Signal* signal); /* ------------------------------------------------------------ */ // Indexes and triggers /* ------------------------------------------------------------ */ // reactivate and rebuild indexes on start up void activateIndexes(Signal* signal, Uint32 i); void rebuildIndexes(Signal* signal, Uint32 i); // create index void createIndex_recvReply(Signal* signal, const CreateIndxConf* conf, const CreateIndxRef* ref); void createIndex_slavePrepare(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_fromCreateTable(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_toAlterIndex(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_fromAlterIndex(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_slaveCommit(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_slaveAbort(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_sendSlaveReq(Signal* signal, OpCreateIndexPtr opPtr); void createIndex_sendReply(Signal* signal, OpCreateIndexPtr opPtr, bool); // drop index void dropIndex_recvReply(Signal* signal, const DropIndxConf* conf, const DropIndxRef* ref); void dropIndex_slavePrepare(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_toAlterIndex(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_fromAlterIndex(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_toDropTable(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_fromDropTable(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_slaveCommit(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_slaveAbort(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_sendSlaveReq(Signal* signal, OpDropIndexPtr opPtr); void dropIndex_sendReply(Signal* signal, OpDropIndexPtr opPtr, bool); // alter index void alterIndex_recvReply(Signal* signal, const AlterIndxConf* conf, const AlterIndxRef* ref); void alterIndex_slavePrepare(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_toCreateTc(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_fromCreateTc(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_toDropTc(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_fromDropTc(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_toCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_fromCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_toDropTrigger(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_fromDropTrigger(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_toBuildIndex(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_fromBuildIndex(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_slaveCommit(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_slaveAbort(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_sendSlaveReq(Signal* signal, OpAlterIndexPtr opPtr); void alterIndex_sendReply(Signal* signal, OpAlterIndexPtr opPtr, bool); // build index void buildIndex_recvReply(Signal* signal, const BuildIndxConf* conf, const BuildIndxRef* ref); void buildIndex_toCreateConstr(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_fromCreateConstr(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_buildTrix(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_toDropConstr(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_fromDropConstr(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_fromOnline(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr); void buildIndex_sendReply(Signal* signal, OpBuildIndexPtr opPtr, bool); // Events void createEventUTIL_PREPARE(Signal* signal, Uint32 callbackData, Uint32 returnCode); void createEventUTIL_EXECUTE(Signal *signal, Uint32 callbackData, Uint32 returnCode); void dropEventUTIL_PREPARE_READ(Signal* signal, Uint32 callbackData, Uint32 returnCode); void dropEventUTIL_EXECUTE_READ(Signal* signal, Uint32 callbackData, Uint32 returnCode); void dropEventUTIL_PREPARE_DELETE(Signal* signal, Uint32 callbackData, Uint32 returnCode); void dropEventUTIL_EXECUTE_DELETE(Signal *signal, Uint32 callbackData, Uint32 returnCode); void dropEventUtilPrepareRef(Signal* signal, Uint32 callbackData, Uint32 returnCode); void dropEventUtilExecuteRef(Signal* signal, Uint32 callbackData, Uint32 returnCode); int sendSignalUtilReq(Callback *c, BlockReference ref, GlobalSignalNumber gsn, Signal* signal, Uint32 length, JobBufferLevel jbuf, LinearSectionPtr ptr[3], Uint32 noOfSections); int recvSignalUtilReq(Signal* signal, Uint32 returnCode); void completeSubStartReq(Signal* signal, Uint32 ptrI, Uint32 returnCode); void completeSubStopReq(Signal* signal, Uint32 ptrI, Uint32 returnCode); void completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 returnCode); void dropEvent_sendReply(Signal* signal, OpDropEventPtr evntRecPtr); void createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr); void createEventComplete_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr); void createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr); void createEventComplete_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr); void createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr); void createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI, Uint32 returnCode); void createEvent_sendReply(Signal* signal, OpCreateEventPtr evntRecPtr, LinearSectionPtr *ptr = NULL, int noLSP = 0); void prepareTransactionEventSysTable (Callback *c, Signal* signal, Uint32 senderData, UtilPrepareReq::OperationTypeValue prepReq); void prepareUtilTransaction(Callback *c, Signal* signal, Uint32 senderData, Uint32 tableId, const char *tableName, UtilPrepareReq::OperationTypeValue prepReq, Uint32 noAttr, Uint32 attrIds[], const char *attrNames[]); void executeTransEventSysTable(Callback *c, Signal *signal, const Uint32 ptrI, sysTab_NDBEVENTS_0& m_eventRec, const Uint32 prepareId, UtilPrepareReq::OperationTypeValue prepReq); void executeTransaction(Callback *c, Signal* signal, Uint32 senderData, Uint32 prepareId, Uint32 noAttr, LinearSectionPtr headerPtr, LinearSectionPtr dataPtr); void parseReadEventSys(Signal *signal, sysTab_NDBEVENTS_0& m_eventRec); // create trigger void createTrigger_recvReply(Signal* signal, const CreateTrigConf* conf, const CreateTrigRef* ref); void createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_masterSeize(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_slaveCreate(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_toAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_fromAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_slaveCommit(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_slaveAbort(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_sendSlaveReq(Signal* signal, OpCreateTriggerPtr opPtr); void createTrigger_sendReply(Signal* signal, OpCreateTriggerPtr opPtr, bool); // drop trigger void dropTrigger_recvReply(Signal* signal, const DropTrigConf* conf, const DropTrigRef* ref); void dropTrigger_slavePrepare(Signal* signal, OpDropTriggerPtr opPtr); void dropTrigger_toAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr); void dropTrigger_fromAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr); void dropTrigger_slaveCommit(Signal* signal, OpDropTriggerPtr opPtr); void dropTrigger_slaveAbort(Signal* signal, OpDropTriggerPtr opPtr); void dropTrigger_sendSlaveReq(Signal* signal, OpDropTriggerPtr opPtr); void dropTrigger_sendReply(Signal* signal, OpDropTriggerPtr opPtr, bool); // alter trigger void alterTrigger_recvReply(Signal* signal, const AlterTrigConf* conf, const AlterTrigRef* ref); void alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_fromCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_fromDropLocal(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_slaveCommit(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_slaveAbort(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_sendSlaveReq(Signal* signal, OpAlterTriggerPtr opPtr); void alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr, bool); // support void getTableKeyList(TableRecordPtr, Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list); void getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id); void getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list); void getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask); /* ------------------------------------------------------------ */ // Initialisation /* ------------------------------------------------------------ */ void initCommonData(); void initRecords(); void initConnectRecord(); void initRetrieveRecord(Signal*, Uint32, Uint32 returnCode); void initSchemaRecord(); void initRestartRecord(); void initSendSchemaRecord(); void initReadTableRecord(); void initWriteTableRecord(); void initReadSchemaRecord(); void initWriteSchemaRecord(); void initNodeRecords(); void initTableRecords(); void initialiseTableRecord(TableRecordPtr tablePtr); void initTriggerRecords(); void initialiseTriggerRecord(TriggerRecordPtr triggerPtr); void initPageRecords(); Uint32 getFsConnRecord(); bool getIsFailed(Uint32 nodeId) const; void dropTable_backup_mutex_locked(Signal* signal, Uint32, Uint32); void dropTableRef(Signal * signal, DropTableReq *, DropTableRef::ErrorCode); void printTables(); // For debugging only int handleAlterTab(AlterTabReq * req, CreateTableRecord * regAlterTabPtr, TableRecordPtr origTablePtr, TableRecordPtr newTablePtr); void revertAlterTable(Signal * signal, Uint32 changeMask, Uint32 tableId, CreateTableRecord * regAlterTabPtr); void alterTable_backup_mutex_locked(Signal* signal, Uint32, Uint32); void alterTableRef(Signal * signal, AlterTableReq *, AlterTableRef::ErrorCode, ParseDictTabInfoRecord* parseRecord = NULL); void alterTabRef(Signal * signal, AlterTabReq *, AlterTableRef::ErrorCode, ParseDictTabInfoRecord* parseRecord = NULL); void alterTab_writeSchemaConf(Signal* signal, Uint32 callbackData, Uint32 returnCode); void alterTab_writeTableConf(Signal* signal, Uint32 callbackData, Uint32 returnCode); void prepDropTab_nextStep(Signal* signal, DropTableRecordPtr); void prepDropTab_complete(Signal* signal, DropTableRecordPtr); void prepDropTab_writeSchemaConf(Signal* signal, Uint32 dropTabPtrI, Uint32); void dropTab_localDROP_TAB_CONF(Signal* signal); void dropTab_nextStep(Signal* signal, DropTableRecordPtr); void dropTab_complete(Signal* signal, Uint32 dropTabPtrI, Uint32); void dropTab_writeSchemaConf(Signal* signal, Uint32 dropTabPtrI, Uint32); void createTab_prepare(Signal* signal, CreateTabReq * req); void createTab_writeSchemaConf1(Signal* signal, Uint32 callback, Uint32); void createTab_writeTableConf(Signal* signal, Uint32 callbackData, Uint32); void createTab_dih(Signal*, CreateTableRecordPtr, SegmentedSectionPtr, Callback*); void createTab_dihComplete(Signal* signal, Uint32 callbackData, Uint32); void createTab_startLcpMutex_locked(Signal* signal, Uint32, Uint32); void createTab_startLcpMutex_unlocked(Signal* signal, Uint32, Uint32); void createTab_commit(Signal* signal, CreateTabReq * req); void createTab_writeSchemaConf2(Signal* signal, Uint32 callbackData, Uint32); void createTab_alterComplete(Signal*, Uint32 callbackData, Uint32); void createTab_drop(Signal* signal, CreateTabReq * req); void createTab_dropComplete(Signal* signal, Uint32 callbackData, Uint32); void createTab_reply(Signal* signal, CreateTableRecordPtr, Uint32 nodeId); void alterTab_activate(Signal*, CreateTableRecordPtr, Callback*); void restartCreateTab(Signal*, Uint32, const SchemaFile::TableEntry *, const SchemaFile::TableEntry *, bool); void restartCreateTab_readTableConf(Signal* signal, Uint32 callback, Uint32); void restartCreateTab_writeTableConf(Signal* signal, Uint32 callback, Uint32); void restartCreateTab_dihComplete(Signal* signal, Uint32 callback, Uint32); void restartCreateTab_activateComplete(Signal*, Uint32 callback, Uint32); void restartDropTab(Signal* signal, Uint32 tableId); void restartDropTab_complete(Signal*, Uint32 callback, Uint32); void restart_checkSchemaStatusComplete(Signal*, Uint32 callback, Uint32); void restart_writeSchemaConf(Signal*, Uint32 callbackData, Uint32); void masterRestart_checkSchemaStatusComplete(Signal*, Uint32, Uint32); void sendSchemaComplete(Signal*, Uint32 callbackData, Uint32); void execCREATE_OBJ_REQ(Signal* signal); void execCREATE_OBJ_REF(Signal* signal); void execCREATE_OBJ_CONF(Signal* signal); void createObj_prepare_start_done(Signal* signal, Uint32 callback, Uint32); void createObj_writeSchemaConf1(Signal* signal, Uint32 callback, Uint32); void createObj_writeObjConf(Signal* signal, Uint32 callbackData, Uint32); void createObj_prepare_complete_done(Signal*, Uint32 callbackData, Uint32); void createObj_commit_start_done(Signal* signal, Uint32 callback, Uint32); void createObj_writeSchemaConf2(Signal* signal, Uint32 callbackData, Uint32); void createObj_commit_complete_done(Signal*, Uint32 callbackData, Uint32); void createObj_abort(Signal*, struct CreateObjReq*); void createObj_abort_start_done(Signal*, Uint32 callbackData, Uint32); void createObj_abort_writeSchemaConf(Signal*, Uint32 callbackData, Uint32); void createObj_abort_complete_done(Signal*, Uint32 callbackData, Uint32); void schemaOp_reply(Signal* signal, SchemaTransaction *, Uint32); void trans_commit_start_done(Signal*, Uint32 callbackData, Uint32); void trans_commit_complete_done(Signal*, Uint32 callbackData, Uint32); void trans_abort_start_done(Signal*, Uint32 callbackData, Uint32); void trans_abort_complete_done(Signal*, Uint32 callbackData, Uint32); void execDROP_OBJ_REQ(Signal* signal); void execDROP_OBJ_REF(Signal* signal); void execDROP_OBJ_CONF(Signal* signal); void dropObj_prepare_start_done(Signal* signal, Uint32 callback, Uint32); void dropObj_prepare_writeSchemaConf(Signal*, Uint32 callback, Uint32); void dropObj_prepare_complete_done(Signal*, Uint32 callbackData, Uint32); void dropObj_commit_start_done(Signal*, Uint32 callbackData, Uint32); void dropObj_commit_writeSchemaConf(Signal*, Uint32 callback, Uint32); void dropObj_commit_complete_done(Signal*, Uint32 callbackData, Uint32); void dropObj_abort_start_done(Signal*, Uint32 callbackData, Uint32); void dropObj_abort_writeSchemaConf(Signal*, Uint32 callback, Uint32); void dropObj_abort_complete_done(Signal*, Uint32 callbackData, Uint32); void restartCreateObj(Signal*, Uint32, const SchemaFile::TableEntry *, const SchemaFile::TableEntry *, bool); void restartCreateObj_readConf(Signal*, Uint32, Uint32); void restartCreateObj_getTabInfoConf(Signal*); void restartCreateObj_prepare_start_done(Signal*, Uint32, Uint32); void restartCreateObj_write_complete(Signal*, Uint32, Uint32); void restartCreateObj_prepare_complete_done(Signal*, Uint32, Uint32); void restartCreateObj_commit_start_done(Signal*, Uint32, Uint32); void restartCreateObj_commit_complete_done(Signal*, Uint32, Uint32); void execDICT_COMMIT_REQ(Signal*); void execDICT_COMMIT_REF(Signal*); void execDICT_COMMIT_CONF(Signal*); void execDICT_ABORT_REQ(Signal*); void execDICT_ABORT_REF(Signal*); void execDICT_ABORT_CONF(Signal*); public: void createObj_commit(Signal*, struct SchemaOp*); void createObj_abort(Signal*, struct SchemaOp*); void create_fg_prepare_start(Signal* signal, SchemaOp*); void create_fg_prepare_complete(Signal* signal, SchemaOp*); void create_fg_abort_start(Signal* signal, SchemaOp*); void create_fg_abort_complete(Signal* signal, SchemaOp*); void create_file_prepare_start(Signal* signal, SchemaOp*); void create_file_prepare_complete(Signal* signal, SchemaOp*); void create_file_commit_start(Signal* signal, SchemaOp*); void create_file_abort_start(Signal* signal, SchemaOp*); void create_file_abort_complete(Signal* signal, SchemaOp*); void dropObj_commit(Signal*, struct SchemaOp*); void dropObj_abort(Signal*, struct SchemaOp*); void drop_file_prepare_start(Signal* signal, SchemaOp*); void drop_file_commit_start(Signal* signal, SchemaOp*); void drop_file_commit_complete(Signal* signal, SchemaOp*); void drop_file_abort_start(Signal* signal, SchemaOp*); void send_drop_file(Signal*, SchemaOp*, DropFileImplReq::RequestInfo); void drop_fg_prepare_start(Signal* signal, SchemaOp*); void drop_fg_commit_start(Signal* signal, SchemaOp*); void drop_fg_commit_complete(Signal* signal, SchemaOp*); void drop_fg_abort_start(Signal* signal, SchemaOp*); void send_drop_fg(Signal*, SchemaOp*, DropFilegroupImplReq::RequestInfo); void drop_undofile_prepare_start(Signal* signal, SchemaOp*); }; inline bool Dbdict::TableRecord::isTable() const { return DictTabInfo::isTable(tableType); } inline bool Dbdict::TableRecord::isIndex() const { return DictTabInfo::isIndex(tableType); } inline bool Dbdict::TableRecord::isUniqueIndex() const { return DictTabInfo::isUniqueIndex(tableType); } inline bool Dbdict::TableRecord::isNonUniqueIndex() const { return DictTabInfo::isNonUniqueIndex(tableType); } inline bool Dbdict::TableRecord::isHashIndex() const { return DictTabInfo::isHashIndex(tableType); } inline bool Dbdict::TableRecord::isOrderedIndex() const { return DictTabInfo::isOrderedIndex(tableType); } #endif