1 /*
2    Copyright (C) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
3     All rights reserved. Use is subject to license terms.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License, version 2.0,
7    as published by the Free Software Foundation.
8 
9    This program is also distributed with certain software (including
10    but not limited to OpenSSL) that is licensed under separate terms,
11    as designated in a particular file or component or in included license
12    documentation.  The authors of MySQL hereby grant you an additional
13    permission to link the program and your derivative works with the
14    separately licensed software that they have included with MySQL.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License, version 2.0, for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 */
25 
26 #ifndef SCAN_TAB_H
27 #define SCAN_TAB_H
28 
29 #include "SignalData.hpp"
30 
31 /**
32  *
33  * SENDER:  API
34  * RECIVER: Dbtc
35  */
36 class ScanTabReq {
37   /**
38    * Reciver(s)
39    */
40   friend class Dbtc;         // Reciver
41 
42   /**
43    * Sender(s)
44    */
45   friend class NdbTransaction;
46   friend class NdbScanOperation;
47   friend class NdbIndexScanOperation;
48   friend class NdbQueryImpl;
49   friend class NdbScanFilterImpl;
50 
51   /**
52    * For printing
53    */
54   friend bool printSCANTABREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
55 
56 public:
57   /**
58    * Length of signal
59    */
60   STATIC_CONST( StaticLength = 11 );
61   STATIC_CONST( MaxTotalAttrInfo = 0xFFFF );
62 
63   /**
64    * Long section nums
65    */
66   STATIC_CONST( ReceiverIdSectionNum = 0 );
67   STATIC_CONST( AttrInfoSectionNum = 1 );    /* Long SCANTABREQ only */
68   STATIC_CONST( KeyInfoSectionNum = 2 );     /* Long SCANTABREQ only */
69 
70 private:
71 
72   // Type definitions
73 
74   /**
75    * DATA VARIABLES
76    */
77   UintR apiConnectPtr;        // DATA 0
78   union {
79     UintR attrLenKeyLen;      // DATA 1 : Short SCANTABREQ (Versions < 6.4.0)
80     UintR spare;              // DATA 1 : Long SCANTABREQ
81   };
82   UintR requestInfo;          // DATA 2
83   /*
84     Table ID. Note that for a range scan of a table using an ordered index,
85     tableID is the ID of the index, not of the underlying table.
86   */
87   UintR tableId;              // DATA 3
88   UintR tableSchemaVersion;   // DATA 4
89   UintR storedProcId;         // DATA 5
90   UintR transId1;             // DATA 6
91   UintR transId2;             // DATA 7
92   UintR buddyConPtr;          // DATA 8
93   UintR batch_byte_size;      // DATA 9
94   UintR first_batch_size;     // DATA 10
95 
96   /**
97    * Optional
98    */
99   Uint32 distributionKey;
100 
101   /**
102    * Get:ers for requestInfo
103    */
104   static Uint8 getParallelism(const UintR & requestInfo);
105   static Uint8 getLockMode(const UintR & requestInfo);
106   static Uint8 getHoldLockFlag(const UintR & requestInfo);
107   static Uint8 getReadCommittedFlag(const UintR & requestInfo);
108   static Uint8 getRangeScanFlag(const UintR & requestInfo);
109   static Uint8 getDescendingFlag(const UintR & requestInfo);
110   static Uint8 getTupScanFlag(const UintR & requestInfo);
111   static Uint8 getKeyinfoFlag(const UintR & requestInfo);
112   static Uint16 getScanBatch(const UintR & requestInfo);
113   static Uint8 getDistributionKeyFlag(const UintR & requestInfo);
114   static UintR getNoDiskFlag(const UintR & requestInfo);
115   static Uint32 getViaSPJFlag(const Uint32 & requestInfo);
116   static Uint32 getPassAllConfsFlag(const Uint32 & requestInfo);
117   static Uint32 get4WordConf(const Uint32&);
118 
119   /**
120    * Set:ers for requestInfo
121    */
122   static void clearRequestInfo(UintR & requestInfo);
123   static void setParallelism(UintR & requestInfo, Uint32 flag);
124   static void setLockMode(UintR & requestInfo, Uint32 flag);
125   static void setHoldLockFlag(UintR & requestInfo, Uint32 flag);
126   static void setReadCommittedFlag(UintR & requestInfo, Uint32 flag);
127   static void setRangeScanFlag(UintR & requestInfo, Uint32 flag);
128   static void setDescendingFlag(UintR & requestInfo, Uint32 flag);
129   static void setTupScanFlag(UintR & requestInfo, Uint32 flag);
130   static void setKeyinfoFlag(UintR & requestInfo, Uint32 flag);
131   static void setScanBatch(Uint32& requestInfo, Uint32 sz);
132   static void setDistributionKeyFlag(Uint32& requestInfo, Uint32 flag);
133   static void setNoDiskFlag(UintR & requestInfo, UintR val);
134   static void setViaSPJFlag(Uint32 & requestInfo, Uint32 val);
135   static void setPassAllConfsFlag(Uint32 & requestInfo, Uint32 val);
136   static void set4WordConf(Uint32 & requestInfo, Uint32 val);
137 };
138 
139 /**
140  * Request Info
141  *
142  p = Parallelism           - 8  Bits -> Max 256 (Bit 0-7)
143  l = Lock mode             - 1  Bit 8
144  h = Hold lock mode        - 1  Bit 10
145  c = Read Committed        - 1  Bit 11
146  k = Keyinfo               - 1  Bit 12  If set, LQH will send back a KEYINFO20
147                                         signal for each scanned row,
148                                         containing information needed to
149                                         identify the row for subsequent
150                                         TCKEYREQ signal(s).
151  t = Tup scan              - 1  Bit 13
152  z = Descending (TUX)      - 1  Bit 14
153  x = Range Scan (TUX)      - 1  Bit 15
154  b = Scan batch            - 10 Bit 16-25 (max 1023)
155  d = Distribution key flag - 1  Bit 26
156  n = No disk flag          - 1  Bit 9
157  j = Via SPJ flag          - 1  Bit 27
158  a = Pass all confs flag   - 1  Bit 28
159  f = 4 word conf           - 1  Bit 29
160 
161            1111111111222222222233
162  01234567890123456789012345678901
163  pppppppplnhcktzxbbbbbbbbbbdjaf
164 */
165 
166 #define PARALLEL_SHIFT     (0)
167 #define PARALLEL_MASK      (255)
168 
169 #define LOCK_MODE_SHIFT     (8)
170 #define LOCK_MODE_MASK      (1)
171 
172 #define HOLD_LOCK_SHIFT     (10)
173 #define HOLD_LOCK_MASK      (1)
174 
175 #define KEYINFO_SHIFT       (12)
176 #define KEYINFO_MASK        (1)
177 
178 #define READ_COMMITTED_SHIFT     (11)
179 #define READ_COMMITTED_MASK      (1)
180 
181 #define RANGE_SCAN_SHIFT        (15)
182 #define RANGE_SCAN_MASK         (1)
183 
184 #define DESCENDING_SHIFT        (14)
185 #define DESCENDING_MASK         (1)
186 
187 #define TUP_SCAN_SHIFT          (13)
188 #define TUP_SCAN_MASK           (1)
189 
190 #define SCAN_BATCH_SHIFT (16)
191 #define SCAN_BATCH_MASK  (1023)
192 
193 #define SCAN_DISTR_KEY_SHIFT (26)
194 #define SCAN_DISTR_KEY_MASK (1)
195 
196 #define SCAN_NODISK_SHIFT (9)
197 #define SCAN_NODISK_MASK (1)
198 
199 #define SCAN_SPJ_SHIFT (27)
200 #define SCAN_PASS_CONF_SHIFT (28)
201 #define SCAN_4WORD_CONF_SHIFT (29)
202 
203 inline
204 Uint8
getParallelism(const UintR & requestInfo)205 ScanTabReq::getParallelism(const UintR & requestInfo){
206   return (Uint8)((requestInfo >> PARALLEL_SHIFT) & PARALLEL_MASK);
207 }
208 
209 inline
210 Uint8
getLockMode(const UintR & requestInfo)211 ScanTabReq::getLockMode(const UintR & requestInfo){
212   return (Uint8)((requestInfo >> LOCK_MODE_SHIFT) & LOCK_MODE_MASK);
213 }
214 
215 inline
216 Uint8
getHoldLockFlag(const UintR & requestInfo)217 ScanTabReq::getHoldLockFlag(const UintR & requestInfo){
218   return (Uint8)((requestInfo >> HOLD_LOCK_SHIFT) & HOLD_LOCK_MASK);
219 }
220 
221 inline
222 Uint8
getReadCommittedFlag(const UintR & requestInfo)223 ScanTabReq::getReadCommittedFlag(const UintR & requestInfo){
224   return (Uint8)((requestInfo >> READ_COMMITTED_SHIFT) & READ_COMMITTED_MASK);
225 }
226 
227 inline
228 Uint8
getRangeScanFlag(const UintR & requestInfo)229 ScanTabReq::getRangeScanFlag(const UintR & requestInfo){
230   return (Uint8)((requestInfo >> RANGE_SCAN_SHIFT) & RANGE_SCAN_MASK);
231 }
232 
233 inline
234 Uint8
getDescendingFlag(const UintR & requestInfo)235 ScanTabReq::getDescendingFlag(const UintR & requestInfo){
236   return (Uint8)((requestInfo >> DESCENDING_SHIFT) & DESCENDING_MASK);
237 }
238 
239 inline
240 Uint8
getTupScanFlag(const UintR & requestInfo)241 ScanTabReq::getTupScanFlag(const UintR & requestInfo){
242   return (Uint8)((requestInfo >> TUP_SCAN_SHIFT) & TUP_SCAN_MASK);
243 }
244 
245 inline
246 Uint16
getScanBatch(const Uint32 & requestInfo)247 ScanTabReq::getScanBatch(const Uint32 & requestInfo){
248   return (Uint16)((requestInfo >> SCAN_BATCH_SHIFT) & SCAN_BATCH_MASK);
249 }
250 
251 inline
252 void
clearRequestInfo(UintR & requestInfo)253 ScanTabReq::clearRequestInfo(UintR & requestInfo){
254   requestInfo = 0;
255 }
256 
257 inline
258 void
setParallelism(UintR & requestInfo,Uint32 type)259 ScanTabReq::setParallelism(UintR & requestInfo, Uint32 type){
260   ASSERT_MAX(type, PARALLEL_MASK, "ScanTabReq::setParallelism");
261   requestInfo= (requestInfo & ~(PARALLEL_MASK << PARALLEL_SHIFT)) |
262                ((type & PARALLEL_MASK) << PARALLEL_SHIFT);
263 }
264 
265 inline
266 void
setLockMode(UintR & requestInfo,Uint32 mode)267 ScanTabReq::setLockMode(UintR & requestInfo, Uint32 mode){
268   ASSERT_MAX(mode, LOCK_MODE_MASK,  "ScanTabReq::setLockMode");
269   requestInfo= (requestInfo & ~(LOCK_MODE_MASK << LOCK_MODE_SHIFT)) |
270                ((mode & LOCK_MODE_MASK) << LOCK_MODE_SHIFT);
271 }
272 
273 inline
274 void
setHoldLockFlag(UintR & requestInfo,Uint32 flag)275 ScanTabReq::setHoldLockFlag(UintR & requestInfo, Uint32 flag){
276   ASSERT_BOOL(flag, "ScanTabReq::setHoldLockFlag");
277   requestInfo= (requestInfo & ~(HOLD_LOCK_MASK << HOLD_LOCK_SHIFT)) |
278                ((flag & HOLD_LOCK_MASK) << HOLD_LOCK_SHIFT);
279 }
280 
281 inline
282 void
setReadCommittedFlag(UintR & requestInfo,Uint32 flag)283 ScanTabReq::setReadCommittedFlag(UintR & requestInfo, Uint32 flag){
284   ASSERT_BOOL(flag, "ScanTabReq::setReadCommittedFlag");
285   requestInfo= (requestInfo & ~(READ_COMMITTED_MASK << READ_COMMITTED_SHIFT)) |
286                ((flag & READ_COMMITTED_MASK) << READ_COMMITTED_SHIFT);
287 }
288 
289 inline
290 void
setRangeScanFlag(UintR & requestInfo,Uint32 flag)291 ScanTabReq::setRangeScanFlag(UintR & requestInfo, Uint32 flag){
292   ASSERT_BOOL(flag, "ScanTabReq::setRangeScanFlag");
293   requestInfo= (requestInfo & ~(RANGE_SCAN_MASK << RANGE_SCAN_SHIFT)) |
294                ((flag & RANGE_SCAN_MASK) << RANGE_SCAN_SHIFT);
295 }
296 
297 inline
298 void
setDescendingFlag(UintR & requestInfo,Uint32 flag)299 ScanTabReq::setDescendingFlag(UintR & requestInfo, Uint32 flag){
300   ASSERT_BOOL(flag, "ScanTabReq::setDescendingFlag");
301   requestInfo= (requestInfo & ~(DESCENDING_MASK << DESCENDING_SHIFT)) |
302                ((flag & DESCENDING_MASK) << DESCENDING_SHIFT);
303 }
304 
305 inline
306 void
setTupScanFlag(UintR & requestInfo,Uint32 flag)307 ScanTabReq::setTupScanFlag(UintR & requestInfo, Uint32 flag){
308   ASSERT_BOOL(flag, "ScanTabReq::setTupScanFlag");
309   requestInfo= (requestInfo & ~(TUP_SCAN_MASK << TUP_SCAN_SHIFT)) |
310                ((flag & TUP_SCAN_MASK) << TUP_SCAN_SHIFT);
311 }
312 
313 inline
314 void
setScanBatch(Uint32 & requestInfo,Uint32 flag)315 ScanTabReq::setScanBatch(Uint32 & requestInfo, Uint32 flag){
316   ASSERT_MAX(flag, SCAN_BATCH_MASK,  "ScanTabReq::setScanBatch");
317   requestInfo= (requestInfo & ~(SCAN_BATCH_MASK << SCAN_BATCH_SHIFT)) |
318                ((flag & SCAN_BATCH_MASK) << SCAN_BATCH_SHIFT);
319 }
320 
321 inline
322 Uint8
getKeyinfoFlag(const UintR & requestInfo)323 ScanTabReq::getKeyinfoFlag(const UintR & requestInfo){
324   return (Uint8)((requestInfo >> KEYINFO_SHIFT) & KEYINFO_MASK);
325 }
326 
327 inline
328 void
setKeyinfoFlag(UintR & requestInfo,Uint32 flag)329 ScanTabReq::setKeyinfoFlag(UintR & requestInfo, Uint32 flag){
330   ASSERT_BOOL(flag, "ScanTabReq::setKeyinfoFlag");
331   requestInfo= (requestInfo & ~(KEYINFO_MASK << KEYINFO_SHIFT)) |
332                ((flag & KEYINFO_MASK) << KEYINFO_SHIFT);
333 }
334 
335 inline
336 Uint8
getDistributionKeyFlag(const UintR & requestInfo)337 ScanTabReq::getDistributionKeyFlag(const UintR & requestInfo){
338   return (Uint8)((requestInfo >> SCAN_DISTR_KEY_SHIFT) & SCAN_DISTR_KEY_MASK);
339 }
340 
341 inline
342 void
setDistributionKeyFlag(UintR & requestInfo,Uint32 flag)343 ScanTabReq::setDistributionKeyFlag(UintR & requestInfo, Uint32 flag){
344   ASSERT_BOOL(flag, "ScanTabReq::setKeyinfoFlag");
345   requestInfo= (requestInfo & ~(SCAN_DISTR_KEY_MASK << SCAN_DISTR_KEY_SHIFT)) |
346                ((flag & SCAN_DISTR_KEY_MASK) << SCAN_DISTR_KEY_SHIFT);
347 }
348 
349 inline
350 UintR
getNoDiskFlag(const UintR & requestInfo)351 ScanTabReq::getNoDiskFlag(const UintR & requestInfo){
352   return (requestInfo >> SCAN_NODISK_SHIFT) & SCAN_NODISK_MASK;
353 }
354 
355 inline
356 void
setNoDiskFlag(UintR & requestInfo,Uint32 flag)357 ScanTabReq::setNoDiskFlag(UintR & requestInfo, Uint32 flag){
358   ASSERT_BOOL(flag, "TcKeyReq::setNoDiskFlag");
359   requestInfo= (requestInfo & ~(SCAN_NODISK_MASK << SCAN_NODISK_SHIFT)) |
360                ((flag & SCAN_NODISK_MASK) << SCAN_NODISK_SHIFT);
361 }
362 
363 inline
364 UintR
getViaSPJFlag(const UintR & requestInfo)365 ScanTabReq::getViaSPJFlag(const UintR & requestInfo){
366   return (requestInfo >> SCAN_SPJ_SHIFT) & 1;
367 }
368 
369 inline
370 void
setViaSPJFlag(UintR & requestInfo,Uint32 flag)371 ScanTabReq::setViaSPJFlag(UintR & requestInfo, Uint32 flag){
372   ASSERT_BOOL(flag, "TcKeyReq::setViaSPJFlag");
373   requestInfo |= (flag << SCAN_SPJ_SHIFT);
374 }
375 
376 inline
377 UintR
getPassAllConfsFlag(const UintR & requestInfo)378 ScanTabReq::getPassAllConfsFlag(const UintR & requestInfo){
379   return (requestInfo >> SCAN_PASS_CONF_SHIFT) & 1;
380 }
381 
382 inline
383 void
setPassAllConfsFlag(UintR & requestInfo,Uint32 flag)384 ScanTabReq::setPassAllConfsFlag(UintR & requestInfo, Uint32 flag){
385   ASSERT_BOOL(flag, "TcKeyReq::setPassAllConfs");
386   requestInfo |= (flag << SCAN_PASS_CONF_SHIFT);
387 }
388 
389 inline
390 UintR
get4WordConf(const UintR & requestInfo)391 ScanTabReq::get4WordConf(const UintR & requestInfo){
392   return (requestInfo >> SCAN_4WORD_CONF_SHIFT) & 1;
393 }
394 
395 inline
396 void
set4WordConf(UintR & requestInfo,Uint32 flag)397 ScanTabReq::set4WordConf(UintR & requestInfo, Uint32 flag){
398   ASSERT_BOOL(flag, "TcKeyReq::setPassAllConfs");
399   requestInfo |= (flag << SCAN_4WORD_CONF_SHIFT);
400 }
401 
402 /**
403  *
404  * SENDER:  Dbtc
405  * RECIVER: API
406  */
407 class ScanTabConf {
408   /**
409    * Reciver(s)
410    */
411   friend class NdbTransaction;         // Reciver
412 
413   /**
414    * Sender(s)
415    */
416   friend class Dbtc;
417 
418   /**
419    * For printing
420    */
421   friend bool printSCANTABCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
422 
423 public:
424   /**
425    * Length of signal
426    */
427   STATIC_CONST( SignalLength = 4 );
428   STATIC_CONST( EndOfData = (1 << 31) );
429 
430 private:
431 
432   // Type definitions
433 
434   /**
435    * DATA VARIABLES
436    */
437   UintR apiConnectPtr;        // DATA 0
438   UintR requestInfo;          // DATA 1
439   UintR transId1;             // DATA 2
440   UintR transId2;             // DATA 3
441 
442   struct OpData {
443     Uint32 apiPtrI;
444     /*
445       tcPtrI is the scan fragment record pointer, used in SCAN_NEXTREQ to
446       acknowledge the reception of the batch of rows from a fragment scan.
447       If RNIL, this means that this particular fragment is done scanning.
448     */
449     Uint32 tcPtrI;
450 
451     Uint32 rows;
452     Uint32 len;
453   };
454 
455   /** for 3 word conf */
getLength(Uint32 opDataInfo)456   static Uint32 getLength(Uint32 opDataInfo) { return opDataInfo >> 10; };
getRows(Uint32 opDataInfo)457   static Uint32 getRows(Uint32 opDataInfo) { return opDataInfo & 1023;}
458 };
459 
460 /**
461  * request info
462  *
463  o = received operations        - 8  Bits -> Max 255 (Bit 0-7)
464  e = end of data                - 1  bit (31)
465 
466            1111111111222222222233
467  01234567890123456789012345678901
468  oooooooo                       e
469 */
470 
471 #define OPERATIONS_SHIFT     (0)
472 #define OPERATIONS_MASK      (0xFF)
473 
474 #define STATUS_SHIFT     (8)
475 #define STATUS_MASK      (0xFF)
476 
477 
478 /**
479  *
480  * SENDER:  Dbtc
481  * RECIVER: API
482  */
483 class ScanTabRef {
484   /**
485    * Reciver(s)
486    */
487   friend class NdbTransaction;         // Reciver
488 
489   /**
490    * Sender(s)
491    */
492   friend class Dbtc;
493 
494   /**
495    * For printing
496    */
497   friend bool printSCANTABREF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
498 
499 public:
500   /**
501    * Length of signal
502    */
503   STATIC_CONST( SignalLength = 5 );
504 
505 private:
506 
507   // Type definitions
508 
509   /**
510    * DATA VARIABLES
511    */
512   UintR apiConnectPtr;        // DATA 0
513   UintR transId1;             // DATA 1
514   UintR transId2;             // DATA 2
515   UintR errorCode;            // DATA 3
516   UintR closeNeeded;          // DATA 4
517 
518 };
519 
520 /*
521   SENDER:  API
522   RECIVER: Dbtc
523 
524   This signal is sent by API to acknowledge the reception of batches of rows
525   from one or more fragment scans, and to request the fetching of the next
526   batches of rows.
527 
528   Any locks held by the transaction on rows in the previously fetched batches
529   are released (unless explicitly transfered to this or another transaction in
530   a TCKEYREQ signal with TakeOverScanFlag set).
531 
532   The fragment scan batches to acknowledge are identified by the tcPtrI words
533   in the list of struct OpData received in ScanTabConf (scan fragment record
534   pointer).
535 
536   The list of scan fragment record pointers is sent as an array of words,
537   inline in the signal if <= 21 words, else as the first section in a long
538   signal.
539  */
540 class ScanNextReq {
541   /**
542    * Reciver(s)
543    */
544   friend class Dbtc;         // Reciver
545 
546   /**
547    * Sender(s)
548    */
549   friend class NdbOperation;
550   friend class NdbQueryImpl;
551 
552   /**
553    * For printing
554    */
555   friend bool printSCANNEXTREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
556 
557 public:
558   /**
559    * Length of signal
560    */
561   STATIC_CONST( SignalLength = 4 );
562 
563   /**
564    * Section carrying receiverIds if num receivers > 21
565    */
566   STATIC_CONST( ReceiverIdsSectionNum = 0);
567 
568 private:
569 
570   // Type definitions
571 
572   /**
573    * DATA VARIABLES
574    */
575   UintR apiConnectPtr;        // DATA 0
576   UintR stopScan;             // DATA 1
577   UintR transId1;             // DATA 2
578   UintR transId2;             // DATA 3
579 
580   // stopScan = 1, stop this scan
581 
582   /*
583     After this data comes the list of scan fragment record pointers for the
584     fragment scans to acknowledge, if they fit within the 25 words available
585     in the signal (else they are sent in the first long signal section).
586   */
587 };
588 
589 #endif
590