📄 ndbdictionaryimpl.cpp
字号:
/* 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 */#include "NdbDictionaryImpl.hpp"#include "API.hpp"#include <NdbOut.hpp>#include "NdbApiSignal.hpp"#include "TransporterFacade.hpp"#include <signaldata/GetTabInfo.hpp>#include <signaldata/DictTabInfo.hpp>#include <signaldata/CreateTable.hpp>#include <signaldata/CreateIndx.hpp>#include <signaldata/CreateEvnt.hpp>#include <signaldata/SumaImpl.hpp>#include <signaldata/DropTable.hpp>#include <signaldata/AlterTable.hpp>#include <signaldata/DropIndx.hpp>#include <signaldata/ListTables.hpp>#include <SimpleProperties.hpp>#include <Bitmask.hpp>#include <AttributeList.hpp>#include <NdbEventOperation.hpp>#include "NdbEventOperationImpl.hpp"#include <NdbBlob.hpp>#include "NdbBlobImpl.hpp"#include <AttributeHeader.hpp>#include <my_sys.h>#define DEBUG_PRINT 0#define INCOMPATIBLE_VERSION -2//#define EVENT_DEBUG/** * Column */NdbColumnImpl::NdbColumnImpl() : NdbDictionary::Column(* this), m_attrId(-1), m_facade(this){ init();}NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f) : NdbDictionary::Column(* this), m_attrId(-1), m_facade(&f){ init();}NdbColumnImpl&NdbColumnImpl::operator=(const NdbColumnImpl& col){ m_attrId = col.m_attrId; m_name = col.m_name; m_type = col.m_type; m_precision = col.m_precision; m_cs = col.m_cs; m_scale = col.m_scale; m_length = col.m_length; m_pk = col.m_pk; m_distributionKey = col.m_distributionKey; m_nullable = col.m_nullable; m_autoIncrement = col.m_autoIncrement; m_autoIncrementInitialValue = col.m_autoIncrementInitialValue; m_defaultValue = col.m_defaultValue; m_attrSize = col.m_attrSize; m_arraySize = col.m_arraySize; m_keyInfoPos = col.m_keyInfoPos; m_blobTable = col.m_blobTable; // Do not copy m_facade !! return *this;}voidNdbColumnImpl::init(Type t){ // do not use default_charset_info as it may not be initialized yet // use binary collation until NDB tests can handle charsets CHARSET_INFO* default_cs = &my_charset_bin; m_type = t; switch (m_type) { case Tinyint: case Tinyunsigned: case Smallint: case Smallunsigned: case Mediumint: case Mediumunsigned: case Int: case Unsigned: case Bigint: case Bigunsigned: case Float: case Double: m_precision = 0; m_scale = 0; m_length = 1; m_cs = NULL; break; case Olddecimal: case Olddecimalunsigned: case Decimal: case Decimalunsigned: m_precision = 10; m_scale = 0; m_length = 1; m_cs = NULL; break; case Char: case Varchar: m_precision = 0; m_scale = 0; m_length = 1; m_cs = default_cs; break; case Binary: case Varbinary: case Datetime: case Date: m_precision = 0; m_scale = 0; m_length = 1; m_cs = NULL; break; case Blob: m_precision = 256; m_scale = 8000; m_length = 4; m_cs = NULL; break; case Text: m_precision = 256; m_scale = 8000; m_length = 4; m_cs = default_cs; break; case Time: case Year: case Timestamp: m_precision = 0; m_scale = 0; m_length = 1; m_cs = NULL; break; case Bit: m_precision = 0; m_scale = 0; m_length = 1; m_cs = NULL; break; case Longvarchar: m_precision = 0; m_scale = 0; m_length = 1; // legal m_cs = default_cs; break; case Longvarbinary: m_precision = 0; m_scale = 0; m_length = 1; // legal m_cs = NULL; break; default: case Undefined: assert(false); break; } m_pk = false; m_nullable = false; m_distributionKey = false; m_keyInfoPos = 0; // next 2 are set at run time m_attrSize = 0; m_arraySize = 0; m_autoIncrement = false; m_autoIncrementInitialValue = 1; m_blobTable = NULL;}NdbColumnImpl::~NdbColumnImpl(){}boolNdbColumnImpl::equal(const NdbColumnImpl& col) const { DBUG_ENTER("NdbColumnImpl::equal"); if(strcmp(m_name.c_str(), col.m_name.c_str()) != 0){ DBUG_RETURN(false); } if(m_type != col.m_type){ DBUG_RETURN(false); } if(m_pk != col.m_pk){ DBUG_RETURN(false); } if(m_nullable != col.m_nullable){ DBUG_RETURN(false); }#ifdef ndb_dictionary_dkey_fixed if(m_pk){ if(m_distributionKey != col.m_distributionKey){ DBUG_RETURN(false); } }#endif if (m_precision != col.m_precision || m_scale != col.m_scale || m_length != col.m_length || m_cs != col.m_cs) { DBUG_RETURN(false); } if (m_autoIncrement != col.m_autoIncrement){ DBUG_RETURN(false); } if(strcmp(m_defaultValue.c_str(), col.m_defaultValue.c_str()) != 0){ DBUG_RETURN(false); } DBUG_RETURN(true);}NdbDictionary::Column *NdbColumnImpl::create_psuedo(const char * name){ NdbDictionary::Column * col = new NdbDictionary::Column(); col->setName(name); if(!strcmp(name, "NDB$FRAGMENT")){ col->setType(NdbDictionary::Column::Unsigned); col->m_impl.m_attrId = AttributeHeader::FRAGMENT; col->m_impl.m_attrSize = 4; col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$FRAGMENT_MEMORY")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::FRAGMENT_MEMORY; col->m_impl.m_attrSize = 8; col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$ROW_COUNT")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::ROW_COUNT; col->m_impl.m_attrSize = 8; col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$COMMIT_COUNT")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::COMMIT_COUNT; col->m_impl.m_attrSize = 8; col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$ROW_SIZE")){ col->setType(NdbDictionary::Column::Unsigned); col->m_impl.m_attrId = AttributeHeader::ROW_SIZE; col->m_impl.m_attrSize = 4; col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$RANGE_NO")){ col->setType(NdbDictionary::Column::Unsigned); col->m_impl.m_attrId = AttributeHeader::RANGE_NO; col->m_impl.m_attrSize = 4; col->m_impl.m_arraySize = 1; } else { abort(); } return col;}/** * NdbTableImpl */NdbTableImpl::NdbTableImpl() : NdbDictionary::Table(* this), m_facade(this){ init();}NdbTableImpl::NdbTableImpl(NdbDictionary::Table & f) : NdbDictionary::Table(* this), m_facade(&f){ init();}NdbTableImpl::~NdbTableImpl(){ if (m_index != 0) { delete m_index; m_index = 0; } for (unsigned i = 0; i < m_columns.size(); i++) delete m_columns[i]; }voidNdbTableImpl::init(){ m_changeMask= 0; m_tableId= RNIL; m_frm.clear(); m_fragmentType= NdbDictionary::Object::FragAllSmall; m_hashValueMask= 0; m_hashpointerValue= 0; m_logging= true; m_kvalue= 6; m_minLoadFactor= 78; m_maxLoadFactor= 80; m_keyLenInWords= 0; m_fragmentCount= 0; m_dictionary= NULL; m_index= NULL; m_indexType= NdbDictionary::Index::Undefined; m_noOfKeys= 0; m_noOfDistributionKeys= 0; m_noOfBlobs= 0; m_replicaCount= 0;}boolNdbTableImpl::equal(const NdbTableImpl& obj) const { DBUG_ENTER("NdbTableImpl::equal"); if ((m_internalName.c_str() == NULL) || (strcmp(m_internalName.c_str(), "") == 0) || (obj.m_internalName.c_str() == NULL) || (strcmp(obj.m_internalName.c_str(), "") == 0)) { // Shallow equal if(strcmp(getName(), obj.getName()) != 0){ DBUG_PRINT("info",("name %s != %s",getName(),obj.getName())); DBUG_RETURN(false); } } else // Deep equal if(strcmp(m_internalName.c_str(), obj.m_internalName.c_str()) != 0){ { DBUG_PRINT("info",("m_internalName %s != %s", m_internalName.c_str(),obj.m_internalName.c_str())); DBUG_RETURN(false); } } if(m_fragmentType != obj.m_fragmentType){ DBUG_PRINT("info",("m_fragmentType %d != %d",m_fragmentType,obj.m_fragmentType)); DBUG_RETURN(false); } if(m_columns.size() != obj.m_columns.size()){ DBUG_PRINT("info",("m_columns.size %d != %d",m_columns.size(),obj.m_columns.size())); DBUG_RETURN(false); } for(unsigned i = 0; i<obj.m_columns.size(); i++){ if(!m_columns[i]->equal(* obj.m_columns[i])){ DBUG_PRINT("info",("m_columns [%d] != [%d]",i,i)); DBUG_RETURN(false); } } if(m_logging != obj.m_logging){ DBUG_PRINT("info",("m_logging %d != %d",m_logging,obj.m_logging)); DBUG_RETURN(false); } if(m_kvalue != obj.m_kvalue){ DBUG_PRINT("info",("m_kvalue %d != %d",m_kvalue,obj.m_kvalue)); DBUG_RETURN(false); } if(m_minLoadFactor != obj.m_minLoadFactor){ DBUG_PRINT("info",("m_minLoadFactor %d != %d",m_minLoadFactor,obj.m_minLoadFactor)); DBUG_RETURN(false); } if(m_maxLoadFactor != obj.m_maxLoadFactor){ DBUG_PRINT("info",("m_maxLoadFactor %d != %d",m_maxLoadFactor,obj.m_maxLoadFactor)); DBUG_RETURN(false); } DBUG_RETURN(true);}voidNdbTableImpl::assign(const NdbTableImpl& org){ m_tableId = org.m_tableId; m_internalName.assign(org.m_internalName); m_externalName.assign(org.m_externalName); m_newExternalName.assign(org.m_newExternalName); m_frm.assign(org.m_frm.get_data(), org.m_frm.length()); m_fragmentType = org.m_fragmentType; m_fragmentCount = org.m_fragmentCount; for(unsigned i = 0; i<org.m_columns.size(); i++){ NdbColumnImpl * col = new NdbColumnImpl(); const NdbColumnImpl * iorg = org.m_columns[i]; (* col) = (* iorg); m_columns.push_back(col); } m_logging = org.m_logging; m_kvalue = org.m_kvalue; m_minLoadFactor = org.m_minLoadFactor; m_maxLoadFactor = org.m_maxLoadFactor; if (m_index != 0) delete m_index; m_index = org.m_index; m_noOfDistributionKeys = org.m_noOfDistributionKeys; m_noOfKeys = org.m_noOfKeys; m_keyLenInWords = org.m_keyLenInWords; m_noOfBlobs = org.m_noOfBlobs; m_version = org.m_version; m_status = org.m_status;}void NdbTableImpl::setName(const char * name){ m_newExternalName.assign(name);}const char * NdbTableImpl::getName() const{ if (m_newExternalName.empty()) return m_externalName.c_str(); else return m_newExternalName.c_str();}voidNdbTableImpl::buildColumnHash(){ const Uint32 size = m_columns.size(); int i; for(i = 31; i >= 0; i--){ if(((1 << i) & size) != 0){ m_columnHashMask = (1 << (i + 1)) - 1; break; } } Vector<Uint32> hashValues; Vector<Vector<Uint32> > chains; chains.fill(size, hashValues); for(i = 0; i< (int) size; i++){ Uint32 hv = Hash(m_columns[i]->getName()) & 0xFFFE; Uint32 bucket = hv & m_columnHashMask; bucket = (bucket < size ? bucket : bucket - size); assert(bucket < size); hashValues.push_back(hv); chains[bucket].push_back(i); } m_columnHash.clear(); Uint32 tmp = 1; m_columnHash.fill((unsigned)size-1, tmp); // Default no chaining Uint32 pos = 0; // In overflow vector for(i = 0; i< (int) size; i++){ Uint32 sz = chains[i].size(); if(sz == 1){ Uint32 col = chains[i][0]; Uint32 hv = hashValues[col]; Uint32 bucket = hv & m_columnHashMask; bucket = (bucket < size ? bucket : bucket - size); m_columnHash[bucket] = (col << 16) | hv | 1; } else if(sz > 1){ Uint32 col = chains[i][0]; Uint32 hv = hashValues[col]; Uint32 bucket = hv & m_columnHashMask; bucket = (bucket < size ? bucket : bucket - size); m_columnHash[bucket] = (sz << 16) | (((size - bucket) + pos) << 1); for(size_t j = 0; j<sz; j++, pos++){ Uint32 col = chains[i][j]; Uint32 hv = hashValues[col]; m_columnHash.push_back((col << 16) | hv); } } } m_columnHash.push_back(0); // Overflow when looping in end of array#if 0 for(size_t i = 0; i<m_columnHash.size(); i++){ Uint32 tmp = m_columnHash[i]; int col = -1; if(i < size && (tmp & 1) == 1){ col = (tmp >> 16); } else if(i >= size){ col = (tmp >> 16); } ndbout_c("m_columnHash[%d] %s = %x", i, col > 0 ? m_columns[col]->getName() : "" , m_columnHash[i]); }#endif}Uint32NdbTableImpl::get_nodes(Uint32 hashValue, const Uint16 ** nodes) const{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -