1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef SCAN_FRAG_HPP
26 #define SCAN_FRAG_HPP
27
28 #include "SignalData.hpp"
29 #include "ndb_limits.h"
30
31 class ScanFragReq {
32 /**
33 * Sender(s)
34 */
35 friend class Dbtc;
36 friend class Backup;
37 friend class Suma;
38
39 /**
40 * Reciver(s)
41 */
42 friend class Dblqh;
43 friend class Dbspj;
44 public:
45 STATIC_CONST( SignalLength = 12 );
46
47 STATIC_CONST( AttrInfoSectionNum = 0 );
48 STATIC_CONST( KeyInfoSectionNum = 1 );
49
50 friend bool printSCAN_FRAGREQ(FILE *, const Uint32*, Uint32, Uint16);
51 friend bool printSCAN_FRAGCONF(FILE *, const Uint32*, Uint32, Uint16);
52
53 public:
54 enum ReorgFlag
55 {
56 REORG_ALL = 0
57 ,REORG_NOT_MOVED = 1 // Only return not moved rows
58 ,REORG_MOVED = 2 // Only return moved rows
59 };
60
61 Uint32 senderData;
62 Uint32 resultRef; // Where to send the result
63 Uint32 savePointId;
64 Uint32 requestInfo;
65 Uint32 tableId;
66 Uint32 fragmentNoKeyLen;
67 Uint32 schemaVersion;
68 Uint32 transId1;
69 Uint32 transId2;
70 union {
71 Uint32 clientOpPtr;
72 Uint32 resultData;
73 };
74 Uint32 batch_size_rows;
75 Uint32 batch_size_bytes;
76 Uint32 variableData[1];
77
78 static Uint32 getLockMode(const Uint32 & requestInfo);
79 static Uint32 getHoldLockFlag(const Uint32 & requestInfo);
80 static Uint32 getKeyinfoFlag(const Uint32 & requestInfo);
81 static Uint32 getReadCommittedFlag(const Uint32 & requestInfo);
82 static Uint32 getRangeScanFlag(const Uint32 & requestInfo);
83 static Uint32 getDescendingFlag(const Uint32 & requestInfo);
84 static Uint32 getTupScanFlag(const Uint32 & requestInfo);
85 static Uint32 getAttrLen(const Uint32 & requestInfo);
86 static Uint32 getScanPrio(const Uint32 & requestInfo);
87 static Uint32 getNoDiskFlag(const Uint32 & requestInfo);
88 static Uint32 getLcpScanFlag(const Uint32 & requestInfo);
89 static Uint32 getStatScanFlag(const Uint32 & requestInfo);
90
91 static void setLockMode(Uint32 & requestInfo, Uint32 lockMode);
92 static void setHoldLockFlag(Uint32 & requestInfo, Uint32 holdLock);
93 static void setKeyinfoFlag(Uint32 & requestInfo, Uint32 keyinfo);
94 static void setReadCommittedFlag(Uint32 & requestInfo, Uint32 readCommitted);
95 static void setRangeScanFlag(Uint32 & requestInfo, Uint32 rangeScan);
96 static void setDescendingFlag(Uint32 & requestInfo, Uint32 descending);
97 static void setTupScanFlag(Uint32 & requestInfo, Uint32 tupScan);
98 static void setAttrLen(Uint32 & requestInfo, Uint32 attrLen);
99 static void setScanPrio(Uint32& requestInfo, Uint32 prio);
100 static void setNoDiskFlag(Uint32& requestInfo, Uint32 val);
101 static void setLcpScanFlag(Uint32 & requestInfo, Uint32 val);
102 static void setStatScanFlag(Uint32 & requestInfo, Uint32 val);
103
104 static void setReorgFlag(Uint32 & requestInfo, Uint32 val);
105 static Uint32 getReorgFlag(const Uint32 & requestInfo);
106
107 static void setCorrFactorFlag(Uint32 & requestInfo, Uint32 val);
108 static Uint32 getCorrFactorFlag(const Uint32 & requestInfo);
109 };
110
111 /*
112 The KEYINFO20 signal is sent from LQH to API for each row in a scan when the
113 ScanTabReq::getKeyinfoFlag() is set in requestInfo in the SCAN_TABREQ signal.
114
115 The '20' in the signal name refers to the number of keyInfo data words in
116 the signal, which is actually a bit misleading since now it is sent as a
117 single long signal if the keyinfo has more than 20 words.
118
119 The information in this signal is used in the NDB API to request the take
120 over of a lock from the scan with a TCKEYREQ, using the primary key info
121 sent as data and the scanInfo_Node word to identify the lock.
122 */
123 class KeyInfo20 {
124 /**
125 * Sender(s)
126 */
127 friend class Dblqh;
128
129 /**
130 * Reciver(s)
131 */
132 friend class Backup;
133 friend class NdbOperation;
134 friend class NdbScanReceiver;
135 public:
136 STATIC_CONST( HeaderLength = 5);
137 STATIC_CONST( DataLength = 20 );
138
139
140 static Uint32 setScanInfo(Uint32 noOfOps, Uint32 scanNo);
141 static Uint32 getScanNo(Uint32 scanInfo);
142 static Uint32 getScanOp(Uint32 scanInfo);
143
144 public:
145 Uint32 clientOpPtr;
146 Uint32 keyLen;
147 /*
148 The scanInfo_Node word contains the information needed to identify the
149 row and lock to take over in the TCKEYREQ signal. It has two parts:
150 1. ScanInfo Lower 20 bits
151 2. ScanFragment Upper 14 bits
152 */
153 Uint32 scanInfo_Node;
154 Uint32 transId1;
155 Uint32 transId2;
156 Uint32 keyData[DataLength];
157 /*
158 Note that if the key info data does not fit within the maximum of 20
159 in-signal words, the entire key info is instead sent in long signal
160 section 0.
161 The data here is a word string suitable for sending as KEYINFO in
162 the TCKEYREQ signal.
163 */
164 };
165
166 class ScanFragConf {
167 /**
168 * Sender(s)
169 */
170 friend class Dblqh;
171
172 /**
173 * Reciver(s)
174 */
175 friend class Dbtc;
176 friend class Backup;
177 friend class Suma;
178 public:
179 STATIC_CONST( SignalLength = 6 );
180
181 public:
182 Uint32 senderData;
183 Uint32 completedOps;
184 Uint32 fragmentCompleted;
185 Uint32 transId1;
186 Uint32 transId2;
187 Uint32 total_len;
188 };
189
190 class ScanFragRef {
191 /**
192 * Sender(s)
193 */
194 friend class Dblqh;
195
196 /**
197 * Reciver(s)
198 */
199 friend class Dbtc;
200 friend class Backup;
201 friend class Suma;
202 public:
203 STATIC_CONST( SignalLength = 4 );
204 public:
205 enum ErrorCode {
206 ZNO_FREE_TC_CONREC_ERROR = 484,
207 ZTOO_FEW_CONCURRENT_OPERATIONS = 485,
208 ZTOO_MANY_CONCURRENT_OPERATIONS = 486,
209 ZSCAN_NO_FRAGMENT_ERROR = 487,
210 ZTOO_MANY_ACTIVE_SCAN_ERROR = 488,
211 ZNO_FREE_SCANREC_ERROR = 489,
212 ZWRONG_BATCH_SIZE = 1230,
213 ZSTANDBY_SCAN_ERROR = 1209,
214 NO_TC_CONNECT_ERROR = 1217,
215 ZSCAN_BOOK_ACC_OP_ERROR = 1219,
216 ZUNKNOWN_TRANS_ERROR = 1227
217 };
218
219 Uint32 senderData;
220 Uint32 transId1;
221 Uint32 transId2;
222 Uint32 errorCode;
223 };
224
225 /**
226 * This is part of Scan Fragment protocol
227 *
228 * Not to be confused with ScanNextReq in Scan Table protocol
229 */
230 class ScanFragNextReq {
231 /**
232 * Sender(s)
233 */
234 friend class Dbtc;
235 friend class Backup;
236 friend class Suma;
237
238 /**
239 * Reciver(s)
240 */
241 friend class Dblqh;
242
243 friend bool printSCANFRAGNEXTREQ(FILE * output, const Uint32 * theData,
244 Uint32 len, Uint16 receiverBlockNo);
245 public:
246 STATIC_CONST( SignalLength = 6 );
247
248 public:
249 Uint32 senderData;
250 Uint32 requestInfo; // 1 == close
251 Uint32 transId1;
252 Uint32 transId2;
253 Uint32 batch_size_rows;
254 Uint32 batch_size_bytes;
255 Uint32 variableData[1];
256
257 STATIC_CONST( ZCLOSE = 1 );
258
259 static Uint32 getCloseFlag(const Uint32&);
260 static void setCloseFlag(Uint32&, Uint32);
261
262 static Uint32 getCorrFactorFlag(const Uint32&);
263 static void setCorrFactorFlag(Uint32&);
264 };
265
266 /**
267 * Request Info (SCANFRAGREQ)
268 *
269 * a = Length of attrinfo - 16 Bits (16-31) (Short only)
270 * c = LCP scan - 1 Bit 3
271 * d = No disk - 1 Bit 4
272 * l = Lock Mode - 1 Bit 5
273 * h = Hold lock - 1 Bit 7
274 * k = Keyinfo - 1 Bit 8
275 * r = read committed - 1 Bit 9
276 * x = range scan - 1 Bit 6
277 * z = descending - 1 Bit 10
278 * t = tup scan - 1 Bit 11 (implies x=z=0)
279 * p = Scan prio - 4 Bits (12-15) -> max 15
280 * r = Reorg flag - 2 Bits (1-2)
281 * C = corr value flag - 1 Bit (16)
282 * s = Stat scan - 1 Bit 17
283 *
284 * 1111111111222222222233
285 * 01234567890123456789012345678901
286 * rrcdlxhkrztppppaaaaaaaaaaaaaaaa Short variant ( < 6.4.0)
287 * rrcdlxhkrztppppAs Long variant (6.4.0 +)
288 */
289 #define SF_LOCK_MODE_SHIFT (5)
290 #define SF_LOCK_MODE_MASK (1)
291
292 #define SF_NO_DISK_SHIFT (4)
293 #define SF_HOLD_LOCK_SHIFT (7)
294 #define SF_KEYINFO_SHIFT (8)
295 #define SF_READ_COMMITTED_SHIFT (9)
296 #define SF_RANGE_SCAN_SHIFT (6)
297 #define SF_DESCENDING_SHIFT (10)
298 #define SF_TUP_SCAN_SHIFT (11)
299 #define SF_LCP_SCAN_SHIFT (3)
300
301 #define SF_ATTR_LEN_SHIFT (16)
302 #define SF_ATTR_LEN_MASK (65535)
303
304 #define SF_PRIO_SHIFT 12
305 #define SF_PRIO_MASK 15
306
307 #define SF_REORG_SHIFT (1)
308 #define SF_REORG_MASK (3)
309
310 #define SF_CORR_FACTOR_SHIFT (16)
311
312 #define SF_STAT_SCAN_SHIFT (17)
313
314 inline
315 Uint32
getLockMode(const Uint32 & requestInfo)316 ScanFragReq::getLockMode(const Uint32 & requestInfo){
317 return (requestInfo >> SF_LOCK_MODE_SHIFT) & SF_LOCK_MODE_MASK;
318 }
319
320 inline
321 Uint32
getHoldLockFlag(const Uint32 & requestInfo)322 ScanFragReq::getHoldLockFlag(const Uint32 & requestInfo){
323 return (requestInfo >> SF_HOLD_LOCK_SHIFT) & 1;
324 }
325
326 inline
327 Uint32
getKeyinfoFlag(const Uint32 & requestInfo)328 ScanFragReq::getKeyinfoFlag(const Uint32 & requestInfo){
329 return (requestInfo >> SF_KEYINFO_SHIFT) & 1;
330 }
331
332 inline
333 Uint32
getRangeScanFlag(const Uint32 & requestInfo)334 ScanFragReq::getRangeScanFlag(const Uint32 & requestInfo){
335 return (requestInfo >> SF_RANGE_SCAN_SHIFT) & 1;
336 }
337
338 inline
339 Uint32
getDescendingFlag(const Uint32 & requestInfo)340 ScanFragReq::getDescendingFlag(const Uint32 & requestInfo){
341 return (requestInfo >> SF_DESCENDING_SHIFT) & 1;
342 }
343
344 inline
345 Uint32
getTupScanFlag(const Uint32 & requestInfo)346 ScanFragReq::getTupScanFlag(const Uint32 & requestInfo){
347 return (requestInfo >> SF_TUP_SCAN_SHIFT) & 1;
348 }
349
350 inline
351 Uint32
getReadCommittedFlag(const Uint32 & requestInfo)352 ScanFragReq::getReadCommittedFlag(const Uint32 & requestInfo){
353 return (requestInfo >> SF_READ_COMMITTED_SHIFT) & 1;
354 }
355
356 inline
357 Uint32
getAttrLen(const Uint32 & requestInfo)358 ScanFragReq::getAttrLen(const Uint32 & requestInfo){
359 return (requestInfo >> SF_ATTR_LEN_SHIFT) & SF_ATTR_LEN_MASK;
360 }
361
362 inline
363 Uint32
getScanPrio(const Uint32 & requestInfo)364 ScanFragReq::getScanPrio(const Uint32 & requestInfo){
365 return (requestInfo >> SF_PRIO_SHIFT) & SF_PRIO_MASK;
366 }
367
368 inline
369 void
setScanPrio(UintR & requestInfo,UintR val)370 ScanFragReq::setScanPrio(UintR & requestInfo, UintR val){
371 ASSERT_MAX(val, SF_PRIO_MASK, "ScanFragReq::setScanPrio");
372 requestInfo |= (val << SF_PRIO_SHIFT);
373 }
374
375 inline
376 void
setLockMode(UintR & requestInfo,UintR val)377 ScanFragReq::setLockMode(UintR & requestInfo, UintR val){
378 ASSERT_MAX(val, SF_LOCK_MODE_MASK, "ScanFragReq::setLockMode");
379 requestInfo |= (val << SF_LOCK_MODE_SHIFT);
380 }
381
382 inline
383 void
setHoldLockFlag(UintR & requestInfo,UintR val)384 ScanFragReq::setHoldLockFlag(UintR & requestInfo, UintR val){
385 ASSERT_BOOL(val, "ScanFragReq::setHoldLockFlag");
386 requestInfo |= (val << SF_HOLD_LOCK_SHIFT);
387 }
388
389 inline
390 void
setKeyinfoFlag(UintR & requestInfo,UintR val)391 ScanFragReq::setKeyinfoFlag(UintR & requestInfo, UintR val){
392 ASSERT_BOOL(val, "ScanFragReq::setKeyinfoFlag");
393 requestInfo |= (val << SF_KEYINFO_SHIFT);
394 }
395
396 inline
397 void
setReadCommittedFlag(UintR & requestInfo,UintR val)398 ScanFragReq::setReadCommittedFlag(UintR & requestInfo, UintR val){
399 ASSERT_BOOL(val, "ScanFragReq::setReadCommittedFlag");
400 requestInfo |= (val << SF_READ_COMMITTED_SHIFT);
401 }
402
403 inline
404 void
setRangeScanFlag(UintR & requestInfo,UintR val)405 ScanFragReq::setRangeScanFlag(UintR & requestInfo, UintR val){
406 ASSERT_BOOL(val, "ScanFragReq::setRangeScanFlag");
407 requestInfo |= (val << SF_RANGE_SCAN_SHIFT);
408 }
409
410 inline
411 void
setDescendingFlag(UintR & requestInfo,UintR val)412 ScanFragReq::setDescendingFlag(UintR & requestInfo, UintR val){
413 ASSERT_BOOL(val, "ScanFragReq::setDescendingFlag");
414 requestInfo |= (val << SF_DESCENDING_SHIFT);
415 }
416
417 inline
418 void
setTupScanFlag(UintR & requestInfo,UintR val)419 ScanFragReq::setTupScanFlag(UintR & requestInfo, UintR val){
420 ASSERT_BOOL(val, "ScanFragReq::setTupScanFlag");
421 requestInfo |= (val << SF_TUP_SCAN_SHIFT);
422 }
423
424 inline
425 void
setAttrLen(UintR & requestInfo,UintR val)426 ScanFragReq::setAttrLen(UintR & requestInfo, UintR val){
427 ASSERT_MAX(val, SF_ATTR_LEN_MASK, "ScanFragReq::setAttrLen");
428 requestInfo |= (val << SF_ATTR_LEN_SHIFT);
429 }
430
431 inline
432 Uint32
getNoDiskFlag(const Uint32 & requestInfo)433 ScanFragReq::getNoDiskFlag(const Uint32 & requestInfo){
434 return (requestInfo >> SF_NO_DISK_SHIFT) & 1;
435 }
436
437 inline
438 void
setNoDiskFlag(UintR & requestInfo,UintR val)439 ScanFragReq::setNoDiskFlag(UintR & requestInfo, UintR val){
440 ASSERT_BOOL(val, "ScanFragReq::setNoDiskFlag");
441 requestInfo |= (val << SF_NO_DISK_SHIFT);
442 }
443
444 inline
445 Uint32
getLcpScanFlag(const Uint32 & requestInfo)446 ScanFragReq::getLcpScanFlag(const Uint32 & requestInfo){
447 return (requestInfo >> SF_LCP_SCAN_SHIFT) & 1;
448 }
449
450 inline
451 void
setLcpScanFlag(UintR & requestInfo,UintR val)452 ScanFragReq::setLcpScanFlag(UintR & requestInfo, UintR val){
453 ASSERT_BOOL(val, "ScanFragReq::setLcpScanFlag");
454 requestInfo |= (val << SF_LCP_SCAN_SHIFT);
455 }
456
457 inline
458 Uint32
setScanInfo(Uint32 opNo,Uint32 scanNo)459 KeyInfo20::setScanInfo(Uint32 opNo, Uint32 scanNo){
460 ASSERT_MAX(opNo, 1023, "KeyInfo20::setScanInfo");
461 ASSERT_MAX(scanNo, 255, "KeyInfo20::setScanInfo");
462 return (opNo << 8) + scanNo;
463 }
464
465 inline
466 Uint32
getScanNo(Uint32 scanInfo)467 KeyInfo20::getScanNo(Uint32 scanInfo){
468 return scanInfo & 0xFF;
469 }
470
471 inline
472 Uint32
getScanOp(Uint32 scanInfo)473 KeyInfo20::getScanOp(Uint32 scanInfo){
474 return (scanInfo >> 8) & 0x3FF;
475 }
476
477 inline
478 Uint32
getReorgFlag(const Uint32 & requestInfo)479 ScanFragReq::getReorgFlag(const Uint32 & requestInfo){
480 return (requestInfo >> SF_REORG_SHIFT) & SF_REORG_MASK;
481 }
482
483 inline
484 void
setReorgFlag(UintR & requestInfo,UintR val)485 ScanFragReq::setReorgFlag(UintR & requestInfo, UintR val){
486 ASSERT_MAX(val, SF_REORG_MASK, "ScanFragReq::setLcpScanFlag");
487 requestInfo |= (val << SF_REORG_SHIFT);
488 }
489
490 inline
491 Uint32
getCorrFactorFlag(const Uint32 & requestInfo)492 ScanFragReq::getCorrFactorFlag(const Uint32 & requestInfo){
493 return (requestInfo >> SF_CORR_FACTOR_SHIFT) & 1;
494 }
495
496 inline
497 void
setCorrFactorFlag(UintR & requestInfo,UintR val)498 ScanFragReq::setCorrFactorFlag(UintR & requestInfo, UintR val){
499 ASSERT_BOOL(val, "ScanFragReq::setCorrFactorFlag");
500 requestInfo |= (val << SF_CORR_FACTOR_SHIFT);
501 }
502
503 inline
504 Uint32
getStatScanFlag(const Uint32 & requestInfo)505 ScanFragReq::getStatScanFlag(const Uint32 & requestInfo){
506 return (requestInfo >> SF_STAT_SCAN_SHIFT) & 1;
507 }
508
509 inline
510 void
setStatScanFlag(UintR & requestInfo,UintR val)511 ScanFragReq::setStatScanFlag(UintR & requestInfo, UintR val){
512 ASSERT_BOOL(val, "ScanFragReq::setStatScanFlag");
513 requestInfo |= (val << SF_STAT_SCAN_SHIFT);
514 }
515
516 /**
517 * Request Info (SCAN_NEXTREQ)
518 *
519 * c = close - 1 Bit 0
520 * C = corr value flag - 1 Bit 1
521 *
522 * 1111111111222222222233
523 * 01234567890123456789012345678901
524 * cC
525 */
526 #define SFN_CLOSE_SHIFT 0
527 #define SFN_CORR_SHIFT 1
528
529 inline
530 Uint32
getCorrFactorFlag(const Uint32 & ri)531 ScanFragNextReq::getCorrFactorFlag(const Uint32 & ri)
532 {
533 return (ri >> SFN_CORR_SHIFT) & 1;
534 }
535
536 inline
537 void
setCorrFactorFlag(Uint32 & ri)538 ScanFragNextReq::setCorrFactorFlag(Uint32 & ri)
539 {
540 ri |= (1 << SFN_CORR_SHIFT);
541 }
542
543 #endif
544