correct NAND/NOR scan operations, and add a test case for it.

parent 6b3ace03
...@@ -41,7 +41,9 @@ public: ...@@ -41,7 +41,9 @@ public:
int m_label; int m_label;
State m_current; State m_current;
Uint32 m_negative; //used for translating NAND/NOR to AND/OR, equal 0 or 1
Vector<State> m_stack; Vector<State> m_stack;
Vector<Uint32> m_stack2; //to store info of m_negative
NdbOperation * m_operation; NdbOperation * m_operation;
Uint32 m_latestAttrib; Uint32 m_latestAttrib;
...@@ -65,6 +67,7 @@ NdbScanFilter::NdbScanFilter(class NdbOperation * op) ...@@ -65,6 +67,7 @@ NdbScanFilter::NdbScanFilter(class NdbOperation * op)
m_impl.m_label = 0; m_impl.m_label = 0;
m_impl.m_latestAttrib = ~0; m_impl.m_latestAttrib = ~0;
m_impl.m_operation = op; m_impl.m_operation = op;
m_impl.m_negative = 0;
} }
NdbScanFilter::~NdbScanFilter(){ NdbScanFilter::~NdbScanFilter(){
...@@ -74,18 +77,39 @@ NdbScanFilter::~NdbScanFilter(){ ...@@ -74,18 +77,39 @@ NdbScanFilter::~NdbScanFilter(){
int int
NdbScanFilter::begin(Group group){ NdbScanFilter::begin(Group group){
m_impl.m_stack2.push_back(m_impl.m_negative);
switch(group){ switch(group){
case NdbScanFilter::AND: case NdbScanFilter::AND:
INT_DEBUG(("Begin(AND)")); INT_DEBUG(("Begin(AND)"));
if(m_impl.m_negative == 1){
group = NdbScanFilter::OR;
}
break; break;
case NdbScanFilter::OR: case NdbScanFilter::OR:
INT_DEBUG(("Begin(OR)")); INT_DEBUG(("Begin(OR)"));
if(m_impl.m_negative == 1){
group = NdbScanFilter::AND;
}
break; break;
case NdbScanFilter::NAND: case NdbScanFilter::NAND:
INT_DEBUG(("Begin(NAND)")); INT_DEBUG(("Begin(NAND)"));
if(m_impl.m_negative == 0){
group = NdbScanFilter::OR;
m_impl.m_negative = 1;
}else{
group = NdbScanFilter::AND;
m_impl.m_negative = 0;
}
break; break;
case NdbScanFilter::NOR: case NdbScanFilter::NOR:
INT_DEBUG(("Begin(NOR)")); INT_DEBUG(("Begin(NOR)"));
if(m_impl.m_negative == 0){
group = NdbScanFilter::AND;
m_impl.m_negative = 1;
}else{
group = NdbScanFilter::OR;
m_impl.m_negative = 0;
}
break; break;
} }
...@@ -129,6 +153,13 @@ NdbScanFilter::begin(Group group){ ...@@ -129,6 +153,13 @@ NdbScanFilter::begin(Group group){
int int
NdbScanFilter::end(){ NdbScanFilter::end(){
if(m_impl.m_stack2.size() == 0){
m_impl.m_operation->setErrorCodeAbort(4259);
return -1;
}
m_impl.m_negative = m_impl.m_stack2.back();
m_impl.m_stack2.erase(m_impl.m_stack2.size() - 1);
switch(m_impl.m_current.m_group){ switch(m_impl.m_current.m_group){
case NdbScanFilter::AND: case NdbScanFilter::AND:
INT_DEBUG(("End(AND pc=%d)", m_impl.m_current.m_popCount)); INT_DEBUG(("End(AND pc=%d)", m_impl.m_current.m_popCount));
...@@ -150,6 +181,10 @@ NdbScanFilter::end(){ ...@@ -150,6 +181,10 @@ NdbScanFilter::end(){
} }
NdbScanFilterImpl::State tmp = m_impl.m_current; NdbScanFilterImpl::State tmp = m_impl.m_current;
if(m_impl.m_stack.size() == 0){
m_impl.m_operation->setErrorCodeAbort(4259);
return -1;
}
m_impl.m_current = m_impl.m_stack.back(); m_impl.m_current = m_impl.m_stack.back();
m_impl.m_stack.erase(m_impl.m_stack.size() - 1); m_impl.m_stack.erase(m_impl.m_stack.size() - 1);
...@@ -394,8 +429,17 @@ NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, ...@@ -394,8 +429,17 @@ NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op,
m_operation->setErrorCodeAbort(4260); m_operation->setErrorCodeAbort(4260);
return -1; return -1;
} }
StrBranch2 branch;
if(m_negative == 1){ //change NdbOperation to its negative
if(m_current.m_group == NdbScanFilter::AND)
branch = table3[op].m_branches[(Uint32)(m_current.m_group) + 1];
if(m_current.m_group == NdbScanFilter::OR)
branch = table3[op].m_branches[(Uint32)(m_current.m_group) - 1];
}else{
branch = table3[op].m_branches[(Uint32)(m_current.m_group)];
}
StrBranch2 branch = table3[op].m_branches[m_current.m_group];
const NdbDictionary::Column * col = const NdbDictionary::Column * col =
m_operation->m_currentTable->getColumn(AttrId); m_operation->m_currentTable->getColumn(AttrId);
......
...@@ -325,6 +325,12 @@ public: ...@@ -325,6 +325,12 @@ public:
// supply argc and argv as parameters // supply argc and argv as parameters
int execute(int, const char**); int execute(int, const char**);
// NDBT's test tables are fixed and it always create
// and drop fixed table when execute, add this method
// in order to run CTX only and adapt to some new
// customized testsuite
int executeOneCtx(Ndb_cluster_connection&,
const NdbDictionary::Table* ptab, const char* testname = NULL);
// These function can be used from main in the test program // These function can be used from main in the test program
// to control the behaviour of the testsuite // to control the behaviour of the testsuite
......
...@@ -39,6 +39,7 @@ testOperations \ ...@@ -39,6 +39,7 @@ testOperations \
testRestartGci \ testRestartGci \
testScan \ testScan \
testInterpreter \ testInterpreter \
testScanFilter \
testScanInterpreter \ testScanInterpreter \
testScanPerf \ testScanPerf \
testSystemRestart \ testSystemRestart \
...@@ -83,6 +84,7 @@ testOperations_SOURCES = testOperations.cpp ...@@ -83,6 +84,7 @@ testOperations_SOURCES = testOperations.cpp
testRestartGci_SOURCES = testRestartGci.cpp testRestartGci_SOURCES = testRestartGci.cpp
testScan_SOURCES = testScan.cpp ScanFunctions.hpp testScan_SOURCES = testScan.cpp ScanFunctions.hpp
testInterpreter_SOURCES = testInterpreter.cpp testInterpreter_SOURCES = testInterpreter.cpp
testScanFilter_SOURCES = testScanFilter.cpp
testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp
testScanPerf_SOURCES = testScanPerf.cpp testScanPerf_SOURCES = testScanPerf.cpp
testSystemRestart_SOURCES = testSystemRestart.cpp testSystemRestart_SOURCES = testSystemRestart.cpp
......
This diff is collapsed.
...@@ -817,6 +817,63 @@ NDBT_TestSuite::executeOne(Ndb_cluster_connection& con, ...@@ -817,6 +817,63 @@ NDBT_TestSuite::executeOne(Ndb_cluster_connection& con,
} }
} }
int
NDBT_TestSuite::executeOneCtx(Ndb_cluster_connection& con,
const NdbDictionary::Table *ptab, const char* _testname){
testSuiteTimer.doStart();
do{
if(tests.size() == 0)
break;
Ndb ndb(&con, "TEST_DB");
ndb.init(1024);
int result = ndb.waitUntilReady(300); // 5 minutes
if (result != 0){
g_err << name <<": Ndb was not ready" << endl;
break;
}
ndbout << name << " started [" << getDate() << "]" << endl;
ndbout << "|- " << ptab->getName() << endl;
for (unsigned t = 0; t < tests.size(); t++){
if (_testname != NULL &&
strcasecmp(tests[t]->getName(), _testname) != 0)
continue;
tests[t]->initBeforeTest();
ctx = new NDBT_Context(con);
ctx->setTab(ptab);
ctx->setNumRecords(records);
ctx->setNumLoops(loops);
if(remote_mgm != NULL)
ctx->setRemoteMgm(remote_mgm);
ctx->setSuite(this);
result = tests[t]->execute(ctx);
if (result != NDBT_OK)
numTestsFail++;
else
numTestsOk++;
numTestsExecuted++;
delete ctx;
}
if (numTestsFail > 0)
break;
}while(0);
testSuiteTimer.doStop();
int res = report(_testname);
return NDBT_ProgramExit(res);
}
void NDBT_TestSuite::execute(Ndb_cluster_connection& con, void NDBT_TestSuite::execute(Ndb_cluster_connection& con,
Ndb* ndb, const NdbDictionary::Table* pTab, Ndb* ndb, const NdbDictionary::Table* pTab,
const char* _testname){ const char* _testname){
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment