MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbIndexStat.cpp
1 /*
2  Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <ndb_global.h>
19 #include <AttributeHeader.hpp>
20 #include <NdbSqlUtil.hpp>
21 #include <NdbIndexStat.hpp>
22 #include <NdbTransaction.hpp>
23 #include "NdbDictionaryImpl.hpp"
24 #include <NdbInterpretedCode.hpp>
25 #include <NdbRecord.hpp>
26 #include "NdbIndexStatImpl.hpp"
27 
28 NdbIndexStat::NdbIndexStat() :
29  m_impl(*new NdbIndexStatImpl(*this))
30 {
31 }
32 
33 NdbIndexStat::NdbIndexStat(NdbIndexStatImpl& impl) :
34  m_impl(impl)
35 {
36 }
37 
38 NdbIndexStat::~NdbIndexStat()
39 {
40  NdbIndexStatImpl* impl = &m_impl;
41  if (this != impl)
42  delete impl;
43 }
44 
60 int
61 NdbIndexStat::addKeyPartInfo(const NdbRecord* record,
62  const char* keyRecordData,
63  Uint32 keyPartNum,
64  const NdbIndexScanOperation::BoundType boundType,
65  Uint32* keyStatData,
66  Uint32& keyLength)
67 {
68  char buf[NdbRecord::Attr::SHRINK_VARCHAR_BUFFSIZE];
69 
70  Uint32 key_index= record->key_indexes[ keyPartNum ];
71  const NdbRecord::Attr *column= &record->columns[ key_index ];
72 
73  bool is_null= column->is_null(keyRecordData);
74  Uint32 len= 0;
75  const void *aValue= keyRecordData + column->offset;
76 
77  if (!is_null)
78  {
79  bool len_ok;
80  /* Support for special mysqld varchar format in keys. */
81  if (column->flags & NdbRecord::IsMysqldShrinkVarchar)
82  {
83  len_ok= column->shrink_varchar(keyRecordData,
84  len,
85  buf);
86  aValue= buf;
87  }
88  else
89  {
90  len_ok= column->get_var_length(keyRecordData, len);
91  }
92  if (!len_ok) {
93  m_impl.setError(4209, __LINE__);
94  return -1;
95  }
96  }
97 
98  /* Insert attribute header. */
99  Uint32 tIndexAttrId= column->index_attrId;
100  Uint32 sizeInWords= (len + 3) / 4;
101  AttributeHeader ah(tIndexAttrId, sizeInWords << 2);
102  const Uint32 ahValue= ah.m_value;
103 
104  if (keyLength + (2 + len) > NdbIndexStatImpl::BoundBufWords )
105  {
106  /* Something wrong, key data would be too big */
107  /* Key size is limited to 4092 bytes */
108  m_impl.setError(4207, __LINE__);
109  return -1;
110  }
111 
112  /* Fill in key data */
113  keyStatData[ keyLength++ ]= boundType;
114  keyStatData[ keyLength++ ]= ahValue;
115  /* Zero last word prior to byte copy, in case we're not aligned */
116  keyStatData[ keyLength + sizeInWords - 1] = 0;
117  memcpy(&keyStatData[ keyLength ], aValue, len);
118 
119  keyLength+= sizeInWords;
120 
121  return 0;
122 }
123 
124 int
125 NdbIndexStat::records_in_range(const NdbDictionary::Index* index,
126  NdbTransaction* trans,
127  const NdbRecord* key_record,
128  const NdbRecord* result_record,
130  Uint64 table_rows,
131  Uint64* count,
132  int flags)
133 {
134  DBUG_ENTER("NdbIndexStat::records_in_range");
135  Uint64 rows;
136  Uint32 key1[NdbIndexStatImpl::BoundBufWords], keylen1;
137  Uint32 key2[NdbIndexStatImpl::BoundBufWords], keylen2;
138 
139  if (true)
140  {
141  // get start and end key from NdbIndexBound, using NdbRecord to
142  // get values into a standard format.
143  Uint32 maxBoundParts= (ib->low_key_count > ib->high_key_count) ?
144  ib->low_key_count : ib->high_key_count;
145 
146  keylen1= keylen2= 0;
147 
148  /* Fill in keyX buffers */
149  for (Uint32 keyPartNum=0; keyPartNum < maxBoundParts; keyPartNum++)
150  {
151  if (ib->low_key_count > keyPartNum)
152  {
153  /* Set bound to LT only if it's not inclusive
154  * and this is the last key
155  */
158  if ((! ib->low_inclusive) &&
159  (keyPartNum == (ib->low_key_count -1 )))
161 
162  if (addKeyPartInfo(key_record,
163  ib->low_key,
164  keyPartNum,
165  boundType,
166  key1,
167  keylen1) != 0)
168  DBUG_RETURN(-1);
169  }
170  if (ib->high_key_count > keyPartNum)
171  {
172  /* Set bound to GT only if it's not inclusive
173  * and this is the last key
174  */
177  if ((! ib->high_inclusive) &&
178  (keyPartNum == (ib->high_key_count -1)))
179  boundType= NdbIndexScanOperation::BoundGT;
180 
181  if (addKeyPartInfo(key_record,
182  ib->high_key,
183  keyPartNum,
184  boundType,
185  key2,
186  keylen2) != 0)
187  DBUG_RETURN(-1);
188  }
189  }
190  }
191 
192  if (true)
193  {
194  Uint32 out[4] = { 0, 0, 0, 0 }; // rows, in, before, after
195  float tot[4] = { 0, 0, 0, 0 }; // totals of above
196  int cnt, ret;
197  bool forceSend = true;
198  const Uint32 codeWords= 1;
199  Uint32 codeSpace[ codeWords ];
200  NdbInterpretedCode code(NULL, // No table
201  &codeSpace[0],
202  codeWords);
203  if ((code.interpret_exit_last_row() != 0) ||
204  (code.finalise() != 0))
205  {
206  m_impl.setError(code.getNdbError().code, __LINE__);
207  DBUG_PRINT("error", ("code: %d", code.getNdbError().code));
208  DBUG_RETURN(-1);
209  }
210 
211  NdbIndexScanOperation* op= NULL;
214 
215  options.optionsPresent=
216  NdbScanOperation::ScanOptions::SO_GETVALUE |
217  NdbScanOperation::ScanOptions::SO_INTERPRETED;
218 
219  /* Read RECORDS_IN_RANGE pseudo column */
220  extraGet.column= NdbDictionary::Column::RECORDS_IN_RANGE;
221  extraGet.appStorage= (void*) out;
222  extraGet.recAttr= NULL;
223 
224  options.extraGetValues= &extraGet;
225  options.numExtraGetValues= 1;
226 
227  /* Add interpreted code to return on 1st row */
228  options.interpretedCode= &code;
229 
230  const Uint32 keyBitmaskWords= (NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY + 31) >> 5;
231  Uint32 emptyMask[keyBitmaskWords];
232  memset(&emptyMask[0], 0, keyBitmaskWords << 2);
233 
234  if (NULL ==
235  (op= trans->scanIndex(key_record,
236  result_record,
238  (const unsigned char*) &emptyMask[0],
239  ib,
240  &options,
242  {
243  m_impl.setError(trans->getNdbError().code, __LINE__);
244  DBUG_PRINT("error", ("scanIndex : %d", trans->getNdbError().code));
245  DBUG_RETURN(-1);
246  }
247 
249  NdbOperation::AbortOnError, forceSend) == -1) {
250  m_impl.setError(trans->getNdbError().code, __LINE__);
251  DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code,
252  op->getNdbError().code));
253  DBUG_RETURN(-1);
254  }
255  cnt = 0;
256  const char* dummy_out_ptr= NULL;
257  while ((ret = op->nextResult(&dummy_out_ptr,
258  true, forceSend)) == 0) {
259  DBUG_PRINT("info", ("frag rows=%u in=%u before=%u after=%u [error=%d]",
260  out[0], out[1], out[2], out[3],
261  (int)(out[1] + out[2] + out[3]) - (int)out[0]));
262  unsigned i;
263  for (i = 0; i < 4; i++)
264  tot[i] += (float)out[i];
265  cnt++;
266  }
267  if (ret == -1) {
268  m_impl.setError(op->getNdbError().code, __LINE__);
269  DBUG_PRINT("error nextResult ", ("trans:%d op:%d", trans->getNdbError().code,
270  op->getNdbError().code));
271  DBUG_RETURN(-1);
272  }
273  op->close(forceSend);
274  rows = (Uint64)tot[1];
275  }
276 
277  *count = rows;
278  DBUG_PRINT("value", ("rows=%u/%u flags=%x",
279  (unsigned)(rows>>32), (unsigned)(rows), flags));
280  DBUG_RETURN(0);
281 }
282 
283 // stored stats
284 
285 int
286 NdbIndexStat::create_systables(Ndb* ndb)
287 {
288  DBUG_ENTER("NdbIndexStat::create_systables");
289  if (m_impl.create_systables(ndb) == -1)
290  DBUG_RETURN(-1);
291  DBUG_RETURN(0);
292 }
293 
294 int
295 NdbIndexStat::drop_systables(Ndb* ndb)
296 {
297  DBUG_ENTER("NdbIndexStat::drop_systables");
298  if (m_impl.drop_systables(ndb) == -1)
299  DBUG_RETURN(-1);
300  DBUG_RETURN(0);
301 }
302 
303 int
304 NdbIndexStat::check_systables(Ndb* ndb)
305 {
306  DBUG_ENTER("NdbIndexStat::check_systables");
307  if (m_impl.check_systables(ndb) == -1)
308  DBUG_RETURN(-1);
309  DBUG_RETURN(0);
310 }
311 
312 int
313 NdbIndexStat::set_index(const NdbDictionary::Index& index,
315 {
316  DBUG_ENTER("NdbIndexStat::set_index");
317  if (m_impl.set_index(index, table) == -1)
318  DBUG_RETURN(-1);
319  m_impl.m_facadeHead.m_indexId = index.getObjectId();
320  m_impl.m_facadeHead.m_indexVersion = index.getObjectVersion();
321  m_impl.m_facadeHead.m_tableId = table.getObjectId();
322  DBUG_RETURN(0);
323 }
324 
325 void
326 NdbIndexStat::reset_index()
327 {
328  DBUG_ENTER("NdbIndexStat::reset_index");
329  m_impl.reset_index();
330  DBUG_VOID_RETURN;
331 }
332 
333 int
334 NdbIndexStat::update_stat(Ndb* ndb)
335 {
336  DBUG_ENTER("NdbIndexStat::update_stat");
337  if (m_impl.update_stat(ndb, m_impl.m_facadeHead) == -1)
338  DBUG_RETURN(-1);
339  DBUG_RETURN(0);
340 }
341 
342 int
343 NdbIndexStat::delete_stat(Ndb* ndb)
344 {
345  DBUG_ENTER("NdbIndexStat::delete_stat");
346  if (m_impl.delete_stat(ndb, m_impl.m_facadeHead) == -1)
347  DBUG_RETURN(-1);
348  DBUG_RETURN(0);
349 }
350 
351 // cache
352 
353 void
354 NdbIndexStat::move_cache()
355 {
356  DBUG_ENTER("NdbIndexStat::move_cache");
357  m_impl.move_cache();
358  DBUG_VOID_RETURN;
359 }
360 
361 void
362 NdbIndexStat::clean_cache()
363 {
364  DBUG_ENTER("NdbIndexStat::clean_cache");
365  m_impl.clean_cache();
366  DBUG_VOID_RETURN;
367 }
368 
369 void
370 NdbIndexStat::get_cache_info(CacheInfo& info, CacheType type) const
371 {
372  const NdbIndexStatImpl::Cache* c = 0;
373  switch (type) {
374  case CacheBuild:
375  c = m_impl.m_cacheBuild;
376  break;
377  case CacheQuery:
378  c = m_impl.m_cacheQuery;
379  break;
380  case CacheClean:
381  c = m_impl.m_cacheClean;
382  break;
383  }
384  info.m_count = 0;
385  info.m_valid = 0;
386  info.m_sampleCount = 0;
387  info.m_totalBytes = 0;
388  info.m_save_time = 0;
389  info.m_sort_time = 0;
390  while (c != 0)
391  {
392  info.m_count += 1;
393  info.m_valid += c->m_valid;
394  info.m_sampleCount += c->m_sampleCount;
395  info.m_totalBytes += c->m_keyBytes + c->m_valueBytes + c->m_addrBytes;
396  info.m_save_time += c->m_save_time;
397  info.m_sort_time += c->m_sort_time;
398  c = c->m_nextClean;
399  }
400  // build and query cache have at most one instance
401  require(type == CacheClean || info.m_count <= 1);
402 }
403 
404 // read
405 
406 void
407 NdbIndexStat::get_head(Head& head) const
408 {
409  head = m_impl.m_facadeHead;
410 }
411 
412 int
413 NdbIndexStat::read_head(Ndb* ndb)
414 {
415  DBUG_ENTER("NdbIndexStat::read_head");
416  if (m_impl.read_head(ndb, m_impl.m_facadeHead) == -1)
417  DBUG_RETURN(-1);
418  DBUG_RETURN(0);
419 }
420 
421 int
422 NdbIndexStat::read_stat(Ndb* ndb)
423 {
424  DBUG_ENTER("NdbIndexStat::read_stat");
425  if (m_impl.read_stat(ndb, m_impl.m_facadeHead) == -1)
426  DBUG_RETURN(-1);
427  DBUG_RETURN(0);
428 }
429 
430 // bound
431 
432 NdbIndexStat::Bound::Bound(const NdbIndexStat* is, void* buffer)
433 {
434  DBUG_ENTER("NdbIndexStat::Bound::Bound");
435  require(is != 0 && is->m_impl.m_indexSet);
436  require(buffer != 0);
437  Uint8* buf = (Uint8*)buffer;
438  // bound impl
439  Uint8* buf1 = buf;
440  UintPtr ubuf1 = (UintPtr)buf1;
441  if (ubuf1 % 8 != 0)
442  buf1 += (8 - ubuf1 % 8);
443  new (buf1) NdbIndexStatImpl::Bound(is->m_impl.m_keySpec);
444  m_impl = (void*)buf1;
446  // bound data
447  Uint8* buf2 = buf1 + sizeof(NdbIndexStatImpl::Bound);
448  uint used = (uint)(buf2 - buf);
449  uint bytes = BoundBufferBytes - used;
450  bound.m_data.set_buf(buf2, bytes);
451  DBUG_VOID_RETURN;
452 }
453 
454 int
455 NdbIndexStat::add_bound(Bound& bound_f, const void* value)
456 {
457  DBUG_ENTER("NdbIndexStat::add_bound");
458  NdbIndexStatImpl::Bound& bound =
459  *(NdbIndexStatImpl::Bound*)bound_f.m_impl;
460  Uint32 len_out;
461  if (value == 0)
462  {
463  m_impl.setError(UsageError, __LINE__);
464  DBUG_RETURN(-1);
465  }
466  if (bound.m_data.add(value, &len_out) == -1)
467  {
468  m_impl.setError(UsageError, __LINE__);
469  DBUG_RETURN(-1);
470  }
471  DBUG_RETURN(0);
472 }
473 
474 int
475 NdbIndexStat::add_bound_null(Bound& bound_f)
476 {
477  DBUG_ENTER("NdbIndexStat::add_bound_null");
478  NdbIndexStatImpl::Bound& bound =
479  *(NdbIndexStatImpl::Bound*)bound_f.m_impl;
480  Uint32 len_out;
481  if (bound.m_data.add_null(&len_out) == -1)
482  {
483  m_impl.setError(UsageError, __LINE__);
484  DBUG_RETURN(-1);
485  }
486  DBUG_RETURN(0);
487 }
488 
489 void
490 NdbIndexStat::set_bound_strict(Bound& bound_f, int strict)
491 {
492  DBUG_ENTER("NdbIndexStat::set_bound_strict");
493  NdbIndexStatImpl::Bound& bound =
494  *(NdbIndexStatImpl::Bound*)bound_f.m_impl;
495  bound.m_strict = strict;
496  DBUG_VOID_RETURN;
497 }
498 
499 void
500 NdbIndexStat::reset_bound(Bound& bound_f)
501 {
502  DBUG_ENTER("NdbIndexStat::reset_bound");
503  NdbIndexStatImpl::Bound& bound =
504  *(NdbIndexStatImpl::Bound*)bound_f.m_impl;
505  bound.m_bound.reset();
506  bound.m_type = -1;
507  bound.m_strict = -1;
508  DBUG_VOID_RETURN;
509 }
510 
511 // range
512 
513 NdbIndexStat::Range::Range(Bound& bound1, Bound& bound2) :
514  m_bound1(bound1),
515  m_bound2(bound2)
516 {
517  DBUG_ENTER("NdbIndexStat::Range::Range");
518  DBUG_VOID_RETURN;
519 }
520 
521 int
522 NdbIndexStat::finalize_range(Range& range_f)
523 {
524  DBUG_ENTER("NdbIndexStat::finalize_range");
525  Bound& bound1_f = range_f.m_bound1;
526  Bound& bound2_f = range_f.m_bound2;
527  NdbIndexStatImpl::Bound& bound1 =
528  *(NdbIndexStatImpl::Bound*)bound1_f.m_impl;
529  NdbIndexStatImpl::Bound& bound2 =
530  *(NdbIndexStatImpl::Bound*)bound2_f.m_impl;
531  NdbIndexStatImpl::Range range(bound1, bound2);
532  if (m_impl.finalize_range(range) == -1)
533  DBUG_RETURN(-1);
534  DBUG_RETURN(0);
535 }
536 
537 void
538 NdbIndexStat::reset_range(Range& range)
539 {
540  DBUG_ENTER("NdbIndexStat::reset_range");
541  reset_bound(range.m_bound1);
542  reset_bound(range.m_bound2);
543  DBUG_VOID_RETURN;
544 }
545 
546 int
547 NdbIndexStat::convert_range(Range& range_f,
548  const NdbRecord* key_record,
550 {
551  DBUG_ENTER("NdbIndexStat::convert_range");
552  Bound& bound1_f = range_f.m_bound1;
553  Bound& bound2_f = range_f.m_bound2;
554  NdbIndexStatImpl::Bound& bound1 =
555  *(NdbIndexStatImpl::Bound*)bound1_f.m_impl;
556  NdbIndexStatImpl::Bound& bound2 =
557  *(NdbIndexStatImpl::Bound*)bound2_f.m_impl;
558  NdbIndexStatImpl::Range range(bound1, bound2);
559  if (m_impl.convert_range(range, key_record, ib) == -1)
560  DBUG_RETURN(-1);
561  DBUG_RETURN(0);
562 }
563 
564 // stat
565 
566 NdbIndexStat::Stat::Stat(void* buffer)
567 {
568  DBUG_ENTER("NdbIndexStat::Stat::Stat");
569  require(buffer != 0);
570  Uint8* buf = (Uint8*)buffer;
571  // stat impl
572  Uint8* buf1 = buf;
573  UintPtr ubuf1 = (UintPtr)buf1;
574  if (ubuf1 % 8 != 0)
575  buf1 += (8 - ubuf1 % 8);
576  new (buf1) NdbIndexStatImpl::Stat;
577  m_impl = (void*)buf1;
578  DBUG_VOID_RETURN;
579 }
580 
581 int
582 NdbIndexStat::query_stat(const Range& range_f, Stat& stat_f)
583 {
584  DBUG_ENTER("NdbIndexStat::query_stat");
585  Bound& bound1_f = range_f.m_bound1;
586  Bound& bound2_f = range_f.m_bound2;
587  NdbIndexStatImpl::Bound& bound1 =
588  *(NdbIndexStatImpl::Bound*)bound1_f.m_impl;
589  NdbIndexStatImpl::Bound& bound2 =
590  *(NdbIndexStatImpl::Bound*)bound2_f.m_impl;
591  NdbIndexStatImpl::Range range(bound1, bound2);
592 #ifndef DBUG_OFF
593  const uint sz = 8000;
594  char buf[sz];
595  DBUG_PRINT("index_stat", ("lo: %s", bound1.m_bound.print(buf, sz)));
596  DBUG_PRINT("index_stat", ("hi: %s", bound2.m_bound.print(buf, sz)));
597 #endif
598  NdbIndexStatImpl::Stat& stat =
599  *(NdbIndexStatImpl::Stat*)stat_f.m_impl;
600  if (m_impl.query_stat(range, stat) == -1)
601  DBUG_RETURN(-1);
602  DBUG_RETURN(0);
603 }
604 
605 void
606 NdbIndexStat::get_empty(const Stat& stat_f, bool* empty)
607 {
608  DBUG_ENTER("NdbIndexStat::get_empty");
609  const NdbIndexStatImpl::Stat& stat =
610  *(const NdbIndexStatImpl::Stat*)stat_f.m_impl;
611  require(empty != 0);
612  *empty = stat.m_value.m_empty;
613  DBUG_PRINT("index_stat", ("empty:%d", *empty));
614  DBUG_VOID_RETURN;
615 }
616 
617 void
618 NdbIndexStat::get_rir(const Stat& stat_f, double* rir)
619 {
620  DBUG_ENTER("NdbIndexStat::get_rir");
621  const NdbIndexStatImpl::Stat& stat =
622  *(const NdbIndexStatImpl::Stat*)stat_f.m_impl;
623  double x = stat.m_value.m_rir;
624  if (x < 1.0)
625  x = 1.0;
626  require(rir != 0);
627  *rir = x;
628 #ifndef DBUG_OFF
629  char buf[100];
630  sprintf(buf, "%.2f", *rir);
631 #endif
632  DBUG_PRINT("index_stat", ("rir:%s", buf));
633  DBUG_VOID_RETURN;
634 }
635 
636 void
637 NdbIndexStat::get_rpk(const Stat& stat_f, Uint32 k, double* rpk)
638 {
639  DBUG_ENTER("NdbIndexStat::get_rpk");
640  const NdbIndexStatImpl::Stat& stat =
641  *(const NdbIndexStatImpl::Stat*)stat_f.m_impl;
642  double x = stat.m_value.m_rir / stat.m_value.m_unq[k];
643  if (x < 1.0)
644  x = 1.0;
645  require(rpk != 0);
646  *rpk = x;
647 #ifndef DBUG_OFF
648  char buf[100];
649  sprintf(buf, "%.2f", *rpk);
650 #endif
651  DBUG_PRINT("index_stat", ("rpk[%u]:%s", k, buf));
652  DBUG_VOID_RETURN;
653 }
654 
655 void
656 NdbIndexStat::get_rule(const Stat& stat_f, char* buffer)
657 {
658  DBUG_ENTER("NdbIndexStat::get_rule");
659  const NdbIndexStatImpl::Stat& stat =
660  *(const NdbIndexStatImpl::Stat*)stat_f.m_impl;
661  require(buffer != 0);
662  BaseString::snprintf(buffer, RuleBufferBytes, "%s/%s/%s",
663  stat.m_rule[0], stat.m_rule[1], stat.m_rule[2]);
664  DBUG_VOID_RETURN;
665 }
666 
667 // events and polling
668 
669 int
670 NdbIndexStat::create_sysevents(Ndb* ndb)
671 {
672  DBUG_ENTER("NdbIndexStat::create_sysevents");
673  if (m_impl.create_sysevents(ndb) == -1)
674  DBUG_RETURN(-1);
675  DBUG_RETURN(0);
676 }
677 
678 int
679 NdbIndexStat::drop_sysevents(Ndb* ndb)
680 {
681  DBUG_ENTER("NdbIndexStat::drop_sysevents");
682  if (m_impl.drop_sysevents(ndb) == -1)
683  DBUG_RETURN(-1);
684  DBUG_RETURN(0);
685 }
686 
687 int
688 NdbIndexStat::check_sysevents(Ndb* ndb)
689 {
690  DBUG_ENTER("NdbIndexStat::check_sysevents");
691  if (m_impl.check_sysevents(ndb) == -1)
692  DBUG_RETURN(-1);
693  DBUG_RETURN(0);
694 }
695 
696 int
697 NdbIndexStat::create_listener(Ndb* ndb)
698 {
699  DBUG_ENTER("NdbIndexStat::create_listener");
700  if (m_impl.create_listener(ndb) == -1)
701  DBUG_RETURN(-1);
702  DBUG_RETURN(0);
703 }
704 
705 int
706 NdbIndexStat::execute_listener(Ndb* ndb)
707 {
708  DBUG_ENTER("NdbIndexStat::execute_listener");
709  if (m_impl.execute_listener(ndb) == -1)
710  DBUG_RETURN(-1);
711  DBUG_RETURN(0);
712 }
713 
714 int
715 NdbIndexStat::poll_listener(Ndb* ndb, int max_wait_ms)
716 {
717  DBUG_ENTER("NdbIndexStat::poll_listener");
718  int ret = m_impl.poll_listener(ndb, max_wait_ms);
719  if (ret == -1)
720  DBUG_RETURN(-1);
721  DBUG_RETURN(ret);
722 }
723 
724 int
725 NdbIndexStat::next_listener(Ndb* ndb)
726 {
727  DBUG_ENTER("NdbIndexStat::next_listener");
728  int ret = m_impl.next_listener(ndb);
729  if (ret == -1)
730  DBUG_RETURN(-1);
731  DBUG_RETURN(ret);
732 }
733 
734 int
735 NdbIndexStat::drop_listener(Ndb* ndb)
736 {
737  DBUG_ENTER("NdbIndexStat::drop_listener");
738  if (m_impl.drop_listener(ndb) == -1)
739  DBUG_RETURN(-1);
740  DBUG_RETURN(0);
741 }
742 
743 // mem
744 
745 NdbIndexStat::Mem::Mem()
746 {
747 }
748 
749 NdbIndexStat::Mem::~Mem()
750 {
751 }
752 
753 void
754 NdbIndexStat::set_mem_handler(Mem* mem)
755 {
756  m_impl.m_mem_handler = mem;
757 }
758 
759 // get impl
760 
762 NdbIndexStat::getImpl()
763 {
764  return m_impl;
765 }
766 
767 // error
768 
769 NdbIndexStat::Error::Error()
770 {
771  line = 0;
772  extra = 0;
773 }
774 
775 const NdbIndexStat::Error&
776 NdbIndexStat::getNdbError() const
777 {
778  return m_impl.getNdbError();
779 }
780 
781 class NdbOut&
782 operator<<(class NdbOut& out, const NdbIndexStat::Error& error)
783 {
784  out << static_cast<const NdbError&>(error);
785  out << " (line " << error.line << ", extra " << error.extra << ")";
786  return out;
787 }