1 /*
2 Copyright (c) 2003, 2021, Oracle and/or its affiliates.
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 #include <ndb_math.h>
26 #include <NdbDictionary.hpp>
27 #include "NdbDictionaryImpl.hpp"
28 #include <NdbOut.hpp>
29 #include <signaldata/CreateHashMap.hpp>
30 #include <NdbBlob.hpp>
31 C_MODE_START
32 #include <decimal.h>
33 C_MODE_END
34
35 /* NdbRecord static helper methods */
36
37 NdbDictionary::RecordType
getRecordType(const NdbRecord * record)38 NdbDictionary::getRecordType(const NdbRecord* record)
39 {
40 return NdbDictionaryImpl::getRecordType(record);
41 }
42
43 const char*
getRecordTableName(const NdbRecord * record)44 NdbDictionary::getRecordTableName(const NdbRecord* record)
45 {
46 return NdbDictionaryImpl::getRecordTableName(record);
47 }
48
49 const char*
getRecordIndexName(const NdbRecord * record)50 NdbDictionary::getRecordIndexName(const NdbRecord* record)
51 {
52 return NdbDictionaryImpl::getRecordIndexName(record);
53 }
54
55 bool
getFirstAttrId(const NdbRecord * record,Uint32 & firstAttrId)56 NdbDictionary::getFirstAttrId(const NdbRecord* record,
57 Uint32& firstAttrId)
58 {
59 return NdbDictionaryImpl::getNextAttrIdFrom(record,
60 0,
61 firstAttrId);
62 }
63
64 bool
getNextAttrId(const NdbRecord * record,Uint32 & attrId)65 NdbDictionary::getNextAttrId(const NdbRecord* record,
66 Uint32& attrId)
67 {
68 return NdbDictionaryImpl::getNextAttrIdFrom(record,
69 attrId+1,
70 attrId);
71 }
72
73 bool
getOffset(const NdbRecord * record,Uint32 attrId,Uint32 & offset)74 NdbDictionary::getOffset(const NdbRecord* record,
75 Uint32 attrId,
76 Uint32& offset)
77 {
78 return NdbDictionaryImpl::getOffset(record, attrId, offset);
79 }
80
81 bool
getNullBitOffset(const NdbRecord * record,Uint32 attrId,Uint32 & nullbit_byte_offset,Uint32 & nullbit_bit_in_byte)82 NdbDictionary::getNullBitOffset(const NdbRecord* record,
83 Uint32 attrId,
84 Uint32& nullbit_byte_offset,
85 Uint32& nullbit_bit_in_byte)
86 {
87 return NdbDictionaryImpl::getNullBitOffset(record,
88 attrId,
89 nullbit_byte_offset,
90 nullbit_bit_in_byte);
91 }
92
93
94 const char*
getValuePtr(const NdbRecord * record,const char * row,Uint32 attrId)95 NdbDictionary::getValuePtr(const NdbRecord* record,
96 const char* row,
97 Uint32 attrId)
98 {
99 return NdbDictionaryImpl::getValuePtr(record, row, attrId);
100 }
101
102 char*
getValuePtr(const NdbRecord * record,char * row,Uint32 attrId)103 NdbDictionary::getValuePtr(const NdbRecord* record,
104 char* row,
105 Uint32 attrId)
106 {
107 return NdbDictionaryImpl::getValuePtr(record, row, attrId);
108 }
109
110 bool
isNull(const NdbRecord * record,const char * row,Uint32 attrId)111 NdbDictionary::isNull(const NdbRecord* record,
112 const char* row,
113 Uint32 attrId)
114 {
115 return NdbDictionaryImpl::isNull(record, row, attrId);
116 }
117
118 int
setNull(const NdbRecord * record,char * row,Uint32 attrId,bool value)119 NdbDictionary::setNull(const NdbRecord* record,
120 char* row,
121 Uint32 attrId,
122 bool value)
123 {
124 return NdbDictionaryImpl::setNull(record, row, attrId, value);
125 }
126
127 Uint32
getRecordRowLength(const NdbRecord * record)128 NdbDictionary::getRecordRowLength(const NdbRecord* record)
129 {
130 return NdbDictionaryImpl::getRecordRowLength(record);
131 }
132
133 const unsigned char*
getEmptyBitmask()134 NdbDictionary::getEmptyBitmask()
135 {
136 return (const unsigned char*) NdbDictionaryImpl::m_emptyMask;
137 }
138
139 /* --- */
140
ObjectId()141 NdbDictionary::ObjectId::ObjectId()
142 : m_impl(* new NdbDictObjectImpl(NdbDictionary::Object::TypeUndefined))
143 {
144 }
145
~ObjectId()146 NdbDictionary::ObjectId::~ObjectId()
147 {
148 NdbDictObjectImpl * tmp = &m_impl;
149 delete tmp;
150 }
151
152 NdbDictionary::Object::Status
getObjectStatus() const153 NdbDictionary::ObjectId::getObjectStatus() const {
154 return m_impl.m_status;
155 }
156
157 int
getObjectVersion() const158 NdbDictionary::ObjectId::getObjectVersion() const {
159 return m_impl.m_version;
160 }
161
162 int
getObjectId() const163 NdbDictionary::ObjectId::getObjectId() const {
164 return m_impl.m_id;
165 }
166
167 /*****************************************************************
168 * Column facade
169 */
Column(const char * name)170 NdbDictionary::Column::Column(const char * name)
171 : m_impl(* new NdbColumnImpl(* this))
172 {
173 setName(name);
174 }
175
Column(const NdbDictionary::Column & org)176 NdbDictionary::Column::Column(const NdbDictionary::Column & org)
177 : m_impl(* new NdbColumnImpl(* this))
178 {
179 m_impl = org.m_impl;
180 }
181
Column(NdbColumnImpl & impl)182 NdbDictionary::Column::Column(NdbColumnImpl& impl)
183 : m_impl(impl)
184 {
185 }
186
~Column()187 NdbDictionary::Column::~Column(){
188 NdbColumnImpl * tmp = &m_impl;
189 if(this != tmp){
190 delete tmp;
191 }
192 }
193
194 NdbDictionary::Column&
operator =(const NdbDictionary::Column & column)195 NdbDictionary::Column::operator=(const NdbDictionary::Column& column)
196 {
197 m_impl = column.m_impl;
198
199 return *this;
200 }
201
202 int
setName(const char * name)203 NdbDictionary::Column::setName(const char * name){
204 return !m_impl.m_name.assign(name);
205 }
206
207 const char*
getName() const208 NdbDictionary::Column::getName() const {
209 return m_impl.m_name.c_str();
210 }
211
212 void
setType(Type t)213 NdbDictionary::Column::setType(Type t){
214 m_impl.init(t);
215 }
216
217 NdbDictionary::Column::Type
getType() const218 NdbDictionary::Column::getType() const {
219 return m_impl.m_type;
220 }
221
222 void
setPrecision(int val)223 NdbDictionary::Column::setPrecision(int val){
224 m_impl.m_precision = val;
225 }
226
227 int
getPrecision() const228 NdbDictionary::Column::getPrecision() const {
229 return m_impl.m_precision;
230 }
231
232 void
setScale(int val)233 NdbDictionary::Column::setScale(int val){
234 m_impl.m_scale = val;
235 }
236
237 int
getScale() const238 NdbDictionary::Column::getScale() const{
239 return m_impl.m_scale;
240 }
241
242 void
setLength(int length)243 NdbDictionary::Column::setLength(int length){
244 m_impl.m_length = length;
245 }
246
247 int
getLength() const248 NdbDictionary::Column::getLength() const{
249 return m_impl.m_length;
250 }
251
252 void
setInlineSize(int size)253 NdbDictionary::Column::setInlineSize(int size)
254 {
255 m_impl.m_precision = size;
256 }
257
258 void
setCharset(CHARSET_INFO * cs)259 NdbDictionary::Column::setCharset(CHARSET_INFO* cs)
260 {
261 m_impl.m_cs = cs;
262 }
263
264 CHARSET_INFO*
getCharset() const265 NdbDictionary::Column::getCharset() const
266 {
267 return m_impl.m_cs;
268 }
269
270 int
getCharsetNumber() const271 NdbDictionary::Column::getCharsetNumber() const
272 {
273 return m_impl.m_cs->number;
274 }
275
276 int
getInlineSize() const277 NdbDictionary::Column::getInlineSize() const
278 {
279 return m_impl.m_precision;
280 }
281
282 void
setPartSize(int size)283 NdbDictionary::Column::setPartSize(int size)
284 {
285 m_impl.m_scale = size;
286 }
287
288 int
getPartSize() const289 NdbDictionary::Column::getPartSize() const
290 {
291 return m_impl.m_scale;
292 }
293
294 void
setStripeSize(int size)295 NdbDictionary::Column::setStripeSize(int size)
296 {
297 m_impl.m_length = size;
298 }
299
300 int
getStripeSize() const301 NdbDictionary::Column::getStripeSize() const
302 {
303 return m_impl.m_length;
304 }
305
306 int
getSize() const307 NdbDictionary::Column::getSize() const{
308 return m_impl.m_attrSize;
309 }
310
311 void
setNullable(bool val)312 NdbDictionary::Column::setNullable(bool val){
313 m_impl.m_nullable = val;
314 }
315
316 bool
getNullable() const317 NdbDictionary::Column::getNullable() const {
318 return m_impl.m_nullable;
319 }
320
321 void
setPrimaryKey(bool val)322 NdbDictionary::Column::setPrimaryKey(bool val){
323 m_impl.m_pk = val;
324 }
325
326 bool
getPrimaryKey() const327 NdbDictionary::Column::getPrimaryKey() const {
328 return m_impl.m_pk;
329 }
330
331 void
setPartitionKey(bool val)332 NdbDictionary::Column::setPartitionKey(bool val){
333 m_impl.m_distributionKey = val;
334 }
335
336 bool
getPartitionKey() const337 NdbDictionary::Column::getPartitionKey() const{
338 return m_impl.m_distributionKey;
339 }
340
341 const NdbDictionary::Table *
getBlobTable() const342 NdbDictionary::Column::getBlobTable() const {
343 NdbTableImpl * t = m_impl.m_blobTable;
344 if (t)
345 return t->m_facade;
346 return 0;
347 }
348
349 void
setAutoIncrement(bool val)350 NdbDictionary::Column::setAutoIncrement(bool val){
351 m_impl.m_autoIncrement = val;
352 }
353
354 bool
getAutoIncrement() const355 NdbDictionary::Column::getAutoIncrement() const {
356 return m_impl.m_autoIncrement;
357 }
358
359 void
setAutoIncrementInitialValue(Uint64 val)360 NdbDictionary::Column::setAutoIncrementInitialValue(Uint64 val){
361 m_impl.m_autoIncrementInitialValue = val;
362 }
363
364 int
getSizeInBytesForRecord() const365 NdbDictionary::Column::getSizeInBytesForRecord() const {
366 const bool isBlob= ((m_impl.m_type == Blob) || (m_impl.m_type == Text));
367 return isBlob ? sizeof(NdbBlob *) : getSizeInBytes();
368 }
369
370 /*
371 * setDefaultValue() with only one const char * parameter is reserved
372 * for backward compatible api consideration, but is broken.
373 */
374 int
setDefaultValue(const char * defaultValue)375 NdbDictionary::Column::setDefaultValue(const char* defaultValue)
376 {
377 return -1;
378 }
379
380 /*
381 The significant length of a column can't easily be calculated before
382 the column type is fully defined, so the length of the default value
383 is passed in as a parameter explicitly.
384 */
385 int
setDefaultValue(const void * defaultValue,unsigned int n)386 NdbDictionary::Column::setDefaultValue(const void* defaultValue, unsigned int n)
387 {
388 if (defaultValue == NULL)
389 return m_impl.m_defaultValue.assign(NULL, 0);
390
391 return m_impl.m_defaultValue.assign(defaultValue, n);
392 }
393
394 const void*
getDefaultValue(unsigned int * len) const395 NdbDictionary::Column::getDefaultValue(unsigned int* len) const
396 {
397 if (len)
398 *len = m_impl.m_defaultValue.length();
399
400 return m_impl.m_defaultValue.get_data();
401 }
402
403 int
getColumnNo() const404 NdbDictionary::Column::getColumnNo() const {
405 return m_impl.m_column_no;
406 }
407
408 int
getAttrId() const409 NdbDictionary::Column::getAttrId() const {
410 return m_impl.m_attrId;
411 }
412
413 bool
equal(const NdbDictionary::Column & col) const414 NdbDictionary::Column::equal(const NdbDictionary::Column & col) const {
415 return m_impl.equal(col.m_impl);
416 }
417
418 int
getSizeInBytes() const419 NdbDictionary::Column::getSizeInBytes() const
420 {
421 return m_impl.m_attrSize * m_impl.m_arraySize;
422 }
423
424 void
setArrayType(ArrayType type)425 NdbDictionary::Column::setArrayType(ArrayType type)
426 {
427 m_impl.m_arrayType = type;
428 }
429
430 NdbDictionary::Column::ArrayType
getArrayType() const431 NdbDictionary::Column::getArrayType() const
432 {
433 return (ArrayType)m_impl.m_arrayType;
434 }
435
436 void
setStorageType(StorageType type)437 NdbDictionary::Column::setStorageType(StorageType type)
438 {
439 m_impl.m_storageType = type;
440 }
441
442 NdbDictionary::Column::StorageType
getStorageType() const443 NdbDictionary::Column::getStorageType() const
444 {
445 return (StorageType)m_impl.m_storageType;
446 }
447
448 int
getBlobVersion() const449 NdbDictionary::Column::getBlobVersion() const
450 {
451 return m_impl.getBlobVersion();
452 }
453
454 void
setBlobVersion(int blobVersion)455 NdbDictionary::Column::setBlobVersion(int blobVersion)
456 {
457 m_impl.setBlobVersion(blobVersion);
458 }
459
460 void
setDynamic(bool val)461 NdbDictionary::Column::setDynamic(bool val){
462 m_impl.m_dynamic = val;
463 }
464
465 bool
getDynamic() const466 NdbDictionary::Column::getDynamic() const {
467 return m_impl.m_dynamic;
468 }
469
470 bool
getIndexSourced() const471 NdbDictionary::Column::getIndexSourced() const {
472 return m_impl.m_indexSourced;
473 }
474
475 int
isBindable(const NdbDictionary::Column & col) const476 NdbDictionary::Column::isBindable(const NdbDictionary::Column & col) const
477 {
478 const NdbColumnImpl& parentColumn = col.m_impl;
479
480 if (m_impl.m_type != parentColumn.m_type ||
481 m_impl.m_precision != parentColumn.m_precision ||
482 m_impl.m_scale != parentColumn.m_scale ||
483 m_impl.m_length != parentColumn.m_length ||
484 m_impl.m_cs != parentColumn.m_cs)
485 return -1;
486
487 if (m_impl.m_type == NdbDictionary::Column::Blob ||
488 m_impl.m_type == NdbDictionary::Column::Text)
489 return -1;
490
491 return 0; // ok
492 }
493
494 /*****************************************************************
495 * Table facade
496 */
Table(const char * name)497 NdbDictionary::Table::Table(const char * name)
498 : m_impl(* new NdbTableImpl(* this))
499 {
500 setName(name);
501 }
502
Table(const NdbDictionary::Table & org)503 NdbDictionary::Table::Table(const NdbDictionary::Table & org)
504 : Object(org), m_impl(* new NdbTableImpl(* this))
505 {
506 m_impl.assign(org.m_impl);
507 }
508
Table(NdbTableImpl & impl)509 NdbDictionary::Table::Table(NdbTableImpl & impl)
510 : m_impl(impl)
511 {
512 }
513
~Table()514 NdbDictionary::Table::~Table(){
515 NdbTableImpl * tmp = &m_impl;
516 if(this != tmp){
517 delete tmp;
518 }
519 }
520
521 NdbDictionary::Table&
operator =(const NdbDictionary::Table & table)522 NdbDictionary::Table::operator=(const NdbDictionary::Table& table)
523 {
524 m_impl.assign(table.m_impl);
525
526 m_impl.m_facade = this;
527 return *this;
528 }
529
530 int
setName(const char * name)531 NdbDictionary::Table::setName(const char * name){
532 return m_impl.setName(name);
533 }
534
535 const char *
getName() const536 NdbDictionary::Table::getName() const {
537 return m_impl.getName();
538 }
539
540 const char *
getMysqlName() const541 NdbDictionary::Table::getMysqlName() const {
542 return m_impl.getMysqlName();
543 }
544
545 int
getTableId() const546 NdbDictionary::Table::getTableId() const {
547 return m_impl.m_id;
548 }
549
550 int
addColumn(const Column & c)551 NdbDictionary::Table::addColumn(const Column & c){
552 NdbColumnImpl* col = new NdbColumnImpl;
553 if (col == NULL)
554 {
555 errno = ENOMEM;
556 return -1;
557 }
558 (* col) = NdbColumnImpl::getImpl(c);
559 if (m_impl.m_columns.push_back(col))
560 {
561 return -1;
562 }
563 if (m_impl.buildColumnHash())
564 {
565 return -1;
566 }
567 col->m_column_no = m_impl.m_columns.size() - 1;
568 return 0;
569 }
570
571 const NdbDictionary::Column*
getColumn(const char * name) const572 NdbDictionary::Table::getColumn(const char * name) const {
573 return m_impl.getColumn(name);
574 }
575
576 const NdbDictionary::Column*
getColumn(const int attrId) const577 NdbDictionary::Table::getColumn(const int attrId) const {
578 return m_impl.getColumn(attrId);
579 }
580
581 NdbDictionary::Column*
getColumn(const char * name)582 NdbDictionary::Table::getColumn(const char * name)
583 {
584 return m_impl.getColumn(name);
585 }
586
587 NdbDictionary::Column*
getColumn(const int attrId)588 NdbDictionary::Table::getColumn(const int attrId)
589 {
590 return m_impl.getColumn(attrId);
591 }
592
593 void
setLogging(bool val)594 NdbDictionary::Table::setLogging(bool val){
595 m_impl.m_logging = val;
596 }
597
598 bool
getLogging() const599 NdbDictionary::Table::getLogging() const {
600 return m_impl.m_logging;
601 }
602
603 void
setFragmentType(FragmentType ft)604 NdbDictionary::Table::setFragmentType(FragmentType ft){
605 m_impl.m_fragmentType = ft;
606 }
607
608 NdbDictionary::Object::FragmentType
getFragmentType() const609 NdbDictionary::Table::getFragmentType() const {
610 return m_impl.m_fragmentType;
611 }
612
613 void
setKValue(int kValue)614 NdbDictionary::Table::setKValue(int kValue){
615 m_impl.m_kvalue = kValue;
616 }
617
618 int
getKValue() const619 NdbDictionary::Table::getKValue() const {
620 return m_impl.m_kvalue;
621 }
622
623 void
setMinLoadFactor(int lf)624 NdbDictionary::Table::setMinLoadFactor(int lf){
625 m_impl.m_minLoadFactor = lf;
626 }
627
628 int
getMinLoadFactor() const629 NdbDictionary::Table::getMinLoadFactor() const {
630 return m_impl.m_minLoadFactor;
631 }
632
633 void
setMaxLoadFactor(int lf)634 NdbDictionary::Table::setMaxLoadFactor(int lf){
635 m_impl.m_maxLoadFactor = lf;
636 }
637
638 int
getMaxLoadFactor() const639 NdbDictionary::Table::getMaxLoadFactor() const {
640 return m_impl.m_maxLoadFactor;
641 }
642
643 int
getNoOfColumns() const644 NdbDictionary::Table::getNoOfColumns() const {
645 return m_impl.m_columns.size();
646 }
647
648 int
getNoOfAutoIncrementColumns() const649 NdbDictionary::Table::getNoOfAutoIncrementColumns() const {
650 return m_impl.m_noOfAutoIncColumns;
651 }
652
653 int
getNoOfPrimaryKeys() const654 NdbDictionary::Table::getNoOfPrimaryKeys() const {
655 return m_impl.m_noOfKeys;
656 }
657
658 void
setMaxRows(Uint64 maxRows)659 NdbDictionary::Table::setMaxRows(Uint64 maxRows)
660 {
661 m_impl.m_max_rows = maxRows;
662 }
663
664 Uint64
getMaxRows() const665 NdbDictionary::Table::getMaxRows() const
666 {
667 return m_impl.m_max_rows;
668 }
669
670 void
setMinRows(Uint64 minRows)671 NdbDictionary::Table::setMinRows(Uint64 minRows)
672 {
673 m_impl.m_min_rows = minRows;
674 }
675
676 Uint64
getMinRows() const677 NdbDictionary::Table::getMinRows() const
678 {
679 return m_impl.m_min_rows;
680 }
681
682 void
setDefaultNoPartitionsFlag(Uint32 flag)683 NdbDictionary::Table::setDefaultNoPartitionsFlag(Uint32 flag)
684 {
685 m_impl.m_default_no_part_flag = flag;
686 }
687
688 Uint32
getDefaultNoPartitionsFlag() const689 NdbDictionary::Table::getDefaultNoPartitionsFlag() const
690 {
691 return m_impl.m_default_no_part_flag;
692 }
693
694 const char*
getPrimaryKey(int no) const695 NdbDictionary::Table::getPrimaryKey(int no) const {
696 int count = 0;
697 for (unsigned i = 0; i < m_impl.m_columns.size(); i++) {
698 if (m_impl.m_columns[i]->m_pk) {
699 if (count++ == no)
700 return m_impl.m_columns[i]->m_name.c_str();
701 }
702 }
703 return 0;
704 }
705
706 const void*
getFrmData() const707 NdbDictionary::Table::getFrmData() const {
708 return m_impl.getFrmData();
709 }
710
711 Uint32
getFrmLength() const712 NdbDictionary::Table::getFrmLength() const {
713 return m_impl.getFrmLength();
714 }
715
716 enum NdbDictionary::Table::SingleUserMode
getSingleUserMode() const717 NdbDictionary::Table::getSingleUserMode() const
718 {
719 return (enum SingleUserMode)m_impl.m_single_user_mode;
720 }
721
722 void
setSingleUserMode(enum NdbDictionary::Table::SingleUserMode mode)723 NdbDictionary::Table::setSingleUserMode(enum NdbDictionary::Table::SingleUserMode mode)
724 {
725 m_impl.m_single_user_mode = (Uint8)mode;
726 }
727
728 #if 0
729 int
730 NdbDictionary::Table::setTablespaceNames(const void *data, Uint32 len)
731 {
732 return m_impl.setTablespaceNames(data, len);
733 }
734
735 const void*
736 NdbDictionary::Table::getTablespaceNames()
737 {
738 return m_impl.getTablespaceNames();
739 }
740
741 Uint32
742 NdbDictionary::Table::getTablespaceNamesLen() const
743 {
744 return m_impl.getTablespaceNamesLen();
745 }
746 #endif
747
748 void
setLinearFlag(Uint32 flag)749 NdbDictionary::Table::setLinearFlag(Uint32 flag)
750 {
751 m_impl.m_linear_flag = flag;
752 }
753
754 bool
getLinearFlag() const755 NdbDictionary::Table::getLinearFlag() const
756 {
757 return m_impl.m_linear_flag;
758 }
759
760 void
setFragmentCount(Uint32 count)761 NdbDictionary::Table::setFragmentCount(Uint32 count)
762 {
763 m_impl.setFragmentCount(count);
764 }
765
766 Uint32
getFragmentCount() const767 NdbDictionary::Table::getFragmentCount() const
768 {
769 return m_impl.getFragmentCount();
770 }
771
772 int
setFrm(const void * data,Uint32 len)773 NdbDictionary::Table::setFrm(const void* data, Uint32 len){
774 return m_impl.setFrm(data, len);
775 }
776
777 const Uint32*
getFragmentData() const778 NdbDictionary::Table::getFragmentData() const {
779 return m_impl.getFragmentData();
780 }
781
782 Uint32
getFragmentDataLen() const783 NdbDictionary::Table::getFragmentDataLen() const {
784 return m_impl.getFragmentDataLen();
785 }
786
787 int
setFragmentData(const Uint32 * data,Uint32 cnt)788 NdbDictionary::Table::setFragmentData(const Uint32* data, Uint32 cnt)
789 {
790 return m_impl.setFragmentData(data, cnt);
791 }
792
793 const Int32*
getRangeListData() const794 NdbDictionary::Table::getRangeListData() const {
795 return m_impl.getRangeListData();
796 }
797
798 Uint32
getRangeListDataLen() const799 NdbDictionary::Table::getRangeListDataLen() const {
800 return m_impl.getRangeListDataLen();
801 }
802
803 int
setRangeListData(const Int32 * data,Uint32 len)804 NdbDictionary::Table::setRangeListData(const Int32* data, Uint32 len)
805 {
806 return m_impl.setRangeListData(data, len);
807 }
808
809 Uint32
getFragmentNodes(Uint32 fragmentId,Uint32 * nodeIdArrayPtr,Uint32 arraySize) const810 NdbDictionary::Table::getFragmentNodes(Uint32 fragmentId,
811 Uint32* nodeIdArrayPtr,
812 Uint32 arraySize) const
813 {
814 return m_impl.getFragmentNodes(fragmentId, nodeIdArrayPtr, arraySize);
815 }
816
817 NdbDictionary::Object::Status
getObjectStatus() const818 NdbDictionary::Table::getObjectStatus() const {
819 return m_impl.m_status;
820 }
821
822 void
setStatusInvalid() const823 NdbDictionary::Table::setStatusInvalid() const {
824 m_impl.m_status = NdbDictionary::Object::Invalid;
825 }
826
827 int
getObjectVersion() const828 NdbDictionary::Table::getObjectVersion() const {
829 return m_impl.m_version;
830 }
831
832 int
getObjectId() const833 NdbDictionary::Table::getObjectId() const {
834 return m_impl.m_id;
835 }
836
837 bool
equal(const NdbDictionary::Table & col) const838 NdbDictionary::Table::equal(const NdbDictionary::Table & col) const {
839 return m_impl.equal(col.m_impl);
840 }
841
842 int
getRowSizeInBytes() const843 NdbDictionary::Table::getRowSizeInBytes() const {
844 int sz = 0;
845 for(int i = 0; i<getNoOfColumns(); i++){
846 const NdbDictionary::Column * c = getColumn(i);
847 sz += (c->getSizeInBytes()+ 3) / 4;
848 }
849 return sz * 4;
850 }
851
852 int
getReplicaCount() const853 NdbDictionary::Table::getReplicaCount() const {
854 return m_impl.m_replicaCount;
855 }
856
857 bool
getTemporary() const858 NdbDictionary::Table::getTemporary() const {
859 return m_impl.m_temporary;
860 }
861
862 void
setTemporary(bool val)863 NdbDictionary::Table::setTemporary(bool val) {
864 m_impl.m_temporary = val;
865 }
866
867 int
createTableInDb(Ndb * pNdb,bool equalOk) const868 NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const {
869 const NdbDictionary::Table * pTab =
870 pNdb->getDictionary()->getTable(getName());
871 if(pTab != 0 && equal(* pTab))
872 return 0;
873 if(pTab != 0 && !equal(* pTab))
874 return -1;
875 return pNdb->getDictionary()->createTable(* this);
876 }
877
878 bool
getTablespace(Uint32 * id,Uint32 * version) const879 NdbDictionary::Table::getTablespace(Uint32 *id, Uint32 *version) const
880 {
881 if (m_impl.m_tablespace_id == RNIL)
882 return false;
883 if (id)
884 *id= m_impl.m_tablespace_id;
885 if (version)
886 *version= m_impl.m_version;
887 return true;
888 }
889
890 const char *
getTablespaceName() const891 NdbDictionary::Table::getTablespaceName() const
892 {
893 return m_impl.m_tablespace_name.c_str();
894 }
895
896 int
setTablespaceName(const char * name)897 NdbDictionary::Table::setTablespaceName(const char * name){
898 m_impl.m_tablespace_id = ~0;
899 m_impl.m_tablespace_version = ~0;
900 return !m_impl.m_tablespace_name.assign(name);
901 }
902
903 int
setTablespace(const NdbDictionary::Tablespace & ts)904 NdbDictionary::Table::setTablespace(const NdbDictionary::Tablespace & ts){
905 m_impl.m_tablespace_id = NdbTablespaceImpl::getImpl(ts).m_id;
906 m_impl.m_tablespace_version = ts.getObjectVersion();
907 return !m_impl.m_tablespace_name.assign(ts.getName());
908 }
909
910 bool
getHashMap(Uint32 * id,Uint32 * version) const911 NdbDictionary::Table::getHashMap(Uint32 *id, Uint32 *version) const
912 {
913 if (m_impl.m_hash_map_id == RNIL)
914 return false;
915 if (id)
916 *id= m_impl.m_hash_map_id;
917 if (version)
918 *version= m_impl.m_hash_map_version;
919 return true;
920 }
921
922 int
setHashMap(const NdbDictionary::HashMap & hm)923 NdbDictionary::Table::setHashMap(const NdbDictionary::HashMap& hm)
924 {
925 m_impl.m_hash_map_id = hm.getObjectId();
926 m_impl.m_hash_map_version = hm.getObjectVersion();
927 return 0;
928 }
929
930 void
setRowChecksumIndicator(bool val)931 NdbDictionary::Table::setRowChecksumIndicator(bool val){
932 m_impl.m_row_checksum = val;
933 }
934
935 bool
getRowChecksumIndicator() const936 NdbDictionary::Table::getRowChecksumIndicator() const {
937 return m_impl.m_row_checksum;
938 }
939
940 void
setRowGCIIndicator(bool val)941 NdbDictionary::Table::setRowGCIIndicator(bool val){
942 m_impl.m_row_gci = val;
943 }
944
945 bool
getRowGCIIndicator() const946 NdbDictionary::Table::getRowGCIIndicator() const {
947 return m_impl.m_row_gci;
948 }
949
950 void
setExtraRowGciBits(Uint32 val)951 NdbDictionary::Table::setExtraRowGciBits(Uint32 val)
952 {
953 if (val <= 31)
954 {
955 m_impl.m_extra_row_gci_bits = val;
956 }
957 }
958
959 Uint32
getExtraRowGciBits() const960 NdbDictionary::Table::getExtraRowGciBits() const
961 {
962 return m_impl.m_extra_row_gci_bits;
963 }
964
965 void
setExtraRowAuthorBits(Uint32 val)966 NdbDictionary::Table::setExtraRowAuthorBits(Uint32 val)
967 {
968 if (val <= 31)
969 {
970 m_impl.m_extra_row_author_bits = val;
971 }
972 }
973
974 Uint32
getExtraRowAuthorBits() const975 NdbDictionary::Table::getExtraRowAuthorBits() const
976 {
977 return m_impl.m_extra_row_author_bits;
978 }
979
980 void
setForceVarPart(bool val)981 NdbDictionary::Table::setForceVarPart(bool val){
982 m_impl.m_force_var_part = val;
983 }
984
985 bool
getForceVarPart() const986 NdbDictionary::Table::getForceVarPart() const {
987 return m_impl.m_force_var_part;
988 }
989
990 bool
hasDefaultValues() const991 NdbDictionary::Table::hasDefaultValues() const {
992 return m_impl.m_has_default_values;
993 }
994
995 const NdbRecord*
getDefaultRecord() const996 NdbDictionary::Table::getDefaultRecord() const {
997 return m_impl.m_ndbrecord;
998 }
999
1000 int
aggregate(NdbError & error)1001 NdbDictionary::Table::aggregate(NdbError& error)
1002 {
1003 return m_impl.aggregate(error);
1004 }
1005
1006 int
validate(NdbError & error)1007 NdbDictionary::Table::validate(NdbError& error)
1008 {
1009 return m_impl.validate(error);
1010 }
1011
1012 Uint32
getPartitionId(Uint32 hashValue) const1013 NdbDictionary::Table::getPartitionId(Uint32 hashValue) const
1014 {
1015 switch (m_impl.m_fragmentType){
1016 case NdbDictionary::Object::FragAllSmall:
1017 case NdbDictionary::Object::FragAllMedium:
1018 case NdbDictionary::Object::FragAllLarge:
1019 case NdbDictionary::Object::FragSingle:
1020 case NdbDictionary::Object::DistrKeyLin:
1021 {
1022 Uint32 fragmentId = hashValue & m_impl.m_hashValueMask;
1023 if(fragmentId < m_impl.m_hashpointerValue)
1024 fragmentId = hashValue & ((m_impl.m_hashValueMask << 1) + 1);
1025 return fragmentId;
1026 }
1027 case NdbDictionary::Object::DistrKeyHash:
1028 {
1029 Uint32 cnt = m_impl.m_fragmentCount;
1030 return hashValue % (cnt ? cnt : 1);
1031 }
1032 case NdbDictionary::Object::HashMapPartition:
1033 {
1034 Uint32 cnt = m_impl.m_hash_map.size();
1035 return m_impl.m_hash_map[hashValue % cnt];
1036 }
1037 default:
1038 return 0;
1039 }
1040 }
1041
1042 void
assignObjId(const NdbDictionary::ObjectId & _objId)1043 NdbDictionary::Table::assignObjId(const NdbDictionary::ObjectId& _objId)
1044 {
1045 const NdbDictObjectImpl& objId = NdbDictObjectImpl::getImpl(_objId);
1046 m_impl.m_id = objId.m_id;
1047 m_impl.m_version = objId.m_version;
1048 }
1049
1050 void
setStorageType(NdbDictionary::Column::StorageType type)1051 NdbDictionary::Table::setStorageType(NdbDictionary::Column::StorageType type)
1052 {
1053 m_impl.m_storageType = type;
1054 }
1055
1056 NdbDictionary::Column::StorageType
getStorageType() const1057 NdbDictionary::Table::getStorageType() const
1058 {
1059 return (NdbDictionary::Column::StorageType)m_impl.m_storageType;
1060 }
1061
1062 /*****************************************************************
1063 * Index facade
1064 */
1065
Index(const char * name)1066 NdbDictionary::Index::Index(const char * name)
1067 : m_impl(* new NdbIndexImpl(* this))
1068 {
1069 setName(name);
1070 }
1071
Index(NdbIndexImpl & impl)1072 NdbDictionary::Index::Index(NdbIndexImpl & impl)
1073 : m_impl(impl)
1074 {
1075 }
1076
~Index()1077 NdbDictionary::Index::~Index(){
1078 NdbIndexImpl * tmp = &m_impl;
1079 if(this != tmp){
1080 delete tmp;
1081 }
1082 }
1083
1084 int
setName(const char * name)1085 NdbDictionary::Index::setName(const char * name){
1086 return m_impl.setName(name);
1087 }
1088
1089 const char *
getName() const1090 NdbDictionary::Index::getName() const {
1091 return m_impl.getName();
1092 }
1093
1094 int
setTable(const char * table)1095 NdbDictionary::Index::setTable(const char * table){
1096 return m_impl.setTable(table);
1097 }
1098
1099 const char *
getTable() const1100 NdbDictionary::Index::getTable() const {
1101 return m_impl.getTable();
1102 }
1103
1104 unsigned
getNoOfColumns() const1105 NdbDictionary::Index::getNoOfColumns() const {
1106 return m_impl.m_columns.size();
1107 }
1108
1109 int
getNoOfIndexColumns() const1110 NdbDictionary::Index::getNoOfIndexColumns() const {
1111 return m_impl.m_columns.size();
1112 }
1113
1114 const NdbDictionary::Column *
getColumn(unsigned no) const1115 NdbDictionary::Index::getColumn(unsigned no) const {
1116 if(no < m_impl.m_columns.size())
1117 return m_impl.m_columns[no];
1118 return NULL;
1119 }
1120
1121 const char *
getIndexColumn(int no) const1122 NdbDictionary::Index::getIndexColumn(int no) const {
1123 const NdbDictionary::Column* col = getColumn(no);
1124
1125 if (col)
1126 return col->getName();
1127 else
1128 return NULL;
1129 }
1130
1131 const NdbRecord*
getDefaultRecord() const1132 NdbDictionary::Index::getDefaultRecord() const {
1133 return m_impl.m_table->m_ndbrecord;
1134 }
1135
1136 int
addColumn(const Column & c)1137 NdbDictionary::Index::addColumn(const Column & c){
1138 NdbColumnImpl* col = new NdbColumnImpl;
1139 if (col == NULL)
1140 {
1141 errno = ENOMEM;
1142 return -1;
1143 }
1144 (* col) = NdbColumnImpl::getImpl(c);
1145
1146 col->m_indexSourced=true;
1147
1148 /* Remove defaults from indexed columns */
1149 col->m_defaultValue.clear();
1150
1151 if (m_impl.m_columns.push_back(col))
1152 {
1153 return -1;
1154 }
1155 return 0;
1156 }
1157
1158 int
addColumnName(const char * name)1159 NdbDictionary::Index::addColumnName(const char * name){
1160 const Column c(name);
1161 return addColumn(c);
1162 }
1163
1164 int
addIndexColumn(const char * name)1165 NdbDictionary::Index::addIndexColumn(const char * name){
1166 const Column c(name);
1167 return addColumn(c);
1168 }
1169
1170 int
addColumnNames(unsigned noOfNames,const char ** names)1171 NdbDictionary::Index::addColumnNames(unsigned noOfNames, const char ** names){
1172 for(unsigned i = 0; i < noOfNames; i++) {
1173 const Column c(names[i]);
1174 if (addColumn(c))
1175 {
1176 return -1;
1177 }
1178 }
1179 return 0;
1180 }
1181
1182 int
addIndexColumns(int noOfNames,const char ** names)1183 NdbDictionary::Index::addIndexColumns(int noOfNames, const char ** names){
1184 for(int i = 0; i < noOfNames; i++) {
1185 const Column c(names[i]);
1186 if (addColumn(c))
1187 {
1188 return -1;
1189 }
1190 }
1191 return 0;
1192 }
1193
1194 void
setType(NdbDictionary::Index::Type t)1195 NdbDictionary::Index::setType(NdbDictionary::Index::Type t){
1196 m_impl.m_type = (NdbDictionary::Object::Type)t;
1197 }
1198
1199 NdbDictionary::Index::Type
getType() const1200 NdbDictionary::Index::getType() const {
1201 return (NdbDictionary::Index::Type)m_impl.m_type;
1202 }
1203
1204 void
setLogging(bool val)1205 NdbDictionary::Index::setLogging(bool val){
1206 m_impl.m_logging = val;
1207 }
1208
1209 bool
getTemporary() const1210 NdbDictionary::Index::getTemporary() const {
1211 return m_impl.m_temporary;
1212 }
1213
1214 void
setTemporary(bool val)1215 NdbDictionary::Index::setTemporary(bool val){
1216 m_impl.m_temporary = val;
1217 }
1218
1219 bool
getLogging() const1220 NdbDictionary::Index::getLogging() const {
1221 return m_impl.m_logging;
1222 }
1223
1224 NdbDictionary::Object::Status
getObjectStatus() const1225 NdbDictionary::Index::getObjectStatus() const {
1226 return m_impl.m_table->m_status;
1227 }
1228
1229 int
getObjectVersion() const1230 NdbDictionary::Index::getObjectVersion() const {
1231 return m_impl.m_table->m_version;
1232 }
1233
1234 int
getObjectId() const1235 NdbDictionary::Index::getObjectId() const {
1236 return m_impl.m_table->m_id;
1237 }
1238
1239 /*****************************************************************
1240 * OptimizeTableHandle facade
1241 */
OptimizeTableHandle()1242 NdbDictionary::OptimizeTableHandle::OptimizeTableHandle()
1243 : m_impl(* new NdbOptimizeTableHandleImpl(* this))
1244 {}
1245
OptimizeTableHandle(NdbOptimizeTableHandleImpl & impl)1246 NdbDictionary::OptimizeTableHandle::OptimizeTableHandle(NdbOptimizeTableHandleImpl & impl)
1247 : m_impl(impl)
1248 {}
1249
~OptimizeTableHandle()1250 NdbDictionary::OptimizeTableHandle::~OptimizeTableHandle()
1251 {
1252 NdbOptimizeTableHandleImpl * tmp = &m_impl;
1253 if(this != tmp){
1254 delete tmp;
1255 }
1256 }
1257
1258 int
next()1259 NdbDictionary::OptimizeTableHandle::next()
1260 {
1261 return m_impl.next();
1262 }
1263
1264 int
close()1265 NdbDictionary::OptimizeTableHandle::close()
1266 {
1267 int result = m_impl.close();
1268 return result;
1269 }
1270
1271 /*****************************************************************
1272 * OptimizeIndexHandle facade
1273 */
OptimizeIndexHandle()1274 NdbDictionary::OptimizeIndexHandle::OptimizeIndexHandle()
1275 : m_impl(* new NdbOptimizeIndexHandleImpl(* this))
1276 {}
1277
OptimizeIndexHandle(NdbOptimizeIndexHandleImpl & impl)1278 NdbDictionary::OptimizeIndexHandle::OptimizeIndexHandle(NdbOptimizeIndexHandleImpl & impl)
1279 : m_impl(impl)
1280 {}
1281
~OptimizeIndexHandle()1282 NdbDictionary::OptimizeIndexHandle::~OptimizeIndexHandle()
1283 {
1284 NdbOptimizeIndexHandleImpl * tmp = &m_impl;
1285 if(this != tmp){
1286 delete tmp;
1287 }
1288 }
1289
1290 int
next()1291 NdbDictionary::OptimizeIndexHandle::next()
1292 {
1293 return m_impl.next();
1294 }
1295
1296 int
close()1297 NdbDictionary::OptimizeIndexHandle::close()
1298 {
1299 int result = m_impl.close();
1300 return result;
1301 }
1302
1303 /*****************************************************************
1304 * Event facade
1305 */
Event(const char * name)1306 NdbDictionary::Event::Event(const char * name)
1307 : m_impl(* new NdbEventImpl(* this))
1308 {
1309 setName(name);
1310 }
1311
Event(const char * name,const Table & table)1312 NdbDictionary::Event::Event(const char * name, const Table& table)
1313 : m_impl(* new NdbEventImpl(* this))
1314 {
1315 setName(name);
1316 setTable(table);
1317 }
1318
Event(NdbEventImpl & impl)1319 NdbDictionary::Event::Event(NdbEventImpl & impl)
1320 : m_impl(impl)
1321 {
1322 }
1323
~Event()1324 NdbDictionary::Event::~Event()
1325 {
1326 NdbEventImpl * tmp = &m_impl;
1327 if(this != tmp){
1328 delete tmp;
1329 }
1330 }
1331
1332 int
setName(const char * name)1333 NdbDictionary::Event::setName(const char * name)
1334 {
1335 return m_impl.setName(name);
1336 }
1337
1338 const char *
getName() const1339 NdbDictionary::Event::getName() const
1340 {
1341 return m_impl.getName();
1342 }
1343
1344 void
setTable(const Table & table)1345 NdbDictionary::Event::setTable(const Table& table)
1346 {
1347 m_impl.setTable(table);
1348 }
1349
1350 int
setTable(const Table * table)1351 NdbDictionary::Event::setTable(const Table *table)
1352 {
1353 return m_impl.setTable(table);
1354 }
1355
1356 const NdbDictionary::Table *
getTable() const1357 NdbDictionary::Event::getTable() const
1358 {
1359 return m_impl.getTable();
1360 }
1361
1362 int
setTable(const char * table)1363 NdbDictionary::Event::setTable(const char * table)
1364 {
1365 return m_impl.setTable(table);
1366 }
1367
1368 const char*
getTableName() const1369 NdbDictionary::Event::getTableName() const
1370 {
1371 return m_impl.getTableName();
1372 }
1373
1374 void
addTableEvent(const TableEvent t)1375 NdbDictionary::Event::addTableEvent(const TableEvent t)
1376 {
1377 m_impl.addTableEvent(t);
1378 }
1379
1380 bool
getTableEvent(const TableEvent t) const1381 NdbDictionary::Event::getTableEvent(const TableEvent t) const
1382 {
1383 return m_impl.getTableEvent(t);
1384 }
1385
1386 void
setDurability(EventDurability d)1387 NdbDictionary::Event::setDurability(EventDurability d)
1388 {
1389 m_impl.setDurability(d);
1390 }
1391
1392 NdbDictionary::Event::EventDurability
getDurability() const1393 NdbDictionary::Event::getDurability() const
1394 {
1395 return m_impl.getDurability();
1396 }
1397
1398 void
setReport(EventReport r)1399 NdbDictionary::Event::setReport(EventReport r)
1400 {
1401 m_impl.setReport(r);
1402 }
1403
1404 NdbDictionary::Event::EventReport
getReport() const1405 NdbDictionary::Event::getReport() const
1406 {
1407 return m_impl.getReport();
1408 }
1409
1410 void
addColumn(const Column & c)1411 NdbDictionary::Event::addColumn(const Column & c){
1412 NdbColumnImpl* col = new NdbColumnImpl;
1413 (* col) = NdbColumnImpl::getImpl(c);
1414 m_impl.m_columns.push_back(col);
1415 }
1416
1417 void
addEventColumn(unsigned attrId)1418 NdbDictionary::Event::addEventColumn(unsigned attrId)
1419 {
1420 m_impl.m_attrIds.push_back(attrId);
1421 }
1422
1423 void
addEventColumn(const char * name)1424 NdbDictionary::Event::addEventColumn(const char * name)
1425 {
1426 const Column c(name);
1427 addColumn(c);
1428 }
1429
1430 void
addEventColumns(int n,const char ** names)1431 NdbDictionary::Event::addEventColumns(int n, const char ** names)
1432 {
1433 for (int i = 0; i < n; i++)
1434 addEventColumn(names[i]);
1435 }
1436
getNoOfEventColumns() const1437 int NdbDictionary::Event::getNoOfEventColumns() const
1438 {
1439 return m_impl.getNoOfEventColumns();
1440 }
1441
1442 const NdbDictionary::Column *
getEventColumn(unsigned no) const1443 NdbDictionary::Event::getEventColumn(unsigned no) const
1444 {
1445 return m_impl.getEventColumn(no);
1446 }
1447
mergeEvents(bool flag)1448 void NdbDictionary::Event::mergeEvents(bool flag)
1449 {
1450 m_impl.m_mergeEvents = flag;
1451 }
1452
1453 NdbDictionary::Object::Status
getObjectStatus() const1454 NdbDictionary::Event::getObjectStatus() const
1455 {
1456 return m_impl.m_status;
1457 }
1458
1459 int
getObjectVersion() const1460 NdbDictionary::Event::getObjectVersion() const
1461 {
1462 return m_impl.m_version;
1463 }
1464
1465 int
getObjectId() const1466 NdbDictionary::Event::getObjectId() const {
1467 return m_impl.m_id;
1468 }
1469
print()1470 void NdbDictionary::Event::print()
1471 {
1472 m_impl.print();
1473 }
1474
1475 /*****************************************************************
1476 * Tablespace facade
1477 */
Tablespace()1478 NdbDictionary::Tablespace::Tablespace()
1479 : m_impl(* new NdbTablespaceImpl(* this))
1480 {
1481 }
1482
Tablespace(NdbTablespaceImpl & impl)1483 NdbDictionary::Tablespace::Tablespace(NdbTablespaceImpl & impl)
1484 : m_impl(impl)
1485 {
1486 }
1487
Tablespace(const NdbDictionary::Tablespace & org)1488 NdbDictionary::Tablespace::Tablespace(const NdbDictionary::Tablespace & org)
1489 : Object(org), m_impl(* new NdbTablespaceImpl(* this))
1490 {
1491 m_impl.assign(org.m_impl);
1492 }
1493
~Tablespace()1494 NdbDictionary::Tablespace::~Tablespace(){
1495 NdbTablespaceImpl * tmp = &m_impl;
1496 if(this != tmp){
1497 delete tmp;
1498 }
1499 }
1500
1501 void
setName(const char * name)1502 NdbDictionary::Tablespace::setName(const char * name){
1503 m_impl.m_name.assign(name);
1504 }
1505
1506 const char *
getName() const1507 NdbDictionary::Tablespace::getName() const {
1508 return m_impl.m_name.c_str();
1509 }
1510
1511 void
setAutoGrowSpecification(const NdbDictionary::AutoGrowSpecification & spec)1512 NdbDictionary::Tablespace::setAutoGrowSpecification
1513 (const NdbDictionary::AutoGrowSpecification& spec){
1514 m_impl.m_grow_spec = spec;
1515 }
1516 const NdbDictionary::AutoGrowSpecification&
getAutoGrowSpecification() const1517 NdbDictionary::Tablespace::getAutoGrowSpecification() const {
1518 return m_impl.m_grow_spec;
1519 }
1520
1521 void
setExtentSize(Uint32 sz)1522 NdbDictionary::Tablespace::setExtentSize(Uint32 sz){
1523 m_impl.m_extent_size = sz;
1524 }
1525
1526 Uint32
getExtentSize() const1527 NdbDictionary::Tablespace::getExtentSize() const {
1528 return m_impl.m_extent_size;
1529 }
1530
1531 void
setDefaultLogfileGroup(const char * name)1532 NdbDictionary::Tablespace::setDefaultLogfileGroup(const char * name){
1533 m_impl.m_logfile_group_id = ~0;
1534 m_impl.m_logfile_group_version = ~0;
1535 m_impl.m_logfile_group_name.assign(name);
1536 }
1537
1538 void
setDefaultLogfileGroup(const NdbDictionary::LogfileGroup & lg)1539 NdbDictionary::Tablespace::setDefaultLogfileGroup
1540 (const NdbDictionary::LogfileGroup & lg){
1541 m_impl.m_logfile_group_id = NdbLogfileGroupImpl::getImpl(lg).m_id;
1542 m_impl.m_logfile_group_version = lg.getObjectVersion();
1543 m_impl.m_logfile_group_name.assign(lg.getName());
1544 }
1545
1546 const char *
getDefaultLogfileGroup() const1547 NdbDictionary::Tablespace::getDefaultLogfileGroup() const {
1548 return m_impl.m_logfile_group_name.c_str();
1549 }
1550
1551 Uint32
getDefaultLogfileGroupId() const1552 NdbDictionary::Tablespace::getDefaultLogfileGroupId() const {
1553 return m_impl.m_logfile_group_id;
1554 }
1555
1556 NdbDictionary::Object::Status
getObjectStatus() const1557 NdbDictionary::Tablespace::getObjectStatus() const {
1558 return m_impl.m_status;
1559 }
1560
1561 int
getObjectVersion() const1562 NdbDictionary::Tablespace::getObjectVersion() const {
1563 return m_impl.m_version;
1564 }
1565
1566 int
getObjectId() const1567 NdbDictionary::Tablespace::getObjectId() const {
1568 return m_impl.m_id;
1569 }
1570
1571 /*****************************************************************
1572 * LogfileGroup facade
1573 */
LogfileGroup()1574 NdbDictionary::LogfileGroup::LogfileGroup()
1575 : m_impl(* new NdbLogfileGroupImpl(* this))
1576 {
1577 }
1578
LogfileGroup(NdbLogfileGroupImpl & impl)1579 NdbDictionary::LogfileGroup::LogfileGroup(NdbLogfileGroupImpl & impl)
1580 : m_impl(impl)
1581 {
1582 }
1583
LogfileGroup(const NdbDictionary::LogfileGroup & org)1584 NdbDictionary::LogfileGroup::LogfileGroup(const NdbDictionary::LogfileGroup & org)
1585 : Object(org), m_impl(* new NdbLogfileGroupImpl(* this))
1586 {
1587 m_impl.assign(org.m_impl);
1588 }
1589
~LogfileGroup()1590 NdbDictionary::LogfileGroup::~LogfileGroup(){
1591 NdbLogfileGroupImpl * tmp = &m_impl;
1592 if(this != tmp){
1593 delete tmp;
1594 }
1595 }
1596
1597 void
setName(const char * name)1598 NdbDictionary::LogfileGroup::setName(const char * name){
1599 m_impl.m_name.assign(name);
1600 }
1601
1602 const char *
getName() const1603 NdbDictionary::LogfileGroup::getName() const {
1604 return m_impl.m_name.c_str();
1605 }
1606
1607 void
setUndoBufferSize(Uint32 sz)1608 NdbDictionary::LogfileGroup::setUndoBufferSize(Uint32 sz){
1609 m_impl.m_undo_buffer_size = sz;
1610 }
1611
1612 Uint32
getUndoBufferSize() const1613 NdbDictionary::LogfileGroup::getUndoBufferSize() const {
1614 return m_impl.m_undo_buffer_size;
1615 }
1616
1617 void
setAutoGrowSpecification(const NdbDictionary::AutoGrowSpecification & spec)1618 NdbDictionary::LogfileGroup::setAutoGrowSpecification
1619 (const NdbDictionary::AutoGrowSpecification& spec){
1620 m_impl.m_grow_spec = spec;
1621 }
1622 const NdbDictionary::AutoGrowSpecification&
getAutoGrowSpecification() const1623 NdbDictionary::LogfileGroup::getAutoGrowSpecification() const {
1624 return m_impl.m_grow_spec;
1625 }
1626
getUndoFreeWords() const1627 Uint64 NdbDictionary::LogfileGroup::getUndoFreeWords() const {
1628 return m_impl.m_undo_free_words;
1629 }
1630
1631 NdbDictionary::Object::Status
getObjectStatus() const1632 NdbDictionary::LogfileGroup::getObjectStatus() const {
1633 return m_impl.m_status;
1634 }
1635
1636 int
getObjectVersion() const1637 NdbDictionary::LogfileGroup::getObjectVersion() const {
1638 return m_impl.m_version;
1639 }
1640
1641 int
getObjectId() const1642 NdbDictionary::LogfileGroup::getObjectId() const {
1643 return m_impl.m_id;
1644 }
1645
1646 /*****************************************************************
1647 * Datafile facade
1648 */
Datafile()1649 NdbDictionary::Datafile::Datafile()
1650 : m_impl(* new NdbDatafileImpl(* this))
1651 {
1652 }
1653
Datafile(NdbDatafileImpl & impl)1654 NdbDictionary::Datafile::Datafile(NdbDatafileImpl & impl)
1655 : m_impl(impl)
1656 {
1657 }
1658
Datafile(const NdbDictionary::Datafile & org)1659 NdbDictionary::Datafile::Datafile(const NdbDictionary::Datafile & org)
1660 : Object(org), m_impl(* new NdbDatafileImpl(* this))
1661 {
1662 m_impl.assign(org.m_impl);
1663 }
1664
~Datafile()1665 NdbDictionary::Datafile::~Datafile(){
1666 NdbDatafileImpl * tmp = &m_impl;
1667 if(this != tmp){
1668 delete tmp;
1669 }
1670 }
1671
1672 void
setPath(const char * path)1673 NdbDictionary::Datafile::setPath(const char * path){
1674 m_impl.m_path.assign(path);
1675 }
1676
1677 const char *
getPath() const1678 NdbDictionary::Datafile::getPath() const {
1679 return m_impl.m_path.c_str();
1680 }
1681
1682 void
setSize(Uint64 sz)1683 NdbDictionary::Datafile::setSize(Uint64 sz){
1684 m_impl.m_size = sz;
1685 }
1686
1687 Uint64
getSize() const1688 NdbDictionary::Datafile::getSize() const {
1689 return m_impl.m_size;
1690 }
1691
1692 Uint64
getFree() const1693 NdbDictionary::Datafile::getFree() const {
1694 return m_impl.m_free;
1695 }
1696
1697 int
setTablespace(const char * tablespace)1698 NdbDictionary::Datafile::setTablespace(const char * tablespace){
1699 m_impl.m_filegroup_id = ~0;
1700 m_impl.m_filegroup_version = ~0;
1701 return !m_impl.m_filegroup_name.assign(tablespace);
1702 }
1703
1704 int
setTablespace(const NdbDictionary::Tablespace & ts)1705 NdbDictionary::Datafile::setTablespace(const NdbDictionary::Tablespace & ts){
1706 m_impl.m_filegroup_id = NdbTablespaceImpl::getImpl(ts).m_id;
1707 m_impl.m_filegroup_version = ts.getObjectVersion();
1708 return !m_impl.m_filegroup_name.assign(ts.getName());
1709 }
1710
1711 const char *
getTablespace() const1712 NdbDictionary::Datafile::getTablespace() const {
1713 return m_impl.m_filegroup_name.c_str();
1714 }
1715
1716 void
getTablespaceId(NdbDictionary::ObjectId * dst) const1717 NdbDictionary::Datafile::getTablespaceId(NdbDictionary::ObjectId* dst) const
1718 {
1719 if (dst)
1720 {
1721 NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id;
1722 NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version;
1723 }
1724 }
1725
1726 NdbDictionary::Object::Status
getObjectStatus() const1727 NdbDictionary::Datafile::getObjectStatus() const {
1728 return m_impl.m_status;
1729 }
1730
1731 int
getObjectVersion() const1732 NdbDictionary::Datafile::getObjectVersion() const {
1733 return m_impl.m_version;
1734 }
1735
1736 int
getObjectId() const1737 NdbDictionary::Datafile::getObjectId() const {
1738 return m_impl.m_id;
1739 }
1740
1741 /*****************************************************************
1742 * Undofile facade
1743 */
Undofile()1744 NdbDictionary::Undofile::Undofile()
1745 : m_impl(* new NdbUndofileImpl(* this))
1746 {
1747 }
1748
Undofile(NdbUndofileImpl & impl)1749 NdbDictionary::Undofile::Undofile(NdbUndofileImpl & impl)
1750 : m_impl(impl)
1751 {
1752 }
1753
Undofile(const NdbDictionary::Undofile & org)1754 NdbDictionary::Undofile::Undofile(const NdbDictionary::Undofile & org)
1755 : Object(org), m_impl(* new NdbUndofileImpl(* this))
1756 {
1757 m_impl.assign(org.m_impl);
1758 }
1759
~Undofile()1760 NdbDictionary::Undofile::~Undofile(){
1761 NdbUndofileImpl * tmp = &m_impl;
1762 if(this != tmp){
1763 delete tmp;
1764 }
1765 }
1766
1767 void
setPath(const char * path)1768 NdbDictionary::Undofile::setPath(const char * path){
1769 m_impl.m_path.assign(path);
1770 }
1771
1772 const char *
getPath() const1773 NdbDictionary::Undofile::getPath() const {
1774 return m_impl.m_path.c_str();
1775 }
1776
1777 void
setSize(Uint64 sz)1778 NdbDictionary::Undofile::setSize(Uint64 sz){
1779 m_impl.m_size = sz;
1780 }
1781
1782 Uint64
getSize() const1783 NdbDictionary::Undofile::getSize() const {
1784 return m_impl.m_size;
1785 }
1786
1787 void
setLogfileGroup(const char * logfileGroup)1788 NdbDictionary::Undofile::setLogfileGroup(const char * logfileGroup){
1789 m_impl.m_filegroup_id = ~0;
1790 m_impl.m_filegroup_version = ~0;
1791 m_impl.m_filegroup_name.assign(logfileGroup);
1792 }
1793
1794 void
setLogfileGroup(const NdbDictionary::LogfileGroup & ts)1795 NdbDictionary::Undofile::setLogfileGroup
1796 (const NdbDictionary::LogfileGroup & ts){
1797 m_impl.m_filegroup_id = NdbLogfileGroupImpl::getImpl(ts).m_id;
1798 m_impl.m_filegroup_version = ts.getObjectVersion();
1799 m_impl.m_filegroup_name.assign(ts.getName());
1800 }
1801
1802 const char *
getLogfileGroup() const1803 NdbDictionary::Undofile::getLogfileGroup() const {
1804 return m_impl.m_filegroup_name.c_str();
1805 }
1806
1807 void
getLogfileGroupId(NdbDictionary::ObjectId * dst) const1808 NdbDictionary::Undofile::getLogfileGroupId(NdbDictionary::ObjectId * dst)const
1809 {
1810 if (dst)
1811 {
1812 NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id;
1813 NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version;
1814 }
1815 }
1816
1817 NdbDictionary::Object::Status
getObjectStatus() const1818 NdbDictionary::Undofile::getObjectStatus() const {
1819 return m_impl.m_status;
1820 }
1821
1822 int
getObjectVersion() const1823 NdbDictionary::Undofile::getObjectVersion() const {
1824 return m_impl.m_version;
1825 }
1826
1827 int
getObjectId() const1828 NdbDictionary::Undofile::getObjectId() const {
1829 return m_impl.m_id;
1830 }
1831
1832 /*****************************************************************
1833 * HashMap facade
1834 */
HashMap()1835 NdbDictionary::HashMap::HashMap()
1836 : m_impl(* new NdbHashMapImpl(* this))
1837 {
1838 }
1839
HashMap(NdbHashMapImpl & impl)1840 NdbDictionary::HashMap::HashMap(NdbHashMapImpl & impl)
1841 : m_impl(impl)
1842 {
1843 }
1844
HashMap(const NdbDictionary::HashMap & org)1845 NdbDictionary::HashMap::HashMap(const NdbDictionary::HashMap & org)
1846 : Object(org), m_impl(* new NdbHashMapImpl(* this))
1847 {
1848 m_impl.assign(org.m_impl);
1849 }
1850
~HashMap()1851 NdbDictionary::HashMap::~HashMap(){
1852 NdbHashMapImpl * tmp = &m_impl;
1853 if(this != tmp){
1854 delete tmp;
1855 }
1856 }
1857
1858 void
setName(const char * path)1859 NdbDictionary::HashMap::setName(const char * path)
1860 {
1861 m_impl.m_name.assign(path);
1862 }
1863
1864 const char *
getName() const1865 NdbDictionary::HashMap::getName() const
1866 {
1867 return m_impl.m_name.c_str();
1868 }
1869
1870 void
setMap(const Uint32 * map,Uint32 len)1871 NdbDictionary::HashMap::setMap(const Uint32* map, Uint32 len)
1872 {
1873 m_impl.m_map.assign(map, len);
1874 }
1875
1876 Uint32
getMapLen() const1877 NdbDictionary::HashMap::getMapLen() const
1878 {
1879 return m_impl.m_map.size();
1880 }
1881
1882 int
getMapValues(Uint32 * dst,Uint32 len) const1883 NdbDictionary::HashMap::getMapValues(Uint32* dst, Uint32 len) const
1884 {
1885 if (len != getMapLen())
1886 return -1;
1887
1888 memcpy(dst, m_impl.m_map.getBase(), sizeof(Uint32) * len);
1889 return 0;
1890 }
1891
1892 bool
equal(const NdbDictionary::HashMap & obj) const1893 NdbDictionary::HashMap::equal(const NdbDictionary::HashMap & obj) const
1894 {
1895 return m_impl.m_map.equal(obj.m_impl.m_map);
1896 }
1897
1898 NdbDictionary::Object::Status
getObjectStatus() const1899 NdbDictionary::HashMap::getObjectStatus() const {
1900 return m_impl.m_status;
1901 }
1902
1903 int
getObjectVersion() const1904 NdbDictionary::HashMap::getObjectVersion() const {
1905 return m_impl.m_version;
1906 }
1907
1908 int
getObjectId() const1909 NdbDictionary::HashMap::getObjectId() const {
1910 return m_impl.m_id;
1911 }
1912
1913 int
getDefaultHashMap(NdbDictionary::HashMap & dst,Uint32 fragments)1914 NdbDictionary::Dictionary::getDefaultHashMap(NdbDictionary::HashMap& dst,
1915 Uint32 fragments)
1916 {
1917 return getDefaultHashMap(dst, m_impl.getDefaultHashmapSize(), fragments);
1918 }
1919
1920 int
getDefaultHashMap(NdbDictionary::HashMap & dst,Uint32 buckets,Uint32 fragments)1921 NdbDictionary::Dictionary::getDefaultHashMap(NdbDictionary::HashMap& dst,
1922 Uint32 buckets,
1923 Uint32 fragments)
1924 {
1925 BaseString tmp;
1926 tmp.assfmt("DEFAULT-HASHMAP-%u-%u",
1927 buckets, fragments);
1928
1929 return getHashMap(dst, tmp.c_str());
1930 }
1931
1932 int
getHashMap(NdbDictionary::HashMap & dst,const char * name)1933 NdbDictionary::Dictionary::getHashMap(NdbDictionary::HashMap& dst,
1934 const char * name)
1935 {
1936 return m_impl.m_receiver.get_hashmap(NdbHashMapImpl::getImpl(dst), name);
1937 }
1938
1939 int
getHashMap(NdbDictionary::HashMap & dst,const NdbDictionary::Table * tab)1940 NdbDictionary::Dictionary::getHashMap(NdbDictionary::HashMap& dst,
1941 const NdbDictionary::Table* tab)
1942 {
1943 if (tab == 0 ||
1944 tab->getFragmentType() != NdbDictionary::Object::HashMapPartition)
1945 {
1946 return -1;
1947 }
1948 return
1949 m_impl.m_receiver.get_hashmap(NdbHashMapImpl::getImpl(dst),
1950 NdbTableImpl::getImpl(*tab).m_hash_map_id);
1951 }
1952
1953 int
initDefaultHashMap(NdbDictionary::HashMap & dst,Uint32 fragments)1954 NdbDictionary::Dictionary::initDefaultHashMap(NdbDictionary::HashMap& dst,
1955 Uint32 fragments)
1956 {
1957 return initDefaultHashMap(dst, m_impl.getDefaultHashmapSize(), fragments);
1958 }
1959
1960 int
initDefaultHashMap(NdbDictionary::HashMap & dst,Uint32 buckets,Uint32 fragments)1961 NdbDictionary::Dictionary::initDefaultHashMap(NdbDictionary::HashMap& dst,
1962 Uint32 buckets,
1963 Uint32 fragments)
1964 {
1965 BaseString tmp;
1966 tmp.assfmt("DEFAULT-HASHMAP-%u-%u",
1967 buckets, fragments);
1968
1969 dst.setName(tmp.c_str());
1970
1971 Vector<Uint32> map;
1972 for (Uint32 i = 0; i < buckets; i++)
1973 {
1974 map.push_back(i % fragments);
1975 }
1976
1977 dst.setMap(map.getBase(), map.size());
1978 return 0;
1979 }
1980
1981 int
prepareHashMap(const Table & oldTableF,Table & newTableF)1982 NdbDictionary::Dictionary::prepareHashMap(const Table& oldTableF,
1983 Table& newTableF)
1984 {
1985 return prepareHashMap(oldTableF, newTableF, m_impl.getDefaultHashmapSize());
1986 }
1987
1988 int
prepareHashMap(const Table & oldTableF,Table & newTableF,Uint32 buckets)1989 NdbDictionary::Dictionary::prepareHashMap(const Table& oldTableF,
1990 Table& newTableF,
1991 Uint32 buckets)
1992 {
1993 if (!hasSchemaTrans())
1994 {
1995 return -1;
1996 }
1997
1998 const NdbTableImpl& oldTable = NdbTableImpl::getImpl(oldTableF);
1999 NdbTableImpl& newTable = NdbTableImpl::getImpl(newTableF);
2000
2001 if (oldTable.getFragmentType() == NdbDictionary::Object::HashMapPartition)
2002 {
2003 HashMap oldmap;
2004 if (getHashMap(oldmap, &oldTable) == -1)
2005 {
2006 return -1;
2007 }
2008
2009 if (oldmap.getObjectVersion() != (int)oldTable.m_hash_map_version)
2010 {
2011 return -1;
2012 }
2013
2014 HashMap newmapF;
2015
2016 Uint32 oldcnt = oldTable.getFragmentCount();
2017 Uint32 newcnt = newTable.getFragmentCount();
2018 if (newcnt == 0)
2019 {
2020 /**
2021 * reorg...we don't know how many fragments new table should have
2022 * create if exist a default map...which will "know" how many fragments there are
2023 */
2024 ObjectId tmp;
2025 int ret = m_impl.m_receiver.create_hashmap(NdbHashMapImpl::getImpl(newmapF),
2026 &NdbDictObjectImpl::getImpl(tmp),
2027 CreateHashMapReq::CreateDefault |
2028 CreateHashMapReq::CreateIfNotExists);
2029 if (ret)
2030 {
2031 return ret;
2032 }
2033
2034 HashMap hm;
2035 ret = m_impl.m_receiver.get_hashmap(NdbHashMapImpl::getImpl(hm), tmp.getObjectId());
2036 if (ret)
2037 {
2038 return ret;
2039 }
2040 Uint32 zero = 0;
2041 Vector<Uint32> values;
2042 values.fill(hm.getMapLen() - 1, zero);
2043 hm.getMapValues(values.getBase(), values.size());
2044 for (Uint32 i = 0; i<hm.getMapLen(); i++)
2045 {
2046 if (values[i] > newcnt)
2047 newcnt = values[i];
2048 }
2049 newcnt++; // Loop will find max val, cnt = max + 1
2050 if (newcnt < oldcnt)
2051 {
2052 /**
2053 * drop partition is currently not supported...
2054 * and since this is a "reorg" (newcnt == 0) we silently change it to a nop
2055 */
2056 newcnt = oldcnt;
2057 }
2058 newTable.setFragmentCount(newcnt);
2059 }
2060
2061 /*
2062 * if fragment count has not changed,
2063 * dont move data and keep old hashmap.
2064 */
2065
2066 if (newcnt == oldcnt)
2067 {
2068 newTable.m_hash_map_id = oldTable.m_hash_map_id;
2069 newTable.m_hash_map_version = oldTable.m_hash_map_version;
2070 return 0;
2071 }
2072
2073 Uint32 newmapsize = buckets;
2074 Uint32 oldmapsize = oldmap.getMapLen();
2075
2076 /**
2077 * if old hashmap size is smaller than new hashmap size
2078 * and new fragment count is a multiple of old hashmap
2079 * size, no need to extend map, keep old hashmap size
2080 */
2081
2082 if (oldmapsize < newmapsize &&
2083 oldmapsize % newcnt == 0)
2084 {
2085 newmapsize = oldmapsize;
2086 }
2087
2088 NdbHashMapImpl& newmap = NdbHashMapImpl::getImpl(newmapF);
2089 NdbHashMapImpl const& oldmapimpl = NdbHashMapImpl::getImpl(oldmap);
2090
2091 newmap.m_map.expand(newmapsize);
2092 for (Uint32 i = 0; i < newmapsize; i++)
2093 {
2094 Uint32 newval = i % newcnt;
2095 if (newval < oldcnt)
2096 {
2097 newval = oldmapimpl.m_map[i % oldmapsize];
2098 }
2099 newmap.m_map.push_back(newval);
2100 }
2101
2102 /**
2103 * check that new map do not imply data movement
2104 * from old fragment to another old fragment.
2105 * in such case, fall back to use old hashmap size
2106 */
2107
2108 if (oldmapsize != newmapsize)
2109 {
2110 Uint32 period = lcm(oldmapsize, newmapsize);
2111 Uint32 i;
2112
2113 for (i = 0; i < period; i++)
2114 {
2115 if (oldmapimpl.m_map[i % oldmapsize] != newmap.m_map[i % newmapsize] &&
2116 newmap.m_map[i % newmapsize] < oldcnt)
2117 {
2118 /**
2119 * move from old fragment to another old fragment
2120 * not supported - keep old hashmap size
2121 */
2122 break;
2123 }
2124 }
2125
2126 /* keep old hashmap size, recreate newmap */
2127 if (i < period)
2128 {
2129 newmapsize = oldmapsize;
2130 newmap.m_map.clear();
2131 newmap.m_map.expand(newmapsize);
2132 for (Uint32 i = 0; i < newmapsize; i++)
2133 {
2134 Uint32 newval = i % newcnt;
2135 if (newval < oldcnt)
2136 {
2137 newval = oldmapimpl.m_map[i % oldmapsize];
2138 }
2139 newmap.m_map.push_back(newval);
2140 }
2141 }
2142 }
2143
2144 /**
2145 * Check if this accidently became a "default" map
2146 */
2147 HashMap def;
2148 if (getDefaultHashMap(def, newmapsize, newcnt) == 0)
2149 {
2150 if (def.equal(newmapF))
2151 {
2152 newTable.m_hash_map_id = def.getObjectId();
2153 newTable.m_hash_map_version = def.getObjectVersion();
2154 return 0;
2155 }
2156 }
2157
2158 initDefaultHashMap(def, newmapsize, newcnt);
2159 if (def.equal(newmapF))
2160 {
2161 ObjectId tmp;
2162 if (createHashMap(def, &tmp) == -1)
2163 {
2164 return -1;
2165 }
2166 newTable.m_hash_map_id = tmp.getObjectId();
2167 newTable.m_hash_map_version = tmp.getObjectVersion();
2168 return 0;
2169 }
2170
2171 int cnt = 0;
2172 retry:
2173 if (cnt == 0)
2174 {
2175 newmap.m_name.assfmt("HASHMAP-%u-%u-%u",
2176 newmapsize,
2177 oldcnt,
2178 newcnt);
2179 }
2180 else
2181 {
2182 newmap.m_name.assfmt("HASHMAP-%u-%u-%u-#%u",
2183 newmapsize,
2184 oldcnt,
2185 newcnt,
2186 cnt);
2187
2188 }
2189
2190 if (getHashMap(def, newmap.getName()) == 0)
2191 {
2192 if (def.equal(newmap))
2193 {
2194 newTable.m_hash_map_id = def.getObjectId();
2195 newTable.m_hash_map_version = def.getObjectVersion();
2196 return 0;
2197 }
2198 cnt++;
2199 goto retry;
2200 }
2201
2202 ObjectId tmp;
2203 if (createHashMap(newmapF, &tmp) == -1)
2204 {
2205 return -1;
2206 }
2207 newTable.m_hash_map_id = tmp.getObjectId();
2208 newTable.m_hash_map_version = tmp.getObjectVersion();
2209 return 0;
2210 }
2211 assert(false); // NOT SUPPORTED YET
2212 return -1;
2213 }
2214
2215 /*****************************************************************
2216 * ForeignKey facade
2217 */
ForeignKey()2218 NdbDictionary::ForeignKey::ForeignKey()
2219 : m_impl(* new NdbForeignKeyImpl(* this))
2220 {
2221 }
2222
ForeignKey(NdbForeignKeyImpl & impl)2223 NdbDictionary::ForeignKey::ForeignKey(NdbForeignKeyImpl & impl)
2224 : m_impl(impl)
2225 {
2226 }
2227
ForeignKey(const NdbDictionary::ForeignKey & org)2228 NdbDictionary::ForeignKey::ForeignKey(const NdbDictionary::ForeignKey & org)
2229 : Object(org), m_impl(* new NdbForeignKeyImpl(* this))
2230 {
2231 m_impl.assign(org.m_impl);
2232 }
2233
~ForeignKey()2234 NdbDictionary::ForeignKey::~ForeignKey(){
2235 NdbForeignKeyImpl * tmp = &m_impl;
2236 if(this != tmp){
2237 delete tmp;
2238 }
2239 }
2240
2241 const char *
getName() const2242 NdbDictionary::ForeignKey::getName() const
2243 {
2244 return m_impl.m_name.c_str();
2245 }
2246
2247 NdbDictionary::Object::Status
getObjectStatus() const2248 NdbDictionary::ForeignKey::getObjectStatus() const {
2249 return m_impl.m_status;
2250 }
2251
2252 int
getObjectVersion() const2253 NdbDictionary::ForeignKey::getObjectVersion() const {
2254 return m_impl.m_version;
2255 }
2256
2257 int
getObjectId() const2258 NdbDictionary::ForeignKey::getObjectId() const {
2259 return m_impl.m_id;
2260 }
2261
2262 void
setName(const char * name)2263 NdbDictionary::ForeignKey::setName(const char * name)
2264 {
2265 m_impl.m_name.assign(name);
2266 }
2267
2268 void
setParent(const Table & tab,const Index * idx,const Column * cols[])2269 NdbDictionary::ForeignKey::setParent(const Table& tab,
2270 const Index * idx,
2271 const Column * cols[])
2272 {
2273 m_impl.m_references[0].m_name.assign(tab.getName());
2274 m_impl.m_references[0].m_objectId = RNIL;
2275 m_impl.m_references[0].m_objectVersion = RNIL;
2276 m_impl.m_references[2].m_name.clear();
2277 m_impl.m_references[2].m_objectId = RNIL;
2278 m_impl.m_references[2].m_objectVersion = RNIL;
2279
2280 switch(tab.getObjectStatus()) {
2281 case NdbDictionary::Object::New:
2282 break;
2283 default:
2284 m_impl.m_references[0].m_objectId = tab.getObjectId();
2285 m_impl.m_references[0].m_objectVersion = tab.getObjectVersion();
2286 break;
2287 }
2288
2289 if (idx)
2290 {
2291 m_impl.m_references[2].m_name.assign(idx->getName());
2292 switch(idx->getObjectStatus()){
2293 case NdbDictionary::Object::New:
2294 break;
2295 default:
2296 m_impl.m_references[2].m_objectId = idx->getObjectId();
2297 m_impl.m_references[2].m_objectVersion = idx->getObjectVersion();
2298 }
2299 }
2300
2301 m_impl.m_parent_columns.clear();
2302 if (cols)
2303 {
2304 for (Uint32 i = 0; cols[i] != 0; i++)
2305 {
2306 m_impl.m_parent_columns.push_back(cols[i]->getColumnNo());
2307 }
2308 }
2309 else if (idx == 0)
2310 {
2311 for (int i = 0; i < tab.getNoOfColumns(); i++)
2312 {
2313 if (tab.getColumn(i)->getPrimaryKey())
2314 {
2315 m_impl.m_parent_columns.push_back(tab.getColumn(i)->getColumnNo());
2316 }
2317 }
2318 }
2319 else
2320 {
2321 for (unsigned i = 0; i < idx->getNoOfColumns(); i++)
2322 {
2323 const Column * idxcol = idx->getColumn(i);
2324 const Column * tabcol = tab.getColumn(idxcol->getName());
2325 if (tabcol)
2326 {
2327 // no way of reporting error...just add the if...
2328 // and let dict complain at ::create()
2329 m_impl.m_parent_columns.push_back(tabcol->getColumnNo());
2330 }
2331 }
2332 }
2333 }
2334
2335 const char *
getParentTable() const2336 NdbDictionary::ForeignKey::getParentTable() const
2337 {
2338 return m_impl.m_references[0].m_name.c_str();
2339 }
2340
2341 const char *
getParentIndex() const2342 NdbDictionary::ForeignKey::getParentIndex() const
2343 {
2344 if (m_impl.m_references[2].m_name.empty())
2345 return 0;
2346 return m_impl.m_references[2].m_name.c_str();
2347 }
2348
2349 void
setChild(const Table & tab,const Index * idx,const Column * cols[])2350 NdbDictionary::ForeignKey::setChild(const Table& tab,
2351 const Index * idx,
2352 const Column * cols[])
2353 {
2354 m_impl.m_references[1].m_name.assign(tab.getName());
2355 m_impl.m_references[1].m_objectId = RNIL;
2356 m_impl.m_references[1].m_objectVersion = RNIL;
2357 m_impl.m_references[3].m_name.clear();
2358 m_impl.m_references[3].m_objectId = RNIL;
2359 m_impl.m_references[3].m_objectVersion = RNIL;
2360
2361 switch(tab.getObjectStatus()) {
2362 case NdbDictionary::Object::New:
2363 break;
2364 default:
2365 m_impl.m_references[1].m_objectId = tab.getObjectId();
2366 m_impl.m_references[1].m_objectVersion = tab.getObjectVersion();
2367 break;
2368 }
2369
2370 if (idx)
2371 {
2372 m_impl.m_references[3].m_name.assign(idx->getName());
2373 switch(idx->getObjectStatus()){
2374 case NdbDictionary::Object::New:
2375 break;
2376 default:
2377 m_impl.m_references[3].m_objectId = idx->getObjectId();
2378 m_impl.m_references[3].m_objectVersion = idx->getObjectVersion();
2379 }
2380 }
2381
2382 m_impl.m_child_columns.clear();
2383 if (cols)
2384 {
2385 for (Uint32 i = 0; cols[i] != 0; i++)
2386 {
2387 m_impl.m_child_columns.push_back(cols[i]->getColumnNo());
2388 }
2389 }
2390 else if (idx == 0)
2391 {
2392 for (int i = 0; i < tab.getNoOfColumns(); i++)
2393 {
2394 if (tab.getColumn(i)->getPrimaryKey())
2395 {
2396 m_impl.m_child_columns.push_back(tab.getColumn(i)->getColumnNo());
2397 }
2398 }
2399 }
2400 else
2401 {
2402 for (unsigned i = 0; i < idx->getNoOfColumns(); i++)
2403 {
2404 const Column * idxcol = idx->getColumn(i);
2405 const Column * tabcol = tab.getColumn(idxcol->getName());
2406 if (tabcol)
2407 {
2408 // no way of reporting error...just add the if...
2409 // and let dict complain at ::create()
2410 m_impl.m_child_columns.push_back(tabcol->getColumnNo());
2411 }
2412 }
2413 }
2414 }
2415
2416 const char *
getChildTable() const2417 NdbDictionary::ForeignKey::getChildTable() const
2418 {
2419 return m_impl.m_references[1].m_name.c_str();
2420 }
2421
2422 const char *
getChildIndex() const2423 NdbDictionary::ForeignKey::getChildIndex() const
2424 {
2425 if (m_impl.m_references[3].m_name.empty())
2426 return 0;
2427 return m_impl.m_references[3].m_name.c_str();
2428 }
2429
2430
2431 NdbDictionary::ForeignKey::FkAction
getOnUpdateAction() const2432 NdbDictionary::ForeignKey::getOnUpdateAction() const
2433 {
2434 return m_impl.m_on_update_action;
2435 }
2436
2437 void
setOnUpdateAction(FkAction _action)2438 NdbDictionary::ForeignKey::setOnUpdateAction(FkAction _action)
2439 {
2440 m_impl.m_on_update_action = _action;
2441 }
2442
2443 NdbDictionary::ForeignKey::FkAction
getOnDeleteAction() const2444 NdbDictionary::ForeignKey::getOnDeleteAction() const
2445 {
2446 return m_impl.m_on_delete_action;
2447 }
2448
2449 void
setOnDeleteAction(FkAction _action)2450 NdbDictionary::ForeignKey::setOnDeleteAction(FkAction _action)
2451 {
2452 m_impl.m_on_delete_action = _action;
2453 }
2454
2455 unsigned
getParentColumnCount() const2456 NdbDictionary::ForeignKey::getParentColumnCount() const
2457 {
2458 return m_impl.m_parent_columns.size();
2459 }
2460
2461 int
getParentColumnNo(unsigned no) const2462 NdbDictionary::ForeignKey::getParentColumnNo(unsigned no) const
2463 {
2464 if (no < m_impl.m_parent_columns.size())
2465 {
2466 return (int)m_impl.m_parent_columns[no];
2467 }
2468 return -1;
2469 }
2470
2471 unsigned
getChildColumnCount() const2472 NdbDictionary::ForeignKey::getChildColumnCount() const
2473 {
2474 return m_impl.m_child_columns.size();
2475 }
2476
2477 int
getChildColumnNo(unsigned no) const2478 NdbDictionary::ForeignKey::getChildColumnNo(unsigned no) const
2479 {
2480 if (no < m_impl.m_child_columns.size())
2481 {
2482 return (int)m_impl.m_child_columns[no];
2483 }
2484 return -1;
2485 }
2486
2487 /*****************************************************************
2488 * Dictionary facade
2489 */
Dictionary(Ndb & ndb)2490 NdbDictionary::Dictionary::Dictionary(Ndb & ndb)
2491 : m_impl(* new NdbDictionaryImpl(ndb, *this))
2492 {
2493 }
2494
Dictionary(NdbDictionaryImpl & impl)2495 NdbDictionary::Dictionary::Dictionary(NdbDictionaryImpl & impl)
2496 : m_impl(impl)
2497 {
2498 }
~Dictionary()2499 NdbDictionary::Dictionary::~Dictionary(){
2500 NdbDictionaryImpl * tmp = &m_impl;
2501 if(this != tmp){
2502 delete tmp;
2503 }
2504 }
2505
2506 // do op within trans if no trans exists
2507 #define DO_TRANS(ret, action) \
2508 { \
2509 bool trans = hasSchemaTrans(); \
2510 if ((trans || (ret = beginSchemaTrans()) == 0) && \
2511 (ret = (action)) == 0 && \
2512 (trans || (ret = endSchemaTrans()) == 0)) \
2513 ; \
2514 else if (!trans) { \
2515 NdbError save_error = m_impl.m_error; \
2516 (void)endSchemaTrans(SchemaTransAbort); \
2517 m_impl.m_error = save_error; \
2518 } \
2519 }
2520
2521 int
createTable(const Table & t)2522 NdbDictionary::Dictionary::createTable(const Table & t)
2523 {
2524 return createTable(t, 0);
2525 }
2526
2527 int
createTable(const Table & t,ObjectId * objId)2528 NdbDictionary::Dictionary::createTable(const Table & t, ObjectId * objId)
2529 {
2530 int ret;
2531 ObjectId tmp;
2532 if (objId == 0)
2533 objId = &tmp;
2534
2535 if (likely(! is_ndb_blob_table(t.getName())))
2536 {
2537 DO_TRANS(
2538 ret,
2539 m_impl.createTable(NdbTableImpl::getImpl(t),
2540 NdbDictObjectImpl::getImpl( *objId))
2541 );
2542 }
2543 else
2544 {
2545 /* 4307 : Invalid table name */
2546 m_impl.m_error.code = 4307;
2547 ret = -1;
2548 }
2549 return ret;
2550 }
2551
2552 int
optimizeTable(const Table & t,OptimizeTableHandle & h)2553 NdbDictionary::Dictionary::optimizeTable(const Table &t,
2554 OptimizeTableHandle &h){
2555 DBUG_ENTER("NdbDictionary::Dictionary::optimzeTable");
2556 DBUG_RETURN(m_impl.optimizeTable(NdbTableImpl::getImpl(t),
2557 NdbOptimizeTableHandleImpl::getImpl(h)));
2558 }
2559
2560 int
optimizeIndex(const Index & ind,NdbDictionary::OptimizeIndexHandle & h)2561 NdbDictionary::Dictionary::optimizeIndex(const Index &ind,
2562 NdbDictionary::OptimizeIndexHandle &h)
2563 {
2564 DBUG_ENTER("NdbDictionary::Dictionary::optimzeIndex");
2565 DBUG_RETURN(m_impl.optimizeIndex(NdbIndexImpl::getImpl(ind),
2566 NdbOptimizeIndexHandleImpl::getImpl(h)));
2567 }
2568
2569 int
dropTable(Table & t)2570 NdbDictionary::Dictionary::dropTable(Table & t)
2571 {
2572 int ret;
2573 if (likely(! is_ndb_blob_table(t.getName())))
2574 {
2575 DO_TRANS(
2576 ret,
2577 m_impl.dropTable(NdbTableImpl::getImpl(t))
2578 );
2579 }
2580 else
2581 {
2582 /* 4249 : Invalid table */
2583 m_impl.m_error.code = 4249;
2584 ret = -1;
2585 }
2586 return ret;
2587 }
2588
2589 int
dropTableGlobal(const Table & t)2590 NdbDictionary::Dictionary::dropTableGlobal(const Table & t)
2591 {
2592 return dropTableGlobal(t, 0);
2593 }
2594
2595 int
dropTableGlobal(const Table & t,int flags)2596 NdbDictionary::Dictionary::dropTableGlobal(const Table & t, int flags)
2597 {
2598 int ret;
2599 if (likely(! is_ndb_blob_table(t.getName())))
2600 {
2601 DO_TRANS(
2602 ret,
2603 m_impl.dropTableGlobal(NdbTableImpl::getImpl(t), flags)
2604 );
2605 }
2606 else
2607 {
2608 /* 4249 : Invalid table */
2609 m_impl.m_error.code = 4249;
2610 ret = -1;
2611 }
2612 return ret;
2613 }
2614
2615 int
dropTable(const char * name)2616 NdbDictionary::Dictionary::dropTable(const char * name)
2617 {
2618 int ret;
2619 if (likely(! is_ndb_blob_table(name)))
2620 {
2621 DO_TRANS(
2622 ret,
2623 m_impl.dropTable(name)
2624 );
2625 }
2626 else
2627 {
2628 /* 4307 : Invalid table name */
2629 m_impl.m_error.code = 4307;
2630 ret = -1;
2631 }
2632 return ret;
2633 }
2634
2635 bool
supportedAlterTable(const Table & f,const Table & t)2636 NdbDictionary::Dictionary::supportedAlterTable(const Table & f,
2637 const Table & t)
2638 {
2639 return m_impl.supportedAlterTable(NdbTableImpl::getImpl(f),
2640 NdbTableImpl::getImpl(t));
2641 }
2642
2643 int
alterTable(const Table & f,const Table & t)2644 NdbDictionary::Dictionary::alterTable(const Table & f, const Table & t)
2645 {
2646 int ret;
2647 DO_TRANS(
2648 ret,
2649 m_impl.alterTable(NdbTableImpl::getImpl(f),
2650 NdbTableImpl::getImpl(t))
2651 );
2652 return ret;
2653 }
2654
2655 int
alterTableGlobal(const Table & f,const Table & t)2656 NdbDictionary::Dictionary::alterTableGlobal(const Table & f,
2657 const Table & t)
2658 {
2659 int ret;
2660 DO_TRANS(
2661 ret,
2662 m_impl.alterTableGlobal(NdbTableImpl::getImpl(f),
2663 NdbTableImpl::getImpl(t))
2664 );
2665 return ret;
2666 }
2667
2668 const NdbDictionary::Table *
getTable(const char * name,void ** data) const2669 NdbDictionary::Dictionary::getTable(const char * name, void **data) const
2670 {
2671 NdbTableImpl * t = m_impl.getTable(name, data);
2672 if(t)
2673 return t->m_facade;
2674 return 0;
2675 }
2676
2677 const NdbDictionary::Index *
getIndexGlobal(const char * indexName,const Table & ndbtab) const2678 NdbDictionary::Dictionary::getIndexGlobal(const char * indexName,
2679 const Table &ndbtab) const
2680 {
2681 NdbIndexImpl * i = m_impl.getIndexGlobal(indexName,
2682 NdbTableImpl::getImpl(ndbtab));
2683 if(i)
2684 return i->m_facade;
2685 return 0;
2686 }
2687
2688 const NdbDictionary::Index *
getIndexGlobal(const char * indexName,const char * tableName) const2689 NdbDictionary::Dictionary::getIndexGlobal(const char * indexName,
2690 const char * tableName) const
2691 {
2692 NdbIndexImpl * i = m_impl.getIndexGlobal(indexName,
2693 tableName);
2694 if(i)
2695 return i->m_facade;
2696 return 0;
2697 }
2698
2699 const NdbDictionary::Table *
getTableGlobal(const char * name) const2700 NdbDictionary::Dictionary::getTableGlobal(const char * name) const
2701 {
2702 NdbTableImpl * t = m_impl.getTableGlobal(name);
2703 if(t)
2704 return t->m_facade;
2705 return 0;
2706 }
2707
2708 int
removeIndexGlobal(const Index & ndbidx,int invalidate) const2709 NdbDictionary::Dictionary::removeIndexGlobal(const Index &ndbidx,
2710 int invalidate) const
2711 {
2712 return m_impl.releaseIndexGlobal(NdbIndexImpl::getImpl(ndbidx), invalidate);
2713 }
2714
2715 int
removeTableGlobal(const Table & ndbtab,int invalidate) const2716 NdbDictionary::Dictionary::removeTableGlobal(const Table &ndbtab,
2717 int invalidate) const
2718 {
2719 return m_impl.releaseTableGlobal(NdbTableImpl::getImpl(ndbtab), invalidate);
2720 }
2721
2722 NdbRecord *
createRecord(const Table * table,const RecordSpecification * recSpec,Uint32 length,Uint32 elemSize,Uint32 flags)2723 NdbDictionary::Dictionary::createRecord(const Table *table,
2724 const RecordSpecification *recSpec,
2725 Uint32 length,
2726 Uint32 elemSize,
2727 Uint32 flags)
2728 {
2729 /* We want to obtain a global reference to the Table object */
2730 NdbTableImpl* impl=&NdbTableImpl::getImpl(*table);
2731 Ndb* myNdb= &m_impl.m_ndb;
2732
2733 /* Temporarily change Ndb object to use table's database
2734 * and schema
2735 */
2736 BaseString currentDb(myNdb->getDatabaseName());
2737 BaseString currentSchema(myNdb->getDatabaseSchemaName());
2738
2739 myNdb->setDatabaseName
2740 (Ndb::getDatabaseFromInternalName(impl->m_internalName.c_str()).c_str());
2741 myNdb->setDatabaseSchemaName
2742 (Ndb::getSchemaFromInternalName(impl->m_internalName.c_str()).c_str());
2743
2744 /* Get global ref to table. This is released below, or when the
2745 * NdbRecord is released
2746 */
2747 const Table* globalTab= getTableGlobal(impl->m_externalName.c_str());
2748
2749 /* Restore Ndb object's DB and Schema */
2750 myNdb->setDatabaseName(currentDb.c_str());
2751 myNdb->setDatabaseSchemaName(currentSchema.c_str());
2752
2753 if (globalTab == NULL)
2754 /* An error is set on the dictionary */
2755 return NULL;
2756
2757 NdbTableImpl* globalTabImpl= &NdbTableImpl::getImpl(*globalTab);
2758
2759 assert(impl->m_id == globalTabImpl->m_id);
2760 if (table_version_major(impl->m_version) !=
2761 table_version_major(globalTabImpl->m_version))
2762 {
2763 removeTableGlobal(*globalTab, false); // Don't invalidate
2764 m_impl.m_error.code= 241; //Invalid schema object version
2765 return NULL;
2766 }
2767
2768 NdbRecord* result= m_impl.createRecord(globalTabImpl,
2769 recSpec,
2770 length,
2771 elemSize,
2772 flags,
2773 false); // Not default NdbRecord
2774
2775 if (!result)
2776 {
2777 removeTableGlobal(*globalTab, false); // Don't invalidate
2778 }
2779 return result;
2780 }
2781
2782 NdbRecord *
createRecord(const Index * index,const Table * table,const RecordSpecification * recSpec,Uint32 length,Uint32 elemSize,Uint32 flags)2783 NdbDictionary::Dictionary::createRecord(const Index *index,
2784 const Table *table,
2785 const RecordSpecification *recSpec,
2786 Uint32 length,
2787 Uint32 elemSize,
2788 Uint32 flags)
2789 {
2790 /* We want to obtain a global reference to the Index's underlying
2791 * table object
2792 */
2793 NdbTableImpl* tabImpl=&NdbTableImpl::getImpl(*table);
2794 Ndb* myNdb= &m_impl.m_ndb;
2795
2796 /* Temporarily change Ndb object to use table's database
2797 * and schema. Index's database and schema are not
2798 * useful for finding global table reference
2799 */
2800 BaseString currentDb(myNdb->getDatabaseName());
2801 BaseString currentSchema(myNdb->getDatabaseSchemaName());
2802
2803 myNdb->setDatabaseName
2804 (Ndb::getDatabaseFromInternalName(tabImpl->m_internalName.c_str()).c_str());
2805 myNdb->setDatabaseSchemaName
2806 (Ndb::getSchemaFromInternalName(tabImpl->m_internalName.c_str()).c_str());
2807
2808 /* Get global ref to index. This is released below, or when the
2809 * NdbRecord object is released
2810 */
2811 const Index* globalIndex= getIndexGlobal(index->getName(), *table);
2812
2813 /* Restore Ndb object's DB and Schema */
2814 myNdb->setDatabaseName(currentDb.c_str());
2815 myNdb->setDatabaseSchemaName(currentSchema.c_str());
2816
2817 if (globalIndex == NULL)
2818 /* An error is set on the dictionary */
2819 return NULL;
2820
2821 NdbIndexImpl* indexImpl= &NdbIndexImpl::getImpl(*index);
2822 NdbIndexImpl* globalIndexImpl= &NdbIndexImpl::getImpl(*globalIndex);
2823
2824 assert(indexImpl->m_id == globalIndexImpl->m_id);
2825
2826 if (table_version_major(indexImpl->m_version) !=
2827 table_version_major(globalIndexImpl->m_version))
2828 {
2829 removeIndexGlobal(*globalIndex, false); // Don't invalidate
2830 m_impl.m_error.code= 241; //Invalid schema object version
2831 return NULL;
2832 }
2833
2834 NdbRecord* result= m_impl.createRecord(globalIndexImpl->m_table,
2835 recSpec,
2836 length,
2837 elemSize,
2838 flags,
2839 false); // Not default NdbRecord
2840
2841 if (!result)
2842 {
2843 removeIndexGlobal(*globalIndex, false); // Don't invalidate
2844 }
2845 return result;
2846 }
2847
2848 NdbRecord *
createRecord(const Index * index,const RecordSpecification * recSpec,Uint32 length,Uint32 elemSize,Uint32 flags)2849 NdbDictionary::Dictionary::createRecord(const Index *index,
2850 const RecordSpecification *recSpec,
2851 Uint32 length,
2852 Uint32 elemSize,
2853 Uint32 flags)
2854 {
2855 const NdbDictionary::Table *table= getTable(index->getTable());
2856 if (!table)
2857 return NULL;
2858 return createRecord(index,
2859 table,
2860 recSpec,
2861 length,
2862 elemSize,
2863 flags);
2864 }
2865
2866 void
releaseRecord(NdbRecord * rec)2867 NdbDictionary::Dictionary::releaseRecord(NdbRecord *rec)
2868 {
2869 m_impl.releaseRecord_impl(rec);
2870 }
2871
putTable(const NdbDictionary::Table * table)2872 void NdbDictionary::Dictionary::putTable(const NdbDictionary::Table * table)
2873 {
2874 NdbDictionary::Table *copy_table = new NdbDictionary::Table;
2875 *copy_table = *table;
2876 m_impl.putTable(&NdbTableImpl::getImpl(*copy_table));
2877 }
2878
set_local_table_data_size(unsigned sz)2879 void NdbDictionary::Dictionary::set_local_table_data_size(unsigned sz)
2880 {
2881 m_impl.m_local_table_data_size= sz;
2882 }
2883
2884 const NdbDictionary::Table *
getTable(const char * name) const2885 NdbDictionary::Dictionary::getTable(const char * name) const
2886 {
2887 return getTable(name, 0);
2888 }
2889
2890 const NdbDictionary::Table *
getBlobTable(const NdbDictionary::Table * table,const char * col_name)2891 NdbDictionary::Dictionary::getBlobTable(const NdbDictionary::Table* table,
2892 const char* col_name)
2893 {
2894 const NdbDictionary::Column* col = table->getColumn(col_name);
2895 if (col == NULL) {
2896 m_impl.m_error.code = 4318;
2897 return NULL;
2898 }
2899 return getBlobTable(table, col->getColumnNo());
2900 }
2901
2902 const NdbDictionary::Table *
getBlobTable(const NdbDictionary::Table * table,Uint32 col_no)2903 NdbDictionary::Dictionary::getBlobTable(const NdbDictionary::Table* table,
2904 Uint32 col_no)
2905 {
2906 return m_impl.getBlobTable(NdbTableImpl::getImpl(*table), col_no);
2907 }
2908
2909 void
invalidateTable(const char * name)2910 NdbDictionary::Dictionary::invalidateTable(const char * name){
2911 DBUG_ENTER("NdbDictionaryImpl::invalidateTable");
2912 NdbTableImpl * t = m_impl.getTable(name);
2913 if(t)
2914 m_impl.invalidateObject(* t);
2915 DBUG_VOID_RETURN;
2916 }
2917
2918 void
invalidateTable(const Table * table)2919 NdbDictionary::Dictionary::invalidateTable(const Table *table){
2920 NdbTableImpl &t = NdbTableImpl::getImpl(*table);
2921 m_impl.invalidateObject(t);
2922 }
2923
2924 void
removeCachedTable(const char * name)2925 NdbDictionary::Dictionary::removeCachedTable(const char * name){
2926 NdbTableImpl * t = m_impl.getTable(name);
2927 if(t)
2928 m_impl.removeCachedObject(* t);
2929 }
2930
2931 void
removeCachedTable(const Table * table)2932 NdbDictionary::Dictionary::removeCachedTable(const Table *table){
2933 NdbTableImpl &t = NdbTableImpl::getImpl(*table);
2934 m_impl.removeCachedObject(t);
2935 }
2936
2937 int
createIndex(const Index & ind,bool offline)2938 NdbDictionary::Dictionary::createIndex(const Index & ind, bool offline)
2939 {
2940 int ret;
2941 DO_TRANS(
2942 ret,
2943 m_impl.createIndex(NdbIndexImpl::getImpl(ind), offline)
2944 );
2945 return ret;
2946 }
2947
2948 int
createIndex(const Index & ind,const Table & tab,bool offline)2949 NdbDictionary::Dictionary::createIndex(const Index & ind, const Table & tab,
2950 bool offline)
2951 {
2952 int ret;
2953 DO_TRANS(
2954 ret,
2955 m_impl.createIndex(NdbIndexImpl::getImpl(ind),
2956 NdbTableImpl::getImpl(tab),
2957 offline)
2958 );
2959 return ret;
2960 }
2961
2962 int
dropIndex(const char * indexName,const char * tableName)2963 NdbDictionary::Dictionary::dropIndex(const char * indexName,
2964 const char * tableName)
2965 {
2966 int ret;
2967 DO_TRANS(
2968 ret,
2969 m_impl.dropIndex(indexName, tableName)
2970 );
2971 return ret;
2972 }
2973
2974 int
dropIndexGlobal(const Index & ind)2975 NdbDictionary::Dictionary::dropIndexGlobal(const Index &ind)
2976 {
2977 int ret;
2978 DO_TRANS(
2979 ret,
2980 m_impl.dropIndexGlobal(NdbIndexImpl::getImpl(ind))
2981 );
2982 return ret;
2983 }
2984
2985 int
updateIndexStat(const Index & index,const Table & table)2986 NdbDictionary::Dictionary::updateIndexStat(const Index& index,
2987 const Table& table)
2988 {
2989 int ret;
2990 DO_TRANS(
2991 ret,
2992 m_impl.updateIndexStat(NdbIndexImpl::getImpl(index),
2993 NdbTableImpl::getImpl(table))
2994 );
2995 return ret;
2996 }
2997
2998 int
updateIndexStat(Uint32 indexId,Uint32 indexVersion,Uint32 tableId)2999 NdbDictionary::Dictionary::updateIndexStat(Uint32 indexId,
3000 Uint32 indexVersion,
3001 Uint32 tableId)
3002 {
3003 int ret;
3004 DO_TRANS(
3005 ret,
3006 m_impl.updateIndexStat(indexId,
3007 indexVersion,
3008 tableId)
3009 );
3010 return ret;
3011 }
3012
3013 int
deleteIndexStat(const Index & index,const Table & table)3014 NdbDictionary::Dictionary::deleteIndexStat(const Index& index,
3015 const Table& table)
3016 {
3017 int ret;
3018 DO_TRANS(
3019 ret,
3020 m_impl.deleteIndexStat(NdbIndexImpl::getImpl(index),
3021 NdbTableImpl::getImpl(table))
3022 );
3023 return ret;
3024 }
3025
3026 int
deleteIndexStat(Uint32 indexId,Uint32 indexVersion,Uint32 tableId)3027 NdbDictionary::Dictionary::deleteIndexStat(Uint32 indexId,
3028 Uint32 indexVersion,
3029 Uint32 tableId)
3030 {
3031 int ret;
3032 DO_TRANS(
3033 ret,
3034 m_impl.deleteIndexStat(indexId,
3035 indexVersion,
3036 tableId)
3037 );
3038 return ret;
3039 }
3040
3041 const NdbDictionary::Index *
getIndex(const char * indexName,const char * tableName) const3042 NdbDictionary::Dictionary::getIndex(const char * indexName,
3043 const char * tableName) const
3044 {
3045 NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
3046 if(i)
3047 return i->m_facade;
3048 return 0;
3049 }
3050
3051 const NdbDictionary::Index *
getIndex(const char * indexName,const NdbDictionary::Table & base) const3052 NdbDictionary::Dictionary::getIndex(const char * indexName,
3053 const NdbDictionary::Table& base) const
3054 {
3055 NdbIndexImpl * i = m_impl.getIndex(indexName, NdbTableImpl::getImpl(base));
3056 if (i)
3057 return i->m_facade;
3058 return 0;
3059 }
3060
3061 void
invalidateIndex(const Index * index)3062 NdbDictionary::Dictionary::invalidateIndex(const Index *index){
3063 DBUG_ENTER("NdbDictionary::Dictionary::invalidateIndex");
3064 NdbIndexImpl &i = NdbIndexImpl::getImpl(*index);
3065 assert(i.m_table != 0);
3066 m_impl.invalidateObject(* i.m_table);
3067 DBUG_VOID_RETURN;
3068 }
3069
3070 void
invalidateIndex(const char * indexName,const char * tableName)3071 NdbDictionary::Dictionary::invalidateIndex(const char * indexName,
3072 const char * tableName){
3073 DBUG_ENTER("NdbDictionaryImpl::invalidateIndex");
3074 NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
3075 if(i) {
3076 assert(i->m_table != 0);
3077 m_impl.invalidateObject(* i->m_table);
3078 }
3079 DBUG_VOID_RETURN;
3080 }
3081
3082 int
forceGCPWait()3083 NdbDictionary::Dictionary::forceGCPWait()
3084 {
3085 return forceGCPWait(0);
3086 }
3087
3088 int
forceGCPWait(int type)3089 NdbDictionary::Dictionary::forceGCPWait(int type)
3090 {
3091 return m_impl.forceGCPWait(type);
3092 }
3093
3094 int
getRestartGCI(Uint32 * gci)3095 NdbDictionary::Dictionary::getRestartGCI(Uint32 * gci)
3096 {
3097 return m_impl.getRestartGCI(gci);
3098 }
3099
3100 void
removeCachedIndex(const Index * index)3101 NdbDictionary::Dictionary::removeCachedIndex(const Index *index){
3102 DBUG_ENTER("NdbDictionary::Dictionary::removeCachedIndex");
3103 NdbIndexImpl &i = NdbIndexImpl::getImpl(*index);
3104 assert(i.m_table != 0);
3105 m_impl.removeCachedObject(* i.m_table);
3106 DBUG_VOID_RETURN;
3107 }
3108
3109 void
removeCachedIndex(const char * indexName,const char * tableName)3110 NdbDictionary::Dictionary::removeCachedIndex(const char * indexName,
3111 const char * tableName){
3112 NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
3113 if(i) {
3114 assert(i->m_table != 0);
3115 m_impl.removeCachedObject(* i->m_table);
3116 }
3117 }
3118
3119 const NdbDictionary::Table *
getIndexTable(const char * indexName,const char * tableName) const3120 NdbDictionary::Dictionary::getIndexTable(const char * indexName,
3121 const char * tableName) const
3122 {
3123 NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
3124 NdbTableImpl * t = m_impl.getTable(tableName);
3125 if(i && t) {
3126 NdbTableImpl * it = m_impl.getIndexTable(i, t);
3127 return it->m_facade;
3128 }
3129 return 0;
3130 }
3131
3132
3133 int
createEvent(const Event & ev)3134 NdbDictionary::Dictionary::createEvent(const Event & ev)
3135 {
3136 return m_impl.createEvent(NdbEventImpl::getImpl(ev));
3137 }
3138
3139 int
dropEvent(const char * eventName,int force)3140 NdbDictionary::Dictionary::dropEvent(const char * eventName, int force)
3141 {
3142 return m_impl.dropEvent(eventName, force);
3143 }
3144
3145 const NdbDictionary::Event *
getEvent(const char * eventName)3146 NdbDictionary::Dictionary::getEvent(const char * eventName)
3147 {
3148 NdbEventImpl * t = m_impl.getEvent(eventName);
3149 if(t)
3150 return t->m_facade;
3151 return 0;
3152 }
3153
3154 int
listEvents(List & list)3155 NdbDictionary::Dictionary::listEvents(List& list)
3156 {
3157 // delegate to overloaded const function for same semantics
3158 const NdbDictionary::Dictionary * const cthis = this;
3159 return cthis->NdbDictionary::Dictionary::listEvents(list);
3160 }
3161
3162 int
listEvents(List & list) const3163 NdbDictionary::Dictionary::listEvents(List& list) const
3164 {
3165 return m_impl.listEvents(list);
3166 }
3167
3168 int
listObjects(List & list,Object::Type type)3169 NdbDictionary::Dictionary::listObjects(List& list, Object::Type type)
3170 {
3171 // delegate to overloaded const function for same semantics
3172 const NdbDictionary::Dictionary * const cthis = this;
3173 return cthis->NdbDictionary::Dictionary::listObjects(list, type);
3174 }
3175
3176 int
listObjects(List & list,Object::Type type) const3177 NdbDictionary::Dictionary::listObjects(List& list, Object::Type type) const
3178 {
3179 // delegate to variant with FQ names param
3180 return listObjects(list, type,
3181 m_impl.m_ndb.usingFullyQualifiedNames());
3182 }
3183
3184 int
listObjects(List & list,Object::Type type,bool fullyQualified) const3185 NdbDictionary::Dictionary::listObjects(List& list, Object::Type type,
3186 bool fullyQualified) const
3187 {
3188 return m_impl.listObjects(list, type,
3189 fullyQualified);
3190 }
3191
3192 int
listIndexes(List & list,const char * tableName)3193 NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName)
3194 {
3195 // delegate to overloaded const function for same semantics
3196 const NdbDictionary::Dictionary * const cthis = this;
3197 return cthis->NdbDictionary::Dictionary::listIndexes(list, tableName);
3198 }
3199
3200 int
listIndexes(List & list,const char * tableName) const3201 NdbDictionary::Dictionary::listIndexes(List& list,
3202 const char * tableName) const
3203 {
3204 const NdbDictionary::Table* tab= getTable(tableName);
3205 if(tab == 0)
3206 {
3207 return -1;
3208 }
3209 return m_impl.listIndexes(list, tab->getTableId());
3210 }
3211
3212 int
listIndexes(List & list,const NdbDictionary::Table & table) const3213 NdbDictionary::Dictionary::listIndexes(List& list,
3214 const NdbDictionary::Table &table) const
3215 {
3216 return m_impl.listIndexes(list, table.getTableId());
3217 }
3218
3219 int
listDependentObjects(List & list,const NdbDictionary::Table & tab) const3220 NdbDictionary::Dictionary::listDependentObjects(List& list,
3221 const NdbDictionary::Table&tab)
3222 const
3223 {
3224 return m_impl.listDependentObjects(list, tab.getTableId());
3225 }
3226
3227 const struct NdbError &
getNdbError() const3228 NdbDictionary::Dictionary::getNdbError() const {
3229 return m_impl.getNdbError();
3230 }
3231
3232 int
getWarningFlags() const3233 NdbDictionary::Dictionary::getWarningFlags() const
3234 {
3235 return m_impl.m_warn;
3236 }
3237
3238 // printers
3239
3240 static
3241 void
pretty_print_string(NdbOut & out,const NdbDictionary::NdbDataPrintFormat & f,const char * type,bool is_binary,const void * aref,unsigned sz)3242 pretty_print_string(NdbOut& out,
3243 const NdbDictionary::NdbDataPrintFormat &f,
3244 const char *type, bool is_binary,
3245 const void *aref, unsigned sz)
3246 {
3247 const unsigned char* ref = (const unsigned char*)aref;
3248 int i, len, printable= 1;
3249 // trailing zeroes are not printed
3250 for (i=sz-1; i >= 0; i--)
3251 if (ref[i] == 0) sz--;
3252 else break;
3253 if (!is_binary)
3254 {
3255 // trailing spaces are not printed
3256 for (i=sz-1; i >= 0; i--)
3257 if (ref[i] == 32) sz--;
3258 else break;
3259 }
3260 if (is_binary && f.hex_format)
3261 {
3262 if (sz == 0)
3263 {
3264 out.print("0x0");
3265 return;
3266 }
3267 out.print("0x");
3268 for (len = 0; len < (int)sz; len++)
3269 out.print("%02X", (int)ref[len]);
3270 return;
3271 }
3272 if (sz == 0) return; // empty
3273
3274 // NOTE! This for loop both checks printable and counts length
3275 for (len=0; len < (int)sz && ref[i] != 0; len++)
3276 {
3277 if (printable && !isprint((int)ref[i]))
3278 printable= 0;
3279 }
3280
3281 if (printable)
3282 out.print("%.*s", len, ref);
3283 else
3284 {
3285 out.print("0x");
3286 for (i=0; i < len; i++)
3287 out.print("%02X", (int)ref[i]);
3288 }
3289 if (len != (int)sz)
3290 {
3291 out.print("[");
3292 for (i= len+1; ref[i] != 0; i++)
3293 out.print("%u]",len-i);
3294 assert((int)sz > i);
3295 pretty_print_string(out,f,type,is_binary,ref+i,sz-i);
3296 }
3297 }
3298
3299 /* Three MySQL defs duplicated here : */
3300 static const int MaxMySQLDecimalPrecision= 65;
3301 static const int MaxMySQLDecimalScale= 30;
3302 static const int DigitsPerDigit_t= 9; // (Decimal digits in 2^32)
3303
3304 /* Implications */
3305 /* Space for -, . and \0 */
3306 static const int MaxDecimalStrLen= MaxMySQLDecimalPrecision + 3;
3307 static const int IntPartDigit_ts=
3308 ((MaxMySQLDecimalPrecision -
3309 MaxMySQLDecimalScale) +
3310 DigitsPerDigit_t -1) / DigitsPerDigit_t;
3311 static const int FracPartDigit_ts=
3312 (MaxMySQLDecimalScale +
3313 DigitsPerDigit_t - 1) / DigitsPerDigit_t;
3314 static const int DigitArraySize= IntPartDigit_ts + FracPartDigit_ts;
3315
3316 NdbOut&
printFormattedValue(NdbOut & out,const NdbDataPrintFormat & format,const NdbDictionary::Column * c,const void * val)3317 NdbDictionary::printFormattedValue(NdbOut& out,
3318 const NdbDataPrintFormat& format,
3319 const NdbDictionary::Column* c,
3320 const void* val)
3321 {
3322 if (val == NULL)
3323 {
3324 out << format.null_string;
3325 return out;
3326 }
3327
3328 const unsigned char* val_p= (const unsigned char*) val;
3329
3330 uint length = c->getLength();
3331 Uint32 j;
3332 {
3333 const char *fields_optionally_enclosed_by;
3334 if (format.fields_enclosed_by[0] == '\0')
3335 fields_optionally_enclosed_by=
3336 format.fields_optionally_enclosed_by;
3337 else
3338 fields_optionally_enclosed_by= "";
3339 out << format.fields_enclosed_by;
3340
3341 switch(c->getType()){
3342 case NdbDictionary::Column::Bigunsigned:
3343 {
3344 Uint64 temp;
3345 memcpy(&temp, val, 8);
3346 out << temp;
3347 break;
3348 }
3349 case NdbDictionary::Column::Bit:
3350 {
3351 out << format.hex_prefix << "0x";
3352 {
3353 const Uint32 *buf = (const Uint32 *)val;
3354 unsigned int k = (length+31)/32;
3355 const unsigned int sigbits= length & 31;
3356 Uint32 wordMask= (1 << sigbits) -1;
3357
3358 /* Skip leading all-0 words */
3359 while (k > 0)
3360 {
3361 const Uint32 v= buf[--k] & wordMask;
3362 if (v != 0)
3363 break;
3364 /* Following words have all bits significant */
3365 wordMask= ~0;
3366 }
3367
3368 /* Write first sig word with non-zero bits */
3369 out.print("%X", (buf[k] & wordMask));
3370
3371 /* Write remaining words (less significant) */
3372 while (k > 0)
3373 out.print("%.8X", buf[--k]);
3374 }
3375 break;
3376 }
3377 case NdbDictionary::Column::Unsigned:
3378 {
3379 if (length > 1)
3380 out << format.start_array_enclosure;
3381 out << *(const Uint32*)val;
3382 for (j = 1; j < length; j++)
3383 out << " " << *(((const Uint32*)val) + j);
3384 if (length > 1)
3385 out << format.end_array_enclosure;
3386 break;
3387 }
3388 case NdbDictionary::Column::Mediumunsigned:
3389 out << (const Uint32) uint3korr(val_p);
3390 break;
3391 case NdbDictionary::Column::Smallunsigned:
3392 out << *((const Uint16*) val);
3393 break;
3394 case NdbDictionary::Column::Tinyunsigned:
3395 out << *((const Uint8*) val);
3396 break;
3397 case NdbDictionary::Column::Bigint:
3398 {
3399 Int64 temp;
3400 memcpy(&temp, val, 8);
3401 out << temp;
3402 break;
3403 }
3404 case NdbDictionary::Column::Int:
3405 out << *((Int32*)val);
3406 break;
3407 case NdbDictionary::Column::Mediumint:
3408 out << sint3korr(val_p);
3409 break;
3410 case NdbDictionary::Column::Smallint:
3411 out << *((const short*) val);
3412 break;
3413 case NdbDictionary::Column::Tinyint:
3414 out << *((Int8*) val);
3415 break;
3416 case NdbDictionary::Column::Binary:
3417 if (!format.hex_format)
3418 out << fields_optionally_enclosed_by;
3419 j = c->getLength();
3420 pretty_print_string(out,format,"Binary", true, val, j);
3421 if (!format.hex_format)
3422 out << fields_optionally_enclosed_by;
3423 break;
3424 case NdbDictionary::Column::Char:
3425 out << fields_optionally_enclosed_by;
3426 j = c->getLength();
3427 pretty_print_string(out,format,"Char", false, val, j);
3428 out << fields_optionally_enclosed_by;
3429 break;
3430 case NdbDictionary::Column::Varchar:
3431 {
3432 out << fields_optionally_enclosed_by;
3433 unsigned len = *val_p;
3434 pretty_print_string(out,format,"Varchar", false, val_p+1,len);
3435 j = length;
3436 out << fields_optionally_enclosed_by;
3437 }
3438 break;
3439 case NdbDictionary::Column::Varbinary:
3440 {
3441 if (!format.hex_format)
3442 out << fields_optionally_enclosed_by;
3443 unsigned len = *val_p;
3444 pretty_print_string(out,format,"Varbinary", true, val_p+1,len);
3445 j = length;
3446 if (!format.hex_format)
3447 out << fields_optionally_enclosed_by;
3448 }
3449 break;
3450 case NdbDictionary::Column::Float:
3451 {
3452 float temp;
3453 memcpy(&temp, val, sizeof(temp));
3454 out << temp;
3455 break;
3456 }
3457 case NdbDictionary::Column::Double:
3458 {
3459 double temp;
3460 memcpy(&temp, val, sizeof(temp));
3461 out << temp;
3462 break;
3463 }
3464 case NdbDictionary::Column::Olddecimal:
3465 {
3466 short len = 1 + c->getPrecision() + (c->getScale() > 0);
3467 out.print("%.*s", len, val_p);
3468 }
3469 break;
3470 case NdbDictionary::Column::Olddecimalunsigned:
3471 {
3472 short len = 0 + c->getPrecision() + (c->getScale() > 0);
3473 out.print("%.*s", len, val_p);
3474 }
3475 break;
3476 case NdbDictionary::Column::Decimal:
3477 case NdbDictionary::Column::Decimalunsigned:
3478 {
3479 int precision= c->getPrecision();
3480 int scale= c->getScale();
3481
3482 assert(precision <= MaxMySQLDecimalPrecision);
3483 assert(scale <= MaxMySQLDecimalScale);
3484 assert(decimal_size(precision, scale) <= DigitArraySize );
3485 decimal_digit_t buff[ DigitArraySize ];
3486 decimal_t tmpDec;
3487 tmpDec.buf= buff;
3488 tmpDec.len= DigitArraySize;
3489 decimal_make_zero(&tmpDec);
3490 int rc;
3491
3492 const uchar* data= (const uchar*) val_p;
3493 if ((rc= bin2decimal(data, &tmpDec, precision, scale)))
3494 {
3495 out.print("***Error : Bad bin2decimal conversion %d ***",
3496 rc);
3497 break;
3498 }
3499
3500 /* Get null terminated var-length string representation */
3501 char decStr[MaxDecimalStrLen];
3502 assert(decimal_string_size(&tmpDec) <= MaxDecimalStrLen);
3503 int len= MaxDecimalStrLen;
3504 if ((rc= decimal2string(&tmpDec, decStr,
3505 &len,
3506 0, // 0 = Var length output length
3507 0, // 0 = Var length fractional part
3508 0))) // Filler char for fixed length
3509 {
3510 out.print("***Error : bad decimal2string conversion %d ***",
3511 rc);
3512 break;
3513 }
3514
3515 out.print("%s", decStr);
3516
3517 break;
3518 }
3519 case NdbDictionary::Column::Datetime:
3520 {
3521 NdbSqlUtil::Datetime s;
3522 NdbSqlUtil::unpack_datetime(s, val_p);
3523 out.print("%04d-%02d-%02d", s.year, s.month, s.day);
3524 out.print("/%02d:%02d:%02d", s.hour, s.minute, s.second);
3525 }
3526 break;
3527 case NdbDictionary::Column::Date:
3528 {
3529 NdbSqlUtil::Date s;
3530 NdbSqlUtil::unpack_date(s, val_p);
3531 out.print("%04d-%02d-%02d", s.year, s.month, s.day);
3532 }
3533 break;
3534 case NdbDictionary::Column::Time:
3535 {
3536 NdbSqlUtil::Time s;
3537 NdbSqlUtil::unpack_time(s, val_p);
3538 const char* sign = (s.sign ? "" : "-");
3539 out.print("%s%02u:%02u:%02u", sign, s.hour, s.minute, s.second);
3540 }
3541 break;
3542 case NdbDictionary::Column::Year:
3543 {
3544 NdbSqlUtil::Year s;
3545 NdbSqlUtil::unpack_year(s, val_p);
3546 out.print("%04d", s.year);
3547 }
3548 break;
3549 case NdbDictionary::Column::Timestamp:
3550 {
3551 NdbSqlUtil::Timestamp s;
3552 NdbSqlUtil::unpack_timestamp(s, val_p);
3553 out.print("%u", s.second);
3554 }
3555 break;
3556 case NdbDictionary::Column::Blob:
3557 case NdbDictionary::Column::Text:
3558 {
3559 NdbBlob::Head head;
3560 NdbBlob::unpackBlobHead(head, (const char*) val_p, c->getBlobVersion());
3561 out << head.length << ":";
3562 const unsigned char* p = val_p + head.headsize;
3563 unsigned n = c->getInlineSize();
3564 for (unsigned k = 0; k < n && k < head.length; k++) {
3565 if (c->getType() == NdbDictionary::Column::Blob)
3566 out.print("%02X", (int)p[k]);
3567 else
3568 out.print("%c", (int)p[k]);
3569 }
3570 j = length;
3571 }
3572 break;
3573 case NdbDictionary::Column::Longvarchar:
3574 {
3575 out << fields_optionally_enclosed_by;
3576 unsigned len = uint2korr(val_p);
3577 pretty_print_string(out,format,"Longvarchar", false,
3578 val_p+2,len);
3579 j = length;
3580 out << fields_optionally_enclosed_by;
3581 }
3582 break;
3583 case NdbDictionary::Column::Longvarbinary:
3584 {
3585 if (!format.hex_format)
3586 out << fields_optionally_enclosed_by;
3587 unsigned len = uint2korr(val_p);
3588 pretty_print_string(out,format,"Longvarbinary", true,
3589 val_p+2,len);
3590 j = length;
3591 if (!format.hex_format)
3592 out << fields_optionally_enclosed_by;
3593 }
3594 break;
3595 // fractional time types, see wl#946
3596 case NdbDictionary::Column::Time2:
3597 {
3598 uint prec = c->getPrecision();
3599 assert(prec <= 6);
3600 NdbSqlUtil::Time2 s;
3601 NdbSqlUtil::unpack_time2(s, val_p, prec);
3602 const char* sign = (s.sign ? "" : "-");
3603 out.print("%s%02d:%02d:%02d", sign, s.hour, s.minute, s.second);
3604 if (prec != 0)
3605 out.print(".%0*d", prec, s.fraction);
3606 }
3607 break;
3608 case NdbDictionary::Column::Datetime2:
3609 {
3610 uint prec = c->getPrecision();
3611 assert(prec <= 6);
3612 NdbSqlUtil::Datetime2 s;
3613 NdbSqlUtil::unpack_datetime2(s, val_p, prec);
3614 out.print("%04d-%02d-%02d", s.year, s.month, s.day);
3615 out.print("/%02d:%02d:%02d", s.hour, s.minute, s.second);
3616 if (prec != 0)
3617 out.print(".%0*d", prec, s.fraction);
3618 }
3619 break;
3620 case NdbDictionary::Column::Timestamp2:
3621 {
3622 uint prec = c->getPrecision();
3623 assert(prec <= 6);
3624 NdbSqlUtil::Timestamp2 s;
3625 NdbSqlUtil::unpack_timestamp2(s, val_p, prec);
3626 out.print("%u", s.second);
3627 if (prec != 0)
3628 out.print(".%0*d", prec, s.fraction);
3629 }
3630 break;
3631
3632 default: /* no print functions for the rest, just print type */
3633 out << "Unable to format type ("
3634 << (int) c->getType()
3635 << ")";
3636 if (length > 1)
3637 out << " " << length << " times";
3638 break;
3639 }
3640 out << format.fields_enclosed_by;
3641 }
3642
3643 return out;
3644 }
3645
NdbDataPrintFormat()3646 NdbDictionary::NdbDataPrintFormat::NdbDataPrintFormat()
3647 {
3648 fields_terminated_by= ";";
3649 start_array_enclosure= "[";
3650 end_array_enclosure= "]";
3651 fields_enclosed_by= "";
3652 fields_optionally_enclosed_by= "\"";
3653 lines_terminated_by= "\n";
3654 hex_prefix= "H'";
3655 null_string= "[NULL]";
3656 hex_format= 0;
3657 }
~NdbDataPrintFormat()3658 NdbDictionary::NdbDataPrintFormat::~NdbDataPrintFormat() {};
3659
3660
3661 NdbOut&
operator <<(NdbOut & out,const NdbDictionary::Column & col)3662 operator<<(NdbOut& out, const NdbDictionary::Column& col)
3663 {
3664 const CHARSET_INFO *cs = col.getCharset();
3665 const char *csname = cs ? cs->name : "?";
3666 out << col.getName() << " ";
3667 switch (col.getType()) {
3668 case NdbDictionary::Column::Tinyint:
3669 out << "Tinyint";
3670 break;
3671 case NdbDictionary::Column::Tinyunsigned:
3672 out << "Tinyunsigned";
3673 break;
3674 case NdbDictionary::Column::Smallint:
3675 out << "Smallint";
3676 break;
3677 case NdbDictionary::Column::Smallunsigned:
3678 out << "Smallunsigned";
3679 break;
3680 case NdbDictionary::Column::Mediumint:
3681 out << "Mediumint";
3682 break;
3683 case NdbDictionary::Column::Mediumunsigned:
3684 out << "Mediumunsigned";
3685 break;
3686 case NdbDictionary::Column::Int:
3687 out << "Int";
3688 break;
3689 case NdbDictionary::Column::Unsigned:
3690 out << "Unsigned";
3691 break;
3692 case NdbDictionary::Column::Bigint:
3693 out << "Bigint";
3694 break;
3695 case NdbDictionary::Column::Bigunsigned:
3696 out << "Bigunsigned";
3697 break;
3698 case NdbDictionary::Column::Float:
3699 out << "Float";
3700 break;
3701 case NdbDictionary::Column::Double:
3702 out << "Double";
3703 break;
3704 case NdbDictionary::Column::Olddecimal:
3705 out << "Olddecimal(" << col.getPrecision() << "," << col.getScale() << ")";
3706 break;
3707 case NdbDictionary::Column::Olddecimalunsigned:
3708 out << "Olddecimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")";
3709 break;
3710 case NdbDictionary::Column::Decimal:
3711 out << "Decimal(" << col.getPrecision() << "," << col.getScale() << ")";
3712 break;
3713 case NdbDictionary::Column::Decimalunsigned:
3714 out << "Decimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")";
3715 break;
3716 case NdbDictionary::Column::Char:
3717 out << "Char(" << col.getLength() << ";" << csname << ")";
3718 break;
3719 case NdbDictionary::Column::Varchar:
3720 out << "Varchar(" << col.getLength() << ";" << csname << ")";
3721 break;
3722 case NdbDictionary::Column::Binary:
3723 out << "Binary(" << col.getLength() << ")";
3724 break;
3725 case NdbDictionary::Column::Varbinary:
3726 out << "Varbinary(" << col.getLength() << ")";
3727 break;
3728 case NdbDictionary::Column::Datetime:
3729 out << "Datetime";
3730 break;
3731 case NdbDictionary::Column::Date:
3732 out << "Date";
3733 break;
3734 case NdbDictionary::Column::Blob:
3735 out << "Blob(" << col.getInlineSize() << "," << col.getPartSize()
3736 << "," << col.getStripeSize() << ")";
3737 break;
3738 case NdbDictionary::Column::Text:
3739 out << "Text(" << col.getInlineSize() << "," << col.getPartSize()
3740 << "," << col.getStripeSize() << ";" << csname << ")";
3741 break;
3742 case NdbDictionary::Column::Time:
3743 out << "Time";
3744 break;
3745 case NdbDictionary::Column::Year:
3746 out << "Year";
3747 break;
3748 case NdbDictionary::Column::Timestamp:
3749 out << "Timestamp";
3750 break;
3751 case NdbDictionary::Column::Undefined:
3752 out << "Undefined";
3753 break;
3754 case NdbDictionary::Column::Bit:
3755 out << "Bit(" << col.getLength() << ")";
3756 break;
3757 case NdbDictionary::Column::Longvarchar:
3758 out << "Longvarchar(" << col.getLength() << ";" << csname << ")";
3759 break;
3760 case NdbDictionary::Column::Longvarbinary:
3761 out << "Longvarbinary(" << col.getLength() << ")";
3762 break;
3763 case NdbDictionary::Column::Datetime2:
3764 out << "Datetime2(" << col.getPrecision() << ")";
3765 break;
3766 case NdbDictionary::Column::Time2:
3767 out << "Time2(" << col.getPrecision() << ")";
3768 break;
3769 case NdbDictionary::Column::Timestamp2:
3770 out << "Timestamp2(" << col.getPrecision() << ")";
3771 break;
3772 default:
3773 out << "Type" << (Uint32)col.getType();
3774 break;
3775 }
3776 // show unusual (non-MySQL) array size
3777 if (col.getLength() != 1) {
3778 switch (col.getType()) {
3779 case NdbDictionary::Column::Char:
3780 case NdbDictionary::Column::Varchar:
3781 case NdbDictionary::Column::Binary:
3782 case NdbDictionary::Column::Varbinary:
3783 case NdbDictionary::Column::Blob:
3784 case NdbDictionary::Column::Text:
3785 case NdbDictionary::Column::Bit:
3786 case NdbDictionary::Column::Longvarchar:
3787 case NdbDictionary::Column::Longvarbinary:
3788 break;
3789 default:
3790 out << " [" << col.getLength() << "]";
3791 break;
3792 }
3793 }
3794
3795 if (col.getPrimaryKey())
3796 out << " PRIMARY KEY";
3797 else if (! col.getNullable())
3798 out << " NOT NULL";
3799 else
3800 out << " NULL";
3801
3802 if(col.getDistributionKey())
3803 out << " DISTRIBUTION KEY";
3804
3805 switch (col.getArrayType()) {
3806 case NDB_ARRAYTYPE_FIXED:
3807 out << " AT=FIXED";
3808 break;
3809 case NDB_ARRAYTYPE_SHORT_VAR:
3810 out << " AT=SHORT_VAR";
3811 break;
3812 case NDB_ARRAYTYPE_MEDIUM_VAR:
3813 out << " AT=MEDIUM_VAR";
3814 break;
3815 default:
3816 out << " AT=" << (int)col.getArrayType() << "?";
3817 break;
3818 }
3819
3820 switch (col.getStorageType()) {
3821 case NDB_STORAGETYPE_MEMORY:
3822 out << " ST=MEMORY";
3823 break;
3824 case NDB_STORAGETYPE_DISK:
3825 out << " ST=DISK";
3826 break;
3827 default:
3828 out << " ST=" << (int)col.getStorageType() << "?";
3829 break;
3830 }
3831
3832 if (col.getAutoIncrement())
3833 out << " AUTO_INCR";
3834
3835 switch (col.getType()) {
3836 case NdbDictionary::Column::Blob:
3837 case NdbDictionary::Column::Text:
3838 out << " BV=" << col.getBlobVersion();
3839 out << " BT=" << ((col.getBlobTable() != 0) ? col.getBlobTable()->getName() : "<none>");
3840 break;
3841 default:
3842 break;
3843 }
3844
3845 if(col.getDynamic())
3846 out << " DYNAMIC";
3847
3848 const void *default_data = col.getDefaultValue();
3849
3850 if (default_data != NULL)
3851 {
3852 NdbDictionary::NdbDataPrintFormat f;
3853
3854 /* Display binary field defaults as hex */
3855 f.hex_format = 1;
3856
3857 out << " DEFAULT ";
3858
3859 NdbDictionary::printFormattedValue(out,
3860 f,
3861 &col,
3862 default_data);
3863 }
3864
3865 return out;
3866 }
3867
3868 int
createLogfileGroup(const LogfileGroup & lg,ObjectId * obj)3869 NdbDictionary::Dictionary::createLogfileGroup(const LogfileGroup & lg,
3870 ObjectId * obj)
3871 {
3872 int ret;
3873 DO_TRANS(ret,
3874 m_impl.createLogfileGroup(NdbLogfileGroupImpl::getImpl(lg),
3875 obj ?
3876 & NdbDictObjectImpl::getImpl(* obj) : 0));
3877 return ret;
3878 }
3879
3880 int
dropLogfileGroup(const LogfileGroup & lg)3881 NdbDictionary::Dictionary::dropLogfileGroup(const LogfileGroup & lg)
3882 {
3883 int ret;
3884 DO_TRANS(ret,
3885 m_impl.dropLogfileGroup(NdbLogfileGroupImpl::getImpl(lg)));
3886 return ret;
3887 }
3888
3889 NdbDictionary::LogfileGroup
getLogfileGroup(const char * name)3890 NdbDictionary::Dictionary::getLogfileGroup(const char * name)
3891 {
3892 NdbDictionary::LogfileGroup tmp;
3893 m_impl.m_receiver.get_filegroup(NdbLogfileGroupImpl::getImpl(tmp),
3894 NdbDictionary::Object::LogfileGroup, name);
3895 return tmp;
3896 }
3897
3898 int
createTablespace(const Tablespace & lg,ObjectId * obj)3899 NdbDictionary::Dictionary::createTablespace(const Tablespace & lg,
3900 ObjectId * obj)
3901 {
3902 int ret;
3903 DO_TRANS(ret,
3904 m_impl.createTablespace(NdbTablespaceImpl::getImpl(lg),
3905 obj ?
3906 & NdbDictObjectImpl::getImpl(* obj) : 0));
3907 return ret;
3908 }
3909
3910 int
dropTablespace(const Tablespace & lg)3911 NdbDictionary::Dictionary::dropTablespace(const Tablespace & lg)
3912 {
3913 int ret;
3914 DO_TRANS(ret,
3915 m_impl.dropTablespace(NdbTablespaceImpl::getImpl(lg)));
3916 return ret;
3917 }
3918
3919 NdbDictionary::Tablespace
getTablespace(const char * name)3920 NdbDictionary::Dictionary::getTablespace(const char * name)
3921 {
3922 NdbDictionary::Tablespace tmp;
3923 m_impl.m_receiver.get_filegroup(NdbTablespaceImpl::getImpl(tmp),
3924 NdbDictionary::Object::Tablespace, name);
3925 return tmp;
3926 }
3927
3928 NdbDictionary::Tablespace
getTablespace(Uint32 tablespaceId)3929 NdbDictionary::Dictionary::getTablespace(Uint32 tablespaceId)
3930 {
3931 NdbDictionary::Tablespace tmp;
3932 m_impl.m_receiver.get_filegroup(NdbTablespaceImpl::getImpl(tmp),
3933 NdbDictionary::Object::Tablespace,
3934 tablespaceId);
3935 return tmp;
3936 }
3937
3938 int
createDatafile(const Datafile & df,bool force,ObjectId * obj)3939 NdbDictionary::Dictionary::createDatafile(const Datafile & df,
3940 bool force,
3941 ObjectId * obj)
3942 {
3943 int ret;
3944 DO_TRANS(ret,
3945 m_impl.createDatafile(NdbDatafileImpl::getImpl(df),
3946 force,
3947 obj ? & NdbDictObjectImpl::getImpl(* obj): 0));
3948 return ret;
3949 }
3950
3951 int
dropDatafile(const Datafile & df)3952 NdbDictionary::Dictionary::dropDatafile(const Datafile& df)
3953 {
3954 int ret;
3955 DO_TRANS(ret,
3956 m_impl.dropDatafile(NdbDatafileImpl::getImpl(df)));
3957 return ret;
3958 }
3959
3960 NdbDictionary::Datafile
getDatafile(Uint32 node,const char * path)3961 NdbDictionary::Dictionary::getDatafile(Uint32 node, const char * path)
3962 {
3963 NdbDictionary::Datafile tmp;
3964 m_impl.m_receiver.get_file(NdbDatafileImpl::getImpl(tmp),
3965 NdbDictionary::Object::Datafile,
3966 node ? (int)node : -1, path);
3967 return tmp;
3968 }
3969
3970 int
createUndofile(const Undofile & df,bool force,ObjectId * obj)3971 NdbDictionary::Dictionary::createUndofile(const Undofile & df,
3972 bool force,
3973 ObjectId * obj)
3974 {
3975 int ret;
3976 DO_TRANS(ret,
3977 m_impl.createUndofile(NdbUndofileImpl::getImpl(df),
3978 force,
3979 obj ? & NdbDictObjectImpl::getImpl(* obj): 0));
3980 return ret;
3981 }
3982
3983 int
dropUndofile(const Undofile & df)3984 NdbDictionary::Dictionary::dropUndofile(const Undofile& df)
3985 {
3986 int ret;
3987 DO_TRANS(ret,
3988 m_impl.dropUndofile(NdbUndofileImpl::getImpl(df)));
3989 return ret;
3990 }
3991
3992 NdbDictionary::Undofile
getUndofile(Uint32 node,const char * path)3993 NdbDictionary::Dictionary::getUndofile(Uint32 node, const char * path)
3994 {
3995 NdbDictionary::Undofile tmp;
3996 m_impl.m_receiver.get_file(NdbUndofileImpl::getImpl(tmp),
3997 NdbDictionary::Object::Undofile,
3998 node ? (int)node : -1, path);
3999 return tmp;
4000 }
4001
4002 void
invalidateDbGlobal(const char * name)4003 NdbDictionary::Dictionary::invalidateDbGlobal(const char * name)
4004 {
4005 if (m_impl.m_globalHash && name != 0)
4006 {
4007 size_t len = strlen(name);
4008 m_impl.m_globalHash->lock();
4009 m_impl.m_globalHash->invalidateDb(name, len);
4010 m_impl.m_globalHash->unlock();
4011 }
4012 }
4013
4014 int
beginSchemaTrans()4015 NdbDictionary::Dictionary::beginSchemaTrans()
4016 {
4017 return m_impl.beginSchemaTrans();
4018 }
4019
4020 int
endSchemaTrans(Uint32 flags)4021 NdbDictionary::Dictionary::endSchemaTrans(Uint32 flags)
4022 {
4023 return m_impl.endSchemaTrans(flags);
4024 }
4025
4026 bool
hasSchemaTrans() const4027 NdbDictionary::Dictionary::hasSchemaTrans() const
4028 {
4029 return m_impl.hasSchemaTrans();
4030 }
4031
4032 int
createHashMap(const HashMap & map,ObjectId * dst)4033 NdbDictionary::Dictionary::createHashMap(const HashMap& map, ObjectId * dst)
4034 {
4035 ObjectId tmp;
4036 if (dst == 0)
4037 dst = &tmp;
4038
4039 int ret;
4040 DO_TRANS(ret,
4041 m_impl.m_receiver.create_hashmap(NdbHashMapImpl::getImpl(map),
4042 &NdbDictObjectImpl::getImpl(*dst),
4043 0));
4044 return ret;
4045 }
4046
4047 int
createForeignKey(const ForeignKey & fk,ObjectId * dst,int flags)4048 NdbDictionary::Dictionary::createForeignKey(const ForeignKey& fk,
4049 ObjectId * dst,
4050 int flags)
4051 {
4052 ObjectId tmp;
4053 if (dst == 0)
4054 dst = &tmp;
4055
4056 if (fk.getParentIndex() == 0 // primary key
4057 && fk.getOnUpdateAction() == NdbDictionary::ForeignKey::Cascade)
4058 {
4059 m_impl.m_error.code = 21000;
4060 return -1;
4061 }
4062
4063 int ret;
4064 int implFlags = 0;
4065 if (flags & CreateFK_NoVerify)
4066 {
4067 implFlags |= DictSignal::RF_NO_BUILD;
4068 }
4069
4070 DO_TRANS(ret,
4071 m_impl.m_receiver.create_fk(NdbForeignKeyImpl::getImpl(fk),
4072 &NdbDictObjectImpl::getImpl(*dst),
4073 implFlags));
4074 return ret;
4075 }
4076
4077 int
getForeignKey(ForeignKey & fk,const char * name)4078 NdbDictionary::Dictionary::getForeignKey(ForeignKey& fk,
4079 const char * name)
4080 {
4081 return m_impl.m_receiver.get_fk(NdbForeignKeyImpl::getImpl(fk), name);
4082 }
4083
4084 int
dropForeignKey(const ForeignKey & fk)4085 NdbDictionary::Dictionary::dropForeignKey(const ForeignKey& fk)
4086 {
4087 int ret;
4088 DO_TRANS(ret,
4089 m_impl.m_receiver.drop_fk(NdbForeignKeyImpl::getImpl(fk)));
4090 return ret;
4091 }
4092
operator <<(NdbOut & ndbout,NdbDictionary::Object::FragmentType const fragtype)4093 NdbOut& operator <<(NdbOut& ndbout, NdbDictionary::Object::FragmentType const fragtype)
4094 {
4095 switch (fragtype)
4096 {
4097 case NdbDictionary::Object::FragUndefined:
4098 ndbout << "FragUndefined";
4099 break;
4100 case NdbDictionary::Object::FragSingle:
4101 ndbout << "FragSingle";
4102 break;
4103 case NdbDictionary::Object::FragAllSmall:
4104 ndbout << "FragAllSmall";
4105 break;
4106 case NdbDictionary::Object::FragAllMedium:
4107 ndbout << "FragAllMedium";
4108 break;
4109 case NdbDictionary::Object::FragAllLarge:
4110 ndbout << "FragAllLarge";
4111 break;
4112 case NdbDictionary::Object::DistrKeyHash:
4113 ndbout << "DistrKeyHash";
4114 break;
4115 case NdbDictionary::Object::DistrKeyLin:
4116 ndbout << "DistrKeyLin";
4117 break;
4118 case NdbDictionary::Object::UserDefined:
4119 ndbout << "UserDefined";
4120 break;
4121 case NdbDictionary::Object::HashMapPartition:
4122 ndbout << "HashMapPartition";
4123 break;
4124 default:
4125 ndbout << "Unknown(" << (unsigned) fragtype << ")";
4126 }
4127 return ndbout;
4128 }
4129
operator <<(NdbOut & ndbout,NdbDictionary::Object::Type const type)4130 NdbOut& operator <<(NdbOut& ndbout, NdbDictionary::Object::Type const type)
4131 {
4132 switch (type)
4133 {
4134 case NdbDictionary::Object::TypeUndefined:
4135 ndbout << "Undefined";
4136 break;
4137 case NdbDictionary::Object::SystemTable:
4138 ndbout << "SystemTable";
4139 break;
4140 case NdbDictionary::Object::UserTable:
4141 ndbout << "UserTable";
4142 break;
4143 case NdbDictionary::Object::UniqueHashIndex:
4144 ndbout << "UniqueHashIndex";
4145 break;
4146 case NdbDictionary::Object::OrderedIndex:
4147 ndbout << "OrderedIndex";
4148 break;
4149 case NdbDictionary::Object::HashIndexTrigger:
4150 ndbout << "HashIndexTrigger";
4151 break;
4152 case NdbDictionary::Object::IndexTrigger:
4153 ndbout << "IndexTrigger";
4154 break;
4155 case NdbDictionary::Object::SubscriptionTrigger:
4156 ndbout << "SubscriptionTrigger";
4157 break;
4158 case NdbDictionary::Object::ReadOnlyConstraint:
4159 ndbout << "ReadOnlyConstraint";
4160 break;
4161 case NdbDictionary::Object::TableEvent:
4162 ndbout << "TableEvent";
4163 break;
4164 case NdbDictionary::Object::Tablespace:
4165 ndbout << "Tablespace";
4166 break;
4167 case NdbDictionary::Object::LogfileGroup:
4168 ndbout << "LogfileGroup";
4169 break;
4170 case NdbDictionary::Object::Datafile:
4171 ndbout << "Datafile";
4172 break;
4173 case NdbDictionary::Object::Undofile:
4174 ndbout << "Undofile";
4175 break;
4176 case NdbDictionary::Object::ReorgTrigger:
4177 ndbout << "ReorgTrigger";
4178 break;
4179 case NdbDictionary::Object::HashMap:
4180 ndbout << "HashMap";
4181 break;
4182 case NdbDictionary::Object::ForeignKey:
4183 ndbout << "ForeignKey";
4184 break;
4185 case NdbDictionary::Object::FKParentTrigger:
4186 ndbout << "FKParentTrigger";
4187 break;
4188 case NdbDictionary::Object::FKChildTrigger:
4189 ndbout << "FKChildTrigger";
4190 break;
4191 default:
4192 ndbout << "Type " << (unsigned) type;
4193 }
4194 return ndbout;
4195 }
4196
operator <<(NdbOut & ndbout,NdbDictionary::Index::Type const type)4197 NdbOut& operator <<(NdbOut& ndbout, NdbDictionary::Index::Type const type)
4198 {
4199 switch (type)
4200 {
4201 case NdbDictionary::Index::Undefined:
4202 ndbout << "Undefined";
4203 break;
4204 case NdbDictionary::Index::UniqueHashIndex:
4205 ndbout << "UniqueHashIndex";
4206 break;
4207 case NdbDictionary::Index::OrderedIndex:
4208 ndbout << "OrderedIndex";
4209 break;
4210 default:
4211 ndbout << "Type " << (unsigned) type;
4212 }
4213 return ndbout;
4214 }
4215
operator <<(NdbOut & ndbout,NdbDictionary::Object::Status const status)4216 NdbOut& operator <<(NdbOut& ndbout, NdbDictionary::Object::Status const status)
4217 {
4218 switch (status)
4219 {
4220 case NdbDictionary::Object::New:
4221 ndbout << "New";
4222 break;
4223 case NdbDictionary::Object::Changed:
4224 ndbout << "Changed";
4225 break;
4226 case NdbDictionary::Object::Retrieved:
4227 ndbout << "Retrieved";
4228 break;
4229 case NdbDictionary::Object::Invalid:
4230 ndbout << "Invalid";
4231 break;
4232 case NdbDictionary::Object::Altered:
4233 ndbout << "Altered";
4234 break;
4235 default:
4236 ndbout << "Undefined(" << (unsigned) status << ")";
4237 }
4238 return ndbout;
4239 }
4240
operator <<(NdbOut & ndbout,NdbDictionary::Index const & idx)4241 NdbOut& operator <<(NdbOut& ndbout, NdbDictionary::Index const& idx)
4242 {
4243 ndbout << "Version: " << idx.getObjectVersion() << endl;
4244 ndbout << "Base table: " << idx.getTable() << endl;
4245 ndbout << "Number of attributes: " << idx.getNoOfColumns() << endl;
4246 ndbout << "Logging: " << idx.getLogging() << endl;
4247 ndbout << "Index type: " << idx.getType() << endl;
4248 ndbout << "Index status: " << idx.getObjectStatus() << endl;
4249
4250 return ndbout;
4251 }
4252
print(NdbOut & ndbout,NdbDictionary::Index const & idx)4253 void NdbDictionary::Dictionary::print(NdbOut& ndbout, NdbDictionary::Index const& idx)
4254 {
4255 ndbout << idx;
4256
4257 ndbout << "-- Attributes --" << endl;
4258 for (unsigned col = 0; col < idx.getNoOfColumns() ; col++)
4259 {
4260 ndbout << *idx.getColumn(col) << endl;
4261 }
4262
4263 Table const& indexTable = *NdbIndexImpl::getImpl(idx).getIndexTable();
4264 ndbout << "-- IndexTable " << indexTable.getName() << " --" << endl;
4265
4266 print(ndbout, indexTable);
4267 }
4268
operator <<(class NdbOut &,NdbDictionary::Table const & tab)4269 NdbOut& operator <<(class NdbOut&, NdbDictionary::Table const& tab)
4270 {
4271 ndbout << "Version: " << tab.getObjectVersion() << endl;
4272 ndbout << "Fragment type: " << tab.getFragmentType() << endl;
4273 ndbout << "K Value: " << tab.getKValue()<< endl;
4274 ndbout << "Min load factor: " << tab.getMinLoadFactor()<< endl;
4275 ndbout << "Max load factor: " << tab.getMaxLoadFactor()<< endl;
4276 ndbout << "Temporary table: " << (tab.getStoredTable() ? "no" : "yes") << endl;
4277 ndbout << "Number of attributes: " << tab.getNoOfColumns() << endl;
4278 ndbout << "Number of primary keys: " << tab.getNoOfPrimaryKeys() << endl;
4279 ndbout << "Length of frm data: " << tab.getFrmLength() << endl;
4280 ndbout << "Row Checksum: " << tab.getRowChecksumIndicator() << endl;
4281 ndbout << "Row GCI: " << tab.getRowGCIIndicator() << endl;
4282 ndbout << "SingleUserMode: " << (Uint32) tab.getSingleUserMode() << endl;
4283 ndbout << "ForceVarPart: " << tab.getForceVarPart() << endl;
4284 ndbout << "FragmentCount: " << tab.getFragmentCount() << endl;
4285 ndbout << "ExtraRowGciBits: " << tab.getExtraRowGciBits() << endl;
4286 ndbout << "ExtraRowAuthorBits: " << tab.getExtraRowAuthorBits() << endl;
4287 ndbout << "TableStatus: " << tab.getObjectStatus() << endl;
4288 return ndbout;
4289 }
4290
4291 NdbOut&
print_fk_tab_ref(NdbOut & ndbout,const char * fqn)4292 print_fk_tab_ref(NdbOut& ndbout, const char * fqn)
4293 {
4294 int cnt_slash = 0;
4295 {
4296 const char * ptr = fqn;
4297 while ((ptr = strchr(ptr, '/')) != 0)
4298 {
4299 ptr++;
4300 cnt_slash++;
4301 }
4302 }
4303
4304 if (cnt_slash == 2) // expected...
4305 {
4306 for (; * fqn != '/' ; fqn++)
4307 ndbout.print("%c", (* fqn));
4308 ndbout << ".";
4309
4310 for (fqn++ ; * fqn != '/' ; fqn++)
4311 {
4312 /**
4313 * catalog...
4314 */
4315 }
4316 for (fqn++ ; * fqn != 0; fqn++)
4317 {
4318 ndbout.print("%c", (* fqn));
4319 }
4320 }
4321 else
4322 {
4323 ndbout << fqn;
4324 }
4325 return ndbout;
4326 }
4327
4328 NdbOut&
print_fk_idx_ref(NdbOut & ndbout,const char * fqn)4329 print_fk_idx_ref(NdbOut& ndbout, const char * fqn)
4330 {
4331 if (fqn == 0)
4332 {
4333 ndbout << "PRIMARY KEY";
4334 }
4335 else
4336 {
4337 const char * ptr = strrchr(fqn, '/');
4338 if (ptr)
4339 {
4340 ndbout << (ptr + 1);
4341 }
4342 }
4343 return ndbout;
4344 }
4345
print(NdbOut & ndbout,NdbDictionary::Table const & tab)4346 void NdbDictionary::Dictionary::print(NdbOut& ndbout, NdbDictionary::Table const& tab)
4347 {
4348 ndbout << tab;
4349
4350 HashMap hashmap;
4351 if (getHashMap(hashmap, &tab) != -1)
4352 {
4353 ndbout << "HashMap: " << hashmap.getName() << endl;
4354 }
4355
4356 ndbout << "-- Attributes --" << endl;
4357 for (int col = 0; col < tab.getNoOfColumns() ; col++)
4358 {
4359 ndbout << *tab.getColumn(col) << endl;
4360 }
4361
4362 ndbout << "-- Indexes -- " << endl;
4363 ndbout << "PRIMARY KEY(";
4364 unsigned j;
4365 for (j= 0; (int)j < tab.getNoOfPrimaryKeys(); j++)
4366 {
4367 const Column * col= tab.getColumn(tab.getPrimaryKey(j));
4368 ndbout << col->getName();
4369 if ((int)j < tab.getNoOfPrimaryKeys()-1)
4370 ndbout << ", ";
4371 }
4372 ndbout << ") - UniqueHashIndex" << endl;
4373
4374 List list;
4375 if (listDependentObjects(list, tab) == 0)
4376 {
4377 for (j= 0; j < list.count; j++) {
4378 List::Element& elt = list.elements[j];
4379 if (elt.type != NdbDictionary::Object::UniqueHashIndex &&
4380 elt.type != NdbDictionary::Object::OrderedIndex)
4381 continue;
4382
4383 const Index *pIdx = getIndex(elt.name, tab);
4384 if (!pIdx)
4385 {
4386 #ifdef VM_TRACE
4387 assert(false);
4388 #endif
4389 continue;
4390 }
4391
4392 ndbout << pIdx->getName();
4393 ndbout << "(";
4394 unsigned noOfAttributes = pIdx->getNoOfColumns();
4395 for (unsigned i = 0; i < noOfAttributes; i++)
4396 {
4397 const Column *col = pIdx->getColumn(i);
4398 ndbout << col->getName();
4399 if (i < noOfAttributes - 1)
4400 ndbout << ", ";
4401 }
4402 ndbout << ")";
4403 ndbout << " - " << pIdx->getType();
4404 ndbout << endl;
4405 }
4406 }
4407 #ifdef VM_TRACE
4408 else assert(false);
4409 #endif
4410
4411 bool first = true;
4412 for (j= 0; j < list.count; j++)
4413 {
4414 List::Element& elt = list.elements[j];
4415 if (elt.type != NdbDictionary::Object::ForeignKey)
4416 continue;
4417
4418 NdbDictionary::ForeignKey fk;
4419 if (getForeignKey(fk, elt.name) == 0)
4420 {
4421 if (strcmp(fk.getChildTable(),
4422 NdbTableImpl::getImpl(tab).m_internalName.c_str()) == 0)
4423 {
4424 if (first)
4425 {
4426 first = false;
4427 ndbout << "-- ForeignKeys --" << endl;
4428 }
4429
4430 ndbout << fk.getName() << " ";
4431 print_fk_idx_ref(ndbout, fk.getChildIndex());
4432 ndbout << " (";
4433 for (unsigned i = 0; i < fk.getChildColumnCount(); i++)
4434 {
4435 ndbout << tab.getColumn(fk.getChildColumnNo(i))->getName();
4436 if (i + 1 != fk.getChildColumnCount())
4437 ndbout << ", ";
4438 }
4439 ndbout << ") REFERENCES ";
4440 print_fk_tab_ref(ndbout, fk.getParentTable());
4441 ndbout << "/";
4442 print_fk_idx_ref(ndbout, fk.getParentIndex());
4443 ndbout << " (";
4444 /**
4445 * TODO...
4446 */
4447 ndbout << ") ";
4448
4449 ndbout << "on update ";
4450 switch(fk.getOnUpdateAction()) {
4451 case NdbDictionary::ForeignKey::NoAction:
4452 ndbout << "noaction";
4453 break;
4454 case NdbDictionary::ForeignKey::Restrict:
4455 ndbout << "restrict";
4456 break;
4457 case NdbDictionary::ForeignKey::Cascade:
4458 ndbout << "cascade";
4459 break;
4460 case NdbDictionary::ForeignKey::SetNull:
4461 ndbout << "set null";
4462 break;
4463 case NdbDictionary::ForeignKey::SetDefault:
4464 ndbout << "set default";
4465 break;
4466 }
4467
4468 ndbout << " on delete ";
4469 switch(fk.getOnDeleteAction()) {
4470 case NdbDictionary::ForeignKey::NoAction:
4471 ndbout << "noaction";
4472 break;
4473 case NdbDictionary::ForeignKey::Restrict:
4474 ndbout << "restrict";
4475 break;
4476 case NdbDictionary::ForeignKey::Cascade:
4477 ndbout << "cascade";
4478 break;
4479 case NdbDictionary::ForeignKey::SetNull:
4480 ndbout << "set null";
4481 break;
4482 case NdbDictionary::ForeignKey::SetDefault:
4483 ndbout << "set default";
4484 break;
4485 }
4486
4487 ndbout << endl;
4488 }
4489 }
4490 }
4491 }
4492