MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbDictionary.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <NdbDictionary.hpp>
19 #include "NdbDictionaryImpl.hpp"
20 #include <NdbOut.hpp>
21 #include <signaldata/CreateHashMap.hpp>
22 #include <NdbBlob.hpp>
23 C_MODE_START
24 #include <decimal.h>
25 C_MODE_END
26 
27 /* NdbRecord static helper methods */
28 
29 NdbDictionary::RecordType
30 NdbDictionary::getRecordType(const NdbRecord* record)
31 {
32  return NdbDictionaryImpl::getRecordType(record);
33 }
34 
35 const char*
36 NdbDictionary::getRecordTableName(const NdbRecord* record)
37 {
38  return NdbDictionaryImpl::getRecordTableName(record);
39 }
40 
41 const char*
42 NdbDictionary::getRecordIndexName(const NdbRecord* record)
43 {
44  return NdbDictionaryImpl::getRecordIndexName(record);
45 }
46 
47 bool
48 NdbDictionary::getFirstAttrId(const NdbRecord* record,
49  Uint32& firstAttrId)
50 {
51  return NdbDictionaryImpl::getNextAttrIdFrom(record,
52  0,
53  firstAttrId);
54 }
55 
56 bool
57 NdbDictionary::getNextAttrId(const NdbRecord* record,
58  Uint32& attrId)
59 {
60  return NdbDictionaryImpl::getNextAttrIdFrom(record,
61  attrId+1,
62  attrId);
63 }
64 
65 bool
66 NdbDictionary::getOffset(const NdbRecord* record,
67  Uint32 attrId,
68  Uint32& offset)
69 {
70  return NdbDictionaryImpl::getOffset(record, attrId, offset);
71 }
72 
73 bool
74 NdbDictionary::getNullBitOffset(const NdbRecord* record,
75  Uint32 attrId,
76  Uint32& nullbit_byte_offset,
77  Uint32& nullbit_bit_in_byte)
78 {
79  return NdbDictionaryImpl::getNullBitOffset(record,
80  attrId,
81  nullbit_byte_offset,
82  nullbit_bit_in_byte);
83 }
84 
85 
86 const char*
87 NdbDictionary::getValuePtr(const NdbRecord* record,
88  const char* row,
89  Uint32 attrId)
90 {
91  return NdbDictionaryImpl::getValuePtr(record, row, attrId);
92 }
93 
94 char*
95 NdbDictionary::getValuePtr(const NdbRecord* record,
96  char* row,
97  Uint32 attrId)
98 {
99  return NdbDictionaryImpl::getValuePtr(record, row, attrId);
100 }
101 
102 bool
103 NdbDictionary::isNull(const NdbRecord* record,
104  const char* row,
105  Uint32 attrId)
106 {
107  return NdbDictionaryImpl::isNull(record, row, attrId);
108 }
109 
110 int
111 NdbDictionary::setNull(const NdbRecord* record,
112  char* row,
113  Uint32 attrId,
114  bool value)
115 {
116  return NdbDictionaryImpl::setNull(record, row, attrId, value);
117 }
118 
119 Uint32
120 NdbDictionary::getRecordRowLength(const NdbRecord* record)
121 {
122  return NdbDictionaryImpl::getRecordRowLength(record);
123 }
124 
125 const unsigned char*
126 NdbDictionary::getEmptyBitmask()
127 {
128  return (const unsigned char*) NdbDictionaryImpl::m_emptyMask;
129 }
130 
131 /* --- */
132 
133 NdbDictionary::ObjectId::ObjectId()
134  : m_impl(* new NdbDictObjectImpl(NdbDictionary::Object::TypeUndefined))
135 {
136 }
137 
138 NdbDictionary::ObjectId::~ObjectId()
139 {
140  NdbDictObjectImpl * tmp = &m_impl;
141  delete tmp;
142 }
143 
146  return m_impl.m_status;
147 }
148 
149 int
151  return m_impl.m_version;
152 }
153 
154 int
155 NdbDictionary::ObjectId::getObjectId() const {
156  return m_impl.m_id;
157 }
158 
159 /*****************************************************************
160  * Column facade
161  */
163  : m_impl(* new NdbColumnImpl(* this))
164 {
165  setName(name);
166 }
167 
169  : m_impl(* new NdbColumnImpl(* this))
170 {
171  m_impl = org.m_impl;
172 }
173 
175  : m_impl(impl)
176 {
177 }
178 
179 NdbDictionary::Column::~Column(){
180  NdbColumnImpl * tmp = &m_impl;
181  if(this != tmp){
182  delete tmp;
183  }
184 }
185 
187 NdbDictionary::Column::operator=(const NdbDictionary::Column& column)
188 {
189  m_impl = column.m_impl;
190 
191  return *this;
192 }
193 
194 int
196  return !m_impl.m_name.assign(name);
197 }
198 
199 const char*
201  return m_impl.m_name.c_str();
202 }
203 
204 void
206  m_impl.init(t);
207 }
208 
211  return m_impl.m_type;
212 }
213 
214 void
216  m_impl.m_precision = val;
217 }
218 
219 int
221  return m_impl.m_precision;
222 }
223 
224 void
226  m_impl.m_scale = val;
227 }
228 
229 int
231  return m_impl.m_scale;
232 }
233 
234 void
236  m_impl.m_length = length;
237 }
238 
239 int
241  return m_impl.m_length;
242 }
243 
244 void
246 {
247  m_impl.m_precision = size;
248 }
249 
250 void
252 {
253  m_impl.m_cs = cs;
254 }
255 
258 {
259  return m_impl.m_cs;
260 }
261 
262 int
264 {
265  return m_impl.m_cs->number;
266 }
267 
268 int
270 {
271  return m_impl.m_precision;
272 }
273 
274 void
276 {
277  m_impl.m_scale = size;
278 }
279 
280 int
282 {
283  return m_impl.m_scale;
284 }
285 
286 void
288 {
289  m_impl.m_length = size;
290 }
291 
292 int
294 {
295  return m_impl.m_length;
296 }
297 
298 int
300  return m_impl.m_attrSize;
301 }
302 
303 void
305  m_impl.m_nullable = val;
306 }
307 
308 bool
310  return m_impl.m_nullable;
311 }
312 
313 void
315  m_impl.m_pk = val;
316 }
317 
318 bool
320  return m_impl.m_pk;
321 }
322 
323 void
325  m_impl.m_distributionKey = val;
326 }
327 
328 bool
330  return m_impl.m_distributionKey;
331 }
332 
333 const NdbDictionary::Table *
334 NdbDictionary::Column::getBlobTable() const {
335  NdbTableImpl * t = m_impl.m_blobTable;
336  if (t)
337  return t->m_facade;
338  return 0;
339 }
340 
341 void
342 NdbDictionary::Column::setAutoIncrement(bool val){
343  m_impl.m_autoIncrement = val;
344 }
345 
346 bool
347 NdbDictionary::Column::getAutoIncrement() const {
348  return m_impl.m_autoIncrement;
349 }
350 
351 void
352 NdbDictionary::Column::setAutoIncrementInitialValue(Uint64 val){
353  m_impl.m_autoIncrementInitialValue = val;
354 }
355 
356 /*
357 * setDefaultValue() with only one const char * parameter is reserved
358 * for backward compatible api consideration, but is broken.
359 */
360 int
361 NdbDictionary::Column::setDefaultValue(const char* defaultValue)
362 {
363  return -1;
364 }
365 
366 /*
367  The significant length of a column can't easily be calculated before
368  the column type is fully defined, so the length of the default value
369  is passed in as a parameter explicitly.
370 */
371 int
372 NdbDictionary::Column::setDefaultValue(const void* defaultValue, unsigned int n)
373 {
374  if (defaultValue == NULL)
375  return m_impl.m_defaultValue.assign(NULL, 0);
376 
377  return m_impl.m_defaultValue.assign(defaultValue, n);
378 }
379 
380 const void*
381 NdbDictionary::Column::getDefaultValue(unsigned int* len) const
382 {
383  if (len)
384  *len = m_impl.m_defaultValue.length();
385 
386  return m_impl.m_defaultValue.get_data();
387 }
388 
389 int
391  return m_impl.m_column_no;
392 }
393 
394 int
395 NdbDictionary::Column::getAttrId() const {
396  return m_impl.m_attrId;
397 }
398 
399 bool
401  return m_impl.equal(col.m_impl);
402 }
403 
404 int
405 NdbDictionary::Column::getSizeInBytes() const
406 {
407  return m_impl.m_attrSize * m_impl.m_arraySize;
408 }
409 
410 void
411 NdbDictionary::Column::setArrayType(ArrayType type)
412 {
413  m_impl.m_arrayType = type;
414 }
415 
416 NdbDictionary::Column::ArrayType
417 NdbDictionary::Column::getArrayType() const
418 {
419  return (ArrayType)m_impl.m_arrayType;
420 }
421 
422 void
423 NdbDictionary::Column::setStorageType(StorageType type)
424 {
425  m_impl.m_storageType = type;
426 }
427 
428 NdbDictionary::Column::StorageType
429 NdbDictionary::Column::getStorageType() const
430 {
431  return (StorageType)m_impl.m_storageType;
432 }
433 
434 int
435 NdbDictionary::Column::getBlobVersion() const
436 {
437  return m_impl.getBlobVersion();
438 }
439 
440 void
441 NdbDictionary::Column::setBlobVersion(int blobVersion)
442 {
443  m_impl.setBlobVersion(blobVersion);
444 }
445 
446 void
448  m_impl.m_dynamic = val;
449 }
450 
451 bool
453  return m_impl.m_dynamic;
454 }
455 
456 bool
458  return m_impl.m_indexSourced;
459 }
460 
461 int
463 {
464  const NdbColumnImpl& parentColumn = col.m_impl;
465 
466  if (m_impl.m_type != parentColumn.m_type ||
467  m_impl.m_precision != parentColumn.m_precision ||
468  m_impl.m_scale != parentColumn.m_scale ||
469  m_impl.m_length != parentColumn.m_length ||
470  m_impl.m_cs != parentColumn.m_cs)
471  return -1;
472 
473  if (m_impl.m_type == NdbDictionary::Column::Blob ||
474  m_impl.m_type == NdbDictionary::Column::Text)
475  return -1;
476 
477  return 0; // ok
478 }
479 
480 /*****************************************************************
481  * Table facade
482  */
484  : m_impl(* new NdbTableImpl(* this))
485 {
486  setName(name);
487 }
488 
490  : Object(org), m_impl(* new NdbTableImpl(* this))
491 {
492  m_impl.assign(org.m_impl);
493 }
494 
496  : m_impl(impl)
497 {
498 }
499 
500 NdbDictionary::Table::~Table(){
501  NdbTableImpl * tmp = &m_impl;
502  if(this != tmp){
503  delete tmp;
504  }
505 }
506 
509 {
510  m_impl.assign(table.m_impl);
511 
512  m_impl.m_facade = this;
513  return *this;
514 }
515 
516 int
518  return m_impl.setName(name);
519 }
520 
521 const char *
523  return m_impl.getName();
524 }
525 
526 const char *
527 NdbDictionary::Table::getMysqlName() const {
528  return m_impl.getMysqlName();
529 }
530 
531 int
533  return m_impl.m_id;
534 }
535 
536 int
538  NdbColumnImpl* col = new NdbColumnImpl;
539  if (col == NULL)
540  {
541  errno = ENOMEM;
542  return -1;
543  }
544  (* col) = NdbColumnImpl::getImpl(c);
545  if (m_impl.m_columns.push_back(col))
546  {
547  return -1;
548  }
549  if (m_impl.buildColumnHash())
550  {
551  return -1;
552  }
553  col->m_column_no = m_impl.m_columns.size() - 1;
554  return 0;
555 }
556 
559  return m_impl.getColumn(name);
560 }
561 
562 const NdbDictionary::Column*
563 NdbDictionary::Table::getColumn(const int attrId) const {
564  return m_impl.getColumn(attrId);
565 }
566 
569 {
570  return m_impl.getColumn(name);
571 }
572 
575 {
576  return m_impl.getColumn(attrId);
577 }
578 
579 void
581  m_impl.m_logging = val;
582 }
583 
584 bool
586  return m_impl.m_logging;
587 }
588 
589 void
591  m_impl.m_fragmentType = ft;
592 }
593 
596  return m_impl.m_fragmentType;
597 }
598 
599 void
601  m_impl.m_kvalue = kValue;
602 }
603 
604 int
606  return m_impl.m_kvalue;
607 }
608 
609 void
611  m_impl.m_minLoadFactor = lf;
612 }
613 
614 int
616  return m_impl.m_minLoadFactor;
617 }
618 
619 void
621  m_impl.m_maxLoadFactor = lf;
622 }
623 
624 int
626  return m_impl.m_maxLoadFactor;
627 }
628 
629 int
631  return m_impl.m_columns.size();
632 }
633 
634 int
636  return m_impl.m_noOfAutoIncColumns;
637 }
638 
639 int
641  return m_impl.m_noOfKeys;
642 }
643 
644 void
646 {
647  m_impl.m_max_rows = maxRows;
648 }
649 
650 Uint64
651 NdbDictionary::Table::getMaxRows() const
652 {
653  return m_impl.m_max_rows;
654 }
655 
656 void
658 {
659  m_impl.m_min_rows = minRows;
660 }
661 
662 Uint64
663 NdbDictionary::Table::getMinRows() const
664 {
665  return m_impl.m_min_rows;
666 }
667 
668 void
670 {
671  m_impl.m_default_no_part_flag = flag;
672 }
673 
674 Uint32
675 NdbDictionary::Table::getDefaultNoPartitionsFlag() const
676 {
677  return m_impl.m_default_no_part_flag;
678 }
679 
680 const char*
682  int count = 0;
683  for (unsigned i = 0; i < m_impl.m_columns.size(); i++) {
684  if (m_impl.m_columns[i]->m_pk) {
685  if (count++ == no)
686  return m_impl.m_columns[i]->m_name.c_str();
687  }
688  }
689  return 0;
690 }
691 
692 const void*
694  return m_impl.getFrmData();
695 }
696 
697 Uint32
698 NdbDictionary::Table::getFrmLength() const {
699  return m_impl.getFrmLength();
700 }
701 
702 enum NdbDictionary::Table::SingleUserMode
703 NdbDictionary::Table::getSingleUserMode() const
704 {
705  return (enum SingleUserMode)m_impl.m_single_user_mode;
706 }
707 
708 void
709 NdbDictionary::Table::setSingleUserMode(enum NdbDictionary::Table::SingleUserMode mode)
710 {
711  m_impl.m_single_user_mode = (Uint8)mode;
712 }
713 
714 #if 0
715 int
716 NdbDictionary::Table::setTablespaceNames(const void *data, Uint32 len)
717 {
718  return m_impl.setTablespaceNames(data, len);
719 }
720 
721 const void*
722 NdbDictionary::Table::getTablespaceNames()
723 {
724  return m_impl.getTablespaceNames();
725 }
726 
727 Uint32
728 NdbDictionary::Table::getTablespaceNamesLen() const
729 {
730  return m_impl.getTablespaceNamesLen();
731 }
732 #endif
733 
734 void
736 {
737  m_impl.m_linear_flag = flag;
738 }
739 
740 bool
741 NdbDictionary::Table::getLinearFlag() const
742 {
743  return m_impl.m_linear_flag;
744 }
745 
746 void
748 {
749  m_impl.setFragmentCount(count);
750 }
751 
752 Uint32
754 {
755  return m_impl.getFragmentCount();
756 }
757 
758 int
759 NdbDictionary::Table::setFrm(const void* data, Uint32 len){
760  return m_impl.setFrm(data, len);
761 }
762 
763 const Uint32*
765  return m_impl.getFragmentData();
766 }
767 
768 Uint32
769 NdbDictionary::Table::getFragmentDataLen() const {
770  return m_impl.getFragmentDataLen();
771 }
772 
773 int
774 NdbDictionary::Table::setFragmentData(const Uint32* data, Uint32 cnt)
775 {
776  return m_impl.setFragmentData(data, cnt);
777 }
778 
779 const Int32*
781  return m_impl.getRangeListData();
782 }
783 
784 Uint32
785 NdbDictionary::Table::getRangeListDataLen() const {
786  return m_impl.getRangeListDataLen();
787 }
788 
789 int
790 NdbDictionary::Table::setRangeListData(const Int32* data, Uint32 len)
791 {
792  return m_impl.setRangeListData(data, len);
793 }
794 
795 Uint32
797  Uint32* nodeIdArrayPtr,
798  Uint32 arraySize) const
799 {
800  return m_impl.getFragmentNodes(fragmentId, nodeIdArrayPtr, arraySize);
801 }
802 
805  return m_impl.m_status;
806 }
807 
808 void
809 NdbDictionary::Table::setStatusInvalid() const {
810  m_impl.m_status = NdbDictionary::Object::Invalid;
811 }
812 
813 int
815  return m_impl.m_version;
816 }
817 
818 int
820  return m_impl.m_id;
821 }
822 
823 bool
825  return m_impl.equal(col.m_impl);
826 }
827 
828 int
829 NdbDictionary::Table::getRowSizeInBytes() const {
830  int sz = 0;
831  for(int i = 0; i<getNoOfColumns(); i++){
832  const NdbDictionary::Column * c = getColumn(i);
833  sz += (c->getSizeInBytes()+ 3) / 4;
834  }
835  return sz * 4;
836 }
837 
838 int
839 NdbDictionary::Table::getReplicaCount() const {
840  return m_impl.m_replicaCount;
841 }
842 
843 bool
844 NdbDictionary::Table::getTemporary() const {
845  return m_impl.m_temporary;
846 }
847 
848 void
849 NdbDictionary::Table::setTemporary(bool val) {
850  m_impl.m_temporary = val;
851 }
852 
853 int
854 NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const {
855  const NdbDictionary::Table * pTab =
856  pNdb->getDictionary()->getTable(getName());
857  if(pTab != 0 && equal(* pTab))
858  return 0;
859  if(pTab != 0 && !equal(* pTab))
860  return -1;
861  return pNdb->getDictionary()->createTable(* this);
862 }
863 
864 bool
865 NdbDictionary::Table::getTablespace(Uint32 *id, Uint32 *version) const
866 {
867  if (m_impl.m_tablespace_id == RNIL)
868  return false;
869  if (id)
870  *id= m_impl.m_tablespace_id;
871  if (version)
872  *version= m_impl.m_version;
873  return true;
874 }
875 
876 const char *
877 NdbDictionary::Table::getTablespaceName() const
878 {
879  return m_impl.m_tablespace_name.c_str();
880 }
881 
882 int
883 NdbDictionary::Table::setTablespaceName(const char * name){
884  m_impl.m_tablespace_id = ~0;
885  m_impl.m_tablespace_version = ~0;
886  return !m_impl.m_tablespace_name.assign(name);
887 }
888 
889 int
890 NdbDictionary::Table::setTablespace(const NdbDictionary::Tablespace & ts){
891  m_impl.m_tablespace_id = NdbTablespaceImpl::getImpl(ts).m_id;
892  m_impl.m_tablespace_version = ts.getObjectVersion();
893  return !m_impl.m_tablespace_name.assign(ts.getName());
894 }
895 
896 bool
897 NdbDictionary::Table::getHashMap(Uint32 *id, Uint32 *version) const
898 {
899  if (m_impl.m_hash_map_id == RNIL)
900  return false;
901  if (id)
902  *id= m_impl.m_hash_map_id;
903  if (version)
904  *version= m_impl.m_hash_map_version;
905  return true;
906 }
907 
908 int
909 NdbDictionary::Table::setHashMap(const NdbDictionary::HashMap& hm)
910 {
911  m_impl.m_hash_map_id = hm.getObjectId();
912  m_impl.m_hash_map_version = hm.getObjectVersion();
913  return 0;
914 }
915 
916 void
917 NdbDictionary::Table::setRowChecksumIndicator(bool val){
918  m_impl.m_row_checksum = val;
919 }
920 
921 bool
922 NdbDictionary::Table::getRowChecksumIndicator() const {
923  return m_impl.m_row_checksum;
924 }
925 
926 void
927 NdbDictionary::Table::setRowGCIIndicator(bool val){
928  m_impl.m_row_gci = val;
929 }
930 
931 bool
932 NdbDictionary::Table::getRowGCIIndicator() const {
933  return m_impl.m_row_gci;
934 }
935 
936 void
938 {
939  if (val <= 31)
940  {
941  m_impl.m_extra_row_gci_bits = val;
942  }
943 }
944 
945 Uint32
946 NdbDictionary::Table::getExtraRowGciBits() const
947 {
948  return m_impl.m_extra_row_gci_bits;
949 }
950 
951 void
953 {
954  if (val <= 31)
955  {
956  m_impl.m_extra_row_author_bits = val;
957  }
958 }
959 
960 Uint32
961 NdbDictionary::Table::getExtraRowAuthorBits() const
962 {
963  return m_impl.m_extra_row_author_bits;
964 }
965 
966 void
967 NdbDictionary::Table::setForceVarPart(bool val){
968  m_impl.m_force_var_part = val;
969 }
970 
971 bool
973  return m_impl.m_force_var_part;
974 }
975 
976 bool
977 NdbDictionary::Table::hasDefaultValues() const {
978  return m_impl.m_has_default_values;
979 }
980 
981 const NdbRecord*
983  return m_impl.m_ndbrecord;
984 }
985 
986 int
988 {
989  return m_impl.aggregate(error);
990 }
991 
992 int
994 {
995  return m_impl.validate(error);
996 }
997 
998 Uint32
1000 {
1001  switch (m_impl.m_fragmentType){
1006  case NdbDictionary::Object::DistrKeyLin:
1007  {
1008  Uint32 fragmentId = hashValue & m_impl.m_hashValueMask;
1009  if(fragmentId < m_impl.m_hashpointerValue)
1010  fragmentId = hashValue & ((m_impl.m_hashValueMask << 1) + 1);
1011  return fragmentId;
1012  }
1013  case NdbDictionary::Object::DistrKeyHash:
1014  {
1015  Uint32 cnt = m_impl.m_fragmentCount;
1016  return hashValue % (cnt ? cnt : 1);
1017  }
1018  case NdbDictionary::Object::HashMapPartition:
1019  {
1020  Uint32 cnt = m_impl.m_hash_map.size();
1021  return m_impl.m_hash_map[hashValue % cnt];
1022  }
1023  default:
1024  return 0;
1025  }
1026 }
1027 
1028 void
1030 {
1031  const NdbDictObjectImpl& objId = NdbDictObjectImpl::getImpl(_objId);
1032  m_impl.m_id = objId.m_id;
1033  m_impl.m_version = objId.m_version;
1034 }
1035 
1036 void
1037 NdbDictionary::Table::setStorageType(NdbDictionary::Column::StorageType type)
1038 {
1039  m_impl.m_storageType = type;
1040 }
1041 
1042 NdbDictionary::Column::StorageType
1043 NdbDictionary::Table::getStorageType() const
1044 {
1045  return (NdbDictionary::Column::StorageType)m_impl.m_storageType;
1046 }
1047 
1048 /*****************************************************************
1049  * Index facade
1050  */
1051 
1053  : m_impl(* new NdbIndexImpl(* this))
1054 {
1055  setName(name);
1056 }
1057 
1059  : m_impl(impl)
1060 {
1061 }
1062 
1063 NdbDictionary::Index::~Index(){
1064  NdbIndexImpl * tmp = &m_impl;
1065  if(this != tmp){
1066  delete tmp;
1067  }
1068 }
1069 
1070 int
1072  return m_impl.setName(name);
1073 }
1074 
1075 const char *
1077  return m_impl.getName();
1078 }
1079 
1080 int
1082  return m_impl.setTable(table);
1083 }
1084 
1085 const char *
1087  return m_impl.getTable();
1088 }
1089 
1090 unsigned
1092  return m_impl.m_columns.size();
1093 }
1094 
1095 int
1097  return m_impl.m_columns.size();
1098 }
1099 
1100 const NdbDictionary::Column *
1102  if(no < m_impl.m_columns.size())
1103  return m_impl.m_columns[no];
1104  return NULL;
1105 }
1106 
1107 const char *
1109  const NdbDictionary::Column* col = getColumn(no);
1110 
1111  if (col)
1112  return col->getName();
1113  else
1114  return NULL;
1115 }
1116 
1117 const NdbRecord*
1119  return m_impl.m_table->m_ndbrecord;
1120 }
1121 
1122 int
1124  NdbColumnImpl* col = new NdbColumnImpl;
1125  if (col == NULL)
1126  {
1127  errno = ENOMEM;
1128  return -1;
1129  }
1130  (* col) = NdbColumnImpl::getImpl(c);
1131 
1132  col->m_indexSourced=true;
1133 
1134  /* Remove defaults from indexed columns */
1135  col->m_defaultValue.clear();
1136 
1137  if (m_impl.m_columns.push_back(col))
1138  {
1139  return -1;
1140  }
1141  return 0;
1142 }
1143 
1144 int
1146  const Column c(name);
1147  return addColumn(c);
1148 }
1149 
1150 int
1152  const Column c(name);
1153  return addColumn(c);
1154 }
1155 
1156 int
1157 NdbDictionary::Index::addColumnNames(unsigned noOfNames, const char ** names){
1158  for(unsigned i = 0; i < noOfNames; i++) {
1159  const Column c(names[i]);
1160  if (addColumn(c))
1161  {
1162  return -1;
1163  }
1164  }
1165  return 0;
1166 }
1167 
1168 int
1169 NdbDictionary::Index::addIndexColumns(int noOfNames, const char ** names){
1170  for(int i = 0; i < noOfNames; i++) {
1171  const Column c(names[i]);
1172  if (addColumn(c))
1173  {
1174  return -1;
1175  }
1176  }
1177  return 0;
1178 }
1179 
1180 void
1182  m_impl.m_type = (NdbDictionary::Object::Type)t;
1183 }
1184 
1187  return (NdbDictionary::Index::Type)m_impl.m_type;
1188 }
1189 
1190 void
1192  m_impl.m_logging = val;
1193 }
1194 
1195 bool
1196 NdbDictionary::Index::getTemporary() const {
1197  return m_impl.m_temporary;
1198 }
1199 
1200 void
1201 NdbDictionary::Index::setTemporary(bool val){
1202  m_impl.m_temporary = val;
1203 }
1204 
1205 bool
1207  return m_impl.m_logging;
1208 }
1209 
1212  return m_impl.m_table->m_status;
1213 }
1214 
1215 int
1217  return m_impl.m_table->m_version;
1218 }
1219 
1220 int
1222  return m_impl.m_table->m_id;
1223 }
1224 
1225 /*****************************************************************
1226  * OptimizeTableHandle facade
1227  */
1229  : m_impl(* new NdbOptimizeTableHandleImpl(* this))
1230 {}
1231 
1233  : m_impl(impl)
1234 {}
1235 
1236 NdbDictionary::OptimizeTableHandle::~OptimizeTableHandle()
1237 {
1238  NdbOptimizeTableHandleImpl * tmp = &m_impl;
1239  if(this != tmp){
1240  delete tmp;
1241  }
1242 }
1243 
1244 int
1246 {
1247  return m_impl.next();
1248 }
1249 
1250 int
1252 {
1253  int result = m_impl.close();
1254  return result;
1255 }
1256 
1257 /*****************************************************************
1258  * OptimizeIndexHandle facade
1259  */
1261  : m_impl(* new NdbOptimizeIndexHandleImpl(* this))
1262 {}
1263 
1265  : m_impl(impl)
1266 {}
1267 
1268 NdbDictionary::OptimizeIndexHandle::~OptimizeIndexHandle()
1269 {
1270  NdbOptimizeIndexHandleImpl * tmp = &m_impl;
1271  if(this != tmp){
1272  delete tmp;
1273  }
1274 }
1275 
1276 int
1278 {
1279  return m_impl.next();
1280 }
1281 
1282 int
1284 {
1285  int result = m_impl.close();
1286  return result;
1287 }
1288 
1289 /*****************************************************************
1290  * Event facade
1291  */
1293  : m_impl(* new NdbEventImpl(* this))
1294 {
1295  setName(name);
1296 }
1297 
1298 NdbDictionary::Event::Event(const char * name, const Table& table)
1299  : m_impl(* new NdbEventImpl(* this))
1300 {
1301  setName(name);
1302  setTable(table);
1303 }
1304 
1306  : m_impl(impl)
1307 {
1308 }
1309 
1310 NdbDictionary::Event::~Event()
1311 {
1312  NdbEventImpl * tmp = &m_impl;
1313  if(this != tmp){
1314  delete tmp;
1315  }
1316 }
1317 
1318 int
1320 {
1321  return m_impl.setName(name);
1322 }
1323 
1324 const char *
1326 {
1327  return m_impl.getName();
1328 }
1329 
1330 void
1332 {
1333  m_impl.setTable(table);
1334 }
1335 
1336 const NdbDictionary::Table *
1338 {
1339  return m_impl.getTable();
1340 }
1341 
1342 int
1344 {
1345  return m_impl.setTable(table);
1346 }
1347 
1348 const char*
1350 {
1351  return m_impl.getTableName();
1352 }
1353 
1354 void
1356 {
1357  m_impl.addTableEvent(t);
1358 }
1359 
1360 bool
1362 {
1363  return m_impl.getTableEvent(t);
1364 }
1365 
1366 void
1368 {
1369  m_impl.setDurability(d);
1370 }
1371 
1374 {
1375  return m_impl.getDurability();
1376 }
1377 
1378 void
1380 {
1381  m_impl.setReport(r);
1382 }
1383 
1386 {
1387  return m_impl.getReport();
1388 }
1389 
1390 void
1391 NdbDictionary::Event::addColumn(const Column & c){
1392  NdbColumnImpl* col = new NdbColumnImpl;
1393  (* col) = NdbColumnImpl::getImpl(c);
1394  m_impl.m_columns.push_back(col);
1395 }
1396 
1397 void
1399 {
1400  m_impl.m_attrIds.push_back(attrId);
1401 }
1402 
1403 void
1405 {
1406  const Column c(name);
1407  addColumn(c);
1408 }
1409 
1410 void
1411 NdbDictionary::Event::addEventColumns(int n, const char ** names)
1412 {
1413  for (int i = 0; i < n; i++)
1414  addEventColumn(names[i]);
1415 }
1416 
1418 {
1419  return m_impl.getNoOfEventColumns();
1420 }
1421 
1422 const NdbDictionary::Column *
1424 {
1425  return m_impl.getEventColumn(no);
1426 }
1427 
1429 {
1430  m_impl.m_mergeEvents = flag;
1431 }
1432 
1435 {
1436  return m_impl.m_status;
1437 }
1438 
1439 int
1441 {
1442  return m_impl.m_version;
1443 }
1444 
1445 int
1447  return m_impl.m_id;
1448 }
1449 
1450 void NdbDictionary::Event::print()
1451 {
1452  m_impl.print();
1453 }
1454 
1455 /*****************************************************************
1456  * Tablespace facade
1457  */
1458 NdbDictionary::Tablespace::Tablespace()
1459  : m_impl(* new NdbTablespaceImpl(* this))
1460 {
1461 }
1462 
1463 NdbDictionary::Tablespace::Tablespace(NdbTablespaceImpl & impl)
1464  : m_impl(impl)
1465 {
1466 }
1467 
1468 NdbDictionary::Tablespace::Tablespace(const NdbDictionary::Tablespace & org)
1469  : Object(org), m_impl(* new NdbTablespaceImpl(* this))
1470 {
1471  m_impl.assign(org.m_impl);
1472 }
1473 
1474 NdbDictionary::Tablespace::~Tablespace(){
1475  NdbTablespaceImpl * tmp = &m_impl;
1476  if(this != tmp){
1477  delete tmp;
1478  }
1479 }
1480 
1481 void
1482 NdbDictionary::Tablespace::setName(const char * name){
1483  m_impl.m_name.assign(name);
1484 }
1485 
1486 const char *
1487 NdbDictionary::Tablespace::getName() const {
1488  return m_impl.m_name.c_str();
1489 }
1490 
1491 void
1492 NdbDictionary::Tablespace::setAutoGrowSpecification
1494  m_impl.m_grow_spec = spec;
1495 }
1497 NdbDictionary::Tablespace::getAutoGrowSpecification() const {
1498  return m_impl.m_grow_spec;
1499 }
1500 
1501 void
1502 NdbDictionary::Tablespace::setExtentSize(Uint32 sz){
1503  m_impl.m_extent_size = sz;
1504 }
1505 
1506 Uint32
1507 NdbDictionary::Tablespace::getExtentSize() const {
1508  return m_impl.m_extent_size;
1509 }
1510 
1511 void
1512 NdbDictionary::Tablespace::setDefaultLogfileGroup(const char * name){
1513  m_impl.m_logfile_group_id = ~0;
1514  m_impl.m_logfile_group_version = ~0;
1515  m_impl.m_logfile_group_name.assign(name);
1516 }
1517 
1518 void
1519 NdbDictionary::Tablespace::setDefaultLogfileGroup
1520 (const NdbDictionary::LogfileGroup & lg){
1521  m_impl.m_logfile_group_id = NdbLogfileGroupImpl::getImpl(lg).m_id;
1522  m_impl.m_logfile_group_version = lg.getObjectVersion();
1523  m_impl.m_logfile_group_name.assign(lg.getName());
1524 }
1525 
1526 const char *
1527 NdbDictionary::Tablespace::getDefaultLogfileGroup() const {
1528  return m_impl.m_logfile_group_name.c_str();
1529 }
1530 
1531 Uint32
1532 NdbDictionary::Tablespace::getDefaultLogfileGroupId() const {
1533  return m_impl.m_logfile_group_id;
1534 }
1535 
1538  return m_impl.m_status;
1539 }
1540 
1541 int
1543  return m_impl.m_version;
1544 }
1545 
1546 int
1548  return m_impl.m_id;
1549 }
1550 
1551 /*****************************************************************
1552  * LogfileGroup facade
1553  */
1554 NdbDictionary::LogfileGroup::LogfileGroup()
1555  : m_impl(* new NdbLogfileGroupImpl(* this))
1556 {
1557 }
1558 
1559 NdbDictionary::LogfileGroup::LogfileGroup(NdbLogfileGroupImpl & impl)
1560  : m_impl(impl)
1561 {
1562 }
1563 
1564 NdbDictionary::LogfileGroup::LogfileGroup(const NdbDictionary::LogfileGroup & org)
1565  : Object(org), m_impl(* new NdbLogfileGroupImpl(* this))
1566 {
1567  m_impl.assign(org.m_impl);
1568 }
1569 
1570 NdbDictionary::LogfileGroup::~LogfileGroup(){
1571  NdbLogfileGroupImpl * tmp = &m_impl;
1572  if(this != tmp){
1573  delete tmp;
1574  }
1575 }
1576 
1577 void
1578 NdbDictionary::LogfileGroup::setName(const char * name){
1579  m_impl.m_name.assign(name);
1580 }
1581 
1582 const char *
1583 NdbDictionary::LogfileGroup::getName() const {
1584  return m_impl.m_name.c_str();
1585 }
1586 
1587 void
1588 NdbDictionary::LogfileGroup::setUndoBufferSize(Uint32 sz){
1589  m_impl.m_undo_buffer_size = sz;
1590 }
1591 
1592 Uint32
1593 NdbDictionary::LogfileGroup::getUndoBufferSize() const {
1594  return m_impl.m_undo_buffer_size;
1595 }
1596 
1597 void
1598 NdbDictionary::LogfileGroup::setAutoGrowSpecification
1600  m_impl.m_grow_spec = spec;
1601 }
1603 NdbDictionary::LogfileGroup::getAutoGrowSpecification() const {
1604  return m_impl.m_grow_spec;
1605 }
1606 
1607 Uint64 NdbDictionary::LogfileGroup::getUndoFreeWords() const {
1608  return m_impl.m_undo_free_words;
1609 }
1610 
1613  return m_impl.m_status;
1614 }
1615 
1616 int
1618  return m_impl.m_version;
1619 }
1620 
1621 int
1623  return m_impl.m_id;
1624 }
1625 
1626 /*****************************************************************
1627  * Datafile facade
1628  */
1629 NdbDictionary::Datafile::Datafile()
1630  : m_impl(* new NdbDatafileImpl(* this))
1631 {
1632 }
1633 
1634 NdbDictionary::Datafile::Datafile(NdbDatafileImpl & impl)
1635  : m_impl(impl)
1636 {
1637 }
1638 
1639 NdbDictionary::Datafile::Datafile(const NdbDictionary::Datafile & org)
1640  : Object(org), m_impl(* new NdbDatafileImpl(* this))
1641 {
1642  m_impl.assign(org.m_impl);
1643 }
1644 
1645 NdbDictionary::Datafile::~Datafile(){
1646  NdbDatafileImpl * tmp = &m_impl;
1647  if(this != tmp){
1648  delete tmp;
1649  }
1650 }
1651 
1652 void
1653 NdbDictionary::Datafile::setPath(const char * path){
1654  m_impl.m_path.assign(path);
1655 }
1656 
1657 const char *
1658 NdbDictionary::Datafile::getPath() const {
1659  return m_impl.m_path.c_str();
1660 }
1661 
1662 void
1663 NdbDictionary::Datafile::setSize(Uint64 sz){
1664  m_impl.m_size = sz;
1665 }
1666 
1667 Uint64
1668 NdbDictionary::Datafile::getSize() const {
1669  return m_impl.m_size;
1670 }
1671 
1672 Uint64
1673 NdbDictionary::Datafile::getFree() const {
1674  return m_impl.m_free;
1675 }
1676 
1677 int
1678 NdbDictionary::Datafile::setTablespace(const char * tablespace){
1679  m_impl.m_filegroup_id = ~0;
1680  m_impl.m_filegroup_version = ~0;
1681  return !m_impl.m_filegroup_name.assign(tablespace);
1682 }
1683 
1684 int
1685 NdbDictionary::Datafile::setTablespace(const NdbDictionary::Tablespace & ts){
1686  m_impl.m_filegroup_id = NdbTablespaceImpl::getImpl(ts).m_id;
1687  m_impl.m_filegroup_version = ts.getObjectVersion();
1688  return !m_impl.m_filegroup_name.assign(ts.getName());
1689 }
1690 
1691 const char *
1692 NdbDictionary::Datafile::getTablespace() const {
1693  return m_impl.m_filegroup_name.c_str();
1694 }
1695 
1696 void
1697 NdbDictionary::Datafile::getTablespaceId(NdbDictionary::ObjectId* dst) const
1698 {
1699  if (dst)
1700  {
1701  NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id;
1702  NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version;
1703  }
1704 }
1705 
1708  return m_impl.m_status;
1709 }
1710 
1711 int
1713  return m_impl.m_version;
1714 }
1715 
1716 int
1718  return m_impl.m_id;
1719 }
1720 
1721 /*****************************************************************
1722  * Undofile facade
1723  */
1724 NdbDictionary::Undofile::Undofile()
1725  : m_impl(* new NdbUndofileImpl(* this))
1726 {
1727 }
1728 
1729 NdbDictionary::Undofile::Undofile(NdbUndofileImpl & impl)
1730  : m_impl(impl)
1731 {
1732 }
1733 
1734 NdbDictionary::Undofile::Undofile(const NdbDictionary::Undofile & org)
1735  : Object(org), m_impl(* new NdbUndofileImpl(* this))
1736 {
1737  m_impl.assign(org.m_impl);
1738 }
1739 
1740 NdbDictionary::Undofile::~Undofile(){
1741  NdbUndofileImpl * tmp = &m_impl;
1742  if(this != tmp){
1743  delete tmp;
1744  }
1745 }
1746 
1747 void
1748 NdbDictionary::Undofile::setPath(const char * path){
1749  m_impl.m_path.assign(path);
1750 }
1751 
1752 const char *
1753 NdbDictionary::Undofile::getPath() const {
1754  return m_impl.m_path.c_str();
1755 }
1756 
1757 void
1758 NdbDictionary::Undofile::setSize(Uint64 sz){
1759  m_impl.m_size = sz;
1760 }
1761 
1762 Uint64
1763 NdbDictionary::Undofile::getSize() const {
1764  return m_impl.m_size;
1765 }
1766 
1767 void
1768 NdbDictionary::Undofile::setLogfileGroup(const char * logfileGroup){
1769  m_impl.m_filegroup_id = ~0;
1770  m_impl.m_filegroup_version = ~0;
1771  m_impl.m_filegroup_name.assign(logfileGroup);
1772 }
1773 
1774 void
1775 NdbDictionary::Undofile::setLogfileGroup
1776 (const NdbDictionary::LogfileGroup & ts){
1777  m_impl.m_filegroup_id = NdbLogfileGroupImpl::getImpl(ts).m_id;
1778  m_impl.m_filegroup_version = ts.getObjectVersion();
1779  m_impl.m_filegroup_name.assign(ts.getName());
1780 }
1781 
1782 const char *
1783 NdbDictionary::Undofile::getLogfileGroup() const {
1784  return m_impl.m_filegroup_name.c_str();
1785 }
1786 
1787 void
1788 NdbDictionary::Undofile::getLogfileGroupId(NdbDictionary::ObjectId * dst)const
1789 {
1790  if (dst)
1791  {
1792  NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id;
1793  NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version;
1794  }
1795 }
1796 
1799  return m_impl.m_status;
1800 }
1801 
1802 int
1804  return m_impl.m_version;
1805 }
1806 
1807 int
1809  return m_impl.m_id;
1810 }
1811 
1812 /*****************************************************************
1813  * HashMap facade
1814  */
1815 NdbDictionary::HashMap::HashMap()
1816  : m_impl(* new NdbHashMapImpl(* this))
1817 {
1818 }
1819 
1820 NdbDictionary::HashMap::HashMap(NdbHashMapImpl & impl)
1821  : m_impl(impl)
1822 {
1823 }
1824 
1825 NdbDictionary::HashMap::HashMap(const NdbDictionary::HashMap & org)
1826  : Object(org), m_impl(* new NdbHashMapImpl(* this))
1827 {
1828  m_impl.assign(org.m_impl);
1829 }
1830 
1831 NdbDictionary::HashMap::~HashMap(){
1832  NdbHashMapImpl * tmp = &m_impl;
1833  if(this != tmp){
1834  delete tmp;
1835  }
1836 }
1837 
1838 void
1839 NdbDictionary::HashMap::setName(const char * path)
1840 {
1841  m_impl.m_name.assign(path);
1842 }
1843 
1844 const char *
1845 NdbDictionary::HashMap::getName() const
1846 {
1847  return m_impl.m_name.c_str();
1848 }
1849 
1850 void
1851 NdbDictionary::HashMap::setMap(const Uint32* map, Uint32 len)
1852 {
1853  m_impl.m_map.assign(map, len);
1854 }
1855 
1856 Uint32
1857 NdbDictionary::HashMap::getMapLen() const
1858 {
1859  return m_impl.m_map.size();
1860 }
1861 
1862 int
1863 NdbDictionary::HashMap::getMapValues(Uint32* dst, Uint32 len) const
1864 {
1865  if (len != getMapLen())
1866  return -1;
1867 
1868  memcpy(dst, m_impl.m_map.getBase(), sizeof(Uint32) * len);
1869  return 0;
1870 }
1871 
1872 bool
1874 {
1875  return m_impl.m_map.equal(obj.m_impl.m_map);
1876 }
1877 
1880  return m_impl.m_status;
1881 }
1882 
1883 int
1885  return m_impl.m_version;
1886 }
1887 
1888 int
1890  return m_impl.m_id;
1891 }
1892 
1893 int
1895  Uint32 fragments)
1896 {
1897  BaseString tmp;
1898  tmp.assfmt("DEFAULT-HASHMAP-%u-%u",
1899  NDB_DEFAULT_HASHMAP_BUCKTETS, fragments);
1900 
1901  return getHashMap(dst, tmp.c_str());
1902 }
1903 
1904 int
1906  const char * name)
1907 {
1908  return m_impl.m_receiver.get_hashmap(NdbHashMapImpl::getImpl(dst), name);
1909 }
1910 
1911 int
1913  const NdbDictionary::Table* tab)
1914 {
1915  if (tab == 0 ||
1916  tab->getFragmentType() != NdbDictionary::Object::HashMapPartition)
1917  {
1918  return -1;
1919  }
1920  return
1921  m_impl.m_receiver.get_hashmap(NdbHashMapImpl::getImpl(dst),
1922  NdbTableImpl::getImpl(*tab).m_hash_map_id);
1923 }
1924 
1925 int
1927  Uint32 fragments)
1928 {
1929  BaseString tmp;
1930  tmp.assfmt("DEFAULT-HASHMAP-%u-%u",
1931  NDB_DEFAULT_HASHMAP_BUCKTETS, fragments);
1932 
1933  dst.setName(tmp.c_str());
1934 
1935  Vector<Uint32> map;
1936  for (Uint32 i = 0; i<NDB_DEFAULT_HASHMAP_BUCKTETS; i++)
1937  {
1938  map.push_back(i % fragments);
1939  }
1940 
1941  dst.setMap(map.getBase(), map.size());
1942  return 0;
1943 }
1944 
1945 int
1947  Table& newTableF)
1948 {
1949  if (!hasSchemaTrans())
1950  {
1951  return -1;
1952  }
1953 
1954  const NdbTableImpl& oldTable = NdbTableImpl::getImpl(oldTableF);
1955  NdbTableImpl& newTable = NdbTableImpl::getImpl(newTableF);
1956 
1957  if (oldTable.getFragmentType() == NdbDictionary::Object::HashMapPartition)
1958  {
1959  HashMap oldmap;
1960  if (getHashMap(oldmap, &oldTable) == -1)
1961  {
1962  return -1;
1963  }
1964 
1965  if (oldmap.getObjectVersion() != (int)oldTable.m_hash_map_version)
1966  {
1967  return -1;
1968  }
1969 
1970  HashMap newmapF;
1971  NdbHashMapImpl& newmap = NdbHashMapImpl::getImpl(newmapF);
1972  newmap.assign(NdbHashMapImpl::getImpl(oldmap));
1973 
1974  Uint32 oldcnt = oldTable.getFragmentCount();
1975  Uint32 newcnt = newTable.getFragmentCount();
1976  if (newcnt == 0)
1977  {
1982  ObjectId tmp;
1983  int ret = m_impl.m_receiver.create_hashmap(NdbHashMapImpl::getImpl(newmapF),
1984  &NdbDictObjectImpl::getImpl(tmp),
1985  CreateHashMapReq::CreateDefault |
1986  CreateHashMapReq::CreateIfNotExists);
1987  if (ret)
1988  {
1989  return ret;
1990  }
1991 
1992  HashMap hm;
1993  ret = m_impl.m_receiver.get_hashmap(NdbHashMapImpl::getImpl(hm), tmp.getObjectId());
1994  if (ret)
1995  {
1996  return ret;
1997  }
1998  Uint32 zero = 0;
1999  Vector<Uint32> values;
2000  values.fill(hm.getMapLen() - 1, zero);
2001  hm.getMapValues(values.getBase(), values.size());
2002  for (Uint32 i = 0; i<hm.getMapLen(); i++)
2003  {
2004  if (values[i] > newcnt)
2005  newcnt = values[i];
2006  }
2007  newcnt++; // Loop will find max val, cnt = max + 1
2008  if (newcnt < oldcnt)
2009  {
2014  newcnt = oldcnt;
2015  }
2016  newTable.setFragmentCount(newcnt);
2017  }
2018 
2019  for (Uint32 i = 0; i<newmap.m_map.size(); i++)
2020  {
2021  Uint32 newval = i % newcnt;
2022  if (newval >= oldcnt)
2023  {
2024  newmap.m_map[i] = newval;
2025  }
2026  }
2027 
2031  HashMap def;
2032  if (getDefaultHashMap(def, newcnt) == 0)
2033  {
2034  if (def.equal(newmapF))
2035  {
2036  newTable.m_hash_map_id = def.getObjectId();
2037  newTable.m_hash_map_version = def.getObjectVersion();
2038  return 0;
2039  }
2040  }
2041 
2042  initDefaultHashMap(def, newcnt);
2043  if (def.equal(newmapF))
2044  {
2045  ObjectId tmp;
2046  if (createHashMap(def, &tmp) == -1)
2047  {
2048  return -1;
2049  }
2050  newTable.m_hash_map_id = tmp.getObjectId();
2051  newTable.m_hash_map_version = tmp.getObjectVersion();
2052  return 0;
2053  }
2054 
2055  int cnt = 0;
2056 retry:
2057  if (cnt == 0)
2058  {
2059  newmap.m_name.assfmt("HASHMAP-%u-%u-%u",
2060  NDB_DEFAULT_HASHMAP_BUCKTETS,
2061  oldcnt,
2062  newcnt);
2063  }
2064  else
2065  {
2066  newmap.m_name.assfmt("HASHMAP-%u-%u-%u-#%u",
2067  NDB_DEFAULT_HASHMAP_BUCKTETS,
2068  oldcnt,
2069  newcnt,
2070  cnt);
2071 
2072  }
2073 
2074  if (getHashMap(def, newmap.getName()) == 0)
2075  {
2076  if (def.equal(newmap))
2077  {
2078  newTable.m_hash_map_id = def.getObjectId();
2079  newTable.m_hash_map_version = def.getObjectVersion();
2080  return 0;
2081  }
2082  cnt++;
2083  goto retry;
2084  }
2085 
2086  ObjectId tmp;
2087  if (createHashMap(newmapF, &tmp) == -1)
2088  {
2089  return -1;
2090  }
2091  newTable.m_hash_map_id = tmp.getObjectId();
2092  newTable.m_hash_map_version = tmp.getObjectVersion();
2093  return 0;
2094  }
2095  assert(false); // NOT SUPPORTED YET
2096  return -1;
2097 }
2098 
2099 /*****************************************************************
2100  * Dictionary facade
2101  */
2102 NdbDictionary::Dictionary::Dictionary(Ndb & ndb)
2103  : m_impl(* new NdbDictionaryImpl(ndb, *this))
2104 {
2105 }
2106 
2107 NdbDictionary::Dictionary::Dictionary(NdbDictionaryImpl & impl)
2108  : m_impl(impl)
2109 {
2110 }
2111 NdbDictionary::Dictionary::~Dictionary(){
2112  NdbDictionaryImpl * tmp = &m_impl;
2113  if(this != tmp){
2114  delete tmp;
2115  }
2116 }
2117 
2118 // do op within trans if no trans exists
2119 #define DO_TRANS(ret, action) \
2120  { \
2121  bool trans = hasSchemaTrans(); \
2122  if ((trans || (ret = beginSchemaTrans()) == 0) && \
2123  (ret = (action)) == 0 && \
2124  (trans || (ret = endSchemaTrans()) == 0)) \
2125  ; \
2126  else if (!trans) { \
2127  NdbError save_error = m_impl.m_error; \
2128  (void)endSchemaTrans(SchemaTransAbort); \
2129  m_impl.m_error = save_error; \
2130  } \
2131  }
2132 
2133 int
2135 {
2136  return createTable(t, 0);
2137 }
2138 
2139 int
2141 {
2142  int ret;
2143  ObjectId tmp;
2144  if (objId == 0)
2145  objId = &tmp;
2146 
2147  if (likely(! is_ndb_blob_table(t.getName())))
2148  {
2149  DO_TRANS(
2150  ret,
2151  m_impl.createTable(NdbTableImpl::getImpl(t),
2152  NdbDictObjectImpl::getImpl( *objId))
2153  );
2154  }
2155  else
2156  {
2157  /* 4307 : Invalid table name */
2158  m_impl.m_error.code = 4307;
2159  ret = -1;
2160  }
2161  return ret;
2162 }
2163 
2164 int
2166  OptimizeTableHandle &h){
2167  DBUG_ENTER("NdbDictionary::Dictionary::optimzeTable");
2168  DBUG_RETURN(m_impl.optimizeTable(NdbTableImpl::getImpl(t),
2169  NdbOptimizeTableHandleImpl::getImpl(h)));
2170 }
2171 
2172 int
2175 {
2176  DBUG_ENTER("NdbDictionary::Dictionary::optimzeIndex");
2177  DBUG_RETURN(m_impl.optimizeIndex(NdbIndexImpl::getImpl(ind),
2178  NdbOptimizeIndexHandleImpl::getImpl(h)));
2179 }
2180 
2181 int
2183 {
2184  int ret;
2185  if (likely(! is_ndb_blob_table(t.getName())))
2186  {
2187  DO_TRANS(
2188  ret,
2189  m_impl.dropTable(NdbTableImpl::getImpl(t))
2190  );
2191  }
2192  else
2193  {
2194  /* 4249 : Invalid table */
2195  m_impl.m_error.code = 4249;
2196  ret = -1;
2197  }
2198  return ret;
2199 }
2200 
2201 int
2202 NdbDictionary::Dictionary::dropTableGlobal(const Table & t)
2203 {
2204  int ret;
2205  if (likely(! is_ndb_blob_table(t.getName())))
2206  {
2207  DO_TRANS(
2208  ret,
2209  m_impl.dropTableGlobal(NdbTableImpl::getImpl(t))
2210  );
2211  }
2212  else
2213  {
2214  /* 4249 : Invalid table */
2215  m_impl.m_error.code = 4249;
2216  ret = -1;
2217  }
2218  return ret;
2219 }
2220 
2221 int
2223 {
2224  int ret;
2225  if (likely(! is_ndb_blob_table(name)))
2226  {
2227  DO_TRANS(
2228  ret,
2229  m_impl.dropTable(name)
2230  );
2231  }
2232  else
2233  {
2234  /* 4307 : Invalid table name */
2235  m_impl.m_error.code = 4307;
2236  ret = -1;
2237  }
2238  return ret;
2239 }
2240 
2241 bool
2243  const Table & t)
2244 {
2245  return m_impl.supportedAlterTable(NdbTableImpl::getImpl(f),
2246  NdbTableImpl::getImpl(t));
2247 }
2248 
2249 int
2251 {
2252  int ret;
2253  DO_TRANS(
2254  ret,
2255  m_impl.alterTable(NdbTableImpl::getImpl(f),
2256  NdbTableImpl::getImpl(t))
2257  );
2258  return ret;
2259 }
2260 
2261 int
2262 NdbDictionary::Dictionary::alterTableGlobal(const Table & f,
2263  const Table & t)
2264 {
2265  int ret;
2266  DO_TRANS(
2267  ret,
2268  m_impl.alterTableGlobal(NdbTableImpl::getImpl(f),
2269  NdbTableImpl::getImpl(t))
2270  );
2271  return ret;
2272 }
2273 
2274 const NdbDictionary::Table *
2275 NdbDictionary::Dictionary::getTable(const char * name, void **data) const
2276 {
2277  NdbTableImpl * t = m_impl.getTable(name, data);
2278  if(t)
2279  return t->m_facade;
2280  return 0;
2281 }
2282 
2283 const NdbDictionary::Index *
2284 NdbDictionary::Dictionary::getIndexGlobal(const char * indexName,
2285  const Table &ndbtab) const
2286 {
2287  NdbIndexImpl * i = m_impl.getIndexGlobal(indexName,
2288  NdbTableImpl::getImpl(ndbtab));
2289  if(i)
2290  return i->m_facade;
2291  return 0;
2292 }
2293 
2294 const NdbDictionary::Index *
2295 NdbDictionary::Dictionary::getIndexGlobal(const char * indexName,
2296  const char * tableName) const
2297 {
2298  NdbIndexImpl * i = m_impl.getIndexGlobal(indexName,
2299  tableName);
2300  if(i)
2301  return i->m_facade;
2302  return 0;
2303 }
2304 
2305 const NdbDictionary::Table *
2306 NdbDictionary::Dictionary::getTableGlobal(const char * name) const
2307 {
2308  NdbTableImpl * t = m_impl.getTableGlobal(name);
2309  if(t)
2310  return t->m_facade;
2311  return 0;
2312 }
2313 
2314 int
2315 NdbDictionary::Dictionary::removeIndexGlobal(const Index &ndbidx,
2316  int invalidate) const
2317 {
2318  return m_impl.releaseIndexGlobal(NdbIndexImpl::getImpl(ndbidx), invalidate);
2319 }
2320 
2321 int
2322 NdbDictionary::Dictionary::removeTableGlobal(const Table &ndbtab,
2323  int invalidate) const
2324 {
2325  return m_impl.releaseTableGlobal(NdbTableImpl::getImpl(ndbtab), invalidate);
2326 }
2327 
2328 NdbRecord *
2329 NdbDictionary::Dictionary::createRecord(const Table *table,
2330  const RecordSpecification *recSpec,
2331  Uint32 length,
2332  Uint32 elemSize,
2333  Uint32 flags)
2334 {
2335  /* We want to obtain a global reference to the Table object */
2336  NdbTableImpl* impl=&NdbTableImpl::getImpl(*table);
2337  Ndb* myNdb= &m_impl.m_ndb;
2338 
2339  /* Temporarily change Ndb object to use table's database
2340  * and schema
2341  */
2342  BaseString currentDb(myNdb->getDatabaseName());
2343  BaseString currentSchema(myNdb->getDatabaseSchemaName());
2344 
2345  myNdb->setDatabaseName
2346  (Ndb::getDatabaseFromInternalName(impl->m_internalName.c_str()).c_str());
2347  myNdb->setDatabaseSchemaName
2348  (Ndb::getSchemaFromInternalName(impl->m_internalName.c_str()).c_str());
2349 
2350  /* Get global ref to table. This is released below, or when the
2351  * NdbRecord is released
2352  */
2353  const Table* globalTab= getTableGlobal(impl->m_externalName.c_str());
2354 
2355  /* Restore Ndb object's DB and Schema */
2356  myNdb->setDatabaseName(currentDb.c_str());
2357  myNdb->setDatabaseSchemaName(currentSchema.c_str());
2358 
2359  if (globalTab == NULL)
2360  /* An error is set on the dictionary */
2361  return NULL;
2362 
2363  NdbTableImpl* globalTabImpl= &NdbTableImpl::getImpl(*globalTab);
2364 
2365  assert(impl->m_id == globalTabImpl->m_id);
2366  if (table_version_major(impl->m_version) !=
2367  table_version_major(globalTabImpl->m_version))
2368  {
2369  removeTableGlobal(*globalTab, false); // Don't invalidate
2370  m_impl.m_error.code= 241; //Invalid schema object version
2371  return NULL;
2372  }
2373 
2374  NdbRecord* result= m_impl.createRecord(globalTabImpl,
2375  recSpec,
2376  length,
2377  elemSize,
2378  flags,
2379  false); // Not default NdbRecord
2380 
2381  if (!result)
2382  {
2383  removeTableGlobal(*globalTab, false); // Don't invalidate
2384  }
2385  return result;
2386 }
2387 
2388 NdbRecord *
2389 NdbDictionary::Dictionary::createRecord(const Index *index,
2390  const Table *table,
2391  const RecordSpecification *recSpec,
2392  Uint32 length,
2393  Uint32 elemSize,
2394  Uint32 flags)
2395 {
2396  /* We want to obtain a global reference to the Index's underlying
2397  * table object
2398  */
2399  NdbTableImpl* tabImpl=&NdbTableImpl::getImpl(*table);
2400  Ndb* myNdb= &m_impl.m_ndb;
2401 
2402  /* Temporarily change Ndb object to use table's database
2403  * and schema. Index's database and schema are not
2404  * useful for finding global table reference
2405  */
2406  BaseString currentDb(myNdb->getDatabaseName());
2407  BaseString currentSchema(myNdb->getDatabaseSchemaName());
2408 
2409  myNdb->setDatabaseName
2410  (Ndb::getDatabaseFromInternalName(tabImpl->m_internalName.c_str()).c_str());
2411  myNdb->setDatabaseSchemaName
2412  (Ndb::getSchemaFromInternalName(tabImpl->m_internalName.c_str()).c_str());
2413 
2414  /* Get global ref to index. This is released below, or when the
2415  * NdbRecord object is released
2416  */
2417  const Index* globalIndex= getIndexGlobal(index->getName(), *table);
2418 
2419  /* Restore Ndb object's DB and Schema */
2420  myNdb->setDatabaseName(currentDb.c_str());
2421  myNdb->setDatabaseSchemaName(currentSchema.c_str());
2422 
2423  if (globalIndex == NULL)
2424  /* An error is set on the dictionary */
2425  return NULL;
2426 
2427  NdbIndexImpl* indexImpl= &NdbIndexImpl::getImpl(*index);
2428  NdbIndexImpl* globalIndexImpl= &NdbIndexImpl::getImpl(*globalIndex);
2429 
2430  assert(indexImpl->m_id == globalIndexImpl->m_id);
2431 
2432  if (table_version_major(indexImpl->m_version) !=
2433  table_version_major(globalIndexImpl->m_version))
2434  {
2435  removeIndexGlobal(*globalIndex, false); // Don't invalidate
2436  m_impl.m_error.code= 241; //Invalid schema object version
2437  return NULL;
2438  }
2439 
2440  NdbRecord* result= m_impl.createRecord(globalIndexImpl->m_table,
2441  recSpec,
2442  length,
2443  elemSize,
2444  flags,
2445  false); // Not default NdbRecord
2446 
2447  if (!result)
2448  {
2449  removeIndexGlobal(*globalIndex, false); // Don't invalidate
2450  }
2451  return result;
2452 }
2453 
2454 NdbRecord *
2455 NdbDictionary::Dictionary::createRecord(const Index *index,
2456  const RecordSpecification *recSpec,
2457  Uint32 length,
2458  Uint32 elemSize,
2459  Uint32 flags)
2460 {
2461  const NdbDictionary::Table *table= getTable(index->getTable());
2462  if (!table)
2463  return NULL;
2464  return createRecord(index,
2465  table,
2466  recSpec,
2467  length,
2468  elemSize,
2469  flags);
2470 }
2471 
2472 void
2473 NdbDictionary::Dictionary::releaseRecord(NdbRecord *rec)
2474 {
2475  m_impl.releaseRecord_impl(rec);
2476 }
2477 
2478 void NdbDictionary::Dictionary::putTable(const NdbDictionary::Table * table)
2479 {
2480  NdbDictionary::Table *copy_table = new NdbDictionary::Table;
2481  *copy_table = *table;
2482  m_impl.putTable(&NdbTableImpl::getImpl(*copy_table));
2483 }
2484 
2485 void NdbDictionary::Dictionary::set_local_table_data_size(unsigned sz)
2486 {
2487  m_impl.m_local_table_data_size= sz;
2488 }
2489 
2490 const NdbDictionary::Table *
2491 NdbDictionary::Dictionary::getTable(const char * name) const
2492 {
2493  return getTable(name, 0);
2494 }
2495 
2496 const NdbDictionary::Table *
2498  const char* col_name)
2499 {
2500  const NdbDictionary::Column* col = table->getColumn(col_name);
2501  if (col == NULL) {
2502  m_impl.m_error.code = 4318;
2503  return NULL;
2504  }
2505  return getBlobTable(table, col->getColumnNo());
2506 }
2507 
2508 const NdbDictionary::Table *
2510  Uint32 col_no)
2511 {
2512  return m_impl.getBlobTable(NdbTableImpl::getImpl(*table), col_no);
2513 }
2514 
2515 void
2517  DBUG_ENTER("NdbDictionaryImpl::invalidateTable");
2518  NdbTableImpl * t = m_impl.getTable(name);
2519  if(t)
2520  m_impl.invalidateObject(* t);
2521  DBUG_VOID_RETURN;
2522 }
2523 
2524 void
2526  NdbTableImpl &t = NdbTableImpl::getImpl(*table);
2527  m_impl.invalidateObject(t);
2528 }
2529 
2530 void
2532  NdbTableImpl * t = m_impl.getTable(name);
2533  if(t)
2534  m_impl.removeCachedObject(* t);
2535 }
2536 
2537 void
2539  NdbTableImpl &t = NdbTableImpl::getImpl(*table);
2540  m_impl.removeCachedObject(t);
2541 }
2542 
2543 int
2545 {
2546  int ret;
2547  DO_TRANS(
2548  ret,
2549  m_impl.createIndex(NdbIndexImpl::getImpl(ind), offline)
2550  );
2551  return ret;
2552 }
2553 
2554 int
2555 NdbDictionary::Dictionary::createIndex(const Index & ind, const Table & tab,
2556  bool offline)
2557 {
2558  int ret;
2559  DO_TRANS(
2560  ret,
2561  m_impl.createIndex(NdbIndexImpl::getImpl(ind),
2562  NdbTableImpl::getImpl(tab),
2563  offline)
2564  );
2565  return ret;
2566 }
2567 
2568 int
2570  const char * tableName)
2571 {
2572  int ret;
2573  DO_TRANS(
2574  ret,
2575  m_impl.dropIndex(indexName, tableName)
2576  );
2577  return ret;
2578 }
2579 
2580 int
2581 NdbDictionary::Dictionary::dropIndexGlobal(const Index &ind)
2582 {
2583  int ret;
2584  DO_TRANS(
2585  ret,
2586  m_impl.dropIndexGlobal(NdbIndexImpl::getImpl(ind))
2587  );
2588  return ret;
2589 }
2590 
2591 int
2592 NdbDictionary::Dictionary::updateIndexStat(const Index& index,
2593  const Table& table)
2594 {
2595  int ret;
2596  DO_TRANS(
2597  ret,
2598  m_impl.updateIndexStat(NdbIndexImpl::getImpl(index),
2599  NdbTableImpl::getImpl(table))
2600  );
2601  return ret;
2602 }
2603 
2604 int
2605 NdbDictionary::Dictionary::updateIndexStat(Uint32 indexId,
2606  Uint32 indexVersion,
2607  Uint32 tableId)
2608 {
2609  int ret;
2610  DO_TRANS(
2611  ret,
2612  m_impl.updateIndexStat(indexId,
2613  indexVersion,
2614  tableId)
2615  );
2616  return ret;
2617 }
2618 
2619 int
2620 NdbDictionary::Dictionary::deleteIndexStat(const Index& index,
2621  const Table& table)
2622 {
2623  int ret;
2624  DO_TRANS(
2625  ret,
2626  m_impl.deleteIndexStat(NdbIndexImpl::getImpl(index),
2627  NdbTableImpl::getImpl(table))
2628  );
2629  return ret;
2630 }
2631 
2632 int
2633 NdbDictionary::Dictionary::deleteIndexStat(Uint32 indexId,
2634  Uint32 indexVersion,
2635  Uint32 tableId)
2636 {
2637  int ret;
2638  DO_TRANS(
2639  ret,
2640  m_impl.deleteIndexStat(indexId,
2641  indexVersion,
2642  tableId)
2643  );
2644  return ret;
2645 }
2646 
2647 const NdbDictionary::Index *
2649  const char * tableName) const
2650 {
2651  NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
2652  if(i)
2653  return i->m_facade;
2654  return 0;
2655 }
2656 
2657 void
2659  DBUG_ENTER("NdbDictionary::Dictionary::invalidateIndex");
2660  NdbIndexImpl &i = NdbIndexImpl::getImpl(*index);
2661  assert(i.m_table != 0);
2662  m_impl.invalidateObject(* i.m_table);
2663  DBUG_VOID_RETURN;
2664 }
2665 
2666 void
2668  const char * tableName){
2669  DBUG_ENTER("NdbDictionaryImpl::invalidateIndex");
2670  NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
2671  if(i) {
2672  assert(i->m_table != 0);
2673  m_impl.invalidateObject(* i->m_table);
2674  }
2675  DBUG_VOID_RETURN;
2676 }
2677 
2678 int
2680 {
2681  return forceGCPWait(0);
2682 }
2683 
2684 int
2686 {
2687  return m_impl.forceGCPWait(type);
2688 }
2689 
2690 int
2692 {
2693  return m_impl.getRestartGCI(gci);
2694 }
2695 
2696 void
2698  DBUG_ENTER("NdbDictionary::Dictionary::removeCachedIndex");
2699  NdbIndexImpl &i = NdbIndexImpl::getImpl(*index);
2700  assert(i.m_table != 0);
2701  m_impl.removeCachedObject(* i.m_table);
2702  DBUG_VOID_RETURN;
2703 }
2704 
2705 void
2707  const char * tableName){
2708  NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
2709  if(i) {
2710  assert(i->m_table != 0);
2711  m_impl.removeCachedObject(* i->m_table);
2712  }
2713 }
2714 
2715 const NdbDictionary::Table *
2716 NdbDictionary::Dictionary::getIndexTable(const char * indexName,
2717  const char * tableName) const
2718 {
2719  NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
2720  NdbTableImpl * t = m_impl.getTable(tableName);
2721  if(i && t) {
2722  NdbTableImpl * it = m_impl.getIndexTable(i, t);
2723  return it->m_facade;
2724  }
2725  return 0;
2726 }
2727 
2728 
2729 int
2731 {
2732  return m_impl.createEvent(NdbEventImpl::getImpl(ev));
2733 }
2734 
2735 int
2736 NdbDictionary::Dictionary::dropEvent(const char * eventName, int force)
2737 {
2738  return m_impl.dropEvent(eventName, force);
2739 }
2740 
2741 const NdbDictionary::Event *
2743 {
2744  NdbEventImpl * t = m_impl.getEvent(eventName);
2745  if(t)
2746  return t->m_facade;
2747  return 0;
2748 }
2749 
2750 int
2752 {
2753  // delegate to overloaded const function for same semantics
2754  const NdbDictionary::Dictionary * const cthis = this;
2755  return cthis->NdbDictionary::Dictionary::listEvents(list);
2756 }
2757 
2758 int
2760 {
2761  return m_impl.listEvents(list);
2762 }
2763 
2764 int
2766 {
2767  // delegate to overloaded const function for same semantics
2768  const NdbDictionary::Dictionary * const cthis = this;
2769  return cthis->NdbDictionary::Dictionary::listObjects(list, type);
2770 }
2771 
2772 int
2774 {
2775  // delegate to variant with FQ names param
2776  return listObjects(list, type,
2777  m_impl.m_ndb.usingFullyQualifiedNames());
2778 }
2779 
2780 int
2782  bool fullyQualified) const
2783 {
2784  return m_impl.listObjects(list, type,
2785  fullyQualified);
2786 }
2787 
2788 int
2789 NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName)
2790 {
2791  // delegate to overloaded const function for same semantics
2792  const NdbDictionary::Dictionary * const cthis = this;
2793  return cthis->NdbDictionary::Dictionary::listIndexes(list, tableName);
2794 }
2795 
2796 int
2798  const char * tableName) const
2799 {
2800  const NdbDictionary::Table* tab= getTable(tableName);
2801  if(tab == 0)
2802  {
2803  return -1;
2804  }
2805  return m_impl.listIndexes(list, tab->getTableId());
2806 }
2807 
2808 int
2810  const NdbDictionary::Table &table) const
2811 {
2812  return m_impl.listIndexes(list, table.getTableId());
2813 }
2814 
2815 const struct NdbError &
2817  return m_impl.getNdbError();
2818 }
2819 
2820 int
2822 {
2823  return m_impl.m_warn;
2824 }
2825 
2826 // printers
2827 
2828 void
2829 pretty_print_string(NdbOut& out,
2831  const char *type, bool is_binary,
2832  const void *aref, unsigned sz)
2833 {
2834  const unsigned char* ref = (const unsigned char*)aref;
2835  int i, len, printable= 1;
2836  // trailing zeroes are not printed
2837  for (i=sz-1; i >= 0; i--)
2838  if (ref[i] == 0) sz--;
2839  else break;
2840  if (!is_binary)
2841  {
2842  // trailing spaces are not printed
2843  for (i=sz-1; i >= 0; i--)
2844  if (ref[i] == 32) sz--;
2845  else break;
2846  }
2847  if (is_binary && f.hex_format)
2848  {
2849  if (sz == 0)
2850  {
2851  out.print("0x0");
2852  return;
2853  }
2854  out.print("0x");
2855  for (len = 0; len < (int)sz; len++)
2856  out.print("%02X", (int)ref[len]);
2857  return;
2858  }
2859  if (sz == 0) return; // empty
2860 
2861  for (len=0; len < (int)sz && ref[i] != 0; len++)
2862  if (printable && !isprint((int)ref[i]))
2863  printable= 0;
2864 
2865  if (printable)
2866  out.print("%.*s", len, ref);
2867  else
2868  {
2869  out.print("0x");
2870  for (i=0; i < len; i++)
2871  out.print("%02X", (int)ref[i]);
2872  }
2873  if (len != (int)sz)
2874  {
2875  out.print("[");
2876  for (i= len+1; ref[i] != 0; i++)
2877  out.print("%u]",len-i);
2878  assert((int)sz > i);
2879  pretty_print_string(out,f,type,is_binary,ref+i,sz-i);
2880  }
2881 }
2882 
2883 /* Three MySQL defs duplicated here : */
2884 static const int MaxMySQLDecimalPrecision= 65;
2885 static const int MaxMySQLDecimalScale= 30;
2886 static const int DigitsPerDigit_t= 9; // (Decimal digits in 2^32)
2887 
2888 /* Implications */
2889 /* Space for -, . and \0 */
2890 static const int MaxDecimalStrLen= MaxMySQLDecimalPrecision + 3;
2891 static const int IntPartDigit_ts=
2892  ((MaxMySQLDecimalPrecision -
2893  MaxMySQLDecimalScale) +
2894  DigitsPerDigit_t -1) / DigitsPerDigit_t;
2895 static const int FracPartDigit_ts=
2896  (MaxMySQLDecimalScale +
2897  DigitsPerDigit_t - 1) / DigitsPerDigit_t;
2898 static const int DigitArraySize= IntPartDigit_ts + FracPartDigit_ts;
2899 
2900 NdbOut&
2901 NdbDictionary::printFormattedValue(NdbOut& out,
2902  const NdbDataPrintFormat& format,
2903  const NdbDictionary::Column* c,
2904  const void* val)
2905 {
2906  if (val == NULL)
2907  {
2908  out << format.null_string;
2909  return out;
2910  }
2911 
2912  const unsigned char* val_p= (const unsigned char*) val;
2913 
2914  uint length = c->getLength();
2915  Uint32 j;
2916  {
2917  const char *fields_optionally_enclosed_by;
2918  if (format.fields_enclosed_by[0] == '\0')
2919  fields_optionally_enclosed_by=
2920  format.fields_optionally_enclosed_by;
2921  else
2922  fields_optionally_enclosed_by= "";
2923  out << format.fields_enclosed_by;
2924 
2925  switch(c->getType()){
2927  {
2928  Uint64 temp;
2929  memcpy(&temp, val, 8);
2930  out << temp;
2931  break;
2932  }
2934  {
2935  out << format.hex_prefix << "0x";
2936  {
2937  const Uint32 *buf = (const Uint32 *)val;
2938  unsigned int k = (length+31)/32;
2939  const unsigned int sigbits= length & 31;
2940  Uint32 wordMask= (1 << sigbits) -1;
2941 
2942  /* Skip leading all-0 words */
2943  while (k > 0)
2944  {
2945  const Uint32 v= buf[--k] & wordMask;
2946  if (v != 0)
2947  break;
2948  /* Following words have all bits significant */
2949  wordMask= ~0;
2950  }
2951 
2952  /* Write first sig word with non-zero bits */
2953  out.print("%X", (buf[k] & wordMask));
2954 
2955  /* Write remaining words (less significant) */
2956  while (k > 0)
2957  out.print("%.8X", buf[--k]);
2958  }
2959  break;
2960  }
2962  {
2963  if (length > 1)
2964  out << format.start_array_enclosure;
2965  out << *(const Uint32*)val;
2966  for (j = 1; j < length; j++)
2967  out << " " << *(((const Uint32*)val) + j);
2968  if (length > 1)
2969  out << format.end_array_enclosure;
2970  break;
2971  }
2973  out << (const Uint32) uint3korr(val_p);
2974  break;
2976  out << *((const Uint16*) val);
2977  break;
2979  out << *((const Uint8*) val);
2980  break;
2982  {
2983  Int64 temp;
2984  memcpy(&temp, val, 8);
2985  out << temp;
2986  break;
2987  }
2989  out << *((Int32*)val);
2990  break;
2992  out << sint3korr(val_p);
2993  break;
2995  out << *((const short*) val);
2996  break;
2998  out << *((Int8*) val);
2999  break;
3001  if (!format.hex_format)
3002  out << fields_optionally_enclosed_by;
3003  j = c->getLength();
3004  pretty_print_string(out,format,"Binary", true, val, j);
3005  if (!format.hex_format)
3006  out << fields_optionally_enclosed_by;
3007  break;
3009  out << fields_optionally_enclosed_by;
3010  j = c->getLength();
3011  pretty_print_string(out,format,"Char", false, val, j);
3012  out << fields_optionally_enclosed_by;
3013  break;
3015  {
3016  out << fields_optionally_enclosed_by;
3017  unsigned len = *val_p;
3018  pretty_print_string(out,format,"Varchar", false, val_p+1,len);
3019  j = length;
3020  out << fields_optionally_enclosed_by;
3021  }
3022  break;
3024  {
3025  if (!format.hex_format)
3026  out << fields_optionally_enclosed_by;
3027  unsigned len = *val_p;
3028  pretty_print_string(out,format,"Varbinary", true, val_p+1,len);
3029  j = length;
3030  if (!format.hex_format)
3031  out << fields_optionally_enclosed_by;
3032  }
3033  break;
3035  {
3036  float temp;
3037  memcpy(&temp, val, sizeof(temp));
3038  out << temp;
3039  break;
3040  }
3042  {
3043  double temp;
3044  memcpy(&temp, val, sizeof(temp));
3045  out << temp;
3046  break;
3047  }
3049  {
3050  short len = 1 + c->getPrecision() + (c->getScale() > 0);
3051  out.print("%.*s", len, val_p);
3052  }
3053  break;
3054  case NdbDictionary::Column::Olddecimalunsigned:
3055  {
3056  short len = 0 + c->getPrecision() + (c->getScale() > 0);
3057  out.print("%.*s", len, val_p);
3058  }
3059  break;
3061  case NdbDictionary::Column::Decimalunsigned:
3062  {
3063  int precision= c->getPrecision();
3064  int scale= c->getScale();
3065 
3066  assert(precision <= MaxMySQLDecimalPrecision);
3067  assert(scale <= MaxMySQLDecimalScale);
3068  assert(decimal_size(precision, scale) <= DigitArraySize );
3069  decimal_digit_t buff[ DigitArraySize ];
3070  decimal_t tmpDec;
3071  tmpDec.buf= buff;
3072  tmpDec.len= DigitArraySize;
3073  decimal_make_zero(&tmpDec);
3074  int rc;
3075 
3076  const uchar* data= (const uchar*) val_p;
3077  if ((rc= bin2decimal(data, &tmpDec, precision, scale)))
3078  {
3079  out.print("***Error : Bad bin2decimal conversion %d ***",
3080  rc);
3081  break;
3082  }
3083 
3084  /* Get null terminated var-length string representation */
3085  char decStr[MaxDecimalStrLen];
3086  assert(decimal_string_size(&tmpDec) <= MaxDecimalStrLen);
3087  int len= MaxDecimalStrLen;
3088  if ((rc= decimal2string(&tmpDec, decStr,
3089  &len,
3090  0, // 0 = Var length output length
3091  0, // 0 = Var length fractional part
3092  0))) // Filler char for fixed length
3093  {
3094  out.print("***Error : bad decimal2string conversion %d ***",
3095  rc);
3096  break;
3097  }
3098 
3099  out.print("%s", decStr);
3100 
3101  break;
3102  }
3103  // for dates cut-and-paste from field.cc
3105  {
3106  ulonglong tmp;
3107  memcpy(&tmp, val, 8);
3108 
3109  long part1,part2,part3;
3110  part1=(long) (tmp/LL(1000000));
3111  part2=(long) (tmp - (ulonglong) part1*LL(1000000));
3112  char buf[40];
3113  char* pos=(char*) buf+19;
3114  *pos--=0;
3115  *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
3116  *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
3117  *pos--= ':';
3118  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
3119  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
3120  *pos--= ':';
3121  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
3122  *pos--= (char) ('0'+(char) part3);
3123  *pos--= '/';
3124  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
3125  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
3126  *pos--= '-';
3127  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
3128  *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
3129  *pos--= '-';
3130  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
3131  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
3132  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
3133  *pos=(char) ('0'+(char) part3);
3134  out << buf;
3135  }
3136  break;
3138  {
3139  uint32 tmp=(uint32) uint3korr(val_p);
3140  int part;
3141  char buf[40];
3142  char *pos=(char*) buf+10;
3143  *pos--=0;
3144  part=(int) (tmp & 31);
3145  *pos--= (char) ('0'+part%10);
3146  *pos--= (char) ('0'+part/10);
3147  *pos--= '-';
3148  part=(int) (tmp >> 5 & 15);
3149  *pos--= (char) ('0'+part%10);
3150  *pos--= (char) ('0'+part/10);
3151  *pos--= '-';
3152  part=(int) (tmp >> 9);
3153  *pos--= (char) ('0'+part%10); part/=10;
3154  *pos--= (char) ('0'+part%10); part/=10;
3155  *pos--= (char) ('0'+part%10); part/=10;
3156  *pos= (char) ('0'+part);
3157  out << buf;
3158  }
3159  break;
3161  {
3162  long tmp=(long) sint3korr(val_p);
3163  int hour=(uint) (tmp/10000);
3164  int minute=(uint) (tmp/100 % 100);
3165  int second=(uint) (tmp % 100);
3166  char buf[40];
3167  sprintf(buf, "%02d:%02d:%02d", hour, minute, second);
3168  out << buf;
3169  }
3170  break;
3172  {
3173  uint year = 1900 + *((const Uint8*) val);
3174  char buf[40];
3175  sprintf(buf, "%04d", year);
3176  out << buf;
3177  }
3178  break;
3180  {
3181  time_t time = *(const Uint32*) val;
3182  out << (uint)time;
3183  }
3184  break;
3187  {
3188  NdbBlob::Head head;
3189  NdbBlob::unpackBlobHead(head, (const char*) val_p, c->getBlobVersion());
3190  out << head.length << ":";
3191  const unsigned char* p = val_p + head.headsize;
3192  if ((unsigned int) c->getLength() < head.headsize)
3193  out << "***error***"; // really cannot happen
3194  else {
3195  unsigned n = c->getLength() - head.headsize;
3196  for (unsigned k = 0; k < n && k < head.length; k++) {
3198  out.print("%02X", (int)p[k]);
3199  else
3200  out.print("%c", (int)p[k]);
3201  }
3202  }
3203  j = length;
3204  }
3205  break;
3207  {
3208  out << fields_optionally_enclosed_by;
3209  unsigned len = uint2korr(val_p);
3210  pretty_print_string(out,format,"Longvarchar", false,
3211  val_p+2,len);
3212  j = length;
3213  out << fields_optionally_enclosed_by;
3214  }
3215  break;
3217  {
3218  if (!format.hex_format)
3219  out << fields_optionally_enclosed_by;
3220  unsigned len = uint2korr(val_p);
3221  pretty_print_string(out,format,"Longvarbinary", true,
3222  val_p+2,len);
3223  j = length;
3224  if (!format.hex_format)
3225  out << fields_optionally_enclosed_by;
3226  }
3227  break;
3228 
3229  default: /* no print functions for the rest, just print type */
3230  out << "Unable to format type ("
3231  << (int) c->getType()
3232  << ")";
3233  if (length > 1)
3234  out << " " << length << " times";
3235  break;
3236  }
3237  out << format.fields_enclosed_by;
3238  }
3239 
3240  return out;
3241 }
3242 
3243 NdbDictionary::NdbDataPrintFormat::NdbDataPrintFormat()
3244 {
3245  fields_terminated_by= ";";
3246  start_array_enclosure= "[";
3247  end_array_enclosure= "]";
3248  fields_enclosed_by= "";
3249  fields_optionally_enclosed_by= "\"";
3250  lines_terminated_by= "\n";
3251  hex_prefix= "H'";
3252  null_string= "[NULL]";
3253  hex_format= 0;
3254 }
3255 NdbDictionary::NdbDataPrintFormat::~NdbDataPrintFormat() {};
3256 
3257 
3258 NdbOut&
3259 operator<<(NdbOut& out, const NdbDictionary::Column& col)
3260 {
3261  const CHARSET_INFO *cs = col.getCharset();
3262  const char *csname = cs ? cs->name : "?";
3263  out << col.getName() << " ";
3264  switch (col.getType()) {
3266  out << "Tinyint";
3267  break;
3269  out << "Tinyunsigned";
3270  break;
3272  out << "Smallint";
3273  break;
3275  out << "Smallunsigned";
3276  break;
3278  out << "Mediumint";
3279  break;
3281  out << "Mediumunsigned";
3282  break;
3284  out << "Int";
3285  break;
3287  out << "Unsigned";
3288  break;
3290  out << "Bigint";
3291  break;
3293  out << "Bigunsigned";
3294  break;
3296  out << "Float";
3297  break;
3299  out << "Double";
3300  break;
3302  out << "Olddecimal(" << col.getPrecision() << "," << col.getScale() << ")";
3303  break;
3304  case NdbDictionary::Column::Olddecimalunsigned:
3305  out << "Olddecimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")";
3306  break;
3308  out << "Decimal(" << col.getPrecision() << "," << col.getScale() << ")";
3309  break;
3310  case NdbDictionary::Column::Decimalunsigned:
3311  out << "Decimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")";
3312  break;
3314  out << "Char(" << col.getLength() << ";" << csname << ")";
3315  break;
3317  out << "Varchar(" << col.getLength() << ";" << csname << ")";
3318  break;
3320  out << "Binary(" << col.getLength() << ")";
3321  break;
3323  out << "Varbinary(" << col.getLength() << ")";
3324  break;
3326  out << "Datetime";
3327  break;
3329  out << "Date";
3330  break;
3332  out << "Blob(" << col.getInlineSize() << "," << col.getPartSize()
3333  << "," << col.getStripeSize() << ")";
3334  break;
3336  out << "Text(" << col.getInlineSize() << "," << col.getPartSize()
3337  << "," << col.getStripeSize() << ";" << csname << ")";
3338  break;
3340  out << "Time";
3341  break;
3343  out << "Year";
3344  break;
3346  out << "Timestamp";
3347  break;
3349  out << "Undefined";
3350  break;
3352  out << "Bit(" << col.getLength() << ")";
3353  break;
3355  out << "Longvarchar(" << col.getLength() << ";" << csname << ")";
3356  break;
3358  out << "Longvarbinary(" << col.getLength() << ")";
3359  break;
3360  default:
3361  out << "Type" << (Uint32)col.getType();
3362  break;
3363  }
3364  // show unusual (non-MySQL) array size
3365  if (col.getLength() != 1) {
3366  switch (col.getType()) {
3376  break;
3377  default:
3378  out << " [" << col.getLength() << "]";
3379  break;
3380  }
3381  }
3382 
3383  if (col.getPrimaryKey())
3384  out << " PRIMARY KEY";
3385  else if (! col.getNullable())
3386  out << " NOT NULL";
3387  else
3388  out << " NULL";
3389 
3390  if(col.getDistributionKey())
3391  out << " DISTRIBUTION KEY";
3392 
3393  switch (col.getArrayType()) {
3394  case NDB_ARRAYTYPE_FIXED:
3395  out << " AT=FIXED";
3396  break;
3397  case NDB_ARRAYTYPE_SHORT_VAR:
3398  out << " AT=SHORT_VAR";
3399  break;
3400  case NDB_ARRAYTYPE_MEDIUM_VAR:
3401  out << " AT=MEDIUM_VAR";
3402  break;
3403  default:
3404  out << " AT=" << (int)col.getArrayType() << "?";
3405  break;
3406  }
3407 
3408  switch (col.getStorageType()) {
3409  case NDB_STORAGETYPE_MEMORY:
3410  out << " ST=MEMORY";
3411  break;
3412  case NDB_STORAGETYPE_DISK:
3413  out << " ST=DISK";
3414  break;
3415  default:
3416  out << " ST=" << (int)col.getStorageType() << "?";
3417  break;
3418  }
3419 
3420  if (col.getAutoIncrement())
3421  out << " AUTO_INCR";
3422 
3423  switch (col.getType()) {
3426  out << " BV=" << col.getBlobVersion();
3427  out << " BT=" << ((col.getBlobTable() != 0) ? col.getBlobTable()->getName() : "<none>");
3428  break;
3429  default:
3430  break;
3431  }
3432 
3433  if(col.getDynamic())
3434  out << " DYNAMIC";
3435 
3436  const void *default_data = col.getDefaultValue();
3437 
3438  if (default_data != NULL)
3439  {
3441 
3442  /* Display binary field defaults as hex */
3443  f.hex_format = 1;
3444 
3445  out << " DEFAULT ";
3446 
3447  NdbDictionary::printFormattedValue(out,
3448  f,
3449  &col,
3450  default_data);
3451  }
3452 
3453  return out;
3454 }
3455 
3456 int
3457 NdbDictionary::Dictionary::createLogfileGroup(const LogfileGroup & lg,
3458  ObjectId * obj)
3459 {
3460  int ret;
3461  DO_TRANS(ret,
3462  m_impl.createLogfileGroup(NdbLogfileGroupImpl::getImpl(lg),
3463  obj ?
3464  & NdbDictObjectImpl::getImpl(* obj) : 0));
3465  return ret;
3466 }
3467 
3468 int
3469 NdbDictionary::Dictionary::dropLogfileGroup(const LogfileGroup & lg)
3470 {
3471  int ret;
3472  DO_TRANS(ret,
3473  m_impl.dropLogfileGroup(NdbLogfileGroupImpl::getImpl(lg)));
3474  return ret;
3475 }
3476 
3478 NdbDictionary::Dictionary::getLogfileGroup(const char * name)
3479 {
3481  m_impl.m_receiver.get_filegroup(NdbLogfileGroupImpl::getImpl(tmp),
3483  return tmp;
3484 }
3485 
3486 int
3487 NdbDictionary::Dictionary::createTablespace(const Tablespace & lg,
3488  ObjectId * obj)
3489 {
3490  int ret;
3491  DO_TRANS(ret,
3492  m_impl.createTablespace(NdbTablespaceImpl::getImpl(lg),
3493  obj ?
3494  & NdbDictObjectImpl::getImpl(* obj) : 0));
3495  return ret;
3496 }
3497 
3498 int
3499 NdbDictionary::Dictionary::dropTablespace(const Tablespace & lg)
3500 {
3501  int ret;
3502  DO_TRANS(ret,
3503  m_impl.dropTablespace(NdbTablespaceImpl::getImpl(lg)));
3504  return ret;
3505 }
3506 
3508 NdbDictionary::Dictionary::getTablespace(const char * name)
3509 {
3511  m_impl.m_receiver.get_filegroup(NdbTablespaceImpl::getImpl(tmp),
3513  return tmp;
3514 }
3515 
3517 NdbDictionary::Dictionary::getTablespace(Uint32 tablespaceId)
3518 {
3520  m_impl.m_receiver.get_filegroup(NdbTablespaceImpl::getImpl(tmp),
3522  tablespaceId);
3523  return tmp;
3524 }
3525 
3526 int
3527 NdbDictionary::Dictionary::createDatafile(const Datafile & df,
3528  bool force,
3529  ObjectId * obj)
3530 {
3531  int ret;
3532  DO_TRANS(ret,
3533  m_impl.createDatafile(NdbDatafileImpl::getImpl(df),
3534  force,
3535  obj ? & NdbDictObjectImpl::getImpl(* obj): 0));
3536  return ret;
3537 }
3538 
3539 int
3540 NdbDictionary::Dictionary::dropDatafile(const Datafile& df)
3541 {
3542  int ret;
3543  DO_TRANS(ret,
3544  m_impl.dropDatafile(NdbDatafileImpl::getImpl(df)));
3545  return ret;
3546 }
3547 
3549 NdbDictionary::Dictionary::getDatafile(Uint32 node, const char * path)
3550 {
3552  m_impl.m_receiver.get_file(NdbDatafileImpl::getImpl(tmp),
3554  node ? (int)node : -1, path);
3555  return tmp;
3556 }
3557 
3558 int
3559 NdbDictionary::Dictionary::createUndofile(const Undofile & df,
3560  bool force,
3561  ObjectId * obj)
3562 {
3563  int ret;
3564  DO_TRANS(ret,
3565  m_impl.createUndofile(NdbUndofileImpl::getImpl(df),
3566  force,
3567  obj ? & NdbDictObjectImpl::getImpl(* obj): 0));
3568  return ret;
3569 }
3570 
3571 int
3572 NdbDictionary::Dictionary::dropUndofile(const Undofile& df)
3573 {
3574  int ret;
3575  DO_TRANS(ret,
3576  m_impl.dropUndofile(NdbUndofileImpl::getImpl(df)));
3577  return ret;
3578 }
3579 
3581 NdbDictionary::Dictionary::getUndofile(Uint32 node, const char * path)
3582 {
3584  m_impl.m_receiver.get_file(NdbUndofileImpl::getImpl(tmp),
3586  node ? (int)node : -1, path);
3587  return tmp;
3588 }
3589 
3590 void
3591 NdbDictionary::Dictionary::invalidateDbGlobal(const char * name)
3592 {
3593  if (m_impl.m_globalHash && name != 0)
3594  {
3595  size_t len = strlen(name);
3596  m_impl.m_globalHash->lock();
3597  m_impl.m_globalHash->invalidateDb(name, len);
3598  m_impl.m_globalHash->unlock();
3599  }
3600 }
3601 
3602 int
3604 {
3605  return m_impl.beginSchemaTrans();
3606 }
3607 
3608 int
3610 {
3611  return m_impl.endSchemaTrans(flags);
3612 }
3613 
3614 bool
3616 {
3617  return m_impl.hasSchemaTrans();
3618 }
3619 
3620 int
3622 {
3623  ObjectId tmp;
3624  if (dst == 0)
3625  dst = &tmp;
3626 
3627  int ret;
3628  DO_TRANS(ret,
3629  m_impl.m_receiver.create_hashmap(NdbHashMapImpl::getImpl(map),
3630  &NdbDictObjectImpl::getImpl(*dst),
3631  0));
3632  return ret;
3633 }