List:Commits« Previous MessageNext Message »
From:pekka Date:March 24 2007 5:41pm
Subject:bk commit into 5.1 tree (pekka:1.2502)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of pekka. When pekka 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-24 17:41:03+01:00, pekka@stripped +6 -0
  ndb - wl#3717 event ops
  passes testBlobs and test_event_merge in V1 and V2

  storage/ndb/include/ndbapi/NdbBlob.hpp@stripped, 2007-03-24 17:38:39+01:00, pekka@stripped +5 -2
    wl#3717 event ops

  storage/ndb/src/ndbapi/NdbBlob.cpp@stripped, 2007-03-24 17:38:39+01:00, pekka@stripped +93 -22
    wl#3717 event ops

  storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp@stripped, 2007-03-24 17:38:39+01:00, pekka@stripped +71 -17
    wl#3717 event ops

  storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp@stripped, 2007-03-24 17:38:46+01:00, pekka@stripped +2 -3
    wl#3717 event ops

  storage/ndb/test/ndbapi/testBlobs.cpp@stripped, 2007-03-24 17:38:49+01:00, pekka@stripped +40 -15
    wl#3717 event ops

  storage/ndb/test/ndbapi/test_event_merge.cpp@stripped, 2007-03-24 17:38:52+01:00, pekka@stripped +11 -2
    wl#3717 event ops

# 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:	pekka
# Host:	clam.(none)
# Root:	/export/space/pekka/ndb/version/my51-wl3717-a

--- 1.83/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp	2007-03-06 18:36:43 +01:00
+++ 1.84/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp	2007-03-24 17:38:39 +01:00
@@ -66,16 +66,6 @@
 
 // EventBufData
 
-Uint32
-EventBufData::get_blob_part_no() const
-{
-  assert(ptr[0].sz > 2);
-  Uint32 pos = AttributeHeader(ptr[0].p[0]).getDataSize() +
-              AttributeHeader(ptr[0].p[1]).getDataSize();
-  Uint32 no = ptr[1].p[pos];
-  return no;
-}
-
 void
 EventBufData::add_part_size(Uint32 & full_count, Uint32 & full_sz) const
 {
@@ -173,6 +163,7 @@
   theBlobList = NULL;
   theBlobOpList = NULL;
   theMainOp = NULL;
+  theBlobVersion = 0;
 
   m_data_item= NULL;
   m_eventImpl = NULL;
@@ -433,6 +424,7 @@
       // pointer to main table op
       tBlobOp->theMainOp = this;
       tBlobOp->m_mergeEvents = m_mergeEvents;
+      tBlobOp->theBlobVersion = tAttrInfo->m_blobVersion;
 
       // to hide blob op it is linked under main op, not under m_ndb
       if (tLastBlopOp == NULL)
@@ -465,6 +457,34 @@
   DBUG_RETURN(tBlob);
 }
 
+Uint32
+NdbEventOperationImpl::get_blob_part_no()
+{
+  assert(theBlobVersion == 1 || theBlobVersion == 2);
+  assert(theMainOp != NULL);
+  const NdbTableImpl* mainTable = theMainOp->m_eventImpl->m_tableImpl;
+  assert(m_data_item != NULL);
+  LinearSectionPtr (&ptr)[3] = m_data_item->ptr;
+
+  uint pos = 0; // PK and DIST to skip
+
+  if (unlikely(theBlobVersion == 1)) {
+    pos += AttributeHeader(ptr[0].p[0]).getDataSize();
+    pos += AttributeHeader(ptr[0].p[1]).getDataSize();
+  } else {
+    uint n = mainTable->m_noOfKeys;
+    uint i;
+    for (i = 0; i < n; i++) {
+      pos += AttributeHeader(ptr[0].p[i]).getDataSize();
+    }
+    pos += AttributeHeader(ptr[0].p[n]).getDataSize();
+  }
+
+  assert(pos < ptr[1].sz);
+  Uint32 no = ptr[1].p[pos];
+  return no;
+}
+
 int
 NdbEventOperationImpl::readBlobParts(char* buf, NdbBlob* blob,
                                      Uint32 part, Uint32 count)
@@ -506,9 +526,23 @@
     blob_op->m_data_item = data;
     int r = blob_op->receive_event();
     assert(r > 0);
