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

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. // ODBC.cpp : Defines the entry point for the console application.
  14. //
  15. #include "SQL99_test.h"
  16. #include <iostream> // Loose later
  17. using namespace std; //
  18. #define MAXCOL 64
  19. #define DEFCOL 4
  20. #define MAXROW 64
  21. #define DEFROW 8
  22. #define MAXTHREADS 24
  23. #define DEFTHREADS 2
  24. #define MAXTABLES 16
  25. #define DEFTABLES 2
  26. #define MAXLOOPS 100000
  27. #define DEFLOOPS 4
  28. #define UPDATE_VALUE 7
  29. #define PKSIZE 2
  30. static int nNoOfThreads = 1 ;
  31. static int nNoOfCol = 4 ;
  32. static int nNoOfRows = 2 ;
  33. static int nNoOfLoops = 0 ;
  34. static int nNoOfTables = 2 ;
  35. static int nAPI = 0 ;
  36. static int tAttributeSize = sizeof(char) ;
  37. static attr_type AttributeType = T_CHAR ;
  38. static int nAggregate = 0 ;
  39. static int nArithmetic = 0 ;
  40. static int nPrint = 0 ;
  41. static int nColList = 0 ;
  42. static char szColNames[MAXCOL*MAX_COL_NAME] = { 0 } ;
  43. int createTables(char* szTableName, int nTables) ;
  44. /*************************************************
  45. Function: main - the entry point
  46. *************************************************/
  47. int main(int argc, char* argv[]){
  48. int nRetrunValue = NDBT_FAILED ;
  49. SQLRETURN rc = SQL_ERROR ;
  50. double dResultA = 0 ;
  51.     double dResultB = 0 ;
  52.     double dInput = 0 ;
  53.     int x = 0, y = 0 ;
  54.     int* pIntRefBuffer = NULL ;
  55.     float* pFloatRefBuffer = NULL ;
  56.     double* pDoubleRefBuffer = NULL ;
  57.     char* pCharRefBuffer = NULL ;
  58. char szColBuffer[MAX_COL_NAME] = { 0 } ;
  59.     ParseArguments(argc, (const char**)argv) ;
  60.     PARAMS* pparams = (PARAMS*)malloc(sizeof(PARAMS)*nNoOfThreads) ;
  61.     memset(pparams, 0, (sizeof(PARAMS)*nNoOfThreads)) ;
  62.     char* szTableNames = (char*)malloc(sizeof(char)*nNoOfTables*MAX_TABLE_NAME) ;
  63.     memset(szTableNames, 0, sizeof(char)*nNoOfTables*MAX_TABLE_NAME) ;
  64. UintPtr pThreadHandles[MAXTHREADS] = { NULL } ;
  65.     AssignTableNames(szTableNames, nNoOfTables) ;
  66. if(nAPI){
  67. if(0 != createTables(szTableNames, nNoOfTables)){
  68. printf("Failed to create tables through NDB API; quitting...n") ;
  69. NDBT_ProgramExit(NDBT_FAILED) ;
  70. return NDBT_FAILED ;
  71. }
  72. }else{
  73. //CreateDemoTables(szTableNames, nNoOfTables, DROP) ;
  74. rc = CreateDemoTables(szTableNames, nNoOfTables, CREATE) ;
  75. if(!(SQL_SUCCESS == rc || SQL_SUCCESS_WITH_INFO == rc)){
  76. printf("Failed to create tables, quiting now.n") ;
  77. NDBT_ProgramExit(NDBT_FAILED) ;
  78. return NDBT_FAILED ;
  79. }
  80. }
  81. // Store column names in the buffer for use in some stmts
  82. int k = 0 ;
  83. for(;;){
  84. memset((char*)szColBuffer, 0, strlen(szColBuffer)) ;
  85. sprintf((char*)szColBuffer, "COL%d", k) ;
  86.         strcat((char*)szColNames, (char*)szColBuffer) ;
  87.         ++k ;
  88. if( k == nNoOfCol ){
  89. break ;
  90. }
  91. strcat((char*)szColNames, ", ") ;
  92. } // for
  93.     switch(AttributeType){
  94.         case T_INT:
  95.             pIntRefBuffer = (int*)malloc(sizeof(int)*nNoOfRows*nNoOfCol*nNoOfThreads) ;
  96.             memset(pIntRefBuffer, 0, sizeof(int)*nNoOfRows*nNoOfCol*nNoOfThreads) ;
  97.             AssignRefNumValues(pIntRefBuffer, T_INT, nPrint) ;
  98.             StartThreads(pparams, (void*)pIntRefBuffer, nNoOfTables, szTableNames, AttributeType, pThreadHandles) ;
  99.             break ;
  100.         case T_FLOAT:
  101.             pFloatRefBuffer = (float*)malloc(sizeof(float)*nNoOfRows*nNoOfCol*nNoOfThreads) ;
  102.             memset(pFloatRefBuffer, 0, sizeof(float)*nNoOfRows*nNoOfCol*nNoOfThreads) ;
  103.             AssignRefNumValues(pFloatRefBuffer, T_FLOAT, nPrint) ;
  104.             StartThreads(pparams, (void*)pFloatRefBuffer, nNoOfTables, szTableNames, AttributeType, pThreadHandles) ;
  105.             break ;
  106. /*        case T_DOUBLE:
  107.             pDoubleRefBuffer = (double*)malloc(sizeof(double)*nNoOfRows*nNoOfCol*nNoOfThreads) ;
  108.             memset(pDoubleRefBuffer, 0, sizeof(double)*nNoOfRows*nNoOfCol*nNoOfThreads) ;
  109.             AssignRefNumValues(pDoubleRefBuffer, T_DOUBLE, 0) ;
  110.             StartThreads(pparams, (void*)pDoubleRefBuffer, nNoOfTables, szTableNames, AttributeType, pThreadHandles) ;
  111.             break ;
  112. */
  113.         case T_CHAR:
  114.             pCharRefBuffer = (char*)malloc(sizeof(char)*nNoOfRows*nNoOfCol*nNoOfThreads*MAX_CHAR_ATTR_LEN) ;
  115.             memset(pCharRefBuffer, 0, sizeof(char)*nNoOfRows*nNoOfCol*nNoOfThreads*MAX_CHAR_ATTR_LEN) ;
  116.             AssignRefCharValues(pCharRefBuffer, nPrint ) ;
  117.             StartThreads(pparams, (void*)pCharRefBuffer, nNoOfTables, szTableNames, AttributeType, pThreadHandles) ;
  118.             break ;
  119.         default:
  120.             break ;
  121.         }
  122. NdbThread_SetConcurrencyLevel(nNoOfThreads + 2) ;
  123. printf("nPerforming inserts...") ;
  124. SetThreadOperationType(pparams, T_INSERT) ;
  125. if(0 < WaitForThreads(pparams)){
  126. printf("tt%d thread(s) failedn") ;
  127. }else{
  128. printf("ttdonen") ;
  129. }
  130. printf("----------------------nn") ;
  131. PrintAll(szTableNames, nNoOfTables, AttributeType) ;
  132. printf("nVerifying inserts...") ;
  133. SetThreadOperationType(pparams, T_READ_VERIFY) ;
  134. if(0 < WaitForThreads(pparams)){
  135. printf("tt%d thread(s) failedn") ;
  136. }else{
  137. printf("ttdonen") ;
  138. }
  139. printf("----------------------nn") ;
  140. printf("nPerforming updates...") ;
  141. SetThreadOperationType(pparams, T_UPDATE) ;
  142. if(0 < WaitForThreads(pparams)){
  143. printf("tt%d thread(s) failedn") ;
  144. }else{
  145. printf("ttdonen") ;
  146. }
  147. printf("----------------------nn") ;
  148. //PrintAll(szTableNames, nNoOfTables, AttributeType) ;
  149. printf("nVerifying updates...") ;
  150. SetThreadOperationType(pparams, T_READ_VERIFY) ;
  151. if(0 < WaitForThreads(pparams)){
  152. printf("tt%d thread(s) failedn") ;
  153. }else{
  154. printf("ttdonen") ;
  155. }
  156. printf("----------------------nn") ;
  157. printf("nPerforming reads...") ;
  158. SetThreadOperationType(pparams, T_READ) ;
  159. if(0 < WaitForThreads(pparams)){
  160. printf("tt%d thread(s) failedn") ;
  161. }else{
  162. printf("ttdonen") ;
  163. }
  164. printf("----------------------nn") ;
  165. PrintAll(szTableNames, nNoOfTables, AttributeType) ;
  166. if(T_CHAR != AttributeType && nAggregate){
  167. printf("nTesting aggregate functions for each tablenn") ;
  168. printf("FNtCOLUMNtVALUEtttTOTAL ROWS WHEREntttttVALUE(S) > VALUEn--------------------------------------------------------nn") ;
  169. for(y = 0 ; y < nNoOfTables ; ++y){
  170. for(x = 0; x < nNoOfCol ; ++x){
  171. dResultA = dResultB = 0 ;
  172. AggregateFn(FN_MIN, (char*)(szTableNames + MAX_TABLE_NAME*y), x, NULL, &dResultA, AttributeType) ;
  173. AggregateFn(FN_COUNT, (char*)(szTableNames + MAX_TABLE_NAME*y) , x, &dResultA, &dResultB, AttributeType) ;
  174. ATTR_TYPE_SWITCH_AGR("MIN", x, dResultA, dResultB, AttributeType) ;
  175. }
  176. }
  177. for(y = 0; y < nNoOfTables ; ++y){ 
  178. for(x = 0; x < nNoOfCol ; ++x){
  179. dResultA = dResultB = 0 ;
  180. AggregateFn(FN_MAX, (char*)(szTableNames + MAX_TABLE_NAME*y), x, NULL, &dResultA, AttributeType) ;
  181. AggregateFn(FN_COUNT, (char*)(szTableNames + MAX_TABLE_NAME*y), x, &dResultA, &dResultB, AttributeType) ;
  182. ATTR_TYPE_SWITCH_AGR("MAX", x, dResultA, dResultB, AttributeType) ;
  183. }
  184. }
  185. for(y = 0 ; y < nNoOfTables ; ++y){
  186. for(x = 0; x < nNoOfCol ; ++x){
  187. dResultA = dResultB = 0 ;
  188. AggregateFn(FN_AVG, (char*)(szTableNames + MAX_TABLE_NAME*y), x, NULL, &dResultA, AttributeType) ;
  189. AggregateFn(FN_COUNT, (char*)(szTableNames + MAX_TABLE_NAME*y), x, &dResultA, &dResultB, AttributeType) ;
  190. ATTR_TYPE_SWITCH_AGR("AVG", x, dResultA, dResultB, AttributeType)
  191. }
  192. }
  193. printf("--------------------------------------------------------nn") ;
  194. }
  195. if(T_CHAR != AttributeType && nArithmetic){
  196. float nVal = (rand() % 10) /1.82342 ;
  197. for(int h = 0 ; h < nNoOfTables ; ++h){
  198. printf("nTesting arithmetic operatorsnfor each column in %s:n----------------------n", (char*)(szTableNames + MAX_TABLE_NAME*sizeof(char)*h) ) ;
  199. printf("nOperator [ * ]... tt") ;
  200. ArithOp((char*)(szTableNames + MAX_TABLE_NAME*sizeof(char)*h), nNoOfCol, &nVal, AttributeType, MULTI) ;
  201. printf("donen") ;
  202. printf("nOperator [ / ]... tt") ;
  203. ArithOp((char*)(szTableNames + MAX_TABLE_NAME*sizeof(char)*h), nNoOfCol, &nVal, AttributeType, DIVIDE) ;
  204. printf("donen") ;
  205. printf("nOperator [ + ]... tt") ;
  206. ArithOp((char*)(szTableNames + MAX_TABLE_NAME*sizeof(char)*h), nNoOfCol, &nVal, AttributeType, PLUS) ;
  207. printf("donen") ;
  208. printf("nOperator [ - ]... tt") ;
  209. ArithOp((char*)(szTableNames + MAX_TABLE_NAME*sizeof(char)*h), nNoOfCol, &nVal, AttributeType, MINUS) ;
  210. printf("donenn") ;
  211. /*
  212. printf("nOperator [ % ]... tt") ;
  213. ArithOp((char*)szTableNames, nNoOfCol, &nVal, AttributeType, MODULO) ;
  214. printf("donenn") ;
  215. */
  216. }
  217. }
  218. /*
  219. printf("nPerforming deletes...") ;
  220. SetThreadOperationType(pparams, T_DELETE) ;
  221. if(0 < WaitForThreads(pparams)){
  222. printf("tt%d thread(s) failedn") ;
  223. }else{
  224. printf("ttdonen") ;
  225. }
  226. printf("----------------------nn") ;
  227. printf("nVerifying deletes...") ;
  228. SetThreadOperationType(pparams, T_DELETE_VERIFY) ;
  229. if(0 < WaitForThreads(pparams)){
  230. printf("tt%d thread(s) failedn") ;
  231. }else{
  232. printf("ttdonen") ;
  233. }
  234. printf("----------------------nn") ;
  235. */
  236. StopThreads(pparams, pThreadHandles) ;
  237. //PrintAll(szTableNames, nNoOfTables, AttributeType) ;
  238. //CreateDemoTables(szTableNames, nNoOfTables, DROP) ;
  239. free((void*)szTableNames) ;
  240. free((void*)pparams) ;
  241. free((void*)pIntRefBuffer) ;
  242. free((void*)pFloatRefBuffer) ;
  243. free((void*)pDoubleRefBuffer) ;
  244. free((void*)pCharRefBuffer) ;
  245. return 0;
  246. }
  247. /**************************************************
  248. Function: ParseArguments
  249. ***************************************************/
  250. void ParseArguments(int argc, const char** argv){
  251.     int i = 1;
  252.     while (argc > 1){
  253.         if (strcmp(argv[i], "-t") == 0)
  254.             {
  255.             nNoOfThreads = atoi(argv[i+1]);
  256.             if ((nNoOfThreads < 1) || (nNoOfThreads > MAXTHREADS))
  257.                 nNoOfThreads = DEFTHREADS ;
  258.             }
  259.         else if (strcmp(argv[i], "-c") == 0)
  260.             {
  261.             nNoOfCol = atoi(argv[i+1]);
  262.             if ((nNoOfCol < 2) || (nNoOfCol > MAXCOL))
  263.                 nNoOfCol = DEFCOL ;
  264.             }
  265.         else if (strcmp(argv[i], "-l") == 0)
  266.             {
  267.             nNoOfLoops = atoi(argv[i+1]);
  268.             if ((nNoOfLoops < 0) || (nNoOfLoops > MAXLOOPS))
  269.                 nNoOfLoops = DEFLOOPS ;
  270.             }
  271.         else if (strcmp(argv[i], "-r") == 0)
  272.             {
  273.             nNoOfRows = atoi(argv[i+1]);;
  274.             if ((nNoOfRows < 0) || (nNoOfRows > MAXROW))
  275.                 nNoOfRows = DEFROW ;
  276.             }
  277. else if (strcmp(argv[i], "-m") == 0)
  278.             {
  279.             nArithmetic = 1 ;
  280. argc++ ;
  281. i-- ;
  282.             }
  283. else if (strcmp(argv[i], "-g") == 0)
  284.             {
  285.             nAggregate = 1 ;
  286. argc++ ;
  287. i-- ;
  288.             }
  289. else if (strcmp(argv[i], "-n") == 0)
  290.             {
  291. nAPI = 1 ;
  292. argc++ ;
  293. i-- ;
  294.             }
  295. else if (strcmp(argv[i], "-v") == 0)
  296.             {
  297. nPrint = 1 ;
  298. argc++ ;
  299. i-- ;
  300.             }
  301.         else if (strcmp(argv[i], "-a") == 0)
  302.             {
  303.             if(strcmp(argv[i+1], "int") == 0){
  304.                 AttributeType = T_INT ;
  305. tAttributeSize = 32 ;
  306.                 }else if(strcmp(argv[i+1], "float") == 0){
  307.                     AttributeType = T_FLOAT ;
  308. tAttributeSize = 64 ;
  309.                     }else if(strcmp(argv[i+1], "char") == 0){
  310.                         AttributeType = T_CHAR ;
  311.                         }
  312.             }
  313.         else
  314.             {
  315.             cout << "Arguments:n";
  316. cout << "-n Create tables using NDB API (vs ODBC by default)" << endl;
  317.             cout << "-t Number of threads; maximum 24, default 2n" << endl;
  318.             cout << "-c Number of columns per table; maximum 64, default 4n" << endl;
  319.             cout << "-r Number of rows; maximum 64, default 8n" << endl;
  320.             cout << "-a Type of attribute to use: int, double or char; default int " << endl;
  321.             cout << "-g Test aggregate functions" << endl;
  322. cout << "-m Test arithmetic operators" << endl;
  323. cout << "-v Print executed statements" << endl;
  324.             exit(-1);
  325.             }
  326.         argc -= 2 ;
  327.         i = i + 2 ;
  328.         }
  329. char *szAttrType[MAX_STR_LEN] = { 0 } ;
  330. switch(AttributeType){
  331.         case T_INT:
  332.             strcpy((char*)szAttrType, "Integer") ;
  333.             break ;
  334.         case T_FLOAT:
  335.             strcpy((char*)szAttrType, "Float") ;
  336.             break ;
  337. /*        case T_DOUBLE:
  338.             strcpy((char*)szAttrType, "Double") ;
  339.             break ;
  340. */
  341.         case T_CHAR:
  342.             strcpy((char*)szAttrType, "Character") ;
  343.             break ;
  344.         default:
  345.             strcpy((char*)szAttrType, "Not defined") ;
  346.             break ;
  347.     }
  348. printf("nnCurrent parameters: %d thread(s), %d tables, %d rows, %d colums, attribute type: %snn", nNoOfThreads, nNoOfTables, nNoOfRows, nNoOfCol, szAttrType) ;
  349.     }
  350. /*************************************************
  351. Function: ThreadFnInt - thread function
  352. for int attributes
  353. *************************************************/
  354. void* ThreadFnInt(void* pparams){
  355.     SQLRETURN retcode = SQL_ERROR ;
  356.     SQLCHAR szStmtBuffer[MAX_SQL_STMT] = { 0 } ;
  357.     SQLCHAR szValueBuffer[MAX_VALUE_LEN] = { 0 } ;
  358.     SQLCHAR szAuxBuffer[MAX_STR_LEN] = { 0 } ;
  359.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  360.     SQLINTEGER cbInt = 0 ;
  361.     ODBC_HANDLES stHandles ;
  362.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  363.     int r = 0, j = 0 ;
  364.     //Get thread parameters 
  365.     PARAMS* p = (PARAMS*)pparams ;
  366.     int* pRef = (int*)p->pThreadRef ;
  367.     int* pBindBuffer = (int*)malloc(sizeof(int)*nNoOfCol) ;
  368.     //printf("Thread #%dn", p->nThreadID) ;
  369.     retcode = GetHandles(&stHandles, GET, 0) ;
  370. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ) {
  371. p->report_status = S_STARTED ;
  372. }else{
  373. printf("Thread #%d failed to allocate handles, exiting now.n", p->nThreadID) ;
  374. free((void*)pBindBuffer) ;
  375. p->nError = 1 ;
  376. p->report_status = S_EXIT ;
  377. return 0 ;
  378. }
  379.     
  380. //p->report_status = S_STARTED ;
  381.     //Main thread loop
  382.     for(;;){
  383.         while(S_IDLE == p->thread_status){
  384.             NdbSleep_MilliSleep(1) ;
  385.             }
  386.     if(S_STOP == p->thread_status) {
  387.         break ;
  388.         }else{
  389.             p->thread_status = S_BUSY ;
  390.             }
  391.     switch(p->op_type){
  392.         /************************************** T_INSERT case **************************************/
  393.         case T_INSERT:
  394.             for(r = 0 ; r < nNoOfRows ; ++r){
  395. if(!nColList){
  396. sprintf((char*)szStmtBuffer, "INSERT INTO %s VALUES(", p->szTableName) ; 
  397. }else{
  398. sprintf((char*)szStmtBuffer, "INSERT INTO %s (%s) VALUES(", p->szTableName, szColNames) ;
  399. }
  400.                 //sprintf((char*)szStmtBuffer, "INSERT INTO %s VALUES(", p->szTableName) ; 
  401.                 for(j = 0 ;;){
  402.                     sprintf((char*)szValueBuffer,"%d", pRef[nNoOfCol*r + j]) ;
  403.                     strncat((char*)szStmtBuffer, (char*)szValueBuffer, strlen((char*)szValueBuffer)) ;
  404.                     ++j ;
  405.                     if(nNoOfCol == j) break ;
  406.                     strcat((char*)szStmtBuffer, ", ") ;
  407.                     }
  408.             strcat((char*)szStmtBuffer, ")") ;
  409. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  410.             retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  411. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  412. }else{
  413. p->nError = 1 ;
  414. printf("INSERT in thread #%d failedn", p->nThreadID) ;
  415. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  416. }
  417. }
  418.         break ;
  419.         /************************************** T_READ case **************************************/
  420.         case T_READ:
  421.             for(r = 0 ; r < nNoOfRows ; r++){
  422.                 sprintf((char*)szStmtBuffer, "SELECT * FROM %s WHERE COL0 = %d", p->szTableName, pRef[nNoOfCol*r]) ;
  423. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  424.                 ODBC_FN(SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmtBuffer, SQL_NTS), retcode) ;
  425.                 for(j = 0 ; j < nNoOfCol ; ++j){
  426.                     ODBC_FN(SQLBindCol(stHandles.hstmt, (j+1), SQL_C_SLONG, (void*)&pBindBuffer[j], sizeof(SQLINTEGER), &cbInt), retcode) ;
  427.                     }
  428.             for (;;) {
  429.                 retcode = SQLFetch(stHandles.hstmt);
  430.                 if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  431.                     for(int k = 0 ; k < nNoOfCol ; ++k){
  432.                         if(p->nVerifyFlag){
  433.                             if(pBindBuffer[k] != pRef[nNoOfCol*r + k])
  434.                                 printf("Expected: %d Actual: %dn", pBindBuffer[k], pRef[nNoOfCol*r + k]) ;
  435.                             }
  436.                         }
  437.                     }else if(SQL_NO_DATA == retcode){
  438.                         break ;
  439.                         }else{
  440. p->nError = 1 ;
  441. printf("READ in thread #%d failedn", p->nThreadID) ;
  442.                             HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  443.                             }
  444.                     //printf("n") ;
  445.                 }
  446. SQLCloseCursor(stHandles.hstmt) ;
  447. }
  448.         break ;
  449.         /************************************** T_UPDATE case **************************************/
  450.         case T_UPDATE:
  451.             for(r = 0 ; r < nNoOfRows ; ++r){
  452.                 sprintf((char*)szStmtBuffer, "UPDATE %s SET ", p->szTableName) ; 
  453.                 for(j = 1 ;;){
  454.                     pRef[nNoOfCol*r + j] = pRef[nNoOfCol*r + j] + UPDATE_VALUE ;
  455.                     sprintf((char*)szColBuffer,"COL%d = %d",  j, pRef[nNoOfCol*r + j]) ;
  456.                     strncat((char*)szStmtBuffer, (char*)szColBuffer, strlen((char*)szColBuffer)) ;
  457.                     ++j ;
  458.                     if(nNoOfCol == j) break ;
  459.                     strcat((char*)szStmtBuffer, ", ") ;
  460. }
  461. sprintf((char*)szAuxBuffer, " WHERE COL0 = %d ;", pRef[nNoOfCol*r]) ;
  462. strcat((char*)szStmtBuffer, (char*)szAuxBuffer);
  463. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  464. retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  465. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  466. }else{
  467. p->nError = 1 ;
  468. printf("UPDATE in thread %d failedn", p->nThreadID) ;
  469. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  470. }
  471. }
  472.         break ;
  473.         /************************************** T_DELETE case **************************************/
  474.         case T_DELETE:
  475.             for(r = 0 ; r < nNoOfRows ; ++r){
  476.                 sprintf((char*)szStmtBuffer, "DELETE * FROM %s WHERE COL0 = %d", p->szTableName, pRef[nNoOfCol*r]) ;
  477.                 if(nPrint) printf("n> %sn", szStmtBuffer) ;
  478. retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  479. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  480. }else if( 1 == p->nVerifyFlag  && SQL_NO_DATA != retcode){
  481. p->nError = 1 ;
  482. printf("nVerification failed: the row foundn") ;
  483.                 }else{
  484. p->nError = 1 ;
  485. printf("INSERT in thread %d failedn", p->nThreadID) ;
  486. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  487. }
  488. }
  489.         break ;
  490.         /************************************** default case **************************************/
  491.         default:
  492.             break ;
  493.         }//switch
  494. p->thread_status = S_IDLE ;
  495.         } //for
  496. free((void*)pBindBuffer) ;
  497. GetHandles(&stHandles, FREE, 0) ;
  498. p->thread_status = S_EXIT ;
  499. return 0 ;
  500.     };
  501. /*************************************************
  502. Function: ThreadFnFloat - thread function
  503. for float attributes
  504. *************************************************/
  505. void* ThreadFnFloat(void* pparams){
  506.     SQLRETURN retcode = SQL_ERROR ;
  507.     SQLCHAR szStmtBuffer[MAX_SQL_STMT] = { 0 } ;
  508.     SQLCHAR szValueBuffer[MAX_VALUE_LEN] = { 0 } ;
  509.     SQLCHAR szAuxBuffer[MAX_STR_LEN] = { 0 } ;
  510.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  511.     SQLINTEGER cbFloat = 0 ;
  512.     ODBC_HANDLES stHandles ;
  513.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  514.     int r = 0, j = 0 ;
  515.     //Get thread parameters 
  516.     PARAMS* p = (PARAMS*)pparams ;
  517.     float* pRef = (float*)p->pThreadRef ;
  518.     float* pBindBuffer = (float*)malloc(sizeof(float)*nNoOfCol) ;
  519.     //printf("Thread #%dn", p->nThreadID) ;
  520.     retcode = GetHandles(&stHandles, GET, 0) ;
  521. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ) {
  522. p->report_status = S_STARTED ;
  523. }else{
  524. printf("Thread #%d failed to allocate handles, exiting now.n", p->nThreadID) ;
  525. free((void*)pBindBuffer) ;
  526. p->nError = 1 ;
  527. p->report_status = S_EXIT ;
  528. return 0 ;
  529. }
  530.     //p->report_status = S_STARTED ;
  531.     //Main thread loop
  532.     for(;;){
  533.         while(S_IDLE == p->thread_status){
  534.             NdbSleep_MilliSleep(1) ;
  535.             }
  536.     if(S_STOP == p->thread_status) {
  537.         break ;
  538.         }else{
  539.             p->thread_status = S_BUSY ;
  540.             }
  541.     switch(p->op_type){
  542.         /************************************** T_INSERT case **************************************/
  543.         case T_INSERT:
  544.             for(r = 0 ; r < nNoOfRows ; ++r){
  545. if(!nColList){
  546. sprintf((char*)szStmtBuffer, "INSERT INTO %s VALUES(", p->szTableName) ; 
  547. }else{
  548. sprintf((char*)szStmtBuffer, "INSERT INTO %s (%s) VALUES(", p->szTableName, szColNames) ;
  549. }
  550.                 //sprintf((char*)szStmtBuffer, "INSERT INTO %s VALUES(", p->szTableName) ; 
  551.                 for(j = 0 ;;){
  552.                     sprintf((char*)szValueBuffer,"%f", pRef[nNoOfCol*r + j]) ;
  553.                     strncat((char*)szStmtBuffer, (char*)szValueBuffer, strlen((const char*)szValueBuffer)) ;
  554.                     ++j ;
  555.                     if(nNoOfCol == j) break ;
  556.                     strcat((char*)szStmtBuffer, ", ") ;
  557.                     }
  558.             strcat((char*)szStmtBuffer, ")") ;
  559. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  560.             retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  561. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  562. }else{
  563. p->nError = 1 ;
  564. printf("INSERT in thread #%d failedn", p->nThreadID) ;
  565. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  566. }
  567.                 }
  568.         break ;
  569.         /************************************** T_READ case **************************************/
  570.         case T_READ:
  571.             for(r = 0 ; r < nNoOfRows ; ++r){
  572.                 sprintf((char*)szStmtBuffer, "SELECT * FROM %s WHERE COL0 = %f", p->szTableName, pRef[nNoOfCol*r]) ;
  573. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  574.                 ODBC_FN(SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmtBuffer, SQL_NTS), retcode) ;
  575.                 for(j = 0 ; j < nNoOfCol ; ++j){
  576.                     ODBC_FN(SQLBindCol(stHandles.hstmt, (j+1), SQL_C_FLOAT, (void*)&pBindBuffer[j], sizeof(SQLFLOAT), &cbFloat), retcode) ;
  577.                     }
  578.             for (;;) {
  579.                 retcode = SQLFetch(stHandles.hstmt);
  580.                 if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  581.                     for(int k = 0 ; k < nNoOfCol ; ++k){
  582.                         if(p->nVerifyFlag){
  583.                             if(abs(pBindBuffer[k] - pRef[nNoOfCol*r + k]) > FLTDEV )
  584.                                 printf("Expected: %f Actual: %fn", pBindBuffer[k], pRef[nNoOfCol*r + k]) ;
  585.                             }
  586.                         }
  587.                     }else if(SQL_NO_DATA == retcode){
  588.                         break ;
  589. }else{
  590. p->nError = 1 ;
  591. printf("READ in thread #%d failedn", p->nThreadID) ;
  592. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  593. }
  594.                     //printf("n") ;
  595.                 }
  596.         SQLCloseCursor(stHandles.hstmt) ;
  597.                 }
  598.         break ;
  599.         /************************************** T_UPDATE case **************************************/
  600.         case T_UPDATE:
  601.             for(r = 0 ; r < nNoOfRows ; ++r){
  602.                 sprintf((char*)szStmtBuffer, "UPDATE %s SET ", p->szTableName) ; 
  603.                 for(j = 1 ;;){
  604.                     pRef[nNoOfCol*r + j] = pRef[nNoOfCol*r + j] + UPDATE_VALUE ;
  605.                     sprintf((char*)szColBuffer,"COL%d = %f",  j, pRef[nNoOfCol*r + j]) ;
  606.                     strncat((char*)szStmtBuffer, (char*)szColBuffer, strlen((char*)szColBuffer)) ;
  607.                     ++j ;
  608.                     if(nNoOfCol == j) break ;
  609.                     strcat((char*)szStmtBuffer, ", ") ;
  610.                     }
  611.             sprintf((char*)szAuxBuffer, " WHERE COL0 = %f ;", pRef[nNoOfCol*r]) ;
  612.             strcat((char*)szStmtBuffer, (char*)szAuxBuffer);
  613. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  614. retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  615. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  616. }else{
  617. p->nError = 1 ;
  618. printf("UPDATE in thread #%d failedn", p->nThreadID) ;
  619. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  620. }
  621. }
  622.         break ;
  623.         /************************************** T_DELETE case **************************************/
  624.         case T_DELETE:
  625.             for(r = 0 ; r < nNoOfRows ; ++r){
  626.                 sprintf((char*)szStmtBuffer, "DELETE * FROM %s WHERE COL0 = %f", p->szTableName, pRef[nNoOfCol*r]) ;
  627.                 if(nPrint) printf("n> %sn", szStmtBuffer) ;
  628. retcode = SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmtBuffer, SQL_NTS) ;
  629. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  630. }else if( 1 == p->nVerifyFlag && SQL_NO_DATA != retcode){
  631. p->nError = 1 ;
  632.                     printf("nVerification failed: still row existsn") ;
  633. }else{
  634. p->nError = 1 ;
  635. printf("DELETE in thread #%d failedn", p->nThreadID) ;
  636. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  637. }
  638. }
  639.         break ;
  640.         /************************************** default case **************************************/
  641.         default:
  642.             break ;
  643.         }//switch
  644. p->thread_status = S_IDLE ;
  645.         } //for
  646. free((void*)pBindBuffer) ;
  647. GetHandles(&stHandles, FREE, 0) ;
  648. p->thread_status = S_EXIT ;
  649. return 0 ;
  650.     };
  651. /*************************************************
  652. Function: ThreadFnDouble - thread function
  653. for double attributes
  654. *************************************************/
  655. /*
  656. void* ThreadFnDouble(void* pparams){
  657.     SQLRETURN retcode = SQL_ERROR ;
  658.     SQLCHAR szStmtBuffer[MAX_SQL_STMT] = { 0 } ;
  659.     SQLCHAR szValueBuffer[MAX_VALUE_LEN] = { 0 } ;
  660.     SQLCHAR szAuxBuffer[MAX_STR_LEN] = { 0 } ;
  661.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  662.     SQLINTEGER cbDouble = 0 ;
  663.     ODBC_HANDLES stHandles ;
  664.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  665.     int r = 0, j = 0 ;
  666.     //Get thread parameters 
  667.     PARAMS* p = (PARAMS*)pparams ;
  668.     double* pRef = (double*)p->pThreadRef ;
  669.     double* pBindBuffer = (double*)malloc(sizeof(double)*nNoOfCol) ;
  670.     //printf("Thread #%dn", p->nThreadID) ;
  671.     retcode = GetHandles(&stHandles, GET, 0) ;
  672. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ) {
  673. p->report_status = S_STARTED ;
  674. }else{
  675. printf("Thread #%d failed to allocate handles, exiting now.n", p->nThreadID) ;
  676. free((void*)pBindBuffer) ;
  677. p->report_status = S_EXIT ;
  678. return 0 ;
  679. }
  680.     //p->report_status = S_STARTED ;
  681.     //Main thread loop
  682.     for(;;){
  683.         while(S_IDLE == p->thread_status){
  684.             NdbSleep_MilliSleep(1) ;
  685.             }
  686.     if(S_STOP == p->thread_status) {
  687.         break ;
  688.         }else{
  689.             p->thread_status = S_BUSY ;
  690.             }
  691.     switch(p->op_type){
  692.   /************************************** T_INSERT case **************************************/
  693.   /*     case T_INSERT:
  694.             for(r = 0 ; r < nNoOfRows ; ++r){
  695.                 sprintf((char*)szStmtBuffer, "INSERT INTO %s VALUES(", p->szTableName) ; 
  696.                 for(j = 0 ;;){
  697.                     sprintf((char*)szValueBuffer,"%.9f", pRef[nNoOfCol*r + j]) ;
  698.                     strncat((char*)szStmtBuffer, (char*)szValueBuffer, strlen((const char*)szValueBuffer)) ;
  699.                     ++j ;
  700.                     if(nNoOfCol == j) break ;
  701.                     strcat((char*)szStmtBuffer, ", ") ;
  702.                     }
  703.             strcat((char*)szStmtBuffer, ")") ;
  704.             ODBC_FN(SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS), retcode) ;
  705.                 }
  706.         break ;
  707.   /************************************** T_READ case **************************************/
  708.   /*      case T_READ:
  709.             for(r = 0 ; r < nNoOfRows ; ++r){
  710.                 sprintf((char*)szStmtBuffer, "SELECT * FROM %s WHERE COL0 = %.9f", p->szTableName, pRef[nNoOfCol*r]) ;
  711.                 ODBC_FN(SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmtBuffer, SQL_NTS), retcode) ;
  712.                 for(j = 0 ; j < nNoOfCol ; ++j){
  713.                     ODBC_FN(SQLBindCol(stHandles.hstmt, (j+1), SQL_C_DOUBLE, (void*)&pBindBuffer[j], sizeof(SQLDOUBLE), &cbDouble), retcode) ;
  714.                     }
  715.             for (;;) {
  716.                 retcode = SQLFetch(stHandles.hstmt);
  717.                 if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  718.                     for(int k = 0 ; k < nNoOfCol ; ++k){
  719.                         if(p->nVerifyFlag){
  720.                             if(abs(pBindBuffer[k] - pRef[nNoOfCol*r + k]) > DBLDEV)
  721.                                 printf("Expected: %.9f Actual: %.9fn", pBindBuffer[k], pRef[nNoOfCol*r + k]) ;
  722.                             }
  723.                         }
  724.                     }else if(SQL_NO_DATA == retcode){
  725.                         break ;
  726.                         }else{
  727.                             HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  728.                             }
  729.                     //printf("n") ;
  730.                 }
  731.         SQLCloseCursor(stHandles.hstmt) ;
  732.                 }
  733.         break ;
  734.     /************************************** T_UPDATE case **************************************/
  735.     /*    case T_UPDATE:
  736.             for(r = 0 ; r < nNoOfRows ; ++r){
  737.                 sprintf((char*)szStmtBuffer, "UPDATE %s SET ", p->szTableName) ; 
  738.                 for(j = 1 ;;){
  739.                     pRef[nNoOfCol*r + j] = pRef[nNoOfCol*r + j] + UPDATE_VALUE ;
  740.                     sprintf((char*)szColBuffer,"COL%d = %.9f",  j, pRef[nNoOfCol*r + j]) ;
  741.                     strncat((char*)szStmtBuffer, (char*)szColBuffer, strlen((char*)szColBuffer)) ;
  742.                     ++j ;
  743.                     if(nNoOfCol == j) break ;
  744.                     strcat((char*)szStmtBuffer, ", ") ;
  745.                     }
  746.             sprintf((char*)szAuxBuffer, " WHERE COL0 = %.9f ;", pRef[nNoOfCol*r]) ;
  747.             strcat((char*)szStmtBuffer, (char*)szAuxBuffer);
  748.             ODBC_FN(SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS), retcode) ;
  749.                 }
  750.         break ;
  751.   /************************************** T_DELETE case **************************************/
  752.   /*      case T_DELETE:
  753.             for(r = 0 ; r < nNoOfRows ; ++r){
  754.                 sprintf((char*)szStmtBuffer, "DELETE FROM %s WHERE COL0 = %.9f", p->szTableName, pRef[nNoOfCol*r]) ;
  755.                 retcode = SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmtBuffer, SQL_NTS) ;
  756.                 if( 1 == p->nVerifyFlag && SQL_NO_DATA != retcode ){
  757.                     printf("nVerification failed: still row existsn") ;
  758.                     }
  759.                 }
  760.         break ;
  761.     /************************************** default case **************************************/
  762.     /*    default:
  763.             break ;
  764.         }//switch
  765. p->thread_status = S_IDLE ;
  766.         } //for
  767. free((void*)pBindBuffer) ;
  768. GetHandles(&stHandles, FREE, 0) ;
  769. p->thread_status = S_EXIT ;
  770. return 0 ;
  771.     };
  772. /*************************************************
  773. Function: ThreadFnChar - thread function
  774. for character attributes
  775. *************************************************/
  776. void* ThreadFnChar(void* pparams){
  777.     SQLRETURN retcode = SQL_ERROR ;
  778.     SQLCHAR szStmtBuffer[MAX_SQL_STMT] = { 0 } ;
  779.     SQLCHAR szValueBuffer[MAX_VALUE_LEN] = { 0 } ;
  780.     SQLCHAR szAuxBuffer[MAX_STR_LEN] = { 0 } ;
  781.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  782.     SQLINTEGER cbChar = 0 ;
  783.     ODBC_HANDLES stHandles ;
  784.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  785.     int r = 0, j = 0 ;
  786.     //Get thread parameters 
  787.     PARAMS* p = (PARAMS*)pparams ;
  788.     char* pRef = (char*)p->pThreadRef ;
  789.     char* pBindBuffer = (char*)malloc(sizeof(char)*nNoOfCol*MAX_CHAR_ATTR_LEN) ;
  790.     //printf("Thread #%dn", p->nThreadID) ;
  791.     retcode = GetHandles(&stHandles, GET, 0) ;
  792. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ) {
  793. p->report_status = S_STARTED ;
  794. }else{
  795. printf("Thread #%d failed to allocate handles, retcode = %d, exiting now.n", p->nThreadID, retcode) ;
  796. p->nError = 1 ;
  797. free((void*)pBindBuffer) ;
  798. p->report_status = S_EXIT ;
  799. return 0 ;
  800. }
  801.     //Main thread loop
  802.     for(;;){
  803. while(S_IDLE == p->thread_status){
  804.             NdbSleep_MilliSleep(1) ;
  805. }
  806. if(S_STOP == p->thread_status) {
  807. break ;
  808.         }else{
  809.             p->thread_status = S_BUSY ;
  810. }
  811. switch(p->op_type){
  812.         /************************************** T_INSERT case **************************************/
  813.         case T_INSERT:
  814.             for(r = 0 ; r < nNoOfRows ; ++r){
  815.                 memset(szStmtBuffer, 0, strlen(szStmtBuffer)) ;
  816. if(!nColList){
  817. sprintf((char*)szStmtBuffer, "INSERT INTO %s VALUES(", p->szTableName) ; 
  818. }else{
  819. sprintf((char*)szStmtBuffer, "INSERT INTO %s (%s) VALUES(", p->szTableName, szColNames) ;
  820. }
  821.                 for(j = 0 ;;){
  822.                     sprintf((char*)szValueBuffer,"'%s'", (char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char) + j*MAX_CHAR_ATTR_LEN*sizeof(char))) ;
  823.                     strncat((char*)szStmtBuffer, (char*)szValueBuffer, strlen((const char*)szValueBuffer)) ;
  824.                     ++j ;
  825.                     if(nNoOfCol == j) break ;
  826.                     strcat((char*)szStmtBuffer, ", ") ;
  827.                     }
  828.             strcat((char*)szStmtBuffer, ")") ;
  829. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  830. retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  831. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  832. }else{
  833. p->nError = 1 ;
  834. printf("INSERT in thread #%d failedn", p->nThreadID) ;
  835. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  836. }
  837. }
  838.         break ;
  839.         /************************************** T_READ case **************************************/
  840.         case T_READ:
  841.             for(r = 0 ; r < nNoOfRows ; ++r){
  842.                 sprintf((char*)szStmtBuffer, "SELECT * FROM %s WHERE COL0 = '%s'", p->szTableName, (char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char))) ;
  843.         if(nPrint) printf("n> %sn", szStmtBuffer) ;
  844. ODBC_FN(SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmtBuffer, SQL_NTS), retcode) ;
  845.                 for(j = 0 ; j < nNoOfCol ; ++j){
  846.                     ODBC_FN(SQLBindCol(stHandles.hstmt, (j+1), SQL_C_CHAR, (void*)(pBindBuffer+j*MAX_CHAR_ATTR_LEN*sizeof(char)), MAX_CHAR_ATTR_LEN, &cbChar), retcode) ;
  847.                     }
  848.             for (;;) {
  849. retcode = SQLFetch(stHandles.hstmt);
  850.                 if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  851. for(int k = 0 ; k < nNoOfCol ; ++k){
  852. if(p->nVerifyFlag){
  853.                             if(!strcmp((char*)(pBindBuffer + k*MAX_CHAR_ATTR_LEN*sizeof(char)), (char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char) + k*MAX_CHAR_ATTR_LEN*sizeof(char))))
  854.                                 printf("Expected: %s Actual: %sn", (char*)(pBindBuffer + k*MAX_CHAR_ATTR_LEN*sizeof(char)), (char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char) + k*MAX_CHAR_ATTR_LEN*sizeof(char))) ;
  855.                             }
  856. }
  857. }else if(SQL_NO_DATA == retcode){
  858. break ;
  859. }else{
  860. p->nError = 1 ;
  861. printf("READ in thread #%d failedn", p->nThreadID) ;
  862. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  863. }
  864.                     //printf("n") ;
  865. }
  866. SQLCloseCursor(stHandles.hstmt) ;
  867. }
  868.         break ;
  869.         /************************************** T_UPDATE case **************************************/
  870.         case T_UPDATE:
  871.             for(r = 0 ; r < nNoOfRows ; ++r){
  872.                 sprintf((char*)szStmtBuffer, "UPDATE %s SET ", p->szTableName) ; 
  873.                 for(j = 1 ;;){
  874.                     swab((char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char) + j*MAX_CHAR_ATTR_LEN*sizeof(char)), (char*)szColBuffer, MAX_CHAR_ATTR_LEN*sizeof(char)) ;
  875.                     memcpy((void*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char) + j*MAX_CHAR_ATTR_LEN*sizeof(char)), (void*)szColBuffer, MAX_CHAR_ATTR_LEN*sizeof(char)) ;
  876.                     sprintf((char*)szColBuffer,"COL%d = '%s'",  j, (char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char) + j*MAX_CHAR_ATTR_LEN*sizeof(char))) ;
  877.                     strncat((char*)szStmtBuffer, (char*)szColBuffer, strlen((char*)szColBuffer)) ;
  878.                     ++j ;
  879.                     if(nNoOfCol == j) break ;
  880.                     strcat((char*)szStmtBuffer, ", ") ;
  881.                     }
  882.             sprintf( (char*)szAuxBuffer, " WHERE COL0 = '%s';", (char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char)) ) ;
  883.             strcat((char*)szStmtBuffer, (char*)szAuxBuffer) ;
  884. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  885.             retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  886. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  887. }else{
  888. p->nError = 1 ;
  889. printf("UPDATE in thread #%d failedn", p->nThreadID) ;
  890. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  891. }
  892. }
  893.         break ;
  894.         /************************************** T_DELETE case **************************************/
  895.         case T_DELETE:
  896.             for(r = 0 ; r < nNoOfRows ; ++r){
  897.                 sprintf((char*)szStmtBuffer, "DELETE FROM %s WHERE COL0 = '%s'", p->szTableName, (char*)(pRef + nNoOfCol*r*MAX_CHAR_ATTR_LEN*sizeof(char))) ;
  898.              if(nPrint) printf("n> %sn", szStmtBuffer) ;
  899. retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  900. if(SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  901. }else if(1 == p->nVerifyFlag && SQL_NO_DATA != retcode){
  902.                     p->nError = 1 ;
  903. printf("nVerification failed: still row existsn") ;
  904. }else{
  905. p->nError = 1 ;
  906. printf("INSERT in thread #%d failedn", p->nThreadID) ;
  907. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  908.                 }
  909. }
  910.         break ;
  911.         /************************************** default case **************************************/
  912.         default:
  913.             break ;
  914. }//switch
  915. p->thread_status = S_IDLE ;
  916. } //for
  917. free((void*)pBindBuffer) ;
  918. GetHandles(&stHandles, FREE, 0) ;
  919. p->thread_status = S_EXIT ;
  920. return 0 ;
  921. };
  922. /*************************************************
  923. Function: CreateDemoTable
  924. *************************************************/
  925. SQLRETURN CreateDemoTables(char* szTableName, int nTables, table_opt op){
  926.     SQLRETURN retcode = SQL_ERROR ;
  927.     SQLCHAR szStmtBuffer[MAX_SQL_STMT] = { 0 } ;
  928.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  929. SQLCHAR szAuxBuffer[32] = { 0 } ;
  930.     ODBC_HANDLES stHandles ;
  931.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  932.     int c = 0  ;
  933. GetHandles(&stHandles, GET, 0) ;
  934.     if(CREATE == op){
  935.         for(c = 0; c < nTables ; ++c){
  936. sprintf((char*)szStmtBuffer, "CREATE TABLE %s (", (char*)(szTableName+MAX_TABLE_NAME*c)) ;
  937.             int j = 0 ;
  938. for(;;){
  939. sprintf((char*)szColBuffer, "COL%d ", j) ;
  940.                 strcat((char*)szStmtBuffer, (char*)szColBuffer) ;
  941.                 ++j ;
  942.                 switch(AttributeType){
  943.                     case T_INT:
  944.                         strcat((char*)szStmtBuffer, "INTEGER") ;
  945.                         break ;
  946.                     case T_FLOAT:
  947.                         strcat((char*)szStmtBuffer, "FLOAT") ;
  948.                         break ;
  949. /*                    case T_DOUBLE:
  950.                         strcat((char*)szStmtBuffer, "DOUBLE") ;
  951.                         break ;
  952. */
  953.                     case T_CHAR:
  954. sprintf((char*)szAuxBuffer, "CHAR(%d)", MAX_CHAR_ATTR_LEN) ;
  955. strcat((char*)szStmtBuffer,  (char*)szAuxBuffer) ;
  956.                         break ;
  957.                     default:
  958.                         break ;
  959. }
  960. if(nNoOfCol <= j){
  961. strcat((char*)szStmtBuffer, ")") ;
  962. break ;
  963. }
  964. strcat((char*)szStmtBuffer, ", ") ;
  965.             } //for(;;)
  966. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  967. ODBC_FN(SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS), retcode) ;
  968. if(SQL_SUCCESS != retcode) HandleError(stHandles.hstmt , SQL_HANDLE_STMT) ;
  969. }// for()
  970. }else{
  971. for(c = 0 ; c < nTables ; ++c){
  972. sprintf((char*)szStmtBuffer, "DROP TABLE %s ", (char*)(szTableName + MAX_TABLE_NAME*c)) ;
  973. //ODBC_FN(SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS), retcode) ;
  974. if(nPrint) printf("n> %sn", szStmtBuffer) ;
  975. retcode = SQLExecDirect(stHandles.hstmt, szStmtBuffer, SQL_NTS) ;
  976. }
  977. }
  978.     GetHandles(&stHandles, FREE, 0) ;
  979.     return retcode ;
  980. }
  981. /*************************************************
  982. Function: AssignTableNames()
  983. *************************************************/
  984. inline void AssignTableNames(char* szBuffer, int nTables){
  985.     for(int c = 0 ; c < nTables ; ++c){
  986.         sprintf((char*)(szBuffer + MAX_TABLE_NAME*sizeof(char)*c), "TAB%d", c) ;
  987.         }
  988. return ;
  989.     }
  990. /*************************************************
  991. Function: StartThreads()
  992. *************************************************/
  993. inline void StartThreads(PARAMS* p, void* pRef, int nTables, char* szTables, attr_type attrType, UintPtr* pHandles) {
  994.     int* pInt = NULL ;
  995.     float* pFloat = NULL ;
  996.     double* pDouble = NULL ;
  997.     char* pChar = NULL ;
  998. UintPtr pTmpThread = NULL ;
  999.     bool bFlap = 1 ;
  1000.     for(int f = 0 ; f < nNoOfThreads ; ++f){
  1001.         p[f].nThreadID = f ;
  1002.         p[f].nError = 0 ;
  1003.         p[f].thread_status = S_IDLE ;
  1004.         p[f].op_type = T_WAIT ;
  1005.         if(bFlap){
  1006. strncpy((char*)p[f].szTableName, (char*)szTables, MAX_TABLE_NAME) ;
  1007. }else{
  1008.             strncpy((char*)p[f].szTableName, (char*)(szTables + MAX_TABLE_NAME*sizeof(char)), MAX_TABLE_NAME) ;
  1009. }
  1010.         bFlap = !bFlap ;
  1011. //pTmpThread = pHandles[ ;
  1012.         switch(attrType){
  1013.             case T_INT:
  1014.                 pInt = (int*)pRef ;
  1015.                 p[f].pThreadRef = (void*)&pInt[nNoOfRows*nNoOfCol*f] ;
  1016.                 pHandles[f] = (UintPtr)NdbThread_Create(ThreadFnInt, (void**)&p[f], 32768, "SQL99_test", NDB_THREAD_PRIO_MEAN) ;
  1017.                 break ;
  1018.             case T_FLOAT:
  1019.                 pFloat = (float*)pRef ;
  1020.                 p[f].pThreadRef = (void*)&pFloat[nNoOfRows*nNoOfCol*f] ;
  1021.                 pHandles[f] = (UintPtr)NdbThread_Create(ThreadFnFloat, (void**)&p[f], 32768, "SQL99_test", NDB_THREAD_PRIO_MEAN) ;
  1022.                 break ;
  1023.             /*
  1024. case T_DOUBLE:
  1025.                 pDouble = (double*)pRef ;
  1026.                 p[f].pThreadRef = (void*)&pDouble[nNoOfRows*nNoOfCol*f] ;
  1027.                 pHandles[f] = (UintPtr)NdbThread_Create(ThreadFnDouble, (void**)&p[f], 32768, "SQL99_test", NDB_THREAD_PRIO_MEAN) ;
  1028.                 break ;
  1029. */
  1030.             case T_CHAR:
  1031.                 pChar = (char*)pRef ;
  1032.                 p[f].pThreadRef = (void*)&pChar[nNoOfRows*nNoOfCol*f*MAX_CHAR_ATTR_LEN] ;
  1033.                 pHandles[f] = (UintPtr)NdbThread_Create(ThreadFnChar,  (void**)&p[f], 32768, "SQL99_test", NDB_THREAD_PRIO_MEAN) ;
  1034.             default:
  1035.                 break ;
  1036.             }
  1037.     while(!(S_STARTED != p[f].report_status || S_EXIT != p[f].report_status)){
  1038.         NdbSleep_MilliSleep(1) ;
  1039. }
  1040.         }
  1041. return ;
  1042. }
  1043. /*************************************************
  1044. Function: SetThreadOperationType()
  1045. *************************************************/
  1046. inline void SetThreadOperationType(PARAMS* p, type op){
  1047.     for(int e = 0 ; e < nNoOfThreads ; ++e){
  1048.         p[e].nVerifyFlag = 0 ;
  1049.         if(T_READ_VERIFY == op){
  1050.             p[e].nVerifyFlag = 1 ;
  1051.             p[e].op_type = T_READ ;
  1052.             }else if(T_DELETE_VERIFY == op){
  1053.                 p[e].nVerifyFlag = 1 ;
  1054.                 p[e].op_type = T_DELETE ;
  1055.                 }else{
  1056.                     p[e].op_type = op ;
  1057.                     }
  1058.             p[e].thread_status = S_GET_BUSY ;
  1059.         }
  1060. return ;
  1061.     }
  1062. /*************************************************
  1063. Function: WaitForThreads()
  1064. *************************************************/
  1065. inline int WaitForThreads(PARAMS* p) {
  1066. int ret_value = 0 ;
  1067.     for(int w = 0 ; w < nNoOfThreads ; ++w){
  1068.         while(!(S_IDLE != p[w].thread_status || S_EXIT != p[w].report_status)) {
  1069.             NdbSleep_MilliSleep(1) ;
  1070. }
  1071. ret_value += p[w].nError ;
  1072. }
  1073. return ret_value ;
  1074. }
  1075. /*************************************************
  1076. Function: StopThreads()
  1077. *************************************************/
  1078. inline void StopThreads(PARAMS* p, UintPtr* pHandles) {
  1079.     for(int k = 0 ; k < nNoOfThreads ; ++k){
  1080. while(!(S_IDLE != p[k].thread_status || S_EXIT != p[k].report_status)){
  1081. NdbSleep_MilliSleep(1) ;
  1082. }
  1083. p[k].thread_status = S_STOP ;
  1084. while(!(S_EXIT != p[k].thread_status || S_EXIT != p[k].report_status)){
  1085. NdbSleep_MilliSleep(1) ;
  1086. }
  1087. NdbThread_Destroy((NdbThread**)&pHandles[k]) ;
  1088. }
  1089. return ;
  1090. }
  1091. /*************************************************
  1092. Function: PrintAll()
  1093. *************************************************/
  1094. inline void PrintAll(char* szTableName, int nTables, attr_type attrType){
  1095.     SQLRETURN retcode = SQL_ERROR ;
  1096.     SQLCHAR* szStmt[MAX_SQL_STMT] = { 0 } ;
  1097.     ODBC_HANDLES stHandles ;
  1098.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  1099.     double* pDoubleBuffer = NULL ;
  1100.     char* pCharBuffer = NULL ;
  1101.     if(T_CHAR != attrType){
  1102.         pDoubleBuffer = (double*)malloc(sizeof(double)*nNoOfCol) ;
  1103. }else{
  1104.          pCharBuffer = (char*)malloc(sizeof(char)*nNoOfCol*MAX_CHAR_ATTR_LEN) ;
  1105. }
  1106.     SQLINTEGER   cbLen = 0 ;
  1107.     GetHandles(&stHandles, GET, 0) ;
  1108.     for(int c = 0 ; c < nTables ; ++c){
  1109.         int nCol = 0, nRows = 0 ;
  1110.         printf("Table: "%s":n------------------n", (char*)(szTableName + MAX_TABLE_NAME*c*sizeof(char))) ;
  1111.         sprintf((char*)szStmt, "SELECT * FROM %s", (char*)(szTableName + MAX_TABLE_NAME*c*sizeof(char))) ;
  1112. if(nPrint) printf("n> %sn", szStmt) ;
  1113.         ODBC_FN(SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmt, SQL_NTS), retcode) ;
  1114.         for(int i = 0 ; i < nNoOfCol ; ++i){
  1115.             if(T_CHAR != attrType){
  1116.                 ODBC_FN(SQLBindCol(stHandles.hstmt, (i+1), SQL_C_DOUBLE, (void*)&pDoubleBuffer[i], sizeof(SQLDOUBLE), &cbLen), retcode) ;
  1117. }else{
  1118.                 ODBC_FN(SQLBindCol(stHandles.hstmt, (i+1), SQL_C_CHAR, (void*)(pCharBuffer + i*MAX_CHAR_ATTR_LEN*sizeof(char)), MAX_CHAR_ATTR_LEN*sizeof(char), &cbLen), retcode) ;
  1119. }
  1120.             nCol++ ;
  1121. }
  1122.     int k = 0 ; //out of the <for> loop
  1123.     for (;;) {
  1124.         retcode = SQLFetch(stHandles.hstmt);
  1125.         if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ){
  1126.             for(k = 0 ; k < nNoOfCol ; ++k){
  1127.                 if(T_CHAR != attrType){
  1128.                     ATTR_TYPE_SWITCH_T(pDoubleBuffer[k], AttributeType) ;
  1129.                     }else{
  1130.                         printf("%st", (char*)(pCharBuffer + k*MAX_CHAR_ATTR_LEN)) ;
  1131. }
  1132.                 }
  1133.             }else if(SQL_NO_DATA == retcode){
  1134.                 if(0 == k){
  1135.                     printf("<empty>n") ;
  1136.                     break ;
  1137.                     }else{
  1138.                         break ;
  1139. }
  1140.                 }else{
  1141.                     HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  1142. }
  1143.             ++nRows ;
  1144.             printf("n") ;
  1145.         }
  1146. SQLCloseCursor(stHandles.hstmt) ;
  1147. printf("------------------n") ;
  1148. printf("Rows: %d Columns: %dnn", nRows, nCol) ;
  1149. }
  1150. free((void*)pDoubleBuffer) ;
  1151. free((void*)pCharBuffer) ;
  1152. GetHandles(&stHandles, FREE, 0) ;
  1153. return ;
  1154. }
  1155. /*************************************************
  1156. Function: AssignRefCharValues()
  1157. *************************************************/
  1158. void AssignRefCharValues(char* pRef, bool bVerbose) {
  1159.     int count = 0, rows = 0, nThreadOffset = 0, nRowOffset = 0 ;
  1160.     char szStrBuffer[MAX_CHAR_ATTR_LEN] = { 0 } ;
  1161.     int char_count = sizeof(szANSI)/sizeof(char) ;
  1162.     for(int c = 0 ; c < nNoOfThreads ; ++c){
  1163.         nThreadOffset = nNoOfRows*nNoOfCol*c*MAX_CHAR_ATTR_LEN*sizeof(char) ;
  1164.         for(int d = 0 ; d < nNoOfRows ; ++d){
  1165.             nRowOffset = nNoOfCol*d*MAX_CHAR_ATTR_LEN*sizeof(char) ; ++rows ;
  1166.             for(int i = 0 ; i < nNoOfCol ; ++i){
  1167.                 for(int j = 0 ; j < (MAX_CHAR_ATTR_LEN - 2) ; ++j){
  1168.                     int h = (char)(rand() % (char_count-1)) ;
  1169.                     szStrBuffer[j] = szANSI[h] ;
  1170.                     }
  1171.             szStrBuffer[MAX_CHAR_ATTR_LEN - 1] = '' ;
  1172.             strcpy((char*)(pRef + nThreadOffset + nRowOffset + i*MAX_CHAR_ATTR_LEN*sizeof(char)), (char*)szStrBuffer) ;
  1173.             count++ ;
  1174.             if(bVerbose){
  1175.                 printf(" %s ", (char*)(pRef + nThreadOffset + nRowOffset + i*MAX_CHAR_ATTR_LEN*sizeof(char))) ;
  1176.                 }
  1177.                 }
  1178.         if(bVerbose) { 
  1179.             printf("n") ;
  1180.             NdbSleep_MilliSleep(10) ;
  1181.             }
  1182.             }
  1183.         }
  1184. if(bVerbose){
  1185.     printf("_____________________") ;
  1186.     printf("nRows: %d Values: %dnn", rows, count) ;
  1187.     }
  1188. return ;
  1189.     }
  1190. /*
  1191. sprintf((char*)szStmtBuffer, "INSERT INTO %s VALUES(", p->szTableName) ; 
  1192. for(j = 0 ;;){
  1193. strcat((char*)szStmtBuffer, "?") ;
  1194. ++j ;
  1195. if(nNoOfCol == j) break ;
  1196. strcat((char*)szStmtBuffer, ", ") ;
  1197. }
  1198. strcat((char*)szStmtBuffer, ")") ;
  1199. ODBC_FN(SQLPrepare(stHandles.hstmt, szStmtBuffer, SQL_NTS), retcode) ;
  1200. for(j = 0 ; j < nNoOfCol ; ++j){
  1201. ODBC_FN(SQLBindParameter(stHandles.hstmt, (j+1), SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, 0, 0, (void*)&pBindBuffer[j], 0, &cbFloat), retcode) ;
  1202. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  1203. }
  1204. for(r = 0 ; r < nNoOfRows ; ++r){
  1205. for(j = 0 ; j < nNoOfCol ; ++j){
  1206. pBindBuffer[j] = pRef[nNoOfCol*r + j] ;
  1207. }
  1208. ODBC_FN(SQLExecute(stHandles.hstmt), retcode) ;
  1209. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  1210. }
  1211. */
  1212. /*************************************************
  1213. Function: HandleError
  1214. *************************************************/
  1215. void HandleError(void* handle, SQLSMALLINT HandleType){
  1216.     SQLCHAR szError[MAX_STR_LEN], szSqlState[32] ;
  1217.     SQLINTEGER nError = 0 ;
  1218.     SQLSMALLINT nHandleType = HandleType ;
  1219.     SQLSMALLINT nLength = 0 ;
  1220.     SQLHANDLE SQLHandle = handle ;
  1221.     SQLGetDiagRec(nHandleType, SQLHandle, 1, szSqlState, &nError, szError, 128, &nLength) ;
  1222.     printf("Error: %snSqlState: %sn", szError, szSqlState) ;
  1223.     return ;
  1224.     }
  1225. /*************************************************
  1226. Function: ReportError
  1227. *************************************************/
  1228. void ReportError(char* szFn, char* szBuffer, char* szFile, int iLine){
  1229.     printf("%s %snFile: %snLine: %dn", szFn, szBuffer, szFile, iLine) ;
  1230.     return ;
  1231. }
  1232. /*************************************************
  1233. Function: GetHandles()
  1234. *************************************************/
  1235. SQLRETURN GetHandles(ODBC_HANDLES* pHandles, handle_op op, bool bDriverInfo){
  1236.     SQLRETURN   retcode = SQL_ERROR ;
  1237.     if(GET == op){
  1238. retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &pHandles->henv);
  1239.         if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ) {
  1240. retcode = SQLSetEnvAttr(pHandles->henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC2, 0);
  1241.             if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode) {
  1242. retcode = SQLAllocHandle(SQL_HANDLE_DBC, pHandles->henv, &pHandles->hdbc);
  1243.                 if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode) {
  1244.                     
  1245. //SQLSetConnectAttr(pHandles->hdbc, SQL_LOGIN_TIMEOUT, (void*)5, 0);
  1246. retcode = SQLConnect(pHandles->hdbc, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS ) ;
  1247. SQL_SUCCESS == SQLSetConnectAttr(pHandles->hdbc, SQL_ATTR_AUTOCOMMIT, (void*)SQL_AUTOCOMMIT_ON, 0) ;
  1248. //printf("AUTOCOMMIT is onn") ; 
  1249. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode) {
  1250. // retcode still holds the value returned by SQLConnect
  1251.     retcode = SQLAllocHandle(SQL_HANDLE_STMT, pHandles->hdbc, &pHandles->hstmt) ;
  1252. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode) {
  1253. if(bDriverInfo) GetDriverAndSourceInfo(pHandles->hdbc) ;
  1254. // printf("All handles allocated OKn", retcode);
  1255. }else{ // SQLAllocHandle()
  1256. REPORTERROR((char*)"SQLAllocHandle()", (char*)"failed") ;
  1257. HandleError(pHandles->hdbc, SQL_HANDLE_DBC) ;
  1258. ODBC_FN(SQLDisconnect(pHandles->hdbc), retcode) ;
  1259. ODBC_FN(SQLFreeHandle(SQL_HANDLE_DBC, pHandles->hdbc), retcode) ;
  1260. ODBC_FN(SQLFreeHandle(SQL_HANDLE_ENV, pHandles->henv), retcode) ;
  1261. retcode = SQL_ERROR ;
  1262. }
  1263. }else{ // SQLConnect()
  1264. REPORTERROR((char*)"SQLConnect()", (char*)"failed" ) ;
  1265. HandleError(pHandles->hdbc, SQL_HANDLE_DBC) ;
  1266. ODBC_FN(SQLFreeHandle(SQL_HANDLE_DBC, pHandles->hdbc), retcode) ;
  1267. ODBC_FN(SQLFreeHandle(SQL_HANDLE_ENV, pHandles->henv), retcode) ;
  1268. retcode = SQL_ERROR ;
  1269. }
  1270. }else{ // SQLAllocHandle()
  1271. REPORTERROR((char*)"SQLAllocHandle()", "failed" ) ;
  1272. HandleError(pHandles->hdbc, SQL_HANDLE_DBC) ;
  1273. ODBC_FN(SQLFreeHandle(SQL_HANDLE_ENV, pHandles->henv), retcode) ;
  1274. retcode = SQL_ERROR ;
  1275. }
  1276. }else{ // SQLSetEnvAttr()
  1277. REPORTERROR((char*)"SQLSetEnvAttr()", "failed" ) ;
  1278. HandleError(pHandles->henv, SQL_HANDLE_ENV) ;
  1279. ODBC_FN(SQLFreeHandle(SQL_HANDLE_ENV, pHandles->henv), retcode) ;
  1280. retcode = SQL_ERROR ;
  1281. }
  1282. }else{ // SQLAllocHandle()
  1283. REPORTERROR((char*)"SQLAllocHandle()", "failed" ) ;
  1284. HandleError(pHandles->henv, SQL_HANDLE_ENV) ;
  1285. retcode = SQL_ERROR ;
  1286. }
  1287. }else{
  1288. ODBC_FN(SQLFreeHandle(SQL_HANDLE_STMT, pHandles->hstmt), retcode) ;
  1289. ODBC_FN(SQLDisconnect(pHandles->hdbc), retcode) ;
  1290. ODBC_FN(SQLFreeHandle(SQL_HANDLE_DBC, pHandles->hdbc), retcode) ;
  1291. ODBC_FN(SQLFreeHandle(SQL_HANDLE_ENV, pHandles->henv), retcode) ;
  1292. }
  1293.     return retcode ;
  1294. }
  1295. /*************************************************
  1296. Function: AggretateFn():
  1297. <aggr_fn fn> - name of the aggregate function to use
  1298. <char* szTableName> - name of the table
  1299. <int nCol> - number of the column
  1300. <double* pdIn> - pointer to double containing the value to be used in a call to COUNT; used only by this function
  1301. <double* pdOut> - pointer to double that will recieve the result
  1302. <attr_type attrType> - type of the attribute
  1303. *************************************************/
  1304. SQLRETURN AggregateFn(aggr_fn fn, char* szTableName, int nCol, double* pdIn, double* pdOut, attr_type attrType){
  1305.     SQLRETURN retcode = SQL_ERROR ;
  1306.     SQLCHAR* szStmt[MAX_SQL_STMT] = { 0 } ;
  1307.     SQLCHAR szValueBuffer[MAX_VALUE_LEN] = { 0 } ;
  1308.     SQLCHAR szAuxBuffer[MAX_STR_LEN] = { 0 } ;
  1309.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  1310.     ODBC_HANDLES stHandles ;
  1311.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  1312.     SQLINTEGER  cbDouble = 0 ;
  1313.     GetHandles(&stHandles, GET, 0) ;
  1314.     switch(fn){
  1315.     case FN_COUNT:
  1316.         switch(attrType){
  1317.     case T_INT:
  1318.         sprintf((char*)szStmt, "SELECT COUNT(*) FROM %s WHERE COL%d > %d", szTableName, nCol, (int)*pdIn) ;
  1319.         break ;
  1320.     case T_FLOAT:
  1321.         sprintf((char*)szStmt, "SELECT COUNT(*) FROM %s WHERE COL%d > %f", szTableName, nCol, (float)*pdIn) ;
  1322.         break ;
  1323. /*    case T_DOUBLE:
  1324.         sprintf((char*)szStmt, "SELECT COUNT(*) FROM %s WHERE COL%d > %.15f", szTableName, nCol, *pdIn) ;
  1325.         break ;
  1326. */
  1327.     default:
  1328.         break ;
  1329.             }
  1330.     break ;
  1331.     case FN_SUM:
  1332.         sprintf((char*)szStmt, "SELECT SUM(COL%d) FROM %s", nCol, szTableName) ;
  1333.         break ;
  1334.     case FN_AVG:
  1335.         sprintf((char*)szStmt, "SELECT AVG(COL%d) FROM %s", nCol, szTableName) ;
  1336.         break ;
  1337.     case FN_MAX:
  1338.         sprintf((char*)szStmt, "SELECT MAX(COL%d) FROM %s", nCol, szTableName) ;
  1339.         break ;
  1340.     case FN_MIN:
  1341.         sprintf((char*)szStmt, "SELECT MIN(COL%d) FROM %s", nCol, szTableName) ;
  1342.         break ;
  1343.     case FN_VARIANCE: // not implemented
  1344.         //sprintf((char*)szStmt, "SELECT VARIANCE(COL%d) FROM %s;", nCol, szTableName) ;
  1345.         break ;
  1346.     case FN_STDDEV: // not implemented
  1347.         //sprintf((char*)szStmt, "SELECT STDDEV(COL%d) FROM %s;", nCol, szTableName) ;
  1348.         break ;
  1349.     default:
  1350.         break ;
  1351.         }
  1352. //printf("%sn", szStmt) ; 
  1353. retcode = SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmt, SQL_NTS) ;
  1354. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ){
  1355.     retcode = SQLBindCol(stHandles.hstmt, 1, SQL_C_DOUBLE, (void*)pdOut, sizeof(SQLDOUBLE), &cbDouble) ;
  1356.     if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ){
  1357.         retcode = SQLFetch(stHandles.hstmt) ;
  1358.         }
  1359.     }
  1360. if(SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode){
  1361.     HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  1362.     }
  1363. SQLCloseCursor(stHandles.hstmt) ;
  1364. GetHandles(&stHandles, FREE, 0) ;
  1365. return retcode ;
  1366.     };
  1367. /*************************************************
  1368. Function: GetDriverAndSourceInfo()
  1369. *************************************************/
  1370. SQLRETURN GetDriverAndSourceInfo(SQLHDBC hdbc){
  1371.     SQLRETURN retcode = SQL_ERROR ;
  1372.     SQLCHAR buffer[255] ;
  1373.     SQLUSMALLINT snValue = 0 ;
  1374.     SQLSMALLINT outlen =  0 ;
  1375.     printf( "-------------------------------------------n" ) ;
  1376.     retcode = SQLGetInfo( hdbc, SQL_DATA_SOURCE_NAME, buffer, 255, &outlen ) ;
  1377.     printf( "Connected to Server: %sn", buffer ) ;
  1378.     retcode = SQLGetInfo( hdbc, SQL_DATABASE_NAME, buffer, 255, &outlen ) ;
  1379.     printf( "      Database name: %sn", buffer ) ;
  1380.     retcode = SQLGetInfo( hdbc, SQL_SERVER_NAME, buffer, 255, &outlen ) ;
  1381.     printf( "      Instance name: %sn", buffer ) ;
  1382.     retcode = SQLGetInfo( hdbc, SQL_DBMS_NAME, buffer, 255, &outlen ) ;
  1383.     printf( "          DBMS name: %sn", buffer ) ;
  1384.     retcode = SQLGetInfo( hdbc, SQL_DBMS_VER, buffer, 255, &outlen ) ;
  1385.     printf( "       DBMS version: %sn", buffer ) ;
  1386.     retcode = SQLGetInfo( hdbc, SQL_ODBC_VER, buffer, 255, &outlen ) ;
  1387.     printf( "       ODBC version: %sn", buffer ) ;
  1388.     retcode = SQLGetInfo( hdbc, SQL_DRIVER_NAME, buffer, 255, &outlen ) ;
  1389.     printf( "        Driver name: %sn", buffer ) ;
  1390.     retcode = SQLGetInfo( hdbc, SQL_DRIVER_VER, buffer, 255, &outlen ) ;
  1391.     printf( "     Driver version: %sn", buffer ) ;
  1392.     retcode = SQLGetInfo( hdbc, SQL_MAX_DRIVER_CONNECTIONS, &snValue, sizeof(SQLSMALLINT), &outlen ) ;
  1393.     printf( "    Max connections: %dn", snValue ) ;
  1394.     retcode = SQLGetInfo( hdbc, SQL_CURSOR_COMMIT_BEHAVIOR, &snValue, sizeof(SQLSMALLINT), &outlen ) ;
  1395.     printf( "Autocommit behavior:") ;
  1396.     switch(snValue){
  1397.     case SQL_CB_DELETE:
  1398.         printf(" SQL_CB_DELETEn") ;
  1399.         break ;
  1400.     case SQL_CB_CLOSE:
  1401.         printf(" SQL_CB_CLOSEn") ;
  1402.         break ;
  1403.     case SQL_CB_PRESERVE:
  1404.         printf(" SQL_CB_PRESERVEn") ;
  1405.         break ;
  1406.     default:
  1407.         printf(" undefinedn") ;
  1408.         break ;
  1409.         }
  1410. printf( "-------------------------------------------n" ) ;
  1411. return retcode ;
  1412. }
  1413. /*************************************************
  1414. Function: ArithOp()
  1415. *************************************************/
  1416. int ArithOp(char* szTable, int nTotalCols, float* pValue, attr_type attrType, arth_op op){
  1417.     SQLRETURN retcode = SQL_ERROR ;
  1418. int nVerRet = -1 ;
  1419.     SQLCHAR szStmt[MAX_SQL_STMT] = { 0 } ;
  1420.     SQLCHAR szEndBuffer[MAX_STR_LEN] = { 0 } ;
  1421.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  1422.     SQLCHAR szAuxBuffer[MAX_STR_LEN] = { 0 } ;
  1423.     ODBC_HANDLES stHandles ;
  1424.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  1425.     void* pBuffer = NULL ;
  1426.     SQLINTEGER BindInt = 0, IntResult = 0, RefIntResult = 0 ;
  1427.     SQLFLOAT BindFloat = 0, FloatResult = 0, RefFloatResult = 0 ;
  1428.     SQLDOUBLE BindDouble = 0, DoubleResult = 0, RefDoubleResult = 0 ;
  1429.     SQLINTEGER cbSize = 0 ;
  1430.     SQLINTEGER  cbLen = 0 ;
  1431.     SQLSMALLINT cbTarget = 0 ;
  1432.     GetHandles(&stHandles, GET, 0) ;
  1433.     for(int c = 0 ; c < nTotalCols ; ++c){
  1434. sprintf((char*)szStmt, "SELECT COL%d, (COL%d", c, c) ;
  1435.         switch(op){
  1436.         case MINUS:
  1437.             strcat((char*)szStmt, " - ") ;
  1438.             break ;
  1439.         case PLUS:
  1440.             strcat((char*)szStmt, " + ") ;
  1441.             break ;
  1442.         case MULTI:
  1443.             strcat((char*)szStmt, " * ") ;
  1444.             break ;
  1445.         case DIVIDE:
  1446.             strcat((char*)szStmt, " / ") ;
  1447.             break ;
  1448.         case MODULO:
  1449.             //strcat((char*)szStmt, " % ") ; Not implemented
  1450.             GetHandles(&stHandles, FREE, 0) ;
  1451.             return -1 ; //Close handles and return
  1452.             break ;
  1453.         default:
  1454.             break ;
  1455. }
  1456. sprintf((char*)(szAuxBuffer),"%.9f) ", *((float*)(pValue))) ;
  1457. strcat((char*)szStmt, (char*)szAuxBuffer) ;
  1458. sprintf((char*)szEndBuffer, "FROM %s", szTable) ;
  1459. strcat((char*)szStmt, (char*)szEndBuffer) ;
  1460. ODBC_FN(SQLExecDirect(stHandles.hstmt, (SQLCHAR*)szStmt, SQL_NTS), retcode) ;
  1461. if(retcode == SQL_ERROR){
  1462. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ; 
  1463. printf("n%sn", szStmt) ;
  1464. }
  1465. SQLSMALLINT cbNameLen = 0, cbSqlType = 0, cbNullable = 0, cbColScale = 0  ;
  1466. SQLINTEGER cbColSize = 0 ;
  1467. SQLDescribeCol(stHandles.hstmt, 2, szColBuffer, MAX_COL_NAME-1, &cbNameLen, &cbSqlType, (unsigned long*)&cbColSize, &cbColScale, &cbNullable) ;
  1468. switch(cbSqlType){
  1469. case SQL_NUMERIC:
  1470. pBuffer = &IntResult ;
  1471. cbSize = sizeof(SQLINTEGER) ;
  1472. cbTarget = SQL_C_ULONG ;
  1473. case SQL_INTEGER:
  1474. pBuffer = &IntResult ;
  1475. cbSize = sizeof(SQLINTEGER) ;
  1476. cbTarget = SQL_C_LONG ;
  1477. break ;
  1478. case SQL_FLOAT:
  1479. pBuffer = &FloatResult ; 
  1480. cbSize = sizeof(SQLFLOAT) ;
  1481. cbTarget = SQL_C_FLOAT ;
  1482. break ;
  1483. case SQL_DOUBLE:
  1484. pBuffer = &DoubleResult ;
  1485. cbSize = sizeof(SQLDOUBLE) ;
  1486. cbTarget = SQL_C_DOUBLE ;
  1487. break ;
  1488. default:
  1489. printf("nUndefined result type: %dn", cbSqlType) ;
  1490. break ;
  1491. }
  1492. switch(attrType){
  1493. case T_INT:
  1494. ODBC_FN(SQLBindCol(stHandles.hstmt, 1, SQL_C_SLONG, (void*)&BindInt, sizeof(SQLINTEGER), &cbLen), retcode) ;
  1495. break ;
  1496. case T_FLOAT:
  1497. ODBC_FN(SQLBindCol(stHandles.hstmt, 1, SQL_C_FLOAT, (void*)&BindFloat, sizeof(SQLFLOAT), &cbLen), retcode) ;
  1498. break ;
  1499. /*        case T_DOUBLE:
  1500. ODBC_FN(SQLBindCol(stHandles.hstmt, 1, SQL_C_DOUBLE, (void*)&BindDouble, sizeof(SQLDOUBLE), &cbLen), retcode) ;
  1501. break ;
  1502. */
  1503. default:
  1504. break ;
  1505. }
  1506. ODBC_FN(SQLBindCol(stHandles.hstmt, 2, cbTarget, pBuffer, cbSize, &cbLen), retcode) ;
  1507. retcode = SQLFetch(stHandles.hstmt) ;
  1508. if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode){
  1509. switch(attrType){
  1510. case T_INT:
  1511. switch(cbSqlType){
  1512. case SQL_INTEGER:
  1513. nVerRet = VerifyArthOp((int*)&BindInt, pValue, (int*)pBuffer, op) ;
  1514. break ;
  1515. case SQL_FLOAT:
  1516. nVerRet = VerifyArthOp((int*)&BindInt, pValue, (float*)pBuffer, op) ;
  1517. break ;
  1518. case SQL_DOUBLE:
  1519. nVerRet = VerifyArthOp((int*)&BindInt, pValue, (double*)pBuffer, op) ;
  1520. break ;
  1521. case SQL_NUMERIC:
  1522. nVerRet = VerifyArthOp((int*)&BindInt, pValue, (int*)pBuffer, op) ;
  1523. break ;
  1524. default:
  1525. break ;
  1526. }
  1527. break ;
  1528. case T_FLOAT:
  1529. switch(cbSqlType){
  1530. case SQL_INTEGER:
  1531. nVerRet = VerifyArthOp((float*)&BindFloat, pValue, (int*)pBuffer, op) ;
  1532. break ;
  1533. case SQL_FLOAT:
  1534. nVerRet = VerifyArthOp((float*)&BindFloat, pValue, (float*)pBuffer, op) ;
  1535. break ;
  1536. case SQL_DOUBLE:
  1537. nVerRet = VerifyArthOp((float*)&BindFloat, pValue, (double*)pBuffer, op) ;
  1538. break ;
  1539. default:
  1540. break ;
  1541. }
  1542. break ;
  1543. /*                case T_DOUBLE:
  1544. switch(cbSqlType){
  1545. case SQL_INTEGER:
  1546. nVerRet = VerifyArthOp((double*)&BindDouble, pValue, (int*)pBuffer, op) ;
  1547. break ;
  1548. case SQL_FLOAT:
  1549. nVerRet = VerifyArthOp((double*)&BindDouble, pValue, (float*)pBuffer, op) ;
  1550. break ;
  1551. case SQL_DOUBLE:
  1552. nVerRet = VerifyArthOp((double*)&BindDouble, pValue, (double*)pBuffer, op) ;
  1553. break ;
  1554. default:
  1555. break ;
  1556. }
  1557. break ;
  1558. */
  1559. default:
  1560. break ;
  1561. }
  1562. if(-1 == nVerRet){
  1563. printf("nVerification failed.n") ;
  1564. return nVerRet ;
  1565. }else if(SQL_NO_DATA == retcode){
  1566. break ;
  1567. }
  1568. }else{
  1569. HandleError(stHandles.hstmt, SQL_HANDLE_STMT) ;
  1570. }
  1571. SQLCloseCursor(stHandles.hstmt) ;
  1572. }
  1573. GetHandles(&stHandles, FREE, 0) ;
  1574. return nVerRet ;
  1575. }
  1576. /*************************************************
  1577. Function: Join()
  1578. *************************************************/
  1579. SQLRETURN Join(char* szTable, int nTables, int nCol, join_type joinType){
  1580.     SQLRETURN retcode = SQL_ERROR ;
  1581.     SQLCHAR szStmt[MAX_SQL_STMT] = { 0 } ;
  1582.     SQLCHAR szEndBuffer[MAX_STR_LEN] = { 0 } ;
  1583.     SQLCHAR szColBuffer[MAX_COL_NAME] = { 0 } ;
  1584.     SQLCHAR szAuxBuffer[MAX_STR_LEN] = { 0 } ;
  1585.     ODBC_HANDLES stHandles ;
  1586.     memset(&stHandles, 0, sizeof(ODBC_HANDLES)) ;
  1587.     int c = 0, t = 0 ;
  1588.     GetHandles(&stHandles, GET, 0) ;
  1589.     for(c = 0 ; c < nCol ; ++c) {
  1590.         switch(joinType){
  1591.         case ITSELF:
  1592.             sprintf((char*)szStmt, "SELECT * FROM %s, %s", (char*)szTable, (char*)szTable) ;
  1593.             break ;
  1594.         case EQUI:
  1595.             break ;
  1596.         case NON_EQUI:
  1597.             break ;
  1598.         case INNER:
  1599.             break ;
  1600.         case OUTTER:
  1601.             break ;
  1602.         default:
  1603.             break ;
  1604.             }
  1605.         }
  1606. GetHandles(&stHandles, FREE, 0) ;
  1607. return retcode ;
  1608. }
  1609. SQLRETURN GetResults(SQLHSTMT){
  1610.     SQLRETURN retcode = SQL_ERROR ;
  1611.     return retcode ;
  1612. }
  1613. /*
  1614. int createTables(char* szTableName, int nTables){
  1615.   
  1616. for (int i = 0; i < nNoOfCol; i++){
  1617. snprintf(attrName[i], MAXSTRLEN, "COL%d", i) ;
  1618. }
  1619. for (int i = 0; i < nTables; i++){
  1620. snprintf(tableName[i], MAXSTRLEN, "TAB%d", i) ;
  1621. }
  1622.   
  1623. for(unsigned i = 0; i < nTables; i++){
  1624. ndbout << "Creating " << szTableName[i] << "... " ;
  1625. NDBT_Table tmpTable(szTableName[i]) ;
  1626. tmpTable.setStoredTable(!theTempTable) ;
  1627.     
  1628.    tmpTable.addAttribute(NDBT_Attribute(attrName[0],
  1629.                                     UnSigned,
  1630.                                     4, // 4 Bytes
  1631.                                     TupleKey));
  1632. }
  1633. for (int j = 1 ; j < nNoOfCol ; j++)
  1634. tmpTable.addAttribute(NDBT_Attribute(attrName[j], UnSigned, 4*tAttributeSize)) ;
  1635. if(tmpTable.createTableInDb(pMyNdb) == -1){
  1636. return -1 ;
  1637. }
  1638.     
  1639. ndbout << "done" << endl ;
  1640. return 0;
  1641. }
  1642. */
  1643. /*************************************************
  1644. Function: createTables()
  1645. Uses NDB API to create tables for the tests
  1646. *************************************************/
  1647. int createTables(char* szTableName, int nTables){
  1648.   Ndb * pNdb = new Ndb("TEST_DB") ;
  1649.   pNdb->init();
  1650.   
  1651.   ndbout << "Waiting for ndb to become ready..." <<endl;
  1652.   if (pNdb->waitUntilReady(10000) != 0){
  1653.     ndbout << "NDB is not ready" << endl;
  1654.     ndbout << "Benchmark failed!" << endl;
  1655.     delete pNdb ;
  1656. return -1 ;
  1657.   }
  1658.   NdbSchemaCon          *MySchemaTransaction = NULL ;
  1659.   NdbSchemaOp           *MySchemaOp = NULL ;
  1660.   int                   check = -1 ;
  1661.   char szColNameBuffer[MAX_COL_NAME] = { 0 } ;
  1662.   int tLoadFactor = 80 ;
  1663.   
  1664.   for(int i=0 ; i < nTables ; ++i) {
  1665.   
  1666.   ndbout << "Creating " << (char*)(szTableName+MAX_TABLE_NAME*i) << "..." << endl ;
  1667.       MySchemaTransaction = pNdb->startSchemaTransaction() ;
  1668.   //printf("MySchemaTransaction - OKn") ;
  1669.       if(MySchemaTransaction == NULL){
  1670.   printf("MySchemaTransaction is NULLn") ;
  1671.   delete pNdb ;
  1672.   return -1 ;
  1673.   }
  1674.       
  1675.       MySchemaOp = MySchemaTransaction->getNdbSchemaOp();       
  1676.      //printf("MySchemaTransaction->getNdb... - OKn") ;
  1677.       if(MySchemaOp == NULL){
  1678.      printf("MySchemaOp is NULLn") ;
  1679.   delete pNdb ;
  1680.   return -1 ;
  1681.   }
  1682.       
  1683.       check = MySchemaOp->createTable( (const char*)(szTableName+MAX_TABLE_NAME*i)
  1684.                                        ,8                       // Table Size
  1685.                                        ,TupleKey                // Key Type
  1686.                                        ,40                      // Nr of Pages
  1687.                                        ,All
  1688.                                        ,6
  1689.                                        ,(tLoadFactor - 5)
  1690.                                        ,(tLoadFactor)
  1691.                                        ,1
  1692.                                        ,0
  1693.                                        );
  1694.       
  1695.       if (check == -1){
  1696.     printf("MySchemaOp->createTable failedn") ;
  1697.   delete pNdb ;
  1698.   return -1 ;
  1699.   }
  1700.       snprintf(szColNameBuffer, MAX_COL_NAME, "COL%d", 0) ;
  1701.       check = MySchemaOp->createAttribute( szColNameBuffer,
  1702.                                            TupleKey,
  1703.                                            32,
  1704.                                            PKSIZE,
  1705.                                            UnSigned,
  1706.                                            MMBased,
  1707.                                            NotNullAttribute );
  1708.       
  1709.       if (check == -1){
  1710.      printf("MySchemaOp->createAttribute() #1 failedn") ;
  1711.   delete pNdb ;
  1712.   return -1 ;
  1713.   }
  1714.       for (int j = 1; j < nNoOfCol ; j++){
  1715.   snprintf(szColNameBuffer, MAX_COL_NAME, "COL%d", j) ;
  1716.   check = MySchemaOp->createAttribute(szColNameBuffer,
  1717.                                              NoKey,
  1718.                                              32,
  1719.                                              tAttributeSize,
  1720.                                              UnSigned,
  1721.                                              MMBased,
  1722.                                              NotNullAttribute );
  1723.   if (check == -1){
  1724.        printf("MySchemaOp->createAttribute() #2 failedn") ;
  1725.   delete pNdb ;
  1726.   return -1;
  1727.   }
  1728.       }
  1729.       
  1730.       if (MySchemaTransaction->execute() == -1){
  1731.       printf("MySchemaTransaction->execute() failedn") ;
  1732.   printf("%sn", MySchemaTransaction->getNdbError().message) ; 
  1733.   return -1 ;
  1734.   delete pNdb ;
  1735.   }
  1736.       
  1737.       pNdb->closeSchemaTransaction(MySchemaTransaction);
  1738.     }
  1739.   
  1740.   return 0;
  1741. }