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

 2971 Jan Wedvik	2009-09-09
      Linked operation sanity test works for simple index lookup.

    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 11:39:30 +0000
+++ b/storage/ndb/test/tools/spj_sanity_test.cpp	2009-09-09 07:04:51 +0000
@@ -17,6 +17,14 @@
 
 namespace SPJSanityTest{
 
+  static const char* colName(int colNo){
+    static const char* names[] = {
+      "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"
+    };
+    assert(static_cast<unsigned int>(colNo)< sizeof names/sizeof names[0]);
+    return names[colNo];
+  };
+  
   static void printMySQLError(MYSQL& mysql, const char* before=NULL){
     if(before!=NULL){
       ndbout << before;
@@ -133,6 +141,20 @@ namespace SPJSanityTest{
                            const NdbDictionary::Table& tab);
   };
 
+  template <typename Row, typename Key>
+  class IndexLookupOperation: public Operation<Row>{
+  public:
+    explicit IndexLookupOperation(Query<Row>& query, 
+                                  const char* indexName,
+                                  Operation<Row>* parent = NULL);
+    virtual void verifyOwnRow() const;
+  protected:
+    virtual void buildThis(NdbQueryBuilder& builder, 
+                           const NdbDictionary::Table& tab);
+  private:
+    const char* const m_indexName;
+  };
+
   template <typename Row>
   class TableScanOperation: public Operation<Row>{
   public:
@@ -292,18 +314,26 @@ namespace SPJSanityTest{
   template <typename Row, typename Key>
   void LookupOperation<Row, Key>::buildThis(NdbQueryBuilder& builder,
                                             const NdbDictionary::Table& tab){
-    //const Uint32 size = Operation<Row>::m_children.size();
-    //assert(size<);
-    NdbQueryOperand* key[Key::size+1];
+    NdbQueryOperand* keyOperands[Key::size+1];
     if(Operation<Row>::m_parent==NULL){
-      Row(0).makeConstKey(builder, key);
+      const Key key = Row(0).getPrimaryKey();
+      NdbQueryOperand* keyOperands[Key::size+1];
+      for(int i = 0; i<Key::size; i++){
+        keyOperands[i] = key.makeConstOperand(builder, i);
+      }
     }else{
-      Row::makeLinkedKey(builder, key, 
+      for(int i = 0; i<Key::size; i++){
+        keyOperands[i] = 
+          builder.linkedValue(Operation<Row>::m_parent->m_operationDef, 
+                              colName(Row::getForeignKeyColNo(Operation<Row>::m_childNo, i)));
+        assert(keyOperands[i]!=NULL);
+        /*Row::makeLinkedKey(builder, keyOperands, 
                          Operation<Row>::m_parent->m_operationDef, 
-                         Operation<Row>::m_childNo);
+                         Operation<Row>::m_childNo);*/
+      }
     }
-    key[Key::size] = NULL;
-    Operation<Row>::m_operationDef = builder.readTuple(&tab, key);
+    keyOperands[Key::size] = NULL;
+    Operation<Row>::m_operationDef = builder.readTuple(&tab, keyOperands);
   }
 
   template <typename Row, typename Key>
@@ -340,6 +370,85 @@ namespace SPJSanityTest{
     }
   }
 
+  // IndexLookupOperation methods.
+
+  template <typename Row, typename Key>
+  IndexLookupOperation<Row, Key>
+  ::IndexLookupOperation(Query<Row>& query, 
+                         const char* indexName, 
+                         Operation<Row>* parent):
+    Operation<Row>(query, parent),
+    m_indexName(indexName){
+  }
+
+  template <typename Row, typename Key>
+  void IndexLookupOperation<Row, Key>
+  ::buildThis(NdbQueryBuilder& builder,
+              const NdbDictionary::Table& tab){
+    const NdbDictionary::Dictionary* const dict 
+      = Operation<Row>::m_query.getDictionary();
+    char fullName[200];
+    sprintf(fullName, "%s$unique", m_indexName);
+    const NdbDictionary::Index* const index
+      = dict->getIndex(fullName, tab.getName());
+    assert(index!=NULL);
+
+    NdbQueryOperand* keyOperands[Key::size+1];
+    if(Operation<Row>::m_parent==NULL){
+      const Key key = Row(0).getIndexKey();
+      for(int i = 0; i<Key::size; i++){
+        keyOperands[i] = key.makeConstOperand(builder, i);
+      }
+    }else{
+      for(int i = 0; i<Key::size; i++){
+        keyOperands[i] = 
+          builder.linkedValue(Operation<Row>::m_parent->m_operationDef,
+                              colName(Row::getForeignKeyColNo(0, i)));
+        assert(keyOperands[i]!=NULL);
+      }
+      /*Row::makeLinkedKey(builder, keyOperands, 
+                         Operation<Row>::m_parent->m_operationDef, 
+                         Operation<Row>::m_childNo);*/
+    }
+    keyOperands[Key::size] = NULL;
+    Operation<Row>::m_operationDef = builder.readTuple(index, 
+                                                       &tab, 
+                                                       keyOperands);
+  }
+
+  template <typename Row, typename Key>
+  void IndexLookupOperation<Row, Key>::verifyOwnRow() const{
+    if(Operation<Row>::m_parent==NULL){
+      const Row expected(0);
+      Operation<Row>::compareRows("index lookup root operation",
+                                  &expected, 
+                                  Operation<Row>::m_resultPtr);
+    }else{
+      NdbQueryOperation* queryOp 
+        = Operation<Row>::m_query
+        .getOperation(Operation<Row>::m_operationId);
+      if(!queryOp->getParentOperation(0)->isRowNULL()){
+        const Key key = 
+          Operation<Row>::m_parent->m_resultPtr->getForeignKey(0);
+        bool found = false;
+        for(int i = 0; i<Operation<Row>::m_query.getTableSize(); i++){
+          const Row row(i);
+          if(row.getIndexKey() == key){
+            found = true;
+            Operation<Row>::compareRows("index lookup child operation",
+                                        &row, 
+                                        Operation<Row>::m_resultPtr);
+          }
+        }
+        if(!found && !queryOp->isRowNULL()){
+          Operation<Row>::compareRows("index lookup child operation",
+                                      NULL,
+                                      Operation<Row>::m_resultPtr);
+        }
+      }
+    }
+  }
+
   // TableScanOperation methods.
 
   template <typename Row>
@@ -401,7 +510,7 @@ namespace SPJSanityTest{
 
   template <typename Row, typename Key>
   void IndexScanOperation<Row, Key>::buildThis(NdbQueryBuilder& builder,
-                                          const NdbDictionary::Table& tab){
+                                               const NdbDictionary::Table& tab){
     const NdbDictionary::Dictionary* const dict 
       = Operation<Row>::m_query.getDictionary();
     const NdbDictionary::Index* const index
@@ -460,14 +569,6 @@ namespace SPJSanityTest{
 
   // Misc. functions.
 
-  static const char* colName(int colNo){
-    static const char* names[] = {
-      "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"
-    };
-    assert(static_cast<unsigned int>(colNo)< sizeof names/sizeof names[0]);
-    return names[colNo];
-  };
-  
   template <typename Row, typename Key>
   void makeTable(MYSQL& mysql, const char* name, int rowCount){
     char cmd[500];
@@ -485,6 +586,15 @@ namespace SPJSanityTest{
       if(i<Key::size - 1){
         strcat(cmd, ",");
       }else{
+        strcat(cmd, "),\n");
+      }
+    }
+    strcat(cmd, "   UNIQUE KEY UIX (");
+    for(int i = 0; i<Key::size; i++){
+      strcat(cmd, colName(Row::getIndexKeyColNo(i)));
+      if(i<Key::size - 1){
+        strcat(cmd, ",");
+      }else{
         strcat(cmd, "))\n");
       }
     }
@@ -523,6 +633,27 @@ namespace SPJSanityTest{
   }
 
   template <typename Row, typename Key>
+  void testIndexLookup(MYSQL& mysql, Ndb& ndb, int tableSize){
+    makeTable<Row, Key>(mysql, "tt", tableSize);
+    Query<Row> query(ndb);
+    IndexLookupOperation<Row, Key> root(query, "UIX");
+    IndexLookupOperation<Row, Key> child(query, "UIX", &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);
+    assert(query.nextResult() ==  NdbQuery::NextResult_gotRow);
+    query.verifyRow();
+    assert(query.nextResult() ==  NdbQuery::NextResult_scanComplete);
+    ndb.closeTransaction(trans);
+  }
+
+  template <typename Row, typename Key>
   void testIndexScanWithLookup(MYSQL& mysql, Ndb& ndb, int tableSize){
     makeTable<Row, Key>(mysql, "tt", tableSize);
     Query<Row> query(ndb);
@@ -592,6 +723,7 @@ namespace SPJSanityTest{
     static const int size = 4;
     //static const int keySize = 2;
 
+#ifdef UNUSED
     static void makeLinkedKey(NdbQueryBuilder& builder, 
                               NdbQueryOperand* key[size],
                               const NdbQueryOperationDef* parent,
@@ -603,6 +735,7 @@ namespace SPJSanityTest{
         assert(key[i] != NULL);
       }
     }
+#endif
 
     int m_values[size];
 
@@ -615,13 +748,15 @@ namespace SPJSanityTest{
     static const char *getType(int colNo){
       return "INT";
     }
-    
+   
+#ifdef UNUSED 
     void makeConstKey(NdbQueryBuilder& builder, NdbQueryOperand* key[size]){
       for(int i = 0; i<KeyInt::size; i++){
         key[i] = builder.constValue(m_values[i]);
         assert(key[i] != NULL);
       }
     }
+#endif
 
     static void makeSQLValues(char* buffer, int rowNo){
       const RowInt row(rowNo);
@@ -639,7 +774,13 @@ namespace SPJSanityTest{
 
     KeyInt getPrimaryKey() const;
     
+    KeyInt getIndexKey() const;
+    
     KeyInt getForeignKey(int keyNo) const;
+
+    static int getIndexKeyColNo(int indexCol);
+
+    static int getForeignKeyColNo(int keyNo, int keyCol);
   };
 
   KeyInt RowInt::getPrimaryKey() const {
@@ -647,12 +788,27 @@ namespace SPJSanityTest{
     return key;
   }
 
+  KeyInt RowInt::getIndexKey() const {
+    return getForeignKey(1);
+  }
+
   KeyInt RowInt::getForeignKey(int keyNo) const {
     assert(keyNo<=1);
-    const KeyInt key = {m_values[2-keyNo], m_values[3-keyNo]};
+    const KeyInt key = {m_values[getForeignKeyColNo(keyNo, 0)], 
+                        m_values[getForeignKeyColNo(keyNo, 1)]};
     return key;
   }
 
+  int RowInt::getIndexKeyColNo(int indexCol){
+    return getForeignKeyColNo(1, indexCol);
+  }
+
+  int RowInt::getForeignKeyColNo(int keyNo, int keyCol){
+    assert(keyNo<RowInt::size-KeyInt::size);
+    assert(keyCol<KeyInt::size);
+    return size-KeyInt::size-keyNo+keyCol;
+  }
+
   bool operator==(const RowInt& a, const RowInt& b){
     for(int i = 0; i<RowInt::size; i++){
       if(a.m_values[i]!=b.m_values[i]){
@@ -743,8 +899,9 @@ int main(int argc, char** argv){
   
   // FIXME: Running both tests causes the second test to hang in API.
   //testNestedLookup<RowInt, KeyInt>(mysql, ndb, 5);
+  testIndexLookup<RowInt, KeyInt>(mysql, ndb, 5);
   //testTableScanWithLookup<RowInt, KeyInt>(mysql, ndb, 5);
-  testIndexScanWithLookup<RowInt, KeyInt>(mysql, ndb, 5);
+  //testIndexScanWithLookup<RowInt, KeyInt>(mysql, ndb, 5);
   return 0;
 }
 
@@ -752,6 +909,7 @@ int main(int argc, char** argv){
 template class Vector<Operation<RowInt>*>;
 template class Operation<RowInt>;
 template class LookupOperation<RowInt, KeyInt>;
+template class IndexLookupOperation<RowInt, KeyInt>;
 template class TableScanOperation<RowInt>;
 template class IndexScanOperation<RowInt, KeyInt>;
 template class Query<RowInt>;
@@ -761,6 +919,9 @@ template void makeTable<RowInt, KeyInt>(
 template void testNestedLookup<RowInt, KeyInt>(MYSQL& mysql, 
                                                Ndb& ndb, 
                                                int tableSize);
+template void testIndexLookup<RowInt, KeyInt>(MYSQL& mysql, 
+                                              Ndb& ndb, 
+                                              int tableSize);
 template void testTableScanWithLookup<RowInt, KeyInt>(MYSQL& mysql, 
                                                       Ndb& ndb, 
                                                       int tableSize);


Attachment: [text/bzr-bundle] bzr/jan.wedvik@sun.com-20090909070451-tz7jh17yjq2orucy.bundle
Thread
bzr commit into mysql-5.1-telco-7.0-spj branch (jan.wedvik:2971) Jan Wedvik9 Sep