-    Uint32 no = data->get_blob_part_no();
-    Uint32 sz = blob->thePartSize;
+    // XXX should be: no = blob->theBlobEventPartValue
+    Uint32 no = blob_op->get_blob_part_no();
+
+    /*
+     * wl3717_todo
+     * NdbBlob::readData V2 wants one part at a time, including
+     * length bytes.  This will be fixed later.
+     */
     const char* src = blob->theBlobEventDataBuf.data;
+    Uint32 sz = 0;
+    if (unlikely(blob_op->theBlobVersion == 1)) {
+      sz = blob->thePartSize;
+    } else {
+      const uchar* p = (const uchar*)blob->theBlobEventDataBuf.data;
+      sz = 2 + p[0] + (p[1] << 8);
+      assert(count == 1);
+    }
 
     DBUG_PRINT_EVENT("info", ("part_data=%p part no=%u part sz=%u", data, no, sz));
 
@@ -2456,6 +2490,9 @@
 {
   DBUG_ENTER_EVENT("NdbEventBuffer::get_main_data");
 
+  int blobVersion = blob_data->m_event_op->theBlobVersion;
+  assert(blobVersion == 1 || blobVersion == 2);
+
   NdbEventOperationImpl* main_op = blob_data->m_event_op->theMainOp;
   assert(main_op != NULL);
   const NdbTableImpl* mainTable = main_op->m_eventImpl->m_tableImpl;
@@ -2463,13 +2500,30 @@
   // create LinearSectionPtr for main table key
   LinearSectionPtr ptr[3];
   Uint32 ah_buffer[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
-  ptr[0].sz = mainTable->m_noOfKeys;
-  ptr[0].p = ah_buffer;
-  ptr[1].sz = AttributeHeader(blob_data->ptr[0].p[0]).getDataSize();
-  ptr[1].p = blob_data->ptr[1].p;
+
+  if (unlikely(blobVersion == 1)) {
+    ptr[0].sz = mainTable->m_noOfKeys;
+    ptr[0].p = ah_buffer;
+    // get sz of PK Unsigned [sz]
+    ptr[1].sz = AttributeHeader(blob_data->ptr[0].p[0]).getDataSize();
+    // get pointer to PK
+    ptr[1].p = blob_data->ptr[1].p;
+    split_concatenated_pk(mainTable, ptr[0].p, ptr[1].p, ptr[1].sz);
+  } else {
+    // blob part key is table key + dist + part
+    ptr[0].sz = mainTable->m_noOfKeys;
+    ptr[0].p = blob_data->ptr[0].p;
+    // count size of table PK
+    uint sz = 0;
+    uint i;
+    for (i = 0; i < mainTable->m_noOfKeys; i++) {
+      sz += AttributeHeader(blob_data->ptr[0].p[i]).getDataSize();
+    }
+    ptr[1].sz = sz;
+    ptr[1].p = blob_data->ptr[1].p;
+  }
   ptr[2].sz = 0;
   ptr[2].p = 0;
-  split_concatenated_pk(mainTable, ptr[0].p, ptr[1].p, ptr[1].sz);
 
   DBUG_DUMP_EVENT("ah", (char*)ptr[0].p, ptr[0].sz << 2);
   DBUG_DUMP_EVENT("pk", (char*)ptr[1].p, ptr[1].sz << 2);

--- 1.34/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp	2007-01-25 05:17:41 +01:00
+++ 1.35/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp	2007-03-24 17:38:46 +01:00
@@ -76,9 +76,6 @@
 
   EventBufData() {}
 
-  // Get blob part number from blob data
-  Uint32 get_blob_part_no() const;
-
   /*
    * Main item does not include summary of parts (space / performance
    * tradeoff).  The summary is needed when moving single data item.
@@ -359,6 +356,7 @@
   NdbRecAttr *getValue(const NdbColumnImpl *, char *aValue, int n);
   NdbBlob *getBlobHandle(const char *colName, int n);
   NdbBlob *getBlobHandle(const NdbColumnImpl *, int n);
+  Uint32 get_blob_part_no();
   int readBlobParts(char* buf, NdbBlob* blob, Uint32 part, Uint32 count);
   int receive_event();
   const bool tableNameChanged() const;
@@ -392,6 +390,7 @@
   NdbBlob* theBlobList;
   NdbEventOperationImpl* theBlobOpList; // in main op, list of blob ops
   NdbEventOperationImpl* theMainOp; // in blob op, the main op
+  int theBlobVersion; // in blob op, NDB_BLOB_V1 or NDB_BLOB_V2
 
   NdbEventOperation::State m_state; /* note connection to mi_type */
   Uint32 mi_type; /* should be == 0 if m_state != EO_EXECUTING

--- 1.38/storage/ndb/test/ndbapi/testBlobs.cpp	2007-03-22 09:15:05 +01:00
+++ 1.39/storage/ndb/test/ndbapi/testBlobs.cpp	2007-03-24 17:38:49 +01:00
@@ -38,14 +38,20 @@
     {}
 };
 
+#define TEST_BLOBS_SIZE1        false, 240, 2000, 4
+#define TEST_BLOBS_SIZE2        true, 99, 55, 1
+#define TEST_BLOBS_MIN_SIZE1    false, 8, 8, 4
+#define TEST_BLOBS_MIN_SIZE2    true, 9, 5, 1
+
 struct Opt {
   unsigned m_batch;
   bool m_core;
   bool m_dbg;
-  const char* m_dbug;
+  const char* m_debug;
   bool m_fac;
   bool m_full;
   unsigned m_loop;
+  bool m_min;
   unsigned m_parts;
   unsigned m_rows;
   int m_seed;
@@ -71,10 +77,11 @@
     m_batch(7),
     m_core(false),
     m_dbg(false),
-    m_dbug(0),
+    m_debug(0),
     m_fac(false),
     m_full(false),
     m_loop(1),
+    m_min(false),
     m_parts(10),
     m_rows(100),
     m_seed(-1),
@@ -88,8 +95,8 @@
     m_pk1off(0x12340000),
     m_pk2len(55),
     m_oneblob(false),
-    m_blob1(false, 240, 2000, 4), // head+inline=256 bytes
-    m_blob2(true, 99, 55, 1),
+    m_blob1(TEST_BLOBS_SIZE1), // head+inline=256 bytes
+    m_blob2(TEST_BLOBS_SIZE2),
     // perf
     m_tnameperf("TB2"),
     m_rowsperf(10000),
@@ -110,10 +117,11 @@
     << "  -batch N    number of pk ops in batch [" << d.m_batch << "]" << endl
     << "  -core       dump core on error" << endl
     << "  -dbg        print program debug" << endl
-    << "  -dbug opt   print program debug and ndb api DBUG" << endl
+    << "  -debug opt  print program debug and ndb api DBUG" << endl
     << "  -fac        fetch across commit in scan delete [" << d.m_fac << "]" << endl
     << "  -full       read/write only full blob values" << endl
     << "  -loop N     loop N times 0=forever [" << d.m_loop << "]" << endl
+    << "  -min        small blob sizes" << endl
     << "  -parts N    max parts in blob value [" << d.m_parts << "]" << endl
     << "  -rows N     number of rows [" << d.m_rows << "]" << endl
     << "  -rowsperf N rows for performace test [" << d.m_rowsperf << "]" << endl
@@ -242,10 +250,10 @@
     col.setPrimaryKey(true);
     tab.addColumn(col);
   }
-  // col BL1 - Blob not-nullable
+  // col BL1 - Text not-nullable
   { NdbDictionary::Column col("BL1");
     const Bcol& b = g_opt.m_blob1;
-    col.setType(NdbDictionary::Column::Blob);
+    col.setType(NdbDictionary::Column::Text);
     col.setBlobVersion(g_opt.m_blob_version);
     col.setInlineSize(b.m_inline);
     col.setPartSize(b.m_partsize);
@@ -260,11 +268,11 @@
     col.setPrimaryKey(true);
     tab.addColumn(col);
   }
-  // col BL2 - Text nullable
+  // col BL2 - Blob nullable
   if (! g_opt.m_oneblob)
   { NdbDictionary::Column col("BL2");
     const Bcol& b = g_opt.m_blob2;
-    col.setType(NdbDictionary::Column::Text);
+    col.setType(NdbDictionary::Column::Blob);
     col.setBlobVersion(g_opt.m_blob_version);
     col.setNullable(true);
     col.setInlineSize(b.m_inline);
@@ -334,6 +342,17 @@
   Bval& operator=(const Bval&);
 };
 
+NdbOut&
+operator<<(NdbOut& out, const Bval& v)
+{
+  if (g_opt.m_min && v.m_val != 0) {
+    out << "[" << v.m_len << "]";
+    for (uint i = 0; i < v.m_len; i++)
+      out.print("%c", v.m_val[i]);
+  }
+  return out;
+}
+
 struct Tup {
   bool m_exists;        // exists in table
   Uint32 m_pk1;         // primary keys concatenated like keyinfo
@@ -469,7 +488,7 @@
   bool null = (v.m_val == 0);
   bool isNull;
   unsigned len;
-  DBG("setValue " <<  h->getColumn()->getName() << " len=" << v.m_len << " null=" << null);
+  DBG("setValue " <<  h->getColumn()->getName() << " len=" << v.m_len << " null=" << null << " " << v);
   if (null) {
     CHK(h->setNull() == 0 || h->getNdbError().code == error_code);
     if (error_code)
@@ -1939,7 +1958,7 @@
     const char* progname =
       strchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0];
     strcpy(cmdline, progname);
-    for (uint i = 0; i < argc; i++) {
+    for (uint i = 1; i < argc; i++) {
       strcat(cmdline, " ");
       strcat(cmdline, argv[i]);
     }
@@ -1960,10 +1979,10 @@
       g_opt.m_dbg = true;
       continue;
     }
-    if (strcmp(arg, "-dbug") == 0) {
+    if (strcmp(arg, "-debug") == 0) {
       if (++argv, --argc > 0) {
         g_opt.m_dbg = true;
-        g_opt.m_dbug = strdup(argv[0]);
+        g_opt.m_debug = strdup(argv[0]);
 	continue;
       }
     }
@@ -1981,6 +2000,12 @@
 	continue;
       }
     }
+    if (strcmp(arg, "-min") == 0) {
+      g_opt.m_min = true;
+      new (&g_opt.m_blob1) Bcol(TEST_BLOBS_MIN_SIZE1);
+      new (&g_opt.m_blob2) Bcol(TEST_BLOBS_MIN_SIZE2);
+      continue;
+    }
     if (strcmp(arg, "-parts") == 0) {
       if (++argv, --argc > 0) {
 	g_opt.m_parts = atoi(argv[0]);
@@ -2054,8 +2079,8 @@
     printusage();
     return NDBT_ProgramExit(NDBT_WRONGARGS);
   }
-  if (g_opt.m_dbug != 0) {
-    DBUG_PUSH(g_opt.m_dbug);
+  if (g_opt.m_debug != 0) {
+    DBUG_PUSH(g_opt.m_debug);
     ndbout.m_out = new FileOutputStream(DBUG_FILE);
   }
   if (g_opt.m_pk2len == 0) {

--- 1.25/storage/ndb/include/ndbapi/NdbBlob.hpp	2007-03-22 09:15:04 +01:00
+++ 1.26/storage/ndb/include/ndbapi/NdbBlob.hpp	2007-03-24 17:38:39 +01:00
@@ -300,7 +300,7 @@
   static void getBlobEvent(NdbEventImpl& be, const NdbEventImpl* e, const NdbColumnImpl* c);
   // compute blob table column number for faster access
   enum {
-    BtColumnPk = 0,     /* V1 only */
+    BtColumnPk = 0,    /* V1 only */
     BtColumnDist = 1,
     BtColumnPart = 2,
     BtColumnPkid = 3,  /* V2 only */
@@ -316,6 +316,7 @@
   NdbRecAttr* theBlobEventPkRecAttr;
   NdbRecAttr* theBlobEventDistRecAttr;
   NdbRecAttr* theBlobEventPartRecAttr;
+  NdbRecAttr* theBlobEventPkidRecAttr;
   NdbRecAttr* theBlobEventDataRecAttr;
   const NdbTableImpl* theTable;
   const NdbTableImpl* theAccessTable;
@@ -355,7 +356,9 @@
   Buf theHeadInlineCopyBuf;     // for writeTuple
   Buf thePartBuf;
   Buf theBlobEventDataBuf;
-  Uint32 thePartNumber;         // for event
+  Uint32 theBlobEventDistValue;
+  Uint32 theBlobEventPartValue;
+  Uint32 theBlobEventPkidValue;
   Head theHead;
   char* theInlineData;
   char* thePartData;

--- 1.55/storage/ndb/src/ndbapi/NdbBlob.cpp	2007-03-22 09:15:04 +01:00
+++ 1.56/storage/ndb/src/ndbapi/NdbBlob.cpp	2007-03-24 17:38:39 +01:00
@@ -170,16 +170,17 @@
   } else {
     {
       // table PK attributes
-      uint i;
       const uint columns = t->m_columns.size();
-      unsigned n = t->m_noOfKeys;
-      assert(n != 0);
-      for (i = 0; i < columns && n != 0; i++) {
+      const uint noOfKeys = t->m_noOfKeys;
+      uint n = 0;
+      uint i;
+      for (i = 0; n < noOfKeys; i++) {
+        assert(i < columns);
         NdbColumnImpl* c = t->m_columns[i];
         assert(c != NULL);
         if (c->m_pk) {
           bt.addColumn(*c);
-          n--;
+          n++;
         }
       }
     }
@@ -193,7 +194,12 @@
     { NdbDictionary::Column bc("NDB$PART");
       bc.setType(NdbDictionary::Column::Unsigned);
       bc.setPrimaryKey(true);
-      bc.setDistributionKey(false);
+      /*
+       * Cannot allow partial distribution key now because
+       * primary table PK may contain unsupported types.
+       * Must be fixed.  All PK types must be supported.
+       */
+      bc.setDistributionKey(true);
       bt.addColumn(bc);
     }
     // in V2 add id sequence for use in blob event code
@@ -310,6 +316,7 @@
   theBlobEventPkRecAttr = NULL;
   theBlobEventDistRecAttr = NULL;
   theBlobEventPartRecAttr = NULL;
+  theBlobEventPkidRecAttr = NULL;
   theBlobEventDataRecAttr = NULL;
   theTable = NULL;
   theAccessTable = NULL;
@@ -700,7 +707,8 @@
   uint n = 0;
   const uint noOfKeys = theTable->m_noOfKeys;
   unsigned pos = 0;
-  for (unsigned i = 0; i < columns && n < noOfKeys; i++) {
+  for (unsigned i = 0;  n < noOfKeys; i++) {
+    assert(i < columns);
     NdbColumnImpl* c = theTable->m_columns[i];
     assert(c != NULL);
     if (c->m_pk) {
@@ -715,8 +723,10 @@
       n++;
     }
   }
+#if wl3717_todo // decide partition stuff later
   if (theNdbOp->theDistrKeyIndicator_)
     anOp->setPartitionId(theNdbOp->getPartitionId());
+#endif
   assert(pos == theKeyBuf.size / 4);
   DBUG_RETURN(0);
 }
@@ -1203,6 +1213,8 @@
          *
          * Suggested fix is a new getValue() method which
          * returns length bytes and data into separate buffers.
+         *
+         * Reading event data must be adjusted similarly.
          */
         for (unsigned i = 0; i < count; i++) {
           if (readParts(thePartBuf.data, part + i, 1) == -1)
@@ -1757,7 +1769,7 @@
   // tinyblob sanity
   assert((theBlobEventOp == NULL) == (theBlobTable == NULL));
   // extra buffers
-  theBlobEventDataBuf.alloc(thePartSize);
+  theBlobEventDataBuf.alloc(theVarsizeBytes + thePartSize);
   // prepare receive of head+inline
   theHeadInlineRecAttr = theEventOp->getValue(aColumn, theHeadInlineBuf.data, version);
   if (theHeadInlineRecAttr == NULL) {
@@ -1766,20 +1778,79 @@
   }
   // prepare receive of blob part
   if (theBlobEventOp != NULL) {
-    if ((theBlobEventPkRecAttr =
-           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)0),
-                                    thePackKeyBuf.data, version)) == NULL ||
-        (theBlobEventDistRecAttr =
-           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)1),
-                                    (char*)0, version)) == NULL ||
-        (theBlobEventPartRecAttr =
-           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)2),
-                                    (char*)&thePartNumber, version)) == NULL ||
-        (theBlobEventDataRecAttr =
-           theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)3),
-                                    theBlobEventDataBuf.data, version)) == NULL) {
-      setErrorCode(theBlobEventOp);
-      DBUG_RETURN(-1);
+    const NdbColumnImpl* bc;
+    char* buf;
+    // one must subscribe to all primary keys
+    if (unlikely(theBlobVersion == NDB_BLOB_V1)) {
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnPk]);
+      buf = thePackKeyBuf.data;
+      theBlobEventPkRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      //
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnDist]);
+      buf = (char*)&theBlobEventDistValue;
+      theBlobEventDistRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      //
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnPart]);
+      buf = (char*)&theBlobEventPartValue;
+      theBlobEventPartRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      //
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnData]);
+      buf = theBlobEventDataBuf.data;
+      theBlobEventDataRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      if (unlikely(
+            theBlobEventPkRecAttr == NULL ||
+            theBlobEventDistRecAttr == NULL ||
+            theBlobEventPartRecAttr == NULL ||
+            theBlobEventDataRecAttr == NULL
+         )) {
+        setErrorCode(theBlobEventOp);
+        DBUG_RETURN(-1);
+      }
+    } else {
+      const uint columns = theTable->m_columns.size();
+      const uint noOfKeys = theTable->m_noOfKeys;
+      uint n = 0;
+      uint i;
+      for (i = 0; n < noOfKeys; i++) {
+        assert(i < columns);
+        const NdbColumnImpl* c = theTable->m_columns[i];
+        assert(c != NULL);
+        if (c->m_pk) {
+          bc = theBlobTable->m_columns[n];
+          assert(bc != NULL && bc->m_pk);
+          NdbRecAttr* ra;
+          ra = theBlobEventOp->getValue(bc, (char*)0, version);
+          if (unlikely(ra == NULL)) {
+            setErrorCode(theBlobEventOp);
+            DBUG_RETURN(-1);
+          }
+          n++;
+        }
+      }
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnDist]);
+      buf = (char*)&theBlobEventDistValue;
+      theBlobEventDistRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      //
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnPart]);
+      buf = (char*)&theBlobEventPartValue;
+      theBlobEventPartRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      //
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnPkid]);
+      buf = (char*)&theBlobEventPkidValue;
+      theBlobEventPkidRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      //
+      bc = theBlobTable->getColumn(theBtColumnNo[BtColumnData]);
+      buf = theBlobEventDataBuf.data;
+      theBlobEventDataRecAttr = theBlobEventOp->getValue(bc, buf, version);
+      if (unlikely(
+            theBlobEventDistRecAttr == NULL ||
+            theBlobEventPartRecAttr == NULL ||
+            theBlobEventPkidRecAttr == NULL ||
+            theBlobEventDataRecAttr == NULL
+         )) {
+        setErrorCode(theBlobEventOp);
+        DBUG_RETURN(-1);
+      }
     }
   }
   setState(Prepared);

