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