List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:August 16 2011 1:43pm
Subject:bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch
(ole.john.aske:3534 to 3535)
View as plain text  
 3535 Ole John Aske	2011-08-16 [merge]
      Merge

    modified:
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
 3534 Ole John Aske	2011-08-16 [merge]
      Merge

    modified:
      mysql-test/r/group_by.result
      mysql-test/t/group_by.test
      sql/sql_select.cc
      storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
      storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
      storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2011-08-16 13:33:13 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2011-08-16 13:42:49 +0000
@@ -247,6 +247,16 @@ public:
    */
   bool isEmpty() const;
 
+  /** 
+   * This method is used for marking which streams belonging to this
+   * NdbRootFragment which has remaining batches for a sub scan
+   * instantiated from the current batch of its parent operation.
+   */
+  void setRemainingSubScans(Uint32 nodeMask)
+  { 
+    m_remainingScans = nodeMask;
+  }
+
   /** Release resources after last row has been returned */
   void postFetchRelease();
 
@@ -280,6 +290,12 @@ private:
    * TCKEYCONF message has been received */
   bool m_confReceived;
 
+  /**
+   * A bitmask of operation id's for which we will receive more
+   * ResultSets in a NEXTREQ.
+   */
+  Uint32 m_remainingScans;
+
   /** 
    * Used for implementing a hash map from root receiver ids to a 
    * NdbRootFragment instance. m_idMapHead is the index of the first
@@ -353,7 +369,7 @@ public:
    * Update whatever required before the appl. are allowed to navigate the result.
    * @return true if node and all its siblings have returned all rows.
    */ 
-  bool prepareResultSet();
+  bool prepareResultSet(Uint32 remainingScans);
 
   /**
    * Navigate within the current result batch to resp. first and next row.
@@ -373,29 +389,23 @@ public:
   { return m_iterState == Iter_finished; }
 
   /** 
-   * This method is
-   * used for marking a stream as holding the last batch of a sub scan. 
-   * This means that it is the last batch of the scan that was instantiated 
-   * from the current batch of its parent operation.
-   */
-  void setSubScanCompletion(bool complete)
-  { 
-    // Lookups should always be 'complete'
-    assert(complete || isScanResult());
-    m_subScanComplete = complete; 
-  }
-
-  /** 
    * This method 
-   * returns true if this result stream holds the last batch of a sub scan
+   * returns true if this result stream holds the last batch of a sub scan.
    * This means that it is the last batch of the scan that was instantiated 
    * from the current batch of its parent operation.
    */
-  bool isSubScanComplete() const
+  bool isSubScanComplete(Uint32 remainingScans) const
   { 
-    // Lookups should always be 'complete'
-    assert(m_subScanComplete || isScanResult());
-    return m_subScanComplete; 
+    /**
+     * Find the node number seen by the SPJ block. Since a unique index
+     * operation will have two distincts nodes in the tree used by the
+     * SPJ block, this number may be different from 'opNo'.
+     */
+    const Uint32 internalOpNo = m_operation.getQueryOperationDef().getQueryOperationId();
+
+    const bool complete = !((remainingScans >> internalOpNo) & 1);
+    assert(complete || isScanResult());    // Lookups should always be 'complete'
+    return complete; 
   }
 
   bool isScanQuery() const
@@ -508,14 +518,6 @@ private:
    */
   Uint16 m_currentRow;
   
-  /** 
-   * This field is only used for result streams of scan operations. If set,
-   * it indicates that the stream is holding the last batch of a sub scan. 
-   * This means that it is the last batch of the scan that was instantiated 
-   * from the current batch of its parent operation.
-   */
-  bool m_subScanComplete;
-
   /** Max #rows which this stream may recieve in its TupleSet structures */
   Uint32 m_maxRows;
 
