List:Commits« Previous MessageNext Message »
From:jonas Date:March 7 2007 5:11pm
Subject:bk commit into 5.1 tree (jonas:1.2453)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of jonas. When jonas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-03-07 17:11:00+01:00, jonas@stripped +4 -0
  ndb -
    Add new interface for doing startTransaction with hints
      when using multi-parts keys also supports charsets!

  storage/ndb/include/ndbapi/Ndb.hpp@stripped, 2007-03-07 17:10:57+01:00, jonas@stripped +41 -0
    Add new interface for doing startTransaction with hints
      when using multi-parts keys
      also supports charsets!

  storage/ndb/src/ndbapi/Ndb.cpp@stripped, 2007-03-07 17:10:57+01:00, jonas@stripped +171 -0
    Add new interface for doing startTransaction with hints
      when using multi-parts keys
      also supports charsets!

  storage/ndb/src/ndbapi/ndberror.c@stripped, 2007-03-07 17:10:57+01:00, jonas@stripped +5 -0
    Add new interface for doing startTransaction with hints
      when using multi-parts keys
      also supports charsets!

  storage/ndb/test/ndbapi/testPartitioning.cpp@stripped, 2007-03-07 17:10:57+01:00, jonas@stripped +8 -2
    test new api

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jonas
# Host:	perch.ndb.mysql.com
# Root:	/home/jonas/src/51-telco

--- 1.10/storage/ndb/test/ndbapi/testPartitioning.cpp	2007-03-07 17:11:05 +01:00
+++ 1.11/storage/ndb/test/ndbapi/testPartitioning.cpp	2007-03-07 17:11:05 +01:00
@@ -347,21 +347,27 @@
     char* start= buffer + (rand() & 7);
     char* pos= start;
     