--- 1.15/storage/ndb/test/ndbapi/test_event_merge.cpp	2006-12-23 20:20:27 +01:00
+++ 1.16/storage/ndb/test/ndbapi/test_event_merge.cpp	2007-03-24 17:38:52 +01:00
@@ -65,6 +65,7 @@
 
 struct Opts {
   my_bool abort_on_error;
+  int blob_version;
   int loglevel;
   uint loop;
   uint maxops;
@@ -315,12 +316,14 @@
       col.setCharset(cs);
       break;
     case NdbDictionary::Column::Text:
+      col.setBlobVersion(g_opts.blob_version);
       col.setInlineSize(g_blobinlinesize);
       col.setPartSize(g_blobpartsize);
       col.setStripeSize(g_blobstripesize);
       col.setCharset(cs);
       break;
     case NdbDictionary::Column::Blob:
+      col.setBlobVersion(g_opts.blob_version);
       col.setInlineSize(g_blobinlinesize);
       col.setPartSize(0);
       col.setStripeSize(0);
@@ -1554,7 +1557,7 @@
       cnt++;
     }
   }
-  ll1("use " << cnt << "/" << maxrun() << " tables in this loop");
+  ll0("selecttables: use " << cnt << "/" << maxrun() << " in this loop");
 }
 
 static void
@@ -1564,7 +1567,7 @@
   for (uint i = 0; i < maxrun(); i++)
     if (! run(i).skip)
       makeops(run(i));
-  ll1("makeops: used recs = " << g_usedops << " com recs = " << g_gciops);
+  ll0("makeops: used records = " << g_usedops);
 }
 
 static int
@@ -2236,6 +2239,9 @@
   { "use-table", 1017, "Use existing tables",
     (gptr*)&g_opts.use_table, (gptr*)&g_opts.use_table, 0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "blob-version", 1018, "Blob version 1 or 2 (default 2)",
+    (gptr*)&g_opts.blob_version, (gptr*)&g_opts.blob_version, 0,
+    GET_INT, REQUIRED_ARG, 2, 0, 0, 0, 0, 0 },
   { 0, 0, 0,
     0, 0, 0,
     GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
@@ -2250,6 +2256,9 @@
 static int
 checkopts()
 {
+  if (g_opts.blob_version < 1 || g_opts.blob_version > 2) {
+    return -1;
+  }
   if (g_opts.separate_events) {
     g_opts.no_blobs = true;
   }
Thread
bk commit into 5.1 tree (pekka:1.2502)pekka24 Mar