#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 Aske | 4 Jul |