MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ScanInterpretTest.hpp
1 /*
2  Copyright (C) 2003-2006, 2008 MySQL AB, 2008 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef SCAN_INTERPRET_TEST_HPP
20 #define SCAN_INTERPRET_TEST_HPP
21 
22 #include "ScanFilter.hpp"
23 
25 public:
27  const NdbDictionary::Table& _restab) :
28  tab(_tab),
29  restab(_restab),
30  row(_tab){
31  }
32 
33  int scanRead(Ndb*,
34  int records,
35  int parallelism,
36  ScanFilter& filter);
37  int scanReadVerify(Ndb*,
38  int records,
39  int parallelism,
40  ScanFilter& filter);
41 
42  int addRowToInsert(Ndb* pNdb,
43  NdbConnection* pInsTrans);
44  int addRowToCheckTrans(Ndb* pNdb,
45  NdbConnection* pCheckTrans);
46 private:
47  const NdbDictionary::Table& tab;
48  const NdbDictionary::Table& restab;
49  NDBT_ResultRow row;
50 
51 };
52 
53 
54 inline
55 int
56 ScanInterpretTest::addRowToInsert(Ndb* pNdb,
57  NdbConnection* pInsTrans){
58 
59  NdbOperation* pOp =
60  pInsTrans->getNdbOperation(restab.getName());
61  if (pOp == NULL) {
62  ERR(pInsTrans->getNdbError());
63  pNdb->closeTransaction(pInsTrans);
64  return NDBT_FAILED;
65  }
66 
67  if( pOp->insertTuple() == -1 ) {
68  ERR(pInsTrans->getNdbError());
69  pNdb->closeTransaction(pInsTrans);
70  return NDBT_FAILED;
71  }
72 
73  // Copy all attribute to the new operation
74  for (int a = 0; a<restab.getNoOfColumns(); a++){
75  const NdbDictionary::Column* attr = tab.getColumn(a);
76  NdbRecAttr* reca = row.attributeStore(a);
77  int check = -1;
78  switch (attr->getType()){
83  check = pOp->setValue( attr->getName(),
84  reca->aRef());
85  break;
86  }
88  check = pOp->setValue( attr->getName(),
89  reca->int32_value());
90  }
91  break;
93  check = pOp->setValue( attr->getName(),
94  reca->int64_value());
95  }
96  break;
98  check = pOp->setValue( attr->getName(),
99  reca->u_32_value());
100  }
101  break;
103  check = pOp->setValue( attr->getName(),
104  reca->u_64_value());
105  }
106  break;
108  check = pOp->setValue( attr->getName(),
109  reca->float_value());
110 
111  break;
112  default:
113  check = -1;
114  break;
115  }
116  if(check != 0){
117  ERR(pInsTrans->getNdbError());
118  pNdb->closeTransaction(pInsTrans);
119  return NDBT_FAILED;
120  }
121  }
122 
123  return NDBT_OK;
124 }
125 
126 inline
127 int
128 ScanInterpretTest::addRowToCheckTrans(Ndb* pNdb,
129  NdbConnection* pCheckTrans){
130 
131  NdbOperation* pOp =
132  pCheckTrans->getNdbOperation(restab.getName());
133  if (pOp == NULL) {
134  ERR(pNdb->getNdbError());
135  return NDBT_FAILED;
136  }
137 
138  if(pOp->readTuple() != 0) {
139  ERR(pNdb->getNdbError());
140  return NDBT_FAILED;
141  }
142 
143  // Copy pk attribute's to the new operation
144  for (int a = 0; a<restab.getNoOfColumns(); a++){
145  const NdbDictionary::Column* attr = restab.getColumn(a);
146  if (attr->getPrimaryKey() == true){
147  NdbRecAttr* reca = row.attributeStore(a);
148  int check = -1;
149  switch (attr->getType()){
154  check = pOp->equal( attr->getName(),
155  reca->aRef());
156  break;
157  }
159  check = pOp->equal( attr->getName(),
160  reca->int32_value());
161  }
162  break;
164  check = pOp->equal( attr->getName(),
165  reca->int64_value());
166  }
167  break;
169  check = pOp->equal( attr->getName(),
170  reca->u_32_value());
171  }
172  break;
174  check = pOp->equal( attr->getName(),
175  reca->u_64_value());
176  }
177  break;
178  default:
179  check = -1;
180  break;
181  }
182  if(check != 0){
183  ERR(pNdb->getNdbError());
184  return NDBT_FAILED;
185  }
186  }
187  }
188 
189  return NDBT_OK;
190 }
191 
192 inline
193 int
194 ScanInterpretTest::scanRead(Ndb* pNdb,
195  int records,
196  int parallelism,
197  ScanFilter& filter){
198  int retryAttempt = 0;
199  int retryMax = 100;
200  int check;
201  NdbConnection *pTrans;
202  NdbScanOperation *pOp;
203 
204  while (true){
205 
206  if (retryAttempt >= retryMax){
207  ndbout << "ERROR: has retried this operation " << retryAttempt
208  << " times, failing!" << endl;
209  return NDBT_FAILED;
210  }
211 
212  pTrans = pNdb->startTransaction();
213  if (pTrans == NULL) {
214  const NdbError err = pNdb->getNdbError();
215  if (err.status == NdbError::TemporaryError){
216  ERR(err);
217  NdbSleep_MilliSleep(50);
218  retryAttempt++;
219  continue;
220  }
221  ERR(err);
222  return NDBT_FAILED;
223  }
224 
225  pOp = pTrans->getNdbScanOperation(tab.getName());
226  if (pOp == NULL) {
227  ERR(pTrans->getNdbError());
228  pNdb->closeTransaction(pTrans);
229  return NDBT_FAILED;
230  }
231 
232  if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) {
233  ERR(pTrans->getNdbError());
234  pNdb->closeTransaction(pTrans);
235  return NDBT_FAILED;
236  }
237 
238  if (filter.filterOp(pOp) != 0){
239  ERR(pTrans->getNdbError());
240  pNdb->closeTransaction(pTrans);
241  return NDBT_FAILED;
242  }
243 
244  // Read all attributes
245  for(int a = 0; a<tab.getNoOfColumns(); a++){
246  if((row.attributeStore(a) =
247  pOp->getValue(tab.getColumn(a)->getName())) == 0) {
248  ERR(pTrans->getNdbError());
249  pNdb->closeTransaction(pTrans);
250  return NDBT_FAILED;
251  }
252  }
253  check = pTrans->execute(NoCommit);
254  if( check == -1 ) {
255  ERR(pTrans->getNdbError());
256  pNdb->closeTransaction(pTrans);
257  return NDBT_FAILED;
258  }
259 
260  int eof;
261  int rows = 0;
262 
263  while((eof = pOp->nextResult(true)) == 0){
264  do {
265  rows++;
266  if (addRowToInsert(pNdb, pTrans) != 0){
267  pNdb->closeTransaction(pTrans);
268  return NDBT_FAILED;
269  }
270  } while((eof = pOp->nextResult(false)) == 0);
271 
272  check = pTrans->execute(Commit);
273  if( check == -1 ) {
274  const NdbError err = pTrans->getNdbError();
275  ERR(err);
276  pNdb->closeTransaction(pTrans);
277  return NDBT_FAILED;
278  }
279  }
280  if (eof == -1) {
281  const NdbError err = pTrans->getNdbError();
282 
283  if (err.status == NdbError::TemporaryError){
284  ERR(err);
285  pNdb->closeTransaction(pTrans);
286  NdbSleep_MilliSleep(50);
287  retryAttempt++;
288  continue;
289  }
290  ERR(err);
291  pNdb->closeTransaction(pTrans);
292  return NDBT_FAILED;
293  }
294 
295  pNdb->closeTransaction(pTrans);
296 
297  g_info << rows << " rows have been scanned" << endl;
298 
299  return NDBT_OK;
300  }
301  return NDBT_FAILED;
302 }
303 
304 inline
305 int
306 ScanInterpretTest::scanReadVerify(Ndb* pNdb,
307  int records,
308  int parallelism,
309  ScanFilter& filter){
310  int retryAttempt = 0;
311  const int retryMax = 100;
312  int check;
313  NdbConnection *pTrans;
314  NdbScanOperation *pOp;
315 
316  while (true){
317 
318  if (retryAttempt >= retryMax){
319  ndbout << "ERROR: has retried this operation " << retryAttempt
320  << " times, failing!" << endl;
321  return NDBT_FAILED;
322  }
323 
324  pTrans = pNdb->startTransaction();
325  if (pTrans == NULL) {
326  const NdbError err = pNdb->getNdbError();
327  if (err.status == NdbError::TemporaryError){
328  ERR(err);
329  NdbSleep_MilliSleep(50);
330  retryAttempt++;
331  continue;
332  }
333  ERR(err);
334  return NDBT_FAILED;
335  }
336 
337 
338  pOp = pTrans->getNdbScanOperation(tab.getName());
339  if (pOp == NULL) { if (pOp->getValue("KOL2") == 0){
340  ERR(pNdb->getNdbError());
341  return NDBT_FAILED;
342  }
343 
344 
345  ERR(pTrans->getNdbError());
346  pNdb->closeTransaction(pTrans);
347  return NDBT_FAILED;
348  }
349 
350  if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) {
351  ERR(pTrans->getNdbError());
352  pNdb->closeTransaction(pTrans);
353  return NDBT_FAILED;
354  }
355 
356  // Read all attributes
357  for(int a = 0; a<tab.getNoOfColumns(); a++){
358  if((row.attributeStore(a) =
359  pOp->getValue(tab.getColumn(a)->getName())) == 0) {
360  ERR(pTrans->getNdbError());
361  pNdb->closeTransaction(pTrans);
362  return NDBT_FAILED;
363  }
364  }
365  check = pTrans->execute(NoCommit);
366  if( check == -1 ) {
367  ERR(pTrans->getNdbError());
368  pNdb->closeTransaction(pTrans);
369  return NDBT_FAILED;
370  }
371 
372  int eof;
373  int rows = 0;
374  int rowsNoExist = 0;
375  int rowsExist = 0;
376  int existingRecordsNotFound = 0;
377  int nonExistingRecordsFound = 0;
378 
379 
380  NdbConnection* pExistTrans;
381  NdbConnection* pNoExistTrans;
382 
383  while((eof = pOp->nextResult(true)) == 0){
384  pExistTrans = pNdb->startTransaction();
385  if (pExistTrans == NULL) {
386  const NdbError err = pNdb->getNdbError();
387  ERR(err);
388  return NDBT_FAILED;
389  }
390  pNoExistTrans = pNdb->startTransaction();
391  if (pNoExistTrans == NULL) {
392  const NdbError err = pNdb->getNdbError();
393  ERR(err);
394  return NDBT_FAILED;
395  }
396  do {
397  rows++;
398  if (filter.verifyRecord(row) == NDBT_OK){
399  rowsExist++;
400  if (addRowToCheckTrans(pNdb, pExistTrans) != 0){
401  pNdb->closeTransaction(pTrans);
402  pNdb->closeTransaction(pExistTrans);
403  pNdb->closeTransaction(pNoExistTrans);
404  return NDBT_FAILED;
405  }
406  }else{
407  rowsNoExist++;
408  if (addRowToCheckTrans(pNdb, pNoExistTrans) != 0){
409  pNdb->closeTransaction(pTrans);
410  pNdb->closeTransaction(pExistTrans);
411  pNdb->closeTransaction(pNoExistTrans);
412  return NDBT_FAILED;
413  }
414  }
415  } while((eof = pOp->nextResult(false)) == 0);
416 
417 
418  // Execute the transaction containing reads of
419  // all the records that should be in the result table
420  check = pExistTrans->execute(Commit);
421  if( check == -1 ) {
422  const NdbError err = pExistTrans->getNdbError();
423  ERR(err);
424  if (err.code != 626){
425  pNdb->closeTransaction(pExistTrans);
426  pNdb->closeTransaction(pNoExistTrans);
427  pNdb->closeTransaction(pTrans);
428  return NDBT_FAILED;
429  }else{
430  // Some of the records expected to be found wasn't
431  // there
432  existingRecordsNotFound = 1;
433  }
434  }
435  pNdb->closeTransaction(pExistTrans);
436 
437  // Execute the transaction containing reads of
438  // all the records that should NOT be in the result table
439  check = pNoExistTrans->execute(Commit, CommitAsMuchAsPossible);
440  if( check == -1 ) {
441  const NdbError err = pNoExistTrans->getNdbError();
442  // The transactions error code should be zero
443  if (err.code != 626){
444  ERR(err);
445  pNdb->closeTransaction(pNoExistTrans);
446  pNdb->closeTransaction(pTrans);
447  return NDBT_FAILED;
448  }
449  // Loop through the no existing transaction and check that no
450  // operations where successful
451  const NdbOperation* pOp2 = NULL;
452  while ((pOp2 = pNoExistTrans->getNextCompletedOperation(pOp2)) != NULL){
453  const NdbError err = pOp2->getNdbError();
454  if (err.code != 626){
455  ndbout << "err.code = " << err.code<< endl;
456  nonExistingRecordsFound = 1;
457  }
458  }
459  }
460 
461  pNdb->closeTransaction(pNoExistTrans);
462 
463 
464  }
465  if (eof == -1) {
466  const NdbError err = pTrans->getNdbError();
467 
468  if (err.status == NdbError::TemporaryError){
469  ERR(err);
470  pNdb->closeTransaction(pTrans);
471  NdbSleep_MilliSleep(50);
472  retryAttempt++;
473  continue;
474  }
475  ERR(err);
476  pNdb->closeTransaction(pTrans);
477  return NDBT_FAILED;
478  }
479 
480  int testResult = NDBT_OK;
481  int rowsResult = 0;
482  UtilTransactions utilTrans(restab);
483  if (utilTrans.selectCount(pNdb,
484  240,
485  &rowsResult) != 0){
486  return NDBT_FAILED;
487  }
488  if (existingRecordsNotFound == 1){
489  ndbout << "!!! Expected records not found" << endl;
490  testResult = NDBT_FAILED;
491  }
492  if (nonExistingRecordsFound == 1){
493  ndbout << "!!! Unxpected records found" << endl;
494  testResult = NDBT_FAILED;
495  }
496  ndbout << rows << " rows scanned("
497  << rowsExist << " found, " << rowsResult<<" expected)" << endl;
498  if (rowsResult != rowsExist){
499  ndbout << "!!! Number of rows in result table different from expected" << endl;
500  testResult = NDBT_FAILED;
501  }
502 
503  return testResult;
504  }
505  return NDBT_FAILED;
506 }
507 
508 #endif