#At file:///export/home2/tmp/jw1159207/mysql/mysql-5.1-telco-7.0-spj/ based on revid:jan.wedvik@stripped
2936 Jan Wedvik 2009-07-24 [merge]
Merged from bk-internal.mysql.com/bzrroot/server/mysql-5.1-telco-7.0-spj/ branch.
modified:
storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp
storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
storage/ndb/src/ndbapi/NdbQueryBuilder.cpp
storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp
storage/ndb/src/ndbapi/NdbQueryOperation.cpp
storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp
storage/ndb/src/ndbapi/Ndbif.cpp
=== modified file 'storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp'
--- a/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp 2009-07-13 11:15:51 +0000
+++ b/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp 2009-07-24 08:55:33 +0000
@@ -53,7 +53,7 @@
/**
* Define NDB_CONNECT_STRING if you don't connect through the default localhost:1186
*/
- #define NDB_CONNECT_STRING "loki43:2360"
+ #define NDB_CONNECT_STRING "127.0.0.1:2360"
/*****************************************************
@@ -89,6 +89,7 @@ struct SalaryRow
const char* employeeDef =
"CREATE TABLE employees ("
" emp_no INT NOT NULL,"
+" dept_no INT NOT NULL," // Temporary added OJA
" birth_date DATE NOT NULL,"
" first_name VARCHAR(14) NOT NULL,"
" last_name VARCHAR(16) NOT NULL,"
@@ -107,7 +108,7 @@ const char* departmentsDef =
const char* dept_managerDef =
"CREATE TABLE dept_manager ("
-" dept_no CHAR(4) NOT NULL,"
+" dept_no INT NOT NULL,"
" emp_no INT NOT NULL,"
" from_date DATE NOT NULL,"
" to_date DATE NOT NULL,"
@@ -169,7 +170,7 @@ int createEmployeeDb()
// mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, "/home/oa136780/mysql/mysql-5.1-telco-7.0-spj/install/config/my.cnf");
const char *mysqld_sock = "/tmp/mysql.sock";
- if ( !mysql_real_connect(&mysql, "loki43", "root", "", "",
+ if ( !mysql_real_connect(&mysql, "127.0.0.1", "root", "", "",
4401, NULL, 0) )
return 0;
@@ -208,13 +209,27 @@ int createEmployeeDb()
mysql_commit(&mysql);
printf("Created 'salaries' table\n");
+
+
+ /****
printf("Insert simple test data\n");
- if (mysql_query(&mysql, "Insert into dept_manager(dept_no,emp_no) values ('d005', 110567)") != 0) MYSQLERROR(mysql);
+ if (mysql_query(&mysql, "Insert into dept_manager(dept_no,emp_no) values ('d005',110567)") != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+
+ if (mysql_query(&mysql, "Insert into employees(emp_no,dept_no) values (110567,'d005')") != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ ******/
+
+ /********/
+ printf("Insert simple test data\n");
+ if (mysql_query(&mysql, "Insert into dept_manager(dept_no,emp_no) values (1005,110567)") != 0) MYSQLERROR(mysql);
mysql_commit(&mysql);
- if (mysql_query(&mysql, "Insert into employees(emp_no) values (110567)") != 0) MYSQLERROR(mysql);
+ if (mysql_query(&mysql, "Insert into employees(emp_no,dept_no) values (110567,1005)") != 0) MYSQLERROR(mysql);
mysql_commit(&mysql);
+ /************/
+
mysql_close(&mysql);
}
@@ -266,6 +281,9 @@ static void init_ndbrecord_info(Ndb &myN
int testQueryBuilder(Ndb &myNdb)
{
const NdbDictionary::Table *manager, *employee, *salary;
+ int res;
+ NdbTransaction* myTransaction;
+ NdbQuery* myQuery;
printf("\n -- Building query --\n");
@@ -289,6 +307,7 @@ int testQueryBuilder(Ndb &myNdb)
*/
NdbQueryBuilder myBuilder(myNdb);
+#if 0
/* qt1 is 'const defined' */
printf("q1\n");
const NdbQueryDef* q1 = 0;
@@ -350,7 +369,6 @@ int testQueryBuilder(Ndb &myNdb)
}
*****/
-
/* Composite operations building real *trees* aka. linked operations.
* (First part is identical to building 'qt2' above)
*
@@ -382,17 +400,18 @@ int testQueryBuilder(Ndb &myNdb)
// A linked value is used to let employee lookup refer values
// from the parent operation on manger.
- const NdbQueryOperand* empJoinKey[] = // Employee is indexed om {"emp_no"}
+ const NdbQueryOperand* joinEmployeeKey[] = // Employee is indexed om {"emp_no"}
{ qb->linkedValue(readManager, "emp_no"), // where '= readManger.emp_no'
0
};
- const NdbQueryLookupOperationDef* readEmployee = qb->readTuple(employee, empJoinKey);
+ const NdbQueryLookupOperationDef* readEmployee = qb->readTuple(employee, joinEmployeeKey);
if (readEmployee == NULL) APIERROR(qb->getNdbError());
q4 = qb->prepare();
if (q4 == NULL) APIERROR(qb->getNdbError());
}
+
///////////////////////////////////////////////////
// q4 may later be executed as:
// (Possibly multiple ::execute() or multiple NdbQueryDef instances
@@ -402,17 +421,13 @@ int testQueryBuilder(Ndb &myNdb)
Uint32 emp_no = 110567;
void* paramList[] = {&dept_no, &emp_no};
- NdbTransaction* myTransaction= myNdb.startTransaction();
+ myTransaction= myNdb.startTransaction();
if (myTransaction == NULL) APIERROR(myNdb.getNdbError());
- NdbQuery* myQuery = myTransaction->createQuery(q4, paramList);
+ myQuery = myTransaction->createQuery(q4,0); // paramList);
if (myQuery == NULL)
APIERROR(myTransaction->getNdbError());
- // TEMP HACK: Set keys for root lookup.
- myQuery->getImpl().getNdbOperation()->equal("dept_no", "d005");
- myQuery->getImpl().getNdbOperation()->equal("emp_no", 110567);
-
#if 0
ManagerRow managerRow;
memset (&managerRow, 0, sizeof(managerRow));
@@ -435,11 +450,6 @@ int testQueryBuilder(Ndb &myNdb)
key[i][0] = op->getValue(table->getColumn(0));
key[i][1] = op->getValue(table->getColumn(1));
-
- for (Uint32 col=2; col<table->getNoOfColumns(); col++)
- {
- op->getValue(table->getColumn(col));
- }
}
#endif
@@ -450,7 +460,7 @@ int testQueryBuilder(Ndb &myNdb)
// All NdbQuery operations are handled as scans with cursor placed 'before'
// first record: Fetch next to retrieve result:
- int res = myQuery->nextResult();
+ res = myQuery->nextResult();
if (res == -1)
APIERROR(myQuery->getNdbError());
@@ -461,6 +471,92 @@ int testQueryBuilder(Ndb &myNdb)
myNdb.closeTransaction(myTransaction);
myTransaction = 0;
+#endif
+
+ //////////////////////////////////////////////////
+ printf("q4_1\n");
+ const NdbQueryDef* q4_1 = 0;
+ {
+ NdbQueryBuilder* qb = &myBuilder; //myDict->getQueryBuilder();
+
+ const NdbQueryOperand* constEmpKey[] = // Employee is indexed om {"emp_no"}
+ { qb->constValue(110567), // emp_no = 110567
+ 0
+ };
+ const NdbQueryLookupOperationDef* readEmployee = qb->readTuple(employee, constEmpKey);
+ if (readEmployee == NULL) APIERROR(qb->getNdbError());
+
+ const NdbQueryOperand* joinManagerKey[] = // Manager is indexed om {"dept_no", "emp_no"}
+ {
+ //qb->constValue(1005), // dept_no = "d005"
+ qb->linkedValue(readEmployee,"dept_no"),
+ //qb->linkedValue(readEmployee,"emp_no"), // emp_no = 110567
+ qb->constValue(110567),
+ //qb->paramValue(), //BEWARE: param serialization incomplete and will cause node failure!!
+ 0
+ };
+
+ // Join with a single tuple with key defined by linked employee fields
+ const NdbQueryLookupOperationDef *readManager = qb->readTuple(manager, joinManagerKey);
+ if (readManager == NULL) APIERROR(qb->getNdbError());
+
+ q4_1 = qb->prepare();
+ if (q4_1 == NULL) APIERROR(qb->getNdbError());
+ }
+
+ ///////////////////////////////////////////////////
+ // q4 may later be executed as:
+ // (Possibly multiple ::execute() or multiple NdbQueryDef instances
+ // within the same NdbTransaction::execute(). )
+ ////////////////////////////////////////////////////
+ //char* dept_no = "d005";
+ Uint32 emp_no_q4 = 110567;
+ void* paramList_q4[] = {&emp_no_q4};
+
+ myTransaction= myNdb.startTransaction();
+ if (myTransaction == NULL) APIERROR(myNdb.getNdbError());
+
+ myQuery = myTransaction->createQuery(q4_1,0); //paramList_q4);
+ if (myQuery == NULL)
+ APIERROR(myTransaction->getNdbError());
+
+ const NdbRecAttr *value_q4[2][2];
+
+ for (Uint32 i=0; i<myQuery->getNoOfOperations(); ++i)
+ {
+ NdbQueryOperation* op = myQuery->getQueryOperation(i);
+ const NdbDictionary::Table* table = op->getQueryOperationDef().getTable();
+
+ value_q4[i][0] = op->getValue(table->getColumn(0));
+ value_q4[i][1] = op->getValue(table->getColumn(1));
+ }
+
+ printf("Start execute\n");
+ if (myTransaction->execute( NdbTransaction::NoCommit ) == -1)
+ APIERROR(myTransaction->getNdbError());
+ printf("Done executed\n");
+
+ // All NdbQuery operations are handled as scans with cursor placed 'before'
+ // first record: Fetch next to retrieve result:
+ res = myQuery->nextResult();
+ if (res == -1)
+ APIERROR(myQuery->getNdbError());
+
+ printf("employee emp_no: %d\n", value_q4[0][0]->u_32_value());
+ printf("manager emp_no: %d\n", value_q4[1][1]->u_32_value());
+
+ // NOW: Result is available in 'managerRow' buffer
+
+ myNdb.closeTransaction(myTransaction);
+ myTransaction = 0;
+
+
+
+ /////////////////////////////////////////////////
+
+
+
+#if 0
// Example: ::readTuple() using Index for unique key lookup
printf("q5\n");
@@ -517,23 +613,29 @@ int testQueryBuilder(Ndb &myNdb)
const NdbQueryScanOperationDef* scanManager = qb->scanTable(manager);
if (scanManager == NULL) APIERROR(qb->getNdbError());
+ // THEN: employee table is joined:
+ // A linked value is used to let employee lookup refer values
+ // from the parent operation on manager.
+
+ const NdbQueryOperand* empJoinKey[] = // Employee is indexed om {"emp_no"}
+ { qb->linkedValue(scanManager, "emp_no"), // where '= readManger.emp_no'
+ 0
+ };
+ const NdbQueryLookupOperationDef* readEmployee = qb->readTuple(employee, empJoinKey);
+ if (readEmployee == NULL) APIERROR(qb->getNdbError());
+
q6 = qb->prepare();
if (q6 == NULL) APIERROR(qb->getNdbError());
}
+
myTransaction= myNdb.startTransaction();
if (myTransaction == NULL) APIERROR(myNdb.getNdbError());
- myQuery = myTransaction->createQuery(q6, paramList);
+ myQuery = myTransaction->createQuery(q6, 0);
if (myQuery == NULL)
APIERROR(myTransaction->getNdbError());
- // TEMP HACK: Set keys for root lookup.
- // NOTE: There should not be any keys for table scans!
- // However, index scans may have a 'prune key'
-// myQuery->getImpl().getNdbOperation()->equal("dept_no", "d005");
-// myQuery->getImpl().getNdbOperation()->equal("emp_no", 110567);
-
const NdbRecAttr* value[2][2];
for (Uint32 i=0; i<myQuery->getNoOfOperations(); ++i)
@@ -562,12 +664,14 @@ int testQueryBuilder(Ndb &myNdb)
APIERROR(myQuery->getNdbError());
printf("manager emp_no: %d\n", value[0][1]->u_32_value());
-//printf("employee emp_no: %d\n", value[1][0]->u_32_value());
+ printf("employee emp_no: %d\n", value[1][0]->u_32_value());
// NOW: Result is available in 'managerRow' buffer
myNdb.closeTransaction(myTransaction);
myTransaction = 0;
+#endif
+
return 0;
}
=== modified file 'storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp 2009-06-25 06:13:48 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp 2009-07-17 21:57:40 +0000
@@ -75,7 +75,7 @@ public:
* This struct represent a row being passed to a child
* currently only the RT_SECTION type is supported
* but RT_ROW_BUF is also planned (for buffered rows)
- * that will be used for eqi-join (and increased parallelism on scans)
+ * that will be used for equi-join (and increased parallelism on scans)
*/
struct RowRef
{
@@ -249,7 +249,7 @@ public:
/**
* A node in a Query
- * (This is is an instantiated version of QueryNode in
+ * (This is an instantiated version of QueryNode in
* include/kernel/signal/QueryTree.hpp)
*/
struct TreeNode
=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2009-07-13 11:15:51 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2009-07-24 08:55:33 +0000
@@ -1347,6 +1347,8 @@ Dbspj::lookup_execLQHKEYREF(Signal* sign
ref->errorCode = errCode;
ref->errorData = 0;
+ DEBUG("lookup_execLQHKEYREF, errorCode:" << errCode);
+
sendSignal(resultRef, GSN_TCKEYREF, signal,
TcKeyRef::SignalLength, JBB);
}
@@ -1397,13 +1399,15 @@ Dbspj::lookup_start_child(Signal* signal
const Uint32 tableId = LqhKeyReq::getTableId(src->tableSchemaVersion);
const Uint32 corrVal = rowRef.m_src_correlation;
+ DEBUG("::lookup_start_child");
+
do
{
Uint32 ptrI = RNIL;
if (treeNodePtr.p->m_bits & TreeNode::T_KEYINFO_CONSTRUCTED)
{
jam();
-
+ DEBUG("start_child w/ T_KEYINFO_CONSTRUCTED");
/**
* Get key-pattern
*/
@@ -1491,8 +1495,15 @@ Dbspj::getNodes(Signal* signal, BuildKey
req->hashValue = dst.hashInfo[1];
req->distr_key_indicator = 0; // userDefinedPartitioning not supported!
+#if 1
EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal,
DiGetNodesReq::SignalLength);
+#else
+ sendSignal(DBDIH_REF, GSN_DIGETNODESREQ, signal,
+ DiGetNodesReq::SignalLength, JBB);
+ jamEntry();
+
+#endif
DiGetNodesConf * conf = (DiGetNodesConf *)&signal->theData[0];
err = signal->theData[0];
@@ -1500,6 +1511,8 @@ Dbspj::getNodes(Signal* signal, BuildKey
Uint32 nodeId = conf->nodes[0];
Uint32 instanceKey = (Tdata2 >> 24) & 127;
+ DEBUG("HASH to nodeId:" << nodeId << ", instanceKey" << instanceKey);
+
jamEntry();
if (unlikely(err != 0))
goto error;
@@ -2006,7 +2019,7 @@ Dbspj::buildRowHeader(RowRef::Header * h
{
Uint32 tmp, len;
Uint32 * dst = (Uint32*)header->m_headers;
- Uint32 * save = dst;
+ const Uint32 * save = dst;
SectionReader r0(ptr, getSectionSegmentPool());
do
{
@@ -2026,11 +2039,12 @@ Uint32
Dbspj::buildRowHeader(RowRef::Header * header, const Uint32 * src, Uint32 len)
{
Uint32 * dst = (Uint32*)header->m_headers;
- Uint32 * save = dst;
+ const Uint32 * save = dst;
for (Uint32 i = 0; i<len; i++)
{
Uint32 tmp = * src++;
Uint32 tmp_len = AttributeHeader::getDataSize(tmp);
+ DEBUG("::buildRowHeader, tmp:" << tmp << ", tmp_len:" << tmp_len);
* dst++ = tmp;
src += tmp_len;
}
@@ -2042,6 +2056,8 @@ Uint32
Dbspj::appendToPattern(Local_pattern_store & pattern,
DABuffer & tree, Uint32 len)
{
+ DEBUG("::appendToPattern, len:" << len);
+
Uint32 err = DbspjErr::InvalidTreeNodeSpecification;
if (tree.ptr + len <= tree.end)
{
@@ -2119,6 +2135,8 @@ Dbspj::getColData32(const RowRef::Sectio
Uint32
Dbspj::appendColToSection(Uint32 & dst, const RowRef::Section & row, Uint32 col)
{
+ DEBUG("::appendColToSection1, col:" << col);
+
/**
* TODO handle errors
*/
@@ -2140,6 +2158,8 @@ Dbspj::appendColToSection(Uint32 & dst,
Uint32
Dbspj::appendColToSection(Uint32 & dst, const RowRef::Linear & row, Uint32 col)
{
+ DEBUG("::appendColToSection2, col:" << col);
+
/**
* TODO handle errors
*/
@@ -2160,6 +2180,8 @@ Dbspj::appendDataToSection(Uint32 & ptrI
Local_pattern_store::ConstDataBufferIterator& it,
Uint32 len)
{
+ DEBUG("::appendDataToSection, len:" << len);
+
#if 0
/**
* TODO handle errors
@@ -2182,6 +2204,7 @@ Dbspj::appendDataToSection(Uint32 & ptrI
while(remaining>0 && !it.isNull())
{
+ DEBUG(" data:" << *it.data);
tmp[dstIdx] = *it.data;
remaining--;
dstIdx++;
@@ -2236,23 +2259,31 @@ Uint32
Dbspj::expand(Uint32 & _dst, Local_pattern_store& pattern,
const RowRef::Section & row)
{
+ DEBUG("::expand1");
+
Uint32 err;
Uint32 dst = _dst;
Local_pattern_store::ConstDataBufferIterator it;
- for (pattern.first(it); !it.isNull(); pattern.next(it))
+ pattern.first(it);
+ while (!it.isNull())
{
Uint32 info = *it.data;
Uint32 type = QueryPattern::getType(info);
Uint32 val = QueryPattern::getLength(info);
- err = DbspjErr::InvalidPattern;
+ pattern.next(it);
+
switch(type){
case QueryPattern::P_COL:
+ DEBUG(" COL, val:" << val);
err = appendColToSection(dst, row, val);
break;
case QueryPattern::P_DATA:
- pattern.next(it);
+ DEBUG(" DATA, val:" << val);
err = appendDataToSection(dst, pattern, it, val);
break;
+ default:
+ err = DbspjErr::InvalidPattern;
+ DEBUG_CRASH();
}
if (unlikely(err != 0))
{
@@ -2271,6 +2302,7 @@ Uint32
Dbspj::expand(Uint32 & ptrI, DABuffer& pattern, Uint32 len,
DABuffer& param, Uint32 cnt)
{
+ DEBUG("::expand2, len:" << len << ", cnt:" << cnt);
/**
* TODO handle error
*/
@@ -2291,17 +2323,23 @@ Dbspj::expand(Uint32 & ptrI, DABuffer& p
Uint32 info = * ptr++;
Uint32 type = QueryPattern::getType(info);
Uint32 val = QueryPattern::getLength(info);
- err = DbspjErr::InvalidPattern;
switch(type){
case QueryPattern::P_COL:
+ DEBUG(" COL, val:" << val);
err = appendColToSection(dst, row, val);
break;
case QueryPattern::P_DATA:
+ DEBUG(" DATA, val:" << val);
if(likely(appendToSection(dst, ptr, val))){
err = 0;
+ } else {
+ err = DbspjErr::InvalidPattern;
}
ptr += val;
break;
+ default:
+ err = DbspjErr::InvalidPattern;
+ DEBUG_CRASH();
}
if (unlikely(err != 0))
{
@@ -2325,6 +2363,7 @@ Uint32
Dbspj::expand(Local_pattern_store& dst, DABuffer& pattern, Uint32 len,
DABuffer& param, Uint32 cnt)
{
+ DEBUG("::expand3, len:" << len << ", cnt:" << cnt << ", param: @" << param.ptr);
/**
* TODO handle error
*/
@@ -2335,6 +2374,10 @@ Dbspj::expand(Local_pattern_store& dst,
row.m_header = (RowRef::Header*)tmp;
row.m_data = param.ptr;
+ DEBUG("row.header.len:" << row.m_header->m_len);
+
+ DEBUG("(Param) row @" << param.ptr);
+
const Uint32 * ptr = pattern.ptr;
const Uint32 * end = ptr + len;
@@ -2343,15 +2386,19 @@ Dbspj::expand(Local_pattern_store& dst,
Uint32 info = * ptr++;
Uint32 type = QueryPattern::getType(info);
Uint32 val = QueryPattern::getLength(info);
- err = DbspjErr::InvalidPattern;
switch(type){
case QueryPattern::P_COL:
+ DEBUG(" COL pattern, val:" << val);
err = appendColToPattern(dst, row, val);
break;
case QueryPattern::P_DATA:
+ DEBUG(" DATA pattern, val:" << val);
err = dst.append(ptr, val) ? 0 : DbspjErr::OutOfQueryMemory;
ptr += val;
break;
+ default:
+ err = DbspjErr::InvalidPattern;
+ DEBUG_CRASH();
}
if (unlikely(err != 0))
{
@@ -2366,6 +2413,8 @@ Dbspj::expand(Local_pattern_store& dst,
pattern.ptr = end;
param.ptr += row.m_header->m_len;
+ DEBUG("param end at" << param.ptr << ", row.header.len:" << row.m_header->m_len);
+
return 0;
error:
@@ -2431,7 +2480,7 @@ Dbspj::parseDA(Build_context& ctx,
| DABits::NI_KEY_CONSTS))
{
jam();
- DEBUG("NI_KEY_PARAMS | NI_KEY_LINKED");
+ DEBUG("NI_KEY_PARAMS | NI_KEY_LINKED | NI_KEY_CONSTS");
/**
* OPTIONAL PART 2:
@@ -2483,7 +2532,7 @@ Dbspj::parseDA(Build_context& ctx,
treeNodePtr.p->m_send.m_keyInfoPtrI = keyInfoPtrI;
}
}
- else
+ else // cnt==0 -> No parameters in key (const + linked)
{
jam();
DEBUG("KEY-PATTERN: len: " << len);
@@ -2492,6 +2541,9 @@ Dbspj::parseDA(Build_context& ctx,
*/
ndbrequire((treeBits & DABits::NI_KEY_PARAMS) == 0);
ndbrequire((paramBits & DABits::PI_KEY_PARAMS) == 0);
+
+ // FIXME: Key may contain *both* CONST, PARAM and LINKED KEY fields
+ // .... which currently does not work...
if((treeBits & DABits::NI_KEY_LINKED) == 0)
{
DEBUG("FIXED-CONST-KEY");
@@ -2501,14 +2553,16 @@ Dbspj::parseDA(Build_context& ctx,
* This means a "fixed" key from here on
*/
Uint32 keyInfoPtrI = RNIL;
- err = expand(keyInfoPtrI, tree, len, param, 0);
+ err = expand(keyInfoPtrI, tree, len, param, 0); // ... 'expand2'
assert(err==0);
treeNodePtr.p->m_send.m_keyInfoPtrI = keyInfoPtrI;
-
}
else
{
- err = appendToPattern(pattern, tree, len);
+ DEBUG("LINKED-KEY");
+ //err = expand(pattern, tree, len, param, cnt);
+
+ err = appendToPattern(pattern, tree, len);
/**
* This node constructs a new key for each send
*/
=== modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2009-07-15 10:40:01 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2009-07-24 08:55:33 +0000
@@ -37,18 +37,13 @@
* (Particular the ConstOperant in order to implement multiple datatypes)
*
* In order to avoid allocating both an interface object and its particular
- * Impl object, all 'final' Impl objects inherit its interface class.
- * As all 'Impl' object 'is a' interface object:
- * - C++ auto downcasting may be used to get the interface object.
- * - Impl classes does not have to be friend of the interface classes.
+ * Impl object, all 'final' Impl objects contains a m_interface object with
+ * the type of its interface class.
+ * All 'Impl' object 'has a' interface object which is accessible through
+ * the virtual method ::getInterface.
*
- * ::getImpl() functions has been defined for convenient access
- * to all available interface classes.
- *
- * CODE STATUS:
- * Except for creating the Query objects, the NdbQueryBuilder factory
- * does not do any usefull work yet. This is a framework for further
- * logic to be added.
+ * ::getImpl() methods has been defined for convenient access
+ * to all available Impl classes.
*
*/
@@ -73,162 +68,20 @@ setErrorCode(NdbQueryBuilder* qb, int aE
return NULL; \
}
-/** The type of an operand. This corresponds to the set of subclasses
- * of NdbQueryOperand.*/
-enum OperandKind{
- OperandKind_Linked,
- OperandKind_Param,
- OperandKind_Const
-};
//////////////////////////////////////////////
// Implementation of NdbQueryOperand interface
-//////////////////////////////////////////////
-
-
-// Baseclass for the QueryOperand implementation
-class NdbQueryOperandImpl
-{
-public:
- const NdbDictionary::Column* getColumn() const
- { return m_column; };
-
- virtual int bindOperand(const NdbDictionary::Column& column,
- NdbQueryOperationDefImpl& operation)
- { if (m_column && m_column != &column)
- // Already bounded to a different column
- return QRY_OPERAND_ALREADY_BOUND;
- m_column = &column;
- return 0;
- }
-
- virtual const NdbQueryOperand& getInterface() const = 0;
-
- OperandKind getKind() const
- { return m_kind;
- }
-protected:
- virtual ~NdbQueryOperandImpl()=0;
-
- NdbQueryOperandImpl(OperandKind kind)
- : m_column(0),
- m_kind(kind)
- {}
-
-private:
- const NdbDictionary::Column* m_column; // Initial NULL, assigned w/ bindOperand()
- /** This is used to tell the type of an NdbQueryOperand. This allow safe
- * downcasting to a subclass.
- */
- const OperandKind m_kind;
-}; // class NdbQueryOperandImpl
-
-
-class NdbLinkedOperandImpl : public NdbQueryOperandImpl
-{
- friend class NdbQueryBuilder; // Allow privat access from builder interface
-
-public:
- virtual int bindOperand(const NdbDictionary::Column& column,
- NdbQueryOperationDefImpl& operation);
-
- const NdbQueryOperationDefImpl& getParentOperation() const
- { return m_parentOperation;
- }
- // 'LinkedSrc' is index into parent op's spj-projection list where
- // the refered column value is available
- Uint32 getLinkedSrc() const
- { return m_parentColumnIx;
- }
- const NdbDictionary::Column& getParentColumn() const
- { return *m_parentOperation.getSPJProjection()[m_parentColumnIx];
- }
- virtual const NdbQueryOperand& getInterface() const
- { return m_interface;
- }
-
-private:
- friend NdbQueryBuilderImpl::~NdbQueryBuilderImpl();
- virtual ~NdbLinkedOperandImpl() {};
-
- NdbLinkedOperandImpl (NdbQueryOperationDefImpl& parent,
- Uint32 columnIx)
- : NdbQueryOperandImpl(OperandKind_Linked),
- m_interface(*this),
- m_parentOperation(parent),
- m_parentColumnIx(columnIx)
- {};
-
- NdbLinkedOperand m_interface;
- NdbQueryOperationDefImpl& m_parentOperation;
- const Uint32 m_parentColumnIx;
-}; // class NdbLinkedOperandImpl
-
-
-class NdbParamOperandImpl : public NdbQueryOperandImpl
-{
- friend class NdbQueryBuilder; // Allow privat access from builder interface
-
-public:
- const char* getName() const
- { return m_name; };
-
- Uint32 getEnum() const
- { return 0; }; // FIXME
-
- virtual const NdbQueryOperand& getInterface() const
- { return m_interface;
- }
-
-private:
- friend NdbQueryBuilderImpl::~NdbQueryBuilderImpl();
- virtual ~NdbParamOperandImpl() {};
- NdbParamOperandImpl (const char* name)
- : NdbQueryOperandImpl(OperandKind_Param),
- m_interface(*this),
- m_name(name)
- {};
-
- NdbParamOperand m_interface;
- const char* const m_name; // Optional parameter name or NULL
-}; // class NdbParamOperandImpl
-
-
-/////////////////////////////////////////////////////
-// Pure virtual baseclass for ConstOperand.
-// Each specific const datatype has its own subclass.
-/////////////////////////////////////////////////////
-class NdbConstOperandImpl : public NdbQueryOperandImpl
-{
- friend class NdbQueryBuilder; // Allow privat access from builder interface
-public:
- virtual size_t getLength() const = 0;
- virtual const void* getAddr() const = 0;
-
- virtual int bindOperand(const NdbDictionary::Column& column,
- NdbQueryOperationDefImpl& operation);
-
- virtual NdbDictionary::Column::Type getType() const = 0;
-
- virtual const NdbQueryOperand& getInterface() const
- { return m_interface;
- }
-
-protected:
- friend NdbQueryBuilderImpl::~NdbQueryBuilderImpl();
- virtual ~NdbConstOperandImpl() {};
- NdbConstOperandImpl ()
- : NdbQueryOperandImpl(OperandKind_Const),
- m_interface(*this)
- {};
-
-private:
- NdbConstOperand m_interface;
-}; // class NdbConstOperandImpl
+//
+// The common baseclass 'class NdbQueryOperandImpl',
+// and its 'const', 'linked' and 'param' subclasses are
+// defined in "NdbQueryBuilderImpl.hpp"
+// The 'const' operand subclass is a pure virtual baseclass
+// which has different type specific subclasses defined below:
+//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////
// Implements different const datatypes by further
-// subclassing of NdbConstOperand.
+// subclassing of the baseclass NdbConstOperand.
//////////////////////////////////////////////////
class NdbInt32ConstOperandImpl : public NdbConstOperandImpl
{
@@ -313,7 +166,7 @@ private:
// Implementation of NdbQueryOperation interface
////////////////////////////////////////////////
-// Common Baseclass 'class NdbQueryOperationDefImp' is
+// Common Baseclass 'class NdbQueryOperationDefImpl' is
// defined in "NdbQueryBuilderImpl.hpp"
@@ -543,7 +396,7 @@ NdbParamOperand::getName() const
Uint32
NdbParamOperand::getEnum() const
{
- return ::getImpl(*this).getEnum();
+ return ::getImpl(*this).getParamIx();
}
/****************************************************************************
@@ -676,7 +529,7 @@ NdbQueryBuilder::constValue(const char*
NdbConstOperandImpl* constOp = new NdbCharConstOperandImpl(value);
returnErrIf(constOp==0,4000);
- m_pimpl->m_constOperands.push_back(constOp);
+ m_pimpl->m_operands.push_back(constOp);
return &constOp->m_interface;
}
NdbConstOperand*
@@ -686,7 +539,7 @@ NdbQueryBuilder::constValue(const void*
NdbConstOperandImpl* constOp = new NdbGenericConstOperandImpl(value,length);
returnErrIf(constOp==0,4000);
- m_pimpl->m_constOperands.push_back(constOp);
+ m_pimpl->m_operands.push_back(constOp);
return &constOp->m_interface;
}
NdbConstOperand*
@@ -695,7 +548,7 @@ NdbQueryBuilder::constValue(Int32 value)
NdbConstOperandImpl* constOp = new NdbInt32ConstOperandImpl(value);
returnErrIf(constOp==0,4000);
- m_pimpl->m_constOperands.push_back(constOp);
+ m_pimpl->m_operands.push_back(constOp);
return &constOp->m_interface;
}
NdbConstOperand*
@@ -704,7 +557,7 @@ NdbQueryBuilder::constValue(Uint32 value
NdbConstOperandImpl* constOp = new NdbUint32ConstOperandImpl(value);
returnErrIf(constOp==0,4000);
- m_pimpl->m_constOperands.push_back(constOp);
+ m_pimpl->m_operands.push_back(constOp);
return &constOp->m_interface;
}
NdbConstOperand*
@@ -713,7 +566,7 @@ NdbQueryBuilder::constValue(Int64 value)
NdbConstOperandImpl* constOp = new NdbInt64ConstOperandImpl(value);
returnErrIf(constOp==0,4000);
- m_pimpl->m_constOperands.push_back(constOp);
+ m_pimpl->m_operands.push_back(constOp);
return &constOp->m_interface;
}
NdbConstOperand*
@@ -722,17 +575,17 @@ NdbQueryBuilder::constValue(Uint64 value
NdbConstOperandImpl* constOp = new NdbUint64ConstOperandImpl(value);
returnErrIf(constOp==0,4000);
- m_pimpl->m_constOperands.push_back(constOp);
+ m_pimpl->m_operands.push_back(constOp);
return &constOp->m_interface;
}
NdbParamOperand*
NdbQueryBuilder::paramValue(const char* name)
{
- NdbParamOperandImpl* paramOp = new NdbParamOperandImpl(name);
+ NdbParamOperandImpl* paramOp = new NdbParamOperandImpl(name,getImpl().m_paramCnt++);
returnErrIf(paramOp==0,4000);
- m_pimpl->m_paramOperands.push_back(paramOp);
+ m_pimpl->m_operands.push_back(paramOp);
return ¶mOp->m_interface;
}
@@ -752,12 +605,12 @@ NdbQueryBuilder::linkedValue(const NdbQu
// Locate refered parrent column in parent operations SPJ projection list;
// Add if not already present
- Uint32 spjRef = parentImpl.addColumnRef(column);
+ Uint32 colIx = parentImpl.addColumnRef(column);
- NdbLinkedOperandImpl* linkedOp = new NdbLinkedOperandImpl(parentImpl,spjRef);
+ NdbLinkedOperandImpl* linkedOp = new NdbLinkedOperandImpl(parentImpl,colIx);
returnErrIf(linkedOp==0, 4000);
- m_pimpl->m_linkedOperands.push_back(linkedOp);
+ m_pimpl->m_operands.push_back(linkedOp);
return &linkedOp->m_interface;
}
@@ -953,8 +806,10 @@ NdbQueryBuilder::prepare()
////////////////////////////////////////
NdbQueryBuilderImpl::NdbQueryBuilderImpl(Ndb& ndb)
-: m_ndb(ndb), m_error(), m_operations(),
- m_paramOperands(), m_constOperands(), m_linkedOperands()
+: m_ndb(ndb), m_error(),
+ m_operations(),
+ m_operands(),
+ m_paramCnt(0)
{}
NdbQueryBuilderImpl::~NdbQueryBuilderImpl()
@@ -965,14 +820,8 @@ NdbQueryBuilderImpl::~NdbQueryBuilderImp
for (i=0; i<m_operations.size(); ++i)
{ delete m_operations[i];
}
- for (i=0; i<m_paramOperands.size(); ++i)
- { delete m_paramOperands[i];
- }
- for (i=0; i<m_constOperands.size(); ++i)
- { delete m_constOperands[i];
- }
- for (i=0; i<m_linkedOperands.size(); ++i)
- { delete m_linkedOperands[i];
+ for (i=0; i<m_operands.size(); ++i)
+ { delete m_operands[i];
}
}
@@ -1000,9 +849,7 @@ NdbQueryBuilderImpl::prepare()
return NULL;
}
m_operations.clear();
- m_paramOperands.clear();
- m_constOperands.clear();
- m_linkedOperands.clear();
+ m_operands.clear();
return def;
}
@@ -1013,9 +860,11 @@ NdbQueryBuilderImpl::prepare()
NdbQueryDefImpl::
NdbQueryDefImpl(const NdbQueryBuilderImpl& builder,
const Vector<NdbQueryOperationDefImpl*>& operations,
+ //const Vector<NdbQueryOperandImpl*> operands; FIXME
int& error)
: m_interface(*this),
- m_operations(operations)
+ m_operations(operations),
+ m_operands()
{
/* Sets size to 1, such that serialization of operation 0 will start from
* offset 1, leaving space for the length field.*/
@@ -1047,6 +896,9 @@ NdbQueryDefImpl::~NdbQueryDefImpl()
for (Uint32 i=0; i<m_operations.size(); ++i)
{ delete m_operations[i];
}
+ for (Uint32 i=0; i<m_operands.size(); ++i)
+ { delete m_operands[i];
+ }
}
const NdbQueryOperationDefImpl*
@@ -1106,43 +958,6 @@ NdbQueryLookupOperationDefImpl::NdbQuery
}
-void
-NdbQueryLookupOperationDefImpl
-::materializeRootOperands(NdbOperation& ndbOperation,
- const constVoidPtr actualParam[]) const
-{
- assert(getQueryOperationIx()==0); // Should only be called for root operation.
- const int keyCount = m_index==NULL ?
- getTable().getNoOfPrimaryKeys() :
- static_cast<int>(getIndex()->getNoOfColumns());
- int paramNo = 0;
- int keyNo;
- for(keyNo = 0; keyNo<keyCount; keyNo++){
- switch(m_keys[keyNo]->getKind()){
- case OperandKind_Const:
- {
- const NdbConstOperandImpl* const constOp
- = static_cast<const NdbConstOperandImpl*>(m_keys[keyNo]);
- ndbOperation.equal(keyNo,
- static_cast<const char*>(constOp->getAddr()));
- }
- break;
- case OperandKind_Param:
- assert(actualParam[paramNo] != NULL);
- ndbOperation.equal(keyNo,
- static_cast<const char*>(actualParam[paramNo++]));
- break;
- default:
- // Root operation cannot have linked operands.
- assert(false);
- }
- }
- // All actual parameters should have been consumed.
- assert(actualParam[paramNo] == NULL);
- // All key fields should have been assigned a value.
- assert(m_keys[keyNo] == NULL);
-}
-
NdbQueryIndexScanOperationDefImpl::NdbQueryIndexScanOperationDefImpl (
const NdbDictionary::Index& index,
const NdbDictionary::Table& table,
@@ -1190,6 +1005,44 @@ NdbQueryIndexScanOperationDefImpl::NdbQu
void
+NdbQueryLookupOperationDefImpl
+::materializeRootOperands(NdbOperation& ndbOperation,
+ const constVoidPtr actualParam[]) const
+{
+ assert(getQueryOperationIx()==0); // Should only be called for root operation.
+ const int keyCount = m_index==NULL ?
+ getTable().getNoOfPrimaryKeys() :
+ static_cast<int>(getIndex()->getNoOfColumns());
+ int paramNo = 0;
+ int keyNo;
+ for(keyNo = 0; keyNo<keyCount; keyNo++){
+ switch(m_keys[keyNo]->getKind()){
+ case NdbQueryOperandImpl::Const:
+ {
+ const NdbConstOperandImpl* const constOp
+ = static_cast<const NdbConstOperandImpl*>(m_keys[keyNo]);
+ ndbOperation.equal(keyNo,
+ static_cast<const char*>(constOp->getAddr()));
+ }
+ break;
+ case NdbQueryOperandImpl::Param:
+ assert(actualParam[paramNo] != NULL);
+ ndbOperation.equal(keyNo,
+ static_cast<const char*>(actualParam[paramNo++]));
+ break;
+ default:
+ // Root operation cannot have linked operands.
+ assert(false);
+ }
+ }
+ // All actual parameters should have been consumed.
+ // assert(actualParam[paramNo] == NULL); // FIXME: param[] might be NULL
+ // All key fields should have been assigned a value.
+ assert(m_keys[keyNo] == NULL);
+}
+
+
+void
NdbQueryIndexScanOperationDefImpl
::materializeRootOperands(NdbOperation& ndbOperation,
const constVoidPtr actualParam[]) const
@@ -1205,6 +1058,7 @@ NdbQueryTableScanOperationDefImpl
assert(false); // TODO: Implement this.
}
+
void
NdbQueryOperationDefImpl::addParent(NdbQueryOperationDefImpl* parentOp)
{
@@ -1263,6 +1117,16 @@ NdbLinkedOperandImpl::bindOperand(
int
+NdbParamOperandImpl::bindOperand(
+ const NdbDictionary::Column& column,
+ NdbQueryOperationDefImpl& operation)
+{
+ operation.addParamRef(this);
+ return NdbQueryOperandImpl::bindOperand(column,operation);
+}
+
+
+int
NdbConstOperandImpl::bindOperand(
const NdbDictionary::Column& column,
NdbQueryOperationDefImpl& operation)
@@ -1327,11 +1191,14 @@ private:
// Find offset (in 32-bit words) of field within struct QN_ScanFragNode.
#define POS_IN_SCAN(field) (offsetof(QN_ScanFragNode, field)/sizeof(Uint32))
+
//#define POS_IN_QUERY(field) (offsetof(QueryNode, field)/sizeof(Uint32))
+
int
NdbQueryLookupOperationDefImpl
-::serializeOperation(Uint32Buffer& serializedDef) const{
+::serializeOperation(Uint32Buffer& serializedDef) const
+{
Uint32Slice nodeBuffer(serializedDef, serializedDef.getSize());
QN_LookupNode& node = reinterpret_cast<QN_LookupNode&>
(nodeBuffer.get(0, SIZE_IN_WORDS(QN_LookupNode)));
@@ -1368,14 +1235,14 @@ NdbQueryLookupOperationDefImpl
const NdbQueryOperandImpl* op = m_keys[0];
while(op!=NULL){
switch(op->getKind()){
- case OperandKind_Linked:
+ case NdbQueryOperandImpl::Linked:
{
node.requestInfo |= DABits::NI_KEY_LINKED;
const NdbLinkedOperandImpl& linkedOp = *static_cast<const NdbLinkedOperandImpl*>(op);
- keyPattern.get(keyPatternPos++) = QueryPattern::col(linkedOp.getLinkedSrc());
+ keyPattern.get(keyPatternPos++) = QueryPattern::col(linkedOp.getLinkedColumnIx());
break;
}
- case OperandKind_Const:
+ case NdbQueryOperandImpl::Const:
{
node.requestInfo |= DABits::NI_KEY_CONSTS;
const NdbConstOperandImpl& constOp
@@ -1395,11 +1262,10 @@ NdbQueryLookupOperationDefImpl
keyPatternPos += wordCount;
break;
}
- case OperandKind_Param: // TODO: Implement this
-/**** FIXME: can't set NI_KEY_PARAMS yet as this also require PI_KEY_PARAMS in parameter part
+ case NdbQueryOperandImpl::Param: // TODO: Implement this
+ /**** FIXME: can't set NI_KEY_PARAMS yet as this also require PI_KEY_PARAMS in parameter part *****/
node.requestInfo |= DABits::NI_KEY_PARAMS;
paramCnt++;
-*****/
keyPattern.get(keyPatternPos++) = QueryPattern::data(0); // Simple hack to avoid 'assert(keyPatternPos>0)' below
break;
default:
@@ -1444,6 +1310,8 @@ NdbQueryLookupOperationDefImpl
return 0;
}
+
+
int
NdbQueryTableScanOperationDefImpl
::serializeOperation(Uint32Buffer& serializedDef) const
@@ -1513,9 +1381,9 @@ NdbQueryIndexScanOperationDefImpl
// Instantiate Vector templates
template class Vector<NdbQueryOperationDefImpl*>;
-template class Vector<NdbParamOperandImpl*>;
-template class Vector<NdbConstOperandImpl*>;
-template class Vector<NdbLinkedOperandImpl*>;
+template class Vector<NdbQueryOperandImpl*>;
+
+template class Vector<const NdbParamOperandImpl*>;
template class Vector<const NdbDictionary::Column*>;
#if 0
=== modified file 'storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 2009-07-16 12:11:21 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 2009-07-24 08:55:33 +0000
@@ -168,9 +168,7 @@ private:
NdbQueryDef m_interface;
Vector<NdbQueryOperationDefImpl*> m_operations;
-//Vector<NdbParamOperand*> m_paramOperand;
-//Vector<NdbConstOperand*> m_constOperand;
-//Vector<NdbLinkedOperand*> m_linkedOperand;
+ Vector<NdbQueryOperandImpl*> m_operands;
Uint32Buffer m_serializedDef;
}; // class NdbQueryDefImpl
@@ -204,17 +202,18 @@ private:
NdbError m_error;
Vector<NdbQueryOperationDefImpl*> m_operations;
- Vector<NdbParamOperandImpl*> m_paramOperands;
- Vector<NdbConstOperandImpl*> m_constOperands;
- Vector<NdbLinkedOperandImpl*> m_linkedOperands;
-
+ Vector<NdbQueryOperandImpl*> m_operands;
+ Uint32 m_paramCnt;
}; // class NdbQueryBuilderImpl
+////////////////////////////////////////////////
+// Implementation of NdbQueryOperation interface
+////////////////////////////////////////////////
+
/** For making complex declarations more readable.*/
typedef const void* constVoidPtr;
-
class NdbQueryOperationDefImpl
{
public:
@@ -230,25 +229,25 @@ public:
// Get the ordinal position of this operation within the query
Uint32 getQueryOperationIx() const
- { return m_ix; };
+ { return m_ix; }
Uint32 getNoOfParentOperations() const
- { return m_parents.size(); };
+ { return m_parents.size(); }
const NdbQueryOperationDefImpl& getParentOperation(Uint32 i) const
- { return *m_parents[i]; };
+ { return *m_parents[i]; }
Uint32 getNoOfChildOperations() const
- { return m_children.size(); };
+ { return m_children.size(); }
const NdbQueryOperationDefImpl& getChildOperation(Uint32 i) const
- { return *m_children[i]; };
+ { return *m_children[i]; }
const NdbDictionary::Table& getTable() const
- { return m_table; };
+ { return m_table; }
const char* getName() const
- { return m_ident; };
+ { return m_ident; }
// Register a operation as parent of this operation
void addParent(NdbQueryOperationDefImpl*);
@@ -257,8 +256,22 @@ public:
void addChild(NdbQueryOperationDefImpl*);
// Register a linked reference to a column from operation
+ // Return position in list of refered columns available from
+ // this (parent) operation. Child ops later refer linked
+ // columns by its position in this list
Uint32 addColumnRef(const NdbDictionary::Column*);
+ // Register a param operand which is refered by this operation.
+ // Param values are supplied pr. operation when code is serialized.
+ void addParamRef(const NdbParamOperandImpl* param)
+ { m_params.push_back(param); }
+
+ Uint32 getNoOfParameters() const
+ { return m_params.size(); }
+
+ const NdbParamOperandImpl& getParameter(Uint32 ix) const
+ { return *m_params[ix]; }
+
// Get type of query operation
virtual Type getType() const = 0;
@@ -295,21 +308,180 @@ protected:
const char* ident,
Uint32 ix)
: m_table(table), m_ident(ident), m_ix(ix),
- m_parents(), m_children(),
+ m_parents(), m_children(), m_params(),
m_spjProjection()
- {};
+ {}
private:
const NdbDictionary::Table& m_table;
const char* const m_ident; // Optional name specified by aplication
- const Uint32 m_ix; // Index if this operation within operation array
+ const Uint32 m_ix; // Index of this operation within operation array
// parent / child vectors contains dependencies as defined
// with linkedValues
Vector<NdbQueryOperationDefImpl*> m_parents;
Vector<NdbQueryOperationDefImpl*> m_children;
+
+ // Params required by this operation
+ Vector<const NdbParamOperandImpl*> m_params;
+
+ // Column from this operation required by its child operations
Vector<const NdbDictionary::Column*> m_spjProjection;
}; // class NdbQueryOperationDefImpl
+
+//////////////////////////////////////////////
+// Implementation of NdbQueryOperand interface
+//////////////////////////////////////////////
+
+// Baseclass for the QueryOperand implementation
+class NdbQueryOperandImpl
+{
+public:
+
+ /** The type of an operand. This corresponds to the set of subclasses
+ * of NdbQueryOperandImpl.
+ */
+ enum Kind {
+ Linked,
+ Param,
+ Const
+ };
+
+ const NdbDictionary::Column* getColumn() const
+ { return m_column; }
+
+ virtual int bindOperand(const NdbDictionary::Column& column,
+ NdbQueryOperationDefImpl& operation)
+ { if (m_column && m_column != &column)
+ // Already bounded to a different column
+ return QRY_OPERAND_ALREADY_BOUND;
+ m_column = &column;
+ return 0;
+ }
+
+ virtual const NdbQueryOperand& getInterface() const = 0;
+
+ Kind getKind() const
+ { return m_kind; }
+
+protected:
+ friend NdbQueryBuilderImpl::~NdbQueryBuilderImpl();
+ friend NdbQueryDefImpl::~NdbQueryDefImpl();
+
+ virtual ~NdbQueryOperandImpl()=0;
+
+ NdbQueryOperandImpl(Kind kind)
+ : m_column(0),
+ m_kind(kind)
+ {}
+
+private:
+ const NdbDictionary::Column* m_column; // Initial NULL, assigned w/ bindOperand()
+ /** This is used to tell the type of an NdbQueryOperand. This allow safe
+ * downcasting to a subclass.
+ */
+ const Kind m_kind;
+}; // class NdbQueryOperandImpl
+
+
+class NdbLinkedOperandImpl : public NdbQueryOperandImpl
+{
+ friend class NdbQueryBuilder; // Allow privat access from builder interface
+
+public:
+ virtual int bindOperand(const NdbDictionary::Column& column,
+ NdbQueryOperationDefImpl& operation);
+
+ const NdbQueryOperationDefImpl& getParentOperation() const
+ { return m_parentOperation; }
+
+ // 'LinkedSrc' is index into parent op's spj-projection list where
+ // the refered column value is available
+ Uint32 getLinkedColumnIx() const
+ { return m_parentColumnIx; }
+
+ const NdbDictionary::Column& getParentColumn() const
+ { return *m_parentOperation.getSPJProjection()[m_parentColumnIx]; }
+
+ virtual const NdbQueryOperand& getInterface() const
+ { return m_interface; }
+
+private:
+ virtual ~NdbLinkedOperandImpl() {};
+
+ NdbLinkedOperandImpl (NdbQueryOperationDefImpl& parent,
+ Uint32 columnIx)
+ : NdbQueryOperandImpl(Linked),
+ m_interface(*this),
+ m_parentOperation(parent),
+ m_parentColumnIx(columnIx)
+ {}
+
+ NdbLinkedOperand m_interface;
+ NdbQueryOperationDefImpl& m_parentOperation;
+ const Uint32 m_parentColumnIx;
+}; // class NdbLinkedOperandImpl
+
+
+class NdbParamOperandImpl : public NdbQueryOperandImpl
+{
+ friend class NdbQueryBuilder; // Allow privat access from builder interface
+
+public:
+ virtual int bindOperand(const NdbDictionary::Column& column,
+ NdbQueryOperationDefImpl& operation);
+
+ const char* getName() const
+ { return m_name; }
+
+ Uint32 getParamIx() const
+ { return m_paramIx; }
+
+ virtual const NdbQueryOperand& getInterface() const
+ { return m_interface; }
+
+private:
+ virtual ~NdbParamOperandImpl() {};
+ NdbParamOperandImpl (const char* name, Uint32 paramIx)
+ : NdbQueryOperandImpl(Param),
+ m_interface(*this),
+ m_name(name),
+ m_paramIx(paramIx)
+ {}
+
+ NdbParamOperand m_interface;
+ const char* const m_name; // Optional parameter name or NULL
+ const Uint32 m_paramIx;
+}; // class NdbParamOperandImpl
+
+
+class NdbConstOperandImpl : public NdbQueryOperandImpl
+{
+ friend class NdbQueryBuilder; // Allow privat access from builder interface
+public:
+ virtual size_t getLength() const = 0;
+ virtual const void* getAddr() const = 0;
+
+ virtual int bindOperand(const NdbDictionary::Column& column,
+ NdbQueryOperationDefImpl& operation);
+
+ virtual NdbDictionary::Column::Type getType() const = 0;
+
+ virtual const NdbQueryOperand& getInterface() const
+ { return m_interface; }
+
+protected:
+ virtual ~NdbConstOperandImpl() {};
+ NdbConstOperandImpl ()
+ : NdbQueryOperandImpl(Const),
+ m_interface(*this)
+ {}
+
+private:
+ NdbConstOperand m_interface;
+}; // class NdbConstOperandImpl
+
+
#endif // __cplusplus
#endif
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2009-07-16 12:11:21 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2009-07-24 08:55:33 +0000
@@ -22,6 +22,7 @@
#include "NdbQueryBuilder.hpp"
#include "NdbQueryBuilderImpl.hpp"
#include "signaldata/QueryTree.hpp"
+
#include "AttributeHeader.hpp"
#include "NdbRecord.hpp"
@@ -225,15 +226,14 @@ NdbQueryImpl::NdbQueryImpl(NdbTransactio
{
NdbOperation* lookupOp = m_transaction.getNdbOperation(&def.getTable());
lookupOp->readTuple(NdbOperation::LM_Dirty);
- lookupOp->m_isLinked = true;
+ lookupOp->m_isLinked = true; //(queryDef.getNoOfOperations()>1);
lookupOp->setQueryImpl(this);
m_ndbOperation = lookupOp;
}
else if (def.getType() == NdbQueryOperationDefImpl::TableScan)
{
NdbScanOperation* scanOp = m_transaction.scanTable(def.getTable().getDefaultRecord(), NdbOperation::LM_Dirty);
-// scanOp->readTuples(NdbOperation::LM_Dirty);
- scanOp->m_isLinked = true;
+ scanOp->m_isLinked = true; // if (queryDef.getNoOfOperations()> 1);
scanOp->setQueryImpl(this);
m_ndbOperation = scanOp;
} else {
@@ -351,19 +351,15 @@ NdbQueryImpl::prepareSend(){
// Serialize parameters.
for(Uint32 i = 0; i < m_operations.size(); i++){
const int error = m_operations[i]->prepareSend(m_serializedParams);
- if(error != 0){
+ if(unlikely(error != 0)){
return error;
}
}
- // Append serialized query tree and params to ATTRINFO of the NdnOperation.
- m_ndbOperation->insertATTRINFOloop(&m_queryDef.getSerialized().get(0),
- m_queryDef.getSerialized().getSize());
- m_ndbOperation->insertATTRINFOloop(&m_serializedParams.get(0),
- m_serializedParams.getSize());
// Build explicit key/filter/bounds for root operation.
m_operations[0]->getQueryOperationDef()
.materializeRootOperands(*getNdbOperation(), m_param);
+
#ifdef TRACE_SERIALIZATION
ndbout << "Serialized params for all : ";
for(Uint32 i = 0; i < m_serializedParams.getSize(); i++){
@@ -373,6 +369,29 @@ NdbQueryImpl::prepareSend(){
}
ndbout << endl;
#endif
+
+ // Append serialized query tree and params to ATTRINFO of the NdnOperation.
+ //
+ // Handled differently depending on if the operation is a NdbRecord type operation
+ // (Long signals) or a old type NdbApi operation.(Short signals)
+ // NOTE1: All scans are 'NdbRecord'
+ // NOTE2: It should be our goal to remove the dependency of the existing
+ // NdbOperations for building signals for NdbQueryOperations
+ if (m_ndbOperation->isNdbRecordOperation())
+ {
+ m_ndbOperation->insertATTRINFOData_NdbRecord((char*)&m_queryDef.getSerialized().get(0),
+ m_queryDef.getSerialized().getSize()*4);
+ m_ndbOperation->insertATTRINFOData_NdbRecord((char*)&m_serializedParams.get(0),
+ m_serializedParams.getSize()*4);
+ }
+ else
+ {
+ m_ndbOperation->insertATTRINFOloop(&m_queryDef.getSerialized().get(0),
+ m_queryDef.getSerialized().getSize());
+ m_ndbOperation->insertATTRINFOloop(&m_serializedParams.get(0),
+ m_serializedParams.getSize());
+ }
+
return 0;
}
@@ -461,7 +480,7 @@ NdbQueryOperationImpl::getValue(
const NdbDictionary::Column* const column
= m_operationDef.getTable().getColumn(anAttrName);
if(unlikely(column==NULL)){
- return NULL;
+ return NULL; // FIXME: Don't return NULL wo/ setting errorcode
} else {
return getValue(column, resultBuffer);
}
@@ -563,6 +582,7 @@ NdbQueryOperationImpl::UserProjection
::UserProjection(const NdbDictionary::Table& tab):
m_columnCount(0),
m_noOfColsInTable(tab.getNoOfColumns()),
+ m_mask(),
m_isOrdered(true),
m_maxColNo(-1){
assert(m_noOfColsInTable<=MAX_ATTRIBUTES_IN_TABLE);
@@ -645,16 +665,22 @@ int NdbQueryOperationImpl::prepareSend(U
int optPos = 0;
+ //printf("operation has %d params\n", getQueryOperationDef().getNoOfParameters());
+
// SPJ block assume PARAMS to be supplied before ATTR_LIST
- if (false) // TODO: Check if serialized tree code has 'NI_KEY_PARAMS'
+ if (getQueryOperationDef().getNoOfParameters() > 0)
{
int size = 0;
requestInfo |= DABits::PI_KEY_PARAMS;
Uint32Slice keyParam(optional, optPos);
- assert (getQuery().getParam(0) != NULL);
// FIXME: Add parameters here, unsure about the serialized format yet
-
+ for (Uint32 i=0; i<getQueryOperationDef().getNoOfParameters(); i++)
+ {
+ const NdbParamOperandImpl& param = getQueryOperationDef().getParameter(i);
+ const void* paramValue = getQuery().getParamValue(param.getParamIx());
+ assert (paramValue != NULL);
+ }
optPos += size;
}
@@ -698,7 +724,6 @@ void NdbQueryOperationImpl::release(){
}
-
bool
NdbQueryOperationImpl::execTRANSID_AI(const Uint32* ptr, Uint32 len){
ndbout << "NdbQueryOperationImpl::execTRANSID_AI(): *this="
@@ -736,8 +761,9 @@ NdbQueryOperationImpl::execTRANSID_AI(co
return false;
}
+
bool
-NdbQueryOperationImpl::execTCKEYREF(){
+NdbQueryOperationImpl::execTCKEYREF(NdbApiSignal* aSignal){
ndbout << "NdbQueryOperationImpl::execTCKEYREF(): *this="
<< *this << endl;
m_pendingResults--;
@@ -754,7 +780,6 @@ NdbQueryOperationImpl::execTCKEYREF(){
}
-
/** For debugging.*/
NdbOut& operator<<(NdbOut& out, const NdbQueryOperationImpl& op){
out << "[ this: " << &op
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp 2009-07-16 12:11:21 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp 2009-07-24 08:55:33 +0000
@@ -82,8 +82,11 @@ public:
/** Release all NdbReceiver instances.*/
void release();
- bool checkMagicNumber() const { return m_magic == MAGIC;}
- Uint32 ptr2int() const {return m_id;}
+ bool checkMagicNumber() const
+ { return m_magic == MAGIC; }
+
+ Uint32 ptr2int() const
+ { return m_id; }
const NdbQuery& getInterface() const
{ return m_interface; }
@@ -91,14 +94,17 @@ public:
NdbQuery& getInterface()
{ return m_interface; }
- const void* getParam(Uint32 i) const
- { return m_param[i]; }
+ const void* getParamValue(Uint32 ix) const
+ { return m_param[ix]; }
/** Get next query in same transaction.*/
- NdbQueryImpl* getNext() const {return m_next;}
+ NdbQueryImpl* getNext() const
+ { return m_next; }
/** TODO: Remove. Temporary hack for prototype.*/
- NdbOperation* getNdbOperation() const {return m_ndbOperation;}
+ NdbOperation* getNdbOperation() const
+ { return m_ndbOperation; }
+
private:
NdbQuery m_interface;
@@ -191,7 +197,7 @@ public:
/** Process absence of result data for this operation.
* Return true if query complete.*/
- bool execTCKEYREF();
+ bool execTCKEYREF(NdbApiSignal* aSignal);
/** Prepare for execution.
* @return possible error code.*/
@@ -246,7 +252,7 @@ private:
int m_columnCount;
/** The number of columns in the table that the operation refers to.*/
const int m_noOfColsInTable;
- /** User Projection, represented as a bitmap (indexd with column numbers).*/
+ /** User Projection, represented as a bitmap (indexed with column numbers).*/
Bitmask<MAXNROFATTRIBUTESINWORDS> m_mask;
/** True if columns were added in ascending order (ordered according to
* column number).*/
=== modified file 'storage/ndb/src/ndbapi/Ndbif.cpp'
--- a/storage/ndb/src/ndbapi/Ndbif.cpp 2009-07-10 07:41:22 +0000
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp 2009-07-24 08:55:33 +0000
@@ -549,7 +549,7 @@ Ndb::handleReceivedSignal(NdbApiSignal*
return;
}//if
} else {
- if(queryOpImpl->execTCKEYREF() &&
+ if(queryOpImpl->execTCKEYREF(aSignal) &&
tCon->OpCompleteFailure(queryOpImpl->getQuery()
.getNdbOperation()) != -1){
completedTransaction(tCon);
Attachment: [text/bzr-bundle] bzr/jan.wedvik@sun.com-20090724085533-nsgl1kjp6apk7lv1.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-7.0-spj branch (jan.wedvik:2936) | Jan Wedvik | 24 Jul |