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