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