1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
#include <NDBT_Test.hpp>
29
for(size_t i = 0; i < attriblist.size(); i++){
33
void buildAttribList(const NdbDictionary::Table* pTab);
34
Vector<Attrib*> attriblist;
38
// Functions that help out in testing that we may call
39
// scan functions in wrong order etc
40
// and receive a proper errormessage
43
ScanFunctions(const NdbDictionary::Table& _tab) : tab(_tab){
48
ExecuteScanWithOutOpenScan,
50
OnlyOneOpBeforeOpenScan,
53
CheckInactivityTimeOut,
54
CheckInactivityBeforeClose ,
60
int scanReadFunctions(Ndb* pNdb,
66
const NdbDictionary::Table& tab;
72
ScanFunctions::scanReadFunctions(Ndb* pNdb,
78
const int retryMax = 100;
81
NdbConnection *pTrans = 0;
82
NdbScanOperation *pOp = 0;
85
if (retryAttempt >= retryMax){
86
g_err << "ERROR: has retried this operation " << retryAttempt
87
<< " times, failing!" << endl;
91
pTrans = pNdb->startTransaction();
93
const NdbError err = pNdb->getNdbError();
94
if (err.status == NdbError::TemporaryError){
96
NdbSleep_MilliSleep(50);
104
// Execute the scan without defining a scan operation
105
pOp = pTrans->getNdbScanOperation(tab.getName());
107
ERR(pTrans->getNdbError());
108
pNdb->closeTransaction(pTrans);
112
if( pOp->readTuples(exclusive ?
113
NdbScanOperation::LM_Exclusive :
114
NdbScanOperation::LM_Read) ) {
115
ERR(pTrans->getNdbError());
116
pNdb->closeTransaction(pTrans);
121
if (action == OnlyOpenScanOnce){
122
// Call openScan one more time when it's already defined
123
if( pOp->readTuples(NdbScanOperation::LM_Read) ) {
124
ERR(pTrans->getNdbError());
125
pNdb->closeTransaction(pTrans);
130
if (action==EqualAfterOpenScan){
131
check = pOp->equal(tab.getColumn(0)->getName(), 10);
133
ERR(pTrans->getNdbError());
134
pNdb->closeTransaction(pTrans);
139
check = pOp->interpret_exit_ok();
141
ERR(pTrans->getNdbError());
142
pNdb->closeTransaction(pTrans);
146
for(int a = 0; a<tab.getNoOfColumns(); a++){
147
if(pOp->getValue(tab.getColumn(a)->getName()) == NULL) {
148
ERR(pTrans->getNdbError());
149
pNdb->closeTransaction(pTrans);
154
check = pTrans->execute(NoCommit);
156
ERR(pTrans->getNdbError());
157
pNdb->closeTransaction(pTrans);
161
int abortCount = records / 10;
162
bool abortTrans = (action==CloseWithoutStop);
165
eof = pOp->nextResult();
170
if (abortCount == rows && abortTrans == true){
171
g_info << "Scan is aborted after "<<abortCount<<" rows" << endl;
173
if (action != CloseWithoutStop){
174
// Test that we can closeTrans without stopScan
177
ERR(pTrans->getNdbError());
178
pNdb->closeTransaction(pTrans);
184
pNdb->closeTransaction(pTrans);
188
if(action == CheckInactivityTimeOut){
189
if ((rows % (records / 10)) == 0){
190
// Sleep for a long time before calling nextScanResult
193
g_info << "Sleeping "<<sleepTime<<" secs " << endl;
194
NdbSleep_SecSleep(sleepTime);
198
eof = pOp->nextResult();
201
const NdbError err = pTrans->getNdbError();
203
if (err.status == NdbError::TemporaryError){
206
// Be cruel, call nextScanResult after error
207
for(int i=0; i<10; i++){
208
eof = pOp->nextResult();
210
g_err << "nextScanResult returned eof = " << eof << endl
211
<< " That is an error when there are no more records" << endl;
217
pNdb->closeTransaction(pTrans);
218
NdbSleep_MilliSleep(50);
220
g_info << "Starting over" << endl;
222
// If test is CheckInactivityTimeOut
223
// error 296 is expected
224
if ((action == CheckInactivityTimeOut) &&
231
pNdb->closeTransaction(pTrans);
235
if (action == NextScanWhenNoMore){
236
g_info << "Calling nextScanresult when there are no more records" << endl;
237
for(int i=0; i<10; i++){
238
eof = pOp->nextResult();
240
g_err << "nextScanResult returned eof = " << eof << endl
241
<< " That is an error when there are no more records" << endl;
247
if(action == CheckInactivityBeforeClose){
248
// Sleep for a long time before calling close
249
g_info << "NdbSleep_SecSleep(5) before close transaction" << endl;
250
NdbSleep_SecSleep(5);
252
if(action == NoCloseTransaction)
253
g_info << "Forgetting to close transaction" << endl;
255
pNdb->closeTransaction(pTrans);
257
g_info << rows << " rows have been read" << endl;
258
if (records != 0 && rows != records){
259
g_err << "Check expected number of records failed" << endl
260
<< " expected=" << records <<", " << endl
261
<< " read=" << rows << endl;
272
void AttribList::buildAttribList(const NdbDictionary::Table* pTab){
276
// Build attrib definitions that describes which attributes to read
277
// Try to build strange combinations, not just "all" or all PK's
279
// Scan without reading any attributes
281
attr->numAttribs = 0;
282
attriblist.push_back(attr);
284
for(i = 1; i < pTab->getNoOfColumns(); i++){
286
attr->numAttribs = i;
287
for(int a = 0; a<i; a++)
288
attr->attribs[a] = a;
289
attriblist.push_back(attr);
291
for(i = pTab->getNoOfColumns()-1; i > 0; i--){
293
attr->numAttribs = i;
294
for(int a = 0; a<i; a++)
295
attr->attribs[a] = a;
296
attriblist.push_back(attr);
298
for(i = pTab->getNoOfColumns(); i > 0; i--){
300
attr->numAttribs = pTab->getNoOfColumns() - i;
301
for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
302
attr->attribs[a] = pTab->getNoOfColumns()-a-1;
303
attriblist.push_back(attr);
305
for(i = 1; i < pTab->getNoOfColumns(); i++){
307
attr->numAttribs = pTab->getNoOfColumns() - i;
308
for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
309
attr->attribs[a] = pTab->getNoOfColumns()-a-1;
310
attriblist.push_back(attr);
312
for(i = 1; i < pTab->getNoOfColumns(); i++){
314
attr->numAttribs = 2;
315
for(int a = 0; a<2; a++){
316
attr->attribs[a] = i%pTab->getNoOfColumns();
318
attriblist.push_back(attr);
323
attr->numAttribs = 1;
324
attr->attribs[0] = pTab->getNoOfColumns()-1;
325
attriblist.push_back(attr);
329
attr->numAttribs = 2;
330
attr->attribs[0] = pTab->getNoOfColumns()-1;
331
attr->attribs[1] = 0;
332
attriblist.push_back(attr);
336
attr->numAttribs = 2;
337
attr->attribs[0] = 0;
338
attr->attribs[1] = pTab->getNoOfColumns()-1;
339
attriblist.push_back(attr);
342
for(size_t j = 0; j < attriblist.size(); j++){
344
g_info << attriblist[j]->numAttribs << ": " ;
345
for(int a = 0; a < attriblist[j]->numAttribs; a++)
346
g_info << attriblist[j]->attribs[a] << ", ";