summaryrefslogtreecommitdiff
path: root/storage/tokudb
diff options
context:
space:
mode:
authorRich Prohaska <prohaska@tokutek.com>2014-11-13 10:53:22 -0500
committerRich Prohaska <prohaska@tokutek.com>2014-11-13 10:53:22 -0500
commit2db029048fc0ee91bd5026ecfa46c37954430e13 (patch)
tree85f429eadcc4aff561d24e469b6f75705b97c1e2 /storage/tokudb
parent2b13aba809dc26ab4451e2851b3ccab64554399e (diff)
downloadmariadb-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.cc2
-rw-r--r--storage/tokudb/tests/card_test_alter.cc142
-rw-r--r--storage/tokudb/tokudb_card.h9
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;
}