From 30b73cac67cd019842bf47ea1aca18abb8b33e98 Mon Sep 17 00:00:00 2001 From: Rahul Malik Date: Tue, 5 Jul 2022 15:35:15 +0530 Subject: [PATCH 1/2] pstress-78 Add support for generated virtual column queries in pstress https://jira.percona.com/browse/PSTRESS-78 pstress-119 Option to manipulate length of CHAR, VARCHAR, BLOB https://jira.percona.com/browse/PSTRESS-119 Introduced below new options --columns-in-generated: maximum number of columns in a generated column default#: 6 --generated-stored: Probability of generated columns STORED or VIRTUAL 50 ==> equal chances of stored and virtual 100 => all columns are stored 0 => all columns are virtual any other value sets the probability of stored column accordingly default#: 50 --char-length: char column maximum length default#: 20 --varchar-length: varchar column maximum length. default#: 40 --blob-length: Maximum lenght of blob/text columns TINYBLOB/TINYTEXT 1/4 of blob-length TEXT/BLOB 1/3 of blob-length MEDIUMBLOB/MEDIUMTEXT 1/2 of blob-length LONGBLOB/LONGTEXT blob-length default#: 1000 --- src/common.hpp | 7 +- src/help.cpp | 42 +++++++-- src/random_test.cpp | 210 ++++++++++++++++++++++++++++---------------- src/random_test.hpp | 8 +- 4 files changed, 180 insertions(+), 87 deletions(-) diff --git a/src/common.hpp b/src/common.hpp index 1427231..c8ef4bf 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -50,7 +50,7 @@ struct Option { NO_TABLE_COMPRESSION, NO_TABLESPACE, NO_BLOB, - NO_VIRTUAL_COLUMNS, + NO_GENERATED_COLUMNS, TABLES, INDEXES, ALGORITHM, @@ -140,6 +140,11 @@ struct Option { DROP_CREATE, EXACT_INITIAL_RECORDS, PREPARE, + BASE_COLUMNS_IN_GENERATED, + GENERATED_STORED, + CHAR_LENGTH, + VARCHAR_LENGTH, + BLOB_LENGTH, MAX } option; Option(Type t, Opt o, std::string n) diff --git a/src/help.cpp b/src/help.cpp index e60493f..5554a97 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -148,13 +148,45 @@ void add_options() { opt->setSQL(); opt->setDDL(); - /* disable virtual columns*/ - opt = newOption(Option::BOOL, Option::NO_VIRTUAL_COLUMNS, "no-virtual"); - opt->help = "Disable virtual columns"; + /* disable generated columns*/ + opt = newOption(Option::BOOL, Option::NO_GENERATED_COLUMNS, "no-generated"); + opt->help = "Disable generated columns"; opt->setBool(false); opt->setArgs(no_argument); - /* disable blob,text columns*/ + /* number of base columns in a generated column*/ + opt = newOption(Option::INT, Option::BASE_COLUMNS_IN_GENERATED, + "columns-in-generated"); + opt->help = "maximum number of columns in a generated column"; + opt->setInt(6); + + /* generated column types */ + opt = newOption(Option::INT, Option::GENERATED_STORED, "generated-stored"); + opt->help = "Probability of generated columns STORED or VIRTUAL\n50 ==> " + "equal chances of stored and virtual\n100 => all columns are " + "stored\n0 all columns are virtual\n any other value sets the " + "probability of stored column accordingly"; + opt->setInt(50); + + /* blob column length */ + opt = newOption(Option::INT, Option::BLOB_LENGTH, "blob-length"); + opt->help = + "Maximum lenght of blob/text columns\nTINYBLOB/TINYTEXT 1/4 of " + "blob-length \nTEXT/BLOB 1/3 of blob-length \nMEDIUMBLOB/MEDIUMTEXT 1/2 " + "of blob-length\nLONGBLOB/LONGTEXT blob-length"; + opt->setInt(1000); + + /* char column length */ + opt = newOption(Option::INT, Option::CHAR_LENGTH, "char-length"); + opt->help = "char column maximum length"; + opt->setInt(20); + + /* varchar column length */ + opt = newOption(Option::INT, Option::VARCHAR_LENGTH, "varchar-length"); + opt->help = "varchar column maximum length."; + opt->setInt(40); + + /* disable blob, text columns*/ opt = newOption(Option::BOOL, Option::NO_BLOB, "no-blob"); opt->help = "Disable blob columns"; opt->setBool(false); @@ -624,7 +656,7 @@ void add_options() { /* log all queries */ opt = newOption(Option::BOOL, Option::LOG_ALL_QUERIES, "log-all-queries"); opt->help = "Log all queries (succeeded and failed)"; - opt->setBool(true); // todo diable while merge + opt->setBool(false); opt->setArgs(no_argument); /* execute sql sequentially */ diff --git a/src/random_test.cpp b/src/random_test.cpp index e42b2dd..6e56ef5 100644 --- a/src/random_test.cpp +++ b/src/random_test.cpp @@ -31,7 +31,6 @@ static std::vector g_tablespace; static std::vector locks; static std::vector algorithms; static std::vector g_key_block_size; -static int g_max_columns_length = 30; static int g_innodb_page_size; static int sum_of_all_opts = 0; // sum of all probablility std::mutex ddl_logs_write; @@ -152,11 +151,6 @@ int sum_of_all_options(Thd1 *thd) { algorithms.push_back("DEFAULT"); } - /* Disabling until Bug: https://jira.percona.com/browse/PS-7865 is fixed by upstream */ - if (server_version() >= 80000 && server_version() <= 80026) { - opt_int_set(ALTER_DISCARD_TABLESPACE, 0); - } - auto enc_type = options->at(Option::ENCRYPTION_TYPE)->getString(); /* for percona-server we have additional encryption type keyring */ @@ -406,6 +400,7 @@ std::vector *random_strs_generator(unsigned long int seed) { std::vector *random_strs; int rand_int(int upper, int lower) { + assert(uppper > lower); /*todo change the approach if it is too slow */ std::uniform_int_distribution dist( lower, upper); // distribution in range [lower, upper] @@ -590,22 +585,19 @@ std::string Column::definition() { /* add new column, part of create table or Alter table */ Column::Column(std::string name, Table *table, COLUMN_TYPES type) - : table_(table) { - type_ = type; + : type_(type), table_(table) { switch (type) { case CHAR: name_ = "c" + name; - length = rand_int(g_max_columns_length, 10); + length = rand_int(options->at(Option::CHAR_LENGTH)->getInt(), 1); break; case VARCHAR: name_ = "v" + name; - length = rand_int(g_max_columns_length, 10); + length = rand_int(options->at(Option::VARCHAR_LENGTH)->getInt(), 1); break; case INT: case INTEGER: name_ = "i" + name; - if (rand_int(10) == 1) - length = rand_int(100, 20); break; case FLOAT: name_ = "f" + name; @@ -614,7 +606,7 @@ Column::Column(std::string name, Table *table, COLUMN_TYPES type) name_ = "d" + name; break; case BOOL: - name_ = "t" + name; + name_ = "l" + name; // l for logical as t is for text break; default: throw std::runtime_error("unhandled " + col_type_to_string(type_) + @@ -629,26 +621,47 @@ Blob_Column::Blob_Column(std::string name, Table *table) if (options->at(Option::NO_COLUMN_COMPRESSION)->getBool() == false && rand_int(1) == 1) compressed = true; - switch (rand_int(5, 1)) { + + switch (rand_int(8, 1)) { case 1: - sub_type = "MEDIUMTEXT"; - name_ = "mt" + name; + sub_type = "TINYTEXT"; + name_ = "tt" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt() / 4, 1); break; case 2: sub_type = "TEXT"; name_ = "t" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt() / 3, 1); break; case 3: - sub_type = "LONGTEXT"; - name_ = "lt" + name; + sub_type = "MEDIUMTEXT"; + name_ = "tm" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt() / 2, 1); break; case 4: + sub_type = "LONGTEXT"; + name_ = "tl" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt(), 1); + break; + case 5: + sub_type = "TINYBLOB"; + name_ = "bt" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt() / 4, 1); + break; + case 6: sub_type = "BLOB"; name_ = "b" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt() / 3, 1); break; - case 5: + case 7: + sub_type = "MEDIUMBLOB"; + name_ = "bm" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt() / 2, 1); + break; + case 8: sub_type = "LONGBLOB"; - name_ = "lb" + name; + name_ = "bl" + name; + length = rand_int(options->at(Option::BLOB_LENGTH)->getInt(), 1); break; } } @@ -660,8 +673,9 @@ Blob_Column::Blob_Column(std::string name, Table *table, std::string sub_type_) } /* Constructor used for load metadata */ -Generated_Column::Generated_Column(std::string name, Table *table, - std::string clause, std::string sub_type) +Generated_Column::Generated_Column(const std::string &name, Table *table, + const std::string &clause, + const std::string &sub_type) : Column(table, Column::GENERATED) { name_ = name; str = clause; @@ -669,21 +683,22 @@ Generated_Column::Generated_Column(std::string name, Table *table, } /* Generated column constructor. lock table before calling */ -Generated_Column::Generated_Column(std::string name, Table *table) +Generated_Column::Generated_Column(const std::string &name, Table *table) : Column(table, Column::GENERATED) { + name_ = "g" + name; auto blob_supported = !options->at(Option::NO_BLOB)->getBool(); g_type = COLUMN_MAX; - /* Generated columns are 2:2:2:2 (INT:VARCHAR:CHAR:BLOB) */ + /* Generated columns are 2:2:2:1 (INT:VARCHAR:CHAR:BLOB) */ while (g_type == COLUMN_MAX) { - auto x = rand_int(4, 1); - if (x <= 1) + auto x = rand_int(7, 1); + if (x <= 2) g_type = INT; - else if (x <= 2) + else if (x <= 4) g_type = VARCHAR; - else if (x <= 3) + else if (x <= 6) g_type = CHAR; - else if (blob_supported && x <= 4) { + else if (blob_supported && x <= 7) { g_type = BLOB; } } @@ -693,89 +708,123 @@ Generated_Column::Generated_Column(std::string name, Table *table) compressed = true; /*number of columns in generated columns */ - size_t columns = rand_int(.6 * table->columns_->size()) + 1; + size_t expected_num_of_columns = + rand_int(options->at(Option::BASE_COLUMNS_IN_GENERATED)->getInt(), 1); std::vector col_pos; // position of columns - while (col_pos.size() < columns) { + + if (expected_num_of_columns > table->columns_->size() && rand_int(100) > 5) + expected_num_of_columns = rand_int(table->columns_->size(), 1); + + while (col_pos.size() < expected_num_of_columns) { size_t col = rand_int(table->columns_->size() - 1); if (!table->columns_->at(col)->auto_increment && table->columns_->at(col)->type_ != GENERATED) col_pos.push_back(col); } + std::string clause_sql; + size_t actual_size = 0; + if (g_type == INT || g_type == INTEGER) { - str = " " + col_type_to_string(g_type) + " GENERATED ALWAYS AS ("; for (auto pos : col_pos) { auto col = table->columns_->at(pos); if (col->type_ == VARCHAR || col->type_ == CHAR || col->type_ == BLOB) - str += " LENGTH(" + col->name_ + ")+"; + clause_sql += "LENGTH(" + col->name_ + ")+"; else if (col->type_ == INT || col->type_ == INTEGER || col->type_ == BOOL || col->type_ == FLOAT || col->type_ == DOUBLE) - str += " " + col->name_ + "+"; + clause_sql += " " + col->name_ + "+"; else throw std::runtime_error("unhandled " + col_type_to_string(col->type_) + " at line " + std::to_string(__LINE__)); } - str.pop_back(); + clause_sql.pop_back(); } else if (g_type == VARCHAR || g_type == CHAR || g_type == BLOB) { - auto size = rand_int(g_max_columns_length, col_pos.size()); - int actual_size = 0; - std::string gen_sql; + + size_t expected_size = 0; + std::vector generated_base_column; + + if (g_type == CHAR) + expected_size = rand_int(options->at(Option::CHAR_LENGTH)->getInt(), 1); + else if (g_type == VARCHAR) + expected_size = + rand_int(options->at(Option::VARCHAR_LENGTH)->getInt(), 1); + else if (g_type == BLOB) + expected_size = rand_int(options->at(Option::BLOB_LENGTH)->getInt(), 1); + + for (auto pos : col_pos) { auto col = table->columns_->at(pos); - auto current_size = rand_int((int)size / col_pos.size() * 2, 1); int column_size = 0; /* base column */ switch (col->type_) { + case BOOL: + column_size = 1; + break; case INT: case INTEGER: + case FLOAT: column_size = 10; // interger max string size is 10 break; - case FLOAT: case DOUBLE: - column_size = 10; - break; - case BOOL: - column_size = 1; + column_size = 20; break; case VARCHAR: case CHAR: - column_size = col->length; - break; - case BLOB: - column_size = 5000; // todo set it different subtype - break; - case COLUMN_MAX: + case BLOB: { + size_t max_base_size = 2 * expected_size / expected_num_of_columns; + if (max_base_size < 1) + max_base_size = 1; + column_size = rand_int(max_base_size, 1); + } break; case GENERATED: + case COLUMN_MAX: throw std::runtime_error("unhandled " + col_type_to_string(col->type_) + " at line " + std::to_string(__LINE__)); } - if (column_size > current_size) { - actual_size += current_size; - gen_sql += - "SUBSTRING(" + col->name_ + ",1," + std::to_string(current_size) + "),"; + + if (column_size < col->length) { + actual_size += column_size; + generated_base_column.push_back("SUBSTRING(" + col->name_ + ",1," + + std::to_string(column_size) + ")"); } else { actual_size += column_size; - gen_sql += col->name_ + ","; + generated_base_column.push_back(col->name_); } } - gen_sql.pop_back(); - str = " " + col_type_to_string(g_type); - if (g_type == VARCHAR || g_type == CHAR) - str += "(" + std::to_string(actual_size) + ")"; - str += " GENERATED ALWAYS AS (CONCAT("; - str += gen_sql; - str += ")"; + + if (generated_base_column.size() > 1) { + clause_sql += "CONCAT("; + for (auto &c : generated_base_column) + clause_sql += c + ", "; + + clause_sql.erase(clause_sql.length() - 2); + + clause_sql += ")"; + } else + clause_sql += generated_base_column[0]; + length = actual_size; + } else { throw std::runtime_error("unhandled " + col_type_to_string(g_type) + " at line " + std::to_string(__LINE__)); } - str += ")"; - if (rand_int(2) == 1 || compressed) + str = " " + col_type_to_string(g_type); + + if (g_type == VARCHAR || g_type == CHAR) + str += "(" + std::to_string(actual_size) + ")"; + + str += " GENERATED ALWAYS AS (" + clause_sql + ")"; + + if (rand_int(100, 1) < options->at(Option::GENERATED_STORED)->getInt() || + compressed) str += " STORED"; + /* DEFAULT is VIRTUAL, so add keyword only in some cases */ + else if (rand_int(2, 1) == 1) + str += " VIRTUAL"; } template void Column::Serialize(Writer &writer) const { @@ -962,7 +1011,8 @@ std::string Index::definition() { (idc->column->type_ == Column::GENERATED && static_cast(idc->column)->generate_type() == Column::BLOB)) - def += "(" + std::to_string(rand_int(g_max_columns_length, 1)) + ")"; + // todo add it inside AddIndex + def += "(" + std::to_string(30) + ")"; def += (idc->desc ? " DESC" : (rand_int(3) ? "" : " ASC")); def += ", "; @@ -1352,7 +1402,7 @@ void Table::CreateDefaultColumn() { } else { name = std::to_string(i); Column::COLUMN_TYPES col_type = Column::COLUMN_MAX; - static auto no_virtual_col = opt_bool(NO_VIRTUAL_COLUMNS); + static auto no_generated_col = opt_bool(NO_GENERATED_COLUMNS); static auto no_blob_col = opt_bool(NO_BLOB); /* loop untill we select some column */ @@ -1362,8 +1412,8 @@ void Table::CreateDefaultColumn() { auto prob = rand_int(19); /* intial columns can't be generated columns. also 50% of tables last - * columns are virtuals */ - if (!no_virtual_col && i >= .8 * max_columns && rand_int(1) == 1) + * columns are generateds */ + if (!no_generated_col && i >= .8 * max_columns && rand_int(1) == 1) col_type = Column::GENERATED; else if (prob < 5) col_type = Column::INT; @@ -1871,11 +1921,12 @@ void Table::ModifyColumn(Thd1 *thd) { std::string sql = "ALTER TABLE " + name_ + " MODIFY COLUMN "; int i = 0; Column *col = nullptr; + /* store old value */ int length = 0; std::string default_value; bool auto_increment = false; - bool compressed = false; // percona type compressed + bool column_compressed = false; // percona type compressed // try maximum 50 times to get a valid column while (i < 50 && col == nullptr) { @@ -1892,7 +1943,7 @@ void Table::ModifyColumn(Thd1 *thd) { col = col1; length = col->length; auto_increment = col->auto_increment; - compressed = col->compressed; + column_compressed = col->compressed; col->mutex.lock(); // lock column so no one can modify it // break; /* todo no support for BOOL INT so far */ @@ -1907,7 +1958,12 @@ void Table::ModifyColumn(Thd1 *thd) { if (col == nullptr) return; - col->length = rand_int(g_max_columns_length, 0); + if(col->type_ == Column::BLOB) + col->length = rand_int(options->at(Option::BLOB_LENGTH)->getInt(), 1); + else if (col->type_ == Column::CHAR) + col->length = rand_int(options->at(Option::CHAR_LENGTH)->getInt(), 1); + else if (col->type_ == Column::VARCHAR) + col->length = rand_int(options->at(Option::VARCHAR_LENGTH)->getInt(), 1); if (col->auto_increment == true and rand_int(5) == 0) col->auto_increment = false; @@ -1925,7 +1981,7 @@ void Table::ModifyColumn(Thd1 *thd) { if (!execute_sql(sql, thd)) { col->length = length; col->auto_increment = auto_increment; - col->compressed = compressed; + col->compressed = column_compressed; } col->mutex.unlock(); @@ -2001,21 +2057,21 @@ void Table::DropColumn(Thd1 *thd) { /* alter table add random column */ void Table::AddColumn(Thd1 *thd) { - static auto no_use_virtual = opt_bool(NO_VIRTUAL_COLUMNS); + static auto no_use_generated = opt_bool(NO_GENERATED_COLUMNS); static auto use_blob = !options->at(Option::NO_BLOB)->getBool(); std::string sql = "ALTER TABLE " + name_ + " ADD COLUMN "; Column::COLUMN_TYPES col_type = Column::COLUMN_MAX; - auto use_virtual = true; + auto use_generated = true; // lock table to create definition table_mutex.lock(); - if (no_use_virtual || + if (no_use_generated || (columns_->size() == 1 && columns_->at(0)->auto_increment == true)) - use_virtual = false; + use_generated = false; while (col_type == Column::COLUMN_MAX) { /* new columns are in ratio of 3:2:1:1:1:1 @@ -2029,7 +2085,7 @@ void Table::AddColumn(Thd1 *thd) { col_type = Column::VARCHAR; else if (prob < 6) col_type = Column::CHAR; - else if (prob < 7 && use_virtual) + else if (prob < 7 && use_generated) col_type = Column::GENERATED; else if (prob < 8) col_type = Column::BOOL; diff --git a/src/random_test.hpp b/src/random_test.hpp index 10c5feb..6ba9084 100644 --- a/src/random_test.hpp +++ b/src/random_test.hpp @@ -99,7 +99,7 @@ class Column { struct Blob_Column : public Column { Blob_Column(std::string name, Table *table); Blob_Column(std::string name, Table *table, std::string sub_type_); - std::string sub_type; // sub_type can be tiny, medium, large blob + std::string sub_type; std::string clause() { return sub_type; }; std::string rand_value() { return "\'" + rand_string(1000) + "\'"; } template void Serialize(Writer &writer) const; @@ -108,11 +108,11 @@ struct Blob_Column : public Column { struct Generated_Column : public Column { /* constructor for new random generated column */ - Generated_Column(std::string name, Table *table); + Generated_Column(const std::string &name, Table *table); /* constructor used to prepare metadata */ - Generated_Column(std::string name, Table *table, std::string clause, - std::string sub_type); + Generated_Column(const std::string &name, Table *table, + const std::string &clause, const std::string &sub_type); template void Serialize(Writer &writer) const; From cedc07102df34c7434547254a11e001348e8c5e8 Mon Sep 17 00:00:00 2001 From: Rahul Malik Date: Tue, 26 Jul 2022 15:52:03 +0530 Subject: [PATCH 2/2] WIP, Creating lot of default indexes --- src/common.hpp | 1 + src/help.cpp | 5 ++ src/random_test.cpp | 136 +++++++++++++++++++++----------------------- src/random_test.hpp | 5 +- 4 files changed, 75 insertions(+), 72 deletions(-) diff --git a/src/common.hpp b/src/common.hpp index c8ef4bf..db77a77 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -145,6 +145,7 @@ struct Option { CHAR_LENGTH, VARCHAR_LENGTH, BLOB_LENGTH, + DESC_INDEXES_IN_COLUMN, MAX } option; Option(Type t, Opt o, std::string n) diff --git a/src/help.cpp b/src/help.cpp index 5554a97..7c9d12b 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -248,6 +248,11 @@ void add_options() { opt->setBool(false); opt->setArgs(no_argument); + /* Number of columns in an index of a table */ + opt = newOption(Option::INT, Option::DESC_INDEXES_IN_COLUMN, "desc-prob"); + opt->help = "probability of using desc in index"; + opt->setInt(34); + /* Only Partition tables */ opt = newOption(Option::BOOL, Option::ONLY_PARTITION, "only-partition-tables"); diff --git a/src/random_test.cpp b/src/random_test.cpp index 6e56ef5..b4acc09 100644 --- a/src/random_test.cpp +++ b/src/random_test.cpp @@ -1451,83 +1451,85 @@ void Table::CreateDefaultColumn() { } } -/* create default indexes */ -void Table::CreateDefaultIndex() { - - int auto_inc_pos = -1; // auto_inc_column_position +static Index *add_index(const std::string &name, const Columns *cols, + bool auto_inc, int number_of_compressed) { - static size_t max_indexes = opt_int(INDEXES); - - if (max_indexes == 0) - return; - - /* if table have few column, decrease number of indexes */ - int indexes = rand_int( - columns_->size() < max_indexes ? columns_->size() : max_indexes, 1); + Index *id = new Index(name); + size_t number_of_columns = rand_int(cols->size() - number_of_compressed, 1); /* for auto-inc columns handling, we need to add auto_inc as first column */ - for (size_t i = 0; i < columns_->size(); i++) { - if (columns_->at(i)->auto_increment) { - auto_inc_pos = i; + int auto_inc_pos = -1; + if (auto_inc) { + for (size_t i = 0; i < cols->size(); i++) { + if (cols->at(i)->auto_increment) { + auto_inc_pos = i; + } } } - /*which column will hve auto_inc */ - int auto_inc_index = rand_int(indexes - 1, 0); - - for (int i = 0; i < indexes; i++) { - Index *id = new Index(name_ + "i" + std::to_string(i)); - - static size_t max_columns = opt_int(INDEX_COLUMNS); - - int number_of_compressed = 0; + std::vector col_pos; // position of columns + /* pick some columns */ + while (col_pos.size() < number_of_columns) { + int current = rand_int(cols->size() - 1); - for (auto column : *columns_) - if (column->compressed) - number_of_compressed++; + if (cols->at(current)->compressed) + continue; - size_t number_of_columns = columns_->size() - number_of_compressed; + /* auto-inc column should be first column in auto_inc_index */ + if (auto_inc_pos != -1 && col_pos.size() == 0) + col_pos.push_back(auto_inc_pos); + else { + bool already_added = false; + for (auto id : col_pos) { + if (id == current) + already_added = true; + } + if (!already_added) + col_pos.push_back(current); + } + } // while - /* only compressed columns */ - if (number_of_columns == 0) - return; + for (auto pos : col_pos) { + auto col = cols->at(pos); + bool column_desc = false; + if (options->at(Option::NO_DESC_INDEX)->getBool() == false && + rand_int(100) < options->at(Option::DESC_INDEXES_IN_COLUMN)->getInt()) { + column_desc = true; + } + id->AddInternalColumn(new Ind_col(col, column_desc)); // desc is set as true + } + return id; +} - number_of_columns = rand_int( - (max_columns < number_of_columns ? max_columns : number_of_columns), 1); +/* create default indexes */ +void Table::CreateDefaultIndex() { - std::vector col_pos; // position of columns + size_t number_of_compressed = 0; + for (auto column : *columns_) + if (column->compressed) + number_of_compressed++; - /* pick some columns */ - while (col_pos.size() < number_of_columns) { - int current = rand_int(columns_->size() - 1); - if (columns_->at(current)->compressed) - continue; - /* auto-inc column should be first column in auto_inc_index */ - if (auto_inc_pos != -1 && i == auto_inc_index && col_pos.size() == 0) - col_pos.push_back(auto_inc_pos); - else { - bool already_added = false; - for (auto id : col_pos) { - if (id == current) - already_added = true; - } - if (!already_added) - col_pos.push_back(current); - } - } // while + /* only compressed columns */ + if (columns_->size() == number_of_compressed) { + return; + } - for (auto pos : col_pos) { - auto col = columns_->at(pos); - static bool no_desc_support = opt_bool(NO_DESC_INDEX); - bool column_desc = false; - if (!no_desc_support) { - column_desc = rand_int(100) < DESC_INDEXES_IN_COLUMN - ? true - : false; // 33 % are desc // - } - id->AddInternalColumn( - new Ind_col(col, column_desc)); // desc is set as true - } + /* If table has few columns, decrease number of indexes */ + size_t indexes = rand_int(options->at(Option::INDEXES)->getInt()); + if (indexes == 0) + return; + else if (indexes > columns_->size() - number_of_compressed) + indexes = columns_->size() - number_of_compressed; + + /*which column will have auto_inc */ + size_t auto_inc_index = 0; + if (rand_int(100) <= 50) + auto_inc_index = rand_int(indexes, 1); + + for (size_t i = 1; i <= indexes; i++) { + std::string name = name_ + std::to_string(i); + auto try_autoinc = auto_inc_index == i ? true : false; + Index *id = add_index(name, columns_, try_autoinc, number_of_compressed); AddInternalIndex(id); } } @@ -2185,13 +2187,7 @@ void Table::AddIndex(Thd1 *thd) { for (auto pos : col_pos) { auto col = columns_->at(pos); - static bool no_desc_support = opt_bool(NO_DESC_INDEX); bool column_desc = false; - if (!no_desc_support) { - column_desc = rand_int(100) < DESC_INDEXES_IN_COLUMN - ? true - : false; // 33 % are desc // - } id->AddInternalColumn(new Ind_col(col, column_desc)); // desc is set as true } diff --git a/src/random_test.hpp b/src/random_test.hpp index 6ba9084..d8dc290 100644 --- a/src/random_test.hpp +++ b/src/random_test.hpp @@ -26,7 +26,6 @@ #define MIN_SEED_SIZE 10000 #define MAX_SEED_SIZE 100000 #define MAX_RANDOM_STRING_SIZE 32 -#define DESC_INDEXES_IN_COLUMN 34 #define MYSQL_8 8.0 #define opt_int(a) options->at(Option::a)->getInt(); @@ -34,6 +33,8 @@ #define opt_bool(a) options->at(Option::a)->getBool(); #define opt_string(a) options->at(Option::a)->getString() +class Column; +typedef std::vector Columns; int rand_int(int upper, int lower = 0); std::string rand_float(float upper, float lower = 0); std::string rand_double(double upper, double lower = 0); @@ -218,7 +219,7 @@ struct Table { std::string encryption = "N"; int key_block_size = 0; // std::string data_directory; todo add corressponding code - std::vector *columns_; + Columns *columns_; std::vector *indexes_; std::mutex table_mutex;