List:Commits« Previous MessageNext Message »
From:tomas Date:July 10 2007 8:55pm
Subject:bk commit into 5.2 tree (tomas:1.2539)
View as plain text  
Below is the list of changes that have just been committed into a local
5.2 repository of tomas. When tomas 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-07-10 22:55:40+02:00, tomas@stripped +3 -0
  correction of merge

  mysql-test/t/disabled.def@stripped, 2007-07-10 22:55:37+02:00, tomas@stripped +1 -0
    disable because of bug (bug present before the merge, but there was no test that triggered it)

  sql/ha_ndbcluster.cc@stripped, 2007-07-10 22:55:38+02:00, tomas@stripped +86 -79
    correction of merge

  sql/ha_ndbcluster.h@stripped, 2007-07-10 22:55:38+02:00, tomas@stripped +1 -1
    correction of merge

diff -Nrup a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
--- a/mysql-test/t/disabled.def	2007-07-10 21:48:33 +02:00
+++ b/mysql-test/t/disabled.def	2007-07-10 22:55:37 +02:00
@@ -23,6 +23,7 @@ concurrent_innodb        : BUG#21579 200
 ndb_single_user          : Bug will not be fixed in this release (not yet atleast)
 ndb_autodiscover         : BUG#18952 2006-02-16 NDB Auto Discovery is failing designed tests in ndb_autodiscovery.test
 ndb_autodiscover2         : BUG#18952 2006-02-16 NDB Auto Discovery is failing designed tests in ndb_autodiscovery.test
+ndb_blob_partition       : BUG#29699 2007-07-09 tomas fails in partition by range
 ndb_load                 : BUG#17233 2006-05-04 tomas failed load data from infile causes mysqld dbug_assert, binlog not flushed
 
 partition_03ndb          : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table
diff -Nrup a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
--- a/sql/ha_ndbcluster.cc	2007-07-10 22:04:25 +02:00
+++ b/sql/ha_ndbcluster.cc	2007-07-10 22:55:38 +02:00
@@ -9414,8 +9414,6 @@ ha_ndbcluster::multi_range_read_info_con
   ha_rows rows, total_rows= 0;
   uint n_ranges=0;
   bool null_ranges= FALSE;
-  m_write_op= FALSE;
-
 
   seq_it= seq->init(seq_init_param, n_ranges, *flags);
   while (!seq->next(seq_it, &range))
