MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbDictionaryImpl.hpp
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 #ifndef NdbDictionaryImpl_H
19 #define NdbDictionaryImpl_H
20 
21 #include <ndb_types.h>
22 #include <kernel_types.h>
23 #include <NdbError.hpp>
24 #include <BaseString.hpp>
25 #include <Vector.hpp>
26 #include <UtilBuffer.hpp>
27 #include <SimpleProperties.hpp>
28 #include <NdbSqlUtil.hpp>
29 #include <NdbDictionary.hpp>
30 #include <Bitmask.hpp>
31 #include <AttributeList.hpp>
32 #include <Ndb.hpp>
33 #include "DictCache.hpp"
34 #include <signaldata/DictSignal.hpp>
35 
36 class ListTablesReq;
37 
38 bool
39 is_ndb_blob_table(const char* name, Uint32* ptab_id = 0, Uint32* pcol_no = 0);
40 bool
41 is_ndb_blob_table(const class NdbTableImpl* t);
42 
43 extern int ndb_dictionary_is_mysqld;
44 #define ASSERT_NOT_MYSQLD assert(ndb_dictionary_is_mysqld == 0)
45 
47 public:
48  int m_id;
49  Uint32 m_version;
52 
53  bool change();
54 
55  static NdbDictObjectImpl & getImpl(NdbDictionary::ObjectId & t) {
56  return t.m_impl;
57  }
58  static const NdbDictObjectImpl & getImpl(const NdbDictionary::ObjectId & t){
59  return t.m_impl;
60  }
61 
62 protected:
63  friend class NdbDictionary::ObjectId;
64 
66  m_type(type),
67  m_status(NdbDictionary::Object::New) {
68  m_id = -1;
69  }
70 };
71 
76 public:
77  NdbColumnImpl();
78  NdbColumnImpl(NdbDictionary::Column &); // This is not a copy constructor
79  ~NdbColumnImpl();
80  NdbColumnImpl& operator=(const NdbColumnImpl&);
81  void init(Type t = Unsigned);
82 
83  int m_attrId;
84  BaseString m_name;
86  int m_precision;
87  int m_scale;
88  int m_length;
89  int m_column_no;
90  CHARSET_INFO * m_cs; // not const in MySQL
91 
92  bool m_pk;
93  bool m_distributionKey;
94  bool m_nullable;
95  bool m_autoIncrement;
96  Uint64 m_autoIncrementInitialValue;
97  UtilBuffer m_defaultValue;
98  /*
99  * Table holding the blob parts.
100  *
101  * Note that if getPartSize() is 0, there is no parts table, so
102  * m_blobTable==NULL.
103  */
104  NdbTableImpl * m_blobTable;
105 
110  Uint32 m_attrSize; // element size (size when arraySize==1)
111  Uint32 m_arraySize; // length or maxlength+1/2 for Var* types
112  Uint32 m_arrayType; // NDB_ARRAYTYPE_FIXED or _VAR
113  Uint32 m_storageType; // NDB_STORAGETYPE_MEMORY or _DISK
114  // for blob, storage type of NDB$DATA
115  bool m_dynamic;
116 
117  bool m_indexSourced; // Computed when column defined, or when
118  // table schema read. Not stored in kernel
119 
120  /*
121  * NdbTableImpl: if m_pk, 0-based index of key in m_attrId order
122  * NdbIndexImpl: m_column_no of primary table column
123  */
124  Uint32 m_keyInfoPos;
125  // TODO: use bits in attr desc 2
126  bool getInterpretableType() const ;
127  bool getCharType() const;
128  bool getStringType() const;
129  bool getBlobType() const;
130 
131  int m_blobVersion; // if blob, NDB_BLOB_V1 or NDB_BLOB_V2
132  int getBlobVersion() const;
133  void setBlobVersion(int blobVersion);
134 
138  bool equal(const NdbColumnImpl&) const;
139 
140  static NdbColumnImpl & getImpl(NdbDictionary::Column & t);
141  static const NdbColumnImpl & getImpl(const NdbDictionary::Column & t);
142  NdbDictionary::Column * m_facade;
143 
144  static void create_pseudo_columns();
145  static void destory_pseudo_columns();
146  static NdbDictionary::Column * create_pseudo(const char *);
147 
148  // Get total length in bytes, used by NdbOperation
149  bool get_var_length(const void* value, Uint32& len) const;
150 };
151 
153 public:
154  NdbTableImpl();
156  ~NdbTableImpl();
157 
158  void init();
159  int setName(const char * name);
160  const char * getName() const;
161  void setFragmentCount(Uint32 count);
162  Uint32 getFragmentCount() const;
163  int setFrm(const void* data, Uint32 len);
164  const void * getFrmData() const;
165  Uint32 getFrmLength() const;
166 
167  int setFragmentData(const Uint32* data, Uint32 cnt);
168  const Uint32 * getFragmentData() const;
169  Uint32 getFragmentDataLen() const;
170 
171  int setRangeListData(const Int32* data, Uint32 cnt);
172  const Int32 * getRangeListData() const;
173  Uint32 getRangeListDataLen() const;
174 
175  Uint32 getFragmentNodes(Uint32 fragmentId,
176  Uint32* nodeIdArrayPtr,
177  Uint32 arraySize) const;
178 
179  const char * getMysqlName() const;
180  int updateMysqlName();
181 
182  bool matchDb(const char * name, size_t len) const;
183 
184  int aggregate(NdbError& error);
185  int validate(NdbError& error);
186 
187  Uint32 m_primaryTableId;
188  BaseString m_internalName; // db/schema/table
189  BaseString m_externalName; // table
190  BaseString m_mysqlName; // db/table
191  UtilBuffer m_frm;
192  Vector<Uint32> m_fd;
193  Vector<Int32> m_range;
195 
196  int getDbName(char * buf, size_t len) const;
197  int getSchemaName(char * buf, size_t len) const;
198  void setDbSchema(const char * db, const char * schema);
199 
203  Uint32 m_columnHashMask;
204  Vector<Uint32> m_columnHash;
205  /*
206  List of all columns in the table.
207  Note that for index table objects, there is one additional column at the
208  end, NDB$TNODE (ordered index) or NDB$PK. This must be taken into account
209  if iterating over columns.
210  */
211  Vector<NdbColumnImpl *> m_columns;
212  Uint32 m_noOfAutoIncColumns;
213  void computeAggregates();
214  int buildColumnHash();
215 
220  Uint32 m_hashpointerValue;
221  Vector<Uint16> m_fragments;
222  Vector<Uint8> m_hash_map;
223 
224  Uint64 m_max_rows;
225  Uint64 m_min_rows;
226  Uint32 m_default_no_part_flag;
227  bool m_linear_flag;
228  bool m_logging;
229  bool m_temporary;
230  bool m_row_gci;
231  bool m_row_checksum;
232  bool m_force_var_part;
233  bool m_has_default_values;
234  int m_kvalue;
235  int m_minLoadFactor;
236  int m_maxLoadFactor;
237  Uint16 m_keyLenInWords;
238  Uint16 m_fragmentCount;
239  Uint8 m_single_user_mode;
240  Uint8 m_storageType; // NDB_STORAGETYPE_MEMORY or _DISK or DEFAULT
241  Uint8 m_extra_row_gci_bits;
242  Uint8 m_extra_row_author_bits;
243 
244  NdbIndexImpl * m_index;
245  NdbColumnImpl * getColumn(unsigned attrId);
246  NdbColumnImpl * getColumn(const char * name);
247  const NdbColumnImpl * getColumn(unsigned attrId) const;
248  const NdbColumnImpl * getColumn(const char * name) const;
249 
253  BaseString m_primaryTable; // Name of table indexed by us
254  NdbDictionary::Object::Type m_indexType;
255 
259  Uint8 m_noOfKeys;
260  // if all pk = dk then this is zero!
261  Uint8 m_noOfDistributionKeys;
262  Uint8 m_noOfBlobs;
263  Uint8 m_noOfDiskColumns;
264  Uint8 m_replicaCount;
265 
271 
276  const unsigned char * m_pkMask;
277 
281  bool equal(const NdbTableImpl&) const;
282  int assign(const NdbTableImpl&);
283 
284  static NdbTableImpl & getImpl(NdbDictionary::Table & t);
285  static NdbTableImpl & getImpl(const NdbDictionary::Table & t);
286  NdbDictionary::Table * m_facade;
287 
291  Uint32 get_nodes(Uint32 partitionId, const Uint16** nodes) const ;
292 
297  Uint32 m_tablespace_id;
298  Uint32 m_tablespace_version;
299 
300  Uint32 m_hash_map_id;
301  Uint32 m_hash_map_version;
302 };
303 
305 public:
306  NdbIndexImpl();
308  ~NdbIndexImpl();
309 
310  void init();
311  int setName(const char * name);
312  const char * getName() const;
313  int setTable(const char * table);
314  const char * getTable() const;
315  const NdbTableImpl * getIndexTable() const;
316 
317  BaseString m_internalName;
318  BaseString m_externalName;
319  BaseString m_tableName;
320  Uint32 m_table_id;
321  Uint32 m_table_version;
322  Vector<NdbColumnImpl *> m_columns;
323  Vector<int> m_key_ids;
324 
325  bool m_logging;
326  bool m_temporary;
327 
328  /*
329  The m_table member refers to the NDB table object that holds the actual
330  index, not the table that is indexed by the index (so it is of index
331  type, not table type).
332  */
333  NdbTableImpl * m_table;
334 
335  static NdbIndexImpl & getImpl(NdbDictionary::Index & t);
336  static NdbIndexImpl & getImpl(const NdbDictionary::Index & t);
337  NdbDictionary::Index * m_facade;
338 };
339 
341 {
342  enum State { CREATED, INITIALIZED, FINISHED, ABORTED, CLOSED };
343 private:
344  int start();
345 
346  State m_state;
347  Ndb *m_ndb;
348  struct fifo_element_st {
349  fifo_element_st(const NdbTableImpl *tab, fifo_element_st *prev)
350  {
351  table = tab;
352  previous = prev;
353  next = NULL;
354  if (prev)
355  prev->next = this;
356  }
357  const NdbTableImpl * table;
358  fifo_element_st * previous;
359  fifo_element_st * next;
360  };
361  const NdbTableImpl * m_table;
362  fifo_element_st * m_table_queue;
363  fifo_element_st * m_table_queue_first;
364  fifo_element_st * m_table_queue_end;
365  NdbTransaction * m_trans;
366  NdbScanOperation * m_scan_op;
367 
369 public:
373  { return h.m_impl; }
374 
375  int init(Ndb *ndb, const NdbTableImpl &table);
376  int next();
377  int close();
378 };
379 
381 {
382  enum State { CREATED, INITIALIZED, FINISHED, ABORTED, CLOSED };
383 private:
384  State m_state;
385  Ndb *m_ndb;
386  const NdbIndexImpl *m_index;
387  class NdbDictionary::OptimizeTableHandle m_optimize_table_handle;
389 public:
393  { return h.m_impl; }
394 
395  int init(Ndb *ndb, const NdbIndexImpl &index);
396  int next();
397  int close();
398 };
399 
401  friend class NdbDictInterface;
402  friend class NdbDictionaryImpl;
403  friend class NdbEventOperation;
404  friend class NdbEventOperationImpl;
405  friend class NdbEventBuffer;
406  friend class EventBufData_hash;
407  friend class NdbBlob;
408 public:
409  NdbEventImpl();
411  ~NdbEventImpl();
412 
413  void init();
414  int setName(const char * name);
415  const char * getName() const;
416  int setTable(const NdbDictionary::Table& table);
417  const NdbDictionary::Table * getTable() const;
418  int setTable(const char * table);
419  const char * getTableName() const;
426  int getNoOfEventColumns() const;
427  const NdbDictionary::Column * getEventColumn(unsigned no) const;
428 
429  void print() {
430  ndbout_c("NdbEventImpl: id=%d, key=%d",
431  m_eventId,
432  m_eventKey);
433  };
434 
435  Uint32 m_eventId;
436  Uint32 m_eventKey;
437  AttributeMask m_attrListBitmask;
438  Uint32 m_table_id;
439  Uint32 m_table_version;
440  BaseString m_name;
441  Uint32 mi_type;
444  bool m_mergeEvents;
445 
446  BaseString m_tableName;
447  Vector<NdbColumnImpl *> m_columns;
448  Vector<unsigned> m_attrIds;
449 
450  static NdbEventImpl & getImpl(NdbDictionary::Event & t);
451  static NdbEventImpl & getImpl(const NdbDictionary::Event & t);
452  NdbDictionary::Event * m_facade;
453 private:
454  NdbTableImpl *m_tableImpl;
455  void setTable(NdbTableImpl *tableImpl);
456 };
457 
460 
461  BaseString m_name;
463 
464  union {
465  Uint32 m_extent_size;
466  Uint32 m_undo_buffer_size;
467  };
468 
469  BaseString m_logfile_group_name;
470  Uint32 m_logfile_group_id;
471  Uint32 m_logfile_group_version;
472  Uint64 m_undo_free_words;
473 };
474 
476  public NdbFilegroupImpl {
477 public:
481 
482  int assign(const NdbTablespaceImpl&);
483 
484  static NdbTablespaceImpl & getImpl(NdbDictionary::Tablespace & t);
485  static const NdbTablespaceImpl & getImpl(const NdbDictionary::Tablespace &);
486  NdbDictionary::Tablespace * m_facade;
487 };
488 
490  public NdbFilegroupImpl {
491 public:
495 
496  int assign(const NdbLogfileGroupImpl&);
497 
498  static NdbLogfileGroupImpl & getImpl(NdbDictionary::LogfileGroup & t);
499  static const NdbLogfileGroupImpl& getImpl(const
501  NdbDictionary::LogfileGroup * m_facade;
502 };
503 
506 
507  Uint64 m_size;
508  Uint64 m_free;
509  BaseString m_path;
510  BaseString m_filegroup_name;
511  Uint32 m_filegroup_id;
512  Uint32 m_filegroup_version;
513 };
514 
516 public:
517  NdbDatafileImpl();
519  ~NdbDatafileImpl();
520 
521  int assign(const NdbDatafileImpl&);
522 
523  static NdbDatafileImpl & getImpl(NdbDictionary::Datafile & t);
524  static const NdbDatafileImpl & getImpl(const NdbDictionary::Datafile & t);
525  NdbDictionary::Datafile * m_facade;
526 };
527 
529 public:
530  NdbUndofileImpl();
532  ~NdbUndofileImpl();
533 
534  int assign(const NdbUndofileImpl&);
535 
536  static NdbUndofileImpl & getImpl(NdbDictionary::Undofile & t);
537  static const NdbUndofileImpl & getImpl(const NdbDictionary::Undofile & t);
538  NdbDictionary::Undofile * m_facade;
539 };
540 
542 {
543 public:
544  NdbHashMapImpl();
546  ~NdbHashMapImpl();
547 
548  int assign(const NdbHashMapImpl& src);
549 
550  BaseString m_name;
551  Vector<Uint32> m_map;
552  NdbDictionary::HashMap * m_facade;
553 
554  static NdbHashMapImpl & getImpl(NdbDictionary::HashMap & t){
555  return t.m_impl;
556  }
557 
558  static const NdbHashMapImpl & getImpl(const NdbDictionary::HashMap & t){
559  return t.m_impl;
560  }
561 
562 
563 };
564 
566 public:
567  // one transaction per Dictionary instance is supported
568  struct Tx {
569  // api-side schema op, currently only for alter table
570  struct Op {
571  Uint32 m_gsn;
572  NdbTableImpl* m_impl;
573  };
574  enum State {
575  NotStarted,
576  Started,
577  Committed,
578  Aborted
579  };
580  State m_state;
581  NdbError m_error;
582  Uint32 m_transId; // API
583  Uint32 m_transKey; // DICT
584  Vector<Op> m_op;
585  Tx() :
586  m_state(NotStarted),
587  m_transId(0),
588  m_transKey(0)
589  {
590  m_error.code = 0;
591  }
592  Uint32 transId() const {
593  return (m_state == Started) ? m_transId : 0;
594  }
595  Uint32 transKey() const {
596  return (m_state == Started) ? m_transKey : 0;
597  }
598  Uint32 requestFlags() const {
599  Uint32 flags = 0;
600  // not yet supported in DICT
601  return flags;
602  }
603  };
604 
605  NdbDictInterface(Tx& tx, NdbError& err, int& warn) :
606  m_tx(tx), m_error(err), m_warn(warn) {
607  m_reference = 0;
608  m_masterNodeId = 0;
609  m_impl = 0;
610  }
611  ~NdbDictInterface();
612 
613  bool setTransporter(class Ndb * ndb);
614  class TransporterFacade *getTransporter() const;
615 
616  // To abstract the stuff thats made in all create/drop/lists below
617  int dictSignal(NdbApiSignal* signal, LinearSectionPtr ptr[3], int secs,
618  int nodeId, // -1 any, 0 = master, >1 = specified
619  Uint32 waitsignaltype,
620  int timeout, Uint32 RETRIES,
621  const int *errcodes = 0, int temporaryMask = 0);
622 
623  int createTable(class Ndb & ndb, NdbTableImpl &);
624  bool supportedAlterTable(const NdbTableImpl &,
625  NdbTableImpl &);
626  int alterTable(class Ndb & ndb, const NdbTableImpl &, NdbTableImpl&, Uint32&);
627  void syncInternalName(Ndb & ndb, NdbTableImpl &impl);
628  int compChangeMask(const NdbTableImpl &old_impl,
629  const NdbTableImpl &impl,
630  Uint32 &change_mask);
631  int serializeTableDesc(Ndb & ndb,
632  NdbTableImpl & impl,
633  UtilBufferWriter & w);
634  int sendAlterTable(const NdbTableImpl &impl,
635  Uint32 change_mask,
636  UtilBufferWriter &w);
637  int sendCreateTable(const NdbTableImpl &impl, UtilBufferWriter &w);
638 
639  int dropTable(const NdbTableImpl &);
640 
641  int createIndex(class Ndb & ndb, const NdbIndexImpl &, const NdbTableImpl &,
642  bool offline);
643  int dropIndex(const NdbIndexImpl &, const NdbTableImpl &);
644  int doIndexStatReq(class Ndb& ndb,
645  const NdbIndexImpl&, const NdbTableImpl&,
646  Uint32 requestType);
647  int doIndexStatReq(class Ndb& ndb,
648  Uint32 indexId, Uint32 indexVersion, Uint32 tableId,
649  Uint32 requestType);
650 
651  int createEvent(class Ndb & ndb, NdbEventImpl &, int getFlag);
652  int dropEvent(const NdbEventImpl &);
653  int dropEvent(NdbApiSignal* signal, LinearSectionPtr ptr[3], int noLSP);
654 
655  int executeSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &, Uint32&);
656  int stopSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &);
657 
658  int listObjects(NdbDictionary::Dictionary::List& list,
659  ListTablesReq& ltreq, bool fullyQualifiedNames);
660  int listObjects(NdbApiSignal* signal, bool& listTablesLongSignal);
661 
662  int unpackListTables(NdbDictionary::Dictionary::List& list,
663  bool fullyQualifiedNames);
664  int unpackOldListTables(NdbDictionary::Dictionary::List& list,
665  bool fullyQualifiedNames);
666 
667  NdbTableImpl * getTable(int tableId, bool fullyQualifiedNames);
668  NdbTableImpl * getTable(const BaseString& name, bool fullyQualifiedNames);
669  NdbTableImpl * getTable(class NdbApiSignal * signal,
670  LinearSectionPtr ptr[3],
671  Uint32 noOfSections, bool fullyQualifiedNames);
672 
673  int forceGCPWait(int type);
674  int getRestartGCI(Uint32 *);
675 
676  static int parseTableInfo(NdbTableImpl ** dst,
677  const Uint32 * data, Uint32 len,
678  bool fullyQualifiedNames,
679  Uint32 version= 0xFFFFFFFF);
680 
681  static int parseFileInfo(NdbFileImpl &dst,
682  const Uint32 * data, Uint32 len);
683 
684  static int parseFilegroupInfo(NdbFilegroupImpl &dst,
685  const Uint32 * data, Uint32 len);
686 
687  static int parseHashMapInfo(NdbHashMapImpl& dst,
688  const Uint32 * data, Uint32 len);
689 
690  int create_file(const NdbFileImpl &, const NdbFilegroupImpl&,
691  bool overwrite, NdbDictObjectImpl*);
692  int drop_file(const NdbFileImpl &);
693  int create_filegroup(const NdbFilegroupImpl &, NdbDictObjectImpl*);
694  int drop_filegroup(const NdbFilegroupImpl &);
695 
696  int get_filegroup(NdbFilegroupImpl&, NdbDictionary::Object::Type, Uint32);
697  int get_filegroup(NdbFilegroupImpl&,NdbDictionary::Object::Type,const char*);
698  int get_file(NdbFileImpl&, NdbDictionary::Object::Type, int, int);
699  int get_file(NdbFileImpl&, NdbDictionary::Object::Type, int, const char *);
700 
701  static int create_index_obj_from_table(NdbIndexImpl ** dst,
702  NdbTableImpl* index_table,
703  const NdbTableImpl* primary_table);
704 
706  int get_hashmap(NdbHashMapImpl&, Uint32 id);
707  int get_hashmap(NdbHashMapImpl&, const char * name);
708 
709  int beginSchemaTrans(bool retry711 = true);
710  int endSchemaTrans(Uint32 flags);
711  Tx & m_tx; // shared with NdbDictionaryImpl
712 
713  bool checkAllNodeVersionsMin(Uint32 minNdbVersion) const;
714 
715  const NdbError &getNdbError() const;
716  NdbError & m_error;
717  int & m_warn;
718 private:
719  Uint32 m_reference;
720  Uint32 m_masterNodeId;
721 
722  class NdbImpl * m_impl;
723 
724  friend class Ndb;
725  friend class NdbImpl;
726  friend class NdbDictionaryImpl;
727  static void execSignal(void* dictImpl,
728  const class NdbApiSignal* signal,
729  const struct LinearSectionPtr ptr[3]);
730 
731  static void execNodeStatus(void* dictImpl, Uint32, Uint32);
732 
733  void execGET_TABINFO_REF(const NdbApiSignal *, const LinearSectionPtr p[3]);
734  void execGET_TABINFO_CONF(const NdbApiSignal *, const LinearSectionPtr p[3]);
735  void execCREATE_TABLE_REF(const NdbApiSignal *, const LinearSectionPtr p[3]);
736  void execCREATE_TABLE_CONF(const NdbApiSignal *, const LinearSectionPtr [3]);
737  void execALTER_TABLE_REF(const NdbApiSignal *, const LinearSectionPtr pr[3]);
738  void execALTER_TABLE_CONF(const NdbApiSignal *, const LinearSectionPtr p[3]);
739 
740  void execCREATE_INDX_REF(const NdbApiSignal *, const LinearSectionPtr pr[3]);
741  void execCREATE_INDX_CONF(const NdbApiSignal *, const LinearSectionPtr p[3]);
742  void execDROP_INDX_REF(const NdbApiSignal *, const LinearSectionPtr ptr[3]);
743  void execDROP_INDX_CONF(const NdbApiSignal *, const LinearSectionPtr ptr[3]);
744 
745  void execINDEX_STAT_CONF(const NdbApiSignal *, const LinearSectionPtr ptr[3]);
746  void execINDEX_STAT_REF(const NdbApiSignal *, const LinearSectionPtr ptr[3]);
747 
748  void execCREATE_EVNT_REF(const NdbApiSignal *, const LinearSectionPtr pr[3]);
749  void execCREATE_EVNT_CONF(const NdbApiSignal *, const LinearSectionPtr p[3]);
750  void execSUB_START_CONF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
751  void execSUB_START_REF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
752  void execSUB_STOP_CONF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
753  void execSUB_STOP_REF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
754  void execDROP_EVNT_REF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
755  void execDROP_EVNT_CONF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
756 
757  void execDROP_TABLE_REF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
758  void execDROP_TABLE_CONF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
759  void execOLD_LIST_TABLES_CONF(const NdbApiSignal*,
760  const LinearSectionPtr ptr[3]);
761  void execLIST_TABLES_CONF(const NdbApiSignal*, const LinearSectionPtr pt[3]);
762 
763  void execCREATE_FILE_REF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
764  void execCREATE_FILE_CONF(const NdbApiSignal*, const LinearSectionPtr pr[3]);
765 
766  void execCREATE_FILEGROUP_REF(const NdbApiSignal*,
767  const LinearSectionPtr ptr[3]);
768  void execCREATE_FILEGROUP_CONF(const NdbApiSignal*,
769  const LinearSectionPtr ptr[3]);
770 
771  void execDROP_FILE_REF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
772  void execDROP_FILE_CONF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
773 
774  void execDROP_FILEGROUP_REF(const NdbApiSignal*, const LinearSectionPtr [3]);
775  void execDROP_FILEGROUP_CONF(const NdbApiSignal*,
776  const LinearSectionPtr ptr[3]);
777 
778  void execSCHEMA_TRANS_BEGIN_CONF(const NdbApiSignal*,
779  const LinearSectionPtr ptr[3]);
780  void execSCHEMA_TRANS_BEGIN_REF(const NdbApiSignal*,
781  const LinearSectionPtr ptr[3]);
782  void execSCHEMA_TRANS_END_CONF(const NdbApiSignal*,
783  const LinearSectionPtr ptr[3]);
784  void execSCHEMA_TRANS_END_REF(const NdbApiSignal*,
785  const LinearSectionPtr ptr[3]);
786  void execSCHEMA_TRANS_END_REP(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
787 
788  void execWAIT_GCP_CONF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
789  void execWAIT_GCP_REF(const NdbApiSignal*, const LinearSectionPtr ptr[3]);
790 
791  void execCREATE_HASH_MAP_REF(const NdbApiSignal*,
792  const LinearSectionPtr ptr[3]);
793  void execCREATE_HASH_MAP_CONF(const NdbApiSignal*,
794  const LinearSectionPtr ptr[3]);
795 
796  Uint32 m_fragmentId;
797  UtilBuffer m_buffer;
798 
799  Uint32 m_noOfTables;
800  UtilBuffer m_tableData;
801  UtilBuffer m_tableNames;
802 
803  union {
804  struct SubStartConfData {
805  Uint32 m_buckets;
806  } m_sub_start_conf;
807  struct WaitGcpData {
808  Uint32 gci_hi;
809  Uint32 gci_lo;
810  } m_wait_gcp_conf;
811  } m_data;
812 };
813 
814 class NdbDictionaryImpl;
816 {
817 public:
818  const BaseString &m_name;
820  m_name(name)
821  {}
822  virtual ~GlobalCacheInitObject() {}
823  virtual int init(NdbDictionaryImpl *dict, NdbTableImpl &tab) const = 0;
824 };
825 
827 public:
828  NdbDictionaryImpl(Ndb &ndb);
831 
832  bool setTransporter(class Ndb * ndb, class TransporterFacade * tf);
833  bool setTransporter(class TransporterFacade * tf);
834 
835  int createTable(NdbTableImpl &t, NdbDictObjectImpl &);
836  int optimizeTable(const NdbTableImpl &t,
838  int optimizeIndex(const NdbIndexImpl &index,
840  int createBlobTables(const NdbTableImpl& t);
841  bool supportedAlterTable(NdbTableImpl &old_impl, NdbTableImpl &impl);
842  int alterTable(NdbTableImpl &old_impl, NdbTableImpl &impl);
843  int dropTable(const char * name);
844  int dropTable(NdbTableImpl &);
845  int dropBlobTables(NdbTableImpl &);
846  int renameBlobTables(const NdbTableImpl &old_impl, const NdbTableImpl &impl);
847  int invalidateObject(NdbTableImpl &);
848  int removeCachedObject(NdbTableImpl &);
849 
850  int createIndex(NdbIndexImpl &ix, bool offline);
851  int createIndex(NdbIndexImpl &ix, NdbTableImpl & tab, bool offline);
852  int dropIndex(const char * indexName,
853  const char * tableName);
854  int dropIndex(NdbIndexImpl &, const char * tableName);
855  NdbTableImpl * getIndexTable(NdbIndexImpl * index,
856  NdbTableImpl * table);
857 
858  int updateIndexStat(const NdbIndexImpl&, const NdbTableImpl&);
859  int updateIndexStat(Uint32 indexId, Uint32 indexVersion, Uint32 tableId);
860  int deleteIndexStat(const NdbIndexImpl&, const NdbTableImpl&);
861  int deleteIndexStat(Uint32 indexId, Uint32 indexVersion, Uint32 tableId);
862 
863  int createEvent(NdbEventImpl &);
864  int createBlobEvents(NdbEventImpl &);
865  int dropEvent(const char * eventName, int force);
866  int dropEvent(const NdbEventImpl &);
867  int dropBlobEvents(const NdbEventImpl &);
868  int listEvents(List& list);
869 
870  int executeSubscribeEvent(NdbEventOperationImpl &, Uint32 & buckets);
871  int stopSubscribeEvent(NdbEventOperationImpl &);
872 
873  int forceGCPWait(int type);
874  int getRestartGCI(Uint32*);
875 
876  int listObjects(List& list, NdbDictionary::Object::Type type,
877  bool fullyQualified);
878  int listIndexes(List& list, Uint32 indexId);
879 
880  NdbTableImpl * getTableGlobal(const char * tableName);
881  NdbIndexImpl * getIndexGlobal(const char * indexName,
882  NdbTableImpl &ndbtab);
883  NdbIndexImpl * getIndexGlobal(const char * indexName,
884  const char * tableName);
885  int alterTableGlobal(NdbTableImpl &orig_impl, NdbTableImpl &impl);
886  int dropTableGlobal(NdbTableImpl &);
887  int dropIndexGlobal(NdbIndexImpl & impl);
888  int releaseTableGlobal(const NdbTableImpl & impl, int invalidate);
889  int releaseIndexGlobal(const NdbIndexImpl & impl, int invalidate);
890 
891  NdbTableImpl * getTable(const char * tableName, void **data= 0);
892  NdbTableImpl * getBlobTable(const NdbTableImpl&, uint col_no);
893  NdbTableImpl * getBlobTable(uint tab_id, uint col_no);
894  void putTable(NdbTableImpl *impl);
895  int getBlobTables(NdbTableImpl &);
897  get_local_table_info(const BaseString& internalTableName);
898  NdbIndexImpl * getIndex(const char * indexName,
899  const char * tableName);
900  NdbIndexImpl * getIndex(const char * indexName, const NdbTableImpl& prim);
901  NdbEventImpl * getEvent(const char * eventName, NdbTableImpl* = NULL);
902  NdbEventImpl * getBlobEvent(const NdbEventImpl& ev, uint col_no);
903  NdbEventImpl * getEventImpl(const char * internalName);
904 
905  int createDatafile(const NdbDatafileImpl &, bool force, NdbDictObjectImpl*);
906  int dropDatafile(const NdbDatafileImpl &);
907  int createUndofile(const NdbUndofileImpl &, bool force, NdbDictObjectImpl*);
908  int dropUndofile(const NdbUndofileImpl &);
909 
910  int createTablespace(const NdbTablespaceImpl &, NdbDictObjectImpl*);
911  int dropTablespace(const NdbTablespaceImpl &);
912 
913  int createLogfileGroup(const NdbLogfileGroupImpl &, NdbDictObjectImpl*);
914  int dropLogfileGroup(const NdbLogfileGroupImpl &);
915 
916  int beginSchemaTrans(bool retry711 = true);
917  int endSchemaTrans(Uint32 flags);
918  bool hasSchemaTrans() const
919  { return (m_tx.m_state == NdbDictInterface::Tx::Started); }
921 
922  const NdbError & getNdbError() const;
923  NdbError m_error;
924  int m_warn;
925  Uint32 m_local_table_data_size;
926 
927  LocalDictCache m_localHash;
928  GlobalDictCache * m_globalHash;
929 
930  static NdbDictionaryImpl & getImpl(NdbDictionary::Dictionary & t);
931  static const NdbDictionaryImpl & getImpl(const NdbDictionary::Dictionary &t);
932  NdbDictionary::Dictionary * m_facade;
933  int initialiseColumnData(bool isIndex,
934  Uint32 flags,
935  const NdbDictionary::RecordSpecification *recSpec,
936  Uint32 colNum,
937  NdbRecord *rec);
938 
939  NdbDictInterface m_receiver;
940  Ndb & m_ndb;
941 
942  NdbIndexImpl* getIndexImpl(const char * externalName,
943  const BaseString& internalName,
944  NdbTableImpl &tab,
945  NdbTableImpl &prim);
946  NdbIndexImpl * getIndexImpl(const char * name,
947  const BaseString& internalName);
948 
949 
950  int createDefaultNdbRecord(NdbTableImpl* tableOrIndex,
951  const NdbTableImpl* baseTableForIndex);
952 
953  bool validateRecordSpec(const NdbDictionary::RecordSpecification *recSpec,
954  Uint32 length,
955  Uint32 flags);
956 
957  NdbRecord *createRecord(const NdbTableImpl *table,
958  const NdbDictionary::RecordSpecification *recSpec,
959  Uint32 length,
960  Uint32 elemSize,
961  Uint32 flags,
962  bool defaultRecord);
963  void releaseRecord_impl(NdbRecord *rec);
964 
965  static NdbDictionary::RecordType
966  getRecordType(const NdbRecord* record);
967  static const char* getRecordTableName(const NdbRecord* record);
968  static const char* getRecordIndexName(const NdbRecord* record);
969  static bool getNextAttrIdFrom(const NdbRecord* record,
970  Uint32 startAttrId,
971  Uint32& nextAttrId);
972  static bool getOffset(const NdbRecord* record,
973  Uint32 attrId,
974  Uint32& offset);
975  static bool getNullBitOffset(const NdbRecord* record,
976  Uint32 attrId,
977  Uint32& nullbit_byte_offset,
978  Uint32& nullbit_bit_in_byte);
979  static const char* getValuePtr(const NdbRecord* record,
980  const char* row,
981  Uint32 attrId);
982  static char* getValuePtr(const NdbRecord* record,
983  char* row,
984  Uint32 attrId);
985  static bool isNull(const NdbRecord* record,
986  const char* row,
987  Uint32 attrId);
988  static int setNull(const NdbRecord* record,
989  char* row,
990  Uint32 attrId,
991  bool value);
992  static Uint32 getRecordRowLength(const NdbRecord* record);
993 
994  /* Empty NdbRecord column mask for user convenience */
995  static const Uint32 m_emptyMask[MAXNROFATTRIBUTESINWORDS];
996 
997 private:
998  NdbTableImpl * fetchGlobalTableImplRef(const GlobalCacheInitObject &obj);
999 };
1000 
1001 inline
1002 NdbEventImpl &
1003 NdbEventImpl::getImpl(const NdbDictionary::Event & t){
1004  return t.m_impl;
1005 }
1006 
1007 inline
1008 NdbEventImpl &
1009 NdbEventImpl::getImpl(NdbDictionary::Event & t){
1010  return t.m_impl;
1011 }
1012 
1013 inline
1014 NdbColumnImpl &
1015 NdbColumnImpl::getImpl(NdbDictionary::Column & t){
1016  return t.m_impl;
1017 }
1018 
1019 inline
1020 const NdbColumnImpl &
1021 NdbColumnImpl::getImpl(const NdbDictionary::Column & t){
1022  return t.m_impl;
1023 }
1024 
1025 inline
1026 bool
1027 NdbColumnImpl::getInterpretableType() const {
1028  return (m_type == NdbDictionary::Column::Unsigned ||
1030 }
1031 
1032 inline
1033 bool
1034 NdbColumnImpl::getCharType() const {
1035  return (m_type == NdbDictionary::Column::Char ||
1036  m_type == NdbDictionary::Column::Varchar ||
1037  m_type == NdbDictionary::Column::Text ||
1039 }
1040 
1041 inline
1042 bool
1043 NdbColumnImpl::getStringType() const {
1044  return (m_type == NdbDictionary::Column::Char ||
1045  m_type == NdbDictionary::Column::Varchar ||
1047  m_type == NdbDictionary::Column::Binary ||
1050 }
1051 
1052 inline
1053 bool
1054 NdbColumnImpl::getBlobType() const {
1055  return (m_type == NdbDictionary::Column::Blob ||
1056  m_type == NdbDictionary::Column::Text);
1057 }
1058 
1059 inline
1060 int
1061 NdbColumnImpl::getBlobVersion() const {
1062  return m_blobVersion;
1063 }
1064 
1065 inline
1066 void
1067 NdbColumnImpl::setBlobVersion(int blobVersion) {
1068  if (blobVersion == NDB_BLOB_V1) {
1069  m_arrayType = NDB_ARRAYTYPE_FIXED;
1070  } else if (blobVersion == NDB_BLOB_V2) {
1071  // always 2 length bytes for head+inline
1072  m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
1073  }
1074  // invalid value should be detected at validate
1075  m_blobVersion = blobVersion;
1076 }
1077 
1078 inline
1079 bool
1080 NdbColumnImpl::get_var_length(const void* value, Uint32& len) const
1081 {
1082  DBUG_ENTER("NdbColumnImpl::get_var_length");
1083  Uint32 max_len = m_attrSize * m_arraySize;
1084  switch (m_arrayType) {
1085  case NDB_ARRAYTYPE_SHORT_VAR:
1086  len = 1 + *((Uint8*)value);
1087  DBUG_PRINT("info", ("SHORT_VAR: len=%u max_len=%u", len, max_len));
1088  break;
1089  case NDB_ARRAYTYPE_MEDIUM_VAR:
1090  len = 2 + uint2korr((char*)value);
1091  DBUG_PRINT("info", ("MEDIUM_VAR: len=%u max_len=%u", len, max_len));
1092  break;
1093  default:
1094  len = max_len;
1095  DBUG_PRINT("info", ("FIXED: len=%u max_len=%u", len, max_len));
1096  DBUG_RETURN(true);
1097  }
1098  DBUG_RETURN(len <= max_len);
1099 }
1100 
1101 inline
1102 NdbTableImpl &
1103 NdbTableImpl::getImpl(NdbDictionary::Table & t){
1104  return t.m_impl;
1105 }
1106 
1107 inline
1108 NdbTableImpl &
1109 NdbTableImpl::getImpl(const NdbDictionary::Table & t){
1110  return t.m_impl;
1111 }
1112 
1113 inline
1114 NdbColumnImpl *
1115 NdbTableImpl::getColumn(unsigned attrId){
1116  if(m_columns.size() > attrId){
1117  return m_columns[attrId];
1118  }
1119  return 0;
1120 }
1121 
1122 inline
1123 const char *
1124 NdbTableImpl::getMysqlName() const
1125 {
1126  return m_mysqlName.c_str();
1127 }
1128 
1129 inline
1130 bool
1131 NdbTableImpl::matchDb(const char * name, size_t len) const
1132 {
1133  return
1134  len < m_internalName.length() &&
1135  memcmp(name, m_internalName.c_str(), len) == 0;
1136 }
1137 
1138 inline
1139 Uint32
1140 Hash( const char* str ){
1141  Uint32 h = 0;
1142  size_t len = strlen(str);
1143  while(len >= 4){
1144  h = (h << 5) + h + str[0];
1145  h = (h << 5) + h + str[1];
1146  h = (h << 5) + h + str[2];
1147  h = (h << 5) + h + str[3];
1148  len -= 4;
1149  str += 4;
1150  }
1151 
1152  switch(len){
1153  case 3:
1154  h = (h << 5) + h + *str++;
1155  case 2:
1156  h = (h << 5) + h + *str++;
1157  case 1:
1158  h = (h << 5) + h + *str++;
1159  }
1160  return h + h;
1161 }
1162 
1163 
1164 inline
1165 NdbColumnImpl *
1166 NdbTableImpl::getColumn(const char * name){
1167 
1168  Uint32 sz = m_columns.size();
1169  NdbColumnImpl** cols = m_columns.getBase();
1170  const Uint32 * hashtable = m_columnHash.getBase();
1171 
1172  if(sz > 5 && false){
1173  Uint32 hashValue = Hash(name) & 0xFFFE;
1174  Uint32 bucket = hashValue & m_columnHashMask;
1175  bucket = (bucket < sz ? bucket : bucket - sz);
1176  hashtable += bucket;
1177  Uint32 tmp = * hashtable;
1178  if((tmp & 1) == 1 ){ // No chaining
1179  sz = 1;
1180  } else {
1181  sz = (tmp >> 16);
1182  hashtable += (tmp & 0xFFFE) >> 1;
1183  tmp = * hashtable;
1184  }
1185  do {
1186  if(hashValue == (tmp & 0xFFFE)){
1187  NdbColumnImpl* col = cols[tmp >> 16];
1188  if(strncmp(name, col->m_name.c_str(), col->m_name.length()) == 0){
1189  return col;
1190  }
1191  }
1192  hashtable++;
1193  tmp = * hashtable;
1194  } while(--sz > 0);
1195 #if 0
1196  Uint32 dir = m_columnHash[bucket];
1197  Uint32 pos = bucket + ((dir & 0xFFFE) >> 1);
1198  Uint32 cnt = dir >> 16;
1199  ndbout_c("col: %s hv: %x bucket: %d dir: %x pos: %d cnt: %d tmp: %d -> 0",
1200  name, hashValue, bucket, dir, pos, cnt, tmp);
1201 #endif
1202  return 0;
1203  } else {
1204  for(Uint32 i = 0; i<sz; i++){
1205  NdbColumnImpl* col = * cols++;
1206  if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
1207  return col;
1208  }
1209  }
1210  return 0;
1211 }
1212 
1213 inline
1214 const NdbColumnImpl *
1215 NdbTableImpl::getColumn(unsigned attrId) const {
1216  if(m_columns.size() > attrId){
1217  return m_columns[attrId];
1218  }
1219  return 0;
1220 }
1221 
1222 inline
1223 const NdbColumnImpl *
1224 NdbTableImpl::getColumn(const char * name) const {
1225  Uint32 sz = m_columns.size();
1226  NdbColumnImpl* const * cols = m_columns.getBase();
1227  for(Uint32 i = 0; i<sz; i++, cols++){
1228  NdbColumnImpl* col = * cols;
1229  if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
1230  return col;
1231  }
1232  return 0;
1233 }
1234 
1235 inline
1236 NdbIndexImpl &
1237 NdbIndexImpl::getImpl(NdbDictionary::Index & t){
1238  return t.m_impl;
1239 }
1240 
1241 inline
1242 NdbIndexImpl &
1243 NdbIndexImpl::getImpl(const NdbDictionary::Index & t){
1244  return t.m_impl;
1245 }
1246 
1247 inline
1249 NdbDictionaryImpl::getImpl(NdbDictionary::Dictionary & t){
1250  return t.m_impl;
1251 }
1252 
1253 inline
1254 const NdbDictionaryImpl &
1255 NdbDictionaryImpl::getImpl(const NdbDictionary::Dictionary & t){
1256  return t.m_impl;
1257 }
1258 
1259 /*****************************************************************
1260  * Inline:d getters
1261  */
1262 
1264 {
1265 public:
1266  InitTable(const BaseString &name) :
1267  GlobalCacheInitObject(name)
1268  {}
1269  int init(NdbDictionaryImpl *dict, NdbTableImpl &tab) const
1270  {
1271  int res= dict->getBlobTables(tab);
1272  if (res == 0)
1273  res= dict->createDefaultNdbRecord(&tab, NULL);
1274 
1275  return res;
1276  }
1277 };
1278 
1279 inline
1280 NdbTableImpl *
1281 NdbDictionaryImpl::getTableGlobal(const char * table_name)
1282 {
1283  if (unlikely(strchr(table_name, '$') != 0)) {
1284  if (is_ndb_blob_table(table_name))
1285  {
1286  /* Could attempt to get the Blob table here, but
1287  * instead we will generate an error.
1288  * The non-global getTable() calls can fetch Blob
1289  * tables correctly if necessary.
1290  *
1291  * 4307 Invalid Table name
1292  */
1293  m_error.code = 4307;
1294  return NULL;
1295  }
1296  }
1297 
1298  const BaseString internal_tabname(m_ndb.internalize_table_name(table_name));
1299  return fetchGlobalTableImplRef(InitTable(internal_tabname));
1300 }
1301 
1302 inline
1303 NdbTableImpl *
1304 NdbDictionaryImpl::getTable(const char * table_name, void **data)
1305 {
1306  DBUG_ENTER("NdbDictionaryImpl::getTable");
1307  DBUG_PRINT("enter", ("table: %s", table_name));
1308 
1309  if (unlikely(strchr(table_name, '$') != 0)) {
1310  Uint32 tab_id, col_no;
1311  if (is_ndb_blob_table(table_name, &tab_id, &col_no)) {
1312  NdbTableImpl* t = getBlobTable(tab_id, col_no);
1313  DBUG_RETURN(t);
1314  }
1315  }
1316 
1317  const BaseString internal_tabname(m_ndb.internalize_table_name(table_name));
1318  Ndb_local_table_info *info=
1319  get_local_table_info(internal_tabname);
1320  if (info == 0)
1321  DBUG_RETURN(0);
1322  if (data)
1323  *data= info->m_local_data;
1324  DBUG_RETURN(info->m_table_impl);
1325 }
1326 
1327 inline
1329 NdbDictionaryImpl::get_local_table_info(const BaseString& internalTableName)
1330 {
1331  DBUG_ENTER("NdbDictionaryImpl::get_local_table_info");
1332  DBUG_PRINT("enter", ("table: %s", internalTableName.c_str()));
1333 
1334  Ndb_local_table_info *info= m_localHash.get(internalTableName.c_str());
1335  if (info == 0)
1336  {
1337  NdbTableImpl *tab=
1338  fetchGlobalTableImplRef(InitTable(internalTableName));
1339  if (tab)
1340  {
1341  info= Ndb_local_table_info::create(tab, m_local_table_data_size);
1342  if (info)
1343  {
1344  m_localHash.put(internalTableName.c_str(), info);
1345  }
1346  }
1347  }
1348  DBUG_RETURN(info); // autoincrement already initialized
1349 }
1350 
1352 {
1353 public:
1354  const char *m_index_name;
1355  const NdbTableImpl &m_prim;
1356 
1357  InitIndex(const BaseString &internal_indexname,
1358  const char *index_name,
1359  const NdbTableImpl &prim) :
1360  GlobalCacheInitObject(internal_indexname),
1361  m_index_name(index_name),
1362  m_prim(prim)
1363  {}
1364 
1365  int init(NdbDictionaryImpl *dict, NdbTableImpl &tab) const {
1366  DBUG_ENTER("InitIndex::init");
1367  DBUG_ASSERT(tab.m_indexType != NdbDictionary::Object::TypeUndefined);
1371  NdbIndexImpl* idx;
1372  if(NdbDictInterface::create_index_obj_from_table(&idx, &tab, &m_prim) == 0)
1373  {
1374  idx->m_table = &tab;
1375  if (!idx->m_externalName.assign(m_index_name) ||
1376  !idx->m_internalName.assign(m_name))
1377  DBUG_RETURN(4000);
1378  tab.m_index = idx;
1379 
1380  /* Finally, create default NdbRecord for this index */
1381  DBUG_RETURN(dict->createDefaultNdbRecord(&tab, &m_prim));
1382  }
1383  DBUG_RETURN(1);
1384  }
1385 };
1386 
1387 inline
1388 NdbIndexImpl *
1389 NdbDictionaryImpl::getIndexGlobal(const char * index_name,
1390  NdbTableImpl &ndbtab)
1391 {
1392  DBUG_ENTER("NdbDictionaryImpl::getIndexGlobal");
1393  const BaseString
1394  internal_indexname(m_ndb.internalize_index_name(&ndbtab, index_name));
1395  int retry= 2;
1396 
1397  while (retry)
1398  {
1399  NdbTableImpl *tab=
1400  fetchGlobalTableImplRef(InitIndex(internal_indexname,
1401  index_name, ndbtab));
1402  if (tab)
1403  {
1404  // tab->m_index sould be set. otherwise tab == 0
1405  NdbIndexImpl *idx= tab->m_index;
1406  if (idx->m_table_id != (unsigned)ndbtab.getObjectId() ||
1407  idx->m_table_version != (unsigned)ndbtab.getObjectVersion())
1408  {
1409  releaseIndexGlobal(*idx, 1);
1410  retry--;
1411  continue;
1412  }
1413  DBUG_RETURN(idx);
1414  }
1415  break;
1416  }
1417  {
1418  // Index not found, try old format
1419  const BaseString
1420  old_internal_indexname(m_ndb.old_internalize_index_name(&ndbtab,
1421  index_name));
1422  retry= 2;
1423  while (retry)
1424  {
1425  NdbTableImpl *tab=
1426  fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
1427  index_name, ndbtab));
1428  if (tab)
1429  {
1430  // tab->m_index sould be set. otherwise tab == 0
1431  NdbIndexImpl *idx= tab->m_index;
1432  if (idx->m_table_id != (unsigned)ndbtab.getObjectId() ||
1433  idx->m_table_version != (unsigned)ndbtab.getObjectVersion())
1434  {
1435  releaseIndexGlobal(*idx, 1);
1436  retry--;
1437  continue;
1438  }
1439  DBUG_RETURN(idx);
1440  }
1441  break;
1442  }
1443  }
1444  m_error.code= 4243;
1445  DBUG_RETURN(0);
1446 }
1447 
1448 inline
1449 NdbIndexImpl *
1450 NdbDictionaryImpl::getIndexGlobal(const char * indexName,
1451  const char * tableName)
1452 {
1453  DBUG_ENTER("NdbDictionaryImpl::getIndexGlobal");
1454  NdbTableImpl * t = getTableGlobal(tableName);
1455  if(t == NULL)
1456  DBUG_RETURN(0);
1457  DBUG_RETURN(getIndexGlobal(indexName, *t));
1458 }
1459 
1460 inline int
1461 NdbDictionaryImpl::releaseTableGlobal(const NdbTableImpl & impl, int invalidate)
1462 {
1463  DBUG_ENTER("NdbDictionaryImpl::releaseTableGlobal");
1464  DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
1465  m_globalHash->lock();
1466  m_globalHash->release(&impl, invalidate);
1467  m_globalHash->unlock();
1468  DBUG_RETURN(0);
1469 }
1470 
1471 inline int
1472 NdbDictionaryImpl::releaseIndexGlobal(const NdbIndexImpl & impl, int invalidate)
1473 {
1474  DBUG_ENTER("NdbDictionaryImpl::releaseIndexGlobal");
1475  DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
1476  m_globalHash->lock();
1477  m_globalHash->release(impl.m_table, invalidate);
1478  m_globalHash->unlock();
1479  DBUG_RETURN(0);
1480 }
1481 
1482 inline
1483 NdbIndexImpl *
1484 NdbDictionaryImpl::getIndex(const char * index_name,
1485  const char * table_name)
1486 {
1487  if (table_name == 0)
1488  {
1489  assert(0);
1490  m_error.code= 4243;
1491  return 0;
1492  }
1493 
1494 
1495  NdbTableImpl* prim = getTable(table_name);
1496  if (prim == 0)
1497  {
1498  m_error.code= 4243;
1499  return 0;
1500  }
1501 
1502  return getIndex(index_name, *prim);
1503 }
1504 
1505 inline
1506 NdbIndexImpl *
1507 NdbDictionaryImpl::getIndex(const char* index_name,
1508  const NdbTableImpl& prim)
1509 {
1510 
1511  const BaseString
1512  internal_indexname(m_ndb.internalize_index_name(&prim, index_name));
1513 
1514  Ndb_local_table_info *info= m_localHash.get(internal_indexname.c_str());
1515  NdbTableImpl *tab;
1516  if (info == 0)
1517  {
1518  tab= fetchGlobalTableImplRef(InitIndex(internal_indexname,
1519  index_name,
1520  prim));
1521  if (!tab)
1522  goto retry;
1523 
1524  info= Ndb_local_table_info::create(tab, 0);
1525  if (!info)
1526  goto retry;
1527  m_localHash.put(internal_indexname.c_str(), info);
1528  }
1529  else
1530  tab= info->m_table_impl;
1531 
1532  return tab->m_index;
1533 
1534 retry:
1535  // Index not found, try fetching it from current database
1536  const BaseString
1537  old_internal_indexname(m_ndb.old_internalize_index_name(&prim, index_name));
1538 
1539  info= m_localHash.get(old_internal_indexname.c_str());
1540  if (info == 0)
1541  {
1542  tab= fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
1543  index_name,
1544  prim));
1545  if (!tab)
1546  goto err;
1547 
1548  info= Ndb_local_table_info::create(tab, 0);
1549  if (!info)
1550  goto err;
1551  m_localHash.put(old_internal_indexname.c_str(), info);
1552  }
1553  else
1554  tab= info->m_table_impl;
1555 
1556  return tab->m_index;
1557 
1558 err:
1559  m_error.code= 4243;
1560  return 0;
1561 }
1562 
1563 inline
1565 NdbTablespaceImpl::getImpl(NdbDictionary::Tablespace & t){
1566  return t.m_impl;
1567 }
1568 
1569 inline
1570 const NdbTablespaceImpl &
1571 NdbTablespaceImpl::getImpl(const NdbDictionary::Tablespace & t){
1572  return t.m_impl;
1573 }
1574 
1575 inline
1577 NdbLogfileGroupImpl::getImpl(NdbDictionary::LogfileGroup & t){
1578  return t.m_impl;
1579 }
1580 
1581 inline
1582 const NdbLogfileGroupImpl &
1583 NdbLogfileGroupImpl::getImpl(const NdbDictionary::LogfileGroup & t){
1584  return t.m_impl;
1585 }
1586 
1587 inline
1589 NdbDatafileImpl::getImpl(NdbDictionary::Datafile & t){
1590  return t.m_impl;
1591 }
1592 
1593 inline
1594 const NdbDatafileImpl &
1595 NdbDatafileImpl::getImpl(const NdbDictionary::Datafile & t){
1596  return t.m_impl;
1597 }
1598 
1599 inline
1601 NdbUndofileImpl::getImpl(NdbDictionary::Undofile & t){
1602  return t.m_impl;
1603 }
1604 
1605 inline
1606 const NdbUndofileImpl &
1607 NdbUndofileImpl::getImpl(const NdbDictionary::Undofile & t){
1608  return t.m_impl;
1609 }
1610 
1611 #endif