MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbQueryBuilderImpl.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 St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #ifndef NdbQueryBuilderImpl_H
20 #define NdbQueryBuilderImpl_H
21 
22 /* Query-related error codes. */
23 #define QRY_REQ_ARG_IS_NULL 4800
24 #define QRY_TOO_FEW_KEY_VALUES 4801
25 #define QRY_TOO_MANY_KEY_VALUES 4802
26 #define QRY_OPERAND_HAS_WRONG_TYPE 4803
27 #define QRY_CHAR_OPERAND_TRUNCATED 4804
28 #define QRY_NUM_OPERAND_RANGE 4805
29 #define QRY_MULTIPLE_PARENTS 4806
30 #define QRY_UNKONWN_PARENT 4807
31 #define QRY_UNKNOWN_COLUMN 4808
32 #define QRY_UNRELATED_INDEX 4809
33 #define QRY_WRONG_INDEX_TYPE 4810
34 #define QRY_OPERAND_ALREADY_BOUND 4811
35 #define QRY_DEFINITION_TOO_LARGE 4812
36 #define QRY_SEQUENTIAL_SCAN_SORTED 4813
37 #define QRY_RESULT_ROW_ALREADY_DEFINED 4814
38 #define QRY_HAS_ZERO_OPERATIONS 4815
39 #define QRY_IN_ERROR_STATE 4816
40 #define QRY_ILLEGAL_STATE 4817
41 #define QRY_WRONG_OPERATION_TYPE 4820
42 #define QRY_SCAN_ORDER_ALREADY_SET 4821
43 #define QRY_PARAMETER_HAS_WRONG_TYPE 4822
44 #define QRY_CHAR_PARAMETER_TRUNCATED 4823
45 #define QRY_MULTIPLE_SCAN_SORTED 4824
46 #define QRY_BATCH_SIZE_TOO_SMALL 4825
47 
48 #ifdef __cplusplus
49 #include <Vector.hpp>
50 #include <Bitmask.hpp>
51 #include "NdbQueryBuilder.hpp"
52 #include "NdbIndexScanOperation.hpp"
53 #include "ndb_limits.h"
54 
55 // Forward declared
56 class NdbTableImpl;
57 class NdbIndexImpl;
58 class NdbColumnImpl;
59 class NdbQueryBuilderImpl;
60 class NdbQueryDefImpl;
61 class NdbQueryOperationDefImpl;
62 class NdbQueryParamValue;
63 class NdbParamOperandImpl;
64 class NdbConstOperandImpl;
65 class NdbLinkedOperandImpl;
66 
67 // For debuggging.
68 //#define TRACE_SERIALIZATION
69 
90 class Uint32Buffer{
91 public:
92 
93 //#define TEST_Uint32Buffer
94 
95 #if defined(TEST_Uint32Buffer)
96  STATIC_CONST(initSize = 1); // Small size to force test of buffer expand.
97 #else
98  STATIC_CONST(initSize = 32); // Initial buffer size, extend on demand but probably sufficent
99 #endif
100 
101  explicit Uint32Buffer():
102  m_array(m_local),
103  m_avail(initSize),
104  m_size(0),
105  m_memoryExhausted(false),
106  m_bytesLeft(0)
107  {}
108 
109  ~Uint32Buffer() {
110  if (unlikely(m_array != m_local)) {
111  delete[] m_array;
112  }
113  }
114 
118  void releaseExtend() {
119  if (unlikely(m_array != m_local)) {
120  delete[] m_array;
121  }
122  m_array = NULL;
123  m_size = 0;
124  }
125 
132  Uint32* alloc(Uint32 count) {
133  Uint32 reqSize = m_size+count;
134  if(unlikely(reqSize >= m_avail)) {
135  if (unlikely(m_memoryExhausted)) {
136  return NULL;
137  }
138 #if defined(TEST_Uint32Buffer)
139  Uint32 newSize = reqSize; // -> Always expand on next alloc
140 #else
141  Uint32 newSize = reqSize*2;
142 #endif
143 // ndbout << "Uint32Buffer::alloc() Extend buffer from: " << m_avail
144 // << ", to: " << newSize << endl;
145  Uint32* newBuf = new Uint32[newSize];
146  if (likely(newBuf!=NULL)) {
147  assert(newBuf);
148  memcpy (newBuf, m_array, m_size*sizeof(Uint32));
149  if (m_array != m_local) {
150  delete[] m_array;
151  }
152  m_array = newBuf;
153  m_avail = static_cast<Uint32>(newSize);
154  } else {
155  m_size = m_avail;
156  m_memoryExhausted = true;
157  return NULL;
158  }
159  }
160  Uint32* extend = &m_array[m_size];
161  m_size += static_cast<Uint32>(count);
162  return extend;
163  }
164 
167  void put(Uint32 idx, Uint32 value) {
168  assert(idx < m_size);
169  m_array[idx] = value;
170  }
171 
174  void append(const Uint32 src) {
175  m_bytesLeft = 0;
176  if (likely(m_size < m_avail)) {
177  m_array[m_size++] = src;
178  } else {
179  Uint32* dst = alloc(1);
180  if (likely(dst!=NULL))
181  *dst = src;
182  }
183  }
184 
187  void append(const Uint32Buffer& src) {
188  assert (!src.isMemoryExhausted());
189  m_bytesLeft = 0;
190  Uint32 len = src.getSize();
191  if (likely(len > 0)) {
192  Uint32* dst = alloc(len);
193  if (likely(dst!=NULL)) {
194  memcpy(dst, src.addr(), len*sizeof(Uint32));
195  }
196  }
197  }
198 
202  void appendBytes(const void* src, Uint32 len) {
203  if (likely(len > 0)) {
204  Uint32 wordCount =
205  static_cast<Uint32>((len + sizeof(Uint32)-1 - m_bytesLeft)
206  / sizeof(Uint32));
207  Uint32* dst = alloc(wordCount);
208  if (likely(dst!=NULL)) {
209  // Copy src
210  Uint8* const start = reinterpret_cast<Uint8*>(dst) - m_bytesLeft;
211  memcpy(start, src, len);
212  m_bytesLeft = (m_bytesLeft - len) % sizeof(Uint32);
213  // Make sure that any trailing bytes in the last word are zero.
214  bzero(start + len, m_bytesLeft);
215  }
216  }
217  }
218 
221  void skipRestOfWord()
222  { m_bytesLeft = 0; }
223 
224  Uint32* addr(Uint32 idx=0) {
225  return (likely(!m_memoryExhausted && m_size>idx)) ?&m_array[idx] :NULL;
226  }
227  const Uint32* addr(Uint32 idx=0) const {
228  return (likely(!m_memoryExhausted && m_size>idx)) ?&m_array[idx] :NULL;
229  }
230 
232  Uint32 get(Uint32 idx) const {
233  assert(idx < m_size);
234  return m_array[idx];
235  }
236 
238  bool isMemoryExhausted() const {
239  return m_memoryExhausted;
240  }
241 
242  Uint32 getSize() const {
243  return m_size;
244  }
245 
246 private:
248  Uint32Buffer(Uint32Buffer&);
249  Uint32Buffer& operator=(Uint32Buffer&);
250 
251 private:
252  Uint32 m_local[initSize]; // Initial static bufferspace
253  Uint32* m_array; // Refers m_local initially, or extended large buffer
254  Uint32 m_avail; // Available buffer space
255  Uint32 m_size; // Actuall size <= m_avail
256  bool m_memoryExhausted;
258  Uint32 m_bytesLeft;
259 };
260 
261 
262 class NdbQueryOptionsImpl
263 {
264  friend class NdbQueryOptions;
265  friend class NdbQueryOperationDefImpl;
266 
267 public:
268  explicit NdbQueryOptionsImpl()
269  : m_matchType(NdbQueryOptions::MatchAll),
270  m_scanOrder(NdbQueryOptions::ScanOrdering_void),
271  m_parent(NULL),
272  m_interpretedCode(NULL)
273  {};
274  NdbQueryOptionsImpl(const NdbQueryOptionsImpl&);
275  ~NdbQueryOptionsImpl();
276 
277 private:
278  NdbQueryOptions::MatchType m_matchType;
279  NdbQueryOptions::ScanOrdering m_scanOrder;
280  NdbQueryOperationDefImpl* m_parent;
281  const NdbInterpretedCode* m_interpretedCode;
282 
287  int copyInterpretedCode(const NdbInterpretedCode& src);
288 
289  NdbQueryOptionsImpl&operator=(const NdbQueryOptionsImpl&); // Not impl.
290 };
291 
292 
294 // Implementation of NdbQueryOperation interface
296 
297 class NdbQueryOperationDefImpl
298 {
299  friend class NdbQueryOperationDef;
300  friend class NdbQueryOperationImpl;
301  friend class NdbQueryImpl;
302 
303 public:
304 
305  struct IndexBound { // Limiting 'bound ' definition for indexScan
306  NdbQueryOperandImpl* low[MAX_ATTRIBUTES_IN_INDEX];
307  NdbQueryOperandImpl* high[MAX_ATTRIBUTES_IN_INDEX];
308  Uint32 lowKeys, highKeys;
309  bool lowIncl, highIncl;
310  };
311 
312  /* Currently only a single parent is supported */
313  Uint32 getNoOfParentOperations() const
314  { return (m_parent) ? 1 : 0; }
315 
316  NdbQueryOperationDefImpl& getParentOperation(Uint32 i) const
317  { assert(i==0 && m_parent!=NULL);
318  return *m_parent;
319  }
320 
321  NdbQueryOperationDefImpl* getParentOperation() const
322  { return m_parent;
323  }
324 
325  Uint32 getNoOfChildOperations() const
326  { return m_children.size(); }
327 
328  NdbQueryOperationDefImpl& getChildOperation(Uint32 i) const
329  { return *m_children[i]; }
330 
331  const NdbTableImpl& getTable() const
332  { return m_table; }
333 
334  const char* getName() const
335  { return m_ident; }
336 
337  enum NdbQueryOptions::MatchType getMatchType() const
338  { return m_options.m_matchType; }
339 
340  enum NdbQueryOptions::ScanOrdering getOrdering() const
341  { return m_options.m_scanOrder; }
342 
343  const NdbInterpretedCode* getInterpretedCode() const
344  { return m_options.m_interpretedCode; }
345 
346  Uint32 assignQueryOperationId(Uint32& nodeId)
347  { if (getType()==NdbQueryOperationDef::UniqueIndexAccess) nodeId++;
348  m_id = nodeId++;
349  return m_id;
350  }
351 
352  // Establish a linked parent <-> child relationship with this operation
353  int linkWithParent(NdbQueryOperationDefImpl* parentOp);
354 
363  Uint32 addColumnRef(const NdbColumnImpl* column, int& error);
364 
371  int addParamRef(const NdbParamOperandImpl* param);
372 
373  Uint32 getNoOfParameters() const
374  { return m_params.size(); }
375 
376  const NdbParamOperandImpl& getParameter(Uint32 ix) const
377  { return *m_params[ix]; }
378 
379  virtual const NdbIndexImpl* getIndex() const
380  { return NULL; }
381 
382  virtual const NdbQueryOperandImpl* const* getKeyOperands() const
383  { return NULL; }
384 
385  virtual const IndexBound* getBounds() const
386  { return NULL; }
387 
388  // Return 'true' is query type is a multi-row scan
389  virtual bool isScanOperation() const = 0;
390 
391  virtual const NdbQueryOperationDef& getInterface() const = 0;
392 
397  virtual int serializeOperation(Uint32Buffer& serializedTree) = 0;
398 
402  const Vector<const NdbColumnImpl*>& getSPJProjection() const {
403  return m_spjProjection;
404  }
405 
406  virtual int checkPrunable(const Uint32Buffer& keyInfo,
407  Uint32 shortestBound,
408  bool& isPruned,
409  Uint32& hashValue) const {
410  isPruned = false;
411  return 0;
412  }
413 
414  virtual ~NdbQueryOperationDefImpl();
415 
416 protected:
417  explicit NdbQueryOperationDefImpl (const NdbTableImpl& table,
418  const NdbQueryOptionsImpl& options,
419  const char* ident,
420  Uint32 ix,
421  int& error);
422 public:
423  // Get the ordinal position of this operation within the query def.
424  Uint32 getQueryOperationIx() const
425  { return m_ix; }
426 
427  // Get id of node as known inside queryTree
428  Uint32 getQueryOperationId() const
429  { return m_id; }
430 
431  // Get type of query operation
432  virtual NdbQueryOperationDef::Type getType() const = 0;
433 
439  void printTree(
440  Uint32 depth,
441  Bitmask<(NDB_SPJ_MAX_TREE_NODES+31)/32> hasMoreSiblingsMask) const;
442 
443 protected:
444  // QueryTree building:
445  // Append list of parent nodes to serialized code
446  Uint32 appendParentList(Uint32Buffer& serializedDef) const;
447 
448  // Append list of columns required by SPJ to instantiate child operations.
449  Uint32 appendChildProjection(Uint32Buffer& serializedDef) const;
450 
451 protected:
453  bool m_isPrepared;
454 
459  bool m_diskInChildProjection;
460 
461 private:
462  bool isChildOf(const NdbQueryOperationDefImpl* parentOp) const;
463 
469  int addChild(NdbQueryOperationDefImpl* child);
470 
471  // Remove a linked child refering specified operation
472  void removeChild(const NdbQueryOperationDefImpl*);
473 
474 private:
475  const NdbTableImpl& m_table;
476  const char* const m_ident; // Optional name specified by aplication
477  const Uint32 m_ix; // Index of this operation within operation array
478  Uint32 m_id; // Operation id when materialized into queryTree.
479  // If op has index, index id is 'm_id-1'.
480 
481  // Optional (or default) options specified when building query:
482  // - Scan order which may specify ascending or descending scan order
483  // - Match type used for hinting on optimal inner-, outer-, semijoin exec.
484  const NdbQueryOptionsImpl m_options;
485 
486  // parent pointer & child ptr. vector contains dependencies
487  // as defined with linkedValues
488  NdbQueryOperationDefImpl* m_parent;
490 
491  // Params required by this operation
493 
494  // Column from this operation required by its child operations
495  Vector<const NdbColumnImpl*> m_spjProjection;
496 }; // class NdbQueryOperationDefImpl
497 
498 
499 class NdbQueryScanOperationDefImpl :
500  public NdbQueryOperationDefImpl
501 {
502 public:
503  explicit NdbQueryScanOperationDefImpl (
504  const NdbTableImpl& table,
505  const NdbQueryOptionsImpl& options,
506  const char* ident,
507  Uint32 ix,
508  int& error);
509 
510  virtual bool isScanOperation() const
511  { return true; }
512 
513 protected:
514  int serialize(Uint32Buffer& serializedDef,
515  const NdbTableImpl& tableOrIndex);
516 
517  // Append pattern for creating complete range bounds to serialized code
518  virtual Uint32 appendBoundPattern(Uint32Buffer& serializedDef) const
519  { return 0; }
520 
521  virtual Uint32 appendPrunePattern(Uint32Buffer& serializedDef) const
522  { return 0; }
523 
524 }; // class NdbQueryScanOperationDefImpl
525 
526 
527 class NdbQueryIndexScanOperationDefImpl : public NdbQueryScanOperationDefImpl
528 {
529  friend class NdbQueryBuilder; // Allow privat access from builder interface
530 
531 public:
532  virtual const NdbIndexImpl* getIndex() const
533  { return &m_index; }
534 
535  virtual int serializeOperation(Uint32Buffer& serializedDef);
536 
537  virtual const NdbQueryIndexScanOperationDef& getInterface() const
538  { return m_interface; }
539 
540  virtual NdbQueryOperationDef::Type getType() const
542 
543  virtual int checkPrunable(const Uint32Buffer& keyInfo,
544  Uint32 shortestBound,
545  bool& isPruned,
546  Uint32& hashValue) const;
547 
548  virtual const IndexBound* getBounds() const
549  { return &m_bound; }
550 
551 protected:
552  // Append pattern for creating complete range bounds to serialized code
553  virtual Uint32 appendBoundPattern(Uint32Buffer& serializedDef) const;
554 
555  virtual Uint32 appendPrunePattern(Uint32Buffer& serializedDef) const;
556 
557 private:
558 
559  explicit NdbQueryIndexScanOperationDefImpl (
560  const NdbIndexImpl& index,
561  const NdbTableImpl& table,
562  const NdbQueryIndexBound* bound,
563  const NdbQueryOptionsImpl& options,
564  const char* ident,
565  Uint32 ix,
566  int& error);
567 
568  // Append pattern for creating a single bound value to serialized code
569  Uint32 appendBoundValue( Uint32Buffer& serializedDef,
571  const NdbQueryOperandImpl* value,
572  int& paramCnt) const;
573 
574 private:
575  NdbQueryIndexScanOperationDef m_interface;
576  const NdbIndexImpl& m_index;
577 
579  IndexBound m_bound;
580 }; // class NdbQueryIndexScanOperationDefImpl
581 
582 
583 class NdbQueryDefImpl
584 {
585  friend class NdbQueryDef;
586 
587 public:
588  explicit NdbQueryDefImpl(const Vector<NdbQueryOperationDefImpl*>& operations,
589  const Vector<NdbQueryOperandImpl*>& operands,
590  int& error);
591  ~NdbQueryDefImpl();
592 
593  // Entire query is a scan iff root operation is scan.
594  // May change in the future as we implement more complicated SPJ operations.
595  bool isScanQuery() const
596  { return m_operations[0]->isScanOperation(); }
597 
598  NdbQueryDef::QueryType getQueryType() const;
599 
600  Uint32 getNoOfOperations() const
601  { return m_operations.size(); }
602 
603  // Get a specific NdbQueryOperationDef by ident specified
604  // when the NdbQueryOperationDef was created.
605  const NdbQueryOperationDefImpl& getQueryOperation(Uint32 index) const
606  { return *m_operations[index]; }
607 
608  const NdbQueryOperationDefImpl* getQueryOperation(const char* ident) const;
609 
610  const NdbQueryDef& getInterface() const
611  { return m_interface; }
612 
614  Uint32Buffer& getSerialized()
615  { return m_serializedDef; }
616 
618  const Uint32Buffer& getSerialized() const
619  { return m_serializedDef; }
620 
621 private:
622  NdbQueryDef m_interface;
623 
625  Vector<NdbQueryOperandImpl*> m_operands;
626  Uint32Buffer m_serializedDef;
627 }; // class NdbQueryDefImpl
628 
629 
630 class NdbQueryBuilderImpl
631 {
632  friend class NdbQueryBuilder;
633 
634 public:
635  ~NdbQueryBuilderImpl();
636  explicit NdbQueryBuilderImpl();
637 
638  const NdbQueryDefImpl* prepare();
639 
640  const NdbError& getNdbError() const;
641 
642  void setErrorCode(int aErrorCode);
643 
644 private:
645  bool hasError() const
646  { return m_hasError; }
647 
654  NdbQueryOperand* addOperand(NdbQueryOperandImpl* operand);
655 
664  int takeOwnership(NdbQueryOperandImpl*);
665  int takeOwnership(NdbQueryOperationDefImpl*);
666 
667  bool contains(const NdbQueryOperationDefImpl*);
668 
669  NdbQueryBuilder m_interface;
670  NdbError m_error;
671 
673  Vector<NdbQueryOperandImpl*> m_operands;
674  Uint32 m_paramCnt;
676  bool m_hasError;
677 }; // class NdbQueryBuilderImpl
678 
679 
681 // Implementation of NdbQueryOperand interface
683 
684 // Baseclass for the QueryOperand implementation
685 class NdbQueryOperandImpl
686 {
687  friend class NdbQueryBuilderImpl;
688 public:
689 
693  enum Kind {
694  Linked,
695  Param,
696  Const
697  };
698 
699  const NdbColumnImpl* getColumn() const
700  { return m_column; }
701 
702  virtual int bindOperand(const NdbColumnImpl& column,
703  NdbQueryOperationDefImpl& operation)
704  { if (m_column && m_column != &column)
705  // Already bounded to a different column
706  return QRY_OPERAND_ALREADY_BOUND;
707  m_column = &column;
708  return 0;
709  }
710 
711  Kind getKind() const
712  { return m_kind; }
713 
714  virtual NdbQueryOperand& getInterface() = 0;
715 
716 protected:
717  friend NdbQueryBuilderImpl::~NdbQueryBuilderImpl();
718  friend NdbQueryDefImpl::~NdbQueryDefImpl();
719 
720  virtual ~NdbQueryOperandImpl(){};
721 
722  NdbQueryOperandImpl(Kind kind)
723  : m_column(0),
724  m_kind(kind)
725  {}
726 
727 protected:
728  const NdbColumnImpl* m_column; // Initial NULL, assigned w/ bindOperand()
729 
733  const Kind m_kind;
734 }; // class NdbQueryOperandImpl
735 
736 
737 class NdbLinkedOperandImpl : public NdbQueryOperandImpl
738 {
739  friend class NdbQueryBuilder; // Allow privat access from builder interface
740 
741 public:
742  const NdbQueryOperationDefImpl& getParentOperation() const
743  { return m_parentOperation; }
744 
745  // 'LinkedSrc' is index into parent op's spj-projection list where
746  // the refered column value is available
747  Uint32 getLinkedColumnIx() const
748  { return m_parentColumnIx; }
749 
750  const NdbColumnImpl& getParentColumn() const
751  { return *m_parentOperation.getSPJProjection()[m_parentColumnIx]; }
752 
753  virtual NdbQueryOperand& getInterface()
754  { return m_interface; }
755 
756  virtual int bindOperand(const NdbColumnImpl& column,
757  NdbQueryOperationDefImpl& operation);
758 
759 private:
760  NdbLinkedOperandImpl (NdbQueryOperationDefImpl& parent,
761  Uint32 columnIx)
762  : NdbQueryOperandImpl(Linked),
763  m_interface(*this),
764  m_parentOperation(parent),
765  m_parentColumnIx(columnIx)
766  {}
767 
768  NdbLinkedOperand m_interface;
769  NdbQueryOperationDefImpl& m_parentOperation;
770  const Uint32 m_parentColumnIx;
771 }; // class NdbLinkedOperandImpl
772 
773 
774 class NdbParamOperandImpl : public NdbQueryOperandImpl
775 {
776  friend class NdbQueryBuilder; // Allow privat access from builder interface
777 
778 public:
779  const char* getName() const
780  { return m_name; }
781 
782  Uint32 getParamIx() const
783  { return m_paramIx; }
784 
785  virtual NdbQueryOperand& getInterface()
786  { return m_interface; }
787 
788  virtual int bindOperand(const NdbColumnImpl& column,
789  NdbQueryOperationDefImpl& operation);
790 
791 private:
792  NdbParamOperandImpl (const char* name, Uint32 paramIx)
793  : NdbQueryOperandImpl(Param),
794  m_interface(*this),
795  m_name(name),
796  m_paramIx(paramIx)
797  {}
798 
799  NdbParamOperand m_interface;
800  const char* const m_name; // Optional parameter name or NULL
801  const Uint32 m_paramIx;
802 }; // class NdbParamOperandImpl
803 
804 
805 class NdbConstOperandImpl : public NdbQueryOperandImpl
806 {
807  friend class NdbQueryBuilder; // Allow privat access from builder interface
808 public:
809  Uint32 getSizeInBytes() const
810  { return m_converted.len; }
811  const void* getAddr() const
812  { return likely(m_converted.buffer==NULL) ? &m_converted.val : m_converted.buffer; }
813 
814  virtual NdbQueryOperand& getInterface()
815  { return m_interface; }
816 
817  virtual int bindOperand(const NdbColumnImpl& column,
818  NdbQueryOperationDefImpl& operation);
819 
820 protected:
821  NdbConstOperandImpl ()
822  : NdbQueryOperandImpl(Const),
823  m_converted(),
824  m_interface(*this)
825  {}
826 
827  #define UNDEFINED_CONVERSION \
828  { return QRY_OPERAND_HAS_WRONG_TYPE; }
829 
830  virtual int convertUint8() UNDEFINED_CONVERSION;
831  virtual int convertInt8() UNDEFINED_CONVERSION;
832  virtual int convertUint16() UNDEFINED_CONVERSION;
833  virtual int convertInt16() UNDEFINED_CONVERSION;
834  virtual int convertUint24() UNDEFINED_CONVERSION;
835  virtual int convertInt24() UNDEFINED_CONVERSION;
836  virtual int convertUint32() UNDEFINED_CONVERSION;
837  virtual int convertInt32() UNDEFINED_CONVERSION;
838  virtual int convertUint64() UNDEFINED_CONVERSION;
839  virtual int convertInt64() UNDEFINED_CONVERSION;
840  virtual int convertFloat() UNDEFINED_CONVERSION;
841  virtual int convertDouble() UNDEFINED_CONVERSION
842 
843  virtual int convertUDec() UNDEFINED_CONVERSION;
844  virtual int convertDec() UNDEFINED_CONVERSION;
845 
846  virtual int convertBit() UNDEFINED_CONVERSION;
847  virtual int convertChar() UNDEFINED_CONVERSION;
848  virtual int convertVChar() UNDEFINED_CONVERSION;
849  virtual int convertLVChar() UNDEFINED_CONVERSION;
850  virtual int convertBin() UNDEFINED_CONVERSION;
851  virtual int convertVBin() UNDEFINED_CONVERSION;
852  virtual int convertLVBin() UNDEFINED_CONVERSION;
853 
854  virtual int convertDate() UNDEFINED_CONVERSION;
855  virtual int convertDatetime() UNDEFINED_CONVERSION;
856  virtual int convertTime() UNDEFINED_CONVERSION;
857  virtual int convertYear() UNDEFINED_CONVERSION;
858  virtual int convertTimestamp() UNDEFINED_CONVERSION;
859 
860  virtual int convert2ColumnType();
861 
865  class ConvertedValue {
866  public:
867  ConvertedValue() : len(0), buffer(NULL) {};
868  ~ConvertedValue() {
869  if (buffer) delete[] ((char*)buffer);
870  };
871 
872  char* getCharBuffer(Uint32 size) {
873  char* dst = val.shortChar;
874  if (unlikely(size > sizeof(val.shortChar))) {
875  dst = new char[size];
876  buffer = dst;
877  }
878  len = size;
879  return dst;
880  }
881 
882  STATIC_CONST(maxShortChar = 32);
883 
884  union
885  {
886  Uint8 uint8;
887  Int8 int8;
888  Uint16 uint16;
889  Int16 int16;
890  Uint32 uint32;
891  Int32 int32;
892  Uint64 uint64;
893  Int64 int64;
894 
895  double dbl;
896  float flt;
897 
898  char shortChar[maxShortChar];
899  } val;
900 
901  Uint32 len;
902  void* buffer; // Optional; storage for converted value
903  } m_converted;
904 
905 private:
906  NdbConstOperand m_interface;
907 }; // class NdbConstOperandImpl
908 
909 
910 #endif /* __cplusplus */
911 #endif