Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
void
Dbtux::freeDescEnt(IndexPtr indexPtr)
{
  DescPagePtr pagePtr;
  c_descPagePool.getPtr(pagePtr, indexPtr.p->m_descPage);
  Uint32* const data = pagePtr.p->m_data;
  const Uint32 size = getDescSize(*indexPtr.p);
  Uint32 off = indexPtr.p->m_descOff;
  // move the gap to the free area at the top
  while (off + size < DescPageSize - pagePtr.p->m_numFree) {
    jam();
    // next entry to move over the gap
    DescHead& descHead2 = *(DescHead*)&data[off + size];
    Uint32 indexId2 = descHead2.m_indexId;
    Index& index2 = *c_indexPool.getPtr(indexId2);
    Uint32 size2 = getDescSize(index2);
    ndbrequire(
        index2.m_descPage == pagePtr.i &&
        index2.m_descOff == off + size &&
        index2.m_numAttrs == descHead2.m_numAttrs);
    // move the entry (overlapping copy if size < size2)
    Uint32 i;
    for (i = 0; i < size2; i++) {
      jam();
      data[off + i] = data[off + size + i];
    }
    off += size2;
    // adjust page offset in index
    index2.m_descOff -= size;
    {
      // move KeySpec pointer
      DescHead& descHead2 = getDescHead(index2);
      KeyType* keyType2 = getKeyTypes(descHead2);
      index2.m_keySpec.set_buf(keyType2);
      ndbrequire(index2.m_keySpec.validate() == 0);
     }
  }
  ndbrequire(off + size == DescPageSize - pagePtr.p->m_numFree);
  pagePtr.p->m_numFree += size;
}
Ejemplo n.º 3
0
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
}