List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:July 3 2009 11:54am
Subject:bzr commit into mysql-5.1-telco-7.0-spj branch (ole.john.aske:2908)
View as plain text  
#At file:///home/oa136780/mysql/mysql-5.1-telco-7.0-spj/ based on revid:jan.wedvik@stripped

 2908 Ole John Aske	2009-07-03
      - Implemented semantic check for ::scanIndex() + example code

    modified:
      storage/ndb/include/ndbapi/NdbQueryBuilder.hpp
      storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp
      storage/ndb/src/ndbapi/NdbQueryBuilder.cpp
      storage/ndb/src/ndbapi/ndberror.c
=== modified file 'storage/ndb/include/ndbapi/NdbQueryBuilder.hpp'
--- a/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp	2009-07-02 14:21:25 +0000
+++ b/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp	2009-07-03 09:53:56 +0000
@@ -99,15 +99,6 @@ protected:
 };
 
 
-class NdbQueryIndexBound
-{
-public:
-  const NdbQueryOperand* const *low_key;  // 'Pointer to array of pointers', NULL terminated
-  bool low_inclusive;
-  const NdbQueryOperand* const *high_key; // 'Pointer to array of pointers', NULL terminated
-  bool high_inclusive;
-};
-
 
 /**
  * NdbQueryOperationDef defines an operation on a single NDB table
@@ -181,6 +172,40 @@ protected:
 }; // class NdbQueryIndexScanOperationDef
 
 
+/**
+ * class NdbQueryIndexBound is an argument container for defining
+ * a NdbQueryIndexScanOperationDef.
+ * The contents of this object is copied into the
+ * NdbQueryIndexScanOperationDef and does not have to be 
+ * persistent after the NdbQueryBuilder::scanIndex() call
+ */
+class NdbQueryIndexBound
+{
+public:
+  // C'tor for an equal bound:
+  NdbQueryIndexBound(const NdbQueryOperand* const *eqKey)
+   : m_low(eqKey), m_lowInclusive(true), m_high(eqKey), m_highInclusive(true)
+  {};
+
+  // C'tor for a normal range including low & high limit:
+  NdbQueryIndexBound(const NdbQueryOperand* const *low,
+                     const NdbQueryOperand* const *high)
+   : m_low(low), m_lowInclusive(true), m_high(high), m_highInclusive(true)
+  {};
+
+  // Complete C'tor where limits might be exluded:
+  NdbQueryIndexBound(const NdbQueryOperand* const *low,  bool lowIncl,
+                     const NdbQueryOperand* const *high, bool highIncl)
+   : m_low(low), m_lowInclusive(lowIncl), m_high(high), m_highInclusive(highIncl)
+  {}
+
+private:
+  friend class NdbQueryIndexScanOperationDefImpl;
+  const NdbQueryOperand* const *m_low;  // 'Pointer to array of pointers', NULL terminated
+  const bool m_lowInclusive;
+  const NdbQueryOperand* const *m_high; // 'Pointer to array of pointers', NULL terminated
+  const bool m_highInclusive;
+};
 
 
 /**

=== modified file 'storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp'
--- a/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp	2009-06-30 13:01:58 +0000
+++ b/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp	2009-07-03 09:53:56 +0000
@@ -481,6 +481,38 @@ int testQueryBuilder(Ndb &myNdb)
     if (q5 == NULL) APIERROR(qb->getNdbError());
   }
 
+  // Example: ::readTuple() using Index for unique key lookup
+  printf("q6\n");
+
+  NdbQueryDef* q6 = 0;
+  {
+    NdbQueryBuilder* qb = &myBuilder; //myDict->getQueryBuilder();
+
+    // Lookup Primary key for manager table
+    const NdbDictionary::Index *myPIndex= myDict->getIndex("PRIMARY", manager->getName());
+    if (myPIndex == NULL)
+      APIERROR(myDict->getNdbError());
+
+    const NdbQueryOperand* low[] =  // Manager PK index is {"emp_no","dept_no", }
+    {  qb->constValue(110567),      // emp_no  = 110567
+       0
+    };
+    const NdbQueryOperand* high[] =  // Manager PK index is {"emp_no","dept_no", }
+    {  qb->constValue("illegal key"),
+       0
+    };
+    const NdbQueryIndexBound  bound        (low, NULL);   // emp_no = [110567, oo]
+    const NdbQueryIndexBound  bound_illegal(low, high);   // 'high' is char type -> illegal
+    const NdbQueryIndexBound  boundEq(low);
+
+    // Lookup on a single tuple with key define by 'managerKey' param. tuple
+    const NdbQueryScanOperationDef* scanManager = qb->scanIndex(myPIndex, manager, &boundEq);
+    if (scanManager == NULL) APIERROR(qb->getNdbError());
+
+    q6 = qb->prepare();
+    if (q6 == NULL) APIERROR(qb->getNdbError());
+  }
+
   return 0;
 }
 

=== modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp	2009-07-02 14:21:25 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp	2009-07-03 09:53:56 +0000
@@ -95,7 +95,9 @@ public:
 
   virtual int bindOperand(const NdbDictionary::Column* column,
                           NdbQueryOperationDef* operation)
-  { m_column = column;
+  { if (m_column  && m_column != column)
+      return 4807;  // Already bounded to a different column
+    m_column = column;
     return 0;
   }
   
@@ -296,27 +298,22 @@ public:
 private:
   virtual ~NdbQueryLookupOperationDefImpl() {};
   NdbQueryLookupOperationDefImpl (
+                           const NdbDictionary::Index* index,
                            const NdbDictionary::Table* table,
                            const NdbQueryOperand* const keys[],
                            const char* ident,
-                           Uint32      ix)
-   : NdbQueryLookupOperationDef(this), NdbQueryOperationDefImpl(table,ident,ix),
-     m_index(0), m_keys(keys)
-  {};
+                           Uint32      ix);
   NdbQueryLookupOperationDefImpl (
-                           const NdbDictionary::Index* index,
                            const NdbDictionary::Table* table,
                            const NdbQueryOperand* const keys[],
                            const char* ident,
-                           Uint32      ix)
-   : NdbQueryLookupOperationDef(this), NdbQueryOperationDefImpl(table,ident,ix),
-     m_index(index), m_keys(keys)
-  {};
+                           Uint32      ix);
   
 private:
   virtual void updateSPJProjection(NdbQueryOperationDefImpl& parent) const;
   const NdbDictionary::Index* const m_index;
-  const NdbQueryOperand* const *m_keys;
+  const NdbQueryOperand* m_keys[MAX_ATTRIBUTES_IN_INDEX+1];
+
 }; // class NdbQueryLookupOperationDefImpl
 
 
@@ -375,10 +372,7 @@ private:
                            const NdbDictionary::Table* table,
                            const NdbQueryIndexBound* bound,
                            const char* ident,
-                           Uint32      ix)
-  : NdbQueryIndexScanOperationDef(this), NdbQueryScanOperationDefImpl(table,ident,ix),
-    m_index(index), m_bound(bound)
-  {};
+                           Uint32      ix);
 
   virtual void updateSPJProjection(NdbQueryOperationDefImpl& parent) const {
     // TODO: implement this;
@@ -386,7 +380,13 @@ private:
   }
 private:
   const NdbDictionary::Index* const m_index;
-  const NdbQueryIndexBound* const m_bound;
+//const NdbQueryIndexBound* const m_bound;
+  struct bound {  // Limiting 'bound ' definition
+    const NdbQueryOperand* low[MAX_ATTRIBUTES_IN_INDEX+1];
+    const NdbQueryOperand* high[MAX_ATTRIBUTES_IN_INDEX+1];
+    bool lowIncl, highIncl;
+    bool eqBound;  // True if 'low == high'
+  } m_bound;
 }; // class NdbQueryIndexScanOperationDefImpl
 
 
@@ -835,7 +835,7 @@ NdbQueryBuilder::scanIndex(const NdbDict
 {
   if (m_pimpl->hasError())
     return NULL;
-  returnErrIf(table==0 || index==0 || bound==0, 4800);  // Required non-NULL arguments
+  returnErrIf(table==0 || index==0, 4800);  // Required non-NULL arguments
 
   // TODO: Restrict to only table_version_major() mismatch?
   returnErrIf(NdbIndexImpl::getImpl(*index).m_table_id != table->getObjectId() ||
@@ -846,6 +846,36 @@ NdbQueryBuilder::scanIndex(const NdbDict
                                           m_pimpl->m_operations.size());
   returnErrIf(op==0, 4000);
 
+  int i;
+  int inxfields = index->getNoOfColumns();
+  for (i=0; i<inxfields; ++i)
+  {
+    if (op->m_bound.low[i] == NULL)
+      break;
+    const NdbDictionary::Column *col = index->getColumn(i);
+    int error = op->m_bound.low[i]->getImpl().bindOperand(col,op);
+    if (unlikely(error))
+    { m_pimpl->setErrorCode(error);
+      delete op;
+      return NULL;
+    }
+  }
+  if (!op->m_bound.eqBound)
+  {
+    for (i=0; i<inxfields; ++i)
+    {
+      if (op->m_bound.high[i] == NULL)
+        break;
+      const NdbDictionary::Column *col = index->getColumn(i);
+      int error = op->m_bound.high[i]->getImpl().bindOperand(col,op);
+      if (unlikely(error))
+      { m_pimpl->setErrorCode(error);
+        delete op;
+        return NULL;
+      }
+    }
+  }
+
   m_pimpl->m_operations.push_back(op);
   return op;
 }
@@ -950,6 +980,85 @@ NdbQueryDefImpl::~NdbQueryDefImpl()
 }
 
 
+NdbQueryLookupOperationDefImpl::NdbQueryLookupOperationDefImpl (
+                           const NdbDictionary::Table* table,
+                           const NdbQueryOperand* const keys[],
+                           const char* ident,
+                           Uint32      ix)
+ : NdbQueryLookupOperationDef(this), NdbQueryOperationDefImpl(table,ident,ix),
+   m_index(0)
+{
+  int i;
+  for (i=0; i<=MAX_ATTRIBUTES_IN_INDEX; ++i)
+  { m_keys[i] = keys[i];
+    if (m_keys[i] == NULL)
+      break;
+  }
+  assert (m_keys[i] == NULL);
+}
+
+NdbQueryLookupOperationDefImpl::NdbQueryLookupOperationDefImpl (
+                           const NdbDictionary::Index* index,
+                           const NdbDictionary::Table* table,
+                           const NdbQueryOperand* const keys[],
+                           const char* ident,
+                           Uint32      ix)
+ : NdbQueryLookupOperationDef(this), NdbQueryOperationDefImpl(table,ident,ix),
+   m_index(index)
+{
+  int i;
+  for (i=0; i<=MAX_ATTRIBUTES_IN_INDEX; ++i)
+  { m_keys[i] = keys[i];
+    if (m_keys[i] == NULL)
+      break;
+  }
+  assert (m_keys[i] == NULL);
+}
+
+
+NdbQueryIndexScanOperationDefImpl::NdbQueryIndexScanOperationDefImpl (
+                           const NdbDictionary::Index* index,
+                           const NdbDictionary::Table* table,
+                           const NdbQueryIndexBound* bound,
+                           const char* ident,
+                           Uint32      ix)
+: NdbQueryIndexScanOperationDef(this), NdbQueryScanOperationDefImpl(table,ident,ix),
+  m_index(index), m_bound()
+{
+  if (bound!=NULL) {
+
+    if (bound->m_low!=NULL) {
+      int i;
+      for (i=0; i<=MAX_ATTRIBUTES_IN_INDEX; ++i)
+      { m_bound.low[i] = bound->m_low[i];
+        if (m_bound.low[i] == NULL)
+          break;
+      }
+      assert (m_bound.low[i] == NULL);
+    }
+    if (bound->m_high!=NULL) {
+      int i;
+      for (i=0; i<=MAX_ATTRIBUTES_IN_INDEX; ++i)
+      { m_bound.high[i] = bound->m_high[i];
+        if (m_bound.high[i] == NULL)
+          break;
+      }
+      assert (m_bound.high[i] == NULL);
+    }
+    m_bound.lowIncl = bound->m_lowInclusive;
+    m_bound.highIncl = bound->m_highInclusive;
+    m_bound.eqBound = (bound->m_low==bound->m_high && bound->m_low!=NULL);
+  }
+  else {
+    m_bound.low[0] = NULL;
+    m_bound.high[0] = NULL;
+    m_bound.lowIncl = true;
+    m_bound.highIncl = true;
+    m_bound.eqBound = false;
+  }
+}
+
+
 void
 NdbQueryOperationDefImpl::addParent(const NdbQueryOperationDef *opDef)
 {

=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c	2009-06-30 13:01:58 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c	2009-07-03 09:53:56 +0000
@@ -731,6 +731,7 @@ ErrorBundle ErrorCodes[] = {
   { 4804, DMEC, AE, "Unknown 'parent' specified in linkedValue" },
   { 4805, DMEC, AE, "Unknown 'column' specified in linkedValue" },
   { 4806, DMEC, AE, "Specified 'index' does not belong to specified 'table'" },
+  { 4807, DMEC, AE, "Can't use same operand value to specify different column values" },
 
 
   { NO_CONTACT_WITH_PROCESS, DMEC, AE,


Attachment: [text/bzr-bundle] bzr/ole.john.aske@sun.com-20090703095356-5rj54t60j2cyu8iu.bundle
Thread
bzr commit into mysql-5.1-telco-7.0-spj branch (ole.john.aske:2908) Ole John Aske4 Jul