MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbQueryOperation.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 NdbQueryOperation_H
18 #define NdbQueryOperation_H
19 
20 #include <ndb_types.h>
21 
22 // this file is currently not located in include/ndbapi
23 // which means that we need to use <> to include instead of ""
24 // for files located in include/ndbapi
25 
26 // this file is currently not located in include/ndbapi
27 // skip includes...and require them to be included first
28 // BUH!
29 
30 /* There is no way to forward declare nested class NdbDictionary::Column,
31  * so this header file must be included.*/
32 // #include <NdbDictionary.hpp>
33 
34 // Needed to get NdbQueryOptions::ScanOrdering.
35 // #include "NdbQueryBuilder.hpp"
36 // #include <NdbIndexScanOperation.hpp>
37 
38 
39 class Ndb;
40 struct NdbError;
41 class NdbParamOperand;
42 class NdbQueryOperation;
44 class NdbRecAttr;
45 class NdbTransaction;
46 class NdbRecord;
47 class NdbInterpretedCode;
48 
50 class NdbQueryImpl;
52 
53 
54 /********************** OVERVIEW ***********************
55  *
56  * a NdbQuery is created when a NdbQueryDefinition is added to a
57  * NdbTransaction for execution with NdbTransaction::creatQuery().
58  *
59  * A NdbQuery is associated with a collection of NdbQueryOperation which
60  * are instantiated (1::1) to reflect the NdbQueryOperationDef objects
61  * which the NdbQueryDef consists of. The same NdbQueryDef may be used to
62  * instantiate multiple NdbQuery obejects.
63  *
64  * When we have an instantiated NdbQuery, we should either bind result buffers
65  * for retrieving entire rows from each operation,
66  * (aka NdbRecord interface,::setResultRowRef(), ::setResultRowBuf())
67  * or set up retrieval operations for each attribute values, (::getValue()).
68  *
69  * Optionally we may also:
70  * - Specify a scan ordering for the result set (parent only)
71  * - Add multiple bounds to a range scan, (::setBound()) (parent only)
72  * - Append a filter condition for each operation (aka mysqlds pushed condition)
73  *
74  * The NdbQuery is then executed together with other pending operations
75  * in the next NdbTransaction::execute().
76  * The resultset available from a NdbQuery is natively a 'left outer join'
77  * between the parent / child operations. If an application is not interested
78  * in the 'outer part' of the resultset, it is its own responsibility to
79  * filter these rows. Same is valid for any filter condition which has
80  * not been appended to the NdbQuery.
81  *
82  *
83  * We provide two different interfaces for iterating the result set:
84  *
85  * The 'local cursor' (NdbQueryOperation::firstResult(), ::nextResult())
86  * Will navigate the resultset, and fetch results, from this specific operation.
87  * It will only be possible to navigate within those rows which depends
88  * on the current row(s) from any ancestor of the operation.
89  * The local cursor will only retrieve the results, or a NULL row,
90  * resulting from its own operation. -> All child operations of a
91  * renavigated local cursor should be navigated to ::firstResult()
92  * to ensure that they contain results related to the renavigated parent.
93  *
94  * The 'global cursor' (NdbQuery::nextResult())
95  * Will present the result set as a scan on the root operation
96  * with rows from its child operations appearing in an unpredictable
97  * order. A new set of results, or NULL rows, from *all* operations
98  * in the query tree are retrieved for each ::nextResult().
99  * NULL rows resulting from the outer joins may appear anywhere
100  * inside the resultset.
101  *
102  * As the global cursor is implemented on top of the local cursors, it is
103  * possible to mix the usage of global and local cursors.
104  *
105  ************************************************************************/
106 class NdbQuery
107 {
108 private:
109  // Only constructable through ::buildQuery()
110  friend class NdbQueryImpl;
111  explicit NdbQuery(NdbQueryImpl& impl);
112  ~NdbQuery();
113 
114 public:
117  NextResult_error = -1,
118  NextResult_gotRow = 0,
119  NextResult_scanComplete = 1,
120  NextResult_bufferEmpty = 2
121  };
122 
123  Uint32 getNoOfOperations() const;
124 
125  // Get a specific NdbQueryOperation by ident specified
126  // when the NdbQueryOperationDef was created.
127  NdbQueryOperation* getQueryOperation(const char* ident) const;
128  NdbQueryOperation* getQueryOperation(Uint32 index) const;
129 //NdbQueryOperation* getQueryOperation(const NdbQueryOperationDef* def) const;
130 
131  Uint32 getNoOfParameters() const;
132  const NdbParamOperand* getParameter(const char* name) const;
133  const NdbParamOperand* getParameter(Uint32 num) const;
134 
135  int setBound(const NdbRecord *keyRecord,
136  const struct NdbIndexScanOperation::IndexBound *bound);
137 
174  NextResultOutcome nextResult(bool fetchAllowed = true,
175  bool forceSend = false);
176 
181 
193  void close(bool forceSend = false);
194 
205  const NdbError& getNdbError() const;
206 
209  { return m_impl; }
210 
220  int isPrunable(bool& pruned) const;
221 
222 private:
224  NdbQueryImpl& m_impl;
225 
226 }; // class NdbQuery
227 
228 
229 
230 
232 {
233 private:
234  // Only constructable through executing a NdbQueryDef
235  friend class NdbQueryOperationImpl;
238 
239 public:
240  // Collection of get'ers to navigate in root, parent/child hierarchy
241 
242  Uint32 getNoOfParentOperations() const;
243  NdbQueryOperation* getParentOperation(Uint32 parentNo) const;
244 
245  Uint32 getNoOfChildOperations() const;
246  NdbQueryOperation* getChildOperation(Uint32 childNo) const;
247 
248  const NdbQueryOperationDef& getQueryOperationDef() const;
249 
250  // Get the entire query object which this operation is part of
251  NdbQuery& getQuery() const;
252 
253 
254 
286  NdbRecAttr* getValue(const char* anAttrName, char* resultBuffer = 0);
287  NdbRecAttr* getValue(Uint32 anAttrId, char* resultBuffer = 0);
288  NdbRecAttr* getValue(const NdbDictionary::Column* column,
289  char* resultBuffer = 0);
290 
310  int setResultRowBuf (const NdbRecord *rec,
311  char* resBuffer,
312  const unsigned char* result_mask = 0);
313 
314  int setResultRowRef (const NdbRecord* rec,
315  const char* & bufRef,
316  const unsigned char* result_mask = 0);
317 
318  // TODO: define how BLOB/CLOB should be retrieved.
319  // ... Replicate ::getBlobHandle() from NdbOperation class?
320 
323  { return m_impl; }
324 
333 
336 
343  int setParallelism(Uint32 parallelism);
344 
350  int setMaxParallelism();
351 
360 
369  int setBatchSize(Uint32 batchSize);
370 
389  int setInterpretedCode(const NdbInterpretedCode& code) const;
390 
404 
431  bool fetchAllowed = true,
432  bool forceSend = false);
433 
434  // Result handling for this NdbQueryOperation
435  bool isRowNULL() const; // Row associated with Operation is NULL value?
436 
437  bool isRowChanged() const; // Prev ::nextResult() on NdbQuery retrived a new
438  // value for this NdbQueryOperation
439 
440 
441 private:
442  // Opaque implementation class instance.
443  NdbQueryOperationImpl& m_impl;
444 
445 }; // class NdbQueryOperation
446 
447 
449 {
450 public:
451 
452  // Raw data formated according to bound Column format.
453  // NOTE: This is how mysqld prepare parameter values!
454  NdbQueryParamValue(const void* val, bool shrinkVarChar= false);
455 
456  // C-type string, terminated by '\0'
457  NdbQueryParamValue(const char* val);
458 
459  // NULL-value, also used as optional end marker
461  NdbQueryParamValue(Uint16 val);
462  NdbQueryParamValue(Uint32 val);
463  NdbQueryParamValue(Uint64 val);
464  NdbQueryParamValue(double val);
465 
466  // More parameter C'tor to be added when required:
467 //NdbQueryParamValue(Uint8 val);
468 //NdbQueryParamValue(Int8 val);
469 //NdbQueryParamValue(Int16 val);
470 //NdbQueryParamValue(Int32 val);
471 //NdbQueryParamValue(Int64 val);
472 
483  int serializeValue(const class NdbColumnImpl& column,
484  class Uint32Buffer& dst,
485  Uint32& len,
486  bool& isNull) const;
487 
488 private:
489  int m_type;
490 
491  union
492  {
493  Uint8 uint8;
494  Int8 int8;
495  Uint16 uint16;
496  Int16 int16;
497  Uint32 uint32;
498  Int32 int32;
499  Uint64 uint64;
500  Int64 int64;
501  double dbl;
502  const char* string;
503  const void* raw;
504  } m_value;
505 };
506 
507 #endif