2900 Ole John Aske 2009-06-25
Implemented basic semantics checks in the NdbQueryBuilder - checks:
- Refered parent operations is known within this querybuilder context.
- linked 'column' is a valid column available from referred operation
- key[] values are specified for all columns in the Primary (hash)Key.
- Correct datatypes for all operands in the key[]
In addition, basic (Vector<>) structures has been added to collect the set of
operation & operands being built in the QueryBuilder. Parent/child relations
are collected from the linkedValue() where apropriate.
added:
storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp
modified:
storage/ndb/include/ndbapi/NdbQueryBuilder.hpp
storage/ndb/include/ndbapi/NdbQueryOperation.hpp
storage/ndb/ndbapi-examples/ndbapi_multi_cursor/Makefile
storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp
storage/ndb/src/ndbapi/NdbQueryBuilder.cpp
storage/ndb/src/ndbapi/NdbQueryOperation.cpp
storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp
storage/ndb/src/ndbapi/Ndberr.cpp
storage/ndb/src/ndbapi/ndberror.c
2899 Jan Wedvik 2009-06-25 [merge]
Merged from bk-internal.mysql.com/bzrroot/server/mysql-5.1-telco-7.0-spj/ .
modified:
storage/ndb/include/transporter/TransporterDefinitions.hpp
storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
=== modified file 'storage/ndb/include/ndbapi/NdbQueryBuilder.hpp'
--- a/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp 2009-06-24 07:44:43 +0000
+++ b/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp 2009-06-25 13:38:11 +0000
@@ -26,6 +26,7 @@
class Ndb;
+class NdbQueryBuilderImpl;
class NdbQueryOperandImpl;
class NdbQueryOperationDefImpl;
@@ -213,7 +214,6 @@ public:
NdbQueryBuilder(Ndb&); // Or getQueryBuilder() from Ndb..
~NdbQueryBuilder();
-
class NdbQueryDef* prepare(); // Complete building a queryTree from 'this' NdbQueryBuilder
// NdbQueryOperand builders:
@@ -274,27 +274,11 @@ public:
*/
const NdbError& getNdbError() const;
- /**
- * Get the method number where the latest error occured.
- *
- * @return Line number where latest error occured.
- */
-//int getNdbErrorLine();
+ NdbQueryBuilderImpl& getImpl() const;
-/*** LIKELY TO BE REMOVED:
- void next(NdbQueryBuilder* next) // Set next pointer
- { m_next = next; };
-
- NdbQueryBuilder* next() // Get next pointer
- { return m_next; };
-
private:
- NdbQueryBuilder* m_next;
-********/
+ NdbQueryBuilderImpl* const m_pimpl;
-private:
- Ndb& m_ndb;
- NdbError m_error;
}; // class NdbQueryBuilder
/**
@@ -321,7 +305,7 @@ private:
class NdbQueryDef
{
protected:
- // C'tor is private - only NdbQueryBuilder::prepare() is allowed to construct a new NdbQueryDef
+ // C'tor is protected - only NdbQueryBuilder::prepare() is allowed to construct a new NdbQueryDef
NdbQueryDef();
public:
@@ -335,8 +319,20 @@ public:
const NdbQueryOperationDef* getRootOperation() const;
- // Remove this NdbQueryDef.
+//Uint32 getNoOfOperations() const;
+
+ // Get a specific NdbQueryOperationDef by ident specified
+ // when the NdbQueryOperationDef was created.
+//NdbQueryOperationDef* getQueryOperationDef(const char* ident) const;
+//NdbQueryOperationDef* getQueryOperationDef(Uint32 index) const;
+
+ // Remove this NdbQueryDef including operation and operands it contains
//void release(); Just delete it instead ?
+
+//class NdbQueryDefImpl& getImpl() const;
+
+private:
+//class NdbQueryDefImpl* const m_pimpl;
};
=== modified file 'storage/ndb/include/ndbapi/NdbQueryOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbQueryOperation.hpp 2009-06-22 13:22:11 +0000
+++ b/storage/ndb/include/ndbapi/NdbQueryOperation.hpp 2009-06-25 13:38:11 +0000
@@ -39,11 +39,6 @@ class NdbQueryImpl;
class NdbQueryOperationImpl;
class NdbRecord;
-/** Opaque implementation classes */
-class NdbQueryImpl;
-class NdbQueryOperationImpl;
-
-
/**
* NdbQuery are create when a NdbQueryDefinition is submitted for
* execution.
@@ -81,7 +76,7 @@ public:
// Get a specific NdbQueryOperation by ident specified
// when the NdbQueryOperationDef was created.
NdbQueryOperation* getQueryOperation(const char* ident) const;
- NdbQueryOperation* getQueryOperation(Uint32 ident) const;
+ NdbQueryOperation* getQueryOperation(Uint32 index) const;
//NdbQueryOperation* getQueryOperation(const NdbQueryOperationDef* def) const;
=== modified file 'storage/ndb/ndbapi-examples/ndbapi_multi_cursor/Makefile'
--- a/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/Makefile 2009-06-10 12:37:22 +0000
+++ b/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/Makefile 2009-06-25 13:38:11 +0000
@@ -8,14 +8,15 @@ DEBUG =
LDFLAGS = -g -m64
TOP_SRCDIR = ../../../..
INCLUDE_DIR = $(TOP_SRCDIR)/storage/ndb/include
-LIB_DIR = -L$(TOP_SRCDIR)/storage/ndb/src/.libs
+LIB_DIR = -L$(TOP_SRCDIR)/storage/ndb/src/.libs \
+ -L$(TOP_SRCDIR)/libmysql_r/.libs
SYS_LIB =
$(TARGET): $(OBJS)
- $(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) $(OBJS) -lrt -lndbclient $(SYS_LIB) -o $(TARGET)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) $(OBJS) -lrt -lndbclient -lmysqlclient_r $(SYS_LIB) -o $(TARGET)
$(TARGET).quantify: $(OBJS)
- quantify $(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) $(OBJS) -lrt -lndbclient $(SYS_LIB) -o $(TARGET)
+ quantify $(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) $(OBJS) -lrt -lndbclient -lmysqlclient_r $(SYS_LIB) -o $(TARGET)
$(OBJS): $(SRCS)
=== modified file 'storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp'
--- a/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp 2009-06-18 07:57:55 +0000
+++ b/storage/ndb/ndbapi-examples/ndbapi_multi_cursor/main.cpp 2009-06-25 13:38:11 +0000
@@ -20,6 +20,8 @@
**************************************************************/
+#include <mysql.h>
+#include <mysqld_error.h>
#include <NdbApi.hpp>
// Used for cout
#include <iostream>
@@ -37,6 +39,9 @@
std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \
<< ", code: " << code \
<< ", msg: " << msg << "." << std::endl
+#define MYSQLERROR(mysql) { \
+ PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \
+ exit(-1); }
#define APIERROR(error) { \
PRINT_ERROR((error).code,(error).message); \
exit(-1); }
@@ -46,7 +51,7 @@
/**
* Define NDB_CONNECT_STRING if you don't connect through the default localhost:1186
*/
- #define NDB_CONNECT_STRING "fimafeng08:1"
+ #define NDB_CONNECT_STRING "loki43:2360"
@@ -112,6 +117,143 @@ struct SalaryRow
};
+ NdbQuery*
+ NdbTransaction::createQuery(const NdbQueryDef* def,
+ const void* const param[],
+ NdbOperation::LockMode lock_mode)
+{
+ NdbQuery* query = NdbQuery::buildQuery(*this, *def);
+
+ return query;
+}
+
+const char* employeeDef =
+"CREATE TABLE employees ("
+" emp_no INT NOT NULL,"
+" birth_date DATE NOT NULL,"
+" first_name VARCHAR(14) NOT NULL,"
+" last_name VARCHAR(16) NOT NULL,"
+" gender ENUM ('M','F') NOT NULL, "
+" hire_date DATE NOT NULL,"
+" PRIMARY KEY (emp_no))"
+" ENGINE=NDB";
+
+const char* departmentsDef =
+"CREATE TABLE departments ("
+" dept_no CHAR(4) NOT NULL,"
+" dept_name VARCHAR(40) NOT NULL,"
+" PRIMARY KEY (dept_no),"
+" UNIQUE KEY (dept_name))"
+" ENGINE=NDB";
+
+const char* dept_managerDef =
+"CREATE TABLE dept_manager ("
+" dept_no CHAR(4) NOT NULL,"
+" emp_no INT NOT NULL,"
+" from_date DATE NOT NULL,"
+" to_date DATE NOT NULL,"
+" KEY (emp_no),"
+" KEY (dept_no),"
+" FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,"
+" FOREIGN KEY (dept_no) REFERENCES departments (dept_no) ON DELETE CASCADE,"
+" PRIMARY KEY (emp_no,dept_no))"
+" ENGINE=NDB";
+
+const char* dept_empDef =
+"CREATE TABLE dept_emp ("
+" emp_no INT NOT NULL,"
+" dept_no CHAR(4) NOT NULL,"
+" from_date DATE NOT NULL,"
+" to_date DATE NOT NULL,"
+" KEY (emp_no),"
+" KEY (dept_no),"
+" FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,"
+" FOREIGN KEY (dept_no) REFERENCES departments (dept_no) ON DELETE CASCADE,"
+" PRIMARY KEY (emp_no,dept_no))"
+" ENGINE=NDB";
+
+const char* titlesDef =
+"CREATE TABLE titles ("
+" emp_no INT NOT NULL,"
+" title VARCHAR(50) NOT NULL,"
+" from_date DATE NOT NULL,"
+" to_date DATE,"
+" KEY (emp_no),"
+" FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,"
+" PRIMARY KEY (emp_no,title, from_date))"
+" ENGINE=NDB";
+
+const char* salariesDef =
+"CREATE TABLE salaries ("
+" emp_no INT NOT NULL,"
+" salary INT NOT NULL,"
+" from_date DATE NOT NULL,"
+" to_date DATE NOT NULL,"
+" KEY (emp_no),"
+" FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,"
+" PRIMARY KEY (emp_no, from_date))"
+" ENGINE=NDB";
+
+
+int createEmployeeDb()
+{
+ /**************************************************************
+ * Connect to mysql server and create testDB *
+ **************************************************************/
+ if (true)
+ {
+ MYSQL mysql;
+ if ( !mysql_init(&mysql) ) {
+ std::cout << "mysql_init failed\n";
+ exit(-1);
+ }
+// 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", "", "",
+ 4401, NULL, 0) )
+ return 0;
+
+ printf("Mysql connected\n");
+ mysql_query(&mysql, "DROP DATABASE employees");
+ printf("Dropped existing employees DB\n");
+ mysql_query(&mysql, "CREATE DATABASE employees");
+ mysql_commit(&mysql);
+ printf("Created new employees DB\n");
+
+ if (mysql_query(&mysql, "USE employees") != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ printf("USE employees DB\n");
+
+ if (mysql_query(&mysql, employeeDef) != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ printf("Created 'employee' table\n");
+
+ if (mysql_query(&mysql, departmentsDef) != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ printf("Created 'departments' table\n");
+
+ if (mysql_query(&mysql, dept_managerDef) != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ printf("Created 'dept_manager' table\n");
+
+ if (mysql_query(&mysql, dept_empDef) != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ printf("Created 'dept_emp' table\n");
+
+ if (mysql_query(&mysql, titlesDef) != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ printf("Created 'titles' table\n");
+
+ if (mysql_query(&mysql, salariesDef) != 0) MYSQLERROR(mysql);
+ mysql_commit(&mysql);
+ printf("Created 'salaries' table\n");
+
+ mysql_close(&mysql);
+ }
+
+ return 1;
+}
/**************************************************************
* Initialise NdbRecord structures for table and index access *
@@ -139,10 +281,10 @@ static void init_ndbrecord_info(Ndb &myN
if (manager_to_date == NULL) APIERROR(myDict->getNdbError());
const NdbDictionary::RecordSpecification mngSpec[] = {
-// NdbDictionary::RecordSpecification(manager_dept_no, offsetof(ManagerRow, dept_no)),
-// NdbDictionary::RecordSpecification(manager_emp_no, offsetof(ManagerRow, emp_no)),
-// NdbDictionary::RecordSpecification(manager_from_date, offsetof(ManagerRow, from_date)),
-// NdbDictionary::RecordSpecification(manager_to_date, offsetof(ManagerRow, to_date)),
+ NdbDictionary::RecordSpecification(manager_dept_no, offsetof(ManagerRow, dept_no)),
+ NdbDictionary::RecordSpecification(manager_emp_no, offsetof(ManagerRow, emp_no)),
+ NdbDictionary::RecordSpecification(manager_from_date, offsetof(ManagerRow, from_date)),
+ NdbDictionary::RecordSpecification(manager_to_date, offsetof(ManagerRow, to_date)),
};
pkeyManagerRecord =
@@ -171,14 +313,12 @@ static void init_ndbrecord_info(Ndb &myN
if (employee_gender == NULL) APIERROR(myDict->getNdbError());
const NdbDictionary::RecordSpecification empSpec[] = {
-/****
NdbDictionary::RecordSpecification(employee_emp_no, offsetof(EmployeeRow, emp_no)),
NdbDictionary::RecordSpecification(employee_birth_date, offsetof(EmployeeRow, birth_date)),
NdbDictionary::RecordSpecification(employee_first_name, offsetof(EmployeeRow, first_name)),
NdbDictionary::RecordSpecification(employee_last_name, offsetof(EmployeeRow, last_name)),
NdbDictionary::RecordSpecification(employee_gender, offsetof(EmployeeRow, gender)),
NdbDictionary::RecordSpecification(employee_hire_date, offsetof(EmployeeRow, hire_date)),
-****/
};
pkeyEmployeeRecord =
@@ -202,12 +342,10 @@ static void init_ndbrecord_info(Ndb &myN
if (salary_to_date == NULL) APIERROR(myDict->getNdbError());
const NdbDictionary::RecordSpecification salarySpec[] = {
-/****
NdbDictionary::RecordSpecification(salary_emp_no, offsetof(SalaryRow, emp_no)),
NdbDictionary::RecordSpecification(salary_from_date, offsetof(SalaryRow, from_date)),
NdbDictionary::RecordSpecification(salary_salary, offsetof(SalaryRow, salary)),
NdbDictionary::RecordSpecification(salary_to_date, offsetof(SalaryRow, to_date))
-***/
};
// Lookup Primary key for salaries table
@@ -233,7 +371,7 @@ static void init_ndbrecord_info(Ndb &myN
* Simple example of intended usage of the new (SPJ) QueryBuilder API.
*
* STATUS:
- * Compilable code, but neither link nor execute.
+ * Compilable code, NdbQueryBuilder do some semantics checks.
*
*/
@@ -264,6 +402,7 @@ int testQueryBuilder(Ndb &myNdb)
NdbQueryBuilder myBuilder(myNdb);
/* qt1 is 'const defined' */
+ printf("q1\n");
NdbQueryDef* q1 = 0;
{
NdbQueryBuilder* qb = &myBuilder; //myDict->getQueryBuilder();
@@ -274,7 +413,7 @@ int testQueryBuilder(Ndb &myNdb)
0
};
const NdbQueryLookupOperationDef *readManager = qb->readTuple(manager, managerKey);
- if (readManager == NULL) APIERROR(myNdb.getNdbError());
+ if (readManager == NULL) APIERROR(qb->getNdbError());
q1 = qb->prepare();
if (q1 == NULL) APIERROR(qb->getNdbError());
@@ -286,6 +425,7 @@ int testQueryBuilder(Ndb &myNdb)
// NdbQueryLookupOperationDef illegalCopy2(*readManager);
}
+ printf("q2\n");
NdbQueryDef* q2 = 0;
{
NdbQueryBuilder* qb = &myBuilder; //myDict->getQueryBuilder();
@@ -298,13 +438,14 @@ int testQueryBuilder(Ndb &myNdb)
};
// Lookup on a single tuple with key define by 'managerKey' param. tuple
const NdbQueryLookupOperationDef* readManager = qb->readTuple(manager, managerKey);
- if (readManager == NULL) APIERROR(myNdb.getNdbError());
+ if (readManager == NULL) APIERROR(qb->getNdbError());
q2 = qb->prepare();
if (q2 == NULL) APIERROR(qb->getNdbError());
}
/**** UNFINISHED...
+ printf("q3\n");
NdbQueryDef* q3 = 0;
{
NdbQueryBuilder* qb = &myBuilder; //myDict->getQueryBuilder();
@@ -314,7 +455,7 @@ int testQueryBuilder(Ndb &myNdb)
};
// Lookup on a single tuple with key define by 'managerKey' param. tuple
const NdbQueryScanNode *scanManager = qb->scanIndex(manager, managerKey);
- if (scanManager == NULL) APIERROR(myNdb.getNdbError());
+ if (scanManager == NULL) APIERROR(qb->getNdbError());
q3 = qb->prepare();
if (q3 == NULL) APIERROR(qb->getNdbError());
@@ -341,19 +482,21 @@ int testQueryBuilder(Ndb &myNdb)
ManagerRow managerRow;
memset (&managerRow, 0, sizeof(managerRow));
+/*******
// Specify result handling NdbRecord style - need the (single) NdbQueryOperation:
assert(myQuery->getNoOfOperations()==1);
- assert (myQuery->getQueryOperation((Uint32)0) == myQuery->getRootOperation());
NdbQueryOperation* op = myQuery->getQueryOperation((Uint32)0);
op->setResultRowBuf(rowManagerRecord, (char*)&managerRow);
if (myTransaction->execute( NdbTransaction::NoCommit ) == -1)
APIERROR(myTransaction->getNdbError());
+******/
// All NdbQuery operations are handled as scans with cursor placed 'before'
// first record: Fetch next to retrieve result:
- if (myQuery->nextResult() != 0)
+ int res = myQuery->nextResult();
+ if (res == -1)
APIERROR(myQuery->getNdbError());
// NOW: Result is available in 'managerRow' buffer
@@ -370,6 +513,7 @@ int testQueryBuilder(Ndb &myNdb)
* select * from dept_manager join employees using(emp_no)
* where dept_no = 'd005' and emp_no = 110567;
*/
+ printf("q4\n");
NdbQueryDef* q4 = 0;
{
NdbQueryBuilder* qb = &myBuilder; //myDict->getQueryBuilder();
@@ -381,7 +525,7 @@ int testQueryBuilder(Ndb &myNdb)
};
// Lookup a single tuple with key define by 'managerKey' param. tuple
const NdbQueryLookupOperationDef *readManager = qb->readTuple(manager, managerKey);
- if (readManager == NULL) APIERROR(myNdb.getNdbError());
+ if (readManager == NULL) APIERROR(qb->getNdbError());
// THEN: employee table is joined:
// A linked value is used to let employee lookup refer values
@@ -392,7 +536,7 @@ int testQueryBuilder(Ndb &myNdb)
0
};
const NdbQueryLookupOperationDef* readEmployee = qb->readTuple(employee, empJoinKey);
- if (readEmployee == NULL) APIERROR(myNdb.getNdbError());
+ if (readEmployee == NULL) APIERROR(qb->getNdbError());
q4 = qb->prepare();
if (q4 == NULL) APIERROR(qb->getNdbError());
@@ -420,8 +564,13 @@ main(int argc, const char** argv){
//printf("sizeof(NdbOperation): %d\n", sizeof(NdbOperation));
//printf("sizeof(NdbScanOperation): %d\n", sizeof(NdbScanOperation));
//printf("sizeof(NdbIndexScanOperation): %d\n", sizeof(NdbIndexScanOperation));
-
-//printf("offset: %d\n", offsetof(NdbOperation, NdbOperation::m_type));
+ //printf("offset: %d\n", offsetof(NdbOperation, NdbOperation::m_type));
+
+
+ if (!createEmployeeDb())
+ { std::cout << "Create of employee DB failed" << std::endl;
+ exit(-1);
+ }
if (cluster_connection.connect(4, 5, 1))
{
@@ -439,10 +588,13 @@ main(int argc, const char** argv){
APIERROR(myNdb.getNdbError());
exit(-1);
}
+ std::cout << "Connected to Cluster\n";
+
/*******************************************
* Check table existence *
*******************************************/
+ if (true)
{
bool has_tables = true;
const NdbDictionary::Dictionary* myDict= myNdb.getDictionary();
=== modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2009-06-22 14:29:27 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2009-06-25 13:38:11 +0000
@@ -17,9 +17,11 @@
*/
#include <ndb_global.h>
+#include <Vector.hpp>
#include "Ndb.hpp"
#include "NdbQueryBuilder.hpp"
+#include "NdbQueryBuilderImpl.hpp"
#include "NdbDictionary.hpp"
/**
@@ -36,12 +38,10 @@
* 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.
- * - No explicit 'pimpl ptr' required in the interface. Impl object
- * available by casting the interface obj. to its Impl class.
* - Impl classes does not have to be friend of the interface classes.
*
* ::getImpl() functions has been defined for convenient access
- * all available interface classes.
+ * to all available interface classes.
*
* CODE STATUS:
* Except for creating the Query objects, the NdbQueryBuilder factory
@@ -50,10 +50,33 @@
*
*/
+static void
+setErrorCode(NdbQueryBuilderImpl* qb, int aErrorCode)
+{ qb->setErrorCode(aErrorCode);
+}
+
+static void
+setErrorCode(NdbQueryBuilder* qb, int aErrorCode)
+{ qb->getImpl().setErrorCode(aErrorCode);
+}
+
+
+//////////////////////////////////////////////////////////////////
+// Convenient macro for returning specific errorcodes if
+// 'cond' does not evaluate to true.
+//////////////////////////////////////////////////////////////////
+#define returnErrIf(cond,err) \
+ if (unlikely((cond))) \
+ { ::setErrorCode(this,err); \
+ return NULL; \
+ }
+
+
//////////////////////////////////////////////
// Implementation of NdbQueryOperand interface
//////////////////////////////////////////////
+
// Baseclass for the QueryOperand implementation
class NdbQueryOperandImpl
{
@@ -61,13 +84,19 @@ public:
const NdbDictionary::Column* getColumn() const
{ return m_column; };
+ virtual int bindOperand(const NdbDictionary::Column* column,
+ NdbQueryOperationDefImpl* operation)
+ { m_column = column;
+ return 0;
+ }
+
protected:
virtual ~NdbQueryOperandImpl() {};
NdbQueryOperandImpl()
: m_column(0) {}
private:
- const NdbDictionary::Column* m_column;
+ const NdbDictionary::Column* m_column; // Initial NULL, assigned w/ bindOperand()
}; // class NdbQueryOperandImpl
@@ -77,15 +106,20 @@ class NdbLinkedOperandImpl :
{
friend class NdbQueryBuilder; // Allow privat access from builder interface
+public:
+ virtual int bindOperand(const NdbDictionary::Column* column,
+ NdbQueryOperationDefImpl* operation);
+
private:
virtual ~NdbLinkedOperandImpl() {};
- NdbLinkedOperandImpl (const NdbQueryOperationDef* parent, const char* attr)
+ NdbLinkedOperandImpl (const NdbQueryOperationDef* parent,
+ const NdbDictionary::Column* column)
: NdbLinkedOperand(this), NdbQueryOperandImpl(),
- m_parent(parent), m_attr(attr)
+ m_parent(&parent->getImpl()), m_column(column)
{};
- const NdbQueryOperationDef* const m_parent;
- const char* const m_attr;
+ NdbQueryOperationDefImpl* const m_parent;
+ const NdbDictionary::Column* const m_column;
}; // class NdbLinkedOperandImpl
@@ -126,6 +160,11 @@ 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;
+
protected:
virtual ~NdbConstOperandImpl() {};
NdbConstOperandImpl ()
@@ -143,6 +182,7 @@ public:
NdbInt32ConstOperandImpl (Int32 value) : NdbConstOperandImpl(), m_value(value) {};
size_t getLength() const { return sizeof(m_value); };
const void* getAddr() const { return &m_value; };
+ NdbDictionary::Column::Type getType() const { return NdbDictionary::Column::Int; };
private:
const Int32 m_value;
};
@@ -153,6 +193,7 @@ public:
NdbUint32ConstOperandImpl (Uint32 value) : NdbConstOperandImpl(), m_value(value) {};
size_t getLength() const { return sizeof(m_value); };
const void* getAddr() const { return &m_value; };
+ NdbDictionary::Column::Type getType() const { return NdbDictionary::Column::Unsigned; };
private:
const Uint32 m_value;
};
@@ -163,6 +204,7 @@ public:
NdbInt64ConstOperandImpl (Int64 value) : NdbConstOperandImpl(), m_value(value) {};
size_t getLength() const { return sizeof(m_value); };
const void* getAddr() const { return &m_value; };
+ NdbDictionary::Column::Type getType() const { return NdbDictionary::Column::Bigint; };
private:
const Int64 m_value;
};
@@ -173,6 +215,7 @@ public:
NdbUint64ConstOperandImpl (Uint64 value) : NdbConstOperandImpl(), m_value(value) {};
size_t getLength() const { return sizeof(m_value); };
const void* getAddr() const { return &m_value; };
+ NdbDictionary::Column::Type getType() const { return NdbDictionary::Column::Bigunsigned; };
private:
const Uint64 m_value;
};
@@ -183,6 +226,7 @@ public:
NdbCharConstOperandImpl (const char* value) : NdbConstOperandImpl(), m_value(value) {};
size_t getLength() const { return strlen(m_value); };
const void* getAddr() const { return m_value; };
+ NdbDictionary::Column::Type getType() const { return NdbDictionary::Column::Char; };
private:
const char* const m_value;
};
@@ -196,6 +240,7 @@ public:
size_t getLength() const { return m_length; };
const void* getAddr() const { return m_value; };
+ NdbDictionary::Column::Type getType() const { return NdbDictionary::Column::Undefined; };
private:
const void* const m_value;
const size_t m_length;
@@ -223,16 +268,25 @@ public:
const NdbDictionary::Table* getTable() const
{ return m_table; };
+ void addParent(NdbQueryOperationDefImpl *);
+ void addChild(NdbQueryOperationDefImpl *);
+
protected:
virtual ~NdbQueryOperationDefImpl() {};
NdbQueryOperationDefImpl (
const NdbDictionary::Table* table,
const char* ident)
- : m_table(table), m_ident(ident) {};
+ : m_table(table), m_ident(ident),
+ m_parent(), m_child()
+ {};
private:
const NdbDictionary::Table* const m_table;
const char* const m_ident;
+
+ Vector<NdbQueryOperationDefImpl*> m_parent;
+ Vector<NdbQueryOperationDefImpl*> m_child;
+
}; // class NdbQueryOperationDefImpl
@@ -326,22 +380,32 @@ private:
}; // class NdbQueryIndexScanOperationDefImpl
+
+
class NdbQueryDefImpl : public NdbQueryDef
{
+public:
+ NdbQueryDefImpl();
+ ~NdbQueryDefImpl();
+
+
private:
+ Vector<NdbQueryOperationDefImpl*> m_operation;
+//Vector<NdbParamOperand*> m_paramOperand;
+//Vector<NdbConstOperand*> m_constOperand;
+//Vector<NdbLinkedOperand*> m_linkedOperand;
}; // class NdbQueryDefImpl
-/**
- * class NdbQueryBuilder is not (yet?) hidden in a pimpl object.
- *
- */
-// class NdbQueryBuilderImpl : public NdbQueryBuilder {};
-/*************************************************************************
- * Glue layer between NdbQueryOperand interface and its Impl'ementation.
- ************************************************************************/
+///////////////////////////////////////////////////
+/////// End 'Impl' class declarations /////////////
+///////////////////////////////////////////////////
+
NdbQueryDef::NdbQueryDef()
{}
+NdbQueryDef::~NdbQueryDef()
+{}
+
const NdbQueryOperationDef*
NdbQueryDef::getRootOperation() const
@@ -349,6 +413,12 @@ NdbQueryDef::getRootOperation() const
return NULL; // FIXME
}
+
+
+/*************************************************************************
+ * Glue layer between NdbQueryOperand interface and its Impl'ementation.
+ ************************************************************************/
+
NdbQueryOperand::NdbQueryOperand(NdbQueryOperandImpl* pimpl) : m_pimpl(pimpl)
{ assert(pimpl!=NULL); }
NdbConstOperand::NdbConstOperand(NdbQueryOperandImpl* pimpl) : NdbQueryOperand(pimpl)
@@ -509,11 +579,23 @@ NdbQueryLookupOperationDef::getIndex() c
* Implementation of NdbQueryBuilder factory
******************************************/
NdbQueryBuilder::NdbQueryBuilder(Ndb& ndb)
-: m_ndb(ndb), m_error()
+: m_pimpl(new NdbQueryBuilderImpl(ndb))
{}
NdbQueryBuilder::~NdbQueryBuilder()
-{}
+{ delete m_pimpl;
+}
+
+inline NdbQueryBuilderImpl&
+NdbQueryBuilder::getImpl() const
+{ return *m_pimpl;
+}
+
+const NdbError&
+NdbQueryBuilder::getNdbError() const
+{
+ return m_pimpl->getNdbError();
+}
//////////////////////////////////////////////////
// Implements different const datatypes by further
@@ -522,37 +604,57 @@ NdbQueryBuilder::~NdbQueryBuilder()
NdbConstOperand*
NdbQueryBuilder::constValue(const char* value)
{
+ returnErrIf(value==0,4800);
NdbConstOperandImpl* constOp = new NdbCharConstOperandImpl(value);
+ returnErrIf(constOp==0,4000);
+
+ m_pimpl->m_constOperand.push_back(constOp);
return constOp;
}
NdbConstOperand*
NdbQueryBuilder::constValue(const void* value, size_t length)
{
+ returnErrIf(value==0 && length>0,4800);
NdbConstOperandImpl* constOp = new NdbGenericConstOperandImpl(value,length);
+ returnErrIf(constOp==0,4000);
+
+ m_pimpl->m_constOperand.push_back(constOp);
return constOp;
}
NdbConstOperand*
NdbQueryBuilder::constValue(Int32 value)
{
NdbConstOperandImpl* constOp = new NdbInt32ConstOperandImpl(value);
+ returnErrIf(constOp==0,4000);
+
+ m_pimpl->m_constOperand.push_back(constOp);
return constOp;
}
NdbConstOperand*
NdbQueryBuilder::constValue(Uint32 value)
{
NdbConstOperandImpl* constOp = new NdbUint32ConstOperandImpl(value);
+ returnErrIf(constOp==0,4000);
+
+ m_pimpl->m_constOperand.push_back(constOp);
return constOp;
}
NdbConstOperand*
NdbQueryBuilder::constValue(Int64 value)
{
NdbConstOperandImpl* constOp = new NdbInt64ConstOperandImpl(value);
+ returnErrIf(constOp==0,4000);
+
+ m_pimpl->m_constOperand.push_back(constOp);
return constOp;
}
NdbConstOperand*
NdbQueryBuilder::constValue(Uint64 value)
{
NdbConstOperandImpl* constOp = new NdbUint64ConstOperandImpl(value);
+ returnErrIf(constOp==0,4000);
+
+ m_pimpl->m_constOperand.push_back(constOp);
return constOp;
}
@@ -560,17 +662,29 @@ NdbParamOperand*
NdbQueryBuilder::paramValue(const char* name)
{
NdbParamOperandImpl* paramOp = new NdbParamOperandImpl(name);
+ returnErrIf(paramOp==0,4000);
+
+ m_pimpl->m_paramOperand.push_back(paramOp);
return paramOp;
}
NdbLinkedOperand*
NdbQueryBuilder::linkedValue(const NdbQueryOperationDef* parent, const char* attr)
{
- if (parent && attr)
- { NdbLinkedOperandImpl* linkedOp = new NdbLinkedOperandImpl(parent,attr);
- return linkedOp;
- }
- return NULL;
+ returnErrIf(parent==0 || attr==0, 4800); // Required non-NULL arguments
+
+ // Parent should be a OperationDef contained in this query builder context
+ returnErrIf(!m_pimpl->contains(&parent->getImpl()), 4804); // Unknown parent
+
+ // 'attr' should refer a column from the underlying table in parent:
+ const NdbDictionary::Column* column = parent->getTable()->getColumn(attr);
+ returnErrIf(column==0, 4805); // Unknown column
+
+ NdbLinkedOperandImpl* linkedOp = new NdbLinkedOperandImpl(parent,column);
+ returnErrIf(linkedOp==0, 4000);
+
+ m_pimpl->m_linkedOperand.push_back(linkedOp);
+ return linkedOp;
}
@@ -579,31 +693,68 @@ NdbQueryBuilder::readTuple(const NdbDict
const NdbQueryOperand* const keys[], // Terminated by NULL element
const char* ident)
{
- if (table)
+ if (m_pimpl->hasError())
+ return NULL;
+
+ int i;
+ returnErrIf(table==0 || keys==0, 4800); // Required non-NULL arguments
+
+ // All column values being part of primary key should be specified:
+ int keyfields = table->getNoOfPrimaryKeys();
+ int colcount = table->getNoOfColumns();
+
+ // Check: keys[] are specified for all fields in PK
+ for (i=0; i<keyfields; ++i)
{
- NdbQueryLookupOperationDefImpl* op =
- new NdbQueryLookupOperationDefImpl(table,keys,ident);
- return op;
+ returnErrIf(keys[i]==NULL, 4801); // A 'Key' value is undefineds
}
+ // Check for propper NULL termination of keys[] spec
+ returnErrIf(keys[keyfields]!=NULL, 4802);
+
+ NdbQueryLookupOperationDefImpl* op =
+ new NdbQueryLookupOperationDefImpl(table,keys,ident);
+ returnErrIf(op==0, 4000);
-// setOperationErrorCodeAbort(4271);
- return NULL;
+ int keyindex = 0;
+ for (i=0; i<colcount; ++i)
+ {
+ const NdbDictionary::Column *col = table->getColumn(i);
+ if (col->getPrimaryKey())
+ {
+ int error = keys[keyindex]->getImpl().bindOperand(col,op);
+ if (unlikely(error))
+ { m_pimpl->setErrorCode(error);
+ delete op;
+ return NULL;
+ }
+
+ keyindex++;
+ if (keyindex >= keyfields)
+ break; // Seen all PK fields
+ }
+ }
+
+ m_pimpl->m_operation.push_back(op);
+ return op;
}
+
NdbQueryLookupOperationDef*
NdbQueryBuilder::readTuple(const NdbDictionary::Index* index, // Unique key lookup w/ index
const NdbDictionary::Table* table, // Primary key lookup
const NdbQueryOperand* const keys[], // Terminated by NULL element
const char* ident)
{
- if (index && table)
- {
- NdbQueryLookupOperationDefImpl* op =
- new NdbQueryLookupOperationDefImpl(index,table,keys,ident);
- return op;
- }
-// setOperationErrorCodeAbort(4271);
- return NULL;
+ if (m_pimpl->hasError())
+ return NULL;
+ returnErrIf(table==0 || index==0 || keys==0, 4800); // Required non-NULL arguments
+
+ NdbQueryLookupOperationDefImpl* op =
+ new NdbQueryLookupOperationDefImpl(index,table,keys,ident);
+ returnErrIf(op==0, 4000);
+
+ m_pimpl->m_operation.push_back(op);
+ return op;
}
@@ -611,9 +762,15 @@ NdbQueryTableScanOperationDef*
NdbQueryBuilder::scanTable(const NdbDictionary::Table* table,
const char* ident)
{
+ if (m_pimpl->hasError())
+ return NULL;
+ returnErrIf(table==0, 4800); // Required non-NULL arguments
+
NdbQueryTableScanOperationDefImpl* op =
new NdbQueryTableScanOperationDefImpl(table,ident);
+ returnErrIf(op==0, 4000);
+ m_pimpl->m_operation.push_back(op);
return op;
}
@@ -624,21 +781,147 @@ NdbQueryBuilder::scanIndex(const NdbDict
const NdbQueryIndexBound* bound,
const char* ident)
{
+ if (m_pimpl->hasError())
+ return NULL;
+ returnErrIf(table==0 || index==0 || bound==0, 4800); // Required non-NULL arguments
+
NdbQueryIndexScanOperationDefImpl* op =
new NdbQueryIndexScanOperationDefImpl(index,table,bound,ident);
+ returnErrIf(op==0, 4000);
+ m_pimpl->m_operation.push_back(op);
return op;
}
+NdbQueryDef*
+NdbQueryBuilder::prepare()
+{
+ return m_pimpl->prepare();
+}
+
+////////////////////////////////////////
+// The (hidden) Impl of NdbQueryBuilder
+////////////////////////////////////////
+NdbQueryBuilderImpl::NdbQueryBuilderImpl(Ndb& ndb)
+: m_ndb(ndb), m_error(), m_operation(),
+ m_paramOperand(), m_constOperand(), m_linkedOperand()
+{}
+
+NdbQueryBuilderImpl::~NdbQueryBuilderImpl()
+{
+ // FIXME: Delete all operand and operator in Vector's
+}
+
+
+bool
+NdbQueryBuilderImpl::contains(const NdbQueryOperationDefImpl* opDef)
+{
+ for (int i=0; i<m_operation.size(); ++i)
+ { if (m_operation[i] == opDef)
+ return true;
+ }
+ return false;
+}
NdbQueryDef*
-NdbQueryBuilder::prepare()
+NdbQueryBuilderImpl::prepare()
+{
+ int i;
+
+/****
+ // FIXME: Build parent/child operation references
+ // Install named OperationDef's in HashMap
+ for (i = 0; i<m_operation.size(); ++i)
+ { const NdbQueryOperationDef *def = m_operation[i];
+ }
+****/
+
+ NdbQueryDef* def = new NdbQueryDefImpl();
+ returnErrIf(def==0, 4000);
+
+ // TODO: Copy or handover of below Operand and Operations to NdbQueryDef:
+
+ m_operation.clear();
+ m_paramOperand.clear();
+ m_constOperand.clear();
+ m_linkedOperand.clear();
+
+ return def;
+}
+
+
+
+void
+NdbQueryOperationDefImpl::addParent(NdbQueryOperationDefImpl *operation)
+{
+ for (int i=0; i<m_parent.size(); ++i)
+ { if (m_parent[i] == operation)
+ return;
+ }
+ m_parent.push_back(operation);
+}
+
+void
+NdbQueryOperationDefImpl::addChild(NdbQueryOperationDefImpl *operation)
{
- return new NdbQueryDefImpl();
+ for (int i=0; i<m_child.size(); ++i)
+ { if (m_child[i] == operation)
+ return;
+ }
+ m_child.push_back(operation);
}
+int
+NdbLinkedOperandImpl::bindOperand(
+ const NdbDictionary::Column* column,
+ NdbQueryOperationDefImpl* operation)
+{
+ NdbDictionary::Column::Type type = column->getType();
+ if (type != m_column->getType())
+ return 4803; // Incompatible datatypes
+
+ // TODO? Check length if Char, and prec,scale if decimal type
+
+ // Register parent/child relations
+ this->m_parent->addChild(operation);
+ operation->addParent(this->m_parent);
+
+ return NdbQueryOperandImpl::bindOperand(column,operation);
+}
+
+
+int
+NdbConstOperandImpl::bindOperand(
+ const NdbDictionary::Column* column,
+ NdbQueryOperationDefImpl* operation)
+{
+ NdbDictionary::Column::Type type = column->getType();
+ if (type != this->getType())
+ return 4803; // Incompatible datatypes
+
+ // TODO? Check length if Char, and prec,scale if decimal type
+
+ return NdbQueryOperandImpl::bindOperand(column,operation);
+}
+
+
+NdbQueryDefImpl::NdbQueryDefImpl()
+{}
+NdbQueryDefImpl::~NdbQueryDefImpl()
+{
+ // FIXME: Release elements in Vector<>
+}
+
+
+// Instantiate Vector templates
+template class Vector<NdbQueryOperationDefImpl*>;
+template class Vector<NdbParamOperandImpl*>;
+template class Vector<NdbConstOperandImpl*>;
+template class Vector<NdbLinkedOperandImpl*>;
+
+
#if 0
/**********************************************
* Simple hack for module test & experimenting
=== added file 'storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 2009-06-25 13:38:11 +0000
@@ -0,0 +1,67 @@
+/*
+ Copyright (C) 2009 Sun Microsystems Inc
+ All rights reserved. Use is subject to license terms.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+
+#ifndef NdbQueryBuilderImpl_H
+#define NdbQueryBuilderImpl_H
+
+
+#include <Vector.hpp>
+
+class NdbQueryOperationDefImpl;
+class NdbParamOperandImpl;
+class NdbConstOperandImpl;
+class NdbLinkedOperandImpl;
+
+
+class NdbQueryBuilderImpl
+{
+ friend class NdbQueryBuilder;
+
+public:
+ ~NdbQueryBuilderImpl();
+ NdbQueryBuilderImpl(Ndb& ndb);
+
+ class NdbQueryDef* prepare();
+
+ const NdbError& getNdbError() const;
+
+ void setErrorCode(int aErrorCode)
+ { if (!m_error.code)
+ m_error.code = aErrorCode;
+ }
+
+private:
+ bool hasError() const
+ { return (m_error.code!=0); }
+
+ bool contains(const NdbQueryOperationDefImpl*);
+
+ Ndb& m_ndb;
+ NdbError m_error;
+
+ Vector<NdbQueryOperationDefImpl*> m_operation;
+ Vector<NdbParamOperandImpl*> m_paramOperand;
+ Vector<NdbConstOperandImpl*> m_constOperand;
+ Vector<NdbLinkedOperandImpl*> m_linkedOperand;
+
+}; // class NdbQueryBuilderImpl
+
+
+
+#endif
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2009-06-25 09:13:50 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2009-06-25 13:38:11 +0000
@@ -55,9 +55,9 @@ NdbQuery::getQueryOperation(const char*
}
NdbQueryOperation*
-NdbQuery::getQueryOperation(Uint32 ident) const
+NdbQuery::getQueryOperation(Uint32 index) const
{
- return m_pimpl->getQueryOperation(ident);
+ return m_pimpl->getQueryOperation(index);
}
Uint32
@@ -285,7 +285,7 @@ NdbQueryImpl::getQueryOperation(const ch
}
NdbQueryOperation*
-NdbQueryImpl::getQueryOperation(Uint32 ident) const
+NdbQueryImpl::getQueryOperation(Uint32 index) const
{
return NULL; // FIXME
}
@@ -475,6 +475,13 @@ NdbQueryOperationImpl::setResultRowBuf (
char* resBuffer,
const unsigned char* result_mask)
{
+/***
+ if (rec->tableId != m_table->tableId)
+ {
+ setErrorCode(4287);
+ return -1;
+ }
+***/
return 0; // FIXME
}
@@ -484,6 +491,13 @@ NdbQueryOperationImpl::setResultRowRef (
char* & bufRef,
const unsigned char* result_mask)
{
+/***
+ if (rec->tableId != m_table->tableId)
+ {
+ setErrorCode(4287);
+ return -1;
+ }
+***/
return 0; // FIXME
}
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp 2009-06-25 09:13:50 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp 2009-06-25 13:38:11 +0000
@@ -110,7 +110,8 @@ private:
/** We should receive the same number of TCKEYCONF and TRANSID_AI messages.
This is the (possibly negative) no of such messages pending.*/
//int m_missingTransidAIs;
-}; // class QueryImpl
+}; // class NdbQueryImpl
+
// Compiler settings require explicit instantiation.
template class Vector<NdbQueryOperationImpl*>;
=== modified file 'storage/ndb/src/ndbapi/Ndberr.cpp'
--- a/storage/ndb/src/ndbapi/Ndberr.cpp 2009-06-21 21:42:48 +0000
+++ b/storage/ndb/src/ndbapi/Ndberr.cpp 2009-06-25 13:38:11 +0000
@@ -22,7 +22,7 @@
#include "NdbDictionaryImpl.hpp"
#include <NdbOperation.hpp>
#include <NdbTransaction.hpp>
-#include "NdbQueryBuilder.hpp"
+#include "NdbQueryBuilderImpl.hpp"
#include "NdbQueryOperationImpl.hpp"
#include <NdbBlob.hpp>
#include "NdbEventOperationImpl.hpp"
@@ -94,7 +94,7 @@ NdbDictInterface::getNdbError() const {
const
NdbError &
-NdbQueryBuilder::getNdbError() const {
+NdbQueryBuilderImpl::getNdbError() const {
update(m_error);
return m_error;
}
=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c 2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c 2009-06-25 13:38:11 +0000
@@ -95,6 +95,7 @@ static const char* empty_string = "";
* 4500 - ""
* 4600 - ""
* 4700 - "" Event
+ * 4800 - API, QueryBuilder
* 5000 - Management server
*/
@@ -720,6 +721,17 @@ ErrorBundle ErrorCodes[] = {
{ 2811, DMEC, TR, "Error with file permissions, please check file system" },
{ 2815, DMEC, TR, "Error in reading files, please check file system" },
+ /**
+ * NdbQueryBuilder API errors
+ */
+ { 4800, DMEC, AE, "Required argument is NULL" },
+ { 4801, DMEC, AE, "All required 'key' values was not specified" },
+ { 4802, DMEC, AE, "Too many 'key' values was specified" },
+ { 4803, DMEC, AE, "Incompatible datatype specified in operand argument" },
+ { 4804, DMEC, AE, "Unknown 'parent' specified in linkedValue" },
+ { 4805, DMEC, AE, "Unknown 'column' specified in linkedValue" },
+
+
{ NO_CONTACT_WITH_PROCESS, DMEC, AE,
"No contact with the process (dead ?)."},
{ WRONG_PROCESS_TYPE, DMEC, AE,
Attachment: [text/bzr-bundle] bzr/ole.john.aske@sun.com-20090625133811-vlcro0mit6eatdsy.bundle
| Thread |
|---|
| • bzr push into mysql-5.1-telco-7.0-spj branch (ole.john.aske:2899 to 2900) | Ole John Aske | 25 Jun |