summaryrefslogtreecommitdiff
path: root/ndb/src/ndbapi/NdbDictionaryImpl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/ndbapi/NdbDictionaryImpl.hpp')
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.hpp653
1 files changed, 653 insertions, 0 deletions
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp
new file mode 100644
index 00000000000..f6b0644ea15
--- /dev/null
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -0,0 +1,653 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef NdbDictionaryImpl_H
+#define NdbDictionaryImpl_H
+
+#include <ndb_types.h>
+#include <kernel_types.h>
+#include <ndb_limits.h>
+#include <NdbError.hpp>
+#include <BaseString.hpp>
+#include <Vector.hpp>
+#include <UtilBuffer.hpp>
+#include <NdbDictionary.hpp>
+#include <Bitmask.hpp>
+#include <AttributeList.hpp>
+#include <Ndb.hpp>
+#include "NdbImpl.hpp"
+#include "DictCache.hpp"
+
+class NdbDictObjectImpl {
+public:
+ int m_version;
+ NdbDictionary::Object::Status m_status;
+
+ bool change();
+protected:
+ NdbDictObjectImpl() :
+ m_status(NdbDictionary::Object::New) {
+ }
+};
+
+/**
+ * Column
+ */
+class NdbColumnImpl : public NdbDictionary::Column {
+public:
+ NdbColumnImpl();
+ NdbColumnImpl(NdbDictionary::Column &); // This is not a copy constructor
+ ~NdbColumnImpl();
+ NdbColumnImpl& operator=(const NdbColumnImpl&);
+ void init();
+
+ int m_attrId;
+ BaseString m_name;
+ NdbDictionary::Column::Type m_type;
+ int m_precision;
+ int m_scale;
+ int m_length;
+
+ bool m_pk;
+ bool m_tupleKey;
+ bool m_distributionKey;
+ bool m_distributionGroup;
+ int m_distributionGroupBits;
+ bool m_nullable;
+ bool m_indexOnly;
+ bool m_autoIncrement;
+ Uint64 m_autoIncrementInitialValue;
+ BaseString m_defaultValue;
+
+ /**
+ * Internal types and sizes, and aggregates
+ */
+ Uint32 m_attrType; // type outsize API and DICT
+ Uint32 m_attrSize; // element size (size when arraySize==1)
+ Uint32 m_arraySize; // length or length+2 for Var* types
+ Uint32 m_keyInfoPos;
+ Uint32 m_extType; // used by restore (kernel type in versin v2x)
+ bool getInterpretableType() const ;
+
+ /**
+ * Equality/assign
+ */
+ bool equal(const NdbColumnImpl&) const;
+ void assign(const NdbColumnImpl&);
+
+ static NdbColumnImpl & getImpl(NdbDictionary::Column & t);
+ static const NdbColumnImpl & getImpl(const NdbDictionary::Column & t);
+ NdbDictionary::Column * m_facade;
+};
+
+class NdbTableImpl : public NdbDictionary::Table, public NdbDictObjectImpl {
+public:
+ NdbTableImpl();
+ NdbTableImpl(NdbDictionary::Table &);
+ ~NdbTableImpl();
+
+ void init();
+ void setName(const char * name);
+ const char * getName() const;
+
+ Uint32 m_changeMask;
+ Uint32 m_tableId;
+ BaseString m_internalName;
+ BaseString m_externalName;
+ BaseString m_newExternalName; // Used for alter table
+ UtilBuffer m_frm;
+ NdbDictionary::Object::FragmentType m_fragmentType;
+
+ /**
+ *
+ */
+ Uint32 m_columnHashMask;
+ Vector<Uint32> m_columnHash;
+ Vector<NdbColumnImpl *> m_columns;
+ void buildColumnHash();
+
+ bool m_logging;
+ int m_kvalue;
+ int m_minLoadFactor;
+ int m_maxLoadFactor;
+
+ NdbDictionaryImpl * m_dictionary;
+ NdbIndexImpl * m_index;
+ NdbColumnImpl * getColumn(unsigned attrId);
+ NdbColumnImpl * getColumn(const char * name);
+ const NdbColumnImpl * getColumn(unsigned attrId) const;
+ const NdbColumnImpl * getColumn(const char * name) const;
+
+ /**
+ * Index only stuff
+ */
+ BaseString m_primaryTable;
+ NdbDictionary::Index::Type m_indexType;
+
+ /**
+ * Aggregates
+ */
+ Uint32 m_noOfKeys;
+
+ /**
+ * Equality/assign
+ */
+ bool equal(const NdbTableImpl&) const;
+ void assign(const NdbTableImpl&);
+ void clearNewProperties();
+ void copyNewProperties();
+
+ static NdbTableImpl & getImpl(NdbDictionary::Table & t);
+ static NdbTableImpl & getImpl(const NdbDictionary::Table & t);
+ NdbDictionary::Table * m_facade;
+};
+
+class NdbIndexImpl : public NdbDictionary::Index, public NdbDictObjectImpl {
+public:
+ NdbIndexImpl();
+ NdbIndexImpl(NdbDictionary::Index &);
+ ~NdbIndexImpl();
+
+ void setName(const char * name);
+ const char * getName() const;
+ void setTable(const char * table);
+ const char * getTable() const;
+
+ Uint32 m_indexId;
+ BaseString m_internalName;
+ BaseString m_externalName;
+ BaseString m_tableName;
+ Vector<NdbColumnImpl *> m_columns;
+ NdbDictionary::Index::Type m_type;
+
+ bool m_logging;
+
+ NdbTableImpl * m_table;
+
+ static NdbIndexImpl & getImpl(NdbDictionary::Index & t);
+ static NdbIndexImpl & getImpl(const NdbDictionary::Index & t);
+ NdbDictionary::Index * m_facade;
+};
+
+class NdbEventImpl : public NdbDictionary::Event, public NdbDictObjectImpl {
+public:
+ NdbEventImpl();
+ NdbEventImpl(NdbDictionary::Event &);
+ ~NdbEventImpl();
+
+ void setName(const char * name);
+ const char * getName() const;
+ void setTable(const char * table);
+ const char * getTable() const;
+ void addTableEvent(const NdbDictionary::Event::TableEvent t);
+ void setDurability(const NdbDictionary::Event::EventDurability d);
+ void addEventColumn(const NdbColumnImpl &c);
+
+ void print() {
+ ndbout_c("NdbEventImpl: id=%d, key=%d",
+ m_eventId,
+ m_eventKey);
+ };
+
+ Uint32 m_eventId;
+ Uint32 m_eventKey;
+ Uint32 m_tableId;
+ AttributeMask m_attrListBitmask;
+ //BaseString m_internalName;
+ BaseString m_externalName;
+ Uint32 mi_type;
+ NdbDictionary::Event::EventDurability m_dur;
+
+
+ NdbTableImpl *m_tableImpl;
+ BaseString m_tableName;
+ Vector<NdbColumnImpl *> m_columns;
+ Vector<unsigned> m_attrIds;
+
+ int m_bufferId;
+
+ NdbEventOperation *eventOp;
+
+ static NdbEventImpl & getImpl(NdbDictionary::Event & t);
+ static NdbEventImpl & getImpl(const NdbDictionary::Event & t);
+ NdbDictionary::Event * m_facade;
+};
+
+
+class NdbDictInterface {
+public:
+ NdbDictInterface(NdbError& err) : m_error(err) {
+ m_reference = 0;
+ m_masterNodeId = 0;
+ m_blockNumber = -1;
+ m_transporter= NULL;
+ }
+ ~NdbDictInterface();
+
+ bool setTransporter(class Ndb * ndb, class TransporterFacade * tf);
+ bool setTransporter(class TransporterFacade * tf);
+
+ // To abstract the stuff thats made in all create/drop/lists below
+ int
+ dictSignal(NdbApiSignal* signal,
+ LinearSectionPtr ptr[3], int noLPTR,
+ const int useMasterNodeId,
+ const Uint32 RETRIES,
+ const WaitSignalType wst,
+ const int theWait,
+ const int *errcodes,
+ const int noerrcodes,
+ const int temporaryMask = 0);
+
+ int createOrAlterTable(class Ndb & ndb, NdbTableImpl &, bool alter);
+
+ int createTable(class Ndb & ndb, NdbTableImpl &);
+ int createTable(NdbApiSignal* signal, LinearSectionPtr ptr[3]);
+
+ int alterTable(class Ndb & ndb, NdbTableImpl &);
+ int alterTable(NdbApiSignal* signal, LinearSectionPtr ptr[3]);
+
+ int createIndex(class Ndb & ndb,
+ NdbIndexImpl &,
+ const NdbTableImpl &);
+ int createIndex(NdbApiSignal* signal, LinearSectionPtr ptr[3]);
+
+ int createEvent(class Ndb & ndb, NdbEventImpl &, int getFlag);
+ int createEvent(NdbApiSignal* signal, LinearSectionPtr ptr[3], int noLSP);
+
+ int dropTable(const NdbTableImpl &);
+ int dropTable(NdbApiSignal* signal, LinearSectionPtr ptr[3]);
+
+ int dropIndex(const NdbIndexImpl &, const NdbTableImpl &);
+ int dropIndex(NdbApiSignal* signal, LinearSectionPtr ptr[3]);
+
+ int dropEvent(const NdbEventImpl &);
+ int dropEvent(NdbApiSignal* signal, LinearSectionPtr ptr[3], int noLSP);
+
+ int executeSubscribeEvent(class Ndb & ndb, NdbEventImpl &);
+ int executeSubscribeEvent(NdbApiSignal* signal, LinearSectionPtr ptr[3]);
+
+ int stopSubscribeEvent(class Ndb & ndb, NdbEventImpl &);
+ int stopSubscribeEvent(NdbApiSignal* signal, LinearSectionPtr ptr[3]);
+
+ int listObjects(NdbDictionary::Dictionary::List& list, Uint32 requestData);
+ int listObjects(NdbApiSignal* signal);
+
+ NdbTableImpl * getTable(int tableId);
+ NdbTableImpl * getTable(const char * name);
+ NdbTableImpl * getTable(class NdbApiSignal * signal,
+ LinearSectionPtr ptr[3],
+ Uint32 noOfSections);
+
+ static int parseTableInfo(NdbTableImpl ** dst,
+ const Uint32 * data, Uint32 len);
+
+ NdbError & m_error;
+private:
+ Uint32 m_reference;
+ Uint32 m_masterNodeId;
+ int m_blockNumber;
+
+ NdbWaiter m_waiter;
+ class TransporterFacade * m_transporter;
+
+ friend class Ndb;
+ static void execSignal(void* dictImpl,
+ class NdbApiSignal* signal,
+ class LinearSectionPtr ptr[3]);
+
+ static void execNodeStatus(void* dictImpl, NodeId,
+ bool alive, bool nfCompleted);
+
+ void execGET_TABINFO_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execGET_TABINFO_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execCREATE_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execCREATE_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execALTER_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execALTER_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+
+ void execCREATE_INDX_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execCREATE_INDX_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execDROP_INDX_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execDROP_INDX_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+
+ void execCREATE_EVNT_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execCREATE_EVNT_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execSUB_START_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execSUB_START_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execSUB_TABLE_DATA(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execSUB_GCP_COMPLETE_REP(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execSUB_STOP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execSUB_STOP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execDROP_EVNT_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execDROP_EVNT_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+
+ void execDROP_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execDROP_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+ void execLIST_TABLES_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
+
+ Uint32 m_fragmentId;
+ UtilBuffer m_buffer;
+};
+
+class NdbDictionaryImpl : public NdbDictionary::Dictionary {
+public:
+ NdbDictionaryImpl(Ndb &ndb);
+ NdbDictionaryImpl(Ndb &ndb, NdbDictionary::Dictionary & f);
+ ~NdbDictionaryImpl();
+
+ bool setTransporter(class Ndb * ndb, class TransporterFacade * tf);
+ bool setTransporter(class TransporterFacade * tf);
+
+ int createTable(NdbTableImpl &t)
+ {
+ return m_receiver.createTable(m_ndb, t);
+ }
+ int alterTable(NdbTableImpl &t);
+ int dropTable(const char * name);
+ int dropTable(NdbTableImpl &);
+ int invalidateObject(NdbTableImpl &);
+ int removeCachedObject(NdbTableImpl &);
+
+ int createIndex(NdbIndexImpl &ix);
+ int dropIndex(const char * indexName,
+ const char * tableName);
+ int dropIndex(NdbIndexImpl &, const char * tableName);
+ NdbTableImpl * getIndexTable(NdbIndexImpl * index,
+ NdbTableImpl * table);
+
+ int createEvent(NdbEventImpl &);
+ int dropEvent(const char * eventName);
+
+ int executeSubscribeEvent(NdbEventImpl &);
+ int stopSubscribeEvent(NdbEventImpl &);
+
+ int listObjects(List& list, NdbDictionary::Object::Type type);
+ int listIndexes(List& list, const char * tableName);
+
+ NdbTableImpl * getTable(const char * tableName);
+ NdbTableImpl * getTableImpl(const char * internalName);
+ NdbIndexImpl * getIndex(const char * indexName,
+ const char * tableName);
+ NdbIndexImpl * getIndexImpl(const char * name, const char * internalName);
+ NdbEventImpl * getEvent(const char * eventName);
+ NdbEventImpl * getEventImpl(const char * internalName);
+
+ const NdbError & getNdbError() const;
+ NdbError m_error;
+
+ LocalDictCache m_localHash;
+ GlobalDictCache * m_globalHash;
+
+ static NdbDictionaryImpl & getImpl(NdbDictionary::Dictionary & t);
+ static const NdbDictionaryImpl & getImpl(const NdbDictionary::Dictionary &t);
+ NdbDictionary::Dictionary * m_facade;
+
+ NdbDictInterface m_receiver;
+ Ndb & m_ndb;
+};
+
+inline
+NdbEventImpl &
+NdbEventImpl::getImpl(const NdbDictionary::Event & t){
+ return t.m_impl;
+}
+
+inline
+NdbEventImpl &
+NdbEventImpl::getImpl(NdbDictionary::Event & t){
+ return t.m_impl;
+}
+
+inline
+NdbColumnImpl &
+NdbColumnImpl::getImpl(NdbDictionary::Column & t){
+ return t.m_impl;
+}
+
+inline
+const NdbColumnImpl &
+NdbColumnImpl::getImpl(const NdbDictionary::Column & t){
+ return t.m_impl;
+}
+
+inline
+bool
+NdbColumnImpl::getInterpretableType() const {
+ return (m_type == NdbDictionary::Column::Unsigned ||
+ m_type == NdbDictionary::Column::Bigunsigned);
+}
+
+inline
+NdbTableImpl &
+NdbTableImpl::getImpl(NdbDictionary::Table & t){
+ return t.m_impl;
+}
+
+inline
+NdbTableImpl &
+NdbTableImpl::getImpl(const NdbDictionary::Table & t){
+ return t.m_impl;
+}
+
+inline
+NdbColumnImpl *
+NdbTableImpl::getColumn(unsigned attrId){
+ if(m_columns.size() > attrId){
+ return m_columns[attrId];
+ }
+ return 0;
+}
+
+inline
+Uint32
+Hash( const char* str ){
+ Uint32 h = 0;
+ Uint32 len = strlen(str);
+ while(len >= 4){
+ h = (h << 5) + h + str[0];
+ h = (h << 5) + h + str[1];
+ h = (h << 5) + h + str[2];
+ h = (h << 5) + h + str[3];
+ len -= 4;
+ str += 4;
+ }
+
+ switch(len){
+ case 3:
+ h = (h << 5) + h + *str++;
+ case 2:
+ h = (h << 5) + h + *str++;
+ case 1:
+ h = (h << 5) + h + *str++;
+ }
+ return h + h;
+}
+
+
+inline
+NdbColumnImpl *
+NdbTableImpl::getColumn(const char * name){
+
+ Uint32 sz = m_columns.size();
+ NdbColumnImpl** cols = m_columns.getBase();
+ const Uint32 * hashtable = m_columnHash.getBase();
+
+ if(sz > 5 && false){
+ Uint32 hashValue = Hash(name) & 0xFFFE;
+ Uint32 bucket = hashValue & m_columnHashMask;
+ bucket = (bucket < sz ? bucket : bucket - sz);
+ hashtable += bucket;
+ Uint32 tmp = * hashtable;
+ if((tmp & 1) == 1 ){ // No chaining
+ sz = 1;
+ } else {
+ sz = (tmp >> 16);
+ hashtable += (tmp & 0xFFFE) >> 1;
+ tmp = * hashtable;
+ }
+ do {
+ if(hashValue == (tmp & 0xFFFE)){
+ NdbColumnImpl* col = cols[tmp >> 16];
+ if(strcmp(name, col->m_name.c_str()) == 0){
+ return col;
+ }
+ }
+ hashtable++;
+ tmp = * hashtable;
+ } while(--sz > 0);
+#if 0
+ Uint32 dir = m_columnHash[bucket];
+ Uint32 pos = bucket + ((dir & 0xFFFE) >> 1);
+ Uint32 cnt = dir >> 16;
+ ndbout_c("col: %s hv: %x bucket: %d dir: %x pos: %d cnt: %d tmp: %d -> 0",
+ name, hashValue, bucket, dir, pos, cnt, tmp);
+#endif
+ return 0;
+ } else {
+ for(Uint32 i = 0; i<sz; i++){
+ NdbColumnImpl* col = * cols++;
+ if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
+ return col;
+ }
+ }
+ return 0;
+}
+
+inline
+const NdbColumnImpl *
+NdbTableImpl::getColumn(unsigned attrId) const {
+ if(m_columns.size() > attrId){
+ return m_columns[attrId];
+ }
+ return 0;
+}
+
+inline
+const NdbColumnImpl *
+NdbTableImpl::getColumn(const char * name) const {
+ Uint32 sz = m_columns.size();
+ NdbColumnImpl* const * cols = m_columns.getBase();
+ for(Uint32 i = 0; i<sz; i++, cols++){
+ NdbColumnImpl* col = * cols;
+ if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
+ return col;
+ }
+ return 0;
+}
+
+inline
+NdbIndexImpl &
+NdbIndexImpl::getImpl(NdbDictionary::Index & t){
+ return t.m_impl;
+}
+
+inline
+NdbIndexImpl &
+NdbIndexImpl::getImpl(const NdbDictionary::Index & t){
+ return t.m_impl;
+}
+
+inline
+NdbDictionaryImpl &
+NdbDictionaryImpl::getImpl(NdbDictionary::Dictionary & t){
+ return t.m_impl;
+}
+
+inline
+const NdbDictionaryImpl &
+NdbDictionaryImpl::getImpl(const NdbDictionary::Dictionary & t){
+ return t.m_impl;
+}
+
+/*****************************************************************
+ * Inline:d getters
+ */
+
+inline
+NdbTableImpl *
+NdbDictionaryImpl::getTable(const char * tableName)
+{
+ const char * internalTableName = m_ndb.internalizeTableName(tableName);
+
+ return getTableImpl(internalTableName);
+}
+
+inline
+NdbTableImpl *
+NdbDictionaryImpl::getTableImpl(const char * internalTableName)
+{
+ NdbTableImpl *ret = m_localHash.get(internalTableName);
+
+ if (ret != 0) {
+ return ret; // autoincrement already initialized
+ }
+
+ m_globalHash->lock();
+ ret = m_globalHash->get(internalTableName);
+ m_globalHash->unlock();
+
+ if (ret == 0){
+ ret = m_receiver.getTable(internalTableName);
+
+ m_globalHash->lock();
+ m_globalHash->put(internalTableName, ret);
+ m_globalHash->unlock();
+
+ if(ret == 0){
+ return 0;
+ }
+ }
+ m_localHash.put(internalTableName, ret);
+
+ m_ndb.theFirstTupleId[ret->getTableId()] = ~0;
+ m_ndb.theLastTupleId[ret->getTableId()] = ~0;
+
+ return ret;
+}
+
+inline
+NdbIndexImpl *
+NdbDictionaryImpl::getIndex(const char * indexName,
+ const char * tableName)
+{
+ if (tableName || Ndb::usingFullyQualifiedNames()) {
+ const char * internalIndexName = 0;
+ if (tableName) {
+ NdbTableImpl * t = getTable(tableName);
+ if (t != 0)
+ internalIndexName = m_ndb.internalizeIndexName(t, indexName);
+ } else {
+ internalIndexName = m_ndb.internalizeTableName(indexName); // Index is also a table
+ }
+ if (internalIndexName) {
+ NdbTableImpl * tab = getTableImpl(internalIndexName);
+
+ if (tab) {
+ if (tab->m_index == 0)
+ tab->m_index = getIndexImpl(indexName, internalIndexName);
+ if (tab->m_index != 0)
+ tab->m_index->m_table = tab;
+ return tab->m_index;
+ }
+ }
+ }
+
+ m_error.code = 4243;
+ return 0;
+}
+
+#endif