1 /* Copyright (c) 2003-2007 MySQL AB
2 Use is subject to license terms
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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17 #ifndef NdbDictionaryImpl_H
18 #define NdbDictionaryImpl_H
19
20 #include <ndb_types.h>
21 #include <kernel_types.h>
22 #include <NdbError.hpp>
23 #include <BaseString.hpp>
24 #include <Vector.hpp>
25 #include <UtilBuffer.hpp>
26 #include <NdbDictionary.hpp>
27 #include <Bitmask.hpp>
28 #include <AttributeList.hpp>
29 #include <Ndb.hpp>
30 #include "NdbWaiter.hpp"
31 #include "DictCache.hpp"
32
33 bool
34 is_ndb_blob_table(const char* name, Uint32* ptab_id = 0, Uint32* pcol_no = 0);
35 bool
36 is_ndb_blob_table(const class NdbTableImpl* t);
37
38 extern int ndb_dictionary_is_mysqld;
39 #define ASSERT_NOT_MYSQLD assert(ndb_dictionary_is_mysqld == 0)
40
41 class NdbDictObjectImpl {
42 public:
43 int m_id;
44 Uint32 m_version;
45 NdbDictionary::Object::Type m_type;
46 NdbDictionary::Object::Status m_status;
47
48 bool change();
49
getImpl(NdbDictionary::ObjectId & t)50 static NdbDictObjectImpl & getImpl(NdbDictionary::ObjectId & t) {
51 return t.m_impl;
52 }
getImpl(const NdbDictionary::ObjectId & t)53 static const NdbDictObjectImpl & getImpl(const NdbDictionary::ObjectId & t){
54 return t.m_impl;
55 }
56
57 protected:
58 friend class NdbDictionary::ObjectId;
59
NdbDictObjectImpl(NdbDictionary::Object::Type type)60 NdbDictObjectImpl(NdbDictionary::Object::Type type) :
61 m_type(type),
62 m_status(NdbDictionary::Object::New) {
63 m_id = -1;
64 }
65 };
66
67 /**
68 * Column
69 */
70 class NdbColumnImpl : public NdbDictionary::Column {
71 public:
72 NdbColumnImpl();
73 NdbColumnImpl(NdbDictionary::Column &); // This is not a copy constructor
74 ~NdbColumnImpl();
75 NdbColumnImpl& operator=(const NdbColumnImpl&);
76 void init(Type t = Unsigned);
77
78 int m_attrId;
79 BaseString m_name;
80 NdbDictionary::Column::Type m_type;
81 int m_precision;
82 int m_scale;
83 int m_length;
84 int m_column_no;
85 CHARSET_INFO * m_cs; // not const in MySQL
86
87 bool m_pk;
88 bool m_distributionKey;
89 bool m_nullable;
90 bool m_autoIncrement;
91 Uint64 m_autoIncrementInitialValue;
92 BaseString m_defaultValue;
93 NdbTableImpl * m_blobTable;
94
95 /**
96 * Internal types and sizes, and aggregates
97 */
98 Uint32 m_attrSize; // element size (size when arraySize==1)
99 Uint32 m_arraySize; // length or maxlength+1/2 for Var* types
100 Uint32 m_arrayType; // NDB_ARRAYTYPE_FIXED or _VAR
101 Uint32 m_storageType; // NDB_STORAGETYPE_MEMORY or _DISK
102 /*
103 * NdbTableImpl: if m_pk, 0-based index of key in m_attrId order
104 * NdbIndexImpl: m_column_no of primary table column
105 */
106 Uint32 m_keyInfoPos;
107 // TODO: use bits in attr desc 2
108 bool getInterpretableType() const ;
109 bool getCharType() const;
110 bool getStringType() const;
111 bool getBlobType() const;
112
113 /**
114 * Equality/assign
115 */
116 bool equal(const NdbColumnImpl&) const;
117
118 static NdbColumnImpl & getImpl(NdbDictionary::Column & t);
119 static const NdbColumnImpl & getImpl(const NdbDictionary::Column & t);
120 NdbDictionary::Column * m_facade;
121
122 static NdbDictionary::Column * create_pseudo(const char *);
123
124 // Get total length in bytes, used by NdbOperation
125 bool get_var_length(const void* value, Uint32& len) const;
126 };
127
128 class NdbTableImpl : public NdbDictionary::Table, public NdbDictObjectImpl {
129 public:
130 NdbTableImpl();
131 NdbTableImpl(NdbDictionary::Table &);
132 ~NdbTableImpl();
133
134 void init();
135 int setName(const char * name);
136 const char * getName() const;
137 void setFragmentCount(Uint32 count);
138 Uint32 getFragmentCount() const;
139 int setFrm(const void* data, Uint32 len);
140 const void * getFrmData() const;
141 Uint32 getFrmLength() const;
142 int setFragmentData(const void* data, Uint32 len);
143 const void * getFragmentData() const;
144 Uint32 getFragmentDataLen() const;
145 int setTablespaceNames(const void* data, Uint32 len);
146 Uint32 getTablespaceNamesLen() const;
147 const void * getTablespaceNames() const;
148 int setTablespaceData(const void* data, Uint32 len);
149 const void * getTablespaceData() const;
150 Uint32 getTablespaceDataLen() const;
151 int setRangeListData(const void* data, Uint32 len);
152 const void * getRangeListData() const;
153 Uint32 getRangeListDataLen() const;
154
155 const char * getMysqlName() const;
156 int updateMysqlName();
157
158 int aggregate(NdbError& error);
159 int validate(NdbError& error);
160
161 Uint32 m_changeMask;
162 Uint32 m_primaryTableId;
163 BaseString m_internalName;
164 BaseString m_externalName;
165 BaseString m_mysqlName;
166 BaseString m_newExternalName; // Used for alter table
167 UtilBuffer m_frm;
168 UtilBuffer m_newFrm; // Used for alter table
169 UtilBuffer m_ts_name; //Tablespace Names
170 UtilBuffer m_new_ts_name; //Tablespace Names
171 UtilBuffer m_ts; //TablespaceData
172 UtilBuffer m_new_ts; //TablespaceData
173 UtilBuffer m_fd; //FragmentData
174 UtilBuffer m_new_fd; //FragmentData
175 UtilBuffer m_range; //Range Or List Array
176 UtilBuffer m_new_range; //Range Or List Array
177 NdbDictionary::Object::FragmentType m_fragmentType;
178
179 /**
180 *
181 */
182 Uint32 m_columnHashMask;
183 Vector<Uint32> m_columnHash;
184 Vector<NdbColumnImpl *> m_columns;
185 void computeAggregates();
186 int buildColumnHash();
187
188 /**
189 * Fragment info
190 */
191 Uint32 m_hashValueMask;
192 Uint32 m_hashpointerValue;
193 Vector<Uint16> m_fragments;
194
195 Uint64 m_max_rows;
196 Uint64 m_min_rows;
197 Uint32 m_default_no_part_flag;
198 bool m_linear_flag;
199 bool m_logging;
200 bool m_temporary;
201 bool m_row_gci;
202 bool m_row_checksum;
203 bool m_force_var_part;
204 int m_kvalue;
205 int m_minLoadFactor;
206 int m_maxLoadFactor;
207 Uint16 m_keyLenInWords;
208 Uint16 m_fragmentCount;
209 Uint8 m_single_user_mode;
210
211 NdbIndexImpl * m_index;
212 NdbColumnImpl * getColumn(unsigned attrId);
213 NdbColumnImpl * getColumn(const char * name);
214 const NdbColumnImpl * getColumn(unsigned attrId) const;
215 const NdbColumnImpl * getColumn(const char * name) const;
216
217 /**
218 * Index only stuff
219 */
220 BaseString m_primaryTable;
221 NdbDictionary::Object::Type m_indexType;
222
223 /**
224 * Aggregates
225 */
226 Uint8 m_noOfKeys;
227 // if all pk = dk then this is zero!
228 Uint8 m_noOfDistributionKeys;
229 Uint8 m_noOfBlobs;
230 Uint8 m_noOfDiskColumns;
231 Uint8 m_replicaCount;
232
233 /**
234 * Equality/assign
235 */
236 bool equal(const NdbTableImpl&) const;
237 int assign(const NdbTableImpl&);
238
239 static NdbTableImpl & getImpl(NdbDictionary::Table & t);
240 static NdbTableImpl & getImpl(const NdbDictionary::Table & t);
241 NdbDictionary::Table * m_facade;
242
243 /**
244 * Return count
245 */
246 Uint32 get_nodes(Uint32 hashValue, const Uint16** nodes) const ;
247
248 /**
249 * Disk stuff
250 */
251 BaseString m_tablespace_name;
252 Uint32 m_tablespace_id;
253 Uint32 m_tablespace_version;
254 };
255
256 class NdbIndexImpl : public NdbDictionary::Index, public NdbDictObjectImpl {
257 public:
258 NdbIndexImpl();
259 NdbIndexImpl(NdbDictionary::Index &);
260 ~NdbIndexImpl();
261
262 void init();
263 int setName(const char * name);
264 const char * getName() const;
265 int setTable(const char * table);
266 const char * getTable() const;
267 const NdbTableImpl * getIndexTable() const;
268
269 BaseString m_internalName;
270 BaseString m_externalName;
271 BaseString m_tableName;
272 Uint32 m_table_id;
273 Uint32 m_table_version;
274 Vector<NdbColumnImpl *> m_columns;
275 Vector<int> m_key_ids;
276
277 bool m_logging;
278 bool m_temporary;
279
280 NdbTableImpl * m_table;
281
282 static NdbIndexImpl & getImpl(NdbDictionary::Index & t);
283 static NdbIndexImpl & getImpl(const NdbDictionary::Index & t);
284 NdbDictionary::Index * m_facade;
285 };
286
287 class NdbEventImpl : public NdbDictionary::Event, public NdbDictObjectImpl {
288 friend class NdbDictInterface;
289 friend class NdbDictionaryImpl;
290 friend class NdbEventOperation;
291 friend class NdbEventOperationImpl;
292 friend class NdbEventBuffer;
293 friend class EventBufData_hash;
294 friend class NdbBlob;
295 public:
296 NdbEventImpl();
297 NdbEventImpl(NdbDictionary::Event &);
298 ~NdbEventImpl();
299
300 void init();
301 int setName(const char * name);
302 const char * getName() const;
303 int setTable(const NdbDictionary::Table& table);
304 const NdbDictionary::Table * getTable() const;
305 int setTable(const char * table);
306 const char * getTableName() const;
307 void addTableEvent(const NdbDictionary::Event::TableEvent t);
308 bool getTableEvent(const NdbDictionary::Event::TableEvent t) const;
309 void setDurability(NdbDictionary::Event::EventDurability d);
310 NdbDictionary::Event::EventDurability getDurability() const;
311 void setReport(NdbDictionary::Event::EventReport r);
312 NdbDictionary::Event::EventReport getReport() const;
313 int getNoOfEventColumns() const;
314 const NdbDictionary::Column * getEventColumn(unsigned no) const;
315
print()316 void print() {
317 ndbout_c("NdbEventImpl: id=%d, key=%d",
318 m_eventId,
319 m_eventKey);
320 };
321
322 Uint32 m_eventId;
323 Uint32 m_eventKey;
324 AttributeMask m_attrListBitmask;
325 Uint32 m_table_id;
326 Uint32 m_table_version;
327 BaseString m_name;
328 Uint32 mi_type;
329 NdbDictionary::Event::EventDurability m_dur;
330 NdbDictionary::Event::EventReport m_rep;
331 bool m_mergeEvents;
332
333 BaseString m_tableName;
334 Vector<NdbColumnImpl *> m_columns;
335 Vector<unsigned> m_attrIds;
336
337 static NdbEventImpl & getImpl(NdbDictionary::Event & t);
338 static NdbEventImpl & getImpl(const NdbDictionary::Event & t);
339 NdbDictionary::Event * m_facade;
340 private:
341 NdbTableImpl *m_tableImpl;
342 void setTable(NdbTableImpl *tableImpl);
343 };
344
345 struct NdbFilegroupImpl : public NdbDictObjectImpl {
346 NdbFilegroupImpl(NdbDictionary::Object::Type t);
347
348 BaseString m_name;
349 NdbDictionary::AutoGrowSpecification m_grow_spec;
350
351 union {
352 Uint32 m_extent_size;
353 Uint32 m_undo_buffer_size;
354 };
355
356 BaseString m_logfile_group_name;
357 Uint32 m_logfile_group_id;
358 Uint32 m_logfile_group_version;
359 Uint64 m_undo_free_words;
360 };
361
362 class NdbTablespaceImpl : public NdbDictionary::Tablespace,
363 public NdbFilegroupImpl {
364 public:
365 NdbTablespaceImpl();
366 NdbTablespaceImpl(NdbDictionary::Tablespace &);
367 ~NdbTablespaceImpl();
368
369 int assign(const NdbTablespaceImpl&);
370
371 static NdbTablespaceImpl & getImpl(NdbDictionary::Tablespace & t);
372 static const NdbTablespaceImpl & getImpl(const NdbDictionary::Tablespace &);
373 NdbDictionary::Tablespace * m_facade;
374 };
375
376 class NdbLogfileGroupImpl : public NdbDictionary::LogfileGroup,
377 public NdbFilegroupImpl {
378 public:
379 NdbLogfileGroupImpl();
380 NdbLogfileGroupImpl(NdbDictionary::LogfileGroup &);
381 ~NdbLogfileGroupImpl();
382
383 int assign(const NdbLogfileGroupImpl&);
384
385 static NdbLogfileGroupImpl & getImpl(NdbDictionary::LogfileGroup & t);
386 static const NdbLogfileGroupImpl& getImpl(const
387 NdbDictionary::LogfileGroup&);
388 NdbDictionary::LogfileGroup * m_facade;
389 };
390
391 struct NdbFileImpl : public NdbDictObjectImpl {
392 NdbFileImpl(NdbDictionary::Object::Type t);
393
394 Uint64 m_size;
395 Uint64 m_free;
396 BaseString m_path;
397 BaseString m_filegroup_name;
398 Uint32 m_filegroup_id;
399 Uint32 m_filegroup_version;
400 };
401
402 class NdbDatafileImpl : public NdbDictionary::Datafile, public NdbFileImpl {
403 public:
404 NdbDatafileImpl();
405 NdbDatafileImpl(NdbDictionary::Datafile &);
406 ~NdbDatafileImpl();
407
408 int assign(const NdbDatafileImpl&);
409
410 static NdbDatafileImpl & getImpl(NdbDictionary::Datafile & t);
411 static const NdbDatafileImpl & getImpl(const NdbDictionary::Datafile & t);
412 NdbDictionary::Datafile * m_facade;
413 };
414
415 class NdbUndofileImpl : public NdbDictionary::Undofile, public NdbFileImpl {
416 public:
417 NdbUndofileImpl();
418 NdbUndofileImpl(NdbDictionary::Undofile &);
419 ~NdbUndofileImpl();
420
421 int assign(const NdbUndofileImpl&);
422
423 static NdbUndofileImpl & getImpl(NdbDictionary::Undofile & t);
424 static const NdbUndofileImpl & getImpl(const NdbDictionary::Undofile & t);
425 NdbDictionary::Undofile * m_facade;
426 };
427
428 class NdbDictInterface {
429 public:
NdbDictInterface(NdbError & err)430 NdbDictInterface(NdbError& err) : m_error(err) {
431 m_reference = 0;
432 m_masterNodeId = 0;
433 m_transporter= NULL;
434 }
435 ~NdbDictInterface();
436
437 bool setTransporter(class Ndb * ndb, class TransporterFacade * tf);
438 bool setTransporter(class TransporterFacade * tf);
439
440 // To abstract the stuff thats made in all create/drop/lists below
441 int dictSignal(NdbApiSignal* signal, LinearSectionPtr ptr[3], int secs,
442 int nodeId, // -1 any, 0 = master, >1 = specified
443 WaitSignalType wst,
444 int timeout, Uint32 RETRIES,
445 const int *errcodes = 0, int temporaryMask = 0);
446
447 int createOrAlterTable(class Ndb & ndb, NdbTableImpl &, bool alter);
448
449 int createTable(class Ndb & ndb, NdbTableImpl &);
450 int alterTable(class Ndb & ndb, NdbTableImpl &);
451 int dropTable(const NdbTableImpl &);
452
453 int createIndex(class Ndb & ndb, const NdbIndexImpl &, const NdbTableImpl &);
454 int dropIndex(const NdbIndexImpl &, const NdbTableImpl &);
455
456 int createEvent(class Ndb & ndb, NdbEventImpl &, int getFlag);
457 int dropEvent(const NdbEventImpl &);
458 int dropEvent(NdbApiSignal* signal, LinearSectionPtr ptr[3], int noLSP);
459
460 int executeSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &);
461 int stopSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &);
462
463 int listObjects(NdbDictionary::Dictionary::List& list, Uint32 requestData, bool fullyQualifiedNames);
464 int listObjects(NdbApiSignal* signal);
465
466 NdbTableImpl * getTable(int tableId, bool fullyQualifiedNames);
467 NdbTableImpl * getTable(const BaseString& name, bool fullyQualifiedNames);
468 NdbTableImpl * getTable(class NdbApiSignal * signal,
469 LinearSectionPtr ptr[3],
470 Uint32 noOfSections, bool fullyQualifiedNames);
471
472 int forceGCPWait();
473
474 static int parseTableInfo(NdbTableImpl ** dst,
475 const Uint32 * data, Uint32 len,
476 bool fullyQualifiedNames,
477 Uint32 version= 0xFFFFFFFF);
478
479 static int parseFileInfo(NdbFileImpl &dst,
480 const Uint32 * data, Uint32 len);
481
482 static int parseFilegroupInfo(NdbFilegroupImpl &dst,
483 const Uint32 * data, Uint32 len);
484
485 int create_file(const NdbFileImpl &, const NdbFilegroupImpl&,
486 bool overwrite, NdbDictObjectImpl*);
487 int drop_file(const NdbFileImpl &);
488 int create_filegroup(const NdbFilegroupImpl &, NdbDictObjectImpl*);
489 int drop_filegroup(const NdbFilegroupImpl &);
490
491 int get_filegroup(NdbFilegroupImpl&, NdbDictionary::Object::Type, Uint32);
492 int get_filegroup(NdbFilegroupImpl&,NdbDictionary::Object::Type,const char*);
493 int get_file(NdbFileImpl&, NdbDictionary::Object::Type, int, int);
494 int get_file(NdbFileImpl&, NdbDictionary::Object::Type, int, const char *);
495
496 static int create_index_obj_from_table(NdbIndexImpl ** dst,
497 NdbTableImpl* index_table,
498 const NdbTableImpl* primary_table);
499
500 const NdbError &getNdbError() const;
501 NdbError & m_error;
502 private:
503 Uint32 m_reference;
504 Uint32 m_masterNodeId;
505
506 NdbWaiter m_waiter;
507 class TransporterFacade * m_transporter;
508
509 friend class Ndb;
510 friend class NdbDictionaryImpl;
511 static void execSignal(void* dictImpl,
512 class NdbApiSignal* signal,
513 struct LinearSectionPtr ptr[3]);
514
515 static void execNodeStatus(void* dictImpl, Uint32,
516 bool alive, bool nfCompleted);
517
518 void execGET_TABINFO_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
519 void execGET_TABINFO_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
520 void execCREATE_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
521 void execCREATE_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
522 void execALTER_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
523 void execALTER_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
524
525 void execCREATE_INDX_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
526 void execCREATE_INDX_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
527 void execDROP_INDX_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
528 void execDROP_INDX_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
529
530 void execCREATE_EVNT_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
531 void execCREATE_EVNT_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
532 void execSUB_START_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
533 void execSUB_START_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
534 void execSUB_STOP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
535 void execSUB_STOP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
536 void execDROP_EVNT_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
537 void execDROP_EVNT_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
538
539 void execDROP_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
540 void execDROP_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
541 void execLIST_TABLES_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
542
543 void execCREATE_FILE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
544 void execCREATE_FILE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
545
546 void execCREATE_FILEGROUP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
547 void execCREATE_FILEGROUP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
548
549 void execDROP_FILE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
550 void execDROP_FILE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
551
552 void execDROP_FILEGROUP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
553 void execDROP_FILEGROUP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
554
555 void execWAIT_GCP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
556 void execWAIT_GCP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
557
558 Uint32 m_fragmentId;
559 UtilBuffer m_buffer;
560 };
561
562 class NdbDictionaryImpl;
563 class GlobalCacheInitObject
564 {
565 public:
566 NdbDictionaryImpl *m_dict;
567 const BaseString &m_name;
GlobalCacheInitObject(NdbDictionaryImpl * dict,const BaseString & name)568 GlobalCacheInitObject(NdbDictionaryImpl *dict,
569 const BaseString &name) :
570 m_dict(dict),
571 m_name(name)
572 {}
~GlobalCacheInitObject()573 virtual ~GlobalCacheInitObject() {}
574 virtual int init(NdbTableImpl &tab) const = 0;
575 };
576
577 class NdbDictionaryImpl : public NdbDictionary::Dictionary {
578 public:
579 NdbDictionaryImpl(Ndb &ndb);
580 NdbDictionaryImpl(Ndb &ndb, NdbDictionary::Dictionary & f);
581 ~NdbDictionaryImpl();
582
583 bool setTransporter(class Ndb * ndb, class TransporterFacade * tf);
584 bool setTransporter(class TransporterFacade * tf);
585
586 int createTable(NdbTableImpl &t);
587 int createBlobTables(NdbTableImpl& org, NdbTableImpl& created);
588 int alterTable(NdbTableImpl &t);
589 int dropTable(const char * name);
590 int dropTable(NdbTableImpl &);
591 int dropBlobTables(NdbTableImpl &);
592 int invalidateObject(NdbTableImpl &);
593 int removeCachedObject(NdbTableImpl &);
594
595 int createIndex(NdbIndexImpl &ix);
596 int createIndex(NdbIndexImpl &ix, NdbTableImpl & tab);
597 int dropIndex(const char * indexName,
598 const char * tableName);
599 int dropIndex(NdbIndexImpl &, const char * tableName);
600 NdbTableImpl * getIndexTable(NdbIndexImpl * index,
601 NdbTableImpl * table);
602
603 int createEvent(NdbEventImpl &);
604 int createBlobEvents(NdbEventImpl &);
605 int dropEvent(const char * eventName);
606 int dropEvent(const NdbEventImpl &);
607 int dropBlobEvents(const NdbEventImpl &);
608
609 int executeSubscribeEvent(NdbEventOperationImpl &);
610 int stopSubscribeEvent(NdbEventOperationImpl &);
611
612 int forceGCPWait();
613
614 int listObjects(List& list, NdbDictionary::Object::Type type);
615 int listIndexes(List& list, Uint32 indexId);
616
617 NdbTableImpl * getTableGlobal(const char * tableName);
618 NdbIndexImpl * getIndexGlobal(const char * indexName,
619 NdbTableImpl &ndbtab);
620 int alterTableGlobal(NdbTableImpl &orig_impl, NdbTableImpl &impl);
621 int dropTableGlobal(NdbTableImpl &);
622 int dropIndexGlobal(NdbIndexImpl & impl);
623 int releaseTableGlobal(NdbTableImpl & impl, int invalidate);
624 int releaseIndexGlobal(NdbIndexImpl & impl, int invalidate);
625
626 NdbTableImpl * getTable(const char * tableName, void **data= 0);
627 NdbTableImpl * getBlobTable(const NdbTableImpl&, uint col_no);
628 NdbTableImpl * getBlobTable(uint tab_id, uint col_no);
629 void putTable(NdbTableImpl *impl);
630 int getBlobTables(NdbTableImpl &);
631 Ndb_local_table_info*
632 get_local_table_info(const BaseString& internalTableName);
633 NdbIndexImpl * getIndex(const char * indexName,
634 const char * tableName);
635 NdbIndexImpl * getIndex(const char * indexName, const NdbTableImpl& prim);
636 NdbEventImpl * getEvent(const char * eventName, NdbTableImpl* = NULL);
637 NdbEventImpl * getBlobEvent(const NdbEventImpl& ev, uint col_no);
638 NdbEventImpl * getEventImpl(const char * internalName);
639
640 int createDatafile(const NdbDatafileImpl &, bool force, NdbDictObjectImpl*);
641 int dropDatafile(const NdbDatafileImpl &);
642 int createUndofile(const NdbUndofileImpl &, bool force, NdbDictObjectImpl*);
643 int dropUndofile(const NdbUndofileImpl &);
644
645 int createTablespace(const NdbTablespaceImpl &, NdbDictObjectImpl*);
646 int dropTablespace(const NdbTablespaceImpl &);
647
648 int createLogfileGroup(const NdbLogfileGroupImpl &, NdbDictObjectImpl*);
649 int dropLogfileGroup(const NdbLogfileGroupImpl &);
650
651 const NdbError & getNdbError() const;
652 NdbError m_error;
653 Uint32 m_local_table_data_size;
654
655 LocalDictCache m_localHash;
656 GlobalDictCache * m_globalHash;
657
658 static NdbDictionaryImpl & getImpl(NdbDictionary::Dictionary & t);
659 static const NdbDictionaryImpl & getImpl(const NdbDictionary::Dictionary &t);
660 NdbDictionary::Dictionary * m_facade;
661
662 NdbDictInterface m_receiver;
663 Ndb & m_ndb;
664
665 NdbIndexImpl* getIndexImpl(const char * externalName,
666 const BaseString& internalName,
667 NdbTableImpl &tab,
668 NdbTableImpl &prim);
669 NdbIndexImpl * getIndexImpl(const char * name,
670 const BaseString& internalName);
671 private:
672 NdbTableImpl * fetchGlobalTableImplRef(const GlobalCacheInitObject &obj);
673 };
674
675 inline
676 NdbEventImpl &
getImpl(const NdbDictionary::Event & t)677 NdbEventImpl::getImpl(const NdbDictionary::Event & t){
678 return t.m_impl;
679 }
680
681 inline
682 NdbEventImpl &
getImpl(NdbDictionary::Event & t)683 NdbEventImpl::getImpl(NdbDictionary::Event & t){
684 return t.m_impl;
685 }
686
687 inline
688 NdbColumnImpl &
getImpl(NdbDictionary::Column & t)689 NdbColumnImpl::getImpl(NdbDictionary::Column & t){
690 return t.m_impl;
691 }
692
693 inline
694 const NdbColumnImpl &
getImpl(const NdbDictionary::Column & t)695 NdbColumnImpl::getImpl(const NdbDictionary::Column & t){
696 return t.m_impl;
697 }
698
699 inline
700 bool
getInterpretableType() const701 NdbColumnImpl::getInterpretableType() const {
702 return (m_type == NdbDictionary::Column::Unsigned ||
703 m_type == NdbDictionary::Column::Bigunsigned);
704 }
705
706 inline
707 bool
getCharType() const708 NdbColumnImpl::getCharType() const {
709 return (m_type == NdbDictionary::Column::Char ||
710 m_type == NdbDictionary::Column::Varchar ||
711 m_type == NdbDictionary::Column::Text ||
712 m_type == NdbDictionary::Column::Longvarchar);
713 }
714
715 inline
716 bool
getStringType() const717 NdbColumnImpl::getStringType() const {
718 return (m_type == NdbDictionary::Column::Char ||
719 m_type == NdbDictionary::Column::Varchar ||
720 m_type == NdbDictionary::Column::Longvarchar ||
721 m_type == NdbDictionary::Column::Binary ||
722 m_type == NdbDictionary::Column::Varbinary ||
723 m_type == NdbDictionary::Column::Longvarbinary);
724 }
725
726 inline
727 bool
getBlobType() const728 NdbColumnImpl::getBlobType() const {
729 return (m_type == NdbDictionary::Column::Blob ||
730 m_type == NdbDictionary::Column::Text);
731 }
732
733 inline
734 bool
get_var_length(const void * value,Uint32 & len) const735 NdbColumnImpl::get_var_length(const void* value, Uint32& len) const
736 {
737 Uint32 max_len = m_attrSize * m_arraySize;
738 switch (m_arrayType) {
739 case NDB_ARRAYTYPE_SHORT_VAR:
740 len = 1 + *((Uint8*)value);
741 break;
742 case NDB_ARRAYTYPE_MEDIUM_VAR:
743 len = 2 + uint2korr((char*)value);
744 break;
745 default:
746 len = max_len;
747 return true;
748 }
749 return (len <= max_len);
750 }
751
752 inline
753 NdbTableImpl &
getImpl(NdbDictionary::Table & t)754 NdbTableImpl::getImpl(NdbDictionary::Table & t){
755 return t.m_impl;
756 }
757
758 inline
759 NdbTableImpl &
getImpl(const NdbDictionary::Table & t)760 NdbTableImpl::getImpl(const NdbDictionary::Table & t){
761 return t.m_impl;
762 }
763
764 inline
765 NdbColumnImpl *
getColumn(unsigned attrId)766 NdbTableImpl::getColumn(unsigned attrId){
767 if(m_columns.size() > attrId){
768 return m_columns[attrId];
769 }
770 return 0;
771 }
772
773 inline
774 const char *
getMysqlName() const775 NdbTableImpl::getMysqlName() const
776 {
777 return m_mysqlName.c_str();
778 }
779
780 inline
781 Uint32
Hash(const char * str)782 Hash( const char* str ){
783 Uint32 h = 0;
784 Uint32 len = strlen(str);
785 while(len >= 4){
786 h = (h << 5) + h + str[0];
787 h = (h << 5) + h + str[1];
788 h = (h << 5) + h + str[2];
789 h = (h << 5) + h + str[3];
790 len -= 4;
791 str += 4;
792 }
793
794 switch(len){
795 case 3:
796 h = (h << 5) + h + *str++;
797 case 2:
798 h = (h << 5) + h + *str++;
799 case 1:
800 h = (h << 5) + h + *str++;
801 }
802 return h + h;
803 }
804
805
806 inline
807 NdbColumnImpl *
getColumn(const char * name)808 NdbTableImpl::getColumn(const char * name){
809
810 Uint32 sz = m_columns.size();
811 NdbColumnImpl** cols = m_columns.getBase();
812 const Uint32 * hashtable = m_columnHash.getBase();
813
814 if(sz > 5 && false){
815 Uint32 hashValue = Hash(name) & 0xFFFE;
816 Uint32 bucket = hashValue & m_columnHashMask;
817 bucket = (bucket < sz ? bucket : bucket - sz);
818 hashtable += bucket;
819 Uint32 tmp = * hashtable;
820 if((tmp & 1) == 1 ){ // No chaining
821 sz = 1;
822 } else {
823 sz = (tmp >> 16);
824 hashtable += (tmp & 0xFFFE) >> 1;
825 tmp = * hashtable;
826 }
827 do {
828 if(hashValue == (tmp & 0xFFFE)){
829 NdbColumnImpl* col = cols[tmp >> 16];
830 if(strncmp(name, col->m_name.c_str(), col->m_name.length()) == 0){
831 return col;
832 }
833 }
834 hashtable++;
835 tmp = * hashtable;
836 } while(--sz > 0);
837 #if 0
838 Uint32 dir = m_columnHash[bucket];
839 Uint32 pos = bucket + ((dir & 0xFFFE) >> 1);
840 Uint32 cnt = dir >> 16;
841 ndbout_c("col: %s hv: %x bucket: %d dir: %x pos: %d cnt: %d tmp: %d -> 0",
842 name, hashValue, bucket, dir, pos, cnt, tmp);
843 #endif
844 return 0;
845 } else {
846 for(Uint32 i = 0; i<sz; i++){
847 NdbColumnImpl* col = * cols++;
848 if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
849 return col;
850 }
851 }
852 return 0;
853 }
854
855 inline
856 const NdbColumnImpl *
getColumn(unsigned attrId) const857 NdbTableImpl::getColumn(unsigned attrId) const {
858 if(m_columns.size() > attrId){
859 return m_columns[attrId];
860 }
861 return 0;
862 }
863
864 inline
865 const NdbColumnImpl *
getColumn(const char * name) const866 NdbTableImpl::getColumn(const char * name) const {
867 Uint32 sz = m_columns.size();
868 NdbColumnImpl* const * cols = m_columns.getBase();
869 for(Uint32 i = 0; i<sz; i++, cols++){
870 NdbColumnImpl* col = * cols;
871 if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
872 return col;
873 }
874 return 0;
875 }
876
877 inline
878 NdbIndexImpl &
getImpl(NdbDictionary::Index & t)879 NdbIndexImpl::getImpl(NdbDictionary::Index & t){
880 return t.m_impl;
881 }
882
883 inline
884 NdbIndexImpl &
getImpl(const NdbDictionary::Index & t)885 NdbIndexImpl::getImpl(const NdbDictionary::Index & t){
886 return t.m_impl;
887 }
888
889 inline
890 NdbDictionaryImpl &
getImpl(NdbDictionary::Dictionary & t)891 NdbDictionaryImpl::getImpl(NdbDictionary::Dictionary & t){
892 return t.m_impl;
893 }
894
895 inline
896 const NdbDictionaryImpl &
getImpl(const NdbDictionary::Dictionary & t)897 NdbDictionaryImpl::getImpl(const NdbDictionary::Dictionary & t){
898 return t.m_impl;
899 }
900
901 /*****************************************************************
902 * Inline:d getters
903 */
904
905 class InitTable : public GlobalCacheInitObject
906 {
907 public:
InitTable(NdbDictionaryImpl * dict,const BaseString & name)908 InitTable(NdbDictionaryImpl *dict,
909 const BaseString &name) :
910 GlobalCacheInitObject(dict, name)
911 {}
init(NdbTableImpl & tab) const912 int init(NdbTableImpl &tab) const
913 {
914 return m_dict->getBlobTables(tab);
915 }
916 };
917
918 inline
919 NdbTableImpl *
getTableGlobal(const char * table_name)920 NdbDictionaryImpl::getTableGlobal(const char * table_name)
921 {
922 const BaseString internal_tabname(m_ndb.internalize_table_name(table_name));
923 return fetchGlobalTableImplRef(InitTable(this, internal_tabname));
924 }
925
926 inline
927 NdbTableImpl *
getTable(const char * table_name,void ** data)928 NdbDictionaryImpl::getTable(const char * table_name, void **data)
929 {
930 DBUG_ENTER("NdbDictionaryImpl::getTable");
931 DBUG_PRINT("enter", ("table: %s", table_name));
932
933 if (unlikely(strchr(table_name, '$') != 0)) {
934 Uint32 tab_id, col_no;
935 if (is_ndb_blob_table(table_name, &tab_id, &col_no)) {
936 NdbTableImpl* t = getBlobTable(tab_id, col_no);
937 DBUG_RETURN(t);
938 }
939 }
940
941 const BaseString internal_tabname(m_ndb.internalize_table_name(table_name));
942 Ndb_local_table_info *info=
943 get_local_table_info(internal_tabname);
944 if (info == 0)
945 DBUG_RETURN(0);
946 if (data)
947 *data= info->m_local_data;
948 DBUG_RETURN(info->m_table_impl);
949 }
950
951 inline
952 Ndb_local_table_info *
get_local_table_info(const BaseString & internalTableName)953 NdbDictionaryImpl::get_local_table_info(const BaseString& internalTableName)
954 {
955 DBUG_ENTER("NdbDictionaryImpl::get_local_table_info");
956 DBUG_PRINT("enter", ("table: %s", internalTableName.c_str()));
957
958 Ndb_local_table_info *info= m_localHash.get(internalTableName.c_str());
959 if (info == 0)
960 {
961 NdbTableImpl *tab=
962 fetchGlobalTableImplRef(InitTable(this, internalTableName));
963 if (tab)
964 {
965 info= Ndb_local_table_info::create(tab, m_local_table_data_size);
966 if (info)
967 {
968 m_localHash.put(internalTableName.c_str(), info);
969 }
970 }
971 }
972 DBUG_RETURN(info); // autoincrement already initialized
973 }
974
975 class InitIndex : public GlobalCacheInitObject
976 {
977 public:
978 const char *m_index_name;
979 const NdbTableImpl &m_prim;
980
InitIndex(const BaseString & internal_indexname,const char * index_name,const NdbTableImpl & prim)981 InitIndex(const BaseString &internal_indexname,
982 const char *index_name,
983 const NdbTableImpl &prim) :
984 GlobalCacheInitObject(0, internal_indexname),
985 m_index_name(index_name),
986 m_prim(prim)
987 {}
988
init(NdbTableImpl & tab) const989 int init(NdbTableImpl &tab) const {
990 DBUG_ENTER("InitIndex::init");
991 DBUG_ASSERT(tab.m_indexType != NdbDictionary::Object::TypeUndefined);
992 /**
993 * Create index impl
994 */
995 NdbIndexImpl* idx;
996 if(NdbDictInterface::create_index_obj_from_table(&idx, &tab, &m_prim) == 0)
997 {
998 idx->m_table = &tab;
999 if (!idx->m_externalName.assign(m_index_name) ||
1000 !idx->m_internalName.assign(m_name))
1001 DBUG_RETURN(4000);
1002 tab.m_index = idx;
1003 DBUG_RETURN(0);
1004 }
1005 DBUG_RETURN(1);
1006 }
1007 };
1008
1009 inline
1010 NdbIndexImpl *
getIndexGlobal(const char * index_name,NdbTableImpl & ndbtab)1011 NdbDictionaryImpl::getIndexGlobal(const char * index_name,
1012 NdbTableImpl &ndbtab)
1013 {
1014 DBUG_ENTER("NdbDictionaryImpl::getIndexGlobal");
1015 const BaseString
1016 internal_indexname(m_ndb.internalize_index_name(&ndbtab, index_name));
1017 int retry= 2;
1018
1019 while (retry)
1020 {
1021 NdbTableImpl *tab=
1022 fetchGlobalTableImplRef(InitIndex(internal_indexname,
1023 index_name, ndbtab));
1024 if (tab)
1025 {
1026 // tab->m_index sould be set. otherwise tab == 0
1027 NdbIndexImpl *idx= tab->m_index;
1028 if (idx->m_table_id != (unsigned)ndbtab.getObjectId() ||
1029 idx->m_table_version != (unsigned)ndbtab.getObjectVersion())
1030 {
1031 releaseIndexGlobal(*idx, 1);
1032 retry--;
1033 continue;
1034 }
1035 DBUG_RETURN(idx);
1036 }
1037 break;
1038 }
1039 {
1040 // Index not found, try old format
1041 const BaseString
1042 old_internal_indexname(m_ndb.old_internalize_index_name(&ndbtab,
1043 index_name));
1044 retry= 2;
1045 while (retry)
1046 {
1047 NdbTableImpl *tab=
1048 fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
1049 index_name, ndbtab));
1050 if (tab)
1051 {
1052 // tab->m_index sould be set. otherwise tab == 0
1053 NdbIndexImpl *idx= tab->m_index;
1054 if (idx->m_table_id != (unsigned)ndbtab.getObjectId() ||
1055 idx->m_table_version != (unsigned)ndbtab.getObjectVersion())
1056 {
1057 releaseIndexGlobal(*idx, 1);
1058 retry--;
1059 continue;
1060 }
1061 DBUG_RETURN(idx);
1062 }
1063 break;
1064 }
1065 }
1066 m_error.code= 4243;
1067 DBUG_RETURN(0);
1068 }
1069
1070 inline int
releaseTableGlobal(NdbTableImpl & impl,int invalidate)1071 NdbDictionaryImpl::releaseTableGlobal(NdbTableImpl & impl, int invalidate)
1072 {
1073 DBUG_ENTER("NdbDictionaryImpl::releaseTableGlobal");
1074 DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
1075 m_globalHash->lock();
1076 m_globalHash->release(&impl, invalidate);
1077 m_globalHash->unlock();
1078 DBUG_RETURN(0);
1079 }
1080
1081 inline int
releaseIndexGlobal(NdbIndexImpl & impl,int invalidate)1082 NdbDictionaryImpl::releaseIndexGlobal(NdbIndexImpl & impl, int invalidate)
1083 {
1084 DBUG_ENTER("NdbDictionaryImpl::releaseIndexGlobal");
1085 DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
1086 m_globalHash->lock();
1087 m_globalHash->release(impl.m_table, invalidate);
1088 m_globalHash->unlock();
1089 DBUG_RETURN(0);
1090 }
1091
1092 inline
1093 NdbIndexImpl *
getIndex(const char * index_name,const char * table_name)1094 NdbDictionaryImpl::getIndex(const char * index_name,
1095 const char * table_name)
1096 {
1097 if (table_name == 0)
1098 {
1099 assert(0);
1100 m_error.code= 4243;
1101 return 0;
1102 }
1103
1104
1105 NdbTableImpl* prim = getTable(table_name);
1106 if (prim == 0)
1107 {
1108 m_error.code= 4243;
1109 return 0;
1110 }
1111
1112 return getIndex(index_name, *prim);
1113 }
1114
1115 inline
1116 NdbIndexImpl *
getIndex(const char * index_name,const NdbTableImpl & prim)1117 NdbDictionaryImpl::getIndex(const char* index_name,
1118 const NdbTableImpl& prim)
1119 {
1120
1121 const BaseString
1122 internal_indexname(m_ndb.internalize_index_name(&prim, index_name));
1123
1124 Ndb_local_table_info *info= m_localHash.get(internal_indexname.c_str());
1125 NdbTableImpl *tab;
1126 if (info == 0)
1127 {
1128 tab= fetchGlobalTableImplRef(InitIndex(internal_indexname,
1129 index_name,
1130 prim));
1131 if (!tab)
1132 goto retry;
1133
1134 info= Ndb_local_table_info::create(tab, 0);
1135 if (!info)
1136 goto retry;
1137 m_localHash.put(internal_indexname.c_str(), info);
1138 }
1139 else
1140 tab= info->m_table_impl;
1141
1142 return tab->m_index;
1143
1144 retry:
1145 // Index not found, try fetching it from current database
1146 const BaseString
1147 old_internal_indexname(m_ndb.old_internalize_index_name(&prim, index_name));
1148
1149 info= m_localHash.get(old_internal_indexname.c_str());
1150 if (info == 0)
1151 {
1152 tab= fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
1153 index_name,
1154 prim));
1155 if (!tab)
1156 goto err;
1157
1158 info= Ndb_local_table_info::create(tab, 0);
1159 if (!info)
1160 goto err;
1161 m_localHash.put(old_internal_indexname.c_str(), info);
1162 }
1163 else
1164 tab= info->m_table_impl;
1165
1166 return tab->m_index;
1167
1168 err:
1169 m_error.code= 4243;
1170 return 0;
1171 }
1172
1173 inline
1174 NdbTablespaceImpl &
getImpl(NdbDictionary::Tablespace & t)1175 NdbTablespaceImpl::getImpl(NdbDictionary::Tablespace & t){
1176 return t.m_impl;
1177 }
1178
1179 inline
1180 const NdbTablespaceImpl &
getImpl(const NdbDictionary::Tablespace & t)1181 NdbTablespaceImpl::getImpl(const NdbDictionary::Tablespace & t){
1182 return t.m_impl;
1183 }
1184
1185 inline
1186 NdbLogfileGroupImpl &
getImpl(NdbDictionary::LogfileGroup & t)1187 NdbLogfileGroupImpl::getImpl(NdbDictionary::LogfileGroup & t){
1188 return t.m_impl;
1189 }
1190
1191 inline
1192 const NdbLogfileGroupImpl &
getImpl(const NdbDictionary::LogfileGroup & t)1193 NdbLogfileGroupImpl::getImpl(const NdbDictionary::LogfileGroup & t){
1194 return t.m_impl;
1195 }
1196
1197 inline
1198 NdbDatafileImpl &
getImpl(NdbDictionary::Datafile & t)1199 NdbDatafileImpl::getImpl(NdbDictionary::Datafile & t){
1200 return t.m_impl;
1201 }
1202
1203 inline
1204 const NdbDatafileImpl &
getImpl(const NdbDictionary::Datafile & t)1205 NdbDatafileImpl::getImpl(const NdbDictionary::Datafile & t){
1206 return t.m_impl;
1207 }
1208
1209 inline
1210 NdbUndofileImpl &
getImpl(NdbDictionary::Undofile & t)1211 NdbUndofileImpl::getImpl(NdbDictionary::Undofile & t){
1212 return t.m_impl;
1213 }
1214
1215 inline
1216 const NdbUndofileImpl &
getImpl(const NdbDictionary::Undofile & t)1217 NdbUndofileImpl::getImpl(const NdbDictionary::Undofile & t){
1218 return t.m_impl;
1219 }
1220
1221 #endif
1222