MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HugoQueries.cpp
1 /*
2  Copyright (C) 2003 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 "HugoQueries.hpp"
20 #include <NDBT_Stats.hpp>
21 #include <NdbSleep.h>
22 #include <NdbTick.h>
23 #include "../../src/ndbapi/NdbQueryOperation.hpp"
24 
25 HugoQueries::HugoQueries(const NdbQueryDef & query)
26 {
27  m_retryMax = 100;
28  m_query_def = &query;
29 
30  for (Uint32 i = 0; i<query.getNoOfOperations(); i++)
31  {
32  struct Op op;
33  op.m_query_op = query.getQueryOperation(i);
34  op.m_calc = 0;
35  if (op.m_query_op->getTable())
36  {
37  op.m_calc = new HugoCalculator(* op.m_query_op->getTable());
38  }
39  m_ops.push_back(op);
40  }
41 }
42 
43 HugoQueries::~HugoQueries()
44 {
45  for (size_t o = 0; o<m_ops.size(); o++)
46  {
47  while (m_ops[o].m_rows.size())
48  {
49  delete m_ops[o].m_rows.back();
50  m_ops[o].m_rows.erase(m_ops[o].m_rows.size() - 1);
51  }
52  if (m_ops[o].m_calc)
53  delete m_ops[o].m_calc;
54  }
55 }
56 
57 void
58 HugoQueries::allocRows(int batch)
59 {
60  for (size_t o = 0; o<m_ops.size(); o++)
61  {
62  const NdbQueryOperationDef * pOp =m_query_def->getQueryOperation((Uint32)o);
63  const NdbDictionary::Table* tab = pOp->getTable();
64 
65  if (tab)
66  {
67  while (m_ops[o].m_rows.size() < (size_t)batch)
68  {
69  m_ops[o].m_rows.push_back(new NDBT_ResultRow(* tab));
70  }
71  }
72  }
73 }
74 
75 int
76 HugoQueries::equalForParameters(char * buf,
77  Op & op,
78  NdbQueryParamValue params[],
79  int rowNo)
80 {
81  Uint32 no = 0;
82  HugoCalculator & calc = * op.m_calc;
83  const NdbDictionary::Table & tab = calc.getTable();
84  if (op.m_query_op->getType() == NdbQueryOperationDef::TableScan)
85  {
86 
87  }
88  else if (op.m_query_op->getType() == NdbQueryOperationDef::PrimaryKeyAccess)
89  {
90  for (int i = 0; i<tab.getNoOfColumns(); i++)
91  {
92  const NdbDictionary::Column* attr = tab.getColumn(i);
93  if (attr->getPrimaryKey())
94  {
95  Uint32 len = attr->getSizeInBytes();
96  Uint32 real_len;
97  bzero(buf, len);
98  calc.calcValue((Uint32)rowNo, i, 0, buf, len, &real_len);
99  params[no++]= NdbQueryParamValue((void*)buf);
100  buf += len;
101  }
102  }
103  }
104  else if (op.m_query_op->getType() == NdbQueryOperationDef::UniqueIndexAccess||
105  op.m_query_op->getType() == NdbQueryOperationDef::OrderedIndexScan)
106  {
107  const NdbDictionary::Index* idx = op.m_query_op->getIndex();
108  for (unsigned i = 0; i < idx->getNoOfColumns(); i++)
109  {
110  const NdbDictionary::Column* attr =
111  tab.getColumn(idx->getColumn(i)->getName());
112  Uint32 len = attr->getSizeInBytes();
113  Uint32 real_len;
114  bzero(buf, len);
115  calc.calcValue((Uint32)rowNo, attr->getColumnNo(),
116  0, buf, len, &real_len);
117  params[no++]= NdbQueryParamValue((void*)buf);
118  buf += len;
119  }
120  }
121  return 0;
122 }
123 
124 int
125 HugoQueries::getValueForQueryOp(NdbQueryOperation* pOp, NDBT_ResultRow * pRow)
126 {
127  const NdbDictionary::Table & tab = pRow->getTable();
128  for(int a = 0; a<tab.getNoOfColumns(); a++)
129  {
130  pRow->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName());
131  }
132 
133  return 0;
134 }
135 
136 int
137 HugoQueries::runLookupQuery(Ndb* pNdb,
138  int records,
139  int batch)
140 {
141  int r = 0;
142  int retryAttempt = 0;
143 
144  m_rows_found.clear();
145  Uint32 zero = 0;
146  m_rows_found.fill(m_query_def->getNoOfOperations() - 1, zero);
147 
148  if (batch == 0) {
149  g_info << "ERROR: Argument batch == 0 in runLookupQuery. Not allowed."
150  << endl;
151  return NDBT_FAILED;
152  }
153 
154  allocRows(batch);
155 
156  while (r < records)
157  {
158  if(r + batch > records)
159  batch = records - r;
160 
161  if (retryAttempt >= m_retryMax)
162  {
163  g_info << "ERROR: has retried this operation " << retryAttempt
164  << " times, failing!" << endl;
165  return NDBT_FAILED;
166  }
167 
168  Vector<Uint32> batch_rows_found;
169  batch_rows_found.fill(m_query_def->getNoOfOperations() - 1, zero);
170  Vector<NdbQuery*> queries;
171 
172  NdbTransaction * pTrans = pNdb->startTransaction();
173  if (pTrans == NULL)
174  {
175  const NdbError err = pNdb->getNdbError();
176 
177  if (err.status == NdbError::TemporaryError){
178  ERR(err);
179  NdbSleep_MilliSleep(50);
180  retryAttempt++;
181  continue;
182  }
183  ERR(err);
184  return NDBT_FAILED;
185  }
186 
187  for (int b = 0; b<batch; b++)
188  {
189  char buf[NDB_MAX_TUPLE_SIZE];
190  NdbQueryParamValue params[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
191  equalForParameters(buf, m_ops[0], params, b + r);
192 
193  NdbQuery * query = pTrans->createQuery(m_query_def, params);
194  if (query == 0)
195  {
196  const NdbError err = pTrans->getNdbError();
197  ERR(err);
198  return NDBT_FAILED;
199  }
200 
201  for (size_t o = 0; o<m_ops.size(); o++)
202  {
203  NdbQueryOperation * pOp = query->getQueryOperation((Uint32)o);
204  HugoQueries::getValueForQueryOp(pOp, m_ops[o].m_rows[b]);
205  }
206  queries.push_back(query);
207  }
208 
209  int check = pTrans->execute(NoCommit, AbortOnError);
210  if (check == -1)
211  {
212  const NdbError err = pTrans->getNdbError();
213  ERR(err);
214  if (err.status == NdbError::TemporaryError){
215  pTrans->close();
216  NdbSleep_MilliSleep(50);
217  retryAttempt++;
218  continue;
219  }
220  pTrans->close();
221  return NDBT_FAILED;
222  }
223 
224  for (int b = 0; b<batch; b++)
225  {
226  NdbQuery * query = queries[b];
227  if (query->nextResult() == NdbQuery::NextResult_gotRow)
228  {
229  for (size_t o = 0; o<m_ops.size(); o++)
230  {
231  NdbQueryOperation * pOp = query->getQueryOperation((Uint32)o);
232  if (!pOp->isRowNULL())
233  {
234  batch_rows_found[o]++;
235  if (m_ops[o].m_calc->verifyRowValues(m_ops[o].m_rows[b]) != 0)
236  {
237  pTrans->close();
238  return NDBT_FAILED;
239  }
240  }
241  }
242  }
243  }
244  pTrans->close();
245  r += batch;
246 
247  for (size_t i = 0; i<batch_rows_found.size(); i++)
248  m_rows_found[i] += batch_rows_found[i];
249  }
250 
251  return NDBT_OK;
252 }
253 
254 int
255 HugoQueries::runScanQuery(Ndb * pNdb,
256  int abort,
257  int parallelism,
258  int scan_flags)
259 {
260  int retryAttempt = 0;
261 
262  allocRows(1);
263 
264  while (retryAttempt < m_retryMax)
265  {
266  m_rows_found.clear();
267  Uint32 zero = 0;
268  m_rows_found.fill(m_query_def->getNoOfOperations() - 1, zero);
269 
270  NdbTransaction * pTrans = pNdb->startTransaction();
271  if (pTrans == NULL)
272  {
273  const NdbError err = pNdb->getNdbError();
274  ERR(err);
275  if (err.status == NdbError::TemporaryError){
276  NdbSleep_MilliSleep(50);
277  retryAttempt++;
278  continue;
279  }
280  return NDBT_FAILED;
281  }
282 
283  NdbQuery * query = 0;
284 
285  char buf[NDB_MAX_TUPLE_SIZE];
286  NdbQueryParamValue params[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
287  equalForParameters(buf, m_ops[0], params, /* rowNo */ 0);
288  query = pTrans->createQuery(m_query_def, params);
289  if (query == 0)
290  {
291  const NdbError err = pTrans->getNdbError();
292  ERR(err);
293  return NDBT_FAILED;
294  }
295 
296  for (size_t o = 0; o<m_ops.size(); o++)
297  {
298  NdbQueryOperation * pOp = query->getQueryOperation((Uint32)o);
299  HugoQueries::getValueForQueryOp(pOp, m_ops[o].m_rows[0]);
300  }
301 
302  int check = pTrans->execute(NoCommit, AbortOnError);
303  if (check == -1)
304  {
305  const NdbError err = pTrans->getNdbError();
306  ERR(err);
307  if (err.status == NdbError::TemporaryError){
308  pTrans->close();
309  NdbSleep_MilliSleep(50);
310  retryAttempt++;
311  continue;
312  }
313  pTrans->close();
314  return NDBT_FAILED;
315  }
316 
317  int r = rand() % 100;
318  if (r < abort && ((r & 1) == 0))
319  {
320  ndbout_c("Query aborted!");
321  query->close();
322  pTrans->close();
323  m_rows_found.clear();
324  return NDBT_OK;
325  }
326 
328  while ((res = query->nextResult()) == NdbQuery::NextResult_gotRow)
329  {
330  if (r < abort && ((r & 1) == 1))
331  {
332  ndbout_c("Query aborted 2!");
333  query->close();
334  pTrans->close();
335  m_rows_found.clear();
336  return NDBT_OK;
337  }
338 
339  for (size_t o = 0; o<m_ops.size(); o++)
340  {
341  NdbQueryOperation * pOp = query->getQueryOperation((Uint32)o);
342  if (!pOp->isRowNULL())
343  {
344  m_rows_found[o]++;
345  if (m_ops[o].m_calc->verifyRowValues(m_ops[o].m_rows[0]) != 0)
346  {
347  pTrans->close();
348  return NDBT_FAILED;
349  }
350  }
351  }
352  }
353 
354  const NdbError err = query->getNdbError();
355  query->close();
356  pTrans->close();
357  if (res == NdbQuery::NextResult_error)
358  {
359  ERR(err);
360  if (err.status == NdbError::TemporaryError)
361  {
362  NdbSleep_MilliSleep(50);
363  retryAttempt++;
364  continue;
365  }
366  return NDBT_FAILED;
367  }
368  else if (res != NdbQuery::NextResult_scanComplete)
369  {
370  ndbout_c("Got %u from nextResult()", res);
371  return NDBT_FAILED;
372  }
373  break;
374  }
375 
376  return NDBT_OK;
377 }
378 
379 template class Vector<HugoQueries::Op>;
380 template class Vector<NdbQuery*>;