1 /*
2 Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef DBTUP_H
26 #define DBTUP_H
27
28 #include <pc.hpp>
29 #include <SimulatedBlock.hpp>
30 #include <ndb_limits.h>
31 #include <trigger_definitions.h>
32 #include <AttributeHeader.hpp>
33 #include <Bitmask.hpp>
34 #include <signaldata/TupKey.hpp>
35 #include <signaldata/CreateTrig.hpp>
36 #include <signaldata/CreateTrigImpl.hpp>
37 #include <signaldata/DropTrig.hpp>
38 #include <signaldata/DropTrigImpl.hpp>
39 #include <signaldata/TrigAttrInfo.hpp>
40 #include <signaldata/BuildIndxImpl.hpp>
41 #include <signaldata/AlterTab.hpp>
42 #include <AttributeDescriptor.hpp>
43 #include "AttributeOffset.hpp"
44 #include "Undo_buffer.hpp"
45 #include "tuppage.hpp"
46 #include <DynArr256.hpp>
47 #include "../pgman.hpp"
48 #include "../tsman.hpp"
49 #include <EventLogger.hpp>
50 #include "../backup/BackupFormat.hpp"
51 #include <portlib/ndb_prefetch.h>
52 #include "util/ndb_math.h"
53 #include "TransientPool.hpp"
54 #include "TransientSlotPool.hpp"
55
56 #define JAM_FILE_ID 414
57
58 extern EventLogger* g_eventLogger;
59
60 #ifdef VM_TRACE
dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS> & bm)61 inline const char* dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS>& bm) {
62 static int i=0; static char buf[5][200];
63 bm.getText(buf[i%5]); return buf[i++%5]; }
dbgmask(const Uint32 bm[2])64 inline const char* dbgmask(const Uint32 bm[2]) {
65 static int i=0; static char buf[5][200];
66 sprintf(buf[i%5],"%08x%08x",bm[1],bm[0]); return buf[i++%5]; }
67 #endif
68
69 #define ZWORDS_ON_PAGE 8192 /* NUMBER OF WORDS ON A PAGE. */
70 #define ZMIN_PAGE_LIMIT_TUPKEYREQ 5
71 #define ZTUP_VERSION_BITS 15
72 #define ZTUP_VERSION_MASK ((1 << ZTUP_VERSION_BITS) - 1)
73 #define MAX_FREE_LIST 5
74
ALIGN_WORD(void * ptr)75 inline Uint32* ALIGN_WORD(void * ptr)
76 {
77 return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
78 }
79
ALIGN_WORD(const void * ptr)80 inline const Uint32* ALIGN_WORD(const void* ptr)
81 {
82 return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
83 }
84
85 #ifdef DBTUP_C
86
87 /*
88 2.2 LOCAL SYMBOLS
89 -----------------
90 */
91 /* ---------------------------------------------------------------- */
92 /* S I Z E O F R E C O R D S */
93 /* ---------------------------------------------------------------- */
94 #define ZNO_OF_CONCURRENT_OPEN_OP 40 /* NUMBER OF CONCURRENT OPENS */
95 #define ZNO_OF_CONCURRENT_WRITE_OP 80 /* NUMBER OF CONCURRENT DISK WRITES*/
96 #define ZNO_OF_FRAGOPREC 20 /* NUMBER OF CONCURRENT ADD FRAG. */
97 #define TOT_PAGE_RECORD_SPACE 262144 /* SIZE OF PAGE RECORD FILE. */
98 #define ZNO_OF_PAGE TOT_PAGE_RECORD_SPACE/ZWORDS_ON_PAGE
99 #define ZNO_OF_PAGE_RANGE_REC 128 /* SIZE OF PAGE RANGE FILE */
100 // Trigger constants
101 #define ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE 16
102
103 /* ---------------------------------------------------------------- */
104 /* A ATTRIBUTE MAY BE NULL, DYNAMIC OR NORMAL. A NORMAL ATTRIBUTE */
105 /* IS A ATTRIBUTE THAT IS NOT NULL OR DYNAMIC. A NULL ATTRIBUTE */
106 /* MAY HAVE NO VALUE. A DYNAMIC ATTRIBUTE IS A NULL ATTRIBUTE THAT */
107 /* DOES NOT HAVE TO BE A MEMBER OF EVERY TUPLE I A CERTAIN TABLE. */
108 /* ---------------------------------------------------------------- */
109 /**
110 * #defines moved into include/kernel/Interpreter.hpp
111 */
112 #define ZINSERT_DELETE 0
113 #define ZUPDATE_ALL 8
114 /* ---------------------------------------------------------------- */
115 /* THE MINIMUM SIZE OF AN 'EMPTY' TUPLE HEADER IN R-WORDS */
116 /* ---------------------------------------------------------------- */
117 /* THE TUPLE HEADER FIELD 'SIZE OF NULL ATTR. FIELD' SPECIFYES */
118 /* THE SIZE OF THE TUPLE HEADER FIELD 'NULL ATTR. FIELD'. */
119 /* THE TUPLE HEADER FIELD 'TYPE' SPECIFYES THE TYPE OF THE TUPLE */
120 /* HEADER. */
121 /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
122 /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER. */
123 /* IT MAY ALSO CONTAIN SHORT ATTRIBUTES AND */
124 /* POINTERS TO LONG ATTRIBUTE HEADERS. */
125 /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
126 /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER. */
127
128 /* DATA STRUCTURE TYPES */
129 /* WHEN ATTRIBUTE INFO IS SENT WITH A ATTRINFO-SIGNAL THE */
130 /* VARIABLE TYPE IS SPECIFYED. THIS MUST BE DONE TO BE ABLE TO */
131 /* NOW HOW MUCH DATA OF A ATTRIBUTE TO READ FROM ATTRINFO. */
132
133 /* WHEN A REQUEST CAN NOT BE EXECUTED BECAUSE OF A ERROR THE */
134 /* ERROR MUST BE IDENTIFYED BY MEANS OF A ERROR CODE AND SENT TO */
135 /* THE REQUESTER. */
136 #define ZGET_OPREC_ERROR 804 // TUP_SEIZEREF
137
138 #define ZEXIST_FRAG_ERROR 816 // Add fragment
139 #define ZFULL_FRAGRECORD_ERROR 817 // Add fragment
140 #define ZNO_FREE_PAGE_RANGE_ERROR 818 // Add fragment
141 #define ZNOFREE_FRAGOP_ERROR 830 // Add fragment
142 #define ZTOO_LARGE_TUPLE_ERROR 851 // Add fragment
143 #define ZNO_FREE_TAB_ENTRY_ERROR 852 // Add fragment
144 #define ZNO_PAGES_ALLOCATED_ERROR 881 // Add fragment
145
146 #define ZGET_REALPID_ERROR 809
147 #define ZNOT_IMPLEMENTED_ERROR 812
148 #define ZSEIZE_ATTRINBUFREC_ERROR 805
149 #define ZTOO_MUCH_ATTRINFO_ERROR 823
150 #define ZMEM_NOTABDESCR_ERROR 826
151 #define ZMEM_NOMEM_ERROR 827
152 #define ZAI_INCONSISTENCY_ERROR 829
153 #define ZNO_ILLEGAL_NULL_ATTR 839
154 #define ZNOT_NULL_ATTR 840
155 #define ZBAD_DEFAULT_VALUE_LEN 850
156 #define ZNO_INSTRUCTION_ERROR 871
157 #define ZOUTSIDE_OF_PROGRAM_ERROR 876
158 #define ZSTORED_PROC_ID_ERROR 877
159 #define ZREGISTER_INIT_ERROR 878
160 #define ZATTRIBUTE_ID_ERROR 879
161 #define ZTRY_TO_READ_TOO_MUCH_ERROR 880
162 #define ZTOTAL_LEN_ERROR 882
163 #define ZATTR_INTERPRETER_ERROR 883
164 #define ZSTACK_OVERFLOW_ERROR 884
165 #define ZSTACK_UNDERFLOW_ERROR 885
166 #define ZTOO_MANY_INSTRUCTIONS_ERROR 886
167 #define ZTRY_TO_UPDATE_ERROR 888
168 #define ZCALL_ERROR 890
169 #define ZTEMPORARY_RESOURCE_FAILURE 891
170 #define ZUNSUPPORTED_BRANCH 892
171
172 #define ZSTORED_TOO_MUCH_ATTRINFO_ERROR 874
173
174 #define ZREAD_ONLY_CONSTRAINT_VIOLATION 893
175 #define ZVAR_SIZED_NOT_SUPPORTED 894
176 #define ZINCONSISTENT_NULL_ATTRIBUTE_COUNT 895
177 #define ZTUPLE_CORRUPTED_ERROR 896
178 #define ZTRY_UPDATE_PRIMARY_KEY 897
179 #define ZMUST_BE_ABORTED_ERROR 898
180 #define ZTUPLE_DELETED_ERROR 626
181 #define ZINSERT_ERROR 630
182 #define ZOP_AFTER_REFRESH_ERROR 920
183 #define ZNO_COPY_TUPLE_MEMORY_ERROR 921
184 #define ZNO_UNDO_BUFFER_MEMORY_ERROR 923
185 #define ZOUT_OF_STORED_PROC_MEMORY_ERROR 924
186
187 #define ZINVALID_CHAR_FORMAT 744
188 #define ZROWID_ALLOCATED 899
189 #define ZINVALID_ALTER_TAB 741
190
191 #define ZTOO_MANY_BITS_ERROR 791
192
193 /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */
194
195 #define ZTH_MM_FREE 3 /* PAGE STATE, TUPLE HEADER PAGE WITH FREE AREA */
196 #define ZTH_MM_FULL 4 /* PAGE STATE, TUPLE HEADER PAGE WHICH IS FULL */
197
198 #define ZTD_HEADER 0 /* HEADER POSITION */
199 #define ZTD_DATASIZE 1 /* SIZE OF THE DATA IN THIS CHUNK */
200 #define ZTD_SIZE 2 /* TOTAL SIZE OF TABLE DESCRIPTOR */
201
202 /* TRAILER POSITIONS FROM END OF TABLE DESCRIPTOR RECORD */
203 #define ZTD_TR_SIZE 1 /* SIZE DESCRIPTOR POS FROM END+1 */
204 #define ZTD_TR_TYPE 2
205 #define ZTD_TRAILER_SIZE 2 /* TOTAL SIZE OF TABLE TRAILER */
206 #define ZAD_SIZE 2 /* TOTAL SIZE OF ATTR DESCRIPTOR */
207 #define ZAD_LOG_SIZE 1 /* TWO LOG OF TOTAL SIZE OF ATTR DESCRIPTOR */
208
209 /* CONSTANTS USED TO HANDLE TABLE DESCRIPTOR AS A FREELIST */
210 #define ZTD_FL_HEADER 0 /* HEADER POSITION */
211 #define ZTD_FL_SIZE 1 /* TOTAL SIZE OF THIS FREELIST ENTRY */
212 #define ZTD_FL_PREV 2 /* PREVIOUS RECORD IN FREELIST */
213 #define ZTD_FL_NEXT 3 /* NEXT RECORD IN FREELIST */
214 #define ZTD_FREE_SIZE 16 /* SIZE NEEDED TO HOLD ONE FL ENTRY */
215
216 /* CONSTANTS USED IN LSB OF TABLE DESCRIPTOR HEADER DESCRIBING USAGE */
217 #define ZTD_TYPE_FREE 0 /* RECORD LINKED INTO FREELIST */
218 #define ZTD_TYPE_NORMAL 1 /* RECORD USED AS TABLE DESCRIPTOR */
219 /* ATTRIBUTE OPERATION CONSTANTS */
220 #define ZLEAF 1
221 #define ZNON_LEAF 2
222
223 /* RETURN POINTS. */
224 /* RESTART PHASES */
225 #define ZSTARTPHASE1 1
226 #define ZSTARTPHASE2 2
227 #define ZSTARTPHASE3 3
228 #define ZSTARTPHASE4 4
229 #define ZSTARTPHASE6 6
230
231 #define ZADDFRAG 0
232
233 //------------------------------------------------------------
234 // TUP_CONTINUEB codes
235 //------------------------------------------------------------
236 #define ZINITIALISE_RECORDS 6
237 #define ZREL_FRAG 7
238 #define ZREPORT_MEMORY_USAGE 8
239 #define ZBUILD_INDEX 9
240 #define ZTUP_SCAN 10
241 #define ZFREE_EXTENT 11
242 #define ZUNMAP_PAGES 12
243 #define ZFREE_VAR_PAGES 13
244 #define ZFREE_PAGES 14
245 #define ZREBUILD_FREE_PAGE_LIST 15
246 #define ZDISK_RESTART_UNDO 16
247 #define ZTUP_SHRINK_TRANSIENT_POOLS 17
248 #define ZTUP_TRANSIENT_POOL_STAT 18
249
250 #define ZSCAN_PROCEDURE 0
251 #define ZCOPY_PROCEDURE 2
252 #define ZSTORED_PROCEDURE_DELETE 3
253 #define ZSTORED_PROCEDURE_FREE 0xffff
254 #define ZMIN_PAGE_LIMIT_TUP_COMMITREQ 2
255
256 #define ZSKIP_TUX_TRIGGERS 0x1 // flag for TUP_ABORTREQ
257 #define ZABORT_DEALLOC 0x2 // flag for TUP_ABORTREQ
258
259 #endif
260
261 class Dbtup: public SimulatedBlock {
262 friend class DbtupProxy;
263 friend class Suma;
264 public:
265 struct KeyReqStruct;
266 friend struct KeyReqStruct; // CC
267 typedef bool (* ReadFunction)(Uint8*,
268 KeyReqStruct*,
269 AttributeHeader*,
270 Uint64);
271 typedef bool (* UpdateFunction)(Uint32*,
272 KeyReqStruct*,
273 Uint64);
274 void prepare_scan_ctx(Uint32 scanPtrI);
275 private:
276
277 typedef Tup_fixsize_page Fix_page;
278 typedef Tup_varsize_page Var_page;
279
280 public:
281 class Dblqh *c_lqh;
282 class Backup *c_backup;
283 Tsman* c_tsman;
284 Lgman* c_lgman;
285 Pgman* c_pgman;
286
287 enum CallbackIndex {
288 // lgman
289 DROP_TABLE_LOG_BUFFER_CALLBACK = 1,
290 DROP_FRAGMENT_FREE_EXTENT_LOG_BUFFER_CALLBACK = 2,
291 NR_DELETE_LOG_BUFFER_CALLBACK = 3,
292 DISK_PAGE_LOG_BUFFER_CALLBACK = 4,
293 COUNT_CALLBACKS = 5
294 };
295 CallbackEntry m_callbackEntry[COUNT_CALLBACKS];
296 CallbackTable m_callbackTable;
297
298 enum TransState {
299 TRANS_IDLE = 0,
300 TRANS_STARTED = 1,
301 TRANS_NOT_USED_STATE = 2, // No longer used.
302 TRANS_ERROR_WAIT_STORED_PROCREQ = 3,
303 TRANS_ERROR_WAIT_TUPKEYREQ = 4,
304 TRANS_TOO_MUCH_AI = 5,
305 TRANS_DISCONNECTED = 6
306 };
307
308 enum TupleState {
309 TUPLE_PREPARED = 1,
310 TUPLE_ALREADY_ABORTED = 2,
311 TUPLE_TO_BE_COMMITTED = 3
312 };
313
314 enum State {
315 NOT_INITIALIZED = 0,
316 IDLE = 17,
317 ACTIVE = 18,
318 SYSTEM_RESTART = 19,
319 DEFINED = 34,
320 NOT_DEFINED = 37,
321 NORMAL_PAGE = 40,
322 DEFINING = 65,
323 DROPPING = 68
324 };
325
326
327 struct Fragoperrec {
328 Uint64 minRows;
329 Uint64 maxRows;
330 Uint32 nextFragoprec;
331 Uint32 lqhPtrFrag;
332 Uint32 fragidFrag;
333 Uint32 tableidFrag;
334 Uint32 fragPointer;
335 Uint32 attributeCount;
336 Uint32 charsetIndex;
337 Uint32 m_null_bits[2];
338 Uint32 m_extra_row_gci_bits;
339 Uint32 m_extra_row_author_bits;
340 union {
341 BlockReference lqhBlockrefFrag;
342 Uint32 m_senderRef;
343 };
344 Uint32 m_senderData;
345 Uint32 m_restoredLcpId;
346 Uint32 m_restoredLocalLcpId;
347 Uint32 m_maxGciCompleted;
348 bool inUse;
349 bool definingFragment;
350 };
351 typedef Ptr<Fragoperrec> FragoperrecPtr;
352
353 /* Operation record used during alter table. */
354 struct AlterTabOperation {
AlterTabOperationDbtup::AlterTabOperation355 AlterTabOperation() { memset(this, 0, sizeof(AlterTabOperation)); }
356 Uint32 nextAlterTabOp;
357 Uint32 newNoOfAttrs;
358 Uint32 newNoOfCharsets;
359 Uint32 newNoOfKeyAttrs;
360 Uint32 noOfDynNullBits;
361 Uint32 noOfDynVar;
362 Uint32 noOfDynFix;
363 Uint32 noOfDynamic;
364 Uint32 tabDesOffset[7];
365 Uint32 tableDescriptor;
366 Uint32 dynTabDesOffset[3];
367 Uint32 dynTableDescriptor;
368 };
369 typedef Ptr<AlterTabOperation> AlterTabOperationPtr;
370
371 typedef Tup_page Page;
372 typedef Ptr<Page> PagePtr;
373 typedef ArrayPool<Page> Page_pool;
374 typedef DLList<Page_pool> Page_list;
375 typedef LocalDLList<Page_pool> Local_Page_list;
376 typedef DLFifoList<Page_pool> Page_fifo;
377 typedef LocalDLFifoList<Page_pool> Local_Page_fifo;
378
379 // Scan position
380 struct ScanPos {
381 enum Get {
382 Get_undef = 0,
383 Get_next_page,
384 Get_page,
385 Get_next_page_mm,
386 Get_page_mm,
387 Get_next_page_dd,
388 Get_page_dd,
389 Get_next_tuple,
390 Get_tuple
391 };
392 Get m_get; // entry point in scanNext
393 Local_key m_key; // scan position pointer MM or DD
394 Page* m_page; // scanned MM or DD (cache) page
395 Local_key m_key_mm; // MM local key returned
396 Uint32 m_realpid_mm; // MM real page id
397 Uint32 m_extent_info_ptr_i;
398 Uint32 m_next_small_area_check_idx;
399 Uint32 m_next_large_area_check_idx;
400 bool m_all_rows;
401 bool m_lcp_scan_changed_rows_page;
402 bool m_is_last_lcp_state_D;
ScanPosDbtup::ScanPos403 ScanPos() {
404 /*
405 * Position is Null until scanFirst(). In particular in LCP scan
406 * it is Null between LCP_FRAG_ORD and ACC_SCANREQ.
407 */
408 m_key.setNull();
409 }
410 };
411
412 // Scan Lock
413 struct ScanLock {
414 STATIC_CONST( TYPE_ID = RT_DBTUP_SCAN_LOCK);
415 Uint32 m_magic;
416
ScanLockDbtup::ScanLock417 ScanLock() :
418 m_magic(Magic::make(TYPE_ID))
419 {
420 }
421
~ScanLockDbtup::ScanLock422 ~ScanLock()
423 {
424 }
425
426 Uint32 m_accLockOp;
427 union {
428 Uint32 nextPool;
429 Uint32 nextList;
430 };
431 Uint32 prevList;
432 };
433 STATIC_CONST( DBTUP_SCAN_LOCK_TRANSIENT_POOL_INDEX = 2);
434 typedef Ptr<ScanLock> ScanLockPtr;
435 typedef TransientPool<ScanLock> ScanLock_pool;
436 typedef DLFifoList<ScanLock_pool> ScanLock_fifo;
437 typedef LocalDLFifoList<ScanLock_pool> Local_ScanLock_fifo;
438 ScanLock_pool c_scanLockPool;
439 /**
440 * To ensure that we have a lock resource before we scan a row
441 * in lock mode, we grab it before the scan and store the
442 * ScanLock i-value in this variable. It can only store a single
443 * object, no list of objects.
444 */
445 Uint32 c_freeScanLock;
446
447 // Tup scan, similar to Tux scan. Later some of this could
448 // be moved to common superclass.
449 struct ScanOp {
450 STATIC_CONST( TYPE_ID = RT_DBTUP_SCAN_OPERATION);
451 Uint32 m_magic;
ScanOpDbtup::ScanOp452 ScanOp() :
453 m_magic(Magic::make(TYPE_ID)),
454 m_state(Undef),
455 m_bits(0),
456 m_last_seen(0),
457 m_userPtr(RNIL),
458 m_userRef(RNIL),
459 m_tableId(RNIL),
460 m_fragId(~(Uint32)0),
461 m_fragPtrI(RNIL),
462 m_transId1(0),
463 m_transId2(0),
464 m_savePointId(0),
465 m_accLockOp(RNIL)
466 {}
467
468 enum State {
469 Undef = 0,
470 First = 1, // before first entry
471 Current = 2, // at current before locking
472 Blocked = 3, // at current waiting for ACC lock
473 Locked = 4, // at current and locked or no lock needed
474 Next = 5, // looking for next extry
475 Last = 6, // after last entry
476 Aborting = 7, // lock wait at scan close
477 Invalid = 9 // cannot return REF to LQH currently
478 };
479 Uint16 m_state;
480
481 enum Bits {
482 SCAN_DD = 0x01, // scan disk pages
483 SCAN_VS = 0x02, // page format is var size
484 SCAN_LCP = 0x04, // LCP mem page scan
485 SCAN_LOCK_SH = 0x10, // lock mode shared
486 SCAN_LOCK_EX = 0x20, // lock mode exclusive
487 SCAN_LOCK_WAIT = 0x40, // lock wait
488 // any lock mode
489 SCAN_LOCK = SCAN_LOCK_SH | SCAN_LOCK_EX,
490 SCAN_NR = 0x80, // Node recovery scan
491 SCAN_COPY_FRAG = 0x100 // Copy fragment scan
492 };
493 Uint16 m_bits;
494 Uint16 m_last_seen;
495
496 Uint32 m_userPtr; // scanptr.i in LQH
497 Uint32 m_userRef;
498 Uint32 m_tableId;
499 Uint32 m_fragId;
500 Uint32 m_fragPtrI;
501 Uint32 m_transId1;
502 Uint32 m_transId2;
503 union {
504 Uint32 m_savePointId;
505 Uint32 m_scanGCI;
506 };
507 Uint32 m_endPage;
508 // lock waited for or obtained and not yet passed to LQH
509 Uint32 m_accLockOp;
510
511 ScanPos m_scanPos;
512
513 ScanLock_fifo::Head m_accLockOps;
514
515 union {
516 Uint32 nextPool;
517 Uint32 nextList;
518 };
519 Uint32 prevList;
520 };
521 STATIC_CONST(DBTUP_SCAN_OPERATION_TRANSIENT_POOL_INDEX = 3);
522 typedef Ptr<ScanOp> ScanOpPtr;
523 typedef TransientPool<ScanOp> ScanOp_pool;
524 typedef DLList<ScanOp_pool> ScanOp_list;
525 typedef LocalDLList<ScanOp_pool> Local_ScanOp_list;
526 ScanOp_pool c_scanOpPool;
527
528 void scanReply(Signal*, ScanOpPtr scanPtr);
529 void scanFirst(Signal*, ScanOpPtr scanPtr);
530 bool scanNext(Signal*, ScanOpPtr scanPtr);
531 void scanCont(Signal*, ScanOpPtr scanPtr);
532 void disk_page_tup_scan_callback(Signal*, Uint32 scanPtrI, Uint32 page_i);
533 void scanClose(Signal*, ScanOpPtr scanPtr);
534 void addAccLockOp(ScanOp& scan, Uint32 accLockOp);
535 void removeAccLockOp(ScanOp& scan, Uint32 accLockOp);
536 void releaseScanOp(ScanOpPtr& scanPtr);
537
538 struct Tuple_header;
539
540 Uint32 prepare_lcp_scan_page(ScanOp& scan,
541 Local_key& key,
542 Uint32 *next_ptr,
543 Uint32 *prev_ptr);
544 Uint32 handle_lcp_skip_page(ScanOp& scan,
545 Local_key key,
546 Page *page);
547 Uint32 handle_scan_change_page_rows(ScanOp& scan,
548 Fix_page *fix_page,
549 Tuple_header* tuple_header_ptr,
550 Uint32 & foundGCI);
551 Uint32 setup_change_page_for_scan(ScanOp& scan,
552 Fix_page *fix_page,
553 Local_key& key,
554 Uint32 size);
555 Uint32 move_to_next_change_page_row(ScanOp & scan,
556 Fix_page *fix_page,
557 Tuple_header **tuple_header_ptr,
558 Uint32 & loop_count,
559 Uint32 size);
560
561 // for md5 of key (could maybe reuse existing temp buffer)
562 Uint64 c_dataBuffer[ZWORDS_ON_PAGE/2 + 1];
563
564 // Crash the node when a tuple got corrupted
565 bool c_crashOnCorruptedTuple;
566
567 struct Page_request
568 {
Page_requestDbtup::Page_request569 Page_request() {}
570 Local_key m_key;
571 Uint32 m_frag_ptr_i;
572 Uint32 m_extent_info_ptr;
573 Uint16 m_original_estimated_free_space; // in bytes/records
574 Uint16 m_list_index; // in Disk_alloc_info.m_page_requests
575 Uint16 m_ref_count; // Waiters for page
576 Uint16 m_uncommitted_used_space;
577 Uint32 nextList;
578 Uint32 prevList;
579 Uint32 m_magic;
580 }; // 32 bytes
581
582 typedef RecordPool<WOPool<Page_request> > Page_request_pool;
583 typedef DLFifoList<Page_request_pool> Page_request_list;
584 typedef LocalDLFifoList<Page_request_pool> Local_page_request_list;
585
586 STATIC_CONST( EXTENT_SEARCH_MATRIX_COLS = 4 ); // Guarantee size
587 STATIC_CONST( EXTENT_SEARCH_MATRIX_ROWS = 5 ); // Total size
588 STATIC_CONST( EXTENT_SEARCH_MATRIX_SIZE = 20 );
589
590 struct Extent_info
591 {
592 Uint32 m_magic;
593 Uint32 m_first_page_no;
594 Uint32 m_empty_page_no;
595 Local_key m_key;
596 Uint32 m_free_space;
597 Uint32 m_free_matrix_pos;
598 Uint16 m_free_page_count[EXTENT_SEARCH_MATRIX_COLS];
599 union {
600 Uint32 nextList;
601 Uint32 nextPool;
602 };
603 Uint32 prevList;
604 Uint32 nextHash, prevHash;
605 Uint32 nextFragment;
606
hashValueDbtup::Extent_info607 Uint32 hashValue() const {
608 return (m_key.m_file_no << 16) ^ m_key.m_page_idx;
609 }
610
Extent_infoDbtup::Extent_info611 Extent_info() {}
equalDbtup::Extent_info612 bool equal(const Extent_info & rec) const {
613 return m_key.m_file_no == rec.m_key.m_file_no &&
614 m_key.m_page_idx == rec.m_key.m_page_idx;
615 }
616 }; // 40 bytes
617
618 typedef RecordPool<RWPool<Extent_info> > Extent_info_pool;
619 typedef DLList<Extent_info_pool> Extent_info_list;
620 typedef LocalDLList<Extent_info_pool> Local_extent_info_list;
621 typedef DLHashTable<Extent_info_pool> Extent_info_hash;
622 typedef SLList<Extent_info_pool, IA_Fragment> Fragment_extent_list;
623 typedef LocalSLList<Extent_info_pool, IA_Fragment> Local_fragment_extent_list;
624 struct Tablerec;
625 struct Disk_alloc_info
626 {
Disk_alloc_infoDbtup::Disk_alloc_info627 Disk_alloc_info() {}
628 Disk_alloc_info(const Tablerec* tabPtrP,
629 Uint32 extent_size_in_pages);
630 Uint32 m_extent_size;
631
632 /**
633 * Disk allocation
634 *
635 * 1) Allocate space on pages that already are dirty
636 * (4 free lists for different requests)
637 * 2) Allocate space on pages waiting to be mapped that will be dirty
638 * (4 free lists for different requests)
639 * 3) Check if "current" extent can accommodate request
640 * If so, allocate page from there
641 * Else put "current" into free matrix
642 * 4) Search free matrix for extent with greatest amount of free space
643 * while still accommodating current request
644 * (20 free lists for different requests)
645 */
646
647 /**
648 * Free list of pages in different size
649 * that are dirty
650 */
651 Page_list::Head m_dirty_pages[EXTENT_SEARCH_MATRIX_COLS]; // In real page id's
652
653 /**
654 * Requests (for update) that have sufficient space left after request
655 * these are currently being "mapped"
656 */
657 Page_request_list::Head m_page_requests[EXTENT_SEARCH_MATRIX_COLS];
658
659 Page_list::Head m_unmap_pages;
660
661 /**
662 * Current extent
663 */
664 Uint32 m_curr_extent_info_ptr_i;
665
666 /**
667 *
668 */
669 STATIC_CONST( SZ = EXTENT_SEARCH_MATRIX_SIZE );
670 Extent_info_list::Head m_free_extents[SZ];
671 Uint32 m_total_extent_free_space_thresholds[EXTENT_SEARCH_MATRIX_ROWS];
672 Uint32 m_page_free_bits_map[EXTENT_SEARCH_MATRIX_COLS];
673
674 Uint32 find_extent(Uint32 sz) const;
675 Uint32 calc_extent_pos(const Extent_info*) const;
676
677 /**
678 * Compute minimum free space on page given bits
679 */
calc_page_free_spaceDbtup::Disk_alloc_info680 Uint32 calc_page_free_space(Uint32 bits) const {
681 return m_page_free_bits_map[bits];
682 }
683
684 /**
685 * Compute page free bits, given free space
686 */
calc_page_free_bitsDbtup::Disk_alloc_info687 Uint32 calc_page_free_bits(Uint32 free) const {
688 for(Uint32 i = 0; i<EXTENT_SEARCH_MATRIX_COLS-1; i++)
689 if(free >= m_page_free_bits_map[i])
690 return i;
691 return EXTENT_SEARCH_MATRIX_COLS - 1;
692 }
693
694 Fragment_extent_list::Head m_extent_list;
695 };
696
697 void dump_disk_alloc(Disk_alloc_info&);
698
699 STATIC_CONST( FREE_PAGE_BIT = 0x80000000 );
700 STATIC_CONST( LCP_SCANNED_BIT = 0x40000000 );
701 STATIC_CONST( LAST_LCP_FREE_BIT = 0x40000000 );
702 STATIC_CONST( FREE_PAGE_RNIL = 0x3fffffff );
703 STATIC_CONST( PAGE_BIT_MASK = 0x3fffffff );
704 STATIC_CONST( MAX_PAGES_IN_DYN_ARRAY = (RNIL & PAGE_BIT_MASK));
705
706 struct Fragrecord {
707 // Number of allocated pages for fixed-sized data.
708 Uint32 noOfPages;
709 // Number of allocated pages for var-sized data.
710 Uint32 noOfVarPages;
711 // No of allocated but unused words for var-sized fields.
712 Uint64 m_varWordsFree;
713
714 /**
715 * m_max_page_cnt contains the next page number to use when allocating
716 * a new page and all pages with lower page numbers are filled with
717 * rows. At fragment creation it is 0 since no pages are yet allocated.
718 * With 1 page allocated it is set to 1. The actual max page number with
719 * 1 page is however 0 since we start with page numbers from 0.
720 */
721 Uint32 m_max_page_cnt;
722 Uint32 m_free_page_id_list;
723 DynArr256::Head m_page_map;
724 Page_fifo::Head thFreeFirst; // pages with atleast 1 free record
725
726 Uint32 m_lcp_scan_op;
727 Local_key m_lcp_keep_list_head;
728 Local_key m_lcp_keep_list_tail;
729
730 enum FragState
731 { FS_FREE
732 ,FS_ONLINE // Ordinary fragment
733 ,FS_REORG_NEW // A new (not yet "online" fragment)
734 ,FS_REORG_COMMIT // An ordinary fragment which has been split
735 ,FS_REORG_COMMIT_NEW // An new fragment which is online
736 ,FS_REORG_COMPLETE // An ordinary fragment which has been split
737 ,FS_REORG_COMPLETE_NEW // An new fragment which is online
738 } fragStatus;
739 Uint32 fragTableId;
740 Uint32 fragmentId;
741 Uint32 partitionId;
742 Uint32 nextfreefrag;
743 // +1 is as "full" pages are stored last
744 Page_list::Head free_var_page_array[MAX_FREE_LIST+1];
745
746 ScanOp_list::Head m_scanList;
747
748 enum
749 {
750 UC_LCP = 1,
751 UC_CREATE = 2,
752 UC_SET_LCP = 3,
753 UC_NO_LCP = 4,
754 UC_DROP = 5
755 };
756 /* Calculated average row size of the rows in the fragment */
757 Uint32 m_average_row_size;
758 Uint32 m_restore_lcp_id;
759 Uint32 m_restore_local_lcp_id;
760 Uint32 m_undo_complete;
761 Uint32 m_tablespace_id;
762 Uint32 m_logfile_group_id;
763 Disk_alloc_info m_disk_alloc_info;
764 // GCI at time of start LCP (used to deduce if one should count row changes)
765 Uint32 m_lcp_start_gci;
766 // Number of changed rows since last LCP (approximative)
767 Uint64 m_lcp_changed_rows;
768 // Number of fixed-seize tuple parts (which equals the tuple count).
769 Uint64 m_fixedElemCount;
770 Uint64 m_row_count;
771 Uint64 m_prev_row_count;
772 Uint64 m_committed_changes;
773 /**
774 Number of variable-size tuple parts, i.e. the number of tuples that has
775 one or more non-NULL varchar/varbinary or blob fields. (The first few bytes
776 of a blob is stored like that, the rest in a blob table.)
777 */
778 Uint64 m_varElemCount;
779
780 // Consistency check.
verifyVarSpaceDbtup::Fragrecord781 bool verifyVarSpace() const
782 {
783 if ((m_varWordsFree < Uint64(1)<<60) && //Underflow.
784 m_varWordsFree * sizeof(Uint32) <=
785 Uint64(noOfVarPages) * File_formats::NDB_PAGE_SIZE)
786 {
787 return true;
788 }
789 else
790 {
791 g_eventLogger->info("TUP : T%uF%u verifyVarSpace fails : "
792 "m_varWordsFree : %llu "
793 "noOfVarPages : %u",
794 fragTableId,
795 fragmentId,
796 m_varWordsFree,
797 noOfVarPages);
798 return false;
799 }
800 }
801
802 };
803 typedef Ptr<Fragrecord> FragrecordPtr;
804
805 struct Operationrec {
806 STATIC_CONST( TYPE_ID = RT_DBTUP_OPERATION);
807 Uint32 m_magic;
808
OperationrecDbtup::Operationrec809 Operationrec() :
810 m_magic(Magic::make(TYPE_ID)),
811 prevActiveOp(RNIL),
812 nextActiveOp(RNIL),
813 m_any_value(0),
814 op_type(ZREAD),
815 trans_state(Uint32(TRANS_DISCONNECTED))
816 {
817 op_struct.bit_field.in_active_list = false;
818 op_struct.bit_field.tupVersion = ZNIL;
819 op_struct.bit_field.delete_insert_flag = false;
820 }
821
~OperationrecDbtup::Operationrec822 ~Operationrec()
823 {
824 }
825
826 /*
827 * Doubly linked list with anchor on tuple.
828 * This is to handle multiple updates on the same tuple
829 * by the same transaction.
830 */
831 Uint32 prevActiveOp;
832 Uint32 nextActiveOp;
833
is_first_operationDbtup::Operationrec834 bool is_first_operation() const { return prevActiveOp == RNIL;}
is_last_operationDbtup::Operationrec835 bool is_last_operation() const { return nextActiveOp == RNIL;}
836
837 Uint32 m_undo_buffer_space; // In words
838
839 Uint32 m_any_value;
840 Uint32 nextPool;
841
842 /*
843 * From fragment i-value we can find fragment and table record
844 */
845 Uint32 fragmentPtr;
846
847 /*
848 * We need references to both the original tuple and the copy tuple.
849 * We keep the page's real i-value and its index and from there we
850 * can find out about the fragment page id and the page offset.
851 */
852 Local_key m_tuple_location;
853 Local_key m_copy_tuple_location;
854
855 /*
856 * We keep the record linked to the operation record in LQH.
857 * This is needed due to writing of REDO log must be performed
858 * in correct order, which is the same order as the writes
859 * occurred. LQH can receive the records in different order.
860 */
861 Uint32 userpointer;
862
863 /*
864 * When responding to queries in the same transaction they will see
865 * a result from the save point id the query was started. Again
866 * functionality for multi-updates of the same record in one
867 * transaction.
868 */
869 union {
870 Uint32 savepointId;
871 Uint32 m_commit_disk_callback_page;
872 };
873
874 Uint32 op_type;
875 Uint32 trans_state;
876 Uint32 tuple_state;
877
878 /*
879 * State variables on connection.
880 * State variable on tuple after multi-updates
881 * Is operation undo logged or not
882 * Is operation in fragment list
883 * Is operation in multi-update list
884 * Operation type (READ, UPDATE, etc)
885 * Is record primary replica
886 * Is delete or insert performed
887 */
888 struct OpBitFields {
889 /*
890 * TUX needs to know the tuple version of the tuple since it
891 * keeps an entry for both the committed and all versions in
892 * a transaction currently. So each update will create a new
893 * version even if in the same transaction.
894 */
895 unsigned int tupVersion : 16;
896
897 unsigned int m_reorg : 2;
898 unsigned int in_active_list : 1;
899 unsigned int delete_insert_flag : 1;
900 unsigned int m_disk_preallocated : 1;
901 unsigned int m_load_diskpage_on_commit : 1;
902 unsigned int m_wait_log_buffer : 1;
903 unsigned int m_gci_written : 1;
904
905 /**
906 * @see TupKeyReq
907 *
908 * 0 = non-primary replica, fire detached triggers
909 * 1 = primary replica, fire immediate and detached triggers
910 * 2 = no fire triggers
911 * e.g If the op has no logical effect, it should not be
912 * sent as an event. Example op is OPTIMIZE table,
913 * which uses ZUPDATE to move varpart values physically.
914 */
915 unsigned int m_triggers : 2;
916
917 /*
918 * The TupKeyReq requested the after<Op>Triggers to be deferred.
919 * Thus, the *constraints* defined in this trigger list should be
920 * deferred until FIRE_TRIG_REQ arrives.
921 * Note that this does not affect the triggers *declared* as deferred
922 * ('no action') which are managed in the deferred<Op>Triggers and
923 * always deferred until commit time (FIRE_TRIG_REQ)
924 */
925 unsigned int m_deferred_constraints : 1;
926
927 /* No foreign keys should be checked for this operation.
928 * No fk triggers will be fired.
929 */
930 unsigned int m_disable_fk_checks : 1;
931 unsigned int m_tuple_existed_at_start : 1;
932 };
933
934 union OpStruct {
935 OpBitFields bit_field;
936 Uint32 op_bit_fields;
937 };
938 OpStruct op_struct;
939
940 /*
941 * When refreshing a row, there are four scenarios
942 * The actual scenario is encoded in the 'copy tuple location'
943 * to enable special handling at commit time
944 */
945 enum RefreshScenario
946 {
947 RF_SINGLE_NOT_EXIST = 1, /* Refresh op first in trans, no row */
948 RF_SINGLE_EXIST = 2, /* Refresh op first in trans, row exists */
949 RF_MULTI_NOT_EXIST = 3, /* Refresh op !first in trans, row deleted */
950 RF_MULTI_EXIST = 4 /* Refresh op !first in trans, row exists */
951 };
952 };
953 STATIC_CONST(DBTUP_OPERATION_RECORD_TRANSIENT_POOL_INDEX = 0);
954 typedef Ptr<Operationrec> OperationrecPtr;
955 typedef TransientPool<Operationrec> Operationrec_pool;
956 OperationrecPtr prepare_oper_ptr;
957
958 /* ************* TRIGGER DATA ************* */
959 /* THIS RECORD FORMS LISTS OF ACTIVE */
960 /* TRIGGERS FOR EACH TABLE. */
961 /* THE RECORDS ARE MANAGED BY A TRIGGER */
962 /* POOL wHERE A TRIGGER RECORD IS SEIZED */
963 /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
964 /* WHEN THE TRIGGER IS DEACTIVATED. */
965 /* **************************************** */
966 struct TupTriggerData {
TupTriggerDataDbtup::TupTriggerData967 TupTriggerData() {}
968
969 /**
970 * Trigger id, used by DICT/TRIX to identify the trigger
971 *
972 * trigger Ids are unique per block for SUBSCRIPTION triggers.
973 * This is so that BACKUP can use TUP triggers directly and delete them
974 * properly.
975 */
976 Uint32 triggerId;
977
978 /**
979 * In 6.3 there is one trigger per operation
980 */
981 Uint32 oldTriggerIds[3]; // INS/UPD/DEL
982
983 /**
984 * Index id is needed for ordered index.
985 */
986 Uint32 indexId;
987
988 /**
989 * Trigger type etc, defines what the trigger is used for
990 */
991 TriggerType::Value triggerType;
992 TriggerActionTime::Value triggerActionTime;
993 TriggerEvent::Value triggerEvent;
994 /**
995 * Receiver block reference
996 */
997 Uint32 m_receiverRef;
998
999 /**
1000 * Monitor all replicas, i.e. trigger will fire on all nodes where tuples
1001 * are stored
1002 */
1003 bool monitorReplicas;
1004
1005 /**
1006 * Monitor all attributes, the trigger monitors all changes to attributes
1007 * in the table
1008 */
1009 bool monitorAllAttributes;
1010
1011 /**
1012 * Send only changed attributes at trigger firing time.
1013 */
1014 bool sendOnlyChangedAttributes;
1015
1016 /**
1017 * Send also before values at trigger firing time.
1018 */
1019 bool sendBeforeValues;
1020
1021 /**
1022 * Attribute mask, defines what attributes are to be monitored
1023 * Can be seen as a compact representation of SQL column name list
1024 */
1025 Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
1026
1027 /**
1028 * Next ptr (used in pool/list)
1029 */
1030 union {
1031 Uint32 nextPool;
1032 Uint32 nextList;
1033 };
1034
1035 /**
1036 * Prev pointer (used in list)
1037 */
1038 Uint32 prevList;
1039
printDbtup::TupTriggerData1040 inline void print(NdbOut & s) const { s << "[TriggerData = " << triggerId << "]"; }
1041 };
1042
1043 typedef Ptr<TupTriggerData> TriggerPtr;
1044 typedef ArrayPool<TupTriggerData> TupTriggerData_pool;
1045 typedef DLFifoList<TupTriggerData_pool> TupTriggerData_list;
1046
1047 /**
1048 * Pool of trigger data record
1049 */
1050 TupTriggerData_pool c_triggerPool;
1051
1052 /* ************ TABLE RECORD ************ */
1053 /* THIS RECORD FORMS A LIST OF TABLE */
1054 /* REFERENCE INFORMATION. ONE RECORD */
1055 /* PER TABLE REFERENCE. */
1056 /* ************************************** */
1057 STATIC_CONST( MM = 0 );
1058 STATIC_CONST( DD = 1 );
1059 STATIC_CONST( DYN_BM_LEN_BITS = 8 );
1060 STATIC_CONST( DYN_BM_LEN_MASK = ((1 << DYN_BM_LEN_BITS) - 1));
1061
1062 /* Array length in the data structures like
1063 dynTabDescriptor, dynVarSizeMask, dynFixSizeMask, etc.
1064 1 for dynamic main memory data,
1065 2 for dynamic main memory and dynamic disk data.
1066 */
1067 STATIC_CONST( NO_DYNAMICS = 2 );
1068
1069 struct Tablerec {
TablerecDbtup::Tablerec1070 Tablerec(TupTriggerData_pool & triggerPool) :
1071 afterInsertTriggers(triggerPool),
1072 afterDeleteTriggers(triggerPool),
1073 afterUpdateTriggers(triggerPool),
1074 subscriptionInsertTriggers(triggerPool),
1075 subscriptionDeleteTriggers(triggerPool),
1076 subscriptionUpdateTriggers(triggerPool),
1077 constraintUpdateTriggers(triggerPool),
1078 deferredInsertTriggers(triggerPool),
1079 deferredUpdateTriggers(triggerPool),
1080 deferredDeleteTriggers(triggerPool),
1081 tuxCustomTriggers(triggerPool)
1082 {}
1083
1084 Bitmask<MAXNROFATTRIBUTESINWORDS> notNullAttributeMask;
1085 Bitmask<MAXNROFATTRIBUTESINWORDS> blobAttributeMask;
1086
1087 /*
1088 Extra table descriptor for dynamic attributes, or RNIL if none.
1089 The size of this depends on actual column definitions, so it is allocated
1090 _after_ seeing all columns, hence must be separate from the readKeyArray
1091 et al descriptor, which is allocated before seeing columns.
1092 */
1093 Uint32 dynTabDescriptor[2];
1094
1095 /* Mask of variable-sized dynamic attributes. */
1096 Uint32* dynVarSizeMask[2];
1097 /*
1098 Mask of fixed-sized dynamic attributes. There is one bit set for each
1099 32-bit word occupied by fixed-size attributes, so fixed-size dynamic
1100 attributes >32bit have multiple bits here.
1101 */
1102 Uint32* dynFixSizeMask[2];
1103
1104 ReadFunction* readFunctionArray;
1105 UpdateFunction* updateFunctionArray;
1106 CHARSET_INFO** charsetArray;
1107
1108 Uint32 readKeyArray;
1109 /*
1110 Offset into Dbtup::tableDescriptor of the start of the descriptor
1111 words for each attribute.
1112 For attribute i, the AttributeDescriptor word is stored at index
1113 Tablerec::tabDescriptor+i*ZAD_SIZE, and the AttributeOffset word at
1114 index Tablerec::tabDescriptor+i*ZAD_SIZE+1.
1115 */
1116 Uint32 tabDescriptor;
1117 /*
1118 Offset into Dbtup::tableDescriptor of memory used as an array of Uint16.
1119
1120 The values stored are offsets from Tablerec::tabDescriptor first for all
1121 fixed-sized static attributes, then static varsized attributes, then
1122 dynamic fixed-size, then dynamic varsized, and finally disk-stored fixed
1123 size:
1124 [mm_fix mm_var mm_dynfix mm_dynvar dd_fix]
1125 This is used to find the AttributeDescriptor and AttributeOffset words
1126 for an attribute. For example, the offset for the second dynamic
1127 fixed-size attribute is at index <num fixed> + <num varsize> + 1.
1128 */
1129 Uint32 m_real_order_descriptor;
1130
1131 enum Bits
1132 {
1133 TR_Checksum = 0x1, // Need to be 1
1134 TR_RowGCI = 0x2,
1135 TR_ForceVarPart = 0x4,
1136 TR_DiskPart = 0x8,
1137 TR_ExtraRowGCIBits = 0x10,
1138 TR_ExtraRowAuthorBits = 0x20
1139 };
1140 Uint16 m_bits;
1141 Uint16 total_rec_size; // Max total size for entire tuple in words
1142
1143 /**
1144 * Aggregates
1145 */
1146 Uint16 m_no_of_extra_columns; // "Hidden" columns
1147 Uint16 m_dyn_null_bits[2];
1148 Uint16 noOfKeyAttr;
1149 Uint16 noOfCharsets;
1150 Uint16 m_no_of_disk_attributes;
1151 Uint16 m_no_of_attributes;
1152
need_expandDbtup::Tablerec1153 bool need_expand() const {
1154 return m_no_of_attributes > m_attributes[MM].m_no_of_fixsize;
1155 }
1156
need_expandDbtup::Tablerec1157 bool need_expand(bool disk) const {
1158 return m_attributes[MM].m_no_of_varsize > 0 ||
1159 m_attributes[MM].m_no_of_dynamic > 0 ||
1160 (disk && m_no_of_disk_attributes > 0);
1161 }
1162
need_shrinkDbtup::Tablerec1163 bool need_shrink() const {
1164 return
1165 m_attributes[MM].m_no_of_varsize > 0 ||
1166 m_attributes[MM].m_no_of_dynamic > 0 ||
1167 m_attributes[DD].m_no_of_varsize > 0;
1168 }
1169
need_shrinkDbtup::Tablerec1170 bool need_shrink(bool disk) const {
1171 return
1172 m_attributes[MM].m_no_of_varsize > 0 ||
1173 m_attributes[MM].m_no_of_dynamic > 0 ||
1174 (disk && m_attributes[DD].m_no_of_varsize > 0);
1175 }
1176
getExtraAttrIdDbtup::Tablerec1177 template <Uint32 bit> Uint32 getExtraAttrId() const {
1178 if (bit == TR_ExtraRowGCIBits)
1179 return 0;
1180 Uint32 no = 0;
1181 if (m_bits & TR_ExtraRowGCIBits)
1182 no++;
1183 assert(bit == TR_ExtraRowAuthorBits);
1184 //if (bit == TR_ExtraRowAuthorBits)
1185 return no;
1186 }
1187
1188 struct {
1189 Uint16 m_no_of_fixsize;
1190 Uint16 m_no_of_varsize;
1191 Uint16 m_no_of_dynamic; // Total no. of dynamic attrs
1192 Uint16 m_no_of_dyn_fix; // No. of fixsize dynamic
1193 Uint16 m_no_of_dyn_var; // No. of varsize dynamic
1194 /*
1195 Note that due to bit types, we may have
1196 m_no_of_dynamic > m_no_of_dyn_fix + m_no_of_dyn_var
1197 */
1198 } m_attributes[2];
1199
1200 /**
1201 * Descriptors for MM and DD part
1202 */
1203 struct Tuple_offsets {
1204 Uint8 m_null_words;
1205 Uint8 m_null_offset;
1206 Uint16 m_disk_ref_offset; // In words relative m_data
1207 Uint16 m_fix_header_size; // For fix size tuples= total rec size(part)
1208 Uint16 m_max_var_offset; // In bytes relative m_var_data.m_data_ptr
1209 Uint16 m_max_dyn_offset; // In bytes relative m_var_data.m_dyn_data_ptr
1210 Uint16 m_dyn_null_words; // 32-bit words in dynattr bitmap
1211 } m_offsets[2];
1212
get_check_offsetDbtup::Tablerec1213 Uint32 get_check_offset(Uint32 mm) const {
1214 return m_offsets[mm].m_fix_header_size;
1215 }
1216
1217 // Lists of trigger data for active triggers
1218 TupTriggerData_list afterInsertTriggers;
1219 TupTriggerData_list afterDeleteTriggers;
1220 TupTriggerData_list afterUpdateTriggers;
1221 TupTriggerData_list subscriptionInsertTriggers;
1222 TupTriggerData_list subscriptionDeleteTriggers;
1223 TupTriggerData_list subscriptionUpdateTriggers;
1224 TupTriggerData_list constraintUpdateTriggers;
1225 TupTriggerData_list deferredInsertTriggers;
1226 TupTriggerData_list deferredUpdateTriggers;
1227 TupTriggerData_list deferredDeleteTriggers;
1228
1229 // List of ordered indexes
1230 TupTriggerData_list tuxCustomTriggers;
1231
1232 Uint32 fragid[MAX_FRAG_PER_LQH];
1233 Uint32 fragrec[MAX_FRAG_PER_LQH];
1234
1235 union {
1236 struct {
1237 Uint32 tabUserPtr;
1238 Uint32 tabUserRef;
1239 Uint32 m_outstanding_ops;
1240 Uint32 m_fragPtrI;
1241 Uint32 m_filePointer;
1242 Uint16 m_firstFileId;
1243 Uint16 m_lastFileId;
1244 Uint16 m_numDataFiles;
1245 Uint8 m_file_type;
1246 Uint8 m_lcpno;
1247 } m_dropTable;
1248 struct {
1249 Uint32 m_fragOpPtrI;
1250 Uint32 defValSectionI;
1251 Local_key defValLocation;
1252 } m_createTable;
1253 struct {
1254 Uint32 m_gci_hi;
1255 } m_reorg_suma_filter;
1256 };
1257
1258 State tableStatus;
1259 Local_key m_default_value_location;
1260 };
1261 Uint32
1262 m_read_ctl_file_data[BackupFormat::LCP_CTL_FILE_BUFFER_SIZE_IN_WORDS];
1263 /*
1264 It is more space efficient to store dynamic fixed-size attributes
1265 of more than about 16 words as variable-sized internally.
1266 */
1267 STATIC_CONST(InternalMaxDynFix= 16);
1268
1269 struct Disk_undo
1270 {
1271 enum
1272 {
1273 UNDO_ALLOC = File_formats::Undofile::UNDO_TUP_ALLOC
1274 ,UNDO_UPDATE = File_formats::Undofile::UNDO_TUP_UPDATE
1275 ,UNDO_FREE = File_formats::Undofile::UNDO_TUP_FREE
1276 ,UNDO_DROP = File_formats::Undofile::UNDO_TUP_DROP
1277 ,UNDO_UPDATE_PART = File_formats::Undofile::UNDO_TUP_UPDATE_PART
1278 ,UNDO_FIRST_UPDATE_PART =
1279 File_formats::Undofile::UNDO_TUP_FIRST_UPDATE_PART
1280 ,UNDO_FREE_PART = File_formats::Undofile::UNDO_TUP_FREE_PART
1281 };
1282
1283 struct Alloc
1284 {
1285 Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1286 Uint32 m_page_no;
1287 Uint32 m_type_length; // 16 bit type, 16 bit length
1288 };
1289
1290 struct Update
1291 {
1292 Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1293 Uint32 m_page_no;
1294 Uint32 m_gci;
1295 Uint32 m_data[1];
1296 Uint32 m_type_length; // 16 bit type, 16 bit length
1297 };
1298
1299 struct UpdatePart
1300 {
1301 Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1302 Uint32 m_page_no;
1303 Uint32 m_gci;
1304 Uint32 m_offset;
1305 Uint32 m_data[1];
1306 Uint32 m_type_length; // 16 bit type, 16 bit length
1307 };
1308
1309 struct Free
1310 {
1311 Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
1312 Uint32 m_page_no;
1313 Uint32 m_gci;
1314 Uint32 m_data[1];
1315 Uint32 m_type_length; // 16 bit type, 16 bit length
1316 };
1317
1318 struct Create
1319 {
1320 Uint32 m_table;
1321 Uint32 m_type_length; // 16 bit type, 16 bit length
1322 };
1323
1324 struct Drop
1325 {
1326 Uint32 m_table;
1327 Uint32 m_type_length; // 16 bit type, 16 bit length
1328 };
1329 };
1330
1331 Extent_info_pool c_extent_pool;
1332 Extent_info_hash c_extent_hash;
1333 Page_request_pool c_page_request_pool;
1334
1335 typedef Ptr<Tablerec> TablerecPtr;
1336
1337 struct storedProc {
1338 STATIC_CONST(TYPE_ID = RT_DBTUP_STORED_PROCEDURE);
1339 Uint32 m_magic;
1340
storedProcDbtup::storedProc1341 storedProc() :
1342 m_magic(Magic::make(TYPE_ID))
1343 {
1344 }
1345
~storedProcDbtup::storedProc1346 ~storedProc()
1347 {
1348 }
1349
1350 Uint32 storedProcIVal;
1351 Uint32 nextPool;
1352 Uint16 storedCode;
1353 };
1354 typedef Ptr<storedProc> StoredProcPtr;
1355 typedef TransientPool<storedProc> StoredProc_pool;
1356 STATIC_CONST(DBTUP_STORED_PROCEDURE_TRANSIENT_POOL_INDEX = 1);
1357
1358 StoredProc_pool c_storedProcPool;
1359 RSS_AP_SNAPSHOT(c_storedProcPool);
1360 Uint32 c_storedProcCountNonAPI;
1361 void storedProcCountNonAPI(BlockReference apiBlockref, int add_del);
1362
1363 /* **************************** TABLE_DESCRIPTOR RECORD ******************************** */
1364 /* THIS VARIABLE IS USED TO STORE TABLE DESCRIPTIONS. A TABLE DESCRIPTION IS STORED AS A */
1365 /* CONTIGUOS ARRAY IN THIS VARIABLE. WHEN A NEW TABLE IS ADDED A CHUNK IS ALLOCATED IN */
1366 /* THIS RECORD. WHEN ATTRIBUTES ARE ADDED TO THE TABLE, A NEW CHUNK OF PROPER SIZE IS */
1367 /* ALLOCATED AND ALL DATA IS COPIED TO THIS NEW CHUNK AND THEN THE OLD CHUNK IS PUT IN */
1368 /* THE FREE LIST. EACH TABLE IS DESCRIBED BY A NUMBER OF TABLE DESCRIPTIVE ATTRIBUTES */
1369 /* AND A NUMBER OF ATTRIBUTE DESCRIPTORS AS SHOWN IN FIGURE BELOW */
1370 /* */
1371 /* WHEN ALLOCATING A TABLE DESCRIPTOR THE SIZE IS ALWAYS A MULTIPLE OF 16 WORDS. */
1372 /* */
1373 /* ---------------------------------------------- */
1374 /* | TRAILER USED FOR ALLOC/DEALLOC | */
1375 /* ---------------------------------------------- */
1376 /* | TABLE DESCRIPTIVE ATTRIBUTES | */
1377 /* ---------------------------------------------- */
1378 /* | ATTRIBUTE DESCRIPTION 1 | */
1379 /* ---------------------------------------------- */
1380 /* | ATTRIBUTE DESCRIPTION 2 | */
1381 /* ---------------------------------------------- */
1382 /* | | */
1383 /* | | */
1384 /* | | */
1385 /* ---------------------------------------------- */
1386 /* | ATTRIBUTE DESCRIPTION N | */
1387 /* ---------------------------------------------- */
1388 /* */
1389 /* THE TABLE DESCRIPTIVE ATTRIBUTES CONTAINS THE FOLLOWING ATTRIBUTES: */
1390 /* */
1391 /* ---------------------------------------------- */
1392 /* | HEADER (TYPE OF INFO) | */
1393 /* ---------------------------------------------- */
1394 /* | SIZE OF WHOLE CHUNK (INCL. TRAILER) | */
1395 /* ---------------------------------------------- */
1396 /* | TABLE IDENTITY | */
1397 /* ---------------------------------------------- */
1398 /* | FRAGMENT IDENTITY | */
1399 /* ---------------------------------------------- */
1400 /* | NUMBER OF ATTRIBUTES | */
1401 /* ---------------------------------------------- */
1402 /* | SIZE OF FIXED ATTRIBUTES | */
1403 /* ---------------------------------------------- */
1404 /* | NUMBER OF NULL FIELDS | */
1405 /* ---------------------------------------------- */
1406 /* | NOT USED | */
1407 /* ---------------------------------------------- */
1408 /* */
1409 /* THESE ATTRIBUTES ARE ALL ONE R-VARIABLE IN THE RECORD. */
1410 /* NORMALLY ONLY ONE TABLE DESCRIPTOR IS USED. DURING SCHEMA CHANGES THERE COULD */
1411 /* HOWEVER EXIST MORE THAN ONE TABLE DESCRIPTION SINCE THE SCHEMA CHANGE OF VARIOUS */
1412 /* FRAGMENTS ARE NOT SYNCHRONISED. THIS MEANS THAT ALTHOUGH THE SCHEMA HAS CHANGED */
1413 /* IN ALL FRAGMENTS, BUT THE FRAGMENTS HAVE NOT REMOVED THE ATTRIBUTES IN THE SAME */
1414 /* TIME-FRAME. THEREBY SOME ATTRIBUTE INFORMATION MIGHT DIFFER BETWEEN FRAGMENTS. */
1415 /* EXAMPLES OF ATTRIBUTES THAT MIGHT DIFFER ARE SIZE OF FIXED ATTRIBUTES, NUMBER OF */
1416 /* ATTRIBUTES, FIELD START WORD, START BIT. */
1417 /* */
1418 /* AN ATTRIBUTE DESCRIPTION CONTAINS THE FOLLOWING ATTRIBUTES: */
1419 /* */
1420 /* ---------------------------------------------- */
1421 /* | Field Type, 4 bits (LSB Bits) | */
1422 /* ---------------------------------------------- */
1423 /* | Attribute Size, 4 bits | */
1424 /* ---------------------------------------------- */
1425 /* | NULL indicator 1 bit | */
1426 /* ---------------------------------------------- */
1427 /* | Indicator if TUP stores attr. 1 bit | */
1428 /* ---------------------------------------------- */
1429 /* | Not used 6 bits | */
1430 /* ---------------------------------------------- */
1431 /* | No. of elements in fixed array 16 bits | */
1432 /* ---------------------------------------------- */
1433 /* ---------------------------------------------- */
1434 /* | Field Start Word, 21 bits (LSB Bits) | */
1435 /* ---------------------------------------------- */
1436 /* | NULL Bit, 11 bits | */
1437 /* ---------------------------------------------- */
1438 /* */
1439 /* THE ATTRIBUTE SIZE CAN BE 1,2,4,8,16,32,64 AND 128 BITS. */
1440 /* */
1441 /* THE UNUSED PARTS OF THE RECORDS ARE PUT IN A LINKED LIST OF FREE PARTS. EACH OF */
1442 /* THOSE FREE PARTS HAVE THREE RECORDS ASSIGNED AS SHOWN IN THIS STRUCTURE */
1443 /* ALL FREE PARTS ARE SET INTO A CHUNK LIST WHERE EACH CHUNK IS AT LEAST 16 WORDS */
1444 /* */
1445 /* ---------------------------------------------- */
1446 /* | HEADER = RNIL | */
1447 /* ---------------------------------------------- */
1448 /* | SIZE OF FREE AREA | */
1449 /* ---------------------------------------------- */
1450 /* | POINTER TO PREVIOUS FREE AREA | */
1451 /* ---------------------------------------------- */
1452 /* | POINTER TO NEXT FREE AREA | */
1453 /* ---------------------------------------------- */
1454 /* */
1455 /* IF THE POINTER TO THE NEXT AREA IS RNIL THEN THIS IS THE LAST FREE AREA. */
1456 /* */
1457 /*****************************************************************************************/
1458 struct TableDescriptor {
1459 Uint32 tabDescr;
1460 };
1461 typedef Ptr<TableDescriptor> TableDescriptorPtr;
1462
1463 struct HostBuffer {
1464 bool inPackedList;
1465 Uint32 packetLenTA;
1466 Uint32 noOfPacketsTA;
1467 Uint32 packetBufferTA[30];
1468 };
1469 typedef Ptr<HostBuffer> HostBufferPtr;
1470
1471 /*
1472 * Build index operation record.
1473 */
1474 struct BuildIndexRec {
BuildIndexRecDbtup::BuildIndexRec1475 BuildIndexRec() {}
1476
1477 BuildIndxImplReq m_request;
1478 Uint8 m_build_vs; // varsize pages
1479 Uint32 m_indexId; // the index
1480 Uint32 m_fragNo; // fragment number under Tablerec
1481 Uint32 m_pageId; // logical fragment page id
1482 Uint32 m_tupleNo; // tuple number on page
1483 Uint32 m_buildRef; // Where to send tuples
1484 Uint32 m_outstanding; // If mt-build...
1485 BuildIndxImplRef::ErrorCode m_errorCode;
1486 union {
1487 Uint32 nextPool;
1488 Uint32 nextList;
1489 };
1490 Uint32 prevList;
1491 };
1492 typedef Ptr<BuildIndexRec> BuildIndexPtr;
1493 typedef ArrayPool<BuildIndexRec> BuildIndexRec_pool;
1494 typedef DLList<BuildIndexRec_pool> BuildIndexRec_list;
1495 BuildIndexRec_pool c_buildIndexPool;
1496 BuildIndexRec_list c_buildIndexList;
1497 Uint32 c_noOfBuildIndexRec;
1498
1499 int mt_scan_init(Uint32 tableId, Uint32 fragId, Local_key * pos, Uint32 * fragPtrI);
1500 int mt_scan_next(Uint32 tableId, Uint32 fragPtrI, Local_key* pos, bool moveNext);
1501
1502 /**
1503 * Reference to variable part when a tuple is chained
1504 */
1505 struct Var_part_ref
1506 {
1507 Uint32 m_page_no;
1508 Uint32 m_page_idx;
1509 STATIC_CONST( SZ32 = 2 );
1510
copyoutDbtup::Var_part_ref1511 void copyout(Local_key* dst) const {
1512 dst->m_page_no = m_page_no;
1513 dst->m_page_idx = m_page_idx;
1514 }
1515
assignDbtup::Var_part_ref1516 void assign(const Local_key* src) {
1517 m_page_no = src->m_page_no;
1518 m_page_idx = src->m_page_idx;
1519 }
1520 };
1521
1522 struct Disk_part_ref
1523 {
1524 STATIC_CONST( SZ32 = 2 );
1525 };
1526
1527 struct Tuple_header
1528 {
1529 union {
1530 /**
1531 * List of prepared operations for this tuple.
1532 * Points to most recent/last operation, ie. to walk the list must follow
1533 * regOperPtr->prevActiveOp links.
1534 */
1535 Uint32 m_operation_ptr_i; // OperationPtrI
1536 Uint32 m_base_record_page_no; // For disk tuple, ref to MM tuple
1537 Uint32 m_first_words[1];
1538 };
1539 union
1540 {
1541 Uint32 m_header_bits; // Header word
1542 Uint32 m_base_record_page_idx; // For disk tuple, ref to MM tuple
1543 };
1544 union {
1545 Uint32 m_checksum;
1546 Uint32 m_data[1];
1547 Uint32 m_null_bits[1];
1548 };
1549
1550 STATIC_CONST( HeaderSize = 2 );
1551
1552 /*
1553 Header bits.
1554
1555 MM_GROWN: When a tuple is updated to a bigger size, the original varpart
1556 of the tuple is immediately re-allocated to a location with sufficient
1557 size for the new data (but containing only the original smaller-sized
1558 data). This is so that commit can be sure to find room for the extra
1559 data. In the case of abort, the varpart must then be shrunk. For a
1560 MM_GROWN tuple, the original size is stored in the last word of the
1561 varpart until commit.
1562
1563 DELETE_WAIT: When a tuple has been marked to be deleted, the tuple header
1564 has the DELETE_WAIT bit set. Note that DELETE_WAIT means that the tuple
1565 hasn't actually been deleted. When a tuple has been deleted, it is marked
1566 with the FREE flag and DELETE_WAIT is reset.
1567 The need for DELETE_WAIT arises due to the real-time break between the
1568 marking of the tuple and the actual deletion of the tuple for disk data
1569 rows. This information would be useful for reads since they'd know the
1570 proper state of the row. (Related Bug #27584165)
1571 */
1572 STATIC_CONST( TUP_VERSION_MASK = 0xFFFF );
1573 STATIC_CONST( COPY_TUPLE = 0x00010000 ); // Is this a copy tuple
1574 STATIC_CONST( DISK_PART = 0x00020000 ); // Is there a disk part
1575 STATIC_CONST( DISK_ALLOC = 0x00040000 ); // Is disk part allocated
1576 STATIC_CONST( DISK_INLINE = 0x00080000 ); // Is disk inline
1577 STATIC_CONST( ALLOC = 0x00100000 ); // Is record allocated now
1578 STATIC_CONST( NOT_USED_BIT= 0x00200000 ); //
1579 STATIC_CONST( MM_GROWN = 0x00400000 ); // Has MM part grown
1580 STATIC_CONST( FREE = 0x00800000 ); // Is free
1581 STATIC_CONST( LCP_SKIP = 0x01000000 ); // Should not be returned in LCP
1582 STATIC_CONST( VAR_PART = 0x04000000 ); // Is there a varpart
1583 STATIC_CONST( REORG_MOVE = 0x08000000 ); // Tuple will be moved in reorg
1584 STATIC_CONST( LCP_DELETE = 0x10000000 ); // Tuple deleted at LCP start
1585 STATIC_CONST( DELETE_WAIT = 0x20000000 ); // Waiting for delete tuple page
1586
Tuple_headerDbtup::Tuple_header1587 Tuple_header() {}
get_tuple_versionDbtup::Tuple_header1588 Uint32 get_tuple_version() const {
1589 return m_header_bits & TUP_VERSION_MASK;
1590 }
set_tuple_versionDbtup::Tuple_header1591 void set_tuple_version(Uint32 version) {
1592 m_header_bits=
1593 (m_header_bits & ~(Uint32)TUP_VERSION_MASK) |
1594 (version & TUP_VERSION_MASK);
1595 }
get_base_record_refDbtup::Tuple_header1596 void get_base_record_ref(Local_key& key)
1597 {
1598 require(m_base_record_page_idx <= MAX_TUPLES_PER_PAGE);
1599 key.m_page_no = m_base_record_page_no;
1600 key.m_page_idx = m_base_record_page_idx;
1601 }
set_base_record_refDbtup::Tuple_header1602 void set_base_record_ref(Local_key key)
1603 {
1604 m_base_record_page_no = key.m_page_no;
1605 m_base_record_page_idx = key.m_page_idx;
1606 }
get_null_bitsDbtup::Tuple_header1607 Uint32* get_null_bits(const Tablerec* tabPtrP) {
1608 return m_null_bits+tabPtrP->m_offsets[MM].m_null_offset;
1609 }
1610
get_null_bitsDbtup::Tuple_header1611 Uint32* get_null_bits(const Tablerec* tabPtrP, Uint32 mm) {
1612 return m_null_bits+tabPtrP->m_offsets[mm].m_null_offset;
1613 }
1614
get_var_part_ref_ptrDbtup::Tuple_header1615 Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) {
1616 return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
1617 }
1618
get_var_part_ref_ptrDbtup::Tuple_header1619 const Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) const {
1620 return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
1621 }
1622
get_end_of_fix_part_ptrDbtup::Tuple_header1623 Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) {
1624 return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
1625 Tuple_header::HeaderSize;
1626 }
1627
get_end_of_fix_part_ptrDbtup::Tuple_header1628 const Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) const {
1629 return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
1630 Tuple_header::HeaderSize;
1631 }
1632
get_disk_ref_ptrDbtup::Tuple_header1633 Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) {
1634 return m_first_words + tabPtrP->m_offsets[MM].m_disk_ref_offset;
1635 }
1636
get_disk_ref_ptrDbtup::Tuple_header1637 const Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) const {
1638 return m_first_words + tabPtrP->m_offsets[MM].m_disk_ref_offset;
1639 }
1640
get_mm_gciDbtup::Tuple_header1641 Uint32 *get_mm_gci(const Tablerec* tabPtrP){
1642 /* Mandatory position even if TR_RowGCI isn't set (happens in restore */
1643 return m_data + (tabPtrP->m_bits & Tablerec::TR_Checksum);
1644 }
1645
get_dd_gciDbtup::Tuple_header1646 Uint32 *get_dd_gci(const Tablerec* tabPtrP, Uint32 mm){
1647 assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
1648 return m_data;
1649 }
1650 };
1651
1652 /**
1653 * Format of varpart after insert/update
1654 */
1655 struct Varpart_copy
1656 {
1657 Uint32 m_len;
1658 Uint32 m_data[1]; // Only used for easy offset handling
1659
1660 STATIC_CONST( SZ32 = 1 );
1661 };
1662
1663 static constexpr Uint32 MAX_EXPANDED_TUPLE_SIZE_IN_WORDS =
1664 Tuple_header::HeaderSize +
1665
1666 /* Fixpart without null bits (see below) */
1667 1 /* checksum */ +
1668 1 /* GCI */ +
1669 Var_part_ref::SZ32 +
1670 Disk_part_ref::SZ32 +
1671
1672 /* Varpart without dynamic column bits (see below) */
1673 1 /* Length word, only in expanded tuple */ +
1674 ndb_ceil_div(MAX_ATTRIBUTES_IN_TABLE + 1 /* dynamic part */, 2) +
1675 1 /* Dynamic bit length (8bit) plus padding */ +
1676
1677 /* Diskpart */
1678 0 +
1679
1680 /* Null bits and dynamic columns bits. Dynamic columns do not have null
1681 bits so total number of bits will not be more than
1682 MAX_ATTRIBUTES_IN_TABLE. But since bits are splitted on two parts an
1683 extra word for padding may be needed.
1684 */
1685 ndb_ceil_div(MAX_ATTRIBUTES_IN_TABLE, 32) + 1 +
1686
1687 /* Tuple data for all parts */
1688 MAX_TUPLE_SIZE_IN_WORDS;
1689
1690 enum When
1691 {
1692 KRS_PREPARE = 0,
1693 KRS_COMMIT = 1,
1694 KRS_PRE_COMMIT_BASE = 2,
1695 KRS_UK_PRE_COMMIT0 = KRS_PRE_COMMIT_BASE + TriggerPreCommitPass::UK_PASS_0,
1696 KRS_UK_PRE_COMMIT1 = KRS_PRE_COMMIT_BASE + TriggerPreCommitPass::UK_PASS_1,
1697 KRS_FK_PRE_COMMIT = KRS_PRE_COMMIT_BASE + TriggerPreCommitPass::FK_PASS_0
1698 };
1699
1700 struct KeyReqStruct {
1701
KeyReqStructDbtup::KeyReqStruct1702 KeyReqStruct(EmulatedJamBuffer * _jamBuffer, When when) :
1703 changeMask()
1704 {
1705 #if defined VM_TRACE || defined ERROR_INSERT
1706 memset(this, 0xf3, sizeof(* this));
1707 #endif
1708 jamBuffer = _jamBuffer;
1709 m_when = when;
1710 m_deferred_constraints = true;
1711 m_disable_fk_checks = false;
1712 m_tuple_ptr = NULL;
1713 }
1714
KeyReqStructDbtup::KeyReqStruct1715 KeyReqStruct(EmulatedJamBuffer * _jamBuffer) :
1716 changeMask(false)
1717 {
1718 #if defined VM_TRACE || defined ERROR_INSERT
1719 memset(this, 0xf3, sizeof(* this));
1720 #endif
1721 jamBuffer = _jamBuffer;
1722 m_when = KRS_PREPARE;
1723 m_deferred_constraints = true;
1724 m_disable_fk_checks = false;
1725 }
1726
KeyReqStructDbtup::KeyReqStruct1727 KeyReqStruct(Dbtup* tup) :
1728 changeMask(false)
1729 {
1730 #if defined VM_TRACE || defined ERROR_INSERT
1731 memset(this, 0xf3, sizeof(* this));
1732 #endif
1733 jamBuffer = tup->jamBuffer();
1734 m_when = KRS_PREPARE;
1735 m_deferred_constraints = true;
1736 m_disable_fk_checks = false;
1737 }
1738
KeyReqStructDbtup::KeyReqStruct1739 KeyReqStruct(Dbtup* tup, When when) :
1740 changeMask()
1741 {
1742 #if defined VM_TRACE || defined ERROR_INSERT
1743 memset(this, 0xf3, sizeof(* this));
1744 #endif
1745 jamBuffer = tup->jamBuffer();
1746 m_when = when;
1747 m_deferred_constraints = true;
1748 m_disable_fk_checks = false;
1749 m_tuple_ptr = NULL;
1750 }
1751
1752 /**
1753 * These variables are used as temporary storage during execution of the
1754 * TUPKEYREQ signal.
1755 *
1756 * The first set of variables defines a number of variables needed for
1757 * the fix part of the tuple.
1758 *
1759 * The second part defines a number of commonly used meta data variables.
1760 *
1761 * The third part is variables needed only for updates and inserts.
1762 *
1763 * The fourth set of variables defines a set of variables needed for the
1764 * variable part.
1765 *
1766 * The fifth part is a long array of real lengths which is is put last
1767 * for cache memory reasons. This is part of the variable part and
1768 * contains the real allocated lengths whereas the tuple contains
1769 * the length of attribute stored.
1770 */
1771
1772 Tablerec* tablePtrP;
1773 Fragrecord* fragPtrP;
1774 Operationrec * operPtrP;
1775 EmulatedJamBuffer * jamBuffer;
1776 Tuple_header *m_tuple_ptr;
1777
1778 /**
1779 * Variables often used in read of columns
1780 */
1781 TableDescriptor *attr_descr;
1782 Uint32 check_offset[2];
1783 Uint32 max_read;
1784 Uint32 out_buf_index;
1785
1786 Uint32 out_buf_bits;
1787 Uint32 in_buf_index;
1788
1789
1790 union {
1791 Uint32 in_buf_len;
1792 Uint32 m_lcp_varpart_len;
1793 };
1794 Uint32 errorCode; // Used in DbtupRoutines read/update functions
1795 bool xfrm_flag;
1796
1797 /* Flag: is tuple in expanded or in shrunken/stored format? */
1798 bool is_expanded;
1799 bool m_is_lcp;
1800 enum When m_when;
1801
1802 Tuple_header *m_disk_ptr;
1803 PagePtr m_page_ptr;
1804 PagePtr m_varpart_page_ptr; // could be same as m_page_ptr_p
1805 PagePtr m_disk_page_ptr; //
1806 Local_key m_row_id;
1807 Uint32 optimize_options;
1808
1809 bool dirty_op;
1810 bool interpreted_exec;
1811 bool last_row;
1812 bool m_use_rowid;
1813 bool m_nr_copy_or_redo;
1814 Uint8 m_reorg;
1815 Uint8 m_prio_a_flag;
1816 bool m_deferred_constraints;
1817 bool m_disable_fk_checks;
1818
1819 Signal* signal;
1820 Uint32 num_fired_triggers;
1821 Uint32 no_exec_instructions;
1822 Uint32 frag_page_id;
1823 Uint32 hash_value;
1824 Uint32 gci_hi;
1825 Uint32 gci_lo;
1826 Uint32 log_size;
1827 Uint32 read_length;
1828 Uint32 attrinfo_len;
1829 Uint32 tc_operation_ptr;
1830 Uint32 trans_id1;
1831 Uint32 trans_id2;
1832 Uint32 TC_index;
1833 // next 2 apply only to attrids >= 64 (zero otherwise)
1834 BlockReference TC_ref;
1835 BlockReference rec_blockref;
1836
1837 struct Var_data {
1838 /*
1839 These are the pointers and offsets to the variable-sized part of the row
1840 (static part, alwways stored even if NULL). They are used both for
1841 expanded and shrunken form, with different values to allow using the
1842 same read/update code for both forms.
1843 */
1844 char *m_data_ptr;
1845 Uint16 *m_offset_array_ptr;
1846 Uint16 m_var_len_offset;
1847 Uint16 m_max_var_offset;
1848 Uint16 m_max_dyn_offset;
1849
1850 /* These are the pointers and offsets to the dynamic part of the row. */
1851
1852 /* Pointer to the start of the bitmap for the dynamic part of the row. */
1853 char *m_dyn_data_ptr;
1854 /* Number of 32-bit words in dynamic part (stored/shrunken format). */
1855 Uint32 m_dyn_part_len;
1856 /*
1857 Pointer to array with one element for each dynamic attribute (both
1858 variable and fixed size). Each value is the offset from the end of the
1859 bitmap to the start of the data for that attribute.
1860 */
1861 Uint16 *m_dyn_offset_arr_ptr;
1862 /*
1863 Offset from m_dyn_offset_array_ptr of array with one element for each
1864 dynamic attribute. Each value is the offset to the end of data for that
1865 attribute, so the difference to m_dyn_offset_array_ptr elements provides
1866 the data lengths.
1867 */
1868 Uint16 m_dyn_len_offset;
1869 } m_var_data[2];
1870
1871 /*
1872 * A bit mask where a bit set means that the update or insert
1873 * was updating this record.
1874 */
1875 Bitmask<MAXNROFATTRIBUTESINWORDS> changeMask;
1876 Uint16 var_pos_array[2*MAX_ATTRIBUTES_IN_TABLE + 1];
1877 OperationrecPtr prevOpPtr;
1878 };
1879
1880 friend struct Undo_buffer;
1881 Undo_buffer c_undo_buffer;
1882
1883 /*
1884 No longer used:
1885 Implemented by shift instructions in subroutines instead
1886
1887 struct TupHeadInfo {
1888 struct BitPart {
1889 unsigned int disk_indicator : 1;
1890 unsigned int var_part_loc_ind : 1;
1891 unsigned int initialised : 1;
1892 unsigned int not_used_yet : 5;
1893 unsigned int no_var_sized : 8;
1894 unsigned int tuple_version : 16;
1895 };
1896 union {
1897 Uint32 all;
1898 BitPart bit_part;
1899 };
1900 };
1901 */
1902
1903 struct ChangeMask
1904 {
1905 Uint32 m_cols;
1906 Uint32 m_mask[1];
1907
end_of_maskDbtup::ChangeMask1908 const Uint32 * end_of_mask() const { return end_of_mask(m_cols); }
end_of_maskDbtup::ChangeMask1909 const Uint32 * end_of_mask(Uint32 cols) const {
1910 return m_mask + ((cols + 31) >> 5);
1911 }
1912
end_of_maskDbtup::ChangeMask1913 Uint32 * end_of_mask() { return end_of_mask(m_cols); }
end_of_maskDbtup::ChangeMask1914 Uint32 * end_of_mask(Uint32 cols) {
1915 return m_mask + ((cols + 31) >> 5);
1916 }
1917 };
1918
1919 // updateAttributes module
1920 Uint32 terrorCode;
1921
1922 public:
1923 Dbtup(Block_context&, Uint32 instanceNumber = 0);
1924 virtual ~Dbtup();
1925
1926 /*
1927 * TUX uses logical tuple address when talking to ACC and LQH.
1928 */
1929 void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset,
1930 Uint32& lkey1, Uint32& lkey2);
1931
1932 /*
1933 * TUX index in TUP has single Uint32 array attribute which stores an
1934 * index node. TUX reads and writes the node directly via pointer.
1935 */
1936 int tuxAllocNode(EmulatedJamBuffer*,
1937 Uint32* fragPtrP,
1938 Uint32* tablePtrP,
1939 Uint32& pageId,
1940 Uint32& pageOffset,
1941 Uint32*& node);
1942 void tuxFreeNode(Uint32* fragPtrP,
1943 Uint32* tablePtrP,
1944 Uint32 pageId,
1945 Uint32 pageOffset,
1946 Uint32* node);
1947 void tuxGetNode(Uint32 attrDataOffset,
1948 Uint32 tuxFixHeaderSize,
1949 Uint32 pageId,
1950 Uint32 pageOffset,
1951 Uint32*& node);
1952
1953 /*
1954 * TUX reads primary table attributes for index keys. Tuple is
1955 * specified by location of original tuple and version number. Input
1956 * is attribute ids in AttributeHeader format. Output is attribute
1957 * data with headers. Uses readAttributes with xfrm option set.
1958 * After wl4163, xfrm is not set.
1959 * Returns number of words or negative (-terrorCode) on error.
1960 */
1961 int tuxReadAttrs(EmulatedJamBuffer*,
1962 Uint32 fragPtrI,
1963 Uint32 pageId,
1964 Uint32 pageOffset,
1965 Uint32 tupVersion,
1966 const Uint32* attrIds,
1967 Uint32 numAttrs,
1968 Uint32* dataOut,
1969 bool xfrmFlag);
1970 int tuxReadAttrsOpt(EmulatedJamBuffer*,
1971 Uint32* fragPtrP,
1972 Uint32* tablePtrP,
1973 Uint32 pageId,
1974 Uint32 pageOffset,
1975 Uint32 tupVersion,
1976 const Uint32* attrIds,
1977 Uint32 numAttrs,
1978 Uint32* dataOut,
1979 bool xfrmFlag);
1980 int tuxReadAttrsCurr(EmulatedJamBuffer*,
1981 const Uint32* attrIds,
1982 Uint32 numAttrs,
1983 Uint32* dataOut,
1984 bool xfrmFlag,
1985 Uint32 tupVersion);
1986 int tuxReadAttrsCommon(KeyReqStruct &req_struct,
1987 const Uint32* attrIds,
1988 Uint32 numAttrs,
1989 Uint32* dataOut,
1990 bool xfrmFlag,
1991 Uint32 tupVersion);
1992
1993 /*
1994 * TUX reads primary key without headers into an array of words. Used
1995 * for md5 summing and when returning keyinfo. Returns number of
1996 * words or negative (-terrorCode) on error.
1997 */
1998 int tuxReadPk(Uint32* fragPtrP,
1999 Uint32* tablePtrP,
2000 Uint32 pageId,
2001 Uint32 pageOffset,
2002 Uint32* dataOut,
2003 bool xfrmFlag);
2004
2005 /*
2006 * ACC reads primary key without headers into an array of words. At
2007 * this point in ACC deconstruction, ACC still uses logical references
2008 * to fragment and tuple.
2009 */
2010 int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag);
2011
get_tuple_operation_ptr_i()2012 inline Uint32 get_tuple_operation_ptr_i()
2013 {
2014 Tuple_header *tuple_ptr = (Tuple_header*)prepare_tuple_ptr;
2015 return tuple_ptr->m_operation_ptr_i;
2016 }
2017 /*
2018 * TUX checks if tuple is visible to scan.
2019 */
2020 bool tuxQueryTh(Uint32 opPtrI,
2021 Uint32 tupVersion,
2022 Uint32 transId1,
2023 Uint32 transId2,
2024 bool dirty,
2025 Uint32 savepointId);
2026
2027 int load_diskpage(Signal*, Uint32 opRec, Uint32 fragPtrI,
2028 Uint32 lkey1, Uint32 lkey2, Uint32 flags);
2029
2030 int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI,
2031 Uint32 lkey1, Uint32 lkey2,
2032 Uint32 tux_flags, Uint32 disk_flag);
2033
2034 void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
2035 void complete_restore_lcp(Signal*,
2036 Uint32 ref,
2037 Uint32 data,
2038 Uint32 restoredLcpId,
2039 Uint32 restoredLocalLcpId,
2040 Uint32 maxGciCompleted,
2041 Uint32 maxGciWritten,
2042 Uint32 tableId,
2043 Uint32 fragmentId);
2044 Uint32 get_max_lcp_record_size(Uint32 tableId);
2045
2046 int nr_read_pk(Uint32 fragPtr, const Local_key*, Uint32* dataOut, bool©);
2047 int nr_update_gci(Uint32 fragPtr,
2048 const Local_key*,
2049 Uint32 gci,
2050 bool tuple_exists);
2051 int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci);
2052
2053 void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page);
2054 void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page);
2055
2056 bool get_frag_info(Uint32 tableId, Uint32 fragId, Uint32* maxPage);
2057
2058 void execSTORED_PROCREQ(Signal* signal);
2059
2060 void start_lcp_scan(Uint32 tableId,
2061 Uint32 fragmentId,
2062 Uint32 & max_page_cnt);
2063 void stop_lcp_scan(Uint32 tableId, Uint32 fragmentId);
2064 void lcp_frag_watchdog_print(Uint32 tableId, Uint32 fragmentId);
2065
2066 Uint64 get_restore_row_count(Uint32 tableId, Uint32 fragmentId);
2067 void set_lcp_start_gci(Uint32 fragPtrI, Uint32 startGci);
2068 void get_lcp_frag_stats(Uint32 fragPtrI,
2069 Uint32 startGci,
2070 Uint32 & maxPageCount,
2071 Uint64 & row_count,
2072 Uint64 & prev_row_count,
2073 Uint64 & row_change_count,
2074 Uint64 & memory_used_in_bytes,
2075 bool reset_flag);
2076
2077 // Statistics about fragment memory usage.
2078 struct FragStats
2079 {
2080 Uint64 committedRowCount;
2081 Uint64 committedChanges;
2082 // Size of fixed-size part of record.
2083 Uint32 fixedRecordBytes;
2084 // Page size (32k, see File_formats::NDB_PAGE_SIZE).
2085 Uint32 pageSizeBytes;
2086 // Number of fixed-size parts that fits in each page.
2087 Uint32 fixedSlotsPerPage;
2088 // Number of pages allocated for storing fixed-size parts.
2089 Uint64 fixedMemoryAllocPages;
2090 // Number of pages allocated for storing var-size parts.
2091 Uint64 varMemoryAllocPages;
2092 /**
2093 Number of bytes for storing var-size parts that are allocated but not yet
2094 used.
2095 */
2096 Uint64 varMemoryFreeBytes;
2097 // Number of fixed-size elements (i.e. number of rows.)
2098 Uint64 fixedElemCount;
2099 /**
2100 Number of var-size elements. There will be one for each row that has at
2101 least one non-null var-size field (varchar/varbinary/blob).
2102 */
2103 Uint64 varElemCount;
2104 // Size of the page map (DynArr256) that maps from logical to physical pages.
2105 Uint64 logToPhysMapAllocBytes;
2106 };
2107
2108 const FragStats get_frag_stats(Uint32 fragId) const;
2109
2110 private:
2111 BLOCK_DEFINES(Dbtup);
2112
2113 // Transit signals
2114 void execDEBUG_SIG(Signal* signal);
2115 void execCONTINUEB(Signal* signal);
2116
2117 // Received signals
2118 void execDUMP_STATE_ORD(Signal* signal);
2119 void execSEND_PACKED(Signal* signal);
2120 void execSTTOR(Signal* signal);
2121 void execTUP_LCPREQ(Signal* signal);
2122 void execEND_LCPREQ(Signal* signal);
2123 void execSTART_RECREQ(Signal* signal);
2124 void execMEMCHECKREQ(Signal* signal);
2125 void execTUPSEIZEREQ(Signal* signal);
2126 void execTUPRELEASEREQ(Signal* signal);
2127
2128 void execCREATE_TAB_REQ(Signal*);
2129 void execTUP_ADD_ATTRREQ(Signal* signal);
2130 void execTUPFRAGREQ(Signal* signal);
2131 void execTUP_COMMITREQ(Signal* signal);
2132 void execTUP_ABORTREQ(Signal* signal);
2133 void execNDB_STTOR(Signal* signal);
2134 void execREAD_CONFIG_REQ(Signal* signal);
2135 void execDROP_TAB_REQ(Signal* signal);
2136 void execALTER_TAB_REQ(Signal* signal);
2137 void execTUP_DEALLOCREQ(Signal* signal);
2138 void execTUP_WRITELOG_REQ(Signal* signal);
2139 void execNODE_FAILREP(Signal* signal);
2140
2141 void execDROP_FRAG_REQ(Signal*);
2142
2143 // Ordered index related
2144 void execBUILD_INDX_IMPL_REQ(Signal* signal);
2145 void execBUILD_INDX_IMPL_REF(Signal* signal);
2146 void execBUILD_INDX_IMPL_CONF(Signal* signal);
2147 void buildIndex(Signal* signal, Uint32 buildPtrI);
2148 void buildIndexReply(Signal* signal, const BuildIndexRec* buildRec);
2149 void buildIndexOffline(Signal* signal, Uint32 buildPtrI);
2150 void buildIndexOffline_table_readonly(Signal* signal, Uint32 buildPtrI);
2151 void execALTER_TAB_CONF(Signal*);
2152
2153 // Tup scan
2154 void execACC_SCANREQ(Signal* signal);
2155 void execNEXT_SCANREQ(Signal* signal);
2156 void execACC_CHECK_SCAN(Signal* signal);
2157 void execACCKEYCONF(Signal* signal);
2158 void execACCKEYREF(Signal* signal);
2159 void execACC_ABORTCONF(Signal* signal);
2160
2161
2162 // Drop table
2163 void execFSREMOVEREF(Signal*);
2164 void execFSREMOVECONF(Signal*);
2165 void execFSOPENREF(Signal*);
2166 void execFSOPENCONF(Signal*);
2167 void execFSREADREF(Signal*);
2168 void execFSREADCONF(Signal*);
2169 void execFSCLOSEREF(Signal*);
2170 void execFSCLOSECONF(Signal*);
2171
2172 void execDBINFO_SCANREQ(Signal*);
2173 void execSUB_GCP_COMPLETE_REP(Signal*);
2174
2175 //------------------------------------------------------------------
2176 //------------------------------------------------------------------
2177 // Methods to handle execution of TUPKEYREQ + ATTRINFO.
2178 //
2179 // Module Execution Manager
2180 //
2181 // The TUPKEYREQ signal is central to this block. This signal is used
2182 // by everybody that needs to read data residing in DBTUP. The data is
2183 // read using an interpreter approach.
2184 //
2185 // Operations only needing to read execute a simplified version of the
2186 // interpreter where the only instruction is read Attribute to send.
2187 // Operations only needing to update the record (insert or update)
2188 // execute a simplified version of the interpreter where the only
2189 // instruction is write Attribute.
2190 //
2191 // Currently TUPKEYREQ is used in the following situations.
2192 // 1) Normal transaction execution. Can be any of the types described
2193 // below.
2194 // 2) Execution of fragment redo log during system restart.
2195 // In this situation there will only be normal updates, inserts
2196 // and deletes performed.
2197 // 3) A special type of normal transaction execution is to write the
2198 // records arriving from the primary replica in the node restart
2199 // processing. This will always be normal write operations which
2200 // are translated to inserts or updates before arriving to TUP.
2201 // 4) Scan processing. The scan processing will use normal reads or
2202 // interpreted reads in their execution. There will be one TUPKEYREQ
2203 // signal for each record processed.
2204 // 5) Copy fragment processing. This is a special type of scan used in the
2205 // primary replica at system restart. It reads the entire reads and
2206 // converts those to writes to the starting node. In this special case
2207 // LQH acts as an API node and receives also the ATTRINFO sent in the
2208 // TRANSID_AI signals.
2209 //
2210 // Signal Diagram:
2211 //
2212 // In Signals:
2213 // -----------
2214 //
2215 // ---> TUPKEYREQ
2216 // A single TUPKEYREQ is received. The TUPKEYREQ can contain an I-value
2217 // for a long section containing AttrInfo words. Delete requests usually
2218 // contain no AttrInfo, and requests referencing a stored procedure (e.g.
2219 // scan originated requests) do not contain AttrInfo.
2220 //
2221 // The total size of the ATTRINFO is not allowed to be more than 16384 words.
2222 // There is always one and only one TUPKEYREQ.
2223 //
2224 // Response Signals (successful case):
2225 //
2226 // Simple/Dirty Read Operation
2227 // ---------------------------
2228 //
2229 // <---- TRANSID_AI (to API)
2230 // ...
2231 // <---- TRANSID_AI (to API)
2232 // <---- READCONF (to API)
2233 // <---- TUPKEYCONF (to LQH)
2234 // There is always exactly one READCONF25 sent last. The number of
2235 // TRANSID_AI is dependent on how much that was read. The maximum size
2236 // of the ATTRINFO sent back is 16384 words. The signals are sent
2237 // directly to the application with an address provided by the
2238 // TUPKEYREQ signal.
2239 // A positive response signal is also sent to LQH.
2240 //
2241 // Normal Read Operation
2242 // ---------------------
2243 //
2244 // <---- TRANSID_AI (to API)
2245 // ...
2246 // <---- TRANSID_AI (to API)
2247 // <---- TUPKEYCONF (to LQH)
2248 // The number of TRANSID_AI is dependent on how much that was read.
2249 // The maximum size of the ATTRINFO sent back is 16384 words. The
2250 // signals are sent directly to the application with an address
2251 // provided by the TUPKEYREQ signal.
2252 // A positive response signal is also sent to LQH.
2253 //
2254 // Normal update/insert/delete operation
2255 // -------------------------------------
2256 //
2257 // <---- TUPKEYCONF
2258 // After successful updating of the tuple LQH is informed of this.
2259 //
2260 // Delete with read
2261 // ----------------
2262 //
2263 // Will behave as a normal read although it also prepares the
2264 // deletion of the tuple.
2265 //
2266 // Interpreted Update
2267 // ------------------
2268 //
2269 // <---- TRANSID_AI (to API)
2270 // ...
2271 // <---- TRANSID_AI (to API)
2272 // <---- TUP_ATTRINFO (to LQH)
2273 // ...
2274 // <---- TUP_ATTRINFO (to LQH)
2275 // <---- TUPKEYCONF (to LQH)
2276 //
2277 // The interpreted Update contains five sections:
2278 // The first section performs read Attribute operations
2279 // that send results back to the API.
2280 //
2281 // The second section executes the interpreted program
2282 // where data from attributes can be updated and it
2283 // can also read attribute values into the registers.
2284 //
2285 // The third section performs unconditional updates of
2286 // attributes.
2287 //
2288 // The fourth section can read the attributes to be sent to the
2289 // API after updating the record.
2290 //
2291 // The fifth section contains subroutines used by the interpreter
2292 // in the second section.
2293 //
2294 // All types of interpreted programs contains the same five sections.
2295 // The only difference is that only interpreted updates can update
2296 // attributes. Interpreted inserts are not allowed.
2297 //
2298 // Interpreted Updates have to send back the information about the
2299 // attributes they have updated. This information will be shipped to
2300 // the log and also to any other replicas. Thus interpreted updates
2301 // are only performed in the primary replica. The fragment redo log
2302 // in LQH will contain information so that normal update/inserts/deletes
2303 // can be performed using TUPKEYREQ.
2304 //
2305 // Interpreted Read
2306 // ----------------
2307 //
2308 // From a signalling point of view the Interpreted Read behaves as
2309 // as a Normal Read. The interpreted Read is often used by Scan's.
2310 //
2311 // Interpreted Delete
2312 // ------------------
2313 //
2314 // <---- TUPKEYCONF
2315 // After successful prepartion to delete the tuple LQH is informed
2316 // of this.
2317 //
2318 // Interpreted Delete with Read
2319 // ----------------------------
2320 //
2321 // From a signalling point of view an interpreted delete with read
2322 // behaves as a normal read.
2323 //
2324 // Continuation after successful case:
2325 //
2326 // After a read of any kind the operation record is ready to be used
2327 // again by a new operation.
2328 //
2329 // Any updates, inserts or deletes waits for either of two messages.
2330 // A commit specifying that the operation is to be performed for real
2331 // or an abort specifying that the operation is to be rolled back and
2332 // the record to be restored in its original format.
2333 //
2334 // This is handled by the module Transaction Manager.
2335 //
2336 // Response Signals (unsuccessful case):
2337 //
2338 // <---- TUPKEYREF (to LQH)
2339 // A signal is sent back to LQH informing about the unsuccessful
2340 // operation. In this case TUP waits for an abort signal to arrive
2341 // before the operation record is ready for the next operation.
2342 // This is handled by the Transaction Manager.
2343 //------------------------------------------------------------------
2344 //------------------------------------------------------------------
2345
2346 // *****************************************************************
2347 // Signal Reception methods.
2348 // *****************************************************************
2349 //------------------------------------------------------------------
2350 //------------------------------------------------------------------
2351 public:
2352 bool execTUPKEYREQ(Signal* signal);
2353 /**
2354 * Prepare for execTUPKEYREQ by prefetching row and preparing
2355 * some variables as part of row address calculation.
2356 */
2357 void prepareTUPKEYREQ(Uint32 page_id,
2358 Uint32 page_idx,
2359 Uint32 frag_id);
2360 void prepare_scanTUPKEYREQ(Uint32 page_id, Uint32 page_idx);
2361 void prepare_scan_tux_TUPKEYREQ(Uint32 page_id, Uint32 page_idx);
2362 void prepare_op_pointer(Uint32 opPtrI,
2363 Dbtup::Operationrec *opPtrP);
2364 void prepare_tab_pointers(Uint32 fragPtrI);
2365 void get_all_tup_ptrs(Uint32 indexFragPtrI,
2366 Uint32 tableFragPtrI,
2367 Uint32** index_fragptr,
2368 Uint32** index_tabptr,
2369 Uint32** real_fragptr,
2370 Uint32** real_tabptr,
2371 Uint32& attrDataOffset,
2372 Uint32& tuxFixHeaderSize);
2373 Uint32 get_current_frag_page_id();
2374 private:
2375 void disk_page_load_callback(Signal*, Uint32 op, Uint32 page);
2376 void disk_page_load_scan_callback(Signal*, Uint32 op, Uint32 page);
2377
2378 private:
2379
2380 // Trigger signals
2381 //------------------------------------------------------------------
2382 //------------------------------------------------------------------
2383 void execCREATE_TRIG_IMPL_REQ(Signal* signal);
2384
2385 //------------------------------------------------------------------
2386 //------------------------------------------------------------------
2387 void execDROP_TRIG_IMPL_REQ(Signal* signal);
2388
2389 /**
2390 * Deferred triggers execute when execFIRE_TRIG_REQ
2391 * is called
2392 */
2393 void execFIRE_TRIG_REQ(Signal* signal);
2394 void sendFIRE_TRIG_ORD(Signal* signal);
2395 void sendBatchedFIRE_TRIG_ORD(Signal* signal,
2396 Uint32 ref,
2397 Uint32 siglen,
2398 SectionHandle* handle);
2399 void sendBatchedFIRE_TRIG_ORD(Signal* signal,
2400 Uint32 ref,
2401 Uint32 siglen,
2402 LinearSectionPtr ptr[],
2403 Uint32 nptr);
2404
2405 // *****************************************************************
2406 // Setting up the environment for reads, inserts, updates and deletes.
2407 // *****************************************************************
2408 //------------------------------------------------------------------
2409 //------------------------------------------------------------------
2410 int handleReadReq(Signal* signal,
2411 Operationrec* regOperPtr,
2412 Tablerec* regTabPtr,
2413 KeyReqStruct* req_struct);
2414
2415 //------------------------------------------------------------------
2416 //------------------------------------------------------------------
2417 int handleUpdateReq(Signal* signal,
2418 Operationrec* regOperPtr,
2419 Fragrecord* regFragPtr,
2420 Tablerec* regTabPtr,
2421 KeyReqStruct* req_struct,
2422 bool disk);
2423
2424 //------------------------------------------------------------------
2425 //------------------------------------------------------------------
2426 int handleInsertReq(Signal* signal,
2427 Ptr<Operationrec> regOperPtr,
2428 Ptr<Fragrecord>,
2429 Tablerec* regTabPtr,
2430 KeyReqStruct* req_struct,
2431 Local_key ** accminupdateptr);
2432
2433 //------------------------------------------------------------------
2434 //------------------------------------------------------------------
2435 int handleDeleteReq(Signal* signal,
2436 Operationrec* regOperPtr,
2437 Fragrecord* regFragPtr,
2438 Tablerec* regTabPtr,
2439 KeyReqStruct* req_struct,
2440 bool disk);
2441
2442 int handleRefreshReq(Signal* signal,
2443 Ptr<Operationrec>,
2444 Ptr<Fragrecord>,
2445 Tablerec*,
2446 KeyReqStruct*,
2447 bool disk);
2448
2449 //------------------------------------------------------------------
2450 //------------------------------------------------------------------
2451 int updateStartLab(Signal* signal,
2452 Operationrec* regOperPtr,
2453 Fragrecord* regFragPtr,
2454 Tablerec* regTabPtr,
2455 KeyReqStruct* req_struct);
2456
2457 // *****************************************************************
2458 // Interpreter Handling methods.
2459 // *****************************************************************
2460
2461 //------------------------------------------------------------------
2462 //------------------------------------------------------------------
2463 int interpreterStartLab(Signal* signal,
2464 KeyReqStruct *req_struct);
2465
2466 //------------------------------------------------------------------
2467 //------------------------------------------------------------------
2468 Uint32 brancher(Uint32, Uint32);
2469 int interpreterNextLab(Signal* signal,
2470 KeyReqStruct *req_struct,
2471 Uint32* logMemory,
2472 Uint32* mainProgram,
2473 Uint32 TmainProgLen,
2474 Uint32* subroutineProg,
2475 Uint32 TsubroutineLen,
2476 Uint32 * tmpArea,
2477 Uint32 tmpAreaSz);
2478
2479 const Uint32 * lookupInterpreterParameter(Uint32 paramNo,
2480 const Uint32 * subptr,
2481 Uint32 sublen) const;
2482
2483 // *****************************************************************
2484 // Signal Sending methods.
2485 // *****************************************************************
2486 //------------------------------------------------------------------
2487 //------------------------------------------------------------------
2488 void sendReadAttrinfo(Signal* signal,
2489 KeyReqStruct *req_struct,
2490 Uint32 TnoOfData);
2491
2492 //------------------------------------------------------------------
2493 //------------------------------------------------------------------
2494 int sendLogAttrinfo(Signal* signal,
2495 KeyReqStruct *req_struct,
2496 Uint32 TlogSize,
2497 Operationrec * regOperPtr);
2498
2499 //------------------------------------------------------------------
2500 //------------------------------------------------------------------
2501 void returnTUPKEYCONF(Signal* signal,
2502 KeyReqStruct *req_struct,
2503 Operationrec * regOperPtr,
2504 TransState trans_state);
2505
2506 //------------------------------------------------------------------
2507 //------------------------------------------------------------------
2508 // *****************************************************************
2509 // The methods that perform the actual read and update of attributes
2510 // in the tuple.
2511 // *****************************************************************
2512 //------------------------------------------------------------------
2513 //------------------------------------------------------------------
2514 int readAttributes(KeyReqStruct* req_struct,
2515 const Uint32* inBuffer,
2516 Uint32 inBufLen,
2517 Uint32* outBuffer,
2518 Uint32 TmaxRead,
2519 bool xfrmFlag);
2520
2521 //------------------------------------------------------------------
2522 //------------------------------------------------------------------
2523 int updateAttributes(KeyReqStruct *req_struct,
2524 Uint32* inBuffer,
2525 Uint32 inBufLen);
2526
2527 //------------------------------------------------------------------
2528 //------------------------------------------------------------------
2529 static bool readFixedSizeTHOneWordNotNULL(Uint8* outBuffer,
2530 KeyReqStruct *req_struct,
2531 AttributeHeader* ahOut,
2532 Uint64 attrDes);
2533
2534 //------------------------------------------------------------------
2535 //------------------------------------------------------------------
2536 static bool updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer,
2537 KeyReqStruct *req_struct,
2538 Uint64 attrDes);
2539
2540 //------------------------------------------------------------------
2541 //------------------------------------------------------------------
2542 static bool readFixedSizeTHTwoWordNotNULL(Uint8* outBuffer,
2543 KeyReqStruct *req_struct,
2544 AttributeHeader* ahOut,
2545 Uint64 attrDes);
2546
2547 //------------------------------------------------------------------
2548 //------------------------------------------------------------------
2549 static bool updateFixedSizeTHTwoWordNotNULL(Uint32* inBuffer,
2550 KeyReqStruct *req_struct,
2551 Uint64 attrDes);
2552
2553 //------------------------------------------------------------------
2554 //------------------------------------------------------------------
2555 static bool readFixedSizeTHManyWordNotNULL(Uint8* outBuffer,
2556 KeyReqStruct *req_struct,
2557 AttributeHeader* ahOut,
2558 Uint64 attrDes);
2559
2560 //------------------------------------------------------------------
2561 //------------------------------------------------------------------
2562 static bool fixsize_updater(Uint32* inBuffer,
2563 KeyReqStruct *req_struct,
2564 Uint64 attrDes,
2565 Uint32 *dst_ptr,
2566 Uint32 updateOffset,
2567 Uint32 checkOffset);
2568 static bool updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
2569 KeyReqStruct *req_struct,
2570 Uint64 attrDes);
2571
2572 //------------------------------------------------------------------
2573 //------------------------------------------------------------------
2574 static bool readFixedSizeTHOneWordNULLable(Uint8* outBuffer,
2575 KeyReqStruct *req_struct,
2576 AttributeHeader* ahOut,
2577 Uint64 attrDes);
2578
2579 //------------------------------------------------------------------
2580 //------------------------------------------------------------------
2581 static bool updateFixedSizeTHOneWordNULLable(Uint32* inBuffer,
2582 KeyReqStruct *req_struct,
2583 Uint64 attrDes);
2584
2585 //------------------------------------------------------------------
2586 //------------------------------------------------------------------
2587 static bool readFixedSizeTHTwoWordNULLable(Uint8* outBuffer,
2588 KeyReqStruct *req_struct,
2589 AttributeHeader* ahOut,
2590 Uint64 attrDes);
2591
2592 //------------------------------------------------------------------
2593 //------------------------------------------------------------------
2594 static bool updateFixedSizeTHTwoWordNULLable(Uint32* inBuffer,
2595 KeyReqStruct *req_struct,
2596 Uint64 attrDes);
2597
2598 //------------------------------------------------------------------
2599 //------------------------------------------------------------------
2600 static bool readFixedSizeTHManyWordNULLable(Uint8* outBuffer,
2601 KeyReqStruct *req_struct,
2602 AttributeHeader* ahOut,
2603 Uint64 attrDes);
2604
2605 //------------------------------------------------------------------
2606 //------------------------------------------------------------------
2607 static bool readFixedSizeTHZeroWordNULLable(Uint8* outBuffer,
2608 KeyReqStruct *req_struct,
2609 AttributeHeader* ahOut,
2610 Uint64 attrDes);
2611 //------------------------------------------------------------------
2612 //------------------------------------------------------------------
2613 static bool updateFixedSizeTHManyWordNULLable(Uint32* inBuffer,
2614 KeyReqStruct *req_struct,
2615 Uint64 attrDes);
2616
2617 //------------------------------------------------------------------
2618 //------------------------------------------------------------------
2619 static bool varsize_reader(Uint8* out_buffer,
2620 KeyReqStruct *req_struct,
2621 AttributeHeader* ah_out,
2622 Uint64 attr_des,
2623 const void* src_ptr,
2624 Uint32 vsize_in_bytes);
2625
2626 static bool xfrm_reader(Uint8* out_buffer,
2627 KeyReqStruct *req_struct,
2628 AttributeHeader* ah_out,
2629 Uint64 attr_des,
2630 const void* src_ptr,
2631 Uint32 srcBytes);
2632
2633 static bool bits_reader(Uint8* out_buffer,
2634 KeyReqStruct *req_struct,
2635 AttributeHeader* ah_out,
2636 const Uint32* bm_ptr, Uint32 bm_len,
2637 Uint32 bitPos, Uint32 bitCnt);
2638
2639 static bool varsize_updater(Uint32* in_buffer,
2640 KeyReqStruct *req_struct,
2641 char *var_data_start,
2642 Uint32 var_attr_pos,
2643 Uint16 *len_offset_ptr,
2644 Uint32 check_offset,
2645 Uint64 attrDes);
2646 //------------------------------------------------------------------
2647 //------------------------------------------------------------------
2648 static bool readVarSizeNotNULL(Uint8* outBuffer,
2649 KeyReqStruct *req_struct,
2650 AttributeHeader* ahOut,
2651 Uint64 attrDes);
2652
2653 //------------------------------------------------------------------
2654 //------------------------------------------------------------------
2655 static bool updateVarSizeNotNULL(Uint32* inBuffer,
2656 KeyReqStruct *req_struct,
2657 Uint64 attrDes);
2658
2659 //------------------------------------------------------------------
2660 //------------------------------------------------------------------
2661 static bool readVarSizeNULLable(Uint8* outBuffer,
2662 KeyReqStruct *req_struct,
2663 AttributeHeader* ahOut,
2664 Uint64 attrDes);
2665
2666 //------------------------------------------------------------------
2667 //------------------------------------------------------------------
2668 static bool updateVarSizeNULLable(Uint32* inBuffer,
2669 KeyReqStruct *req_struct,
2670 Uint64 attrDes);
2671
2672 //------------------------------------------------------------------
2673 //------------------------------------------------------------------
2674 static bool readDynFixedSizeNotNULL(Uint8* outBuffer,
2675 KeyReqStruct *req_struct,
2676 AttributeHeader* ahOut,
2677 Uint64 attrDes);
2678 static bool readDynFixedSizeNULLable(Uint8* outBuffer,
2679 KeyReqStruct *req_struct,
2680 AttributeHeader* ahOut,
2681 Uint64 attrDes);
2682 static bool readDynFixedSizeExpandedNotNULL(Uint8* outBuffer,
2683 KeyReqStruct *req_struct,
2684 AttributeHeader* ahOut,
2685 Uint64 attrDes);
2686 static bool readDynFixedSizeShrunkenNotNULL(Uint8* outBuffer,
2687 KeyReqStruct *req_struct,
2688 AttributeHeader* ahOut,
2689 Uint64 attrDes);
2690 static bool readDynFixedSizeExpandedNULLable(Uint8* outBuffer,
2691 KeyReqStruct *req_struct,
2692 AttributeHeader* ahOut,
2693 Uint64 attrDes);
2694 static bool readDynFixedSizeShrunkenNULLable(Uint8* outBuffer,
2695 KeyReqStruct *req_struct,
2696 AttributeHeader* ahOut,
2697 Uint64 attrDes);
2698
2699 //------------------------------------------------------------------
2700 //------------------------------------------------------------------
2701 static bool updateDynFixedSizeNotNULL(Uint32* inBuffer,
2702 KeyReqStruct *req_struct,
2703 Uint64 attrDes);
2704 static bool updateDynFixedSizeNULLable(Uint32* inBuffer,
2705 KeyReqStruct *req_struct,
2706 Uint64 attrDes);
2707
2708 //------------------------------------------------------------------
2709 //------------------------------------------------------------------
2710 static bool readDynBigFixedSizeNotNULL(Uint8* outBuffer,
2711 KeyReqStruct *req_struct,
2712 AttributeHeader* ahOut,
2713 Uint64 attrDes);
2714 static bool readDynBigFixedSizeNULLable(Uint8* outBuffer,
2715 KeyReqStruct *req_struct,
2716 AttributeHeader* ahOut,
2717 Uint64 attrDes);
2718 static bool readDynBigFixedSizeExpandedNotNULL(Uint8* outBuffer,
2719 KeyReqStruct *req_struct,
2720 AttributeHeader* ahOut,
2721 Uint64 attrDes);
2722 static bool readDynBigFixedSizeShrunkenNotNULL(Uint8* outBuffer,
2723 KeyReqStruct *req_struct,
2724 AttributeHeader* ahOut,
2725 Uint64 attrDes);
2726 static bool readDynBigFixedSizeExpandedNULLable(Uint8* outBuffer,
2727 KeyReqStruct *req_struct,
2728 AttributeHeader* ahOut,
2729 Uint64 attrDes);
2730 static bool readDynBigFixedSizeShrunkenNULLable(Uint8* outBuffer,
2731 KeyReqStruct *req_struct,
2732 AttributeHeader* ahOut,
2733 Uint64 attrDes);
2734
2735 //------------------------------------------------------------------
2736 //------------------------------------------------------------------
2737 static bool updateDynBigFixedSizeNotNULL(Uint32* inBuffer,
2738 KeyReqStruct *req_struct,
2739 Uint64 attrDes);
2740 static bool updateDynBigFixedSizeNULLable(Uint32* inBuffer,
2741 KeyReqStruct *req_struct,
2742 Uint64 attrDes);
2743
2744 //------------------------------------------------------------------
2745 //------------------------------------------------------------------
2746 static bool readDynBitsNotNULL(Uint8* outBuffer,
2747 KeyReqStruct *req_struct,
2748 AttributeHeader* ahOut,
2749 Uint64 attrDes);
2750 static bool readDynBitsNULLable(Uint8* outBuffer,
2751 KeyReqStruct *req_struct,
2752 AttributeHeader* ahOut,
2753 Uint64 attrDes);
2754 static bool readDynBitsExpandedNotNULL(Uint8* outBuffer,
2755 KeyReqStruct *req_struct,
2756 AttributeHeader* ahOut,
2757 Uint64 attrDes);
2758 static bool readDynBitsShrunkenNotNULL(Uint8* outBuffer,
2759 KeyReqStruct *req_struct,
2760 AttributeHeader* ahOut,
2761 Uint64 attrDes);
2762 static bool readDynBitsExpandedNULLable(Uint8* outBuffer,
2763 KeyReqStruct *req_struct,
2764 AttributeHeader* ahOut,
2765 Uint64 attrDes);
2766 static bool readDynBitsShrunkenNULLable(Uint8* outBuffer,
2767 KeyReqStruct *req_struct,
2768 AttributeHeader* ahOut,
2769 Uint64 attrDes);
2770
2771 //------------------------------------------------------------------
2772 //------------------------------------------------------------------
2773 static bool updateDynBitsNotNULL(Uint32* inBuffer,
2774 KeyReqStruct *req_struct,
2775 Uint64 attrDes);
2776 static bool updateDynBitsNULLable(Uint32* inBuffer,
2777 KeyReqStruct *req_struct,
2778 Uint64 attrDes);
2779
2780 //------------------------------------------------------------------
2781 //------------------------------------------------------------------
2782 static bool readDynVarSizeNotNULL(Uint8* outBuffer,
2783 KeyReqStruct *req_struct,
2784 AttributeHeader* ahOut,
2785 Uint64 attrDes);
2786 static bool readDynVarSizeNULLable(Uint8* outBuffer,
2787 KeyReqStruct *req_struct,
2788 AttributeHeader* ahOut,
2789 Uint64 attrDes);
2790 static bool readDynVarSizeExpandedNotNULL(Uint8* outBuffer,
2791 KeyReqStruct *req_struct,
2792 AttributeHeader* ahOut,
2793 Uint64 attrDes);
2794 static bool readDynVarSizeShrunkenNotNULL(Uint8* outBuffer,
2795 KeyReqStruct *req_struct,
2796 AttributeHeader* ahOut,
2797 Uint64 attrDes);
2798 static bool readDynVarSizeExpandedNULLable(Uint8* outBuffer,
2799 KeyReqStruct *req_struct,
2800 AttributeHeader* ahOut,
2801 Uint64 attrDes);
2802 static bool readDynVarSizeShrunkenNULLable(Uint8* outBuffer,
2803 KeyReqStruct *req_struct,
2804 AttributeHeader* ahOut,
2805 Uint64 attrDes);
2806
2807 //------------------------------------------------------------------
2808 //------------------------------------------------------------------
2809 static bool updateDynVarSizeNotNULL(Uint32* inBuffer,
2810 KeyReqStruct *req_struct,
2811 Uint64 attrDes);
2812 static bool updateDynVarSizeNULLable(Uint32* inBuffer,
2813 KeyReqStruct *req_struct,
2814 Uint64 attrDes);
2815
2816 static bool readCharNotNULL(Uint8* outBuffer,
2817 KeyReqStruct *req_struct,
2818 AttributeHeader* ahOut,
2819 Uint64 attrDes);
2820
2821 static bool readCharNULLable(Uint8* outBuffer,
2822 KeyReqStruct *req_struct,
2823 AttributeHeader* ahOut,
2824 Uint64 attrDes);
2825
2826 static bool readBitsNULLable(Uint8* outBuffer,
2827 KeyReqStruct *req_struct,
2828 AttributeHeader*,
2829 Uint64);
2830 static bool updateBitsNULLable(Uint32* inBuffer,
2831 KeyReqStruct *req_struct,
2832 Uint64);
2833 static bool readBitsNotNULL(Uint8* outBuffer,
2834 KeyReqStruct *req_struct,
2835 AttributeHeader*,
2836 Uint64);
2837 static bool updateBitsNotNULL(Uint32* inBuffer,
2838 KeyReqStruct *req_struct,
2839 Uint64);
2840
2841 static bool updateFixedNULLable(Uint32* inBuffer,
2842 KeyReqStruct *req_struct,
2843 Uint64);
2844 static bool updateFixedNotNull(Uint32* inBuffer,
2845 KeyReqStruct *req_struct,
2846 Uint64);
2847
2848 static bool updateVarNULLable(Uint32* inBuffer,
2849 KeyReqStruct *req_struct,
2850 Uint64);
2851 static bool updateVarNotNull(Uint32* inBuffer,
2852 KeyReqStruct *req_struct,
2853 Uint64);
2854
2855 static bool readDiskFixedSizeNotNULL(Uint8* outBuffer,
2856 KeyReqStruct *req_struct,
2857 AttributeHeader* ahOut,
2858 Uint64 attrDes);
2859
2860 static bool readDiskFixedSizeNULLable(Uint8* outBuffer,
2861 KeyReqStruct *req_struct,
2862 AttributeHeader* ahOut,
2863 Uint64 attrDes);
2864
2865 static bool readDiskVarAsFixedSizeNotNULL(Uint8* outBuffer,
2866 KeyReqStruct *req_struct,
2867 AttributeHeader* ahOut,
2868 Uint64 attrDes);
2869
2870 static bool readDiskVarAsFixedSizeNULLable(Uint8* outBuffer,
2871 KeyReqStruct *req_struct,
2872 AttributeHeader* ahOut,
2873 Uint64 attrDes);
2874 static bool readDiskVarSizeNULLable(Uint8*,
2875 KeyReqStruct*,
2876 AttributeHeader*,
2877 Uint64);
2878 static bool readDiskVarSizeNotNULL(Uint8*,
2879 KeyReqStruct*,
2880 AttributeHeader*,
2881 Uint64);
2882
2883 static bool updateDiskFixedSizeNULLable(Uint32*,
2884 KeyReqStruct*,
2885 Uint64);
2886 static bool updateDiskFixedSizeNotNULL(Uint32*,
2887 KeyReqStruct*,
2888 Uint64);
2889
2890 static bool updateDiskVarAsFixedSizeNULLable(Uint32*,
2891 KeyReqStruct*,
2892 Uint64);
2893 static bool updateDiskVarAsFixedSizeNotNULL(Uint32*,
2894 KeyReqStruct*,
2895 Uint64);
2896
2897 static bool updateDiskVarSizeNULLable(Uint32*,
2898 KeyReqStruct *,
2899 Uint64);
2900 static bool updateDiskVarSizeNotNULL(Uint32*,
2901 KeyReqStruct *,
2902 Uint64);
2903
2904 static bool readDiskBitsNULLable(Uint8*,
2905 KeyReqStruct*,
2906 AttributeHeader*,
2907 Uint64);
2908 static bool readDiskBitsNotNULL(Uint8*,
2909 KeyReqStruct*,
2910 AttributeHeader*,
2911 Uint64);
2912 static bool updateDiskBitsNULLable(Uint32*,
2913 KeyReqStruct*,
2914 Uint64);
2915 static bool updateDiskBitsNotNULL(Uint32*,
2916 KeyReqStruct*,
2917 Uint64);
2918
2919 /* Alter table methods. */
2920 void handleAlterTablePrepare(Signal *, const AlterTabReq *, const Tablerec *);
2921 void handleAlterTableCommit(Signal *, const AlterTabReq *, Tablerec *);
2922 void handleAlterTableComplete(Signal *, const AlterTabReq *, Tablerec *);
2923 void handleAlterTableAbort(Signal *, const AlterTabReq *, const Tablerec *);
2924 void sendAlterTabRef(Signal *signal, Uint32 errorCode);
2925 void sendAlterTabConf(Signal *, Uint32 clientData=RNIL);
2926
2927 void handleCharsetPos(Uint32 csNumber, CHARSET_INFO** charsetArray,
2928 Uint32 noOfCharsets,
2929 Uint32 & charsetIndex, Uint32 & attrDes2);
2930 Uint32 computeTableMetaData(Tablerec *regTabPtr);
2931
2932 //------------------------------------------------------------------
2933 //------------------------------------------------------------------
2934 static bool nullFlagCheck(KeyReqStruct *req_struct, Uint64 attrDes);
2935 static bool disk_nullFlagCheck(KeyReqStruct *req_struct, Uint64 attrDes);
2936 int read_pseudo(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
2937 Uint32 read_packed(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
2938 Uint32 update_packed(KeyReqStruct*, const Uint32* src);
2939
2940 Uint32 read_lcp(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
2941 void update_lcp(KeyReqStruct *req_struct, const Uint32* src, Uint32 len);
2942
2943 void flush_read_buffer(KeyReqStruct *, const Uint32* outBuf,
2944 Uint32 resultRef, Uint32 resultData, Uint32 routeRef);
2945 public:
2946 Uint32 copyAttrinfo(Uint32 storedProcId);
2947 void copyAttrinfo(Uint32 expectedLen,
2948 Uint32 attrInfoIVal);
2949 /**
2950 * Used by Restore...
2951 */
2952 Uint32 read_lcp_keys(Uint32, const Uint32 * src, Uint32 len, Uint32 *dst);
2953 private:
2954
2955 //------------------------------------------------------------------
2956 //------------------------------------------------------------------
2957 void setUpQueryRoutines(Tablerec* regTabPtr);
2958
2959 // *****************************************************************
2960 // Service methods.
2961 // *****************************************************************
2962 TransState get_trans_state(Operationrec * const);
2963 void set_trans_state(Operationrec * const, TransState);
2964 TupleState get_tuple_state(Operationrec * const);
2965 void set_tuple_state(Operationrec * const, TupleState);
2966 Uint32 get_fix_page_offset(Uint32 page_index, Uint32 tuple_size);
2967
2968 Uint32 decr_tup_version(Uint32 tuple_version);
2969 void update_change_mask_info(const Tablerec*, ChangeMask* dst, const Uint32*src);
2970 void set_change_mask_info(const Tablerec*, ChangeMask* dst);
2971 void clear_change_mask_info(const Tablerec*, ChangeMask* dst);
2972 void copy_change_mask_info(const Tablerec*, ChangeMask* dst, const ChangeMask * src);
2973 void set_commit_change_mask_info(const Tablerec*,
2974 KeyReqStruct*,
2975 const Operationrec*);
2976
2977 //------------------------------------------------------------------
2978 //------------------------------------------------------------------
2979 void initOpConnection(Operationrec* regOperPtr);
2980
2981 //------------------------------------------------------------------
2982 //------------------------------------------------------------------
2983 void initOperationrec(Signal* signal);
2984
2985 //------------------------------------------------------------------
2986 //------------------------------------------------------------------
2987 void getStoredProcAttrInfo(Uint32 storedId,
2988 KeyReqStruct* req_struct,
2989 Uint32& attrInfoIVal);
2990
2991 //------------------------------------------------------------------
2992 //------------------------------------------------------------------
2993 bool insertActiveOpList(OperationrecPtr, KeyReqStruct* req_struct);
2994
2995 //------------------------------------------------------------------
2996 //------------------------------------------------------------------
2997
2998 int store_default_record(const TablerecPtr& regTabPtr);
2999 bool receive_defvalue(Signal* signal, const TablerecPtr& regTabPtr);
3000 //------------------------------------------------------------------
3001 //------------------------------------------------------------------
3002 void bufferTRANSID_AI(Signal* signal, BlockReference aRef,
3003 const Uint32 *dataBuf,
3004 Uint32 lenOfData);
3005
3006 void sendAPI_TRANSID_AI(Signal* signal,
3007 BlockReference recBlockRef,
3008 const Uint32 *dataBuf,
3009 Uint32 lenOfData);
3010
3011 //------------------------------------------------------------------
3012 // Trigger handling routines
3013 //------------------------------------------------------------------
3014 TupTriggerData_list*
3015 findTriggerList(Tablerec* table,
3016 TriggerType::Value ttype,
3017 TriggerActionTime::Value ttime,
3018 TriggerEvent::Value tevent);
3019
3020 bool createTrigger(Tablerec*, const CreateTrigImplReq*, const AttributeMask&);
3021
3022 Uint32 dropTrigger(Tablerec* table,
3023 const DropTrigImplReq* req,
3024 BlockNumber sender);
3025
3026 Uint32 getOldTriggerId(const TupTriggerData*, Uint32 op);
3027
3028 void
3029 checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
3030 Operationrec* regOperPtr,
3031 Tablerec* tablePtr,
3032 bool disk);
3033
3034 void
3035 checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
3036 Operationrec* regOperPtr,
3037 Tablerec* tablePtr,
3038 bool disk);
3039
3040 void
3041 checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
3042 Operationrec* regOperPtr,
3043 Tablerec* tablePtr,
3044 bool disk);
3045
3046 void checkDeferredTriggers(KeyReqStruct *req_struct,
3047 Operationrec* regOperPtr,
3048 Tablerec* regTablePtr,
3049 bool disk);
3050
3051 void checkDetachedTriggers(KeyReqStruct *req_struct,
3052 Operationrec* regOperPtr,
3053 Tablerec* regTablePtr,
3054 bool disk,
3055 Uint32 diskPagePtrI);
3056
3057 void fireImmediateTriggers(KeyReqStruct *req_struct,
3058 TupTriggerData_list& triggerList,
3059 Operationrec* regOperPtr,
3060 bool disk);
3061
3062 void checkDeferredTriggersDuringPrepare(KeyReqStruct *req_struct,
3063 TupTriggerData_list& triggerList,
3064 Operationrec* const regOperPtr,
3065 bool disk);
3066 void fireDeferredTriggers(KeyReqStruct *req_struct,
3067 TupTriggerData_list& triggerList,
3068 Operationrec* const regOperPtr,
3069 bool disk);
3070
3071 void fireDeferredConstraints(KeyReqStruct *req_struct,
3072 TupTriggerData_list& triggerList,
3073 Operationrec* const regOperPtr,
3074 bool disk);
3075
3076 void fireDetachedTriggers(KeyReqStruct *req_struct,
3077 TupTriggerData_list& triggerList,
3078 Operationrec* regOperPtr,
3079 bool disk,
3080 Uint32 diskPagePtrI);
3081
3082 void executeTrigger(KeyReqStruct *req_struct,
3083 TupTriggerData* trigPtr,
3084 Operationrec* regOperPtr,
3085 bool disk);
3086
3087 bool check_fire_trigger(const Fragrecord*,
3088 const TupTriggerData*,
3089 const KeyReqStruct*,
3090 const Operationrec*) const;
3091
3092 bool check_fire_reorg(const KeyReqStruct *, Fragrecord::FragState) const;
3093 bool check_fire_fully_replicated(const KeyReqStruct *,
3094 Fragrecord::FragState) const;
3095 bool check_fire_suma(const KeyReqStruct *,
3096 const Operationrec*,
3097 const Fragrecord*) const;
3098
3099 bool readTriggerInfo(TupTriggerData* trigPtr,
3100 Operationrec* regOperPtr,
3101 KeyReqStruct * req_struct,
3102 Fragrecord* regFragPtr,
3103 Uint32* keyBuffer,
3104 Uint32& noPrimKey,
3105 Uint32* afterBuffer,
3106 Uint32& noAfterWords,
3107 Uint32* beforeBuffer,
3108 Uint32& noBeforeWords,
3109 bool disk);
3110
3111 void sendTrigAttrInfo(Signal* signal,
3112 Uint32* data,
3113 Uint32 dataLen,
3114 bool executeDirect,
3115 BlockReference receiverReference);
3116
3117 Uint32 setAttrIds(Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask,
3118 Uint32 noOfAttributes,
3119 Uint32* inBuffer);
3120
3121 bool primaryKey(Tablerec* const, Uint32);
3122
3123 // these set terrorCode and return non-zero on error
3124
3125 int executeTuxInsertTriggers(Signal* signal,
3126 Operationrec* regOperPtr,
3127 Fragrecord* regFragPtr,
3128 Tablerec* regTabPtr);
3129
3130 int executeTuxUpdateTriggers(Signal* signal,
3131 Operationrec* regOperPtr,
3132 Fragrecord* regFragPtr,
3133 Tablerec* regTabPtr);
3134
3135 int executeTuxDeleteTriggers(Signal* signal,
3136 Operationrec* regOperPtr,
3137 Fragrecord* regFragPtr,
3138 Tablerec* regTabPtr);
3139
3140 int addTuxEntries(Signal* signal,
3141 Operationrec* regOperPtr,
3142 Tablerec* regTabPtr);
3143
3144 // these crash the node on error
3145
3146 void executeTuxCommitTriggers(Signal* signal,
3147 Operationrec* regOperPtr,
3148 Fragrecord* regFragPtr,
3149 Tablerec* regTabPtr);
3150
3151 void executeTuxAbortTriggers(Signal* signal,
3152 Operationrec* regOperPtr,
3153 Fragrecord* regFragPtr,
3154 Tablerec* regTabPtr);
3155
3156 void removeTuxEntries(Signal* signal,
3157 Tablerec* regTabPtr);
3158
3159 void ndbmtd_buffer_suma_trigger(Signal* signal, Uint32 len,
3160 LinearSectionPtr ptr[]);
3161 void flush_ndbmtd_suma_buffer(Signal*);
3162
3163 struct SumaTriggerBuffer
3164 {
SumaTriggerBufferDbtup::SumaTriggerBuffer3165 SumaTriggerBuffer()
3166 : m_out_of_memory(0),
3167 m_pageId(RNIL),
3168 m_freeWords(0),
3169 m_usedWords(0) {}
3170 Uint32 m_out_of_memory;
3171 Uint32 m_pageId;
3172 Uint32 m_freeWords;
3173 Uint32 m_usedWords;
3174 } m_suma_trigger_buffer;
3175
3176 // *****************************************************************
3177 // Error Handling routines.
3178 // *****************************************************************
3179 //------------------------------------------------------------------
3180 //------------------------------------------------------------------
3181 int TUPKEY_abort(KeyReqStruct*, int error_type);
3182
3183 //------------------------------------------------------------------
3184 //------------------------------------------------------------------
3185 void tupkeyErrorLab(KeyReqStruct*);
3186 void do_tup_abortreq(Signal*, Uint32 flags);
3187 void do_tup_abort_operation(Signal*, Tuple_header *,
3188 Operationrec*,
3189 Fragrecord*,
3190 Tablerec*);
3191
3192 //------------------------------------------------------------------
3193 //------------------------------------------------------------------
3194 // Methods to handle execution of TUP_COMMITREQ + TUP_ABORTREQ.
3195 //
3196 // Module Transaction Manager
3197 //
3198 // The Transaction Manager module is responsible for the commit
3199 // and abort of operations started by the Execution Manager.
3200 //
3201 // Commit Operation:
3202 // ----------------
3203 //
3204 // Failures in commit processing is not allowed since that would
3205 // leave the database in an unreliable state. Thus the only way
3206 // to handle failures in commit processing is to crash the node.
3207 //
3208 // TUP_COMMITREQ can only be received in the wait state after a
3209 // successful TUPKEYREQ which was not a read operation.
3210 //
3211 // Commit of Delete:
3212 // -----------------
3213 //
3214 // This will actually perform the deletion of the record unless
3215 // other operations also are connected to the record. In this case
3216 // we will set the delete state on the record that becomes the ownerd
3217 // of the record.
3218 //
3219 // Commit of Update:
3220 // ----------------
3221 //
3222 // We will release the copy record where the original record was kept.
3223 // Also here we will take special care if more operations are updating
3224 // the record simultaneously.
3225 //
3226 // Commit of Insert:
3227 // -----------------
3228 //
3229 // Will simply reset the state of the operation record.
3230 //
3231 // Signal Diagram:
3232 // ---> TUP_COMMITREQ (from LQH)
3233 // <---- TUP_COMMITCONF (to LQH)
3234 //
3235 //
3236 // Abort Operation:
3237 // ----------------
3238 //
3239 // Signal Diagram:
3240 // ---> TUP_ABORTREQ (from LQH)
3241 // <---- TUP_ABORTCONF (to LQH)
3242 //
3243 // Failures in abort processing is not allowed since that would
3244 // leave the database in an unreliable state. Thus the only way
3245 // to handle failures in abort processing is to crash the node.
3246 //
3247 // Abort messages can arrive at any time. It can arrive even before
3248 // anything at all have arrived of the operation. It can arrive after
3249 // receiving a number of ATTRINFO but before TUPKEYREQ has been received.
3250 // It must arrive after that we sent TUPKEYREF in response to TUPKEYREQ
3251 // and finally it can arrive after successfully performing the TUPKEYREQ
3252 // in all cases including the read case.
3253 //------------------------------------------------------------------
3254 //------------------------------------------------------------------
3255
3256 #if 0
3257 void checkPages(Fragrecord* regFragPtr);
3258 #endif
convert_byte_to_word_size(Uint32 byte_size)3259 Uint32 convert_byte_to_word_size(Uint32 byte_size)
3260 {
3261 return ((byte_size + 3) >> 2);
3262 }
convert_bit_to_word_size(Uint32 bit_size)3263 Uint32 convert_bit_to_word_size(Uint32 bit_size)
3264 {
3265 return ((bit_size + 31) >> 5);
3266 }
3267
3268 void prepare_initial_insert(KeyReqStruct*, Operationrec*, Tablerec*);
3269 void fix_disk_insert_no_mem_insert(KeyReqStruct*, Operationrec*, Tablerec*);
3270 void setup_fixed_tuple_ref_opt(KeyReqStruct* req_struct);
3271 void setup_fixed_tuple_ref(KeyReqStruct* req_struct,
3272 Operationrec* regOperPtr,
3273 Tablerec* regTabPtr);
3274 void setup_fixed_part(KeyReqStruct* req_struct,
3275 Operationrec* regOperPtr,
3276 Tablerec* regTabPtr);
3277
3278 void send_TUPKEYREF(const KeyReqStruct* req_struct);
3279 void early_tupkey_error(KeyReqStruct*);
3280
3281 void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit);
3282
3283 bool checkUpdateOfPrimaryKey(KeyReqStruct *req_struct,
3284 Uint32* updateBuffer,
3285 Tablerec* regTabPtr);
3286
3287 void setNullBits(Uint32*, Tablerec* regTabPtr);
3288 bool checkNullAttributes(KeyReqStruct * const, Tablerec* const);
3289 bool find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId);
3290 bool setup_read(KeyReqStruct* req_struct,
3291 Operationrec* regOperPtr,
3292 Tablerec* regTabPtr,
3293 bool disk);
3294
3295 Uint32 calculateChecksum(Tuple_header*, const Tablerec* regTabPtr);
3296 void setChecksum(Tuple_header*, const Tablerec* regTabPtr);
3297 void setInvalidChecksum(Tuple_header*, const Tablerec* regTabPtr);
3298 void updateChecksum(Tuple_header *,
3299 const Tablerec *,
3300 Uint32 old_header,
3301 Uint32 new_header);
3302 int corruptedTupleDetected(KeyReqStruct*, Tablerec*);
3303
3304 void complexTrigger(Signal* signal,
3305 KeyReqStruct *req_struct,
3306 Operationrec* regOperPtr,
3307 Fragrecord* regFragPtr,
3308 Tablerec* regTabPtr);
3309
3310 void setTupleStatesSetOpType(Operationrec* regOperPtr,
3311 KeyReqStruct *req_struct,
3312 Page* pagePtr,
3313 Uint32& opType,
3314 OperationrecPtr& firstOpPtr);
3315
3316 void findBeforeValueOperation(OperationrecPtr& befOpPtr,
3317 OperationrecPtr firstOpPtr);
3318
3319 void updateGcpId(KeyReqStruct *req_struct,
3320 Operationrec* regOperPtr,
3321 Fragrecord* regFragPtr,
3322 Tablerec* regTabPtr);
3323
3324 void setTupleStateOnPreviousOps(Uint32 prevOpIndex);
3325 void copyMem(Signal* signal, Uint32 sourceIndex, Uint32 destIndex);
3326
3327 void removeActiveOpList(Operationrec* const regOperPtr, Tuple_header*);
3328
3329 void updatePackedList(Uint16 ahostIndex);
3330
3331 void setUpDescriptorReferences(Uint32 descriptorReference,
3332 Tablerec* regTabPtr,
3333 const Uint32* offset);
3334 void setupDynDescriptorReferences(Uint32 dynDescr,
3335 Tablerec* const regTabPtr,
3336 const Uint32* offset,
3337 Uint32 ind=0);
3338 void setUpKeyArray(Tablerec* regTabPtr);
3339 bool addfragtotab(Tablerec* regTabPtr, Uint32 fragId, Uint32 fragIndex);
3340 Uint32 get_frag_from_tab(TablerecPtr tabPtr, Uint32 fragId);
3341 void remove_frag_from_tab(TablerecPtr tabPtr, Uint32 fragId);
3342 void deleteFragTab(Tablerec* regTabPtr, Uint32 fragId);
3343 void abortAddFragOp(Signal* signal);
3344 void releaseTabDescr(Tablerec* regTabPtr);
3345 void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* regTabPtr);
3346
3347 void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32);
3348 void initializeCheckpointInfoRec();
3349 void initializeDiskBufferSegmentRecord();
3350 void initializeFragoperrec();
3351 void initializeFragrecord();
3352 void initializeAlterTabOperation();
3353 void initializeHostBuffer();
3354 void initializeLocalLogInfo();
3355 void initializePendingFileOpenInfoRecord();
3356 void initializeRestartInfoRec();
3357 void initializeTablerec();
3358 void initializeTabDescr();
3359 void initializeUndoPage();
3360 void initializeDefaultValuesFrag();
3361
3362 void initTab(Tablerec* regTabPtr);
3363
3364 void fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr);
3365 void fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr);
3366 void fragrefuse2Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr);
3367 void fragrefuse3Lab(Signal* signal,
3368 FragoperrecPtr fragOperPtr,
3369 FragrecordPtr regFragPtr,
3370 Tablerec* regTabPtr,
3371 Uint32 fragId);
3372 void fragrefuse4Lab(Signal* signal,
3373 FragoperrecPtr fragOperPtr,
3374 FragrecordPtr regFragPtr,
3375 Tablerec* regTabPtr,
3376 Uint32 fragId);
3377 void addattrrefuseLab(Signal* signal,
3378 FragrecordPtr regFragPtr,
3379 FragoperrecPtr fragOperPtr,
3380 Tablerec* regTabPtr,
3381 Uint32 fragId);
3382
3383 void releaseFragment(Signal*, Uint32, Uint32);
3384 void drop_fragment_free_var_pages(Signal*);
3385 void drop_fragment_free_pages(Signal*);
3386 void drop_fragment_free_extent(Signal*, TablerecPtr, FragrecordPtr, Uint32);
3387 void drop_fragment_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
3388 void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32);
3389 void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32);
3390 void drop_fragment_fsremove_init(Signal*, TablerecPtr, FragrecordPtr);
3391 void lcp_open_ctl_file(Signal*, Uint32, Uint32, Uint32, Uint32);
3392 void lcp_read_ctl_file(Signal*, Uint32, Uint32, Uint32, Uint32, Uint32);
3393 void lcp_close_ctl_file(Signal*, Uint32, Uint32);
3394 bool handle_ctl_info(TablerecPtr, FragrecordPtr, Uint32);
3395 void lcp_read_completed(Signal*, TablerecPtr, FragrecordPtr);
3396 void drop_fragment_fsremove(Signal*, TablerecPtr, FragrecordPtr);
3397 void drop_fragment_fsremove_done(Signal*, TablerecPtr, FragrecordPtr);
3398
3399 // Initialisation
3400 void initData();
3401 void initRecords(const ndb_mgm_configuration_iterator *mgm_cfg);
3402
3403 // 2 words for optional GCI64 + AUTHOR info
3404 #define EXTRA_COPY_PROC_WORDS 2
3405 #define MAX_COPY_PROC_LEN (MAX_ATTRIBUTES_IN_TABLE + EXTRA_COPY_PROC_WORDS)
3406
3407
3408 void deleteScanProcedure(Signal* signal, Operationrec* regOperPtr);
3409 void allocCopyProcedure();
3410 void freeCopyProcedure();
3411 void prepareCopyProcedure(Uint32 numAttrs, Uint16 tableBits);
3412 void releaseCopyProcedure();
3413 void copyProcedure(Signal* signal,
3414 TablerecPtr regTabPtr,
3415 Operationrec* regOperPtr);
3416 void scanProcedure(Signal* signal,
3417 Operationrec* regOperPtr,
3418 SectionHandle* handle,
3419 bool isCopy);
3420 void storedProcBufferSeizeErrorLab(Signal* signal,
3421 Operationrec* regOperPtr,
3422 Uint32 storedProcPtr,
3423 Uint32 errorCode);
3424
3425 //-----------------------------------------------------------------------------
3426 // Table Descriptor Memory Manager
3427 //-----------------------------------------------------------------------------
3428
3429 // Public methods
3430 Uint32 getTabDescrOffsets(Uint32, Uint32, Uint32, Uint32, Uint32*);
3431 Uint32 getDynTabDescrOffsets(Uint32 MaskSize, Uint32* offset);
3432 Uint32 allocTabDescr(Uint32 allocSize);
3433 void releaseTabDescr(Uint32 desc);
3434
3435 void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
3436 Uint32 getTabDescrWord(Uint32 index);
3437 void setTabDescrWord(Uint32 index, Uint32 word);
3438
3439 // Private methods
3440 Uint32 sizeOfReadFunction();
3441 void removeTdArea(Uint32 tabDesRef, Uint32 list);
3442 void insertTdArea(Uint32 tabDesRef, Uint32 list);
3443 void itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
3444 void verifytabdes();
3445
3446 void seizeOpRec(OperationrecPtr& regOperPtr);
3447 void seizeFragrecord(FragrecordPtr& regFragPtr);
3448 void seizeFragoperrec(FragoperrecPtr& fragOperPtr);
3449 void seizeAlterTabOperation(AlterTabOperationPtr& alterTabOpPtr);
3450 void releaseFragoperrec(FragoperrecPtr fragOperPtr);
3451 void releaseFragrec(FragrecordPtr);
3452 void releaseAlterTabOpRec(AlterTabOperationPtr regAlterTabOpPtr);
3453
3454 //----------------------------------------------------------------------------
3455 // Page Memory Manager
3456 //----------------------------------------------------------------------------
3457
3458 // Public methods
3459 void allocConsPages(EmulatedJamBuffer* jamBuf,
3460 Uint32 noOfPagesToAllocate,
3461 Uint32& noOfPagesAllocated,
3462 Uint32& allocPageRef);
3463 void returnCommonArea(Uint32 retPageRef, Uint32 retNo);
3464 bool returnCommonArea_for_reuse(Uint32 retPageRef, Uint32 retNo);
3465 void initializePage();
3466
3467 Uint32 nextHigherTwoLog(Uint32 input);
3468
3469 Uint32 m_pages_allocated;
3470 Uint32 m_pages_allocated_max;
3471
3472 //------------------------------------------------------------------------------------------------------
3473 // Page Mapper, convert logical page id's to physical page id's
3474 // The page mapper also handles the pages allocated to the fragment.
3475 //------------------------------------------------------------------------------------------------------
3476 //
3477 // Public methods
3478 Uint32 getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId);
3479 Uint32 getRealpidCheck(Fragrecord* regFragPtr, Uint32 logicalPageId);
3480 Uint32 getRealpidScan(Fragrecord* regFragPtr,
3481 Uint32 logicalPageId,
3482 Uint32 **next_ptr,
3483 Uint32 **prev_ptr);
3484 void set_last_lcp_state(Fragrecord*, Uint32, bool);
3485 void set_last_lcp_state(Uint32*, bool);
3486 bool get_last_lcp_state(Uint32 *prev_ptr);
3487 bool get_lcp_scanned_bit(Fragrecord*, Uint32);
3488 bool get_lcp_scanned_bit(Uint32 *next_ptr);
3489 //void reset_lcp_scanned_bit(Fragrecord*, Uint32);
3490 void reset_lcp_scanned_bit(Uint32 *next_ptr);
3491
3492 Uint32 getNoOfPages(Fragrecord* regFragPtr);
3493 Uint32 getEmptyPage(Fragrecord* regFragPtr);
3494 Uint32 allocFragPage(EmulatedJamBuffer* jamBuf,
3495 Uint32 * err,
3496 Fragrecord* regFragPtr,
3497 Tablerec *regTabPtr);
3498 Uint32 allocFragPage(Uint32 * err, Tablerec*, Fragrecord*, Uint32 page_no);
3499 void releaseFragPage(Fragrecord* regFragPtr,
3500 Uint32 logicalPageId,
3501 PagePtr);
3502 void rebuild_page_free_list(Signal*);
3503 Uint32 get_empty_var_page(Fragrecord* frag_ptr);
3504 void init_page(Fragrecord*, PagePtr, Uint32 page_no);
3505
3506 // Private methods
3507 void errorHandler(Uint32 errorCode);
3508 Uint32 insert_new_page_into_page_map(EmulatedJamBuffer *jamBuf,
3509 Fragrecord *fragPtrP,
3510 PagePtr pagePtr,
3511 Uint32 noOfPagesAllocated);
3512 Uint32 remove_first_free_from_page_map(EmulatedJamBuffer *jamBuf,
3513 Fragrecord *fragPtrP,
3514 PagePtr pagePtr);
3515 void remove_page_id_from_dll(Fragrecord *fragPtrP,
3516 Uint32 page_no,
3517 Uint32 pagePtrI,
3518 Uint32 *ptr);
3519 void handle_lcp_skip_bit(EmulatedJamBuffer *jamBuf,
3520 Fragrecord *fragPtrP,
3521 PagePtr pagePtr,
3522 Uint32 page_no);
3523 void handle_new_page(EmulatedJamBuffer *jamBuf,
3524 Fragrecord *fragPtrP,
3525 Tablerec *tabPtrP,
3526 PagePtr pagePtr,
3527 Uint32 page_no);
3528
3529 void record_delete_by_pageid(Signal *signal,
3530 Uint32 tableId,
3531 Uint32 fragmentId,
3532 ScanOp &scan,
3533 Uint32 page_no,
3534 Uint32 record_size,
3535 bool set_scan_state);
3536
3537 void record_delete_by_rowid(Signal *signal,
3538 Uint32 tableId,
3539 Uint32 fragmentId,
3540 ScanOp &scan,
3541 Local_key &key,
3542 Uint32 foundGCI,
3543 bool set_scan_state);
3544
3545 //---------------------------------------------------------------
3546 // Variable Allocator
3547 // Allocates and deallocates tuples of fixed size on a fragment.
3548 //---------------------------------------------------------------
3549 //
3550 // Public methods
3551
3552 void init_list_sizes(void);
3553
3554 // Private methods
3555
3556 Uint32 get_alloc_page(Fragrecord* const, Uint32);
3557 void update_free_page_list(Fragrecord* const, Ptr<Page>);
3558
3559 #if 0
3560 Uint32 calc_free_list(const Tablerec* regTabPtr, Uint32 sz) const {
3561 return regTabPtr->m_disk_alloc_info.calc_page_free_bits(sz);
3562 }
3563 #endif
3564
3565 Uint32 calculate_free_list_impl(Uint32) const;
3566 Uint32 calculate_free_list_for_alloc(Uint32) const;
3567 Uint64 calculate_used_var_words(Fragrecord* fragPtr);
3568 void remove_free_page(Fragrecord*, Var_page*, Uint32);
3569 void insert_free_page(Fragrecord*, Var_page*, Uint32);
3570
3571 //---------------------------------------------------------------
3572 // Fixed Allocator
3573 // Allocates and deallocates tuples of fixed size on a fragment.
3574 //---------------------------------------------------------------
3575 //
3576 // Public methods
3577 Uint32* alloc_var_rec(Uint32 * err,
3578 Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
3579 void free_var_rec(Fragrecord*, Tablerec*, Local_key*, Ptr<Page>);
3580 void free_var_part(Fragrecord*, Tablerec*, Local_key*);
3581 Uint32* alloc_var_part(Uint32*err,Fragrecord*, Tablerec*, Uint32, Local_key*);
3582 Uint32 *realloc_var_part(Uint32 * err, Fragrecord*, Tablerec*,
3583 PagePtr, Var_part_ref*, Uint32, Uint32);
3584
3585 void move_var_part(Fragrecord* fragPtr, Tablerec* tabPtr, PagePtr pagePtr,
3586 Var_part_ref* refptr, Uint32 size);
3587
3588 void free_var_part(Fragrecord* fragPtr, PagePtr pagePtr, Uint32 page_idx);
3589
3590 void validate_page(Tablerec*, Var_page* page);
3591
3592 Uint32* alloc_fix_rec(EmulatedJamBuffer* jamBuf, Uint32* err,
3593 Fragrecord*const, Tablerec*const, Local_key*,
3594 Uint32*);
3595 void free_fix_rec(Fragrecord*, Tablerec*, Local_key*, Fix_page*);
3596
3597 Uint32* alloc_fix_rowid(Uint32 * err,
3598 Fragrecord*, Tablerec*, Local_key*, Uint32 *);
3599 Uint32* alloc_var_rowid(Uint32 * err,
3600 Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
3601 // Private methods
3602 void convertThPage(Fix_page* regPagePtr,
3603 Tablerec*,
3604 Uint32 mm);
3605
3606 /**
3607 * Return offset
3608 */
3609 Uint32 alloc_tuple_from_page(Fragrecord* regFragPtr,
3610 Fix_page* regPagePtr);
3611
3612 //---------------------------------------------------------------
3613 // Temporary variables used for storing commonly used variables
3614 // in certain modules
3615 //---------------------------------------------------------------
3616
3617 Uint32 c_lcp_scan_op;
3618 Uint32 c_copy_frag_scan_op;
3619
3620 // readAttributes and updateAttributes module
3621 //------------------------------------------------------------------------------------------------------
3622 // Common stored variables. Variables that have a valid value always.
3623 //------------------------------------------------------------------------------------------------------
3624 bool m_immediate_flag; // Temporary variable
3625 Fragoperrec *fragoperrec;
3626 Uint32 cfirstfreeFragopr;
3627 Uint32 cnoOfFragoprec;
3628 RSS_OP_COUNTER(cnoOfFreeFragoprec);
3629 RSS_OP_SNAPSHOT(cnoOfFreeFragoprec);
3630
3631 Fragrecord *fragrecord;
3632 Uint32 cfirstfreefrag;
3633 Uint32 cnoOfFragrec;
3634 RSS_OP_COUNTER(cnoOfFreeFragrec);
3635 RSS_OP_SNAPSHOT(cnoOfFreeFragrec);
3636 FragrecordPtr prepare_fragptr;
3637
3638 /*
3639 * DefaultValuesFragment is a normal struct Fragrecord.
3640 * It is TUP block-variable.
3641 * There is only ONE DefaultValuesFragment shared
3642 * among all table fragments stored by this TUP block.
3643 */
3644 FragrecordPtr DefaultValuesFragment;
3645 RSS_OP_SNAPSHOT(defaultValueWordsHi);
3646 RSS_OP_SNAPSHOT(defaultValueWordsLo);
3647
3648 AlterTabOperation *alterTabOperRec;
3649 Uint32 cfirstfreeAlterTabOp;
3650 Uint32 cnoOfAlterTabOps;
3651
3652 HostBuffer *hostBuffer;
3653
3654 NdbMutex c_page_map_pool_mutex;
3655 DynArr256Pool c_page_map_pool;
3656 Operationrec_pool c_operation_pool;
3657
3658 bool c_allow_alloc_spare_page;
3659 Page_pool c_page_pool;
3660
3661 /* read ahead in pages during disk order scan */
3662 Uint32 m_max_page_read_ahead;
3663
3664 Tablerec *tablerec;
3665 Uint32 cnoOfTablerec;
3666
3667 TableDescriptor *tableDescriptor;
3668 Uint32 cnoOfTabDescrRec;
3669 RSS_OP_COUNTER(cnoOfFreeTabDescrRec);
3670 RSS_OP_SNAPSHOT(cnoOfFreeTabDescrRec);
3671 TablerecPtr prepare_tabptr;
3672
3673 TablerecPtr m_curr_tabptr;
3674 FragrecordPtr m_curr_fragptr;
3675
3676 PagePtr prepare_pageptr;
3677 Uint32 *prepare_tuple_ptr;
3678 #ifdef VM_TRACE
3679 Local_key prepare_orig_local_key;
3680 #endif
3681 Uint32 prepare_page_no;
3682 Uint32 prepare_page_idx;
3683 Uint64 c_debug_count;
3684
3685 Uint32 cdata[32];
3686 Uint32 cdataPages[16];
3687 Uint32 cpackedListIndex;
3688 Uint32 cpackedList[MAX_NODES];
3689 Uint32 cerrorPackedDelay;
3690 Uint32 cfreeTdList[16];
3691 Uint32 clastBitMask;
3692 Uint32 clblPageCounter;
3693 Uint32 clblPagesPerTick;
3694 Uint32 clblPagesPerTickAfterSr;
3695 BlockReference clqhBlockref;
3696 Uint32 clqhUserpointer;
3697 Uint32 cminusOne;
3698 BlockReference cndbcntrRef;
3699 BlockReference cownref;
3700 Uint32 cownNodeId;
3701 Uint32 czero;
3702 Uint32 cCopyProcedure;
3703 Uint32 cCopyLastSeg;
3704 Uint32 cCopyOverwrite;
3705 Uint32 cCopyOverwriteLen;
3706
3707 // A little bit bigger to cover overwrites in copy algorithms (16384 real size).
3708 #define ZATTR_BUFFER_SIZE 16384
3709 Uint32 clogMemBuffer[ZATTR_BUFFER_SIZE + 16];
3710 Uint32 coutBuffer[ZATTR_BUFFER_SIZE + 16];
3711 Uint32 cinBuffer[ZATTR_BUFFER_SIZE + 16];
3712
3713 /*
3714 * In executeTrigger()
3715 * - cinBuffer also used for key
3716 * - coutBuffer also used for after values
3717 * - clogMemBuffer also used for before values
3718 */
3719 static_assert(sizeof(clogMemBuffer) >=
3720 sizeof(Uint32) * (MAX_TUPLE_SIZE_IN_WORDS + MAX_ATTRIBUTES_IN_TABLE), "");
3721 static_assert(sizeof(coutBuffer) >=
3722 sizeof(Uint32) * (MAX_TUPLE_SIZE_IN_WORDS + MAX_ATTRIBUTES_IN_TABLE), "");
3723 static_assert(sizeof(cinBuffer) >=
3724 sizeof(Uint32) * (MAX_KEY_SIZE_IN_WORDS + MAX_ATTRIBUTES_IN_INDEX), "");
3725
3726 Uint32 ctemp_page[ZWORDS_ON_PAGE];
3727 Uint32 ctemp_var_record[ZWORDS_ON_PAGE];
3728
3729 // Trigger variables
3730 Uint32 c_maxTriggersPerTable;
3731 Uint32 m_max_parallel_index_build;
3732
3733 Uint32 c_errorInsert4000TableId;
3734 Uint32 c_min_list_size[MAX_FREE_LIST + 1];
3735 Uint32 c_max_list_size[MAX_FREE_LIST + 1];
3736
3737 void initGlobalTemporaryVars();
3738 void reportMemoryUsage(Signal* signal, int incDec);
3739
3740
3741 #ifdef VM_TRACE
3742 struct Th {
3743 Uint32 data[1];
3744 };
3745 friend class NdbOut& operator<<(NdbOut&, const Operationrec&);
3746 friend class NdbOut& operator<<(NdbOut&, const Th&);
3747 #endif
3748
3749 void expand_tuple(KeyReqStruct*,
3750 Uint32 sizes[4],
3751 Tuple_header *org,
3752 const Tablerec*,
3753 bool disk,
3754 bool from_lcp_keep = false);
3755 void shrink_tuple(KeyReqStruct*,
3756 Uint32 sizes[2],
3757 const Tablerec*,
3758 bool disk);
3759
3760 Uint32* get_ptr(Var_part_ref);
3761 Uint32* get_ptr(PagePtr*, Var_part_ref);
3762 Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
3763 Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
3764 Uint32* get_default_ptr(const Tablerec*, Uint32&);
3765 Uint32 get_len(Ptr<Page>* pagePtr, Var_part_ref ref);
3766
3767 STATIC_CONST( COPY_TUPLE_HEADER32 = 4 );
3768
alloc_copy_tuple(const Tablerec * tabPtrP,Local_key * ptr)3769 Tuple_header* alloc_copy_tuple(const Tablerec* tabPtrP, Local_key* ptr){
3770 Uint32 * dst = c_undo_buffer.alloc_copy_tuple(ptr,
3771 tabPtrP->total_rec_size);
3772 if (unlikely(dst == 0))
3773 return 0;
3774 #ifdef HAVE_VALGRIND
3775 bzero(dst, tabPtrP->total_rec_size);
3776 #endif
3777 Uint32 count = tabPtrP->m_no_of_attributes;
3778 ChangeMask * mask = (ChangeMask*)(dst + COPY_TUPLE_HEADER32);
3779 mask->m_cols = count;
3780 return (Tuple_header*)(mask->end_of_mask(count));
3781 }
3782
get_copy_tuple_raw(const Local_key * ptr)3783 Uint32 * get_copy_tuple_raw(const Local_key* ptr) {
3784 return c_undo_buffer.get_ptr(ptr);
3785 }
3786
get_copy_tuple(Uint32 * rawptr)3787 Tuple_header * get_copy_tuple(Uint32 * rawptr) {
3788 return (Tuple_header*)
3789 (get_change_mask_ptr(rawptr)->end_of_mask());
3790 }
3791
get_change_mask_ptr(Uint32 * rawptr)3792 ChangeMask * get_change_mask_ptr(Uint32 * rawptr) {
3793 return (ChangeMask*)(rawptr + COPY_TUPLE_HEADER32);
3794 }
3795
get_copy_tuple(const Local_key * ptr)3796 Tuple_header* get_copy_tuple(const Local_key* ptr){
3797 return get_copy_tuple(get_copy_tuple_raw(ptr));
3798 }
3799
get_change_mask_ptr(const Tablerec * tabP,Tuple_header * copytuple)3800 ChangeMask* get_change_mask_ptr(const Tablerec* tabP,Tuple_header* copytuple){
3801 Uint32 * raw = (Uint32*)copytuple;
3802 Uint32 * tmp = raw - (1 + ((tabP->m_no_of_attributes + 31) >> 5));
3803 ChangeMask* mask = (ChangeMask*)tmp;
3804 assert(mask->end_of_mask() == raw);
3805 assert(get_copy_tuple(tmp - COPY_TUPLE_HEADER32) == copytuple);
3806 return mask;
3807 }
3808
3809 /**
3810 * prealloc space from disk
3811 * key.m_file_no contains file no
3812 * key.m_page_no contains disk page
3813 * key.m_page_idx contains byte preallocated
3814 */
3815 int disk_page_prealloc(Signal*, Ptr<Fragrecord>, Local_key*, Uint32);
3816 void disk_page_prealloc_dirty_page(Disk_alloc_info&,
3817 Ptr<Page>,
3818 Uint32,
3819 Uint32,
3820 Fragrecord*);
3821 void disk_page_prealloc_transit_page(Disk_alloc_info&,
3822 Ptr<Page_request>, Uint32, Uint32);
3823
3824 void disk_page_abort_prealloc(Signal*, Fragrecord*,Local_key*, Uint32);
3825 void disk_page_abort_prealloc_callback(Signal*, Uint32, Uint32);
3826 void disk_page_abort_prealloc_callback_1(Signal*, Fragrecord*,
3827 PagePtr, Uint32);
3828
3829 void disk_page_prealloc_callback(Signal*, Uint32, Uint32);
3830 void disk_page_prealloc_initial_callback(Signal*, Uint32, Uint32);
3831 void disk_page_prealloc_callback_common(Signal*,
3832 Ptr<Page_request>,
3833 Ptr<Fragrecord>,
3834 Ptr<Page>);
3835
3836 void disk_page_alloc(Signal*,
3837 Tablerec*,
3838 Fragrecord*,
3839 Local_key*,
3840 PagePtr,
3841 Uint32,
3842 const Local_key*,
3843 Uint32 alloc_size);
3844 void disk_page_free(Signal*,
3845 Tablerec*,
3846 Fragrecord*,
3847 Local_key*,
3848 PagePtr,
3849 Uint32,
3850 const Local_key*,
3851 Uint32 alloc_size);
3852
3853 void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);
3854
3855 void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32);
3856
3857 void disk_page_alloc_extent_log_buffer_callback(Signal*, Uint32, Uint32);
3858 void disk_page_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
3859
3860 Uint64 disk_page_undo_alloc(Signal *signal,
3861 Page*,
3862 const Local_key*,
3863 Uint32 sz,
3864 Uint32 gci,
3865 Uint32 logfile_group_id,
3866 Uint32 alloc_size);
3867
3868 Uint64 disk_page_undo_update(Signal *signal,
3869 Page*,
3870 const Local_key*,
3871 const Uint32*,
3872 Uint32 sz,
3873 Uint32 gci,
3874 Uint32 logfile_group_id,
3875 Uint32 alloc_size);
3876
3877 Uint64 disk_page_undo_free(Signal *signal,
3878 Page*,
3879 const Local_key*,
3880 const Uint32*,
3881 Uint32 sz,
3882 Uint32 gci,
3883 Uint32 logfile_group_id,
3884 Uint32 alloc_size);
3885
3886 void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
3887
3888 void drop_table_logsync_callback(Signal*, Uint32, Uint32);
3889 void drop_table_log_buffer_callback(Signal*, Uint32, Uint32);
3890
3891 void disk_page_set_dirty(Ptr<Page>);
3892 void restart_setup_page(Ptr<Fragrecord> fragPtr,
3893 Disk_alloc_info&,
3894 Ptr<Page>,
3895 Int32 estimate);
3896 void update_extent_pos(EmulatedJamBuffer* jamBuf, Disk_alloc_info&,
3897 Ptr<Extent_info>, Int32 delta);
3898
3899 void disk_page_move_page_request(Disk_alloc_info& alloc,
3900 Ptr<Extent_info>,
3901 Ptr<Page_request> req,
3902 Uint32 old_idx, Uint32 new_idx);
3903
3904 void disk_page_move_dirty_page(Disk_alloc_info& alloc,
3905 Ptr<Extent_info> extentPtr,
3906 Ptr<Page> pagePtr,
3907 Uint32 old_idx,
3908 Uint32 new_idx,
3909 Fragrecord*);
3910
3911 void disk_page_get_allocated(const Tablerec*, const Fragrecord*,
3912 Uint64 res[2]);
3913 /**
3914 * Disk restart code
3915 */
3916 public:
3917 int disk_page_load_hook(Uint32 page_id);
3918
3919 void disk_page_unmap_callback(Uint32 when, Uint32 page, Uint32 dirty_count);
3920
3921 int disk_restart_alloc_extent(EmulatedJamBuffer* jamBuf,
3922 Uint32 tableId,
3923 Uint32 fragId,
3924 Uint32 create_table_version,
3925 const Local_key* key,
3926 Uint32 pages);
3927 void disk_restart_page_bits(EmulatedJamBuffer* jamBuf,
3928 Uint32 tableId,
3929 Uint32 fragId,
3930 Uint32 create_table_version,
3931 const Local_key*,
3932 Uint32 bits);
3933 void disk_restart_undo(Signal* signal,
3934 Uint64 lsn,
3935 Uint32 type,
3936 const Uint32 * ptr,
3937 Uint32 len);
3938
3939 void verify_undo_log_execution();
3940 struct Apply_undo
3941 {
3942 bool m_in_intermediate_log_record;
3943 Uint32 m_type;
3944 Uint32 m_len;
3945 Uint32 m_offset;
3946 const Uint32* m_ptr;
3947 Uint32 m_data[MAX_UNDO_DATA];
3948 Uint64 m_lsn;
3949 Ptr<Tablerec> m_table_ptr;
3950 Ptr<Fragrecord> m_fragment_ptr;
3951 Ptr<Page> m_page_ptr;
3952 Ptr<Extent_info> m_extent_ptr;
3953 Local_key m_key;
3954 Uint32 nextList;
3955 union { Uint32 nextPool; Uint32 prevList; };
3956 Uint32 m_magic;
3957
3958 Apply_undo();
3959 };
3960 typedef RecordPool<RWPool<Apply_undo> > Apply_undo_pool;
3961 typedef DLCFifoList<Apply_undo_pool> Apply_undo_list;
3962 typedef LocalDLCFifoList<Apply_undo_pool> LocalApply_undo_list;
3963
3964 Apply_undo_pool c_apply_undo_pool;
3965
3966 struct Pending_undo_page
3967 {
Pending_undo_pageDbtup::Pending_undo_page3968 Pending_undo_page() {}
Pending_undo_pageDbtup::Pending_undo_page3969 Pending_undo_page(Uint32 file_no, Uint32 page_no)
3970 {
3971 m_file_no = file_no;
3972 m_page_no = page_no;
3973 }
3974
3975 Uint16 m_file_no;
3976 Uint32 m_page_no;
3977 Apply_undo_list::Head m_apply_undo_head;
3978
3979 Uint32 nextHash;
3980 union { Uint32 prevHash; Uint32 nextPool; };
3981 Uint32 m_magic;
3982
hashValueDbtup::Pending_undo_page3983 Uint32 hashValue() const
3984 {
3985 return m_file_no << 16 | m_page_no;
3986 }
3987
equalDbtup::Pending_undo_page3988 bool equal(const Pending_undo_page& obj) const
3989 {
3990 return m_file_no == obj.m_file_no && m_page_no == obj.m_page_no;
3991 }
3992 };
3993
3994 typedef RecordPool<RWPool<Pending_undo_page> >
3995 Pending_undo_page_pool;
3996 typedef DLCHashTable<Pending_undo_page_pool>
3997 Pending_undo_page_hash;
3998
3999 void disk_restart_lcp_id(Uint32 table,
4000 Uint32 frag,
4001 Uint32 lcpId,
4002 Uint32 localLcpId);
4003
4004 bool is_disk_columns_in_table(Uint32 tableId);
4005
4006 private:
4007 bool c_started;
4008
4009 Pending_undo_page_pool c_pending_undo_page_pool;
4010 Pending_undo_page_hash c_pending_undo_page_hash;
4011
4012 // these 2 were file-static before mt-lqh
4013 bool f_undo_done;
4014 Dbtup::Apply_undo f_undo;
4015
4016 // Error code when bailing out of scan
4017 Uint32 m_scan_error_code;
4018 void disk_restart_undo_next(Signal*,
4019 Uint32 applied = 0,
4020 Uint32 count_pending = 1);
4021 void disk_restart_undo_lcp(Uint32,
4022 Uint32,
4023 Uint32 flag,
4024 Uint32 lcpId,
4025 Uint32 localLcpId);
4026 void release_undo_record(Ptr<Apply_undo>&, bool);
4027
4028 void disk_restart_undo_callback(Signal* signal, Uint32, Uint32);
4029 void disk_restart_undo_alloc(Apply_undo*);
4030 void disk_restart_undo_update(Apply_undo*);
4031 void disk_restart_undo_update_first_part(Apply_undo*);
4032 void disk_restart_undo_update_part(Apply_undo*);
4033 void disk_restart_undo_free(Apply_undo*, bool);
4034 void disk_restart_undo_page_bits(Signal*, Apply_undo*);
4035
4036 #ifdef VM_TRACE
4037 void verify_page_lists(Disk_alloc_info&);
4038 #else
verify_page_lists(Disk_alloc_info &)4039 void verify_page_lists(Disk_alloc_info&) {}
4040 #endif
4041
4042 void findFirstOp(OperationrecPtr&);
4043 bool is_rowid_in_remaining_lcp_set(const Page* page,
4044 Fragrecord* regFragPtr,
4045 const Local_key& key1,
4046 const Dbtup::ScanOp& op,
4047 Uint32 check_lcp_scanned_state_reversed);
4048 void update_gci(Fragrecord*, Tablerec*, Tuple_header*, Uint32);
4049 void commit_operation(Signal*,
4050 Uint32,
4051 Uint32,
4052 Tuple_header*,
4053 PagePtr,
4054 Operationrec*,
4055 Fragrecord*,
4056 Tablerec*,
4057 Ptr<GlobalPage> diskPagePtr);
4058
4059 void commit_refresh(Signal*,
4060 Uint32,
4061 Uint32,
4062 Tuple_header*,
4063 PagePtr,
4064 KeyReqStruct*,
4065 Operationrec*,
4066 Fragrecord*,
4067 Tablerec*,
4068 Ptr<GlobalPage> diskPagePtr);
4069
4070 int retrieve_data_page(Signal*,
4071 Page_cache_client::Request,
4072 OperationrecPtr,
4073 Ptr<GlobalPage> &diskPagePtr,
4074 Fragrecord *fragPtrP);
4075 int retrieve_log_page(Signal*, FragrecordPtr, OperationrecPtr);
4076
4077 void dealloc_tuple(Signal* signal,
4078 Uint32,
4079 Uint32,
4080 Page*,
4081 Tuple_header*,
4082 KeyReqStruct*,
4083 Operationrec*,
4084 Fragrecord*,
4085 Tablerec*,
4086 Ptr<GlobalPage> diskPagePtr);
4087
4088 bool store_extra_row_bits(Uint32, const Tablerec*, Tuple_header*, Uint32,
4089 bool);
4090 void read_extra_row_bits(Uint32, const Tablerec*, Tuple_header*, Uint32 *,
4091 bool);
4092
4093 int handle_size_change_after_update(KeyReqStruct* req_struct,
4094 Tuple_header* org,
4095 Operationrec*,
4096 Fragrecord* regFragPtr,
4097 Tablerec* regTabPtr,
4098 Uint32 sizes[4]);
4099 int optimize_var_part(KeyReqStruct* req_struct,
4100 Tuple_header* org,
4101 Operationrec* regOperPtr,
4102 Fragrecord* regFragPtr,
4103 Tablerec* regTabPtr);
4104
4105 /**
4106 * Setup all pointer on keyreqstruct to prepare for read
4107 * req_struct->m_tuple_ptr is set to tuple to read
4108 */
4109 void prepare_read(KeyReqStruct*, Tablerec* const, bool disk);
4110
4111 /* For debugging, dump the contents of a tuple. */
4112 void dump_tuple(const KeyReqStruct* req_struct, const Tablerec* tabPtrP);
4113
4114 #ifdef VM_TRACE
4115 void check_page_map(Fragrecord*);
4116 bool find_page_id_in_list(Fragrecord*, Uint32 pid);
4117 #endif
4118 Uint32* init_page_map_entry(Fragrecord*, Uint32);
4119 const char* insert_free_page_id_list(Fragrecord* fragPtrP,
4120 Uint32 logicalPageId,
4121 Uint32 *next,
4122 Uint32 *prev,
4123 Uint32 lcp_scanned_bit,
4124 Uint32 last_lcp_state);
4125 void remove_top_from_lcp_keep_list(Fragrecord*, Uint32*, Local_key);
4126 void insert_lcp_keep_list(Fragrecord*, Local_key, Uint32*, const Local_key*);
4127 void handle_lcp_drop_change_page(Fragrecord*, Uint32, PagePtr, bool);
4128 void handle_lcp_keep(Signal*, FragrecordPtr, ScanOp*);
4129 void handle_lcp_keep_commit(const Local_key*,
4130 KeyReqStruct *,
4131 Operationrec*, Fragrecord*, Tablerec*);
4132
4133 void setup_lcp_read_copy_tuple( KeyReqStruct *,
4134 Operationrec*,
4135 Tablerec*);
4136
isCopyTuple(Uint32 pageid,Uint32 pageidx) const4137 bool isCopyTuple(Uint32 pageid, Uint32 pageidx) const {
4138 return (pageidx & (Uint16(1) << 15)) != 0;
4139 }
4140
setCopyTuple(Uint32 & pageid,Uint16 & pageidx) const4141 void setCopyTuple(Uint32& pageid, Uint16& pageidx) const {
4142 assert(!isCopyTuple(pageid, pageidx));
4143 pageidx |= (Uint16(1) << 15);
4144 assert(isCopyTuple(pageid, pageidx));
4145 }
4146
clearCopyTuple(Uint32 & pageid,Uint16 & pageidx) const4147 void clearCopyTuple(Uint32& pageid, Uint16& pageidx) const {
4148 assert(isCopyTuple(pageid, pageidx));
4149 pageidx &= ~(Uint16(1) << 15);
4150 assert(!isCopyTuple(pageid, pageidx));
4151 }
4152
4153 private:
4154 void release_c_free_scan_lock();
4155 bool getNextTcConRec(Uint32 &next,
4156 OperationrecPtr &opPtr,
4157 Uint32 max_loops);
4158
4159 void checkPoolShrinkNeed(Uint32 pool_index,
4160 const TransientFastSlotPool& pool);
4161 void sendPoolShrink(Uint32 pool_index);
4162 void shrinkTransientPools(Uint32 pool_index);
4163
4164 static const Uint32 c_transient_pool_count = 4;
4165 TransientFastSlotPool* c_transient_pools[c_transient_pool_count];
4166 Bitmask<1> c_transient_pools_shrinking;
4167
4168 Uint32 c_copy_frag_scan_lock;
4169 void release_scan_lock(ScanLockPtr);
4170
4171 public:
4172 static Uint64 getTransactionMemoryNeed(
4173 const Uint32 ldm_instance_count,
4174 const ndb_mgm_configuration_iterator * mgm_cfg,
4175 const bool use_reserved);
4176 bool seize_op_rec(Uint32 userptr,
4177 BlockReference ref,
4178 Uint32 &i_val,
4179 Operationrec **opPtrP);
4180 Operationrec* get_operation_ptr(Uint32 i);
4181 void release_op_rec(Uint32 opPtrI,
4182 Operationrec *opPtrP);
4183 };
4184
4185 inline void
prepare_op_pointer(Uint32 opPtrI,Dbtup::Operationrec * opPtrP)4186 Dbtup::prepare_op_pointer(Uint32 opPtrI,
4187 Dbtup::Operationrec *opPtrP)
4188 {
4189 jamDebug();
4190 Uint32 *op_ptr = (Uint32*)opPtrP;
4191 NDB_PREFETCH_WRITE(op_ptr);
4192 NDB_PREFETCH_WRITE(op_ptr + 16);
4193 prepare_oper_ptr.i = opPtrI;
4194 prepare_oper_ptr.p = opPtrP;
4195 }
4196
4197
4198 inline void
release_op_rec(Uint32 opPtrI,Dbtup::Operationrec * opPtrP)4199 Dbtup::release_op_rec(Uint32 opPtrI,
4200 Dbtup::Operationrec *opPtrP)
4201 {
4202 OperationrecPtr opPtr;
4203 opPtr.i = opPtrI;
4204 opPtr.p = opPtrP;
4205 c_operation_pool.release(opPtr);
4206 checkPoolShrinkNeed(DBTUP_OPERATION_RECORD_TRANSIENT_POOL_INDEX,
4207 c_operation_pool);
4208 }
4209
checkPoolShrinkNeed(const Uint32 pool_index,const TransientFastSlotPool & pool)4210 inline void Dbtup::checkPoolShrinkNeed(const Uint32 pool_index,
4211 const TransientFastSlotPool& pool)
4212 {
4213 #if defined(VM_TRACE) || defined(ERROR_INSERT)
4214 ndbrequire(pool_index < c_transient_pool_count);
4215 ndbrequire(c_transient_pools[pool_index] == &pool);
4216 #endif
4217 if (pool.may_shrink())
4218 {
4219 sendPoolShrink(pool_index);
4220 }
4221 }
4222
4223 inline
4224 Uint32
get_current_frag_page_id()4225 Dbtup::get_current_frag_page_id()
4226 {
4227 return prepare_pageptr.p->frag_page_id;
4228 }
4229
4230 inline
4231 void
setup_fixed_tuple_ref_opt(KeyReqStruct * req_struct)4232 Dbtup::setup_fixed_tuple_ref_opt(KeyReqStruct* req_struct)
4233 {
4234 req_struct->m_page_ptr = prepare_pageptr;
4235 req_struct->m_tuple_ptr = (Tuple_header*)prepare_tuple_ptr;
4236 }
4237
4238 inline
4239 void
setup_fixed_tuple_ref(KeyReqStruct * req_struct,Operationrec * regOperPtr,Tablerec * regTabPtr)4240 Dbtup::setup_fixed_tuple_ref(KeyReqStruct* req_struct,
4241 Operationrec* regOperPtr,
4242 Tablerec* regTabPtr)
4243 {
4244 PagePtr page_ptr;
4245 Uint32* ptr= get_ptr(&page_ptr, ®OperPtr->m_tuple_location, regTabPtr);
4246 req_struct->m_page_ptr = page_ptr;
4247 req_struct->m_tuple_ptr = (Tuple_header*)ptr;
4248 }
4249
4250 inline
4251 Dbtup::TransState
get_trans_state(Operationrec * regOperPtr)4252 Dbtup::get_trans_state(Operationrec * regOperPtr)
4253 {
4254 return (Dbtup::TransState)regOperPtr->trans_state;
4255 }
4256
4257 inline
4258 void
set_trans_state(Operationrec * regOperPtr,Dbtup::TransState trans_state)4259 Dbtup::set_trans_state(Operationrec* regOperPtr,
4260 Dbtup::TransState trans_state)
4261 {
4262 regOperPtr->trans_state= (Uint32)trans_state;
4263 }
4264
4265 inline
4266 Dbtup::TupleState
get_tuple_state(Operationrec * regOperPtr)4267 Dbtup::get_tuple_state(Operationrec * regOperPtr)
4268 {
4269 return (Dbtup::TupleState)regOperPtr->tuple_state;
4270 }
4271
4272 inline
4273 void
set_tuple_state(Operationrec * regOperPtr,Dbtup::TupleState tuple_state)4274 Dbtup::set_tuple_state(Operationrec* regOperPtr,
4275 Dbtup::TupleState tuple_state)
4276 {
4277 regOperPtr->tuple_state= (Uint32)tuple_state;
4278 }
4279
4280
4281 inline
4282 Uint32
decr_tup_version(Uint32 tup_version)4283 Dbtup::decr_tup_version(Uint32 tup_version)
4284 {
4285 return (tup_version - 1) & ZTUP_VERSION_MASK;
4286 }
4287
4288 inline
4289 Uint32*
get_ptr(Var_part_ref ref)4290 Dbtup::get_ptr(Var_part_ref ref)
4291 {
4292 Ptr<Page> tmp;
4293 return get_ptr(&tmp, ref);
4294 }
4295
4296 inline
4297 Uint32*
get_ptr(Ptr<Page> * pagePtr,Var_part_ref ref)4298 Dbtup::get_ptr(Ptr<Page>* pagePtr, Var_part_ref ref)
4299 {
4300 PagePtr tmp;
4301 Local_key key;
4302 ref.copyout(&key);
4303 tmp.i = key.m_page_no;
4304
4305 c_page_pool.getPtr(tmp);
4306 memcpy(pagePtr, &tmp, sizeof(tmp));
4307 return ((Var_page*)tmp.p)->get_ptr(key.m_page_idx);
4308 }
4309
4310 inline
4311 Uint32*
get_ptr(PagePtr * pagePtr,const Local_key * key,const Tablerec * regTabPtr)4312 Dbtup::get_ptr(PagePtr* pagePtr,
4313 const Local_key* key, const Tablerec* regTabPtr)
4314 {
4315 PagePtr tmp;
4316 tmp.i= key->m_page_no;
4317 c_page_pool.getPtr(tmp);
4318 memcpy(pagePtr, &tmp, sizeof(tmp));
4319
4320 return ((Fix_page*)tmp.p)->
4321 get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
4322 }
4323
4324 inline
4325 Uint32*
get_default_ptr(const Tablerec * regTabPtr,Uint32 & default_len)4326 Dbtup::get_default_ptr(const Tablerec* regTabPtr, Uint32& default_len)
4327 {
4328 Var_part_ref ref;
4329 ref.assign(®TabPtr->m_default_value_location);
4330 Ptr<Page> page;
4331
4332 Uint32* default_data = get_ptr(&page, ref);
4333 default_len = get_len(&page, ref);
4334
4335 return default_data;
4336 }
4337
4338 inline
4339 Uint32*
get_dd_ptr(PagePtr * pagePtr,const Local_key * key,const Tablerec * regTabPtr)4340 Dbtup::get_dd_ptr(PagePtr* pagePtr,
4341 const Local_key* key, const Tablerec* regTabPtr)
4342 {
4343 PagePtr tmp;
4344 tmp.i= key->m_page_no;
4345 tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
4346 memcpy(pagePtr, &tmp, sizeof(tmp));
4347
4348 if(regTabPtr->m_attributes[DD].m_no_of_varsize ||
4349 regTabPtr->m_attributes[DD].m_no_of_dynamic)
4350 return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
4351 else
4352 return ((Fix_page*)tmp.p)->
4353 get_ptr(key->m_page_idx, regTabPtr->m_offsets[DD].m_fix_header_size);
4354 }
4355
4356 /*
4357 This function assumes that get_ptr() has been called first to
4358 initialise the pagePtr argument.
4359 */
4360 inline
4361 Uint32
get_len(Ptr<Page> * pagePtr,Var_part_ref ref)4362 Dbtup::get_len(Ptr<Page>* pagePtr, Var_part_ref ref)
4363 {
4364 Uint32 page_idx= ref.m_page_idx;
4365 return ((Var_page*)pagePtr->p)->get_entry_len(page_idx);
4366 }
4367
4368 NdbOut&
4369 operator<<(NdbOut&, const Dbtup::Tablerec&);
4370
4371 inline
find_savepoint(OperationrecPtr & loopOpPtr,Uint32 savepointId)4372 bool Dbtup::find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId)
4373 {
4374 while (true) {
4375 if (savepointId > loopOpPtr.p->savepointId) {
4376 jam();
4377 return true;
4378 }
4379 loopOpPtr.i = loopOpPtr.p->prevActiveOp;
4380 if (loopOpPtr.i == RNIL) {
4381 break;
4382 }
4383 ndbrequire(c_operation_pool.getValidPtr(loopOpPtr));
4384 }
4385 return false;
4386 }
4387
4388 inline
4389 void
update_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst,const Uint32 * src)4390 Dbtup::update_change_mask_info(const Tablerec* tablePtrP,
4391 ChangeMask* dst,
4392 const Uint32 * src)
4393 {
4394 assert(dst->m_cols == tablePtrP->m_no_of_attributes);
4395 Uint32 * ptr = dst->m_mask;
4396 Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
4397 for (Uint32 i = 0; i<len; i++)
4398 {
4399 * ptr |= *src;
4400 ptr++;
4401 src++;
4402 }
4403 }
4404
4405 inline
4406 void
set_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst)4407 Dbtup::set_change_mask_info(const Tablerec* tablePtrP, ChangeMask* dst)
4408 {
4409 assert(dst->m_cols == tablePtrP->m_no_of_attributes);
4410 Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
4411 BitmaskImpl::set(len, dst->m_mask);
4412 }
4413
4414 inline
4415 void
clear_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst)4416 Dbtup::clear_change_mask_info(const Tablerec* tablePtrP, ChangeMask* dst)
4417 {
4418 assert(dst->m_cols == tablePtrP->m_no_of_attributes);
4419 Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
4420 BitmaskImpl::clear(len, dst->m_mask);
4421 }
4422
4423 inline
4424 void
copy_change_mask_info(const Tablerec * tablePtrP,ChangeMask * dst,const ChangeMask * src)4425 Dbtup::copy_change_mask_info(const Tablerec* tablePtrP,
4426 ChangeMask* dst, const ChangeMask* src)
4427 {
4428 Uint32 dst_cols = tablePtrP->m_no_of_attributes;
4429 assert(dst->m_cols == dst_cols);
4430 Uint32 src_cols = src->m_cols;
4431
4432 if (dst_cols == src_cols)
4433 {
4434 memcpy(dst->m_mask, src->m_mask, 4 * ((dst_cols + 31) >> 5));
4435 }
4436 else
4437 {
4438 ndbassert(dst_cols > src_cols); // drop column not supported
4439 memcpy(dst->m_mask, src->m_mask, 4 * ((src_cols + 31) >> 5));
4440 BitmaskImpl::setRange((dst_cols + 31) >> 5, dst->m_mask,
4441 src_cols, (dst_cols - src_cols));
4442 }
4443 }
4444
4445 inline
4446 void
get_all_tup_ptrs(Uint32 indexFragPtrI,Uint32 tableFragPtrI,Uint32 ** index_fragptr,Uint32 ** index_tabptr,Uint32 ** real_fragptr,Uint32 ** real_tabptr,Uint32 & attrDataOffset,Uint32 & tuxFixHeaderSize)4447 Dbtup::get_all_tup_ptrs(Uint32 indexFragPtrI,
4448 Uint32 tableFragPtrI,
4449 Uint32 **index_fragptr,
4450 Uint32 **index_tabptr,
4451 Uint32 **real_fragptr,
4452 Uint32 **real_tabptr,
4453 Uint32 &attrDataOffset,
4454 Uint32 &tuxFixHeaderSize)
4455 {
4456 FragrecordPtr indexFragPtr;
4457 indexFragPtr.i= indexFragPtrI;
4458 ptrCheckGuard(indexFragPtr, cnoOfFragrec, fragrecord);
4459 TablerecPtr indexTablePtr;
4460 indexTablePtr.i= indexFragPtr.p->fragTableId;
4461 ptrCheckGuard(indexTablePtr, cnoOfTablerec, tablerec);
4462 *index_fragptr = (Uint32*)indexFragPtr.p;
4463 *index_tabptr = (Uint32*)indexTablePtr.p;
4464
4465 Uint32 attrDescIndex= indexTablePtr.p->tabDescriptor;
4466 attrDataOffset = AttributeOffset::getOffset(
4467 tableDescriptor[attrDescIndex + 1].tabDescr);
4468 tuxFixHeaderSize = indexTablePtr.p->m_offsets[MM].m_fix_header_size;
4469
4470 FragrecordPtr realFragPtr;
4471 TablerecPtr realTablePtr;
4472 realFragPtr.i = tableFragPtrI;
4473 ptrCheckGuard(realFragPtr, cnoOfFragrec, fragrecord);
4474 realTablePtr.i= realFragPtr.p->fragTableId;
4475 ptrCheckGuard(realTablePtr, cnoOfTablerec, tablerec);
4476 *real_fragptr = (Uint32*)realFragPtr.p;
4477 *real_tabptr = (Uint32*)realTablePtr.p;
4478 }
4479
4480 // Dbtup_client provides proxying similar to Page_cache_client
4481
4482 class Dbtup_client
4483 {
4484 friend class DbtupProxy;
4485 // jam buffer of caller block.
4486 EmulatedJamBuffer* const m_jamBuf;
4487 class DbtupProxy* m_dbtup_proxy; // set if we go via proxy
4488 Dbtup* m_dbtup;
4489 DEBUG_OUT_DEFINES(DBTUP);
4490
4491 public:
4492 Dbtup_client(SimulatedBlock* block, SimulatedBlock* dbtup);
4493
4494 // LGMAN
4495
4496 void disk_restart_undo(Signal* signal, Uint64 lsn,
4497 Uint32 type, const Uint32 * ptr, Uint32 len);
4498
4499 // TSMAN
4500
4501 int disk_restart_alloc_extent(Uint32 tableId,
4502 Uint32 fragId,
4503 Uint32 create_table_version,
4504 const Local_key* key,
4505 Uint32 pages);
4506
4507 void disk_restart_page_bits(Uint32 tableId,
4508 Uint32 fragId,
4509 Uint32 create_table_version,
4510 const Local_key* key,
4511 Uint32 bits);
4512 };
4513
4514 /**
4515 * Can be called from MT-build of ordered indexes.
4516 */
4517 inline
4518 void
tuxGetNode(Uint32 attrDataOffset,Uint32 tuxFixHeaderSize,Uint32 pageId,Uint32 pageOffset,Uint32 * & node)4519 Dbtup::tuxGetNode(Uint32 attrDataOffset,
4520 Uint32 tuxFixHeaderSize,
4521 Uint32 pageId,
4522 Uint32 pageOffset,
4523 Uint32*& node)
4524 {
4525 PagePtr pagePtr;
4526 c_page_pool.getPtr(pagePtr, pageId);
4527 node= ((Fix_page*)pagePtr.p)->
4528 get_ptr(pageOffset, tuxFixHeaderSize) + attrDataOffset;
4529 NDB_PREFETCH_READ((void*)node);
4530 }
4531
4532
4533 #undef JAM_FILE_ID
4534
4535 #endif
4536