List:Commits« Previous MessageNext Message »
From:Jan Wedvik Date:September 8 2009 11:39am
Subject:bzr commit into mysql-5.1-telco-7.0-spj branch (jan.wedvik:2970)
View as plain text  
#At file:///export/home2/tmp/jw1159207/mysql/mysql-5.1-telco-7.0-spj/ based on revid:jan.wedvik@stripped

 2970 Jan Wedvik	2009-09-08
      Linked operation sanity test works for simple index scan.

    modified:
      storage/ndb/test/tools/spj_sanity_test.cpp
=== modified file 'storage/ndb/test/tools/spj_sanity_test.cpp'
--- a/storage/ndb/test/tools/spj_sanity_test.cpp	2009-09-08 10:10:23 +0000
+++ b/storage/ndb/test/tools/spj_sanity_test.cpp	2009-09-08 11:39:30 +0000
@@ -6,10 +6,6 @@
 #include <ndb_opts.h>
 #include <NDBT.hpp>
 #include <NdbApi.hpp>
-#include <NdbSleep.h>
-#include <HugoOperations.hpp>
-#include <kernel/signaldata/QueryTree.hpp>
-#include <kernel/AttributeHeader.hpp>
 #include <NdbQueryOperation.hpp>
 #include <NdbQueryBuilder.hpp>
 
@@ -95,16 +91,27 @@ namespace SPJSanityTest{
       m_root->verifyRow();
     }
 
-    Uint32 allocOperationId(){ return m_operationCount++;}
+    Uint32 allocOperationId(){ 
+      return m_operationCount++;
+    }
 
     NdbQueryOperation* getOperation(Uint32 ident) const {
       return m_query->getQueryOperation(ident);
     }
 
-    int getTableSize() const { return m_tableSize; }
+    int getTableSize() const { 
+      return m_tableSize; 
+    }
 
-    const NdbRecord* getNdbRecord() const {return m_ndbRecord;}
+    const NdbRecord* getNdbRecord() const {
+      return m_ndbRecord;
+    }
+
+    const NdbDictionary::Dictionary* getDictionary() const {
+      return m_ndb.getDictionary();
+    }
   private:
+    Ndb& m_ndb;
     NdbQueryBuilder m_builder;
     Operation<Row>* m_root;
     const NdbQueryDef* m_queryDef;
@@ -138,11 +145,30 @@ namespace SPJSanityTest{
     bool* m_rowFound;
   };
 
+  template <typename Row, typename Key>
+  class IndexScanOperation: public Operation<Row>{
+  public:
+    explicit IndexScanOperation(Query<Row>& query,
+                                const char* indexName,
+                                int lowerBoundRowNo, 
+                                int upperBoundRowNo);
+    virtual void verifyOwnRow() const;
+  protected:
+    virtual void buildThis(NdbQueryBuilder& builder, 
+                           const NdbDictionary::Table& tab);
+  private:
+    const char* const m_indexName;
+    const int m_lowerBoundRowNo;
+    const int m_upperBoundRowNo;
+    bool* m_rowFound;
+  };
+
 
   // Query methods.
 
   template <typename Row>
   Query<Row>::Query(Ndb& ndb):
+    m_ndb(ndb),
     m_builder(ndb),
     m_root(NULL),
     m_queryDef(NULL),
@@ -340,7 +366,8 @@ namespace SPJSanityTest{
       if(Row(i) == *Operation<Row>::m_resultPtr){
         found = true;
         if(m_rowFound[i]){
-          ndbout << "Root scan operation: " << *Operation<Row>::m_resultPtr
+          ndbout << "Root table scan operation: " 
+                 << *Operation<Row>::m_resultPtr
                  << "appeared twice." << endl;
           assert(false);
         }
@@ -348,16 +375,91 @@ namespace SPJSanityTest{
       }
     }
     if(!found){
-      ndbout << "Root scan operation. Unexpected row: " 
+      ndbout << "Root table scan operation. Unexpected row: " 
              << *Operation<Row>::m_resultPtr << endl;
       assert(false);
     }else{
-      ndbout << "Root scan operation. Got row: " 
+      ndbout << "Root table scan operation. Got row: " 
              << *Operation<Row>::m_resultPtr
              << " as expected." << endl;
     }
   }
 