@@ -611,7 +613,6 @@ NdbResultStream::NdbResultStream(NdbQuer
   m_rowCount(0),
   m_iterState(Iter_notStarted),
   m_currentRow(tupleNotFound),
-  m_subScanComplete(true),
   m_maxRows(0),
   m_tupleSet(NULL)
 {};
@@ -827,10 +828,10 @@ NdbResultStream::execTRANSID_AI(const Ui
  *    rows.
  */
 bool 
-NdbResultStream::prepareResultSet()
+NdbResultStream::prepareResultSet(Uint32 remainingScans)
 {
-  bool isComplete = isSubScanComplete();  //Childs with more rows
-  assert(isComplete || isScanResult());   //Lookups always 'complete'
+  bool isComplete = isSubScanComplete(remainingScans); //Childs with more rows
+  assert(isComplete || isScanResult());                //Lookups always 'complete'
 
   // Set correct #rows received in the NdbReceiver.
   getReceiver().m_result_rows = getRowCount();
@@ -866,7 +867,7 @@ NdbResultStream::prepareResultSet()
   {
     const NdbQueryOperationImpl& child = m_operation.getChildOperation(childNo);
     NdbResultStream& childStream = m_rootFrag.getResultStream(child);
-    const bool allSubScansComplete = childStream.prepareResultSet();
+    const bool allSubScansComplete = childStream.prepareResultSet(remainingScans);
 
     Uint32 childId = child.getQueryOperationDef().getQueryOperationIx();
 
@@ -1035,6 +1036,7 @@ NdbRootFragment::NdbRootFragment():
   m_resultStreams(NULL),
   m_outstandingResults(0),
   m_confReceived(false),
+  m_remainingScans(0),
   m_idMapHead(-1),
   m_idMapNext(-1)
 {
@@ -1097,13 +1099,25 @@ void NdbRootFragment::reset()
   assert(m_fragNo!=voidFragNo);
   assert(m_outstandingResults == 0);
   assert(m_confReceived);
+
+  for (unsigned opNo=0; opNo<m_query->getNoOfOperations(); opNo++) 
+  {
+    if (!m_resultStreams[opNo].isSubScanComplete(m_remainingScans))
+    {
+      /**
+       * Reset m_resultStreams[] and all its descendants, since all these
+       * streams will get a new set of rows in the next batch.
+       */ 
+      m_resultStreams[opNo].reset();
+    }
+  }
   m_confReceived = false;
 }
 
 void NdbRootFragment::prepareResultSet()
 {
   NdbResultStream& rootStream = getResultStream(0);
-  rootStream.prepareResultSet();  
+  rootStream.prepareResultSet(m_remainingScans);  
 
   /* Position at the first (sorted?) row available from this fragments.
    */
@@ -3004,21 +3018,6 @@ NdbQueryImpl::sendFetchMore(NdbRootFragm
 
   emptyFrag.reset();
 
-  for (unsigned opNo=0; opNo<m_countOperations; opNo++) 
-  {
-    NdbResultStream& resultStream = 
-       emptyFrag.getResultStream(opNo);
-
-    if (!resultStream.isSubScanComplete())
-    {
-      /**
-       * Reset resultstream and all its descendants, since all these
-       * streams will get a new set of rows in the next batch.
-       */ 
-      resultStream.reset();
-    }
-  }
-
   Ndb& ndb = *getNdbTransaction().getNdb();
   NdbApiSignal tSignal(&ndb);
   tSignal.setSignal(GSN_SCAN_NEXTREQ, refToBlock(m_scanTransaction->m_tcRef));
@@ -4798,6 +4797,7 @@ NdbQueryOperationImpl::execSCAN_TABCONF(
     return false;
   }
   rootFrag->setConfReceived();
+  rootFrag->setRemainingSubScans(nodeMask);
   rootFrag->incrOutstandingResults(rowCount);
 
   // Handle for SCAN_NEXTREQ, RNIL -> EOF
@@ -4810,31 +4810,6 @@ NdbQueryOperationImpl::execSCAN_TABCONF(
            << endl;
   }
 
-  const NdbQueryDefImpl& queryDef = m_queryImpl.getQueryDef();
-  /* Mark each scan node to indicate if the current batch is the last in the
-   * current sub-scan or not.
-   */
-  for (Uint32 opNo = 0; opNo < queryDef.getNoOfOperations(); opNo++)
-  {
-    const NdbQueryOperationImpl& op = m_queryImpl.getQueryOperation(opNo);
-    /**
-     * Find the node number seen by the SPJ block. Since a unique index
-     * operation will have two distincts nodes in the tree used by the
-     * SPJ block, this number may be different from 'opNo'.
-     */
-    const Uint32 internalOpNo = op.getQueryOperationDef().getQueryOperationId();
-    assert(internalOpNo >= opNo);
-    const bool complete = ((nodeMask >> internalOpNo) & 1) == 0;
-
-    // Lookups should always be 'complete'
-    assert(complete ||  op.getQueryOperationDef().isScanOperation());
-    rootFrag->getResultStream(opNo).setSubScanCompletion(complete);
-  }
-  // Check that nodeMask does not have more bits than we have operations. 
-  assert(nodeMask >> 
-         (1+queryDef.getQueryOperation(queryDef.getNoOfOperations() - 1)
-          .getQueryOperationId()) == 0);
-
   bool ret = false;
   if (rootFrag->isFragBatchComplete())
   {

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch(ole.john.aske:3534 to 3535) Ole John Aske17 Aug