+    int k = 0;
+    Ndb::Key_part_ptr ptrs[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
     for(int j = 0; j<tab->getNoOfColumns(); j++)
     {
       if(tab->getColumn(j)->getPartitionKey())
       {
-	ndbout_c(tab->getColumn(j)->getName());
+	//ndbout_c(tab->getColumn(j)->getName());
 	int sz = tab->getColumn(j)->getSizeInBytes();
 	int aligned_size = 4 * ((sz + 3) >> 2);
 	memset(pos, 0, aligned_size);
 	Uint32 real_size;
 	dummy.calcValue(i, j, 0, pos, sz, &real_size);
+	ptrs[k].ptr = pos;
+	ptrs[k++].len = real_size;
 	pos += (real_size + 3) & ~3;
       }
     }
+    ptrs[k].ptr = 0;
+    
     // Now we have the pk
-    NdbTransaction* pTrans= p_ndb->startTransaction(tab, start,(pos - start));
+    NdbTransaction* pTrans= p_ndb->startTransaction(tab, ptrs);
     HugoOperations ops(*tab);
     ops.setTransaction(pTrans);
     if(ops.pkReadRecord(p_ndb, i, 1) != NDBT_OK)

--- 1.61/storage/ndb/include/ndbapi/Ndb.hpp	2007-03-07 17:11:05 +01:00
+++ 1.62/storage/ndb/include/ndbapi/Ndb.hpp	2007-03-07 17:11:05 +01:00
@@ -1055,6 +1055,8 @@
   friend class NdbDictInterface;
   friend class NdbBlob;
   friend class NdbImpl;
+  friend class Ndb_cluster_connection;
+  friend class Ndb_cluster_connection_impl;
 #endif
 
 public:
@@ -1298,6 +1300,45 @@
   NdbTransaction* startTransaction(const NdbDictionary::Table *table= 0,
 				   const char  *keyData = 0, 
 				   Uint32       keyLen = 0);
+
+
+
+  /**
+   * Structure for passing in pointers to startTransaction
+   *
+   */
+  struct Key_part_ptr
+  {
+    const void * ptr;
+    unsigned len;
+  };
+
+  /**
+   * Start a transaction
+   *
+   * @note When the transaction is completed it must be closed using
+   *       Ndb::closeTransaction or NdbTransaction::close. 
+   *       The transaction must be closed independent of its outcome, i.e.
+   *       even if there is an error.
+   *
+   * @param  table    Pointer to table object used for deciding 
+   *                  which node to run the Transaction Coordinator on
+   * @param  keyData  Null-terminated array of pointers to keyParts that is 
+   *                  part of distribution key.
+   *                  Length of resp. keyPart will be read from
+   *                  metadata and checked against passed value
+   * @param  xfrmbuf  Pointer to temporary buffer that will be used
+   *                  to calculate hashvalue
+   * @param  xfrmbuflen Lengh of buffer
+   *
+   * @note if xfrmbuf is null (default) malloc/free will be made
+   *       if xfrmbuf is not null but length is too short, method will fail
+   *
+   * @return NdbTransaction object, or NULL on failure.
+   */
+  NdbTransaction* startTransaction(const NdbDictionary::Table *table,
+				   const struct Key_part_ptr * keyData,
+				   void* xfrmbuf = 0, Uint32 xfrmbuflen = 0);
 
   /**
    * Close a transaction.

--- 1.87/storage/ndb/src/ndbapi/Ndb.cpp	2007-03-07 17:11:05 +01:00
+++ 1.88/storage/ndb/src/ndbapi/Ndb.cpp	2007-03-07 17:11:05 +01:00
@@ -37,6 +37,7 @@
 #include "API.hpp"
 #include <NdbEnv.h>
 #include <BaseString.hpp>
+#include <NdbSqlUtil.hpp>
 
 /****************************************************************************
 void connect();
@@ -293,6 +294,176 @@
                 Return NULL otherwise.
 Remark:         Start transaction. Synchronous.
 *****************************************************************************/ 
+NdbTransaction* 
+Ndb::startTransaction(const NdbDictionary::Table *table,
+		      const struct Key_part_ptr * keyData, 
+		      void* buf, Uint32 bufLen)
+{
+  Uint32 j = 0;
+  Uint32 sumlen = 0; // Needed len
+  const NdbTableImpl* impl = &NdbTableImpl::getImpl(*table);
+  const NdbColumnImpl* const * cols = impl->m_columns.getBase();
+  
+  Uint32 colcnt = impl->m_columns.size();
+  Uint32 parts = impl->m_noOfDistributionKeys;
+  if (parts == 0)
+  {
+    parts = impl->m_noOfKeys;
+  }
+
+  for (Uint32 i = 0; i<parts; i++)
+  {
+    if (unlikely(keyData[i].ptr == 0))
+      goto enullptr;
+  }
+
+  if (unlikely(keyData[parts].ptr != 0))
+    goto emissingnullptr;
+
+  const NdbColumnImpl* partcols[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
+  for (Uint32 i = 0; i<colcnt && j < parts; i++)
+  {
+    if (cols[i]->m_distributionKey)
+    {
+      partcols[j++] = cols[i];
+    }
+  }
+
+  for (Uint32 i = 0; i<parts; i++)
+  {
+    Uint32 lb, len;
+    if (unlikely(!NdbSqlUtil::get_var_length(partcols[i]->m_type, 
+					     keyData[i].ptr, 
+					     keyData[i].len,
+					     lb, len)))
+      goto emalformedkey;
+
+    if (unlikely(keyData[i].len < (lb + len)))
+      goto elentosmall;
+    
+    Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize);
+
+    if (unlikely(lb == 0 && keyData[i].len != maxlen))
+      goto emalformedkey;
+    
+    if (partcols[i]->m_cs)
+    {
+      Uint32 xmul = partcols[i]->m_cs->strxfrm_multiply;
+      xmul = xmul ? xmul : 1;
+      len = xmul * (maxlen - lb);
+    }
+
+    len = (lb + len + 3) & ~(Uint32)3;
+    sumlen += len;
+
+  }
+  
+  if (buf)
+  {
+    UintPtr org = UintPtr(buf);
+    UintPtr use = (org + 7) & ~(UintPtr)7;
+
+    buf = (void*)use;
+    bufLen -= (use - org);
+
+    if (unlikely(sumlen > bufLen))
+      goto ebuftosmall;
+  }
+  else
+  {
+    buf = malloc(sumlen);
+    if (unlikely(buf == 0))
+      goto enomem;
+    bufLen = 0;
+    assert((UintPtr(buf) & 7) == 0);
+  }
+  
+  char* pos = (char*)buf;
+  for (Uint32 i = 0; i<parts; i++)
+  {
+    Uint32 lb, len;
+    NdbSqlUtil::get_var_length(partcols[i]->m_type, 
+			       keyData[i].ptr, keyData[i].len, lb, len);
+    CHARSET_INFO* cs;
+    if ((cs = partcols[i]->m_cs))
+    {
+      Uint32 xmul = cs->strxfrm_multiply;
+      if (xmul == 0)
+	xmul = 1;
+      /*
+       * Varchar end-spaces are ignored in comparisons.  To get same hash
+       * we blank-pad to maximum length via strnxfrm.
+       */
+      Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize);
+      Uint32 dstLen = xmul * (maxlen - lb);
+      int n = NdbSqlUtil::strnxfrm_bug7284(cs, 
+					   (unsigned char*)pos, 
+					   dstLen, 
+					   ((unsigned char*)keyData[i].ptr)+lb,
+					   len);
+      
+      if (unlikely(n == -1))
+	goto emalformedstring;
+      
+      while ((n & 3) != 0) 
+      {
+	pos[n++] = 0;
+      }
+      pos += n;
+    }
+    else
+    {
+      len += lb;
+      memcpy(pos, keyData[i].ptr, len);
+      while (len & 3)
+      {
+	* (pos + len++) = 0;
+      }
+      pos += len;
+    }
+  }
+  Uint32 len = UintPtr(pos) - UintPtr(buf);
+  assert((len & 3) == 0);
+    
+  NdbTransaction* trans = startTransaction(table, (char*)buf, len);
+
+  if (bufLen == 0)
+    free(buf);
+
+  return trans;
+
+enullptr:
+  theError.code = 4316;
+  return 0;
+  
+emissingnullptr:
+  theError.code = 4276;
+  return 0;
+
+elentosmall:
+  theError.code = 4277;
+  return 0;
+
+ebuftosmall:
+  theError.code = 4278;
+  return 0;
+
+emalformedstring:
+  if (bufLen == 0)
+    free(buf);
+  
+  theError.code = 4279;
+  return 0;
+  
+emalformedkey:
+  theError.code = 4280;
+  return 0;
+
+enomem:
+  theError.code = 4000;
+  return 0;
+}
+
 NdbTransaction* 
 Ndb::startTransaction(const NdbDictionary::Table *table,
 		      const char * keyData, Uint32 keyLen)

--- 1.87/storage/ndb/src/ndbapi/ndberror.c	2007-03-07 17:11:05 +01:00
+++ 1.88/storage/ndb/src/ndbapi/ndberror.c	2007-03-07 17:11:05 +01:00
@@ -615,6 +615,11 @@
   { 4273, DMEC, IE, "No blob table in dict cache" },
   { 4274, DMEC, IE, "Corrupted main table PK in blob operation" },
   { 4275, DMEC, AE, "The blob method is incompatible with operation type or lock mode" },
+  { 4276, DMEC, AE, "Missing NULL ptr in end of keyData list" },
+  { 4277, DMEC, AE, "Key part len is to small for column" },
+  { 4278, DMEC, AE, "Supplied buffer to small" },
+  { 4279, DMEC, AE, "Malformed string" },
+  { 4280, DMEC, AE, "Inconsisten key part length" }
 };
 
 static
Thread
bk commit into 5.1 tree (jonas:1.2453)jonas7 Mar