ScanFunctions.hpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:9k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <NDBT.hpp>
  14. #include <NDBT_Test.hpp>
  15. struct Attrib {
  16.   int numAttribs;
  17.   int attribs[1024];
  18. };
  19. class AttribList {
  20. public:
  21.   AttribList(){};
  22.   ~AttribList(){
  23.     for(size_t i = 0; i < attriblist.size(); i++){      
  24.       delete attriblist[i];
  25.     }
  26.   };
  27.   void buildAttribList(const NdbDictionary::Table* pTab); 
  28.   Vector<Attrib*> attriblist;
  29. };
  30. // Functions that help out in testing that we may call 
  31. // scan functions in wrong order etc
  32. // and receive a proper errormessage
  33. class ScanFunctions {
  34. public:
  35.   ScanFunctions(const NdbDictionary::Table& _tab) : tab(_tab){
  36.   }
  37.   enum ActionType {
  38.     CloseWithoutStop,
  39.     NextScanWhenNoMore,
  40.     ExecuteScanWithOutOpenScan,
  41.     OnlyOneScanPerTrans,
  42.     OnlyOneOpBeforeOpenScan,
  43.     OnlyOpenScanOnce,
  44.     OnlyOneOpInScanTrans,
  45.     CheckInactivityTimeOut,
  46.     CheckInactivityBeforeClose ,
  47.     NoCloseTransaction,
  48.     EqualAfterOpenScan
  49.   };
  50.   int  scanReadFunctions(Ndb* pNdb,
  51.  int records,
  52.  int parallelism,
  53.  ActionType action,
  54.  bool exclusive);
  55. private:
  56.   const NdbDictionary::Table& tab;
  57. };
  58. inline 
  59. int 
  60. ScanFunctions::scanReadFunctions(Ndb* pNdb,
  61.  int records,
  62.  int parallelism,
  63.  ActionType action,
  64.  bool exclusive){
  65.   int                  retryAttempt = 0;
  66.   const int            retryMax = 100;
  67.   int sleepTime = 10;
  68.   int                  check;
  69.   NdbConnection        *pTrans = 0;
  70.   NdbScanOperation     *pOp = 0;
  71.   NdbResultSet         *rs = 0;
  72.   while (true){
  73.     if (retryAttempt >= retryMax){
  74.       g_err << "ERROR: has retried this operation " << retryAttempt 
  75.      << " times, failing!" << endl;
  76.       return NDBT_FAILED;
  77.     }
  78.     pTrans = pNdb->startTransaction();
  79.     if (pTrans == NULL) {
  80.       const NdbError err = pNdb->getNdbError();
  81.       if (err.status == NdbError::TemporaryError){
  82. ERR(err);
  83. NdbSleep_MilliSleep(50);
  84. retryAttempt++;
  85. continue;
  86.       }
  87.       ERR(err);
  88.       return NDBT_FAILED;
  89.     }
  90.     
  91.     // Execute the scan without defining a scan operation
  92.     pOp = pTrans->getNdbScanOperation(tab.getName());
  93.     if (pOp == NULL) {
  94.       ERR(pTrans->getNdbError());
  95.       pNdb->closeTransaction(pTrans);
  96.       return NDBT_FAILED;
  97.     }
  98.     
  99.     
  100.     rs = pOp->readTuples(exclusive ? 
  101.  NdbScanOperation::LM_Exclusive : 
  102.  NdbScanOperation::LM_Read);
  103.     
  104.     if( rs == 0 ) {
  105.       ERR(pTrans->getNdbError());
  106.       pNdb->closeTransaction(pTrans);
  107.       return NDBT_FAILED;
  108.     }
  109.     
  110.     
  111.     if (action == OnlyOpenScanOnce){
  112.       // Call openScan one more time when it's already defined
  113.       NdbResultSet* rs2 = pOp->readTuples(NdbScanOperation::LM_Read);
  114.       if( rs2 == 0 ) {
  115. ERR(pTrans->getNdbError());
  116. pNdb->closeTransaction(pTrans);
  117. return NDBT_FAILED;
  118.       }
  119.     }
  120.     
  121.     if (action==EqualAfterOpenScan){
  122.       check = pOp->equal(tab.getColumn(0)->getName(), 10);
  123.       if( check == -1 ) {
  124. ERR(pTrans->getNdbError());
  125. pNdb->closeTransaction(pTrans);
  126. return NDBT_FAILED;
  127.       }
  128.     }
  129.     
  130.     check = pOp->interpret_exit_ok();
  131.     if( check == -1 ) {
  132.       ERR(pTrans->getNdbError());
  133.       pNdb->closeTransaction(pTrans);
  134.       return NDBT_FAILED;
  135.     }
  136.     
  137.     for(int a = 0; a<tab.getNoOfColumns(); a++){
  138.       if(pOp->getValue(tab.getColumn(a)->getName()) == NULL) {
  139. ERR(pTrans->getNdbError());
  140. pNdb->closeTransaction(pTrans);
  141. return NDBT_FAILED;
  142.       }
  143.     }      
  144.     
  145.     check = pTrans->execute(NoCommit);
  146.     if( check == -1 ) {
  147.       ERR(pTrans->getNdbError());
  148.       pNdb->closeTransaction(pTrans);
  149.       return NDBT_FAILED;
  150.     }
  151.     
  152.     int abortCount = records / 10;
  153.     bool abortTrans = (action==CloseWithoutStop);
  154.     int eof;
  155.     int rows = 0;
  156.     eof = rs->nextResult();
  157.     
  158.     while(eof == 0){
  159.       rows++;
  160.       
  161.       if (abortCount == rows && abortTrans == true){
  162. g_info << "Scan is aborted after "<<abortCount<<" rows" << endl;
  163. if (action != CloseWithoutStop){
  164.   // Test that we can closeTrans without stopScan
  165.   rs->close();
  166.   if( check == -1 ) {
  167.     ERR(pTrans->getNdbError());
  168.     pNdb->closeTransaction(pTrans);
  169.     return NDBT_FAILED;
  170.   }
  171. }
  172. pNdb->closeTransaction(pTrans);
  173. return NDBT_OK;
  174.       }
  175.       
  176.       if(action == CheckInactivityTimeOut){
  177. if ((rows % (records / 10)) == 0){
  178.   // Sleep for a long time before calling nextScanResult
  179.   if (sleepTime > 1)
  180.     sleepTime--;
  181.   g_info << "Sleeping "<<sleepTime<<" secs " << endl;
  182.   NdbSleep_SecSleep(sleepTime); 
  183. }
  184.       }
  185.       eof = rs->nextResult();
  186.     }
  187.     if (eof == -1) {
  188.       const NdbError err = pTrans->getNdbError();
  189.       if (err.status == NdbError::TemporaryError){
  190. ERR(err);
  191. // Be cruel, call nextScanResult after error
  192. for(int i=0; i<10; i++){
  193.   eof = rs->nextResult();
  194.   if(eof == 0){
  195.     g_err << "nextScanResult returned eof = " << eof << endl
  196.    << " That is an error when there are no more records" << endl;
  197.     return NDBT_FAILED;
  198.   }
  199. }
  200. // Be cruel end
  201. pNdb->closeTransaction(pTrans);
  202. NdbSleep_MilliSleep(50);
  203. retryAttempt++;
  204. g_info << "Starting over" << endl;
  205. // If test is CheckInactivityTimeOut
  206. // error 296 is expected
  207. if ((action == CheckInactivityTimeOut) &&
  208.     (err.code == 296))
  209.   return NDBT_OK;
  210. continue;
  211.       }
  212.       ERR(err);
  213.       pNdb->closeTransaction(pTrans);
  214.       return NDBT_FAILED;
  215.     }
  216.     if (action == NextScanWhenNoMore){
  217.       g_info << "Calling nextScanresult when there are no more records" << endl;
  218.       for(int i=0; i<10; i++){
  219. eof = rs->nextResult();
  220. if(eof == 0){
  221.   g_err << "nextScanResult returned eof = " << eof << endl
  222.  << " That is an error when there are no more records" << endl;
  223.   return NDBT_FAILED;
  224. }
  225.       }
  226.     }
  227.     if(action == CheckInactivityBeforeClose){
  228.       // Sleep for a long time before calling close
  229.       g_info << "NdbSleep_SecSleep(5) before close transaction" << endl;
  230.       NdbSleep_SecSleep(5); 
  231.     }
  232.     if(action == NoCloseTransaction)
  233.       g_info << "Forgetting to close transaction" << endl;
  234.     else
  235.       pNdb->closeTransaction(pTrans);
  236.     g_info << rows << " rows have been read" << endl;
  237.     if (records != 0 && rows != records){
  238.       g_err << "Check expected number of records failed" << endl 
  239.      << "  expected=" << records <<", " << endl
  240.      << "  read=" << rows <<  endl;
  241.       return NDBT_FAILED;
  242.     }
  243.     
  244.     return NDBT_OK;
  245.   }
  246.   return NDBT_FAILED;
  247. }
  248. void AttribList::buildAttribList(const NdbDictionary::Table* pTab){
  249.   attriblist.clear();
  250.   Attrib* attr;
  251.   // Build attrib definitions that describes which attributes to read
  252.   // Try to build strange combinations, not just "all" or all PK's
  253.   // Scan without reading any attributes
  254.   attr = new Attrib;
  255.   attr->numAttribs = 0;
  256.   attriblist.push_back(attr);
  257.   int i;
  258.   for(i = 1; i < pTab->getNoOfColumns(); i++){
  259.     attr = new Attrib;
  260.     attr->numAttribs = i;
  261.     for(int a = 0; a<i; a++)
  262.       attr->attribs[a] = a;
  263.     attriblist.push_back(attr);
  264.   }
  265.   for(i = pTab->getNoOfColumns()-1; i > 0; i--){
  266.     attr = new Attrib;
  267.     attr->numAttribs = i;
  268.     for(int a = 0; a<i; a++)
  269.       attr->attribs[a] = a;
  270.     attriblist.push_back(attr);
  271.   }
  272.   for(i = pTab->getNoOfColumns(); i > 0;  i--){
  273.     attr = new Attrib;
  274.     attr->numAttribs = pTab->getNoOfColumns() - i;
  275.     for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
  276.       attr->attribs[a] = pTab->getNoOfColumns()-a-1;
  277.     attriblist.push_back(attr); 
  278.   }  
  279.   for(i = 1; i < pTab->getNoOfColumns(); i++){
  280.     attr = new Attrib;
  281.     attr->numAttribs = pTab->getNoOfColumns() - i;
  282.     for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
  283.       attr->attribs[a] = pTab->getNoOfColumns()-a-1;
  284.     attriblist.push_back(attr); 
  285.   }  
  286.   for(i = 1; i < pTab->getNoOfColumns(); i++){
  287.     attr = new Attrib;
  288.     attr->numAttribs = 2;
  289.     for(int a = 0; a<2; a++){
  290.       attr->attribs[a] = i%pTab->getNoOfColumns();
  291.     }
  292.     attriblist.push_back(attr);
  293.   }
  294.   // Last 
  295.   attr = new Attrib;
  296.   attr->numAttribs = 1;
  297.   attr->attribs[0] = pTab->getNoOfColumns()-1;
  298.   attriblist.push_back(attr);
  299.   // Last and first
  300.   attr = new Attrib;
  301.   attr->numAttribs = 2;
  302.   attr->attribs[0] = pTab->getNoOfColumns()-1;
  303.   attr->attribs[1] = 0;
  304.   attriblist.push_back(attr); 
  305.   // First and last
  306.   attr = new Attrib;
  307.   attr->numAttribs = 2;
  308.   attr->attribs[0] = 0;
  309.   attr->attribs[1] = pTab->getNoOfColumns()-1;
  310.   attriblist.push_back(attr);  
  311. #if 1
  312.   for(size_t j = 0; j < attriblist.size(); j++){
  313.     g_info << attriblist[j]->numAttribs << ": " ;
  314.     for(int a = 0; a < attriblist[j]->numAttribs; a++)
  315.       g_info << attriblist[j]->attribs[a] << ", ";
  316.     g_info << endl;
  317.   }
  318. #endif
  319. }