1 /*
2    Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, 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 NdbSchemaOp_H
26 #define NdbSchemaOp_H
27 
28 #include <NdbDictionary.hpp>
29 
30 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
31 
32   /**
33    * Type of attribute
34    *
35    * NOTE! AttrType is deprecated, use NdbDictionary::Column::Type instead!
36    */
37   enum AttrType {
38     Signed,           ///< Attributes of this type can be read with:
39                       ///< NdbRecAttr::int64_value,
40                       ///< NdbRecAttr::int32_value,
41                       ///< NdbRecAttr::short_value,
42                       ///< NdbRecAttr::char_value
43     UnSigned,         ///< Attributes of this type can be read with:
44                       ///< NdbRecAttr::u_64_value,
45                       ///< NdbRecAttr::u_32_value,
46                       ///< NdbRecAttr::u_short_value,
47                       ///< NdbRecAttr::u_char_value
48     Float,            ///< Attributes of this type can be read with:
49                       ///< NdbRecAttr::float_value and
50                       ///< NdbRecAttr::double_value
51     String,           ///< Attributes of this type can be read with:
52                       ///< NdbRecAttr::aRef,
53                       ///< NdbRecAttr::getAttributeObject
54     NoAttrTypeDef     ///< Used for debugging only
55   };
56 
57 
58   /**
59    * @deprecated
60    */
61   enum NullAttributeType {
62     NoNullTypeDefined = -1,
63     NotNullAttribute,
64     NullAttribute,
65     AttributeDefined
66   };
67   /**
68    * Indicates whether the attribute is part of a primary key or not
69    */
70   enum KeyType {
71     Undefined = -1,               ///< Used for debugging only
72     NoKey,                        ///< Attribute is not part of primary key
73                                   ///< or tuple identity
74     TupleKey,                     ///< Attribute is part of primary key
75     TupleId                       ///< Attribute is part of tuple identity
76                                   ///< (This type of attribute is created
77                                   ///< internally, and should not be
78                                   ///< manually created.)
79   };
80   /**
81    * Indicate whether the attribute should be stored on disk or not
82    * Only for legacy createAttribute().
83    */
84   enum StorageMode {
85     MMBased = NDB_STORAGETYPE_MEMORY,
86     DiskBased = NDB_STORAGETYPE_DISK
87   };
88 
89   /**
90    *  Type of fragmentation used for a table
91    */
92   enum FragmentType {
93     Default = 0,                  ///<  (All is default!)
94     Single = 1,                   ///< Only one fragment
95     All = 2,                      ///< Default value.  One fragment per node group
96     DistributionGroup = 3,        ///< Distribution Group used for fragmentation.
97                                   ///< One fragment per node group
98     DistributionKey = 4,          ///< Distribution Key used for fragmentation.
99                                   ///< One fragment per node group.
100     AllLarge = 5,                 ///< Sixten fragments per node group.
101     DGroupLarge = 6,              ///< Distribution Group used for fragmentation.
102                                   ///< Sixten fragments per node group
103     DKeyLarge = 7                 ///< Distribution Key used for fragmentation.
104                                   ///< Sixten fragments per node group
105   };
106 
107   /**
108    *  Type of table or index.
109    */
110   enum TableType {
111     UndefTableType = 0,
112     SystemTable = 1,              ///< Internal.Table cannot be updated by user
113     UserTable = 2,                  ///< Normal application table
114     UniqueHashIndex = 3,          ///< Unique un-ordered hash index
115     HashIndex = 4,                ///< Non-unique un-ordered hash index
116     UniqueOrderedIndex = 5,       ///< Unique ordered index
117     OrderedIndex = 6              ///< Non-unique ordered index
118   };
119 
120 
121 class NdbSchemaCon;
122 class Ndb;
123 
124 
125 /**
126  * @class NdbSchemaOp
127  * @brief Represents various operations for use in schema transactions
128  *
129  * This class is used for schema operations, e.g. creating tables and
130  * attributes.
131  *
132  * The NdbSchemaOp object is created using NdbSchemaCon::getNdbSchemaOp.
133  *
134  * @note  This class is deprecated and is now replaced with the class
135  *        NdbDictionary.
136  */
137 class NdbSchemaOp
138 {
139   friend class Ndb;
140   friend class NdbSchemaCon;
141 
142 public:
143 
144 
145   /**
146    * Create a new table in the database.
147    *
148    * @note The NdbSchemaCon should be closed with
149    *       Ndb::closeSchemaTransaction, even if this method fails.
150    *
151    * @param  aTableName   Table name.  Should not be NULL.
152    * @param  aTableSize	  (Performance parameter.)
153    *                      Initial size of the data part of the table
154    *                      expressed in kByte.
155    *                      The database handles
156    * 			  bad parameter setting but at a certain
157    *                      loss in performance.
158    *                      The size given here is
159    * 			  the initial size allocated for the table
160    *                      storage (the data part).
161    * 			  When calculating the data storage one should
162    *                      add the size of all attributes (each attribute
163    *                      consumes at least 4 bytes) and also an overhead
164    *                      of 12 byte.
165    *                      Variable size attributes (not supported yet)
166    * 			  will have a size of 12 bytes plus the actual
167    *                      data storage parts where there is an
168    *                      additional overhead based on the size of the
169    * 			  variable part.
170    *                      <br>
171    * 	                  An example table with 5 attributes:
172    *                      one 64 bit attribute, one 32 bit attribute,
173    *                      two 16 bit attributes and one array of 64 8 bits.
174    *                      This table will consume
175    *                        12 (overhead) + 8 + 4 + 2*4 (4 is minimum) + 64 =
176    *                        96 bytes per record.
177    * 	                  Additionally an overhead of about 2 % as page
178    *                      headers and waste should be allocated.
179    *                      Thus, 1 million records should consume 96 MBytes
180    * 	                  plus the overhead 2 MByte and rounded up to
181    *                      100 000 kBytes.
182    *                      <br><em>
183    *                      This parameter is currently not used.
184    *                      </em>
185    * @param  aTupleKey	  Indicates if the table has a primary key or not.
186    * 			  <br>
187    *                        <b>TupleKey</b> means that a <em>primary key</em>
188    *                        consisting of one to four attributes
189    * 			    (at most one of variable size)
190    *                        uniquely identifies each record in the created
191    *                        table.
192    * 			    <br>
193    *                        <b>TupleId</b> means that a <em>tuple identity</em>
194    *                        is used.  The tuple identity is
195    *                        a unique key indentifying each record of the
196    *                        created table.
197    *                        The tuple identity is a (non-stored)
198    *                        64 bit attribute named <b>NDB$TID</b>.
199    * 			    <br>
200    *                        When inserting a record (tuple), the method
201    *                        NdbOperation::setTupleId
202    *                        will generate a unique tuple identity
203    *                        and return it to the user.
204    *                        <br>
205    *                        When reading, updating or deleting a record
206    *                        in a table with <b>TupleId</b>,
207    *                        NdbOperation::equal("NDB$TID", value_Uint64)
208    *                        can be used to identify the record.
209    *                        <br>
210    *                        Legal values: TupleKey or TupleId.
211    * @param aNrOfPages	  (Performance parameter.)
212    *                      Specifies the initial size of the index storage.
213    *                      When calculating the index storage,
214    * 			  each key has approximately 14 byte of
215    *                      overhead plus the size of the key.
216    *                      Each key attribute takes up at least 4 bytes
217    *                      of storage.
218    *                      Thus a mixed key consisting of a
219    *                      64 bit attribute, a 32 bit attribute
220    * 			  and a 16 bit attribute will
221    *                      consume approx. 30 bytes per key.
222    * 			  Thus, the if initial size is to be 1 million rows,
223    *                      then aNrOfPages should be set to
224    *                      30 M / 8k = 2670 pages.
225    *                      <br><em>
226    *                      This parameter is currently not used.
227    *                       </em>
228    * @param aFragmentType Type of fragmentation.<br>
229    *                      <b>All</b> (default) means that the
230    *                      table fragments are automatically
231    *                      distributed on all nodes in the system.<br>
232    *                      <b>DistributionGroup</b> and
233    *                      <b>DistributionKey</b> are
234    *                      also supported. For further details about
235    *                      these types see the documentation of
236    *                      Ndb::startTransaction.
237    * @param aKValue	  (Hash parameter.)
238    *                      Only allowed value is 6.
239    *                      Later implementations might add flexibility
240    * 			  in this parameter.
241    * @param aMinLoadFactor  (Hash parameter.)
242    *                        This value specifies the load factor when
243    *                        starting to shrink the hash table.
244    *                        It must be smaller than aMaxLoadFactor.
245    *                        Both these factors are given in percentage.
246    * @param aMaxLoadFactor  (Hash parameter.)
247    *                        This value specifies the load factor when
248    *                        starting to split the containers in the local
249    *                        hash tables. 100 is the maximum which will
250    * 		     	    optimize memory usage (this is the figure
251    *                        used for the above calculations).
252    * 		       	    A lower figure will store less information in
253    *                        each container and thus
254    * 		            find the key faster but consume more memory.
255    * @param aMemoryType	    Currently only 1 is allowed which specifies
256    *                        storage of table in main memory.
257    *                        Later 2 will be added where the table is stored
258    * 	       		    completely on disk
259    *                        and 3 where the index is in main memory but
260    * 		            data is on disk.
261    *                        If 1 is chosen an individual attribute can
262    * 		            still be specified as a disk attribute.
263    * @param aStoredTable    If set to false it indicates that the table is
264    *                        a temporary table and should not be logged
265    *                        to disk.
266    *                        In case of a system restart the table will still
267    * 	      	   	    be defined and exist but will be empty.
268    *                        Thus no checkpointing and
269    * 		       	    no logging is performed on the table.
270    * 			    The default value is true and indicates a
271    *                        normal table with full checkpointing and
272    *                        logging activated.
273    * @return                Returns 0 when successful and returns -1 otherwise.
274    */
275   int		createTable(	const char* aTableName,
276 				Uint32 aTableSize = 8,
277 				KeyType aTupleKey = TupleKey,
278 				int aNrOfPages = 2,
279 				FragmentType aFragmentType = All,
280 				int aKValue = 6,
281 				int aMinLoadFactor = 78,
282 				int aMaxLoadFactor = 80,
283 				int aMemoryType = 1,
284 				bool aStoredTable = true);
285 
286   /**
287    * This is the old function declaration, don't use.
288    *
289    * @deprecated do not use!
290    */
291 #ifndef NDB_WIN32
createTable(const char * aTableName,Uint32 aTableSize,KeyType aTupleKey,int aNrOfPages,FragmentType aFragmentType,int aKValue,int aMinLoadFactor,int aMaxLoadFactor,int aMemoryType,int aStoredTable)292   inline int	createTable(	const char* aTableName,
293 				Uint32 aTableSize,
294 				KeyType aTupleKey,
295 				int aNrOfPages,
296 				FragmentType aFragmentType,
297 				int aKValue,
298 				int aMinLoadFactor,
299 				int aMaxLoadFactor,
300 				int aMemoryType,
301 				int aStoredTable){
302     return createTable(aTableName,
303                        aTableSize,
304                        aTupleKey,
305                        aNrOfPages,
306                        aFragmentType,
307                        aKValue,
308                        aMinLoadFactor,
309                        aMaxLoadFactor,
310                        aMemoryType,
311                        (aStoredTable == 1 ? true : false));
312   }
313 #endif
314 
315   /**
316    * Add a new attribute to a database table.
317    *
318    * Attributes can only be added to a table in the same transaction
319    * as the transaction creating the table.
320    *
321    * @note The NdbSchemaCon transaction should be closed with
322    *       Ndb::closeSchemaTransaction, even if this method fails.
323    *
324    * Example creating an unsigned int attribute belonging to the primary key
325    * of the table it is created in:
326    * @code
327    *   MySchemaOp->createAttribute("Attr1",   // Attribute name
328    *                               TupleKey,  // Belongs to primary key
329    *                               32,        // 32 bits
330    *                               1,         // Not an array attribute
331    *                               UnSigned,  // Unsigned type
332    *                              );
333    * @endcode
334    *
335    * Example creating a string attribute belonging to the primary key
336    * of the table it is created in:
337    * @code
338    *   MySchemaOp->createAttribute("Attr1",       // Attribute name
339    *                               TupleKey,      // Belongs to primary key
340    *                               8,             // Each character is 8 bits
341    *                               12,            // Max 12 chars in string
342    *                               String,        // Attribute if of type string
343    *                              );
344    * @endcode
345    *
346    * A <em>distribution key</em> is a set of attributes which are used
347    * to distribute the tuples onto the NDB nodes.
348    * A <em>distribution group</em> is a part (currently 16 bits)
349    * of an attribute used to distribute the tuples onto the NDB nodes.
350    * The distribution key uses the NDB Cluster hashing function,
351    * while the distribution group uses a simpler function.
352    *
353    * @param  aAttrName   Attribute name.  Should not be NULL.
354    * @param  aTupleKey	 This parameter specifies whether the
355    *                     attribute is part of the primary key or not.
356    *                     Floats are not allowed in the primary key.
357    *                     <br>
358    *                     Legal values: NoKey, TupleKey
359    * @param  aAttrSize	 Specifies the size of the elements of the
360    *                     attribute.  (An attribute can consist
361    *                     of an array of elements.)
362    *                     <br>
363    *                     Legal values: 8, 16, 32, 64 and 128 bits.
364    * @param  aArraySize	 Size of array.
365    *                     <br>
366    *                     Legal values:
367    *                     0 = variable-sized array,
368    *                     1 = no array, and
369    *                     2- = fixed size array.
370    *                     <br>
371    *                     <em>
372    *                     Variable-sized array attributes are
373    *                     not yet supported.
374    *                     </em>
375    *                     <br>
376    *                     There is no upper limit of the array size
377    *                     for a single attribute.
378    * @param  aAttrType   The attribute type.
379    * 			 This is only of interest if calculations are
380    *                     made within NDB.
381    *                     <br>
382    *                     Legal values: UnSigned, Signed, Float, String
383    * @param aStorageMode    Main memory based or disk based attribute.<br>
384    *                     Legal values: MMBased, DiskBased
385    *                     <br>
386    *                     <em>
387    *                     Disk-based attributes are not yet supported.
388    *                     </em>
389    * @param nullable     Set to true if NULL is a correct value for
390    *                     the attribute.
391    *                     <br>
392    *                     Legal values: true, false
393    * @param aStType      Obsolete since wl-2066
394    * @param aDistributionKey    Sometimes it is preferable to use a subset
395    *                            of the primary key as the distribution key.
396    *                            An example is TPC-C where it might be
397    *                            good to use the warehouse id and district id
398    *                            as the distribution key.
399    *                            <br>
400    *                            Locally in the fragments the full primary key
401    *                            will still be used with the hashing algorithm.
402    *                            Set to 1 if this attribute is part of the
403    *                            distribution key.
404    *                            All distribution key attributes must be
405    *                            defined before
406    *                            any other attributes are defined.
407    * @param aDistributionGroup    In other applications it is desirable to use
408    *                              only a part of an attribute to create the
409    *                              distribution key.
410    *                              This is applicable for some telecom
411    *                              applications.
412    *                              <br>
413    *                              In these situations one must provide how many
414    *                              bits of the attribute that is to
415    *                              be used as the distribution hash value.
416    *                              <br>
417    *                              This provides some control to the
418    *                              application of the distribution.
419    *                              It still needs to be part of a primary key
420    *                              the attribute and must be defined as the
421    *                              first attribute.
422    * @param  aDistributionGroupNoOfBits
423    *                              Number of bits to use of the
424    *                              distribution group attribute in the
425    *                              distribution hash value.
426    *                              <br>
427    *                              Currently, only 16 bits is supported. It will
428    *                              always be the last 16 bits in the attribute
429    *                              which is used for the distribution group.
430    * @param aAutoIncrement        Set to autoincrement attribute.
431    * @param aDefaultValue         Set a default value of attribute.
432    *
433    * @return Returns 0 when successful and returns -1 otherwise.
434    ****************************************************************************/
435   int createAttribute(const char* aAttrName,
436 		      KeyType aTupleKey = NoKey,
437 		      int aAttrSize = 32,
438 		      int aArraySize = 1,
439 		      AttrType aAttrType = UnSigned,
440 		      StorageMode aStorageMode = MMBased,
441 		      bool nullable = false,
442 		      int aStType= 0, // obsolete
443 		      int aDistributionKey = 0,
444 		      int aDistributionGroup = 0,
445 		      int aDistributionGroupNoOfBits = 16,
446                       bool aAutoIncrement = false,
447                       const char* aDefaultValue = 0);
448 
449   /**
450    * @deprecated do not use!
451    */
createAttribute(const char * aAttrName,KeyType aTupleKey,int aAttrSize,int aArraySize,AttrType aAttrType,StorageMode aStorageMode,NullAttributeType aNullAttr,int aStType,int aDistributionKey=0,int aDistributionGroup=0,int aDistributionGroupNoOfBits=16)452   int createAttribute(const char* aAttrName,
453 		      KeyType aTupleKey,
454 		      int aAttrSize,
455 		      int aArraySize,
456 		      AttrType aAttrType,
457 		      StorageMode aStorageMode,
458 		      NullAttributeType aNullAttr,
459 		      int aStType, // obsolete
460 		      int aDistributionKey = 0,
461 		      int aDistributionGroup = 0,
462 		      int aDistributionGroupNoOfBits = 16){
463     return createAttribute(aAttrName,
464 			   aTupleKey,
465 			   aAttrSize,
466 			   aArraySize,
467 			   aAttrType,
468 			   aStorageMode,
469 			   aNullAttr == NullAttribute,
470 			   aStType,
471 			   aDistributionKey,
472 			   aDistributionGroup,
473 			   aDistributionGroupNoOfBits);
474   }
475 
476   const NdbError & getNdbError() const;
477 
478 protected:
479 
480 /*****************************************************************************
481  *   These are the methods used to create and delete the NdbOperation objects.
482  ****************************************************************************/
483   			NdbSchemaOp(Ndb* aNdb);
484 
485   			~NdbSchemaOp();
486 
487 /******************************************************************************
488  *	These methods are service routines used by the other NDBAPI classes.
489  *****************************************************************************/
490 
491   void			release();	// Release all memory connected
492   					      // to the operations object.
493 
494 /****************************************************************************
495  *	The methods below is the execution part of the NdbSchemaOp class.
496  *****************************************************************************/
497 
498   int sendRec();
499   int sendSignals(Uint32 aNodeId, bool HaveMutex);
500 
501   int init(NdbSchemaCon* aSchemaCon);
502 
503   /**************************************************************************
504    * These are the private variables that are defined in the operation
505    * objects.
506    **************************************************************************/
507   Ndb*			theNdb;		// Point back to the Ndb object.
508   NdbSchemaCon* 	theSchemaCon;	// Point back to the connection object.
509 
510 
511   class NdbDictionary::Table * m_currentTable;
512 };
513 
514 
515 /**
516  * Get old attribute type from new type
517  *
518  * NOTE! attrType is deprecated, use getType instead!
519  *
520  * @return Type of attribute: { Signed, UnSigned, Float,a String }
521  */
522 inline
523 AttrType
convertColumnTypeToAttrType(NdbDictionary::Column::Type _type)524 convertColumnTypeToAttrType(NdbDictionary::Column::Type _type)
525 {
526 
527   switch(_type){
528   case NdbDictionary::Column::Bigint:
529   case NdbDictionary::Column::Int:
530     return Signed;
531   case NdbDictionary::Column::Bigunsigned:
532   case NdbDictionary::Column::Unsigned:
533     return UnSigned;
534   case NdbDictionary::Column::Float:
535   case NdbDictionary::Column::Olddecimal:
536   case NdbDictionary::Column::Olddecimalunsigned:
537   case NdbDictionary::Column::Decimal:
538   case NdbDictionary::Column::Decimalunsigned:
539   case NdbDictionary::Column::Double:
540     return Float;
541   case NdbDictionary::Column::Char:
542   case NdbDictionary::Column::Varchar:
543   case NdbDictionary::Column::Binary:
544   case NdbDictionary::Column::Varbinary:
545     return String;
546   default:
547     return NoAttrTypeDef;
548   }
549 }
550 #endif
551 
552 #endif
553 
554 
555