18 #include <ndb_global.h>
21 #include <NdbIndexStat.hpp>
22 #include <NdbTest.hpp>
23 #include <ndb_version.h>
24 #include <NDBT_Stats.hpp>
29 #define min(a, b) ((a) <= (b) ? (a) : (b))
30 #define max(a, b) ((a) >= (b) ? (a) : (b))
33 NdbOut::operator<<(
double x)
36 sprintf(buf,
"%.2f", x);
75 static uint g_loop = 0;
77 static const char* g_tabname =
"ts1";
78 static const char* g_indname =
"ts1x1";
79 static const uint g_numattrs = 3;
80 static const uint g_charlen = 10;
81 static const char* g_csname =
"latin1_swedish_ci";
85 static const bool g_b_nullable =
true;
86 static const bool g_c_nullable =
true;
87 static const bool g_d_nullable =
true;
100 static Lim g_lim_bnd;
103 static Ndb* g_ndb = 0;
104 static Ndb* g_ndb_sys = 0;
117 char m_c[1+g_charlen];
121 static const Uint32 g_ndbrec_a_offset=offsetof(
my_record, m_a);
122 static const Uint32 g_ndbrec_b_offset=offsetof(
my_record, m_b);
123 static const Uint32 g_ndbrec_b_nb_offset=1;
124 static const Uint32 g_ndbrec_c_offset=offsetof(
my_record, m_c);
125 static const Uint32 g_ndbrec_c_nb_offset=2;
126 static const Uint32 g_ndbrec_d_offset=offsetof(
my_record, m_d);
127 static const Uint32 g_ndbrec_d_nb_offset=3;
128 static const Uint32 g_ndbrecord_bytes=
sizeof(
my_record);
136 static bool g_has_created_stat_tables =
false;
137 static bool g_has_created_stat_events =
false;
142 uint r = (uint)random();
156 static int& g_loglevel = g_opts.loglevel;
159 do { if (likely(x)) break; ndbout << "line " << __LINE__ << " FAIL " << #x << endl; errdb(); if (g_opts.abort) abort(); return -1; } while (0)
162 do { if (likely(x)) break; ndbout << "line " << __LINE__ << " FAIL " << #x << endl; ndbout << "errno: " << errno; if (g_opts.abort) abort(); return -1; } while (0)
165 do { if (likely(x)) break; ndbout << "line " << __LINE__ << " FAIL " << #x << endl; if (g_opts.abort) abort(); return -1; } while (0)
168 do { if (likely(g_loglevel < n)) break; ndbout << x << endl; } while (0)
170 #define ll0(x) llx(0, x)
171 #define ll1(x) llx(1, x)
172 #define ll2(x) llx(2, x)
173 #define ll3(x) llx(3, x)
181 e.
code = g_ncc->get_latest_error();
182 e.
message = g_ncc->get_latest_error_msg();
184 ll0(++any <<
" ncc: error" << e);
189 ll0(++any <<
" ndb: error " << e);
194 ll0(++any <<
" dic: error " << e);
199 ll0(++any <<
" con: error " << e);
204 ll0(++any <<
" op: error " << e);
206 if (g_scan_op != 0) {
209 ll0(++any <<
" scan_op: error " << e);
211 if (g_rangescan_op != 0) {
214 ll0(++any <<
" rangescan_op: error " << e);
219 ll0(++any <<
" stat: error " << e);
222 ll0(
"unknown db error");
229 ll1(
"createNdbRecords");
230 const Uint32 numCols=4;
231 const Uint32 numIndexCols=3;
234 recSpec[0].column= g_tab->
getColumn(
"a");
235 recSpec[0].offset= g_ndbrec_a_offset;
236 recSpec[0].nullbit_byte_offset= ~(Uint32)0;
237 recSpec[0].nullbit_bit_in_byte= ~(Uint32)0;
239 recSpec[1].column= g_tab->
getColumn(
"b");
240 recSpec[1].offset= g_ndbrec_b_offset;
242 recSpec[1].nullbit_byte_offset= 0;
243 recSpec[1].nullbit_bit_in_byte= g_ndbrec_b_nb_offset;
245 recSpec[1].nullbit_byte_offset= ~(Uint32)0;
246 recSpec[1].nullbit_bit_in_byte= ~(Uint32)0;
249 recSpec[2].column= g_tab->
getColumn(
"c");
250 recSpec[2].offset= g_ndbrec_c_offset;
252 recSpec[2].nullbit_byte_offset= 0;
253 recSpec[2].nullbit_bit_in_byte= g_ndbrec_c_nb_offset;
255 recSpec[2].nullbit_byte_offset= ~(Uint32)0;
256 recSpec[2].nullbit_bit_in_byte= ~(Uint32)0;
259 recSpec[3].column= g_tab->
getColumn(
"d");
260 recSpec[3].offset= g_ndbrec_d_offset;
262 recSpec[3].nullbit_byte_offset= 0;
263 recSpec[3].nullbit_bit_in_byte= g_ndbrec_d_nb_offset;
265 recSpec[3].nullbit_byte_offset= ~(Uint32)0;
266 recSpec[3].nullbit_bit_in_byte= ~(Uint32)0;
270 g_tab_rec= g_dic->createRecord(g_tab,
276 chkdb(g_tab_rec != NULL);
278 g_ind_rec= g_dic->createRecord(g_ind,
284 chkdb(g_ind_rec != NULL);
300 tab.setLogging(
false);
304 col.setPrimaryKey(
true);
310 col.setNullable(g_b_nullable);
316 col.setLength(g_charlen);
317 col.setCharset(g_cs);
318 col.setNullable(g_c_nullable);
324 col.setNullable(g_d_nullable);
329 if (g_dic->
getTable(g_tabname) != 0)
332 chkdb((g_tab = g_dic->
getTable(g_tabname)) != 0);
342 ind.setTable(g_tabname);
344 ind.setLogging(
false);
345 ind.addColumnName(
"b");
346 ind.addColumnName(
"c");
347 ind.addColumnName(
"d");
351 chkdb((g_ind = g_dic->
getIndex(g_indname, g_tabname)) != 0);
374 uchar c[1 + g_charlen];
378 void copy(
const Val& val2);
379 void make(uint numattrs,
const Lim& lim);
380 int cmp(
const Val& val2, uint numattrs = g_numattrs, uint* num_eq = 0)
const;
384 Val& operator=(
const Val&);
389 operator<<(NdbOut& out,
const Val& val)
392 if (val.m_numattrs >= 1) {
398 if (val.m_numattrs >= 2) {
403 char buf[1 + g_charlen];
404 sprintf(buf,
"%.*s", val.c[0], &val.c[1]);
405 out <<
"'" << buf <<
"'";
408 if (val.m_numattrs >= 3) {
433 memset(c, 0xff,
sizeof(c));
438 Val::copy(
const Val& val2)
440 require(
this != &val2);
442 m_numattrs = val2.m_numattrs;
443 if (m_numattrs >= 1) {
444 require(val2.b_null == 0 || val2.b_null == 1);
445 b_null = val2.b_null;
449 if (m_numattrs >= 2) {
450 require(val2.c_null == 0 || val2.c_null == 1);
451 c_null = val2.c_null;
453 memcpy(c, val2.c,
sizeof(c));
455 if (m_numattrs >= 3) {
456 require(val2.d_null == 0 || val2.d_null == 1);
457 d_null = val2.d_null;
464 Val::make(uint numattrs,
const Lim& lim)
466 require(numattrs <= g_numattrs);
468 const bool nullable = g_b_nullable || lim.all_nullable;
469 if (nullable && urandom(100) < g_opts.nullkeys)
472 require(lim.b_min <= lim.b_max);
473 b = lim.b_min + urandom(lim.b_max - lim.b_min + 1);
478 const bool nullable = g_c_nullable || lim.all_nullable;
479 if (nullable && urandom(100) < g_opts.nullkeys)
483 const uint len = urandom(urandom(g_charlen + 1) + 1);
485 for (uint j = 0; j < len; j++) {
486 uint k = urandom(strlen(lim.c_char));
487 c[1 + j] = lim.c_char[k];
493 const bool nullable = g_d_nullable || lim.all_nullable;
494 if (nullable && urandom(100) < g_opts.nullkeys)
497 require(lim.d_min <= lim.d_max);
498 d = lim.d_min + urandom(lim.d_max - lim.d_min + 1);
502 m_numattrs = numattrs;
506 Val::cmp(
const Val& val2, uint numattrs, uint* num_eq)
const
508 require(numattrs <= m_numattrs);
509 require(numattrs <= val2.m_numattrs);
512 if (k == 0 && numattrs >= 1) {
513 if (! b_null && ! val2.b_null) {
518 }
else if (! b_null) {
520 }
else if (! val2.b_null) {
526 if (k == 0 && numattrs >= 2) {
527 if (! c_null && ! val2.c_null) {
528 const uchar* s1 = &c[1];
529 const uchar* s2 = &val2.c[1];
530 const uint l1 = (uint)c[0];
531 const uint l2 = (uint)val2.c[0];
532 assert(l1 <= g_charlen && l2 <= g_charlen);
533 k = g_cs->coll->strnncollsp(g_cs, s1, l1, s2, l2, 0);
534 }
else if (! c_null) {
536 }
else if (! val2.c_null) {
542 if (k == 0 && numattrs >= 3) {
543 if (! d_null && ! val2.d_null) {
548 }
else if (! d_null) {
550 }
else if (! val2.d_null) {
556 require(n <= numattrs);
565 const char* key = (j == 0 ? ib.low_key : ib.high_key);
566 const uint numattrs = (j == 0 ? ib.low_key_count : ib.high_key_count);
567 const Uint8 nullbits = *(
const Uint8*)key;
568 require(numattrs <= g_numattrs);
570 if (nullbits & (1 << g_ndbrec_b_nb_offset))
573 memcpy(&b, &key[g_ndbrec_b_offset],
sizeof(b));
578 if (nullbits & (1 << g_ndbrec_c_nb_offset))
581 memcpy(c, &key[g_ndbrec_c_offset],
sizeof(c));
586 if (nullbits & (1 << g_ndbrec_d_nb_offset))
589 memcpy(&d, &key[g_ndbrec_d_offset],
sizeof(d));
593 m_numattrs = numattrs;
604 Key& operator=(
const Key&);
609 operator<<(NdbOut& out,
const Key& key)
612 if (key.m_flag != -1)
613 out <<
" flag: " << key.m_flag;
622 static Key* g_keys = 0;
623 static uint* g_sortkeys = 0;
629 delete [] g_sortkeys;
638 g_keys =
new Key [g_opts.rows];
639 g_sortkeys =
new uint [g_opts.rows];
640 require(g_keys != 0 && g_sortkeys != 0);
641 memset(g_sortkeys, 0xff,
sizeof(uint) * g_opts.rows);
645 cmpkeys(
const void* p1,
const void* p2)
647 const uint i1 = *(
const uint*)p1;
648 const uint i2 = *(
const uint*)p2;
649 require(i1 < g_opts.rows && i2 < g_opts.rows);
650 const Key& key1 = g_keys[i1];
651 const Key& key2 = g_keys[i2];
652 const int k = key1.m_val.cmp(key2.m_val, g_opts.attrs);
663 for (i = 0; i < g_opts.rows; i++)
665 qsort(g_sortkeys, g_opts.rows,
sizeof(uint), cmpkeys);
669 for (i = 1; i < g_opts.rows; i++) {
670 const uint i1 = g_sortkeys[i - 1];
671 const uint i2 = g_sortkeys[
i];
672 require(i1 < g_opts.rows && i2 < g_opts.rows);
673 const Key& key1 = g_keys[i1];
674 const Key& key2 = g_keys[i2];
675 const int k = key1.m_val.cmp(key2.m_val, g_opts.attrs);
682 ll1(
"minkey:" << g_keys[g_sortkeys[0]]);
683 ll1(
"maxkey:" << g_keys[g_sortkeys[g_opts.rows - 1]]);
684 ll1(
"unique:" << unique);
692 uint initrows = g_opts.rows / g_opts.rpk;
693 require(initrows != 0);
697 while (i < initrows) {
698 Key& key = g_keys[
i];
699 key.m_val.make(g_numattrs, g_lim_val);
704 while (i < g_opts.rows) {
706 double a = (double)(1 + urandom(g_opts.rpkvar * g_opts.rpkvar));
707 double b = a / (double)g_opts.rpkvar;
708 double c = b * (
double)g_opts.rpk;
709 const uint n = (uint)(c + 0.5);
711 const uint k = urandom(initrows);
713 while (i < g_opts.rows && j < n) {
714 g_keys[
i].m_val.copy(g_keys[k].m_val);
722 while (i < g_opts.rows) {
723 uint j = urandom(g_opts.rows);
726 tmp.m_val.copy(g_keys[i].m_val);
727 g_keys[
i].m_val.copy(g_keys[j].m_val);
728 g_keys[j].m_val.copy(tmp.m_val);
748 val.m_numattrs = g_numattrs;
749 char* a_addr = (
char*)&a;
750 char* b_addr = (
char*)&val.b;
751 char* c_addr = (
char*)val.c;
752 char* d_addr = (
char*)&val.d;
757 chkdb(g_scan_op->
getValue(no++, a_addr) != 0);
758 chkdb((b_ra = g_scan_op->
getValue(no++, b_addr)) != 0);
759 chkdb((c_ra = g_scan_op->
getValue(no++, c_addr)) != 0);
760 chkdb((d_ra = g_scan_op->
getValue(no++, d_addr)) != 0);
764 for (i = 0; i < g_opts.rows; i++) {
765 Key& key = g_keys[
i];
771 chkdb((ret = g_scan_op->
nextResult()) == 0 || ret == 1);
774 val.b_null = b_ra->isNULL();
775 val.c_null = c_ra->isNULL();
776 val.d_null = d_ra->isNULL();
777 require(val.b_null == 0 || (g_b_nullable && val.b_null == 1));
778 require(val.c_null == 0 || (g_c_nullable && val.c_null == 1));
779 require(val.d_null == 0 || (g_d_nullable && val.d_null == 1));
781 chkrc(i < g_opts.rows);
782 Key& key = g_keys[
i];
783 chkrc(key.m_val.cmp(val) == 0);
784 chkrc(key.m_flag ==
false);
791 for (i = 0; i < g_opts.rows; i++) {
792 Key& key = g_keys[
i];
793 chkrc(key.m_flag ==
true);
796 assert(count == g_opts.rows);
797 ll3(
"verifydata: " << g_opts.rows <<
" rows");
802 loaddata(
bool update)
804 ll1(
"loaddata: update: " << update);
805 const uint batch = 512;
808 while (i < g_opts.rows) {
815 const Val& val = g_keys[
i].m_val;
816 const char* a_addr = (
const char*)&a;
817 const char* b_addr = ! val.b_null ? (
const char*)&val.b : 0;
818 const char* c_addr = ! val.c_null ? (
const char*)val.c : 0;
819 const char* d_addr = ! val.d_null ? (
const char*)&val.d : 0;
821 chkdb(g_op->
equal(no++, a_addr) == 0);
822 chkdb(g_op->
setValue(no++, b_addr) == 0);
823 chkdb(g_op->
setValue(no++, c_addr) == 0);
824 chkdb(g_op->
setValue(no++, d_addr) == 0);
825 if (i++ % batch == 0) {
839 chkrc(verifydata() == 0);
841 for (uint i = 0; i < g_opts.rows; i++)
842 ll3(
"load " << i <<
": " << g_keys[i]);
843 ll0(
"loaddata: " << g_opts.rows <<
" rows");
879 bool isempty()
const;
880 void copy(
const Bnd& bnd2);
881 Bnd& make(uint minattrs);
882 Bnd& make(uint minattrs,
const Val& theval);
883 int cmp(
const Key& key)
const;
884 int cmp(
const Bnd& bnd2);
885 int type(uint colno)
const;
889 Bnd& operator=(
const Bnd&);
894 operator<<(NdbOut& out,
const Bnd& bnd)
898 else if (bnd.m_lohi == 1)
901 out << bnd.m_lohi <<
"?";
905 else if (bnd.m_side == -1)
907 else if (bnd.m_side == +1)
921 return m_val.m_numattrs == 0;
925 Bnd::copy(
const Bnd& bnd2)
927 m_val.copy(bnd2.m_val);
928 m_side = bnd2.m_side;
932 Bnd::make(uint minattrs)
934 require(minattrs <= g_opts.attrs);
935 require(m_lohi == 0 || m_lohi == 1);
936 uint numattrs = minattrs + urandom(g_numattrs - minattrs + 1);
937 m_val.make(numattrs, g_lim_bnd);
938 m_side = m_val.m_numattrs == 0 ? 0 : urandom(2) == 0 ? -1 : +1;
943 Bnd::make(uint minattrs,
const Val& theval)
945 uint numattrs = minattrs + urandom(g_numattrs - minattrs);
947 m_val.m_numattrs = numattrs;
948 m_side = m_val.m_numattrs == 0 ? 0 : urandom(2) == 0 ? -1 : +1;
953 Bnd::cmp(
const Key& key)
const
958 int k = key.m_val.cmp(m_val, m_val.m_numattrs);
971 assert(m_val.m_numattrs == 0);
973 ll3(
"bnd: " << *
this <<
" cmp key: " << key
974 <<
" ret: " << ret <<
" place: " << place);
979 Bnd::cmp(
const Bnd& bnd2)
983 const Bnd& bnd1 = *
this;
984 const Val& val1 = bnd1.m_val;
985 const Val& val2 = bnd2.m_val;
986 const uint numattrs1 = val1.m_numattrs;
987 const uint numattrs2 = val2.m_numattrs;
988 const uint n = (numattrs1 < numattrs2 ? numattrs1 : numattrs2);
990 int k = val1.cmp(val2, n);
996 if (numattrs1 < numattrs2) {
998 ret = (+1) * bnd1.m_side;
1001 if (numattrs1 > numattrs2) {
1003 ret = (-1) * bnd1.m_side;
1006 if (bnd1.m_side < bnd2.m_side) {
1011 if (bnd1.m_side > bnd2.m_side) {
1019 ll3(
"bnd: " << *
this <<
" cmp bnd: " << bnd2
1020 <<
" ret: " << ret <<
" place: " << place);
1025 Bnd::type(uint colno)
const
1028 require(colno < m_val.m_numattrs && (m_side == -1 || m_side == +1));
1029 require(m_lohi == 0 || m_lohi == 1);
1031 if (colno + 1 < m_val.m_numattrs)
1033 else if (m_side == -1)
1038 if (colno + 1 < m_val.m_numattrs)
1040 else if (m_side == +1)
1053 const uint numattrs = (j == 0 ? ib.low_key_count : ib.high_key_count);
1054 const bool inclusive = (j == 0 ? ib.low_inclusive : ib.high_inclusive);
1055 if (numattrs == 0) {
1058 m_side = (j == 0 ? (inclusive ? -1 : +1) : (inclusive ? +1 : -1));
1068 double rpk[g_numattrs];
1070 char rule[NdbIndexStat::RuleBufferBytes];
1075 operator<<(NdbOut& out,
const Stval& st)
1077 out <<
"rir_v2: " << st.rir_v2;
1078 out <<
" rir_v4: " << st.rir;
1080 for (uint k = 0; k < g_opts.attrs; k++) {
1086 out <<
" " << (st.empty ?
"E" :
"N");
1087 out <<
" " << st.rule;
1095 for (uint k = 0; k < g_numattrs; k++)
1112 uint minattrs()
const;
1113 uint maxattrs()
const;
1115 bool isempty()
const;
1116 void copy(
const Rng& rng2);
1117 int cmp(
const Key& key)
const;
1118 uint rowcount()
const;
1122 Rng& operator=(
const Rng&);
1127 operator<<(NdbOut& out,
const Rng& rng)
1129 out << rng.m_bnd[0] <<
" " << rng.m_bnd[1];
1130 if (rng.m_rowcount != -1)
1131 out <<
" rows: " << rng.m_rowcount;
1137 m_bnd[0].m_lohi = 0;
1138 m_bnd[1].m_lohi = 1;
1143 Rng::minattrs()
const
1145 return min(m_bnd[0].m_val.m_numattrs, m_bnd[1].m_val.m_numattrs);
1149 Rng::maxattrs()
const
1151 return max(m_bnd[0].m_val.m_numattrs, m_bnd[1].m_val.m_numattrs);
1158 minattrs() == maxattrs() &&
1159 m_bnd[0].m_val.cmp(m_bnd[1].m_val, minattrs()) == 0 &&
1160 m_bnd[0].m_side < m_bnd[1].m_side;
1164 Rng::isempty()
const
1166 return m_bnd[0].isempty() && m_bnd[1].isempty();
1170 Rng::copy(
const Rng& rng2)
1172 m_bnd[0].copy(rng2.m_bnd[0]);
1173 m_bnd[1].copy(rng2.m_bnd[1]);
1174 m_rowcount = rng2.m_rowcount;
1178 Rng::cmp(
const Key& key)
const
1184 k = m_bnd[0].cmp(key);
1190 k = m_bnd[1].cmp(key);
1199 ll3(
"rng: " << *
this <<
" cmp key: " << key
1200 <<
" ret: " << ret <<
" place: " << place);
1205 Rng::rowcount()
const
1207 ll3(
"rowcount: " << *
this);
1211 for (i = 0; i <= 1; i++) {
1212 ll3(
"search i=" << i);
1214 int hi = (int)g_opts.rows;
1219 require(lo < j && j < hi);
1220 ret = cmp(g_keys[g_sortkeys[j]]);
1232 }
while (hi - lo > 1);
1242 const bool verify = (urandom(10) == 0);
1243 const int lo = max(lim[0], 0);
1244 const int hi = min(lim[1], (
int)g_opts.rows - 1);
1247 for (i = 0; i < (int)g_opts.rows; i++) {
1248 int k = cmp(g_keys[g_sortkeys[i]]);
1252 require(lo <= i && i <= hi);
1262 require(hi - lo + 1 >= 0);
1263 uint count = hi - lo + 1;
1264 ll3(
"rowcount: " << count <<
" lim: " << lim[0] <<
" " << lim[1]);
1271 for (uint j = 0; j <= 1; j++) {
1272 Bnd& bnd = m_bnd[j];
1277 static Rng* g_rnglist = 0;
1282 delete [] g_rnglist;
1290 g_rnglist =
new Rng [g_opts.ops];
1291 require(g_rnglist != 0);
1298 const uint mintries = 20;
1299 const uint maxtries = 80;
1300 const uint fudgefac = 10;
1302 for (uint i = 0; i < g_opts.ops; i++) {
1303 const bool eqpart = (urandom(100) < g_opts.eqscans);
1304 const bool eqfull = eqpart && (urandom(100) < g_opts.eqscans);
1307 for (j = 0; j < maxtries; j++) {
1310 rng2.m_bnd[0].make(0);
1311 rng2.m_bnd[1].make(0);
1313 const uint mincnt = eqfull ? g_opts.attrs : 1;
1314 rng2.m_bnd[0].make(mincnt);
1315 rng2.m_bnd[1].copy(rng2.m_bnd[0]);
1316 rng2.m_bnd[0].m_side = -1;
1317 rng2.m_bnd[1].m_side = +1;
1318 require(rng2.iseq());
1320 rng2.m_rowcount = (Int32)rng2.rowcount();
1325 if (rng.m_rowcount == -1) {
1329 require(rng.m_rowcount != -1);
1331 if (rng2.isempty()) {
1332 if (urandom(fudgefac) != 0)
1339 if (rng2.m_rowcount == 0) {
1344 require((uint)rng2.m_rowcount <= g_opts.rows);
1345 if (100 * (uint)rng2.m_rowcount <= g_opts.scanpct * g_opts.rows) {
1346 if (urandom(fudgefac) != 0) {
1352 if (rng2.m_rowcount < rng.m_rowcount) {
1353 if (urandom(fudgefac) != 0) {
1361 if (action == 2 || j >= mintries)
1365 g_rnglist[
i].copy(rng);
1366 ll2(
"rng " << i <<
": " << rng <<
" tries: " << j);
1373 setbounds(
const Rng& rng)
1376 ll3(
"setbounds: " << rng);
1378 const Bnd (&bnd)[2] = rng.m_bnd;
1379 for (i = 0; i < g_numattrs; i++) {
1380 const Uint32 no =
i;
1382 int type[2] = { -1, -1 };
1385 for (j = 0; j <= 1; j++) {
1386 if (no < bnd[j].m_val.m_numattrs)
1387 type[j] = bnd[j].type(no);
1389 for (j = 0; j <= 1; j++) {
1393 if (no + 1 < bnd[j].m_val.m_numattrs)
1395 const Val& val = bnd[j].m_val;
1396 const void* addr = 0;
1398 addr = ! val.b_null ? (
const void*)&val.b : 0;
1400 addr = ! val.c_null ? (
const void*)val.c : 0;
1402 addr = ! val.d_null ? (
const void*)&val.d : 0;
1405 ll3(
"setBound attr:" << no <<
" type:" << t <<
" val: " << val);
1406 chkdb(g_rangescan_op->
setBound(no, t, addr) == 0);
1413 scanrange(
const Rng& rng)
1415 ll3(
"scanrange: " << rng);
1419 chkrc(setbounds(rng) == 0);
1421 char* a_addr = (
char*)&a;
1423 chkdb(g_rangescan_op->
getValue(no++, a_addr) != 0);
1427 for (i = 0; i < g_opts.rows; i++) {
1428 Key& key = g_keys[
i];
1434 chkdb((ret = g_rangescan_op->
nextResult()) == 0 || ret == 1);
1438 chkrc(i < g_opts.rows);
1439 Key& key = g_keys[
i];
1440 ll3(
"scan: " << key);
1441 int k = rng.cmp(key);
1443 chkrc(key.m_flag ==
false);
1451 for (i = 0; i < g_opts.rows; i++) {
1452 Key& key = g_keys[
i];
1453 int k = rng.cmp(key);
1455 chkrc(key.m_flag ==
false);
1457 chkrc(key.m_flag ==
true);
1460 require((uint)rng.m_rowcount == count);
1468 for (uint i = 0; i < g_opts.ops; i++) {
1469 const Rng& rng = g_rnglist[
i];
1470 chkrc(scanrange(rng) == 0);
1481 require(g_is != 0 && g_ind != 0 && g_tab != 0);
1482 chkdb(g_is->set_index(*g_ind, *g_tab) == 0);
1490 if (urandom(2) == 0) {
1492 chkdb(g_dic->updateIndexStat(*g_ind, *g_tab) == 0);
1495 chkdb(g_is->update_stat(g_ndb_sys) == 0);
1506 chkdb(g_is->read_head(g_ndb_sys) == 0);
1507 g_is->get_head(head);
1508 chkrc(head.m_found ==
true);
1509 chkrc(head.m_sampleVersion != 0);
1511 <<
" sampleVersion: " << head.m_sampleVersion
1512 <<
" sampleCount: " << head.m_sampleCount);
1515 chkdb(g_is->read_stat(g_ndb_sys) == 0);
1517 g_is->get_cache_info(infoQuery, NdbIndexStat::CacheQuery);
1518 ll1(
"readstat: cache bytes: " << infoQuery.m_totalBytes);
1527 ll1(
"startlistener");
1528 chkdb(g_is->create_listener(g_ndb_sys) == 0);
1529 chkdb(g_is->execute_listener(g_ndb_sys) == 0);
1538 chkdb((ret = g_is->poll_listener(g_ndb_sys, 10000)) != -1);
1541 chkdb((ret = g_is->next_listener(g_ndb_sys)) != -1);
1543 chkdb((ret = g_is->next_listener(g_ndb_sys)) != -1);
1551 ll1(
"stoplistener");
1552 chkdb(g_is->drop_listener(g_ndb_sys) != -1);
1565 uint unq[g_numattrs];
1567 for (uint k = 0; k < g_opts.attrs; k++)
1570 for (uint i = 0; i < g_opts.rows; i++) {
1571 const Key& key = g_keys[g_sortkeys[
i]];
1572 int res = rng.cmp(key);
1577 for (uint k = 0; k < g_opts.attrs; k++)
1581 int res = prevkey.m_val.cmp(key.m_val, g_opts.attrs, &num_eq);
1583 require(num_eq == g_opts.attrs);
1586 require(num_eq < g_opts.attrs);
1589 for (uint k = num_eq + 1; k < g_opts.attrs; k++)
1593 prevkey.m_val.copy(key.m_val);
1595 require(rng.m_rowcount != -1);
1596 require((uint)rng.m_rowcount == rir);
1598 Stval& st = rng.m_st_scan;
1600 st.rir = rir == 0 ? 1.0 : (double)rir;
1601 for (uint k = 0; k < g_opts.attrs; k++) {
1605 require(rir >= unq[k]);
1606 require(unq[k] != 0);
1607 st.rpk[k] = (double)rir / (
double)unq[k];
1610 st.empty = (rir == 0);
1611 ll2(
"queryscan: " << st);
1621 initialiseIndexBound(
const Rng& rng,
1625 ll3(
"initialiseIndexBound: " << rng);
1627 const Bnd (&bnd)[2] = rng.m_bnd;
1628 Uint32 colsInBound[2]= {0, 0};
1629 bool boundInclusive[2]= {
false,
false};
1631 memset(&ib, 0xf1,
sizeof(ib));
1632 memset(low_key, 0xf2,
sizeof(*low_key));
1633 memset(high_key, 0xf3,
sizeof(*high_key));
1636 low_key->m_null_bm = 0;
1637 high_key->m_null_bm = 0;
1639 for (i = 0; i < g_numattrs; i++) {
1640 const Uint32 no =
i;
1642 int type[2] = { -1, -1 };
1645 for (j = 0; j <= 1; j++) {
1646 if (no < bnd[j].m_val.m_numattrs)
1647 type[j] = bnd[j].type(no);
1649 for (j = 0; j <= 1; j++) {
1651 my_record* keyBuf= (j==0) ? low_key : high_key;
1657 if (no + 1 >= bnd[j].m_val.m_numattrs)
1660 boundInclusive[j]= !(t & 1);
1662 const Val& val = bnd[j].m_val;
1669 keyBuf->m_null_bm |= ((val.b_null?1:0) << g_ndbrec_b_nb_offset);
1674 memcpy(&keyBuf->m_c[0], (
const void*)&val.c, 1+ g_charlen);
1677 keyBuf->m_null_bm |= ((val.c_null?1:0) << g_ndbrec_c_nb_offset);
1685 keyBuf->m_null_bm |= ((val.d_null?1:0) << g_ndbrec_d_nb_offset);
1689 ll3(
"initialiseIndexBound attr:" << no <<
" type:" << t <<
" val: " << val);
1694 ib.low_key = (
char*)low_key;
1695 ib.low_key_count= colsInBound[0];
1696 ib.low_inclusive= boundInclusive[0];
1697 ib.high_key = (
char*)high_key;
1698 ib.high_key_count= colsInBound[1];
1699 ib.high_inclusive= boundInclusive[1];
1702 ll3(
" indexBound low_key_count=" << ib.low_key_count <<
1703 " low_inc=" << ib.low_inclusive <<
1704 " high_key_count=" << ib.high_key_count <<
1705 " high_inc=" << ib.high_inclusive);
1706 ll3(
" low bound b=" << *((Uint32*) &ib.low_key[g_ndbrec_b_offset]) <<
1707 " d=" << *((Uint16*) &ib.low_key[g_ndbrec_d_offset]) <<
1708 " first byte=" << ib.low_key[0]);
1709 ll3(
" high bound b=" << *((Uint32*) &ib.high_key[g_ndbrec_b_offset]) <<
1710 " d=" << *((Uint16*) &ib.high_key[g_ndbrec_d_offset]) <<
1711 " first byte=" << ib.high_key[0]);
1717 require(rng.m_bnd[0].cmp(bnd[0]) == 0);
1718 require(rng.m_bnd[1].cmp(bnd[1]) == 0);
1724 querystat_v2(
Rng& rng)
1726 ll3(
"querystat_v2");
1734 chkrc(initialiseIndexBound(rng, ib, &low_key, &high_key) == 0);
1736 Uint64 count = ~(Uint64)0;
1737 chkdb(g_is->records_in_range(g_ind,
1749 Stval& st = rng.m_st_stat;
1750 chkrc(count < (1 << 30));
1752 ll2(
"querystat_v2: " << st.rir_v2 <<
" rows");
1762 Uint8 bound_lo_buffer[NdbIndexStat::BoundBufferBytes];
1763 Uint8 bound_hi_buffer[NdbIndexStat::BoundBufferBytes];
1772 chkrc(initialiseIndexBound(rng, ib, &low_key, &high_key) == 0);
1773 chkrc(g_is->convert_range(range, g_ind_rec, &ib) == 0);
1776 Uint8 stat_buffer[NdbIndexStat::StatBufferBytes];
1778 chkdb(g_is->query_stat(range, stat) == 0);
1781 Stval& st = rng.m_st_stat;
1782 g_is->get_rir(stat, &st.rir);
1783 for (uint k = 0; k < g_opts.attrs; k++) {
1784 g_is->get_rpk(stat, k, &st.rpk[k]);
1786 g_is->get_empty(stat, &st.empty);
1787 g_is->get_rule(stat, st.rule);
1789 ll2(
"querystat: " << st);
1797 for (uint i = 0; i < g_opts.ops; i++) {
1798 Rng& rng = g_rnglist[
i];
1799 ll1(
"rng " << i <<
": " << rng);
1803 chkrc(querystat_v2(rng) == 0);
1804 chkrc(querystat(rng) == 0);
1805 const Stval& st1 = rng.m_st_scan;
1806 const Stval& st2 = rng.m_st_stat;
1808 chkrc(st2.rir_v2 != 0 || st1.rir_v2 == 0);
1817 void add(
double x2);
1818 void add(
const Stats& sum2);
1822 operator<<(NdbOut& out,
const Stats& st)
1824 out <<
"count: " << st.getCount()
1825 <<
" min: " << st.getMin()
1826 <<
" max: " << st.getMax()
1827 <<
" mean: " << st.getMean()
1828 <<
" stddev: " << st.getStddev();
1837 Stats::add(
double x2)
1843 Stats::add(
const Stats& st2)
1853 Stats rpk[g_numattrs];
1855 void add(
const Sterr& st2);
1859 operator<<(NdbOut& out,
const Sterr& st)
1861 out <<
"rir_v2: " << st.rir_v2 << endl;
1862 out <<
"rir_v4: " << st.rir;
1863 for (uint k = 0; k < g_opts.attrs; k++) {
1864 out << endl <<
"rpk[" << k <<
"]: " << st.rpk[k];
1874 Sterr::add(
const Sterr& st2)
1876 rir_v2.add(st2.rir_v2);
1878 for (uint k = 0; k < g_opts.attrs; k++) {
1879 rpk[k].add(st2.rpk[k]);
1884 sumrange(
const Rng& rng,
Sterr& st)
1886 const Stval& st1 = rng.m_st_scan;
1887 const Stval& st2 = rng.m_st_stat;
1891 double rows = (double)g_opts.rows;
1892 double x1 = (
double)st1.rir_v2;
1893 double x2 = (double)st2.rir_v2;
1894 double x3 = 100.0 * (x2 - x1) / rows;
1900 double rows = (double)g_opts.rows;
1901 double x1 = st1.rir;
1902 double x2 = st2.rir;
1903 double x3 = 100.0 * (x2 - x1) / rows;
1908 for (uint k = 0; k < g_opts.attrs; k++) {
1909 double x1 = st1.rpk[k];
1910 double x2 = st2.rpk[k];
1911 double x3 = (x2 - x1);
1917 sumranges(
Sterr& st)
1919 for (uint i = 0; i < g_opts.ops; i++) {
1920 const Rng& rng = g_rnglist[
i];
1927 static Sterr g_sterr;
1934 if (g_opts.loops != 1) {
1935 ll0(
"=== loop " << g_loop <<
" summary ===");
1946 if (g_opts.dump == 0)
1950 "%s.key.%d", g_opts.dump, g_loop);
1952 chker((f = fopen(file,
"w")) != 0);
1954 for (uint k = 0; k < g_opts.attrs; k++) {
1956 fprintf(f,
",b_null,b");
1958 fprintf(f,
",c_null,c");
1960 fprintf(f,
",d_null,d");
1965 for (uint i = 0; i < g_opts.rows; i++) {
1966 const Key& key = g_keys[g_sortkeys[
i]];
1967 const Val& val = key.m_val;
1968 fprintf(f,
"%u", i);
1969 for (uint k = 0; k < g_opts.attrs; k++) {
1971 fprintf(f,
",%d,", val.b_null);
1973 fprintf(f,
"%u", val.b);
1974 }
else if (k == 1) {
1975 fprintf(f,
",%d,", val.c_null);
1977 fprintf(f,
"%.*s", val.c[0], &val.c[1]);
1978 }
else if (k == 2) {
1979 fprintf(f,
",%d,", val.d_null);
1981 fprintf(f,
"%u", val.d);
1988 chker(fclose(f) == 0);
1992 "%s.range.%d", g_opts.dump, g_loop);
1994 chker((f = fopen(file,
"w")) != 0);
1996 for (uint j = 0; j <= 1; j++) {
1997 const char* suf = (j == 0 ?
"_lo" :
"_hi");
1998 fprintf(f,
",attrs%s", suf);
1999 for (uint k = 0; k < g_opts.attrs; k++) {
2001 fprintf(f,
",b_null%s,b%s", suf, suf);
2003 fprintf(f,
",c_null%s,c%s", suf, suf);
2005 fprintf(f,
",d_null%s,d%s", suf, suf);
2009 fprintf(f,
",side%s", suf);
2012 for (uint i = 0; i < g_opts.ops; i++) {
2013 const Rng& rng = g_rnglist[
i];
2014 fprintf(f,
"%u", i);
2015 for (uint j = 0; j <= 1; j++) {
2016 const Bnd& bnd = rng.m_bnd[j];
2017 const Val& val = bnd.m_val;
2018 fprintf(f,
",%u", val.m_numattrs);
2019 for (uint k = 0; k < g_opts.attrs; k++) {
2020 if (k >= val.m_numattrs)
2023 fprintf(f,
",%d,", val.b_null);
2025 fprintf(f,
"%u", val.b);
2026 }
else if (k == 1) {
2027 fprintf(f,
",%d,", val.c_null);
2029 fprintf(f,
"%.*s", val.c[0], &val.c[1]);
2030 }
else if (k == 2) {
2031 fprintf(f,
",%d,", val.d_null);
2033 fprintf(f,
"%u", val.d);
2038 fprintf(f,
",%d", bnd.m_side);
2042 chker(fclose(f) == 0);
2046 "%s.stat.%d", g_opts.dump, g_loop);
2048 chker((f = fopen(file,
"w")) != 0);
2050 for (uint j = 0; j <= 1; j++) {
2051 const char* suf = (j == 0 ?
"_scan" :
"_stat");
2052 fprintf(f,
",rir_v2%s", suf);
2053 fprintf(f,
",rir%s", suf);
2054 for (uint k = 0; k < g_opts.attrs; k++) {
2055 fprintf(f,
",rpk_%u%s", k, suf);
2057 fprintf(f,
",empty%s", suf);
2059 fprintf(f,
",rule%s", suf);
2062 for (uint i = 0; i < g_opts.ops; i++) {
2063 const Rng& rng = g_rnglist[
i];
2064 fprintf(f,
"%u", i);
2065 for (uint j = 0; j <= 1; j++) {
2066 const Stval& st = (j == 0 ? rng.m_st_scan : rng.m_st_stat);
2067 fprintf(f,
",%u", st.rir_v2);
2068 fprintf(f,
",%.2f", st.rir);
2069 for (uint k = 0; k < g_opts.attrs; k++) {
2070 fprintf(f,
",%.2f", st.rpk[k]);
2072 fprintf(f,
",%d", st.empty);
2074 fprintf(f,
",%s", st.rule);
2078 chker(fclose(f) == 0);
2086 ll0(
"=== summary ===");
2093 ll1(
"sizeof Val: " <<
sizeof(
Val));
2094 ll1(
"sizeof Key: " <<
sizeof(
Key));
2095 ll1(
"sizeof Bnd: " <<
sizeof(
Bnd));
2096 ll1(
"sizeof Rng: " <<
sizeof(
Rng));
2098 uint seed = g_opts.seed;
2101 seed = 2 + (ushort)getpid();
2103 ll0(
"random seed is " << seed);
2106 ll0(
"random seed is " <<
"loop number");
2108 g_cs = get_charset_by_name(g_csname, MYF(0));
2110 g_cs = get_charset_by_csname(g_csname, MY_CS_PRIMARY, MYF(0));
2115 chkrc(createtable() == 0);
2116 chkrc(createindex() == 0);
2117 chkrc(createNdbRecords() == 0);
2118 chkrc(definestat() == 0);
2119 chkrc(startlistener() == 0);
2121 for (g_loop = 0; g_opts.loops == 0 || g_loop < g_opts.loops; g_loop++) {
2122 ll0(
"=== loop " << g_loop <<
" ===");
2123 uint seed = g_opts.seed;
2129 chkrc(loaddata(g_loop != 0) == 0);
2131 chkrc(scanranges() == 0);
2132 chkrc(updatestat() == 0);
2133 chkrc(runlistener() == 0);
2134 chkrc(readstat() == 0);
2135 chkrc(queryranges() == 0);
2137 chkrc(loopdumps() == 0);
2141 chkrc(stoplistener() == 0);
2142 if (!g_opts.keeptable)
2143 chkrc(droptable() == 0);
2153 require(g_ncc != 0);
2154 chkdb(g_ncc->
connect(30) == 0);
2155 g_ndb =
new Ndb(g_ncc,
"TEST_DB");
2156 require(g_ndb != 0);
2157 chkdb(g_ndb->init() == 0 && g_ndb->waitUntilReady(30) == 0);
2158 g_ndb_sys =
new Ndb(g_ncc,
"mysql");
2159 require(g_ndb_sys != 0);
2160 chkdb(g_ndb_sys->init() == 0 && g_ndb_sys->waitUntilReady(30) == 0);
2178 NDB_STD_OPTS(
"testIndexStat"),
2179 {
"loglevel", NDB_OPT_NOSHORT,
2180 "Logging level in this program 0-3 (default 0)",
2181 (uchar **)&g_opts.loglevel, (uchar **)&g_opts.loglevel, 0,
2182 GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
2183 {
"seed", NDB_OPT_NOSHORT,
"Random seed (default 0=random, 1=loop number)",
2184 (uchar **)&g_opts.seed, (uchar **)&g_opts.seed, 0,
2185 GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
2186 {
"loops", NDB_OPT_NOSHORT,
"Number of test loops (default 1, 0=forever)",
2187 (uchar **)&g_opts.loops, (uchar **)&g_opts.loops, 0,
2188 GET_INT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0 },
2189 {
"rows", NDB_OPT_NOSHORT,
"Number of rows (default 10000)",
2190 (uchar **)&g_opts.rows, (uchar **)&g_opts.rows, 0,
2191 GET_UINT, REQUIRED_ARG, 100000, 0, 0, 0, 0, 0 },
2192 {
"ops", NDB_OPT_NOSHORT,
"Number of index scans per loop (default 100)",
2193 (uchar **)&g_opts.ops, (uchar **)&g_opts.ops, 0,
2194 GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0 },
2195 {
"nullkeys", NDB_OPT_NOSHORT,
"Pct nulls in each key attribute (default 10)",
2196 (uchar **)&g_opts.nullkeys, (uchar **)&g_opts.nullkeys, 0,
2197 GET_UINT, REQUIRED_ARG, 10, 0, 0, 0, 0, 0 },
2198 {
"rpk", NDB_OPT_NOSHORT,
"Avg records per full key (default 10)",
2199 (uchar **)&g_opts.rpk, (uchar **)&g_opts.rpk, 0,
2200 GET_UINT, REQUIRED_ARG, 10, 0, 0, 0, 0, 0 },
2201 {
"rpkvar", NDB_OPT_NOSHORT,
"Vary rpk by factor (default 10, none 1)",
2202 (uchar **)&g_opts.rpkvar, (uchar **)&g_opts.rpkvar, 0,
2203 GET_UINT, REQUIRED_ARG, 10, 0, 0, 0, 0, 0 },
2204 {
"scanpct", NDB_OPT_NOSHORT,
2205 "Preferred max pct of total rows per scan (default 10)",
2206 (uchar **)&g_opts.scanpct, (uchar **)&g_opts.scanpct, 0,
2207 GET_UINT, REQUIRED_ARG, 5, 0, 0, 0, 0, 0 },
2208 {
"eqscans", NDB_OPT_NOSHORT,
2209 "Pct scans for partial/full equality (default 30)",
2210 (uchar **)&g_opts.eqscans, (uchar **)&g_opts.eqscans, 0,
2211 GET_UINT, REQUIRED_ARG, 50, 0, 0, 0, 0, 0 },
2212 {
"keeptable", NDB_OPT_NOSHORT,
2213 "Do not drop table at exit",
2214 (uchar **)&g_opts.keeptable, (uchar **)&g_opts.keeptable, 0,
2215 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
2216 {
"abort", NDB_OPT_NOSHORT,
"Dump core on any error",
2217 (uchar **)&g_opts.abort, (uchar **)&g_opts.abort, 0,
2218 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
2219 {
"dump", NDB_OPT_NOSHORT,
"Write CSV files name.* of keys,ranges,stats",
2220 (uchar **)&g_opts.dump, (uchar **)&g_opts.dump, 0,
2221 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
2224 GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
2228 load_default_groups[] = {
"mysql_cluster", 0 };
2233 ndb_short_usage_sub(NULL);
2239 ndbout << my_progname <<
": ordered index stats test" << endl;
2240 ndb_usage(short_usage_sub, load_default_groups, my_long_options);
2246 chkrc(g_opts.rows != 0);
2247 chkrc(g_opts.nullkeys <= 100);
2248 chkrc(g_opts.rpk != 0);
2249 g_opts.rpk = min(g_opts.rpk, g_opts.rows);
2250 chkrc(g_opts.rpkvar != 0);
2251 chkrc(g_opts.scanpct <= 100);
2252 chkrc(g_opts.eqscans <= 100);
2254 g_lim_val.all_nullable =
false;
2255 g_lim_bnd.all_nullable =
true;
2256 g_lim_val.b_min = g_opts.rows;
2257 g_lim_val.b_max = 2 * g_opts.rows;
2258 g_lim_bnd.b_min = 90 * g_lim_val.b_min / 100;
2259 g_lim_bnd.b_max = 110 * g_lim_val.b_max / 100;
2260 g_lim_val.c_char =
"bcd";
2261 g_lim_bnd.c_char =
"abcde";
2262 g_lim_val.d_min = 100;
2263 g_lim_val.d_max = 200;
2264 g_lim_bnd.d_min = 0;
2265 g_lim_bnd.d_max = 300;
2271 docreate_stat_tables()
2273 if (g_is->check_systables(g_ndb_sys) == 0)
2275 ll1(
"check_systables: " << g_is->getNdbError());
2277 ll0(
"create stat tables");
2278 chkdb(g_is->create_systables(g_ndb_sys) == 0);
2279 g_has_created_stat_tables =
true;
2285 dodrop_stat_tables()
2287 if (g_has_created_stat_tables ==
false)
2290 ll0(
"drop stat tables");
2291 chkdb(g_is->drop_systables(g_ndb_sys) == 0);
2296 docreate_stat_events()
2298 if (g_is->check_sysevents(g_ndb_sys) == 0)
2300 ll1(
"check_sysevents: " << g_is->getNdbError());
2302 ll0(
"create stat events");
2303 chkdb(g_is->create_sysevents(g_ndb_sys) == 0);
2304 g_has_created_stat_events =
true;
2309 dodrop_stat_events()
2311 if (g_has_created_stat_events ==
false)
2314 ll0(
"drop stat events");
2315 chkdb(g_is->drop_sysevents(g_ndb_sys) == 0);
2320 docreate_sys_objects()
2322 require(g_is != 0 && g_ndb_sys != 0);
2323 chkrc(docreate_stat_tables() == 0);
2324 chkrc(docreate_stat_events() == 0);
2329 dodrop_sys_objects()
2331 require(g_is != 0 && g_ndb_sys != 0);
2332 chkrc(dodrop_stat_events() == 0);
2333 chkrc(dodrop_stat_tables() == 0);
2338 main(
int argc,
char** argv)
2341 my_progname = strchr(argv[0],
'/') ? strrchr(argv[0],
'/') + 1 : argv[0];
2343 ndbout << my_progname;
2344 for (i = 1; i < (uint)argc; i++)
2345 ndbout <<
" " << argv[i];
2348 ndb_opt_set_usage_funcs(short_usage_sub, usage);
2349 ret = handle_options(&argc, &argv, my_long_options, ndb_std_get_one_option);
2350 if (ret != 0 || argc != 0) {
2352 return NDBT_ProgramExit(NDBT_WRONGARGS);
2354 if (checkoptions() == -1) {
2355 ll0(
"invalid args");
2356 return NDBT_ProgramExit(NDBT_WRONGARGS);
2358 if (doconnect() == -1) {
2359 ll0(
"connect failed");
2360 return NDBT_ProgramExit(NDBT_FAILED);
2362 if (docreate_sys_objects() == -1) {
2363 ll0(
"failed to check or create stat tables and events");
2366 if (runtest() == -1) {
2370 if (dodrop_sys_objects() == -1) {
2371 ll0(
"failed to drop created stat tables or events");
2375 return NDBT_ProgramExit(NDBT_OK);
2377 (void)dodrop_sys_objects();
2379 return NDBT_ProgramExit(NDBT_FAILED);