mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / test / ndbapi / ScanFunctions.hpp
blob81729d67114beaab2d0ce6833daabf9d1f04f754
1 /* Copyright (c) 2003-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <NDBT.hpp>
17 #include <NDBT_Test.hpp>
21 struct Attrib {
22 int numAttribs;
23 int attribs[1024];
25 class AttribList {
26 public:
27 AttribList(){};
28 ~AttribList(){
29 for(size_t i = 0; i < attriblist.size(); i++){
30 delete attriblist[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
41 class ScanFunctions {
42 public:
43 ScanFunctions(const NdbDictionary::Table& _tab) : tab(_tab){
45 enum ActionType {
46 CloseWithoutStop,
47 NextScanWhenNoMore,
48 ExecuteScanWithOutOpenScan,
49 OnlyOneScanPerTrans,
50 OnlyOneOpBeforeOpenScan,
51 OnlyOpenScanOnce,
52 OnlyOneOpInScanTrans,
53 CheckInactivityTimeOut,
54 CheckInactivityBeforeClose ,
55 NoCloseTransaction,
56 EqualAfterOpenScan
60 int scanReadFunctions(Ndb* pNdb,
61 int records,
62 int parallelism,
63 ActionType action,
64 bool exclusive);
65 private:
66 const NdbDictionary::Table& tab;
70 inline
71 int
72 ScanFunctions::scanReadFunctions(Ndb* pNdb,
73 int records,
74 int parallelism,
75 ActionType action,
76 bool exclusive){
77 int retryAttempt = 0;
78 const int retryMax = 100;
79 int sleepTime = 10;
80 int check;
81 NdbConnection *pTrans = 0;
82 NdbScanOperation *pOp = 0;
84 while (true){
85 if (retryAttempt >= retryMax){
86 g_err << "ERROR: has retried this operation " << retryAttempt
87 << " times, failing!" << endl;
88 return NDBT_FAILED;
91 pTrans = pNdb->startTransaction();
92 if (pTrans == NULL) {
93 const NdbError err = pNdb->getNdbError();
94 if (err.status == NdbError::TemporaryError){
95 ERR(err);
96 NdbSleep_MilliSleep(50);
97 retryAttempt++;
98 continue;
100 ERR(err);
101 return NDBT_FAILED;
104 // Execute the scan without defining a scan operation
105 pOp = pTrans->getNdbScanOperation(tab.getName());
106 if (pOp == NULL) {
107 ERR(pTrans->getNdbError());
108 pNdb->closeTransaction(pTrans);
109 return NDBT_FAILED;
112 if( pOp->readTuples(exclusive ?
113 NdbScanOperation::LM_Exclusive :
114 NdbScanOperation::LM_Read) ) {
115 ERR(pTrans->getNdbError());
116 pNdb->closeTransaction(pTrans);
117 return NDBT_FAILED;
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);
126 return NDBT_FAILED;
130 if (action==EqualAfterOpenScan){
131 check = pOp->equal(tab.getColumn(0)->getName(), 10);
132 if( check == -1 ) {
133 ERR(pTrans->getNdbError());
134 pNdb->closeTransaction(pTrans);
135 return NDBT_FAILED;
139 check = pOp->interpret_exit_ok();
140 if( check == -1 ) {
141 ERR(pTrans->getNdbError());
142 pNdb->closeTransaction(pTrans);
143 return NDBT_FAILED;
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);
150 return NDBT_FAILED;
154 check = pTrans->execute(NoCommit);
155 if( check == -1 ) {
156 ERR(pTrans->getNdbError());
157 pNdb->closeTransaction(pTrans);
158 return NDBT_FAILED;
161 int abortCount = records / 10;
162 bool abortTrans = (action==CloseWithoutStop);
163 int eof;
164 int rows = 0;
165 eof = pOp->nextResult();
167 while(eof == 0){
168 rows++;
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
175 pOp->close();
176 if( check == -1 ) {
177 ERR(pTrans->getNdbError());
178 pNdb->closeTransaction(pTrans);
179 return NDBT_FAILED;
184 pNdb->closeTransaction(pTrans);
185 return NDBT_OK;
188 if(action == CheckInactivityTimeOut){
189 if ((rows % (records / 10)) == 0){
190 // Sleep for a long time before calling nextScanResult
191 if (sleepTime > 1)
192 sleepTime--;
193 g_info << "Sleeping "<<sleepTime<<" secs " << endl;
194 NdbSleep_SecSleep(sleepTime);
198 eof = pOp->nextResult();
200 if (eof == -1) {
201 const NdbError err = pTrans->getNdbError();
203 if (err.status == NdbError::TemporaryError){
204 ERR(err);
206 // Be cruel, call nextScanResult after error
207 for(int i=0; i<10; i++){
208 eof = pOp->nextResult();
209 if(eof == 0){
210 g_err << "nextScanResult returned eof = " << eof << endl
211 << " That is an error when there are no more records" << endl;
212 return NDBT_FAILED;
215 // Be cruel end
217 pNdb->closeTransaction(pTrans);
218 NdbSleep_MilliSleep(50);
219 retryAttempt++;
220 g_info << "Starting over" << endl;
222 // If test is CheckInactivityTimeOut
223 // error 296 is expected
224 if ((action == CheckInactivityTimeOut) &&
225 (err.code == 296))
226 return NDBT_OK;
228 continue;
230 ERR(err);
231 pNdb->closeTransaction(pTrans);
232 return NDBT_FAILED;
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();
239 if(eof == 0){
240 g_err << "nextScanResult returned eof = " << eof << endl
241 << " That is an error when there are no more records" << endl;
242 return NDBT_FAILED;
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;
254 else
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;
262 return NDBT_FAILED;
265 return NDBT_OK;
267 return NDBT_FAILED;
272 void AttribList::buildAttribList(const NdbDictionary::Table* pTab){
273 attriblist.clear();
275 Attrib* attr;
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
280 attr = new Attrib;
281 attr->numAttribs = 0;
282 attriblist.push_back(attr);
283 int i;
284 for(i = 1; i < pTab->getNoOfColumns(); i++){
285 attr = new Attrib;
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--){
292 attr = new Attrib;
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--){
299 attr = new Attrib;
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++){
306 attr = new Attrib;
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++){
313 attr = new Attrib;
314 attr->numAttribs = 2;
315 for(int a = 0; a<2; a++){
316 attr->attribs[a] = i%pTab->getNoOfColumns();
318 attriblist.push_back(attr);
321 // Last
322 attr = new Attrib;
323 attr->numAttribs = 1;
324 attr->attribs[0] = pTab->getNoOfColumns()-1;
325 attriblist.push_back(attr);
327 // Last and first
328 attr = new Attrib;
329 attr->numAttribs = 2;
330 attr->attribs[0] = pTab->getNoOfColumns()-1;
331 attr->attribs[1] = 0;
332 attriblist.push_back(attr);
334 // First and last
335 attr = new Attrib;
336 attr->numAttribs = 2;
337 attr->attribs[0] = 0;
338 attr->attribs[1] = pTab->getNoOfColumns()-1;
339 attriblist.push_back(attr);
341 #if 1
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] << ", ";
347 g_info << endl;
349 #endif