1 /*
2    Copyright (c) 2003, 2020, 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, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef NdbDictionary_H
26 #define NdbDictionary_H
27 
28 #include <ndb_types.h>
29 
30 class Ndb;
31 struct CHARSET_INFO;
32 
33 /* Forward declaration only. */
34 class NdbRecord;
35 
36 /**
37  * @class NdbDictionary
38  * @brief Data dictionary class
39  *
40  * The preferred and supported way to create and drop tables and indexes
41  * in ndb is through the
42  * MySQL Server (see MySQL reference Manual, section MySQL Cluster).
43  *
44  * Tables and indexes that are created directly through the
45  * NdbDictionary class
46  * can not be viewed from the MySQL Server.
47  * Dropping indexes directly via the NdbApi will cause inconsistencies
48  * if they were originally created from a MySQL Cluster.
49  *
50  * This class supports schema data enquiries such as:
51  * -# Enquiries about tables
52  *    (Dictionary::getTable, Table::getNoOfColumns,
53  *    Table::getPrimaryKey, and Table::getNoOfPrimaryKeys)
54  * -# Enquiries about indexes
55  *    (Dictionary::getIndex, Index::getNoOfColumns,
56  *    and Index::getColumn)
57  *
58  * This class supports schema data definition such as:
59  * -# Creating tables (Dictionary::createTable) and table columns
60  * -# Dropping tables (Dictionary::dropTable)
61  * -# Creating secondary indexes (Dictionary::createIndex)
62  * -# Dropping secondary indexes (Dictionary::dropIndex)
63  *
64  * NdbDictionary has several help (inner) classes to support this:
65  * -# NdbDictionary::Dictionary the dictionary handling dictionary objects
66  * -# NdbDictionary::Table for creating tables
67  * -# NdbDictionary::Column for creating table columns
68  * -# NdbDictionary::Index for creating secondary indexes
69  *
70  * See @ref ndbapi_simple_index.cpp for details of usage.
71  */
72 class NdbDictionary {
73 public:
NdbDictionary()74   NdbDictionary() {}                          /* Remove gcc warning */
75   /**
76    * @class Object
77    * @brief Meta information about a database object (a table, index, etc)
78    */
79   class Object {
80   public:
Object()81     Object() {}                               /* Remove gcc warning */
~Object()82     virtual ~Object() {}                      /* Remove gcc warning */
83     /**
84      * Status of object
85      */
86     enum Status {
87       New,                    ///< The object only exist in memory and
88                               ///< has not been created in the NDB Kernel
89       Changed,                ///< The object has been modified in memory
90                               ///< and has to be commited in NDB Kernel for
91                               ///< changes to take effect
92       Retrieved,              ///< The object exist and has been read
93                               ///< into main memory from NDB Kernel
94       Invalid,                ///< The object has been invalidated
95                               ///< and should not be used
96       Altered                 ///< Table has been altered in NDB kernel
97                               ///< but is still valid for usage
98     };
99 
100     /**
101      * Get status of object
102      */
103     virtual Status getObjectStatus() const = 0;
104 
105     /**
106      * Get version of object
107      */
108     virtual int getObjectVersion() const = 0;
109 
110     virtual int getObjectId() const = 0;
111 
112     /**
113      * Object type
114      */
115     enum Type {
116       TypeUndefined = 0,      ///< Undefined
117       SystemTable = 1,        ///< System table
118       UserTable = 2,          ///< User table (may be temporary)
119       UniqueHashIndex = 3,    ///< Unique un-ordered hash index
120       OrderedIndex = 6,       ///< Non-unique ordered index
121       HashIndexTrigger = 7,   ///< Index maintenance, internal
122       IndexTrigger = 8,       ///< Index maintenance, internal
123       SubscriptionTrigger = 9,///< Backup or replication, internal
124       ReadOnlyConstraint = 10,///< Trigger, internal
125       TableEvent = 11,        ///< Table event
126       Tablespace = 20,        ///< Tablespace
127       LogfileGroup = 21,      ///< Logfile group
128       Datafile = 22,          ///< Datafile
129       Undofile = 23,          ///< Undofile
130       ReorgTrigger = 19,
131       HashMap = 24,
132       ForeignKey = 25,
133       FKParentTrigger = 26,
134       FKChildTrigger = 27,
135       FullyReplicatedTrigger = 28
136     };
137 
138     /**
139      * Object state
140      */
141     enum State {
142       StateUndefined = 0,     ///< Undefined
143       StateOffline = 1,       ///< Offline, not usable
144       StateBuilding = 2,      ///< Building, not yet usable
145       StateDropping = 3,      ///< Offlining or dropping, not usable
146       StateOnline = 4,        ///< Online, usable
147       ObsoleteStateBackup = 5,///< Online, being backed-up, usable
148       StateBroken = 9         ///< Broken, should be dropped and re-created
149     };
150 
151     /**
152      * Object store
153      */
154     enum Store {
155       StoreUndefined = 0,     ///< Undefined
156       StoreNotLogged = 1,     ///< Object or data deleted on system restart
157       StorePermanent = 2      ///< Permanent. logged to disk
158     };
159 
160     /**
161      * Type of fragmentation.
162      *
163      * This parameter specifies how data in the table or index will
164      * be distributed among the db nodes in the cluster.<br>
165      * The bigger the table the more number of fragments should be used.
166      * Note that all replicas count as same "fragment".<br>
167      * For a table, default is FragAllMedium.  For a unique hash index,
168      * default is taken from underlying table and cannot currently
169      * be changed.
170      */
171     enum FragmentType {
172       FragUndefined = 0,      ///< Fragmentation type undefined or default
173       FragSingle = 1,         ///< Only one fragment
174       FragAllSmall = 2,       ///< One fragment per node, default
175       FragAllMedium = 3,      ///< two fragments per node
176       FragAllLarge = 4,       ///< Four fragments per node.
177       DistrKeyHash = 5,
178       DistrKeyLin = 6,
179       UserDefined = 7,
180       HashMapPartition = 9
181     };
182 
183     /**
184      * This enum defines values that are usable with
185      *   Table::setPartitionBalance
186      */
187     enum PartitionBalance {
188       /**
189        * Use a specific value set using setFragmentCount
190        */
191       PartitionBalance_Specific = NDB_PARTITION_BALANCE_SPECIFIC,
192 
193       /**
194        * Use one fragment per LDM per node
195        *   (current default)
196        */
197       PartitionBalance_ForRPByLDM = NDB_PARTITION_BALANCE_FOR_RP_BY_LDM,
198 
199       /**
200        * Use X fragment per LDM per nodegroup
201        */
202       PartitionBalance_ForRAByLDMx2 = NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_2,
203       PartitionBalance_ForRAByLDMx3 = NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_3,
204       PartitionBalance_ForRAByLDMx4 = NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_4,
205 
206       /**
207        * Use one fragment per LDM per nodegroup
208        */
209       PartitionBalance_ForRAByLDM =
210         NDB_PARTITION_BALANCE_FOR_RA_BY_LDM,
211 
212       /**
213        * Use one fragment per node
214        */
215       PartitionBalance_ForRPByNode = NDB_PARTITION_BALANCE_FOR_RP_BY_NODE,
216 
217       /**
218        * Use one fragment per node group
219        */
220       PartitionBalance_ForRAByNode = NDB_PARTITION_BALANCE_FOR_RA_BY_NODE,
221     };
222 
223     Object(const Object&) = default;
224   private:
225     Object&operator=(const Object&);
226   };
227 
228   class Dictionary; // Forward declaration
229 
230   class ObjectId : public Object
231   {
232   public:
233     ObjectId();
234     virtual ~ObjectId();
235 
236     /**
237      * Get status of object
238      */
239     virtual Status getObjectStatus() const;
240 
241     /**
242      * Get version of object
243      */
244     virtual int getObjectVersion() const;
245 
246     virtual int getObjectId() const;
247 
248   private:
249     friend class NdbDictObjectImpl;
250     class NdbDictObjectImpl & m_impl;
251 
252     ObjectId(const ObjectId&); // Not impl.
253     ObjectId&operator=(const ObjectId&);
254   };
255 
256   class Table; // forward declaration
257   class Tablespace; // forward declaration
258   class HashMap; // Forward
259 
260   /**
261    * @class Column
262    * @brief Represents a column in an NDB Cluster table
263    *
264    * Each column has a type. The type of a column is determined by a number
265    * of type specifiers.
266    * The type specifiers are:
267    * - Builtin type
268    * - Array length or max length
269    * - Precision and scale (not used yet)
270    * - Character set for string types
271    * - Inline and part sizes for blobs
272    *
273    * Types in general correspond to MySQL types and their variants.
274    * Data formats are same as in MySQL.  NDB API provides no support for
275    * constructing such formats.  NDB kernel checks them however.
276    */
277   class Column {
278   public:
279     /**
280      * The builtin column types
281      */
282     enum Type {
283       Undefined = NDB_TYPE_UNDEFINED,   ///< Undefined
284       Tinyint = NDB_TYPE_TINYINT,       ///< 8 bit. 1 byte signed integer, can be used in array
285       Tinyunsigned = NDB_TYPE_TINYUNSIGNED,  ///< 8 bit. 1 byte unsigned integer, can be used in array
286       Smallint = NDB_TYPE_SMALLINT,      ///< 16 bit. 2 byte signed integer, can be used in array
287       Smallunsigned = NDB_TYPE_SMALLUNSIGNED, ///< 16 bit. 2 byte unsigned integer, can be used in array
288       Mediumint = NDB_TYPE_MEDIUMINT,     ///< 24 bit. 3 byte signed integer, can be used in array
289       Mediumunsigned = NDB_TYPE_MEDIUMUNSIGNED,///< 24 bit. 3 byte unsigned integer, can be used in array
290       Int = NDB_TYPE_INT,           ///< 32 bit. 4 byte signed integer, can be used in array
291       Unsigned = NDB_TYPE_UNSIGNED,      ///< 32 bit. 4 byte unsigned integer, can be used in array
292       Bigint = NDB_TYPE_BIGINT,        ///< 64 bit. 8 byte signed integer, can be used in array
293       Bigunsigned = NDB_TYPE_BIGUNSIGNED,   ///< 64 Bit. 8 byte signed integer, can be used in array
294       Float = NDB_TYPE_FLOAT,         ///< 32-bit float. 4 bytes float, can be used in array
295       Double = NDB_TYPE_DOUBLE,        ///< 64-bit float. 8 byte float, can be used in array
296       Olddecimal = NDB_TYPE_OLDDECIMAL,    ///< MySQL < 5.0 signed decimal,  Precision, Scale
297       Olddecimalunsigned = NDB_TYPE_OLDDECIMALUNSIGNED,
298       Decimal = NDB_TYPE_DECIMAL,    ///< MySQL >= 5.0 signed decimal,  Precision, Scale
299       Decimalunsigned = NDB_TYPE_DECIMALUNSIGNED,
300       Char = NDB_TYPE_CHAR,          ///< Len. A fixed array of 1-byte chars
301       Varchar = NDB_TYPE_VARCHAR,       ///< Length bytes: 1, Max: 255
302       Binary = NDB_TYPE_BINARY,        ///< Len
303       Varbinary = NDB_TYPE_VARBINARY,     ///< Length bytes: 1, Max: 255
304       Datetime = NDB_TYPE_DATETIME,    ///< Precision down to 1 sec (sizeof(Datetime) == 8 bytes )
305       Date = NDB_TYPE_DATE,            ///< Precision down to 1 day(sizeof(Date) == 4 bytes )
306       Blob = NDB_TYPE_BLOB,        ///< Binary large object (see NdbBlob)
307       Text = NDB_TYPE_TEXT,         ///< Text blob
308       Bit = NDB_TYPE_BIT,          ///< Bit, length specifies no of bits
309       Longvarchar = NDB_TYPE_LONGVARCHAR,  ///< Length bytes: 2, little-endian
310       Longvarbinary = NDB_TYPE_LONGVARBINARY, ///< Length bytes: 2, little-endian
311       Time = NDB_TYPE_TIME,        ///< Time without date
312       Year = NDB_TYPE_YEAR,   ///< Year 1901-2155 (1 byte)
313       Timestamp = NDB_TYPE_TIMESTAMP, ///< Unix time
314       /**
315        * Time types in MySQL 5.6 add microsecond fraction.
316        * One should use setPrecision(x) to set number of fractional
317        * digits (x = 0-6, default 0).  Data formats are as in MySQL
318        * and must use correct byte length.  NDB does not check data
319        * itself since any values can be compared as binary strings.
320        */
321       Time2 = NDB_TYPE_TIME2, ///< 3 bytes + 0-3 fraction
322       Datetime2 = NDB_TYPE_DATETIME2, ///< 5 bytes plus 0-3 fraction
323       Timestamp2 = NDB_TYPE_TIMESTAMP2 ///< 4 bytes + 0-3 fraction
324     };
325 
326     /*
327      * Array type specifies internal attribute format.
328      *
329      * - ArrayTypeFixed is stored as fixed number of bytes.  This type
330      *   is fastest to access but can waste space.
331      *
332      * - ArrayTypeVar is stored as variable number of bytes with a fixed
333      *   overhead of 2 bytes.
334      *
335      * Default is ArrayTypeVar for Var* types and ArrayTypeFixed for
336      * others.  The default is normally ok.
337      */
338     enum ArrayType {
339       ArrayTypeFixed = NDB_ARRAYTYPE_FIXED,          // 0 length bytes
340       ArrayTypeShortVar = NDB_ARRAYTYPE_SHORT_VAR,   // 1 length bytes
341       ArrayTypeMediumVar = NDB_ARRAYTYPE_MEDIUM_VAR // 2 length bytes
342     };
343 
344     /*
345      * Storage type specifies whether attribute is stored in memory or
346      * on disk.  Default is memory.  Disk attributes are potentially
347      * much slower to access and cannot be indexed in version 5.1.
348      */
349     enum StorageType {
350       StorageTypeMemory = NDB_STORAGETYPE_MEMORY,
351       StorageTypeDisk = NDB_STORAGETYPE_DISK,
352       StorageTypeDefault = NDB_STORAGETYPE_DEFAULT
353     };
354 
355     /**
356      * @name General
357      * @{
358      */
359 
360     /**
361      * Get name of column
362      * @return  Name of the column
363      */
364     const char* getName() const;
365 
366     /**
367      * Get if the column is nullable or not
368      */
369     bool getNullable() const;
370 
371     /**
372      * Check if column is part of primary key
373      */
374     bool getPrimaryKey() const;
375 
376     /**
377      *  Get number of column (horizontal position within table)
378      */
379     int getColumnNo() const;
380 
381 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
382     int getAttrId() const;
383 #endif
384 
385     /**
386      * Check if column is equal to some other column
387      * @param  column  Column to compare with
388      * @return  true if column is equal to some other column otherwise false.
389      */
390     bool equal(const Column& column) const;
391 
392 
393     /** @} *******************************************************************/
394     /**
395      * @name Get Type Specifiers
396      * @{
397      */
398 
399     /**
400      * Get type of column
401      */
402     Type getType() const;
403 
404     /**
405      * Get precision of column.
406      * @note Only applicable for decimal types
407      * @note Also applicable for Time2 etc in mysql 5.6
408      */
409     int getPrecision() const;
410 
411     /**
412      * Get scale of column.
413      * @note Only applicable for decimal types
414      */
415     int getScale() const;
416 
417     /**
418      * Get length for column
419      * Array length for column or max length for variable length arrays.
420      */
421     int getLength() const;
422 
423     /**
424      * Get size required to store column in NdbRecord layout.
425      */
426     int getSizeInBytesForRecord() const;
427 
428     /**
429      * For Char or Varchar or Text, get MySQL CHARSET_INFO.  This
430      * specifies both character set and collation.  See get_charset()
431      * etc in MySQL.  (The cs is not "const" in MySQL).
432      */
433     CHARSET_INFO* getCharset() const;
434 
435     /**
436      * Returns mysql's internal number for the column's character set.
437      */
438     int getCharsetNumber() const;
439 
440     /**
441      * For blob, get "inline size" i.e. number of initial bytes
442      * to store in table's blob attribute.
443      */
444     int getInlineSize() const;
445 
446     /**
447      * For blob, get "part size" i.e. number of bytes to store in
448      * each tuple of the "blob table".  Can be set to zero to omit parts
449      * and to allow only inline bytes ("tinyblob").
450      */
451     int getPartSize() const;
452 
453     /**
454      * For blob, set or get "stripe size" i.e. number of consecutive
455      * <em>parts</em> to store in each node group.
456      */
457     int getStripeSize() const;
458 
459     /**
460      * Get size of element
461      */
462     int getSize() const;
463 
464     /**
465      * Check if column is part of partition key
466      *
467      * A <em>partition key</em> is a set of attributes which are used
468      * to distribute the tuples onto the NDB nodes.
469      * The partition key uses the NDB Cluster hashing function.
470      *
471      * An example where this is useful is TPC-C where it might be
472      * good to use the warehouse id and district id as the partition key.
473      * This would place all data for a specific district and warehouse
474      * in the same database node.
475      *
476      * Locally in the fragments the full primary key
477      * will still be used with the hashing algorithm.
478      *
479      * @return  true then the column is part of
480      *                 the partition key.
481      */
482     bool getPartitionKey() const;
483 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
getDistributionKey() const484     inline bool getDistributionKey() const { return getPartitionKey(); }
485 #endif
486 
487     ArrayType getArrayType() const;
488     StorageType getStorageType() const;
489 
490     /**
491      * Get if the column is dynamic (NULL values not stored)
492      */
493     bool getDynamic() const;
494 
495     /**
496      * Determine if the column is defined relative to an Index
497      * This affects the meaning of the attrId, column no and primary key,
498      */
499     bool getIndexSourced() const;
500 
501     /** @} *******************************************************************/
502 
503 
504     /**
505      * @name Column creation
506      * @{
507      *
508      * These operations should normally not be performed in an NbdApi program
509      * as results will not be visable in the MySQL Server
510      *
511      */
512 
513     /**
514      * Constructor
515      * @param   name   Name of column
516      */
517     Column(const char * name = "");
518     /**
519      * Copy constructor
520      * @param  column  Column to be copied
521      */
522     Column(const Column& column);
523     ~Column();
524 
525     /**
526      * Set name of column
527      * @param  name  Name of the column
528      */
529     int setName(const char * name);
530 
531     /**
532      * Set whether column is nullable or not
533      */
534     void setNullable(bool);
535 
536     /**
537      * Set that column is part of primary key
538      */
539     void setPrimaryKey(bool);
540 
541     /**
542      * Set type of column
543      * @param  type  Type of column
544      *
545      * @note setType resets <em>all</em> column attributes
546      *       to (type dependent) defaults and should be the first
547      *       method to call.  Default type is Unsigned.
548      */
549     void setType(Type type);
550 
551     /**
552      * Set precision of column.
553      * @note Only applicable for decimal types
554      * @note Also applicable for Time2 etc in mysql 5.6
555      */
556     void setPrecision(int);
557 
558     /**
559      * Set scale of column.
560      * @note Only applicable for decimal types
561      */
562     void setScale(int);
563 
564     /**
565      * Set length for column
566      * Array length for column or max length for variable length arrays.
567      */
568     void setLength(int length);
569 
570     /**
571      * For Char or Varchar or Text, get MySQL CHARSET_INFO.  This
572      * specifies both character set and collation.  See get_charset()
573      * etc in MySQL.  (The cs is not "const" in MySQL).
574      */
575     void setCharset(CHARSET_INFO* cs);
576 
577     /**
578      * For blob, set "inline size" i.e. number of initial bytes
579      * to store in table's blob attribute.  This part is normally in
580      * main memory.  It can not currently be indexed.
581      */
582     void setInlineSize(int size);
583 
584     /**
585      * For blob, set "part size" i.e. number of bytes to store in
586      * each tuple of the "blob table".  Can be set to zero to omit parts
587      * and to allow only inline bytes ("tinyblob").
588      */
589     void setPartSize(int size);
590 
591     /**
592      * For blob, set "stripe size" i.e. number of consecutive
593      * <em>parts</em> to store in a fragment, before moving to
594      * another (random) fragment.
595      *
596      * Striping may improve performance for large blobs
597      * since blob part operations are done in parallel.
598      * Optimal stripe size depends on the transport e.g. tcp/ip.
599      *
600      * Example: Given part size 2048 bytes, set stripe size 8.
601      * This assigns i/o in 16k chunks to each fragment.
602      *
603      * Blobs V1 required non-zero stripe size.  Blobs V2
604      * (created in version >= 5.1.x) have following behaviour:
605      *
606      * Default stripe size is zero, which means no striping and
607      * also that blob part data is stored in the same node group
608      * as the primary table row.  This is done by giving blob parts
609      * table same partition key as the primary table.
610      */
611     void setStripeSize(int size);
612 
613     /**
614      * Set partition key
615      * @see getPartitionKey
616      *
617      * @param  enable  If set to true, then the column will be part of
618      *                 the partition key.
619      */
620     void setPartitionKey(bool enable);
621 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
setDistributionKey(bool enable)622     inline void setDistributionKey(bool enable)
623     { setPartitionKey(enable); }
624 #endif
625 
626     void setArrayType(ArrayType type);
627     void setStorageType(StorageType type);
628 
629     /**
630      * Set whether column is dynamic.
631      */
632     void setDynamic(bool);
633 
634     /** @} *******************************************************************/
635 
636 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
637     int setDefaultValue(const char*);
638 #endif
639     /* setDefaultValue
640      * Set buf to NULL for no default value, or null default value for
641      * NULLABLE column, otherwise set buf to pointer to default value.
642      * The len parameter is the number of significant bytes of default
643      * value supplied, which is the type size for fixed size types.
644      * For variable length types, the leading 1 or 2 bytes pointed to
645      * by buf also contain length information as normal for the type.
646      */
647     int setDefaultValue(const void* buf, unsigned int len);
648 
649     /* getDefaultValue
650      * Get the default value data for this column.
651      * Optional int len* will be updated with the significant length
652      * of the default value, or set to 0 for NULL or no default.
653      */
654     const void* getDefaultValue(unsigned int* len = 0) const;
655 
656 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
657     const Table * getBlobTable() const;
658 
659     void setAutoIncrement(bool);
660     bool getAutoIncrement() const;
661     void setAutoIncrementInitialValue(Uint64 val);
662 
663     static const Column * FRAGMENT;
664     static const Column * FRAGMENT_FIXED_MEMORY;
665     static const Column * FRAGMENT_VARSIZED_MEMORY;
666     static const Column * ROW_COUNT;
667     static const Column * COMMIT_COUNT;
668     static const Column * ROW_SIZE;
669     static const Column * RANGE_NO;
670     static const Column * DISK_REF;
671     static const Column * RECORDS_IN_RANGE;
672     static const Column * ROWID;
673     static const Column * ROW_GCI;
674     static const Column * ROW_GCI64;
675     static const Column * ROW_AUTHOR;
676     static const Column * ANY_VALUE;
677     static const Column * COPY_ROWID;
678     static const Column * LOCK_REF;
679     static const Column * OP_ID;
680     static const Column * OPTIMIZE;
681     static const Column * FRAGMENT_EXTENT_SPACE;
682     static const Column * FRAGMENT_FREE_EXTENT_SPACE;
683 
684     int getSizeInBytes() const;
685 
686     int getBlobVersion() const; // NDB_BLOB_V1 or NDB_BLOB_V2
687     void setBlobVersion(int blobVersion); // default NDB_BLOB_V2
688 
689     /**
690      * 0 = yes
691      * -1 = no
692      */
693     int isBindable(const Column&) const;
694 #endif
695 
696   private:
697 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
698     friend class NdbRecAttr;
699     friend class NdbColumnImpl;
700 #endif
701     class NdbColumnImpl & m_impl;
702     Column(NdbColumnImpl&);
703     Column& operator=(const Column&);
704   };
705 
706 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
707   /**
708    * ???
709    */
710   typedef Column Attribute;
711 #endif
712 
713   /**
714    * @brief Represents a table in NDB Cluster
715    *
716    * <em>TableSize</em><br>
717    * When calculating the data storage one should add the size of all
718    * attributes (each attributeconsumes at least 4 bytes) and also an overhead
719    * of 12 byte. Variable size attributes (not supported yet) will have a
720    * size of 12 bytes plus the actual data storage parts where there is an
721    * additional overhead based on the size of the variable part.<br>
722    * An example table with 5 attributes:
723    * one 64 bit attribute, one 32 bit attribute,
724    * two 16 bit attributes and one array of 64 8 bits.
725    * This table will consume
726    * 12 (overhead) + 8 + 4 + 2*4 (4 is minimum) + 64 = 96 bytes per record.
727    * Additionally an overhead of about 2 % as page headers and waste should
728    * be allocated. Thus, 1 million records should consume 96 MBytes
729    * plus the overhead 2 MByte and rounded up to 100 000 kBytes.<br>
730    *
731    */
732   class Table : public Object {
733   public:
734     /*
735      * Single user mode specifies access rights to table during single user mode
736      */
737     enum SingleUserMode {
738       SingleUserModeLocked    = NDB_SUM_LOCKED,
739       SingleUserModeReadOnly  = NDB_SUM_READONLY,
740       SingleUserModeReadWrite = NDB_SUM_READ_WRITE
741     };
742 
743     /**
744      * @name General
745      * @{
746      */
747 
748     /**
749      * Get table name
750      */
751     const char * getName() const;
752 
753     /**
754      * Get table id
755      */
756     int getTableId() const;
757 
758     /**
759      * Get column definition via name.
760      * @return null if none existing name
761      */
762     const Column* getColumn(const char * name) const;
763 
764     /**
765      * Get column definition via index in table.
766      * @return null if none existing name
767      */
768     Column* getColumn(const int attributeId);
769 
770     /**
771      * Get column definition via name.
772      * @return null if none existing name
773      */
774     Column* getColumn(const char * name);
775 
776     /**
777      * Get column definition via index in table.
778      * @return null if none existing name
779      */
780     const Column* getColumn(const int attributeId) const;
781 
782     /** @} *******************************************************************/
783     /**
784      * @name Storage
785      * @{
786      */
787 
788     /**
789      * If set to false, then the table is a temporary
790      * table and is not logged to disk.
791      *
792      * In case of a system restart the table will still
793      * be defined and exist but will be empty.
794      * Thus no checkpointing and no logging is performed on the table.
795      *
796      * The default value is true and indicates a normal table
797      * with full checkpointing and logging activated.
798      */
799     bool getLogging() const;
800 
801     /**
802      * Get fragmentation type
803      */
804     FragmentType getFragmentType() const;
805 
806     /**
807      * Get KValue (Hash parameter.)
808      * Only allowed value is 6.
809      * Later implementations might add flexibility in this parameter.
810      */
811     int getKValue() const;
812 
813     /**
814      * Get MinLoadFactor  (Hash parameter.)
815      * This value specifies the load factor when starting to shrink
816      * the hash table.
817      * It must be smaller than MaxLoadFactor.
818      * Both these factors are given in percentage.
819      */
820     int getMinLoadFactor() const;
821 
822     /**
823      * Get MaxLoadFactor  (Hash parameter.)
824      * This value specifies the load factor when starting to split
825      * the containers in the local hash tables.
826      * 100 is the maximum which will optimize memory usage.
827      * A lower figure will store less information in each container and thus
828      * find the key faster but consume more memory.
829      */
830     int getMaxLoadFactor() const;
831 
832     /** @} *******************************************************************/
833     /**
834      * @name Other
835      * @{
836      */
837 
838     /**
839      * Get number of columns in the table
840      */
841     int getNoOfColumns() const;
842 
843     /**
844      * Get number of auto_increment columns in the table
845      */
846     int getNoOfAutoIncrementColumns() const;
847 
848     /**
849      * Get number of primary keys in the table
850      */
851     int getNoOfPrimaryKeys() const;
852 
853     /**
854      * Get name of primary key
855      */
856     const char* getPrimaryKey(int no) const;
857 
858     /**
859      * Check if table is equal to some other table
860      */
861     bool equal(const Table&) const;
862 
863     /**
864      * Get frm file stored with this table
865      */
866     const void* getFrmData() const;
867     Uint32 getFrmLength() const;
868 
869     /**
870      * Get default NdbRecord object for this table
871      * This NdbRecord object becomes invalid at the same time as
872      * the table object - when the ndb_cluster_connection is closed.
873      */
874     const NdbRecord* getDefaultRecord() const;
875 
876     /** @} *******************************************************************/
877 
878     /**
879      * @name Table creation
880      * @{
881      *
882      * These methods should normally not be used in an application as
883      * the result is not accessible from the MySQL Server
884      *
885      */
886 
887     /**
888      * Constructor
889      * @param  name   Name of table
890      */
891     Table(const char * name = "");
892 
893     /**
894      * Copy constructor
895      * @param  table  Table to be copied
896      */
897     Table(const Table& table);
898     virtual ~Table();
899 
900     /**
901      * Assignment operator, deep copy
902      * @param  table  Table to be copied
903      */
904     Table& operator=(const Table& table);
905 
906     /**
907      * Name of table
908      * @param  name  Name of table
909      */
910     int setName(const char * name);
911 
912     /**
913      * Add a column definition to a table
914      * @note creates a copy
915      */
916     int addColumn(const Column &);
917 
918     /**
919      * @see NdbDictionary::Table::getLogging.
920      */
921     void setLogging(bool);
922 
923     /**
924      * Set/Get Linear Hash Flag
925      */
926     void setLinearFlag(Uint32 flag);
927     bool getLinearFlag() const;
928 
929     /**
930      * Set fragment count
931      *   also sets PartitionBalance_Specific
932      */
933     void setFragmentCount(Uint32);
934 
935     /**
936      * Get fragment count
937      */
938     Uint32 getFragmentCount() const;
939 
940     /**
941      * Get real fragment count, no setter, is set by NDB, always
942      * equal to getFragmentCount except for fully replicated tables.
943      */
944     Uint32 getPartitionCount() const;
945 
946     /**
947      * Set fragment count using cluster agnostics defines
948      */
949     void setPartitionBalance(NdbDictionary::Object::PartitionBalance);
950 
951     /**
952      * Get partition balance
953      */
954     NdbDictionary::Object::PartitionBalance getPartitionBalance() const;
955     static NdbDictionary::Object::PartitionBalance getPartitionBalance(const char str[]);
956 
957     /**
958      * Get partition balance string
959      */
960     const char* getPartitionBalanceString() const;
961     static const char* getPartitionBalanceString(PartitionBalance partition_balance);
962 
963     /**
964      * Set fragmentation type
965      */
966     void setFragmentType(FragmentType);
967 
968     /**
969      * Set KValue (Hash parameter.)
970      * Only allowed value is 6.
971      * Later implementations might add flexibility in this parameter.
972      */
973     void setKValue(int kValue);
974 
975     /**
976      * Set MinLoadFactor  (Hash parameter.)
977      * This value specifies the load factor when starting to shrink
978      * the hash table.
979      * It must be smaller than MaxLoadFactor.
980      * Both these factors are given in percentage.
981      */
982     void setMinLoadFactor(int);
983 
984     /**
985      * Set MaxLoadFactor  (Hash parameter.)
986      * This value specifies the load factor when starting to split
987      * the containers in the local hash tables.
988      * 100 is the maximum which will optimize memory usage.
989      * A lower figure will store less information in each container and thus
990      * find the key faster but consume more memory.
991      */
992     void setMaxLoadFactor(int);
993 
994     int setTablespaceName(const char * name);
995     const char * getTablespaceName() const;
996     int setTablespace(const class Tablespace &);
997     bool getTablespace(Uint32 *id= 0, Uint32 *version= 0) const;
998 
999     bool getHashMap(Uint32* id = 0, Uint32* version = 0) const;
1000     int setHashMap(const class HashMap &);
1001 
1002     /**
1003      * Get object status
1004      */
1005     virtual Object::Status getObjectStatus() const;
1006     void setStatusInvalid() const;
1007 
1008     /**
1009      * Get object version
1010      */
1011     virtual int getObjectVersion() const;
1012 
1013     /**
1014      * Set/Get indicator if default number of partitions is used in table.
1015      */
1016     void setDefaultNoPartitionsFlag(Uint32 indicator);
1017     Uint32 getDefaultNoPartitionsFlag() const;
1018 
1019     /**
1020      * Get object id
1021      */
1022     virtual int getObjectId() const;
1023 
1024     /**
1025      * Set frm file to store with this table
1026      */
1027     int setFrm(const void* data, Uint32 len);
1028 
1029     /**
1030       Set unpacked extra metadata for this table
1031 
1032       NOTE! Function will pack the data into buffer
1033       of Table object without modifying the "data".
1034 
1035       NOTE! Normally version 1 means that extra metadata contains
1036       a frm blob and version 2 means serialized dictionary information.
1037       This is however application specific how to use these version
1038       numbers.
1039 
1040       returns 0 for success and otherwise error code indicating
1041       type of error, for caller error handling
1042     */
1043     int setExtraMetadata(Uint32 version,
1044                          const void* data, Uint32 data_length);
1045 
1046     /**
1047       Get unpacked extra metadata for this table
1048 
1049       NOTE! Function will return memory that must be released
1050       with free()
1051 
1052       returns 0 for success and otherwise error code
1053     */
1054     int getExtraMetadata(Uint32& version,
1055                          void** data, Uint32* data_length) const;
1056 
1057 
1058     /**
1059      * Set fragmentation, maps each fragment to specific nodegroup.
1060      *   One Uint32 per fragment, containing nodegroup of fragment
1061      *   nodegroups[0] - correspondce to fragment 0
1062      *
1063      * Only used if FragmentType is one of DistrKeyHash, DistrKeyLin, or,
1064      * UserDefined.
1065      *
1066      * For other FragmentType it should be called with nodegroups NULL and
1067      * cnt 0.
1068      */
1069     int setFragmentData(const Uint32 * nodegroups, Uint32 cnt);
1070 
1071     /**
1072      * Get Fragment Data (array of node groups)
1073      */
1074     const Uint32 *getFragmentData() const;
1075     Uint32 getFragmentDataLen() const;
1076 
1077     /**
1078      * Set array of information mapping range values and list values
1079      * to fragments.
1080      *
1081      * For range, this is a sorted list of range values
1082      * For list, this is a list of pairs { value, partition }
1083      */
1084     int setRangeListData(const Int32* data, Uint32 cnt);
1085 
1086     /**
1087      * Get Range or List Array (value, partition)
1088      */
1089     const Int32 *getRangeListData() const;
1090     Uint32 getRangeListDataLen() const;
1091 
1092     /**
1093      * Get list of nodes storing given fragment, primary
1094      * is normally entry 0
1095      * Returns : 0 for error, > 0 for fragment count
1096      * If fragment count is > arraySize param, only arraySize
1097      * entries are written.
1098      */
1099     Uint32 getFragmentNodes(Uint32 fragmentId,
1100                             Uint32* nodeIdArrayPtr,
1101                             Uint32 arraySize) const;
1102 
1103     /**
1104      * Set/Get Maximum number of rows in table (only used to calculate
1105      * number of partitions).
1106      */
1107     void setMaxRows(Uint64 maxRows);
1108     Uint64 getMaxRows() const;
1109 
1110     /**
1111      * Set/Get Minimum number of rows in table (only used to calculate
1112      * number of partitions).
1113      */
1114     void setMinRows(Uint64 minRows);
1115     Uint64 getMinRows() const;
1116 
1117     /**
1118      * Set/Get SingleUserMode
1119      */
1120     void setSingleUserMode(enum SingleUserMode);
1121     enum SingleUserMode getSingleUserMode() const;
1122 
1123 
1124     /** @} *******************************************************************/
1125 
1126     /**
1127      *
1128      */
1129     void setRowGCIIndicator(bool value);
1130     bool getRowGCIIndicator() const;
1131 
1132     void setRowChecksumIndicator(bool value);
1133     bool getRowChecksumIndicator() const;
1134 
1135     void setReadBackupFlag(bool value);
1136     bool getReadBackupFlag() const;
1137 
1138 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1139     const char *getMysqlName() const;
1140 
setStoredTable(bool x)1141     void setStoredTable(bool x) { setLogging(x); }
getStoredTable() const1142     bool getStoredTable() const { return getLogging(); }
1143 
1144     int getRowSizeInBytes() const ;
1145     int createTableInDb(Ndb*, bool existingEqualIsOk = true) const ;
1146 
1147     int getReplicaCount() const ;
1148 
1149     bool getTemporary() const;
1150     void setTemporary(bool);
1151 
1152     /**
1153      * Only table with varpart do support online add column
1154      *   Add property so that table wo/ varsize column(s) still
1155      *   allocates varpart-ref, so that later online add column is possible
1156      */
1157     bool getForceVarPart() const;
1158     void setForceVarPart(bool);
1159 
1160     /**
1161      * Check if any of column in bitmaps are disk columns
1162      *   returns bitmap of different columns
1163      *     bit 0 = atleast 1 pk column is set
1164      *     bit 1 = atleast 1 disk column set
1165      *     bit 2 = atleast 1 non disk column set
1166      *   passing NULL pointer will equal to bitmap with all columns set
1167      */
1168     int checkColumns(const Uint32* bitmap, unsigned len_in_bytes) const;
1169 
1170     /**
1171      * Set tableId,tableVersion on a table...
1172      *   this is a "work-around" since createIndex can't (currently)
1173      *   accept an ObjectId instead of table-object in createIndex
1174      *   this as way way too much stuff is pushed into NdbDictInterface
1175      */
1176     void assignObjId(const ObjectId &);
1177 
1178     /**
1179      * set/get table-storage-method
1180      */
1181     void setStorageType(Column::StorageType);
1182     Column::StorageType getStorageType() const;
1183 
1184     /**
1185      * Get/set extra GCI bits (max 31)
1186      */
1187     void setExtraRowGciBits(Uint32);
1188     Uint32 getExtraRowGciBits() const;
1189 
1190     /**
1191      * Get/set extra row author bits (max 31)
1192      */
1193     void setExtraRowAuthorBits(Uint32);
1194     Uint32 getExtraRowAuthorBits() const;
1195 
1196     void setFullyReplicated(bool val);
1197     bool getFullyReplicated() const;
1198 
1199     void setRowChecksum(Uint32);
1200     Uint32 getRowChecksum();
1201 #endif
1202 
1203     // these 2 are not de-doxygenated
1204 
1205     /**
1206      * This method is not needed in normal usage.
1207      *
1208      * Compute aggregate data on table being defined.  Required for
1209      * aggregate methods such as getNoOfPrimaryKeys() to work before
1210      * table has been created and retrieved via getTable().
1211      *
1212      * May adjust some column flags.  If no PK is so far marked as
1213      * distribution key then all PK's will be marked.
1214      *
1215      * Returns 0 on success.  Returns -1 and sets error if an
1216      * inconsistency is detected.
1217      */
1218     int aggregate(struct NdbError& error);
1219 
1220     /**
1221      * This method is not needed in normal usage.
1222      *
1223      * Validate new table definition before create.  Does aggregate()
1224      * and additional checks.  There may still be errors which are
1225      * detected only by NDB kernel at create table.
1226      *
1227      * Create table and retrieve table do validate() automatically.
1228      *
1229      * Returns 0 on success.  Returns -1 and sets error if an
1230      * inconsistency is detected.
1231      */
1232     int validate(struct NdbError& error);
1233 
1234     /**
1235      * Return partitionId given a hashvalue
1236      *   Note, if table is not retreived (e.i using getTable) result
1237      *   will most likely be wrong
1238      */
1239     Uint32 getPartitionId(Uint32 hashvalue) const ;
1240 
1241     /*
1242      * Return TRUE if any of the columns in the table have a
1243      * non NULL default value defined
1244      */
1245     bool hasDefaultValues() const;
1246 
1247   private:
1248 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1249     friend class Ndb;
1250     friend class NdbDictionaryImpl;
1251     friend class NdbTableImpl;
1252     friend class NdbEventOperationImpl;
1253 #endif
1254     class NdbTableImpl & m_impl;
1255     Table(NdbTableImpl&);
1256   };
1257 
1258   /**
1259    * @class Index
1260    * @brief Represents an index in an NDB Cluster
1261    */
1262   class Index : public Object {
1263   public:
1264 
1265     /**
1266      * @name Getting Index properties
1267      * @{
1268      */
1269 
1270     /**
1271      * Get the name of an index
1272      */
1273     const char * getName() const;
1274 
1275     /**
1276      * Get the name of the underlying table being indexed
1277      */
1278     const char * getTable() const;
1279 
1280     /**
1281      * Get the number of columns in the index
1282      */
1283     unsigned getNoOfColumns() const;
1284 
1285 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
1286     /**
1287      * Get the number of columns in the index
1288      * Deprecated, use getNoOfColumns instead.
1289      */
1290     int getNoOfIndexColumns() const;
1291 #endif
1292 
1293     /**
1294      * Get a specific column in the index
1295      */
1296     const Column * getColumn(unsigned no) const ;
1297 
1298 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
1299     /**
1300      * Get a specific column name in the index
1301      * Deprecated, use getColumn instead.
1302      */
1303     const char * getIndexColumn(int no) const ;
1304 #endif
1305 
1306     /**
1307      * Represents type of index
1308      */
1309     enum Type {
1310       Undefined = 0,          ///< Undefined object type (initial value)
1311       UniqueHashIndex = 3,    ///< Unique un-ordered hash index
1312                               ///< (only one currently supported)
1313       OrderedIndex = 6        ///< Non-unique ordered index
1314     };
1315 
1316     /**
1317      * Get index type of the index
1318      */
1319     Type getType() const;
1320 
1321     /**
1322      * Check if index is set to be stored on disk
1323      *
1324      * @return if true then logging is enabled
1325      *
1326      * @note Non-logged indexes are rebuilt at system restart.
1327      * @note Ordered index does not currently support logging.
1328      */
1329     bool getLogging() const;
1330 
1331     /**
1332      * Get object status
1333      */
1334     virtual Object::Status getObjectStatus() const;
1335 
1336     /**
1337      * Get object version
1338      */
1339     virtual int getObjectVersion() const;
1340 
1341     /**
1342      * Get object id
1343      */
1344     virtual int getObjectId() const;
1345 
1346     /**
1347      * Get default NdbRecord object for this index
1348      * This NdbRecord object becomes invalid at the same time as
1349      * the index object does - when the ndb_cluster_connection
1350      * is closed.
1351      */
1352     const NdbRecord* getDefaultRecord() const;
1353 
1354     /** @} *******************************************************************/
1355 
1356     /**
1357      * @name Index creation
1358      * @{
1359      *
1360      * These methods should normally not be used in an application as
1361      * the result will not be visible from the MySQL Server
1362      *
1363      */
1364 
1365     /**
1366      *  Constructor
1367      *  @param  name  Name of index
1368      */
1369     Index(const char * name = "");
1370     virtual ~Index();
1371 
1372     /**
1373      * Set the name of an index
1374      */
1375     int setName(const char * name);
1376 
1377     /**
1378      * Define the name of the table to be indexed
1379      */
1380     int setTable(const char * name);
1381 
1382     /**
1383      * Add a column to the index definition
1384      * Note that the order of columns will be in
1385      * the order they are added (only matters for ordered indexes).
1386      */
1387     int addColumn(const Column & c);
1388 
1389     /**
1390      * Add a column name to the index definition
1391      * Note that the order of indexes will be in
1392      * the order they are added (only matters for ordered indexes).
1393      */
1394     int addColumnName(const char * name);
1395 
1396 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
1397     /**
1398      * Add a column name to the index definition
1399      * Note that the order of indexes will be in
1400      * the order they are added (only matters for ordered indexes).
1401      * Deprecated, use addColumnName instead.
1402      */
1403     int addIndexColumn(const char * name);
1404 #endif
1405 
1406     /**
1407      * Add several column names to the index definition
1408      * Note that the order of indexes will be in
1409      * the order they are added (only matters for ordered indexes).
1410      */
1411     int  addColumnNames(unsigned noOfNames, const char ** names);
1412 
1413 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
1414     /**
1415      * Add several column names to the index definition
1416      * Note that the order of indexes will be in
1417      * the order they are added (only matters for ordered indexes).
1418      * Deprecated, use addColumnNames instead.
1419      */
1420     int addIndexColumns(int noOfNames, const char ** names);
1421 #endif
1422 
1423     /**
1424      * Set index type of the index
1425      */
1426     void setType(Type type);
1427 
1428     /**
1429      * Enable/Disable index storage on disk
1430      *
1431      * @param enable  If enable is set to true, then logging becomes enabled
1432      *
1433      * @see NdbDictionary::Index::getLogging
1434      */
1435     void setLogging(bool enable);
1436 
1437 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
setStoredIndex(bool x)1438     void setStoredIndex(bool x) { setLogging(x); }
getStoredIndex() const1439     bool getStoredIndex() const { return getLogging(); }
1440 
1441     bool getTemporary() const;
1442     void setTemporary(bool);
1443 #endif
1444 
1445     /** @} *******************************************************************/
1446 
1447   private:
1448 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1449     friend class NdbIndexImpl;
1450     friend class NdbIndexStat;
1451 #endif
1452     class NdbIndexImpl & m_impl;
1453     Index(NdbIndexImpl&);
1454   };
1455 
1456   /**
1457    * @brief Represents a Table Optimization Handle
1458    * Passed as argument to optimizeTable
1459    */
1460   class OptimizeTableHandle {
1461   public:
1462     /**
1463      * Supported operations for OptimizeTableHandle
1464      */
1465     OptimizeTableHandle();
1466     ~OptimizeTableHandle();
1467     /**
1468      * Optimize one more batch of records
1469      * @return 1 for more records left to optimize,
1470      *         0 when completed
1471      *         -1 encountered some error
1472      */
1473     int next();
1474     /**
1475      * Close the handle object
1476      * @return 0 when completed
1477      *         -1 encountered some error
1478      */
1479     int close();
1480   private:
1481 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1482     friend class NdbOptimizeTableHandleImpl;
1483     friend class NdbOptimizeIndexHandleImpl;
1484     friend class NdbDicitionaryImpl;
1485 #endif
1486     class NdbOptimizeTableHandleImpl & m_impl;
1487     OptimizeTableHandle(NdbOptimizeTableHandleImpl &);
1488   };
1489 
1490   /**
1491    * @brief Represents a Index Optimization Handle
1492    * passed as argument to optimizeIndex
1493    */
1494   class OptimizeIndexHandle {
1495   public:
1496     /**
1497      * Supported operations for OptimizeIndexHandle
1498      */
1499     OptimizeIndexHandle();
1500     ~OptimizeIndexHandle();
1501     /**
1502      * Optimize one more batch of records
1503      * @return 1 for more records left to optimize,
1504      *         0 when completed
1505      *         -1 encountered some error
1506      */
1507     int next();
1508     /**
1509      * Close the handle object
1510      * @return 0 when completed
1511      *         -1 encountered some error
1512      */
1513     int close();
1514   private:
1515 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1516     friend class NdbOptimizeIndexHandleImpl;
1517     friend class NdbDicitionaryImpl;
1518 #endif
1519     class NdbOptimizeIndexHandleImpl & m_impl;
1520     OptimizeIndexHandle(NdbOptimizeIndexHandleImpl &);
1521   };
1522 
1523   /**
1524    * @brief Represents an Event in NDB Cluster
1525    *
1526    */
1527   class Event : public Object  {
1528   public:
1529     /**
1530      * Specifies the type of database operations an Event listens to
1531      */
1532 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1533     /** TableEvent must match 1 << TriggerEvent */
1534 #endif
1535     enum TableEvent {
1536       TE_INSERT      =1<<0, ///< Insert event on table
1537       TE_DELETE      =1<<1, ///< Delete event on table
1538       TE_UPDATE      =1<<2, ///< Update event on table
1539 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1540       TE_SCAN        =1<<3, ///< Scan event on table
1541       TE_FIRST_NON_DATA_EVENT =1<<4,
1542 #endif
1543       TE_DROP        =1<<4, ///< Drop of table
1544       TE_ALTER       =1<<5, ///< Alter of table
1545       TE_CREATE      =1<<6, ///< Create of table
1546       TE_GCP_COMPLETE=1<<7, ///< GCP is complete
1547       TE_CLUSTER_FAILURE=1<<8, ///< Cluster is unavailable
1548       TE_STOP        =1<<9, ///< Stop of event operation
1549       TE_NODE_FAILURE=1<<10, ///< Node failed
1550       TE_SUBSCRIBE   =1<<11, ///< Node subscribes
1551       TE_UNSUBSCRIBE =1<<12, ///< Node unsubscribes
1552       TE_EMPTY         =1<<15, ///< Empty epoch from data nodes
1553       TE_INCONSISTENT  =1<<21, ///< MISSING_DATA (buffer overflow) at data node
1554       TE_OUT_OF_MEMORY =1<<22, ///< Buffer overflow in event buffer
1555       TE_ALL=0xFFFF         ///< Any/all event on table (not relevant when
1556                             ///< events are received)
1557     };
1558 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1559     enum _TableEvent {
1560       _TE_INSERT=0,
1561       _TE_DELETE=1,
1562       _TE_UPDATE=2,
1563       _TE_SCAN=3,
1564       _TE_FIRST_NON_DATA_EVENT=4,
1565       _TE_DROP=4,
1566       _TE_ALTER=5,
1567       _TE_CREATE=6,
1568       _TE_GCP_COMPLETE=7,
1569       _TE_CLUSTER_FAILURE=8,
1570       _TE_STOP=9,
1571       _TE_NODE_FAILURE=10,
1572       _TE_SUBSCRIBE=11,
1573       _TE_UNSUBSCRIBE=12,
1574       _TE_NUL=13, // internal (e.g. INS o DEL within same GCI)
1575       _TE_ACTIVE=14, // internal (node becomes active)
1576       _TE_EMPTY=15,
1577       _TE_INCONSISTENT=21,
1578       _TE_OUT_OF_MEMORY=22
1579     };
1580 #endif
1581     /**
1582      *  Specifies the durability of an event
1583      * (future version may supply other types)
1584      */
1585     enum EventDurability {
1586       ED_UNDEFINED
1587 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1588       = 0
1589 #endif
1590 #if 0 // not supported
1591       ,ED_SESSION = 1,
1592       // Only this API can use it
1593       // and it's deleted after api has disconnected or ndb has restarted
1594 
1595       ED_TEMPORARY = 2
1596       // All API's can use it,
1597       // But's its removed when ndb is restarted
1598 #endif
1599       ,ED_PERMANENT    ///< All API's can use it.
1600                        ///< It's still defined after a cluster system restart
1601 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1602       = 3
1603 #endif
1604     };
1605 
1606     /**
1607      * Specifies reporting options for table events
1608      */
1609     enum EventReport {
1610       ER_UPDATED = 0,
1611       ER_ALL = 1, // except not-updated blob inlines
1612       ER_SUBSCRIBE = 2,
1613       ER_DDL = 4
1614     };
1615 
1616     /**
1617      *  Constructor
1618      *  @param  name  Name of event
1619      */
1620     Event(const char *name);
1621     /**
1622      *  Constructor
1623      *  @param  name  Name of event
1624      *  @param  table Reference retrieved from NdbDictionary
1625      */
1626     Event(const char *name, const NdbDictionary::Table& table);
1627     virtual ~Event();
1628     /**
1629      * Set unique identifier for the event
1630      */
1631     int setName(const char *name);
1632     /**
1633      * Get unique identifier for the event
1634      */
1635     const char *getName() const;
1636     /**
1637      * Get table that the event is defined on
1638      *
1639      * @return pointer to table or NULL if no table has been defined
1640      */
1641     const NdbDictionary::Table * getTable() const;
1642     /**
1643      * Define table on which events should be detected
1644      *
1645      * @note calling this method will default to detection
1646      *       of events on all columns. Calling subsequent
1647      *       addEventColumn calls will override this.
1648      *
1649      * @param table reference retrieved from NdbDictionary
1650      */
1651     void setTable(const NdbDictionary::Table& table);
1652     /**
1653      * Set table for which events should be detected
1654      *
1655      * @note preferred way is using setTable(const NdbDictionary::Table&)
1656      *       or constructor with table object parameter
1657      */
1658     int setTable(const NdbDictionary::Table *table);
1659     int setTable(const char *tableName);
1660     /**
1661      * Get table name for events
1662      *
1663      * @return table name
1664      */
1665     const char* getTableName() const;
1666     /**
1667      * Add type of event that should be detected
1668      */
1669     void addTableEvent(const TableEvent te);
1670     /**
1671      * Check if a specific table event will be detected
1672      */
1673     bool getTableEvent(const TableEvent te) const;
1674     /**
1675      * Set durability of the event
1676      */
1677     void setDurability(EventDurability);
1678     /**
1679      * Get durability of the event
1680      */
1681     EventDurability getDurability() const;
1682     /**
1683      * Set report option of the event
1684      */
1685     void setReport(EventReport);
1686     /**
1687      * Get report option of the event
1688      */
1689     EventReport getReport() const;
1690 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1691     void addColumn(const Column &c);
1692 #endif
1693     /**
1694      * Add a column on which events should be detected
1695      *
1696      * @param attrId Column id
1697      *
1698      * @note errors will mot be detected until createEvent() is called
1699      */
1700     void addEventColumn(unsigned attrId);
1701     /**
1702      * Add a column on which events should be detected
1703      *
1704      * @param columnName Column name
1705      *
1706      * @note errors will not be detected until createEvent() is called
1707      */
1708     void addEventColumn(const char * columnName);
1709     /**
1710      * Add several columns on which events should be detected
1711      *
1712      * @param n Number of columns
1713      * @param columnNames Column names
1714      *
1715      * @note errors will mot be detected until
1716      *       NdbDictionary::Dictionary::createEvent() is called
1717      */
1718     void addEventColumns(int n, const char ** columnNames);
1719 
1720     /**
1721      * Get no of columns defined in an Event
1722      *
1723      * @return Number of columns, -1 on error
1724      */
1725     int getNoOfEventColumns() const;
1726 
1727     /**
1728      * Get a specific column in the event
1729      */
1730     const Column * getEventColumn(unsigned no) const;
1731 
1732     /**
1733      * The merge events flag is false by default.  Setting it true
1734      * implies that events are merged in following ways:
1735      *
1736      * - for given NdbEventOperation associated with this event,
1737      *   events on same PK within same GCI are merged into single event
1738      *
1739      * - a blob table event is created for each blob attribute
1740      *   and blob events are handled as part of main table events
1741      *
1742      * - blob post/pre data from the blob part events can be read
1743      *   via NdbBlob methods as a single value
1744      *
1745      * NOTE: Currently this flag is not inherited by NdbEventOperation
1746      * and must be set on NdbEventOperation explicitly.
1747      */
1748     void mergeEvents(bool flag);
1749 
1750     /**
1751      * Get object status
1752      */
1753     virtual Object::Status getObjectStatus() const;
1754 
1755     /**
1756      * Get object version
1757      */
1758     virtual int getObjectVersion() const;
1759 
1760     /**
1761      * Get object id
1762      */
1763     virtual int getObjectId() const;
1764 
1765 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1766     void print();
1767 #endif
1768 
1769   private:
1770 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1771     friend class NdbEventImpl;
1772     friend class NdbEventOperationImpl;
1773 #endif
1774     class NdbEventImpl & m_impl;
1775     Event(NdbEventImpl&);
1776   };
1777 
1778   /* Flags for createRecord(). */
1779   enum NdbRecordFlags {
1780     /*
1781       Use special mysqld varchar format in index keys, used only from
1782       inside mysqld.
1783     */
1784     RecMysqldShrinkVarchar= 0x1,
1785     /* Use the mysqld record format for bitfields, only used inside mysqld. */
1786     RecMysqldBitfield= 0x2,
1787     /* Use the column specific flags from RecordSpecification. */
1788     RecPerColumnFlags= 0x4
1789   };
1790   struct RecordSpecification {
1791     /*
1792       Size of the RecordSpecification structure.
1793     */
sizeNdbDictionary::RecordSpecification1794     static inline Uint32 size()
1795     {
1796         return sizeof(RecordSpecification);
1797     }
1798 
1799     /*
1800       Column described by this entry (the column maximum size defines field
1801       size in row).
1802       Note that even when creating an NdbRecord for an index, the column
1803       pointers must be to columns obtained from the underlying table, not
1804       from the index itself.
1805       Note that pseudo columns cannot be used as part of a RecordSpecification.
1806       To read pesudo column values, use the extra get value and set value
1807       APIs.
1808     */
1809     const Column *column;
1810     /*
1811       Offset of data from start of a row.
1812 
1813       For reading blobs, the blob handle (NdbBlob *) will be written into the
1814       result row when the operation is created, not the actual blob data.
1815       So at least sizeof(NdbBlob *) must be available in the row.  Other
1816       operations do not write the blob handle into the row.
1817       In any case, a blob handle can always be obtained with a call to
1818       NdbOperation/NdbScanOperation::getBlobHandle().
1819     */
1820     Uint32 offset;
1821     /*
1822       Offset from start of row of byte containing NULL bit.
1823       Not used for columns that are not NULLable.
1824     */
1825     Uint32 nullbit_byte_offset;
1826     /* NULL bit, 0-7. Not used for columns that are not NULLable. */
1827     Uint32 nullbit_bit_in_byte;
1828     /*
1829       Column specific flags
1830       Used only when RecPerColumnFlags is enabled
1831     */
1832     enum ColumnFlags
1833     {
1834       /*
1835         Skip reading/writing overflow bits in bitmap
1836         Used for MySQLD char(0) column
1837         Used only with RecMysqldBitfield flag
1838       */
1839       BitColMapsNullBitOnly= 0x1
1840     };
1841     Uint32 column_flags;
1842   };
1843 
1844   /*
1845     First version of RecordSpecification
1846     Maintained here for backward compatibility reasons.
1847   */
1848   struct RecordSpecification_v1 {
1849     const Column *column;
1850     Uint32 offset;
1851     Uint32 nullbit_byte_offset;
1852     Uint32 nullbit_bit_in_byte;
1853   };
1854 
1855   /* Types of NdbRecord object */
1856   enum RecordType {
1857     TableAccess,
1858     IndexAccess
1859   };
1860 
1861   /*
1862     Return the type of the passed NdbRecord object
1863   */
1864   static RecordType getRecordType(const NdbRecord* record);
1865 
1866   /*
1867     Return the name of the table object that the NdbRecord
1868     refers to.
1869     This method returns Null if the NdbRecord object is not a
1870     TableAccess NdbRecord.
1871   */
1872   static const char* getRecordTableName(const NdbRecord* record);
1873 
1874   /*
1875     Return the name of the index object that the NdbRecord
1876     refers to.
1877     This method returns Null if the NdbRecord object is not an
1878     IndexAccess NdbRecord
1879   */
1880   static const char* getRecordIndexName(const NdbRecord* record);
1881 
1882   /*
1883     Get the first Attribute Id specified in the NdbRecord object.
1884     Returns false if no Attribute Ids are specified.
1885   */
1886   static bool getFirstAttrId(const NdbRecord* record, Uint32& firstAttrId);
1887 
1888   /* Get the next Attribute Id specified in the NdbRecord object
1889      after the attribute Id passed in.
1890      Returns false if there are no more attribute Ids
1891   */
1892   static bool getNextAttrId(const NdbRecord* record, Uint32& attrId);
1893 
1894   /* Get offset of the given attribute id's storage from the start
1895      of the NdbRecord row.
1896      Returns false if the attribute id is not present
1897   */
1898   static bool getOffset(const NdbRecord* record, Uint32 attrId, Uint32& offset);
1899 
1900   /* Get offset of the given attribute id's null bit from the start
1901      of the NdbRecord row.
1902      Returns false if the attribute is not present or if the
1903      attribute is not nullable
1904   */
1905   static bool getNullBitOffset(const NdbRecord* record,
1906                                Uint32 attrId,
1907                                Uint32& nullbit_byte_offset,
1908                                Uint32& nullbit_bit_in_byte);
1909 
1910   /*
1911     Return pointer to beginning of storage of data specified by
1912     attrId.
1913     This method looks up the offset of the column which is stored in
1914     the NdbRecord object, and returns the value of row + offset.
1915     There are row-const and non-row-const versions.
1916 
1917     @param record : Pointer to NdbRecord object describing the row format
1918     @param row : Pointer to the start of row data
1919     @param attrId : Attribute id of column
1920     @return : Pointer to start of the attribute in the row.  Null if the
1921     attribute is not part of the NdbRecord definition
1922   */
1923   static const char* getValuePtr(const NdbRecord* record,
1924                                  const char* row,
1925                                  Uint32 attrId);
1926 
1927   static char* getValuePtr(const NdbRecord* record,
1928                            char* row,
1929                            Uint32 attrId);
1930 
1931   /*
1932     Return a bool indicating whether the null bit for the given
1933     column is set to true or false.
1934     The location of the null bit in relation to the row pointer is
1935     obtained from the passed NdbRecord object.
1936     If the column is not nullable, false will be returned.
1937     If the column is not part of the NdbRecord definition, false will
1938     be returned.
1939 
1940     @param record : Pointer to NdbRecord object describing the row format
1941     @param row : Pointer to the start of row data
1942     @param attrId : Attibute id of column
1943     @return : true if attrId exists in NdbRecord, is nullable, and null bit
1944     in row is set, false otherwise.
1945   */
1946   static bool isNull(const NdbRecord* record,
1947                      const char* row,
1948                      Uint32 attrId);
1949 
1950   /*
1951     Set the null bit for the given column to the supplied value.
1952     The offset for the null bit is obtained from the passed
1953     NdbRecord object.
1954 
1955     If the attrId is not part of the NdbRecord, or is not nullable
1956     then an error will be returned.
1957 
1958     @param record : Pointer to NdbRecord object describing the row format
1959     @param row : Pointer to the start of row data
1960     @param atrId : Attribute id of the column
1961     @param value : Value to set null bit to
1962     @returns : 0 in success, -1 if the attrId is not part of the record,
1963     or is not nullable
1964   */
1965   static int setNull(const NdbRecord* record,
1966                      char* row,
1967                      Uint32 attrId,
1968                      bool value);
1969 
1970   /*
1971     Return the number of bytes needed to store one row of data
1972     laid out as described by the passed NdbRecord structure.
1973   */
1974   static Uint32 getRecordRowLength(const NdbRecord* record);
1975 
1976   /*
1977     Return an empty column presence bitmask.
1978     This bitmask can be used with any NdbRecord to specify that
1979     no NdbRecord columns are to be included in the operation.
1980   */
1981   static const unsigned char* getEmptyBitmask();
1982 
1983   struct AutoGrowSpecification {
1984     Uint32 min_free;
1985     Uint64 max_size;
1986     Uint64 file_size;
1987     const char * filename_pattern;
1988   };
1989 
1990   /**
1991    * @class LogfileGroup
1992    */
1993   class LogfileGroup : public Object {
1994   public:
1995     LogfileGroup();
1996     LogfileGroup(const LogfileGroup&);
1997     virtual ~LogfileGroup();
1998 
1999     void setName(const char * name);
2000     const char* getName() const;
2001 
2002     void setUndoBufferSize(Uint32 sz);
2003     Uint32 getUndoBufferSize() const;
2004 
2005     void setAutoGrowSpecification(const AutoGrowSpecification&);
2006     const AutoGrowSpecification& getAutoGrowSpecification() const;
2007 
2008     Uint64 getUndoFreeWords() const;
2009 
2010     /**
2011      * Get object status
2012      */
2013     virtual Object::Status getObjectStatus() const;
2014 
2015     /**
2016      * Get object version
2017      */
2018     virtual int getObjectVersion() const;
2019 
2020     /**
2021      * Get object id
2022      */
2023     virtual int getObjectId() const;
2024 
2025   private:
2026     friend class NdbDictionaryImpl;
2027     friend class NdbLogfileGroupImpl;
2028     class NdbLogfileGroupImpl & m_impl;
2029     LogfileGroup(NdbLogfileGroupImpl&);
2030   };
2031 
2032   /**
2033    * @class Tablespace
2034    */
2035   class Tablespace : public Object {
2036   public:
2037     Tablespace();
2038     Tablespace(const Tablespace&);
2039     virtual ~Tablespace();
2040 
2041     void setName(const char * name);
2042     const char* getName() const;
2043 
2044     void setExtentSize(Uint32 sz);
2045     Uint32 getExtentSize() const;
2046 
2047     void setAutoGrowSpecification(const AutoGrowSpecification&);
2048     const AutoGrowSpecification& getAutoGrowSpecification() const;
2049 
2050     void setDefaultLogfileGroup(const char * name);
2051     void setDefaultLogfileGroup(const class LogfileGroup&);
2052 
2053     const char * getDefaultLogfileGroup() const;
2054     Uint32 getDefaultLogfileGroupId() const;
2055 
2056     /**
2057      * Get object status
2058      */
2059     virtual Object::Status getObjectStatus() const;
2060 
2061     /**
2062      * Get object version
2063      */
2064     virtual int getObjectVersion() const;
2065 
2066     /**
2067      * Get object id
2068      */
2069     virtual int getObjectId() const;
2070 
2071   private:
2072     friend class NdbTablespaceImpl;
2073     class NdbTablespaceImpl & m_impl;
2074     Tablespace(NdbTablespaceImpl&);
2075   };
2076 
2077   class Datafile : public Object {
2078   public:
2079     Datafile();
2080     Datafile(const Datafile&);
2081     virtual ~Datafile();
2082 
2083     void setPath(const char * name);
2084     const char* getPath() const;
2085 
2086     void setSize(Uint64);
2087     Uint64 getSize() const;
2088     Uint64 getFree() const;
2089 
2090     int setTablespace(const char * name);
2091     int setTablespace(const class Tablespace &);
2092     const char * getTablespace() const;
2093     void getTablespaceId(ObjectId * dst) const;
2094 
2095     /**
2096      * Get object status
2097      */
2098     virtual Object::Status getObjectStatus() const;
2099 
2100     /**
2101      * Get object version
2102      */
2103     virtual int getObjectVersion() const;
2104 
2105     /**
2106      * Get object id
2107      */
2108     virtual int getObjectId() const;
2109 
2110   private:
2111     friend class NdbDatafileImpl;
2112     class NdbDatafileImpl & m_impl;
2113     Datafile(NdbDatafileImpl&);
2114   };
2115 
2116   class Undofile : public Object {
2117   public:
2118     Undofile();
2119     Undofile(const Undofile&);
2120     virtual ~Undofile();
2121 
2122     void setPath(const char * path);
2123     const char* getPath() const;
2124 
2125     void setSize(Uint64);
2126     Uint64 getSize() const;
2127 
2128     void setLogfileGroup(const char * name);
2129     void setLogfileGroup(const class LogfileGroup &);
2130     const char * getLogfileGroup() const;
2131     void getLogfileGroupId(ObjectId * dst) const;
2132 
2133     /**
2134      * Get object status
2135      */
2136     virtual Object::Status getObjectStatus() const;
2137 
2138     /**
2139      * Get object version
2140      */
2141     virtual int getObjectVersion() const;
2142 
2143     /**
2144      * Get object id
2145      */
2146     virtual int getObjectId() const;
2147 
2148   private:
2149     friend class NdbUndofileImpl;
2150     class NdbUndofileImpl & m_impl;
2151     Undofile(NdbUndofileImpl&);
2152   };
2153 
2154   /**
2155    * @class HashMap
2156    * @brief Represents a HashMap in an NDB Cluster
2157    *
2158    */
2159   class HashMap : public Object {
2160   public:
2161     HashMap();
2162     HashMap(const HashMap&);
2163     virtual ~HashMap();
2164 
2165     void setName(const char *);
2166     const char * getName() const;
2167 
2168     void setMap(const Uint32* values, Uint32 len);
2169     Uint32 getMapLen() const;
2170     int getMapValues(Uint32* dst, Uint32 len) const;
2171 
2172     /**
2173      * equal
2174      *   compares *values* only
2175      */
2176     bool equal(const HashMap&) const;
2177 
2178     /**
2179      * Get object status
2180      */
2181     virtual Object::Status getObjectStatus() const;
2182 
2183     /**
2184      * Get object version
2185      */
2186     virtual int getObjectVersion() const;
2187 
2188     /**
2189      * Get object id
2190      */
2191     virtual int getObjectId() const;
2192 
2193   private:
2194     friend class NdbHashMapImpl;
2195     class NdbHashMapImpl & m_impl;
2196     HashMap(NdbHashMapImpl&);
2197   };
2198 
2199   /**
2200    * @class ForeignKey
2201    * @brief Represents a foreign key in an NDB Cluster
2202    *
2203    */
2204   class ForeignKey : public Object {
2205   public:
2206     ForeignKey();
2207     ForeignKey(const ForeignKey&);
2208     virtual ~ForeignKey();
2209 
2210     enum FkAction
2211     {
2212       NoAction = NDB_FK_NO_ACTION, // deferred check
2213       Restrict = NDB_FK_RESTRICT,
2214       Cascade = NDB_FK_CASCADE,
2215       SetNull = NDB_FK_SET_NULL,
2216       SetDefault = NDB_FK_SET_DEFAULT
2217     };
2218 
2219     const char * getName() const;
2220     const char * getParentTable() const;
2221     const char * getChildTable() const;
2222     unsigned getParentColumnCount() const;
2223     unsigned getChildColumnCount() const;
2224     int getParentColumnNo(unsigned no) const;
2225     int getChildColumnNo(unsigned no) const;
2226 
2227     /**
2228      * return 0 if child referes to parent PK
2229      */
2230     const char * getParentIndex() const;
2231 
2232     /**
2233      * return 0 if child references are resolved using child PK
2234      */
2235     const char * getChildIndex() const;
2236 
2237     FkAction getOnUpdateAction() const;
2238     FkAction getOnDeleteAction() const;
2239 
2240     /**
2241      *
2242      */
2243     void setName(const char *);
2244 
2245     /**
2246      * specify parent/child table
2247      * optionally an index
2248      * and columns in parent/child table (optionally)
2249      *
2250      * if index is not specified primary key is used
2251      *
2252      * if columns is not specified, index order is used
2253      *
2254      * if columns and index is specified, and index is ordered index
2255      *   column order must match given column order
2256      *
2257      */
2258     void setParent(const Table&, const Index * index = 0,
2259                    const Column * cols[] = 0);
2260     void setChild(const Table&, const Index * index = 0,
2261                   const Column * cols[] = 0);
2262 
2263     void setOnUpdateAction(FkAction);
2264     void setOnDeleteAction(FkAction);
2265 
2266     /**
2267      * Get object status
2268      */
2269     virtual Object::Status getObjectStatus() const;
2270 
2271     /**
2272      * Get object id
2273      */
2274     virtual int getObjectId() const;
2275 
2276     /**
2277      * Get object version
2278      */
2279     virtual int getObjectVersion() const;
2280 
2281   private:
2282     friend class NdbForeignKeyImpl;
2283     class NdbForeignKeyImpl & m_impl;
2284     ForeignKey(NdbForeignKeyImpl&);
2285   };
2286 
2287   /**
2288    * @class Dictionary
2289    * @brief Dictionary for defining and retreiving meta data
2290    */
2291   class Dictionary {
2292   public:
2293     /**
2294      * @class List
2295      * @brief Structure for retrieving lists of object names
2296      */
2297     struct List {
2298       /**
2299        * @struct  Element
2300        * @brief   Object to be stored in an NdbDictionary::Dictionary::List
2301        */
2302       List& operator=(const List&) = default;
2303       struct Element {
2304 	unsigned id;            ///< Id of object
2305         Object::Type type;      ///< Type of object
2306         Object::State state;    ///< State of object
2307         Object::Store store;    ///< How object is logged
2308         Uint32 temp;            ///< Temporary status of object
2309 	char * database;        ///< In what database the object resides
2310 	char * schema;          ///< What schema the object is defined in
2311 	char * name;            ///< Name of object
ElementNdbDictionary::Dictionary::List::Element2312         Element() :
2313           id(0),
2314           type(Object::TypeUndefined),
2315           state(Object::StateUndefined),
2316           store(Object::StoreUndefined),
2317           temp(NDB_TEMP_TAB_PERMANENT),
2318 	  database(0),
2319 	  schema(0),
2320           name(0) {
2321         }
2322         /* qsort compare functions */
2323         static int compareByName(const void * p, const void * q);
2324         static int compareById(const void * p, const void * q);
2325       };
2326       unsigned count;           ///< Number of elements in list
2327       Element * elements;       ///< Pointer to array of elements
ListNdbDictionary::Dictionary::List2328       List() : count(0), elements(0) {}
~ListNdbDictionary::Dictionary::List2329       ~List() {
2330         if (elements != 0) {
2331           for (unsigned i = 0; i < count; i++) {
2332             delete[] elements[i].database;
2333             delete[] elements[i].schema;
2334             delete[] elements[i].name;
2335             elements[i].name = 0;
2336           }
2337           delete[] elements;
2338           count = 0;
2339           elements = 0;
2340         }
2341       }
2342       void sortById();
2343       void sortByName();
2344     };
2345 
2346     /**
2347      * @name General
2348      * @{
2349      */
2350 
2351     /**
2352      * Fetch list of all objects, optionally restricted to given type.
2353      *
2354      * @param list   List of objects returned in the dictionary
2355      * @param type   Restrict returned list to only contain objects of
2356      *               this type
2357      *
2358      * @return       -1 if error.
2359      *
2360      */
2361 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
2362     int listObjects(List & list, Object::Type type = Object::TypeUndefined);
2363 #endif
2364     int listObjects(List & list,
2365 		    Object::Type type = Object::TypeUndefined) const;
2366     int listObjects(List & list,
2367                     Object::Type type,
2368                     bool fullyQualified) const;
2369 
2370     /**
2371      * Get the latest error
2372      *
2373      * @return   Error object.
2374      */
2375     const struct NdbError & getNdbError() const;
2376 
2377     /**
2378      * Get warning flags.  The value is valid only if the operation did
2379      * not return an error and can return warnings.  The flags are
2380      * specific to the operation.
2381      */
2382     int getWarningFlags() const;
2383 
2384     /** @} *******************************************************************/
2385 
2386     /**
2387      * @name Retrieving references to Tables and Indexes
2388      * @{
2389      */
2390 
2391     /**
2392      * Get table with given name, NULL if undefined
2393      * @param name   Name of table to get
2394      * @return table if successful otherwise NULL.
2395      */
2396     const Table * getTable(const char * name) const;
2397 
2398 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
2399     /**
2400      * Given main table, get blob table.
2401      */
2402     const Table * getBlobTable(const Table *, const char * col_name);
2403     const Table * getBlobTable(const Table *, Uint32 col_no);
2404 
2405     /*
2406      * Save a table definition in dictionary cache
2407      * @param table Object to put into cache
2408      */
2409     void putTable(const Table * table);
2410 #endif
2411 
2412     /**
2413      * Get index with given name, NULL if undefined
2414      * @param indexName  Name of index to get.
2415      * @param tableName  Name of table that index belongs to.
2416      * @return  index if successful, otherwise 0.
2417      */
2418     const Index * getIndex(const char * indexName,
2419 			   const char * tableName) const;
2420     const Index * getIndex(const char * indexName,
2421                            const Table& base) const;
2422 
2423     /**
2424      * Fetch list of indexes of given table.
2425      * @param list  Reference to list where to store the listed indexes
2426      * @param tableName  Name of table that index belongs to.
2427      * @return  0 if successful, otherwise -1
2428      */
2429 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
2430     int listIndexes(List & list, const char * tableName);
2431 #endif
2432     int listIndexes(List & list, const char * tableName) const;
2433     int listIndexes(List & list, const char * tableName, bool fullyQualified) const;
2434 
2435 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
2436     /**
2437      * Fetch list of indexes of given table.
2438      * @param list  Reference to list where to store the listed indexes
2439      * @param table  Reference to table that index belongs to.
2440      * @return  0 if successful, otherwise -1
2441      */
2442     int listIndexes(List & list, const Table &table) const;
2443 
2444     /**
2445      * Fetch list of objects that table depend on
2446      * @param list  Reference to list where to store the listed objects
2447      * @param table  Reference to table that objects belongs to.
2448      * @return  0 if successful, otherwise -1
2449      */
2450     int listDependentObjects(List & list, const Table &table) const;
2451 #endif
2452 
2453     /** @} *******************************************************************/
2454     /**
2455      * @name Events
2456      * @{
2457      */
2458 
2459     /**
2460      * Create event given defined Event instance
2461      * @param event Event to create
2462      * @return 0 if successful otherwise -1.
2463      */
2464     int createEvent(const Event &event);
2465 
2466     /**
2467      * Drop event with given name
2468      * @param eventName  Name of event to drop.
2469      * @return 0 if successful otherwise -1.
2470      */
2471     int dropEvent(const char * eventName, int force= 0);
2472 
2473     /**
2474      * Get event with given name.
2475      * @param eventName  Name of event to get.
2476      * @return an Event if successful, otherwise NULL.
2477      */
2478     const Event * getEvent(const char * eventName);
2479 
2480     /**
2481      * List defined events
2482      * @param list   List of events returned in the dictionary
2483      * @return 0 if successful otherwise -1.
2484      */
2485 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
2486     int listEvents(List & list);
2487 #endif
2488     int listEvents(List & list) const;
2489 
2490     /** @} *******************************************************************/
2491 
2492     /**
2493      * @name Table creation
2494      * @{
2495      *
2496      * These methods should normally not be used in an application as
2497      * the result will not be visible from the MySQL Server
2498      */
2499 
2500     /**
2501      * Create defined table given defined Table instance
2502      * @param table Table to create
2503      * @return 0 if successful otherwise -1.
2504      */
2505     int createTable(const Table &table);
2506 
2507     /**
2508      * Create defined table given defined Table instance
2509      *   return ObjectId
2510      * @param table Table to create
2511      * @return 0 if successful otherwise -1.
2512      */
2513     int createTable(const Table &table, ObjectId * objid);
2514 
2515     /**
2516      * Start table optimization given defined table object
2517      * @param t Object of table to optimize
2518      * @param h Pre-allocated OptimizeTableHandle
2519      * @return 0 if successful otherwise -1.
2520      */
2521     int
2522     optimizeTable(const Table &t, OptimizeTableHandle &h);
2523 
2524     /**
2525      * Start index optimization given defined index object
2526      * @param ind Object of index to optimize
2527      * @param h Pre-allocated OptimizeIndexHandle
2528      * @return 0 if successful otherwise -1.
2529      */
2530     int
2531     optimizeIndex(const Index &ind, OptimizeIndexHandle &h);
2532 
2533     /**
2534      * Drop table given retrieved Table instance
2535      * @param table Table to drop
2536      * @return 0 if successful otherwise -1.
2537      *
2538      * @note dropTable() drops indexes and foreign keys
2539      * where the table is child or parent
2540      */
2541     int dropTable(Table & table);
2542 
2543     /**
2544      * Drop table given table name
2545      * @param name   Name of table to drop
2546      * @return 0 if successful otherwise -1.
2547      */
2548     int dropTable(const char * name);
2549 
2550     /**
2551      * Check if alter of table given defined
2552      * Table instance to new definition is supported
2553      * @param f Table to alter
2554      * @param t New definition of table
2555      * @return  TRUE supported      <br>
2556      *          FALSE not supported <br>
2557      */
2558     bool supportedAlterTable(const Table & f, const Table & t);
2559 
2560 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
2561     /**
2562      * Alter defined table given defined Table instance
2563      * @param f Table to alter
2564      * @param t New definition of table
2565      * @return  -2 (incompatible version) <br>
2566      *          -1 general error          <br>
2567      *           0 success
2568      */
2569     int alterTable(const Table & f, const Table & t);
2570 
2571 #endif
2572 
2573     /**
2574      * Invalidate cached table object
2575      * @param name  Name of table to invalidate
2576      */
2577     void invalidateTable(const char * name);
2578     /**
2579      * Remove table from local cache
2580      */
2581     void removeCachedTable(const char * table);
2582     /**
2583      * Remove index from local cache
2584      */
2585     void removeCachedIndex(const char * index, const char * table);
2586     /**
2587      * Invalidate cached index object
2588      * @param indexName  Name of index to invalidate
2589      * @param tableName  Name of table the index belongs to
2590      */
2591     void invalidateIndex(const char * indexName,
2592                          const char * tableName);
2593 
2594     /** @} *******************************************************************/
2595     /**
2596      * @name Index creation
2597      * @{
2598      *
2599      * These methods should normally not be used in an application as
2600      * the result will not be visible from the MySQL Server
2601      *
2602      */
2603 
2604     /**
2605      * Create index given defined Index instance
2606      * @param index Index to create
2607      * @return 0 if successful otherwise -1.
2608      */
2609     int createIndex(const Index &index, bool offline = false);
2610     int createIndex(const Index &index, const Table &table, bool offline = false);
2611 
2612     /**
2613      * Drop index with given name
2614      * @param indexName  Name of index to drop.
2615      * @param tableName  Name of table that index belongs to.
2616      * @return 0 if successful otherwise -1.
2617      */
2618     int dropIndex(const char * indexName,
2619 		  const char * tableName);
2620 
2621     /*
2622      * Force update of ordered index stats.  Scans an assigned fragment
2623      * in the kernel and updates result in stats tables.  This one-time
2624      * update is independent of IndexStatAuto settings.  Common use case
2625      * is mysql "analyze table".
2626      */
2627     int updateIndexStat(const Index&, const Table&);
2628 
2629     /*
2630      * Force update of ordered index stats where index is given by id.
2631      */
2632     int updateIndexStat(Uint32 indexId, Uint32 indexVersion, Uint32 tableId);
2633 
2634     /*
2635      * Delete ordered index stats.  If IndexStatAutoUpdate is set, also
2636      * stops automatic updates, until another forced update is done.
2637      */
2638     int deleteIndexStat(const Index&, const Table&);
2639 
2640     /*
2641      * Delete ordered index stats where index is given by id.
2642      */
2643     int deleteIndexStat(Uint32 indexId, Uint32 indexVersion, Uint32 tableId);
2644 
2645 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
2646     void removeCachedTable(const Table *table);
2647     void removeCachedIndex(const Index *index);
2648     void invalidateTable(const Table *table);
2649     void invalidateIndex(const Index *index);
2650     /**
2651      * Force gcp and wait for gcp complete
2652      */
2653     int forceGCPWait();
2654     int forceGCPWait(int type);
2655 
2656     /**
2657      * Get restart gci
2658      */
2659     int getRestartGCI(Uint32 * gci);
2660 #endif
2661 
2662     /** @} *******************************************************************/
2663 
2664     /** @} *******************************************************************/
2665     /**
2666      * @name Disk data objects
2667      * @{
2668      */
2669 
2670     /*
2671      * The four "create" operations can return warning flags defined
2672      * below.  See getWarningFlags().
2673      */
2674     enum {
2675       WarnUndobufferRoundUp = 0x1,  // rounded up to kernel page size
2676       WarnUndofileRoundDown = 0x2,  // rounded down to kernel page size
2677       WarnExtentRoundUp = 0x4,      // rounded up to kernel page size
2678       WarnDatafileRoundDown = 0x8,  // rounded down to kernel page size
2679       WarnDatafileRoundUp = 0x10    // rounded up to extent size
2680     };
2681 
2682     int createLogfileGroup(const LogfileGroup &, ObjectId* = 0);
2683     int dropLogfileGroup(const LogfileGroup&);
2684     LogfileGroup getLogfileGroup(const char * name);
2685 
2686     int createTablespace(const Tablespace &, ObjectId* = 0);
2687     int dropTablespace(const Tablespace&);
2688     Tablespace getTablespace(const char * name);
2689     Tablespace getTablespace(Uint32 tablespaceId);
2690 
2691     int createDatafile(const Datafile &, bool overwrite_existing = false, ObjectId* = 0);
2692     int dropDatafile(const Datafile&);
2693     Datafile getDatafile(Uint32 node, const char * path);
2694 
2695     int createUndofile(const Undofile &, bool overwrite_existing = false, ObjectId * = 0);
2696     int dropUndofile(const Undofile&);
2697     Undofile getUndofile(Uint32 node, const char * path);
2698 
2699 
2700     /** @} *******************************************************************/
2701     /**
2702      * @name HashMap
2703      * @{
2704      */
2705 
2706     /**
2707      * Create a HashMap in database
2708      */
2709     int createHashMap(const HashMap&, ObjectId* = 0);
2710 
2711     /**
2712      * Get a HashMap by name
2713      */
2714     int getHashMap(HashMap& dst, const char* name);
2715 
2716     /**
2717      * Get a HashMap for a table
2718      */
2719     int getHashMap(HashMap& dst, const Table* table);
2720 
2721     /**
2722      * Get default HashMap
2723      */
2724     int getDefaultHashMap(HashMap& dst, Uint32 partitionCount);
2725     int getDefaultHashMap(HashMap& dst, Uint32 buckets, Uint32 partitionCount);
2726 
2727 
2728     /**
2729      * Init a default HashMap
2730      */
2731     int initDefaultHashMap(HashMap& dst, Uint32 partitionCount);
2732     int initDefaultHashMap(HashMap& dst, Uint32 buckets, Uint32 partitionCount);
2733 
2734     /**
2735      * create (or retreive) a HashMap suitable for alter
2736      * NOTE: Requires a started schema transaction
2737      */
2738     int prepareHashMap(const Table& oldTable, Table& newTable);
2739     int prepareHashMap(const Table& oldTable, Table& newTable, Uint32 buckets);
2740 
2741     /** @} *******************************************************************/
2742 
2743     /** @} *******************************************************************/
2744     /**
2745      * @name ForeignKey
2746      * @{
2747      */
2748 
2749     enum CreateFKFlags
2750     {
2751       /**
2752        * CreateFK_NoVerify
2753        * - don't verify FK as part of Create.
2754        * - @NOTE: This allows creation of inconsistent FK
2755        */
2756       CreateFK_NoVerify = 1
2757     };
2758 
2759     /**
2760      * Create a ForeignKey in database
2761      */
2762     int createForeignKey(const ForeignKey&, ObjectId* = 0, int flags = 0);
2763 
2764     /**
2765      * Get a ForeignKey by name
2766      */
2767     int getForeignKey(ForeignKey& dst, const char* name);
2768 
2769     /**
2770      * Drop a ForeignKey
2771      */
2772     int dropForeignKey(const ForeignKey&);
2773 
2774     /** @} *******************************************************************/
2775 
2776     /**
2777      * @name Schema transactions
2778      *
2779      * Metadata operations are create, alter, and drop of objects of
2780      * various types.  An operation may create additional sub-operations
2781      * in the kernel.
2782      *
2783      * By default, each user operation is executed separately.  That is,
2784      * a schema transaction is started implicitly, the operation and its
2785      * suboperations are executed, and the transaction is closed.
2786      *
2787      * The Ndb object and its associated Dictionary support one schema
2788      * transaction at a time.
2789      *
2790      * Using begin and end transaction explicitly it is possible to
2791      * execute a set of user defined operations atomically i.e. either
2792      * all operations succeed or all are aborted (rolled back).
2793      *
2794      * The steps are 1) beginSchemaTrans 2) submit operations such as
2795      * createTable 3) endSchemaTrans.
2796      *
2797      * Each operation is sent to the kernel which parses and saves it.
2798      * Parse failure does rollback to previous user operation before
2799      * returning.  The user can continue or abort entire transaction.
2800      *
2801      * After all operations have been submitted, endSchemaTrans with
2802      * flags 0 (the default) processes and commits them.  On error
2803      * return the transaction is already aborted.
2804      *
2805      * If the user exits before calling endSchemaTrans, the kernel
2806      * aborts the transaction.  If the user exits before the call to
2807      * endSchemaTrans returns, the kernel continues with the request.
2808      * Completion status is reported in cluster log.
2809      */
2810 
2811     //@{
2812     /**
2813      * Begin schema transaction.  Returns error if a transaction is
2814      * already active or if the kernel metadata is locked.
2815      *
2816      * @return 0 on success, -1 on error
2817      */
2818     int beginSchemaTrans();
2819 
2820     /**
2821      * End schema transaction, with commit or with abort.  Combines
2822      * execute and close which do not exist separately.  May be called
2823      * and succeeds even if no transaction is active.
2824      *
2825      * @note Like any method, may overwrite current error code.
2826      *       First save error code from any failed operation.
2827      *
2828      * @param flags
2829      *        Bitmask of options.
2830      *        Default 0 commits the transaction.
2831      *        Including option 1 aborts the transaction.
2832      *        See SchemaTransFlag for others.
2833      * @return 0 on success, -1 on error
2834      */
2835     int endSchemaTrans(Uint32 flags = 0);
2836 
2837     /**
2838      * Flags for endSchemaTrans, or-ed together.
2839      */
2840     enum SchemaTransFlag {
2841       // abort transaction
2842       SchemaTransAbort = 1,
2843       // do not wait for reply, status is reported in cluster log
2844       SchemaTransBackground = 2
2845     };
2846 
2847     /**
2848      * Check if a schema transaction exists currently.
2849      */
2850     bool hasSchemaTrans() const;
2851     //@}
2852 
2853   protected:
2854     Dictionary(Ndb & ndb);
2855     ~Dictionary();
2856 
2857   private:
2858 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
2859     friend class NdbDictionaryImpl;
2860     friend class UtilTransactions;
2861     friend class NdbBlob;
2862 #endif
2863     class NdbDictionaryImpl & m_impl;
2864     Dictionary(NdbDictionaryImpl&);
2865     const Table * getIndexTable(const char * indexName,
2866                                 const char * tableName) const;
2867   public:
2868 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
2869     const Table * getTable(const char * name, void **data) const;
2870     void set_local_table_data_size(unsigned sz);
2871 
2872     const Index * getIndexGlobal(const char * indexName,
2873                                  const Table &ndbtab) const;
2874     const Index * getIndexGlobal(const char * indexName,
2875                                  const char * tableName) const;
2876     const Table * getTableGlobal(const char * tableName) const;
2877     int alterTableGlobal(const Table &f, const Table &t);
2878     int dropTableGlobal(const Table &ndbtab);
2879     /* Flags for second variant of dropTableGlobal */
2880     enum {
2881       /*
2882        * Drop any referring foreign keys on child tables.
2883        * Named after oracle "drop table .. cascade constraints".
2884        */
2885       DropTableCascadeConstraints = 0x1
2886 
2887       /*
2888        * Drop any referring foreign keys within same DB
2889        *   used when dropping database
2890        */
2891       ,DropTableCascadeConstraintsDropDB = 0x2
2892     };
2893     int dropTableGlobal(const Table &ndbtab, int flags);
2894     int dropIndexGlobal(const Index &index);
2895     int removeIndexGlobal(const Index &ndbidx, int invalidate) const;
2896     int removeTableGlobal(const Table &ndbtab, int invalidate) const;
2897     void invalidateDbGlobal(const char * dbname);
2898 #endif
2899 
2900     /*
2901       Create an NdbRecord for use in table operations.
2902     */
2903     NdbRecord *createRecord(const Table *table,
2904                             const RecordSpecification *recSpec,
2905                             Uint32 length,
2906                             Uint32 elemSize,
2907                             Uint32 flags= 0);
2908 
2909     /*
2910       Create an NdbRecord for use in index operations.
2911     */
2912     NdbRecord *createRecord(const Index *index,
2913                             const Table *table,
2914                             const RecordSpecification *recSpec,
2915                             Uint32 length,
2916                             Uint32 elemSize,
2917                             Uint32 flags= 0);
2918     /*
2919       Create an NdbRecord for use in index operations.
2920       This variant assumes that the index is for a table in
2921       the current database and schema
2922     */
2923     NdbRecord *createRecord(const Index *index,
2924                             const RecordSpecification *recSpec,
2925                             Uint32 length,
2926                             Uint32 elemSize,
2927                             Uint32 flags= 0);
2928 
2929     /*
2930       Free an NdbRecord object created earlier with
2931       createRecord
2932     */
2933     void releaseRecord(NdbRecord *rec);
2934 
2935     /*
2936       Methods to print objects more verbose than possible from
2937       object itself.
2938      */
2939     void print(class NdbOut& out, NdbDictionary::Index const& idx);
2940     void print(class NdbOut& out, NdbDictionary::Table const& tab);
2941   }; // class Dictionary
2942 
2943   class NdbDataPrintFormat
2944   {
2945   public:
2946     NdbDataPrintFormat();
2947     virtual ~NdbDataPrintFormat();
2948     const char *lines_terminated_by;
2949     const char *fields_terminated_by;
2950     const char *start_array_enclosure;
2951     const char *end_array_enclosure;
2952     const char *fields_enclosed_by;
2953     const char *fields_optionally_enclosed_by;
2954     const char *hex_prefix;
2955     const char *null_string;
2956     int hex_format;
2957   };
2958 
2959   static
2960   class NdbOut& printFormattedValue(class NdbOut& out,
2961                                     const NdbDataPrintFormat& format,
2962                                     const NdbDictionary::Column* c,
2963                                     const void* val);
2964 
2965 }; // class NdbDictionary
2966 
2967 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Column& col);
2968 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Index& idx);
2969 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Index::Type type);
2970 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Object::FragmentType fragtype);
2971 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Object::Status status);
2972 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Object::Type type);
2973 class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Table& tab);
2974 
2975 #endif
2976