MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbQueryOperationImpl.hpp
1 /*
2  Copyright (c) 2011, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 
17 #ifndef NdbQueryOperationImpl_H
18 #define NdbQueryOperationImpl_H
19 
20 #include "NdbQueryOperation.hpp"
21 #include "NdbQueryBuilderImpl.hpp"
22 #include "NdbIndexScanOperation.hpp"
23 #include <NdbError.hpp>
24 #include <ndb_limits.h>
25 #include <Vector.hpp>
26 
27 // Forward declarations
28 class NdbTableImpl;
29 class NdbIndexImpl;
30 class NdbApiSignal;
31 class NdbResultStream;
32 class NdbParamOperand;
33 class NdbTransaction;
34 class NdbReceiver;
35 class NdbOut;
36 class NdbRootFragment;
37 
43 {
44 public:
48  explicit NdbBulkAllocator(size_t objSize);
50  { reset(); };
51 
58  int init(Uint32 maxObjs);
59 
61  void reset();
62 
67  void* allocObjMem(Uint32 noOfObjs);
68 private:
70  static const char endMarker = -15;
71 
73  const size_t m_objSize;
74 
76  Uint32 m_maxObjs;
77 
79  char* m_buffer;
80 
82  Uint32 m_nextObjNo;
83 
84  // No copying.
86  NdbBulkAllocator& operator= (const NdbBulkAllocator&);
87 };
88 
92 class NdbQueryImpl {
93 
94  /* NdbQueryOperations are allowed to access it containing query */
95  friend class NdbQueryOperationImpl;
96 
98  friend NdbOut& operator<<(NdbOut& out, const class NdbQueryOperationImpl&);
99 
100 public:
103  static NdbQueryImpl* buildQuery(NdbTransaction& trans,
104  const NdbQueryDefImpl& queryDef);
105 
107  Uint32 getNoOfOperations() const;
108 
112  Uint32 getNoOfLeafOperations() const;
113 
114  // Get a specific NdbQueryOperation instance by ident specified
115  // when the NdbQueryOperationDef was created.
116  NdbQueryOperationImpl& getQueryOperation(Uint32 ident) const;
117  NdbQueryOperationImpl* getQueryOperation(const char* ident) const;
118  // Consider to introduce these as convenient shortcuts
119 //NdbQueryOperationDefImpl& getQueryOperationDef(Uint32 ident) const;
120 //NdbQueryOperationDefImpl* getQueryOperationDef(const char* ident) const;
121 
123  Uint32 getNoOfParameters() const;
124  const NdbParamOperand* getParameter(const char* name) const;
125  const NdbParamOperand* getParameter(Uint32 num) const;
126 
140  NdbQuery::NextResultOutcome nextResult(bool fetchAllowed, bool forceSend);
141 
148  int close(bool forceSend);
149 
153  void release();
154 
155  NdbTransaction& getNdbTransaction() const
156  { return m_transaction; }
157 
158  const NdbError& getNdbError() const;
159 
160  void setErrorCode(int aErrorCode);
161 
168  int assignParameters(const NdbQueryParamValue paramValues[]);
169 
170  int setBound(const NdbRecord *keyRecord,
171  const NdbIndexScanOperation::IndexBound *bound);
172 
176  int prepareSend();
177 
181  int doSend(int aNodeId, bool lastFlag);
182 
183  NdbQuery& getInterface()
184  { return m_interface; }
185 
188  { return m_next; }
189 
190  void setNext(NdbQueryImpl* next)
191  { m_next = next; }
192 
194  const NdbQueryDefImpl& getQueryDef() const
195  {
196  assert(m_queryDef);
197  return *m_queryDef;
198  }
199 
201  bool execTCKEYCONF();
202 
204  void execCLOSE_SCAN_REP(int errorCode, bool needClose);
205 
210  bool hasCompleted() const
211  { return (m_state == Closed);
212  }
213 
219  {
220  assert(!getQueryDef().isScanQuery());
221  m_startIndicator = true;
222  }
223 
230  {
231  assert(!getQueryDef().isScanQuery());
232  m_commitIndicator = true;
233  }
234 
244  int isPrunable(bool& pruned);
245 
247  Uint32 getRootFragCount() const
248  { return m_rootFragCount; }
249 
250  NdbBulkAllocator& getResultStreamAlloc()
251  { return m_resultStreamAlloc; }
252 
253  NdbBulkAllocator& getTupleSetAlloc()
254  { return m_tupleSetAlloc; }
255 
256  NdbBulkAllocator& getRowBufferAlloc()
257  { return m_rowBufferAlloc; }
258 
259 private:
264  enum FetchResult{
265  FetchResult_gotError = -4, // There is an error avail in 'm_error.code'
266  FetchResult_sendFail = -3,
267  FetchResult_nodeFail = -2,
268  FetchResult_timeOut = -1,
269  FetchResult_ok = 0,
270  FetchResult_noMoreData = 1,
271  FetchResult_noMoreCache = 2
272  };
273 
281  class OrderedFragSet{
282  public:
283  // For calculating need for dynamically allocated memory.
284  static const Uint32 pointersPerFragment = 2;
285 
286  explicit OrderedFragSet();
287 
288  ~OrderedFragSet();
289 
297  void prepare(NdbBulkAllocator& allocator,
299  int capacity,
300  const NdbRecord* keyRecord,
301  const NdbRecord* resultRecord);
302 
310  void prepareMoreResults(NdbRootFragment rootFrags[], Uint32 cnt); // Need mutex lock
311 
313  NdbRootFragment* getCurrent() const;
314 
320  void reorganize();
321 
323  void clear();
324 
332  Uint32 getFetchMore(NdbRootFragment** &rootFrags);
333 
334  private:
335 
337  int m_capacity;
339  int m_activeFragCount;
341  int m_fetchMoreFragCount;
346  int m_finalFragCount;
350  const NdbRecord* m_keyRecord;
352  const NdbRecord* m_resultRecord;
357  NdbRootFragment** m_activeFrags;
364  NdbRootFragment** m_fetchMoreFrags;
365 
367  void add(NdbRootFragment& frag);
368 
372  int compare(const NdbRootFragment& frag1,
373  const NdbRootFragment& frag2) const;
374 
376  bool verifySortOrder() const;
377 
378  // No copying.
379  OrderedFragSet(const OrderedFragSet&);
380  OrderedFragSet& operator=(const OrderedFragSet&);
381  }; // class OrderedFragSet
382 
384  NdbQuery m_interface;
385 
386  enum { // State of NdbQuery in API
387  Initial, // Constructed object, assiciated with a defined query
388  Defined, // Parameter values has been assigned
389  Prepared, // KeyInfo & AttrInfo prepared for execution
390  Executing, // Signal with exec. req. sent to TC
391  EndOfData, // All results rows consumed
392  Closed, // Query has been ::close()'ed
393  Failed,
394  Destructed
395  } m_state;
396 
397  enum { // Assumed state of query cursor in TC block
398  Inactive, // Execution not started at TC
399  Active
400  } m_tcState;
401 
403  NdbQueryImpl* m_next;
405  const NdbQueryDefImpl* m_queryDef;
406 
408  NdbError m_error;
409 
415  int m_errorReceived; // BEWARE: protect with PollGuard mutex
416 
418  NdbTransaction& m_transaction;
419 
424  NdbTransaction* m_scanTransaction;
425 
427  NdbQueryOperationImpl *m_operations; // 'Array of ' OperationImpls
428  Uint32 m_countOperations; // #elements in above array
429 
433  Uint32 m_globalCursor;
434 
438  Uint32 m_pendingFrags; // BEWARE: protect with PollGuard mutex
439 
442  Uint32 m_rootFragCount;
443 
450  NdbRootFragment* m_rootFrags;
451 
455  OrderedFragSet m_applFrags;
456 
462  Uint32 m_finalBatchFrags; // BEWARE: protect with PollGuard mutex
463 
465  Uint32 m_num_bounds;
466 
471  Uint32 m_shortestBound;
472 
476  Uint32Buffer m_attrInfo; // ATTRINFO: QueryTree + serialized parameters
477  Uint32Buffer m_keyInfo; // KEYINFO: Lookup key or scan bounds
478 
480  bool m_startIndicator;
481 
483  bool m_commitIndicator;
484 
490  enum {
492  Prune_Unknown,
493  Prune_Yes, // The root is a prunable range scan.
494  Prune_No // The root is not a prunable range scan.
495  } m_prunability;
496 
499  Uint32 m_pruneHashVal;
500 
502  NdbBulkAllocator m_operationAlloc;
503 
505  NdbBulkAllocator m_tupleSetAlloc;
506 
508  NdbBulkAllocator m_resultStreamAlloc;
509 
511  NdbBulkAllocator m_pointerAlloc;
512 
514  NdbBulkAllocator m_rowBufferAlloc;
515 
516  // Only constructable from factory ::buildQuery();
517  explicit NdbQueryImpl(
518  NdbTransaction& trans,
519  const NdbQueryDefImpl& queryDef);
520 
521  ~NdbQueryImpl();
522 
524  void postFetchRelease();
525 
527  NdbQuery::NextResultOutcome nextRootResult(bool fetchAllowed, bool forceSend);
528 
532  int sendFetchMore(NdbRootFragment* rootFrags[], Uint32 cnt,
533  bool forceSend);
534 
540  FetchResult awaitMoreResults(bool forceSend);
541 
545  bool hasReceivedError(); // Need mutex lock
546 
547  void setFetchTerminated(int aErrorCode, bool needClose); // Need mutex lock
548 
550  int closeTcCursor(bool forceSend);
551 
555  int sendClose(int nodeId);
556 
557  const NdbQuery& getInterface() const
558  { return m_interface; }
559 
560  NdbQueryOperationImpl& getRoot() const
561  { return getQueryOperation(0U); }
562 
568  bool handleBatchComplete(NdbRootFragment& rootFrag);
569 
570  NdbBulkAllocator& getPointerAlloc()
571  { return m_pointerAlloc; }
572 
573 }; // class NdbQueryImpl
574 
575 
581 
583  friend NdbOut& operator<<(NdbOut& out, const NdbQueryOperationImpl&);
584 
585  friend class NdbQueryImpl;
586 
587 public:
588  Uint32 getNoOfParentOperations() const;
589  NdbQueryOperationImpl& getParentOperation(Uint32 i) const;
590  NdbQueryOperationImpl* getParentOperation() const;
591 
592  Uint32 getNoOfChildOperations() const;
593  NdbQueryOperationImpl& getChildOperation(Uint32 i) const;
594 
597  { return m_queryImpl.getRoot(); }
598 
599  const NdbQueryDefImpl& getQueryDef() const
600  { return m_queryImpl.getQueryDef(); }
601 
602  const NdbQueryOperationDefImpl& getQueryOperationDef() const
603  { return m_operationDef; }
604 
605  // Get the entire query object which this operation is part of
606  NdbQueryImpl& getQuery() const
607  { return m_queryImpl; }
608 
609  NdbRecAttr* getValue(const char* anAttrName, char* resultBuffer);
610  NdbRecAttr* getValue(Uint32 anAttrId, char* resultBuffer);
611  NdbRecAttr* getValue(const NdbColumnImpl&, char* resultBuffer);
612 
613  int setResultRowBuf (const NdbRecord *rec,
614  char* resBuffer,
615  const unsigned char* result_mask);
616 
617  int setResultRowRef (const NdbRecord* rec,
618  const char* & bufRef,
619  const unsigned char* result_mask);
620 
621  NdbQuery::NextResultOutcome firstResult();
622 
623  NdbQuery::NextResultOutcome nextResult(bool fetchAllowed, bool forceSend);
624 
625  bool isRowNULL() const; // Row associated with Operation is NULL value?
626 
627  bool isRowChanged() const; // Prev ::nextResult() on NdbQuery retrieved a new
628  // value for this NdbQueryOperation
629 
631  bool execTRANSID_AI(const Uint32* ptr, Uint32 len);
632 
636  bool execTCKEYREF(const NdbApiSignal* aSignal);
637 
644  bool execSCAN_TABCONF(Uint32 tcPtrI, Uint32 rowCount, Uint32 nodeMask,
645  NdbReceiver* receiver);
646 
647  const NdbQueryOperation& getInterface() const
648  { return m_interface; }
649  NdbQueryOperation& getInterface()
650  { return m_interface; }
651 
660 
661  NdbQueryOptions::ScanOrdering getOrdering() const
662  { return m_ordering; }
663 
670  int setParallelism(Uint32 parallelism);
671 
677  int setMaxParallelism();
678 
687 
696  int setBatchSize(Uint32 batchSize);
697 
707  bool hasInterpretedCode() const;
708 
710  bool checkMagicNumber() const
711  { return m_magic == MAGIC; }
712 
716  Uint32 getMaxBatchRows() const
717  { return m_maxBatchRows; }
718 
720  Uint32 getRowSize() const;
721 
722  const NdbRecord* getNdbRecord() const
723  { return m_ndbRecord; }
724 
725 private:
726 
727  STATIC_CONST (MAGIC = 0xfade1234);
728 
730  NdbQueryOperation m_interface;
732  const Uint32 m_magic;
734  NdbQueryImpl& m_queryImpl;
737  const NdbQueryOperationDefImpl& m_operationDef;
738 
739  /* MAYBE: replace m_children with navigation via m_operationDef.getChildOperation().*/
741  NdbQueryOperationImpl* m_parent;
744 
746  Uint32 m_maxBatchRows;
747 
749  Uint32Buffer m_params;
750 
752  char* m_resultBuffer;
756  const char** m_resultRef;
758  bool m_isRowNull;
759 
761  const NdbRecord* m_ndbRecord;
762  const unsigned char* m_read_mask;
763 
766  NdbRecAttr* m_firstRecAttr;
767  NdbRecAttr* m_lastRecAttr;
768 
771 
774  NdbInterpretedCode* m_interpretedCode;
775 
777  bool m_diskInUserProjection;
778 
781  Uint32 m_parallelism;
782 
784  mutable Uint32 m_rowSize;
785 
786  explicit NdbQueryOperationImpl(NdbQueryImpl& queryImpl,
787  const NdbQueryOperationDefImpl& def);
789 
791  void fetchRow(NdbResultStream& resultStream);
792 
796  void nullifyResult();
797 
799  void postFetchRelease();
800 
802  Int32 getNoOfDescendantOperations() const;
803 
807  Uint32 getNoOfLeafOperations() const;
808 
811  int serializeParams(const NdbQueryParamValue* paramValues);
812 
813  int serializeProject(Uint32Buffer& attrInfo);
814 
815  Uint32 calculateBatchedRows(const NdbQueryOperationImpl* closestScan);
816  void setBatchedRows(Uint32 batchedRows);
817 
820  int prepareAttrInfo(Uint32Buffer& attrInfo);
821 
829  int prepareKeyInfo(Uint32Buffer& keyInfo,
830  const NdbQueryParamValue* actualParam);
831 
832  int prepareLookupKeyInfo(
833  Uint32Buffer& keyInfo,
834  const NdbQueryOperandImpl* const keys[],
835  const NdbQueryParamValue* actualParam);
836 
837  int prepareIndexKeyInfo(
838  Uint32Buffer& keyInfo,
839  const NdbQueryOperationDefImpl::IndexBound* bounds,
840  const NdbQueryParamValue* actualParam);
841 
846  Uint32 getIdOfReceiver() const;
847 
853  int prepareInterpretedCode(Uint32Buffer& attrInfo) const;
854 
856  bool diskInUserProjection() const
857  { return m_diskInUserProjection; }
858 
859 }; // class NdbQueryOperationImpl
860 
861 
862 #endif