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