MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
testOrderedIndex.cpp
1 /*
2  Copyright (C) 2003-2006 MySQL AB
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <NDBT.hpp>
20 #include <NDBT_Test.hpp>
21 #include <HugoTransactions.hpp>
22 #include <UtilTransactions.hpp>
23 #include <NdbRestarter.hpp>
24 #include <Vector.hpp>
25 #include <ndbapi_limits.h>
26 
27 const unsigned MaxTableAttrs = NDB_MAX_ATTRIBUTES_IN_TABLE;
28 const unsigned MaxIndexAttrs = NDB_MAX_ATTRIBUTES_IN_INDEX;
29 const unsigned MaxIndexes = 20;
30 
31 static unsigned
32 urandom(unsigned n)
33 {
34  unsigned i = random();
35  return i % n;
36 }
37 
38 static int
39 runDropIndex(NDBT_Context* ctx, NDBT_Step* step)
40 {
41  const NdbDictionary::Table* pTab = ctx->getTab();
42  Ndb* pNdb = GETNDB(step);
45  if (pDic->listIndexes(list, pTab->getName()) != 0) {
46  g_err << pTab->getName() << ": listIndexes failed" << endl;
47  ERR(pDic->getNdbError());
48  return NDBT_FAILED;
49  }
50  for (unsigned i = 0; i < list.count; i++) {
51  NDBT_Index* pInd = new NDBT_Index(list.elements[i].name);
52  pInd->setTable(pTab->getName());
53  g_info << "Drop index:" << endl << *pInd;
54  if (pInd->dropIndexInDb(pNdb) != 0) {
55  return NDBT_FAILED;
56  }
57  }
58  return NDBT_OK;
59 }
60 
61 static Uint32 workaround[1000];
62 
63 static void
64 setTableProperty(NDBT_Context* ctx, NDBT_Table* pTab, const char* name, Uint32 num)
65 {
66  char key[200];
67  sprintf(key, "%s-%s", name, pTab->getName());
68  //ctx->setProperty(key, num);
69  workaround[pTab->getTableId()] = num;
70 }
71 
72 static Uint32
73 getTableProperty(NDBT_Context* ctx, NDBT_Table* pTab, const char* name)
74 {
75  char key[200];
76  sprintf(key, "%s-%s", name, pTab->getName());
77  //Uint32 num = ctx->getProperty(key, (Uint32)-1);
78  Uint32 num = workaround[pTab->getTableId()];
79  assert(num != (Uint32)-1);
80  return num;
81 }
82 
83 static int
84 runCreateIndex(NDBT_Context* ctx, NDBT_Step* step)
85 {
86  srandom(1);
87  NDBT_Table* pTab = ctx->getTab();
88  Ndb* pNdb = GETNDB(step);
89  unsigned numTabAttrs = pTab->getNumAttributes();
90  unsigned numIndex = 0;
91  while (numIndex < MaxIndexes) {
92  if (numIndex != 0 && urandom(10) == 0)
93  break;
94  char buf[200];
95  sprintf(buf, "%s_X%03d", pTab->getName(), numIndex);
96  NDBT_Index* pInd = new NDBT_Index(buf);
97  pInd->setTable(pTab->getName());
99  pInd->setLogging(false);
100  unsigned numAttrs = 0;
101  while (numAttrs < MaxIndexAttrs) {
102  if (numAttrs != 0 && urandom(5) == 0)
103  break;
104  unsigned i = urandom(numTabAttrs);
105  const NDBT_Attribute* pAttr = pTab->getAttribute(i);
106  bool found = false;
107  for (unsigned j = 0; j < numAttrs; j++) {
108  if (strcmp(pAttr->getName(), pInd->getAttribute(j)->getName()) == 0) {
109  found = true;
110  break;
111  }
112  }
113  if (found)
114  continue;
115  pInd->addAttribute(*pAttr);
116  numAttrs++;
117  }
118  g_info << "Create index:" << endl << *pInd;
119  if (pInd->createIndexInDb(pNdb, false) != 0)
120  continue;
121  numIndex++;
122  }
123  setTableProperty(ctx, pTab, "numIndex", numIndex);
124  g_info << "Created " << numIndex << " indexes on " << pTab->getName() << endl;
125  return NDBT_OK;
126 }
127 
128 static int
129 runInsertUpdate(NDBT_Context* ctx, NDBT_Step* step)
130 {
131  NDBT_Table* pTab = ctx->getTab();
132  Ndb* pNdb = GETNDB(step);
133  int ret;
134  g_info << "Insert: " << pTab->getName() << endl;
135  HugoTransactions hugoTrans(*pTab);
136  ret = hugoTrans.loadTable(pNdb, ctx->getNumRecords(), 100);
137  if (ret != 0) {
138  g_err << "ERR: " << step->getName() << "failed" << endl;
139  return NDBT_FAILED;
140  }
141  return NDBT_OK;
142 }
143 
144 static int
145 runFullScan(NDBT_Context* ctx, NDBT_Step* step)
146 {
147  NDBT_Table* pTab = ctx->getTab();
148  Ndb* pNdb = GETNDB(step);
149  unsigned cntIndex = getTableProperty(ctx, pTab, "numIndex");
150  for (unsigned numIndex = 0; numIndex < cntIndex; numIndex++) {
151  char buf[200];
152  sprintf(buf, "%s_X%03d", pTab->getName(), numIndex);
153  NDBT_Index* pInd = NDBT_Index::discoverIndexFromDb(pNdb, buf, pTab->getName());
154  assert(pInd != 0);
155  g_info << "Scan index:" << pInd->getName() << endl << *pInd;
156  NdbConnection* pCon = pNdb->startTransaction();
157  if (pCon == 0) {
158  ERR(pNdb->getNdbError());
159  return NDBT_FAILED;
160  }
161  NdbOperation* pOp = pCon->getNdbOperation(pInd->getName(),
162  pTab->getName());
163  if (pOp == 0) {
164  ERR(pCon->getNdbError());
165  pNdb->closeTransaction(pCon);
166  return NDBT_FAILED;
167  }
168  if (pOp->openScanRead() != 0) {
169  ERR(pCon->getNdbError());
170  pNdb->closeTransaction(pCon);
171  return NDBT_FAILED;
172  }
173  if (pCon->executeScan() != 0) {
174  ERR(pCon->getNdbError());
175  pNdb->closeTransaction(pCon);
176  return NDBT_FAILED;
177  }
178  unsigned rows = 0;
179  while (1) {
180  int ret = pCon->nextScanResult();
181  if (ret == 0) {
182  rows++;
183  } else if (ret == 1) {
184  break;
185  } else {
186  ERR(pCon->getNdbError());
187  pNdb->closeTransaction(pCon);
188  return NDBT_FAILED;
189  }
190  }
191  pNdb->closeTransaction(pCon);
192  g_info << "Scanned " << rows << " rows" << endl;
193  }
194  return NDBT_OK;
195 }
196 
197 NDBT_TESTSUITE(testOrderedIndex);
198 TESTCASE(
199  "DropIndex",
200  "Drop any old indexes") {
201  INITIALIZER(runDropIndex);
202 }
203 TESTCASE(
204  "CreateIndex",
205  "Create ordered indexes") {
206  INITIALIZER(runCreateIndex);
207 }
208 TESTCASE(
209  "InsertUpdate",
210  "Run inserts and updates") {
211  INITIALIZER(runInsertUpdate);
212 }
213 TESTCASE(
214  "FullScan",
215  "Full scan on each ordered index") {
216  INITIALIZER(runFullScan);
217 }
218 NDBT_TESTSUITE_END(testOrderedIndex);
219 
220 int
221 main(int argc, const char** argv)
222 {
223  ndb_init();
224  return testOrderedIndex.execute(argc, argv);
225 }
226 
227 // vim: set sw=2: