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