1 /*
2    Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef DBTUP_H
26 #define DBTUP_H
27 
28 #include <pc.hpp>
29 #include <SimulatedBlock.hpp>
30 #include <ndb_limits.h>
31 #include <trigger_definitions.h>
32 #include <AttributeHeader.hpp>
33 #include <Bitmask.hpp>
34 #include <signaldata/TupKey.hpp>
35 #include <signaldata/CreateTrig.hpp>
36 #include <signaldata/CreateTrigImpl.hpp>
37 #include <signaldata/DropTrig.hpp>
38 #include <signaldata/DropTrigImpl.hpp>
39 #include <signaldata/TrigAttrInfo.hpp>
40 #include <signaldata/BuildIndxImpl.hpp>
41 #include <signaldata/AlterTab.hpp>
42 #include <AttributeDescriptor.hpp>
43 #include "AttributeOffset.hpp"
44 #include "Undo_buffer.hpp"
45 #include "tuppage.hpp"
46 #include <DynArr256.hpp>
47 #include "../pgman.hpp"
48 #include "../tsman.hpp"
49 
50 // jams
51 #undef jam
52 #undef jamEntry
53 #ifdef DBTUP_BUFFER_CPP
54 #define jam()	 	jamLine(10000 + __LINE__)
55 #define jamEntry() 	jamEntryLine(10000 + __LINE__)
56 #endif
57 #ifdef DBTUP_ROUTINES_CPP
58 #define jam()           jamLine(15000 + __LINE__)
59 #define jamEntry()      jamEntryLine(15000 + __LINE__)
60 #endif
61 #ifdef DBTUP_COMMIT_CPP
62 #define jam()           jamLine(20000 + __LINE__)
63 #define jamEntry()      jamEntryLine(20000 + __LINE__)
64 #endif
65 #ifdef DBTUP_FIXALLOC_CPP
66 #define jam()           jamLine(25000 + __LINE__)
67 #define jamEntry()      jamEntryLine(25000 + __LINE__)
68 #endif
69 #ifdef DBTUP_TRIGGER_CPP
70 #define jam()           jamLine(30000 + __LINE__)
71 #define jamEntry()      jamEntryLine(30000 + __LINE__)
72 #endif
73 #ifdef DBTUP_ABORT_CPP
74 #define jam()           jamLine(35000 + __LINE__)
75 #define jamEntry()      jamEntryLine(35000 + __LINE__)
76 #endif
77 #ifdef DBTUP_PAGE_MAP_CPP
78 #define jam()           jamLine(40000 + __LINE__)
79 #define jamEntry()      jamEntryLine(40000 + __LINE__)
80 #endif
81 #ifdef DBTUP_PAG_MAN_CPP
82 #define jam()           jamLine(45000 + __LINE__)
83 #define jamEntry()      jamEntryLine(45000 + __LINE__)
84 #endif
85 #ifdef DBTUP_STORE_PROC_DEF_CPP
86 #define jam()           jamLine(50000 + __LINE__)
87 #define jamEntry()      jamEntryLine(50000 + __LINE__)
88 #endif
89 #ifdef DBTUP_META_CPP
90 #define jam()           jamLine(55000 + __LINE__)
91 #define jamEntry()      jamEntryLine(55000 + __LINE__)
92 #endif
93 #ifdef DBTUP_TAB_DES_MAN_CPP
94 #define jam()           jamLine(60000 + __LINE__)
95 #define jamEntry()      jamEntryLine(60000 + __LINE__)
96 #endif
97 #ifdef DBTUP_GEN_CPP
98 #define jam()           jamLine(65000 + __LINE__)
99 #define jamEntry()      jamEntryLine(65000 + __LINE__)
100 #endif
101 #ifdef DBTUP_INDEX_CPP
102 #define jam()           jamLine(70000 + __LINE__)
103 #define jamEntry()      jamEntryLine(70000 + __LINE__)
104 #endif
105 #ifdef DBTUP_DEBUG_CPP
106 #define jam()           jamLine(75000 + __LINE__)
107 #define jamEntry()      jamEntryLine(75000 + __LINE__)
108 #endif
109 #ifdef DBTUP_VAR_ALLOC_CPP
110 #define jam()           jamLine(80000 + __LINE__)
111 #define jamEntry()      jamEntryLine(80000 + __LINE__)
112 #endif
113 #ifdef DBTUP_SCAN_CPP
114 #define jam()           jamLine(85000 + __LINE__)
115 #define jamEntry()      jamEntryLine(85000 + __LINE__)
116 #endif
117 #ifdef DBTUP_DISK_ALLOC_CPP
118 #define jam()           jamLine(90000 + __LINE__)
119 #define jamEntry()      jamEntryLine(90000 + __LINE__)
120 #endif
121 #ifndef jam
122 #define jam()           jamLine(__LINE__)
123 #define jamEntry()      jamEntryLine(__LINE__)
124 #endif
125 
126 #ifdef VM_TRACE
dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS> & bm)127 inline const char* dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS>& bm) {
128   static int i=0; static char buf[5][200];
129   bm.getText(buf[i%5]); return buf[i++%5]; }
dbgmask(const Uint32 bm[2])130 inline const char* dbgmask(const Uint32 bm[2]) {
131   static int i=0; static char buf[5][200];
132   sprintf(buf[i%5],"%08x%08x",bm[1],bm[0]); return buf[i++%5]; }
133 #endif
134 
135 #define ZWORDS_ON_PAGE 8192          /* NUMBER OF WORDS ON A PAGE.      */
136 #define ZMIN_PAGE_LIMIT_TUPKEYREQ 5
137 #define ZTUP_VERSION_BITS 15
138 #define ZTUP_VERSION_MASK ((1 << ZTUP_VERSION_BITS) - 1)
139 #define MAX_FREE_LIST 4
140 
ALIGN_WORD(void * ptr)141 inline Uint32* ALIGN_WORD(void * ptr)
142 {
143   return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
144 }
145 
ALIGN_WORD(const void * ptr)146 inline const Uint32* ALIGN_WORD(const void* ptr)
147 {
148   return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
149 }
150 
151 #ifdef DBTUP_C
152 //------------------------------------------------------------------
153 // Jam Handling:
154 //
155 // When DBTUP reports lines through jam in the trace files it has to
156 // be interpreted. 4024 means as an example line 24 in DbtupCommit.cpp
157 // Thus 4000 is added to the line number beacuse it is located in the
158 // file DbtupCommit.cpp. The following is the exhaustive list of the
159 // added value in the various files. ndbrequire, ptrCheckGuard still
160 // only reports the line number in the file it currently is located in.
161 //
162 // DbtupExecQuery.cpp         0
163 // DbtupBuffer.cpp         10000
164 // DbtupRoutines.cpp       15000
165 // DbtupCommit.cpp         20000
166 // DbtupFixAlloc.cpp       25000
167 // DbtupTrigger.cpp        30000
168 // DbtupAbort.cpp          35000
169 // DbtupPageMap.cpp        40000
170 // DbtupPagMan.cpp         45000
171 // DbtupStoredProcDef.cpp  50000
172 // DbtupMeta.cpp           55000
173 // DbtupTabDesMan.cpp      60000
174 // DbtupGen.cpp            65000
175 // DbtupIndex.cpp          70000
176 // DbtupDebug.cpp          75000
177 // DbtupVarAlloc.cpp       80000
178 // DbtupScan.cpp           85000
179 // DbtupDiskAlloc.cpp      90000
180 //------------------------------------------------------------------
181 
182 /*
183 2.2 LOCAL SYMBOLS
184 -----------------
185 */
186 /* ---------------------------------------------------------------- */
187 /*       S I Z E              O F               R E C O R D S       */
188 /* ---------------------------------------------------------------- */
189 #define ZNO_OF_CONCURRENT_OPEN_OP 40        /* NUMBER OF CONCURRENT OPENS      */
190 #define ZNO_OF_CONCURRENT_WRITE_OP 80       /* NUMBER OF CONCURRENT DISK WRITES*/
191 #define ZNO_OF_FRAGOPREC 20                 /* NUMBER OF CONCURRENT ADD FRAG.  */
192 #define TOT_PAGE_RECORD_SPACE 262144        /* SIZE OF PAGE RECORD FILE.       */
193 #define ZNO_OF_PAGE TOT_PAGE_RECORD_SPACE/ZWORDS_ON_PAGE
194 #define ZNO_OF_PAGE_RANGE_REC 128           /* SIZE OF PAGE RANGE FILE         */
195 // Trigger constants
196 #define ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE 16
197 
198 /* ---------------------------------------------------------------- */
199 /* A ATTRIBUTE MAY BE NULL, DYNAMIC OR NORMAL. A NORMAL ATTRIBUTE   */
200 /* IS A ATTRIBUTE THAT IS NOT NULL OR DYNAMIC. A NULL ATTRIBUTE     */
201 /* MAY HAVE NO VALUE. A DYNAMIC ATTRIBUTE IS A NULL ATTRIBUTE THAT  */
202 /* DOES NOT HAVE TO BE A MEMBER OF EVERY TUPLE I A CERTAIN TABLE.   */
203 /* ---------------------------------------------------------------- */
204 /**
205  * #defines moved into include/kernel/Interpreter.hpp
206  */
207 #define ZINSERT_DELETE 0
208 #define ZUPDATE_ALL 8
209 /* ---------------------------------------------------------------- */
210 /* THE MINIMUM SIZE OF AN 'EMPTY' TUPLE HEADER IN R-WORDS           */
211 /* ---------------------------------------------------------------- */
212           /* THE TUPLE HEADER FIELD 'SIZE OF NULL ATTR. FIELD' SPECIFYES    */
213           /* THE SIZE OF THE TUPLE HEADER FIELD 'NULL ATTR. FIELD'.         */
214           /* THE TUPLE HEADER FIELD 'TYPE' SPECIFYES THE TYPE OF THE TUPLE  */
215           /* HEADER.                                                        */
216                                /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
217                                /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER.  */
218                                /* IT MAY ALSO CONTAIN SHORT ATTRIBUTES AND  */
219                                /* POINTERS TO LONG ATTRIBUTE HEADERS.       */
220                                /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
221                                /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER.  */
222 
223           /* DATA STRUCTURE TYPES */
224           /* WHEN ATTRIBUTE INFO IS SENT WITH A ATTRINFO-SIGNAL THE         */
225           /* VARIABLE TYPE IS SPECIFYED. THIS MUST BE DONE TO BE ABLE TO    */
226           /* NOW HOW MUCH DATA OF A ATTRIBUTE TO READ FROM ATTRINFO.        */
227 
228           /* WHEN A REQUEST CAN NOT BE EXECUTED BECAUSE OF A ERROR THE      */
229           /* ERROR MUST BE IDENTIFYED BY MEANS OF A ERROR CODE AND SENT TO  */
230           /* THE REQUESTER.                                                 */
231 #define ZGET_OPREC_ERROR 804            // TUP_SEIZEREF
232 
233 #define ZEXIST_FRAG_ERROR 816           // Add fragment
234 #define ZFULL_FRAGRECORD_ERROR 817      // Add fragment
235 #define ZNO_FREE_PAGE_RANGE_ERROR 818   // Add fragment
236 #define ZNOFREE_FRAGOP_ERROR 830        // Add fragment
237 #define ZTOO_LARGE_TUPLE_ERROR 851      // Add fragment
238 #define ZNO_FREE_TAB_ENTRY_ERROR 852    // Add fragment
239 #define ZNO_PAGES_ALLOCATED_ERROR 881   // Add fragment
240 
241 #define ZGET_REALPID_ERROR 809
242 #define ZNOT_IMPLEMENTED_ERROR 812
243 #define ZSEIZE_ATTRINBUFREC_ERROR 805
244 #define ZTOO_MUCH_ATTRINFO_ERROR 823
245 #define ZMEM_NOTABDESCR_ERROR 826
246 #define ZMEM_NOMEM_ERROR 827
247 #define ZAI_INCONSISTENCY_ERROR 829
248 #define ZNO_ILLEGAL_NULL_ATTR 839
249 #define ZNOT_NULL_ATTR 840
250 #define ZBAD_DEFAULT_VALUE_LEN 850
251 #define ZNO_INSTRUCTION_ERROR 871
252 #define ZOUTSIDE_OF_PROGRAM_ERROR 876
253 #define ZSTORED_PROC_ID_ERROR 877
254 #define ZREGISTER_INIT_ERROR 878
255 #define ZATTRIBUTE_ID_ERROR 879
256 #define ZTRY_TO_READ_TOO_MUCH_ERROR 880
257 #define ZTOTAL_LEN_ERROR 882
258 #define ZATTR_INTERPRETER_ERROR 883
259 #define ZSTACK_OVERFLOW_ERROR 884
260 #define ZSTACK_UNDERFLOW_ERROR 885
261 #define ZTOO_MANY_INSTRUCTIONS_ERROR 886
262 #define ZTRY_TO_UPDATE_ERROR 888
263 #define ZCALL_ERROR 890
264 #define ZTEMPORARY_RESOURCE_FAILURE 891
265 #define ZUNSUPPORTED_BRANCH 892
266 
267 #define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan
268 #define ZSTORED_TOO_MUCH_ATTRINFO_ERROR 874
269 
270 #define ZREAD_ONLY_CONSTRAINT_VIOLATION 893
271 #define ZVAR_SIZED_NOT_SUPPORTED 894
272 #define ZINCONSISTENT_NULL_ATTRIBUTE_COUNT 895
273 #define ZTUPLE_CORRUPTED_ERROR 896
274 #define ZTRY_UPDATE_PRIMARY_KEY 897
275 #define ZMUST_BE_ABORTED_ERROR 898
276 #define ZTUPLE_DELETED_ERROR 626
277 #define ZINSERT_ERROR 630
278 #define ZOP_AFTER_REFRESH_ERROR 920
279 
280 #define ZINVALID_CHAR_FORMAT 744
281 #define ZROWID_ALLOCATED 899
282 #define ZINVALID_ALTER_TAB 741
283 
284 #define ZTOO_MANY_BITS_ERROR 791
285 
286           /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */
287 
288 #define ZTH_MM_FREE 3                     /* PAGE STATE, TUPLE HEADER PAGE WITH FREE AREA      */
289 #define ZTH_MM_FULL 4                     /* PAGE STATE, TUPLE HEADER PAGE WHICH IS FULL       */
290 
291 #define ZTD_HEADER 0                      /* HEADER POSITION                   */
292 #define ZTD_DATASIZE 1                    /* SIZE OF THE DATA IN THIS CHUNK    */
293 #define ZTD_SIZE 2                        /* TOTAL SIZE OF TABLE DESCRIPTOR    */
294 
295           /* TRAILER POSITIONS FROM END OF TABLE DESCRIPTOR RECORD               */
296 #define ZTD_TR_SIZE 1                     /* SIZE DESCRIPTOR POS FROM END+1    */
297 #define ZTD_TR_TYPE 2
298 #define ZTD_TRAILER_SIZE 2                /* TOTAL SIZE OF TABLE TRAILER       */
299 #define ZAD_SIZE 2                        /* TOTAL SIZE OF ATTR DESCRIPTOR     */
300 #define ZAD_LOG_SIZE 1                    /* TWO LOG OF TOTAL SIZE OF ATTR DESCRIPTOR     */
301 
302           /* CONSTANTS USED TO HANDLE TABLE DESCRIPTOR AS A FREELIST             */
303 #define ZTD_FL_HEADER 0                   /* HEADER POSITION                   */
304 #define ZTD_FL_SIZE 1                     /* TOTAL SIZE OF THIS FREELIST ENTRY */
305 #define ZTD_FL_PREV 2                     /* PREVIOUS RECORD IN FREELIST       */
306 #define ZTD_FL_NEXT 3                     /* NEXT RECORD IN FREELIST           */
307 #define ZTD_FREE_SIZE 16                  /* SIZE NEEDED TO HOLD ONE FL ENTRY  */
308 
309           /* CONSTANTS USED IN LSB OF TABLE DESCRIPTOR HEADER DESCRIBING USAGE   */
310 #define ZTD_TYPE_FREE 0                   /* RECORD LINKED INTO FREELIST       */
311 #define ZTD_TYPE_NORMAL 1                 /* RECORD USED AS TABLE DESCRIPTOR   */
312           /* ATTRIBUTE OPERATION CONSTANTS */
313 #define ZLEAF 1
314 #define ZNON_LEAF 2
315 
316           /* RETURN POINTS. */
317           /* RESTART PHASES */
318 #define ZSTARTPHASE1 1
319 #define ZSTARTPHASE2 2
320 #define ZSTARTPHASE3 3
321 #define ZSTARTPHASE4 4
322 #define ZSTARTPHASE6 6
323 
324 #define ZADDFRAG 0
325 
326 //------------------------------------------------------------
327 // TUP_CONTINUEB codes
328 //------------------------------------------------------------
329 #define ZINITIALISE_RECORDS 6
330 #define ZREL_FRAG 7
331 #define ZREPORT_MEMORY_USAGE 8
332 #define ZBUILD_INDEX 9
333 #define ZTUP_SCAN 10
334 #define ZFREE_EXTENT 11
335 #define ZUNMAP_PAGES 12
336 #define ZFREE_VAR_PAGES 13
337 #define ZFREE_PAGES 14
338 #define ZREBUILD_FREE_PAGE_LIST 15
339 #define ZDISK_RESTART_UNDO 16
340 
341 #define ZSCAN_PROCEDURE 0
342 #define ZCOPY_PROCEDURE 2
343 #define ZSTORED_PROCEDURE_DELETE 3
344 #define ZSTORED_PROCEDURE_FREE 0xffff
345 #define ZMIN_PAGE_LIMIT_TUP_COMMITREQ 2
346 
347 #define ZSKIP_TUX_TRIGGERS 0x1 // flag for TUP_ABORTREQ
348 
349 #endif
350 
351 class Dbtup: public SimulatedBlock {
352 friend class DbtupProxy;
353 friend class Suma;
354 public:
355 struct KeyReqStruct;
356 friend struct KeyReqStruct; // CC
357 typedef bool (Dbtup::* ReadFunction)(Uint8*,
358                                      KeyReqStruct*,
359                                      AttributeHeader*,
360                                      Uint32);
361 typedef bool (Dbtup::* UpdateFunction)(Uint32*,
362                                        KeyReqStruct*,
363                                        Uint32);
364 private:
365 
366   typedef Tup_fixsize_page Fix_page;
367   typedef Tup_varsize_page Var_page;
368 
369 public:
370   class Dblqh *c_lqh;
371   Tsman* c_tsman;
372   Lgman* c_lgman;
373   Pgman* c_pgman;
374   // copy of pgman.m_ptr set after each get_page
375   Ptr<GlobalPage> m_pgman_ptr;
376 
377   enum CallbackIndex {
378     // lgman
379     UNDO_CREATETABLE_LOGSYNC_CALLBACK = 1,
380     DROP_TABLE_LOGSYNC_CALLBACK = 2,
381     UNDO_CREATETABLE_CALLBACK = 3,
382     DROP_TABLE_LOG_BUFFER_CALLBACK = 4,
383     DROP_FRAGMENT_FREE_EXTENT_LOG_BUFFER_CALLBACK = 5,
384     NR_DELETE_LOG_BUFFER_CALLBACK = 6,
385     DISK_PAGE_LOG_BUFFER_CALLBACK = 7,
386     COUNT_CALLBACKS = 8
387   };
388   CallbackEntry m_callbackEntry[COUNT_CALLBACKS];
389   CallbackTable m_callbackTable;
390 
391 enum TransState {
392   TRANS_IDLE = 0,
393   TRANS_STARTED = 1,
394   TRANS_NOT_USED_STATE = 2, // No longer used.
395   TRANS_ERROR_WAIT_STORED_PROCREQ = 3,
396   TRANS_ERROR_WAIT_TUPKEYREQ = 4,
397   TRANS_TOO_MUCH_AI = 5,
398   TRANS_DISCONNECTED = 6
399 };
400 
401 enum TupleState {
402   TUPLE_PREPARED = 1,
403   TUPLE_ALREADY_ABORTED = 2,
404   TUPLE_TO_BE_COMMITTED = 3
405 };
406 
407 enum State {
408   NOT_INITIALIZED = 0,
409   IDLE = 17,
410   ACTIVE = 18,
411   SYSTEM_RESTART = 19,
412   DEFINED = 34,
413   NOT_DEFINED = 37,
414   NORMAL_PAGE = 40,
415   DEFINING = 65,
416   DROPPING = 68
417 };
418 
419 
420 struct Fragoperrec {
421   Uint64 minRows;
422   Uint64 maxRows;
423   Uint32 nextFragoprec;
424   Uint32 lqhPtrFrag;
425   Uint32 fragidFrag;
426   Uint32 tableidFrag;
427   Uint32 fragPointer;
428   Uint32 attributeCount;
429   Uint32 charsetIndex;
430   Uint32 m_null_bits[2];
431   Uint32 m_extra_row_gci_bits;
432   Uint32 m_extra_row_author_bits;
433   union {
434     BlockReference lqhBlockrefFrag;
435     Uint32 m_senderRef;
436   };
437   Uint32 m_senderData;
438   bool inUse;
439   bool definingFragment;
440 };
441 typedef Ptr<Fragoperrec> FragoperrecPtr;
442 
443   /* Operation record used during alter table. */
444   struct AlterTabOperation {
AlterTabOperationDbtup::AlterTabOperation445     AlterTabOperation() { memset(this, 0, sizeof(AlterTabOperation)); };
446     Uint32 nextAlterTabOp;
447     Uint32 newNoOfAttrs;
448     Uint32 newNoOfCharsets;
449     Uint32 newNoOfKeyAttrs;
450     Uint32 noOfDynNullBits;
451     Uint32 noOfDynVar;
452     Uint32 noOfDynFix;
453     Uint32 noOfDynamic;
454     Uint32 tabDesOffset[7];
455     Uint32 tableDescriptor;
456     Uint32 dynTabDesOffset[3];
457     Uint32 dynTableDescriptor;
458   };
459   typedef Ptr<AlterTabOperation> AlterTabOperationPtr;
460 
461   typedef Tup_page Page;
462   typedef Ptr<Page> PagePtr;
463 
464   // Scan position
465   struct ScanPos {
466     enum Get {
467       Get_undef = 0,
468       Get_next_page,
469       Get_page,
470       Get_next_page_mm,
471       Get_page_mm,
472       Get_next_page_dd,
473       Get_page_dd,
474       Get_next_tuple,
475       Get_tuple
476     };
477     Get m_get;                  // entry point in scanNext
478     Local_key m_key;            // scan position pointer MM or DD
479     Page* m_page;               // scanned MM or DD (cache) page
480     Local_key m_key_mm;         // MM local key returned
481     Uint32 m_realpid_mm;        // MM real page id
482     Uint32 m_extent_info_ptr_i;
ScanPosDbtup::ScanPos483     ScanPos() {
484       /*
485        * Position is Null until scanFirst().  In particular in LCP scan
486        * it is Null between LCP_FRAG_ORD and ACC_SCANREQ.
487        */
488       m_key.setNull();
489     }
490   };
491 
492   // Scan Lock
493   struct ScanLock {
ScanLockDbtup::ScanLock494     ScanLock() {}
495     Uint32 m_accLockOp;
496     union {
497       Uint32 nextPool;
498       Uint32 nextList;
499     };
500     Uint32 prevList;
501   };
502   typedef Ptr<ScanLock> ScanLockPtr;
503   ArrayPool<ScanLock> c_scanLockPool;
504 
505   // Tup scan, similar to Tux scan.  Later some of this could
506   // be moved to common superclass.
507   struct ScanOp {
ScanOpDbtup::ScanOp508     ScanOp() :
509       m_state(Undef),
510       m_bits(0),
511       m_userPtr(RNIL),
512       m_userRef(RNIL),
513       m_tableId(RNIL),
514       m_fragId(~(Uint32)0),
515       m_fragPtrI(RNIL),
516       m_transId1(0),
517       m_transId2(0),
518       m_savePointId(0),
519       m_accLockOp(RNIL)
520     {}
521 
522     enum State {
523       Undef = 0,
524       First = 1,                // before first entry
525       Current = 2,              // at current before locking
526       Blocked = 3,              // at current waiting for ACC lock
527       Locked = 4,               // at current and locked or no lock needed
528       Next = 5,                 // looking for next extry
529       Last = 6,                 // after last entry
530       Aborting = 7,             // lock wait at scan close
531       Invalid = 9               // cannot return REF to LQH currently
532     };
533     Uint16 m_state;
534 
535     enum Bits {
536       SCAN_DD        = 0x01,        // scan disk pages
537       SCAN_VS        = 0x02,        // page format is var size
538       SCAN_LCP       = 0x04,        // LCP mem page scan
539       SCAN_LOCK_SH   = 0x10,        // lock mode shared
540       SCAN_LOCK_EX   = 0x20,        // lock mode exclusive
541       SCAN_LOCK_WAIT = 0x40,        // lock wait
542       // any lock mode
543       SCAN_LOCK      = SCAN_LOCK_SH | SCAN_LOCK_EX,
544       SCAN_NR        = 0x80        // Node recovery scan
545     };
546     Uint16 m_bits;
547 
548     Uint32 m_userPtr;           // scanptr.i in LQH
549     Uint32 m_userRef;
550     Uint32 m_tableId;
551     Uint32 m_fragId;
552     Uint32 m_fragPtrI;
553     Uint32 m_transId1;
554     Uint32 m_transId2;
555     union {
556       Uint32 m_savePointId;
557       Uint32 m_scanGCI;
558     };
559     Uint32 m_endPage;
560     // lock waited for or obtained and not yet passed to LQH
561     Uint32 m_accLockOp;
562 
563     ScanPos m_scanPos;
564 
565     DLFifoList<ScanLock>::Head m_accLockOps;
566 
567     union {
568     Uint32 nextPool;
569     Uint32 nextList;
570     };
571     Uint32 prevList;
572   };
573   typedef Ptr<ScanOp> ScanOpPtr;
574   ArrayPool<ScanOp> c_scanOpPool;
575 
576   void scanReply(Signal*, ScanOpPtr scanPtr);
577   void scanFirst(Signal*, ScanOpPtr scanPtr);
578   bool scanNext(Signal*, ScanOpPtr scanPtr);
579   void scanCont(Signal*, ScanOpPtr scanPtr);
580   void disk_page_tup_scan_callback(Signal*, Uint32 scanPtrI, Uint32 page_i);
581   void scanClose(Signal*, ScanOpPtr scanPtr);
582   void addAccLockOp(ScanOp& scan, Uint32 accLockOp);
583   void removeAccLockOp(ScanOp& scan, Uint32 accLockOp);
584   void releaseScanOp(ScanOpPtr& scanPtr);
585 
586   // for md5 of key (could maybe reuse existing temp buffer)
587   Uint64 c_dataBuffer[ZWORDS_ON_PAGE/2 + 1];
588 
589   struct Page_request
590   {
Page_requestDbtup::Page_request591     Page_request() {}
592     Local_key m_key;
593     Uint32 m_frag_ptr_i;
594     Uint32 m_extent_info_ptr;
595     Uint16 m_original_estimated_free_space; // in bytes/records
596     Uint16 m_list_index;                  // in Disk_alloc_info.m_page_requests
597     Uint16 m_ref_count;                   // Waiters for page
598     Uint16 m_uncommitted_used_space;
599     Uint32 nextList;
600     Uint32 prevList;
601     Uint32 m_magic;
602   }; // 32 bytes
603 
604   typedef RecordPool<Page_request, WOPool> Page_request_pool;
605   typedef DLFifoListImpl<Page_request_pool, Page_request> Page_request_list;
606   typedef LocalDLFifoListImpl<Page_request_pool, Page_request> Local_page_request_list;
607 
608   STATIC_CONST( EXTENT_SEARCH_MATRIX_COLS = 4 ); // Guarantee size
609   STATIC_CONST( EXTENT_SEARCH_MATRIX_ROWS = 5 ); // Total size
610   STATIC_CONST( EXTENT_SEARCH_MATRIX_SIZE = 20 );
611 
612   struct Extent_list_t
613   {
614     Uint32 nextList;
615   };
616 
617   struct Extent_info : public Extent_list_t
618   {
619     Uint32 m_magic;
620     Uint32 m_first_page_no;
621     Uint32 m_empty_page_no;
622     Local_key m_key;
623     Uint32 m_free_space;
624     Uint32 m_free_matrix_pos;
625     Uint16 m_free_page_count[EXTENT_SEARCH_MATRIX_COLS];
626     union {
627       Uint32 nextList;
628       Uint32 nextPool;
629     };
630     Uint32 prevList;
631     Uint32 nextHash, prevHash;
632 
hashValueDbtup::Extent_info633     Uint32 hashValue() const {
634       return (m_key.m_file_no << 16) ^ m_key.m_page_idx;
635     }
636 
Extent_infoDbtup::Extent_info637     Extent_info() {}
equalDbtup::Extent_info638     bool equal(const Extent_info & rec) const {
639       return m_key.m_file_no == rec.m_key.m_file_no &&
640 	m_key.m_page_idx == rec.m_key.m_page_idx;
641     }
642   }; // 40 bytes
643 
644   typedef RecordPool<Extent_info, RWPool> Extent_info_pool;
645   typedef DLListImpl<Extent_info_pool, Extent_info> Extent_info_list;
646   typedef LocalDLListImpl<Extent_info_pool, Extent_info> Local_extent_info_list;
647   typedef DLHashTableImpl<Extent_info_pool, Extent_info> Extent_info_hash;
648   typedef SLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Fragment_extent_list;
649   typedef LocalSLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Local_fragment_extent_list;
650   struct Tablerec;
651   struct Disk_alloc_info
652   {
Disk_alloc_infoDbtup::Disk_alloc_info653     Disk_alloc_info() {}
654     Disk_alloc_info(const Tablerec* tabPtrP,
655 		    Uint32 extent_size_in_pages);
656     Uint32 m_extent_size;
657 
658     /**
659      * Disk allocation
660      *
661      * 1) Allocate space on pages that already are dirty
662      *    (4 free lists for different requests)
663      * 2) Allocate space on pages waiting to maped that will be dirty
664      *    (4 free lists for different requests)
665      * 3) Check if "current" extent can accommodate request
666      *    If so, allocate page from there
667      *    Else put "current" into free matrix
668      * 4) Search free matrix for extent with greatest amount of free space
669      *    while still accommodating current request
670      *    (20 free lists for different requests)
671      */
672 
673     /**
674      * Free list of pages in different size
675      *   that are dirty
676      */
677     DLList<Page>::Head m_dirty_pages[MAX_FREE_LIST];   // In real page id's
678 
679     /**
680      * Requests (for update) that have sufficient space left after request
681      *   these are currently being "mapped"
682      */
683     Page_request_list::Head m_page_requests[MAX_FREE_LIST];
684 
685     DLList<Page>::Head m_unmap_pages;
686 
687     /**
688      * Current extent
689      */
690     Uint32 m_curr_extent_info_ptr_i;
691 
692     /**
693      *
694      */
695     STATIC_CONST( SZ = EXTENT_SEARCH_MATRIX_SIZE );
696     Extent_info_list::Head m_free_extents[SZ];
697     Uint32 m_total_extent_free_space_thresholds[EXTENT_SEARCH_MATRIX_ROWS];
698     Uint32 m_page_free_bits_map[EXTENT_SEARCH_MATRIX_COLS];
699 
700     Uint32 find_extent(Uint32 sz) const;
701     Uint32 calc_extent_pos(const Extent_info*) const;
702 
703     /**
704      * Compute minimum free space on page given bits
705      */
calc_page_free_spaceDbtup::Disk_alloc_info706     Uint32 calc_page_free_space(Uint32 bits) const {
707       return m_page_free_bits_map[bits];
708     }
709 
710     /**
711      * Compute page free bits, given free space
712      */
calc_page_free_bitsDbtup::Disk_alloc_info713     Uint32 calc_page_free_bits(Uint32 free) const {
714       for(Uint32 i = 0; i<EXTENT_SEARCH_MATRIX_COLS-1; i++)
715 	if(free >= m_page_free_bits_map[i])
716 	  return i;
717       return EXTENT_SEARCH_MATRIX_COLS - 1;
718     }
719 
720     Fragment_extent_list::Head m_extent_list;
721   };
722 
723   void dump_disk_alloc(Disk_alloc_info&);
724 
725   STATIC_CONST( FREE_PAGE_BIT = 0x80000000 );
726   STATIC_CONST( FREE_PAGE_RNIL = RNIL + 1 );
727 
728 struct Fragrecord {
729   Uint32 noOfPages;
730   Uint32 noOfVarPages;
731 
732   Uint32 m_max_page_no;
733   Uint32 m_free_page_id_list;
734   DynArr256::Head m_page_map;
735   DLFifoList<Page>::Head thFreeFirst;   // pages with atleast 1 free record
736 
737   Uint32 m_lcp_scan_op;
738   Local_key m_lcp_keep_list_head;
739   Local_key m_lcp_keep_list_tail;
740 
741   enum FragState
742   { FS_FREE
743     ,FS_ONLINE           // Ordinary fragment
744     ,FS_REORG_NEW        // A new (not yet "online" fragment)
745     ,FS_REORG_COMMIT     // An ordinary fragment which has been split
746     ,FS_REORG_COMMIT_NEW // An new fragment which is online
747     ,FS_REORG_COMPLETE     // An ordinary fragment which has been split
748     ,FS_REORG_COMPLETE_NEW // An new fragment which is online
749   } fragStatus;
750   Uint32 fragTableId;
751   Uint32 fragmentId;
752   Uint32 nextfreefrag;
753   // +1 is as "full" pages are stored last
754   DLList<Page>::Head free_var_page_array[MAX_FREE_LIST+1];
755 
756   DLList<ScanOp>::Head m_scanList;
757 
758   enum { UC_LCP = 1, UC_CREATE = 2, UC_SET_LCP = 3 };
759   Uint32 m_restore_lcp_id;
760   Uint32 m_undo_complete;
761   Uint32 m_tablespace_id;
762   Uint32 m_logfile_group_id;
763   Disk_alloc_info m_disk_alloc_info;
764 };
765 typedef Ptr<Fragrecord> FragrecordPtr;
766 
767 
768 struct Operationrec {
769   /*
770    * Doubly linked list with anchor on tuple.
771    * This is to handle multiple updates on the same tuple
772    * by the same transaction.
773    */
774   Uint32 prevActiveOp;
775   Uint32 nextActiveOp;
776 
OperationrecDbtup::Operationrec777   Operationrec() {}
is_first_operationDbtup::Operationrec778   bool is_first_operation() const { return prevActiveOp == RNIL;}
is_last_operationDbtup::Operationrec779   bool is_last_operation() const { return nextActiveOp == RNIL;}
780 
781   Uint32 m_undo_buffer_space; // In words
782 
783   Uint32 m_any_value;
784   Uint32 nextPool;
785 
786   /*
787    * From fragment i-value we can find fragment and table record
788    */
789   Uint32 fragmentPtr;
790 
791   /*
792    * We need references to both the original tuple and the copy tuple.
793    * We keep the page's real i-value and its index and from there we
794    * can find out about the fragment page id and the page offset.
795    */
796   Local_key m_tuple_location;
797   Local_key m_copy_tuple_location;
798 
799   /*
800    * We keep the record linked to the operation record in LQH.
801    * This is needed due to writing of REDO log must be performed
802    * in correct order, which is the same order as the writes
803    * occurred. LQH can receive the records in different order.
804    */
805   Uint32 userpointer;
806 
807   /*
808    * When responding to queries in the same transaction they will see
809    * a result from the save point id the query was started. Again
810    * functionality for multi-updates of the same record in one
811    * transaction.
812    */
813   union {
814     Uint32 savepointId;
815     Uint32 m_commit_disk_callback_page;
816   };
817 
818   /*
819    * State variables on connection.
820    * State variable on tuple after multi-updates
821    * Is operation undo logged or not
822    * Is operation in fragment list
823    * Is operation in multi-update list
824    * Operation type (READ, UPDATE, etc)
825    * Is record primary replica
826    * Is delete or insert performed
827    */
828   struct OpBitFields {
829     unsigned int trans_state : 3;
830     unsigned int tuple_state : 2;
831     unsigned int in_active_list : 1;
832 
833     unsigned int op_type : 3;
834     unsigned int delete_insert_flag : 1;
835     unsigned int primary_replica : 1;
836     unsigned int m_reorg : 2;
837     unsigned int m_disk_preallocated : 1;
838     unsigned int m_load_diskpage_on_commit : 1;
839     unsigned int m_wait_log_buffer : 1;
840     unsigned int m_gci_written : 1;
841   };
842   union {
843     OpBitFields op_struct;
844     Uint32 op_bit_fields;
845   };
846 
847   /*
848    * TUX needs to know the tuple version of the tuple since it
849    * keeps an entry for both the committed and all versions in
850    * a transaction currently. So each update will create a new
851    * version even if in the same transaction.
852    */
853   Uint16 tupVersion;
854 
855   /*
856    * When refreshing a row, there are four scenarios
857    * The actual scenario is encoded in the 'copy tuple location'
858    * to enable special handling at commit time
859    */
860   enum RefreshScenario
861   {
862     RF_SINGLE_NOT_EXIST = 1,    /* Refresh op first in trans, no row */
863     RF_SINGLE_EXIST     = 2,    /* Refresh op first in trans, row exists */
864     RF_MULTI_NOT_EXIST  = 3,    /* Refresh op !first in trans, row deleted */
865     RF_MULTI_EXIST      = 4     /* Refresh op !first in trans, row exists */
866   };
867 };
868 typedef Ptr<Operationrec> OperationrecPtr;
869 
870   /* ************* TRIGGER DATA ************* */
871   /* THIS RECORD FORMS LISTS OF ACTIVE       */
872   /* TRIGGERS FOR EACH TABLE.                 */
873   /* THE RECORDS ARE MANAGED BY A TRIGGER     */
874   /* POOL wHERE A TRIGGER RECORD IS SEIZED    */
875   /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
876   /* WHEN THE TRIGGER IS DEACTIVATED.         */
877   /* **************************************** */
878 struct TupTriggerData {
TupTriggerDataDbtup::TupTriggerData879   TupTriggerData() {}
880 
881   /**
882    * Trigger id, used by DICT/TRIX to identify the trigger
883    *
884    * trigger Ids are unique per block for SUBSCRIPTION triggers.
885    * This is so that BACKUP can use TUP triggers directly and delete them
886    * properly.
887    */
888   Uint32 triggerId;
889 
890   /**
891    * In 6.3 there is one trigger per operation
892    */
893   Uint32 oldTriggerIds[3]; // INS/UPD/DEL
894 
895   /**
896    * Index id is needed for ordered index.
897    */
898   Uint32 indexId;
899 
900   /**
901    * Trigger type etc, defines what the trigger is used for
902    */
903   TriggerType::Value triggerType;
904   TriggerActionTime::Value triggerActionTime;
905   TriggerEvent::Value triggerEvent;
906   /**
907    * Receiver block reference
908    */
909   Uint32 m_receiverRef;
910 
911   /**
912    * Monitor all replicas, i.e. trigger will fire on all nodes where tuples
913    * are stored
914    */
915   bool monitorReplicas;
916 
917   /**
918    * Monitor all attributes, the trigger monitors all changes to attributes
919    * in the table
920    */
921   bool monitorAllAttributes;
922 
923   /**
924    * Send only changed attributes at trigger firing time.
925    */
926   bool sendOnlyChangedAttributes;
927 
928   /**
929    * Send also before values at trigger firing time.
930    */
931   bool sendBeforeValues;
932 
933   /**
934    * Attribute mask, defines what attributes are to be monitored
935    * Can be seen as a compact representation of SQL column name list
936    */
937   Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
938 
939   /**
940    * Next ptr (used in pool/list)
941    */
942   union {
943     Uint32 nextPool;
944     Uint32 nextList;
945   };
946 
947   /**
948    * Prev pointer (used in list)
949    */
950   Uint32 prevList;
951 
printDbtup::TupTriggerData952   inline void print(NdbOut & s) const { s << "[TriggerData = " << triggerId << "]"; };
953 };
954 
955 typedef Ptr<TupTriggerData> TriggerPtr;
956 
957 /**
958  * Pool of trigger data record
959  */
960 ArrayPool<TupTriggerData> c_triggerPool;
961 
962   /* ************ TABLE RECORD ************ */
963   /* THIS RECORD FORMS A LIST OF TABLE      */
964   /* REFERENCE INFORMATION. ONE RECORD      */
965   /* PER TABLE REFERENCE.                   */
966   /* ************************************** */
967   STATIC_CONST( MM = 0 );
968   STATIC_CONST( DD = 1 );
969   STATIC_CONST( DYN_BM_LEN_BITS = 8 );
970   STATIC_CONST( DYN_BM_LEN_MASK = ((1 << DYN_BM_LEN_BITS) - 1));
971 
972   /* Array length in the data structures like
973      dynTabDescriptor, dynVarSizeMask, dynFixSizeMask, etc.
974      1 for dynamic main memory data,
975      2 for dynamic main memory and dynamic disk data.
976   */
977   STATIC_CONST( NO_DYNAMICS = 2 );
978 
979   struct Tablerec {
TablerecDbtup::Tablerec980     Tablerec(ArrayPool<TupTriggerData> & triggerPool) :
981       afterInsertTriggers(triggerPool),
982       afterDeleteTriggers(triggerPool),
983       afterUpdateTriggers(triggerPool),
984       subscriptionInsertTriggers(triggerPool),
985       subscriptionDeleteTriggers(triggerPool),
986       subscriptionUpdateTriggers(triggerPool),
987       constraintUpdateTriggers(triggerPool),
988       deferredInsertTriggers(triggerPool),
989       deferredUpdateTriggers(triggerPool),
990       deferredDeleteTriggers(triggerPool),
991       tuxCustomTriggers(triggerPool)
992       {}
993 
994     Bitmask<MAXNROFATTRIBUTESINWORDS> notNullAttributeMask;
995     Bitmask<MAXNROFATTRIBUTESINWORDS> blobAttributeMask;
996 
997     /*
998       Extra table descriptor for dynamic attributes, or RNIL if none.
999       The size of this depends on actual column definitions, so it is allocated
1000       _after_ seeing all columns, hence must be separate from the readKeyArray
1001       et al descriptor, which is allocated before seeing columns.
1002     */
1003     Uint32 dynTabDescriptor[2];
1004 
1005     /* Mask of variable-sized dynamic attributes. */
1006     Uint32* dynVarSizeMask[2];
1007     /*
1008       Mask of fixed-sized dynamic attributes. There is one bit set for each
1009       32-bit word occupied by fixed-size attributes, so fixed-size dynamic
1010       attributes >32bit have multiple bits here.
1011     */
1012     Uint32* dynFixSizeMask[2];
1013 
1014     ReadFunction* readFunctionArray;
1015     UpdateFunction* updateFunctionArray;
1016     CHARSET_INFO** charsetArray;
1017 
1018     Uint32 readKeyArray;
1019     /*
1020       Offset into Dbtup::tableDescriptor of the start of the descriptor
1021       words for each attribute.
1022       For attribute i, the AttributeDescriptor word is stored at index
1023       Tablerec::tabDescriptor+i*ZAD_SIZE, and the AttributeOffset word at
1024       index Tablerec::tabDescriptor+i*ZAD_SIZE+1.
1025     */
1026     Uint32 tabDescriptor;
1027     /*
1028       Offset into Dbtup::tableDescriptor of memory used as an array of Uint16.
1029 
1030       The values stored are offsets from Tablerec::tabDescriptor first for all
1031       fixed-sized static attributes, then static varsized attributes, then
1032       dynamic fixed-size, then dynamic varsized, and finally disk-stored fixed
1033       size:
1034               [mm_fix mm_var mm_dynfix mm_dynvar dd_fix]
1035       This is used to find the AttributeDescriptor and AttributeOffset words
1036       for an attribute. For example, the offset for the second dynamic
1037       fixed-size attribute is at index <num fixed> + <num varsize> + 1.
1038     */
1039     Uint32 m_real_order_descriptor;
1040 
1041     enum Bits
1042     {
1043       TR_Checksum = 0x1, // Need to be 1
1044       TR_RowGCI   = 0x2,
1045       TR_ForceVarPart = 0x4,
1046       TR_DiskPart  = 0x8,
1047       TR_ExtraRowGCIBits = 0x10,
1048       TR_ExtraRowAuthorBits = 0x20
1049     };
1050     Uint16 m_bits;
1051     Uint16 total_rec_size; // Max total size for entire tuple in words
1052 
1053     /**
1054      * Aggregates
1055      */
1056     Uint16 m_no_of_attributes;
1057     Uint16 m_no_of_disk_attributes;
1058     Uint16 noOfKeyAttr;
1059     Uint16 noOfCharsets;
1060     Uint16 m_dyn_null_bits[2];
1061     Uint16 m_no_of_extra_columns; // "Hidden" columns
1062 
need_expandDbtup::Tablerec1063     bool need_expand() const {
1064       return m_no_of_attributes > m_attributes[MM].m_no_of_fixsize;
1065     }
1066 
need_expandDbtup::Tablerec1067     bool need_expand(bool disk) const {
1068       return m_attributes[MM].m_no_of_varsize > 0 ||
1069         m_attributes[MM].m_no_of_dynamic > 0 ||
1070 	(disk && m_no_of_disk_attributes > 0);
1071     }
1072 
need_shrinkDbtup::Tablerec1073     bool need_shrink() const {
1074       return
1075 	m_attributes[MM].m_no_of_varsize > 0 ||
1076         m_attributes[MM].m_no_of_dynamic > 0 ||
1077 	m_attributes[DD].m_no_of_varsize > 0;
1078     }
1079 
need_shrinkDbtup::Tablerec1080     bool need_shrink(bool disk) const {
1081       return
1082 	m_attributes[MM].m_no_of_varsize > 0 ||
1083 	m_attributes[MM].m_no_of_dynamic > 0 ||
1084         (disk && m_attributes[DD].m_no_of_varsize > 0);
1085     }
1086 
getExtraAttrIdDbtup::Tablerec1087     template <Uint32 bit> Uint32 getExtraAttrId() const {
1088       if (bit == TR_ExtraRowGCIBits)
1089         return 0;
1090       Uint32 no = 0;
1091       if (m_bits & TR_ExtraRowGCIBits)
1092         no++;
1093       assert(bit == TR_ExtraRowAuthorBits);
1094       //if (bit == TR_ExtraRowAuthorBits)
1095       return no;
1096     }
1097 
1098     /**
1099      * Descriptors for MM and DD part
1100      */
1101     struct Tuple_offsets {
1102       Uint8 m_null_words;
1103       Uint8 m_null_offset;
1104       Uint16 m_disk_ref_offset; // In words relative m_data
1105       Uint16 m_fix_header_size; // For fix size tuples= total rec size(part)
1106       Uint16 m_max_var_offset;  // In bytes relative m_var_data.m_data_ptr
1107       Uint16 m_max_dyn_offset;  // In bytes relative m_var_data.m_dyn_data_ptr
1108       Uint16 m_dyn_null_words;  // 32-bit words in dynattr bitmap
1109     } m_offsets[2];
1110 
get_check_offsetDbtup::Tablerec1111     Uint32 get_check_offset(Uint32 mm) const {
1112       return m_offsets[mm].m_fix_header_size;
1113     }
1114 
1115     struct {
1116       Uint16 m_no_of_fixsize;
1117       Uint16 m_no_of_varsize;
1118       Uint16 m_no_of_dynamic;                   // Total no. of dynamic attrs
1119       Uint16 m_no_of_dyn_fix;                   // No. of fixsize dynamic
1120       Uint16 m_no_of_dyn_var;                   // No. of varsize dynamic
1121       /*
1122         Note that due to bit types, we may have
1123             m_no_of_dynamic > m_no_of_dyn_fix + m_no_of_dyn_var
1124       */
1125     } m_attributes[2];
1126 
1127     // Lists of trigger data for active triggers
1128     DLList<TupTriggerData> afterInsertTriggers;
1129     DLList<TupTriggerData> afterDeleteTriggers;
1130     DLList<TupTriggerData> afterUpdateTriggers;
1131     DLList<TupTriggerData> subscriptionInsertTriggers;
1132     DLList<TupTriggerData> subscriptionDeleteTriggers;
1133     DLList<TupTriggerData> subscriptionUpdateTriggers;
1134     DLList<TupTriggerData> constraintUpdateTriggers;
1135     DLList<TupTriggerData> deferredInsertTriggers;
1136     DLList<TupTriggerData> deferredUpdateTriggers;
1137     DLList<TupTriggerData> deferredDeleteTriggers;
1138 
1139     // List of ordered indexes
1140     DLList<TupTriggerData> tuxCustomTriggers;
1141 
1142     Uint32 fragid[MAX_FRAG_PER_NODE];
1143     Uint32 fragrec[MAX_FRAG_PER_NODE];
1144 
1145     union {
1146       struct {
1147         Uint32 tabUserPtr;
1148         Uint32 tabUserRef;
1149         Uint32 m_lcpno;
1150         Uint32 m_fragPtrI;
1151       } m_dropTable;
1152       struct {
1153         Uint32 m_fragOpPtrI;
1154         Uint32 defValSectionI;
1155         Local_key defValLocation;
1156       } m_createTable;
1157       struct {
1158         Uint32 m_gci_hi;
1159       } m_reorg_suma_filter;
1160     };
1161 
1162     State tableStatus;
1163     Local_key m_default_value_location;
1164   };
1165 
1166   /*
1167     It is more space efficient to store dynamic fixed-size attributes
1168     of more than about 16 words as variable-sized internally.
1169    */
1170   STATIC_CONST(InternalMaxDynFix= 16);
1171 
1172   struct Disk_undo
1173   {
1174     enum
1175     {
1176       UNDO_ALLOC = File_formats::Undofile::UNDO_TUP_ALLOC
1177       ,UNDO_UPDATE = File_formats::Undofile::UNDO_TUP_UPDATE
1178       ,UNDO_FREE = File_formats::Undofile::UNDO_TUP_FREE
1179       ,UNDO_CREATE = File_formats::Undofile::UNDO_TUP_CREATE
1180       ,UNDO_DROP = File_formats::Undofile::UNDO_TUP_DROP
1181       ,UNDO_ALLOC_EXTENT = File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT
1182       ,UNDO_FREE_EXTENT = File_formats::Undofile::UNDO_TUP_FREE_EXTENT
1183     };
1184 
1185     struct Alloc
1186     {
1187       Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1188       Uint32 m_page_no;
1189       Uint32 m_type_length; // 16 bit type, 16 bit length
1190     };
1191 
1192     struct Update
1193     {
1194       Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1195       Uint32 m_page_no;
1196       Uint32 m_gci;
1197       Uint32 m_data[1];
1198       Uint32 m_type_length; // 16 bit type, 16 bit length
1199     };
1200 
1201     struct Free
1202     {
1203       Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1204       Uint32 m_page_no;
1205       Uint32 m_gci;
1206       Uint32 m_data[1];
1207       Uint32 m_type_length; // 16 bit type, 16 bit length
1208     };
1209 
1210     struct Create
1211     {
1212       Uint32 m_table;
1213       Uint32 m_type_length; // 16 bit type, 16 bit length
1214     };
1215 
1216     struct Drop
1217     {
1218       Uint32 m_table;
1219       Uint32 m_type_length; // 16 bit type, 16 bit length
1220     };
1221 
1222     struct AllocExtent
1223     {
1224       Uint32 m_table;
1225       Uint32 m_fragment;
1226       Uint32 m_page_no;
1227       Uint32 m_file_no;
1228       Uint32 m_type_length;
1229     };
1230 
1231     struct FreeExtent
1232     {
1233       Uint32 m_table;
1234       Uint32 m_fragment;
1235       Uint32 m_page_no;
1236       Uint32 m_file_no;
1237       Uint32 m_type_length;
1238     };
1239   };
1240 
1241   Extent_info_pool c_extent_pool;
1242   Extent_info_hash c_extent_hash;
1243   Page_request_pool c_page_request_pool;
1244 
1245   typedef Ptr<Tablerec> TablerecPtr;
1246 
1247   struct storedProc {
1248     Uint32 storedProcIVal;
1249     Uint32 nextPool;
1250     Uint16 storedCode;
1251   };
1252 
1253 typedef Ptr<storedProc> StoredProcPtr;
1254 
1255 ArrayPool<storedProc> c_storedProcPool;
1256 RSS_AP_SNAPSHOT(c_storedProcPool);
1257 Uint32 c_storedProcCountNonAPI;
1258 void storedProcCountNonAPI(BlockReference apiBlockref, int add_del);
1259 
1260 /* **************************** TABLE_DESCRIPTOR RECORD ******************************** */
1261 /* THIS VARIABLE IS USED TO STORE TABLE DESCRIPTIONS. A TABLE DESCRIPTION IS STORED AS A */
1262 /* CONTIGUOS ARRAY IN THIS VARIABLE. WHEN A NEW TABLE IS ADDED A CHUNK IS ALLOCATED IN   */
1263 /* THIS RECORD. WHEN ATTRIBUTES ARE ADDED TO THE TABLE, A NEW CHUNK OF PROPER SIZE IS    */
1264 /* ALLOCATED AND ALL DATA IS COPIED TO THIS NEW CHUNK AND THEN THE OLD CHUNK IS PUT IN   */
1265 /* THE FREE LIST. EACH TABLE IS DESCRIBED BY A NUMBER OF TABLE DESCRIPTIVE ATTRIBUTES    */
1266 /* AND A NUMBER OF ATTRIBUTE DESCRIPTORS AS SHOWN IN FIGURE BELOW                        */
1267 /*                                                                                       */
1268 /* WHEN ALLOCATING A TABLE DESCRIPTOR THE SIZE IS ALWAYS A MULTIPLE OF 16 WORDS.         */
1269 /*                                                                                       */
1270 /*               ----------------------------------------------                          */
1271 /*               |    TRAILER USED FOR ALLOC/DEALLOC          |                          */
1272 /*               ----------------------------------------------                          */
1273 /*               |    TABLE DESCRIPTIVE ATTRIBUTES            |                          */
1274 /*               ----------------------------------------------                          */
1275 /*               |    ATTRIBUTE DESCRIPTION 1                 |                          */
1276 /*               ----------------------------------------------                          */
1277 /*               |    ATTRIBUTE DESCRIPTION 2                 |                          */
1278 /*               ----------------------------------------------                          */
1279 /*               |                                            |                          */
1280 /*               |                                            |                          */
1281 /*               |                                            |                          */
1282 /*               ----------------------------------------------                          */
1283 /*               |    ATTRIBUTE DESCRIPTION N                 |                          */
1284 /*               ----------------------------------------------                          */
1285 /*                                                                                       */
1286 /* THE TABLE DESCRIPTIVE ATTRIBUTES CONTAINS THE FOLLOWING ATTRIBUTES:                   */
1287 /*                                                                                       */
1288 /*               ----------------------------------------------                          */
1289 /*               |    HEADER (TYPE OF INFO)                   |                          */
1290 /*               ----------------------------------------------                          */
1291 /*               |    SIZE OF WHOLE CHUNK (INCL. TRAILER)     |                          */
1292 /*               ----------------------------------------------                          */
1293 /*               |    TABLE IDENTITY                          |                          */
1294 /*               ----------------------------------------------                          */
1295 /*               |    FRAGMENT IDENTITY                       |                          */
1296 /*               ----------------------------------------------                          */
1297 /*               |    NUMBER OF ATTRIBUTES                    |                          */
1298 /*               ----------------------------------------------                          */
1299 /*               |    SIZE OF FIXED ATTRIBUTES                |                          */
1300 /*               ----------------------------------------------                          */
1301 /*               |    NUMBER OF NULL FIELDS                   |                          */
1302 /*               ----------------------------------------------                          */
1303 /*               |    NOT USED                                |                          */
1304 /*               ----------------------------------------------                          */
1305 /*                                                                                       */
1306 /* THESE ATTRIBUTES ARE ALL ONE R-VARIABLE IN THE RECORD.                                */
1307 /* NORMALLY ONLY ONE TABLE DESCRIPTOR IS USED. DURING SCHEMA CHANGES THERE COULD         */
1308 /* HOWEVER EXIST MORE THAN ONE TABLE DESCRIPTION SINCE THE SCHEMA CHANGE OF VARIOUS      */
1309 /* FRAGMENTS ARE NOT SYNCHRONISED. THIS MEANS THAT ALTHOUGH THE SCHEMA HAS CHANGED       */
1310 /* IN ALL FRAGMENTS, BUT THE FRAGMENTS HAVE NOT REMOVED THE ATTRIBUTES IN THE SAME       */
1311 /* TIME-FRAME. THEREBY SOME ATTRIBUTE INFORMATION MIGHT DIFFER BETWEEN FRAGMENTS.        */
1312 /* EXAMPLES OF ATTRIBUTES THAT MIGHT DIFFER ARE SIZE OF FIXED ATTRIBUTES, NUMBER OF      */
1313 /* ATTRIBUTES, FIELD START WORD, START BIT.                                              */
1314 /*                                                                                       */
1315 /* AN ATTRIBUTE DESCRIPTION CONTAINS THE FOLLOWING ATTRIBUTES:                           */
1316 /*                                                                                       */
1317 /*               ----------------------------------------------                          */
1318 /*               |    Field Type, 4 bits (LSB Bits)           |                          */
1319 /*               ----------------------------------------------                          */
1320 /*               |    Attribute Size, 4 bits                  |                          */
1321 /*               ----------------------------------------------                          */
1322 /*               |    NULL indicator 1 bit                    |                          */
1323 /*               ----------------------------------------------                          */
1324 /*               |    Indicator if TUP stores attr. 1 bit     |                          */
1325 /*               ----------------------------------------------                          */
1326 /*               |    Not used 6 bits                         |                          */
1327 /*               ----------------------------------------------                          */
1328 /*               |    No. of elements in fixed array 16 bits  |                          */
1329 /*               ----------------------------------------------                          */
1330 /*               ----------------------------------------------                          */
1331 /*               |    Field Start Word, 21 bits (LSB Bits)    |                          */
1332 /*               ----------------------------------------------                          */
1333 /*               |    NULL Bit, 11 bits                       |                          */
1334 /*               ----------------------------------------------                          */
1335 /*                                                                                       */
1336 /* THE ATTRIBUTE SIZE CAN BE 1,2,4,8,16,32,64 AND 128 BITS.                              */
1337 /*                                                                                       */
1338 /* THE UNUSED PARTS OF THE RECORDS ARE PUT IN A LINKED LIST OF FREE PARTS. EACH OF       */
1339 /* THOSE FREE PARTS HAVE THREE RECORDS ASSIGNED AS SHOWN IN THIS STRUCTURE               */
1340 /* ALL FREE PARTS ARE SET INTO A CHUNK LIST WHERE EACH CHUNK IS AT LEAST 16 WORDS        */
1341 /*                                                                                       */
1342 /*               ----------------------------------------------                          */
1343 /*               |    HEADER = RNIL                           |                          */
1344 /*               ----------------------------------------------                          */
1345 /*               |    SIZE OF FREE AREA                       |                          */
1346 /*               ----------------------------------------------                          */
1347 /*               |    POINTER TO PREVIOUS FREE AREA           |                          */
1348 /*               ----------------------------------------------                          */
1349 /*               |    POINTER TO NEXT FREE AREA               |                          */
1350 /*               ----------------------------------------------                          */
1351 /*                                                                                       */
1352 /* IF THE POINTER TO THE NEXT AREA IS RNIL THEN THIS IS THE LAST FREE AREA.              */
1353 /*                                                                                       */
1354 /*****************************************************************************************/
1355 struct TableDescriptor {
1356   Uint32 tabDescr;
1357 };
1358 typedef Ptr<TableDescriptor> TableDescriptorPtr;
1359 
1360 struct HostBuffer {
1361   bool  inPackedList;
1362   Uint32 packetLenTA;
1363   Uint32 noOfPacketsTA;
1364   Uint32 packetBufferTA[30];
1365 };
1366 typedef Ptr<HostBuffer> HostBufferPtr;
1367 
1368   /*
1369    * Build index operation record.
1370    */
1371   struct BuildIndexRec {
BuildIndexRecDbtup::BuildIndexRec1372     BuildIndexRec() {}
1373 
1374     BuildIndxImplReq m_request;
1375     Uint8  m_build_vs;          // varsize pages
1376     Uint32 m_indexId;           // the index
1377     Uint32 m_fragNo;            // fragment number under Tablerec
1378     Uint32 m_pageId;            // logical fragment page id
1379     Uint32 m_tupleNo;           // tuple number on page
1380     Uint32 m_buildRef;          // Where to send tuples
1381     Uint32 m_outstanding;       // If mt-build...
1382     BuildIndxImplRef::ErrorCode m_errorCode;
1383     union {
1384       Uint32 nextPool;
1385       Uint32 nextList;
1386     };
1387     Uint32 prevList;
1388   };
1389   typedef Ptr<BuildIndexRec> BuildIndexPtr;
1390   ArrayPool<BuildIndexRec> c_buildIndexPool;
1391   DLList<BuildIndexRec> c_buildIndexList;
1392   Uint32 c_noOfBuildIndexRec;
1393 
1394   int mt_scan_init(Uint32 tableId, Uint32 fragId, Local_key * pos, Uint32 * fragPtrI);
1395   int mt_scan_next(Uint32 tableId, Uint32 fragPtrI, Local_key* pos, bool moveNext);
1396 
1397   /**
1398    * Reference to variable part when a tuple is chained
1399    */
1400   struct Var_part_ref
1401   {
1402 #ifdef NDB_32BIT_VAR_REF
1403     /*
1404       In versions prior to ndb 6.1.6, 6.2.1 and mysql 5.1.17
1405       Running this code limits DataMemory to 16G, also online
1406       upgrade not possible between versions
1407      */
1408     Uint32 m_ref;
1409     STATIC_CONST( SZ32 = 1 );
1410 
copyoutDbtup::Var_part_ref1411     void copyout(Local_key* dst) const {
1412       dst->m_page_no = Local_key::ref2page_id(m_ref);
1413       dst->m_page_idx = Local_key::ref2page_idx(m_ref);
1414     }
1415 
assignDbtup::Var_part_ref1416     void assign(const Local_key* src) {
1417       m_ref = Local_key::ref(src->m_page_no, src->m_page_idx);
1418     }
1419 #else
1420     Uint32 m_page_no;
1421     Uint32 m_page_idx;
1422     STATIC_CONST( SZ32 = 2 );
1423 
1424     void copyout(Local_key* dst) const {
1425       dst->m_page_no = m_page_no;
1426       dst->m_page_idx = m_page_idx;
1427     }
1428 
1429     void assign(const Local_key* src) {
1430       m_page_no = src->m_page_no;
1431       m_page_idx = src->m_page_idx;
1432     }
1433 #endif
1434   };
1435 
1436   struct Disk_part_ref
1437   {
1438     STATIC_CONST( SZ32 = 2 );
1439   };
1440 
1441   struct Tuple_header
1442   {
1443     union {
1444       /**
1445        * List of prepared operations for this tuple.
1446        * Points to most recent/last operation, ie. to walk the list must follow
1447        * regOperPtr->prevActiveOp links.
1448        */
1449       Uint32 m_operation_ptr_i;  // OperationPtrI
1450       Uint32 m_base_record_ref;  // For disk tuple, ref to MM tuple
1451     };
1452     Uint32 m_header_bits;      // Header word
1453     union {
1454       Uint32 m_checksum;
1455       Uint32 m_data[1];
1456       Uint32 m_null_bits[1];
1457     };
1458 
1459     STATIC_CONST( HeaderSize = 2 );
1460 
1461     /*
1462      Header bits.
1463 
1464      MM_GROWN: When a tuple is updated to a bigger size, the original varpart
1465      of the tuple is immediately re-allocated to a location with sufficient
1466      size for the new data (but containing only the original smaller-sized
1467      data). This is so that commit can be sure to find room for the extra
1468      data. In the case of abort, the varpart must then be shrunk. For a
1469      MM_GROWN tuple, the original size is stored in the last word of the
1470      varpart until commit.
1471     */
1472     STATIC_CONST( TUP_VERSION_MASK = 0xFFFF );
1473     STATIC_CONST( COPY_TUPLE  = 0x00010000 ); // Is this a copy tuple
1474     STATIC_CONST( DISK_PART   = 0x00020000 ); // Is there a disk part
1475     STATIC_CONST( DISK_ALLOC  = 0x00040000 ); // Is disk part allocated
1476     STATIC_CONST( DISK_INLINE = 0x00080000 ); // Is disk inline
1477     STATIC_CONST( ALLOC       = 0x00100000 ); // Is record allocated now
1478     STATIC_CONST( MM_SHRINK   = 0x00200000 ); // Has MM part shrunk
1479     STATIC_CONST( MM_GROWN    = 0x00400000 ); // Has MM part grown
1480     STATIC_CONST( FREED       = 0x00800000 ); // Is freed
1481     STATIC_CONST( FREE        = 0x00800000 ); // alias
1482     STATIC_CONST( LCP_SKIP    = 0x01000000 ); // Should not be returned in LCP
1483     STATIC_CONST( VAR_PART    = 0x04000000 ); // Is there a varpart
1484     STATIC_CONST( REORG_MOVE  = 0x08000000 );
1485 
Tuple_headerDbtup::Tuple_header1486     Tuple_header() {}
get_tuple_versionDbtup::Tuple_header1487     Uint32 get_tuple_version() const {
1488       return m_header_bits & TUP_VERSION_MASK;
1489     }
set_tuple_versionDbtup::Tuple_header1490     void set_tuple_version(Uint32 version) {
1491       m_header_bits=
1492 	(m_header_bits & ~(Uint32)TUP_VERSION_MASK) |
1493 	(version & TUP_VERSION_MASK);
1494     }
1495 
get_null_bitsDbtup::Tuple_header1496     Uint32* get_null_bits(const Tablerec* tabPtrP) {
1497       return m_null_bits+tabPtrP->m_offsets[MM].m_null_offset;
1498     }
1499 
get_null_bitsDbtup::Tuple_header1500     Uint32* get_null_bits(const Tablerec* tabPtrP, Uint32 mm) {
1501       return m_null_bits+tabPtrP->m_offsets[mm].m_null_offset;
1502     }
1503 
get_var_part_ref_ptrDbtup::Tuple_header1504     Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) {
1505       return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
1506     }
1507 
get_var_part_ref_ptrDbtup::Tuple_header1508     const Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) const {
1509       return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
1510     }
1511 
get_end_of_fix_part_ptrDbtup::Tuple_header1512     Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) {
1513       return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
1514         Tuple_header::HeaderSize;
1515     }
1516 
get_end_of_fix_part_ptrDbtup::Tuple_header1517     const Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) const {
1518       return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
1519         Tuple_header::HeaderSize;
1520     }
1521 
get_disk_ref_ptrDbtup::Tuple_header1522     Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) {
1523       return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
1524     }
1525 
get_disk_ref_ptrDbtup::Tuple_header1526     const Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) const {
1527       return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
1528     }
1529 
get_mm_gciDbtup::Tuple_header1530     Uint32 *get_mm_gci(const Tablerec* tabPtrP){
1531       assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
1532       return m_data + (tabPtrP->m_bits & Tablerec::TR_Checksum);
1533     }
1534 
get_dd_gciDbtup::Tuple_header1535     Uint32 *get_dd_gci(const Tablerec* tabPtrP, Uint32 mm){
1536       assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
1537       return m_data;
1538     }
1539   };
1540 
1541   /**
1542    * Format of varpart after insert/update
1543    */
1544   struct Varpart_copy
1545   {
1546     Uint32 m_len;
1547     Uint32 m_data[1]; // Only used for easy offset handling
1548 
1549     STATIC_CONST( SZ32 = 1 );
1550   };
1551 
1552   enum When
1553   {
1554     KRS_PREPARE = 0,
1555     KRS_COMMIT = 1,
1556     KRS_PRE_COMMIT0 = 2, // There can be multiple pre commit phases...
1557     KRS_PRE_COMMIT1 = 3
1558   };
1559 
1560 struct KeyReqStruct {
1561 
KeyReqStructDbtup::KeyReqStruct1562   KeyReqStruct(EmulatedJamBuffer * _jamBuffer, When when = KRS_PREPARE) {
1563 #if defined VM_TRACE || defined ERROR_INSERT
1564     memset(this, 0xf3, sizeof(* this));
1565 #endif
1566     jamBuffer = _jamBuffer;
1567     m_when = when;
1568     m_deferred_constraints = true;
1569   }
KeyReqStructDbtup::KeyReqStruct1570   KeyReqStruct(Dbtup* tup, When when = KRS_PREPARE) {
1571 #if defined VM_TRACE || defined ERROR_INSERT
1572     memset(this, 0xf3, sizeof(* this));
1573 #endif
1574     jamBuffer = tup->jamBuffer();
1575     m_when = when;
1576     m_deferred_constraints = true;
1577   }
1578 
1579 /**
1580  * These variables are used as temporary storage during execution of the
1581  * TUPKEYREQ signal.
1582  * The first set of variables defines a number of variables needed for
1583  * the fix part of the tuple.
1584  *
1585  * The second part defines a number of commonly used meta data variables.
1586  *
1587  * The third set of variables defines a set of variables needed for the
1588  * variable part.
1589  *
1590  * The fourth part is variables needed only for updates and inserts.
1591  *
1592  * The fifth part is a long array of real lengths which is is put last
1593  * for cache memory reasons. This is part of the variable part and
1594  * contains the real allocated lengths whereas the tuple contains
1595  * the length of attribute stored.
1596  */
1597   Tablerec* tablePtrP;
1598   Fragrecord* fragPtrP;
1599   Operationrec * operPtrP;
1600   EmulatedJamBuffer * jamBuffer;
1601   Tuple_header *m_tuple_ptr;
1602 
1603   Uint32 check_offset[2];
1604 
1605   TableDescriptor *attr_descr;
1606   Uint32          max_read;
1607   Uint32          out_buf_index;
1608   Uint32          out_buf_bits;
1609   Uint32          in_buf_index;
1610   union {
1611     Uint32 in_buf_len;
1612     Uint32 m_lcp_varpart_len;
1613   };
1614   union {
1615     Uint32          attr_descriptor;
1616     Uint32 errorCode; // Used in DbtupRoutines read/update functions
1617   };
1618   bool            xfrm_flag;
1619 
1620   /* Flag: is tuple in expanded or in shrunken/stored format? */
1621   bool is_expanded;
1622   bool m_is_lcp;
1623   enum When m_when;
1624 
1625   struct Var_data {
1626     /*
1627       These are the pointers and offsets to the variable-sized part of the row
1628       (static part, alwways stored even if NULL). They are used both for
1629       expanded and shrunken form, with different values to allow using the
1630       same read/update code for both forms.
1631     */
1632     char *m_data_ptr;
1633     Uint16 *m_offset_array_ptr;
1634     Uint16 m_var_len_offset;
1635     Uint16 m_max_var_offset;
1636     Uint16 m_max_dyn_offset;
1637 
1638     /* These are the pointers and offsets to the dynamic part of the row. */
1639 
1640     /* Pointer to the start of the bitmap for the dynamic part of the row. */
1641     char *m_dyn_data_ptr;
1642     /* Number of 32-bit words in dynamic part (stored/shrunken format). */
1643     Uint32 m_dyn_part_len;
1644     /*
1645       Pointer to array with one element for each dynamic attribute (both
1646       variable and fixed size). Each value is the offset from the end of the
1647       bitmap to the start of the data for that attribute.
1648     */
1649     Uint16 *m_dyn_offset_arr_ptr;
1650     /*
1651       Offset from m_dyn_offset_array_ptr of array with one element for each
1652       dynamic attribute. Each value is the offset to the end of data for that
1653       attribute, so the difference to m_dyn_offset_array_ptr elements provides
1654       the data lengths.
1655     */
1656     Uint16 m_dyn_len_offset;
1657   } m_var_data[2];
1658 
1659   Tuple_header *m_disk_ptr;
1660   PagePtr m_page_ptr;
1661   PagePtr m_varpart_page_ptr;    // could be same as m_page_ptr_p
1662   PagePtr m_disk_page_ptr;       //
1663   Local_key m_row_id;
1664   Uint32 optimize_options;
1665 
1666   bool            dirty_op;
1667   bool            interpreted_exec;
1668   bool            last_row;
1669   bool            m_use_rowid;
1670   Uint8           m_reorg;
1671   bool            m_deferred_constraints;
1672 
1673   Signal*         signal;
1674   Uint32 no_fired_triggers;
1675   Uint32 frag_page_id;
1676   Uint32 hash_value;
1677   Uint32 gci_hi;
1678   Uint32 gci_lo;
1679   Uint32 log_size;
1680   Uint32 read_length;
1681   Uint32 attrinfo_len;
1682   Uint32 tc_operation_ptr;
1683   Uint32 trans_id1;
1684   Uint32 trans_id2;
1685   Uint32 TC_index;
1686   // next 2 apply only to attrids >= 64 (zero otherwise)
1687   BlockReference TC_ref;
1688   BlockReference rec_blockref;
1689 
1690   /*
1691    * A bit mask where a bit set means that the update or insert
1692    * was updating this record.
1693    */
1694   Bitmask<MAXNROFATTRIBUTESINWORDS> changeMask;
1695   Uint16 var_pos_array[2*MAX_ATTRIBUTES_IN_TABLE + 1];
1696   OperationrecPtr prevOpPtr;
1697 };
1698 
1699   friend struct Undo_buffer;
1700   Undo_buffer c_undo_buffer;
1701 
1702 /*
1703  No longer used:
1704  Implemented by shift instructions in subroutines instead
1705 
1706 struct TupHeadInfo {
1707   struct BitPart {
1708     unsigned int disk_indicator : 1;
1709     unsigned int var_part_loc_ind : 1;
1710     unsigned int initialised : 1;
1711     unsigned int not_used_yet : 5;
1712     unsigned int no_var_sized : 8;
1713     unsigned int tuple_version : 16;
1714   };
1715   union {
1716     Uint32 all;
1717     BitPart bit_part;
1718   };
1719 };
1720 */
1721 
1722   struct ChangeMask
1723   {
1724     Uint32 m_cols;
1725     Uint32 m_mask[1];
1726 
end_of_maskDbtup::ChangeMask1727     const Uint32 * end_of_mask() const { return end_of_mask(m_cols); }
end_of_maskDbtup::ChangeMask1728     const Uint32 * end_of_mask(Uint32 cols) const {
1729       return m_mask + ((cols + 31) >> 5);
1730     }
1731 
end_of_maskDbtup::ChangeMask1732     Uint32 * end_of_mask() { return end_of_mask(m_cols); }
end_of_maskDbtup::ChangeMask1733     Uint32 * end_of_mask(Uint32 cols) {
1734       return m_mask + ((cols + 31) >> 5);
1735     }
1736   };
1737 
1738 // updateAttributes module
1739   Uint32          terrorCode;
1740 
1741 public:
1742   Dbtup(Block_context&, Uint32 instanceNumber = 0);
1743   virtual ~Dbtup();
1744 
1745   /*
1746    * TUX uses logical tuple address when talking to ACC and LQH.
1747    */
1748   void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset,
1749                      Uint32& lkey1, Uint32& lkey2);
1750 
1751   /*
1752    * TUX index in TUP has single Uint32 array attribute which stores an
1753    * index node.  TUX reads and writes the node directly via pointer.
1754    */
1755   int tuxAllocNode(EmulatedJamBuffer*, Uint32 fragPtrI, Uint32& pageId, Uint32& pageOffset, Uint32*& node);
1756   void tuxFreeNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* node);
1757   void tuxGetNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32*& node);
1758 
1759   /*
1760    * TUX reads primary table attributes for index keys.  Tuple is
1761    * specified by location of original tuple and version number.  Input
1762    * is attribute ids in AttributeHeader format.  Output is attribute
1763    * data with headers.  Uses readAttributes with xfrm option set.
1764    * After wl4163, xfrm is not set.
1765    * Returns number of words or negative (-terrorCode) on error.
1766    */
1767   int tuxReadAttrs(EmulatedJamBuffer*,
1768                    Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion,
1769                    const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut, bool xfrmFlag);
1770 
1771   /*
1772    * TUX reads primary key without headers into an array of words.  Used
1773    * for md5 summing and when returning keyinfo.  Returns number of
1774    * words or negative (-terrorCode) on error.
1775    */
1776   int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag);
1777 
1778   /*
1779    * ACC reads primary key without headers into an array of words.  At
1780    * this point in ACC deconstruction, ACC still uses logical references
1781    * to fragment and tuple.
1782    */
1783   int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag);
1784 
1785   /*
1786    * TUX checks if tuple is visible to scan.
1787    */
1788   bool tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageIndex, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savepointId);
1789 
1790   int load_diskpage(Signal*, Uint32 opRec, Uint32 fragPtrI,
1791 		    Uint32 lkey1, Uint32 lkey2, Uint32 flags);
1792 
1793   int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI,
1794 			 Uint32 lkey1, Uint32 lkey2, Uint32 flags);
1795 
1796   void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
1797   void complete_restore_lcp(Signal*, Uint32 ref, Uint32 data,
1798                             Uint32 tableId, Uint32 fragmentId);
1799   Uint32 get_max_lcp_record_size(Uint32 tableId);
1800 
1801   int nr_read_pk(Uint32 fragPtr, const Local_key*, Uint32* dataOut, bool&copy);
1802   int nr_update_gci(Uint32 fragPtr, const Local_key*, Uint32 gci);
1803   int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci);
1804 
1805   void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page);
1806   void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page);
1807 
1808   bool get_frag_info(Uint32 tableId, Uint32 fragId, Uint32* maxPage);
1809 private:
1810   BLOCK_DEFINES(Dbtup);
1811 
1812   // Transit signals
1813   void execDEBUG_SIG(Signal* signal);
1814   void execCONTINUEB(Signal* signal);
1815 
1816   // Received signals
1817   void execLCP_FRAG_ORD(Signal*signal);
1818   void execDUMP_STATE_ORD(Signal* signal);
1819   void execSEND_PACKED(Signal* signal);
1820   void execSTTOR(Signal* signal);
1821   void execTUP_LCPREQ(Signal* signal);
1822   void execEND_LCPREQ(Signal* signal);
1823   void execSTART_RECREQ(Signal* signal);
1824   void execMEMCHECKREQ(Signal* signal);
1825   void execTUPSEIZEREQ(Signal* signal);
1826   void execTUPRELEASEREQ(Signal* signal);
1827   void execSTORED_PROCREQ(Signal* signal);
1828 
1829   void execCREATE_TAB_REQ(Signal*);
1830   void execTUP_ADD_ATTRREQ(Signal* signal);
1831   void execTUPFRAGREQ(Signal* signal);
1832   void execTUP_COMMITREQ(Signal* signal);
1833   void execTUP_ABORTREQ(Signal* signal);
1834   void execNDB_STTOR(Signal* signal);
1835   void execREAD_CONFIG_REQ(Signal* signal);
1836   void execDROP_TAB_REQ(Signal* signal);
1837   void execALTER_TAB_REQ(Signal* signal);
1838   void execTUP_DEALLOCREQ(Signal* signal);
1839   void execTUP_WRITELOG_REQ(Signal* signal);
1840   void execNODE_FAILREP(Signal* signal);
1841 
1842   void execDROP_FRAG_REQ(Signal*);
1843 
1844   // Ordered index related
1845   void execBUILD_INDX_IMPL_REQ(Signal* signal);
1846   void execBUILD_INDX_IMPL_REF(Signal* signal);
1847   void execBUILD_INDX_IMPL_CONF(Signal* signal);
1848   void buildIndex(Signal* signal, Uint32 buildPtrI);
1849   void buildIndexReply(Signal* signal, const BuildIndexRec* buildRec);
1850   void buildIndexOffline(Signal* signal, Uint32 buildPtrI);
1851   void buildIndexOffline_table_readonly(Signal* signal, Uint32 buildPtrI);
1852   void execALTER_TAB_CONF(Signal*);
1853 
1854   // Tup scan
1855   void execACC_SCANREQ(Signal* signal);
1856   void execNEXT_SCANREQ(Signal* signal);
1857   void execACC_CHECK_SCAN(Signal* signal);
1858   void execACCKEYCONF(Signal* signal);
1859   void execACCKEYREF(Signal* signal);
1860   void execACC_ABORTCONF(Signal* signal);
1861 
1862 
1863   // Drop table
1864   void execFSREMOVEREF(Signal*);
1865   void execFSREMOVECONF(Signal*);
1866 
1867   void execDBINFO_SCANREQ(Signal*);
1868   void execSUB_GCP_COMPLETE_REP(Signal*);
1869 
1870 //------------------------------------------------------------------
1871 //------------------------------------------------------------------
1872 // Methods to handle execution of TUPKEYREQ + ATTRINFO.
1873 //
1874 // Module Execution Manager
1875 //
1876 // The TUPKEYREQ signal is central to this block. This signal is used
1877 // by everybody that needs to read data residing in DBTUP. The data is
1878 // read using an interpreter approach.
1879 //
1880 // Operations only needing to read execute a simplified version of the
1881 // interpreter where the only instruction is read Attribute to send.
1882 // Operations only needing to update the record (insert or update)
1883 // execute a simplified version of the interpreter where the only
1884 // instruction is write Attribute.
1885 //
1886 // Currently TUPKEYREQ is used in the following situations.
1887 // 1) Normal transaction execution. Can be any of the types described
1888 //    below.
1889 // 2) Execution of fragment redo log during system restart.
1890 //    In this situation there will only be normal updates, inserts
1891 //    and deletes performed.
1892 // 3) A special type of normal transaction execution is to write the
1893 //    records arriving from the primary replica in the node restart
1894 //    processing. This will always be normal write operations which
1895 //    are translated to inserts or updates before arriving to TUP.
1896 // 4) Scan processing. The scan processing will use normal reads or
1897 //    interpreted reads in their execution. There will be one TUPKEYREQ
1898 //    signal for each record processed.
1899 // 5) Copy fragment processing. This is a special type of scan used in the
1900 //    primary replica at system restart. It reads the entire reads and
1901 //    converts those to writes to the starting node. In this special case
1902 //    LQH acts as an API node and receives also the ATTRINFO sent in the
1903 //    TRANSID_AI signals.
1904 //
1905 // Signal Diagram:
1906 //
1907 // In Signals:
1908 // -----------
1909 //
1910 // ---> TUPKEYREQ
1911 // A single TUPKEYREQ is received.  The TUPKEYREQ can contain an I-value
1912 // for a long section containing AttrInfo words.  Delete requests usually
1913 // contain no AttrInfo, and requests referencing a stored procedure (e.g.
1914 // scan originated requests) do not contain AttrInfo.
1915 //
1916 // The total size of the ATTRINFO is not allowed to be more than 16384 words.
1917 // There is always one and only one TUPKEYREQ.
1918 //
1919 // Response Signals (successful case):
1920 //
1921 // Simple/Dirty Read Operation
1922 // ---------------------------
1923 //
1924 // <---- TRANSID_AI (to API)
1925 // ...
1926 // <---- TRANSID_AI (to API)
1927 // <---- READCONF   (to API)
1928 // <---- TUPKEYCONF (to LQH)
1929 // There is always exactly one READCONF25 sent last. The number of
1930 // TRANSID_AI is dependent on how much that was read. The maximum size
1931 // of the ATTRINFO sent back is 16384 words. The signals are sent
1932 // directly to the application with an address provided by the
1933 // TUPKEYREQ signal.
1934 // A positive response signal is also sent to LQH.
1935 //
1936 // Normal Read Operation
1937 // ---------------------
1938 //
1939 // <---- TRANSID_AI (to API)
1940 // ...
1941 // <---- TRANSID_AI (to API)
1942 // <---- TUPKEYCONF (to LQH)
1943 // The number of TRANSID_AI is dependent on how much that was read.
1944 // The maximum size of the ATTRINFO sent back is 16384 words. The
1945 // signals are sent directly to the application with an address
1946 // provided by the TUPKEYREQ signal.
1947 // A positive response signal is also sent to LQH.
1948 //
1949 // Normal update/insert/delete operation
1950 // -------------------------------------
1951 //
1952 // <---- TUPKEYCONF
1953 // After successful updating of the tuple LQH is informed of this.
1954 //
1955 // Delete with read
1956 // ----------------
1957 //
1958 // Will behave as a normal read although it also prepares the
1959 // deletion of the tuple.
1960 //
1961 // Interpreted Update
1962 // ------------------
1963 //
1964 // <---- TRANSID_AI (to API)
1965 // ...
1966 // <---- TRANSID_AI (to API)
1967 // <---- TUP_ATTRINFO (to LQH)
1968 // ...
1969 // <---- TUP_ATTRINFO (to LQH)
1970 // <---- TUPKEYCONF (to LQH)
1971 //
1972 // The interpreted Update contains five sections:
1973 // The first section performs read Attribute operations
1974 // that send results back to the API.
1975 //
1976 // The second section executes the interpreted program
1977 // where data from attributes can be updated and it
1978 // can also read attribute values into the registers.
1979 //
1980 // The third section performs unconditional updates of
1981 // attributes.
1982 //
1983 // The fourth section can read the attributes to be sent to the
1984 // API after updating the record.
1985 //
1986 // The fifth section contains subroutines used by the interpreter
1987 // in the second section.
1988 //
1989 // All types of interpreted programs contains the same five sections.
1990 // The only difference is that only interpreted updates can update
1991 // attributes. Interpreted inserts are not allowed.
1992 //
1993 // Interpreted Updates have to send back the information about the
1994 // attributes they have updated. This information will be shipped to
1995 // the log and also to any other replicas. Thus interpreted updates
1996 // are only performed in the primary replica. The fragment redo log
1997 // in LQH will contain information so that normal update/inserts/deletes
1998 // can be performed using TUPKEYREQ.
1999 //
2000 // Interpreted Read
2001 // ----------------
2002 //
2003 // From a signalling point of view the Interpreted Read behaves as
2004 // as a Normal Read. The interpreted Read is often used by Scan's.
2005 //
2006 // Interpreted Delete
2007 // ------------------
2008 //
2009 // <---- TUPKEYCONF
2010 // After successful prepartion to delete the tuple LQH is informed
2011 // of this.
2012 //
2013 // Interpreted Delete with Read
2014 // ----------------------------
2015 //
2016 // From a signalling point of view an interpreted delete with read
2017 // behaves as a normal read.
2018 //
2019 // Continuation after successful case:
2020 //
2021 // After a read of any kind the operation record is ready to be used
2022 // again by a new operation.
2023 //
2024 // Any updates, inserts or deletes waits for either of two messages.
2025 // A commit specifying that the operation is to be performed for real
2026 // or an abort specifying that the operation is to be rolled back and
2027 // the record to be restored in its original format.
2028 //
2029 // This is handled by the module Transaction Manager.
2030 //
2031 // Response Signals (unsuccessful case):
2032 //
2033 // <---- TUPKEYREF (to LQH)
2034 // A signal is sent back to LQH informing about the unsuccessful
2035 // operation. In this case TUP waits for an abort signal to arrive
2036 // before the operation record is ready for the next operation.
2037 // This is handled by the Transaction Manager.
2038 //------------------------------------------------------------------
2039 //------------------------------------------------------------------
2040 
2041 // *****************************************************************
2042 // Signal Reception methods.
2043 // *****************************************************************
2044 //------------------------------------------------------------------
2045 //------------------------------------------------------------------
2046   void execTUPKEYREQ(Signal* signal);
2047   void disk_page_load_callback(Signal*, Uint32 op, Uint32 page);
2048   void disk_page_load_scan_callback(Signal*, Uint32 op, Uint32 page);
2049 
2050 private:
2051 
2052 // Trigger signals
2053 //------------------------------------------------------------------
2054 //------------------------------------------------------------------
2055   void execCREATE_TRIG_IMPL_REQ(Signal* signal);
2056 
2057 //------------------------------------------------------------------
2058 //------------------------------------------------------------------
2059   void execDROP_TRIG_IMPL_REQ(Signal* signal);
2060 
2061   /**
2062    * Deferred triggers execute when execFIRE_TRIG_REQ
2063    *   is called
2064    */
2065   void execFIRE_TRIG_REQ(Signal* signal);
2066 
2067 // *****************************************************************
2068 // Setting up the environment for reads, inserts, updates and deletes.
2069 // *****************************************************************
2070 //------------------------------------------------------------------
2071 //------------------------------------------------------------------
2072   int handleReadReq(Signal* signal,
2073                     Operationrec* regOperPtr,
2074                     Tablerec* regTabPtr,
2075                     KeyReqStruct* req_struct);
2076 
2077 //------------------------------------------------------------------
2078 //------------------------------------------------------------------
2079   int handleUpdateReq(Signal* signal,
2080                       Operationrec* regOperPtr,
2081                       Fragrecord* regFragPtr,
2082                       Tablerec* regTabPtr,
2083                       KeyReqStruct* req_struct,
2084 		      bool disk);
2085 
2086 //------------------------------------------------------------------
2087 //------------------------------------------------------------------
2088   int handleInsertReq(Signal* signal,
2089                       Ptr<Operationrec> regOperPtr,
2090                       Ptr<Fragrecord>,
2091                       Tablerec* regTabPtr,
2092                       KeyReqStruct* req_struct,
2093                       Local_key ** accminupdateptr);
2094 
2095 //------------------------------------------------------------------
2096 //------------------------------------------------------------------
2097   int handleDeleteReq(Signal* signal,
2098                       Operationrec* regOperPtr,
2099                       Fragrecord* regFragPtr,
2100                       Tablerec* regTabPtr,
2101                       KeyReqStruct* req_struct,
2102 		      bool disk);
2103 
2104   int handleRefreshReq(Signal* signal,
2105                        Ptr<Operationrec>,
2106                        Ptr<Fragrecord>,
2107                        Tablerec*,
2108                        KeyReqStruct*,
2109                        bool disk);
2110 
2111 //------------------------------------------------------------------
2112 //------------------------------------------------------------------
2113   int  updateStartLab(Signal* signal,
2114                       Operationrec* regOperPtr,
2115                       Fragrecord* regFragPtr,
2116                       Tablerec* regTabPtr,
2117                       KeyReqStruct* req_struct);
2118 
2119 // *****************************************************************
2120 // Interpreter Handling methods.
2121 // *****************************************************************
2122 
2123 //------------------------------------------------------------------
2124 //------------------------------------------------------------------
2125   int interpreterStartLab(Signal* signal,
2126                           KeyReqStruct *req_struct);
2127 
2128 //------------------------------------------------------------------
2129 //------------------------------------------------------------------
2130   Uint32 brancher(Uint32, Uint32);
2131   int interpreterNextLab(Signal* signal,
2132                          KeyReqStruct *req_struct,
2133                          Uint32* logMemory,
2134                          Uint32* mainProgram,
2135                          Uint32 TmainProgLen,
2136                          Uint32* subroutineProg,
2137                          Uint32 TsubroutineLen,
2138 			 Uint32 * tmpArea,
2139 			 Uint32 tmpAreaSz);
2140 
2141   const Uint32 * lookupInterpreterParameter(Uint32 paramNo,
2142                                             const Uint32 * subptr,
2143                                             Uint32 sublen) const;
2144 
2145 // *****************************************************************
2146 // Signal Sending methods.
2147 // *****************************************************************
2148 //------------------------------------------------------------------
2149 //------------------------------------------------------------------
2150   void sendReadAttrinfo(Signal* signal,
2151                         KeyReqStruct *req_struct,
2152                         Uint32 TnoOfData,
2153                         const Operationrec * regOperPtr);
2154 
2155 //------------------------------------------------------------------
2156 //------------------------------------------------------------------
2157   int sendLogAttrinfo(Signal* signal,
2158                       KeyReqStruct *req_struct,
2159                       Uint32 TlogSize,
2160                       Operationrec * regOperPtr);
2161 
2162 //------------------------------------------------------------------
2163 //------------------------------------------------------------------
2164   void sendTUPKEYCONF(Signal* signal,
2165                       KeyReqStruct *req_struct,
2166                       Operationrec * regOperPtr);
2167 
2168 //------------------------------------------------------------------
2169 //------------------------------------------------------------------
2170 // *****************************************************************
2171 // The methods that perform the actual read and update of attributes
2172 // in the tuple.
2173 // *****************************************************************
2174 //------------------------------------------------------------------
2175 //------------------------------------------------------------------
2176   int readAttributes(KeyReqStruct* req_struct,
2177                      const Uint32*  inBuffer,
2178                      Uint32   inBufLen,
2179                      Uint32*  outBuffer,
2180                      Uint32   TmaxRead,
2181                      bool     xfrmFlag);
2182 
2183 //------------------------------------------------------------------
2184 //------------------------------------------------------------------
2185   int updateAttributes(KeyReqStruct *req_struct,
2186                        Uint32*     inBuffer,
2187                        Uint32      inBufLen);
2188 
2189 //------------------------------------------------------------------
2190 //------------------------------------------------------------------
2191   bool readFixedSizeTHOneWordNotNULL(Uint8* outBuffer,
2192                                      KeyReqStruct *req_struct,
2193                                      AttributeHeader* ahOut,
2194                                      Uint32  attrDes2);
2195 
2196 //------------------------------------------------------------------
2197 //------------------------------------------------------------------
2198   bool updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer,
2199                                        KeyReqStruct *req_struct,
2200                                        Uint32  attrDes2);
2201 
2202 //------------------------------------------------------------------
2203 //------------------------------------------------------------------
2204   bool readFixedSizeTHTwoWordNotNULL(Uint8* outBuffer,
2205                                      KeyReqStruct *req_struct,
2206                                      AttributeHeader* ahOut,
2207                                      Uint32  attrDes2);
2208 
2209 //------------------------------------------------------------------
2210 //------------------------------------------------------------------
2211   bool updateFixedSizeTHTwoWordNotNULL(Uint32* inBuffer,
2212                                        KeyReqStruct *req_struct,
2213                                        Uint32  attrDes2);
2214 
2215 //------------------------------------------------------------------
2216 //------------------------------------------------------------------
2217   bool readFixedSizeTHManyWordNotNULL(Uint8* outBuffer,
2218                                       KeyReqStruct *req_struct,
2219                                       AttributeHeader* ahOut,
2220                                       Uint32  attrDes2);
2221 
2222 //------------------------------------------------------------------
2223 //------------------------------------------------------------------
2224   bool fixsize_updater(Uint32* inBuffer,
2225                        KeyReqStruct *req_struct,
2226                        Uint32  attrDes2,
2227                        Uint32 *dst_ptr,
2228                        Uint32 updateOffset,
2229                        Uint32 checkOffset);
2230   bool updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
2231                                         KeyReqStruct *req_struct,
2232                                         Uint32  attrDes2);
2233 
2234 //------------------------------------------------------------------
2235 //------------------------------------------------------------------
2236   bool readFixedSizeTHOneWordNULLable(Uint8* outBuffer,
2237                                       KeyReqStruct *req_struct,
2238                                       AttributeHeader* ahOut,
2239                                       Uint32  attrDes2);
2240 
2241 //------------------------------------------------------------------
2242 //------------------------------------------------------------------
2243   bool updateFixedSizeTHOneWordNULLable(Uint32* inBuffer,
2244                                         KeyReqStruct *req_struct,
2245                                         Uint32  attrDes2);
2246 
2247 //------------------------------------------------------------------
2248 //------------------------------------------------------------------
2249   bool readFixedSizeTHTwoWordNULLable(Uint8* outBuffer,
2250                                       KeyReqStruct *req_struct,
2251                                       AttributeHeader* ahOut,
2252                                       Uint32  attrDes2);
2253 
2254 //------------------------------------------------------------------
2255 //------------------------------------------------------------------
2256   bool updateFixedSizeTHTwoWordNULLable(Uint32* inBuffer,
2257                                         KeyReqStruct *req_struct,
2258                                         Uint32  attrDes2);
2259 
2260 //------------------------------------------------------------------
2261 //------------------------------------------------------------------
2262   bool readFixedSizeTHManyWordNULLable(Uint8* outBuffer,
2263                                        KeyReqStruct *req_struct,
2264                                        AttributeHeader* ahOut,
2265                                        Uint32  attrDes2);
2266 
2267 //------------------------------------------------------------------
2268 //------------------------------------------------------------------
2269   bool readFixedSizeTHZeroWordNULLable(Uint8* outBuffer,
2270                                        KeyReqStruct *req_struct,
2271                                        AttributeHeader* ahOut,
2272                                        Uint32  attrDes2);
2273 //------------------------------------------------------------------
2274 //------------------------------------------------------------------
2275   bool updateFixedSizeTHManyWordNULLable(Uint32* inBuffer,
2276                                          KeyReqStruct *req_struct,
2277                                          Uint32  attrDes2);
2278 
2279 //------------------------------------------------------------------
2280 //------------------------------------------------------------------
2281   bool varsize_reader(Uint8* out_buffer,
2282                       KeyReqStruct *req_struct,
2283                       AttributeHeader* ah_out,
2284                       Uint32  attr_des2,
2285                       const void* src_ptr,
2286                       Uint32 vsize_in_bytes);
2287 
2288   bool xfrm_reader(Uint8* out_buffer,
2289                    KeyReqStruct *req_struct,
2290                    AttributeHeader* ah_out,
2291                    Uint32  attr_des2,
2292                    const void* src_ptr,
2293                    Uint32 srcBytes);
2294 
2295   bool bits_reader(Uint8* out_buffer,
2296                    KeyReqStruct *req_struct,
2297                    AttributeHeader* ah_out,
2298                    const Uint32* bm_ptr, Uint32 bm_len,
2299                    Uint32 bitPos, Uint32 bitCnt);
2300 
2301   bool varsize_updater(Uint32* in_buffer,
2302                        KeyReqStruct *req_struct,
2303                        char *var_data_start,
2304                        Uint32 var_attr_pos,
2305                        Uint16 *len_offset_ptr,
2306                        Uint32 check_offset);
2307 //------------------------------------------------------------------
2308 //------------------------------------------------------------------
2309   bool readVarSizeNotNULL(Uint8* outBuffer,
2310                           KeyReqStruct *req_struct,
2311                           AttributeHeader* ahOut,
2312                           Uint32  attrDes2);
2313 
2314 //------------------------------------------------------------------
2315 //------------------------------------------------------------------
2316   bool updateVarSizeNotNULL(Uint32* inBuffer,
2317                             KeyReqStruct *req_struct,
2318                             Uint32  attrDes2);
2319 
2320 //------------------------------------------------------------------
2321 //------------------------------------------------------------------
2322   bool readVarSizeNULLable(Uint8* outBuffer,
2323                            KeyReqStruct *req_struct,
2324                            AttributeHeader* ahOut,
2325                            Uint32  attrDes2);
2326 
2327 //------------------------------------------------------------------
2328 //------------------------------------------------------------------
2329   bool updateVarSizeNULLable(Uint32* inBuffer,
2330                              KeyReqStruct *req_struct,
2331                              Uint32  attrDes2);
2332 
2333 //------------------------------------------------------------------
2334 //------------------------------------------------------------------
2335   bool readDynFixedSizeNotNULL(Uint8* outBuffer,
2336                                KeyReqStruct *req_struct,
2337                                AttributeHeader* ahOut,
2338                                Uint32  attrDes2);
2339   bool readDynFixedSizeNULLable(Uint8* outBuffer,
2340                                 KeyReqStruct *req_struct,
2341                                 AttributeHeader* ahOut,
2342                                 Uint32  attrDes2);
2343   bool readDynFixedSizeExpandedNotNULL(Uint8* outBuffer,
2344                                        KeyReqStruct *req_struct,
2345                                        AttributeHeader* ahOut,
2346                                        Uint32  attrDes2);
2347   bool readDynFixedSizeShrunkenNotNULL(Uint8* outBuffer,
2348                                        KeyReqStruct *req_struct,
2349                                        AttributeHeader* ahOut,
2350                                        Uint32  attrDes2);
2351   bool readDynFixedSizeExpandedNULLable(Uint8* outBuffer,
2352                                         KeyReqStruct *req_struct,
2353                                         AttributeHeader* ahOut,
2354                                         Uint32  attrDes2);
2355   bool readDynFixedSizeShrunkenNULLable(Uint8* outBuffer,
2356                                         KeyReqStruct *req_struct,
2357                                         AttributeHeader* ahOut,
2358                                         Uint32  attrDes2);
2359 
2360 //------------------------------------------------------------------
2361 //------------------------------------------------------------------
2362   bool updateDynFixedSizeNotNULL(Uint32* inBuffer,
2363                                  KeyReqStruct *req_struct,
2364                                  Uint32  attrDes2);
2365   bool updateDynFixedSizeNULLable(Uint32* inBuffer,
2366                                   KeyReqStruct *req_struct,
2367                                   Uint32  attrDes2);
2368 
2369 //------------------------------------------------------------------
2370 //------------------------------------------------------------------
2371   bool readDynBigFixedSizeNotNULL(Uint8* outBuffer,
2372                                   KeyReqStruct *req_struct,
2373                                   AttributeHeader* ahOut,
2374                                   Uint32  attrDes2);
2375   bool readDynBigFixedSizeNULLable(Uint8* outBuffer,
2376                                    KeyReqStruct *req_struct,
2377                                    AttributeHeader* ahOut,
2378                                    Uint32  attrDes2);
2379   bool readDynBigFixedSizeExpandedNotNULL(Uint8* outBuffer,
2380                                           KeyReqStruct *req_struct,
2381                                           AttributeHeader* ahOut,
2382                                           Uint32  attrDes2);
2383   bool readDynBigFixedSizeShrunkenNotNULL(Uint8* outBuffer,
2384                                           KeyReqStruct *req_struct,
2385                                           AttributeHeader* ahOut,
2386                                           Uint32  attrDes2);
2387   bool readDynBigFixedSizeExpandedNULLable(Uint8* outBuffer,
2388                                            KeyReqStruct *req_struct,
2389                                            AttributeHeader* ahOut,
2390                                            Uint32  attrDes2);
2391   bool readDynBigFixedSizeShrunkenNULLable(Uint8* outBuffer,
2392                                            KeyReqStruct *req_struct,
2393                                            AttributeHeader* ahOut,
2394                                            Uint32  attrDes2);
2395 
2396 //------------------------------------------------------------------
2397 //------------------------------------------------------------------
2398   bool updateDynBigFixedSizeNotNULL(Uint32* inBuffer,
2399                                     KeyReqStruct *req_struct,
2400                                     Uint32  attrDes2);
2401   bool updateDynBigFixedSizeNULLable(Uint32* inBuffer,
2402                                      KeyReqStruct *req_struct,
2403                                      Uint32  attrDes2);
2404 
2405 //------------------------------------------------------------------
2406 //------------------------------------------------------------------
2407   bool readDynBitsNotNULL(Uint8* outBuffer,
2408                           KeyReqStruct *req_struct,
2409                           AttributeHeader* ahOut,
2410                           Uint32  attrDes2);
2411   bool readDynBitsNULLable(Uint8* outBuffer,
2412                            KeyReqStruct *req_struct,
2413                            AttributeHeader* ahOut,
2414                            Uint32  attrDes2);
2415   bool readDynBitsExpandedNotNULL(Uint8* outBuffer,
2416                                   KeyReqStruct *req_struct,
2417                                   AttributeHeader* ahOut,
2418                                   Uint32  attrDes2);
2419   bool readDynBitsShrunkenNotNULL(Uint8* outBuffer,
2420                                   KeyReqStruct *req_struct,
2421                                   AttributeHeader* ahOut,
2422                                   Uint32  attrDes2);
2423   bool readDynBitsExpandedNULLable(Uint8* outBuffer,
2424                                    KeyReqStruct *req_struct,
2425                                    AttributeHeader* ahOut,
2426                                    Uint32  attrDes2);
2427   bool readDynBitsShrunkenNULLable(Uint8* outBuffer,
2428                                    KeyReqStruct *req_struct,
2429                                    AttributeHeader* ahOut,
2430                                    Uint32  attrDes2);
2431 
2432 //------------------------------------------------------------------
2433 //------------------------------------------------------------------
2434   bool updateDynBitsNotNULL(Uint32* inBuffer,
2435                             KeyReqStruct *req_struct,
2436                             Uint32  attrDes2);
2437   bool updateDynBitsNULLable(Uint32* inBuffer,
2438                              KeyReqStruct *req_struct,
2439                              Uint32  attrDes2);
2440 
2441 //------------------------------------------------------------------
2442 //------------------------------------------------------------------
2443   bool readDynVarSizeNotNULL(Uint8* outBuffer,
2444                              KeyReqStruct *req_struct,
2445                              AttributeHeader* ahOut,
2446                              Uint32  attrDes2);
2447   bool readDynVarSizeNULLable(Uint8* outBuffer,
2448                               KeyReqStruct *req_struct,
2449                               AttributeHeader* ahOut,
2450                               Uint32  attrDes2);
2451   bool readDynVarSizeExpandedNotNULL(Uint8* outBuffer,
2452                                      KeyReqStruct *req_struct,
2453                                      AttributeHeader* ahOut,
2454                                      Uint32  attrDes2);
2455   bool readDynVarSizeShrunkenNotNULL(Uint8* outBuffer,
2456                                      KeyReqStruct *req_struct,
2457                                      AttributeHeader* ahOut,
2458                                      Uint32  attrDes2);
2459   bool readDynVarSizeExpandedNULLable(Uint8* outBuffer,
2460                                       KeyReqStruct *req_struct,
2461                                       AttributeHeader* ahOut,
2462                                       Uint32  attrDes2);
2463   bool readDynVarSizeShrunkenNULLable(Uint8* outBuffer,
2464                                       KeyReqStruct *req_struct,
2465                                       AttributeHeader* ahOut,
2466                                       Uint32  attrDes2);
2467 
2468 //------------------------------------------------------------------
2469 //------------------------------------------------------------------
2470   bool updateDynVarSizeNotNULL(Uint32* inBuffer,
2471                                KeyReqStruct *req_struct,
2472                                Uint32  attrDes2);
2473   bool updateDynVarSizeNULLable(Uint32* inBuffer,
2474                                 KeyReqStruct *req_struct,
2475                                 Uint32  attrDes2);
2476 
2477   bool readCharNotNULL(Uint8* outBuffer,
2478                        KeyReqStruct *req_struct,
2479                        AttributeHeader* ahOut,
2480                        Uint32  attrDes2);
2481 
2482   bool readCharNULLable(Uint8* outBuffer,
2483                         KeyReqStruct *req_struct,
2484                         AttributeHeader* ahOut,
2485                         Uint32  attrDes2);
2486 
2487   bool readBitsNULLable(Uint8* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
2488   bool updateBitsNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2489   bool readBitsNotNULL(Uint8* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
2490   bool updateBitsNotNULL(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2491 
2492   bool updateFixedNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2493   bool updateFixedNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2494 
2495   bool updateVarNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2496   bool updateVarNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2497 
2498 
2499   bool readDiskFixedSizeNotNULL(Uint8* outBuffer,
2500 				KeyReqStruct *req_struct,
2501 				AttributeHeader* ahOut,
2502 				Uint32  attrDes2);
2503 
2504   bool readDiskFixedSizeNULLable(Uint8* outBuffer,
2505 				 KeyReqStruct *req_struct,
2506 				 AttributeHeader* ahOut,
2507 				 Uint32  attrDes2);
2508 
2509   bool readDiskVarAsFixedSizeNotNULL(Uint8* outBuffer,
2510 				KeyReqStruct *req_struct,
2511 				AttributeHeader* ahOut,
2512 				Uint32  attrDes2);
2513 
2514   bool readDiskVarAsFixedSizeNULLable(Uint8* outBuffer,
2515 				 KeyReqStruct *req_struct,
2516 				 AttributeHeader* ahOut,
2517 				 Uint32  attrDes2);
2518   bool readDiskVarSizeNULLable(Uint8*, KeyReqStruct*, AttributeHeader*,Uint32);
2519   bool readDiskVarSizeNotNULL(Uint8*, KeyReqStruct*, AttributeHeader*, Uint32);
2520 
2521   bool updateDiskFixedSizeNULLable(Uint32*, KeyReqStruct*, Uint32);
2522   bool updateDiskFixedSizeNotNULL(Uint32*, KeyReqStruct*, Uint32);
2523 
2524   bool updateDiskVarAsFixedSizeNULLable(Uint32*, KeyReqStruct*, Uint32);
2525   bool updateDiskVarAsFixedSizeNotNULL(Uint32*, KeyReqStruct*, Uint32);
2526 
2527   bool updateDiskVarSizeNULLable(Uint32*, KeyReqStruct *, Uint32);
2528   bool updateDiskVarSizeNotNULL(Uint32*, KeyReqStruct *, Uint32);
2529 
2530   bool readDiskBitsNULLable(Uint8*, KeyReqStruct*, AttributeHeader*, Uint32);
2531   bool readDiskBitsNotNULL(Uint8*, KeyReqStruct*, AttributeHeader*, Uint32);
2532   bool updateDiskBitsNULLable(Uint32*, KeyReqStruct*, Uint32);
2533   bool updateDiskBitsNotNULL(Uint32*, KeyReqStruct*, Uint32);
2534 
2535 
2536   /* Alter table methods. */
2537   void handleAlterTablePrepare(Signal *, const AlterTabReq *, const Tablerec *);
2538   void handleAlterTableCommit(Signal *, const AlterTabReq *, Tablerec *);
2539   void handleAlterTableComplete(Signal *, const AlterTabReq *, Tablerec *);
2540   void handleAlterTableAbort(Signal *, const AlterTabReq *, const Tablerec *);
2541   void sendAlterTabRef(Signal *signal, Uint32 errorCode);
2542   void sendAlterTabConf(Signal *, Uint32 clientData=RNIL);
2543 
2544   void handleCharsetPos(Uint32 csNumber, CHARSET_INFO** charsetArray,
2545                         Uint32 noOfCharsets,
2546                         Uint32 & charsetIndex, Uint32 & attrDes2);
2547   Uint32 computeTableMetaData(Tablerec *regTabPtr);
2548 
2549 //------------------------------------------------------------------
2550 //------------------------------------------------------------------
2551   bool nullFlagCheck(KeyReqStruct *req_struct, Uint32  attrDes2);
2552   bool disk_nullFlagCheck(KeyReqStruct *req_struct, Uint32 attrDes2);
2553   int read_pseudo(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
2554   Uint32 read_packed(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
2555   Uint32 update_packed(KeyReqStruct*, const Uint32* src);
2556 
2557   Uint32 read_lcp(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
2558   void update_lcp(KeyReqStruct *req_struct, const Uint32* src, Uint32 len);
2559 
2560   void flush_read_buffer(KeyReqStruct *, const Uint32* outBuf,
2561 			 Uint32 resultRef, Uint32 resultData, Uint32 routeRef);
2562 public:
2563   /**
2564    * Used by Restore...
2565    */
2566   Uint32 read_lcp_keys(Uint32, const Uint32 * src, Uint32 len, Uint32 *dst);
2567 private:
2568 
2569 //------------------------------------------------------------------
2570 //------------------------------------------------------------------
2571   void setUpQueryRoutines(Tablerec* regTabPtr);
2572 
2573 // *****************************************************************
2574 // Service methods.
2575 // *****************************************************************
2576   TransState get_trans_state(Operationrec * const);
2577   void set_trans_state(Operationrec * const, TransState);
2578   TupleState get_tuple_state(Operationrec * const);
2579   void set_tuple_state(Operationrec * const, TupleState);
2580   Uint32 get_frag_page_id(Uint32 real_page_id);
2581   Uint32 get_fix_page_offset(Uint32 page_index, Uint32 tuple_size);
2582 
2583   Uint32 decr_tup_version(Uint32 tuple_version);
2584   void update_change_mask_info(const Tablerec*, ChangeMask* dst, const Uint32*src);
2585   void set_change_mask_info(const Tablerec*, ChangeMask* dst);
2586   void clear_change_mask_info(const Tablerec*, ChangeMask* dst);
2587   void copy_change_mask_info(const Tablerec*, ChangeMask* dst, const ChangeMask * src);
2588   void set_commit_change_mask_info(const Tablerec*,
2589                                    KeyReqStruct*,
2590                                    const Operationrec*);
2591 
2592 //------------------------------------------------------------------
2593 //------------------------------------------------------------------
2594   void copyAttrinfo(Operationrec * regOperPtr, Uint32*  inBuffer,
2595                     Uint32 expectedLen, Uint32 attrInfoIVal);
2596 
2597 //------------------------------------------------------------------
2598 //------------------------------------------------------------------
2599   void initOpConnection(Operationrec* regOperPtr);
2600 
2601 //------------------------------------------------------------------
2602 //------------------------------------------------------------------
2603   void initOperationrec(Signal* signal);
2604 
2605 //------------------------------------------------------------------
2606 //------------------------------------------------------------------
2607   int getStoredProcAttrInfo(Uint32 storedId,
2608                             KeyReqStruct* req_struct,
2609                             Uint32& attrInfoIVal);
2610 
2611 //------------------------------------------------------------------
2612 //------------------------------------------------------------------
2613   bool insertActiveOpList(OperationrecPtr, KeyReqStruct* req_struct);
2614 
2615 //------------------------------------------------------------------
2616 //------------------------------------------------------------------
2617 
2618   int  store_default_record(const TablerecPtr& regTabPtr);
2619   bool  receive_defvalue(Signal* signal, const TablerecPtr& regTabPtr);
2620 //------------------------------------------------------------------
2621 //------------------------------------------------------------------
2622   void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen);
2623 
2624 //------------------------------------------------------------------
2625 // Trigger handling routines
2626 //------------------------------------------------------------------
2627   DLList<TupTriggerData>*
2628   findTriggerList(Tablerec* table,
2629                   TriggerType::Value ttype,
2630                   TriggerActionTime::Value ttime,
2631                   TriggerEvent::Value tevent);
2632 
2633   bool createTrigger(Tablerec*, const CreateTrigImplReq*, const AttributeMask&);
2634 
2635   Uint32 dropTrigger(Tablerec* table,
2636 		     const DropTrigImplReq* req,
2637 		     BlockNumber sender);
2638 
2639   Uint32 getOldTriggerId(const TupTriggerData*, Uint32 op);
2640 
2641   void
2642   checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
2643                                     Operationrec* regOperPtr,
2644                                     Tablerec* tablePtr,
2645                                     bool disk);
2646 
2647   void
2648   checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
2649                                     Operationrec* regOperPtr,
2650                                     Tablerec* tablePtr,
2651                                     bool disk);
2652 
2653   void
2654   checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
2655                                     Operationrec* regOperPtr,
2656                                     Tablerec* tablePtr,
2657                                     bool disk);
2658 
2659   void checkDeferredTriggers(KeyReqStruct *req_struct,
2660                              Operationrec* regOperPtr,
2661                              Tablerec* regTablePtr,
2662                              bool disk);
2663 
2664   void checkDetachedTriggers(KeyReqStruct *req_struct,
2665                              Operationrec* regOperPtr,
2666                              Tablerec* regTablePtr,
2667                              bool disk);
2668 
2669   void fireImmediateTriggers(KeyReqStruct *req_struct,
2670                              DLList<TupTriggerData>& triggerList,
2671                              Operationrec* regOperPtr,
2672                              bool disk);
2673 
2674   void checkDeferredTriggersDuringPrepare(KeyReqStruct *req_struct,
2675                                           DLList<TupTriggerData>& triggerList,
2676                                           Operationrec* const regOperPtr,
2677                                           bool disk);
2678   void fireDeferredTriggers(KeyReqStruct *req_struct,
2679                             DLList<TupTriggerData>& triggerList,
2680                             Operationrec* const regOperPtr,
2681                             bool disk);
2682 
2683   void fireDeferredConstraints(KeyReqStruct *req_struct,
2684                                DLList<TupTriggerData>& triggerList,
2685                                Operationrec* const regOperPtr,
2686                                bool disk);
2687 
2688   void fireDetachedTriggers(KeyReqStruct *req_struct,
2689                             DLList<TupTriggerData>& triggerList,
2690                             Operationrec* regOperPtr,
2691                             bool disk);
2692 
2693   void executeTriggers(KeyReqStruct *req_struct,
2694                        DLList<TupTriggerData>& triggerList,
2695                        Operationrec* regOperPtr,
2696                        bool disk);
2697 
2698   void executeTrigger(KeyReqStruct *req_struct,
2699                       TupTriggerData* trigPtr,
2700                       Operationrec* regOperPtr,
2701                       bool disk);
2702 
2703   bool check_fire_trigger(const Fragrecord*,
2704                           const TupTriggerData*,
2705                           const KeyReqStruct*,
2706                           const Operationrec*) const;
2707 
2708   bool check_fire_reorg(const KeyReqStruct *, Fragrecord::FragState) const;
2709   bool check_fire_suma(const KeyReqStruct *,
2710                        const Operationrec*,
2711                        const Fragrecord*) const;
2712 
2713   bool readTriggerInfo(TupTriggerData* trigPtr,
2714                        Operationrec* regOperPtr,
2715                        KeyReqStruct * req_struct,
2716                        Fragrecord* regFragPtr,
2717                        Uint32* keyBuffer,
2718                        Uint32& noPrimKey,
2719                        Uint32* afterBuffer,
2720                        Uint32& noAfterWords,
2721                        Uint32* beforeBuffer,
2722                        Uint32& noBeforeWords,
2723                        bool disk);
2724 
2725   void sendTrigAttrInfo(Signal*        signal,
2726                         Uint32*        data,
2727                         Uint32         dataLen,
2728                         bool           executeDirect,
2729                         BlockReference receiverReference);
2730 
2731   Uint32 setAttrIds(Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask,
2732                     Uint32 noOfAttributes,
2733                     Uint32* inBuffer);
2734 
2735   bool primaryKey(Tablerec* const, Uint32);
2736 
2737   // these set terrorCode and return non-zero on error
2738 
2739   int executeTuxInsertTriggers(Signal* signal,
2740                                Operationrec* regOperPtr,
2741                                Fragrecord* regFragPtr,
2742                                Tablerec* regTabPtr);
2743 
2744   int executeTuxUpdateTriggers(Signal* signal,
2745                                Operationrec* regOperPtr,
2746                                Fragrecord* regFragPtr,
2747                                Tablerec* regTabPtr);
2748 
2749   int executeTuxDeleteTriggers(Signal* signal,
2750                                Operationrec* regOperPtr,
2751                                Fragrecord* regFragPtr,
2752                                Tablerec* regTabPtr);
2753 
2754   int addTuxEntries(Signal* signal,
2755                     Operationrec* regOperPtr,
2756                     Tablerec* regTabPtr);
2757 
2758   // these crash the node on error
2759 
2760   void executeTuxCommitTriggers(Signal* signal,
2761                                 Operationrec* regOperPtr,
2762                                 Fragrecord* regFragPtr,
2763                                 Tablerec* regTabPtr);
2764 
2765   void executeTuxAbortTriggers(Signal* signal,
2766                                Operationrec* regOperPtr,
2767                                Fragrecord* regFragPtr,
2768                                Tablerec* regTabPtr);
2769 
2770   void removeTuxEntries(Signal* signal,
2771                         Tablerec* regTabPtr);
2772 
2773   void ndbmtd_buffer_suma_trigger(Signal* signal, Uint32 len,
2774                                   LinearSectionPtr ptr[]);
2775   void flush_ndbmtd_suma_buffer(Signal*);
2776 
2777   struct SumaTriggerBuffer
2778   {
SumaTriggerBufferDbtup::SumaTriggerBuffer2779     SumaTriggerBuffer() { m_out_of_memory = 0;m_pageId = RNIL; m_freeWords = 0;}
2780     Uint32 m_out_of_memory;
2781     Uint32 m_pageId;
2782     Uint32 m_freeWords;
2783   } m_suma_trigger_buffer;
2784 
2785 // *****************************************************************
2786 // Error Handling routines.
2787 // *****************************************************************
2788 //------------------------------------------------------------------
2789 //------------------------------------------------------------------
2790   int TUPKEY_abort(KeyReqStruct*, int error_type);
2791 
2792 //------------------------------------------------------------------
2793 //------------------------------------------------------------------
2794   void tupkeyErrorLab(KeyReqStruct*);
2795   void do_tup_abortreq(Signal*, Uint32 flags);
2796   bool do_tup_abort_operation(Signal*, Tuple_header *,
2797                               Operationrec*,
2798                               Fragrecord*,
2799                               Tablerec*);
2800 
2801 //------------------------------------------------------------------
2802 //------------------------------------------------------------------
2803 // Methods to handle execution of TUP_COMMITREQ + TUP_ABORTREQ.
2804 //
2805 // Module Transaction Manager
2806 //
2807 // The Transaction Manager module is responsible for the commit
2808 // and abort of operations started by the Execution Manager.
2809 //
2810 // Commit Operation:
2811 // ----------------
2812 //
2813 // Failures in commit processing is not allowed since that would
2814 // leave the database in an unreliable state. Thus the only way
2815 // to handle failures in commit processing is to crash the node.
2816 //
2817 // TUP_COMMITREQ can only be received in the wait state after a
2818 // successful TUPKEYREQ which was not a read operation.
2819 //
2820 // Commit of Delete:
2821 // -----------------
2822 //
2823 // This will actually perform the deletion of the record unless
2824 // other operations also are connected to the record. In this case
2825 // we will set the delete state on the record that becomes the ownerd
2826 // of the record.
2827 //
2828 // Commit of Update:
2829 // ----------------
2830 //
2831 // We will release the copy record where the original record was kept.
2832 // Also here we will take special care if more operations are updating
2833 // the record simultaneously.
2834 //
2835 // Commit of Insert:
2836 // -----------------
2837 //
2838 // Will simply reset the state of the operation record.
2839 //
2840 // Signal Diagram:
2841 // --->  TUP_COMMITREQ (from LQH)
2842 // <---- TUP_COMMITCONF (to LQH)
2843 //
2844 //
2845 // Abort Operation:
2846 // ----------------
2847 //
2848 // Signal Diagram:
2849 // --->  TUP_ABORTREQ (from LQH)
2850 // <---- TUP_ABORTCONF (to LQH)
2851 //
2852 // Failures in abort processing is not allowed since that would
2853 // leave the database in an unreliable state. Thus the only way
2854 // to handle failures in abort processing is to crash the node.
2855 //
2856 // Abort messages can arrive at any time. It can arrive even before
2857 // anything at all have arrived of the operation. It can arrive after
2858 // receiving a number of ATTRINFO but before TUPKEYREQ has been received.
2859 // It must arrive after that we sent TUPKEYREF in response to TUPKEYREQ
2860 // and finally it can arrive after successfully performing the TUPKEYREQ
2861 // in all cases including the read case.
2862 //------------------------------------------------------------------
2863 //------------------------------------------------------------------
2864 
2865 #if 0
2866   void checkPages(Fragrecord* regFragPtr);
2867 #endif
convert_byte_to_word_size(Uint32 byte_size)2868   Uint32 convert_byte_to_word_size(Uint32 byte_size)
2869   {
2870     return ((byte_size + 3) >> 2);
2871   }
convert_bit_to_word_size(Uint32 bit_size)2872   Uint32 convert_bit_to_word_size(Uint32 bit_size)
2873   {
2874     return ((bit_size + 31) >> 5);
2875   }
2876 
2877   void prepare_initial_insert(KeyReqStruct*, Operationrec*, Tablerec*);
2878   void fix_disk_insert_no_mem_insert(KeyReqStruct*, Operationrec*, Tablerec*);
2879   void setup_fixed_part(KeyReqStruct* req_struct,
2880 			Operationrec* regOperPtr,
2881 			Tablerec* regTabPtr);
2882 
2883   void send_TUPKEYREF(Signal* signal,
2884                       Operationrec* regOperPtr);
2885   void early_tupkey_error(KeyReqStruct*);
2886 
2887   void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit);
2888 
2889   bool checkUpdateOfPrimaryKey(KeyReqStruct *req_struct,
2890                                Uint32* updateBuffer,
2891                                Tablerec* regTabPtr);
2892 
2893   void setNullBits(Uint32*, Tablerec* regTabPtr);
2894   bool checkNullAttributes(KeyReqStruct * const, Tablerec* const);
2895   bool find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId);
2896   bool setup_read(KeyReqStruct* req_struct,
2897 		  Operationrec* regOperPtr,
2898 		  Fragrecord* regFragPtr,
2899 		  Tablerec* regTabPtr,
2900 		  bool disk);
2901 
2902   Uint32 calculateChecksum(Tuple_header*, Tablerec* regTabPtr);
2903   void setChecksum(Tuple_header*, Tablerec* regTabPtr);
2904 
2905   void complexTrigger(Signal* signal,
2906                       KeyReqStruct *req_struct,
2907                       Operationrec* regOperPtr,
2908                       Fragrecord* regFragPtr,
2909                       Tablerec* regTabPtr);
2910 
2911   void setTupleStatesSetOpType(Operationrec* regOperPtr,
2912                                KeyReqStruct *req_struct,
2913                                Page* pagePtr,
2914                                Uint32& opType,
2915                                OperationrecPtr& firstOpPtr);
2916 
2917   void findBeforeValueOperation(OperationrecPtr& befOpPtr,
2918                                 OperationrecPtr firstOpPtr);
2919 
2920   void updateGcpId(KeyReqStruct *req_struct,
2921                    Operationrec* regOperPtr,
2922                    Fragrecord* regFragPtr,
2923                    Tablerec* regTabPtr);
2924 
2925   void setTupleStateOnPreviousOps(Uint32 prevOpIndex);
2926   void copyMem(Signal* signal, Uint32 sourceIndex, Uint32 destIndex);
2927 
2928   void removeActiveOpList(Operationrec*  const regOperPtr, Tuple_header*);
2929 
2930   void updatePackedList(Signal* signal, Uint16 ahostIndex);
2931 
2932   void setUpDescriptorReferences(Uint32 descriptorReference,
2933                                  Tablerec* regTabPtr,
2934                                  const Uint32* offset);
2935   void setupDynDescriptorReferences(Uint32 dynDescr,
2936                                     Tablerec* const regTabPtr,
2937                                     const Uint32* offset,
2938                                     Uint32 ind=0);
2939   void setUpKeyArray(Tablerec* regTabPtr);
2940   bool addfragtotab(Tablerec* regTabPtr, Uint32 fragId, Uint32 fragIndex);
2941   void deleteFragTab(Tablerec* regTabPtr, Uint32 fragId);
2942   void abortAddFragOp(Signal* signal);
2943   void releaseTabDescr(Tablerec* regTabPtr);
2944   void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* regTabPtr);
2945 
2946   void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32);
2947   void initializeCheckpointInfoRec();
2948   void initializeDiskBufferSegmentRecord();
2949   void initializeFragoperrec();
2950   void initializeFragrecord();
2951   void initializeAlterTabOperation();
2952   void initializeHostBuffer();
2953   void initializeLocalLogInfo();
2954   void initializeOperationrec();
2955   void initializePendingFileOpenInfoRecord();
2956   void initializeRestartInfoRec();
2957   void initializeTablerec();
2958   void initializeTabDescr();
2959   void initializeUndoPage();
2960   void initializeDefaultValuesFrag();
2961 
2962   void initTab(Tablerec* regTabPtr);
2963 
2964   void startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2);
2965 
2966   void fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr);
2967   void fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr);
2968   void fragrefuse2Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr);
2969   void fragrefuse3Lab(Signal* signal,
2970                       FragoperrecPtr fragOperPtr,
2971                       FragrecordPtr regFragPtr,
2972                       Tablerec* regTabPtr,
2973                       Uint32 fragId);
2974   void fragrefuse4Lab(Signal* signal,
2975                       FragoperrecPtr fragOperPtr,
2976                       FragrecordPtr regFragPtr,
2977                       Tablerec* regTabPtr,
2978                       Uint32 fragId);
2979   void addattrrefuseLab(Signal* signal,
2980                         FragrecordPtr regFragPtr,
2981                         FragoperrecPtr fragOperPtr,
2982                         Tablerec* regTabPtr,
2983                         Uint32 fragId);
2984 
2985   void releaseFragment(Signal*, Uint32, Uint32);
2986   void drop_fragment_free_var_pages(Signal*);
2987   void drop_fragment_free_pages(Signal*);
2988   void drop_fragment_free_extent(Signal*, TablerecPtr, FragrecordPtr, Uint32);
2989   void drop_fragment_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
2990   void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32);
2991   void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32);
2992   void drop_fragment_fsremove(Signal*, TablerecPtr, FragrecordPtr);
2993   void drop_fragment_fsremove_done(Signal*, TablerecPtr, FragrecordPtr);
2994 
2995   // Initialisation
2996   void initData();
2997   void initRecords();
2998 
2999   // 2 words for optional GCI64 + AUTHOR info
3000 #define EXTRA_COPY_PROC_WORDS 2
3001 #define MAX_COPY_PROC_LEN (MAX_ATTRIBUTES_IN_TABLE + EXTRA_COPY_PROC_WORDS)
3002 
3003 
3004   void deleteScanProcedure(Signal* signal, Operationrec* regOperPtr);
3005   void allocCopyProcedure();
3006   void freeCopyProcedure();
3007   void prepareCopyProcedure(Uint32 numAttrs, Uint16 tableBits);
3008   void releaseCopyProcedure();
3009   void copyProcedure(Signal* signal,
3010                      TablerecPtr regTabPtr,
3011                      Operationrec* regOperPtr);
3012   void scanProcedure(Signal* signal,
3013                      Operationrec* regOperPtr,
3014                      SectionHandle* handle,
3015                      bool isCopy);
3016   void storedProcBufferSeizeErrorLab(Signal* signal,
3017                                      Operationrec* regOperPtr,
3018                                      Uint32 storedProcPtr,
3019                                      Uint32 errorCode);
3020 
3021 //-----------------------------------------------------------------------------
3022 // Table Descriptor Memory Manager
3023 //-----------------------------------------------------------------------------
3024 
3025 // Public methods
3026   Uint32 getTabDescrOffsets(Uint32, Uint32, Uint32, Uint32, Uint32*);
3027   Uint32 getDynTabDescrOffsets(Uint32 MaskSize, Uint32* offset);
3028   Uint32 allocTabDescr(Uint32 allocSize);
3029   void releaseTabDescr(Uint32 desc);
3030 
3031   void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
3032   Uint32 getTabDescrWord(Uint32 index);
3033   void setTabDescrWord(Uint32 index, Uint32 word);
3034 
3035 // Private methods
3036   Uint32 sizeOfReadFunction();
3037   void   removeTdArea(Uint32 tabDesRef, Uint32 list);
3038   void   insertTdArea(Uint32 tabDesRef, Uint32 list);
3039   void   itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
3040 #if defined VM_TRACE || defined ERROR_INSERT
3041   void verifytabdes();
3042 #endif
3043 
3044   void seizeOpRec(OperationrecPtr& regOperPtr);
3045   void seizeFragrecord(FragrecordPtr& regFragPtr);
3046   void seizeFragoperrec(FragoperrecPtr& fragOperPtr);
3047   void seizeAlterTabOperation(AlterTabOperationPtr& alterTabOpPtr);
3048   void releaseFragoperrec(FragoperrecPtr fragOperPtr);
3049   void releaseFragrec(FragrecordPtr);
3050   void releaseAlterTabOpRec(AlterTabOperationPtr regAlterTabOpPtr);
3051 
3052 //----------------------------------------------------------------------------
3053 // Page Memory Manager
3054 //----------------------------------------------------------------------------
3055 
3056 // Public methods
3057   void allocConsPages(Uint32 noOfPagesToAllocate,
3058                       Uint32& noOfPagesAllocated,
3059                       Uint32& allocPageRef);
3060   void returnCommonArea(Uint32 retPageRef, Uint32 retNo);
3061   void initializePage();
3062 
3063   Uint32 nextHigherTwoLog(Uint32 input);
3064 
3065   Uint32 m_pages_allocated;
3066   Uint32 m_pages_allocated_max;
3067 
3068 //------------------------------------------------------------------------------------------------------
3069 // Page Mapper, convert logical page id's to physical page id's
3070 // The page mapper also handles the pages allocated to the fragment.
3071 //------------------------------------------------------------------------------------------------------
3072 //
3073 // Public methods
3074   Uint32 getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId);
3075   Uint32 getRealpidCheck(Fragrecord* regFragPtr, Uint32 logicalPageId);
3076   Uint32 getNoOfPages(Fragrecord* regFragPtr);
3077   Uint32 getEmptyPage(Fragrecord* regFragPtr);
3078   Uint32 allocFragPage(Uint32 * err, Fragrecord* regFragPtr);
3079   Uint32 allocFragPage(Uint32 * err, Tablerec*, Fragrecord*, Uint32 page_no);
3080   void releaseFragPage(Fragrecord* regFragPtr, Uint32 logicalPageId, PagePtr);
3081   void rebuild_page_free_list(Signal*);
3082   Uint32 get_empty_var_page(Fragrecord* frag_ptr);
3083   void init_page(Fragrecord*, PagePtr, Uint32 page_no);
3084 
3085 // Private methods
3086   void errorHandler(Uint32 errorCode);
3087 
3088 //---------------------------------------------------------------
3089 // Variable Allocator
3090 // Allocates and deallocates tuples of fixed size on a fragment.
3091 //---------------------------------------------------------------
3092 //
3093 // Public methods
3094 
3095   void init_list_sizes(void);
3096 
3097 // Private methods
3098 
3099   Uint32 get_alloc_page(Fragrecord* const, Uint32);
3100   void update_free_page_list(Fragrecord* const, Ptr<Page>);
3101 
3102 #if 0
3103   Uint32 calc_free_list(const Tablerec* regTabPtr, Uint32 sz) const {
3104     return regTabPtr->m_disk_alloc_info.calc_page_free_bits(sz);
3105   }
3106 #endif
3107 
3108   Uint32 calculate_free_list_impl(Uint32) const ;
3109   Uint64 calculate_used_var_words(Fragrecord* fragPtr);
3110   void remove_free_page(Fragrecord*, Var_page*, Uint32);
3111   void insert_free_page(Fragrecord*, Var_page*, Uint32);
3112 
3113 //---------------------------------------------------------------
3114 // Fixed Allocator
3115 // Allocates and deallocates tuples of fixed size on a fragment.
3116 //---------------------------------------------------------------
3117 //
3118 // Public methods
3119   Uint32* alloc_var_rec(Uint32 * err,
3120                         Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
3121   void free_var_rec(Fragrecord*, Tablerec*, Local_key*, Ptr<Page>);
3122   void free_var_part(Fragrecord*, Tablerec*, Local_key*);
3123   Uint32* alloc_var_part(Uint32*err,Fragrecord*, Tablerec*, Uint32, Local_key*);
3124   Uint32 *realloc_var_part(Uint32 * err, Fragrecord*, Tablerec*,
3125                            PagePtr, Var_part_ref*, Uint32, Uint32);
3126 
3127   void move_var_part(Fragrecord* fragPtr, Tablerec* tabPtr, PagePtr pagePtr,
3128                      Var_part_ref* refptr, Uint32 size);
3129 
3130   void free_var_part(Fragrecord* fragPtr, PagePtr pagePtr, Uint32 page_idx);
3131 
3132   void validate_page(Tablerec*, Var_page* page);
3133 
3134   Uint32* alloc_fix_rec(Uint32 * err,
3135                         Fragrecord*const, Tablerec*const, Local_key*,
3136                         Uint32*);
3137   void free_fix_rec(Fragrecord*, Tablerec*, Local_key*, Fix_page*);
3138 
3139   Uint32* alloc_fix_rowid(Uint32 * err,
3140                           Fragrecord*, Tablerec*, Local_key*, Uint32 *);
3141   Uint32* alloc_var_rowid(Uint32 * err,
3142                           Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
3143 // Private methods
3144   void convertThPage(Fix_page* regPagePtr,
3145 		     Tablerec*,
3146 		     Uint32 mm);
3147 
3148   /**
3149    * Return offset
3150    */
3151   Uint32 alloc_tuple_from_page(Fragrecord* regFragPtr,
3152 			       Fix_page* regPagePtr);
3153 
3154 //---------------------------------------------------------------
3155 // Temporary variables used for storing commonly used variables
3156 // in certain modules
3157 //---------------------------------------------------------------
3158 
3159   Uint32 c_lcp_scan_op;
3160 
3161 // readAttributes and updateAttributes module
3162 //------------------------------------------------------------------------------------------------------
3163 // Common stored variables. Variables that have a valid value always.
3164 //------------------------------------------------------------------------------------------------------
3165   Fragoperrec *fragoperrec;
3166   Uint32 cfirstfreeFragopr;
3167   Uint32 cnoOfFragoprec;
3168   RSS_OP_COUNTER(cnoOfFreeFragoprec);
3169   RSS_OP_SNAPSHOT(cnoOfFreeFragoprec);
3170 
3171   Fragrecord *fragrecord;
3172   Uint32 cfirstfreefrag;
3173   Uint32 cnoOfFragrec;
3174   RSS_OP_COUNTER(cnoOfFreeFragrec);
3175   RSS_OP_SNAPSHOT(cnoOfFreeFragrec);
3176   /*
3177    * DefaultValuesFragment is a normal struct Fragrecord.
3178    * It is TUP block-variable.
3179    * There is only ONE DefaultValuesFragment shared
3180    * among all table fragments stored by this TUP block.
3181   */
3182   FragrecordPtr DefaultValuesFragment;
3183   RSS_OP_SNAPSHOT(defaultValueWordsHi);
3184   RSS_OP_SNAPSHOT(defaultValueWordsLo);
3185 
3186   AlterTabOperation *alterTabOperRec;
3187   Uint32 cfirstfreeAlterTabOp;
3188   Uint32 cnoOfAlterTabOps;
3189 
3190   HostBuffer *hostBuffer;
3191 
3192   NdbMutex c_page_map_pool_mutex;
3193   DynArr256Pool c_page_map_pool;
3194   ArrayPool<Operationrec> c_operation_pool;
3195 
3196   ArrayPool<Page> c_page_pool;
3197 
3198   /* read ahead in pages during disk order scan */
3199   Uint32 m_max_page_read_ahead;
3200 
3201   Tablerec *tablerec;
3202   Uint32 cnoOfTablerec;
3203 
3204   TableDescriptor *tableDescriptor;
3205   Uint32 cnoOfTabDescrRec;
3206   RSS_OP_COUNTER(cnoOfFreeTabDescrRec);
3207   RSS_OP_SNAPSHOT(cnoOfFreeTabDescrRec);
3208 
3209   Uint32 cdata[32];
3210   Uint32 cdataPages[16];
3211   Uint32 cpackedListIndex;
3212   Uint32 cpackedList[MAX_NODES];
3213   Uint32 cfreeTdList[16];
3214   Uint32 clastBitMask;
3215   Uint32 clblPageCounter;
3216   Uint32 clblPagesPerTick;
3217   Uint32 clblPagesPerTickAfterSr;
3218   BlockReference clqhBlockref;
3219   Uint32 clqhUserpointer;
3220   Uint32 cminusOne;
3221   BlockReference cndbcntrRef;
3222   BlockReference cownref;
3223   Uint32 cownNodeId;
3224   Uint32 czero;
3225   Uint32 cCopyProcedure;
3226   Uint32 cCopyLastSeg;
3227   Uint32 cCopyOverwrite;
3228   Uint32 cCopyOverwriteLen;
3229 
3230  // A little bit bigger to cover overwrites in copy algorithms (16384 real size).
3231 #define ZATTR_BUFFER_SIZE 16384
3232   Uint32 clogMemBuffer[ZATTR_BUFFER_SIZE + 16];
3233   Uint32 coutBuffer[ZATTR_BUFFER_SIZE + 16];
3234   Uint32 cinBuffer[ZATTR_BUFFER_SIZE + 16];
3235   Uint32 ctemp_page[ZWORDS_ON_PAGE];
3236   Uint32 ctemp_var_record[ZWORDS_ON_PAGE];
3237 
3238   // Trigger variables
3239   Uint32 c_maxTriggersPerTable;
3240 
3241   Uint32 m_max_parallel_index_build;
3242 
3243   Uint32 c_errorInsert4000TableId;
3244   Uint32 c_min_list_size[MAX_FREE_LIST + 1];
3245   Uint32 c_max_list_size[MAX_FREE_LIST + 1];
3246 
3247   void initGlobalTemporaryVars();
3248   void reportMemoryUsage(Signal* signal, int incDec);
3249 
3250 
3251 #ifdef VM_TRACE
3252   struct Th {
3253     Uint32 data[1];
3254   };
3255   friend class NdbOut& operator<<(NdbOut&, const Operationrec&);
3256   friend class NdbOut& operator<<(NdbOut&, const Th&);
3257 #endif
3258 
3259   void expand_tuple(KeyReqStruct*, Uint32 sizes[4], Tuple_header*org,
3260 		    const Tablerec*, bool disk);
3261   void shrink_tuple(KeyReqStruct*, Uint32 sizes[2], const Tablerec*,
3262 		    bool disk);
3263 
3264   Uint32* get_ptr(Var_part_ref);
3265   Uint32* get_ptr(PagePtr*, Var_part_ref);
3266   Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
3267   Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
3268   Uint32* get_default_ptr(const Tablerec*, Uint32&);
3269   Uint32 get_len(Ptr<Page>* pagePtr, Var_part_ref ref);
3270 
3271   STATIC_CONST( COPY_TUPLE_HEADER32 = 4 );
3272 
alloc_copy_tuple(const Tablerec * tabPtrP,Local_key * ptr)3273   Tuple_header* alloc_copy_tuple(const Tablerec* tabPtrP, Local_key* ptr){
3274     Uint32 * dst = c_undo_buffer.alloc_copy_tuple(ptr,
3275                                                   tabPtrP->total_rec_size);
3276     if (unlikely(dst == 0))
3277       return 0;
3278 #ifdef HAVE_purify
3279     bzero(dst, tabPtrP->total_rec_size);
3280 #endif
3281     Uint32 count = tabPtrP->m_no_of_attributes;
3282     ChangeMask * mask = (ChangeMask*)(dst + COPY_TUPLE_HEADER32);
3283     mask->m_cols = count;
3284     return (Tuple_header*)(mask->end_of_mask(count));
3285   }
3286 
get_copy_tuple_raw(const Local_key * ptr)3287   Uint32 * get_copy_tuple_raw(const Local_key* ptr) {
3288     return c_undo_buffer.get_ptr(ptr);
3289   }
3290 
get_copy_tuple(Uint32 * rawptr)3291   Tuple_header * get_copy_tuple(Uint32 * rawptr) {
3292     return (Tuple_header*)
3293       (get_change_mask_ptr(rawptr)->end_of_mask());
3294   }
3295 
get_change_mask_ptr(Uint32 * rawptr)3296   ChangeMask * get_change_mask_ptr(Uint32 * rawptr) {
3297     return (ChangeMask*)(rawptr + COPY_TUPLE_HEADER32);
3298   }
3299 
get_copy_tuple(const Local_key * ptr)3300   Tuple_header* get_copy_tuple(const Local_key* ptr){
3301     return get_copy_tuple(get_copy_tuple_raw(ptr));
3302   }
3303 
get_change_mask_ptr(const Tablerec * tabP,Tuple_header * copytuple)3304   ChangeMask* get_change_mask_ptr(const Tablerec* tabP,Tuple_header* copytuple){
3305     Uint32 * raw = (Uint32*)copytuple;
3306     Uint32 * tmp = raw - (1 + ((tabP->m_no_of_attributes + 31) >> 5));
3307     ChangeMask* mask = (ChangeMask*)tmp;
3308     assert(mask->end_of_mask() == raw);
3309     assert(get_copy_tuple(tmp - COPY_TUPLE_HEADER32) == copytuple);
3310     return mask;
3311   }
3312 
3313   /**
3314    * prealloc space from disk
3315    *   key.m_file_no  contains file no
3316    *   key.m_page_no  contains disk page
3317    *   key.m_page_idx contains byte preallocated
3318    */
3319   int disk_page_prealloc(Signal*, Ptr<Fragrecord>, Local_key*, Uint32);
3320   void disk_page_prealloc_dirty_page(Disk_alloc_info&,
3321 				     Ptr<Page>, Uint32, Uint32);
3322   void disk_page_prealloc_transit_page(Disk_alloc_info&,
3323 				       Ptr<Page_request>, Uint32, Uint32);
3324 
3325   void disk_page_abort_prealloc(Signal*, Fragrecord*,Local_key*, Uint32);
3326   void disk_page_abort_prealloc_callback(Signal*, Uint32, Uint32);
3327   void disk_page_abort_prealloc_callback_1(Signal*, Fragrecord*,
3328 					   PagePtr, Uint32);
3329 
3330   void disk_page_prealloc_callback(Signal*, Uint32, Uint32);
3331   void disk_page_prealloc_initial_callback(Signal*, Uint32, Uint32);
3332   void disk_page_prealloc_callback_common(Signal*,
3333 					  Ptr<Page_request>,
3334 					  Ptr<Fragrecord>,
3335 					  Ptr<Page>);
3336 
3337   void disk_page_alloc(Signal*,
3338 		       Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
3339   void disk_page_free(Signal*,
3340 		      Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
3341 
3342   void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);
3343 
3344   void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32);
3345 
3346   void disk_page_alloc_extent_log_buffer_callback(Signal*, Uint32, Uint32);
3347   void disk_page_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
3348 
3349   Uint64 disk_page_undo_alloc(Page*, const Local_key*,
3350 			      Uint32 sz, Uint32 gci, Uint32 logfile_group_id);
3351 
3352   Uint64 disk_page_undo_update(Page*, const Local_key*,
3353 			       const Uint32*, Uint32,
3354 			       Uint32 gci, Uint32 logfile_group_id);
3355 
3356   Uint64 disk_page_undo_free(Page*, const Local_key*,
3357 			     const Uint32*, Uint32 sz,
3358 			     Uint32 gci, Uint32 logfile_group_id);
3359 
3360   void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused);
3361   void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
3362 
3363   void drop_table_log_buffer_callback(Signal*, Uint32, Uint32);
3364   void drop_table_logsync_callback(Signal*, Uint32, Uint32);
3365 
3366   void disk_page_set_dirty(Ptr<Page>);
3367   void restart_setup_page(Disk_alloc_info&, Ptr<Page>, Int32 estimate);
3368   void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>, Int32 delta);
3369 
3370   void disk_page_move_page_request(Disk_alloc_info& alloc,
3371                                    Ptr<Extent_info>,
3372                                    Ptr<Page_request> req,
3373                                    Uint32 old_idx, Uint32 new_idx);
3374 
3375   void disk_page_move_dirty_page(Disk_alloc_info& alloc,
3376                                  Ptr<Extent_info> extentPtr,
3377                                  Ptr<Page> pagePtr,
3378                                  Uint32 old_idx, Uint32 new_idx);
3379 
3380   void disk_page_get_allocated(const Tablerec*, const Fragrecord*,
3381                                Uint64 res[2]);
3382   /**
3383    * Disk restart code
3384    */
3385 public:
3386   int disk_page_load_hook(Uint32 page_id);
3387 
3388   void disk_page_unmap_callback(Uint32 when, Uint32 page, Uint32 dirty_count);
3389 
3390   int disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
3391 				const Local_key* key, Uint32 pages);
3392   void disk_restart_page_bits(Uint32 tableId, Uint32 fragId,
3393 			      const Local_key*, Uint32 bits);
3394   void disk_restart_undo(Signal* signal, Uint64 lsn,
3395 			 Uint32 type, const Uint32 * ptr, Uint32 len);
3396 
3397   struct Apply_undo
3398   {
3399     Uint32 m_type, m_len;
3400     const Uint32* m_ptr;
3401     Uint64 m_lsn;
3402     Ptr<Tablerec> m_table_ptr;
3403     Ptr<Fragrecord> m_fragment_ptr;
3404     Ptr<Page> m_page_ptr;
3405     Ptr<Extent_info> m_extent_ptr;
3406     Local_key m_key;
3407     Apply_undo();
3408   };
3409 
3410   void disk_restart_lcp_id(Uint32 table, Uint32 frag, Uint32 lcpId);
3411 
3412 private:
3413   // these 2 were file-static before mt-lqh
3414   bool f_undo_done;
3415   Dbtup::Apply_undo f_undo;
3416   Uint32 c_proxy_undo_data[20 + MAX_TUPLE_SIZE_IN_WORDS];
3417 
3418   void disk_restart_undo_next(Signal*);
3419   void disk_restart_undo_lcp(Uint32, Uint32, Uint32 flag, Uint32 lcpId);
3420   void disk_restart_undo_callback(Signal* signal, Uint32, Uint32);
3421   void disk_restart_undo_alloc(Apply_undo*);
3422   void disk_restart_undo_update(Apply_undo*);
3423   void disk_restart_undo_free(Apply_undo*);
3424   void disk_restart_undo_page_bits(Signal*, Apply_undo*);
3425 
3426 #ifdef VM_TRACE
3427   void verify_page_lists(Disk_alloc_info&);
3428 #else
verify_page_lists(Disk_alloc_info &)3429   void verify_page_lists(Disk_alloc_info&) {}
3430 #endif
3431 
3432   void findFirstOp(OperationrecPtr&);
3433   bool is_rowid_lcp_scanned(const Local_key& key1,
3434                            const Dbtup::ScanOp& op);
3435   void commit_operation(Signal*, Uint32, Uint32, Tuple_header*, PagePtr,
3436 			Operationrec*, Fragrecord*, Tablerec*);
3437   void commit_refresh(Signal*, Uint32, Uint32, Tuple_header*, PagePtr,
3438                       KeyReqStruct*, Operationrec*, Fragrecord*, Tablerec*);
3439   int retrieve_data_page(Signal*,
3440                          Page_cache_client::Request,
3441                          OperationrecPtr);
3442   int retrieve_log_page(Signal*, FragrecordPtr, OperationrecPtr);
3443 
3444   void dealloc_tuple(Signal* signal, Uint32, Uint32, Page*, Tuple_header*,
3445 		     KeyReqStruct*, Operationrec*, Fragrecord*, Tablerec*);
3446   bool store_extra_row_bits(Uint32, const Tablerec*, Tuple_header*, Uint32,
3447                             bool);
3448   void read_extra_row_bits(Uint32, const Tablerec*, Tuple_header*, Uint32 *,
3449                            bool);
3450 
3451   int handle_size_change_after_update(KeyReqStruct* req_struct,
3452 				      Tuple_header* org,
3453 				      Operationrec*,
3454 				      Fragrecord* regFragPtr,
3455 				      Tablerec* regTabPtr,
3456 				      Uint32 sizes[4]);
3457   int optimize_var_part(KeyReqStruct* req_struct,
3458                         Tuple_header* org,
3459                         Operationrec* regOperPtr,
3460                         Fragrecord* regFragPtr,
3461                         Tablerec* regTabPtr);
3462 
3463   /**
3464    * Setup all pointer on keyreqstruct to prepare for read
3465    *   req_struct->m_tuple_ptr is set to tuple to read
3466    */
3467   void prepare_read(KeyReqStruct*, Tablerec* const, bool disk);
3468 
3469   /* For debugging, dump the contents of a tuple. */
3470   void dump_tuple(const KeyReqStruct* req_struct, const Tablerec* tabPtrP);
3471 
3472 #ifdef VM_TRACE
3473   void check_page_map(Fragrecord*);
3474   bool find_page_id_in_list(Fragrecord*, Uint32 pid);
3475 #endif
3476   void handle_lcp_keep(Signal*, Fragrecord*, ScanOp*);
3477   void handle_lcp_keep_commit(const Local_key*,
3478                               KeyReqStruct *,
3479                               Operationrec*, Fragrecord*, Tablerec*);
3480 
3481   void setup_lcp_read_copy_tuple( KeyReqStruct *,
3482                                   Operationrec*,
3483                                   Fragrecord*,
3484                                   Tablerec*);
3485 
isCopyTuple(Uint32 pageid,Uint32 pageidx) const3486   bool isCopyTuple(Uint32 pageid, Uint32 pageidx) const {
3487     return (pageidx & (Uint16(1) << 15)) != 0;
3488   }
3489 
setCopyTuple(Uint32 & pageid,Uint16 & pageidx) const3490   void setCopyTuple(Uint32& pageid, Uint16& pageidx) const {
3491     assert(!isCopyTuple(pageid, pageidx));
3492     pageidx |= (Uint16(1) << 15);
3493     assert(isCopyTuple(pageid, pageidx));
3494   }
3495 
clearCopyTuple(Uint32 & pageid,Uint16 & pageidx) const3496   void clearCopyTuple(Uint32& pageid, Uint16& pageidx) const {
3497     assert(isCopyTuple(pageid, pageidx));
3498     pageidx &= ~(Uint16(1) << 15);
3499     assert(!isCopyTuple(pageid, pageidx));
3500   }
3501 };
3502 
3503 #if 0
3504 inline
3505 Uint32
3506 Dbtup::get_frag_page_id(Uint32 real_page_id)
3507 {
3508   PagePtr real_page_ptr;
3509   real_page_ptr.i= real_page_id;
3510   ptrCheckGuard(real_page_ptr, cnoOfPage, cpage);
3511   return real_page_ptr.p->frag_page_id;
3512 }
3513 #endif
3514 
3515 inline
3516 Dbtup::TransState
get_trans_state(Operationrec * regOperPtr)3517 Dbtup::get_trans_state(Operationrec * regOperPtr)
3518 {
3519   return (Dbtup::TransState)regOperPtr->op_struct.trans_state;
3520 }
3521 
3522 inline
3523 void
set_trans_state(Operationrec * regOperPtr,Dbtup::TransState trans_state)3524 Dbtup::set_trans_state(Operationrec* regOperPtr,
3525                        Dbtup::TransState trans_state)
3526 {
3527   regOperPtr->op_struct.trans_state= (Uint32)trans_state;
3528 }
3529 
3530 inline
3531 Dbtup::TupleState
get_tuple_state(Operationrec * regOperPtr)3532 Dbtup::get_tuple_state(Operationrec * regOperPtr)
3533 {
3534   return (Dbtup::TupleState)regOperPtr->op_struct.tuple_state;
3535 }
3536 
3537 inline
3538 void
set_tuple_state(Operationrec * regOperPtr,Dbtup::TupleState tuple_state)3539 Dbtup::set_tuple_state(Operationrec* regOperPtr,
3540                        Dbtup::TupleState tuple_state)
3541 {
3542   regOperPtr->op_struct.tuple_state= (Uint32)tuple_state;
3543 }
3544 
3545 
3546 inline
3547 Uint32
decr_tup_version(Uint32 tup_version)3548 Dbtup::decr_tup_version(Uint32 tup_version)
3549 {
3550   return (tup_version - 1) & ZTUP_VERSION_MASK;
3551 }
3552 
3553 inline
3554 Uint32*
get_ptr(Var_part_ref ref)3555 Dbtup::get_ptr(Var_part_ref ref)
3556 {
3557   Ptr<Page> tmp;
3558   return get_ptr(&tmp, ref);
3559 }
3560 
3561 inline
3562 Uint32*
get_ptr(Ptr<Page> * pagePtr,Var_part_ref ref)3563 Dbtup::get_ptr(Ptr<Page>* pagePtr, Var_part_ref ref)
3564 {
3565   PagePtr tmp;
3566   Local_key key;
3567   ref.copyout(&key);
3568   tmp.i = key.m_page_no;
3569 
3570   c_page_pool.getPtr(tmp);
3571   memcpy(pagePtr, &tmp, sizeof(tmp));
3572   return ((Var_page*)tmp.p)->get_ptr(key.m_page_idx);
3573 }
3574 
3575 inline
3576 Uint32*
get_ptr(PagePtr * pagePtr,const Local_key * key,const Tablerec * regTabPtr)3577 Dbtup::get_ptr(PagePtr* pagePtr,
3578 	       const Local_key* key, const Tablerec* regTabPtr)
3579 {
3580   PagePtr tmp;
3581   tmp.i= key->m_page_no;
3582   c_page_pool.getPtr(tmp);
3583   memcpy(pagePtr, &tmp, sizeof(tmp));
3584 
3585   return ((Fix_page*)tmp.p)->
3586     get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
3587 }
3588 
3589 inline
3590 Uint32*
get_default_ptr(const Tablerec * regTabPtr,Uint32 & default_len)3591 Dbtup::get_default_ptr(const Tablerec* regTabPtr, Uint32& default_len)
3592 {
3593   Var_part_ref ref;
3594   ref.assign(&regTabPtr->m_default_value_location);
3595   Ptr<Page> page;
3596 
3597   Uint32* default_data = get_ptr(&page, ref);
3598   default_len = get_len(&page, ref);
3599 
3600   return default_data;
3601 }
3602 
3603 inline
3604 Uint32*
get_dd_ptr(PagePtr * pagePtr,const Local_key * key,const Tablerec * regTabPtr)3605 Dbtup::get_dd_ptr(PagePtr* pagePtr,
3606 		  const Local_key* key, const Tablerec* regTabPtr)
3607 {
3608   PagePtr tmp;
3609   tmp.i= key->m_page_no;
3610   tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
3611   memcpy(pagePtr, &tmp, sizeof(tmp));
3612 
3613   if(regTabPtr->m_attributes[DD].m_no_of_varsize ||
3614      regTabPtr->m_attributes[DD].m_no_of_dynamic)
3615     return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
3616   else
3617     return ((Fix_page*)tmp.p)->
3618       get_ptr(key->m_page_idx, regTabPtr->m_offsets[DD].m_fix_header_size);
3619 }
3620 
3621 /*
3622   This function assumes that get_ptr() has been called first to
3623   initialise the pagePtr argument.
3624 */
3625 inline
3626 Uint32
get_len(Ptr<Page> * pagePtr,Var_part_ref ref)3627 Dbtup::get_len(Ptr<Page>* pagePtr, Var_part_ref ref)
3628 {
3629   Uint32 page_idx= ref.m_page_idx;
3630   return ((Var_page*)pagePtr->p)->get_entry_len(page_idx);
3631 }
3632 
3633 NdbOut&
3634 operator<<(NdbOut&, const Dbtup::Tablerec&);
3635 
3636 inline
find_savepoint(OperationrecPtr & loopOpPtr,Uint32 savepointId)3637 bool Dbtup::find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId)
3638 {
3639   while (true) {
3640     if (savepointId > loopOpPtr.p->savepointId) {
3641       jam();
3642       return true;
3643     }
3644     loopOpPtr.i = loopOpPtr.p->prevActiveOp;
3645     if (loopOpPtr.i == RNIL) {
3646       break;
3647     }
3648     c_operation_pool.getPtr(loopOpPtr);
3649   }
3650   return false;
3651 }
3652 
3653 inline
3654 void
update_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst,const Uint32 * src)3655 Dbtup::update_change_mask_info(const Tablerec* tablePtrP,
3656                                ChangeMask* dst,
3657                                const Uint32 * src)
3658 {
3659   assert(dst->m_cols == tablePtrP->m_no_of_attributes);
3660   Uint32 * ptr = dst->m_mask;
3661   Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
3662   for (Uint32 i = 0; i<len; i++)
3663   {
3664     * ptr |= *src;
3665     ptr++;
3666     src++;
3667   }
3668 }
3669 
3670 inline
3671 void
set_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst)3672 Dbtup::set_change_mask_info(const Tablerec* tablePtrP, ChangeMask* dst)
3673 {
3674   assert(dst->m_cols == tablePtrP->m_no_of_attributes);
3675   Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
3676   BitmaskImpl::set(len, dst->m_mask);
3677 }
3678 
3679 inline
3680 void
clear_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst)3681 Dbtup::clear_change_mask_info(const Tablerec* tablePtrP, ChangeMask* dst)
3682 {
3683   assert(dst->m_cols == tablePtrP->m_no_of_attributes);
3684   Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
3685   BitmaskImpl::clear(len, dst->m_mask);
3686 }
3687 
3688 inline
3689 void
copy_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst,const ChangeMask * src)3690 Dbtup::copy_change_mask_info(const Tablerec* tablePtrP,
3691                              ChangeMask* dst, const ChangeMask* src)
3692 {
3693   Uint32 dst_cols = tablePtrP->m_no_of_attributes;
3694   assert(dst->m_cols == dst_cols);
3695   Uint32 src_cols = src->m_cols;
3696 
3697   if (dst_cols == src_cols)
3698   {
3699     memcpy(dst->m_mask, src->m_mask, 4 * ((dst_cols + 31) >> 5));
3700   }
3701   else
3702   {
3703     ndbassert(dst_cols > src_cols); // drop column not supported
3704     memcpy(dst->m_mask, src->m_mask, 4 * ((src_cols + 31) >> 5));
3705     BitmaskImpl::setRange((dst_cols + 31) >> 5, dst->m_mask,
3706                           src_cols,  (dst_cols - src_cols));
3707   }
3708 }
3709 
3710 // Dbtup_client provides proxying similar to Page_cache_client
3711 
3712 class Dbtup_client
3713 {
3714   friend class DbtupProxy;
3715   Uint32 m_block;
3716   class DbtupProxy* m_dbtup_proxy; // set if we go via proxy
3717   Dbtup* m_dbtup;
3718   DEBUG_OUT_DEFINES(DBTUP);
3719 
3720 public:
3721   Dbtup_client(SimulatedBlock* block, SimulatedBlock* dbtup);
3722 
3723   // LGMAN
3724 
3725   void disk_restart_undo(Signal* signal, Uint64 lsn,
3726                          Uint32 type, const Uint32 * ptr, Uint32 len);
3727 
3728   // TSMAN
3729 
3730   int disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
3731 				const Local_key* key, Uint32 pages);
3732 
3733   void disk_restart_page_bits(Uint32 tableId, Uint32 fragId,
3734 			      const Local_key* key, Uint32 bits);
3735 };
3736 
3737 #endif
3738