MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbScanOperation.hpp
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 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 St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef NdbScanOperation_H
19 #define NdbScanOperation_H
20 
21 #include "NdbOperation.hpp"
22 
23 class NdbBlob;
24 class NdbResultSet;
25 class PollGuard;
26 
32 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
33  friend class Ndb;
34  friend class NdbTransaction;
35  friend class NdbResultSet;
36  friend class NdbOperation;
37  friend class NdbBlob;
38  friend class NdbScanFilter;
39  friend class NdbQueryOperationImpl;
40 #endif
41 
42 public:
48  enum ScanFlag {
49  /* Scan TUP order */
50  SF_TupScan = (1 << 16),
51  /* Scan in DISK order */
52  SF_DiskScan = (2 << 16),
53  /*
54  Return rows from an index scan sorted, ordered on the index key.
55  This flag makes the API perform a merge-sort among the ordered scans of
56  each fragment, to get a single sorted result set.
57  */
58  SF_OrderBy = (1 << 24),
63  SF_OrderByFull = (16 << 24),
64 
65  /* Index scan in descending order, instead of default ascending. */
66  SF_Descending = (2 << 24),
67  /*
68  Enable @ref get_range_no (index scan only).
69  When this flag is set, NdbIndexScanOperation::get_range_no() can be
70  called to read back the range_no defined in
71  NdbIndexScanOperation::setBound(). See @ref setBound() for
72  explanation.
73  */
74  SF_ReadRangeNo = (4 << 24),
75  /* Scan is part of multi-range scan. */
76  SF_MultiRange = (8 << 24),
77  /*
78  Request KeyInfo to be sent back.
79  This enables the option to take over the row lock taken by the scan using
80  lockCurrentTuple(), by making sure that the kernel sends back the
81  information needed to identify the row and the lock.
82  It is enabled by default for scans using LM_Exclusive, but must be
83  explicitly specified to enable the taking-over of LM_Read locks.
84  */
85  SF_KeyInfo = 1
86  };
87 
88 
89  /*
90  * ScanOptions
91  * These are options passed to the NdbRecord based scanTable and
92  * scanIndex methods of the NdbTransaction class.
93  * Each option type is marked as present by setting the corresponding
94  * bit in the optionsPresent field. Only the option types marked
95  * in the optionsPresent field need have sensible data.
96  * All data is copied out of the ScanOptions structure (and any
97  * subtended structures) at operation definition time.
98  * If no options are required, then NULL may be passed as the
99  * ScanOptions pointer.
100  *
101  * Most methods take a supplementary sizeOfOptions parameter. This
102  * is optional, and is intended to allow the interface implementation
103  * to remain backwards compatible with older un-recompiled clients
104  * that may pass an older (smaller) version of the ScanOptions
105  * structure. This effect is achieved by passing
106  * sizeof(NdbScanOperation::ScanOptions) into this parameter.
107  */
108  struct ScanOptions
109  {
110  /* Which options are present - see below for possibilities */
111  Uint64 optionsPresent;
112 
113  enum Type { SO_SCANFLAGS = 0x01,
114  SO_PARALLEL = 0x02,
115  SO_BATCH = 0x04,
116  SO_GETVALUE = 0x08,
117  SO_PARTITION_ID = 0x10,
118  SO_INTERPRETED = 0x20,
119  SO_CUSTOMDATA = 0x40,
120  SO_PART_INFO = 0x80
121  };
122 
123  /* Flags controlling scan behaviour
124  * See NdbScanOperation::ScanFlag for details
125  */
126  Uint32 scan_flags;
127 
128  /* Desired scan parallelism.
129  * Default == 0 == Maximum parallelism
130  */
131  Uint32 parallel;
132 
133  /* Desired scan batchsize in rows
134  * for NDBD -> API transfers
135  * Default == 0 == Automatically chosen size
136  */
137  Uint32 batch;
138 
139  /* Extra values to be read for each row meeting
140  * scan criteria
141  */
142  NdbOperation::GetValueSpec *extraGetValues;
143  Uint32 numExtraGetValues;
144 
145  /* Specific partition to limit this scan to
146  * Alternatively, an Ndb::PartitionSpec can be supplied.
147  * For Index Scans, partitioning information can be supplied for
148  * each range
149  */
150  Uint32 partitionId;
151 
152  /* Interpreted code to execute as part of the scan */
153  const NdbInterpretedCode *interpretedCode;
154 
155  /* CustomData ptr to associate with the scan operation */
156  void * customData;
157 
158  /* Partition information for bounding this scan */
159  const Ndb::PartitionSpec* partitionInfo;
160  Uint32 sizeOfPartInfo;
161  };
162 
163 
173  virtual
174  int readTuples(LockMode lock_mode = LM_Read,
175  Uint32 scan_flags = 0,
176  Uint32 parallel = 0,
177  Uint32 batch = 0);
178 
179 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
180 
187 #ifdef ndb_readtuples_impossible_overload
188  int readTuples(LockMode lock_mode = LM_Read,
189  Uint32 batch = 0, Uint32 parallel = 0,
190  bool keyinfo = false, bool multi_range = false);
191 #endif
192 
193  inline int readTuples(int parallell){
194  return readTuples(LM_Read, 0, parallell);
195  }
196 
197  inline int readTuplesExclusive(int parallell = 0){
198  return readTuples(LM_Exclusive, 0, parallell);
199  }
200 
201  /* First version of ScanOptions, defined here for backwards
202  * compatibility reasons
203  */
205  {
206  /* Which options are present - see below for possibilities */
207  Uint64 optionsPresent;
208 
209  enum Type { SO_SCANFLAGS = 0x01,
210  SO_PARALLEL = 0x02,
211  SO_BATCH = 0x04,
212  SO_GETVALUE = 0x08,
213  SO_PARTITION_ID = 0x10,
214  SO_INTERPRETED = 0x20,
215  SO_CUSTOMDATA = 0x40 };
216 
217  /* Flags controlling scan behaviour
218  * See NdbScanOperation::ScanFlag for details
219  */
220  Uint32 scan_flags;
221 
222  /* Desired scan parallelism.
223  * Default == 0 == Maximum parallelism
224  */
225  Uint32 parallel;
226 
227  /* Desired scan batchsize in rows
228  * for NDBD -> API transfers
229  * Default == 0 == Automatically chosen size
230  */
231  Uint32 batch;
232 
233  /* Extra values to be read for each row meeting
234  * scan criteria
235  */
236  NdbOperation::GetValueSpec *extraGetValues;
237  Uint32 numExtraGetValues;
238 
239  /* Specific partition to limit this scan to
240  * Only applicable for tables defined with UserDefined partitioning
241  * For Index Scans, partitioning information can be supplied for
242  * each range
243  */
244  Uint32 partitionId;
245 
246  /* Interpreted code to execute as part of the scan */
247  const NdbInterpretedCode *interpretedCode;
248 
249  /* CustomData ptr to associate with the scan operation */
250  void * customData;
251  };
252 #endif
253 
254 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
255  virtual NdbBlob* getBlobHandle(const char* anAttrName);
256  virtual NdbBlob* getBlobHandle(Uint32 anAttrId);
257 
272 
273 #endif
274 
275 
332  int nextResult(bool fetchAllowed = true, bool forceSend = false);
333 
334  /*
335  * NdbRecord version of nextResult.
336  *
337  * When 0 is returned, this method updates out_row_ptr to point
338  * to the next result row. The location pointed to is valid
339  * (only) until the next call to nextResult() with
340  * fetchAllowed == true.
341  * The NdbRecord object defining the row format was specified in the
342  * NdbTransaction::scanTable (or scanIndex) call.
343  * Note that this variant of nextResult has three parameters, and
344  * all must be supplied to avoid invoking the two-parameter, non
345  * NdbRecord variant of nextResult.
346  */
347  int nextResult(const char ** out_row_ptr,
348  bool fetchAllowed,
349  bool forceSend);
350 
351  /*
352  * Alternate NdbRecord version of nextResult.
353  *
354  * When 0 is returned, this method copies data from the result
355  * to the output buffer. The buffer must be long enough for the
356  * result NdbRecord row as returned by
357  * NdbDictionary::getRecordRowLength(const NdbRecord* record);
358  * The NdbRecord object defining the row format was specified in the
359  * NdbTransaction::scanTable (or scanIndex) call.
360  * @return
361  * - -1: if unsuccessful
362  * - 0: if another tuple was received
363  * - 1: if there are no more tuples to scan
364  * - 2: if there are no more cached records in NdbApi
365  */
366  int nextResultCopyOut(char * buffer,
367  bool fetchAllowed,
368  bool forceSend);
369 
373  void close(bool forceSend = false, bool releaseOp = false);
374 
403 
408  int deleteCurrentTuple();
416  int deleteCurrentTuple(NdbTransaction* takeOverTransaction);
417 
418  /*
419  * NdbRecord versions of scan lock take-over operations.
420  *
421  * Note that calling NdbRecord scan lock take-over on an NdbRecAttr-style
422  * scan is not valid, nor is calling NdbRecAttr-style scan lock take-over
423  * on an NdbRecord-style scan.
424  */
425 
426  /*
427  * Take over the lock without changing the row.
428  * Optionally also read from the row (call with default value NULL for
429  * result_row to not read any attributes.).
430  * The NdbRecord * is required even when not reading any attributes.
431  * Supported OperationOptions : OO_ABORTOPTION, OO_GETVALUE, OO_ANYVALUE
432  */
433  const NdbOperation *lockCurrentTuple(NdbTransaction *takeOverTrans,
434  const NdbRecord *result_rec,
435  char *result_row= 0,
436  const unsigned char *result_mask= 0,
437  const NdbOperation::OperationOptions *opts = 0,
438  Uint32 sizeOfOptions = 0);
439 
440  /*
441  * Update the current tuple, NdbRecord version.
442  * Values to update with are contained in the passed-in row.
443  * Supported OperationOptions : OO_ABORTOPTION, OO_SETVALUE,
444  * OO_INTERPRETED, OO_ANYVALUE
445  */
446  const NdbOperation *updateCurrentTuple(NdbTransaction *takeOverTrans,
447  const NdbRecord *attr_rec,
448  const char *attr_row,
449  const unsigned char *mask= 0,
450  const NdbOperation::OperationOptions *opts = 0,
451  Uint32 sizeOfOptions = 0);
452 
453  /* Delete the current tuple. NdbRecord version.
454  * The tuple can be read before being deleted. Specify the columns to read
455  * and the result storage as usual with result_rec, result_row and result_mask.
456  * Supported OperationOptions : OO_ABORTOPTION, OO_GETVALUE, OO_ANYVALUE
457  */
458  const NdbOperation *deleteCurrentTuple(NdbTransaction *takeOverTrans,
459  const NdbRecord *result_rec,
460  char *result_row = 0,
461  const unsigned char *result_mask = 0,
462  const NdbOperation::OperationOptions *opts = 0,
463  Uint32 sizeOfOptions = 0);
464 
469 
470 
476  bool getPruned() const;
477 
478 protected:
479  NdbScanOperation(Ndb* aNdb,
481  virtual ~NdbScanOperation();
482 
483  virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char* aValue = 0);
484  NdbRecAttr* getValue_NdbRecord_scan(const NdbColumnImpl*, char* aValue);
485  NdbRecAttr* getValue_NdbRecAttr_scan(const NdbColumnImpl*, char* aValue);
486 
487  int handleScanGetValuesOldApi();
488  int addInterpretedCode();
489  int handleScanOptionsVersion(const ScanOptions*& optionsPtr,
490  Uint32 sizeOfOptions,
491  ScanOptions& currOptions);
492  int handleScanOptions(const ScanOptions *options);
493  int validatePartInfoPtr(const Ndb::PartitionSpec*& partInfo,
494  Uint32 sizeOfPartInfo,
495  Ndb::PartitionSpec& partValue);
496  int getPartValueFromInfo(const Ndb::PartitionSpec* partInfo,
497  const NdbTableImpl* table,
498  Uint32* partValue);
499  int generatePackedReadAIs(const NdbRecord *reseult_record, bool& haveBlob,
500  const Uint32 * readMask);
501  int scanImpl(const NdbScanOperation::ScanOptions *options,
502  const Uint32 * readMask);
503  int scanTableImpl(const NdbRecord *result_record,
504  NdbOperation::LockMode lock_mode,
505  const unsigned char *result_mask,
506  const NdbScanOperation::ScanOptions *options,
507  Uint32 sizeOfOptions);
508 
509  int nextResultNdbRecord(const char * & out_row,
510  bool fetchAllowed, bool forceSend);
511  virtual void release();
512 
513  int close_impl(bool forceSend,
514  PollGuard *poll_guard);
515 
516  /* Helper for NdbScanFilter to allocate an InterpretedCode
517  * object owned by the Scan operation
518  */
519  NdbInterpretedCode* allocInterpretedCodeOldApi();
520  void freeInterpretedCodeOldApi();
521 
522  int doSendSetAISectionSizes();
523 
524  // Overloaded methods from NdbCursorOperation
525  int executeCursor(int ProcessorId);
526 
527  // Overloaded private methods from NdbOperation
528  int init(const NdbTableImpl* tab, NdbTransaction*);
529  int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId,
531  int doSend(int ProcessorId);
532  virtual void setReadLockMode(LockMode lockMode);
533 
534  virtual void setErrorCode(int aErrorCode) const;
535  virtual void setErrorCodeAbort(int aErrorCode) const;
536 
537  /* This is the transaction which defined this scan
538  * The transaction(connection) used for the scan is
539  * pointed to by NdbOperation::theNdbCon
540  */
541  NdbTransaction *m_transConnection;
542 
543  // Scan related variables
544  Uint32 theParallelism;
545  /*
546  Whether keyInfo is requested from Kernel.
547  KeyInfo is requested by application (using the SF_KeyInfo scan flag), and
548  also enabled automatically when using exclusive locking (lockmode
549  LM_Exclusive), or when requesting blobs (getBlobHandle()).
550  */
551  Uint32 m_keyInfo;
552 
553  int getFirstATTRINFOScan();
554  int doSendScan(int ProcessorId);
555  int finaliseScanOldApi();
556  int prepareSendScan(Uint32 TC_ConnectPtr, Uint64 TransactionId);
557 
558  int fix_receivers(Uint32 parallel);
559  void reset_receivers(Uint32 parallel, Uint32 ordered);
560  Uint32* m_array; // containing all arrays below
561  Uint32 m_allocated_receivers;
562  NdbReceiver** m_receivers; // All receivers
563 
564  Uint32* m_prepared_receivers; // These are to be sent
565 
566  /*
567  Owned by API/user thread.
568 
569  These receivers, stored in the m_api_receivers array, have all attributes
570  from the current batch fully received, and the API thread has moved them
571  here (under mutex protection) from m_conf_receivers, so that all further
572  nextResult() can access them without extra mutex contention.
573 
574  The m_current_api_receiver member is the index (into m_api_receivers) of
575  the receiver that delivered the last row to the application in
576  nextResult(). If no rows have been delivered yet, it is set to 0 for table
577  scans and to one past the end of the array for ordered index scans.
578 
579  For ordered index scans, the m_api_receivers array is further kept sorted.
580  The entries from (m_current_api_receiver+1) to the end of the array are
581  kept in the order that their first row will be returned in nextResult().
582 
583  Note also that for table scans, the entries available to the API thread
584  are stored in entries 0..(m_api_receivers_count-1), while for ordered
585  index scans, they are stored in entries m_current_api_receiver..array end.
586  */
587  Uint32 m_current_api_receiver;
588  Uint32 m_api_receivers_count;
589  NdbReceiver** m_api_receivers; // These are currently used by api
590 
591  /*
592  Shared by receiver thread and API thread.
593  These are receivers that the receiver thread has obtained all attribute
594  data for (of the current batch).
595  API thread will move them (under mutex protection) to m_api_receivers on
596  first access with nextResult().
597  */
598  Uint32 m_conf_receivers_count; // NOTE needs mutex to access
599  NdbReceiver** m_conf_receivers; // receive thread puts them here
600 
601  /*
602  Owned by receiver thread
603  These are the receivers that the receiver thread is currently receiving
604  attribute data for (of the current batch).
605  Once all is received, they will be moved to m_conf_receivers.
606  */
607  Uint32 m_sent_receivers_count; // NOTE needs mutex to access
608  NdbReceiver** m_sent_receivers; // receive thread puts them here
609 
610  int send_next_scan(Uint32 cnt, bool close);
613  void execCLOSE_SCAN_REP();
614 
615  int getKeyFromKEYINFO20(Uint32* data, Uint32 & size);
616  NdbOperation* takeOverScanOp(OperationType opType, NdbTransaction*);
617  NdbOperation* takeOverScanOpNdbRecord(OperationType opType,
618  NdbTransaction* pTrans,
619  const NdbRecord *record,
620  char *row,
621  const unsigned char *mask,
622  const NdbOperation::OperationOptions *opts,
623  Uint32 sizeOfOptions);
624  bool m_ordered;
625  bool m_descending;
626  Uint32 m_read_range_no;
627  /*
628  m_curr_row: Pointer to last returned row (linked list of NdbRecAttr
629  objects).
630  First comes keyInfo, if requested (explicitly with SF_KeyInfo, or
631  implicitly when using LM_Exclusive).
632  Then comes range_no, if requested with SF_ReadRangeNo, included first in
633  the list of sort columns to get sorting of multiple range scans right.
634  Then the 'real' columns that are participating in the scan.
635  */
636  NdbRecAttr *m_curr_row;
637  bool m_multi_range; // Mark if operation is part of multi-range scan
638  bool m_executed; // Marker if operation should be released at close
639 
640  /* Buffer for rows received during NdbRecord scans, or NULL. */
641  char *m_scan_buffer;
642 
643  /* Initialise scan operation with user provided information */
644  virtual int processTableScanDefs(LockMode lock_mode,
645  Uint32 scan_flags,
646  Uint32 parallel,
647  Uint32 batch);
648 
649  /* This flag indicates whether a scan operation is using the old API */
650  bool m_scanUsingOldApi;
651 
652  /* Whether readTuples has been called - only valid for old Api scans */
653  bool m_readTuplesCalled;
654 
655  /* Scan definition information saved by RecAttr scan API */
656  LockMode m_savedLockModeOldApi;
657  Uint32 m_savedScanFlagsOldApi;
658  Uint32 m_savedParallelOldApi;
659  Uint32 m_savedBatchOldApi;
660 
661  /* NdbInterpretedCode object owned by ScanOperation to support
662  * old NdbScanFilter Api
663  */
664  NdbInterpretedCode* m_interpretedCodeOldApi;
665 
666  enum ScanPruningState {
667  SPS_UNKNOWN, // Initial state
668  SPS_FIXED, // Explicit partitionId passed in ScanOptions
669  SPS_ONE_PARTITION, // Scan pruned to one partition by previous range
670  SPS_MULTI_PARTITION // Scan cannot be pruned due to previous ranges
671  };
672 
673  ScanPruningState m_pruneState;
674  Uint32 m_pruningKey; // Can be distr key hash or actual partition id.
675 private:
676  NdbScanOperation(const NdbScanOperation&); // Not impl.
677  NdbScanOperation&operator=(const NdbScanOperation&);
678 
687  virtual NdbBlob* getBlobHandle(const char* anAttrName) const;
688  virtual NdbBlob* getBlobHandle(Uint32 anAttrId) const;
689 };
690 
691 inline
692 NdbOperation*
694  return lockCurrentTuple(m_transConnection);
695 }
696 
697 inline
698 NdbOperation*
700  return takeOverScanOp(NdbOperation::ReadRequest,
701  takeOverTrans);
702 }
703 
704 inline
705 NdbOperation*
707  return updateCurrentTuple(m_transConnection);
708 }
709 
710 inline
711 NdbOperation*
713  return takeOverScanOp(NdbOperation::UpdateRequest,
714  takeOverTrans);
715 }
716 
717 inline
718 int
720  return deleteCurrentTuple(m_transConnection);
721 }
722 
723 inline
724 int
726  void * res = takeOverScanOp(NdbOperation::DeleteRequest,
727  takeOverTrans);
728  if(res == 0)
729  return -1;
730  return 0;
731 }
732 
733 inline
734 const NdbOperation *
736  const NdbRecord *attr_rec,
737  const char *attr_row,
738  const unsigned char *mask,
739  const NdbOperation::OperationOptions *opts,
740  Uint32 sizeOfOptions)
741 {
742  /*
743  We share the code implementing lockCurrentTuple() and updateCurrentTuple().
744  For lock the row may be updated, for update it is const.
745  Therefore we need to cast away const here, though we won't actually change
746  the row since we pass type 'UpdateRequest'.
747  */
748  return takeOverScanOpNdbRecord(NdbOperation::UpdateRequest, takeOverTrans,
749  attr_rec, (char *)attr_row, mask,
750  opts, sizeOfOptions);
751 }
752 
753 inline
754 const NdbOperation *
756  const NdbRecord *result_rec,
757  char *result_row,
758  const unsigned char *result_mask,
759  const NdbOperation::OperationOptions *opts,
760  Uint32 sizeOfOptions)
761 {
762  return takeOverScanOpNdbRecord(NdbOperation::DeleteRequest, takeOverTrans,
763  result_rec, result_row, result_mask,
764  opts, sizeOfOptions);
765 }
766 
767 inline
770 {
771  /* return the user visible transaction object ptr, not the
772  * scan's 'internal' / buddy transaction object
773  */
774  return m_transConnection;
775 }
776 
777 #endif