1 /* Copyright (c) 2003-2008 MySQL AB
2    Use is subject to license terms
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
16 
17 #ifndef DBTUP_H
18 #define DBTUP_H
19 
20 #include <pc.hpp>
21 #include <SimulatedBlock.hpp>
22 #include <ndb_limits.h>
23 #include <trigger_definitions.h>
24 #include <AttributeHeader.hpp>
25 #include <Bitmask.hpp>
26 #include <signaldata/TupKey.hpp>
27 #include <signaldata/CreateTrig.hpp>
28 #include <signaldata/DropTrig.hpp>
29 #include <signaldata/TrigAttrInfo.hpp>
30 #include <signaldata/BuildIndx.hpp>
31 #include "Undo_buffer.hpp"
32 #include "tuppage.hpp"
33 #include <../pgman.hpp>
34 #include <../tsman.hpp>
35 
36 // jams
37 #undef jam
38 #undef jamEntry
39 #ifdef DBTUP_BUFFER_CPP
40 #define jam()	 	jamLine(10000 + __LINE__)
41 #define jamEntry() 	jamEntryLine(10000 + __LINE__)
42 #endif
43 #ifdef DBTUP_ROUTINES_CPP
44 #define jam()           jamLine(15000 + __LINE__)
45 #define jamEntry()      jamEntryLine(15000 + __LINE__)
46 #endif
47 #ifdef DBTUP_COMMIT_CPP
48 #define jam()           jamLine(20000 + __LINE__)
49 #define jamEntry()      jamEntryLine(20000 + __LINE__)
50 #endif
51 #ifdef DBTUP_FIXALLOC_CPP
52 #define jam()           jamLine(25000 + __LINE__)
53 #define jamEntry()      jamEntryLine(25000 + __LINE__)
54 #endif
55 #ifdef DBTUP_TRIGGER_CPP
56 #define jam()           jamLine(30000 + __LINE__)
57 #define jamEntry()      jamEntryLine(30000 + __LINE__)
58 #endif
59 #ifdef DBTUP_ABORT_CPP
60 #define jam()           jamLine(35000 + __LINE__)
61 #define jamEntry()      jamEntryLine(35000 + __LINE__)
62 #endif
63 #ifdef DBTUP_PAGE_MAP_CPP
64 #define jam()           jamLine(40000 + __LINE__)
65 #define jamEntry()      jamEntryLine(40000 + __LINE__)
66 #endif
67 #ifdef DBTUP_PAG_MAN_CPP
68 #define jam()           jamLine(45000 + __LINE__)
69 #define jamEntry()      jamEntryLine(45000 + __LINE__)
70 #endif
71 #ifdef DBTUP_STORE_PROC_DEF_CPP
72 #define jam()           jamLine(50000 + __LINE__)
73 #define jamEntry()      jamEntryLine(50000 + __LINE__)
74 #endif
75 #ifdef DBTUP_META_CPP
76 #define jam()           jamLine(55000 + __LINE__)
77 #define jamEntry()      jamEntryLine(55000 + __LINE__)
78 #endif
79 #ifdef DBTUP_TAB_DES_MAN_CPP
80 #define jam()           jamLine(60000 + __LINE__)
81 #define jamEntry()      jamEntryLine(60000 + __LINE__)
82 #endif
83 #ifdef DBTUP_GEN_CPP
84 #define jam()           jamLine(65000 + __LINE__)
85 #define jamEntry()      jamEntryLine(65000 + __LINE__)
86 #endif
87 #ifdef DBTUP_INDEX_CPP
88 #define jam()           jamLine(70000 + __LINE__)
89 #define jamEntry()      jamEntryLine(70000 + __LINE__)
90 #endif
91 #ifdef DBTUP_DEBUG_CPP
92 #define jam()           jamLine(75000 + __LINE__)
93 #define jamEntry()      jamEntryLine(75000 + __LINE__)
94 #endif
95 #ifdef DBTUP_VAR_ALLOC_CPP
96 #define jam()           jamLine(80000 + __LINE__)
97 #define jamEntry()      jamEntryLine(80000 + __LINE__)
98 #endif
99 #ifdef DBTUP_SCAN_CPP
100 #define jam()           jamLine(85000 + __LINE__)
101 #define jamEntry()      jamEntryLine(85000 + __LINE__)
102 #endif
103 #ifdef DBTUP_DISK_ALLOC_CPP
104 #define jam()           jamLine(90000 + __LINE__)
105 #define jamEntry()      jamEntryLine(90000 + __LINE__)
106 #endif
107 #ifndef jam
108 #define jam()           jamLine(__LINE__)
109 #define jamEntry()      jamEntryLine(__LINE__)
110 #endif
111 
112 #ifdef VM_TRACE
dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS> & bm)113 inline const char* dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS>& bm) {
114   static int i=0; static char buf[5][200];
115   bm.getText(buf[i%5]); return buf[i++%5]; }
dbgmask(const Uint32 bm[2])116 inline const char* dbgmask(const Uint32 bm[2]) {
117   static int i=0; static char buf[5][200];
118   sprintf(buf[i%5],"%08x%08x",bm[1],bm[0]); return buf[i++%5]; }
119 #endif
120 
121 #define ZWORDS_ON_PAGE 8192          /* NUMBER OF WORDS ON A PAGE.      */
122 #define ZATTRBUF_SIZE 32             /* SIZE OF ATTRIBUTE RECORD BUFFER */
123 #define ZMIN_PAGE_LIMIT_TUPKEYREQ 5
124 #define ZTUP_VERSION_BITS 15
125 #define ZTUP_VERSION_MASK ((1 << ZTUP_VERSION_BITS) - 1)
126 #define MAX_FREE_LIST 4
127 
ALIGN_WORD(void * ptr)128 inline Uint32* ALIGN_WORD(void * ptr)
129 {
130   return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
131 }
132 
ALIGN_WORD(const void * ptr)133 inline const Uint32* ALIGN_WORD(const void* ptr)
134 {
135   return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
136 }
137 
138 #ifdef DBTUP_C
139 //------------------------------------------------------------------
140 // Jam Handling:
141 //
142 // When DBTUP reports lines through jam in the trace files it has to
143 // be interpreted. 4024 means as an example line 24 in DbtupCommit.cpp
144 // Thus 4000 is added to the line number beacuse it is located in the
145 // file DbtupCommit.cpp. The following is the exhaustive list of the
146 // added value in the various files. ndbrequire, ptrCheckGuard still
147 // only reports the line number in the file it currently is located in.
148 //
149 // DbtupExecQuery.cpp         0
150 // DbtupBuffer.cpp         10000
151 // DbtupRoutines.cpp       15000
152 // DbtupCommit.cpp         20000
153 // DbtupFixAlloc.cpp       25000
154 // DbtupTrigger.cpp        30000
155 // DbtupAbort.cpp          35000
156 // DbtupPageMap.cpp        40000
157 // DbtupPagMan.cpp         45000
158 // DbtupStoredProcDef.cpp  50000
159 // DbtupMeta.cpp           55000
160 // DbtupTabDesMan.cpp      60000
161 // DbtupGen.cpp            65000
162 // DbtupIndex.cpp          70000
163 // DbtupDebug.cpp          75000
164 // DbtupVarAlloc.cpp       80000
165 // DbtupScan.cpp           85000
166 // DbtupDiskAlloc.cpp      90000
167 //------------------------------------------------------------------
168 
169 /*
170 2.2 LOCAL SYMBOLS
171 -----------------
172 */
173 /* ---------------------------------------------------------------- */
174 /*       S I Z E              O F               R E C O R D S       */
175 /* ---------------------------------------------------------------- */
176 #define ZNO_OF_ATTRBUFREC 10000             /* SIZE   OF ATTRIBUTE INFO FILE   */
177 #define ZNO_OF_CONCURRENT_OPEN_OP 40        /* NUMBER OF CONCURRENT OPENS      */
178 #define ZNO_OF_CONCURRENT_WRITE_OP 80       /* NUMBER OF CONCURRENT DISK WRITES*/
179 #define ZNO_OF_FRAGOPREC 20                 /* NUMBER OF CONCURRENT ADD FRAG.  */
180 #define TOT_PAGE_RECORD_SPACE 262144        /* SIZE OF PAGE RECORD FILE.       */
181 #define ZNO_OF_PAGE TOT_PAGE_RECORD_SPACE/ZWORDS_ON_PAGE
182 #define ZNO_OF_PAGE_RANGE_REC 128           /* SIZE OF PAGE RANGE FILE         */
183 // Trigger constants
184 #define ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE 16
185 
186 /* ---------------------------------------------------------------- */
187 /* A ATTRIBUTE MAY BE NULL, DYNAMIC OR NORMAL. A NORMAL ATTRIBUTE   */
188 /* IS A ATTRIBUTE THAT IS NOT NULL OR DYNAMIC. A NULL ATTRIBUTE     */
189 /* MAY HAVE NO VALUE. A DYNAMIC ATTRIBUTE IS A NULL ATTRIBUTE THAT  */
190 /* DOES NOT HAVE TO BE A MEMBER OF EVERY TUPLE I A CERTAIN TABLE.   */
191 /* ---------------------------------------------------------------- */
192 /**
193  * #defines moved into include/kernel/Interpreter.hpp
194  */
195 #define ZINSERT_DELETE 0
196 #define ZUPDATE_ALL 8
197 /* ---------------------------------------------------------------- */
198 /* THE MINIMUM SIZE OF AN 'EMPTY' TUPLE HEADER IN R-WORDS           */
199 /* ---------------------------------------------------------------- */
200           /* THE TUPLE HEADER FIELD 'SIZE OF NULL ATTR. FIELD' SPECIFYES    */
201           /* THE SIZE OF THE TUPLE HEADER FIELD 'NULL ATTR. FIELD'.         */
202           /* THE TUPLE HEADER FIELD 'TYPE' SPECIFYES THE TYPE OF THE TUPLE  */
203           /* HEADER.                                                        */
204                                /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
205                                /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER.  */
206                                /* IT MAY ALSO CONTAIN SHORT ATTRIBUTES AND  */
207                                /* POINTERS TO LONG ATTRIBUTE HEADERS.       */
208                                /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
209                                /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER.  */
210 
211           /* DATA STRUCTURE TYPES */
212           /* WHEN ATTRIBUTE INFO IS SENT WITH A ATTRINFO-SIGNAL THE         */
213           /* VARIABLE TYPE IS SPECIFYED. THIS MUST BE DONE TO BE ABLE TO    */
214           /* NOW HOW MUCH DATA OF A ATTRIBUTE TO READ FROM ATTRINFO.        */
215 
216           /* WHEN A REQUEST CAN NOT BE EXECUTED BECAUSE OF A ERROR THE      */
217           /* ERROR MUST BE IDENTIFYED BY MEANS OF A ERROR CODE AND SENT TO  */
218           /* THE REQUESTER.                                                 */
219 #define ZGET_OPREC_ERROR 804            // TUP_SEIZEREF
220 
221 #define ZEXIST_FRAG_ERROR 816           // Add fragment
222 #define ZFULL_FRAGRECORD_ERROR 817      // Add fragment
223 #define ZNO_FREE_PAGE_RANGE_ERROR 818   // Add fragment
224 #define ZNOFREE_FRAGOP_ERROR 830        // Add fragment
225 #define ZTOO_LARGE_TUPLE_ERROR 851      // Add fragment
226 #define ZNO_FREE_TAB_ENTRY_ERROR 852    // Add fragment
227 #define ZNO_PAGES_ALLOCATED_ERROR 881   // Add fragment
228 
229 #define ZGET_REALPID_ERROR 809
230 #define ZNOT_IMPLEMENTED_ERROR 812
231 #define ZSEIZE_ATTRINBUFREC_ERROR 805
232 #define ZTOO_MUCH_ATTRINFO_ERROR 823
233 #define ZMEM_NOTABDESCR_ERROR 826
234 #define ZMEM_NOMEM_ERROR 827
235 #define ZAI_INCONSISTENCY_ERROR 829
236 #define ZNO_ILLEGAL_NULL_ATTR 839
237 #define ZNOT_NULL_ATTR 840
238 #define ZNO_INSTRUCTION_ERROR 871
239 #define ZOUTSIDE_OF_PROGRAM_ERROR 876
240 #define ZSTORED_PROC_ID_ERROR 877
241 #define ZREGISTER_INIT_ERROR 878
242 #define ZATTRIBUTE_ID_ERROR 879
243 #define ZTRY_TO_READ_TOO_MUCH_ERROR 880
244 #define ZTOTAL_LEN_ERROR 882
245 #define ZATTR_INTERPRETER_ERROR 883
246 #define ZSTACK_OVERFLOW_ERROR 884
247 #define ZSTACK_UNDERFLOW_ERROR 885
248 #define ZTOO_MANY_INSTRUCTIONS_ERROR 886
249 #define ZTRY_TO_UPDATE_ERROR 888
250 #define ZCALL_ERROR 890
251 #define ZTEMPORARY_RESOURCE_FAILURE 891
252 #define ZUNSUPPORTED_BRANCH 892
253 
254 #define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan
255 #define ZSTORED_TOO_MUCH_ATTRINFO_ERROR 874
256 
257 #define ZREAD_ONLY_CONSTRAINT_VIOLATION 893
258 #define ZVAR_SIZED_NOT_SUPPORTED 894
259 #define ZINCONSISTENT_NULL_ATTRIBUTE_COUNT 895
260 #define ZTUPLE_CORRUPTED_ERROR 896
261 #define ZTRY_UPDATE_PRIMARY_KEY 897
262 #define ZMUST_BE_ABORTED_ERROR 898
263 #define ZTUPLE_DELETED_ERROR 626
264 #define ZINSERT_ERROR 630
265 
266 #define ZINVALID_CHAR_FORMAT 744
267 #define ZROWID_ALLOCATED 899
268 
269           /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */
270 
271 #define ZFREE_COMMON 1                    /* PAGE STATE, PAGE IN COMMON AREA                   */
272 #define ZEMPTY_MM 2                       /* PAGE STATE, PAGE IN EMPTY LIST                    */
273 #define ZTH_MM_FREE 3                     /* PAGE STATE, TUPLE HEADER PAGE WITH FREE AREA      */
274 #define ZTH_MM_FULL 4                     /* PAGE STATE, TUPLE HEADER PAGE WHICH IS FULL       */
275 
276 #define ZTD_HEADER 0                      /* HEADER POSITION                   */
277 #define ZTD_DATASIZE 1                    /* SIZE OF THE DATA IN THIS CHUNK    */
278 #define ZTD_SIZE 2                        /* TOTAL SIZE OF TABLE DESCRIPTOR    */
279 
280           /* TRAILER POSITIONS FROM END OF TABLE DESCRIPTOR RECORD               */
281 #define ZTD_TR_SIZE 1                     /* SIZE DESCRIPTOR POS FROM END+1    */
282 #define ZTD_TR_TYPE 2
283 #define ZTD_TRAILER_SIZE 2                /* TOTAL SIZE OF TABLE TRAILER       */
284 #define ZAD_SIZE 2                        /* TOTAL SIZE OF ATTR DESCRIPTOR     */
285 #define ZAD_LOG_SIZE 1                    /* TWO LOG OF TOTAL SIZE OF ATTR DESCRIPTOR     */
286 
287           /* CONSTANTS USED TO HANDLE TABLE DESCRIPTOR AS A FREELIST             */
288 #define ZTD_FL_HEADER 0                   /* HEADER POSITION                   */
289 #define ZTD_FL_SIZE 1                     /* TOTAL SIZE OF THIS FREELIST ENTRY */
290 #define ZTD_FL_PREV 2                     /* PREVIOUS RECORD IN FREELIST       */
291 #define ZTD_FL_NEXT 3                     /* NEXT RECORD IN FREELIST           */
292 #define ZTD_FREE_SIZE 16                  /* SIZE NEEDED TO HOLD ONE FL ENTRY  */
293 
294           /* CONSTANTS USED IN LSB OF TABLE DESCRIPTOR HEADER DESCRIBING USAGE   */
295 #define ZTD_TYPE_FREE 0                   /* RECORD LINKED INTO FREELIST       */
296 #define ZTD_TYPE_NORMAL 1                 /* RECORD USED AS TABLE DESCRIPTOR   */
297           /* ATTRIBUTE OPERATION CONSTANTS */
298 #define ZLEAF 1
299 #define ZNON_LEAF 2
300 
301           /* ATTRINBUFREC VARIABLE POSITIONS. */
302 #define ZBUF_PREV 29                      /* POSITION OF 'PREV'-VARIABLE (USED BY INTERPRETED EXEC) */
303 #define ZBUF_DATA_LEN 30                  /* POSITION OF 'DATA LENGTH'-VARIABLE. */
304 #define ZBUF_NEXT 31                      /* POSITION OF 'NEXT'-VARIABLE.        */
305 #define ZSAVE_BUF_NEXT 28
306 #define ZSAVE_BUF_DATA_LEN 27
307 
308           /* RETURN POINTS. */
309           /* RESTART PHASES */
310 #define ZSTARTPHASE1 1
311 #define ZSTARTPHASE2 2
312 #define ZSTARTPHASE3 3
313 #define ZSTARTPHASE4 4
314 #define ZSTARTPHASE6 6
315 
316 #define ZADDFRAG 0
317 
318 //------------------------------------------------------------
319 // TUP_CONTINUEB codes
320 //------------------------------------------------------------
321 #define ZINITIALISE_RECORDS 6
322 #define ZREL_FRAG 7
323 #define ZREPORT_MEMORY_USAGE 8
324 #define ZBUILD_INDEX 9
325 #define ZTUP_SCAN 10
326 #define ZFREE_EXTENT 11
327 #define ZUNMAP_PAGES 12
328 #define ZFREE_VAR_PAGES 13
329 
330 #define ZSCAN_PROCEDURE 0
331 #define ZCOPY_PROCEDURE 2
332 #define ZSTORED_PROCEDURE_DELETE 3
333 #define ZSTORED_PROCEDURE_FREE 0xffff
334 #define ZMIN_PAGE_LIMIT_TUP_COMMITREQ 2
335 
336 #define ZSKIP_TUX_TRIGGERS 0x1 // flag for TUP_ABORTREQ
337 
338 #endif
339 
340 class Dbtup: public SimulatedBlock {
341 friend class Suma;
342 public:
343 struct KeyReqStruct;
344 friend struct KeyReqStruct; // CC
345 typedef bool (Dbtup::* ReadFunction)(Uint32*,
346                                      KeyReqStruct*,
347                                      AttributeHeader*,
348                                      Uint32);
349 typedef bool (Dbtup::* UpdateFunction)(Uint32*,
350                                        KeyReqStruct*,
351                                        Uint32);
352 private:
353 
354   typedef Tup_fixsize_page Fix_page;
355   typedef Tup_varsize_page Var_page;
356 
357 public:
358   class Dblqh *c_lqh;
359   Tsman* c_tsman;
360   Lgman* c_lgman;
361   Page_cache_client m_pgman;
362 
363 // State values
364 enum ChangeMaskState {
365   DELETE_CHANGES = 0,
366   SET_ALL_MASK = 1,
367   USE_SAVED_CHANGE_MASK = 2,
368   RECALCULATE_CHANGE_MASK = 3
369 };
370 
371 enum TransState {
372   TRANS_IDLE = 0,
373   TRANS_STARTED = 1,
374   TRANS_WAIT_STORED_PROCEDURE_ATTR_INFO = 2,
375   TRANS_ERROR_WAIT_STORED_PROCREQ = 3,
376   TRANS_ERROR_WAIT_TUPKEYREQ = 4,
377   TRANS_TOO_MUCH_AI = 5,
378   TRANS_DISCONNECTED = 6
379 };
380 
381 enum TupleState {
382   TUPLE_PREPARED = 1,
383   TUPLE_ALREADY_ABORTED = 2,
384   TUPLE_TO_BE_COMMITTED = 3
385 };
386 
387 enum State {
388   NOT_INITIALIZED = 0,
389   IDLE = 17,
390   ACTIVE = 18,
391   SYSTEM_RESTART = 19,
392   DEFINED = 34,
393   NOT_DEFINED = 37,
394   NORMAL_PAGE = 40,
395   DEFINING = 65,
396   DROPPING = 68
397 };
398 
399 // Records
400 /* ************** ATTRIBUTE INFO BUFFER RECORD ****************** */
401 /* THIS RECORD IS USED AS A BUFFER FOR INCOMING AND OUTGOING DATA */
402 /* ************************************************************** */
403 struct Attrbufrec {
404   Uint32 attrbuf[ZATTRBUF_SIZE];
405 }; /* p2c: size = 128 bytes */
406 
407 typedef Ptr<Attrbufrec> AttrbufrecPtr;
408 
409 
410 
411 struct Fragoperrec {
412   Uint64 minRows;
413   Uint64 maxRows;
414   Uint32 nextFragoprec;
415   Uint32 lqhPtrFrag;
416   Uint32 fragidFrag;
417   Uint32 tableidFrag;
418   Uint32 fragPointer;
419   Uint32 attributeCount;
420   Uint32 charsetIndex;
421   Uint32 m_null_bits[2];
422   Uint32 m_fix_attributes_size[2]; // In words
423   Uint32 m_var_attributes_size[2]; // In bytes
424   BlockReference lqhBlockrefFrag;
425   bool inUse;
426   bool definingFragment;
427 };
428 typedef Ptr<Fragoperrec> FragoperrecPtr;
429 
430 
431   typedef Tup_page Page;
432   typedef Ptr<Page> PagePtr;
433 
434   // Scan position
435   struct ScanPos {
436     enum Get {
437       Get_undef = 0,
438       Get_next_page,
439       Get_page,
440       Get_next_page_mm,
441       Get_page_mm,
442       Get_next_page_dd,
443       Get_page_dd,
444       Get_next_tuple,
445       Get_tuple,
446       Get_next_tuple_fs,
447       Get_tuple_fs
448     };
449     Get m_get;                  // entry point in scanNext
450     Local_key m_key;            // scan position pointer MM or DD
451     Page* m_page;               // scanned MM or DD (cache) page
452     Local_key m_key_mm;         // MM local key returned
453     Uint32 m_realpid_mm;        // MM real page id
454     Uint32 m_extent_info_ptr_i;
455   };
456 
457   // Scan Lock
458   struct ScanLock {
459     Uint32 m_accLockOp;
460     union {
461       Uint32 nextPool;
462       Uint32 nextList;
463     };
464     Uint32 prevList;
465   };
466   typedef Ptr<ScanLock> ScanLockPtr;
467   ArrayPool<ScanLock> c_scanLockPool;
468 
469   // Tup scan, similar to Tux scan.  Later some of this could
470   // be moved to common superclass.
471   struct ScanOp {
ScanOpDbtup::ScanOp472     ScanOp() :
473       m_state(Undef),
474       m_bits(0),
475       m_userPtr(RNIL),
476       m_userRef(RNIL),
477       m_tableId(RNIL),
478       m_fragId(~(Uint32)0),
479       m_fragPtrI(RNIL),
480       m_transId1(0),
481       m_transId2(0),
482       m_savePointId(0),
483       m_accLockOp(RNIL)
484     {}
485 
486     enum State {
487       Undef = 0,
488       First = 1,                // before first entry
489       Current = 2,              // at current before locking
490       Blocked = 3,              // at current waiting for ACC lock
491       Locked = 4,               // at current and locked or no lock needed
492       Next = 5,                 // looking for next extry
493       Last = 6,                 // after last entry
494       Aborting = 7,             // lock wait at scan close
495       Invalid = 9               // cannot return REF to LQH currently
496     };
497     Uint16 m_state;
498 
499     enum Bits {
500       SCAN_DD        = 0x01,        // scan disk pages
501       SCAN_VS        = 0x02,        // page format is var size
502       SCAN_LCP       = 0x04,        // LCP mem page scan
503       SCAN_LOCK_SH   = 0x10,        // lock mode shared
504       SCAN_LOCK_EX   = 0x20,        // lock mode exclusive
505       SCAN_LOCK_WAIT = 0x40,        // lock wait
506       // any lock mode
507       SCAN_LOCK      = SCAN_LOCK_SH | SCAN_LOCK_EX,
508       SCAN_NR        = 0x80        // Node recovery scan
509     };
510     Uint16 m_bits;
511 
512     Uint32 m_userPtr;           // scanptr.i in LQH
513     Uint32 m_userRef;
514     Uint32 m_tableId;
515     Uint32 m_fragId;
516     Uint32 m_fragPtrI;
517     Uint32 m_transId1;
518     Uint32 m_transId2;
519     union {
520       Uint32 m_savePointId;
521       Uint32 m_scanGCI;
522     };
523     Uint32 m_endPage;
524     // lock waited for or obtained and not yet passed to LQH
525     Uint32 m_accLockOp;
526 
527     ScanPos m_scanPos;
528 
529     DLFifoList<ScanLock>::Head m_accLockOps;
530 
531     union {
532     Uint32 nextPool;
533     Uint32 nextList;
534     };
535     Uint32 prevList;
536   };
537   typedef Ptr<ScanOp> ScanOpPtr;
538   ArrayPool<ScanOp> c_scanOpPool;
539 
540   void scanReply(Signal*, ScanOpPtr scanPtr);
541   void scanFirst(Signal*, ScanOpPtr scanPtr);
542   bool scanNext(Signal*, ScanOpPtr scanPtr);
543   void scanCont(Signal*, ScanOpPtr scanPtr);
544   void disk_page_tup_scan_callback(Signal*, Uint32 scanPtrI, Uint32 page_i);
545   void scanClose(Signal*, ScanOpPtr scanPtr);
546   void addAccLockOp(ScanOp& scan, Uint32 accLockOp);
547   void removeAccLockOp(ScanOp& scan, Uint32 accLockOp);
548   void releaseScanOp(ScanOpPtr& scanPtr);
549 
550   // for md5 of key (could maybe reuse existing temp buffer)
551   Uint64 c_dataBuffer[ZWORDS_ON_PAGE/2 + 1];
552 
553   struct Page_request
554   {
555     Local_key m_key;
556     Uint32 m_frag_ptr_i;
557     Uint32 m_extent_info_ptr;
558     Uint16 m_estimated_free_space; // in bytes/records
559     Uint16 m_list_index;           // in Disk_alloc_info.m_page_requests
560     Uint16 m_ref_count;            // Waiters for page
561     Uint16 m_uncommitted_used_space;
562     Uint32 nextList;
563     Uint32 prevList;
564     Uint32 m_magic;
565   }; // 32 bytes
566 
567   typedef RecordPool<Page_request, WOPool> Page_request_pool;
568   typedef DLFifoListImpl<Page_request_pool, Page_request> Page_request_list;
569   typedef LocalDLFifoListImpl<Page_request_pool, Page_request> Local_page_request_list;
570 
571   STATIC_CONST( EXTENT_SEARCH_MATRIX_COLS = 4 ); // Guarantee size
572   STATIC_CONST( EXTENT_SEARCH_MATRIX_ROWS = 5 ); // Total size
573   STATIC_CONST( EXTENT_SEARCH_MATRIX_SIZE = 20 );
574 
575   struct Extent_list_t
576   {
577     Uint32 nextList;
578   };
579 
580   struct Extent_info : public Extent_list_t
581   {
582     Uint32 m_magic;
583     Uint32 m_first_page_no;
584     Local_key m_key;
585     Uint32 m_free_space;
586     Uint32 m_free_matrix_pos;
587     Uint16 m_free_page_count[EXTENT_SEARCH_MATRIX_COLS];
588     union {
589       Uint32 nextList;
590       Uint32 nextPool;
591     };
592     Uint32 prevList;
593     Uint32 nextHash, prevHash;
594 
hashValueDbtup::Extent_info595     Uint32 hashValue() const {
596       return (m_key.m_file_no << 16) ^ m_key.m_page_idx;
597     }
598 
Extent_infoDbtup::Extent_info599     Extent_info() {}
equalDbtup::Extent_info600     bool equal(const Extent_info & rec) const {
601       return m_key.m_file_no == rec.m_key.m_file_no &&
602 	m_key.m_page_idx == rec.m_key.m_page_idx;
603     }
604   }; // 40 bytes
605 
606   typedef RecordPool<Extent_info, RWPool> Extent_info_pool;
607   typedef DLListImpl<Extent_info_pool, Extent_info> Extent_info_list;
608   typedef LocalDLListImpl<Extent_info_pool, Extent_info> Local_extent_info_list;
609   typedef DLHashTableImpl<Extent_info_pool, Extent_info> Extent_info_hash;
610   typedef SLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Fragment_extent_list;
611   typedef LocalSLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Local_fragment_extent_list;
612   struct Tablerec;
613   struct Disk_alloc_info
614   {
Disk_alloc_infoDbtup::Disk_alloc_info615     Disk_alloc_info() {}
616     Disk_alloc_info(const Tablerec* tabPtrP,
617 		    Uint32 extent_size_in_pages);
618     Uint32 m_extent_size;
619 
620     /**
621      * Disk allocation
622      *
623      * 1) Allocate space on pages that already are dirty
624      *    (4 free lists for different requests)
625      * 2) Allocate space on pages waiting to maped that will be dirty
626      *    (4 free lists for different requests)
627      * 3) Check if "current" extent can accommodate request
628      *    If so, allocate page from there
629      *    Else put "current" into free matrix
630      * 4) Search free matrix for extent with greatest amount of free space
631      *    while still accommodating current request
632      *    (20 free lists for different requests)
633      */
634 
635     /**
636      * Free list of pages in different size
637      *   that are dirty
638      */
639     DLList<Page>::Head m_dirty_pages[MAX_FREE_LIST];   // In real page id's
640 
641     /**
642      * Requests (for update) that have sufficient space left after request
643      *   these are currently being "mapped"
644      */
645     Page_request_list::Head m_page_requests[MAX_FREE_LIST];
646 
647     DLList<Page>::Head m_unmap_pages;
648 
649     /**
650      * Current extent
651      */
652     Uint32 m_curr_extent_info_ptr_i;
653 
654     /**
655      *
656      */
657     STATIC_CONST( SZ = EXTENT_SEARCH_MATRIX_SIZE );
658     Extent_info_list::Head m_free_extents[SZ];
659     Uint32 m_total_extent_free_space_thresholds[EXTENT_SEARCH_MATRIX_ROWS];
660     Uint32 m_page_free_bits_map[EXTENT_SEARCH_MATRIX_COLS];
661 
662     Uint32 find_extent(Uint32 sz) const;
663     Uint32 calc_extent_pos(const Extent_info*) const;
664 
665     /**
666      * Compute minimum free space on page given bits
667      */
calc_page_free_spaceDbtup::Disk_alloc_info668     Uint32 calc_page_free_space(Uint32 bits) const {
669       return m_page_free_bits_map[bits];
670     }
671 
672     /**
673      * Compute page free bits, given free space
674      */
calc_page_free_bitsDbtup::Disk_alloc_info675     Uint32 calc_page_free_bits(Uint32 free) const {
676       for(Uint32 i = 0; i<EXTENT_SEARCH_MATRIX_COLS-1; i++)
677 	if(free >= m_page_free_bits_map[i])
678 	  return i;
679       return EXTENT_SEARCH_MATRIX_COLS - 1;
680     }
681 
682     Fragment_extent_list::Head m_extent_list;
683   };
684 
685   void dump_disk_alloc(Disk_alloc_info&);
686 
687 struct Fragrecord {
688   Uint32 nextStartRange;
689   Uint32 currentPageRange;
690   Uint32 rootPageRange;
691   Uint32 noOfPages;
692   Uint32 noOfVarPages;
693   Uint32 noOfPagesToGrow;
694 
695   DLList<Page>::Head emptyPrimPage; // allocated pages (not init)
696   DLFifoList<Page>::Head thFreeFirst;   // pages with atleast 1 free record
697   SLList<Page>::Head m_empty_pages; // Empty pages not in logical/physical map
698 
699   Uint32 m_lcp_scan_op;
700   Uint32 m_lcp_keep_list;
701 
702   State fragStatus;
703   Uint32 fragTableId;
704   Uint32 fragmentId;
705   Uint32 nextfreefrag;
706   DLList<Page>::Head free_var_page_array[MAX_FREE_LIST];
707 
708   DLList<ScanOp>::Head m_scanList;
709 
710   enum { UC_LCP = 1, UC_CREATE = 2, UC_SET_LCP = 3 };
711   Uint32 m_restore_lcp_id;
712   Uint32 m_undo_complete;
713   Uint32 m_tablespace_id;
714   Uint32 m_logfile_group_id;
715   Disk_alloc_info m_disk_alloc_info;
716   Uint32 m_var_page_chunks;
717 };
718 typedef Ptr<Fragrecord> FragrecordPtr;
719 
720 
721 struct Operationrec {
722   /*
723    * To handle Attrinfo signals and buffer them up we need to
724    * a simple list with first and last and we also need to keep track
725    * of how much we received for security check.
726    * Will most likely disappear with introduction of long signals.
727    * These variables are used before TUPKEYREQ is received and not
728    * thereafter and is disposed with after calling copyAttrinfo
729    * which is called before putting the operation into its lists.
730    * Thus we can use union declarations for these variables.
731    */
732 
733   /*
734    * Used by scans to find the Attrinfo buffers.
735    * This is only until returning from copyAttrinfo and
736    * can thus reuse the same memory as needed by the
737    * active operation list variables.
738    */
739 
740   /*
741    * Doubly linked list with anchor on tuple.
742    * This is to handle multiple updates on the same tuple
743    * by the same transaction.
744    */
745   union {
746     Uint32 prevActiveOp;
747     Uint32 storedProcedureId; //Used until copyAttrinfo
748   };
749   union {
750     Uint32 nextActiveOp;
751     Uint32 currentAttrinbufLen; //Used until copyAttrinfo
752   };
753 
OperationrecDbtup::Operationrec754   Operationrec() {}
is_first_operationDbtup::Operationrec755   bool is_first_operation() const { return prevActiveOp == RNIL;}
is_last_operationDbtup::Operationrec756   bool is_last_operation() const { return nextActiveOp == RNIL;}
757 
758   Uint32 m_undo_buffer_space; // In words
759   union {
760     Uint32 firstAttrinbufrec; //Used until copyAttrinfo
761   };
762   Uint32 m_any_value;
763   union {
764     Uint32 lastAttrinbufrec; //Used until copyAttrinfo
765     Uint32 nextPool;
766   };
767   Uint32 attrinbufLen; //only used during STORED_PROCDEF phase
768   Uint32 storedProcPtr; //only used during STORED_PROCDEF phase
769 
770   /*
771    * From fragment i-value we can find fragment and table record
772    */
773   Uint32 fragmentPtr;
774 
775   /*
776    * We need references to both the original tuple and the copy tuple.
777    * We keep the page's real i-value and its index and from there we
778    * can find out about the fragment page id and the page offset.
779    */
780   Local_key m_tuple_location;
781   Local_key m_copy_tuple_location;
782 
783   /*
784    * We keep the record linked to the operation record in LQH.
785    * This is needed due to writing of REDO log must be performed
786    * in correct order, which is the same order as the writes
787    * occurred. LQH can receive the records in different order.
788    */
789   Uint32 userpointer;
790 
791   /*
792    * When responding to queries in the same transaction they will see
793    * a result from the save point id the query was started. Again
794    * functionality for multi-updates of the same record in one
795    * transaction.
796    */
797   union {
798     Uint32 savepointId;
799     Uint32 m_commit_disk_callback_page;
800   };
801 
802   /*
803    * We use 64 bits to save change mask for the most common cases.
804    */
805   Uint32 saved_change_mask[2];
806 
807   /*
808    * State variables on connection.
809    * State variable on tuple after multi-updates
810    * Is operation undo logged or not
811    * Is operation in fragment list
812    * Is operation in multi-update list
813    * Operation type (READ, UPDATE, etc)
814    * Is record primary replica
815    * Is delete or insert performed
816    */
817   struct OpBitFields {
818     unsigned int trans_state : 3;
819     unsigned int tuple_state : 2;
820     unsigned int in_active_list : 1;
821 
822     unsigned int op_type : 3;
823     unsigned int delete_insert_flag : 1;
824     unsigned int primary_replica : 1;
825     unsigned int change_mask_state : 2;
826     unsigned int m_disk_preallocated : 1;
827     unsigned int m_load_diskpage_on_commit : 1;
828     unsigned int m_wait_log_buffer : 1;
829   };
830   union {
831     OpBitFields op_struct;
832     Uint16 op_bit_fields;
833   };
834 
835   /*
836    * TUX needs to know the tuple version of the tuple since it
837    * keeps an entry for both the committed and all versions in
838    * a transaction currently. So each update will create a new
839    * version even if in the same transaction.
840    */
841   Uint16 tupVersion;
842 };
843 typedef Ptr<Operationrec> OperationrecPtr;
844 
845           /* ****************************** PAGE RANGE RECORD ************************** */
846           /* PAGE RANGES AND BASE PAGE ID. EACH RANGE HAS A  CORRESPONDING BASE PAGE ID  */
847           /* THAT IS USED TO  CALCULATE REAL PAGE ID FROM A FRAGMENT PAGE ID AND A TABLE */
848           /* REFERENCE.                                                                  */
849           /* THE PAGE RANGES ARE ORGANISED IN A B-TREE FASHION WHERE THE VARIABLE TYPE   */
850           /* SPECIFIES IF A LEAF NODE HAS BEEN REACHED. IF A LEAF NODE HAS BEEN REACHED  */
851           /* THEN BASE_PAGE_ID IS THE BASE_PAGE_ID OF THE SET OF PAGES THAT WAS          */
852           /* ALLOCATED IN THAT RANGE. OTHERWISE BASE_PAGE_ID IS THE POINTER TO THE NEXT  */
853           /* PAGE_RANGE RECORD.                                                          */
854           /* *************************************************************************** */
855 struct PageRange {
856   Uint32 startRange[4];                                  /* START OF RANGE                                   */
857   Uint32 endRange[4];                                    /* END OF THIS RANGE                                */
858   Uint32 basePageId[4];                                  /* BASE PAGE ID.                                    */
859 /*----               VARIABLE BASE_PAGE_ID2 (4) 8 DS NEEDED WHEN SUPPORTING 40 BIT PAGE ID           -------*/
860   Uint8 type[4];                                        /* TYPE OF BASE PAGE ID                             */
861   Uint32 nextFree;                                       /* NEXT FREE PAGE RANGE RECORD                      */
862   Uint32 parentPtr;                                      /* THE PARENT TO THE PAGE RANGE REC IN THE B-TREE   */
863   Uint8 currentIndexPos;
864 };
865 typedef Ptr<PageRange> PageRangePtr;
866 
867 
868   /* ************* TRIGGER DATA ************* */
869   /* THIS RECORD FORMS LISTS OF ACTIVE       */
870   /* TRIGGERS FOR EACH TABLE.                 */
871   /* THE RECORDS ARE MANAGED BY A TRIGGER     */
872   /* POOL wHERE A TRIGGER RECORD IS SEIZED    */
873   /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
874   /* WHEN THE TRIGGER IS DEACTIVATED.         */
875   /* **************************************** */
876 struct TupTriggerData {
TupTriggerDataDbtup::TupTriggerData877   TupTriggerData() {}
878 
879   /**
880    * Trigger id, used by DICT/TRIX to identify the trigger
881    *
882    * trigger Ids are unique per block for SUBSCRIPTION triggers.
883    * This is so that BACKUP can use TUP triggers directly and delete them
884    * properly.
885    */
886   Uint32 triggerId;
887 
888   /**
889    * Index id is needed for ordered index.
890    */
891   Uint32 indexId;
892 
893   /**
894    * Trigger type etc, defines what the trigger is used for
895    */
896   TriggerType::Value triggerType;
897   TriggerActionTime::Value triggerActionTime;
898   TriggerEvent::Value triggerEvent;
899   /**
900    * Receiver block
901    */
902   Uint32 m_receiverBlock;
903 
904   /**
905    * Monitor all replicas, i.e. trigger will fire on all nodes where tuples
906    * are stored
907    */
908   bool monitorReplicas;
909 
910   /**
911    * Monitor all attributes, the trigger monitors all changes to attributes
912    * in the table
913    */
914   bool monitorAllAttributes;
915 
916   /**
917    * Send only changed attributes at trigger firing time.
918    */
919   bool sendOnlyChangedAttributes;
920 
921   /**
922    * Send also before values at trigger firing time.
923    */
924   bool sendBeforeValues;
925 
926   /**
927    * Attribute mask, defines what attributes are to be monitored
928    * Can be seen as a compact representation of SQL column name list
929    */
930   Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
931 
932   /**
933    * Next ptr (used in pool/list)
934    */
935   union {
936     Uint32 nextPool;
937     Uint32 nextList;
938   };
939 
940   /**
941    * Prev pointer (used in list)
942    */
943   Uint32 prevList;
944 
printDbtup::TupTriggerData945   inline void print(NdbOut & s) const { s << "[TriggerData = " << triggerId << "]"; };
946 };
947 
948 typedef Ptr<TupTriggerData> TriggerPtr;
949 
950 /**
951  * Pool of trigger data record
952  */
953 ArrayPool<TupTriggerData> c_triggerPool;
954 
955   /* ************ TABLE RECORD ************ */
956   /* THIS RECORD FORMS A LIST OF TABLE      */
957   /* REFERENCE INFORMATION. ONE RECORD      */
958   /* PER TABLE REFERENCE.                   */
959   /* ************************************** */
960   STATIC_CONST( MM = 0 );
961   STATIC_CONST( DD = 1 );
962 
963   struct Tablerec {
TablerecDbtup::Tablerec964     Tablerec(ArrayPool<TupTriggerData> & triggerPool) :
965       afterInsertTriggers(triggerPool),
966       afterDeleteTriggers(triggerPool),
967       afterUpdateTriggers(triggerPool),
968       subscriptionInsertTriggers(triggerPool),
969       subscriptionDeleteTriggers(triggerPool),
970       subscriptionUpdateTriggers(triggerPool),
971       constraintUpdateTriggers(triggerPool),
972       tuxCustomTriggers(triggerPool)
973       {}
974 
975     Bitmask<MAXNROFATTRIBUTESINWORDS> notNullAttributeMask;
976     Bitmask<MAXNROFATTRIBUTESINWORDS> blobAttributeMask;
977 
978     ReadFunction* readFunctionArray;
979     UpdateFunction* updateFunctionArray;
980     CHARSET_INFO** charsetArray;
981 
982     Uint32 readKeyArray;
983     Uint32 tabDescriptor;
984     Uint32 m_real_order_descriptor;
985 
986     enum Bits
987     {
988       TR_Checksum = 0x1, // Need to be 1
989       TR_RowGCI   = 0x2,
990       TR_ForceVarPart = 0x4
991     };
992     Uint16 m_bits;
993     Uint16 total_rec_size; // Max total size for entire tuple in words
994 
995     /**
996      * Aggregates
997      */
998     Uint16 m_no_of_attributes;
999     Uint16 m_no_of_disk_attributes;
1000     Uint16 noOfKeyAttr;
1001     Uint16 noOfCharsets;
1002 
need_expandDbtup::Tablerec1003     bool need_expand() const {
1004       return m_no_of_attributes > m_attributes[MM].m_no_of_fixsize;
1005     }
1006 
need_expandDbtup::Tablerec1007     bool need_expand(bool disk) const {
1008       return m_attributes[MM].m_no_of_varsize > 0 ||
1009 	(disk && m_no_of_disk_attributes > 0);
1010     }
1011 
need_shrinkDbtup::Tablerec1012     bool need_shrink() const {
1013       return
1014 	m_attributes[MM].m_no_of_varsize > 0 ||
1015 	m_attributes[DD].m_no_of_varsize > 0;
1016     }
1017 
need_shrinkDbtup::Tablerec1018     bool need_shrink(bool disk) const {
1019       return
1020 	m_attributes[MM].m_no_of_varsize > 0 ||
1021 	(disk && m_attributes[DD].m_no_of_varsize > 0);
1022     }
1023 
1024     /**
1025      * Descriptors for MM and DD part
1026      */
1027     struct Tuple_offsets {
1028       Uint8 m_null_words;
1029       Uint8 m_null_offset;
1030       Uint16 m_disk_ref_offset; // In words relative m_data
1031       Uint16 m_fix_header_size; // For fix size tuples= total rec size(part)
1032       Uint16 m_max_var_offset;  // In bytes relative m_var_data.m_data_ptr
1033     } m_offsets[2];
1034 
get_check_offsetDbtup::Tablerec1035     Uint32 get_check_offset(Uint32 mm) const {
1036       return m_offsets[mm].m_fix_header_size;
1037     }
1038 
1039     struct {
1040       Uint16 m_no_of_fixsize;
1041       Uint16 m_no_of_varsize;
1042     } m_attributes[2];
1043 
1044     // Lists of trigger data for active triggers
1045     DLList<TupTriggerData> afterInsertTriggers;
1046     DLList<TupTriggerData> afterDeleteTriggers;
1047     DLList<TupTriggerData> afterUpdateTriggers;
1048     DLList<TupTriggerData> subscriptionInsertTriggers;
1049     DLList<TupTriggerData> subscriptionDeleteTriggers;
1050     DLList<TupTriggerData> subscriptionUpdateTriggers;
1051     DLList<TupTriggerData> constraintUpdateTriggers;
1052 
1053     // List of ordered indexes
1054     DLList<TupTriggerData> tuxCustomTriggers;
1055 
1056     Uint32 fragid[MAX_FRAG_PER_NODE];
1057     Uint32 fragrec[MAX_FRAG_PER_NODE];
1058 
1059     struct {
1060       Uint32 tabUserPtr;
1061       Uint32 tabUserRef;
1062       Uint32 m_lcpno;
1063       Uint32 m_fragPtrI;
1064     } m_dropTable;
1065     State tableStatus;
1066   };
1067 
1068   struct Disk_undo
1069   {
1070     enum
1071     {
1072       UNDO_ALLOC = File_formats::Undofile::UNDO_TUP_ALLOC
1073       ,UNDO_UPDATE = File_formats::Undofile::UNDO_TUP_UPDATE
1074       ,UNDO_FREE = File_formats::Undofile::UNDO_TUP_FREE
1075       ,UNDO_CREATE = File_formats::Undofile::UNDO_TUP_CREATE
1076       ,UNDO_DROP = File_formats::Undofile::UNDO_TUP_DROP
1077       ,UNDO_ALLOC_EXTENT = File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT
1078       ,UNDO_FREE_EXTENT = File_formats::Undofile::UNDO_TUP_FREE_EXTENT
1079     };
1080 
1081     struct Alloc
1082     {
1083       Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1084       Uint32 m_page_no;
1085       Uint32 m_type_length; // 16 bit type, 16 bit length
1086     };
1087 
1088     struct Update
1089     {
1090       Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1091       Uint32 m_page_no;
1092       Uint32 m_gci;
1093       Uint32 m_data[1];
1094       Uint32 m_type_length; // 16 bit type, 16 bit length
1095     };
1096 
1097     struct Free
1098     {
1099       Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1100       Uint32 m_page_no;
1101       Uint32 m_gci;
1102       Uint32 m_data[1];
1103       Uint32 m_type_length; // 16 bit type, 16 bit length
1104     };
1105 
1106     struct Create
1107     {
1108       Uint32 m_table;
1109       Uint32 m_type_length; // 16 bit type, 16 bit length
1110     };
1111 
1112     struct Drop
1113     {
1114       Uint32 m_table;
1115       Uint32 m_type_length; // 16 bit type, 16 bit length
1116     };
1117 
1118     struct AllocExtent
1119     {
1120       Uint32 m_table;
1121       Uint32 m_fragment;
1122       Uint32 m_page_no;
1123       Uint32 m_file_no;
1124       Uint32 m_type_length;
1125     };
1126 
1127     struct FreeExtent
1128     {
1129       Uint32 m_table;
1130       Uint32 m_fragment;
1131       Uint32 m_page_no;
1132       Uint32 m_file_no;
1133       Uint32 m_type_length;
1134     };
1135   };
1136 
1137   Extent_info_pool c_extent_pool;
1138   Extent_info_hash c_extent_hash;
1139   Page_request_pool c_page_request_pool;
1140 
1141   typedef Ptr<Tablerec> TablerecPtr;
1142 
1143   struct storedProc {
1144     Uint32 storedLinkFirst;
1145     Uint32 storedLinkLast;
1146     Uint32 storedCounter;
1147     Uint32 nextPool;
1148     Uint16 storedCode;
1149     Uint16 storedProcLength;
1150 };
1151 
1152 typedef Ptr<storedProc> StoredProcPtr;
1153 
1154 ArrayPool<storedProc> c_storedProcPool;
1155 
1156 /* **************************** TABLE_DESCRIPTOR RECORD ******************************** */
1157 /* THIS VARIABLE IS USED TO STORE TABLE DESCRIPTIONS. A TABLE DESCRIPTION IS STORED AS A */
1158 /* CONTIGUOS ARRAY IN THIS VARIABLE. WHEN A NEW TABLE IS ADDED A CHUNK IS ALLOCATED IN   */
1159 /* THIS RECORD. WHEN ATTRIBUTES ARE ADDED TO THE TABLE, A NEW CHUNK OF PROPER SIZE IS    */
1160 /* ALLOCATED AND ALL DATA IS COPIED TO THIS NEW CHUNK AND THEN THE OLD CHUNK IS PUT IN   */
1161 /* THE FREE LIST. EACH TABLE IS DESCRIBED BY A NUMBER OF TABLE DESCRIPTIVE ATTRIBUTES    */
1162 /* AND A NUMBER OF ATTRIBUTE DESCRIPTORS AS SHOWN IN FIGURE BELOW                        */
1163 /*                                                                                       */
1164 /* WHEN ALLOCATING A TABLE DESCRIPTOR THE SIZE IS ALWAYS A MULTIPLE OF 16 WORDS.         */
1165 /*                                                                                       */
1166 /*               ----------------------------------------------                          */
1167 /*               |    TRAILER USED FOR ALLOC/DEALLOC          |                          */
1168 /*               ----------------------------------------------                          */
1169 /*               |    TABLE DESCRIPTIVE ATTRIBUTES            |                          */
1170 /*               ----------------------------------------------                          */
1171 /*               |    ATTRIBUTE DESCRIPTION 1                 |                          */
1172 /*               ----------------------------------------------                          */
1173 /*               |    ATTRIBUTE DESCRIPTION 2                 |                          */
1174 /*               ----------------------------------------------                          */
1175 /*               |                                            |                          */
1176 /*               |                                            |                          */
1177 /*               |                                            |                          */
1178 /*               ----------------------------------------------                          */
1179 /*               |    ATTRIBUTE DESCRIPTION N                 |                          */
1180 /*               ----------------------------------------------                          */
1181 /*                                                                                       */
1182 /* THE TABLE DESCRIPTIVE ATTRIBUTES CONTAINS THE FOLLOWING ATTRIBUTES:                   */
1183 /*                                                                                       */
1184 /*               ----------------------------------------------                          */
1185 /*               |    HEADER (TYPE OF INFO)                   |                          */
1186 /*               ----------------------------------------------                          */
1187 /*               |    SIZE OF WHOLE CHUNK (INCL. TRAILER)     |                          */
1188 /*               ----------------------------------------------                          */
1189 /*               |    TABLE IDENTITY                          |                          */
1190 /*               ----------------------------------------------                          */
1191 /*               |    FRAGMENT IDENTITY                       |                          */
1192 /*               ----------------------------------------------                          */
1193 /*               |    NUMBER OF ATTRIBUTES                    |                          */
1194 /*               ----------------------------------------------                          */
1195 /*               |    SIZE OF FIXED ATTRIBUTES                |                          */
1196 /*               ----------------------------------------------                          */
1197 /*               |    NUMBER OF NULL FIELDS                   |                          */
1198 /*               ----------------------------------------------                          */
1199 /*               |    NOT USED                                |                          */
1200 /*               ----------------------------------------------                          */
1201 /*                                                                                       */
1202 /* THESE ATTRIBUTES ARE ALL ONE R-VARIABLE IN THE RECORD.                                */
1203 /* NORMALLY ONLY ONE TABLE DESCRIPTOR IS USED. DURING SCHEMA CHANGES THERE COULD         */
1204 /* HOWEVER EXIST MORE THAN ONE TABLE DESCRIPTION SINCE THE SCHEMA CHANGE OF VARIOUS      */
1205 /* FRAGMENTS ARE NOT SYNCHRONISED. THIS MEANS THAT ALTHOUGH THE SCHEMA HAS CHANGED       */
1206 /* IN ALL FRAGMENTS, BUT THE FRAGMENTS HAVE NOT REMOVED THE ATTRIBUTES IN THE SAME       */
1207 /* TIME-FRAME. THEREBY SOME ATTRIBUTE INFORMATION MIGHT DIFFER BETWEEN FRAGMENTS.        */
1208 /* EXAMPLES OF ATTRIBUTES THAT MIGHT DIFFER ARE SIZE OF FIXED ATTRIBUTES, NUMBER OF      */
1209 /* ATTRIBUTES, FIELD START WORD, START BIT.                                              */
1210 /*                                                                                       */
1211 /* AN ATTRIBUTE DESCRIPTION CONTAINS THE FOLLOWING ATTRIBUTES:                           */
1212 /*                                                                                       */
1213 /*               ----------------------------------------------                          */
1214 /*               |    Field Type, 4 bits (LSB Bits)           |                          */
1215 /*               ----------------------------------------------                          */
1216 /*               |    Attribute Size, 4 bits                  |                          */
1217 /*               ----------------------------------------------                          */
1218 /*               |    NULL indicator 1 bit                    |                          */
1219 /*               ----------------------------------------------                          */
1220 /*               |    Indicator if TUP stores attr. 1 bit     |                          */
1221 /*               ----------------------------------------------                          */
1222 /*               |    Not used 6 bits                         |                          */
1223 /*               ----------------------------------------------                          */
1224 /*               |    No. of elements in fixed array 16 bits  |                          */
1225 /*               ----------------------------------------------                          */
1226 /*               ----------------------------------------------                          */
1227 /*               |    Field Start Word, 21 bits (LSB Bits)    |                          */
1228 /*               ----------------------------------------------                          */
1229 /*               |    NULL Bit, 11 bits                       |                          */
1230 /*               ----------------------------------------------                          */
1231 /*                                                                                       */
1232 /* THE ATTRIBUTE SIZE CAN BE 1,2,4,8,16,32,64 AND 128 BITS.                              */
1233 /*                                                                                       */
1234 /* THE UNUSED PARTS OF THE RECORDS ARE PUT IN A LINKED LIST OF FREE PARTS. EACH OF       */
1235 /* THOSE FREE PARTS HAVE THREE RECORDS ASSIGNED AS SHOWN IN THIS STRUCTURE               */
1236 /* ALL FREE PARTS ARE SET INTO A CHUNK LIST WHERE EACH CHUNK IS AT LEAST 16 WORDS        */
1237 /*                                                                                       */
1238 /*               ----------------------------------------------                          */
1239 /*               |    HEADER = RNIL                           |                          */
1240 /*               ----------------------------------------------                          */
1241 /*               |    SIZE OF FREE AREA                       |                          */
1242 /*               ----------------------------------------------                          */
1243 /*               |    POINTER TO PREVIOUS FREE AREA           |                          */
1244 /*               ----------------------------------------------                          */
1245 /*               |    POINTER TO NEXT FREE AREA               |                          */
1246 /*               ----------------------------------------------                          */
1247 /*                                                                                       */
1248 /* IF THE POINTER TO THE NEXT AREA IS RNIL THEN THIS IS THE LAST FREE AREA.              */
1249 /*                                                                                       */
1250 /*****************************************************************************************/
1251 struct TableDescriptor {
1252   Uint32 tabDescr;
1253 };
1254 typedef Ptr<TableDescriptor> TableDescriptorPtr;
1255 
1256 struct HostBuffer {
1257   bool  inPackedList;
1258   Uint32 packetLenTA;
1259   Uint32 noOfPacketsTA;
1260   Uint32 packetBufferTA[30];
1261 };
1262 typedef Ptr<HostBuffer> HostBufferPtr;
1263 
1264   /*
1265    * Build index operation record.
1266    */
1267   struct BuildIndexRec {
1268     // request cannot use signal class due to extra members
1269     Uint32 m_request[BuildIndxReq::SignalLength];
1270     Uint8  m_build_vs;          // varsize pages
1271     Uint32 m_indexId;           // the index
1272     Uint32 m_fragNo;            // fragment number under Tablerec
1273     Uint32 m_pageId;            // logical fragment page id
1274     Uint32 m_tupleNo;           // tuple number on page
1275     Uint32 m_buildRef;          // Where to send tuples
1276     BuildIndxRef::ErrorCode m_errorCode;
1277     union {
1278       Uint32 nextPool;
1279       Uint32 nextList;
1280     };
1281     Uint32 prevList;
1282   };
1283   typedef Ptr<BuildIndexRec> BuildIndexPtr;
1284   ArrayPool<BuildIndexRec> c_buildIndexPool;
1285   DLList<BuildIndexRec> c_buildIndexList;
1286   Uint32 c_noOfBuildIndexRec;
1287 
1288   /**
1289    * Reference to variable part when a tuple is chained
1290    */
1291   struct Var_part_ref
1292   {
1293 #ifdef NDB_32BIT_VAR_REF
1294     /*
1295       In versions prior to ndb 6.1.6, 6.2.1 and mysql 5.1.17
1296       Running this code limits DataMemory to 16G, also online
1297       upgrade not possible between versions
1298      */
1299     Uint32 m_ref;
1300     STATIC_CONST( SZ32 = 1 );
1301 
copyoutDbtup::Var_part_ref1302     void copyout(Local_key* dst) const {
1303       dst->m_page_no = m_ref >> MAX_TUPLES_BITS;
1304       dst->m_page_idx = m_ref & MAX_TUPLES_PER_PAGE;
1305     }
1306 
assignDbtup::Var_part_ref1307     void assign(const Local_key* src) {
1308       m_ref = (src->m_page_no << MAX_TUPLES_BITS) | src->m_page_idx;
1309     }
1310 #else
1311     Uint32 m_page_no;
1312     Uint32 m_page_idx;
1313     STATIC_CONST( SZ32 = 2 );
1314 
1315     void copyout(Local_key* dst) const {
1316       dst->m_page_no = m_page_no;
1317       dst->m_page_idx = m_page_idx;
1318     }
1319 
1320     void assign(const Local_key* src) {
1321       m_page_no = src->m_page_no;
1322       m_page_idx = src->m_page_idx;
1323     }
1324 #endif
1325   };
1326 
1327   struct Disk_part_ref
1328   {
1329     STATIC_CONST( SZ32 = 2 );
1330   };
1331 
1332   struct Tuple_header
1333   {
1334     union {
1335       /**
1336        * List of prepared operations for this tuple.
1337        * Points to most recent/last operation, ie. to walk the list must follow
1338        * regOperPtr->prevActiveOp links.
1339        */
1340       Uint32 m_operation_ptr_i;  // OperationPtrI
1341       Uint32 m_base_record_ref;  // For disk tuple, ref to MM tuple
1342     };
1343     Uint32 m_header_bits;      // Header word
1344     union {
1345       Uint32 m_checksum;
1346       Uint32 m_data[1];
1347       Uint32 m_null_bits[1];
1348     };
1349 
1350     STATIC_CONST( HeaderSize = 2 );
1351 
1352     /**
1353      * header bits
1354      */
1355     STATIC_CONST( TUP_VERSION_MASK = 0xFFFF );
1356     STATIC_CONST( CHAINED_ROW = 0x00010000 ); // Is var part on different page
1357     STATIC_CONST( DISK_PART   = 0x00020000 ); // Is there a disk part
1358     STATIC_CONST( DISK_ALLOC  = 0x00040000 ); // Is disk part allocated
1359     STATIC_CONST( DISK_INLINE = 0x00080000 ); // Is disk inline
1360     STATIC_CONST( ALLOC       = 0x00100000 ); // Is record allocated now
1361     STATIC_CONST( MM_SHRINK   = 0x00200000 ); // Has MM part shrunk
1362     STATIC_CONST( MM_GROWN    = 0x00400000 ); // Has MM part grown
1363     STATIC_CONST( FREED       = 0x00800000 ); // Is freed
1364     STATIC_CONST( LCP_SKIP    = 0x01000000 ); // Should not be returned in LCP
1365     STATIC_CONST( LCP_KEEP    = 0x02000000 ); // Should be returned in LCP
1366     STATIC_CONST( FREE        = 0x02800000 ); // Is free
1367 
Tuple_headerDbtup::Tuple_header1368     Tuple_header() {}
get_tuple_versionDbtup::Tuple_header1369     Uint32 get_tuple_version() const {
1370       return m_header_bits & TUP_VERSION_MASK;
1371     }
set_tuple_versionDbtup::Tuple_header1372     void set_tuple_version(Uint32 version) {
1373       m_header_bits=
1374 	(m_header_bits & ~(Uint32)TUP_VERSION_MASK) |
1375 	(version & TUP_VERSION_MASK);
1376     }
1377 
get_null_bitsDbtup::Tuple_header1378     Uint32* get_null_bits(const Tablerec* tabPtrP) {
1379       return m_null_bits+tabPtrP->m_offsets[MM].m_null_offset;
1380     }
1381 
get_null_bitsDbtup::Tuple_header1382     Uint32* get_null_bits(const Tablerec* tabPtrP, Uint32 mm) {
1383       return m_null_bits+tabPtrP->m_offsets[mm].m_null_offset;
1384     }
1385 
get_var_part_ref_ptrDbtup::Tuple_header1386     Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) {
1387       return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
1388     }
1389 
get_var_part_ref_ptrDbtup::Tuple_header1390     const Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) const {
1391       return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
1392     }
1393 
get_end_of_fix_part_ptrDbtup::Tuple_header1394     Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) {
1395       return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
1396         Tuple_header::HeaderSize;
1397     }
1398 
get_end_of_fix_part_ptrDbtup::Tuple_header1399     const Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) const {
1400       return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
1401         Tuple_header::HeaderSize;
1402     }
1403 
get_disk_ref_ptrDbtup::Tuple_header1404     Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) {
1405       return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
1406     }
1407 
get_disk_ref_ptrDbtup::Tuple_header1408     const Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) const {
1409       return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
1410     }
1411 
get_mm_gciDbtup::Tuple_header1412     Uint32 *get_mm_gci(const Tablerec* tabPtrP){
1413       assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
1414       return m_data + (tabPtrP->m_bits & Tablerec::TR_Checksum);
1415     }
1416 
get_dd_gciDbtup::Tuple_header1417     Uint32 *get_dd_gci(const Tablerec* tabPtrP, Uint32 mm){
1418       assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
1419       return m_data;
1420     }
1421   };
1422 
1423 struct KeyReqStruct {
1424 /**
1425  * These variables are used as temporary storage during execution of the
1426  * TUPKEYREQ signal.
1427  * The first set of variables defines a number of variables needed for
1428  * the fix part of the tuple.
1429  *
1430  * The second part defines a number of commonly used meta data variables.
1431  *
1432  * The third set of variables defines a set of variables needed for the
1433  * variable part.
1434  *
1435  * The fourth part is variables needed only for updates and inserts.
1436  *
1437  * The fifth part is a long array of real lengths which is is put last
1438  * for cache memory reasons. This is part of the variable part and
1439  * contains the real allocated lengths whereas the tuple contains
1440  * the length of attribute stored.
1441  */
1442   Tuple_header *m_tuple_ptr;
1443 
1444   Uint32 check_offset[2];
1445 
1446   TableDescriptor *attr_descr;
1447   Uint32          max_read;
1448   Uint32          out_buf_index;
1449   Uint32          in_buf_index;
1450   Uint32          in_buf_len;
1451   Uint32          attr_descriptor;
1452   bool            xfrm_flag;
1453 
1454   struct Var_data {
1455     char *m_data_ptr;
1456     Uint16 *m_offset_array_ptr;
1457     Uint16 m_var_len_offset;
1458     Uint16 m_max_var_offset;
1459   } m_var_data[2];
1460 
1461   Tuple_header *m_disk_ptr;
1462   PagePtr m_page_ptr;
1463   PagePtr m_varpart_page_ptr;    // could be same as m_page_ptr_p
1464   PagePtr m_disk_page_ptr;       //
1465   Local_key m_row_id;
1466 
1467   bool            dirty_op;
1468   bool            interpreted_exec;
1469   bool            last_row;
1470   bool            m_use_rowid;
1471 
1472   Signal*         signal;
1473   Uint32 no_fired_triggers;
1474   Uint32 frag_page_id;
1475   Uint32 hash_value;
1476   Uint32 gci;
1477   Uint32 log_size;
1478   Uint32 read_length;
1479   Uint32 attrinfo_len;
1480   Uint32 tc_operation_ptr;
1481   Uint32 trans_id1;
1482   Uint32 trans_id2;
1483   Uint32 TC_index;
1484   // next 2 apply only to attrids >= 64 (zero otherwise)
1485   Uint32 max_attr_id_updated;
1486   Uint32 no_changed_attrs;
1487   BlockReference TC_ref;
1488   BlockReference rec_blockref;
1489   bool change_mask_calculated;
1490   /*
1491    * A bit mask where a bit set means that the update or insert
1492    * was updating this record.
1493    */
1494   Bitmask<MAXNROFATTRIBUTESINWORDS> changeMask;
1495   Uint16 var_pos_array[2*MAX_ATTRIBUTES_IN_TABLE + 1];
1496   OperationrecPtr prevOpPtr;
1497 };
1498 
1499   friend class Undo_buffer;
1500   Undo_buffer c_undo_buffer;
1501 
1502 /*
1503  No longer used:
1504  Implemented by shift instructions in subroutines instead
1505 
1506 struct TupHeadInfo {
1507   struct BitPart {
1508     unsigned int disk_indicator : 1;
1509     unsigned int var_part_loc_ind : 1;
1510     unsigned int initialised : 1;
1511     unsigned int not_used_yet : 5;
1512     unsigned int no_var_sized : 8;
1513     unsigned int tuple_version : 16;
1514   };
1515   union {
1516     Uint32 all;
1517     BitPart bit_part;
1518   };
1519 };
1520 */
1521 
1522 // updateAttributes module
1523   Uint32          terrorCode;
1524 
1525 public:
1526   Dbtup(Block_context&, Pgman*);
1527   virtual ~Dbtup();
1528 
1529   /*
1530    * TUX uses logical tuple address when talking to ACC and LQH.
1531    */
1532   void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32& tupAddr);
1533 
1534   /*
1535    * TUX index in TUP has single Uint32 array attribute which stores an
1536    * index node.  TUX reads and writes the node directly via pointer.
1537    */
1538   int tuxAllocNode(Signal* signal, Uint32 fragPtrI, Uint32& pageId, Uint32& pageOffset, Uint32*& node);
1539   void tuxFreeNode(Signal* signal, Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* node);
1540   void tuxGetNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32*& node);
1541 
1542   /*
1543    * TUX reads primary table attributes for index keys.  Tuple is
1544    * specified by location of original tuple and version number.  Input
1545    * is attribute ids in AttributeHeader format.  Output is attribute
1546    * data with headers.  Uses readAttributes with xfrm option set.
1547    * Returns number of words or negative (-terrorCode) on error.
1548    */
1549   int tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut);
1550 
1551   /*
1552    * TUX reads primary key without headers into an array of words.  Used
1553    * for md5 summing and when returning keyinfo.  Returns number of
1554    * words or negative (-terrorCode) on error.
1555    */
1556   int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag);
1557 
1558   /*
1559    * ACC reads primary key without headers into an array of words.  At
1560    * this point in ACC deconstruction, ACC still uses logical references
1561    * to fragment and tuple.
1562    */
1563   int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag);
1564 
1565   /*
1566    * TUX checks if tuple is visible to scan.
1567    */
1568   bool tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageIndex, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savepointId);
1569 
1570   int load_diskpage(Signal*, Uint32 opRec, Uint32 fragPtrI,
1571 		    Uint32 local_key, Uint32 flags);
1572 
1573   int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI,
1574 			 Uint32 local_key, Uint32 flags);
1575 
1576   int alloc_page(Tablerec*, Fragrecord*, PagePtr*,Uint32 page_no);
1577 
1578   void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
1579   void complete_restore_lcp(Uint32 tableId, Uint32 fragmentId);
1580 
1581   int nr_read_pk(Uint32 fragPtr, const Local_key*, Uint32* dataOut, bool&copy);
1582   int nr_update_gci(Uint32 fragPtr, const Local_key*, Uint32 gci);
1583   int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci);
1584 
1585   void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page);
1586   void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page);
1587 
1588   bool get_frag_info(Uint32 tableId, Uint32 fragId, Uint32* maxPage);
1589 private:
1590   BLOCK_DEFINES(Dbtup);
1591 
1592   // Transit signals
1593   void execDEBUG_SIG(Signal* signal);
1594   void execCONTINUEB(Signal* signal);
1595 
1596   // Received signals
1597   void execLCP_FRAG_ORD(Signal*signal);
1598   void execDUMP_STATE_ORD(Signal* signal);
1599   void execSEND_PACKED(Signal* signal);
1600   void execSTTOR(Signal* signal);
1601   void execTUP_LCPREQ(Signal* signal);
1602   void execEND_LCPREQ(Signal* signal);
1603   void execSTART_RECREQ(Signal* signal);
1604   void execMEMCHECKREQ(Signal* signal);
1605   void execTUPSEIZEREQ(Signal* signal);
1606   void execTUPRELEASEREQ(Signal* signal);
1607   void execSTORED_PROCREQ(Signal* signal);
1608   void execTUPFRAGREQ(Signal* signal);
1609   void execTUP_ADD_ATTRREQ(Signal* signal);
1610   void execTUP_COMMITREQ(Signal* signal);
1611   void execTUP_ABORTREQ(Signal* signal);
1612   void execNDB_STTOR(Signal* signal);
1613   void execREAD_CONFIG_REQ(Signal* signal);
1614   void execDROP_TAB_REQ(Signal* signal);
1615   void execALTER_TAB_REQ(Signal* signal);
1616   void execTUP_DEALLOCREQ(Signal* signal);
1617   void execTUP_WRITELOG_REQ(Signal* signal);
1618 
1619   // Ordered index related
1620   void execBUILDINDXREQ(Signal* signal);
1621   void buildIndex(Signal* signal, Uint32 buildPtrI);
1622   void buildIndexReply(Signal* signal, const BuildIndexRec* buildRec);
1623 
1624   // Tup scan
1625   void execACC_SCANREQ(Signal* signal);
1626   void execNEXT_SCANREQ(Signal* signal);
1627   void execACC_CHECK_SCAN(Signal* signal);
1628   void execACCKEYCONF(Signal* signal);
1629   void execACCKEYREF(Signal* signal);
1630   void execACC_ABORTCONF(Signal* signal);
1631 
1632 
1633   // Drop table
1634   void execFSREMOVEREF(Signal*);
1635   void execFSREMOVECONF(Signal*);
1636 
1637 //------------------------------------------------------------------
1638 //------------------------------------------------------------------
1639 // Methods to handle execution of TUPKEYREQ + ATTRINFO.
1640 //
1641 // Module Execution Manager
1642 //
1643 // The TUPKEYREQ signal is central to this block. This signal is used
1644 // by everybody that needs to read data residing in DBTUP. The data is
1645 // read using an interpreter approach.
1646 //
1647 // Operations only needing to read execute a simplified version of the
1648 // interpreter where the only instruction is read Attribute to send.
1649 // Operations only needing to update the record (insert or update)
1650 // execute a simplified version of the interpreter where the only
1651 // instruction is write Attribute.
1652 //
1653 // Currently TUPKEYREQ is used in the following situations.
1654 // 1) Normal transaction execution. Can be any of the types described
1655 //    below.
1656 // 2) Execution of fragment redo log during system restart.
1657 //    In this situation there will only be normal updates, inserts
1658 //    and deletes performed.
1659 // 3) A special type of normal transaction execution is to write the
1660 //    records arriving from the primary replica in the node restart
1661 //    processing. This will always be normal write operations which
1662 //    are translated to inserts or updates before arriving to TUP.
1663 // 4) Scan processing. The scan processing will use normal reads or
1664 //    interpreted reads in their execution. There will be one TUPKEYREQ
1665 //    signal for each record processed.
1666 // 5) Copy fragment processing. This is a special type of scan used in the
1667 //    primary replica at system restart. It reads the entire reads and
1668 //    converts those to writes to the starting node. In this special case
1669 //    LQH acts as an API node and receives also the ATTRINFO sent in the
1670 //    TRANSID_AI signals.
1671 //
1672 // Signal Diagram:
1673 //
1674 // In Signals:
1675 // -----------
1676 //
1677 // Logically there is one request TUPKEYREQ which requests to read/write data
1678 // of one tuple in the database. Since the definition of what to read and write
1679 // can be bigger than the maximum signal size we segment the signal. The definition
1680 // of what to read/write/interpreted program is sent before the TUPKEYREQ signal.
1681 //
1682 // ---> ATTRINFO
1683 // ...
1684 // ---> ATTRINFO
1685 // ---> TUPKEYREQ
1686 // The number of ATTRINFO signals can be anything between 0 and upwards.
1687 // The total size of the ATTRINFO is not allowed to be more than 16384 words.
1688 // There is always one and only one TUPKEYREQ.
1689 //
1690 // Response Signals (successful case):
1691 //
1692 // Simple/Dirty Read Operation
1693 // ---------------------------
1694 //
1695 // <---- TRANSID_AI (to API)
1696 // ...
1697 // <---- TRANSID_AI (to API)
1698 // <---- READCONF   (to API)
1699 // <---- TUPKEYCONF (to LQH)
1700 // There is always exactly one READCONF25 sent last. The number of
1701 // TRANSID_AI is dependent on how much that was read. The maximum size
1702 // of the ATTRINFO sent back is 16384 words. The signals are sent
1703 // directly to the application with an address provided by the
1704 // TUPKEYREQ signal.
1705 // A positive response signal is also sent to LQH.
1706 //
1707 // Normal Read Operation
1708 // ---------------------
1709 //
1710 // <---- TRANSID_AI (to API)
1711 // ...
1712 // <---- TRANSID_AI (to API)
1713 // <---- TUPKEYCONF (to LQH)
1714 // The number of TRANSID_AI is dependent on how much that was read.
1715 // The maximum size of the ATTRINFO sent back is 16384 words. The
1716 // signals are sent directly to the application with an address
1717 // provided by the TUPKEYREQ signal.
1718 // A positive response signal is also sent to LQH.
1719 //
1720 // Normal update/insert/delete operation
1721 // -------------------------------------
1722 //
1723 // <---- TUPKEYCONF
1724 // After successful updating of the tuple LQH is informed of this.
1725 //
1726 // Delete with read
1727 // ----------------
1728 //
1729 // Will behave as a normal read although it also prepares the
1730 // deletion of the tuple.
1731 //
1732 // Interpreted Update
1733 // ------------------
1734 //
1735 // <---- TRANSID_AI (to API)
1736 // ...
1737 // <---- TRANSID_AI (to API)
1738 // <---- TUP_ATTRINFO (to LQH)
1739 // ...
1740 // <---- TUP_ATTRINFO (to LQH)
1741 // <---- TUPKEYCONF (to LQH)
1742 //
1743 // The interpreted Update contains five sections:
1744 // The first section performs read Attribute operations
1745 // that send results back to the API.
1746 //
1747 // The second section executes the interpreted program
1748 // where data from attributes can be updated and it
1749 // can also read attribute values into the registers.
1750 //
1751 // The third section performs unconditional updates of
1752 // attributes.
1753 //
1754 // The fourth section can read the attributes to be sent to the
1755 // API after updating the record.
1756 //
1757 // The fifth section contains subroutines used by the interpreter
1758 // in the second section.
1759 //
1760 // All types of interpreted programs contains the same five sections.
1761 // The only difference is that only interpreted updates can update
1762 // attributes. Interpreted inserts are not allowed.
1763 //
1764 // Interpreted Updates have to send back the information about the
1765 // attributes they have updated. This information will be shipped to
1766 // the log and also to any other replicas. Thus interpreted updates
1767 // are only performed in the primary replica. The fragment redo log
1768 // in LQH will contain information so that normal update/inserts/deletes
1769 // can be performed using TUPKEYREQ.
1770 //
1771 // Interpreted Read
1772 // ----------------
1773 //
1774 // From a signalling point of view the Interpreted Read behaves as
1775 // as a Normal Read. The interpreted Read is often used by Scan's.
1776 //
1777 // Interpreted Delete
1778 // ------------------
1779 //
1780 // <---- TUPKEYCONF
1781 // After successful prepartion to delete the tuple LQH is informed
1782 // of this.
1783 //
1784 // Interpreted Delete with Read
1785 // ----------------------------
1786 //
1787 // From a signalling point of view an interpreted delete with read
1788 // behaves as a normal read.
1789 //
1790 // Continuation after successful case:
1791 //
1792 // After a read of any kind the operation record is ready to be used
1793 // again by a new operation.
1794 //
1795 // Any updates, inserts or deletes waits for either of two messages.
1796 // A commit specifying that the operation is to be performed for real
1797 // or an abort specifying that the operation is to be rolled back and
1798 // the record to be restored in its original format.
1799 //
1800 // This is handled by the module Transaction Manager.
1801 //
1802 // Response Signals (unsuccessful case):
1803 //
1804 // <---- TUPKEYREF (to LQH)
1805 // A signal is sent back to LQH informing about the unsuccessful
1806 // operation. In this case TUP waits for an abort signal to arrive
1807 // before the operation record is ready for the next operation.
1808 // This is handled by the Transaction Manager.
1809 //------------------------------------------------------------------
1810 //------------------------------------------------------------------
1811 
1812 // *****************************************************************
1813 // Signal Reception methods.
1814 // *****************************************************************
1815 //------------------------------------------------------------------
1816 //------------------------------------------------------------------
1817   void execTUPKEYREQ(Signal* signal);
1818   void disk_page_load_callback(Signal*, Uint32 op, Uint32 page);
1819   void disk_page_load_scan_callback(Signal*, Uint32 op, Uint32 page);
1820 
1821 //------------------------------------------------------------------
1822 //------------------------------------------------------------------
1823   void execATTRINFO(Signal* signal);
1824 public:
1825   void receive_attrinfo(Signal*, Uint32 op, const Uint32* data, Uint32 len);
1826 private:
1827 
1828 // Trigger signals
1829 //------------------------------------------------------------------
1830 //------------------------------------------------------------------
1831   void execCREATE_TRIG_REQ(Signal* signal);
1832 
1833 //------------------------------------------------------------------
1834 //------------------------------------------------------------------
1835   void execDROP_TRIG_REQ(Signal* signal);
1836 
1837 // *****************************************************************
1838 // Support methods for ATTRINFO.
1839 // *****************************************************************
1840 //------------------------------------------------------------------
1841 //------------------------------------------------------------------
1842   void handleATTRINFOforTUPKEYREQ(Signal* signal,
1843 				  const Uint32* data,
1844                                   Uint32 length,
1845                                   Operationrec * regOperPtr);
1846 
1847 // *****************************************************************
1848 // Setting up the environment for reads, inserts, updates and deletes.
1849 // *****************************************************************
1850 //------------------------------------------------------------------
1851 //------------------------------------------------------------------
1852   int handleReadReq(Signal* signal,
1853                     Operationrec* regOperPtr,
1854                     Tablerec* regTabPtr,
1855                     KeyReqStruct* req_struct);
1856 
1857 //------------------------------------------------------------------
1858 //------------------------------------------------------------------
1859   int handleUpdateReq(Signal* signal,
1860                       Operationrec* regOperPtr,
1861                       Fragrecord* regFragPtr,
1862                       Tablerec* regTabPtr,
1863                       KeyReqStruct* req_struct,
1864 		      bool disk);
1865 
1866 //------------------------------------------------------------------
1867 //------------------------------------------------------------------
1868   int handleInsertReq(Signal* signal,
1869                       Ptr<Operationrec> regOperPtr,
1870                       Ptr<Fragrecord>,
1871                       Tablerec* regTabPtr,
1872                       KeyReqStruct* req_struct);
1873 
1874 //------------------------------------------------------------------
1875 //------------------------------------------------------------------
1876   int handleDeleteReq(Signal* signal,
1877                       Operationrec* regOperPtr,
1878                       Fragrecord* regFragPtr,
1879                       Tablerec* regTabPtr,
1880                       KeyReqStruct* req_struct,
1881 		      bool disk);
1882 
1883 //------------------------------------------------------------------
1884 //------------------------------------------------------------------
1885   int  updateStartLab(Signal* signal,
1886                       Operationrec* regOperPtr,
1887                       Fragrecord* regFragPtr,
1888                       Tablerec* regTabPtr,
1889                       KeyReqStruct* req_struct);
1890 
1891 // *****************************************************************
1892 // Interpreter Handling methods.
1893 // *****************************************************************
1894 
1895 //------------------------------------------------------------------
1896 //------------------------------------------------------------------
1897   int interpreterStartLab(Signal* signal,
1898                           KeyReqStruct *req_struct);
1899 
1900 //------------------------------------------------------------------
1901 //------------------------------------------------------------------
1902   int interpreterNextLab(Signal* signal,
1903                          KeyReqStruct *req_struct,
1904                          Uint32* logMemory,
1905                          Uint32* mainProgram,
1906                          Uint32 TmainProgLen,
1907                          Uint32* subroutineProg,
1908                          Uint32 TsubroutineLen,
1909 			 Uint32 * tmpArea,
1910 			 Uint32 tmpAreaSz);
1911 
1912 // *****************************************************************
1913 // Signal Sending methods.
1914 // *****************************************************************
1915 //------------------------------------------------------------------
1916 //------------------------------------------------------------------
1917   void sendReadAttrinfo(Signal* signal,
1918                         KeyReqStruct *req_struct,
1919                         Uint32 TnoOfData,
1920                         const Operationrec * regOperPtr);
1921 
1922 //------------------------------------------------------------------
1923 //------------------------------------------------------------------
1924   void sendLogAttrinfo(Signal* signal,
1925                        Uint32 TlogSize,
1926                        Operationrec * regOperPtr);
1927 
1928 //------------------------------------------------------------------
1929 //------------------------------------------------------------------
1930   void sendTUPKEYCONF(Signal* signal,
1931                       KeyReqStruct *req_struct,
1932                       Operationrec * regOperPtr);
1933 
1934 //------------------------------------------------------------------
1935 //------------------------------------------------------------------
1936 // *****************************************************************
1937 // The methods that perform the actual read and update of attributes
1938 // in the tuple.
1939 // *****************************************************************
1940 //------------------------------------------------------------------
1941 //------------------------------------------------------------------
1942   int readAttributes(KeyReqStruct* req_struct,
1943                      const Uint32*  inBuffer,
1944                      Uint32   inBufLen,
1945                      Uint32*  outBuffer,
1946                      Uint32   TmaxRead,
1947                      bool     xfrmFlag);
1948 
1949 //------------------------------------------------------------------
1950 //------------------------------------------------------------------
1951   int updateAttributes(KeyReqStruct *req_struct,
1952                        Uint32*     inBuffer,
1953                        Uint32      inBufLen);
1954 
1955 //------------------------------------------------------------------
1956 //------------------------------------------------------------------
1957   bool readFixedSizeTHOneWordNotNULL(Uint32* outBuffer,
1958                                      KeyReqStruct *req_struct,
1959                                      AttributeHeader* ahOut,
1960                                      Uint32  attrDes2);
1961 
1962 //------------------------------------------------------------------
1963 //------------------------------------------------------------------
1964   bool updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer,
1965                                        KeyReqStruct *req_struct,
1966                                        Uint32  attrDes2);
1967 
1968 //------------------------------------------------------------------
1969 //------------------------------------------------------------------
1970   bool readFixedSizeTHTwoWordNotNULL(Uint32* outBuffer,
1971                                      KeyReqStruct *req_struct,
1972                                      AttributeHeader* ahOut,
1973                                      Uint32  attrDes2);
1974 
1975 //------------------------------------------------------------------
1976 //------------------------------------------------------------------
1977   bool updateFixedSizeTHTwoWordNotNULL(Uint32* inBuffer,
1978                                        KeyReqStruct *req_struct,
1979                                        Uint32  attrDes2);
1980 
1981 //------------------------------------------------------------------
1982 //------------------------------------------------------------------
1983   bool readFixedSizeTHManyWordNotNULL(Uint32* outBuffer,
1984                                       KeyReqStruct *req_struct,
1985                                       AttributeHeader* ahOut,
1986                                       Uint32  attrDes2);
1987 
1988 //------------------------------------------------------------------
1989 //------------------------------------------------------------------
1990   bool updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
1991                                         KeyReqStruct *req_struct,
1992                                         Uint32  attrDes2);
1993 
1994 //------------------------------------------------------------------
1995 //------------------------------------------------------------------
1996   bool readFixedSizeTHOneWordNULLable(Uint32* outBuffer,
1997                                       KeyReqStruct *req_struct,
1998                                       AttributeHeader* ahOut,
1999                                       Uint32  attrDes2);
2000 
2001 //------------------------------------------------------------------
2002 //------------------------------------------------------------------
2003   bool updateFixedSizeTHOneWordNULLable(Uint32* inBuffer,
2004                                         KeyReqStruct *req_struct,
2005                                         Uint32  attrDes2);
2006 
2007 //------------------------------------------------------------------
2008 //------------------------------------------------------------------
2009   bool readFixedSizeTHTwoWordNULLable(Uint32* outBuffer,
2010                                       KeyReqStruct *req_struct,
2011                                       AttributeHeader* ahOut,
2012                                       Uint32  attrDes2);
2013 
2014 //------------------------------------------------------------------
2015 //------------------------------------------------------------------
2016   bool updateFixedSizeTHTwoWordNULLable(Uint32* inBuffer,
2017                                         KeyReqStruct *req_struct,
2018                                         Uint32  attrDes2);
2019 
2020 //------------------------------------------------------------------
2021 //------------------------------------------------------------------
2022   bool readFixedSizeTHManyWordNULLable(Uint32* outBuffer,
2023                                        KeyReqStruct *req_struct,
2024                                        AttributeHeader* ahOut,
2025                                        Uint32  attrDes2);
2026 
2027 //------------------------------------------------------------------
2028 //------------------------------------------------------------------
2029   bool readFixedSizeTHZeroWordNULLable(Uint32* outBuffer,
2030                                        KeyReqStruct *req_struct,
2031                                        AttributeHeader* ahOut,
2032                                        Uint32  attrDes2);
2033 //------------------------------------------------------------------
2034 //------------------------------------------------------------------
2035   bool updateFixedSizeTHManyWordNULLable(Uint32* inBuffer,
2036                                          KeyReqStruct *req_struct,
2037                                          Uint32  attrDes2);
2038 
2039 //------------------------------------------------------------------
2040 //------------------------------------------------------------------
2041   bool readVarSizeNotNULL(Uint32* outBuffer,
2042                           KeyReqStruct *req_struct,
2043                           AttributeHeader* ahOut,
2044                           Uint32  attrDes2);
2045 
2046 //------------------------------------------------------------------
2047 //------------------------------------------------------------------
2048   bool updateVarSizeNotNULL(Uint32* inBuffer,
2049                             KeyReqStruct *req_struct,
2050                             Uint32  attrDes2);
2051 
2052 //------------------------------------------------------------------
2053 //------------------------------------------------------------------
2054   bool readVarSizeNULLable(Uint32* outBuffer,
2055                            KeyReqStruct *req_struct,
2056                            AttributeHeader* ahOut,
2057                            Uint32  attrDes2);
2058 
2059 //------------------------------------------------------------------
2060 //------------------------------------------------------------------
2061   bool updateVarSizeNULLable(Uint32* inBuffer,
2062                              KeyReqStruct *req_struct,
2063                              Uint32  attrDes2);
2064 
2065 //------------------------------------------------------------------
2066 //------------------------------------------------------------------
2067   bool readDynFixedSize(Uint32* outBuffer,
2068                         KeyReqStruct *req_struct,
2069                         AttributeHeader* ahOut,
2070                         Uint32  attrDes2);
2071 
2072 //------------------------------------------------------------------
2073 //------------------------------------------------------------------
2074   bool updateDynFixedSize(Uint32* inBuffer,
2075                           KeyReqStruct *req_struct,
2076                           Uint32  attrDes2);
2077 
2078 //------------------------------------------------------------------
2079 //------------------------------------------------------------------
2080   bool readDynVarSize(Uint32* outBuffer,
2081                       KeyReqStruct *req_struct,
2082                       AttributeHeader* ahOut,
2083                       Uint32  attrDes2);
2084 
2085 //------------------------------------------------------------------
2086 //------------------------------------------------------------------
2087   bool updateDynVarSize(Uint32* inBuffer,
2088                         KeyReqStruct *req_struct,
2089                         Uint32  attrDes2);
2090 
2091   bool readCharNotNULL(Uint32* outBuffer,
2092                        KeyReqStruct *req_struct,
2093                        AttributeHeader* ahOut,
2094                        Uint32  attrDes2);
2095 
2096   bool readCharNULLable(Uint32* outBuffer,
2097                         KeyReqStruct *req_struct,
2098                         AttributeHeader* ahOut,
2099                         Uint32  attrDes2);
2100 
2101   bool readBitsNULLable(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
2102   bool updateBitsNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2103   bool readBitsNotNULL(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
2104   bool updateBitsNotNULL(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2105 
2106   bool updateFixedNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2107   bool updateFixedNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2108 
2109   bool updateVarNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2110   bool updateVarNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2111 
2112 
2113   bool readDiskFixedSizeNotNULL(Uint32* outBuffer,
2114 				KeyReqStruct *req_struct,
2115 				AttributeHeader* ahOut,
2116 				Uint32  attrDes2);
2117 
2118   bool readDiskFixedSizeNULLable(Uint32* outBuffer,
2119 				 KeyReqStruct *req_struct,
2120 				 AttributeHeader* ahOut,
2121 				 Uint32  attrDes2);
2122   bool readDiskVarSizeNULLable(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
2123   bool readDiskVarSizeNotNULL(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
2124 
2125   bool updateDiskFixedSizeNULLable(Uint32*, KeyReqStruct*, Uint32);
2126   bool updateDiskFixedSizeNotNULL(Uint32*, KeyReqStruct*, Uint32);
2127 
2128   bool updateDiskVarSizeNULLable(Uint32*, KeyReqStruct *, Uint32);
2129   bool updateDiskVarSizeNotNULL(Uint32*, KeyReqStruct *, Uint32);
2130 
2131   bool readDiskBitsNULLable(Uint32*, KeyReqStruct*, AttributeHeader*, Uint32);
2132   bool readDiskBitsNotNULL(Uint32*, KeyReqStruct*, AttributeHeader*, Uint32);
2133   bool updateDiskBitsNULLable(Uint32*, KeyReqStruct*, Uint32);
2134   bool updateDiskBitsNotNULL(Uint32*, KeyReqStruct*, Uint32);
2135 
2136 
2137 //------------------------------------------------------------------
2138 //------------------------------------------------------------------
2139   bool nullFlagCheck(KeyReqStruct *req_struct, Uint32  attrDes2);
2140   bool disk_nullFlagCheck(KeyReqStruct *req_struct, Uint32  attrDes2);
2141   Uint32 read_pseudo(Uint32 attrId,
2142                      KeyReqStruct *req_struct,
2143                      Uint32* outBuffer);
2144 
2145 //------------------------------------------------------------------
2146 //------------------------------------------------------------------
2147   void setUpQueryRoutines(Tablerec* regTabPtr);
2148 
2149 // *****************************************************************
2150 // Service methods.
2151 // *****************************************************************
2152   TransState get_trans_state(Operationrec * const);
2153   void set_trans_state(Operationrec * const, TransState);
2154   TupleState get_tuple_state(Operationrec * const);
2155   void set_tuple_state(Operationrec * const, TupleState);
2156   Uint32 get_frag_page_id(Uint32 real_page_id);
2157   Uint32 get_fix_page_offset(Uint32 page_index, Uint32 tuple_size);
2158 
2159   Uint32 decr_tup_version(Uint32 tuple_version);
2160   void set_change_mask_state(Operationrec * const, ChangeMaskState);
2161   ChangeMaskState get_change_mask_state(Operationrec * const);
2162   void update_change_mask_info(KeyReqStruct * const, Operationrec * const);
2163   void set_change_mask_info(KeyReqStruct * const, Operationrec * const);
2164 
2165 //------------------------------------------------------------------
2166 //------------------------------------------------------------------
2167   void copyAttrinfo(Operationrec * regOperPtr, Uint32*  inBuffer);
2168 
2169 //------------------------------------------------------------------
2170 //------------------------------------------------------------------
2171   void initOpConnection(Operationrec* regOperPtr);
2172 
2173 //------------------------------------------------------------------
2174 //------------------------------------------------------------------
2175   void initOperationrec(Signal* signal);
2176 
2177 //------------------------------------------------------------------
2178 //------------------------------------------------------------------
2179   int initStoredOperationrec(Operationrec* regOperPtr,
2180                              KeyReqStruct* req_struct,
2181                              Uint32 storedId);
2182 
2183 //------------------------------------------------------------------
2184 //------------------------------------------------------------------
2185   bool insertActiveOpList(OperationrecPtr, KeyReqStruct* req_struct);
2186 
2187 //------------------------------------------------------------------
2188 //------------------------------------------------------------------
2189 
2190 //------------------------------------------------------------------
2191 //------------------------------------------------------------------
2192   void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen);
2193 
2194 //------------------------------------------------------------------
2195 // Trigger handling routines
2196 //------------------------------------------------------------------
2197   DLList<TupTriggerData>*
2198   findTriggerList(Tablerec* table,
2199                   TriggerType::Value ttype,
2200                   TriggerActionTime::Value ttime,
2201                   TriggerEvent::Value tevent);
2202 
2203   bool createTrigger(Tablerec* table, const CreateTrigReq* req);
2204 
2205   Uint32 dropTrigger(Tablerec* table,
2206 		     const DropTrigReq* req,
2207 		     BlockNumber sender);
2208 
2209   void
2210   checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
2211                                     Operationrec* regOperPtr,
2212                                     Tablerec* tablePtr,
2213                                     bool disk);
2214 
2215   void
2216   checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
2217                                     Operationrec* regOperPtr,
2218                                     Tablerec* tablePtr,
2219                                     bool disk);
2220 
2221   void
2222   checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
2223                                     Operationrec* regOperPtr,
2224                                     Tablerec* tablePtr,
2225                                     bool disk);
2226 
2227 #if 0
2228   void checkDeferredTriggers(Signal* signal,
2229                              Operationrec* regOperPtr,
2230                              Tablerec* regTablePtr);
2231 #endif
2232   void checkDetachedTriggers(KeyReqStruct *req_struct,
2233                              Operationrec* regOperPtr,
2234                              Tablerec* regTablePtr,
2235                              bool disk);
2236 
2237   void fireImmediateTriggers(KeyReqStruct *req_struct,
2238                              DLList<TupTriggerData>& triggerList,
2239                              Operationrec* regOperPtr,
2240                              bool disk);
2241 
2242   void fireDeferredTriggers(KeyReqStruct *req_struct,
2243                             DLList<TupTriggerData>& triggerList,
2244                             Operationrec* regOperPtr);
2245 
2246   void fireDetachedTriggers(KeyReqStruct *req_struct,
2247                             DLList<TupTriggerData>& triggerList,
2248                             Operationrec* regOperPtr,
2249                             bool disk);
2250 
2251   void executeTriggers(KeyReqStruct *req_struct,
2252                        DLList<TupTriggerData>& triggerList,
2253                        Operationrec* regOperPtr,
2254                        bool disk);
2255 
2256   void executeTrigger(KeyReqStruct *req_struct,
2257                       TupTriggerData* trigPtr,
2258                       Operationrec* regOperPtr,
2259                       bool disk);
2260 
2261   bool readTriggerInfo(TupTriggerData* trigPtr,
2262                        Operationrec* regOperPtr,
2263                        KeyReqStruct * req_struct,
2264                        Fragrecord* regFragPtr,
2265                        Uint32* keyBuffer,
2266                        Uint32& noPrimKey,
2267                        Uint32* afterBuffer,
2268                        Uint32& noAfterWords,
2269                        Uint32* beforeBuffer,
2270                        Uint32& noBeforeWords,
2271                        bool disk);
2272 
2273   void sendTrigAttrInfo(Signal*        signal,
2274                         Uint32*        data,
2275                         Uint32         dataLen,
2276                         bool           executeDirect,
2277                         BlockReference receiverReference);
2278 
2279   Uint32 setAttrIds(Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask,
2280                     Uint32 noOfAttributes,
2281                     Uint32* inBuffer);
2282 
2283   void sendFireTrigOrd(Signal* signal,
2284                        KeyReqStruct *req_struct,
2285                        Operationrec * regOperPtr,
2286                        TupTriggerData* trigPtr,
2287 		       Uint32 fragmentId,
2288                        Uint32 noPrimKeySignals,
2289                        Uint32 noBeforeSignals,
2290                        Uint32 noAfterSignals);
2291 
2292   bool primaryKey(Tablerec* const, Uint32);
2293 
2294   // these set terrorCode and return non-zero on error
2295 
2296   int executeTuxInsertTriggers(Signal* signal,
2297                                Operationrec* regOperPtr,
2298                                Fragrecord* regFragPtr,
2299                                Tablerec* regTabPtr);
2300 
2301   int executeTuxUpdateTriggers(Signal* signal,
2302                                Operationrec* regOperPtr,
2303                                Fragrecord* regFragPtr,
2304                                Tablerec* regTabPtr);
2305 
2306   int executeTuxDeleteTriggers(Signal* signal,
2307                                Operationrec* regOperPtr,
2308                                Fragrecord* regFragPtr,
2309                                Tablerec* regTabPtr);
2310 
2311   int addTuxEntries(Signal* signal,
2312                     Operationrec* regOperPtr,
2313                     Tablerec* regTabPtr);
2314 
2315   // these crash the node on error
2316 
2317   void executeTuxCommitTriggers(Signal* signal,
2318                                 Operationrec* regOperPtr,
2319                                 Fragrecord* regFragPtr,
2320                                 Tablerec* regTabPtr);
2321 
2322   void executeTuxAbortTriggers(Signal* signal,
2323                                Operationrec* regOperPtr,
2324                                Fragrecord* regFragPtr,
2325                                Tablerec* regTabPtr);
2326 
2327   void removeTuxEntries(Signal* signal,
2328                         Tablerec* regTabPtr);
2329 
2330 // *****************************************************************
2331 // Error Handling routines.
2332 // *****************************************************************
2333 //------------------------------------------------------------------
2334 //------------------------------------------------------------------
2335   int TUPKEY_abort(Signal* signal, int error_type);
2336 
2337 //------------------------------------------------------------------
2338 //------------------------------------------------------------------
2339   void tupkeyErrorLab(Signal* signal);
2340   void do_tup_abortreq(Signal*, Uint32 flags);
2341 
2342 //------------------------------------------------------------------
2343 //------------------------------------------------------------------
2344 // Methods to handle execution of TUP_COMMITREQ + TUP_ABORTREQ.
2345 //
2346 // Module Transaction Manager
2347 //
2348 // The Transaction Manager module is responsible for the commit
2349 // and abort of operations started by the Execution Manager.
2350 //
2351 // Commit Operation:
2352 // ----------------
2353 //
2354 // Failures in commit processing is not allowed since that would
2355 // leave the database in an unreliable state. Thus the only way
2356 // to handle failures in commit processing is to crash the node.
2357 //
2358 // TUP_COMMITREQ can only be received in the wait state after a
2359 // successful TUPKEYREQ which was not a read operation.
2360 //
2361 // Commit of Delete:
2362 // -----------------
2363 //
2364 // This will actually perform the deletion of the record unless
2365 // other operations also are connected to the record. In this case
2366 // we will set the delete state on the record that becomes the ownerd
2367 // of the record.
2368 //
2369 // Commit of Update:
2370 // ----------------
2371 //
2372 // We will release the copy record where the original record was kept.
2373 // Also here we will take special care if more operations are updating
2374 // the record simultaneously.
2375 //
2376 // Commit of Insert:
2377 // -----------------
2378 //
2379 // Will simply reset the state of the operation record.
2380 //
2381 // Signal Diagram:
2382 // --->  TUP_COMMITREQ (from LQH)
2383 // <---- TUP_COMMITCONF (to LQH)
2384 //
2385 //
2386 // Abort Operation:
2387 // ----------------
2388 //
2389 // Signal Diagram:
2390 // --->  TUP_ABORTREQ (from LQH)
2391 // <---- TUP_ABORTCONF (to LQH)
2392 //
2393 // Failures in abort processing is not allowed since that would
2394 // leave the database in an unreliable state. Thus the only way
2395 // to handle failures in abort processing is to crash the node.
2396 //
2397 // Abort messages can arrive at any time. It can arrive even before
2398 // anything at all have arrived of the operation. It can arrive after
2399 // receiving a number of ATTRINFO but before TUPKEYREQ has been received.
2400 // It must arrive after that we sent TUPKEYREF in response to TUPKEYREQ
2401 // and finally it can arrive after successfully performing the TUPKEYREQ
2402 // in all cases including the read case.
2403 //------------------------------------------------------------------
2404 //------------------------------------------------------------------
2405 
2406 #if 0
2407   void checkPages(Fragrecord* regFragPtr);
2408 #endif
convert_byte_to_word_size(Uint32 byte_size)2409   Uint32 convert_byte_to_word_size(Uint32 byte_size)
2410   {
2411     return ((byte_size + 3) >> 2);
2412   }
convert_bit_to_word_size(Uint32 bit_size)2413   Uint32 convert_bit_to_word_size(Uint32 bit_size)
2414   {
2415     return ((bit_size + 31) >> 5);
2416   }
2417 
2418   void prepare_initial_insert(KeyReqStruct*, Operationrec*, Tablerec*);
2419   void fix_disk_insert_no_mem_insert(KeyReqStruct*, Operationrec*, Tablerec*);
2420   void setup_fixed_part(KeyReqStruct* req_struct,
2421 			Operationrec* regOperPtr,
2422 			Tablerec* regTabPtr);
2423 
2424   void send_TUPKEYREF(Signal* signal,
2425                       Operationrec* regOperPtr);
2426   void early_tupkey_error(Signal* signal);
2427 
2428   void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit);
2429 
2430   bool checkUpdateOfPrimaryKey(KeyReqStruct *req_struct,
2431                                Uint32* updateBuffer,
2432                                Tablerec* regTabPtr);
2433 
2434   void setNullBits(Uint32*, Tablerec* regTabPtr);
2435   bool checkNullAttributes(KeyReqStruct * const, Tablerec* const);
2436   bool find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId);
2437   bool setup_read(KeyReqStruct* req_struct,
2438 		  Operationrec* regOperPtr,
2439 		  Fragrecord* regFragPtr,
2440 		  Tablerec* regTabPtr,
2441 		  bool disk);
2442 
2443   Uint32 calculateChecksum(Tuple_header*, Tablerec* regTabPtr);
2444   void setChecksum(Tuple_header*, Tablerec* regTabPtr);
2445 
2446   void complexTrigger(Signal* signal,
2447                       KeyReqStruct *req_struct,
2448                       Operationrec* regOperPtr,
2449                       Fragrecord* regFragPtr,
2450                       Tablerec* regTabPtr);
2451 
2452   void setTupleStatesSetOpType(Operationrec* regOperPtr,
2453                                KeyReqStruct *req_struct,
2454                                Page* pagePtr,
2455                                Uint32& opType,
2456                                OperationrecPtr& firstOpPtr);
2457 
2458   void findBeforeValueOperation(OperationrecPtr& befOpPtr,
2459                                 OperationrecPtr firstOpPtr);
2460 
2461   void calculateChangeMask(Page* PagePtr,
2462                            Tablerec* regTabPtr,
2463                            KeyReqStruct * req_struct);
2464 
2465   void updateGcpId(KeyReqStruct *req_struct,
2466                    Operationrec* regOperPtr,
2467                    Fragrecord* regFragPtr,
2468                    Tablerec* regTabPtr);
2469 
2470   void setTupleStateOnPreviousOps(Uint32 prevOpIndex);
2471   void copyMem(Signal* signal, Uint32 sourceIndex, Uint32 destIndex);
2472 
2473   void freeAllAttrBuffers(Operationrec*  const regOperPtr);
2474   void freeAttrinbufrec(Uint32 anAttrBufRec);
2475   void removeActiveOpList(Operationrec*  const regOperPtr, Tuple_header*);
2476 
2477   void updatePackedList(Signal* signal, Uint16 ahostIndex);
2478 
2479   void setUpDescriptorReferences(Uint32 descriptorReference,
2480                                  Tablerec* regTabPtr,
2481                                  const Uint32* offset);
2482   void setUpKeyArray(Tablerec* regTabPtr);
2483   bool addfragtotab(Tablerec* regTabPtr, Uint32 fragId, Uint32 fragIndex);
2484   void deleteFragTab(Tablerec* regTabPtr, Uint32 fragId);
2485   void abortAddFragOp(Signal* signal);
2486   void releaseTabDescr(Tablerec* regTabPtr);
2487   void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* regTabPtr);
2488 
2489   void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32);
2490   void initializeAttrbufrec();
2491   void initializeCheckpointInfoRec();
2492   void initializeDiskBufferSegmentRecord();
2493   void initializeFragoperrec();
2494   void initializeFragrecord();
2495   void initializeHostBuffer();
2496   void initializeLocalLogInfo();
2497   void initializeOperationrec();
2498   void initializePendingFileOpenInfoRecord();
2499   void initializeRestartInfoRec();
2500   void initializeTablerec();
2501   void initializeTabDescr();
2502   void initializeUndoPage();
2503 
2504   void initTab(Tablerec* regTabPtr);
2505 
2506   void startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2);
2507 
2508   void fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr);
2509   void fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr);
2510   void fragrefuse2Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr);
2511   void fragrefuse3Lab(Signal* signal,
2512                       FragoperrecPtr fragOperPtr,
2513                       FragrecordPtr regFragPtr,
2514                       Tablerec* regTabPtr,
2515                       Uint32 fragId);
2516   void fragrefuse4Lab(Signal* signal,
2517                       FragoperrecPtr fragOperPtr,
2518                       FragrecordPtr regFragPtr,
2519                       Tablerec* regTabPtr,
2520                       Uint32 fragId);
2521   void addattrrefuseLab(Signal* signal,
2522                         FragrecordPtr regFragPtr,
2523                         FragoperrecPtr fragOperPtr,
2524                         Tablerec* regTabPtr,
2525                         Uint32 fragId);
2526 
2527 
2528   void releaseFragment(Signal* signal, Uint32 tableId, Uint32);
2529   void drop_fragment_free_var_pages(Signal*);
2530   void drop_fragment_free_extent(Signal*, TablerecPtr, FragrecordPtr, Uint32);
2531   void drop_fragment_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
2532   void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32);
2533   void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32);
2534   void drop_fragment_fsremove(Signal*, TablerecPtr, FragrecordPtr);
2535   void drop_fragment_fsremove_done(Signal*, TablerecPtr, FragrecordPtr);
2536 
2537   // Initialisation
2538   void initData();
2539   void initRecords();
2540 
2541   void deleteScanProcedure(Signal* signal, Operationrec* regOperPtr);
2542   void copyProcedure(Signal* signal,
2543                      TablerecPtr regTabPtr,
2544                      Operationrec* regOperPtr);
2545   void scanProcedure(Signal* signal,
2546                      Operationrec* regOperPtr,
2547                      Uint32 lenAttrInfo);
2548   void storedSeizeAttrinbufrecErrorLab(Signal* signal,
2549                                        Operationrec* regOperPtr,
2550                                        Uint32 errorCode);
2551   bool storedProcedureAttrInfo(Signal* signal,
2552                                Operationrec* regOperPtr,
2553 			       const Uint32* data,
2554                                Uint32 length,
2555                                bool copyProc);
2556 
2557 //-----------------------------------------------------------------------------
2558 // Table Descriptor Memory Manager
2559 //-----------------------------------------------------------------------------
2560 
2561 // Public methods
2562   Uint32 getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset);
2563   Uint32 allocTabDescr(const Tablerec* regTabPtr, Uint32* offset);
2564   void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
2565   Uint32 getTabDescrWord(Uint32 index);
2566   void setTabDescrWord(Uint32 index, Uint32 word);
2567 
2568 // Private methods
2569   Uint32 sizeOfReadFunction();
2570   void   removeTdArea(Uint32 tabDesRef, Uint32 list);
2571   void   insertTdArea(Uint32 tabDesRef, Uint32 list);
2572   void   itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
2573 #ifdef VM_TRACE
2574   void verifytabdes();
2575 #endif
2576 
2577   void seizeOpRec(OperationrecPtr& regOperPtr);
2578   void seizeFragrecord(FragrecordPtr& regFragPtr);
2579   void seizeFragoperrec(FragoperrecPtr& fragOperPtr);
2580   void releaseFragoperrec(FragoperrecPtr fragOperPtr);
2581   void releaseFragrec(FragrecordPtr);
2582 //----------------------------------------------------------------------------
2583 // Page Memory Manager
2584 //----------------------------------------------------------------------------
2585 
2586 // Public methods
2587   void allocConsPages(Uint32 noOfPagesToAllocate,
2588                       Uint32& noOfPagesAllocated,
2589                       Uint32& allocPageRef);
2590   void returnCommonArea(Uint32 retPageRef, Uint32 retNo);
2591   void initializePage();
2592 
2593 // Private methods
2594   void removeCommonArea(Uint32 remPageRef, Uint32 list);
2595   void insertCommonArea(Uint32 insPageRef, Uint32 list);
2596   void findFreeLeftNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate);
2597   void findFreeRightNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate);
2598   Uint32 nextHigherTwoLog(Uint32 input);
2599 
2600 // Private data
2601   Uint32 cfreepageList[16];
2602 
2603 //------------------------------------------------------------------------------------------------------
2604 // Page Mapper, convert logical page id's to physical page id's
2605 // The page mapper also handles the pages allocated to the fragment.
2606 //------------------------------------------------------------------------------------------------------
2607 //
2608 // Public methods
2609   Uint32 getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId);
2610   Uint32 getNoOfPages(Fragrecord* regFragPtr);
2611   void initPageRangeSize(Uint32 size);
2612   bool insertPageRangeTab(Fragrecord* regFragPtr,
2613                           Uint32 startPageId,
2614                           Uint32 noPages);
2615   void releaseFragPages(Fragrecord* regFragPtr);
2616   void initFragRange(Fragrecord* regFragPtr);
2617   void initializePageRange();
2618   Uint32 getEmptyPage(Fragrecord* regFragPtr);
2619   Uint32 allocFragPages(Fragrecord* regFragPtr, Uint32 noOfPagesAllocated);
2620   Uint32 get_empty_var_page(Fragrecord* frag_ptr);
2621 
2622 // Private methods
2623   Uint32 leafPageRangeFull(Fragrecord* regFragPtr, PageRangePtr currPageRangePtr);
2624   void releasePagerange(PageRangePtr regPRPtr);
2625   void seizePagerange(PageRangePtr& regPageRangePtr);
2626   void errorHandler(Uint32 errorCode);
2627   void allocMoreFragPages(Fragrecord* regFragPtr);
2628 
2629 // Private data
2630   Uint32 cfirstfreerange;
2631   PageRange *pageRange;
2632   Uint32 c_noOfFreePageRanges;
2633   Uint32 cnoOfPageRangeRec;
2634 
2635 //---------------------------------------------------------------
2636 // Variable Allocator
2637 // Allocates and deallocates tuples of fixed size on a fragment.
2638 //---------------------------------------------------------------
2639 //
2640 // Public methods
2641 
2642   void init_list_sizes(void);
2643 
2644 // Private methods
2645 
2646   Uint32 get_alloc_page(Fragrecord* const, Uint32);
2647   void update_free_page_list(Fragrecord* const, Ptr<Page>);
2648 
2649 #if 0
2650   Uint32 calc_free_list(const Tablerec* regTabPtr, Uint32 sz) const {
2651     return regTabPtr->m_disk_alloc_info.calc_page_free_bits(sz);
2652   }
2653 #endif
2654 
2655   Uint32 calculate_free_list_impl(Uint32) const ;
2656   void remove_free_page(Fragrecord*, Var_page*, Uint32);
2657   void insert_free_page(Fragrecord*, Var_page*, Uint32);
2658 
2659 //---------------------------------------------------------------
2660 // Fixed Allocator
2661 // Allocates and deallocates tuples of fixed size on a fragment.
2662 //---------------------------------------------------------------
2663 //
2664 // Public methods
2665   Uint32* alloc_var_rec(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
2666   void free_var_rec(Fragrecord*, Tablerec*, Local_key*, Ptr<Page>);
2667   Uint32* alloc_var_part(Fragrecord*, Tablerec*, Uint32, Local_key*);
2668   int realloc_var_part(Fragrecord*, Tablerec*,
2669 		       PagePtr, Var_part_ref*, Uint32, Uint32);
2670 
2671   void validate_page(Tablerec*, Var_page* page);
2672 
2673   Uint32* alloc_fix_rec(Fragrecord*const, Tablerec*const, Local_key*,
2674                         Uint32*);
2675   void free_fix_rec(Fragrecord*, Tablerec*, Local_key*, Fix_page*);
2676 
2677   Uint32* alloc_fix_rowid(Fragrecord*, Tablerec*, Local_key*, Uint32 *);
2678   Uint32* alloc_var_rowid(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
2679 // Private methods
2680   void convertThPage(Fix_page* regPagePtr,
2681 		     Tablerec*,
2682 		     Uint32 mm);
2683 
2684   /**
2685    * Return offset
2686    */
2687   Uint32 alloc_tuple_from_page(Fragrecord* regFragPtr,
2688 			       Fix_page* regPagePtr);
2689 
2690 //---------------------------------------------------------------
2691 // Temporary variables used for storing commonly used variables
2692 // in certain modules
2693 //---------------------------------------------------------------
2694 
2695   Uint32 c_lcp_scan_op;
2696   FragrecordPtr   fragptr;
2697   OperationrecPtr operPtr;
2698   TablerecPtr     tabptr;
2699 
2700 // readAttributes and updateAttributes module
2701 //------------------------------------------------------------------------------------------------------
2702 // Common stored variables. Variables that have a valid value always.
2703 //------------------------------------------------------------------------------------------------------
2704   Attrbufrec *attrbufrec;
2705   Uint32 cfirstfreeAttrbufrec;
2706   Uint32 cnoOfAttrbufrec;
2707   Uint32 cnoFreeAttrbufrec;
2708 
2709   Fragoperrec *fragoperrec;
2710   Uint32 cfirstfreeFragopr;
2711   Uint32 cnoOfFragoprec;
2712 
2713   Fragrecord *fragrecord;
2714   Uint32 cfirstfreefrag;
2715   Uint32 cnoOfFragrec;
2716 
2717   HostBuffer *hostBuffer;
2718 
2719   ArrayPool<Operationrec> c_operation_pool;
2720 
2721   ArrayPool<Page> c_page_pool;
2722   Uint32 cnoOfAllocatedPages;
2723   Uint32 m_max_allocate_pages;
2724 
2725   /* read ahead in pages during disk order scan */
2726   Uint32 m_max_page_read_ahead;
2727 
2728   Tablerec *tablerec;
2729   Uint32 cnoOfTablerec;
2730 
2731   TableDescriptor *tableDescriptor;
2732   Uint32 cnoOfTabDescrRec;
2733 
2734   Uint32 cdata[32];
2735   Uint32 cdataPages[16];
2736   Uint32 cpackedListIndex;
2737   Uint32 cpackedList[MAX_NODES];
2738   Uint32 cfreeTdList[16];
2739   Uint32 clastBitMask;
2740   Uint32 clblPageCounter;
2741   Uint32 clblPagesPerTick;
2742   Uint32 clblPagesPerTickAfterSr;
2743   BlockReference clqhBlockref;
2744   Uint32 clqhUserpointer;
2745   Uint32 cminusOne;
2746   BlockReference cndbcntrRef;
2747   BlockReference cownref;
2748   Uint32 cownNodeId;
2749   Uint32 czero;
2750 
2751  // A little bit bigger to cover overwrites in copy algorithms (16384 real size).
2752 #define ZATTR_BUFFER_SIZE 16384
2753   Uint32 clogMemBuffer[ZATTR_BUFFER_SIZE + 16];
2754   Uint32 coutBuffer[ZATTR_BUFFER_SIZE + 16];
2755   Uint32 cinBuffer[ZATTR_BUFFER_SIZE + 16];
2756   Uint32 ctemp_page[ZWORDS_ON_PAGE];
2757   Uint32 ctemp_var_record[ZWORDS_ON_PAGE];
2758   Uint32 totNoOfPagesAllocated;
2759 
2760   // Trigger variables
2761   Uint32 c_maxTriggersPerTable;
2762   Uint32 c_memusage_report_frequency;
2763 
2764   Uint32 c_errorInsert4000TableId;
2765   Uint32 c_min_list_size[MAX_FREE_LIST + 1];
2766   Uint32 c_max_list_size[MAX_FREE_LIST + 1];
2767 
2768   void initGlobalTemporaryVars();
2769   void reportMemoryUsage(Signal* signal, int incDec);
2770 
2771 
2772 #ifdef VM_TRACE
2773   struct Th {
2774     Uint32 data[1];
2775   };
2776   friend class NdbOut& operator<<(NdbOut&, const Operationrec&);
2777   friend class NdbOut& operator<<(NdbOut&, const Th&);
2778 #endif
2779 
2780   void expand_tuple(KeyReqStruct*, Uint32 sizes[4], Tuple_header*org,
2781 		    const Tablerec*, bool disk);
2782   void shrink_tuple(KeyReqStruct*, Uint32 sizes[2], const Tablerec*,
2783 		    bool disk);
2784 
2785   Uint32* get_ptr(Var_part_ref);
2786   Uint32* get_ptr(PagePtr*, Var_part_ref);
2787   Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
2788   Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
2789 
2790   /**
2791    * prealloc space from disk
2792    *   key.m_file_no  contains file no
2793    *   key.m_page_no  contains disk page
2794    *   key.m_page_idx contains byte preallocated
2795    */
2796   int disk_page_prealloc(Signal*, Ptr<Fragrecord>, Local_key*, Uint32);
2797   void disk_page_prealloc_dirty_page(Disk_alloc_info&,
2798 				     Ptr<Page>, Uint32, Uint32);
2799   void disk_page_prealloc_transit_page(Disk_alloc_info&,
2800 				       Ptr<Page_request>, Uint32, Uint32);
2801 
2802   void disk_page_abort_prealloc(Signal*, Fragrecord*,Local_key*, Uint32);
2803   void disk_page_abort_prealloc_callback(Signal*, Uint32, Uint32);
2804   void disk_page_abort_prealloc_callback_1(Signal*, Fragrecord*,
2805 					   PagePtr, Uint32);
2806 
2807   void disk_page_prealloc_callback(Signal*, Uint32, Uint32);
2808   void disk_page_prealloc_initial_callback(Signal*, Uint32, Uint32);
2809   void disk_page_prealloc_callback_common(Signal*,
2810 					  Ptr<Page_request>,
2811 					  Ptr<Fragrecord>,
2812 					  Ptr<Page>);
2813 
2814   void disk_page_alloc(Signal*,
2815 		       Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
2816   void disk_page_free(Signal*,
2817 		      Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
2818 
2819   void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);
2820 
2821   void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32);
2822 
2823   void disk_page_alloc_extent_log_buffer_callback(Signal*, Uint32, Uint32);
2824   void disk_page_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
2825 
2826   Uint64 disk_page_undo_alloc(Page*, const Local_key*,
2827 			      Uint32 sz, Uint32 gci, Uint32 logfile_group_id);
2828 
2829   Uint64 disk_page_undo_update(Page*, const Local_key*,
2830 			       const Uint32*, Uint32,
2831 			       Uint32 gci, Uint32 logfile_group_id);
2832 
2833   Uint64 disk_page_undo_free(Page*, const Local_key*,
2834 			     const Uint32*, Uint32 sz,
2835 			     Uint32 gci, Uint32 logfile_group_id);
2836 
2837   void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused);
2838   void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
2839 
2840   void drop_table_log_buffer_callback(Signal*, Uint32, Uint32);
2841   void drop_table_logsync_callback(Signal*, Uint32, Uint32);
2842 
2843   void disk_page_set_dirty(Ptr<Page>);
2844   void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
2845   void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>);
2846 
2847   /**
2848    * Disk restart code
2849    */
2850 public:
2851   int disk_page_load_hook(Uint32 page_id);
2852 
2853   void disk_page_unmap_callback(Uint32 when, Uint32 page, Uint32 dirty_count);
2854 
2855   int disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
2856 				const Local_key* key, Uint32 pages);
2857   void disk_restart_page_bits(Uint32 tableId, Uint32 fragId,
2858 			      const Local_key*, Uint32 bits);
2859   void disk_restart_undo(Signal* signal, Uint64 lsn,
2860 			 Uint32 type, const Uint32 * ptr, Uint32 len);
2861 
2862   struct Apply_undo
2863   {
2864     Uint32 m_type, m_len;
2865     const Uint32* m_ptr;
2866     Uint64 m_lsn;
2867     Ptr<Tablerec> m_table_ptr;
2868     Ptr<Fragrecord> m_fragment_ptr;
2869     Ptr<Page> m_page_ptr;
2870     Ptr<Extent_info> m_extent_ptr;
2871     Local_key m_key;
2872   };
2873 
2874   void disk_restart_lcp_id(Uint32 table, Uint32 frag, Uint32 lcpId);
2875 
2876 private:
2877   void disk_restart_undo_next(Signal*);
2878   void disk_restart_undo_lcp(Uint32, Uint32, Uint32 flag, Uint32 lcpId);
2879   void disk_restart_undo_callback(Signal* signal, Uint32, Uint32);
2880   void disk_restart_undo_alloc(Apply_undo*);
2881   void disk_restart_undo_update(Apply_undo*);
2882   void disk_restart_undo_free(Apply_undo*);
2883   void disk_restart_undo_page_bits(Signal*, Apply_undo*);
2884 
2885 #ifdef VM_TRACE
2886   void verify_page_lists(Disk_alloc_info&);
2887 #else
verify_page_lists(Disk_alloc_info &)2888   void verify_page_lists(Disk_alloc_info&) {}
2889 #endif
2890 
2891   void findFirstOp(OperationrecPtr&);
2892   void commit_operation(Signal*, Uint32, Tuple_header*, PagePtr,
2893 			Operationrec*, Fragrecord*, Tablerec*);
2894 
2895   void dealloc_tuple(Signal* signal, Uint32, Page*, Tuple_header*,
2896 		     Operationrec*, Fragrecord*, Tablerec*);
2897 
2898   int handle_size_change_after_update(KeyReqStruct* req_struct,
2899 				      Tuple_header* org,
2900 				      Operationrec*,
2901 				      Fragrecord* regFragPtr,
2902 				      Tablerec* regTabPtr,
2903 				      Uint32 sizes[4]);
2904 
2905   /**
2906    * Setup all pointer on keyreqstruct to prepare for read
2907    *   req_struct->m_tuple_ptr is set to tuple to read
2908    */
2909   void prepare_read(KeyReqStruct*, Tablerec* const, bool disk);
2910 };
2911 
2912 #if 0
2913 inline
2914 Uint32
2915 Dbtup::get_frag_page_id(Uint32 real_page_id)
2916 {
2917   PagePtr real_page_ptr;
2918   real_page_ptr.i= real_page_id;
2919   ptrCheckGuard(real_page_ptr, cnoOfPage, cpage);
2920   return real_page_ptr.p->frag_page_id;
2921 }
2922 #endif
2923 
2924 inline
2925 Dbtup::TransState
get_trans_state(Operationrec * regOperPtr)2926 Dbtup::get_trans_state(Operationrec * regOperPtr)
2927 {
2928   return (Dbtup::TransState)regOperPtr->op_struct.trans_state;
2929 }
2930 
2931 inline
2932 void
set_trans_state(Operationrec * regOperPtr,Dbtup::TransState trans_state)2933 Dbtup::set_trans_state(Operationrec* regOperPtr,
2934                        Dbtup::TransState trans_state)
2935 {
2936   regOperPtr->op_struct.trans_state= (Uint32)trans_state;
2937 }
2938 
2939 inline
2940 Dbtup::TupleState
get_tuple_state(Operationrec * regOperPtr)2941 Dbtup::get_tuple_state(Operationrec * regOperPtr)
2942 {
2943   return (Dbtup::TupleState)regOperPtr->op_struct.tuple_state;
2944 }
2945 
2946 inline
2947 void
set_tuple_state(Operationrec * regOperPtr,Dbtup::TupleState tuple_state)2948 Dbtup::set_tuple_state(Operationrec* regOperPtr,
2949                        Dbtup::TupleState tuple_state)
2950 {
2951   regOperPtr->op_struct.tuple_state= (Uint32)tuple_state;
2952 }
2953 
2954 
2955 inline
2956 Uint32
decr_tup_version(Uint32 tup_version)2957 Dbtup::decr_tup_version(Uint32 tup_version)
2958 {
2959   return (tup_version - 1) & ZTUP_VERSION_MASK;
2960 }
2961 
2962 inline
2963 Dbtup::ChangeMaskState
get_change_mask_state(Operationrec * regOperPtr)2964 Dbtup::get_change_mask_state(Operationrec * regOperPtr)
2965 {
2966   return (Dbtup::ChangeMaskState)regOperPtr->op_struct.change_mask_state;
2967 }
2968 
2969 inline
2970 void
set_change_mask_state(Operationrec * regOperPtr,ChangeMaskState new_state)2971 Dbtup::set_change_mask_state(Operationrec * regOperPtr,
2972                              ChangeMaskState new_state)
2973 {
2974   regOperPtr->op_struct.change_mask_state= (Uint32)new_state;
2975 }
2976 
2977 inline
2978 void
update_change_mask_info(KeyReqStruct * req_struct,Operationrec * regOperPtr)2979 Dbtup::update_change_mask_info(KeyReqStruct * req_struct,
2980                                Operationrec * regOperPtr)
2981 {
2982   if (req_struct->max_attr_id_updated == 0) {
2983     if (get_change_mask_state(regOperPtr) == USE_SAVED_CHANGE_MASK) {
2984       // add new changes
2985       regOperPtr->saved_change_mask[0] |= req_struct->changeMask.getWord(0);
2986       regOperPtr->saved_change_mask[1] |= req_struct->changeMask.getWord(1);
2987     }
2988   } else {
2989     if (req_struct->no_changed_attrs < 16) {
2990       set_change_mask_state(regOperPtr, RECALCULATE_CHANGE_MASK);
2991     } else {
2992       set_change_mask_state(regOperPtr, SET_ALL_MASK);
2993     }
2994   }
2995 }
2996 
2997 inline
2998 Uint32*
get_ptr(Var_part_ref ref)2999 Dbtup::get_ptr(Var_part_ref ref)
3000 {
3001   Ptr<Page> tmp;
3002   return get_ptr(&tmp, ref);
3003 }
3004 
3005 inline
3006 Uint32*
get_ptr(Ptr<Page> * pagePtr,Var_part_ref ref)3007 Dbtup::get_ptr(Ptr<Page>* pagePtr, Var_part_ref ref)
3008 {
3009   PagePtr tmp;
3010   Local_key key;
3011   ref.copyout(&key);
3012   tmp.i = key.m_page_no;
3013 
3014   c_page_pool.getPtr(tmp);
3015   memcpy(pagePtr, &tmp, sizeof(tmp));
3016   return ((Var_page*)tmp.p)->get_ptr(key.m_page_idx);
3017 }
3018 
3019 inline
3020 Uint32*
get_ptr(PagePtr * pagePtr,const Local_key * key,const Tablerec * regTabPtr)3021 Dbtup::get_ptr(PagePtr* pagePtr,
3022 	       const Local_key* key, const Tablerec* regTabPtr)
3023 {
3024   PagePtr tmp;
3025   tmp.i= key->m_page_no;
3026   c_page_pool.getPtr(tmp);
3027   memcpy(pagePtr, &tmp, sizeof(tmp));
3028 
3029   return ((Fix_page*)tmp.p)->
3030     get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
3031 }
3032 
3033 inline
3034 Uint32*
get_dd_ptr(PagePtr * pagePtr,const Local_key * key,const Tablerec * regTabPtr)3035 Dbtup::get_dd_ptr(PagePtr* pagePtr,
3036 		  const Local_key* key, const Tablerec* regTabPtr)
3037 {
3038   PagePtr tmp;
3039   tmp.i= key->m_page_no;
3040   tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
3041   memcpy(pagePtr, &tmp, sizeof(tmp));
3042 
3043   if(regTabPtr->m_attributes[DD].m_no_of_varsize)
3044     return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
3045   else
3046     return ((Fix_page*)tmp.p)->
3047       get_ptr(key->m_page_idx, regTabPtr->m_offsets[DD].m_fix_header_size);
3048 }
3049 
3050 NdbOut&
3051 operator<<(NdbOut&, const Dbtup::Tablerec&);
3052 
3053 inline
find_savepoint(OperationrecPtr & loopOpPtr,Uint32 savepointId)3054 bool Dbtup::find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId)
3055 {
3056   while (true) {
3057     if (savepointId > loopOpPtr.p->savepointId) {
3058       jam();
3059       return true;
3060     }
3061     loopOpPtr.i = loopOpPtr.p->prevActiveOp;
3062     if (loopOpPtr.i == RNIL) {
3063       break;
3064     }
3065     c_operation_pool.getPtr(loopOpPtr);
3066   }
3067   return false;
3068 }
3069 
3070 #endif
3071