MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbIndexScanOperation.hpp
1 /*
2  Copyright (C) 2004-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 as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef NdbIndexScanOperation_H
20 #define NdbIndexScanOperation_H
21 
22 #include "NdbScanOperation.hpp"
23 
29 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
30  friend class Ndb;
31  friend class NdbTransaction;
32  friend class NdbResultSet;
33  friend class NdbOperation;
34  friend class NdbScanOperation;
35  friend class NdbIndexStat;
36 #endif
37 
38 public:
48  virtual int readTuples(LockMode lock_mode = LM_Read,
49  Uint32 scan_flags = 0,
50  Uint32 parallel = 0,
51  Uint32 batch = 0);
52 
53 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
54 
66  inline int readTuples(LockMode lock_mode,
67  Uint32 batch,
68  Uint32 parallel,
69  bool order_by,
70  bool order_desc = false,
71  bool read_range_no = false,
72  bool keyinfo = false,
73  bool multi_range = false) {
74  Uint32 scan_flags =
75  (SF_OrderBy & -(Int32)order_by) |
76  (SF_Descending & -(Int32)order_desc) |
77  (SF_ReadRangeNo & -(Int32)read_range_no) |
78  (SF_KeyInfo & -(Int32)keyinfo) |
79  (SF_MultiRange & -(Int32)multi_range);
80 
81  return readTuples(lock_mode, scan_flags, parallel, batch);
82  }
83 #endif
84 
89  enum BoundType {
90  BoundLE = 0,
91  BoundLT = 1,
92  BoundGE = 2,
93  BoundGT = 3,
94  BoundEQ = 4
95  };
96 
97  /* Maximum number of ranges that can be supplied to a single
98  * NdbIndexScanOperation
99  */
100  enum {
101  MaxRangeNo= 0xfff
102  };
103 
138 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
139  int setBound(const char* attr, int type, const void* value, Uint32 len);
140 #endif
141  int setBound(const char* attr, int type, const void* value);
142 
147 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
148  int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len);
149 #endif
150  int setBound(Uint32 anAttrId, int type, const void* aValue);
151 
169  int end_of_bound(Uint32 range_no= 0);
170 
177  int get_range_no();
178 
179  /* Structure used to describe index scan bounds, for NdbRecord scans. */
180  struct IndexBound {
181  /* Row containing lower bound, or NULL for scan from the start. */
182  const char *low_key;
183  /* Number of columns in lower bound, for bounding by partial prefix. */
184  Uint32 low_key_count;
185  /* True for less-than-or-equal, false for strictly less-than. */
186  bool low_inclusive;
187  /* Row containing upper bound, or NULL for scan to the end. */
188  const char * high_key;
189  /* Number of columns in upper bound, for bounding by partial prefix. */
190  Uint32 high_key_count;
191  /* True for greater-than-or-equal, false for strictly greater-than. */
192  bool high_inclusive;
193  /*
194  Value to identify this bound, may be read with get_range_no().
195  Must be <= MaxRangeNo (set to zero if not using range_no).
196  Note that for ordered scans, the range_no must be strictly increasing
197  for each range, or the result set will not be sorted correctly.
198  */
199  Uint32 range_no;
200  };
201 
230  int setBound(const NdbRecord *key_record,
231  const IndexBound& bound);
232  int setBound(const NdbRecord *key_record,
233  const IndexBound& bound,
234  const Ndb::PartitionSpec* partInfo,
235  Uint32 sizeOfPartInfo= 0);
236 
240  bool getSorted() const { return m_ordered; }
241 
245  bool getDescending() const { return m_descending; }
246 
247 private:
248  NdbIndexScanOperation(Ndb* aNdb);
249  virtual ~NdbIndexScanOperation();
250 
251  int processIndexScanDefs(LockMode lm,
252  Uint32 scan_flags,
253  Uint32 parallel,
254  Uint32 batch);
255  int scanIndexImpl(const NdbRecord *key_record,
256  const NdbRecord *result_record,
257  NdbOperation::LockMode lock_mode,
258  const unsigned char *result_mask,
260  const NdbScanOperation::ScanOptions *options,
261  Uint32 sizeOfOptions);
262 
263  /* Structure used to collect information about an IndexBound
264  * as it is provided by the old Api setBound() calls
265  */
266 public:
268  {
269  Uint32 highestKey;
270  bool highestSoFarIsStrict;
271  Uint32 keysPresentBitmap;
272  char* key;
273  };
274 
275 private:
276  struct OldApiScanRangeDefinition
277  {
278  /* OldApiBoundInfo used during definition
279  * IndexBound used once bound defined
280  * Todo : For heavy old Api use, consider splitting
281  * to allow NdbRecAttr use without malloc
282  */
283  union {
284  struct {
285  OldApiBoundInfo lowBound;
286  OldApiBoundInfo highBound;
287  } oldBound;
288 
289  IndexBound ib;
290  };
291  /* Space for key bounds
292  * Low bound from offset 0
293  * High bound from offset key_record->m_row_size
294  */
295  char space[1];
296  };
297 
298  int setBoundHelperOldApi(OldApiBoundInfo& boundInfo,
299  Uint32 maxKeyRecordBytes,
300  Uint32 index_attrId,
301  Uint32 valueLen,
302  bool inclusive,
303  Uint32 byteOffset,
304  Uint32 nullbit_byte_offset,
305  Uint32 nullbit_bit_in_byte,
306  const void *aValue);
307 
308  int setBound(const NdbColumnImpl*, int type, const void* aValue);
309  int buildIndexBoundOldApi(int range_no);
310  const IndexBound* getIndexBoundFromRecAttr(NdbRecAttr* recAttr);
311  void releaseIndexBoundsOldApi();
312  int ndbrecord_insert_bound(const NdbRecord *key_record,
313  Uint32 column_index,
314  const char *row,
315  Uint32 bound_type,
316  Uint32*& firstWordOfBound);
317  int insert_open_bound(const NdbRecord* key_record,
318  Uint32*& firstWordOfBound);
319 
320  virtual int equal_impl(const NdbColumnImpl*, const char*);
321  virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char*);
322 
323  int getDistKeyFromRange(const NdbRecord* key_record,
324  const NdbRecord* result_record,
325  const char* row,
326  Uint32* distKey);
327  void fix_get_values();
328  int next_result_ordered(bool fetchAllowed, bool forceSend = false);
329  int next_result_ordered_ndbrecord(const char * & out_row,
330  bool fetchAllowed,
331  bool forceSend);
332  void ordered_insert_receiver(Uint32 start, NdbReceiver *receiver);
333  int ordered_send_scan_wait_for_all(bool forceSend);
334  int send_next_scan_ordered(Uint32 idx);
335  int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
336  Uint32 m_sort_columns;
337 
338  /* Number of IndexBounds for this scan (NdbRecord only) */
339  Uint32 m_num_bounds;
340  /* Most recently added IndexBound's range number */
341  Uint32 m_previous_range_num;
342 
343  /* Old Scan API range information
344  * List of RecAttr structures containing OldApiScanRangeDefinition
345  * structures
346  * currentRangeOldApi is range currently being defined (if any)
347  * Once defined (end_of_bound() / execute()) they are added to
348  * the list between first/lastRangeOldApi
349  */
350  NdbRecAttr* firstRangeOldApi;
351  NdbRecAttr* lastRangeOldApi;
352  NdbRecAttr* currentRangeOldApi;
353 
354  friend struct Ndb_free_list_t<NdbIndexScanOperation>;
355 
356 private:
357  NdbIndexScanOperation(const NdbIndexScanOperation&); // Not impl.
359 };
360 
361 inline
362 int
363 NdbIndexScanOperation::setBound(const char* attr, int type, const void* value,
364  Uint32 len)
365 {
366  (void)len; // unused
367  return setBound(attr, type, value);
368 }
369 
370 inline
371 int
372 NdbIndexScanOperation::setBound(Uint32 anAttrId, int type, const void* value,
373  Uint32 len)
374 {
375  (void)len; // unused
376  return setBound(anAttrId, type, value);
377 }
378 
389 int compare_ndbrecord(const NdbReceiver *r1,
390  const NdbReceiver *r2,
391  const NdbRecord *key_record,
392  const NdbRecord *result_record,
393  bool descending,
394  bool read_range_no);
395 #endif