void Dbtux::readKeyAttrs(TuxCtx& ctx, const Frag& frag, TreeEnt ent, KeyData& keyData, Uint32 count) { const Index& index = *c_indexPool.getPtr(frag.m_indexId); const DescHead& descHead = getDescHead(index); const AttributeHeader* keyAttrs = getKeyAttrs(descHead); Uint32* const outputBuffer = ctx.c_dataBuffer; #ifdef VM_TRACE ndbrequire(&keyData.get_spec() == &index.m_keySpec); ndbrequire(keyData.get_spec().validate() == 0); ndbrequire(count <= index.m_numAttrs); #endif const TupLoc tupLoc = ent.m_tupLoc; const Uint32 pageId = tupLoc.getPageId(); const Uint32 pageOffset = tupLoc.getPageOffset(); const Uint32 tupVersion = ent.m_tupVersion; const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI; const Uint32* keyAttrs32 = (const Uint32*)&keyAttrs[0]; int ret; ret = c_tup->tuxReadAttrs(ctx.jamBuffer, tableFragPtrI, pageId, pageOffset, tupVersion, keyAttrs32, count, outputBuffer, false); jamEntry(); ndbrequire(ret > 0); keyData.reset(); Uint32 len; ret = keyData.add_poai(outputBuffer, count, &len); ndbrequire(ret == 0); ret = keyData.finalize(); ndbrequire(ret == 0); #ifdef VM_TRACE if (debugFlags & (DebugMaint | DebugScan)) { debugOut << "readKeyAttrs: "; debugOut << " ent:" << ent << " count:" << count; debugOut << " data:" << keyData.print(ctx.c_debugBuffer, DebugBufferBytes); debugOut << endl; } #endif }
void Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) { jamEntry(); const TuxAddAttrReq reqCopy = *(const TuxAddAttrReq*)signal->getDataPtr(); const TuxAddAttrReq* const req = &reqCopy; // get the records FragOpPtr fragOpPtr; IndexPtr indexPtr; c_fragOpPool.getPtr(fragOpPtr, req->tuxConnectPtr); c_indexPool.getPtr(indexPtr, fragOpPtr.p->m_indexId); TuxAddAttrRef::ErrorCode errorCode = TuxAddAttrRef::NoError; do { // expected attribute id const unsigned attrId = fragOpPtr.p->m_numAttrsRecvd++; ndbrequire( indexPtr.p->m_state == Index::Defining && attrId < indexPtr.p->m_numAttrs && attrId == req->attrId); const Uint32 ad = req->attrDescriptor; const Uint32 typeId = AttributeDescriptor::getType(ad); const Uint32 sizeInBytes = AttributeDescriptor::getSizeInBytes(ad); const Uint32 nullable = AttributeDescriptor::getNullable(ad); const Uint32 csNumber = req->extTypeInfo >> 16; const Uint32 primaryAttrId = req->primaryAttrId; DescHead& descHead = getDescHead(*indexPtr.p); // add type to spec KeySpec& keySpec = indexPtr.p->m_keySpec; KeyType keyType(typeId, sizeInBytes, nullable, csNumber); if (keySpec.add(keyType) == -1) { jam(); errorCode = TuxAddAttrRef::InvalidAttributeType; break; } // add primary attr to read keys array AttributeHeader* keyAttrs = getKeyAttrs(descHead); AttributeHeader& keyAttr = keyAttrs[attrId]; new (&keyAttr) AttributeHeader(primaryAttrId, sizeInBytes); #ifdef VM_TRACE if (debugFlags & DebugMeta) { debugOut << "attr " << attrId << " " << keyType << endl; } #endif if (csNumber != 0) { unsigned err; CHARSET_INFO *cs = all_charsets[csNumber]; ndbrequire(cs != 0); if ((err = NdbSqlUtil::check_column_for_ordered_index(typeId, cs))) { jam(); errorCode = (TuxAddAttrRef::ErrorCode) err; break; } } const bool lastAttr = (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd); if ((ERROR_INSERTED(12003) && attrId == 0) || (ERROR_INSERTED(12004) && lastAttr)) { errorCode = (TuxAddAttrRef::ErrorCode)1; CLEAR_ERROR_INSERT_VALUE; break; } if (lastAttr) { // compute min prefix const KeySpec& keySpec = indexPtr.p->m_keySpec; unsigned attrs = 0; unsigned bytes = keySpec.get_nullmask_len(false); unsigned maxAttrs = indexPtr.p->m_numAttrs; #ifdef VM_TRACE #ifdef NDB_USE_GET_ENV { const char* p = NdbEnv_GetEnv("MAX_TTREE_PREF_ATTRS", (char*)0, 0); if (p != 0 && p[0] != 0 && maxAttrs > (unsigned)atoi(p)) maxAttrs = atoi(p); } #endif #endif while (attrs < maxAttrs) { const KeyType& keyType = keySpec.get_type(attrs); const unsigned newbytes = bytes + keyType.get_byte_size(); if (newbytes > (MAX_TTREE_PREF_SIZE << 2)) break; attrs++; bytes = newbytes; } if (attrs == 0) bytes = 0; indexPtr.p->m_prefAttrs = attrs; indexPtr.p->m_prefBytes = bytes; // fragment is defined #ifdef VM_TRACE if (debugFlags & DebugMeta) { debugOut << "Release frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl; } #endif c_fragOpPool.release(fragOpPtr); } // success TuxAddAttrConf* conf = (TuxAddAttrConf*)signal->getDataPtrSend(); conf->userPtr = fragOpPtr.p->m_userPtr; conf->lastAttr = lastAttr; sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRCONF, signal, TuxAddAttrConf::SignalLength, JBB); return; } while (0); // error TuxAddAttrRef* ref = (TuxAddAttrRef*)signal->getDataPtrSend(); ref->userPtr = fragOpPtr.p->m_userPtr; ref->errorCode = errorCode; sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRREF, signal, TuxAddAttrRef::SignalLength, JBB); #ifdef VM_TRACE if (debugFlags & DebugMeta) { debugOut << "Release on attr error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl; } #endif // let DICT drop the unfinished index }