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