/* 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 DBTUP_H #define DBTUP_H #include <pc.hpp> #include <SimulatedBlock.hpp> #include <ndb_limits.h> #include <trigger_definitions.h> #include <ArrayList.hpp> #include <AttributeHeader.hpp> #include <Bitmask.hpp> #include <signaldata/TupKey.hpp> #include <signaldata/CreateTrig.hpp> #include <signaldata/DropTrig.hpp> #include <signaldata/TrigAttrInfo.hpp> #include <signaldata/BuildIndx.hpp> #define ZWORDS_ON_PAGE 8192 /* NUMBER OF WORDS ON A PAGE. */ #define ZATTRBUF_SIZE 32 /* SIZE OF ATTRIBUTE RECORD BUFFER */ #define ZMIN_PAGE_LIMIT_TUPKEYREQ 5 #define ZTUP_VERSION_BITS 15 typedef bool (Dbtup::* ReadFunction)(Uint32*, AttributeHeader*, Uint32, Uint32); typedef bool (Dbtup::* UpdateFunction)(Uint32*, Uint32, Uint32); #ifdef DBTUP_C //------------------------------------------------------------------ // Jam Handling: // // When DBTUP reports lines through jam in the trace files it has to // be interpreted. 4024 means as an example line 24 in DbtupCommit.cpp // Thus 4000 is added to the line number beacuse it is located in the // file DbtupCommit.cpp. The following is the exhaustive list of the // added value in the various files. ndbrequire, ptrCheckGuard still // only reports the line number in the file it currently is located in. // // DbtupExecQuery.cpp 0 // DbtupBuffer.cpp 2000 // DbtupRoutines.cpp 3000 // DbtupCommit.cpp 5000 // DbtupFixAlloc.cpp 6000 // DbtupTrigger.cpp 7000 // DbtupAbort.cpp 9000 // DbtupLCP.cpp 10000 // DbtupUndoLog.cpp 12000 // DbtupPageMap.cpp 14000 // DbtupPagMan.cpp 16000 // DbtupStoredProcDef.cpp 18000 // DbtupMeta.cpp 20000 // DbtupTabDesMan.cpp 22000 // DbtupGen.cpp 24000 // DbtupSystemRestart.cpp 26000 // DbtupIndex.cpp 28000 // DbtupDebug.cpp 30000 //------------------------------------------------------------------ /* 2.2 LOCAL SYMBOLS ----------------- */ /* ---------------------------------------------------------------- */ /* S I Z E O F R E C O R D S */ /* ---------------------------------------------------------------- */ #define ZNO_OF_ATTRBUFREC 10000 /* SIZE OF ATTRIBUTE INFO FILE */ #define ZNO_OF_CONCURRENT_OPEN_OP 40 /* NUMBER OF CONCURRENT OPENS */ #define ZNO_OF_CONCURRENT_WRITE_OP 80 /* NUMBER OF CONCURRENT DISK WRITES*/ #define ZNO_OF_FRAGOPREC 20 /* NUMBER OF CONCURRENT ADD FRAG. */ #define ZNO_OF_LCP_REC 10 /* NUMBER OF CONCURRENT CHECKPOINTS*/ #define TOT_PAGE_RECORD_SPACE 262144 /* SIZE OF PAGE RECORD FILE. */ #define ZNO_OF_PAGE TOT_PAGE_RECORD_SPACE/ZWORDS_ON_PAGE #define ZNO_OF_PAGE_RANGE_REC 128 /* SIZE OF PAGE RANGE FILE */ #define ZNO_OF_PARALLELL_UNDO_FILES 16 /* NUMBER OF PARALLEL UNDO FILES */ #define ZNO_OF_RESTART_INFO_REC 10 /* MAXIMUM PARALLELL RESTART INFOS */ /* 24 SEGMENTS WITH 8 PAGES IN EACH*/ /* PLUS ONE UNDO BUFFER CACHE */ // Undo record identifiers are 32-bits with page index 13-bits #define ZUNDO_RECORD_ID_PAGE_INDEX 13 /* 13 BITS = 8192 WORDS/PAGE */ #define ZUNDO_RECORD_ID_PAGE_INDEX_MASK (ZWORDS_ON_PAGE - 1) /* 1111111111111 */ // Trigger constants #define ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE 16 /* ---------------------------------------------------------------- */ // VARIABLE NUMBERS OF PAGE_WORD, UNDO_WORD AND LOGIC_WORD FOR // COMMUNICATION WITH FILE SYSTEM /* ---------------------------------------------------------------- */ #define ZBASE_ADDR_PAGE_WORD 1 /* BASE ADDRESS OF PAGE_WORD VAR */ #define ZBASE_ADDR_UNDO_WORD 2 /* BASE ADDRESS OF UNDO_WORD VAR */ #define ZBASE_ADDR_LOGIC_WORD 3 /* BASE ADDRESS OF LOGIC_WORD VAR */ /* ---------------------------------------------------------------- */ // NUMBER OF PAGES SENT TO DISK IN DATA BUFFER AND UNDO BUFFER WHEN // OPTIMUM PERFORMANCE IS ACHIEVED. /* ---------------------------------------------------------------- */ #define ZUB_SEGMENT_SIZE 8 /* SEGMENT SIZE OF UNDO BUFFER */ #define ZDB_SEGMENT_SIZE 8 /* SEGMENT SIZE OF DATA BUFFER */ /* ---------------------------------------------------------------- */ /* A ATTRIBUTE MAY BE NULL, DYNAMIC OR NORMAL. A NORMAL ATTRIBUTE */ /* IS A ATTRIBUTE THAT IS NOT NULL OR DYNAMIC. A NULL ATTRIBUTE */ /* MAY HAVE NO VALUE. A DYNAMIC ATTRIBUTE IS A NULL ATTRIBUTE THAT */ /* DOES NOT HAVE TO BE A MEMBER OF EVERY TUPLE I A CERTAIN TABLE. */ /* ---------------------------------------------------------------- */ /** * #defines moved into include/kernel/Interpreter.hpp */ #define ZMAX_REGISTER 21 #define ZINSERT_DELETE 0 /* ---------------------------------------------------------------- */ /* THE MINIMUM SIZE OF AN 'EMPTY' TUPLE HEADER IN R-WORDS */ /* ---------------------------------------------------------------- */ #define ZTUP_HEAD_MINIMUM_SIZE 2 /* THE TUPLE HEADER FIELD 'SIZE OF NULL ATTR. FIELD' SPECIFYES */ /* THE SIZE OF THE TUPLE HEADER FIELD 'NULL ATTR. FIELD'. */ /* THE TUPLE HEADER FIELD 'TYPE' SPECIFYES THE TYPE OF THE TUPLE */ /* HEADER. */ /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */ /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER. */ /* IT MAY ALSO CONTAIN SHORT ATTRIBUTES AND */ /* POINTERS TO LONG ATTRIBUTE HEADERS. */ /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */ /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER. */ #define ZTH_TYPE3 2 /* TUPLE HEADER THAT MAY HAVE A POINTER TO */ /* A DYNAMIC ATTRIBUTE HEADER. IT MAY ALSO */ /* CONTAIN SHORT ATTRIBUTES AND POINTERS */ /* TO LONG ATTRIBUTE HEADERS. */ /* DATA STRUCTURE TYPES */ /* WHEN ATTRIBUTE INFO IS SENT WITH A ATTRINFO-SIGNAL THE */ /* VARIABLE TYPE IS SPECIFYED. THIS MUST BE DONE TO BE ABLE TO */ /* NOW HOW MUCH DATA OF A ATTRIBUTE TO READ FROM ATTRINFO. */ #define ZFIXED_ARRAY 2 /* ZFIXED ARRAY FIELD. */ #define ZNON_ARRAY 1 /* NORMAL FIELD. */ #define ZVAR_ARRAY 0 /* VARIABLE ARRAY FIELD */ #define ZNOT_STORE 3 /* THE ATTR IS STORED IN THE INDEX BLOCK */ #define ZMAX_SMALL_VAR_ARRAY 256 /* PLEASE OBSERVE THAT THEESE CONSTANTS CORRESPONDS TO THE NUMBER */ /* OF BITS NEEDED TO REPRESENT THEM D O N O T C H A N G E */ #define Z1BIT_VAR 0 /* 1 BIT VARIABLE. */ #define Z2BIT_VAR 1 /* 2 BIT VARIABLE. */ #define Z4BIT_VAR 2 /* 4 BIT VARIABLE. */ #define Z8BIT_VAR 3 /* 8 BIT VARIABLE. */ #define Z16BIT_VAR 4 /* 16 BIT VARIABLE. */ #define Z32BIT_VAR 5 /* 32 BIT VARIABLE. */ #define Z64BIT_VAR 6 /* 64 BIT VARIABLE. */ #define Z128BIT_VAR 7 /* 128 BIT VARIABLE. */ /* WHEN A REQUEST CAN NOT BE EXECUTED BECAUSE OF A ERROR THE */ /* ERROR MUST BE IDENTIFYED BY MEANS OF A ERROR CODE AND SENT TO */ /* THE REQUESTER. */ #define ZGET_OPREC_ERROR 804 // TUP_SEIZEREF #define ZEXIST_FRAG_ERROR 816 // Add fragment #define ZFULL_FRAGRECORD_ERROR 817 // Add fragment #define ZNO_FREE_PAGE_RANGE_ERROR 818 // Add fragment #define ZNOFREE_FRAGOP_ERROR 830 // Add fragment #define ZTOO_LARGE_TUPLE_ERROR 851 // Add fragment #define ZNO_FREE_TAB_ENTRY_ERROR 852 // Add fragment #define ZNO_PAGES_ALLOCATED_ERROR 881 // Add fragment #define ZGET_REALPID_ERROR 809 #define ZNOT_IMPLEMENTED_ERROR 812 #define ZSEIZE_ATTRINBUFREC_ERROR 805 #define ZTOO_MUCH_ATTRINFO_ERROR 823 #define ZMEM_NOTABDESCR_ERROR 826 #define ZMEM_NOMEM_ERROR 827 #define ZAI_INCONSISTENCY_ERROR 829 #define ZNO_ILLEGAL_NULL_ATTR 839 #define ZNOT_NULL_ATTR 840 #define ZNO_INSTRUCTION_ERROR 871 #define ZOUTSIDE_OF_PROGRAM_ERROR 876 #define ZSTORED_PROC_ID_ERROR 877 #define ZREGISTER_INIT_ERROR 878 #define ZATTRIBUTE_ID_ERROR 879 #define ZTRY_TO_READ_TOO_MUCH_ERROR 880 #define ZTOTAL_LEN_ERROR 882 #define ZATTR_INTERPRETER_ERROR 883 #define ZSTACK_OVERFLOW_ERROR 884 #define ZSTACK_UNDERFLOW_ERROR 885 #define ZTOO_MANY_INSTRUCTIONS_ERROR 886 #define ZTRY_TO_UPDATE_ERROR 888 #define ZCALL_ERROR 890 #define ZTEMPORARY_RESOURCE_FAILURE 891 #define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan #define ZREAD_ONLY_CONSTRAINT_VIOLATION 893 #define ZVAR_SIZED_NOT_SUPPORTED 894 #define ZINCONSISTENT_NULL_ATTRIBUTE_COUNT 895 #define ZTUPLE_CORRUPTED_ERROR 896 #define ZTRY_UPDATE_PRIMARY_KEY 897 #define ZMUST_BE_ABORTED_ERROR 898 #define ZTUPLE_DELETED_ERROR 626 #define ZINSERT_ERROR 630 /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */ #define ZPAGE_STATE_POS 0 /* POSITION OF PAGE STATE */ #define ZPAGE_NEXT_POS 1 /* POSITION OF THE NEXT POINTER WHEN IN FREELIST */ #define ZPAGE_PREV_POS 2 /* POSITION OF THE PREVIOUS POINTER WHEN IN FREELIST */ #define ZFREELIST_HEADER_POS 3 /* POSITION OF THE FIRST FREELIST */ #define ZPAGE_FRAG_PAGE_ID_POS 4 /* POSITION OF FRAG PAGE ID WHEN USED*/ #define ZPAGE_NEXT_CLUST_POS 5 /* POSITION OF NEXT FREE SET OF PAGES */ #define ZPAGE_FIRST_CLUST_POS 2 /* POSITION OF THE POINTER TO THE FIRST PAGE IN A CLUSTER */ #define ZPAGE_LAST_CLUST_POS 6 /* POSITION OF THE POINTER TO THE LAST PAGE IN A CLUSTER */ #define ZPAGE_PREV_CLUST_POS 7 /* POSITION OF THE PREVIOUS POINTER */ #define ZPAGE_HEADER_SIZE 32 /* NUMBER OF WORDS IN MEM PAGEHEADER */ #define ZDISK_PAGE_HEADER_SIZE 32 /* NUMBER OF WORDS IN DISK PAGEHEADER */ #define ZNO_OF_FREE_BLOCKS 3 /* NO OF FREE BLOCK IN THE DISK PAGE */ #define ZDISK_PAGE_ID 8 /* ID OF THE PAGE ON THE DISK */ #define ZBLOCK_LIST 9 #define ZCOPY_OF_PAGE 10 #define ZPAGE_PHYSICAL_INDEX 11 #define ZNEXT_IN_PAGE_USED_LIST 12 #define ZPREV_IN_PAGE_USED_LIST 13 #define ZDISK_USED_TYPE 14 #define ZFREE_COMMON 1 /* PAGE STATE, PAGE IN COMMON AREA */ #define ZEMPTY_MM 2 /* PAGE STATE, PAGE IN EMPTY LIST */ #define ZTH_MM_FREE 3 /* PAGE STATE, TUPLE HEADER PAGE WITH FREE AREA */ #define ZTH_MM_FULL 4 /* PAGE STATE, TUPLE HEADER PAGE WHICH IS FULL */ #define ZAC_MM_FREE 5 /* PAGE STATE, ATTRIBUTE CLUSTER PAGE WITH FREE AREA */ #define ZTH_MM_FREE_COPY 7 /* PAGE STATE, TH COPY PAGE WITH FREE AREA */ #define ZTH_MM_FULL_COPY 8 /* PAGE STATE, TH COPY PAGE WHICH IS FULL */ #define ZAC_MM_FREE_COPY 9 /* PAGE STATE, AC COPY PAGE WITH FREE AREA */ #define ZMAX_NO_COPY_PAGES 4 /* THE MAXIMUM NUMBER OF COPY PAGES ALLOWED PER FRAGMENT */ /* CONSTANTS USED TO HANDLE TABLE DESCRIPTOR RECORDS */ /* ALL POSITIONS AND SIZES IS BASED ON R-WORDS (32-BIT ON APZ 212) */ #define ZTD_HEADER 0 /* HEADER POSITION */ #define ZTD_DATASIZE 1 /* SIZE OF THE DATA IN THIS CHUNK */ #define ZTD_SIZE 2 /* TOTAL SIZE OF TABLE DESCRIPTOR */ /* TRAILER POSITIONS FROM END OF TABLE DESCRIPTOR RECORD */ #define ZTD_TR_SIZE 1 /* SIZE DESCRIPTOR POS FROM END+1 */ #define ZTD_TR_TYPE 2 #define ZTD_TRAILER_SIZE 2 /* TOTAL SIZE OF TABLE TRAILER */ #define ZAD_SIZE 2 /* TOTAL SIZE OF ATTR DESCRIPTOR */ #define ZAD_LOG_SIZE 1 /* TWO LOG OF TOTAL SIZE OF ATTR DESCRIPTOR */ /* CONSTANTS USED TO HANDLE TABLE DESCRIPTOR AS A FREELIST */ #define ZTD_FL_HEADER 0 /* HEADER POSITION */ #define ZTD_FL_SIZE 1 /* TOTAL SIZE OF THIS FREELIST ENTRY */ #define ZTD_FL_PREV 2 /* PREVIOUS RECORD IN FREELIST */ #define ZTD_FL_NEXT 3 /* NEXT RECORD IN FREELIST */ #define ZTD_FREE_SIZE 16 /* SIZE NEEDED TO HOLD ONE FL ENTRY */ /* CONSTANTS USED IN LSB OF TABLE DESCRIPTOR HEADER DESCRIBING USAGE */ #define ZTD_TYPE_FREE 0 /* RECORD LINKED INTO FREELIST */ #define ZTD_TYPE_NORMAL 1 /* RECORD USED AS TABLE DESCRIPTOR */ /* ATTRIBUTE OPERATION CONSTANTS */ #define ZLEAF 1 #define ZNON_LEAF 2 /* ATTRINBUFREC VARIABLE POSITIONS. */ #define ZBUF_PREV 29 /* POSITION OF 'PREV'-VARIABLE (USED BY INTERPRETED EXEC) */ #define ZBUF_DATA_LEN 30 /* POSITION OF 'DATA LENGTH'-VARIABLE. */ #define ZBUF_NEXT 31 /* POSITION OF 'NEXT'-VARIABLE. */ #define ZSAVE_BUF_NEXT 28 #define ZSAVE_BUF_DATA_LEN 27 /* RETURN POINTS. */ /* RESTART PHASES */ #define ZSTARTPHASE1 1 #define ZSTARTPHASE2 2 #define ZSTARTPHASE3 3 #define ZSTARTPHASE4 4 #define ZSTARTPHASE6 6 #define ZADDFRAG 0 /* CHECKPOINT RECORD TYPES */ #define ZLCPR_TYPE_INSERT_TH 0 /* INSERT TUPLE HEADER */ #define ZLCPR_TYPE_DELETE_TH 1 /* DELETE TUPLE HEADER */ #define ZLCPR_TYPE_UPDATE_TH 2 /* DON'T CREATE IT, JUST UPDETE */ #define ZLCPR_TYPE_INSERT_TH_NO_DATA 3 /* INSERT TUPLE HEADER */ #define ZLCPR_ABORT_UPDATE 4 /* UNDO AN UPDATE OPERATION THAT WAS ACTIVE IN LCP */ #define ZLCPR_ABORT_INSERT 5 /* UNDO AN INSERT OPERATION THAT WAS ACTIVE IN LCP */ #define ZTABLE_DESCRIPTOR 6 /* TABLE DESCRIPTOR */ #define ZINDICATE_NO_OP_ACTIVE 7 /* ENSURE THAT NO OPERATION ACTIVE AFTER RESTART */ #define ZLCPR_UNDO_LOG_PAGE_HEADER 8 /* CHANGE IN PAGE HEADER IS UNDO LOGGED */ #define ZLCPR_TYPE_UPDATE_GCI 9 /* Update GCI at commit time */ #define ZNO_CHECKPOINT_RECORDS 10 /* NUMBER OF CHECKPOINTRECORD TYPES */ /* RESULT CODES */ /* ELEMENT POSITIONS IN SYSTEM RESTART INFO PAGE OF THE DATA FILE */ #define ZSRI_NO_OF_FRAG_PAGES_POS 10 /* NUMBER OF FRAGMENT PAGES WHEN CHECKPOINT STARTED */ #define ZSRI_TUP_RESERVED_SIZE_POS 11 /* RESERVED SIZE OF THE TUPLE WHEN CP STARTED */ #define ZSRI_TUP_FIXED_AREA_POS 12 /* SIZE OF THE TUPLE FIXED AREA WHEN CP STARTED */ #define ZSRI_TAB_DESCR_SIZE 13 /* SIZE OF THE TABLE DESCRIPTOR WHEN CP STARTED */ #define ZSRI_NO_OF_ATTRIBUTES_POS 14 /* NUMBER OF ATTRIBUTES */ #define ZSRI_UNDO_LOG_END_REC_ID 15 /* LAST UNDO LOG RECORD ID FOR THIS CHECKPOINT */ #define ZSRI_UNDO_LOG_END_PAGE_ID 16 /* LAST USED LOG PAGE ID FOR THIS CHECKPOINT */ #define ZSRI_TH_FREE_FIRST 17 /* FIRST FREE PAGE OF TUPLE HEADERS */ #define ZSRI_TH_FREE_COPY_FIRST 18 /* FIRST FREE PAGE OF TUPLE HEADER COPIES */ #define ZSRI_EMPTY_PRIM_PAGE 27 /* FIRST EMPTY PAGE */ #define ZSRI_NO_COPY_PAGES_ALLOC 28 /* NO COPY PAGES IN FRAGMENT AT LOCAL CHECKPOINT */ #define ZSRI_UNDO_FILE_VER 29 /* CHECK POINT ID OF THE UNDO FILE */ #define ZSRI_NO_OF_INDEX_ATTR 30 /* No of index attributes */ #define ZNO_OF_PAGES_CLUSTER_REC 0 //------------------------------------------------------------ // TUP_CONTINUEB codes //------------------------------------------------------------ #define ZSTART_EXEC_UNDO_LOG 0 #define ZCONT_START_SAVE_CL 1 #define ZCONT_SAVE_DP 2 #define ZCONT_EXECUTE_LC 3 #define ZCONT_LOAD_DP 4 #define ZLOAD_BAL_LCP_TIMER 5 #define ZINITIALISE_RECORDS 6 #define ZREL_FRAG 7 #define ZREPORT_MEMORY_USAGE 8 #define ZBUILD_INDEX 9 #define ZINDEX_STORAGE 0 #define ZDATA_WORD_AT_DISK_PAGE 2030 #define ZALLOC_DISK_PAGE_LAST_INDEX 2047 #define ZWORD_IN_BLOCK 127 /* NO OF WORD IN A BLOCK */ #define ZNO_DISK_PAGES_FILE_REC 100 #define ZMASK_PAGE_INDEX 0x7ff #define ZBIT_PAGE_INDEX 11 /* 8 KBYT PAGE = 2048 WORDS */ #define ZSCAN_PROCEDURE 0 #define ZCOPY_PROCEDURE 2 #define ZSTORED_PROCEDURE_DELETE 3 #define ZSTORED_PROCEDURE_FREE 0xffff #define ZMIN_PAGE_LIMIT_TUP_COMMITREQ 2 #define ZUNDO_PAGE_HEADER_SIZE 2 /* SIZE OF UNDO PAGE HEADER */ #endif class Dbtup: public SimulatedBlock { public: // State values enum State { NOT_INITIALIZED = 0, COMMON_AREA_PAGES = 1, UNDO_RESTART_PAGES = 2, UNDO_PAGES = 3, READ_ONE_PAGE = 4, CHECKPOINT_DATA_READ = 7, CHECKPOINT_DATA_READ_PAGE_ZERO = 8, CHECKPOINT_DATA_WRITE = 9, CHECKPOINT_DATA_WRITE_LAST = 10, CHECKPOINT_DATA_WRITE_FLUSH = 11, CHECKPOINT_UNDO_READ = 12, CHECKPOINT_UNDO_READ_FIRST = 13, CHECKPOINT_UNDO_WRITE = 14, CHECKPOINT_UNDO_WRITE_FLUSH = 15, CHECKPOINT_TD_READ = 16, IDLE = 17, ACTIVE = 18, SYSTEM_RESTART = 19, NO_OTHER_OP = 20, COMMIT_DELETE = 21, TO_BE_COMMITTED = 22, ABORTED = 23, ALREADY_ABORTED_INSERT = 24, ALREADY_ABORTED = 25, ABORT_INSERT = 26, ABORT_UPDATE = 27, INIT = 28, INITIAL_READ = 29, INTERPRETED_EXECUTION = 30, FINAL_READ = 31, FINAL_UPDATE = 32, DISCONNECTED = 33, DEFINED = 34, ERROR_WAIT_TUPKEYREQ = 35, STARTED = 36, NOT_DEFINED = 37, COMPLETED = 38, WAIT_ABORT = 39, NORMAL_PAGE = 40, COPY_PAGE = 41, DELETE_BLOCK = 42, WAIT_STORED_PROCEDURE_ATTR_INFO = 43, DATA_FILE_READ = 45, DATA_FILE_WRITE = 46, LCP_DATA_FILE_READ = 47, LCP_DATA_FILE_WRITE = 48, LCP_DATA_FILE_WRITE_WITH_UNDO = 49, LCP_DATA_FILE_CLOSE = 50, LCP_UNDO_FILE_READ = 51, LCP_UNDO_FILE_CLOSE = 52, LCP_UNDO_FILE_WRITE = 53, OPENING_DATA_FILE = 54, INITIATING_RESTART_INFO = 55, INITIATING_FRAGMENT = 56, OPENING_UNDO_FILE = 57, READING_RESTART_INFO = 58, INIT_UNDO_SEGMENTS = 59, READING_TAB_DESCR = 60, READING_DATA_PAGES = 61, WAIT_COPY_PROCEDURE = 62, TOO_MUCH_AI = 63, SAME_PAGE = 64, DEFINING = 65, TUPLE_BLOCKED = 66, ERROR_WAIT_STORED_PROCREQ = 67 }; // Records /* ************** ATTRIBUTE INFO BUFFER RECORD ****************** */ /* THIS RECORD IS USED AS A BUFFER FOR INCOMING AND OUTGOING DATA */ /* ************************************************************** */ struct Attrbufrec { Uint32 attrbuf[ZATTRBUF_SIZE]; }; /* p2c: size = 128 bytes */ typedef Ptr<Attrbufrec> AttrbufrecPtr; /* ********** CHECKPOINT INFORMATION ************ */ /* THIS RECORD HOLDS INFORMATION NEEDED TO */ /* PERFORM A CHECKPOINT. IT'S POSSIBLE TO RUN */ /* MULTIPLE CHECKPOINTS AT A TIME. THIS RECORD */ /* MAKES IT POSSIBLE TO DISTINGER BETWEEN THE */ /* DIFFERENT CHECKPOINTS. */ /* ********************************************** */ struct CheckpointInfo { Uint32 lcpNextRec; /* NEXT RECORD IN FREELIST */ Uint32 lcpCheckpointVersion; /* VERSION OF THE CHECKPOINT */ Uint32 lcpLocalLogInfoP; /* POINTER TO A LOCAL LOG INFO RECORD */ Uint32 lcpUserptr; /* USERPOINTER TO THE BLOCK REQUESTING THE CP */ Uint32 lcpFragmentP; /* FRAGMENT POINTER TO WHICH THE CHECKPOINT APPLIES */ Uint32 lcpFragmentId; /* FRAGMENT ID */ Uint32 lcpTabPtr; /* TABLE POINTER */ Uint32 lcpDataBufferSegmentP; /* POINTER TO A DISK BUFFER SEGMENT POINTER (DATA) */ Uint32 lcpDataFileHandle; /* FILE HANDLES FOR DATA FILE. LOG FILE HANDLE IN LOCAL_LOG_INFO_RECORD */ /* FILE HANDLE TO THE OPEN DATA FILE */ Uint32 lcpNoOfPages; Uint32 lcpThFreeFirst; Uint32 lcpThFreeCopyFirst; Uint32 lcpEmptyPrimPage; Uint32 lcpNoCopyPagesAlloc; Uint32 lcpTmpOperPtr; /* TEMPORARY STORAGE OF OPER_PTR DURING SAVE */ BlockReference lcpBlockref; /* BLOCKREFERENCE TO THE BLOCK REQUESTING THE CP */ }; typedef Ptr<CheckpointInfo> CheckpointInfoPtr; /* *********** DISK BUFFER SEGMENT INFO ********* */ /* THIS RECORD HOLDS INFORMATION NEEDED DURING */ /* A WRITE OF THE DATA BUFFER TO DISK. WHEN THE */ /* WRITE SIGNAL IS SENT A POINTER TO THIS RECORD */ /* IS INCLUDED. WHEN THE WRITE IS COMPLETED AND */ /* CONFIRMED THE PTR TO THIS RECORD IS RETURNED */ /* AND THE BUFFER PAGES COULD EASILY BE LOCATED */ /* AND DEALLOCATED. THE CHECKPOINT_INFO_VERSION */ /* KEEPS TRACK OF THE CHECPOINT_INFO_RECORD THAT */ /* INITIATED THE WRITE AND THE CP_PAGE_TO_DISK */ /* ELEMENT COULD BE INCREASED BY THE NUMBER OF */ /* PAGES WRITTEN. */ /* ********************************************** */ struct DiskBufferSegmentInfo { Uint32 pdxDataPage[16]; /* ARRAY OF DATA BUFFER PAGES */ Uint32 pdxUndoBufferSet[2]; Uint32 pdxNextRec; State pdxBuffertype; State pdxOperation; /*---------------------------------------------------------------------------*/ /* PDX_FLAGS BITS AND THEIR USAGE: */ /* BIT 0 1 COMMENT */ /*---------------------------------------------------------------------------*/ /* 0 SEGMENT INVALID SEGMENT VALID USED DURING READS */ /* 1-15 NOT USED */ /*---------------------------------------------------------------------------*/ Uint32 pdxCheckpointInfoP; /* USED DURING LOCAL CHKP */ Uint32 pdxRestartInfoP; /* USED DURING RESTART */ Uint32 pdxLocalLogInfoP; /* POINTS TO A LOCAL LOG INFO */ Uint32 pdxFilePage; /* START PAGE IN FILE */ Uint32 pdxNumDataPages; /* NUMBER OF DATA PAGES */ }; typedef Ptr<DiskBufferSegmentInfo> DiskBufferSegmentInfoPtr; struct Fragoperrec { bool definingFragment; Uint32 nextFragoprec; Uint32 lqhPtrFrag; Uint32 fragidFrag; Uint32 tableidFrag; Uint32 fragPointer; Uint32 attributeCount; Uint32 freeNullBit; Uint32 noOfNewAttrCount; Uint32 charsetIndex; BlockReference lqhBlockrefFrag; }; typedef Ptr<Fragoperrec> FragoperrecPtr; struct Fragrecord { Uint32 nextStartRange; Uint32 currentPageRange; Uint32 rootPageRange; Uint32 noOfPages; Uint32 emptyPrimPage; Uint32 firstusedOprec; Uint32 lastusedOprec; Uint32 thFreeFirst; Uint32 thFreeCopyFirst; Uint32 noCopyPagesAlloc; Uint32 checkpointVersion; Uint32 minPageNotWrittenInCheckpoint; Uint32 maxPageWrittenInCheckpoint; State fragStatus; Uint32 fragTableId; Uint32 fragmentId; Uint32 nextfreefrag; }; typedef Ptr<Fragrecord> FragrecordPtr; /* ************ LOCAL LOG FILE INFO ************* */ /* THIS RECORD HOLDS INFORMATION NEEDED DURING */ /* CHECKPOINT AND RESTART. THERE ARE FOUR */ /* PARALLELL UNDO LOG FILES, EACH ONE REPRESENTED */ /* BY AN ENTITY OF THIS RECORD. */ /* BECAUSE EACH FILE IS SHARED BETWEEN FOUR */ /* TABLES AND HAS ITS OWN PAGEPOINTERS AND */ /* WORDPOINTERS. */ /* ********************************************** */ struct LocalLogInfo { Uint32 lliActiveLcp; /* NUMBER OF ACTIVE LOCAL CHECKPOINTS ON THIS FILE */ Uint32 lliEndPageId; /* PAGE IDENTIFIER OF LAST PAGE WITH LOG DATA */ Uint32 lliPrevRecordId; /* PREVIOUS RECORD IN THIS LOGFILE */ Uint32 lliLogFilePage; /* PAGE IN LOGFILE */ Uint32 lliNumFragments; /* NO OF FRAGMENTS RESTARTING FROM THIS LOCAL LOG */ Uint32 lliUndoBufferSegmentP; /* POINTER TO A DISK BUFFER SEGMENT POINTER (UNDO) */ Uint32 lliUndoFileHandle; /* FILE HANDLE OF UNDO LOG FILE */ Uint32 lliUndoPage; /* UNDO PAGE IN BUFFER */ Uint32 lliUndoWord; Uint32 lliUndoPagesToDiskWithoutSynch; }; typedef Ptr<LocalLogInfo> LocalLogInfoPtr; struct Operationrec { // Easy to remove (2 words) Uint32 attroutbufLen; Uint32 logSize; // Needed (20 words) State tupleState; Uint32 prevActiveOp; Uint32 nextActiveOp; Uint32 nextOprecInList; Uint32 prevOprecInList; Uint32 tableRef; Uint32 fragId; Uint32 fragmentPtr; Uint32 fragPageId; Uint32 realPageId; bool undoLogged; Uint32 realPageIdC; Uint32 fragPageIdC; Uint32 firstAttrinbufrec; Uint32 lastAttrinbufrec; Uint32 attrinbufLen; Uint32 currentAttrinbufLen; Uint32 userpointer; State transstate; Uint32 savePointId; // Easy to remove (3 words) Uint32 tcOperationPtr; Uint32 transid1; Uint32 transid2; // Needed (2 words) Uint16 pageIndex; Uint16 pageOffset; Uint16 pageOffsetC; Uint16 pageIndexC; // Hard to remove Uint16 tupVersion; // Easy to remove (1.5 word) BlockReference recBlockref; BlockReference userblockref; Uint16 storedProcedureId; Uint8 inFragList; Uint8 inActiveOpList; Uint8 deleteInsertFlag; // Needed (1 word) Uint8 dirtyOp; Uint8 interpretedExec; Uint8 optype; Uint8 opSimple; // Used by triggers Uint32 primaryReplica; BlockReference coordinatorTC; Uint32 tcOpIndex; Uint32 gci; Uint32 noFiredTriggers; union { Uint32 hashValue; // only used in TUP_COMMITREQ Uint32 lastRow; }; Bitmask<MAXNROFATTRIBUTESINWORDS> changeMask; }; typedef Ptr<Operationrec> OperationrecPtr; struct Page { Uint32 pageWord[ZWORDS_ON_PAGE]; }; typedef Ptr<Page> PagePtr; /* ****************************** PAGE RANGE RECORD ************************** */ /* PAGE RANGES AND BASE PAGE ID. EACH RANGE HAS A CORRESPONDING BASE PAGE ID */ /* THAT IS USED TO CALCULATE REAL PAGE ID FROM A FRAGMENT PAGE ID AND A TABLE */ /* REFERENCE. */ /* THE PAGE RANGES ARE ORGANISED IN A B-TREE FASHION WHERE THE VARIABLE TYPE */ /* SPECIFIES IF A LEAF NODE HAS BEEN REACHED. IF A LEAF NODE HAS BEEN REACHED */ /* THEN BASE_PAGE_ID IS THE BASE_PAGE_ID OF THE SET OF PAGES THAT WAS */ /* ALLOCATED IN THAT RANGE. OTHERWISE BASE_PAGE_ID IS THE POINTER TO THE NEXT */ /* PAGE_RANGE RECORD. */ /* *************************************************************************** */ struct PageRange { Uint32 startRange[4]; /* START OF RANGE */ Uint32 endRange[4]; /* END OF THIS RANGE */ Uint32 basePageId[4]; /* BASE PAGE ID. */ /*---- VARIABLE BASE_PAGE_ID2 (4) 8 DS NEEDED WHEN SUPPORTING 40 BIT PAGE ID -------*/ Uint8 type[4]; /* TYPE OF BASE PAGE ID */ Uint32 nextFree; /* NEXT FREE PAGE RANGE RECORD */ Uint32 parentPtr; /* THE PARENT TO THE PAGE RANGE REC IN THE B-TREE */ Uint8 currentIndexPos; }; typedef Ptr<PageRange> PageRangePtr; /* *********** PENDING UNDO WRITE INFO ********** */ /* THIS RECORD HOLDS INFORMATION NEEDED DURING */ /* A FILE OPEN OPERATION */ /* IF THE FILE OPEN IS A PART OF A CHECKPOINT THE */ /* CHECKPOINT_INFO_P WILL HOLD A POINTER TO THE */ /* CHECKPOINT_INFOR_PTR RECORD */ /* IF IT IS A PART OF RESTART THE PFO_RESTART_INFO*/ /* ELEMENT WILL POINT TO A RESTART INFO RECORD */ /* ********************************************** */ struct PendingFileOpenInfo { Uint32 pfoNextRec; State pfoOpenType; Uint32 pfoCheckpointInfoP; Uint32 pfoRestartInfoP; }; typedef Ptr<PendingFileOpenInfo> PendingFileOpenInfoPtr; struct RestartInfoRecord { Uint32 sriNextRec; State sriState; /* BLOCKREFERENCE TO THE REQUESTING BLOCK */ Uint32 sriUserptr; /* USERPOINTER TO THE REQUESTING BLOCK */ Uint32 sriDataBufferSegmentP; /* POINTER TO A DISK BUFFER SEGMENT POINTER (DATA) */ Uint32 sriDataFileHandle; /* FILE HANDLE TO THE OPEN DATA FILE */ Uint32 sriCheckpointVersion; /* CHECKPOINT VERSION TO RESTART FROM */ Uint32 sriFragid; /* FRAGMENT ID */ Uint32 sriFragP; /* FRAGMENT POINTER */ Uint32 sriTableId; /* TABLE ID */ Uint32 sriLocalLogInfoP; /* POINTER TO A LOCAL LOG INFO RECORD */ Uint32 sriNumDataPages; /* NUMBER OF DATA PAGES TO READ */ Uint32 sriCurDataPageFromBuffer; /* THE CHECKPOINT IS COMPLETED */ BlockReference sriBlockref; }; typedef Ptr<RestartInfoRecord> RestartInfoRecordPtr; /* ************* TRIGGER DATA ************* */ /* THIS RECORD FORMS LISTS OF ACTIVE */ /* TRIGGERS FOR EACH TABLE. */ /* THE RECORDS ARE MANAGED BY A TRIGGER */ /* POOL wHERE A TRIGGER RECORD IS SEIZED */ /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */ /* WHEN THE TRIGGER IS DEACTIVATED. */ /* **************************************** */ struct TupTriggerData { /** * Trigger id, used by DICT/TRIX to identify the trigger */ Uint32 triggerId; /** * Index id is needed for ordered index. */ Uint32 indexId; /** * Trigger type etc, defines what the trigger is used for */ TriggerType::Value triggerType; TriggerActionTime::Value triggerActionTime; TriggerEvent::Value triggerEvent; /** * Receiver block */ Uint32 m_receiverBlock; /** * Monitor all replicas, i.e. trigger will fire on all nodes where tuples * are stored */ bool monitorReplicas; /** * Monitor all attributes, the trigger monitors all changes to attributes * in the table */ bool monitorAllAttributes; /** * Send only changed attributes at trigger firing time. */ bool sendOnlyChangedAttributes; /** * Send also before values at trigger firing time. */ bool sendBeforeValues; /** * Attribute mask, defines what attributes are to be monitored * Can be seen as a compact representation of SQL column name list */ Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask; /** * Next ptr (used in pool/list) */ union { Uint32 nextPool; Uint32 nextList; }; /** * Prev pointer (used in list) */ Uint32 prevList; inline void print(NdbOut & s) const { s << "[TriggerData = " << triggerId << "]"; }; }; typedef Ptr<TupTriggerData> TriggerPtr; /** * Pool of trigger data record */ ArrayPool<TupTriggerData> c_triggerPool; /* ************ TABLE RECORD ************ */ /* THIS RECORD FORMS A LIST OF TABLE */ /* REFERENCE INFORMATION. ONE RECORD */ /* PER TABLE REFERENCE. */ /* ************************************** */ struct Tablerec { Tablerec(ArrayPool<TupTriggerData> & triggerPool) : afterInsertTriggers(triggerPool), afterDeleteTriggers(triggerPool), afterUpdateTriggers(triggerPool), subscriptionInsertTriggers(triggerPool), subscriptionDeleteTriggers(triggerPool), subscriptionUpdateTriggers(triggerPool), constraintUpdateTriggers(triggerPool), tuxCustomTriggers(triggerPool) {} Bitmask<MAXNROFATTRIBUTESINWORDS> notNullAttributeMask; ReadFunction* readFunctionArray; UpdateFunction* updateFunctionArray; CHARSET_INFO** charsetArray; Uint32 readKeyArray; Uint32 tabDescriptor; Uint32 attributeGroupDescriptor; bool GCPIndicator; bool checksumIndicator; Uint16 tupheadsize; Uint16 noOfAttr; Uint16 noOfKeyAttr; Uint16 noOfCharsets; Uint16 noOfNewAttr; Uint16 noOfNullAttr; Uint16 noOfAttributeGroups; Uint8 tupChecksumIndex; Uint8 tupNullIndex; Uint8 tupNullWords; Uint8 tupGCPIndex; // Lists of trigger data for active triggers ArrayList<TupTriggerData> afterInsertTriggers; ArrayList<TupTriggerData> afterDeleteTriggers; ArrayList<TupTriggerData> afterUpdateTriggers; ArrayList<TupTriggerData> subscriptionInsertTriggers; ArrayList<TupTriggerData> subscriptionDeleteTriggers; ArrayList<TupTriggerData> subscriptionUpdateTriggers; ArrayList<TupTriggerData> constraintUpdateTriggers; // List of ordered indexes ArrayList<TupTriggerData> tuxCustomTriggers; Uint32 fragid[2 * MAX_FRAG_PER_NODE]; Uint32 fragrec[2 * MAX_FRAG_PER_NODE]; struct { Uint32 tabUserPtr; Uint32 tabUserRef; } m_dropTable; State tableStatus; }; typedef Ptr<Tablerec> TablerecPtr; struct storedProc { Uint32 storedLinkFirst; Uint32 storedLinkLast; Uint32 storedCounter; Uint32 nextPool; Uint16 storedCode; Uint16 storedProcLength; }; typedef Ptr<storedProc> StoredProcPtr; ArrayPool<storedProc> c_storedProcPool; /* **************************** TABLE_DESCRIPTOR RECORD ******************************** */ /* THIS VARIABLE IS USED TO STORE TABLE DESCRIPTIONS. A TABLE DESCRIPTION IS STORED AS A */ /* CONTIGUOS ARRAY IN THIS VARIABLE. WHEN A NEW TABLE IS ADDED A CHUNK IS ALLOCATED IN */ /* THIS RECORD. WHEN ATTRIBUTES ARE ADDED TO THE TABLE, A NEW CHUNK OF PROPER SIZE IS */ /* ALLOCATED AND ALL DATA IS COPIED TO THIS NEW CHUNK AND THEN THE OLD CHUNK IS PUT IN */ /* THE FREE LIST. EACH TABLE IS DESCRIBED BY A NUMBER OF TABLE DESCRIPTIVE ATTRIBUTES */ /* AND A NUMBER OF ATTRIBUTE DESCRIPTORS AS SHOWN IN FIGURE BELOW */ /* */ /* WHEN ALLOCATING A TABLE DESCRIPTOR THE SIZE IS ALWAYS A MULTIPLE OF 16 WORDS. */ /* */ /* ---------------------------------------------- */ /* | TRAILER USED FOR ALLOC/DEALLOC | */ /* ---------------------------------------------- */ /* | TABLE DESCRIPTIVE ATTRIBUTES | */ /* ---------------------------------------------- */ /* | ATTRIBUTE DESCRIPTION 1 | */ /* ---------------------------------------------- */ /* | ATTRIBUTE DESCRIPTION 2 | */ /* ---------------------------------------------- */ /* | | */ /* | | */ /* | | */ /* ---------------------------------------------- */ /* | ATTRIBUTE DESCRIPTION N | */ /* ---------------------------------------------- */ /* */ /* THE TABLE DESCRIPTIVE ATTRIBUTES CONTAINS THE FOLLOWING ATTRIBUTES: */ /* */ /* ---------------------------------------------- */ /* | HEADER (TYPE OF INFO) | */ /* ---------------------------------------------- */ /* | SIZE OF WHOLE CHUNK (INCL. TRAILER) | */ /* ---------------------------------------------- */ /* | TABLE IDENTITY | */ /* ---------------------------------------------- */ /* | FRAGMENT IDENTITY | */ /* ---------------------------------------------- */ /* | NUMBER OF ATTRIBUTES | */ /* ---------------------------------------------- */ /* | SIZE OF FIXED ATTRIBUTES | */ /* ---------------------------------------------- */ /* | NUMBER OF NULL FIELDS | */ /* ---------------------------------------------- */ /* | NOT USED | */ /* ---------------------------------------------- */ /* */ /* THESE ATTRIBUTES ARE ALL ONE R-VARIABLE IN THE RECORD. */ /* NORMALLY ONLY ONE TABLE DESCRIPTOR IS USED. DURING SCHEMA CHANGES THERE COULD */ /* HOWEVER EXIST MORE THAN ONE TABLE DESCRIPTION SINCE THE SCHEMA CHANGE OF VARIOUS */ /* FRAGMENTS ARE NOT SYNCHRONISED. THIS MEANS THAT ALTHOUGH THE SCHEMA HAS CHANGED */ /* IN ALL FRAGMENTS, BUT THE FRAGMENTS HAVE NOT REMOVED THE ATTRIBUTES IN THE SAME */ /* TIME-FRAME. THEREBY SOME ATTRIBUTE INFORMATION MIGHT DIFFER BETWEEN FRAGMENTS. */ /* EXAMPLES OF ATTRIBUTES THAT MIGHT DIFFER ARE SIZE OF FIXED ATTRIBUTES, NUMBER OF */ /* ATTRIBUTES, FIELD START WORD, START BIT. */ /* */ /* AN ATTRIBUTE DESCRIPTION CONTAINS THE FOLLOWING ATTRIBUTES: */ /* */ /* ---------------------------------------------- */ /* | Field Type, 4 bits (LSB Bits) | */ /* ---------------------------------------------- */ /* | Attribute Size, 4 bits | */ /* ---------------------------------------------- */ /* | NULL indicator 1 bit | */ /* ---------------------------------------------- */ /* | Indicator if TUP stores attr. 1 bit | */ /* ---------------------------------------------- */ /* | Not used 6 bits | */ /* ---------------------------------------------- */ /* | No. of elements in fixed array 16 bits | */ /* ---------------------------------------------- */ /* ---------------------------------------------- */ /* | Field Start Word, 21 bits (LSB Bits) | */ /* ---------------------------------------------- */ /* | NULL Bit, 11 bits | */ /* ---------------------------------------------- */ /* */ /* THE ATTRIBUTE SIZE CAN BE 1,2,4,8,16,32,64 AND 128 BITS. */ /* */ /* THE UNUSED PARTS OF THE RECORDS ARE PUT IN A LINKED LIST OF FREE PARTS. EACH OF */ /* THOSE FREE PARTS HAVE THREE RECORDS ASSIGNED AS SHOWN IN THIS STRUCTURE */ /* ALL FREE PARTS ARE SET INTO A CHUNK LIST WHERE EACH CHUNK IS AT LEAST 16 WORDS */ /* */ /* ---------------------------------------------- */ /* | HEADER = RNIL | */ /* ---------------------------------------------- */ /* | SIZE OF FREE AREA | */ /* ---------------------------------------------- */ /* | POINTER TO PREVIOUS FREE AREA | */ /* ---------------------------------------------- */ /* | POINTER TO NEXT FREE AREA | */ /* ---------------------------------------------- */ /* */ /* IF THE POINTER TO THE NEXT AREA IS RNIL THEN THIS IS THE LAST FREE AREA. */ /* */ /*****************************************************************************************/ struct TableDescriptor { Uint32 tabDescr; }; typedef Ptr<TableDescriptor> TableDescriptorPtr; struct HostBuffer { bool inPackedList; Uint32 packetLenTA; Uint32 noOfPacketsTA; Uint32 packetBufferTA[30]; }; typedef Ptr<HostBuffer> HostBufferPtr; /* **************** UNDO PAGE RECORD ******************* */ /* THIS RECORD FORMS AN UNDO PAGE CONTAINING A NUMBER OF */ /* DATA WORDS. CURRENTLY THERE ARE 2048 WORDS ON A PAGE */ /* EACH OF 32 BITS (4 BYTES) WHICH FORMS AN UNDO PAGE */ /* WITH A TOTAL OF 8192 BYTES */ /* ***************************************************** */ struct UndoPage { Uint32 undoPageWord[ZWORDS_ON_PAGE]; /* 32 KB */ }; typedef Ptr<UndoPage> UndoPagePtr; /* * Build index operation record. */ struct BuildIndexRec { // request cannot use signal class due to extra members Uint32 m_request[BuildIndxReq::SignalLength]; Uint32 m_triggerPtrI; // the index trigger Uint32 m_fragNo; // fragment number under Tablerec Uint32 m_pageId; // logical fragment page id Uint32 m_tupleNo; // tuple number on page (pageIndex >> 1) BuildIndxRef::ErrorCode m_errorCode; union { Uint32 nextPool; Uint32 nextList; }; Uint32 prevList; }; typedef Ptr<BuildIndexRec> BuildIndexPtr; ArrayPool<BuildIndexRec> c_buildIndexPool; ArrayList<BuildIndexRec> c_buildIndexList; Uint32 c_noOfBuildIndexRec; public: Dbtup(const class Configuration &); virtual ~Dbtup(); /* * TUX uses logical tuple address when talking to ACC and LQH. */ void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32& tupAddr); /* * TUX index in TUP has single Uint32 array attribute which stores an * index node. TUX reads and writes the node directly via pointer. */ int tuxAllocNode(Signal* signal, Uint32 fragPtrI, Uint32& pageId, Uint32& pageOffset, Uint32*& node); void tuxFreeNode(Signal* signal, Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* node); void tuxGetNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32*& node); /* * TUX reads primary table attributes for index keys. Tuple is * specified by location of original tuple and version number. Input * is attribute ids in AttributeHeader format. Output is attribute * data with headers. Uses readAttributes with xfrm option set. * Returns number of words or negative (-terrorCode) on error. */ int tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut); /* * TUX reads primary key without headers into an array of words. Used * for md5 summing and when returning keyinfo. Returns number of * words or negative (-terrorCode) on error. */ int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut); /* * TUX checks if tuple is visible to scan. */ bool tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId); private: BLOCK_DEFINES(Dbtup); // Transit signals void execDEBUG_SIG(Signal* signal); void execCONTINUEB(Signal* signal); // Received signals void execDUMP_STATE_ORD(Signal* signal); void execSEND_PACKED(Signal* signal); void execSTTOR(Signal* signal); void execTUP_LCPREQ(Signal* signal); void execEND_LCPREQ(Signal* signal); void execSTART_RECREQ(Signal* signal); void execMEMCHECKREQ(Signal* signal); void execTUPSEIZEREQ(Signal* signal); void execTUPRELEASEREQ(Signal* signal); void execSTORED_PROCREQ(Signal* signal); void execTUPFRAGREQ(Signal* signal); void execTUP_ADD_ATTRREQ(Signal* signal); void execTUP_COMMITREQ(Signal* signal); void execTUP_ABORTREQ(Signal* signal); void execTUP_SRREQ(Signal* signal); void execTUP_PREPLCPREQ(Signal* signal); void execFSOPENCONF(Signal* signal); void execFSOPENREF(Signal* signal); void execFSCLOSECONF(Signal* signal); void execFSCLOSEREF(Signal* signal); void execFSWRITECONF(Signal* signal); void execFSWRITEREF(Signal* signal); void execFSREADCONF(Signal* signal); void execFSREADREF(Signal* signal); void execNDB_STTOR(Signal* signal); void execREAD_CONFIG_REQ(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execDROP_TAB_REQ(Signal* signal); void execALTER_TAB_REQ(Signal* signal); void execFSREMOVECONF(Signal* signal); void execFSREMOVEREF(Signal* signal); void execTUP_ALLOCREQ(Signal* signal); void execTUP_DEALLOCREQ(Signal* signal); void execTUP_WRITELOG_REQ(Signal* signal); // Ordered index related void execBUILDINDXREQ(Signal* signal); void buildIndex(Signal* signal, Uint32 buildPtrI); void buildIndexReply(Signal* signal, const BuildIndexRec* buildRec); //------------------------------------------------------------------ //------------------------------------------------------------------ // Methods to handle execution of TUPKEYREQ + ATTRINFO. // // Module Execution Manager // // The TUPKEYREQ signal is central to this block. This signal is used // by everybody that needs to read data residing in DBTUP. The data is // read using an interpreter approach. // // Operations only needing to read execute a simplified version of the // interpreter where the only instruction is read Attribute to send. // Operations only needing to update the record (insert or update) // execute a simplified version of the interpreter where the only // instruction is write Attribute. // // Currently TUPKEYREQ is used in the following situations. // 1) Normal transaction execution. Can be any of the types described // below. // 2) Execution of fragment redo log during system restart. // In this situation there will only be normal updates, inserts // and deletes performed. // 3) A special type of normal transaction execution is to write the // records arriving from the primary replica in the node restart // processing. This will always be normal write operations which // are translated to inserts or updates before arriving to TUP. // 4) Scan processing. The scan processing will use normal reads or // interpreted reads in their execution. There will be one TUPKEYREQ // signal for each record processed. // 5) Copy fragment processing. This is a special type of scan used in the // primary replica at system restart. It reads the entire reads and // converts those to writes to the starting node. In this special case // LQH acts as an API node and receives also the ATTRINFO sent in the // TRANSID_AI signals. // // Signal Diagram: // // In Signals: // ----------- // // Logically there is one request TUPKEYREQ which requests to read/write data // of one tuple in the database. Since the definition of what to read and write // can be bigger than the maximum signal size we segment the signal. The definition // of what to read/write/interpreted program is sent before the TUPKEYREQ signal. // // ---> ATTRINFO // ... // ---> ATTRINFO // ---> TUPKEYREQ // The number of ATTRINFO signals can be anything between 0 and upwards. // The total size of the ATTRINFO is not allowed to be more than 16384 words. // There is always one and only one TUPKEYREQ. // // Response Signals (successful case): // // Simple/Dirty Read Operation // --------------------------- // // <---- TRANSID_AI (to API) // ... // <---- TRANSID_AI (to API) // <---- READCONF (to API) // <---- TUPKEYCONF (to LQH) // There is always exactly one READCONF25 sent last. The number of // TRANSID_AI is dependent on how much that was read. The maximum size // of the ATTRINFO sent back is 16384 words. The signals are sent // directly to the application with an address provided by the // TUPKEYREQ signal. // A positive response signal is also sent to LQH. // // Normal Read Operation // --------------------- // // <---- TRANSID_AI (to API) // ... // <---- TRANSID_AI (to API) // <---- TUPKEYCONF (to LQH) // The number of TRANSID_AI is dependent on how much that was read. // The maximum size of the ATTRINFO sent back is 16384 words. The // signals are sent directly to the application with an address // provided by the TUPKEYREQ signal. // A positive response signal is also sent to LQH. // // Normal update/insert/delete operation // ------------------------------------- // // <---- TUPKEYCONF // After successful updating of the tuple LQH is informed of this. // // Delete with read // ---------------- // // Will behave as a normal read although it also prepares the // deletion of the tuple. // // Interpreted Update // ------------------ // // <---- TRANSID_AI (to API) // ... // <---- TRANSID_AI (to API) // <---- TUP_ATTRINFO (to LQH) // ... // <---- TUP_ATTRINFO (to LQH) // <---- TUPKEYCONF (to LQH) // // The interpreted Update contains five sections: // The first section performs read Attribute operations // that send results back to the API. // // The second section executes the interpreted program // where data from attributes can be updated and it // can also read attribute values into the registers. // // The third section performs unconditional updates of // attributes. // // The fourth section can read the attributes to be sent to the // API after updating the record. // // The fifth section contains subroutines used by the interpreter // in the second section. // // All types of interpreted programs contains the same five sections. // The only difference is that only interpreted updates can update // attributes. Interpreted inserts are not allowed. // // Interpreted Updates have to send back the information about the // attributes they have updated. This information will be shipped to // the log and also to any other replicas. Thus interpreted updates // are only performed in the primary replica. The fragment redo log // in LQH will contain information so that normal update/inserts/deletes // can be performed using TUPKEYREQ. // // Interpreted Read // ---------------- // // From a signalling point of view the Interpreted Read behaves as // as a Normal Read. The interpreted Read is often used by Scan's. // // Interpreted Delete // ------------------ // // <---- TUPKEYCONF // After successful prepartion to delete the tuple LQH is informed // of this. // // Interpreted Delete with Read // ---------------------------- // // From a signalling point of view an interpreted delete with read // behaves as a normal read. // // Continuation after successful case: // // After a read of any kind the operation record is ready to be used // again by a new operation. // // Any updates, inserts or deletes waits for either of two messages. // A commit specifying that the operation is to be performed for real // or an abort specifying that the operation is to be rolled back and // the record to be restored in its original format. // // This is handled by the module Transaction Manager. // // Response Signals (unsuccessful case): // // <---- TUPKEYREF (to LQH) // A signal is sent back to LQH informing about the unsuccessful // operation. In this case TUP waits for an abort signal to arrive // before the operation record is ready for the next operation. // This is handled by the Transaction Manager. //------------------------------------------------------------------ //------------------------------------------------------------------ // ***************************************************************** // Signal Reception methods. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ void execTUPKEYREQ(Signal* signal); //------------------------------------------------------------------ //------------------------------------------------------------------ void execATTRINFO(Signal* signal); // Trigger signals //------------------------------------------------------------------ //------------------------------------------------------------------ void execCREATE_TRIG_REQ(Signal* signal); //------------------------------------------------------------------ //------------------------------------------------------------------ void execDROP_TRIG_REQ(Signal* signal); // ***************************************************************** // Support methods for ATTRINFO. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ void handleATTRINFOforTUPKEYREQ(Signal* signal, Uint32 length, Operationrec * const regOperPtr); // ***************************************************************** // Setting up the environment for reads, inserts, updates and deletes. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ int handleReadReq(Signal* signal, Operationrec* const regOperPtr, Tablerec* const regTabPtr, Page* pagePtr); //------------------------------------------------------------------ //------------------------------------------------------------------ int handleUpdateReq(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr, Page* const pagePtr); //------------------------------------------------------------------ //------------------------------------------------------------------ int handleInsertReq(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr, Page* const pagePtr); //------------------------------------------------------------------ //------------------------------------------------------------------ int handleDeleteReq(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr, Page* const pagePtr); //------------------------------------------------------------------ //------------------------------------------------------------------ int updateStartLab(Signal* signal, Operationrec* const regOperPtr, Tablerec* const regTabPtr, Page* const pagePtr); // ***************************************************************** // Interpreter Handling methods. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ int interpreterStartLab(Signal* signal, Page* const pagePtr, Uint32 TupHeadOffset); //------------------------------------------------------------------ //------------------------------------------------------------------ int interpreterNextLab(Signal* signal, Page* const pagePtr, Uint32 TupHeadOffset, Uint32* logMemory, Uint32* mainProgram, Uint32 TmainProgLen, Uint32* subroutineProg, Uint32 TsubroutineLen, Uint32 * tmpArea, Uint32 tmpAreaSz); // ***************************************************************** // Signal Sending methods. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ void sendReadAttrinfo(Signal* signal, Uint32 TnoOfData, const Operationrec * const regOperPtr); //------------------------------------------------------------------ //------------------------------------------------------------------ void sendLogAttrinfo(Signal* signal, Uint32 TlogSize, Operationrec * const regOperPtr); //------------------------------------------------------------------ //------------------------------------------------------------------ void sendTUPKEYCONF(Signal* signal, Operationrec * const regOperPtr, Uint32 TlogSize); //------------------------------------------------------------------ //------------------------------------------------------------------ // ***************************************************************** // The methods that perform the actual read and update of attributes // in the tuple. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ int readAttributes(Page* const pagePtr, Uint32 TupHeadOffset, const Uint32* inBuffer, Uint32 inBufLen, Uint32* outBuffer, Uint32 TmaxRead, bool xfrmFlag); //------------------------------------------------------------------ //------------------------------------------------------------------ int readAttributesWithoutHeader(Page* const pagePtr, Uint32 TupHeadOffset, Uint32* inBuffer, Uint32 inBufLen, Uint32* outBuffer, Uint32* attrBuffer, Uint32 TmaxRead); //------------------------------------------------------------------ //------------------------------------------------------------------ int updateAttributes(Page* const pagePtr, Uint32 TupHeadOffset, Uint32* inBuffer, Uint32 inBufLen); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readFixedSizeTHOneWordNotNULL(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readFixedSizeTHTwoWordNotNULL(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateFixedSizeTHTwoWordNotNULL(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readFixedSizeTHManyWordNotNULL(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readFixedSizeTHOneWordNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateFixedSizeTHOneWordNULLable(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readFixedSizeTHTwoWordNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateFixedSizeTHTwoWordNULLable(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readFixedSizeTHManyWordNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readFixedSizeTHZeroWordNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateFixedSizeTHManyWordNULLable(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readVariableSizedAttr(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateVariableSizedAttr(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readVarSizeUnlimitedNotNULL(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateVarSizeUnlimitedNotNULL(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readVarSizeUnlimitedNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateVarSizeUnlimitedNULLable(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readBigVarSizeNotNULL(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateBigVarSizeNotNULL(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readBigVarSizeNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateBigVarSizeNULLable(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readSmallVarSizeNotNULL(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateSmallVarSizeNotNULL(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readSmallVarSizeNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateSmallVarSizeNULLable(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readDynFixedSize(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateDynFixedSize(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readDynVarSizeUnlimited(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateDynVarSizeUnlimited(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readDynBigVarSize(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateDynBigVarSize(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool readDynSmallVarSize(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool updateDynSmallVarSize(Uint32* inBuffer, Uint32 attrDescriptor, Uint32 attrDes2); // ***************************************************************** // Read char routines optionally (tXfrmFlag) apply strxfrm // ***************************************************************** bool readCharNotNULL(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); bool readCharNULLable(Uint32* outBuffer, AttributeHeader* ahOut, Uint32 attrDescriptor, Uint32 attrDes2); //------------------------------------------------------------------ //------------------------------------------------------------------ bool nullFlagCheck(Uint32 attrDes2); Uint32 read_psuedo(Uint32 attrId, Uint32* outBuffer); //------------------------------------------------------------------ //------------------------------------------------------------------ void setUpQueryRoutines(Tablerec* const regTabPtr); // ***************************************************************** // Service methods. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ void copyAttrinfo(Signal* signal, Operationrec * const regOperPtr, Uint32* inBuffer); //------------------------------------------------------------------ //------------------------------------------------------------------ void initOpConnection(Operationrec* regOperPtr, Fragrecord*); //------------------------------------------------------------------ //------------------------------------------------------------------ void initOperationrec(Signal* signal); //------------------------------------------------------------------ //------------------------------------------------------------------ int initStoredOperationrec(Operationrec* const regOperPtr, Uint32 storedId); //------------------------------------------------------------------ //------------------------------------------------------------------ void insertActiveOpList(Signal* signal, OperationrecPtr regOperPtr, Page * const pagePtr, Uint32 pageOffset); //------------------------------------------------------------------ //------------------------------------------------------------------ void linkOpIntoFragList(OperationrecPtr regOperPtr, Fragrecord* const regFragPtr); //------------------------------------------------------------------ //------------------------------------------------------------------ void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen); //------------------------------------------------------------------ // Trigger handling routines //------------------------------------------------------------------ ArrayList<TupTriggerData>* findTriggerList(Tablerec* table, TriggerType::Value ttype, TriggerActionTime::Value ttime, TriggerEvent::Value tevent); bool createTrigger(Tablerec* table, const CreateTrigReq* req); Uint32 dropTrigger(Tablerec* table, const DropTrigReq* req); void checkImmediateTriggersAfterInsert(Signal* signal, Operationrec* const regOperPtr, Tablerec* const tablePtr); void checkImmediateTriggersAfterUpdate(Signal* signal, Operationrec* const regOperPtr, Tablerec* const tablePtr); void checkImmediateTriggersAfterDelete(Signal* signal, Operationrec* const regOperPtr, Tablerec* const tablePtr); #if 0 void checkDeferredTriggers(Signal* signal, Operationrec* const regOperPtr, Tablerec* const regTablePtr); #endif void checkDetachedTriggers(Signal* signal, Operationrec* const regOperPtr, Tablerec* const regTablePtr); void fireImmediateTriggers(Signal* signal, ArrayList<TupTriggerData>& triggerList, Operationrec* const regOperPtr); void fireDeferredTriggers(Signal* signal, ArrayList<TupTriggerData>& triggerList, Operationrec* const regOperPtr); void fireDetachedTriggers(Signal* signal, ArrayList<TupTriggerData>& triggerList, Operationrec* const regOperPtr); void executeTriggers(Signal* signal, ArrayList<TupTriggerData>& triggerList, Operationrec* const regOperPtr); void executeTrigger(Signal* signal, TupTriggerData* const trigPtr, Operationrec* const regOperPtr); bool readTriggerInfo(TupTriggerData* const trigPtr, Operationrec* const regOperPtr, Uint32* const keyBuffer, Uint32& noPrimKey, Uint32* const mainBuffer, Uint32& noMainWords, Uint32* const copyBuffer, Uint32& noCopyWords); void sendTrigAttrInfo(Signal* signal, Uint32* data, Uint32 dataLen, bool executeDirect, BlockReference receiverReference); Uint32 setAttrIds(Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask, Uint32 noOfAttributes, Uint32* inBuffer); void sendFireTrigOrd(Signal* signal, Operationrec * const regOperPtr, TupTriggerData* const trigPtr, Uint32 noPrimKeySignals, Uint32 noBeforeSignals, Uint32 noAfterSignals); bool primaryKey(Tablerec* const, Uint32); // these set terrorCode and return non-zero on error int executeTuxInsertTriggers(Signal* signal, Operationrec* const regOperPtr, Tablerec* const regTabPtr); int executeTuxUpdateTriggers(Signal* signal, Operationrec* const regOperPtr, Tablerec* const regTabPtr); int executeTuxDeleteTriggers(Signal* signal, Operationrec* const regOperPtr, Tablerec* const regTabPtr); // these crash the node on error void executeTuxCommitTriggers(Signal* signal, Operationrec* regOperPtr, Tablerec* const regTabPtr); void executeTuxAbortTriggers(Signal* signal, Operationrec* regOperPtr, Tablerec* const regTabPtr); // ***************************************************************** // Error Handling routines. // ***************************************************************** //------------------------------------------------------------------ //------------------------------------------------------------------ int TUPKEY_abort(Signal* signal, int error_type); //------------------------------------------------------------------ //------------------------------------------------------------------ void tupkeyErrorLab(Signal* signal); //------------------------------------------------------------------ //------------------------------------------------------------------ // Methods to handle execution of TUP_COMMITREQ + TUP_ABORTREQ. // // Module Transaction Manager // // The Transaction Manager module is responsible for the commit // and abort of operations started by the Execution Manager. // // Commit Operation: // ---------------- // // Failures in commit processing is not allowed since that would // leave the database in an unreliable state. Thus the only way // to handle failures in commit processing is to crash the node. // // TUP_COMMITREQ can only be received in the wait state after a // successful TUPKEYREQ which was not a read operation. // // Commit of Delete: // ----------------- // // This will actually perform the deletion of the record unless // other operations also are connected to the record. In this case // we will set the delete state on the record that becomes the owner // of the record. // // Commit of Update: // ---------------- // // We will release the copy record where the original record was kept. // Also here we will take special care if more operations are updating // the record simultaneously. // // Commit of Insert: // ----------------- // // Will simply reset the state of the operation record. // // Signal Diagram: // ---> TUP_COMMITREQ (from LQH) // <---- TUP_COMMITCONF (to LQH) // // // Abort Operation: // ---------------- // // Signal Diagram: // ---> TUP_ABORTREQ (from LQH) // <---- TUP_ABORTCONF (to LQH) // // Failures in abort processing is not allowed since that would // leave the database in an unreliable state. Thus the only way // to handle failures in abort processing is to crash the node. // // Abort messages can arrive at any time. It can arrive even before // anything at all have arrived of the operation. It can arrive after // receiving a number of ATTRINFO but before TUPKEYREQ has been received. // It must arrive after that we sent TUPKEYREF in response to TUPKEYREQ // and finally it can arrive after successfully performing the TUPKEYREQ // in all cases including the read case. //------------------------------------------------------------------ //------------------------------------------------------------------ #if 0 void checkPages(Fragrecord* const regFragPtr); #endif void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit); bool checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr); void setNullBits(Page* const regPage, Tablerec* const regTabPtr, Uint32 pageOffset); bool checkNullAttributes(Operationrec* const, Tablerec* const); bool getPage(PagePtr& pagePtr, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr); bool getPageLastCommitted(Operationrec* const regOperPtr, Operationrec* const leaderOpPtr); bool getPageThroughSavePoint(Operationrec* const regOperPtr, Operationrec* const leaderOpPtr); Uint32 calculateChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize); void setChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize); void commitSimple(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr); void commitRecord(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr); void setTupleStatesSetOpType(Operationrec* const regOperPtr, Page* const pagePtr, Uint32& opType, OperationrecPtr& firstOpPtr); void findBeforeValueOperation(OperationrecPtr& befOpPtr, OperationrecPtr firstOpPtr); void calculateChangeMask(Page* const PagePtr, Tablerec* const regTabPtr, Uint32 pageOffset, Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask); void updateGcpId(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr); void abortUpdate(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr); void commitUpdate(Signal* signal, Operationrec* const regOperPtr, Fragrecord* const regFragPtr, Tablerec* const regTabPtr); void setTupleStateOnPreviousOps(Uint32 prevOpIndex); void copyMem(Signal* signal, Uint32 sourceIndex, Uint32 destIndex); void freeAllAttrBuffers(Operationrec* const regOperPtr); void freeAttrinbufrec(Uint32 anAttrBufRec); void removeActiveOpList(Operationrec* const regOperPtr); void updatePackedList(Signal* signal, Uint16 ahostIndex); void setUpDescriptorReferences(Uint32 descriptorReference, Tablerec* const regTabPtr, const Uint32* offset); void setUpKeyArray(Tablerec* const regTabPtr); bool addfragtotab(Tablerec* const regTabPtr, Uint32 fragId, Uint32 fragIndex); void deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId); void releaseTabDescr(Tablerec* const regTabPtr); void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* const regTabPtr); void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32); void initializeAttrbufrec(); void initializeCheckpointInfoRec(); void initializeDiskBufferSegmentRecord(); void initializeFragoperrec(); void initializeFragrecord(); void initializeHostBuffer(); void initializeLocalLogInfo(); void initializeOperationrec(); void initializePendingFileOpenInfoRecord(); void initializeRestartInfoRec(); void initializeTablerec(); void initializeTabDescr(); void initializeUndoPage(); void initTab(Tablerec* const regTabPtr); void startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2); void fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr); void fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr); void fragrefuse2Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr); void fragrefuse3Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr, Tablerec* const regTabPtr, Uint32 fragId); void fragrefuse4Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr, Tablerec* const regTabPtr, Uint32 fragId); void addattrrefuseLab(Signal* signal, FragrecordPtr regFragPtr, FragoperrecPtr fragOperPtr, Tablerec* const regTabPtr, Uint32 fragId); void checkLcpActiveBufferPage(Uint32 minPageNotWrittenInCheckpoint, DiskBufferSegmentInfoPtr dbsiPtr); void lcpWriteListDataPageSegment(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, CheckpointInfoPtr ciPtr, bool flushFlag); void lcpFlushLogLab(Signal* signal, CheckpointInfoPtr ciPtr); void lcpClosedDataFileLab(Signal* signal, CheckpointInfoPtr ciPtr); void lcpEndconfLab(Signal* signal); void lcpSaveDataPageLab(Signal* signal, Uint32 ciIndex); void lcpCompletedLab(Signal* signal, Uint32 ciIndex); void lcpFlushRestartInfoLab(Signal* signal, Uint32 ciIndex); void lcpSaveCopyListLab(Signal* signal, CheckpointInfoPtr ciPtr); void sendFSREMOVEREQ(Signal* signal, TablerecPtr tabPtr); void releaseFragment(Signal* signal, Uint32 tableId); void allocDataBufferSegment(Signal* signal, DiskBufferSegmentInfoPtr& dbsiPtr); void allocRestartUndoBufferSegment(Signal* signal, DiskBufferSegmentInfoPtr& dbsiPtr, LocalLogInfoPtr lliPtr); void freeDiskBufferSegmentRecord(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr); void freeUndoBufferPages(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr); void releaseCheckpointInfoRecord(CheckpointInfoPtr ciPtr); void releaseDiskBufferSegmentRecord(DiskBufferSegmentInfoPtr dbsiPtr); void releaseFragoperrec(FragoperrecPtr fragOperPtr); void releaseFragrec(FragrecordPtr regFragPtr); void releasePendingFileOpenInfoRecord(PendingFileOpenInfoPtr pfoPtr); void releaseRestartInfoRecord(RestartInfoRecordPtr riPtr); void seizeDiskBufferSegmentRecord(DiskBufferSegmentInfoPtr& dbsiPtr); void seizeCheckpointInfoRecord(CheckpointInfoPtr& ciPtr); void seizeFragoperrec(FragoperrecPtr& fragOperPtr); void seizeFragrecord(FragrecordPtr& regFragPtr); void seizeOpRec(OperationrecPtr& regOperPtr); void seizePendingFileOpenInfoRecord(PendingFileOpenInfoPtr& pfoiPtr); void seizeRestartInfoRecord(RestartInfoRecordPtr& riPtr); // Initialisation void initData(); void initRecords(); void rfrClosedDataFileLab(Signal* signal, Uint32 restartIndex); void rfrCompletedLab(Signal* signal, RestartInfoRecordPtr riPtr); void rfrInitRestartInfoLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr); void rfrLoadDataPagesLab(Signal* signal, RestartInfoRecordPtr riPtr, DiskBufferSegmentInfoPtr dbsiPtr); void rfrReadFirstUndoSegment(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr); void rfrReadNextDataSegment(Signal* signal, RestartInfoRecordPtr riPtr, DiskBufferSegmentInfoPtr dbsiPtr); void rfrReadNextUndoSegment(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr); void rfrReadRestartInfoLab(Signal* signal, RestartInfoRecordPtr riPtr); void rfrReadSecondUndoLogLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr); void startExecUndoLogLab(Signal* signal, Uint32 lliIndex); void readExecUndoLogLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr); void closeExecUndoLogLab(Signal* signal, LocalLogInfoPtr lliPtr); void endExecUndoLogLab(Signal* signal, Uint32 lliIndex); struct XlcStruct { Uint32 PageId; Uint32 PageIndex; Uint32 LogRecordType; Uint32 FragId; FragrecordPtr FragPtr; LocalLogInfoPtr LliPtr; DiskBufferSegmentInfoPtr DbsiPtr; UndoPagePtr UPPtr; TablerecPtr TabPtr; }; void xlcGetNextRecordLab(Signal* signal, DiskBufferSegmentInfoPtr dbsiPtr, LocalLogInfoPtr lliPtr); void xlcRestartCompletedLab(Signal* signal); void xlcCopyData(XlcStruct& xlcStruct, Uint32 pageOffset, Uint32 noOfWords, PagePtr pagePtr); void xlcGetLogHeader(XlcStruct& xlcStruct); Uint32 xlcGetLogWord(XlcStruct& xlcStruct); void xlcAbortInsert(Signal* signal, XlcStruct& xlcStruct); void xlcAbortUpdate(Signal* signal, XlcStruct& xlcStruct); void xlcDeleteTh(XlcStruct& xlcStruct); void xlcIndicateNoOpActive(XlcStruct& xlcStruct); void xlcInsertTh(XlcStruct& xlcStruct); void xlcTableDescriptor(XlcStruct& xlcStruct); void xlcUndoLogPageHeader(XlcStruct& xlcStruct); void xlcUpdateTh(XlcStruct& xlcStruct); void xlcUpdateGCI(XlcStruct& xlcStruct); void cprAddData(Signal* signal, Fragrecord* const regFragPtr, Uint32 pageIndex, Uint32 noOfWords, Uint32 startOffset); void cprAddGCIUpdate(Signal* signal, Uint32 prevGCI, Fragrecord* const regFragPtr); void cprAddLogHeader(Signal* signal, LocalLogInfo* const lliPtr, Uint32 recordType, Uint32 tableId, Uint32 fragId); void cprAddUndoLogPageHeader(Signal* signal, Page* const regPagePtr, Fragrecord* const regFragPtr); void cprAddUndoLogRecord(Signal* signal, Uint32 recordType, Uint32 pageId, Uint32 pageIndex, Uint32 tableId, Uint32 fragId, Uint32 localLogIndex); void cprAddAbortUpdate(Signal* signal, LocalLogInfo* const lliPtr, Operationrec* const regOperPtr); void cprAddUndoLogWord(Signal* signal, LocalLogInfo* const lliPtr, Uint32 undoWord); bool isUndoLoggingNeeded(Fragrecord* const regFragPtr, Uint32 pageId); bool isUndoLoggingActive(Fragrecord* const regFragPtr); bool isUndoLoggingBlocked(Fragrecord* const regFragPtr); bool isPageUndoLogged(Fragrecord* const regFragPtr, Uint32 pageId); void seizeUndoBufferSegment(Signal* signal, UndoPagePtr& regUndoPagePtr); void lcpWriteUndoSegment(Signal* signal, LocalLogInfo* const lliPtr, bool flushFlag); void deleteScanProcedure(Signal* signal, Operationrec* regOperPtr); void copyProcedure(Signal* signal, TablerecPtr regTabPtr, Operationrec* regOperPtr); void scanProcedure(Signal* signal, Operationrec* regOperPtr, Uint32 lenAttrInfo); void storedSeizeAttrinbufrecErrorLab(Signal* signal, Operationrec* regOperPtr); bool storedProcedureAttrInfo(Signal* signal, Operationrec* regOperPtr, Uint32 length, Uint32 firstWord, bool copyProc); //----------------------------------------------------------------------------- // Table Descriptor Memory Manager //----------------------------------------------------------------------------- // Public methods Uint32 getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset); Uint32 allocTabDescr(const Tablerec* regTabPtr, Uint32* offset); void freeTabDescr(Uint32 retRef, Uint32 retNo); Uint32 getTabDescrWord(Uint32 index); void setTabDescrWord(Uint32 index, Uint32 word); // Private methods Uint32 sizeOfReadFunction(); void removeTdArea(Uint32 tabDesRef, Uint32 list); void insertTdArea(Uint32 sizeOfChunk, Uint32 tabDesRef, Uint32 list); Uint32 itdaMergeTabDescr(Uint32 retRef, Uint32 retNo); //------------------------------------------------------------------------------------------------------ // Page Memory Manager //------------------------------------------------------------------------------------------------------ // Public methods void allocConsPages(Uint32 noOfPagesToAllocate, Uint32& noOfPagesAllocated, Uint32& allocPageRef); void returnCommonArea(Uint32 retPageRef, Uint32 retNo); void initializePage(); // Private methods void removeCommonArea(Uint32 remPageRef, Uint32 list); void insertCommonArea(Uint32 insPageRef, Uint32 list); void findFreeLeftNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate); void findFreeRightNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate); Uint32 nextHigherTwoLog(Uint32 input); // Private data Uint32 cfreepageList[16]; //------------------------------------------------------------------------------------------------------ // Page Mapper, convert logical page id's to physical page id's // The page mapper also handles the pages allocated to the fragment. //------------------------------------------------------------------------------------------------------ // // Public methods Uint32 getRealpid(Fragrecord* const regFragPtr, Uint32 logicalPageId); Uint32 getNoOfPages(Fragrecord* const regFragPtr); void initPageRangeSize(Uint32 size); bool insertPageRangeTab(Fragrecord* const regFragPtr, Uint32 startPageId, Uint32 noPages); void releaseFragPages(Fragrecord* const regFragPtr); void initFragRange(Fragrecord* const regFragPtr); void initializePageRange(); Uint32 getEmptyPage(Fragrecord* const regFragPtr); Uint32 allocFragPages(Fragrecord* const regFragPtr, Uint32 noOfPagesAllocated); // Private methods Uint32 leafPageRangeFull(Fragrecord* const regFragPtr, PageRangePtr currPageRangePtr); void releasePagerange(PageRangePtr regPRPtr); void seizePagerange(PageRangePtr& regPageRangePtr); void errorHandler(Uint32 errorCode); void allocMoreFragPages(Fragrecord* const regFragPtr); // Private data Uint32 cfirstfreerange; PageRange *pageRange; Uint32 c_noOfFreePageRanges; Uint32 cnoOfPageRangeRec; //------------------------------------------------------------------------------------------------------ // Fixed Allocator // Allocates and deallocates tuples of fixed size on a fragment. //------------------------------------------------------------------------------------------------------ // // Public methods bool allocTh(Fragrecord* const regFragPtr, Tablerec* const regTabPtr, Uint32 pageType, Signal* signal, Uint32& pageOffset, PagePtr& pagePtr); void freeThSr(Tablerec* const regTabPtr, Page* const regPagePtr, Uint32 freePageOffset); void freeTh(Fragrecord* const regFragPtr, Tablerec* const regTabPtr, Signal* signal, Page* const regPagePtr, Uint32 freePageOffset); void getThAtPageSr(Page* const regPagePtr, Uint32& pageOffset); // Private methods void convertThPage(Uint32 Tupheadsize, Page* const regPagePtr); void getThAtPage(Fragrecord* const regFragPtr, Page* const regPagePtr, Signal* signal, Uint32& pageOffset); void getEmptyPageThCopy(Fragrecord* const regFragPtr, Signal* signal, Page* const regPagePtr); void getEmptyPageTh(Fragrecord* const regFragPtr, Signal* signal, Page* const regPagePtr); //------------------------------------------------------------------------------------------------------ // Temporary variables used for storing commonly used variables in certain modules //------------------------------------------------------------------------------------------------------ FragrecordPtr fragptr; OperationrecPtr operPtr; TablerecPtr tabptr; // readAttributes and updateAttributes module Uint32 tCheckOffset; Uint32 tMaxRead; Uint32 tOutBufIndex; Uint32* tTupleHeader; bool tXfrmFlag; // updateAttributes module Uint32 tInBufIndex; Uint32 tInBufLen; Uint32 terrorCode; //------------------------------------------------------------------------------------------------------ // Common stored variables. Variables that have a valid value always. //------------------------------------------------------------------------------------------------------ Uint32 cnoOfLcpRec; Uint32 cnoOfParallellUndoFiles; Uint32 cnoOfUndoPage; Attrbufrec *attrbufrec; Uint32 cfirstfreeAttrbufrec; Uint32 cnoOfAttrbufrec; Uint32 cnoFreeAttrbufrec; CheckpointInfo *checkpointInfo; Uint32 cfirstfreeLcp; DiskBufferSegmentInfo *diskBufferSegmentInfo; Uint32 cfirstfreePdx; Uint32 cnoOfConcurrentWriteOp; Fragoperrec *fragoperrec; Uint32 cfirstfreeFragopr; Uint32 cnoOfFragoprec; Fragrecord *fragrecord; Uint32 cfirstfreefrag; Uint32 cnoOfFragrec; HostBuffer *hostBuffer; LocalLogInfo *localLogInfo; Uint32 cnoOfLocalLogInfo; Uint32 cfirstfreeOprec; Operationrec *operationrec; Uint32 cnoOfOprec; Page *page; Uint32 cnoOfPage; Uint32 cnoOfAllocatedPages; PendingFileOpenInfo *pendingFileOpenInfo; Uint32 cfirstfreePfo; Uint32 cnoOfConcurrentOpenOp; RestartInfoRecord *restartInfoRecord; Uint32 cfirstfreeSri; Uint32 cnoOfRestartInfoRec; Tablerec *tablerec; Uint32 cnoOfTablerec; TableDescriptor *tableDescriptor; Uint32 cnoOfTabDescrRec; UndoPage *undoPage; Uint32 cfirstfreeUndoSeg; Int32 cnoFreeUndoSeg; Uint32 cnoOfDataPagesToDiskWithoutSynch; Uint32 cdata[32]; Uint32 cdataPages[16]; Uint32 cpackedListIndex; Uint32 cpackedList[MAX_NODES]; Uint32 cfreeTdList[16]; Uint32 clastBitMask; Uint32 clblPageCounter; Uint32 clblPagesPerTick; Uint32 clblPagesPerTickAfterSr; BlockReference clqhBlockref; Uint32 clqhUserpointer; Uint32 cminusOne; BlockReference cndbcntrRef; Uint32 cundoFileVersion; BlockReference cownref; Uint32 cownNodeId; Uint32 czero; // A little bit bigger to cover overwrites in copy algorithms (16384 real size). #define ZATTR_BUFFER_SIZE 16384 Uint32 clogMemBuffer[ZATTR_BUFFER_SIZE + 16]; Uint32 coutBuffer[ZATTR_BUFFER_SIZE + 16]; Uint32 cinBuffer[ZATTR_BUFFER_SIZE + 16]; Uint32 totNoOfPagesAllocated; // Trigger variables Uint32 c_maxTriggersPerTable; // Counters for num UNDO log records executed Uint32 cSrUndoRecords[9]; STATIC_CONST(MAX_PARALLELL_TUP_SRREQ = 2); Uint32 c_sr_free_page_0; Uint32 c_errorInsert4000TableId; void initGlobalTemporaryVars(); void reportMemoryUsage(Signal* signal, int incDec); #ifdef VM_TRACE struct Th { Uint32 data[1]; }; friend class NdbOut& operator<<(NdbOut&, const Operationrec&); friend class NdbOut& operator<<(NdbOut&, const Th&); #endif }; inline bool Dbtup::isUndoLoggingNeeded(Fragrecord* const regFragPtr, Uint32 pageId) { if ((regFragPtr->checkpointVersion != RNIL) && (pageId >= regFragPtr->minPageNotWrittenInCheckpoint) && (pageId < regFragPtr->maxPageWrittenInCheckpoint)) { return true; }//if return false; }//Dbtup::isUndoLoggingNeeded() inline bool Dbtup::isUndoLoggingActive(Fragrecord* const regFragPtr) { if (regFragPtr->checkpointVersion != RNIL) { return true; }//if return false; }//Dbtup::isUndoLoggingNeeded() inline bool Dbtup::isUndoLoggingBlocked(Fragrecord* const regFragPtr) { if ((regFragPtr->checkpointVersion != RNIL) && (cnoFreeUndoSeg < ZMIN_PAGE_LIMIT_TUPKEYREQ)) { return true; }//if return false; }//Dbtup::isUndoLoggingNeeded() inline bool Dbtup::isPageUndoLogged(Fragrecord* const regFragPtr, Uint32 pageId) { if ((pageId >= regFragPtr->minPageNotWrittenInCheckpoint) && (pageId < regFragPtr->maxPageWrittenInCheckpoint)) { return true; }//if return false; }//Dbtup::isUndoLoggingNeeded() #endif