+    // IndexScanOperation methods.
+
+  template <typename Row, typename Key>
+  IndexScanOperation<Row, Key>
+  ::IndexScanOperation(Query<Row>& query, 
+                       const char* indexName,
+                       int lowerBoundRowNo, 
+                       int upperBoundRowNo):
+    Operation<Row>(query, NULL),
+    m_indexName(indexName),
+    m_lowerBoundRowNo(lowerBoundRowNo),
+    m_upperBoundRowNo(upperBoundRowNo){
+  }
+
+  template <typename Row, typename Key>
+  void IndexScanOperation<Row, Key>::buildThis(NdbQueryBuilder& builder,
+                                          const NdbDictionary::Table& tab){
+    const NdbDictionary::Dictionary* const dict 
+      = Operation<Row>::m_query.getDictionary();
+    const NdbDictionary::Index* const index
+      = dict->getIndex(m_indexName, tab.getName());
+    assert(index!=NULL);
+
+    const NdbQueryOperand* low[Key::size+1];
+    const NdbQueryOperand* high[Key::size+1];
+    // Code below assume that we use primary key index.
+    assert(strcmp(m_indexName, "PRIMARY")==0);
+    const Key lowKey = Row(m_lowerBoundRowNo).getPrimaryKey();
+    const Key highKey = Row(m_upperBoundRowNo).getPrimaryKey();
+    
+    for(int i = 0; i<Key::size; i++){
+      low[i] = lowKey.makeConstOperand(builder, i);
+      high[i] = highKey.makeConstOperand(builder, i);
+    }
+    low[Key::size+1] = NULL;
+    high[Key::size+1] = NULL;
+
+    const NdbQueryIndexBound bound(low, high);
+    Operation<Row>::m_operationDef = builder.scanIndex(index, &tab, &bound);
+    assert(Operation<Row>::m_operationDef!=NULL);
+    m_rowFound = new bool[Operation<Row>::m_query.getTableSize()];
+    for(int i = 0; i<Operation<Row>::m_query.getTableSize(); i++){
+      m_rowFound[i] = false;
+    }
+  }
+
+  template <typename Row, typename Key>
+  void IndexScanOperation<Row, Key>::verifyOwnRow() const{
+    bool found = false;
+    for(int i = m_lowerBoundRowNo; i<=m_upperBoundRowNo; i++){
+      //const Row row(i);
+      if(Row(i) == *Operation<Row>::m_resultPtr){
+        found = true;
+        if(m_rowFound[i]){
+          ndbout << "Root index scan operation: " 
+                 << *Operation<Row>::m_resultPtr
+                 << "appeared twice." << endl;
+          assert(false);
+        }
+        m_rowFound[i] = true;
+      }
+    }
+    if(!found){
+      ndbout << "Root index scan operation. Unexpected row: " 
+             << *Operation<Row>::m_resultPtr << endl;
+      assert(false);
+    }else{
+      ndbout << "Root index scan operation. Got row: " 
+             << *Operation<Row>::m_resultPtr
+             << " as expected." << endl;
+    }
+  }
+
+  // Misc. functions.
+
   static const char* colName(int colNo){
     static const char* names[] = {
       "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"
@@ -421,6 +523,32 @@ namespace SPJSanityTest{
   }
 
   template <typename Row, typename Key>
+  void testIndexScanWithLookup(MYSQL& mysql, Ndb& ndb, int tableSize){
+    makeTable<Row, Key>(mysql, "tt", tableSize);
+    Query<Row> query(ndb);
+    const int lower = 1;
+    const int upper = tableSize/2;
+    assert(upper>=lower);
+    IndexScanOperation<Row, Key> root(query, "PRIMARY", lower, upper);
+    LookupOperation<Row, Key> child(query, &root);
+    NdbQueryBuilder builder(ndb);
+    NdbDictionary::Dictionary*  const dict = ndb.getDictionary();
+    const NdbDictionary::Table* const tab = dict->getTable("tt");    
+    assert(tab!=NULL);
+    query.build(*tab, tableSize);
+    NdbTransaction* trans = ndb.startTransaction();
+    assert(trans!=NULL);
+    query.submit(*trans);
+    assert(trans->execute(NoCommit)==0);
+    for(int i = 0; i <= upper - lower; i++){
+      assert(query.nextResult()==NdbQuery::NextResult_gotRow);
+      query.verifyRow();
+    }
+    assert(query.nextResult()==NdbQuery::NextResult_scanComplete);
+    ndb.closeTransaction(trans);
+  }
+
+  template <typename Row, typename Key>
   void testTableScanWithLookup(MYSQL& mysql, Ndb& ndb, int tableSize){
     makeTable<Row, Key>(mysql, "tt", tableSize);
     Query<Row> query(ndb);
@@ -451,6 +579,12 @@ namespace SPJSanityTest{
     //static const int keyFieldCount = 2;
     static const int size = 2;
     int m_values[size];
+
+    NdbConstOperand* makeConstOperand(NdbQueryBuilder& builder, 
+                                      int fieldNo) const {
+      assert(fieldNo<size);
+      return builder.constValue(m_values[fieldNo]);
+    }
   };
 
   class RowInt{
@@ -609,7 +743,8 @@ int main(int argc, char** argv){
   
   // FIXME: Running both tests causes the second test to hang in API.
   //testNestedLookup<RowInt, KeyInt>(mysql, ndb, 5);
-  testTableScanWithLookup<RowInt, KeyInt>(mysql, ndb, 5);
+  //testTableScanWithLookup<RowInt, KeyInt>(mysql, ndb, 5);
+  testIndexScanWithLookup<RowInt, KeyInt>(mysql, ndb, 5);
   return 0;
 }
 
@@ -618,7 +753,17 @@ template class Vector<Operation<RowInt>*
 template class Operation<RowInt>;
 template class LookupOperation<RowInt, KeyInt>;
 template class TableScanOperation<RowInt>;
+template class IndexScanOperation<RowInt, KeyInt>;
 template class Query<RowInt>;
-template void makeTable<RowInt, KeyInt>(MYSQL& mysql, const char* name, int rowCount);
-template void testNestedLookup<RowInt, KeyInt>(MYSQL& mysql, Ndb& ndb, int tableSize);
-template void testTableScanWithLookup<RowInt, KeyInt>(MYSQL& mysql, Ndb& ndb, int tableSize);
+template void makeTable<RowInt, KeyInt>(MYSQL& mysql, 
+                                        const char* name, 
+                                        int rowCount);
+template void testNestedLookup<RowInt, KeyInt>(MYSQL& mysql, 
+                                               Ndb& ndb, 
+                                               int tableSize);
+template void testTableScanWithLookup<RowInt, KeyInt>(MYSQL& mysql, 
+                                                      Ndb& ndb, 
+                                                      int tableSize);
+template void testIndexScanWithLookup<RowInt, KeyInt>(MYSQL& mysql, 
+                                                      Ndb& ndb, 
+                                                      int tableSize);


Attachment: [text/bzr-bundle] bzr/jan.wedvik@sun.com-20090908113930-m9ca88qczo4rvjbf.bundle
Thread
bzr commit into mysql-5.1-telco-7.0-spj branch (jan.wedvik:2970) Jan Wedvik8 Sep