testoibasic.cpp
来自「MySQL源码文件5.X系列, 可自已编译到服务器」· C++ 代码 · 共 2,790 行 · 第 1/5 页
CPP
2,790 行
static intdropindex(Par par){ const Tab& tab = par.tab(); for (unsigned i = 0; i < tab.m_itabs; i++) { if (tab.m_itab[i] == 0) continue; const ITab& itab = *tab.m_itab[i]; CHK(dropindex(par, itab) == 0); } return 0;}static intcreateindex(Par par, const ITab& itab){ Con& con = par.con(); const Tab& tab = par.tab(); LL3("create index " << itab.m_name); LL4(itab); NdbDictionary::Index x(itab.m_name); x.setTable(tab.m_name); x.setType((NdbDictionary::Index::Type)itab.m_type); if (par.m_nologging || itab.m_type == ITab::OrderedIndex) { x.setLogging(false); } for (unsigned k = 0; k < itab.m_icols; k++) { const ICol& icol = *itab.m_icol[k]; const Col& col = icol.m_col; x.addColumnName(col.m_name); } con.m_dic = con.m_ndb->getDictionary(); CHKCON(con.m_dic->createIndex(x) == 0, con); con.m_dic = 0; return 0;}static intcreateindex(Par par){ const Tab& tab = par.tab(); for (unsigned i = 0; i < tab.m_itabs; i++) { if (tab.m_itab[i] == 0) continue; const ITab& itab = *tab.m_itab[i]; CHK(createindex(par, itab) == 0); } return 0;}// data sets// Val - typed column valuestruct Val { const Col& m_col; union { Uint32 m_uint32; unsigned char* m_char; unsigned char* m_varchar; unsigned char* m_longvarchar; }; Val(const Col& col); ~Val(); void copy(const Val& val2); void copy(const void* addr); const void* dataaddr() const; bool m_null; int equal(Par par) const; int equal(Par par, const ICol& icol) const; int setval(Par par) const; void calc(Par par, unsigned i); void calckey(Par par, unsigned i); void calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf); void calcnokey(Par par); void calcnokeychars(Par par, unsigned& n, unsigned char* buf); int verify(Par par, const Val& val2) const; int cmp(Par par, const Val& val2) const; int cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const;private: Val& operator=(const Val& val2);};static NdbOut&operator<<(NdbOut& out, const Val& val);Val::Val(const Col& col) : m_col(col){ switch (col.m_type) { case Col::Unsigned: break; case Col::Char: m_char = new unsigned char [col.m_bytelength]; break; case Col::Varchar: m_varchar = new unsigned char [1 + col.m_bytelength]; break; case Col::Longvarchar: m_longvarchar = new unsigned char [2 + col.m_bytelength]; break; default: assert(false); break; }}Val::~Val(){ const Col& col = m_col; switch (col.m_type) { case Col::Unsigned: break; case Col::Char: delete [] m_char; break; case Col::Varchar: delete [] m_varchar; break; case Col::Longvarchar: delete [] m_longvarchar; break; default: assert(false); break; }}voidVal::copy(const Val& val2){ const Col& col = m_col; const Col& col2 = val2.m_col; assert(col.m_type == col2.m_type && col.m_length == col2.m_length); if (val2.m_null) { m_null = true; return; } copy(val2.dataaddr());}voidVal::copy(const void* addr){ const Col& col = m_col; switch (col.m_type) { case Col::Unsigned: m_uint32 = *(const Uint32*)addr; break; case Col::Char: memcpy(m_char, addr, col.m_bytelength); break; case Col::Varchar: memcpy(m_varchar, addr, 1 + col.m_bytelength); break; case Col::Longvarchar: memcpy(m_longvarchar, addr, 2 + col.m_bytelength); break; default: assert(false); break; } m_null = false;}const void*Val::dataaddr() const{ const Col& col = m_col; switch (col.m_type) { case Col::Unsigned: return &m_uint32; case Col::Char: return m_char; case Col::Varchar: return m_varchar; case Col::Longvarchar: return m_longvarchar; default: break; } assert(false); return 0;}intVal::equal(Par par) const{ Con& con = par.con(); const Col& col = m_col; assert(col.m_pk && ! m_null); const char* addr = (const char*)dataaddr(); LL5("equal [" << col << "] " << *this); CHK(con.equal(col.m_num, addr) == 0); return 0;}intVal::equal(Par par, const ICol& icol) const{ Con& con = par.con(); assert(! m_null); const char* addr = (const char*)dataaddr(); LL5("equal [" << icol << "] " << *this); CHK(con.equal(icol.m_num, addr) == 0); return 0;}intVal::setval(Par par) const{ Con& con = par.con(); const Col& col = m_col; assert(! col.m_pk); const char* addr = ! m_null ? (const char*)dataaddr() : 0; LL5("setval [" << col << "] " << *this); CHK(con.setValue(col.m_num, addr) == 0); return 0;}voidVal::calc(Par par, unsigned i){ const Col& col = m_col; col.m_pk ? calckey(par, i) : calcnokey(par); if (! m_null) col.wellformed(dataaddr());}voidVal::calckey(Par par, unsigned i){ const Col& col = m_col; m_null = false; switch (col.m_type) { case Col::Unsigned: m_uint32 = i; break; case Col::Char: { const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; unsigned n = 0; calckeychars(par, i, n, m_char); // extend by appropriate space (*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20); } break; case Col::Varchar: { unsigned n = 0; calckeychars(par, i, n, m_varchar + 1); // set length and pad with nulls m_varchar[0] = n; memset(&m_varchar[1 + n], 0, col.m_bytelength - n); } break; case Col::Longvarchar: { unsigned n = 0; calckeychars(par, i, n, m_longvarchar + 2); // set length and pad with nulls m_longvarchar[0] = (n & 0xff); m_longvarchar[1] = (n >> 8); memset(&m_longvarchar[2 + n], 0, col.m_bytelength - n); } break; default: assert(false); break; }}voidVal::calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf){ const Col& col = m_col; const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; n = 0; unsigned len = 0; while (len < col.m_length) { if (i % (1 + n) == 0) { break; } const Chr& chr = chs->m_chr[i % maxcharcount]; assert(n + chr.m_size <= col.m_bytelength); memcpy(buf + n, chr.m_bytes, chr.m_size); n += chr.m_size; len++; }}voidVal::calcnokey(Par par){ const Col& col = m_col; m_null = false; if (col.m_nullable && urandom(100) < par.m_pctnull) { m_null = true; return; } int r = irandom((par.m_pctrange * par.m_range) / 100); if (par.m_bdir != 0 && urandom(10) != 0) { if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0) r = -r; } unsigned v = par.m_range + r; switch (col.m_type) { case Col::Unsigned: m_uint32 = v; break; case Col::Char: { const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; unsigned n = 0; calcnokeychars(par, n, m_char); // extend by appropriate space (*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20); } break; case Col::Varchar: { unsigned n = 0; calcnokeychars(par, n, m_varchar + 1); // set length and pad with nulls m_varchar[0] = n; memset(&m_varchar[1 + n], 0, col.m_bytelength - n); } break; case Col::Longvarchar: { unsigned n = 0; calcnokeychars(par, n, m_longvarchar + 2); // set length and pad with nulls m_longvarchar[0] = (n & 0xff); m_longvarchar[1] = (n >> 8); memset(&m_longvarchar[2 + n], 0, col.m_bytelength - n); } break; default: assert(false); break; }}voidVal::calcnokeychars(Par par, unsigned& n, unsigned char* buf){ const Col& col = m_col; const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; n = 0; unsigned len = 0; while (len < col.m_length) { if (urandom(1 + col.m_bytelength) == 0) { break; } unsigned half = maxcharcount / 2; int r = irandom((par.m_pctrange * half) / 100); if (par.m_bdir != 0 && urandom(10) != 0) { if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0) r = -r; } unsigned i = half + r; assert(i < maxcharcount); const Chr& chr = chs->m_chr[i]; assert(n + chr.m_size <= col.m_bytelength); memcpy(buf + n, chr.m_bytes, chr.m_size); n += chr.m_size; len++; }}intVal::verify(Par par, const Val& val2) const{ CHK(cmp(par, val2) == 0); return 0;}intVal::cmp(Par par, const Val& val2) const{ const Col& col = m_col; const Col& col2 = val2.m_col; assert(col.equal(col2)); if (m_null || val2.m_null) { if (! m_null) return +1; if (! val2.m_null) return -1; return 0; } // verify data formats col.wellformed(dataaddr()); col.wellformed(val2.dataaddr()); // compare switch (col.m_type) { case Col::Unsigned: { if (m_uint32 < val2.m_uint32) return -1; if (m_uint32 > val2.m_uint32) return +1; return 0; } break; case Col::Char: { unsigned len = col.m_bytelength; return cmpchars(par, m_char, len, val2.m_char, len); } break; case Col::Varchar: { unsigned len1 = m_varchar[0]; unsigned len2 = val2.m_varchar[0]; return cmpchars(par, m_varchar + 1, len1, val2.m_varchar + 1, len2); } break; case Col::Longvarchar: { unsigned len1 = m_longvarchar[0] + (m_longvarchar[1] << 8); unsigned len2 = val2.m_longvarchar[0] + (val2.m_longvarchar[1] << 8); return cmpchars(par, m_longvarchar + 2, len1, val2.m_longvarchar + 2, len2); } break; default: break; } assert(false); return 0;}intVal::cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const{ const Col& col = m_col; const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; int k; if (! par.m_collsp) { unsigned char x1[maxxmulsize * 8000]; unsigned char x2[maxxmulsize * 8000]; // make strxfrm pad both to same length unsigned len = maxxmulsize * col.m_bytelength; int n1 = NdbSqlUtil::strnxfrm_bug7284(cs, x1, chs->m_xmul * len, buf1, len1); int n2 = NdbSqlUtil::strnxfrm_bug7284(cs, x2, chs->m_xmul * len, buf2, len2); assert(n1 != -1 && n1 == n2); k = memcmp(x1, x2, n1); } else { k = (*cs->coll->strnncollsp)(cs, buf1, len1, buf2, len2, false); } return k < 0 ? -1 : k > 0 ? +1 : 0;}static voidprintstring(NdbOut& out, const unsigned char* str, unsigned len, bool showlen){ char buf[4 * 8000]; char *p = buf; *p++ = '['; if (showlen) { sprintf(p, "%u:", len); p += strlen(p); } for (unsigned i = 0; i < len; i++) { unsigned char c = str[i]; if (c == '\\') { *p++ = '\\'; *p++ = c; } else if (0x20 <= c && c < 0x7e) { *p++ = c; } else { *p++ = '\\'; *p++ = hexstr[c >> 4]; *p++ = hexstr[c & 15]; } } *p++ = ']'; *p = 0; out << buf;}static NdbOut&operator<<(NdbOut& out, const Val& val){ const Col& col = val.m_col; if (val.m_null) { out << "NULL"; return out; } switch (col.m_type) { case Col::Unsigned: out << val.m_uint32; break; case Col::Char: { unsigned len = col.m_bytelength; printstring(out, val.m_char, len, false); } break; case Col::Varchar: { unsigned len = val.m_varchar[0]; printstring(out, val.m_varchar + 1, len, true); } break; case Col::Longvarchar: { unsigned len = val.m_longvarchar[0] + (val.m_longvarchar[1] << 8); printstring(out, val.m_longvarchar + 2, len, true); } break; default: out << "type" << col.m_type; assert(false); break; } return out;}// Row - table tuplestruct Row { const Tab& m_tab; Val** m_val; bool m_exist; enum Op { NoOp = 0, ReadOp = 1, InsOp = 2, UpdOp = 4, DelOp = 8, AnyOp = 15 }; Op m_pending; Row* m_dbrow; // copy of db row before update Row(const Tab& tab); ~Row(); void copy(const Row& row2); void calc(Par par, unsigned i, unsigned mask = 0); const Row& dbrow() const; int verify(Par par, const Row& row2, bool pkonly) const; int insrow(Par par); int updrow(Par par); int updrow(Par par, const ITab& itab); int delrow(Par par); int delrow(Par par, const ITab& itab); int selrow(Par par); int selrow(Par par, const ITab& itab); int setrow(Par par); int cmp(Par par, const Row& row2) const; int cmp(Par par, const Row& row2, const ITab& itab) const;private: Row& operator=(const Row& row2);};Row::Row(const Tab& tab) : m_tab(tab){ m_val = new Val* [tab.m_cols];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?