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