@@ -9442,7 +9440,7 @@ ha_ndbcluster::multi_range_read_info_con
   if (total_rows != HA_POS_ERROR)
   {
     if (*flags & HA_MRR_USE_DEFAULT_IMPL ||
-        uses_blob_value() ||
+        uses_blob_value(table->read_set) ||
         ((get_index_type(keyno) ==  UNIQUE_INDEX &&
          has_null_in_unique_index(keyno)) && null_ranges))
     {
@@ -9486,7 +9484,8 @@ ha_ndbcluster::multi_range_read_info(uin
   uint save_bufsize= *bufsz;
   res= handler::multi_range_read_info(keyno, n_ranges, keys, bufsz, flags,
                                       cost);
-  if (uses_blob_value() || !(*flags & HA_MRR_NO_NULL_ENDPOINTS))
+  if (uses_blob_value(table->read_set) ||
+      !(*flags & HA_MRR_NO_NULL_ENDPOINTS))
   {
     *flags |= HA_MRR_USE_DEFAULT_IMPL;
     *bufsz= 0;
@@ -9527,8 +9526,10 @@ read_multi_needs_scan(NDB_INDEX_TYPE cur
 
 struct read_multi_callback_data {
   const KEY *key_info;
-  const KEY_MULTI_RANGE *first_range;
-  const KEY_MULTI_RANGE *range;
+  int first_range;
+  int range;
+  range_seq_t mrr_iter;
+  RANGE_SEQ_IF *mrr_funcs;
 };
 
 /* Callback to set up scan bounds for read multi range. */
@@ -9540,44 +9541,34 @@ read_multi_bounds_callback(void *arg, Ui
     (struct read_multi_callback_data *)arg;
 
   /* Skip any ranges not to be included in the scan. */
-  while (data->range->range_flag & (SKIP_RANGE|UNIQUE_RANGE))
+  KEY_MULTI_RANGE mrr_cur_range;
+  for(;;)
+  {
+    data->mrr_funcs->next(data->mrr_iter, &mrr_cur_range);
     data->range++;
-
+    if (!(mrr_persistent_flag_storage(data->mrr_iter, data->range)
+          & (SKIP_RANGE|UNIQUE_RANGE)))
+      break;
+  }
   compute_index_bounds(bound, data->key_info,
-                       &data->range->start_key, &data->range->end_key);
+                       &mrr_cur_range.start_key,
+                       &mrr_cur_range.end_key);
   bound.range_no= data->range - data->first_range;
 
-  data->range++;
-
   return 0;                                     // Success
 }
 
-int
-ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
-                                      KEY_MULTI_RANGE *ranges, 
-                                      uint range_count,
-                                      bool sorted, 
-                                      HANDLER_BUFFER *buffer)
+int ha_ndbcluster::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, 
+                                         void *seq_init_param,
+                                         uint n_ranges, uint mode,
+                                         HANDLER_BUFFER *buffer)
 {
-  KEY* key_info= table->key_info + active_index;
-  NDB_INDEX_TYPE cur_index_type= get_index_type(active_index);
-  ulong reclength= table_share->reclength;
-  NdbOperation* op;
+  int res;
   Thd_ndb *thd_ndb= get_thd_ndb(current_thd);
-  struct read_multi_callback_data data;
-
-  DBUG_ENTER("ha_ndbcluster::read_multi_range_first");
-  DBUG_PRINT("info", ("blob fields=%d read_set=0x%x", table_share->blob_fields, table->read_set->bitmap[0]));
+  DBUG_ENTER("ha_ndbcluster::multi_range_read_init");
 
-  /**
-   * blobs and unique hash index with NULL can't be batched currently
-   */
-  if (uses_blob_value(table->read_set) ||
-      (cur_index_type ==  UNIQUE_INDEX &&
-       has_null_in_unique_index(active_index) &&
-       null_value_index_search(ranges, ranges+range_count, buffer)))
+  if (mode & HA_MRR_USE_DEFAULT_IMPL)
   {
-    DBUG_PRINT("info", ("read_multi_range not possible, falling back to default handler implementation"));
     m_disable_multi_read= TRUE;
     DBUG_RETURN(handler::multi_range_read_init(seq_funcs, seq_init_param,
                                                n_ranges, mode, buffer));
@@ -9617,7 +9608,7 @@ ha_ndbcluster::read_multi_range_first(KE
 
 int ha_ndbcluster::multi_range_start_retrievals(int starting_range)
 {
-  int res, range_res;
+  int range_res;
   KEY* key_info= table->key_info + active_index;
   ulong reclength= table_share->reclength;
   NdbOperation* op;
@@ -9651,18 +9642,27 @@ int ha_ndbcluster::multi_range_start_ret
   const NdbOperation* lastOp= m_active_trans->getLastDefinedOperation();
   NdbOperation::LockMode lm= 
     (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type, table->read_set);
-  uchar *row_buf= (uchar *)buffer->buffer;
-  const uchar *end_of_buffer= buffer->buffer_end;
+  uchar *row_buf= (uchar *)multi_range_buffer->buffer;
+  const uchar *end_of_buffer= multi_range_buffer->buffer_end;
   uint num_scan_ranges= 0;
-  uint i;
-  for (i= 0; i < range_count; i++)
-  {
-    KEY_MULTI_RANGE *r= &ranges[i];
+  int range_no= -1;
+  int mrr_range_no= starting_range;
+  struct read_multi_callback_data data;
+  // ToDo: proper interface to save/retrieve point to iterate from
+  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)mrr_iter;
+  QUICK_RANGE **callback_ctx_cur= ctx->cur;
+  data.first_range= starting_range;
 
+  while (!(range_res= mrr_funcs.next(mrr_iter, &mrr_cur_range)) &&
+         row_buf+reclength <= end_of_buffer) // ToDo: is this really correct, will not mrr_cur_range be offset on reentering
+  {
+    range_no++;
+    mrr_range_no++;
     part_id_range part_spec;
     if (m_use_partition_function)
     {
-      get_partition_set(table, table->record[0], active_index, &r->start_key,
+      get_partition_set(table, table->record[0], active_index,
+                        &mrr_cur_range.start_key,
                         &part_spec);
       DBUG_PRINT("info", ("part_spec.start_part: %u  part_spec.end_part: %u",
                           part_spec.start_part, part_spec.end_part));
@@ -9676,23 +9676,24 @@ int ha_ndbcluster::multi_range_start_ret
           We can skip this partition since the key won't fit into any
           partition
         */
-        r->range_flag|= SKIP_RANGE;
+        row_buf += reclength;
+        mrr_persistent_flag_storage(mrr_iter, mrr_range_no)|= SKIP_RANGE;
         continue;
       }
     }
-    r->range_flag&= ~(uint)SKIP_RANGE;
+    mrr_persistent_flag_storage(mrr_iter, mrr_range_no)&= ~(uint)SKIP_RANGE;
 
-    if (read_multi_needs_scan(cur_index_type, key_info, r))
+    if (read_multi_needs_scan(cur_index_type, key_info, &mrr_cur_range))
     {
       /*
         If we reach the limit of ranges allowed in a single scan: stop
         here, send what we have so far, and continue when done with that.
       */
-      if (i > NdbIndexScanOperation::MaxRangeNo)
-        break;
+      if (range_no > NdbIndexScanOperation::MaxRangeNo)
+        break; // ToDo: is this really correct, will not mrr_cur_range be offset on reentering
 
       /* Include this range in the ordered index scan. */
-      r->range_flag&= ~(uint)UNIQUE_RANGE;
+      mrr_persistent_flag_storage(mrr_iter, mrr_range_no)&= ~(uint)UNIQUE_RANGE;
       num_scan_ranges++;
     }
     else
@@ -9706,10 +9707,10 @@ int ha_ndbcluster::multi_range_start_ret
       if (row_buf + reclength > end_of_buffer)
         break;
 
-      r->range_flag|= UNIQUE_RANGE;
+      mrr_persistent_flag_storage(mrr_iter, mrr_range_no)|= UNIQUE_RANGE;
 
       if (!(op= pk_unique_index_read_key(active_index,
-                                         r->start_key.key,
+                                         mrr_cur_range.start_key.key,
                                          row_buf, lm)))
         ERR_RETURN(m_active_trans->getNdbError());
 
@@ -9721,21 +9722,26 @@ int ha_ndbcluster::multi_range_start_ret
       row_buf+= reclength;
     }
   }
-  DBUG_ASSERT(i > 0 || i == range_count);       // Require progress
-  m_multi_range_defined_end= ranges + i;
+
   if (num_scan_ranges > 0)
   {
+    /* save state of iterator */
+    QUICK_RANGE **save_ctx_cur= ctx->cur;
+    ctx->cur= callback_ctx_cur;
+
     /* Do a multi-range index scan for ranges not done by primary/unique key. */
     uchar *mask;
 
     data.key_info= key_info;
-    data.first_range= ranges;
     data.range= data.first_range;
+    data.mrr_iter= mrr_iter;
+    data.mrr_funcs= &mrr_funcs;
+    data.first_range++;
 
     Uint32 flags= NdbScanOperation::SF_ReadRangeNo;
     if (lm == NdbOperation::LM_Read)
       flags|= NdbScanOperation::SF_KeyInfo;
-    if (sorted)
+    if (mrr_is_output_sorted)
       flags|= NdbScanOperation::SF_OrderBy;
 
     if (m_use_partition_function || table_share->primary_key == MAX_KEY)
@@ -9766,14 +9772,14 @@ int ha_ndbcluster::multi_range_start_ret
 
     /* We set m_next_row=0 to say that no row was fetched from the scan yet. */
     m_next_row= 0;
+
+    ctx->cur= save_ctx_cur;
   }
   else
   {
     m_active_cursor= 0;
   }
 
-  buffer->end_of_used_area= row_buf;
-
   /**
    * Set first operation in multi range
    */
@@ -9782,13 +9788,13 @@ int ha_ndbcluster::multi_range_start_ret
   if (execute_no_commit_ie(this, m_active_trans, true))
     ERR_RETURN(m_active_trans->getNdbError());
 
-  m_multi_range_result_ptr= buffer->buffer;
-
-  DBUG_RETURN(read_multi_range_next(found_range_p));
+  m_multi_range_result_ptr= (uchar*)multi_range_buffer->buffer;
+  first_running_range= first_range_in_batch= starting_range + 1;
+  first_unstarted_range= mrr_range_no + 1;
+  DBUG_RETURN(0);
 }
 
-int
-ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p)
+int ha_ndbcluster::multi_range_read_next(char **range_info)
 {
   DBUG_ENTER("ha_ndbcluster::multi_range_read_next");
 
@@ -9797,20 +9803,21 @@ ha_ndbcluster::read_multi_range_next(KEY
     DBUG_RETURN(handler::multi_range_read_next(range_info));
   }
 
-  while (multi_range_curr < m_multi_range_defined_end)
+  int res;
+
+  //for each range (we should have remembered the number)
+  for (;first_running_range < first_unstarted_range; first_running_range++)
   {
-    if (multi_range_curr->range_flag & SKIP_RANGE)
+    if (mrr_persistent_flag_storage(mrr_iter, first_running_range) & SKIP_RANGE)
     {
       /* Nothing in this range, move to next one. */
-      multi_range_curr++;
+      continue;
     }
-    else if (multi_range_curr->range_flag & UNIQUE_RANGE)
+    else if (mrr_persistent_flag_storage(mrr_iter, first_running_range) & UNIQUE_RANGE)
     {
       /*
         Move to next range; we can have at most one record from a unique range.
       */
-      KEY_MULTI_RANGE *old_multi_range_curr= multi_range_curr;
-      multi_range_curr= old_multi_range_curr + 1;
       const NdbOperation *op= m_current_multi_operation;
       m_current_multi_operation= m_active_trans->getNextCompletedOperation(op);
       const uchar *src_row= m_multi_range_result_ptr;
@@ -9819,7 +9826,7 @@ ha_ndbcluster::read_multi_range_next(KEY
       const NdbError &error= op->getNdbError();
       if (error.code == 0)
       {
-        *multi_range_found_p= old_multi_range_curr;
+        *range_info= mrr_get_ptr_by_idx(mrr_iter, first_running_range++);
         memcpy(table->record[0], src_row, table_share->reclength);
         if (table_share->primary_key == MAX_KEY)
         {
@@ -9831,10 +9838,12 @@ ha_ndbcluster::read_multi_range_next(KEY
       }
       else if (error.classification != NdbError::NoDataFound)
       {
+        first_running_range++;
         DBUG_RETURN(ndb_err(m_active_trans));
       }
 
       /* No row found, so fall through to try the next range. */
+      continue;
     }
     else
     {
@@ -9850,7 +9859,7 @@ ha_ndbcluster::read_multi_range_next(KEY
           The whole scan is done, and the cursor has been closed.
           So nothing more for this range. Move to next.
         */
-        multi_range_curr++;
+        continue;
       }
       else
       {
@@ -9859,18 +9868,18 @@ ha_ndbcluster::read_multi_range_next(KEY
         /*
           For a sorted index scan, we will receive rows in increasing range_no
           order, so we can return ranges in order, pausing when range_no
-          indicate that the currently processed range (multi_range_curr) is
+          indicate that the currently processed range (first_running_range) is
           done.
 
           But for unsorted scan, we may receive a high range_no from one
           fragment followed by a low range_no from another fragment. So we
           need to process all index scan ranges together.
         */
-        if (!multi_range_sorted ||
-            (expected_range_no= multi_range_curr - m_multi_ranges)
+        if (!mrr_is_output_sorted ||
+            (expected_range_no= first_running_range - first_range_in_batch)
                 == current_range_no)
         {
-          *multi_range_found_p= m_multi_ranges + current_range_no;
+          *range_info= mrr_get_ptr_by_idx(mrr_iter, first_running_range);
           /* Copy out data from the new row. */
           if (table_share->primary_key == MAX_KEY)
           {
@@ -9889,7 +9898,7 @@ ha_ndbcluster::read_multi_range_next(KEY
         else if (current_range_no > expected_range_no)
         {
           /* Nothing more in scan for this range. Move to next. */
-          multi_range_curr++;
+          continue;
         }
         else
         {
@@ -9898,7 +9907,7 @@ ha_ndbcluster::read_multi_range_next(KEY
             the order we requested them.
           */
           DBUG_ASSERT(0);
-          multi_range_curr++;                     // Attempt to carry on
+          continue;                     // Attempt to carry on
         }
       }
     }
@@ -9914,11 +9923,9 @@ ha_ndbcluster::read_multi_range_next(KEY
   /*
     Read remaining ranges
   */
-  DBUG_RETURN(read_multi_range_first(multi_range_found_p, 
-                                     multi_range_curr,
-                                     multi_range_end - multi_range_curr, 
-                                     multi_range_sorted,
-                                     multi_range_buffer));
+  if ((res= multi_range_start_retrievals(first_running_range-1)))
+    DBUG_RETURN(res);
+  DBUG_RETURN(multi_range_read_next(range_info));
 }
 
 /*
diff -Nrup a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
--- a/sql/ha_ndbcluster.h	2007-07-10 22:04:25 +02:00
+++ b/sql/ha_ndbcluster.h	2007-07-10 22:55:38 +02:00
@@ -665,7 +665,7 @@ private:
 
   ha_ndbcluster_cond *m_cond;
   bool m_disable_multi_read;
-  uchar *m_multi_range_result_ptr;
+  const uchar *m_multi_range_result_ptr;
   const NdbOperation *m_current_multi_operation;
   Ndb *get_ndb();
 };
Thread
bk commit into 5.2 tree (tomas:1.2539)tomas10 Jul