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