Commit 50b928b0 authored by Rich Prohaska's avatar Rich Prohaska

DB-759 test and fix alter table bug with cardinality data

parent 2494bde7
This diff is collapsed.
# test that add index keeps cardinality for older indexes
source include/have_tokudb.inc;
set default_storage_engine='tokudb';
disable_warnings;
drop table if exists tt;
enable_warnings;
create table tt (a int, b int, c int, primary key(a), key(b), key(c));
let $a=0;
while ($a < 500) {
eval insert into tt values ($a, $a, 0), ($a+1, $a, 0), ($a+2, $a, 0), ($a+3, $a, 0);
inc $a; inc $a; inc $a; inc $a;
}
select count(*) from tt;
# compute cardinality
show indexes from tt;
analyze table tt;
show indexes from tt;
# drop key b
alter table tt drop key b;
show indexes from tt;
# drop key c
alter table tt drop key c;
show indexes from tt;
# test that cardinality is persistent
flush tables;
show indexes from tt;
drop table tt;
...@@ -528,7 +528,7 @@ bool ha_tokudb::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha ...@@ -528,7 +528,7 @@ bool ha_tokudb::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha
error = alter_table_expand_blobs(altered_table, ha_alter_info); error = alter_table_expand_blobs(altered_table, ha_alter_info);
if (error == 0 && ctx->reset_card) { if (error == 0 && ctx->reset_card) {
error = tokudb::set_card_from_status(share->status_block, ctx->alter_txn, table->s, altered_table->s); error = tokudb::alter_card(share->status_block, ctx->alter_txn, table->s, altered_table->s);
} }
if (error == 0 && ctx->optimize_needed) { if (error == 0 && ctx->optimize_needed) {
error = do_optimize(ha_thd()); error = do_optimize(ha_thd());
......
...@@ -118,7 +118,7 @@ static void test_no_keys(DB_ENV *env) { ...@@ -118,7 +118,7 @@ static void test_no_keys(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_no_keys", txn); error = tokudb::create_status(env, &status_db, "status_no_keys", txn);
assert(error == 0); assert(error == 0);
const uint keys = 0; const uint keys = 0;
const uint key_parts = 0; const uint key_parts = 0;
TABLE_SHARE s = { MAX_KEY, keys, key_parts, NULL }; TABLE_SHARE s = { MAX_KEY, keys, key_parts, NULL };
...@@ -143,7 +143,7 @@ static void test_keys(DB_ENV *env) { ...@@ -143,7 +143,7 @@ static void test_keys(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_keys", txn); error = tokudb::create_status(env, &status_db, "status_keys", txn);
assert(error == 0); assert(error == 0);
// define tables // define tables
const uint ta_keys = 3; const uint ta_keys = 3;
const uint ta_key_parts = 1; const uint ta_key_parts = 1;
...@@ -190,7 +190,7 @@ static void test_drop_0(DB_ENV *env) { ...@@ -190,7 +190,7 @@ static void test_drop_0(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_drop_0", txn); error = tokudb::create_status(env, &status_db, "status_drop_0", txn);
assert(error == 0); assert(error == 0);
// define tables // define tables
const uint ta_keys = 3; const uint ta_keys = 3;
const uint ta_key_parts = 1; const uint ta_key_parts = 1;
...@@ -249,7 +249,7 @@ static void test_drop_1(DB_ENV *env) { ...@@ -249,7 +249,7 @@ static void test_drop_1(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_drop_1", txn); error = tokudb::create_status(env, &status_db, "status_drop_1", txn);
assert(error == 0); assert(error == 0);
// define tables // define tables
const uint ta_keys = 3; const uint ta_keys = 3;
const uint ta_key_parts = 1; const uint ta_key_parts = 1;
...@@ -308,7 +308,7 @@ static void test_drop_2(DB_ENV *env) { ...@@ -308,7 +308,7 @@ static void test_drop_2(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_drop_2", txn); error = tokudb::create_status(env, &status_db, "status_drop_2", txn);
assert(error == 0); assert(error == 0);
// define tables // define tables
const uint ta_keys = 3; const uint ta_keys = 3;
const uint ta_key_parts = 1; const uint ta_key_parts = 1;
...@@ -357,6 +357,65 @@ static void test_drop_2(DB_ENV *env) { ...@@ -357,6 +357,65 @@ static void test_drop_2(DB_ENV *env) {
assert(error == 0); assert(error == 0);
} }
static void test_drop_1_multiple_parts(DB_ENV *env) {
int error;
DB_TXN *txn = NULL;
error = env->txn_begin(env, NULL, &txn, 0);
assert(error == 0);
DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_drop_1_multiple_parts", txn);
assert(error == 0);
// define tables
const uint ta_keys = 3;
const uint ta_key_parts = 1+2+3;
const uint ta_rec_per_keys = ta_key_parts;
uint64_t ta_rec_per_key[ta_rec_per_keys] = {
1000, 2000, 2001, 3000, 3001, 3002,
};
KEY_INFO ta_key_info[ta_rec_per_keys] = {
{ 0, 1, &ta_rec_per_key[0], (char *) "key_a" },
{ 0, 2, &ta_rec_per_key[0+1], (char *) "key_b" },
{ 0, 3, &ta_rec_per_key[0+1+2], (char *) "key_c" },
};
TABLE_SHARE ta = { MAX_KEY, ta_keys, ta_key_parts, ta_key_info };
const uint tb_keys = 2;
const uint tb_key_parts = 1+3;
const int tb_rec_per_keys = tb_key_parts;
uint64_t tb_rec_per_key[tb_rec_per_keys] = {
1000, 3000, 3001, 3002,
};
KEY_INFO tb_key_info[tb_rec_per_keys] = {
{ 0, 1, &tb_rec_per_key[0], (char *) "key_a" },
{ 0, 3, &tb_rec_per_key[0+1], (char *) "key_c" },
};
TABLE_SHARE tb = { MAX_KEY, tb_keys, tb_key_parts, tb_key_info };
// set initial cardinality
error = tokudb::set_card_in_status(status_db, txn, ta_rec_per_keys, ta_rec_per_key);
assert(error == 0);
error = tokudb::alter_card(status_db, txn, &ta, &tb);
assert(error == 0);
// verify
uint64_t current_rec_per_key[tb_rec_per_keys];
error = tokudb::get_card_from_status(status_db, txn, tb_rec_per_keys, current_rec_per_key);
assert(error == 0);
for (uint i = 0; i < tb_rec_per_keys; i++) {
assert(current_rec_per_key[i] == tb_rec_per_key[i]);
}
error = txn->commit(txn, 0);
assert(error == 0);
error = tokudb::close_status(&status_db);
assert(error == 0);
}
static void test_add_0(DB_ENV *env) { static void test_add_0(DB_ENV *env) {
int error; int error;
...@@ -367,7 +426,7 @@ static void test_add_0(DB_ENV *env) { ...@@ -367,7 +426,7 @@ static void test_add_0(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_add_0", txn); error = tokudb::create_status(env, &status_db, "status_add_0", txn);
assert(error == 0); assert(error == 0);
// define tables // define tables
const uint ta_keys = 2; const uint ta_keys = 2;
const uint ta_key_parts = 1; const uint ta_key_parts = 1;
...@@ -426,7 +485,7 @@ static void test_add_1(DB_ENV *env) { ...@@ -426,7 +485,7 @@ static void test_add_1(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_add_1", txn); error = tokudb::create_status(env, &status_db, "status_add_1", txn);
assert(error == 0); assert(error == 0);
// define tables // define tables
const uint ta_keys = 2; const uint ta_keys = 2;
const uint ta_key_parts = 1; const uint ta_key_parts = 1;
...@@ -485,7 +544,7 @@ static void test_add_2(DB_ENV *env) { ...@@ -485,7 +544,7 @@ static void test_add_2(DB_ENV *env) {
DB *status_db = NULL; DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_add_2", txn); error = tokudb::create_status(env, &status_db, "status_add_2", txn);
assert(error == 0); assert(error == 0);
// define tables // define tables
const uint ta_keys = 2; const uint ta_keys = 2;
const uint ta_key_parts = 1; const uint ta_key_parts = 1;
...@@ -503,7 +562,7 @@ static void test_add_2(DB_ENV *env) { ...@@ -503,7 +562,7 @@ static void test_add_2(DB_ENV *env) {
const uint tb_key_parts = 1; const uint tb_key_parts = 1;
const int tb_rec_per_keys = tb_keys * tb_key_parts; const int tb_rec_per_keys = tb_keys * tb_key_parts;
uint64_t tb_rec_per_key[tb_rec_per_keys] = { uint64_t tb_rec_per_key[tb_rec_per_keys] = {
2000, 3000, 0 /*not computed*/, 2000, 3000, 0 /*not computed*/,
}; };
KEY_INFO tb_key_info[tb_rec_per_keys] = { KEY_INFO tb_key_info[tb_rec_per_keys] = {
{ 0, tb_key_parts, &tb_rec_per_key[0], (char *) "key_b" }, { 0, tb_key_parts, &tb_rec_per_key[0], (char *) "key_b" },
...@@ -534,6 +593,65 @@ static void test_add_2(DB_ENV *env) { ...@@ -534,6 +593,65 @@ static void test_add_2(DB_ENV *env) {
assert(error == 0); assert(error == 0);
} }
static void test_add_0_multiple_parts(DB_ENV *env) {
int error;
DB_TXN *txn = NULL;
error = env->txn_begin(env, NULL, &txn, 0);
assert(error == 0);
DB *status_db = NULL;
error = tokudb::create_status(env, &status_db, "status_add_0_multiple_parts", txn);
assert(error == 0);
// define tables
const uint ta_keys = 2;
const uint ta_key_parts = 3+4;
const uint ta_rec_per_keys = ta_key_parts;
uint64_t ta_rec_per_key[ta_rec_per_keys] = {
2000, 2001, 2002, 3000, 3001, 3002, 3003,
};
KEY_INFO ta_key_info[ta_rec_per_keys] = {
{ 0, 3, &ta_rec_per_key[0], (char *) "key_b" },
{ 0, 4, &ta_rec_per_key[3], (char *) "key_c" },
};
TABLE_SHARE ta = { MAX_KEY, ta_keys, ta_key_parts, ta_key_info };
const uint tb_keys = 3;
const uint tb_key_parts = 2+3+4;
const int tb_rec_per_keys = tb_key_parts;
uint64_t tb_rec_per_key[tb_rec_per_keys] = {
0, 0 /*not computed*/, 2000, 2001, 2002, 3000, 3001, 3002, 3003,
};
KEY_INFO tb_key_info[tb_rec_per_keys] = {
{ 0, 2, &tb_rec_per_key[0], (char *) "key_a" },
{ 0, 3, &tb_rec_per_key[0+2], (char *) "key_b" },
{ 0, 4, &tb_rec_per_key[0+2+3], (char *) "key_c" },
};
TABLE_SHARE tb = { MAX_KEY, tb_keys, tb_key_parts, tb_key_info };
// set initial cardinality
error = tokudb::set_card_in_status(status_db, txn, ta_rec_per_keys, ta_rec_per_key);
assert(error == 0);
error = tokudb::alter_card(status_db, txn, &ta, &tb);
assert(error == 0);
// verify
uint64_t current_rec_per_key[tb_rec_per_keys];
error = tokudb::get_card_from_status(status_db, txn, tb_rec_per_keys, current_rec_per_key);
assert(error == 0);
for (uint i = 0; i < tb_rec_per_keys; i++) {
assert(current_rec_per_key[i] == tb_rec_per_key[i]);
}
error = txn->commit(txn, 0);
assert(error == 0);
error = tokudb::close_status(&status_db);
assert(error == 0);
}
int main() { int main() {
int error; int error;
...@@ -547,7 +665,7 @@ int main() { ...@@ -547,7 +665,7 @@ int main() {
error = db_env_create(&env, 0); error = db_env_create(&env, 0);
assert(error == 0); assert(error == 0);
error = env->open(env, __FILE__ ".testdir", DB_INIT_MPOOL + DB_INIT_LOG + DB_INIT_LOCK + DB_INIT_TXN + DB_PRIVATE + DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO); error = env->open(env, __FILE__ ".testdir", DB_INIT_MPOOL + DB_INIT_LOG + DB_INIT_LOCK + DB_INIT_TXN + DB_PRIVATE + DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
assert(error == 0); assert(error == 0);
test_no_keys(env); test_no_keys(env);
...@@ -555,12 +673,14 @@ int main() { ...@@ -555,12 +673,14 @@ int main() {
test_drop_0(env); test_drop_0(env);
test_drop_1(env); test_drop_1(env);
test_drop_2(env); test_drop_2(env);
test_drop_1_multiple_parts(env);
test_add_0(env); test_add_0(env);
test_add_1(env); test_add_1(env);
test_add_2(env); test_add_2(env);
test_add_0_multiple_parts(env);
error = env->close(env, 0); error = env->close(env, 0);
assert(error == 0); assert(error == 0);
return 0; return 0;
} }
...@@ -174,9 +174,14 @@ namespace tokudb { ...@@ -174,9 +174,14 @@ namespace tokudb {
return false; return false;
} }
static void copy_card(uint64_t *dest, uint64_t *src, size_t n) {
for (size_t i = 0; i < n; i++)
dest[i] = src[i];
}
// Altered table cardinality = select cardinality data from current table cardinality for keys that exist // Altered table cardinality = select cardinality data from current table cardinality for keys that exist
// in the altered table and the current table. // in the altered table and the current table.
int set_card_from_status(DB *status_db, DB_TXN *txn, TABLE_SHARE *table_share, TABLE_SHARE *altered_table_share) { int alter_card(DB *status_db, DB_TXN *txn, TABLE_SHARE *table_share, TABLE_SHARE *altered_table_share) {
int error; int error;
// read existing cardinality data from status // read existing cardinality data from status
uint table_total_key_parts = tokudb::compute_total_key_parts(table_share); uint table_total_key_parts = tokudb::compute_total_key_parts(table_share);
...@@ -201,7 +206,7 @@ namespace tokudb { ...@@ -201,7 +206,7 @@ namespace tokudb {
uint ith_key_parts = get_key_parts(&altered_table_share->key_info[i]); uint ith_key_parts = get_key_parts(&altered_table_share->key_info[i]);
uint orig_key_index; uint orig_key_index;
if (find_index_of_key(altered_table_share->key_info[i].name, table_share, &orig_key_index)) { if (find_index_of_key(altered_table_share->key_info[i].name, table_share, &orig_key_index)) {
memcpy(&altered_rec_per_key[next_key_parts], &rec_per_key[orig_key_offset[orig_key_index]], ith_key_parts); copy_card(&altered_rec_per_key[next_key_parts], &rec_per_key[orig_key_offset[orig_key_index]], ith_key_parts);
} }
next_key_parts += ith_key_parts; next_key_parts += ith_key_parts;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment