diff options
author | Rich Prohaska <prohaska@tokutek.com> | 2014-11-13 10:53:22 -0500 |
---|---|---|
committer | Rich Prohaska <prohaska@tokutek.com> | 2014-11-13 10:53:22 -0500 |
commit | 2db029048fc0ee91bd5026ecfa46c37954430e13 (patch) | |
tree | 85f429eadcc4aff561d24e469b6f75705b97c1e2 /storage/tokudb | |
parent | 2b13aba809dc26ab4451e2851b3ccab64554399e (diff) | |
download | mariadb-git-2db029048fc0ee91bd5026ecfa46c37954430e13.tar.gz |
DB-759 test and fix alter table bug with cardinality data
Diffstat (limited to 'storage/tokudb')
-rw-r--r-- | storage/tokudb/ha_tokudb_alter_56.cc | 2 | ||||
-rw-r--r-- | storage/tokudb/tests/card_test_alter.cc | 142 | ||||
-rw-r--r-- | storage/tokudb/tokudb_card.h | 9 |
3 files changed, 139 insertions, 14 deletions
diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc index e55b7b48ad8..1a03dc815a1 100644 --- a/storage/tokudb/ha_tokudb_alter_56.cc +++ b/storage/tokudb/ha_tokudb_alter_56.cc @@ -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); 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) { error = do_optimize(ha_thd()); diff --git a/storage/tokudb/tests/card_test_alter.cc b/storage/tokudb/tests/card_test_alter.cc index 549996ba58b..2a3e9396b3f 100644 --- a/storage/tokudb/tests/card_test_alter.cc +++ b/storage/tokudb/tests/card_test_alter.cc @@ -118,7 +118,7 @@ static void test_no_keys(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_no_keys", txn); assert(error == 0); - + const uint keys = 0; const uint key_parts = 0; TABLE_SHARE s = { MAX_KEY, keys, key_parts, NULL }; @@ -143,7 +143,7 @@ static void test_keys(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_keys", txn); assert(error == 0); - + // define tables const uint ta_keys = 3; const uint ta_key_parts = 1; @@ -190,7 +190,7 @@ static void test_drop_0(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_drop_0", txn); assert(error == 0); - + // define tables const uint ta_keys = 3; const uint ta_key_parts = 1; @@ -249,7 +249,7 @@ static void test_drop_1(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_drop_1", txn); assert(error == 0); - + // define tables const uint ta_keys = 3; const uint ta_key_parts = 1; @@ -308,7 +308,7 @@ static void test_drop_2(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_drop_2", txn); assert(error == 0); - + // define tables const uint ta_keys = 3; const uint ta_key_parts = 1; @@ -357,6 +357,65 @@ static void test_drop_2(DB_ENV *env) { 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) { int error; @@ -367,7 +426,7 @@ static void test_add_0(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_add_0", txn); assert(error == 0); - + // define tables const uint ta_keys = 2; const uint ta_key_parts = 1; @@ -426,7 +485,7 @@ static void test_add_1(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_add_1", txn); assert(error == 0); - + // define tables const uint ta_keys = 2; const uint ta_key_parts = 1; @@ -485,7 +544,7 @@ static void test_add_2(DB_ENV *env) { DB *status_db = NULL; error = tokudb::create_status(env, &status_db, "status_add_2", txn); assert(error == 0); - + // define tables const uint ta_keys = 2; const uint ta_key_parts = 1; @@ -503,7 +562,7 @@ static void test_add_2(DB_ENV *env) { const uint tb_key_parts = 1; const int tb_rec_per_keys = tb_keys * tb_key_parts; 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] = { { 0, tb_key_parts, &tb_rec_per_key[0], (char *) "key_b" }, @@ -534,6 +593,65 @@ static void test_add_2(DB_ENV *env) { 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 error; @@ -547,7 +665,7 @@ int main() { error = db_env_create(&env, 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); test_no_keys(env); @@ -555,12 +673,14 @@ int main() { test_drop_0(env); test_drop_1(env); test_drop_2(env); + test_drop_1_multiple_parts(env); test_add_0(env); test_add_1(env); test_add_2(env); + test_add_0_multiple_parts(env); error = env->close(env, 0); assert(error == 0); - + return 0; } diff --git a/storage/tokudb/tokudb_card.h b/storage/tokudb/tokudb_card.h index a9439c124eb..797c705bbaf 100644 --- a/storage/tokudb/tokudb_card.h +++ b/storage/tokudb/tokudb_card.h @@ -174,9 +174,14 @@ namespace tokudb { 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 // 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; // read existing cardinality data from status uint table_total_key_parts = tokudb::compute_total_key_parts(table_share); @@ -201,7 +206,7 @@ namespace tokudb { uint ith_key_parts = get_key_parts(&altered_table_share->key_info[i]); uint 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; } |